first attempt at using CARingBuffer

This commit is contained in:
Gordon Childs 2019-06-26 02:09:00 +02:00 committed by Kyle Neideck
parent 76e63965db
commit 40f0128dcd
No known key found for this signature in database
GPG key ID: CAA8D9B8E39EC18C
4 changed files with 37 additions and 44 deletions

View file

@ -87,13 +87,13 @@ public:
// Return false for failure (buffer not large enough).
CARingBufferError Fetch(AudioBufferList *abl, UInt32 nFrames, SampleTime frameNumber);
// will alter mNumDataBytes of the buffers
// will alter mDataByteSize of the buffers
CARingBufferError GetTimeBounds(SampleTime &startTime, SampleTime &endTime);
protected:
int FrameOffset(SampleTime frameNumber) { return (frameNumber & mCapacityFramesMask) * mBytesPerFrame; }
UInt32 FrameOffset(SampleTime frameNumber) { return (frameNumber & mCapacityFramesMask) * mBytesPerFrame; }
CARingBufferError ClipTimeBounds(SampleTime& startRead, SampleTime& endRead);

View file

@ -78,6 +78,8 @@
2795973E1C9847CF00A002FB /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2795973D1C9847CF00A002FB /* Foundation.framework */; };
27D643C31C9FBE1600737F6E /* BGM_XPCHelper.m in Sources */ = {isa = PBXBuildFile; fileRef = 27381A141C8EF50F00DF167C /* BGM_XPCHelper.m */; };
27E6B5F01E01966A00EC0AAB /* BGM_Utils.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 275343BC1DE9B44900DF3858 /* BGM_Utils.cpp */; };
6C6B069522C2DB1D0034C4A9 /* CARingBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 6C6B069322C2DB1D0034C4A9 /* CARingBuffer.cpp */; };
6C6B069622C2DB1D0034C4A9 /* CARingBuffer.h in Headers */ = {isa = PBXBuildFile; fileRef = 6C6B069422C2DB1D0034C4A9 /* CARingBuffer.h */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
@ -163,6 +165,8 @@
27D643B71C9FABF600737F6E /* BGM_Types.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BGM_Types.h; path = ../SharedSource/BGM_Types.h; sourceTree = "<group>"; };
27D643B81C9FABF600737F6E /* BGMXPCProtocols.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BGMXPCProtocols.h; path = ../SharedSource/BGMXPCProtocols.h; sourceTree = "<group>"; };
27D643C21C9FBC5800737F6E /* BGM_TestUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BGM_TestUtils.h; path = ../SharedSource/BGM_TestUtils.h; sourceTree = "<group>"; };
6C6B069322C2DB1D0034C4A9 /* CARingBuffer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CARingBuffer.cpp; path = ../BGMApp/PublicUtility/CARingBuffer.cpp; sourceTree = "<group>"; };
6C6B069422C2DB1D0034C4A9 /* CARingBuffer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CARingBuffer.h; path = ../BGMApp/PublicUtility/CARingBuffer.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -322,6 +326,8 @@
1C3821101C4A18DE00A0C8C6 /* CAPThread.h */,
1CB8B38C1BBCF4A9000E2DD1 /* CAVolumeCurve.cpp */,
1CB8B38D1BBCF4A9000E2DD1 /* CAVolumeCurve.h */,
6C6B069322C2DB1D0034C4A9 /* CARingBuffer.cpp */,
6C6B069422C2DB1D0034C4A9 /* CARingBuffer.h */,
);
name = PublicUtility;
sourceTree = "<group>";
@ -356,6 +362,7 @@
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
6C6B069622C2DB1D0034C4A9 /* CARingBuffer.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -555,6 +562,7 @@
2743C9E01D7EF8760089613B /* CAMutex.cpp in Sources */,
2743C9E21D7EF8760089613B /* CAPThread.cpp in Sources */,
2743C9E41D7EF8760089613B /* CAVolumeCurve.cpp in Sources */,
6C6B069522C2DB1D0034C4A9 /* CARingBuffer.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View file

@ -143,6 +143,10 @@ BGM_Device::BGM_Device(AudioObjectID inObjectID,
{
// Initialises the loopback clock with the default sample rate and, if there is one, sets the wrapped device to the same sample rate
SetSampleRate(kSampleRateDefault, true);
// Had to include channel count in bytesPerFrame to make audio server's interleaved
// look like non-interleaved to CARingBuffer. Right?
mLoopbackRingBuffer.Allocate(2, 2 * sizeof(float), kLoopbackRingBufferFrameSize);
}
BGM_Device::~BGM_Device()
@ -201,7 +205,8 @@ void BGM_Device::InitLoopback()
// Zero-out the loopback buffer
// 2 channels * 32-bit float = bytes in each frame
memset(mLoopbackRingBuffer, 0, sizeof(Float32) * 2 * kLoopbackRingBufferFrameSize);
// memset(mLoopbackRingBuffer, 0, sizeof(Float32) * 2 * kLoopbackRingBufferFrameSize);
// TODO: reset CARingBuffer. but how? can I reallocate here? subclass and call set SetTimeBounds?
}
#pragma mark Property Operations
@ -1425,52 +1430,30 @@ void BGM_Device::EndIOOperation(UInt32 inOperationID, UInt32 inIOBufferFrameSize
void BGM_Device::ReadInputData(UInt32 inIOBufferFrameSize, Float64 inSampleTime, void* outBuffer)
{
// figure out where we are starting
UInt64 theSampleTime = static_cast<UInt64>(inSampleTime);
UInt32 theStartFrameOffset = theSampleTime % kLoopbackRingBufferFrameSize;
// figure out how many frames we need to copy
UInt32 theNumberFramesToCopy1 = inIOBufferFrameSize;
UInt32 theNumberFramesToCopy2 = 0;
if((theStartFrameOffset + theNumberFramesToCopy1) > kLoopbackRingBufferFrameSize)
{
theNumberFramesToCopy1 = kLoopbackRingBufferFrameSize - theStartFrameOffset;
theNumberFramesToCopy2 = inIOBufferFrameSize - theNumberFramesToCopy1;
}
// do the copying (the byte sizes here assume a 32 bit stereo sample format)
Float32* theDestination = reinterpret_cast<Float32*>(outBuffer);
memcpy(theDestination, mLoopbackRingBuffer + (theStartFrameOffset * 2), theNumberFramesToCopy1 * 8);
if(theNumberFramesToCopy2 > 0)
{
memcpy(theDestination + (theNumberFramesToCopy1 * 2), mLoopbackRingBuffer, theNumberFramesToCopy2 * 8);
}
AudioBufferList abl = {
.mNumberBuffers = 1,
.mBuffers[0] = {
.mNumberChannels = 2,
.mDataByteSize = static_cast<UInt32>(inIOBufferFrameSize * sizeof(float) * 2),
.mData = outBuffer
}
};
mLoopbackRingBuffer.Fetch(&abl, inIOBufferFrameSize, static_cast<CARingBuffer::SampleTime>(inSampleTime));
//DebugMsg("BGM_Device::ReadInputData: Reading. theSampleTime=%llu theStartFrameOffset=%u theNumberFramesToCopy1=%u theNumberFramesToCopy2=%u", theSampleTime, theStartFrameOffset, theNumberFramesToCopy1, theNumberFramesToCopy2);
}
void BGM_Device::WriteOutputData(UInt32 inIOBufferFrameSize, Float64 inSampleTime, const void* inBuffer)
{
// figure out where we are starting
UInt64 theSampleTime = static_cast<UInt64>(inSampleTime);
UInt32 theStartFrameOffset = theSampleTime % kLoopbackRingBufferFrameSize;
// figure out how many frames we need to copy
UInt32 theNumberFramesToCopy1 = inIOBufferFrameSize;
UInt32 theNumberFramesToCopy2 = 0;
if((theStartFrameOffset + theNumberFramesToCopy1) > kLoopbackRingBufferFrameSize)
{
theNumberFramesToCopy1 = kLoopbackRingBufferFrameSize - theStartFrameOffset;
theNumberFramesToCopy2 = inIOBufferFrameSize - theNumberFramesToCopy1;
}
// do the copying (the byte sizes here assume a 32 bit stereo sample format)
const Float32* theSource = reinterpret_cast<const Float32*>(inBuffer);
memcpy(mLoopbackRingBuffer + (theStartFrameOffset * 2), theSource, theNumberFramesToCopy1 * 8);
if(theNumberFramesToCopy2 > 0)
{
memcpy(mLoopbackRingBuffer, theSource + (theNumberFramesToCopy1 * 2), theNumberFramesToCopy2 * 8);
}
AudioBufferList abl = {
.mNumberBuffers = 1,
.mBuffers[0] = {
.mNumberChannels = 2,
.mDataByteSize = static_cast<UInt32>(inIOBufferFrameSize * sizeof(float) * 2),
.mData = const_cast<void *>(inBuffer)
}
};
/*CARingBufferError err = */mLoopbackRingBuffer.Store(&abl, inIOBufferFrameSize, static_cast<CARingBuffer::SampleTime>(inSampleTime));
//DebugMsg("BGM_Device::WriteOutputData: Writing. theSampleTime=%llu theStartFrameOffset=%u theNumberFramesToCopy1=%u theNumberFramesToCopy2=%u", theSampleTime, theStartFrameOffset, theNumberFramesToCopy1, theNumberFramesToCopy2);
}

View file

@ -43,6 +43,7 @@
// PublicUtility Includes
#include "CAMutex.h"
#include "CAVolumeCurve.h"
#include "CARingBuffer.h"
// System Includes
#include <CoreFoundation/CoreFoundation.h>
@ -237,7 +238,8 @@ private:
#define kLoopbackRingBufferFrameSize 16384
Float64 mLoopbackSampleRate;
Float32 mLoopbackRingBuffer[kLoopbackRingBufferFrameSize * 2];
CARingBuffer mLoopbackRingBuffer;
// TODO: a comment explaining why we need a clock for loopback-only mode
struct {
Float64 hostTicksPerFrame = 0.0;