/* Adapted from SPEED. */ static ALLEGRO_SAMPLE *generate_ping(void) { float osc1, osc2, vol, ramp; int16_t *p; int len; int i; /* ping consists of two sine waves */ len = 8192; ping = create_sample_s16(22050, len); if (!ping) return NULL; p = (int16_t *)al_get_sample_data(ping); osc1 = 0; osc2 = 0; for (i=0; i<len; i++) { vol = (float)(len - i) / (float)len * 4000; ramp = (float)i / (float)len * 8; if (ramp < 1.0f) vol *= ramp; *p = (sin(osc1) + sin(osc2) - 1) * vol; osc1 += 0.1; osc2 += 0.15; p++; } return ping; }
/* Stop any sample instances which are still playing a sample buffer which * is about to be destroyed. */ static void stop_sample_instances_helper(void *object, void (*func)(void *), void *userdata) { ALLEGRO_SAMPLE_INSTANCE *splinst = object; /* This is ugly. */ if (func == (void (*)(void *)) al_destroy_sample_instance && al_get_sample_data(al_get_sample(splinst)) == userdata && al_get_sample_instance_playing(splinst)) { al_stop_sample_instance(splinst); } }
/* Function: al_destroy_sample */ void al_destroy_sample(ALLEGRO_SAMPLE *spl) { if (spl) { _al_kcm_foreach_destructor(stop_sample_instances_helper, al_get_sample_data(spl)); _al_kcm_unregister_destructor(spl); if (spl->free_buf && spl->buffer.ptr) { al_free(spl->buffer.ptr); } spl->buffer.ptr = NULL; spl->free_buf = false; al_free(spl); } }
/* initialises the sound system */ void init_sound() { float f, osc1, osc2, freq1, freq2, vol, val; char *p; int len; int i; if (!al_is_audio_installed()) return; /* zap (firing sound) consists of multiple falling saw waves */ len = 8192; zap = create_sample_u8(22050, len); p = (char *)al_get_sample_data(zap); osc1 = 0; freq1 = 0.02; osc2 = 0; freq2 = 0.025; for (i=0; i<len; i++) { vol = (float)(len - i) / (float)len * 127; *p = 128 + (fmod(osc1, 1) + fmod(osc2, 1) - 1) * vol; osc1 += freq1; freq1 -= 0.000001; osc2 += freq2; freq2 -= 0.00000125; p++; } /* bang (explosion) consists of filtered noise */ len = 8192; bang = create_sample_u8(22050, len); p = (char *)al_get_sample_data(bang); val = 0; for (i=0; i<len; i++) { vol = (float)(len - i) / (float)len * 255; val = (val * 0.75) + (RAND * 0.25); *p = 128 + val * vol; p++; } /* big bang (explosion) consists of noise plus rumble */ len = 24576; bigbang = create_sample_u8(11025, len); p = (char *)al_get_sample_data(bigbang); val = 0; osc1 = 0; osc2 = 0; for (i=0; i<len; i++) { vol = (float)(len - i) / (float)len * 128; f = 0.5 + ((float)i / (float)len * 0.4); val = (val * f) + (RAND * (1-f)); *p = 128 + (val + (sin(osc1) + sin(osc2)) / 4) * vol; osc1 += 0.03; osc2 += 0.04; p++; } /* ping consists of two sine waves */ len = 8192; ping = create_sample_u8(22050, len); p = (char *)al_get_sample_data(ping); osc1 = 0; osc2 = 0; for (i=0; i<len; i++) { vol = (float)(len - i) / (float)len * 31; *p = 128 + (sin(osc1) + sin(osc2) - 1) * vol; osc1 += 0.2; osc2 += 0.3; p++; } ping_timer = al_install_timer(0.3); /* set up my lurvely music player :-) */ if (!no_music) { init_music(); al_start_timer(music_timer); } sound_update_thread = al_create_thread(sound_update_proc, NULL); al_start_thread(sound_update_thread); }
/* this code is sick */ static void init_music() { float vol, val; char *p; int i; if (!al_is_audio_installed()) return; /* sine waves (one straight and one with oscillator sync) for the bass */ sine = create_sample_u8(22050, 64); p = (char *)al_get_sample_data(sine); for (i=0; i<64; i++) { *p = 128 + (sin((float)i * M_PI / 32.0) + sin((float)i * M_PI / 12.0)) * 8.0; p++; } /* square wave for melody #1 */ square = create_sample_u8(22050, 64); p = (char *)al_get_sample_data(square); for (i=0; i<64; i++) { *p = (i < 32) ? 120 : 136; p++; } /* saw wave for melody #2 */ saw = create_sample_u8(22050, 64); p = (char *)al_get_sample_data(saw); for (i=0; i<64; i++) { *p = 120 + (i*4 & 255) / 16; p++; } /* bass drum */ bd = create_sample_u8(22050, 1024); p = (char *)al_get_sample_data(bd); for (i=0; i<1024; i++) { vol = (float)(1024-i) / 16.0; *p = 128 + (sin((float)i / 48.0) + sin((float)i / 32.0)) * vol; p++; } /* snare drum */ snare = create_sample_u8(22050, 3072); p = (char *)al_get_sample_data(snare); val = 0; for (i=0; i<3072; i++) { vol = (float)(3072-i) / 24.0; val = (val * 0.9) + (RAND * 0.1); *p = 128 + val * vol; p++; } /* hihat */ hihat = create_sample_u8(22050, 1024); p = (char *)al_get_sample_data(hihat); for (i=0; i<1024; i++) { vol = (float)(1024-i) / 192.0; *p = 128 + (sin((float)i / 4.2) + RAND) * vol; p++; } /* start up the player */ for (i=0; i<256; i++) freq_table[i] = (int)(350.0 * pow(2.0, (float)i/12.0)); for (i=0; i<NUM_PARTS; i++) { part_pos[i] = part_ptr[i]; part_time[i] = 0; } part_voice[0] = al_create_sample_instance(sine); part_voice[1] = al_create_sample_instance(square); part_voice[2] = al_create_sample_instance(saw); part_voice[3] = al_create_sample_instance(bd); al_attach_sample_instance_to_mixer(part_voice[0], al_get_default_mixer()); al_attach_sample_instance_to_mixer(part_voice[1], al_get_default_mixer()); al_attach_sample_instance_to_mixer(part_voice[2], al_get_default_mixer()); al_attach_sample_instance_to_mixer(part_voice[3], al_get_default_mixer()); al_set_sample_instance_playmode(part_voice[0], ALLEGRO_PLAYMODE_LOOP); al_set_sample_instance_playmode(part_voice[1], ALLEGRO_PLAYMODE_LOOP); al_set_sample_instance_playmode(part_voice[2], ALLEGRO_PLAYMODE_LOOP); al_set_sample_instance_playmode(part_voice[3], ALLEGRO_PLAYMODE_ONCE); al_set_sample_instance_gain(part_voice[0], 192/255.0); al_set_sample_instance_gain(part_voice[1], 192/255.0); al_set_sample_instance_gain(part_voice[2], 192/255.0); al_set_sample_instance_gain(part_voice[3], 255/255.0); al_set_sample_instance_pan(part_voice[0], PAN(128)); al_set_sample_instance_pan(part_voice[1], PAN(224)); al_set_sample_instance_pan(part_voice[2], PAN(32)); al_set_sample_instance_pan(part_voice[3], PAN(128)); music_timer = al_install_timer(ALLEGRO_BPS_TO_SECS(22)); }