DEADSOFTWARE

rembo
[flatwaifu.git] / sound.c
1 #include "glob.h"
2 #include "files.h"
3 #include "sound.h"
4 #include <SDL.h>
5 #include <SDL_mixer.h>
7 #define NUM_CHANNELS 16
8 #define NUM_CHUNKS 300
10 short snd_vol = 50;
12 int snddisabled = 1;
14 int rrrr;
16 struct {
17 snd_t *s;
18 Mix_Chunk *c;
19 } chunks[NUM_CHUNKS];
21 void S_init(void)
22 {
23 if (!SDL_WasInit(SDL_INIT_AUDIO)) {
24 if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
25 fprintf(stderr, "\nUnable to initialize audio: %s\n", SDL_GetError());
26 snddisabled=1;
27 return;
28 }
30 if (Mix_OpenAudio(22050, AUDIO_S16, 1, 1000) < 0) {
31 fprintf(stderr, "Error initializing SDL_mixer: %s\n", Mix_GetError());
32 snddisabled=1;
33 return;
34 }
36 if (Mix_AllocateChannels(NUM_CHANNELS)!=NUM_CHANNELS) {
37 fprintf(stderr, "Error allocation channels: %s\n", Mix_GetError());
38 snddisabled=1;
39 return;
40 }
41 }
43 int i;
44 for (i=0; i<NUM_CHUNKS; i++) {
45 chunks[i].s = NULL;
46 chunks[i].c = NULL;
47 }
49 snddisabled = (snd_vol==0);
51 S_volume(snd_vol);
52 }
54 void S_done(void)
55 {
56 free_chunks();
57 Mix_CloseAudio();
58 SDL_QuitSubSystem(SDL_INIT_AUDIO);
59 }
61 Mix_Chunk * get_chunk(snd_t *s, int r, int v)
62 {
63 int i, fi = -1;
64 for(i=0; i<NUM_CHUNKS; i++) {
65 if (chunks[i].s == s) return chunks[i].c;
66 if (chunks[i].s == NULL && fi==-1) fi = i;
67 }
69 if (fi==-1) return NULL;
71 Uint8 *data = (Uint8*)s+sizeof(snd_t);
72 Uint32 dlen = s->len;
73 SDL_AudioCVT cvt;
74 SDL_BuildAudioCVT(&cvt, AUDIO_S8, 1, s->rate, AUDIO_S16, 1, 22050);
75 if (!(cvt.buf = malloc(dlen*cvt.len_mult))) ERR_fatal("Out of memory\n");;
76 memcpy(cvt.buf, data, dlen);
77 cvt.len = dlen;
78 SDL_ConvertAudio(&cvt);
80 Mix_Chunk *chunk;
81 if (!(chunk = malloc(sizeof(Mix_Chunk)))) ERR_fatal("Out of memory\n");;
82 chunk->abuf=cvt.buf;
83 chunk->alen=cvt.len_cvt;
84 chunk->allocated=0;
85 chunk->volume=(float)v/255*SDL_MIX_MAXVOLUME;
87 chunks[fi].s = s;
88 chunks[fi].c = chunk;
90 return chunk;
91 }
93 void free_chunks()
94 {
95 if (snddisabled) return;
96 Mix_HaltChannel(-1);
97 int i;
98 for (i=0; i<NUM_CHUNKS; i++) {
99 if (chunks[i].c) {
100 free(chunks[i].c->abuf);
101 free(chunks[i].c);
102 chunks[i].c = NULL;
103 chunks[i].s = NULL;
108 short S_play(snd_t *s,short c,unsigned r,short v)
110 if (snddisabled) return 0;
111 Mix_Chunk *chunk = get_chunk(s,r,v);
112 if (chunk==NULL) return 0;
113 return Mix_PlayChannel(c, chunk, 0);
116 void S_stop(short c)
118 Mix_HaltChannel(c);
121 void S_volume(int v)
123 if (snddisabled) return;
124 snd_vol=v;
125 if (snd_vol>128) snd_vol=128;
126 if (snd_vol<0) snd_vol=0;
127 Mix_Volume(-1, snd_vol);
130 void S_wait()
132 if (snddisabled) return;
133 while (Mix_Playing(-1)) {
134 SDL_Delay(10);