f8ef47efa7f1f7b41737091c62deb0fdb46860e4
4 #include "misc.h" // int2host
5 #include "memory.h" // M_lock M_unlock
6 #include "files.h" // F_findres
10 #include "SDL_mixer.h"
14 #define TAG_MIX1 0x4d495831
18 Uint32 len
; // length [bytes]
19 Uint32 rate
; // freq [Hz]
20 Uint32 lstart
; // loop start offset [bytes]
21 Uint32 llen
; // loop length [bytes]
22 Uint8 data
[]; // sound data
26 typedef struct sdlmixer_snd
{
31 short snd_vol
; // public 0..128
33 static int devfreq
= MIX_DEFAULT_FREQUENCY
;
34 static Uint32 devformat
= AUDIO_S16SYS
; // MIX_DEFAULT_FORMAT
35 static int devchannels
= 1; // MIX_DEFAULT_CHANNELS;
36 static int devchunksize
= 1024;
37 static int devchunkchannels
= 8;
47 void S_initmusic (void) {
51 void S_donemusic (void) {
55 void S_startmusic (int time
) {
59 void S_stopmusic (void) {
63 void S_volumemusic (int v
) {
67 void F_loadmus (char n
[8]) {
71 void F_freemus (void) {
75 void S_updatemusic (void) {
83 logo("S_init: initialize sound\n");
84 if (SDL_InitSubSystem(SDL_INIT_AUDIO
) == 0) {
85 if (Mix_OpenAudio(devfreq
, devformat
, devchannels
, devchunksize
) == 0) {
86 Mix_AllocateChannels(devchunkchannels
);
89 logo("S_init: Mix_OpenAudio: %s\n", Mix_GetError());
90 SDL_QuitSubSystem(SDL_INIT_AUDIO
);
93 logo("S_init: SDL_InitSubSytem: %s\n", SDL_GetError());
97 static Mix_Chunk
*convert_this (int rate
, int sign
, const Uint8
*buf
, int len
) {
100 if (SDL_BuildAudioCVT(&cvt
, sign
? AUDIO_S8
: AUDIO_U8
, 1, rate
, devformat
, devchannels
, devfreq
) != -1) {
101 int maxlen
= len
* cvt
.len_mult
;
102 Uint8
*maxbuf
= malloc(maxlen
);
103 if (maxbuf
!= NULL
) {
104 memcpy(maxbuf
, buf
, len
);
107 if (SDL_ConvertAudio(&cvt
) == 0) {
108 c
= malloc(sizeof(Mix_Chunk
));
112 c
->alen
= len
* cvt
.len_ratio
;
113 c
->volume
= MIX_MAX_VOLUME
;
125 static sdlmixer_snd
*new_sdlmixer_snd (const void *data
, dword len
, dword rate
, dword lstart
, dword llen
, int sign
) {
127 sdlmixer_snd
*snd
= NULL
;
128 c
= convert_this(rate
, sign
, data
, len
);
130 snd
= malloc(sizeof(sdlmixer_snd
));
132 snd
->base
.tag
= TAG_MIX1
;
142 snd_t
*S_get (int id
) {
144 sdlmixer_snd
*snd
= NULL
;
147 if (handle
!= NULL
) {
149 dword len
= F_getreslen(id
);
156 dword hdr_len
= int2host(hdr
->len
);
157 dword hdr_rate
= int2host(hdr
->rate
);
158 dword hdr_lstart
= int2host(hdr
->lstart
);
159 dword hdr_llen
= int2host(hdr
->llen
);
160 if (hdr_len
<= len
- 8 && hdr_lstart
+ hdr_llen
<= len
- 16) {
169 snd
= new_sdlmixer_snd(data
, len
, rate
, lstart
, llen
, sign
);
176 snd_t
*S_load (const char name
[8]) {
177 int id
= F_findres(name
);
181 void S_free (snd_t
*s
) {
183 sdlmixer_snd
*snd
= (sdlmixer_snd
*)s
;
185 assert(snd
->base
.tag
== TAG_MIX1
);
187 for (i
= 0; i
< devchunkchannels
; i
++) {
188 if (Mix_GetChunk(i
) == snd
->c
) {
199 short S_play (snd_t
*s
, short c
, short v
) {
201 sdlmixer_snd
*snd
= (sdlmixer_snd
*)s
;
202 assert(c
>= 0 && c
<= 8);
203 assert(v
>= 0 && v
<= 255);
204 if (devinit
&& snd
!= NULL
) {
205 assert(snd
->base
.tag
== TAG_MIX1
);
206 // TODO care about global volume level
207 snd
->c
->volume
= v
* MIX_MAX_VOLUME
/ 255;
208 channel
= Mix_PlayChannel(c
<= 0 ? -1 : c
- 1, snd
->c
, 0);
209 channel
= channel
== -1 ? 0 : channel
+ 1;
214 void S_stop (short c
) {
215 assert(c
>= 0 && c
<= 8);
216 if (devinit
&& c
> 0) {
217 Mix_HaltChannel(c
- 1);
221 void S_volume (int v
) {
222 snd_vol
= min(max(v
, 0), 128);
224 // TODO change relativelly for every channel
225 Mix_Volume(-1, v
* MIX_MAX_VOLUME
/ 128);
231 while (Mix_Playing(-1) > 0) {
240 Mix_AllocateChannels(0);
242 SDL_QuitSubSystem(SDL_INIT_AUDIO
);