diff --git a/Machines/Electron/Electron.cpp b/Machines/Electron/Electron.cpp index d3d0530d3..403a592da 100644 --- a/Machines/Electron/Electron.cpp +++ b/Machines/Electron/Electron.cpp @@ -32,7 +32,7 @@ Machine::Machine() : for(int c = 0; c < 16; c++) memset(_roms[c], 0xff, 16384); - _speaker.set_input_rate(62500); + _speaker.set_input_rate(125000); setup6502(); } @@ -315,8 +315,8 @@ inline void Machine::update_audio() { int difference = _frameCycles - _audioOutputPosition; _audioOutputPosition = _frameCycles; - _speaker.run_for_cycles((_audioOutputPositionError + difference) >> 5); - _audioOutputPositionError = (_audioOutputPositionError + difference)&31; + _speaker.run_for_cycles((_audioOutputPositionError + difference) >> 4); + _audioOutputPositionError = (_audioOutputPositionError + difference)&15; } inline void Machine::update_display() @@ -493,3 +493,8 @@ void Machine::set_key_state(Key key, bool isPressed) _keyStates[key >> 4] &= ~(key&0xf); } } + +void Machine::Speaker::get_sample_range(uint64_t start_time, int number_of_samples, uint16_t *target) +{ + *target = 0; +} diff --git a/Machines/Electron/Electron.hpp b/Machines/Electron/Electron.hpp index cbbd83c3e..d2fa989bf 100644 --- a/Machines/Electron/Electron.hpp +++ b/Machines/Electron/Electron.hpp @@ -100,6 +100,8 @@ class Machine: public CPU6502::Processor { public: uint8_t divider; bool is_enabled; + + void get_sample_range(uint64_t start_time, int number_of_samples, uint16_t *target); } _speaker; }; diff --git a/Outputs/Speaker.hpp b/Outputs/Speaker.hpp index 6a1b24928..09eb974d6 100644 --- a/Outputs/Speaker.hpp +++ b/Outputs/Speaker.hpp @@ -19,7 +19,7 @@ class Speaker { public: class Delegate { 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) @@ -77,10 +77,28 @@ template class Filter: public Speaker { // point sample for now, as a temporary measure while(input_cycles--) { -// static_cast(this)->perform_bus_operation(); + // get a sample for the current location + static_cast(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: SignalProcessing::Stepper *_stepper; diff --git a/SignalProcessing/Stepper.hpp b/SignalProcessing/Stepper.hpp index ad61480c4..bb4ae754d 100644 --- a/SignalProcessing/Stepper.hpp +++ b/SignalProcessing/Stepper.hpp @@ -16,11 +16,11 @@ namespace SignalProcessing { class Stepper { 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; - adjustment_up_ = (int64_t)(output_rate % input_rate) << 1; - adjustment_down_ = (int64_t)input_rate << 1; + whole_step_ = output_rate / update_rate; + adjustment_up_ = (int64_t)(output_rate % update_rate) << 1; + adjustment_down_ = (int64_t)update_rate << 1; } inline uint64_t update()