objective c - Realtime audio compression with AudioConverterFillComplexBuffer in iOS -
i trying realtime encoding of buffer coming recording callback, seem not understand how this, , how works. in fact spent hours reading apple's reference don't it.
i want through various threads here on so, still no me.
i have recording callback:
static osstatus recordingcallback(void *inrefcon, audiounitrenderactionflags *ioactionflags, const audiotimestamp *intimestamp, uint32 inbusnumber, uint32 innumberframes, audiobufferlist *iodata) { // data gets rendered here audiobuffer buffer; // variable check status osstatus status; /** reference object owns callback. */ audioprocessor *audioprocessor = (__bridge audioprocessor*) inrefcon; /** on point define number of channels, mono iphone. number of frames usally 512 or 1024. */ buffer.mdatabytesize = innumberframes * 2; // sample size buffer.mnumberchannels = 1; // 1 channel buffer.mdata = malloc( innumberframes * 2 ); // buffer size // put our buffer bufferlist array rendering audiobufferlist bufferlist; bufferlist.mnumberbuffers = 1; bufferlist.mbuffers[0] = buffer; // render input , check error status = audiounitrender([audioprocessor audiounit], ioactionflags, intimestamp, inbusnumber, innumberframes, &bufferlist); [audioprocessor haserror:status:__file__:__line__]; // process bufferlist in audio processor [audioprocessor processbuffer:&bufferlist]; [audioprocessor convertbuffer:&bufferlist]; //trying set buffer converting function // clean buffer free(bufferlist.mbuffers[0].mdata); return noerr; }
convertbuffer looks - returns
pointer being freed not allocated
-(void)convertbuffer: (audiobufferlist*) audiobufferlist { unsigned char** stream = audiobufferlist->mbuffers[0].mdata; uint32 *streamsize = &audiobufferlist->mbuffers[0].mdatabytesize; // describe input format's description audiostreambasicdescription inputdescription; inputdescription.msamplerate = sample_rate; inputdescription.mformatid = kaudioformatlinearpcm; inputdescription.mformatflags = kaudioformatflagispacked | kaudioformatflagissignedinteger; inputdescription.mframesperpacket = 1; inputdescription.mchannelsperframe = 1; inputdescription.mbitsperchannel = 16; inputdescription.mbytesperpacket = 2; inputdescription.mbytesperframe = 2; // copy conversion output format's description // output audio unit's description. // adjust framesperpacket match input we'll passing. // framecount of our input stream based on input bytecount. // output stream have same number of frames, different // number of bytes. audiostreambasicdescription outputdescription; outputdescription.msamplerate = 44100.0; outputdescription.mformatid = kaudioformatmpeg4aac; outputdescription.mformatflags = kmpeg4object_aac_main; outputdescription.mchannelsperframe = 1; outputdescription.mbytesperpacket = 1; outputdescription.mbytesperframe = 0; outputdescription.mframesperpacket = 1024; outputdescription.mbitsperchannel = 0; outputdescription.mreserved = 0; // create audio converter audioconverterref audioconverter; osstatus accreationresult = audioconverternew(&inputdescription, &outputdescription, &audioconverter); if(!audioconverter) { // bail out free(*stream); *streamsize = 0; *stream = (unsigned char*)malloc(0); return; } // calculate number of bytes required output of input stream. // allocate buffer of adequate size. uint32 outputbytes = outputdescription.mbytesperpacket * (*streamsize / inputdescription.mbytesperpacket); // outputdescription.mframesperpacket * outputdescription.mbytesperframe; unsigned char *outputbuffer = (unsigned char*)malloc(outputbytes); memset(outputbuffer, 0, outputbytes); // describe input data we'll pass converter audiobuffer inputbuffer; inputbuffer.mnumberchannels = inputdescription.mchannelsperframe; inputbuffer.mdatabytesize = *streamsize; inputbuffer.mdata = *stream; // describe output data buffers can receive data. audiobufferlist outputbufferlist; outputbufferlist.mnumberbuffers = 1; outputbufferlist.mbuffers[0].mnumberchannels = outputdescription.mchannelsperframe; outputbufferlist.mbuffers[0].mdatabytesize = outputbytes; outputbufferlist.mbuffers[0].mdata = outputbuffer; // set output data packet size uint32 outputdatapacketsize = outputbytes / outputdescription.mbytesperpacket; // fill class members data we'll pass // inputdataproc //_converter_currentbuffer = &inputbuffer; //_converter_currentinputdescription = inputdescription; // convert osstatus result = audioconverterfillcomplexbuffer(audioconverter, /* audioconverterref inaudioconverter */ nil, /* audioconvertercomplexinputdataproc ininputdataproc */ nil, /* void *ininputdataprocuserdata */ &outputdatapacketsize, /* uint32 *iooutputdatapacketsize */ &outputbufferlist, /* audiobufferlist *outoutputdata */ null /* audiostreampacketdescription *outpacketdescription */ ); nslog([nsstring stringwithformat:@"err : %ld",result ]); // change "stream" describe our output buffer. // if error occured, we'd rather have silence unconverted audio. free(*stream); *stream = outputbuffer; *streamsize = outputbytes; // dispose of audio converter audioconverterdispose(audioconverter); }
and basicly that's it. cannot work. also, how should callback function look? set nil now.
any appreciated. i'm stuck days on it.
you should provide "audioconvertercomplexinputdataproc" in order convert data. converter repeatedly calls function should provide initial data conversion.
Comments
Post a Comment