mirror of
https://github.com/TomHarte/CLK.git
synced 2024-12-24 12:30:17 +00:00
Added lots of debugging output while I attempt to locate the source of audio scratchiness, also simplified manner of dealing with wraparound within the AudioQueue wrapper.
This commit is contained in:
parent
b58e59e2bb
commit
ddcc34740b
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
#include "../SignalProcessing/Stepper.hpp"
|
||||
|
||||
namespace Outputs {
|
||||
@ -76,6 +77,17 @@ template <class T> 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 T> class Filter: public Speaker {
|
||||
if(steps > 1)
|
||||
static_cast<T *>(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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user