iphone - RemoteIO Audio Problem - simulator = good - device= bad -
o.k , i'm using core audio extract audio 10 different sample sources , mixing them in callback function.
it works perfect in simulator , well. ran trouble when tried run on 4.2 iphone device.
if mix 2 audio files in callback ok. if mix 5 or 6 audio files audio plays after short amount of time audio degrades , no audio go speakers. (the callback not stop).
if try mix 10 audio files callback runs no audio @ comes out.
it's callback running out of time might explain case mix 5 or 6 not explain last case mixing 10 audio sources no audio @ played.
i'm not sure if following has bearing message prints console when i'm debugging. indication problem is?
mem 0x1000 0x3fffffff cache mem 0x40000000 0xffffffff none mem 0x00000000 0x0fff none run running… [switching thread 11523] [switching thread 11523] re-enabling shared library breakpoint 1 continue warning: unable read symbols /developer/platforms/iphoneos.platform/devicesupport/4.2.1 (8c148)/symbols/usr/lib/info/dns.so (file not found).
** set callback**
#pragma mark - #pragma mark callback setup & control - (void) setupcallback { osstatus status; // describe audio component audiocomponentdescription desc; desc.componenttype = kaudiounittype_output; desc.componentsubtype = kaudiounitsubtype_remoteio; desc.componentflags = 0; desc.componentflagsmask = 0; desc.componentmanufacturer = kaudiounitmanufacturer_apple; // component audiocomponent inputcomponent = audiocomponentfindnext(null, &desc); // audio units status = audiocomponentinstancenew(inputcomponent, &audiounit); uint32 flag = 1; // enable io playback status = audiounitsetproperty(audiounit, kaudiooutputunitproperty_enableio, kaudiounitscope_output, koutputbus, &flag, sizeof(flag)); //apply format status = audiounitsetproperty(audiounit, kaudiounitproperty_streamformat, kaudiounitscope_input, koutputbus, &stereostreamformat, sizeof(stereostreamformat)); // set playback callback aurendercallbackstruct callbackstruct; callbackstruct.inputproc = playbackcallback; //!!****assignment incompatible pointer warning here *****!!!!!! //set reference "self" becomes *inrefcon in playback callback callbackstruct.inputprocrefcon = self; status = audiounitsetproperty(audiounit, kaudiounitproperty_setrendercallback, kaudiounitscope_global, koutputbus, &callbackstruct, sizeof(callbackstruct)); // initialise status = audiounitinitialize(audiounit); // error check status }
the callback
static osstatus playbackcallback ( void *inrefcon, // pointer struct containing complete audio data // play, state information such // first sample play on invocation of callback. audiounitrenderactionflags *ioactionflags, // unused here. when generating audio, use ioactionflags indicate silence // between sounds; silence, memset iodata buffers 0. audiotimestamp *intimestamp, // unused here. uint32 inbusnumber, // mixer unit input bus requesting new // frames of audio data play. uint32 innumberframes, // number of frames of audio provide buffer(s) // pointed iodata parameter. audiobufferlist *iodata // on output, audio data play. callback's primary // responsibility fill buffer(s) in // audiobufferlist. ) { engine *remoteioplayer = (engine *)inrefcon; audiounitsampletype *outsampleschannelleft; audiounitsampletype *outsampleschannelright; outsampleschannelleft = (audiounitsampletype *) iodata->mbuffers[0].mdata; outsampleschannelright = (audiounitsampletype *) iodata->mbuffers[1].mdata; int thetime =0; thetime=remoteioplayer.sampletime; (int framenumber = 0; framenumber < innumberframes; ++framenumber) { // nextpacket returns 32 bit value, 1 frame. audiounitsampletype *suml=0; audiounitsampletype *sumr=0; //nslog (@"frame number - %i", framenumber); for(int j=0;j<10;j++) { audiounitsampletype valuetoaddl=0; audiounitsampletype valuetoaddr=0; //valuetoadd = [remoteioplayer getsample:j ]; valuetoaddl = [remoteioplayer getnoninterleavedsample:j currenttime:thetime channel:0 ]; //valuetoaddl = [remoteioplayer getsample:j]; valuetoaddr = [remoteioplayer getnoninterleavedsample:j currenttime:thetime channel:1 ]; suml = suml+(valuetoaddl/10); sumr = sumr+(valuetoaddr/10); } outsampleschannelleft[framenumber]=(audiounitsampletype) suml; outsampleschannelright[framenumber]=(audiounitsampletype) sumr; remoteioplayer.sampletime +=1; } return noerr; }
my audio fetching function
-(audiounitsampletype) getnoninterleavedsample:(int) index currenttime:(int)time channel:(int)ch; { audiounitsampletype returnvalue= 0; soundstruct snd=soundstructarray[index]; uint64 sn= snd.framecount; uint64 st=sampletime; uint64 read= (uint64)(st%sn); if(ch==0) { if (snd.sendvalue==1) { returnvalue = snd.audiodataleft[read]; }else { returnvalue=0; } }else if(ch==1) { if (snd.sendvalue==1) { returnvalue = snd.audiodataright[read]; }else { returnvalue=0; } soundstructarray[index].samplenumber=read; } if(soundstructarray[index].samplenumber >soundstructarray[index].framecount) { soundstructarray[index].samplenumber=0; } return returnvalue; }
edit 1
in response @andre changed callback following still did not help.
static osstatus playbackcallback ( void *inrefcon, // pointer struct containing complete audio data // play, state information such // first sample play on invocation of callback. audiounitrenderactionflags *ioactionflags, // unused here. when generating audio, use ioactionflags indicate silence // between sounds; silence, memset iodata buffers 0. audiotimestamp *intimestamp, // unused here. uint32 inbusnumber, // mixer unit input bus requesting new // frames of audio data play. uint32 innumberframes, // number of frames of audio provide buffer(s) // pointed iodata parameter. audiobufferlist *iodata // on output, audio data play. callback's primary // responsibility fill buffer(s) in // audiobufferlist. ) { engine *remoteioplayer = (engine *)inrefcon; audiounitsampletype *outsampleschannelleft; audiounitsampletype *outsampleschannelright; outsampleschannelleft = (audiounitsampletype *) iodata->mbuffers[0].mdata; outsampleschannelright = (audiounitsampletype *) iodata->mbuffers[1].mdata; int thetime =0; thetime=remoteioplayer.sampletime; (int framenumber = 0; framenumber < innumberframes; ++framenumber) { // nextpacket returns 32 bit value, 1 frame. audiounitsampletype suml=0; audiounitsampletype sumr=0; //nslog (@"frame number - %i", framenumber); for(int j=0;j<16;j++) { soundstruct snd=remoteioplayer->soundstructarray[j]; uint64 sn= snd.framecount; uint64 st=remoteioplayer.sampletime; uint64 read= (uint64)(st%sn); suml+= snd.audiodataleft[read]; suml+= snd.audiodataright[read]; } outsampleschannelleft[framenumber]=(audiounitsampletype) suml; outsampleschannelright[framenumber]=(audiounitsampletype) sumr; remoteioplayer.sampletime +=1; } return noerr; }
like andre said, it's best not have objective-c function calls in callback. should change inputprocrefcon c-struct instead of objective-c object.
also, looks might going frame-by-frame 'manually' copying data buffer. instead, use memcopy copy chunk of data in.
also, i'm pretty sure you're not doing disk i/o in callback, if you shouldn't either.
Comments
Post a Comment