cocoa - AVAssetReader audio capture, samples missing -
i've weird question. i'm capturing audio samples of .mov/.wav/.aiff files playback them. i'm using following codes captures unchanged pcm samples if available , otherwise convert them 32 bit float.
nserror *error = nil; avassetreader *assetreader= [[[avassetreader alloc] initwithasset:self.movieasset error:&error] autorelease]; nsarray *audiotracks=[movieasset trackswithmediatype:avmediatypeaudio]; avassetreadertrackoutput* audioreaderoutput=nil; avassettrack *mainaudiotrack = nil; cmtimerange audiorange; if ([audiotracks count]) { mainaudiotrack=[audiotracks objectatindex:0]; audiorange = mainaudiotrack.timerange; cmtimerange readingrange = cmtimerangemake(kcmtimezero,audiorange.duration); assetreader.timerange = readingrange; nsarray* formatdesc = mainaudiotrack.formatdescriptions; if ([formatdesc count]) { cmaudioformatdescriptionref item = (cmaudioformatdescriptionref)[formatdesc objectatindex:0]; const audiostreambasicdescription* pcmaudiodescription = cmaudioformatdescriptiongetstreambasicdescription (item); nsdictionary * outputsettings; memcpy(&audiodescription,pcmaudiodescription,sizeof(audiostreambasicdescription)); if (pcmaudiodescription->mformatid != kaudioformatlinearpcm ) { // resample outputsettings = [nsdictionary dictionarywithobjectsandkeys: [nsnumber numberwithint:kaudioformatlinearpcm], avformatidkey, [nsnumber numberwithfloat:pcmaudiodescription->msamplerate], avsampleratekey, [nsnumber numberwithint:pcmaudiodescription->mchannelsperframe], avnumberofchannelskey, [nsnumber numberwithint:32], avlinearpcmbitdepthkey, [nsnumber numberwithbool:yes], avlinearpcmisfloatkey, nil]; audiodescription.mformatid = kaudioformatlinearpcm; audiodescription.mbitsperchannel = 32; audiodescription.mframesperpacket = 1; audiodescription.mchannelsperframe = pcmaudiodescription->mchannelsperframe; audiodescription.mbytesperframe = audiodescription.mbitsperchannel / 8 * audiodescription.mchannelsperframe; audiodescription.mbytesperpacket = audiodescription.mframesperpacket * audiodescription.mbytesperframe; audiodescription.mformatflags = kaudioformatflagisfloat; } else { outputsettings = [nsdictionary dictionarywithobjectsandkeys: [nsnumber numberwithint:kaudioformatlinearpcm], avformatidkey, nil]; audiodescription.mformatid = kaudioformatlinearpcm; } audioreaderoutput=[[[avassetreadertrackoutput alloc] initwithtrack:mainaudiotrack outputsettings:outputsettings] autorelease]; if([assetreader canaddoutput:audioreaderoutput]) [assetreader addoutput:audioreaderoutput]; else audioreaderoutput = nil; } } if (audioreaderoutput) { if([assetreader startreading]==yes){ cmsamplebufferref buffer = 0; nstimeinterval duration = 0.0; while([assetreader status]==avassetreaderstatusreading){ if (audioreaderoutput != nil) { buffer=[audioreaderoutput copynextsamplebuffer]; if (buffer) { cmtime sampleduration = cmsamplebuffergetduration (buffer); cmtime currentsampletime = cmsamplebuffergetoutputpresentationtimestamp (buffer); moviesample* sample = [[[moviesample alloc] init] autorelease]; sample.sampletime = currentsampletime; sample.samplebuffer = buffer; sample.sampleduration = sampleduration; [self.audiostore addobject:sample]; //nslog(@"adding sample %lld %lld %f %f",currentsampletime.value,sampleduration.value,currentoutputsampletime.value/(nstimeinterval)currentoutputsampletime.timescale, // (currentoutputsampletime.value+sampleduration.value)/(nstimeinterval)currentoutputsampletime.timescale); nslog(@"received pcm buffer [timestamp:%.1fms]", cmtimegetseconds(currentsampletime) * 1000); nslog(@"buffer contains [samples:%ld]", cmsamplebuffergetnumsamples(buffer)); nslog(@"buffer contains [duration:%.1fms] worth of audio", cmtimegetseconds(sampleduration) * 1000); duration += cmtimegetseconds(cmsamplebuffergetduration(buffer)); } } } nslog(@"total samples duration: %f", duration); nslog(@"total track reported duration: %f", audiorange.duration.value/(nstimeinterval)audiorange.duration.timescale); } else { dlog(@"could not start audio reading asset."); dlog(@"reader status: %ld", [assetreader status]); } }
now weird thing that, no matter file open, miss samples @ of file. following loop http://www.vvertex.com/loop.wav has duration reported 3.75 either audacity , audio track duration, mainaudiotrack.timerange, while dump of code prints samples length , playing offset is: 3.657120
this dump:
2014-03-06 10:48:15.721 framedecoder[665:303] received pcm buffer [timestamp:0.0ms] 2014-03-06 10:48:15.721 framedecoder[665:303] buffer contains [samples:8192] 2014-03-06 10:48:15.721 framedecoder[665:303] buffer contains [duration:185.8ms] worth of audio 2014-03-06 10:48:15.721 framedecoder[665:303] received pcm buffer [timestamp:185.8ms] 2014-03-06 10:48:15.721 framedecoder[665:303] buffer contains [samples:8192] 2014-03-06 10:48:15.721 framedecoder[665:303] buffer contains [duration:185.8ms] worth of audio 2014-03-06 10:48:15.722 framedecoder[665:303] received pcm buffer [timestamp:371.5ms] 2014-03-06 10:48:15.722 framedecoder[665:303] buffer contains [samples:8192] 2014-03-06 10:48:15.722 framedecoder[665:303] buffer contains [duration:185.8ms] worth of audio 2014-03-06 10:48:15.722 framedecoder[665:303] received pcm buffer [timestamp:557.3ms] 2014-03-06 10:48:15.722 framedecoder[665:303] buffer contains [samples:8192] 2014-03-06 10:48:15.722 framedecoder[665:303] buffer contains [duration:185.8ms] worth of audio 2014-03-06 10:48:15.723 framedecoder[665:303] received pcm buffer [timestamp:743.0ms] 2014-03-06 10:48:15.723 framedecoder[665:303] buffer contains [samples:8192] 2014-03-06 10:48:15.723 framedecoder[665:303] buffer contains [duration:185.8ms] worth of audio 2014-03-06 10:48:15.723 framedecoder[665:303] received pcm buffer [timestamp:928.8ms] 2014-03-06 10:48:15.726 framedecoder[665:303] buffer contains [samples:8192] 2014-03-06 10:48:15.726 framedecoder[665:303] buffer contains [duration:185.8ms] worth of audio 2014-03-06 10:48:15.727 framedecoder[665:303] received pcm buffer [timestamp:1114.6ms] 2014-03-06 10:48:15.727 framedecoder[665:303] buffer contains [samples:8192] 2014-03-06 10:48:15.727 framedecoder[665:303] buffer contains [duration:185.8ms] worth of audio 2014-03-06 10:48:15.727 framedecoder[665:303] received pcm buffer [timestamp:1300.3ms] 2014-03-06 10:48:15.727 framedecoder[665:303] buffer contains [samples:8192] 2014-03-06 10:48:15.727 framedecoder[665:303] buffer contains [duration:185.8ms] worth of audio 2014-03-06 10:48:15.727 framedecoder[665:303] received pcm buffer [timestamp:1486.1ms] 2014-03-06 10:48:15.728 framedecoder[665:303] buffer contains [samples:8192] 2014-03-06 10:48:15.728 framedecoder[665:303] buffer contains [duration:185.8ms] worth of audio 2014-03-06 10:48:15.728 framedecoder[665:303] received pcm buffer [timestamp:1671.8ms] 2014-03-06 10:48:15.728 framedecoder[665:303] buffer contains [samples:8192] 2014-03-06 10:48:15.728 framedecoder[665:303] buffer contains [duration:185.8ms] worth of audio 2014-03-06 10:48:15.728 framedecoder[665:303] received pcm buffer [timestamp:1857.6ms] 2014-03-06 10:48:15.729 framedecoder[665:303] buffer contains [samples:8192] 2014-03-06 10:48:15.729 framedecoder[665:303] buffer contains [duration:185.8ms] worth of audio 2014-03-06 10:48:15.729 framedecoder[665:303] received pcm buffer [timestamp:2043.4ms] 2014-03-06 10:48:15.729 framedecoder[665:303] buffer contains [samples:8192] 2014-03-06 10:48:15.729 framedecoder[665:303] buffer contains [duration:185.8ms] worth of audio 2014-03-06 10:48:15.729 framedecoder[665:303] received pcm buffer [timestamp:2229.1ms] 2014-03-06 10:48:15.730 framedecoder[665:303] buffer contains [samples:8192] 2014-03-06 10:48:15.730 framedecoder[665:303] buffer contains [duration:185.8ms] worth of audio 2014-03-06 10:48:15.730 framedecoder[665:303] received pcm buffer [timestamp:2414.9ms] 2014-03-06 10:48:15.730 framedecoder[665:303] buffer contains [samples:8192] 2014-03-06 10:48:15.730 framedecoder[665:303] buffer contains [duration:185.8ms] worth of audio 2014-03-06 10:48:15.731 framedecoder[665:303] received pcm buffer [timestamp:2600.6ms] 2014-03-06 10:48:15.731 framedecoder[665:303] buffer contains [samples:8192] 2014-03-06 10:48:15.731 framedecoder[665:303] buffer contains [duration:185.8ms] worth of audio 2014-03-06 10:48:15.731 framedecoder[665:303] received pcm buffer [timestamp:2786.4ms] 2014-03-06 10:48:15.731 framedecoder[665:303] buffer contains [samples:8192] 2014-03-06 10:48:15.731 framedecoder[665:303] buffer contains [duration:185.8ms] worth of audio 2014-03-06 10:48:15.732 framedecoder[665:303] received pcm buffer [timestamp:2972.2ms] 2014-03-06 10:48:15.732 framedecoder[665:303] buffer contains [samples:8192] 2014-03-06 10:48:15.732 framedecoder[665:303] buffer contains [duration:185.8ms] worth of audio 2014-03-06 10:48:15.732 framedecoder[665:303] received pcm buffer [timestamp:3157.9ms] 2014-03-06 10:48:15.732 framedecoder[665:303] buffer contains [samples:8192] 2014-03-06 10:48:15.733 framedecoder[665:303] buffer contains [duration:185.8ms] worth of audio 2014-03-06 10:48:15.733 framedecoder[665:303] received pcm buffer [timestamp:3343.7ms] 2014-03-06 10:48:15.733 framedecoder[665:303] buffer contains [samples:8192] 2014-03-06 10:48:15.733 framedecoder[665:303] buffer contains [duration:185.8ms] worth of audio 2014-03-06 10:48:15.733 framedecoder[665:303] received pcm buffer [timestamp:3529.4ms] 2014-03-06 10:48:15.734 framedecoder[665:303] buffer contains [samples:5631] 2014-03-06 10:48:15.734 framedecoder[665:303] buffer contains [duration:127.7ms] worth of audio 2014-03-06 10:48:15.734 framedecoder[665:303] total samples duration: 3.657120 2014-03-06 10:48:15.734 framedecoder[665:303] total track reported duration: 3.750000
anyone ever faced strange issue ? i've tried several audio files .mov files different compressions. same stuff ! i'm totally stuck on !
also when play samples through audiounits, seams what's missing beginning of sample....
thanks !
my workaround...
//starting 2 buffers before [_reader settimerange:cmtimerangemake(cmtimemake(-16384, samplerate), kcmtimenegativeinfinity)]; //and while ([_reader status] == avassetreaderstatusreading) { cmsamplebufferref samplebufferref = [_ringbufferreadertrackoutput copynextsamplebuffer]; if (samplebufferref){ cmtime t = cmsamplebuffergetoutputpresentationtimestamp(samplebufferref); if( t.value < 0 ) release, continue... }
but missing 4096 samples on end :-(
Comments
Post a Comment