3 * Copyright (C) 1998 Brainchild Design - http://brainchilddesign.com/
5 * Copyright (C) 2001 Chuck Mason <cemason@users.sourceforge.net>
7 * Copyright (C) 2002 Florian Schulze <crow@icculus.org>
9 * Portions of this code are from the MPEG software simulation group
10 * idct implementation. This code will be replaced with a new
11 * implementation soon.
13 * This file is part of Jump'n'Bump.
15 * Jump'n'Bump is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
20 * Jump'n'Bump is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 static Mix_Music *current_music = (Mix_Music *) NULL;
35 sfx_data sounds[NUM_SFX];
37 static int SAMPLECOUNT = 512;
39 #define MAX_CHANNELS 32
44 // The channel step amount...
46 // ... and a 0.16 bit remainder of last step.
47 unsigned int stepremainder;
48 unsigned int samplerate;
49 // The channel data pointers, start and end.
51 signed short* startdata;
52 signed short* enddata;
53 // Hardware left and right channel volume lookup.
58 channel_info_t channelinfo[MAX_CHANNELS];
60 // Sample rate in samples/second
61 int audio_rate = 44100;
62 int global_sfx_volume = 0;
64 // This function loops all active (internal) sound
65 // channels, retrieves a given number of samples
66 // from the raw sound data, modifies it according
67 // to the current (internal) channel parameters,
68 // mixes the per channel samples into the given
69 // mixing buffer, and clamping it to the allowed
72 // This function currently supports only 16bit.
75 static void stopchan(int i)
77 if (channelinfo[i].data) {
78 memset(&channelinfo[i], 0, sizeof(channel_info_t));
84 // This function adds a sound to the
85 // list of currently active sounds,
86 // which is maintained as a given number
87 // (eight, usually) of internal channels.
90 int addsfx(signed short *data, int len, int loop, int samplerate, int channel)
94 // We will handle the new SFX.
95 // Set pointer to raw data.
96 channelinfo[channel].data = data;
97 channelinfo[channel].startdata = data;
99 /* Set pointer to end of raw data. */
100 channelinfo[channel].enddata = channelinfo[channel].data + len - 1;
101 channelinfo[channel].samplerate = samplerate;
103 channelinfo[channel].loop = loop;
104 channelinfo[channel].stepremainder = 0;
110 static void updateSoundParams(int slot, int volume)
116 // MWM 2000-12-24: Calculates proportion of channel samplerate
117 // to global samplerate for mixing purposes.
118 // Patched to shift left *then* divide, to minimize roundoff errors
119 // as well as to use SAMPLERATE as defined above, not to assume 11025 Hz
120 channelinfo[slot].step = ((channelinfo[slot].samplerate<<16)/audio_rate);
125 // Sanity check, clamp volume.
136 channelinfo[slot].leftvol = leftvol;
137 channelinfo[slot].rightvol = rightvol;
141 void mix_sound(void *unused, Uint8 *stream, int len)
143 // Mix current sound data.
144 // Data, from raw sound, for right and left.
149 // Pointers in audio stream, left, right, end.
150 signed short* leftout;
151 signed short* rightout;
152 signed short* leftend;
153 // Step in stream, left and right, thus two.
156 // Mixing channel index.
159 // Left and right channel
160 // are in audio stream, alternating.
161 leftout = (signed short *)stream;
162 rightout = ((signed short *)stream)+1;
165 // Determine end, for left channel only
166 // (right channel is implicit).
167 leftend = leftout + (len/4)*step;
169 // Mix sounds into the mixing buffer.
170 // Loop over step*SAMPLECOUNT,
171 // that is 512 values for two channels.
172 while (leftout != leftend) {
173 // Reset left/right value.
177 dr = *rightout * 256;
179 // Love thy L2 chache - made this a loop.
180 // Now more channels could be set at compile time
181 // as well. Thus loop those channels.
182 for ( chan = 0; chan < MAX_CHANNELS; chan++ ) {
183 // Check channel, if active.
184 if (channelinfo[chan].data) {
185 // Get the raw data from the channel.
187 // sample = *channelinfo[chan].data;
189 sample = (int)(((int)channelinfo[chan].data[0] * (int)(0x10000 - channelinfo[chan].stepremainder))
190 + ((int)channelinfo[chan].data[1] * (int)(channelinfo[chan].stepremainder))) >> 16;
192 // Add left and right part
193 // for this channel (sound)
194 // to the current data.
195 // Adjust volume accordingly.
196 dl += sample * (channelinfo[chan].leftvol * global_sfx_volume) / 128;
197 dr += sample * (channelinfo[chan].rightvol * global_sfx_volume) / 128;
198 // Increment index ???
199 channelinfo[chan].stepremainder += channelinfo[chan].step;
200 // MSB is next sample???
201 channelinfo[chan].data += channelinfo[chan].stepremainder >> 16;
203 channelinfo[chan].stepremainder &= 0xffff;
205 // Check whether we are done.
206 if (channelinfo[chan].data >= channelinfo[chan].enddata)
207 if (channelinfo[chan].loop) {
208 channelinfo[chan].data = channelinfo[chan].startdata;
215 // Clamp to range. Left hardware channel.
216 // Has been char instead of short.
217 // if (dl > 127) *leftout = 127;
218 // else if (dl < -128) *leftout = -128;
219 // else *leftout = dl;
226 else if (dl < SHRT_MIN)
229 *leftout = (signed short)dl;
231 // Same for right hardware channel.
233 *rightout = SHRT_MAX;
234 else if (dr < SHRT_MIN)
235 *rightout = SHRT_MIN;
237 *rightout = (signed short)dr;
239 // Increment current pointers in stream
249 Uint16 audio_format = AUDIO_S16LSB;
250 int audio_channels = 2;
251 int audio_buffers = 4096;
255 if (main_info.no_sound)
258 audio_buffers = SAMPLECOUNT*audio_rate/11025;
260 if (Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers) < 0) {
261 fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
262 main_info.no_sound = 1;
266 Mix_QuerySpec(&audio_rate, &audio_format, &audio_channels);
267 printf("Opened audio at %dHz %dbit %s, %d bytes audio buffer\n", audio_rate, (audio_format & 0xFF), (audio_channels > 1) ? "stereo" : "mono", audio_buffers);
269 Mix_SetMusicCMD(getenv("MUSIC_CMD"));
271 Mix_SetPostMix(mix_sound, NULL);
273 memset(channelinfo, 0, sizeof(channelinfo));
274 memset(sounds, 0, sizeof(sounds));
281 if (main_info.no_sound)
286 Mix_FreeMusic(current_music);
287 current_music = NULL;
302 char dj_autodetect_sd(void)
307 char dj_set_stereo(char flag)
312 void dj_set_auto_mix(char flag)
316 unsigned short dj_set_mixing_freq(unsigned short freq)
321 void dj_set_dma_time(unsigned short time)
325 void dj_set_nosound(char flag)
337 char dj_set_num_sfx_channels(char num_channels)
342 void dj_set_sfx_volume(char volume)
344 if (main_info.no_sound)
348 global_sfx_volume = volume*2;
352 void dj_play_sfx(unsigned char sfx_num, unsigned short freq, char volume, char panning, unsigned short delay, char channel)
356 if (main_info.music_no_sound || main_info.no_sound)
360 for (slot=0; slot<MAX_CHANNELS; slot++)
361 if (channelinfo[slot].data==NULL)
363 if (slot>=MAX_CHANNELS)
369 addsfx((short *)sounds[sfx_num].buf, sounds[sfx_num].length, sounds[sfx_num].loop, freq, slot);
370 updateSoundParams(slot, volume*2);
374 char dj_get_sfx_settings(unsigned char sfx_num, sfx_data *data)
376 if (main_info.no_sound)
379 memcpy(data, &sounds[sfx_num], sizeof(sfx_data));
383 char dj_set_sfx_settings(unsigned char sfx_num, sfx_data *data)
385 if (main_info.no_sound)
388 memcpy(&sounds[sfx_num], data, sizeof(sfx_data));
392 void dj_set_sfx_channel_volume(char channel_num, char volume)
394 if (main_info.no_sound)
398 updateSoundParams(channel_num, volume*2);
402 void dj_stop_sfx_channel(char channel_num)
404 if (main_info.no_sound)
408 stopchan(channel_num);
412 char dj_load_sfx(FILE * file_handle, char *filename, int file_length, char sfx_type, unsigned char sfx_num)
416 unsigned short *dest;
418 if (main_info.no_sound)
421 sounds[sfx_num].buf = malloc(file_length);
422 fread(sounds[sfx_num].buf, 1, file_length, file_handle);
423 sounds[sfx_num].length = file_length / 2;
424 src = sounds[sfx_num].buf;
425 dest = (unsigned short *)sounds[sfx_num].buf;
426 for (i=0; i<sounds[sfx_num].length; i++)
429 temp = src[0] + (src[1] << 8);
437 void dj_free_sfx(unsigned char sfx_num)
439 if (main_info.no_sound)
442 free(sounds[sfx_num].buf);
443 memset(&sounds[sfx_num], 0, sizeof(sfx_data));
448 char dj_ready_mod(char mod_num)
451 #if ((defined _MSC_VER) || (defined __MINGW32__))
452 char filename[] = "jnb.tmpmusic.mod";
454 char filename[] = "/tmp/jnb.tmpmusic.mod";
459 if (main_info.no_sound)
464 fp = dat_open("jump.mod", datfile_name, "rb");
465 len = dat_filelen("jump.mod", datfile_name);
468 fp = dat_open("bump.mod", datfile_name, "rb");
469 len = dat_filelen("bump.mod", datfile_name);
472 fp = dat_open("scores.mod", datfile_name, "rb");
473 len = dat_filelen("scores.mod", datfile_name);
479 if (Mix_PlayingMusic())
480 Mix_FadeOutMusic(1500);
483 Mix_FreeMusic(current_music);
484 current_music = NULL;
486 tmp = fopen(filename, "wb");
488 for (; len > 0; len--)
489 fputc(fgetc(fp), tmp);
495 current_music = Mix_LoadMUS(filename);
497 if (current_music == NULL) {
498 fprintf(stderr, "Couldn't load music: %s\n", SDL_GetError());
505 char dj_start_mod(void)
507 if (main_info.no_sound)
511 Mix_PlayMusic(current_music, -1);
516 void dj_stop_mod(void)
518 if (main_info.no_sound)
524 void dj_set_mod_volume(char volume)
526 if (main_info.no_sound)
529 Mix_VolumeMusic(volume);
532 char dj_load_mod(FILE * file_handle, char *filename, char mod_num)
537 void dj_free_mod(char mod_num)