2 * SDL_sound Decoder Helpers
4 * Copyright (c) 2013 by Chris Robinson <chris.kcat@gmail.com>
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 /* This file contains routines for helping to decode audio using SDL_sound.
26 * There's very little OpenAL-specific code here.
28 #include "sdl_sound.h"
36 #include <SDL_sound.h>
42 #include "alhelpers.h"
45 static int done_init
= 0;
47 FilePtr
openAudioFile(const char *fname
, size_t buftime_ms
)
54 /* We need to make sure SDL_sound is initialized. */
61 file
= Sound_NewSampleFromFile(fname
, NULL
, 0);
64 fprintf(stderr
, "Failed to open %s: %s\n", fname
, Sound_GetError());
68 if(getAudioInfo(file
, &rate
, &chans
, &type
) != 0)
70 Sound_FreeSample(file
);
74 bufsize
= FramesToBytes((ALsizei
)(buftime_ms
/1000.0*rate
), chans
, type
);
75 if(Sound_SetBufferSize(file
, bufsize
) == 0)
77 fprintf(stderr
, "Failed to set buffer size to %u bytes: %s\n", bufsize
, Sound_GetError());
78 Sound_FreeSample(file
);
85 void closeAudioFile(FilePtr file
)
88 Sound_FreeSample(file
);
92 int getAudioInfo(FilePtr file
, ALuint
*rate
, ALenum
*channels
, ALenum
*type
)
94 if(file
->actual
.channels
== 1)
95 *channels
= AL_MONO_SOFT
;
96 else if(file
->actual
.channels
== 2)
97 *channels
= AL_STEREO_SOFT
;
100 fprintf(stderr
, "Unsupported channel count: %d\n", file
->actual
.channels
);
104 if(file
->actual
.format
== AUDIO_U8
)
105 *type
= AL_UNSIGNED_BYTE_SOFT
;
106 else if(file
->actual
.format
== AUDIO_S8
)
107 *type
= AL_BYTE_SOFT
;
108 else if(file
->actual
.format
== AUDIO_U16LSB
|| file
->actual
.format
== AUDIO_U16MSB
)
109 *type
= AL_UNSIGNED_SHORT_SOFT
;
110 else if(file
->actual
.format
== AUDIO_S16LSB
|| file
->actual
.format
== AUDIO_S16MSB
)
111 *type
= AL_SHORT_SOFT
;
114 fprintf(stderr
, "Unsupported sample format: 0x%04x\n", file
->actual
.format
);
118 *rate
= file
->actual
.rate
;
124 uint8_t *getAudioData(FilePtr file
, size_t *length
)
126 *length
= Sound_Decode(file
);
129 if((file
->actual
.format
== AUDIO_U16LSB
&& AUDIO_U16LSB
!= AUDIO_U16SYS
) ||
130 (file
->actual
.format
== AUDIO_U16MSB
&& AUDIO_U16MSB
!= AUDIO_U16SYS
) ||
131 (file
->actual
.format
== AUDIO_S16LSB
&& AUDIO_S16LSB
!= AUDIO_S16SYS
) ||
132 (file
->actual
.format
== AUDIO_S16MSB
&& AUDIO_S16MSB
!= AUDIO_S16SYS
))
134 /* Swap bytes if the decoded endianness doesn't match the system. */
135 char *buffer
= file
->buffer
;
137 for(i
= 0;i
< *length
;i
+=2)
140 buffer
[i
] = buffer
[i
+1];
147 void *decodeAudioStream(FilePtr file
, size_t *length
)
152 got
= Sound_DecodeAll(file
);
160 memcpy(mem
, file
->buffer
, got
);