5 |
* modify it under the terms of the GNU General Public License |
* modify it under the terms of the GNU General Public License |
6 |
* as published by the Free Software Foundation; either version 2 |
* as published by the Free Software Foundation; either version 2 |
7 |
* of the License, or (at your option) any later version. |
* of the License, or (at your option) any later version. |
8 |
* |
* |
9 |
* This program is distributed in the hope that it will be useful, |
* This program is distributed in the hope that it will be useful, |
10 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
53 |
px::Dict<Mix_Chunk*> wav_cache; |
px::Dict<Mix_Chunk*> wav_cache; |
54 |
} |
} |
55 |
|
|
56 |
void |
void |
57 |
sound::Init() |
sound::Init() |
58 |
{ |
{ |
59 |
// Do nothing if user doesn't want sound or mixer lib is already |
// Do nothing if user doesn't want sound or mixer lib is already |
76 |
{ |
{ |
77 |
if (!sound_initialized) |
if (!sound_initialized) |
78 |
return; // SDL_mixer crashes without this check |
return; // SDL_mixer crashes without this check |
79 |
|
|
80 |
int soundvol = int(options::SoundVolume * MIX_MAX_VOLUME); |
int soundvol = int(options::SoundVolume * MIX_MAX_VOLUME); |
81 |
Mix_Volume(-1, Max(0, Min(soundvol, MIX_MAX_VOLUME))); |
Mix_Volume(-1, Max(0, Min(soundvol, MIX_MAX_VOLUME))); |
82 |
int musicvol = int(options::MusicVolume * MIX_MAX_VOLUME); |
int musicvol = int(options::MusicVolume * MIX_MAX_VOLUME); |
83 |
Mix_VolumeMusic(Max(0, Min(musicvol, MIX_MAX_VOLUME))); |
Mix_VolumeMusic(Max(0, Min(musicvol, MIX_MAX_VOLUME))); |
84 |
} |
} |
85 |
|
|
86 |
void |
void |
87 |
sound::Shutdown() |
sound::Shutdown() |
88 |
{ |
{ |
89 |
if (sound_initialized) { |
if (sound_initialized) { |
92 |
} |
} |
93 |
} |
} |
94 |
|
|
95 |
void |
void |
96 |
sound::DisableSound() |
sound::DisableSound() |
97 |
{ |
{ |
98 |
if (sound_enabled) { |
if (sound_enabled) { |
99 |
sound_enabled = false; |
sound_enabled = false; |
101 |
} |
} |
102 |
} |
} |
103 |
|
|
104 |
void |
void |
105 |
sound::EnableSound() |
sound::EnableSound() |
106 |
{ |
{ |
107 |
if (!sound_enabled) { |
if (!sound_enabled) { |
108 |
sound_enabled = true; |
sound_enabled = true; |
110 |
} |
} |
111 |
} |
} |
112 |
|
|
113 |
void |
void |
114 |
sound::DisableMusic() |
sound::DisableMusic() |
115 |
{ |
{ |
116 |
music_enabled = false; |
music_enabled = false; |
117 |
} |
} |
118 |
|
|
119 |
static Mix_Chunk * |
static Mix_Chunk * |
137 |
return i->second; |
return i->second; |
138 |
} |
} |
139 |
|
|
140 |
void |
void |
141 |
sound::SetListenerPosition (const px::V2 &pos) |
sound::SetListenerPosition (const px::V2 &pos) |
142 |
{ |
{ |
143 |
listener_pos = pos; |
listener_pos = pos; |
144 |
} |
} |
145 |
|
|
146 |
void |
void |
147 |
sound::PlaySound (const char *name, const px::V2 &pos) |
sound::PlaySound (const char *name, const px::V2 &pos) |
148 |
{ |
{ |
149 |
if (!sound_enabled) |
if (!sound_enabled) |
160 |
if (Mix_Chunk *chunk = cache_sound(name)) { |
if (Mix_Chunk *chunk = cache_sound(name)) { |
161 |
int channel = -1; //Mix_GroupOldest(-1); |
int channel = -1; //Mix_GroupOldest(-1); |
162 |
int mixvol = int(volume * options::SoundVolume * MIX_MAX_VOLUME); |
int mixvol = int(volume * options::SoundVolume * MIX_MAX_VOLUME); |
163 |
|
|
164 |
channel = Mix_PlayChannel(channel, chunk, 0); |
channel = Mix_PlayChannel(channel, chunk, 0); |
165 |
Mix_SetPanning(channel, left, right); |
Mix_SetPanning(channel, left, right); |
166 |
Mix_Volume(channel, px::Clamp(mixvol, 0, MIX_MAX_VOLUME)); |
Mix_Volume(channel, px::Clamp(mixvol, 0, MIX_MAX_VOLUME)); |
167 |
} |
} |
168 |
} |
} |
169 |
|
|
170 |
void |
void |
171 |
sound::PlaySound (const char *name) |
sound::PlaySound (const char *name) |
172 |
{ |
{ |
173 |
PlaySound (name, listener_pos); |
PlaySound (name, listener_pos); |
174 |
} |
} |
175 |
|
|
176 |
void |
void |
177 |
sound::FadeoutMusic() |
sound::FadeoutMusic() |
178 |
{ |
{ |
179 |
while (Mix_FadingMusic() != MIX_NO_FADING) |
while (Mix_FadingMusic() != MIX_NO_FADING) |
206 |
current_music_name = ""; |
current_music_name = ""; |
207 |
} |
} |
208 |
|
|
209 |
void |
void |
210 |
sound::StopMusic() |
sound::StopMusic() |
211 |
{ |
{ |
212 |
Mix_HaltMusic(); |
Mix_HaltMusic(); |
248 |
|
|
249 |
const Sint8 *src = data; |
const Sint8 *src = data; |
250 |
Sint8 *dst = newdata; |
Sint8 *dst = newdata; |
251 |
|
|
252 |
float srcpos = 0; |
float srcpos = 0; |
253 |
for (unsigned i=0; i<*newlen; ++i) { |
for (unsigned i=0; i<*newlen; ++i) { |
254 |
int srcidx = static_cast<int>(floor(srcpos)); |
int srcidx = static_cast<int>(floor(srcpos)); |
271 |
|
|
272 |
|
|
273 |
Mix_Chunk * |
Mix_Chunk * |
274 |
sound::ChunkFromRaw (const Uint8 *buf, Uint32 len, |
sound::ChunkFromRaw (const Uint8 *buf, Uint32 len, |
275 |
int sfreq, int sformat, int schannels) |
int sfreq, int sformat, int schannels) |
276 |
{ |
{ |
277 |
if (!sound_initialized || !buf) |
if (!sound_initialized || !buf) |
286 |
|
|
287 |
// resample |
// resample |
288 |
Uint32 newlen=0; |
Uint32 newlen=0; |
289 |
Uint8 *newbuf = (Uint8*) resample ((Sint8*)buf, len, sfreq, dfreq, &newlen); |
Uint8 *newbuf = reinterpret_cast<Uint8*>(resample(reinterpret_cast<Sint8*>(const_cast<Uint8*>(buf)), |
290 |
|
len, sfreq, dfreq, &newlen)); |
291 |
|
|
292 |
|
|
293 |
// convert audio data |
// convert audio data |
295 |
if (!SDL_BuildAudioCVT (&cvt, sformat, schannels, dfreq, |
if (!SDL_BuildAudioCVT (&cvt, sformat, schannels, dfreq, |
296 |
dformat, dchannels, dfreq)) |
dformat, dchannels, dfreq)) |
297 |
return 0; |
return 0; |
298 |
|
|
299 |
cvt.buf = (Uint8*) malloc(newlen * cvt.len_mult); |
cvt.buf = (Uint8*) malloc(newlen * cvt.len_mult); |
300 |
cvt.len = newlen; |
cvt.len = newlen; |
301 |
memcpy(cvt.buf, newbuf, newlen); |
memcpy(cvt.buf, newbuf, newlen); |