memcpy Error Using RemoteIO AU to Play From File (on iPad)
memcpy Error Using RemoteIO AU to Play From File (on iPad)
- Subject: memcpy Error Using RemoteIO AU to Play From File (on iPad)
- From: Carter Allen <email@hidden>
- Date: Fri, 11 Jun 2010 12:48:31 -0600
Hello!
I'm fairly new to CoreAudio, so please give me a chance here. I'm trying to use the RemoteIO AudioUnit to play audio from a file, on an iPad. I need to use AudioUnits and not Queues because I am going to be performing modifications to the sound live, later on. Here is the code that is causing the crash:
@implementation AudioUnit_DemoViewController
@synthesize playing;
@synthesize mFrameData;
@synthesize mMaxFrame;
@synthesize mReadFrame;
#define checkStatus(x) checkStatusWithLineNumber(__LINE__, x)
void checkStatusWithLineNumber(int lineNumber, OSStatus status) {
if (status != 0) NSLog(@"An error occurred on line %d: %d", lineNumber, status);
}
OSStatus audioCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) {
AudioUnit_DemoViewController *this = (AudioUnit_DemoViewController *)inRefCon;
UInt32 frameByteSize = inNumberFrames * sizeof(AudioUnitSampleType);
OSStatus err = noErr;
if (this.playing) {
if (this.mMaxFrame > 0) {
NSLog(@"frameByteSize = %d, inNumberFrames = %d, sizeof(SInt16) = %d", frameByteSize, inNumberFrames, sizeof(SInt16));
UInt32 nextFrame = this.mMaxFrame - this.mReadFrame;
NSLog(@"nextFrame = %d", nextFrame);
if (nextFrame > inNumberFrames) nextFrame = inNumberFrames;
for (NSInteger i = 0; i < ioData->mNumberBuffers; i++) {
SInt16 *p = (SInt16 *)ioData->mBuffers[i].mData;
if (nextFrame < inNumberFrames) memset(p, 0, frameByteSize);
memcpy(p, this.mFrameData + this.mReadFrame, nextFrame * sizeof(SInt16));
}
this.mReadFrame += nextFrame;
if (this.mReadFrame == this.mMaxFrame) {
NSLog (@ "inNumberFrames =% d", inNumberFrames);
this.playing = NO;
}
}
}
else {
for (NSInteger i = 0; i < ioData->mNumberBuffers; i ++) {
SInt32 *p = (SInt32 *) ioData->mBuffers[i].mData;
memset(p, 0, frameByteSize);
}
}
return err;
}
- (id)init {
if ((self = [super init])) {
mFrameData = NULL;
mReadFrame = 0;
playing = NO;
}
return self;
}
- (IBAction)play {
mReadFrame = 0;
if (!playing) playing = YES;
}
- (IBAction)stop { mReadFrame = 0; }
- (void)viewDidLoad {
[super viewDidLoad];
// Start an audio session
AudioSessionSetActive(true);
// Create an OSStatus
OSStatus status;
// Describe the audio unit
AudioComponentDescription description;
memset(&description, 0, sizeof(description));
description.componentType = kAudioUnitType_Output;
description.componentSubType = kAudioUnitSubType_RemoteIO;
description.componentFlags = 0;
description.componentFlagsMask = 0;
description.componentManufacturer = kAudioUnitManufacturer_Apple;
// Get the audio unit
AudioComponent audioUnit = AudioComponentFindNext(NULL, &description);
// Create an instance of the audio unit
AudioComponentInstance audioUnitInstance;
status = AudioComponentInstanceNew(audioUnit, &audioUnitInstance);
checkStatus(status);
// Enable the speaker
UInt32 flag = 1;
status = AudioUnitSetProperty(audioUnitInstance, kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, kOutputBus, &flag, sizeof(flag));
checkStatus(status);
// Find the test tone file
CFBundleRef mainBundle = CFBundleGetMainBundle();
CFURLRef testToneURL = CFBundleCopyResourceURL(mainBundle, CFSTR("Test Tone"), CFSTR("caf"), NULL);
ExtAudioFileRef toneFile;
status = ExtAudioFileOpenURL(testToneURL, &toneFile);
checkStatus(status);
// Describe the test tone file
AudioStreamBasicDescription dataFormat;
UInt32 size = sizeof (AudioStreamBasicDescription);
ExtAudioFileGetProperty(toneFile, kExtAudioFileProperty_FileDataFormat, &size, &dataFormat);
NSLog(@"fileFormat.mSampleRate = %f", dataFormat.mSampleRate);
NSLog(@"fileFormat.mChannelsPerFrame = %d", dataFormat.mChannelsPerFrame);
NSLog(@"fileFormat.mBitsPerChannel = %d", dataFormat.mBitsPerChannel);
NSLog(@"fileFormat.mBytesPerFrame = %d", dataFormat.mBytesPerFrame);
size = sizeof(SInt64);
SInt64 fileLength;
ExtAudioFileGetProperty(toneFile, kExtAudioFileProperty_FileLengthFrames, &size, &fileLength);
//dataFormat.mSampleRate = kSampleRate;
/*dataFormat.mFormatID = kAudioFormatLinearPCM;
dataFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
dataFormat.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical;
dataFormat.mFramesPerPacket = 1;
// dataFormat.mChannelsPerFrame = 1;
//dataFormat.mBitsPerChannel = 16;
dataFormat.mBytesPerPacket = 2;
dataFormat.mBytesPerFrame = 2;*/
// Set the input format for the audio unit to the test tone's data format
status = AudioUnitSetProperty(audioUnitInstance, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, kOutputBus, &dataFormat, sizeof(dataFormat));
checkStatus(status);
/*
// Describe the output
AudioStreamBasicDescription outputDataFormat;
size = sizeof(AudioStreamBasicDescription);
outputDataFormat.mSampleRate = kSampleRate;
outputDataFormat.mFormatID = kAudioFormatLinearPCM;
outputDataFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
outputDataFormat.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical;
outputDataFormat.mFramesPerPacket = 1;
outputDataFormat.mChannelsPerFrame = 1;
outputDataFormat.mBitsPerChannel = 16;
outputDataFormat.mBytesPerPacket = 2;
outputDataFormat.mBytesPerFrame = 2;
// Set the output format for the audio unit to the test tone's data format
status = AudioUnitSetProperty(audioUnitInstance, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, kOutputBus, &outputDataFormat, sizeof(outputDataFormat));
printf("OSSTATITTIES %d: %lx\n", __LINE__, status);
*/
// Read the tone file into a buffer
AudioBufferList toneBuffer;
toneBuffer.mNumberBuffers = 1;
toneBuffer.mBuffers[0].mNumberChannels = 1;
//toneBuffer.mBuffers[0].mData = mFrameData;
//toneBuffer.mBuffers[0].mDataByteSize = fileLength * sizeof(float);
toneBuffer.mBuffers[0].mDataByteSize = ((1024 * 2) * dataFormat.mChannelsPerFrame);
toneBuffer.mBuffers[0].mData = malloc(toneBuffer.mBuffers[0].mDataByteSize);
//NSLog(@"sizeof(mFrameData) = %d", sizeof(mFrameData));
//toneBuffer.mBuffers[0].mDataByteSize = sizeof(mFrameData);
NSLog(@"fileLength = %d mDataByteSize = %d sizeof(int) = %d (fileLength * sizeof(int)) = %d", fileLength, toneBuffer.mBuffers[0].mDataByteSize, sizeof(int), (fileLength * sizeof(int)));
mMaxFrame = fileLength;
ExtAudioFileRead(toneFile, &mMaxFrame, &toneBuffer);
NSLog(@"fileLength = %d", fileLength);
NSLog(@"readFrames = %d", mMaxFrame);
//for (int i = 0; i < 5; i++) NSLog( @"mFrameData[%d] = %d", i, mFrameData[i]);
ExtAudioFileDispose(toneFile);
mReadFrame = 0;
// Set up the render callback for the audio unit
AURenderCallbackStruct callback;
callback.inputProc = audioCallback;
callback.inputProcRefCon = self;
status = AudioUnitSetProperty(audioUnitInstance, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Global, kOutputBus, &callback, sizeof(callback));
checkStatus(status);
// Initialize the audio unit
status = AudioUnitInitialize(audioUnitInstance);
checkStatus(status);
// Start the audio unit
AudioOutputUnitStart(audioUnitInstance);
}
@end
And here is the console log that is printed when I run the app and press the play button (which is connected to the play: action):
2010-06-11 12:41:16.592 AudioUnit Demo[2267:207] fileFormat.mSampleRate = 44100.000000
2010-06-11 12:41:16.597 AudioUnit Demo[2267:207] fileFormat.mChannelsPerFrame = 2
2010-06-11 12:41:16.600 AudioUnit Demo[2267:207] fileFormat.mBitsPerChannel = 16
2010-06-11 12:41:16.604 AudioUnit Demo[2267:207] fileFormat.mBytesPerFrame = 4
2010-06-11 12:41:16.606 AudioUnit Demo[2267:207] fileLength = 1351680 mDataByteSize = 0 sizeof(int) = 4096 (fileLength * sizeof(int)) = 4
2010-06-11 12:41:16.611 AudioUnit Demo[2267:207] fileLength = 1351680
2010-06-11 12:41:16.614 AudioUnit Demo[2267:207] readFrames = 1024
2010-06-11 12:41:18.456 AudioUnit Demo[2267:4f0b] frameByteSize = 4096, inNumberFrames = 1024, sizeof(SInt16) = 2
2010-06-11 12:41:18.463 AudioUnit Demo[2267:4f0b] nextFrame = 1024
Program received signal: “EXC_BAD_ACCESS”.
[Switching to thread 12803]
[Switching to thread 12803]
(gdb) bt
#0 0x30c16fb0 in memmove ()
#1 0x30c97ecc in __memcpy_chk ()
#2 0x00003026 in __inline_memcpy_chk (__dest=0xa3000, __src=0x0, __len=2048) at _string.h:58
#3 0x00002ee2 in audioCallback (inRefCon=0x11d510, ioActionFlags=0x75bd34, inTimeStamp=0x75bcd8, inBusNumber=0, inNumberFrames=1024, ioData=0x1328e0) at /Users/carterallen/Development/iPhone/Apps/Sensations/AudioUnit Demo/Classes/AudioUnit_DemoViewController.m:39
#4 0x307b77fa in AUConverterBase::RenderBus ()
#5 0x308296ce in AURemoteIO::RenderBus ()
#6 0x3078dd46 in AUBase::DoRender ()
#7 0x30829d96 in AURemoteIO::PerformIO ()
#8 0x30829eb2 in AURIOCallbackReceiver_PerformIOSync ()
#9 0x30823eea in _XPerformIOSync ()
#10 0x307afc7e in mshMIGPerform ()
#11 0x30807d58 in MSHMIGDispatchMessage ()
#12 0x3082d974 in AURemoteIO::IOThread::Entry ()
#13 0x3077afae in CAPThread::Entry ()
#14 0x30c8f78c in _pthread_start ()
#15 0x30c85078 in thread_start ()
(gdb)
Does anyone know what is wrong here? I can't tell why it isn't working.
Sincerely,
Carter Allen _______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden