static unsafe void DeriveBufferSize(AudioStreamBasicDescription *ASBDesc, int maxPacketSize, double seconds, int *outBufferSize, int *outNumPacketsToRead) { const int maxBufferSize = 0x10000; const int minBufferSize = 0x4000; if (ASBDesc->FramesPerPacket != 0) { double numPacketsForTime = ASBDesc->SampleRate / ASBDesc->FramesPerPacket * seconds; * outBufferSize = (int)(numPacketsForTime * maxPacketSize); } else { *outBufferSize = maxBufferSize > maxPacketSize ? maxBufferSize : maxPacketSize; } if (*outBufferSize > maxBufferSize && *outBufferSize > maxPacketSize) { *outBufferSize = maxBufferSize; } else { if (*outBufferSize < minBufferSize) { *outBufferSize = minBufferSize; } } *outNumPacketsToRead = *outBufferSize / maxPacketSize; }
private static unsafe void CreateQueue(AudioStream *pThis) { int dataFormatSize = sizeof(AudioStreamBasicDescription); AudioStreamBasicDescription *pDataFormat = &pThis->DataFormat; OSStatus status = API.AudioFileGetProperty(pThis->AudioFile, AudioFileProperty.DataFormat, &dataFormatSize, pDataFormat); API.CheckStatus(status); status = API.AudioQueueNewOutput(pDataFormat, OnReadBuffer, pThis, null, null, 0, &pThis->Queue); API.CheckStatus(status); dataFormatSize = sizeof(int); int *pMaxPacketSize = &pThis->MaxPacketSize; status = API.AudioFileGetProperty(pThis->AudioFile, AudioFileProperty.PacketSizeUpperBound, &dataFormatSize, pMaxPacketSize); API.CheckStatus(status); DeriveBufferSize(&pThis->DataFormat, pThis->MaxPacketSize, 0.5, &pThis->BufferByteSize, &pThis->NumPacketsToRead); }
extern static int AudioFileGetGlobalInfo(AudioFileGlobalProperty propertyID, uint size, ref AudioFileTypeAndFormatID inSpecifier, ref uint ioDataSize, AudioStreamBasicDescription *outPropertyData);
public static extern unsafe OSStatus AudioQueueNewOutput(AudioStreamBasicDescription *pFormat, AudioQueueOutputCallback callback, void *pUserData, void *runLoop, void *pRunLoopMode, uint flags, AudioQueue **pQueue);