1 /***************************************************************************
2 sndsrv.c - description
3 -------------------
4 begin : Thu Apr 20 2000
5 copyright : (C) 2000 by Michael Speck
6 email : kulkanie@gmx.net
7 ***************************************************************************/
8
9 /***************************************************************************
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 ***************************************************************************/
17
18 #include "sndsrv.h"
19
20 #ifdef SOUND
21
22 #include <stdlib.h>
23 #include <string.h>
24 #include <SDL_video.h>
25
26 extern char *src_dir;
27
28 // Wave //
29
Wave_Load(char * fname)30 Wave* Wave_Load(char *fname)
31 {
32 Wave *w;
33 char path[strlen(src_dir) + strlen(fname) + 1];
34 sprintf(path,"%s%s",src_dir,fname);
35 w = (Wave*)malloc(sizeof(Wave));
36 if (w == 0) {
37 fprintf(stderr, "ERR: wave_load: not enough memory\n");
38 exit(1);
39 }
40 w->buf = 0;
41 w->len = 0;
42 if (SDL_LoadWAV(path, &w->spec, &w->buf, &w->len) == 0) {
43 fprintf(stderr, "ERR: wave_load: %s\n", SDL_GetError());
44 exit(1);
45 }
46 w->spec.callback = 0;
47 w->spec.userdata = 0;
48 return w;
49 }
50
Wave_Free(Wave * w)51 void Wave_Free(Wave *w)
52 {
53 if (w->buf) SDL_FreeWAV(w->buf);
54 free(w);
55 }
56
Wave_Format(Wave * w,SDL_AudioSpec dest)57 void Wave_Format(Wave *w, SDL_AudioSpec dest)
58 {
59 SDL_AudioCVT cvt;
60
61 printf("dst:\n");
62 printf("ch: %i | smpls: %i | fmt: %i\n", dest.channels, dest.format, dest.samples);
63 printf("src:\n");
64 printf("ch: %i | smpls: %i | fmt: %i\n", w->spec.channels, w->spec.format, w->spec.samples);
65
66 if (dest.channels != w->spec.channels || dest.format != w->spec.format || dest.samples != w->spec.samples) {
67 SDL_BuildAudioCVT(&cvt, w->spec.format, w->spec.channels, w->spec.samples, dest.format, dest.channels, dest.samples);
68 cvt.len = w->len;
69 cvt.buf = (char*)malloc(cvt.len * cvt.len_mult);
70 memcpy(cvt.buf, w->buf, w->len);
71 SDL_ConvertAudio(&cvt);
72 SDL_FreeWAV(w->buf);
73 w->buf = cvt.buf;
74 }
75 }
76
77 // Soundserver //
78
79 SndSrv sndsrv;
80
SndSrv_Init(int t)81 void SndSrv_Init(int t)
82 {
83 int i;
84 sndsrv.tracks = (Track*)malloc(sizeof(Track) * t);
85 sndsrv.track_num = t;
86 for (i = 0; i < t; i++)
87 sndsrv.tracks[i].wave = 0;
88 SndSrv_SetVolume(8);
89 sndsrv.playing = 0;
90 sndsrv.ok = 1;
91 }
92
SndSrv_Quit()93 void SndSrv_Quit()
94 {
95 free(sndsrv.tracks);
96 }
97
SndSrv_Open(SDL_AudioSpec wanted)98 int SndSrv_Open(SDL_AudioSpec wanted) {
99 sndsrv.spec.callback = SndSrv_Callback;
100 sndsrv.spec.userdata = 0;
101 if (SDL_OpenAudio(&sndsrv.spec, 0) < 0) {
102 fprintf(stderr, "ERR: sndsrv_open: %s\n", SDL_GetError());
103 sndsrv.ok = 0;
104 return 1;
105 }
106 SndSrv_Pause(0);
107 sndsrv.playing = 0;
108 sndsrv.sleeping = 0;
109 return 0;
110 }
111
SndSrv_Close()112 void SndSrv_Close()
113 {
114 if (sndsrv.ok)
115 SDL_CloseAudio();
116 }
117
SndSrv_Pause(int p)118 void SndSrv_Pause(int p)
119 {
120 if (!sndsrv.ok) return;
121 SDL_PauseAudio(p);
122 if (p) sndsrv.playing = 0;
123 }
124
SndSrv_Play(Wave * w,int p)125 void SndSrv_Play(Wave *w, int p)
126 {
127 int j;
128 if (sndsrv.sleeping || !sndsrv.ok) return;
129 //use free track if possible
130 for (j = 0; j < sndsrv.track_num; j++)
131 if (sndsrv.tracks[j].wave == 0) {
132 //empty
133 sndsrv.tracks[j].wave = w;
134 sndsrv.tracks[j].audio_pos = w->buf;
135 sndsrv.tracks[j].len = w->len;
136 sndsrv.playing++;
137 SndSrv_Pause(0);
138 return;
139 }
140 for (j = 0; j < sndsrv.track_num; j++)
141 if (sndsrv.tracks[j].priority <= p) {
142 //lower priority found
143 sndsrv.tracks[j].wave = w;
144 sndsrv.tracks[j].audio_pos = w->buf;
145 sndsrv.tracks[j].len = w->len;
146 sndsrv.playing++;
147 SndSrv_Pause(0);
148 return;
149 }
150 return; //cannot play sound, no track available
151 }
152
SndSrv_SetVolume(char v)153 void SndSrv_SetVolume(char v)
154 {
155 sndsrv.volume = v < 0 ? 0 : v > 8 ? 8 : v;
156 if (sndsrv.volume) sndsrv.volume = sndsrv.volume * 16 - 1;
157 }
158
SndSrv_SetActive(int a)159 void SndSrv_SetActive(int a)
160 {
161 sndsrv.sleeping = !a;
162 }
163
SndSrv_Callback(void * udata,unsigned char * stream,int str_len)164 void SndSrv_Callback(void *udata, unsigned char *stream, int str_len)
165 {
166 int i, len;
167 Track *track;
168 if (sndsrv.sleeping || !sndsrv.ok) return;
169 for (i = 0; i < sndsrv.track_num; i++) {
170 track = &sndsrv.tracks[i];
171 if (track->wave == 0) continue;
172 len = str_len < track->len ? str_len : track->len;
173 SDL_MixAudio(stream, track->audio_pos, len, sndsrv.volume);
174 track->len -= len;
175 track->audio_pos += len;
176 if (track->len == 0) {
177 track->wave = 0;
178 sndsrv.playing--;
179 }
180 if (!sndsrv.playing) SndSrv_Pause(1);
181 }
182 }
183
184 #endif
185
186