diff --git a/OSBindings/Mac/Clock Signal/Audio/CSAudioQueue.m b/OSBindings/Mac/Clock Signal/Audio/CSAudioQueue.m index 1e0e6fd89..538133bcf 100644 --- a/OSBindings/Mac/Clock Signal/Audio/CSAudioQueue.m +++ b/OSBindings/Mac/Clock Signal/Audio/CSAudioQueue.m @@ -30,6 +30,8 @@ atomic_int _enqueuedBuffers; AudioQueueBufferRef _buffers[NumBuffers]; int _bufferWritePointer; + + unsigned int _numChannels; } #pragma mark - Status @@ -49,6 +51,7 @@ atomic_store_explicit(&_enqueuedBuffers, 0, memory_order_relaxed); _samplingRate = samplingRate; + _numChannels = isStereo ? 2 : 1; // Determine preferred buffer size as being the first power of two // not less than 1/100th of a second. @@ -138,20 +141,20 @@ // Allocate future audio buffers. [_queueLock lock]; - const size_t bufferBytes = self.bufferSize * sizeof(int16_t); + const size_t bufferBytes = self.bufferSize * sizeof(int16_t) * _numChannels; for(size_t c = 0; c < NumBuffers; c++) { if(_buffers[c]) { OSSGuard(AudioQueueFreeBuffer(_audioQueue, _buffers[c])); } - OSSGuard(AudioQueueAllocateBuffer(_audioQueue, (UInt32)bufferBytes * 2, &_buffers[c])); + OSSGuard(AudioQueueAllocateBuffer(_audioQueue, (UInt32)bufferBytes, &_buffers[c])); _buffers[c]->mAudioDataByteSize = (UInt32)bufferBytes; } [_queueLock unlock]; } - (void)enqueueAudioBuffer:(const int16_t *)buffer { - const size_t bufferBytes = self.bufferSize * sizeof(int16_t); + const size_t bufferBytes = self.bufferSize * sizeof(int16_t) * _numChannels; // Don't enqueue more than the allowed number of future buffers, // to ensure not too much latency accrues. diff --git a/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm b/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm index 295262a60..cd2a28075 100644 --- a/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm +++ b/OSBindings/Mac/Clock Signal/Machine/CSMachine.mm @@ -176,7 +176,7 @@ struct ActivityObserver: public Activity::Observer { } - (void)speaker:(Outputs::Speaker::Speaker *)speaker didCompleteSamples:(const int16_t *)samples length:(int)length { - assert(NSUInteger(length) == self.audioQueue.bufferSize); + assert(NSUInteger(length) == self.audioQueue.bufferSize*(speaker->get_is_stereo() ? 2 : 1)); [self.audioQueue enqueueAudioBuffer:samples]; } diff --git a/Outputs/Speaker/Implementation/LowpassSpeaker.hpp b/Outputs/Speaker/Implementation/LowpassSpeaker.hpp index d9d6aaa46..2d31d97a7 100644 --- a/Outputs/Speaker/Implementation/LowpassSpeaker.hpp +++ b/Outputs/Speaker/Implementation/LowpassSpeaker.hpp @@ -239,9 +239,9 @@ template class LowpassBase: public Speaker } protected: - void process(size_t length) { + bool process(size_t length) { const auto delegate = delegate_.load(std::memory_order::memory_order_relaxed); - if(!delegate) return; + if(!delegate) return false; const int scale = static_cast(this)->get_scale(); @@ -286,6 +286,8 @@ template class LowpassBase: public Speaker // TODO: input rate is less than output rate. break; } + + return true; } }; @@ -334,8 +336,11 @@ template class PushLowpass: public LowpassBase