4 static Mix_Music *current_music = (Mix_Music *) NULL;
6 sfx_data sounds[NUM_SFX];
8 static int SAMPLECOUNT = 512;
10 #define MAX_CHANNELS 32
15 // The channel step amount...
17 // ... and a 0.16 bit remainder of last step.
18 unsigned int stepremainder;
19 unsigned int samplerate;
20 // The channel data pointers, start and end.
22 signed short* startdata;
23 signed short* enddata;
24 // Hardware left and right channel volume lookup.
29 channel_info_t channelinfo[MAX_CHANNELS];
31 // Sample rate in samples/second
32 int audio_rate = 44100;
33 int global_sfx_volume = 0;
35 // This function loops all active (internal) sound
36 // channels, retrieves a given number of samples
37 // from the raw sound data, modifies it according
38 // to the current (internal) channel parameters,
39 // mixes the per channel samples into the given
40 // mixing buffer, and clamping it to the allowed
43 // This function currently supports only 16bit.
46 static void stopchan(int i)
48 if (channelinfo[i].data) {
49 memset(&channelinfo[i], 0, sizeof(channel_info_t));
55 // This function adds a sound to the
56 // list of currently active sounds,
57 // which is maintained as a given number
58 // (eight, usually) of internal channels.
61 int addsfx(signed short *data, int len, int loop, int samplerate, int channel)
65 // We will handle the new SFX.
66 // Set pointer to raw data.
67 channelinfo[channel].data = data;
68 channelinfo[channel].startdata = data;
70 /* Set pointer to end of raw data. */
71 channelinfo[channel].enddata = channelinfo[channel].data + len - 1;
72 channelinfo[channel].samplerate = samplerate;
74 channelinfo[channel].loop = loop;
75 channelinfo[channel].stepremainder = 0;
81 static void updateSoundParams(int slot, int volume)
87 // MWM 2000-12-24: Calculates proportion of channel samplerate
88 // to global samplerate for mixing purposes.
89 // Patched to shift left *then* divide, to minimize roundoff errors
90 // as well as to use SAMPLERATE as defined above, not to assume 11025 Hz
91 channelinfo[slot].step = ((channelinfo[slot].samplerate<<16)/audio_rate);
96 // Sanity check, clamp volume.
107 channelinfo[slot].leftvol = leftvol;
108 channelinfo[slot].rightvol = rightvol;
112 void mix_sound(void *unused, Uint8 *stream, int len)
114 // Mix current sound data.
115 // Data, from raw sound, for right and left.
120 // Pointers in audio stream, left, right, end.
121 signed short* leftout;
122 signed short* rightout;
123 signed short* leftend;
124 // Step in stream, left and right, thus two.
127 // Mixing channel index.
130 // Left and right channel
131 // are in audio stream, alternating.
132 leftout = (signed short *)stream;
133 rightout = ((signed short *)stream)+1;
136 // Determine end, for left channel only
137 // (right channel is implicit).
138 leftend = leftout + (len/4)*step;
140 // Mix sounds into the mixing buffer.
141 // Loop over step*SAMPLECOUNT,
142 // that is 512 values for two channels.
143 while (leftout != leftend) {
144 // Reset left/right value.
148 dr = *rightout * 256;
150 // Love thy L2 chache - made this a loop.
151 // Now more channels could be set at compile time
152 // as well. Thus loop those channels.
153 for ( chan = 0; chan < MAX_CHANNELS; chan++ ) {
154 // Check channel, if active.
155 if (channelinfo[chan].data) {
156 // Get the raw data from the channel.
158 // sample = *channelinfo[chan].data;
160 sample = (int)(((int)channelinfo[chan].data[0] * (int)(0x10000 - channelinfo[chan].stepremainder))
161 + ((int)channelinfo[chan].data[1] * (int)(channelinfo[chan].stepremainder))) >> 16;
163 // Add left and right part
164 // for this channel (sound)
165 // to the current data.
166 // Adjust volume accordingly.
167 dl += sample * (channelinfo[chan].leftvol * global_sfx_volume) / 128;
168 dr += sample * (channelinfo[chan].rightvol * global_sfx_volume) / 128;
169 // Increment index ???
170 channelinfo[chan].stepremainder += channelinfo[chan].step;
171 // MSB is next sample???
172 channelinfo[chan].data += channelinfo[chan].stepremainder >> 16;
174 channelinfo[chan].stepremainder &= 0xffff;
176 // Check whether we are done.
177 if (channelinfo[chan].data >= channelinfo[chan].enddata)
178 if (channelinfo[chan].loop) {
179 channelinfo[chan].data = channelinfo[chan].startdata;
186 // Clamp to range. Left hardware channel.
187 // Has been char instead of short.
188 // if (dl > 127) *leftout = 127;
189 // else if (dl < -128) *leftout = -128;
190 // else *leftout = dl;
197 else if (dl < SHRT_MIN)
200 *leftout = (signed short)dl;
202 // Same for right hardware channel.
204 *rightout = SHRT_MAX;
205 else if (dr < SHRT_MIN)
206 *rightout = SHRT_MIN;
208 *rightout = (signed short)dr;
210 // Increment current pointers in stream
220 Uint16 audio_format = AUDIO_U16;
221 int audio_channels = 2;
222 int audio_buffers = 4096;
226 audio_buffers = SAMPLECOUNT*audio_rate/11025;
228 if (Mix_OpenAudio(audio_rate, audio_format, audio_channels, audio_buffers) < 0) {
229 fprintf(stderr, "Couldn't open audio: %s\n", SDL_GetError());
233 Mix_QuerySpec(&audio_rate, &audio_format, &audio_channels);
234 printf("Opened audio at %dHz %dbit %s, %d bytes audio buffer\n", audio_rate, (audio_format & 0xFF), (audio_channels > 1) ? "stereo" : "mono", audio_buffers);
236 Mix_SetMusicCMD(getenv("MUSIC_CMD"));
238 Mix_SetPostMix(mix_sound, NULL);
240 memset(channelinfo, 0, sizeof(channelinfo));
241 memset(sounds, 0, sizeof(sounds));
250 Mix_FreeMusic(current_music);
251 current_music = NULL;
266 char dj_autodetect_sd(void)
271 char dj_set_stereo(char flag)
276 void dj_set_auto_mix(char flag)
280 unsigned short dj_set_mixing_freq(unsigned short freq)
285 void dj_set_dma_time(unsigned short time)
289 void dj_set_nosound(char flag)
301 char dj_set_num_sfx_channels(char num_channels)
306 void dj_set_sfx_volume(char volume)
309 global_sfx_volume = volume*2;
313 void dj_play_sfx(unsigned char sfx_num, unsigned short freq, char volume, char panning, unsigned short delay, char channel)
318 for (slot=0; slot<MAX_CHANNELS; slot++)
319 if (channelinfo[slot].data==NULL)
321 if (slot>=MAX_CHANNELS)
327 addsfx((short *)sounds[sfx_num].buf, sounds[sfx_num].length, sounds[sfx_num].loop, freq, slot);
328 updateSoundParams(slot, volume*2);
332 char dj_get_sfx_settings(unsigned char sfx_num, sfx_data *data)
334 memcpy(data, &sounds[sfx_num], sizeof(sfx_data));
338 char dj_set_sfx_settings(unsigned char sfx_num, sfx_data *data)
340 memcpy(&sounds[sfx_num], data, sizeof(sfx_data));
344 void dj_set_sfx_channel_volume(char channel_num, char volume)
347 updateSoundParams(channel_num, volume*2);
351 void dj_stop_sfx_channel(char channel_num)
354 stopchan(channel_num);
358 char dj_load_sfx(FILE * file_handle, char *filename, int file_length, char sfx_type, unsigned char sfx_num)
360 sounds[sfx_num].buf = malloc(file_length);
361 fread(sounds[sfx_num].buf, file_length, 1, file_handle);
362 sounds[sfx_num].length = file_length / 2;
366 void dj_free_sfx(unsigned char sfx_num)
368 free(sounds[sfx_num].buf);
369 memset(&sounds[sfx_num], 0, sizeof(sfx_data));
374 char dj_ready_mod(char mod_num)
378 char filename[] = "jnb.tmpmusic.mod";
380 char filename[] = "/tmp/jnb.tmpmusic.mod";
386 fp = dat_open("jump.mod", datfile_name, "rb");
387 len = dat_filelen("jump.mod", datfile_name);
390 fp = dat_open("bump.mod", datfile_name, "rb");
391 len = dat_filelen("bump.mod", datfile_name);
394 fp = dat_open("scores.mod", datfile_name, "rb");
395 len = dat_filelen("scores.mod", datfile_name);
401 if (Mix_PlayingMusic())
402 Mix_FadeOutMusic(1500);
405 Mix_FreeMusic(current_music);
406 current_music = NULL;
408 tmp = fopen(filename, "wb");
409 for (; len > 0; len--)
410 fputc(fgetc(fp), tmp);
415 current_music = Mix_LoadMUS(filename);
416 if (current_music == NULL) {
417 fprintf(stderr, "Couldn't load music: %s\n", SDL_GetError());
424 char dj_start_mod(void)
426 Mix_PlayMusic(current_music, -1);
431 void dj_stop_mod(void)
436 void dj_set_mod_volume(char volume)
438 Mix_VolumeMusic(volume);
441 char dj_load_mod(FILE * file_handle, char *filename, char mod_num)
446 void dj_free_mod(char mod_num)