mirror of
https://github.com/kyleneideck/BackgroundMusic
synced 2024-11-10 06:34:22 +00:00
first attempt at using CARingBuffer
This commit is contained in:
parent
76e63965db
commit
40f0128dcd
4 changed files with 37 additions and 44 deletions
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue