![]() |
|
|
|
Thread Tools | Display Modes |
|
(#4)
|
|
|
Moderator
Posts: 3,541
Join Date: 2003.06
Location: usa
|
2010.01.29, 12:59 PM
A quick glance at the SDL source code suggests to me that they're using RemoteIO.
Figuring out RemoteIO is not particularly easy because, again as usual, the documentation is nearly non-existent or rather poor -- at least the last time I looked. I put together a tiny demo to maybe get you started. Make a new OpenGL ES app from the template in Xcode. Add the AudioToolbox framework to the project. Then copy the code below and paste it over what's in the <myAppName>AppDelegate.m file. I called mine iPhoneAUTest, so it wound up being iPhoneAUTestAppDelegate.m. You can simply change that to whatever you want. Here's the code: Code:
#import "iPhoneAUTestAppDelegate.h"
#import "EAGLView.h"
#import <AudioUnit/AudioUnit.h>
static bool silent = false;
static float volume = 0.25f;
static AudioUnit audioUnit;
static void RenderAudio(void *left, void *right, unsigned numSamples, unsigned dataSize)
{
// early out
if (silent)
{
memset(left, 0, dataSize);
memset(right, 0, dataSize);
return;
}
// do something like this to generate your own audio
unsigned i;
for (i = 0; i < numSamples; i++)
{
// do a cheesy sine wave in the left channel so we have something to hear,
// and just copy it over to the right channel for demonstration
static unsigned long sampleIndex = 0;
float myFloatSampleLeft = sinf((float)sampleIndex++ * 0.1f) * volume;
float myFloatSampleRight = myFloatSampleLeft;
// output your audio here, in this case, sample by sample, converting from float to int
((AudioSampleType *)left)[i] = (AudioSampleType)(myFloatSampleLeft * 32000.0f);
((AudioSampleType *)right)[i] = (AudioSampleType)(myFloatSampleRight * 32000.0f);
}
/*
do something like this instead for decoding audio using some codec
for (i = 0; i < numSamples; i++)
{
if (myStreamIndex >= myNumSamplesInBuffer)
myDecodeAnotherBufferWorthOfSamples();
// could do memcpy from your buffer here instead for better efficiency
((AudioSampleType *)left)[i] = (AudioSampleType)myBuffer[myStreamIndex++]];
((AudioSampleType *)right)[i] = (AudioSampleType)myBuffer[myStreamIndex++]];
}*/
}
static OSStatus AudioOutputCallback(void *inRefCon,
AudioUnitRenderActionFlags *ioActionFlags,
const AudioTimeStamp *inTimeStamp,
UInt32 inBusNumber,
UInt32 inNumberFrames,
AudioBufferList *ioData)
{
unsigned dataSize = ioData->mBuffers[0].mDataByteSize;
unsigned numSamples = dataSize / sizeof(AudioSampleType); // 16-bit
RenderAudio(ioData->mBuffers[0].mData, ioData->mBuffers[1].mData, numSamples, dataSize);
return noErr;
}
static void DisableAudioOutputiPhone(void)
{
AudioOutputUnitStop(audioUnit);
AURenderCallbackStruct callback;
callback.inputProc = NULL;
callback.inputProcRefCon = NULL;
AudioUnitSetProperty(audioUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Global,
0,
&callback,
sizeof(AURenderCallbackStruct));
AudioUnitUninitialize(audioUnit);
AudioComponentInstanceDispose(audioUnit);
}
static void EnableAudioOutputiPhone(void)
{
OSStatus status;
AudioStreamBasicDescription audioFormat;
AudioComponentDescription desc;
desc.componentType = kAudioUnitType_Output;
desc.componentSubType = kAudioUnitSubType_RemoteIO;
desc.componentFlags = 0;
desc.componentFlagsMask = 0;
desc.componentManufacturer = kAudioUnitManufacturer_Apple;
AudioComponent inputComponent = AudioComponentFindNext(NULL, &desc);
status = AudioComponentInstanceNew(inputComponent, &audioUnit);
UInt32 flag = 1;
status = AudioUnitSetProperty(audioUnit,
kAudioOutputUnitProperty_EnableIO,
kAudioUnitScope_Output,
0,
&flag,
sizeof(flag));
// 16-bit int output
//audioFormat.mSampleRate = 44100.0;
audioFormat.mSampleRate = 22050.0;
audioFormat.mFormatID = kAudioFormatLinearPCM;
audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
audioFormat.mFormatFlags |= kAudioFormatFlagIsNonInterleaved; // split into left/right for the callback
UInt32 sampleSize = sizeof(AudioSampleType); // 16-bit signed int
audioFormat.mBytesPerPacket = sampleSize;
audioFormat.mFramesPerPacket = 1;
audioFormat.mBytesPerFrame = sampleSize;
audioFormat.mChannelsPerFrame = 2;
audioFormat.mBitsPerChannel = 8 * sampleSize;
status = AudioUnitSetProperty(audioUnit,
kAudioUnitProperty_StreamFormat,
kAudioUnitScope_Input,
0,
&audioFormat,
sizeof(audioFormat));
AURenderCallbackStruct callbackStruct;
callbackStruct.inputProc = AudioOutputCallback;
callbackStruct.inputProcRefCon = NULL;
status = AudioUnitSetProperty(audioUnit,
kAudioUnitProperty_SetRenderCallback,
kAudioUnitScope_Global,
0,
&callbackStruct,
sizeof(callbackStruct));
status = AudioUnitInitialize(audioUnit);
if (status != noErr)
{
printf("%s ERROR: AudioUnitInitialize failed\n", __FUNCTION__);
}
AudioOutputUnitStart(audioUnit);
}
@implementation iPhoneAUTestAppDelegate
@synthesize window;
@synthesize glView;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
EnableAudioOutputiPhone();
[glView startAnimation];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
[glView stopAnimation];
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
[glView startAnimation];
}
- (void)applicationWillTerminate:(UIApplication *)application
{
[glView stopAnimation];
}
- (void)dealloc
{
[window release];
[glView release];
[super dealloc];
}
@end
|
|
|
|
| Thread Tools | |
| Display Modes | |
|
|