MS-ADPCM via AudioConverter not working [long]
MS-ADPCM via AudioConverter not working [long]
- Subject: MS-ADPCM via AudioConverter not working [long]
- From: Stephen Davis <email@hidden>
- Date: Wed, 14 Sep 2005 01:43:44 -0700
I'm attempting to convert some old SoundConverter usage over to
AudioConverters and am running into some trouble with two CBR formats
found in WAV files, MP3 (yes, really) and MS-ADPCM.
The basic code I'm working from works for QDesign2, uLaw, aLaw, IMA4,
MACE3, MACE6, and Qualcomm PureVoice so I think the approach is
basically sound but the two above formats are giving crazy results.
Of course, they play fine in QT Player (but that's probably b/c they
still just use the sound manager codecs for these old formats) and
afconvert/afplay (should be closer to what I'm doing).
Now, these codecs are troublesome in SoundConverter-land so this
isn't too surprising but I'd love it if somebody could tell me why
afconvert works and not my code. I've tried looking through the
afconvert code and will attempt to run it in the debugger ASAP but
thought I'd see if anybody had any immediate clues first. The heavy C
++ usage is no doubt convenient for re-use and all but it makes
reading the code difficult/tedious.
I want to read in non-trivial I/O chunks which, since these codecs
extremely high lossy compression, requires converting a large number
of packets at once. What I'm basically doing is reading in ~16KB,
calculating the number of input packets that represents and the
number of output frames (32-bit floats) that will convert into, and
am then calling AudioConverterFillComplexBuffer() to get the data out.
For these formats, I use GetCompressionInfo() with the mFormatID I
pull from the file to determine the bytes/packet and frames/packet
values I stuff into the ABSD. For the MS-ADPCM codec (mFormatID =
0x6D730002), the input ABSD to the converter for a given file looks
like:
Input: 2 ch, 44100 Hz, 'ms ' (0x00000000) 4 bits/channel, 512
bytes/packet, 500 frames/packet, 2 bytes/frame
Calling CAShow() on the converter I just created shows the following:
SoundMgrDecoder 0x36a69b0
Input: 2 ch, 44100 Hz, 'ms ' (0x00000000) 4 bits/channel, 0
bytes/packet, 2036 frames/packet, 0 bytes/frame
Output: 2 ch, 44100 Hz, 'lpcm' (0x0000000E) 16-bit big-endian
signed integer
PCMConverter 0x36a6620
Input: 2 ch, 44100 Hz, 'lpcm' (0x0000000E) 16-bit big-endian
signed integer
Output: 2 ch, 44100 Hz, 'lpcm' (0x0000000B) 32-bit big-endian
float
Note that the frames/packet is now 2036 and the bytes/packet is 0. I
think this may be the crux of the problem as will be seen later. If
I run the following afconvert invocation, I get:
afconvert MSADPCM\ 16b44s.wav /tmp/test.aif -v -f AIFC -d BEF32
Input file: MSADPCM 16b44s.wav, 688000 frames
Formats:
Input file 2 ch, 44100 Hz, 'ms ' (0x00000000) 0 bits/
channel, 512 bytes/packet, 500 frames/packet, 0 bytes/frame
Output file 2 ch, 44100 Hz, 'lpcm' (0x0000000B) 32-bit big-
endian float
Input client 2 ch, 44100 Hz, 'lpcm' (0x0000000B) 32-bit big-
endian float
AudioConverter 0x1837074 [0x320790]:
SoundMgrDecoder 0x31d330
Input: 2 ch, 44100 Hz, 'ms ' (0x00000000) 0 bits/channel,
2048 bytes/packet, 2036 frames/packet, 0 bytes/frame
Output: 2 ch, 44100 Hz, 'lpcm' (0x0000000E) 16-bit big-endian
signed integer
PCMConverter 0x320490
Input: 2 ch, 44100 Hz, 'lpcm' (0x0000000E) 16-bit big-endian
signed integer
Output: 2 ch, 44100 Hz, 'lpcm' (0x0000000B) 32-bit big-endian
float
Output file: test.aif, 688000 frames
The converter shows a similar change in frames/packet but its bytes/
packet value is sane (i.e. !0). ???
If I make one call to my decoding routine and request 16000 frames
from it ((16384/512) * 500), I get the following info from my logging
code:
Decode( 16000 )
# compressed input packets, # output frames, # bytes pulled from
input buffer, total # bytes in input buffer
[pre] in: 32 out: 16000 used: 0 filled: 16384
req: 1024 (2) act: 1024 (2) used: 1024 filled: 16384
<-- requested 1024 bytes = 2 packets, returned same
req: 512 (1) act: 512 (1) used: 1536 filled: 16384
req: 1024 (2) act: 1024 (2) used: 2560 filled: 16384
req: 1024 (2) act: 1024 (2) used: 3584 filled: 16384
req: 512 (1) act: 512 (1) used: 4096 filled: 16384
# requested output frames, # frames returned by
AudioConverterFillComplexBuffer(), # bytes pulled from input buffer,
total # bytes in input buffer
[full] req: 16000 dec: 16000 used: 4096 filled: 16384
Basically, the converter pulled 4096 bytes out of my input buffer and
claims to have returned 16000 frames which, according to the initial
ABSD, would require pulling out 16384 bytes. However, if you use the
second ABSD where it says 2036 frames/packet, 4096 bytes = 8 packets
=> 8 packets * 2036 frames/packet = 16288 frames. Don't know if this
is relevant but it is suspiciously close to what I wanted.
Again, all of the other codecs listed above work just fine with this
same code (in fact, an implementation using AudioConverterFillBuffer
() worked too) so I'm at a loss to what I could do with this codec to
make it happy. How can it change the input ABSD from what I gave it
and expect me to know what happened? Plus, the bytes/packet field in
my case is 0 so I can't use it.
BTW, I tried using some of the audio converter properties to find out
optimal input/output buffer sizes for these codecs a la
SoundConverterGetBufferSizes() but most of the aforementioned codecs
return 0 for everything.
I'll be digging into the example code further but this is weird
enough that I hope one of the experts can chime in and save me some
trouble.
thanks,
stephen
P.S. This is on Tiger 10.4.2 (8C46) w/ QuickTime 7.0.2.
_______________________________________________
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