Skip to content

Commit

Permalink
Fix distorted audio when passing input through tap
Browse files Browse the repository at this point in the history
  • Loading branch information
admsyn committed Jun 24, 2012
1 parent e8c851e commit 0ee34ea
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 39 deletions.
2 changes: 1 addition & 1 deletion src/ofxAudioUnit.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ class ofxAudioUnitInput : public ofxAudioUnit
RingBufferRef ringBuffer;
};

RenderContext _inputContext;
RenderContext _renderContext;
RingBufferRef _ringBuffer;
bool _isReady;
bool configureInputDevice();
Expand Down
50 changes: 28 additions & 22 deletions src/ofxAudioUnitInput.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,16 @@ void ofxAudioUnitInput::RingBuffer::advanceItr(ofxAudioUnitInput::RingBuffer::it
bool ofxAudioUnitInput::RingBuffer::advanceReadHead()
// ----------------------------------------------------------
{
if(_readItrIndex >= _writeItrIndex) return false;
advanceItr(_readItr);
_readItrIndex++;
return true;
if(_readItrIndex >= _writeItrIndex)
{
return false;
}
else
{
advanceItr(_readItr);
_readItrIndex++;
return true;
}
}

// ----------------------------------------------------------
Expand All @@ -71,10 +77,10 @@ ofxAudioUnitInput::ofxAudioUnitInput() : _isReady(false)
_desc = inputDesc;
initUnit();

_ringBuffer = RingBufferRef(new RingBuffer());
_ringBuffer = RingBufferRef(new ofxAudioUnitInput::RingBuffer());

_inputContext.inputUnit = _unit;
_inputContext.ringBuffer = _ringBuffer;
_renderContext.inputUnit = _unit;
_renderContext.ringBuffer = _ringBuffer;
}

// ----------------------------------------------------------
Expand All @@ -92,7 +98,7 @@ void ofxAudioUnitInput::connectTo(ofxAudioUnit &otherUnit, int destinationBus, i
{
AURenderCallbackStruct callback;
callback.inputProc = pullCallback;
callback.inputProcRefCon = &_inputContext;
callback.inputProcRefCon = &_renderContext;

AudioStreamBasicDescription ASBD;
UInt32 ASBDSize = sizeof(ASBD);
Expand Down Expand Up @@ -205,7 +211,7 @@ bool ofxAudioUnitInput::configureInputDevice()

AURenderCallbackStruct inputCallback;
inputCallback.inputProc = ofxAudioUnitInput::renderCallback;
inputCallback.inputProcRefCon = &_inputContext;
inputCallback.inputProcRefCon = &_renderContext;

OFXAU_RET_FALSE(AudioUnitSetProperty(*_unit,
kAudioOutputUnitProperty_SetInputCallback,
Expand All @@ -215,10 +221,8 @@ bool ofxAudioUnitInput::configureInputDevice()
sizeof(inputCallback)),
"setting hardware input callback");

OFXAU_RET_FALSE(AudioUnitInitialize(*_unit),
"initializing hardware input unit after setting it to input mode");

return true;
OFXAU_RET_BOOL(AudioUnitInitialize(*_unit),
"initializing hardware input unit after setting it to input mode");
}

#pragma mark - Callbacks / Rendering
Expand All @@ -231,7 +235,7 @@ OSStatus ofxAudioUnitInput::render(AudioUnitRenderActionFlags *ioActionFlags,
AudioBufferList *ioData)
// ----------------------------------------------------------
{
return pullCallback(&_inputContext, ioActionFlags, inTimeStamp,
return pullCallback(&_renderContext, ioActionFlags, inTimeStamp,
inOutputBusNumber, inNumberFrames, ioData);
}

Expand All @@ -244,9 +248,7 @@ OSStatus ofxAudioUnitInput::renderCallback(void *inRefCon,
AudioBufferList *ioData)
// ----------------------------------------------------------
{
RenderContext * ctx = static_cast<RenderContext *>(inRefCon);

AudioBufferList * d = ctx->ringBuffer->writeHead();
RenderContext * ctx = reinterpret_cast<RenderContext *>(inRefCon);

OSStatus s = AudioUnitRender(*(ctx->inputUnit),
ioActionFlags,
Expand All @@ -255,6 +257,8 @@ OSStatus ofxAudioUnitInput::renderCallback(void *inRefCon,
inNumberFrames,
ctx->ringBuffer->writeHead());

OFXAU_PRINT(s, "rendering audio input");

ctx->ringBuffer->advanceWriteHead();

return s;
Expand All @@ -269,7 +273,7 @@ OSStatus ofxAudioUnitInput::pullCallback(void *inRefCon,
AudioBufferList *ioData)
// ----------------------------------------------------------
{
RenderContext * ctx = static_cast<RenderContext *>(inRefCon);
RenderContext * ctx = reinterpret_cast<RenderContext *>(inRefCon);

// If we can't advance the read head, render silence.
// Otherwise, copy the data from the ring buffer's read head.
Expand All @@ -281,20 +285,22 @@ OSStatus ofxAudioUnitInput::pullCallback(void *inRefCon,
}

*ioActionFlags |= kAudioUnitRenderAction_OutputIsSilence;
return noErr;
}
else
{
AudioBufferList * bufferedAudio = ctx->ringBuffer->readHead();
int buffersToCopy = min(ioData->mNumberBuffers, bufferedAudio->mNumberBuffers);
size_t bytesToCopy = min(ioData->mBuffers[0].mDataByteSize,
bufferedAudio->mBuffers[0].mDataByteSize);
bytesToCopy = min(bytesToCopy, inNumberFrames * sizeof(AudioUnitSampleType));

for(int i = 0; i < buffersToCopy; i++)
{
memcpy(ioData->mBuffers[i].mData,
bufferedAudio->mBuffers[i].mData,
bufferedAudio->mBuffers[i].mDataByteSize);
bytesToCopy);
}

return noErr;
}

return noErr;
}
17 changes: 1 addition & 16 deletions src/ofxAudioUnitTap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,22 +51,7 @@ void ofxAudioUnitTap::connectTo(ofxAudioUnit &destination, int destinationBus, i

AudioStreamBasicDescription asbd = {0};
UInt32 dataSize = sizeof(AudioStreamBasicDescription);

// Connect the source to the destination.
// The only reason for this is so that they can sort out their
// own ASBDs. The destination unit will be connected to the tap's
// render callback afterwards.
AudioUnitConnection c;
c.sourceAudioUnit = *(_sourceUnit->getUnit());
c.sourceOutputNumber = sourceBus;
c.destInputNumber = destinationBus;
AudioUnitSetProperty(*(destination.getUnit()),
kAudioUnitProperty_MakeConnection,
kAudioUnitScope_Global,
destinationBus,
&c,
sizeof(c));


AudioUnitGetProperty(*(_sourceUnit->getUnit()),
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Output,
Expand Down

0 comments on commit 0ee34ea

Please sign in to comment.