92334c7fc0ad58c9aff515e07e7863a8a34e2d7b
4 #include "misc.h" // int2host
5 #include "memory.h" // M_lock M_unlock
6 #include "files.h" // F_findres
10 #include "SDL_mixer.h"
13 #define TAG_MIX1 0x4d495831
17 Uint32 len
; // length [bytes]
18 Uint32 rate
; // freq [Hz]
19 Uint32 lstart
; // loop start offset [bytes]
20 Uint32 llen
; // loop length [bytes]
21 Uint8 data
[]; // sound data
25 typedef struct sdlmixer_snd
{
30 short snd_vol
; // public 0..128
32 static int devfreq
= MIX_DEFAULT_FREQUENCY
;
33 static Uint32 devformat
= AUDIO_S16SYS
; // MIX_DEFAULT_FORMAT
34 static int devchannels
= 1; // MIX_DEFAULT_CHANNELS;
35 static int devchunksize
= 1024;
36 static int devchunkchannels
= 8;
46 void S_initmusic (void) {
50 void S_donemusic (void) {
54 void S_startmusic (int time
) {
58 void S_stopmusic (void) {
62 void S_volumemusic (int v
) {
66 void F_loadmus (char n
[8]) {
70 void F_freemus (void) {
74 void S_updatemusic (void) {
82 logo("S_init: initialize sound\n");
83 if (SDL_InitSubSystem(SDL_INIT_AUDIO
) == 0) {
84 if (Mix_OpenAudio(devfreq
, devformat
, devchannels
, devchunksize
) == 0) {
85 Mix_AllocateChannels(devchunkchannels
);
88 logo("S_init: Mix_OpenAudio: %s\n", Mix_GetError());
89 SDL_QuitSubSystem(SDL_INIT_AUDIO
);
92 logo("S_init: SDL_InitSubSytem: %s\n", SDL_GetError());
96 static Mix_Chunk
*convert_this (int rate
, int sign
, const Uint8
*buf
, int len
) {
99 if (SDL_BuildAudioCVT(&cvt
, sign
? AUDIO_S8
: AUDIO_U8
, 1, rate
, devformat
, devchannels
, devfreq
) != -1) {
100 int maxlen
= len
* cvt
.len_mult
;
101 Uint8
*maxbuf
= malloc(maxlen
);
102 if (maxbuf
!= NULL
) {
103 memcpy(maxbuf
, buf
, len
);
106 if (SDL_ConvertAudio(&cvt
) == 0) {
107 c
= malloc(sizeof(Mix_Chunk
));
111 c
->alen
= len
* cvt
.len_ratio
;
112 c
->volume
= MIX_MAX_VOLUME
;
124 static sdlmixer_snd
*new_sdlmixer_snd (const void *data
, dword len
, dword rate
, dword lstart
, dword llen
, int sign
) {
126 sdlmixer_snd
*snd
= NULL
;
127 c
= convert_this(rate
, sign
, data
, len
);
129 snd
= malloc(sizeof(sdlmixer_snd
));
131 snd
->base
.tag
= TAG_MIX1
;
141 snd_t
*S_get (int id
) {
143 sdlmixer_snd
*snd
= NULL
;
146 if (handle
!= NULL
) {
148 dword len
= F_getreslen(id
);
155 dword hdr_len
= int2host(hdr
->len
);
156 dword hdr_rate
= int2host(hdr
->rate
);
157 dword hdr_lstart
= int2host(hdr
->lstart
);
158 dword hdr_llen
= int2host(hdr
->llen
);
159 if (hdr_len
<= len
- 8 && hdr_lstart
+ hdr_llen
<= len
- 16) {
168 snd
= new_sdlmixer_snd(data
, len
, rate
, lstart
, llen
, sign
);
175 snd_t
*S_load (const char name
[8]) {
176 int id
= F_findres(name
);
180 void S_free (snd_t
*s
) {
182 sdlmixer_snd
*snd
= (sdlmixer_snd
*)s
;
184 assert(snd
->base
.tag
== TAG_MIX1
);
186 for (i
= 0; i
< devchunkchannels
; i
++) {
187 if (Mix_GetChunk(i
) == snd
->c
) {
198 short S_play (snd_t
*s
, short c
, short v
) {
200 sdlmixer_snd
*snd
= (sdlmixer_snd
*)s
;
201 assert(c
>= 0 && c
<= 8);
202 assert(v
>= 0 && v
<= 255);
203 if (devinit
&& snd
!= NULL
) {
204 assert(snd
->base
.tag
== TAG_MIX1
);
205 // TODO care about global volume level
206 snd
->c
->volume
= v
* MIX_MAX_VOLUME
/ 255;
207 channel
= Mix_PlayChannel(c
<= 0 ? -1 : c
- 1, snd
->c
, 0);
208 channel
= channel
== -1 ? 0 : channel
+ 1;
213 void S_stop (short c
) {
214 assert(c
>= 0 && c
<= 8);
215 if (devinit
&& c
> 0) {
216 Mix_HaltChannel(c
- 1);
220 void S_volume (int v
) {
221 snd_vol
= min(max(v
, 0), 128);
223 // TODO change relativelly for every channel
224 Mix_Volume(-1, v
* MIX_MAX_VOLUME
/ 128);
230 while (Mix_Playing(-1) > 0) {
239 Mix_AllocateChannels(0);
241 SDL_QuitSubSystem(SDL_INIT_AUDIO
);