diff --git a/OSBindings/Mac/Clock Signal/Wrappers/AudioQueue.h b/OSBindings/Mac/Clock Signal/Wrappers/AudioQueue.h index d72eed389..cf96e1166 100644 --- a/OSBindings/Mac/Clock Signal/Wrappers/AudioQueue.h +++ b/OSBindings/Mac/Clock Signal/Wrappers/AudioQueue.h @@ -10,6 +10,6 @@ @interface AudioQueue : NSObject -- (void)enqueueAudioBuffer:(const int16_t *)buffer numberOfSamples:(unsigned int)lengthInSamples; +- (void)enqueueAudioBuffer:(const int16_t *)buffer numberOfSamples:(size_t)lengthInSamples; @end diff --git a/OSBindings/Mac/Clock Signal/Wrappers/AudioQueue.m b/OSBindings/Mac/Clock Signal/Wrappers/AudioQueue.m index e22ba865f..b0b72bb59 100644 --- a/OSBindings/Mac/Clock Signal/Wrappers/AudioQueue.m +++ b/OSBindings/Mac/Clock Signal/Wrappers/AudioQueue.m @@ -17,9 +17,8 @@ { AudioQueueRef _audioQueue; AudioQueueBufferRef _audioBuffers[AudioQueueNumAudioBuffers]; - unsigned int _audioStreamReadPosition, _audioStreamWritePosition, _queuedAudioStreamSegments; + unsigned int _audioStreamReadPosition, _audioStreamWritePosition; int16_t _audioStream[AudioQueueStreamLength]; - BOOL _isOutputtingAudio; } @@ -30,18 +29,26 @@ { @synchronized(self) { - if(_queuedAudioStreamSegments > AudioQueueNumAudioBuffers-1) _isOutputtingAudio = YES; - - if(_isOutputtingAudio && _queuedAudioStreamSegments) + const unsigned int writeLead = _audioStreamWritePosition - _audioStreamReadPosition; + const size_t audioDataSampleSize = buffer->mAudioDataByteSize / sizeof(int16_t); + if(writeLead >= audioDataSampleSize) { - _queuedAudioStreamSegments--; - memcpy(buffer->mAudioData, &_audioStream[_audioStreamReadPosition], buffer->mAudioDataByteSize); - _audioStreamReadPosition = (_audioStreamReadPosition + AudioQueueBufferLength)%AudioQueueStreamLength; + size_t samplesBeforeOverflow = AudioQueueStreamLength - (_audioStreamReadPosition % AudioQueueStreamLength); + if(audioDataSampleSize <= samplesBeforeOverflow) + { + memcpy(buffer->mAudioData, &_audioStream[_audioStreamReadPosition % AudioQueueStreamLength], buffer->mAudioDataByteSize); + } + else + { + const size_t bytesRemaining = samplesBeforeOverflow * sizeof(int16_t); + memcpy(buffer->mAudioData, &_audioStream[_audioStreamReadPosition % AudioQueueStreamLength], bytesRemaining); + memcpy(buffer->mAudioData, &_audioStream[0], buffer->mAudioDataByteSize - bytesRemaining); + } + _audioStreamReadPosition += audioDataSampleSize; } else { memset(buffer->mAudioData, 0, buffer->mAudioDataByteSize); - _isOutputtingAudio = NO; } AudioQueueEnqueueBuffer(theAudioQueue, buffer, 0, NULL); } @@ -91,7 +98,6 @@ static void audioOutputCallback( 0, &_audioQueue)) { - _audioStreamWritePosition = AudioQueueBufferLength; UInt32 bufferBytes = AudioQueueBufferLength * sizeof(int16_t); int c = AudioQueueNumAudioBuffers; @@ -115,21 +121,23 @@ static void audioOutputCallback( if(_audioQueue) AudioQueueDispose(_audioQueue, NO); } -- (void)enqueueAudioBuffer:(const int16_t *)buffer numberOfSamples:(unsigned int)lengthInSamples +- (void)enqueueAudioBuffer:(const int16_t *)buffer numberOfSamples:(size_t)lengthInSamples { @synchronized(self) { - memcpy(&_audioStream[_audioStreamWritePosition], buffer, lengthInSamples * sizeof(int16_t)); - _audioStreamWritePosition = (_audioStreamWritePosition + lengthInSamples)%AudioQueueStreamLength; + size_t samplesBeforeOverflow = AudioQueueStreamLength - (_audioStreamWritePosition % AudioQueueStreamLength); - if(_queuedAudioStreamSegments == (AudioQueueStreamLength/AudioQueueBufferLength)) + if(samplesBeforeOverflow < lengthInSamples) { - _audioStreamReadPosition = (_audioStreamReadPosition + lengthInSamples)%AudioQueueStreamLength; + memcpy(&_audioStream[_audioStreamWritePosition % AudioQueueStreamLength], buffer, samplesBeforeOverflow * sizeof(int16_t)); + memcpy(&_audioStream[0], &buffer[samplesBeforeOverflow], (lengthInSamples - samplesBeforeOverflow) * sizeof(int16_t)); } else { - _queuedAudioStreamSegments++; + memcpy(&_audioStream[_audioStreamWritePosition % AudioQueueStreamLength], buffer, lengthInSamples * sizeof(int16_t)); } + + _audioStreamWritePosition += lengthInSamples; } } diff --git a/OSBindings/Mac/Clock Signal/Wrappers/CSElectron.mm b/OSBindings/Mac/Clock Signal/Wrappers/CSElectron.mm index 90477f081..446209f94 100644 --- a/OSBindings/Mac/Clock Signal/Wrappers/CSElectron.mm +++ b/OSBindings/Mac/Clock Signal/Wrappers/CSElectron.mm @@ -13,9 +13,21 @@ @implementation CSElectron { Electron::Machine _electron; + + NSTimeInterval _periodicStart; + int _numberOfCycles; } - (void)doRunForNumberOfCycles:(int)numberOfCycles { + _numberOfCycles += numberOfCycles; + NSTimeInterval timeNow = [NSDate timeIntervalSinceReferenceDate]; + NSTimeInterval difference = timeNow - _periodicStart; + if(difference > 1.0) + { + NSLog(@"cycles: %0.0f", (double)_numberOfCycles / difference); + _periodicStart = timeNow; + _numberOfCycles = 0; + } _electron.run_for_cycles(numberOfCycles); } diff --git a/Outputs/Speaker.hpp b/Outputs/Speaker.hpp index 077b5014b..5b42e651a 100644 --- a/Outputs/Speaker.hpp +++ b/Outputs/Speaker.hpp @@ -11,6 +11,7 @@ #include #include +#include #include "../SignalProcessing/Stepper.hpp" namespace Outputs { @@ -76,6 +77,17 @@ template class Filter: public Speaker { { if(_coefficients_are_dirty) update_filter_coefficients(); + _periodic_cycles += input_cycles; + time_t time_now = time(nullptr); + if(time_now > _periodic_start) + { + printf("input audio samples: %d\n", _periodic_cycles); + printf("output audio samples: %d\n", _periodic_output); + _periodic_cycles = 0; + _periodic_output = 0; + _periodic_start = time_now; + } + // point sample for now, as a temporary measure input_cycles += _input_cycles_carry; while(input_cycles > 0) @@ -99,11 +111,17 @@ template class Filter: public Speaker { if(steps > 1) static_cast(this)->skip_samples((unsigned int)(steps-1)); input_cycles -= steps; + _periodic_output ++; } _input_cycles_carry = input_cycles; } + Filter() : _periodic_cycles(0), _periodic_start(0) {} + private: + time_t _periodic_start; + int _periodic_cycles; + int _periodic_output; SignalProcessing::Stepper *_stepper; int _input_cycles_carry;