osx - iOS Core Audio : Converting between kAudioFormatFlagsCanonical and kAudioFormatFlagsAudioUnitCanonical -


i need convert between format :

        format.msamplerate  = 44100.0;          format.mformatid = kaudioformatlinearpcm;         format.mformatflags = kaudioformatflagscanonical | klinearpcmformatflagisnoninterleaved;         format.mbytesperpacket = sizeof(audiounitsampletype);         format.mframesperpacket = 1;         format.mbytesperframe = sizeof(audiounitsampletype);         format.mchannelsperframe = 2 ;         format.mbitsperchannel = sizeof(audiounitsampletype)*8; 

and format

format.msamplerate  = 44100.0;  format.mformatid = kaudioformatlinearpcm; format.mformatflags = kaudioformatflagsaudiounitcanonical; format.mbytesperpacket = sizeof(audiounitsampletype); format.mframesperpacket = 1; format.mbytesperframe = sizeof(audiounitsampletype); format.mchannelsperframe = 2;  format.mbitsperchannel = sizeof(audiounitsampletype)*8; 

within confines of audio render callback there following code , buffer[] in 2nd format , array[] requires 1st format.

for (k = 0; k < channels; k++){     buffer = (audiounitsampletype *) iodata->mbuffers[k].mdata;     for(j=0; j < samples; j++){         array[j] = buffer[j];     } } 

i know can use apple converter unit, cannot use apple converter audio unit in situation (there's reason).

basically difference between 2 formats following flag format.mformatflags (kaudiounitsamplefractionbits << klinearpcmformatflagssamplefractionshift).

how can convert buffer[] (containing data in 2nd format) array[] (containing data in 1st format) , vice-versa?

thank you.

well, if refer docs on kaudioformatflagsaudiounitcanonical, see:

kaudioformatflagsaudiounitcanonical flags canonical audio unit sample  type. matches audiounitsampletype. 

and

the canonical audio sample type audio units , other audio processing in  iphone os noninterleaved linear pcm 8.24-bit fixed-point samples. 

so, samples in buffer[] array in 8.24-bit fixed-point format. mean?

8.24-bit fixed-point format used represent float numbers fixed precision - 32-bit integer first 8 bits represent whole part, , last 24 bits represent fractional part (the numbers after decimal). (further reading)

in ios audio units, there's minor difference - float number (usually) ranges in [-1, 1) ([-1.000000000000, +0.999969482421875] exact). values outside of range clipped when converting 16-bit pcm. can validate first 8 bits 0x00 or 0xff (-1 in two's compliment) part.

to convert representation 16-bit number, use this:

sign((sint8)(val >> 24)) * 32768 * (val & 0xffffff)/(float)(1<<24) 

that is: extract sign 8 msb, extract fractional value 24 lsb , divide range of 24-bit integer (2^24) resulting in float between 0 , 1, , multiply 32768 value in desired range.

i haven't tried myself though - might have adjust few things here , there.


Comments

Popular posts from this blog

linux - xterm copying to CLIPBOARD using copy-selection causes automatic updating of CLIPBOARD upon mouse selection -

c++ - qgraphicsview horizontal scrolling always has a vertical delta -