Broken drivers 1 and 2. BROKEN_DRIVER_1 plays the audio really poorly (lots of static) but seems to get the playing position correct, at least most of the time it returns a valid position.

BROKEN_DRIVER_2 on the other hand, plays the sound fine, except it seems to change volume, but not during game play, or when it gets a buffer underrun in which case it emits this awful buzzing sound. That happens mostly before the start of a song. However, the position returned is completely invalid.

One of these must work eventually. *sigh*
This commit is contained in:
Steve Checkoway
2003-09-05 00:07:22 +00:00
parent d63eac91f4
commit 6f99281965
2 changed files with 171 additions and 6 deletions
+146 -6
View File
@@ -17,6 +17,10 @@
#include <vector>
#include <AudioToolbox/AudioToolbox.h>
#include <CoreAudio/CoreAudio.h>
#if CURRENT_DRIVER == BROKEN_DRIVER_2
#include <AudioUnit/AudioUnit.h>
#endif
const Float64 kSampleRate = 44100.000;
const UInt32 kChannelsPerFrame = 2;
@@ -25,8 +29,6 @@ const UInt32 kSampleSize = kChannelsPerFrame * kBitsPerChannel / 8;
const UInt32 kPacketSize = kSampleSize;
static AudioDeviceID outputDevice;
#if defined(DEBUG)
static char *__errorMessage;
static char __fourcc[5];
@@ -44,6 +46,10 @@ free(__errorMessage)
RageSound_CA::RageSound_CA()
{
#if CURRENT_DRIVER != BROKEN_DRIVER_1 && CURRENT_DRIVER != BROKEN_DRIVER_2
RageException::ThrowNonfatal("Class not finished");
#endif
#if CURRENT_DRIVER == BROKEN_DRIVER_1
UInt32 thePropertySize = sizeof(AudioDeviceID);
OSStatus err;
@@ -77,6 +83,12 @@ RageSound_CA::RageSound_CA()
err = AudioConverterNew(&idealFormat, &streamFormat, &converter);
TEST_ERR(err);
/*thePropertySize = sizeof(UInt32);
UInt32 frames = 1024;
err = AudioStreamSetProperty(outputDevice, NULL, kAudioPropertyWildcardChannel,
kAudioDevicePropertyBufferFrameSize, thePropertySize, &frames);
TEST_ERR(err);*/
/* Calculate the input buffersize */
thePropertySize = sizeof(UInt32);
err = AudioDeviceGetProperty(outputDevice, 0, 0, kAudioDevicePropertyBufferSize, &thePropertySize,
@@ -116,10 +128,85 @@ RageSound_CA::RageSound_CA()
TEST_ERR(err);
latency = 0; //for now
#elif CURRENT_DRIVER == BROKEN_DRIVER_2
/* Open the default output unit */
OSStatus err;
ComponentDescription desc;
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_DefaultOutput;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
Component comp = FindNextComponent(NULL, &desc);
RAGE_ASSERT_M(comp != NULL, "Couldn't find the component");
err = OpenAComponent(comp, &outputUnit);
TEST_ERR(err);
/* Set the callback */
AURenderCallbackStruct callback;
callback.inputProc = GetData;
callback.inputProcRefCon = this;
err = AudioUnitSetProperty(outputUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Input,
0,
&callback,
sizeof(callback));
TEST_ERR(err);
/* Set the input format */
AudioStreamBasicDescription idealFormat;
idealFormat.mSampleRate = kSampleRate;
idealFormat.mFormatID = kAudioFormatLinearPCM;
idealFormat.mFormatFlags = kLinearPCMFormatFlagIsBigEndian | kLinearPCMFormatFlagIsPacked
| kLinearPCMFormatFlagIsSignedInteger;
idealFormat.mBytesPerPacket = kPacketSize;
idealFormat.mFramesPerPacket = 1;
idealFormat.mBytesPerFrame = kPacketSize;
idealFormat.mChannelsPerFrame = kChannelsPerFrame;
idealFormat.mBitsPerChannel = kBitsPerChannel;
idealFormat.mReserved = 0;
err = AudioUnitSetProperty(outputUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
0,
&idealFormat,
sizeof(idealFormat));
TEST_ERR(err);
/* Calculate the latency */
latency = 0;
/* Initialize the unit */
err = AudioUnitInitialize(outputUnit);
TEST_ERR(err);
/* Get the underlying device */
UInt32 propertySize = sizeof(outputDevice);
err = AudioUnitGetProperty(outputUnit,
kAudioOutputUnitProperty_CurrentDevice,
kAudioUnitScope_Global,
0,
&outputDevice,
&propertySize);
TEST_ERR(err);
RAGE_ASSERT(outputDevice);
/* Start the outputUnit */
AudioOutputUnitStart(outputUnit);
#endif
}
RageSound_CA::~RageSound_CA()
{
#if CURRENT_DRIVER == BROKEN_DRIVER_1
OSStatus err;
err = AudioDeviceStop(outputDevice, GetData);
@@ -130,6 +217,10 @@ RageSound_CA::~RageSound_CA()
err = AudioConverterDispose(converter);
TEST_ERR(err);
#elif CURRENT_DRIVER == BROKEN_DRIVER_2
AudioOutputUnitStop(outputUnit);
CloseComponent(outputUnit);
#endif
}
void RageSound_CA::StartMixing(RageSound *snd)
@@ -182,6 +273,7 @@ void RageSound_CA::Update(float delta)
}
}
#if CURRENT_DRIVER == BROKEN_DRIVER_1
OSStatus RageSound_CA::GetData(AudioDeviceID inDevice,
const AudioTimeStamp* inNow,
const AudioBufferList* inInputData,
@@ -226,13 +318,61 @@ OSStatus RageSound_CA::GetData(AudioDeviceID inDevice,
UInt32 size;
OSStatus err = AudioConverterConvertBuffer(THIS->converter, THIS->buffersize, buffer, &size,
outOutputData->mBuffers[0].mData);
return err;
return AudioConverterConvertBuffer(THIS->converter, THIS->buffersize, buffer, &size,
outOutputData->mBuffers[0].mData);
}
#elif CURRENT_DRIVER == BROKEN_DRIVER_2
OSStatus RageSound_CA::GetData(void *inRefCon,
AudioUnitRenderActionFlags *inActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumFrames,
AudioBufferList *ioData)
{
unsigned outputSize = ioData->mBuffers[0].mDataByteSize;
if (!SOUNDMAN)
{
bzero(ioData->mBuffers[0].mData, outputSize);
*inActionFlags = kAudioUnitRenderAction_OutputIsSilence;
return noErr;
}
RageSound_CA *THIS = (RageSound_CA *)inRefCon;
char *buffer = (char *)ioData->mBuffers[0].mData;
bzero(buffer, THIS->buffersize);
LockMutex L(SOUNDMAN->lock);
static SoundMixBuffer mix;
int position = int(inTimeStamp->mSampleTime); //This should be in frames
bool moreThanOneSound = THIS->sounds.size() > 1;
for (unsigned i=0; i<THIS->sounds.size(); ++i)
{
if (THIS->sounds[i]->stopping)
continue;
unsigned got = THIS->sounds[i]->snd->GetPCM(buffer, outputSize, position);
if (moreThanOneSound)
mix.write((SInt16 *)buffer, got / 2);
if (got < outputSize)
{
THIS->sounds[i]->stopping = true;
THIS->sounds[i]->flush_pos = position + got / kSampleSize;
}
}
if (moreThanOneSound)
mix.read((SInt16 *)buffer);
*inActionFlags = kAudioUnitRenderAction_PostRender;
return noErr;
}
#endif
inline int RageSound_CA::ConvertAudioTimeStampToPosition(const AudioTimeStamp *time)
{
return (int)(time->mSampleTime / time->mRateScalar);
//return int(time->mSampleTime);
}
@@ -10,14 +10,25 @@
*/
#include "RageSoundDriver.h"
#define BROKEN_DRIVER_1 1
#define BROKEN_DRIVER_2 2
#define CURRENT_DRIVER BROKEN_DRIVER_2
struct AudioTimeStamp;
struct AudioBufferList;
#if CURRENT_DRIVER == BROKEN_DRIVER_1
struct OpaqueAudioConverter;
typedef struct OpaqueAudioConverter *AudioConverterRef;
#endif
typedef long OSStatus;
typedef unsigned long UInt32;
typedef UInt32 AudioDeviceID;
typedef UInt32 AudioUnitRenderActionFlags;
#if CURRENT_DRIVER == BROKEN_DRIVER_2
struct ComponentInstanceRecord;
typedef struct ComponentInstanceRecord *AudioUnit;
#endif
class RageSound_CA : public RageSoundDriver
{
@@ -30,7 +41,12 @@ private:
} *soundPtr;
vector<soundPtr> sounds;
#if CURRENT_DRIVER == BROKEN_DRIVER_1
AudioConverterRef converter;
#elif CURRENT_DRIVER == BROKEN_DRIVER_2
AudioUnit outputUnit;
#endif
AudioDeviceID outputDevice;
float latency;
UInt32 buffersize;
@@ -45,6 +61,7 @@ protected:
public:
RageSound_CA();
virtual ~RageSound_CA();
#if CURRENT_DRIVER == BROKEN_DRIVER_1
static OSStatus GetData(AudioDeviceID inDevice,
const AudioTimeStamp* inNow,
const AudioBufferList* inInputData,
@@ -52,6 +69,14 @@ public:
AudioBufferList* outOutputData,
const AudioTimeStamp* inOutputTime,
void* inClientData);
#elif CURRENT_DRIVER == BROKEN_DRIVER_2
static OSStatus GetData(void *inRecCon,
AudioUnitRenderActionFlags *inActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumFrames,
AudioBufferList *ioData);
#endif
};
#endif RAGE_SOUND_CA