I have WAV files of this format:
Opening audio decoder: [pcm] Uncompressed PCM audio decoder
AUDIO: 48000 Hz, 2 ch, s24le, 2304.0 kbit/100.00% (ratio: 288000->288000)
ID_AUDIO_BITRATE=2304000
ID_AUDIO_RATE=48000
ID_AUDIO_NCH=2
Selected audio codec: [pcm] afm: pcm (Uncompressed PCM)
mplayer
plays them at 16bit, and I can convert them to pcm_s16le
with ffmpeg very easily, and they do play in SDL2 fine.
The Problem
These files are 24bit, so we lose some audio converting them to 16bit I'd assume. Since SDL2 only supports 16bit (signed, unsigned, float) and 32bit, I figured I'd convert up to 32bit if that's possible, using this:
ffmpeg -i input.wav -filter:a asetrate="48k" -ac 2 -c:a pcm_s32le output.wav
If I try to use pcm_s32be
I get: pcm_s32be codec not supported in WAVE format
so I have to use little endian with Float, signed or unsigned...
FFmpeg converts it correctly, but SDL2 won't play the 32bit audio, it gives: Unknown WAVE data format: 0xfffe
Here are the valid SDL2 audio formats: https://wiki.libsdl.org/SDL_AudioFormat we're looking at AUDIO_S32LSB
specifically, and yes I am using SDL2 2.0.X
Note this error message comes from https://github.com/spurious/SDL-mirror/blob/13666b37a08a78bb209b5c584f74846f7e7b5cf2/src/audio/SDL_wave.c#L473 Where it seems to be comparing to Swap16LE? and notices it's not pcm_16 and dies.
Here is the definition for the constant we're using: https://github.com/spurious/SDL-mirror/blob/e04f23c7eaa7da672a8904b59001eff09da8db92/include/SDL_audio.h#L103 note that the number given is not 0xfffe
Note: This is related to SDL2 specifically, so I believe it fits gamedev, I don't think posting to an audio related SA would garner as much intimate knowledge on the subject.
TL;DR Question
Does anyone have any insight on how I can get SDL2 to play my 24bit WAV, possibly by converting them to 32bit and getting them to play in SDL2
EDIT #2: Forget the last Edit (I removed).
I've implemented the LoadWav functionality locally and am getting the 0x0001 vs 0xfffe between 32bit wav and 16bit, so we're getting closer...
I'm inspecting how SDL2 is reading the WAV Header, and the difference between 32bit vs 16bit header is and why it's dying.
EDIT #3:
Here are some values from the two files:
32BIT WAVE:
RIFF: 1179011410, WAVELEN: 52043438
WAVE Magic: 1163280727
headerDiff: 4
Start of Chunk Loop:
Chunk Data: 254
headerDiff: 52
Chunk Magic: 544501094
0x000000000000fffe
16BIT WAVE:
RIFF: 1179011410, WAVELEN: 99312
WAVE Magic: 1163280727
headerDiff: 4
Start of Chunk Loop:
Chunk Data: 1
headerDiff: 28
Chunk Magic: 544501094
0x0000000000000001
So it seems the issue is when reading the chunks, note how the Header is double the size and returns the non-0x0001 value...
Edit #4:
Here are the two files each printed 1 byte at a time, and diffed (0-248 bits) 160-168 are where we're having issues. I need to learn the WAV format header information to proceed past this part.
@@ -2,10 +2,10 @@
8 SRC Bytes: 0x49
16 SRC Bytes: 0x46
24 SRC Bytes: 0x46
- 32 SRC Bytes: 0xf0
- 40 SRC Bytes: 0x83
- 48 SRC Bytes: 0x1
- 56 SRC Bytes: 0x0
+ 32 SRC Bytes: 0xae
+ 40 SRC Bytes: 0x1e
+ 48 SRC Bytes: 0x1a
+ 56 SRC Bytes: 0x3
64 SRC Bytes: 0x57
72 SRC Bytes: 0x41
80 SRC Bytes: 0x56
@@ -14,12 +14,12 @@
104 SRC Bytes: 0x6d
112 SRC Bytes: 0x74
120 SRC Bytes: 0x20
-128 SRC Bytes: 0x10
+128 SRC Bytes: 0x28
136 SRC Bytes: 0x0
144 SRC Bytes: 0x0
152 SRC Bytes: 0x0
-160 SRC Bytes: 0x1
-168 SRC Bytes: 0x0
+160 SRC Bytes: 0xfe
+168 SRC Bytes: 0xff
176 SRC Bytes: 0x2
184 SRC Bytes: 0x0
192 SRC Bytes: 0x80
@@ -27,6 +27,6 @@
208 SRC Bytes: 0x0
216 SRC Bytes: 0x0
224 SRC Bytes: 0x0
-232 SRC Bytes: 0xee
-240 SRC Bytes: 0x2
+232 SRC Bytes: 0xdc
+240 SRC Bytes: 0x5
248 SRC Bytes: 0x0
EDIT #5:
Going off of this: http://soundfile.sapp.org/doc/WaveFormat/
We have
Subchunk1Size 16 for PCM. This is the size of the rest of the Subchunk which follows this number.
AudioFormat PCM = 1 (i.e. Linear quantization) Values other than 1 indicate some form of compression.
So Clearly there's some issue with how I'm converting it to 32bit, as it has a 40 chunk size, rather than 16, and 0xfffe rather than 1.