1
0
mirror of https://github.com/TomHarte/CLK.git synced 2024-11-17 10:06:21 +00:00

I'm not yet completely convinced by my approach to time basing, but it'll probably do? If so then this more or less gets me ready for a point-sampled filtering.

This commit is contained in:
Thomas Harte 2016-01-13 22:02:39 -05:00
parent d9a7ef9e46
commit 49e89a4bcb
4 changed files with 34 additions and 9 deletions

View File

@ -32,7 +32,7 @@ Machine::Machine() :
for(int c = 0; c < 16; c++) for(int c = 0; c < 16; c++)
memset(_roms[c], 0xff, 16384); memset(_roms[c], 0xff, 16384);
_speaker.set_input_rate(62500); _speaker.set_input_rate(125000);
setup6502(); setup6502();
} }
@ -315,8 +315,8 @@ inline void Machine::update_audio()
{ {
int difference = _frameCycles - _audioOutputPosition; int difference = _frameCycles - _audioOutputPosition;
_audioOutputPosition = _frameCycles; _audioOutputPosition = _frameCycles;
_speaker.run_for_cycles((_audioOutputPositionError + difference) >> 5); _speaker.run_for_cycles((_audioOutputPositionError + difference) >> 4);
_audioOutputPositionError = (_audioOutputPositionError + difference)&31; _audioOutputPositionError = (_audioOutputPositionError + difference)&15;
} }
inline void Machine::update_display() inline void Machine::update_display()
@ -493,3 +493,8 @@ void Machine::set_key_state(Key key, bool isPressed)
_keyStates[key >> 4] &= ~(key&0xf); _keyStates[key >> 4] &= ~(key&0xf);
} }
} }
void Machine::Speaker::get_sample_range(uint64_t start_time, int number_of_samples, uint16_t *target)
{
*target = 0;
}

View File

@ -100,6 +100,8 @@ class Machine: public CPU6502::Processor<Machine> {
public: public:
uint8_t divider; uint8_t divider;
bool is_enabled; bool is_enabled;
void get_sample_range(uint64_t start_time, int number_of_samples, uint16_t *target);
} _speaker; } _speaker;
}; };

View File

@ -19,7 +19,7 @@ class Speaker {
public: public:
class Delegate { class Delegate {
public: public:
virtual void speaker_did_complete_samples(uint8_t *buffer); virtual void speaker_did_complete_samples(Speaker *speaker, const uint16_t *buffer, int buffer_size);
}; };
void set_output_rate(int cycles_per_second, int buffer_size) void set_output_rate(int cycles_per_second, int buffer_size)
@ -77,10 +77,28 @@ template <class T> class Filter: public Speaker {
// point sample for now, as a temporary measure // point sample for now, as a temporary measure
while(input_cycles--) while(input_cycles--)
{ {
// static_cast<T *>(this)->perform_bus_operation(); // get a sample for the current location
static_cast<T *>(this)->get_sample_range(time_base, 1, &_buffer_in_progress[_buffer_in_progress_pointer]);
_buffer_in_progress_pointer++;
// announce to delegate if full
if(_buffer_in_progress_pointer == _buffer_size)
{
_buffer_in_progress_pointer = 0;
if(_delegate)
{
_delegate->speaker_did_complete_samples(this, _buffer_in_progress, _buffer_size);
} }
} }
// determine how many source samples to step
time_base += _stepper->update();
}
}
protected:
uint64_t time_base;
private: private:
SignalProcessing::Stepper *_stepper; SignalProcessing::Stepper *_stepper;

View File

@ -16,11 +16,11 @@ namespace SignalProcessing {
class Stepper class Stepper
{ {
public: public:
Stepper(uint64_t input_rate, uint64_t output_rate) Stepper(uint64_t output_rate, uint64_t update_rate)
{ {
whole_step_ = output_rate / input_rate; whole_step_ = output_rate / update_rate;
adjustment_up_ = (int64_t)(output_rate % input_rate) << 1; adjustment_up_ = (int64_t)(output_rate % update_rate) << 1;
adjustment_down_ = (int64_t)input_rate << 1; adjustment_down_ = (int64_t)update_rate << 1;
} }
inline uint64_t update() inline uint64_t update()