DEADSOFTWARE

12c5c7fe91948b6588075a1c0f70c994fe383a07
[flatwaifu.git] / src / sound.c
1 /*
2 Copyright (C) Prikol Software 1996-1997
3 Copyright (C) Aleksey Volynskov 1996-1997
4 Copyright (C) <ARembo@gmail.com> 2011
6 This file is part of the Doom2D:Rembo project.
8 Doom2D:Rembo is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License version 2 as
10 published by the Free Software Foundation.
12 Doom2D:Rembo is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, see <http://www.gnu.org/licenses/> or
19 write to the Free Software Foundation, Inc.,
20 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
23 #include "glob.h"
24 #include "files.h"
25 #include "sound.h"
26 #include "error.h"
27 #include <SDL.h>
28 #include <SDL_mixer.h>
30 #define NUM_CHANNELS 16
31 #define NUM_CHUNKS 300
33 short snd_vol = 50;
35 int snddisabled = 1;
37 struct {
38 snd_t *s;
39 Mix_Chunk *c;
40 } chunks[NUM_CHUNKS];
42 void S_init(void)
43 {
44 if (!SDL_WasInit(SDL_INIT_AUDIO)) {
45 if (SDL_InitSubSystem(SDL_INIT_AUDIO) < 0) {
46 fprintf(stderr, "\nUnable to initialize audio: %s\n", SDL_GetError());
47 snddisabled=1;
48 return;
49 }
51 if (Mix_OpenAudio(22050, AUDIO_S16, 1, 1000) < 0) {
52 fprintf(stderr, "Error initializing SDL_mixer: %s\n", Mix_GetError());
53 snddisabled=1;
54 return;
55 }
57 if (Mix_AllocateChannels(NUM_CHANNELS)!=NUM_CHANNELS) {
58 fprintf(stderr, "Error allocation channels: %s\n", Mix_GetError());
59 snddisabled=1;
60 return;
61 }
62 }
64 int i;
65 for (i=0; i<NUM_CHUNKS; i++) {
66 chunks[i].s = NULL;
67 chunks[i].c = NULL;
68 }
70 snddisabled = (snd_vol==0);
72 S_volume(snd_vol);
73 }
75 void S_done(void)
76 {
77 free_chunks();
78 if (SDL_WasInit(SDL_INIT_AUDIO)) {
79 Mix_CloseAudio();
80 SDL_QuitSubSystem(SDL_INIT_AUDIO);
81 }
82 }
84 Mix_Chunk * get_chunk(snd_t *s, int r, int v)
85 {
86 int i, fi = -1;
87 for(i=0; i<NUM_CHUNKS; i++) {
88 if (chunks[i].s == s) return chunks[i].c;
89 if (chunks[i].s == NULL && fi==-1) fi = i;
90 }
92 if (fi==-1) return NULL;
94 Uint8 *data = (Uint8*)s+sizeof(snd_t);
95 Uint32 dlen = s->len;
96 SDL_AudioCVT cvt;
97 SDL_BuildAudioCVT(&cvt, AUDIO_S8, 1, s->rate, AUDIO_S16, 1, 22050);
98 if (!(cvt.buf = malloc(dlen*cvt.len_mult))) ERR_fatal("Out of memory\n");;
99 memcpy(cvt.buf, data, dlen);
100 cvt.len = dlen;
101 SDL_ConvertAudio(&cvt);
103 Mix_Chunk *chunk;
104 if (!(chunk = malloc(sizeof(Mix_Chunk)))) ERR_fatal("Out of memory\n");;
105 chunk->abuf=cvt.buf;
106 chunk->alen=cvt.len_cvt;
107 chunk->allocated=0;
108 chunk->volume=(float)v/255*SDL_MIX_MAXVOLUME;
110 chunks[fi].s = s;
111 chunks[fi].c = chunk;
113 return chunk;
116 void free_chunks()
118 if (snddisabled) return;
119 Mix_HaltChannel(-1);
120 int i;
121 for (i=0; i<NUM_CHUNKS; i++) {
122 if (chunks[i].c) {
123 free(chunks[i].c->abuf);
124 free(chunks[i].c);
125 chunks[i].c = NULL;
126 chunks[i].s = NULL;
131 short S_play(snd_t *s,short c,unsigned r,short v)
133 if (snddisabled) return 0;
134 Mix_Chunk *chunk = get_chunk(s,r,v);
135 if (chunk==NULL) return 0;
136 return Mix_PlayChannel(c, chunk, 0);
139 void S_stop(short c)
141 Mix_HaltChannel(c);
144 void S_volume(int v)
146 if (snddisabled) return;
147 snd_vol=v;
148 if (snd_vol>128) snd_vol=128;
149 if (snd_vol<0) snd_vol=0;
150 Mix_Volume(-1, snd_vol);
153 void S_wait()
155 if (snddisabled) return;
156 while (Mix_Playing(-1)) {
157 SDL_Delay(10);