-
Notifications
You must be signed in to change notification settings - Fork 62
/
SDLSound.c
177 lines (129 loc) · 4.35 KB
/
SDLSound.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#include <Carbon/Carbon.h>
#include "musicai.h"
#ifdef USE_SDL_MIXER
#include <SDL_mixer.h>
static Mix_Chunk *samples_by_channel[SND_MAX_SAMPLES];
static snd_digi_parms digi_parms_by_channel[SND_MAX_SAMPLES];
static Mix_Chunk *playing_audiolog_sample = NULL;
int snd_start_digital(void) {
// Startup the sound system
if(Mix_Init(MIX_INIT_MP3) < 0) {
ERROR("%s: Init failed", __FUNCTION__);
}
if(Mix_OpenAudio(MIX_DEFAULT_FREQUENCY, MIX_DEFAULT_FORMAT, 2, 1024) < 0) {
ERROR("%s: Couldn't open audio device", __FUNCTION__);
}
Mix_AllocateChannels(SND_MAX_SAMPLES);
return OK;
}
int snd_sample_play(int snd_ref, int len, uchar *smp, struct snd_digi_parms *dprm) {
// Play one of the VOC format sounds
Mix_Chunk *sample = Mix_LoadWAV_RW(SDL_RWFromConstMem(smp, len), 1);
if (sample == NULL) {
DEBUG("%s: Failed to load sample", __FUNCTION__);
return ERR_NOEFFECT;
}
int loops = dprm->loops > 0 ? dprm->loops - 1 : -1;
int channel = Mix_PlayChannel(-1, sample, loops);
if (channel < 0) {
DEBUG("%s: Failed to play sample", __FUNCTION__);
Mix_FreeChunk(sample);
return ERR_NOEFFECT;
}
if (samples_by_channel[channel])
Mix_FreeChunk(samples_by_channel[channel]);
samples_by_channel[channel] = sample;
digi_parms_by_channel[channel] = *dprm;
snd_sample_reload_parms(&digi_parms_by_channel[channel]);
return channel;
}
int snd_alog_play(int snd_ref, int len, Uint8 *smp, struct snd_digi_parms *dprm) {
// Get rid of the last playing audiolog
if(playing_audiolog_sample != NULL) {
Mix_FreeChunk(playing_audiolog_sample);
playing_audiolog_sample = NULL;
}
// Play one of the Audiolog sounds
playing_audiolog_sample = Mix_QuickLoad_RAW(smp, len);
if (playing_audiolog_sample == NULL) {
DEBUG("%s: Failed to load sample", __FUNCTION__);
return ERR_NOEFFECT;
}
int channel = Mix_PlayChannel(-1, playing_audiolog_sample, 0);
if (channel < 0) {
DEBUG("%s: Failed to play sample", __FUNCTION__);
Mix_FreeChunk(playing_audiolog_sample);
playing_audiolog_sample = NULL;
return ERR_NOEFFECT;
}
Mix_Volume(channel, dprm->vol / 2);
return channel;
}
void snd_end_sample(int hnd_id) {
Mix_HaltChannel(hnd_id);
if (samples_by_channel[hnd_id]) {
Mix_FreeChunk(samples_by_channel[hnd_id]);
samples_by_channel[hnd_id] = NULL;
}
}
bool snd_sample_playing(int hnd_id) {
return Mix_Playing(hnd_id);
}
snd_digi_parms *snd_sample_parms(int hnd_id)
{
return &digi_parms_by_channel[hnd_id];
}
void snd_kill_all_samples(void) {
for (int channel = 0; channel < SND_MAX_SAMPLES; channel++) {
snd_end_sample(channel);
}
}
void snd_sample_reload_parms(snd_digi_parms *sdp) {
// ignore if *sdp is not one of the items in digi_parms_by_channel[]
if (sdp < digi_parms_by_channel || sdp > digi_parms_by_channel + SND_MAX_SAMPLES)
return;
int channel = sdp - digi_parms_by_channel;
if (!Mix_Playing(channel))
return;
// sdp->vol ranges from 0..255
Mix_Volume(channel, sdp->vol / 2);
// sdp->pan ranges from 1 (left) to 127 (right)
uint8_t right = 2 * sdp->pan;
Mix_SetPanning(channel, 254 - right, right);
}
void MacTuneUpdateVolume(void) {
extern uchar curr_vol_lev;
float music_vol_mod = 0.6f;
Mix_VolumeMusic(((curr_vol_lev * curr_vol_lev) * 128 / 10000) * music_vol_mod);
}
int MacTuneLoadTheme(char* theme_base, int themeID) {
char filename[30];
// Try to play some music! theme_base will be a string like 'thm0'
// FIXME: This should really try to play the .xmi files in res/sound/genmidi if there is a way!
// until then, I'm going to just attempt to play .mid files instead.
// Build the file name
strcpy(filename, "res/music/");
strcat(filename, theme_base);
strcat(filename, ".mid");
DEBUG("Playing music %s", filename);
Mix_Music *music;
music = Mix_LoadMUS(filename);
Mix_PlayMusic(music, -1);
MacTuneUpdateVolume();
return OK;
}
void MacTuneKillCurrentTheme(void) {
Mix_HaltMusic();
}
#else
// Sound stubs that do nothing, when SDL Mixer is not found
int snd_start_digital(void) { return OK; }
int snd_sample_play(int snd_ref, int len, uchar *smp, struct snd_digi_parms *dprm) { return OK; }
int snd_alog_play(int snd_ref, int len, uchar *smp, struct snd_digi_parms *dprm) { return OK; }
void snd_end_sample(int hnd_id);
int MacTuneLoadTheme(char* theme_base, int themeID) { return OK; }
void MacTuneKillCurrentTheme(void) { }
#endif
// Unimplemented sound stubs
void snd_startup(void) { }
int snd_stop_digital(void) { return 1; }