diff --git a/src/allegro/cmake/FileList.cmake b/src/allegro/cmake/FileList.cmake index 497b5d7e5..42f9cfa43 100644 --- a/src/allegro/cmake/FileList.cmake +++ b/src/allegro/cmake/FileList.cmake @@ -9,7 +9,6 @@ set(ALLEGRO_SRC_FILES src/config.c src/datafile.c src/dataregi.c - src/digmid.c src/dither.c src/dispsw.c src/drvlist.c @@ -33,8 +32,6 @@ set(ALLEGRO_SRC_FILES src/lzss.c src/math.c src/math3d.c - src/midi.c - src/mixer.c src/mouse.c src/pcx.c src/poly3d.c @@ -43,14 +40,11 @@ set(ALLEGRO_SRC_FILES src/quat.c src/readbmp.c src/readfont.c - src/readsmp.c src/rle.c src/rotate.c src/rsfb.c src/scene3d.c - src/sound.c src/spline.c - src/stream.c src/text.c src/tga.c src/timer.c @@ -107,10 +101,6 @@ set(ALLEGRO_SRC_WIN_FILES src/win/wddmode.c src/win/wddovl.c src/win/wddwin.c - src/win/wdsinput.c - src/win/wdsndmix.c - src/win/wdsound.c - src/win/wsndwo.c src/win/wdxver.c src/win/wdispsw.c src/win/wfile.c @@ -118,9 +108,7 @@ set(ALLEGRO_SRC_WIN_FILES src/win/wgfxdrv.c src/win/winput.c src/win/wkeybd.c - src/win/wmidi.c src/win/wmouse.c - src/win/wsnddrv.c src/win/wsystem.c src/win/wthread.c src/win/wtimer.c @@ -153,26 +141,17 @@ set(ALLEGRO_SRC_LINUX_FILES ) set(ALLEGRO_SRC_UNIX_FILES - src/unix/alsa9.c - src/unix/alsamidi.c - src/unix/arts.c - src/unix/sgial.c - src/unix/jack.c src/unix/udjgpp.c src/unix/udrvlist.c src/unix/udummy.c - src/unix/uesd.c src/unix/ufile.c src/unix/ugfxdrv.c src/unix/ukeybd.c src/unix/umain.c src/unix/umodules.c src/unix/umouse.c - src/unix/uoss.c - src/unix/uossmidi.c src/unix/uptimer.c src/unix/usigalrm.c - src/unix/usnddrv.c src/unix/ustimer.c src/unix/usystem.c src/unix/uthreads.c @@ -192,18 +171,14 @@ set(ALLEGRO_SRC_X_FILES ) set(ALLEGRO_SRC_MACOSX_FILES - src/macosx/cadigi.m - src/macosx/camidi.m src/macosx/drivers.m src/macosx/hidman.m src/macosx/keybd.m src/macosx/pcpu.m - src/macosx/qtmidi.m src/macosx/quartz.m src/macosx/qzfull.m src/macosx/qzmouse.m src/macosx/qzwindow.m - src/macosx/soundman.m src/macosx/system.m src/unix/ufile.c src/unix/utimer.c @@ -224,7 +199,6 @@ set(ALLEGRO_INCLUDE_ALLEGRO_FILES include/allegro/config.h include/allegro/datafile.h include/allegro/debug.h - include/allegro/digi.h include/allegro/draw.h include/allegro/file.h include/allegro/fix.h @@ -237,13 +211,10 @@ set(ALLEGRO_INCLUDE_ALLEGRO_FILES include/allegro/keyboard.h include/allegro/lzss.h include/allegro/matrix.h - include/allegro/midi.h include/allegro/mouse.h include/allegro/palette.h include/allegro/quat.h include/allegro/rle.h - include/allegro/sound.h - include/allegro/stream.h include/allegro/system.h include/allegro/text.h include/allegro/timer.h diff --git a/src/allegro/include/allegro.h b/src/allegro/include/allegro.h index e6e6f86e1..62501e22f 100644 --- a/src/allegro/include/allegro.h +++ b/src/allegro/include/allegro.h @@ -45,8 +45,6 @@ #include "allegro/fli.h" #include "allegro/config.h" -#include "allegro/sound.h" - #include "allegro/file.h" #include "allegro/lzss.h" #include "allegro/datafile.h" diff --git a/src/allegro/include/allegro/datafile.h b/src/allegro/include/allegro/datafile.h index d44e9a31c..469d350c2 100644 --- a/src/allegro/include/allegro/datafile.h +++ b/src/allegro/include/allegro/datafile.h @@ -35,8 +35,6 @@ struct RGB; #define DAT_FILE DAT_ID('F','I','L','E') #define DAT_DATA DAT_ID('D','A','T','A') #define DAT_FONT DAT_ID('F','O','N','T') -#define DAT_SAMPLE DAT_ID('S','A','M','P') -#define DAT_MIDI DAT_ID('M','I','D','I') #define DAT_PATCH DAT_ID('P','A','T',' ') #define DAT_FLI DAT_ID('F','L','I','C') #define DAT_BITMAP DAT_ID('B','M','P',' ') diff --git a/src/allegro/include/allegro/digi.h b/src/allegro/include/allegro/digi.h deleted file mode 100644 index 5f4868b95..000000000 --- a/src/allegro/include/allegro/digi.h +++ /dev/null @@ -1,219 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * Digital sound routines. - * - * By Shawn Hargreaves. - * - * See readme.txt for copyright information. - */ - - -#ifndef ALLEGRO_DIGI_H -#define ALLEGRO_DIGI_H - -#include "base.h" - -#ifdef __cplusplus - extern "C" { -#endif - -struct PACKFILE; - - -#define DIGI_VOICES 64 /* Theoretical maximums: */ - /* actual drivers may not be */ - /* able to handle this many */ - -typedef struct SAMPLE /* a sample */ -{ - int bits; /* 8 or 16 */ - int stereo; /* sample type flag */ - int freq; /* sample frequency */ - int priority; /* 0-255 */ - unsigned long len; /* length (in samples) */ - unsigned long loop_start; /* loop start position */ - unsigned long loop_end; /* loop finish position */ - unsigned long param; /* for internal use by the driver */ - void *data; /* sample data */ -} SAMPLE; - - -#define DIGI_AUTODETECT -1 /* for passing to install_sound() */ -#define DIGI_NONE 0 - -typedef struct DIGI_DRIVER /* driver for playing digital sfx */ -{ - int id; /* driver ID code */ - AL_CONST char *name; /* driver name */ - AL_CONST char *desc; /* description string */ - AL_CONST char *ascii_name; /* ASCII format name string */ - int voices; /* available voices */ - int basevoice; /* voice number offset */ - int max_voices; /* maximum voices we can support */ - int def_voices; /* default number of voices to use */ - - /* setup routines */ - AL_METHOD(int, detect, (int input)); - AL_METHOD(int, init, (int input, int voices)); - AL_METHOD(void, exit, (int input)); - AL_METHOD(int, set_mixer_volume, (int volume)); - AL_METHOD(int, get_mixer_volume, (void)); - - /* for use by the audiostream functions */ - AL_METHOD(void *, lock_voice, (int voice, int start, int end)); - AL_METHOD(void, unlock_voice, (int voice)); - AL_METHOD(int, buffer_size, (void)); - - /* voice control functions */ - AL_METHOD(void, init_voice, (int voice, AL_CONST SAMPLE *sample)); - AL_METHOD(void, release_voice, (int voice)); - AL_METHOD(void, start_voice, (int voice)); - AL_METHOD(void, stop_voice, (int voice)); - AL_METHOD(void, loop_voice, (int voice, int playmode)); - - /* position control functions */ - AL_METHOD(int, get_position, (int voice)); - AL_METHOD(void, set_position, (int voice, int position)); - - /* volume control functions */ - AL_METHOD(int, get_volume, (int voice)); - AL_METHOD(void, set_volume, (int voice, int volume)); - AL_METHOD(void, ramp_volume, (int voice, int tyme, int endvol)); - AL_METHOD(void, stop_volume_ramp, (int voice)); - - /* pitch control functions */ - AL_METHOD(int, get_frequency, (int voice)); - AL_METHOD(void, set_frequency, (int voice, int frequency)); - AL_METHOD(void, sweep_frequency, (int voice, int tyme, int endfreq)); - AL_METHOD(void, stop_frequency_sweep, (int voice)); - - /* pan control functions */ - AL_METHOD(int, get_pan, (int voice)); - AL_METHOD(void, set_pan, (int voice, int pan)); - AL_METHOD(void, sweep_pan, (int voice, int tyme, int endpan)); - AL_METHOD(void, stop_pan_sweep, (int voice)); - - /* effect control functions */ - AL_METHOD(void, set_echo, (int voice, int strength, int delay)); - AL_METHOD(void, set_tremolo, (int voice, int rate, int depth)); - AL_METHOD(void, set_vibrato, (int voice, int rate, int depth)); - - /* input functions */ - int rec_cap_bits; - int rec_cap_stereo; - AL_METHOD(int, rec_cap_rate, (int bits, int stereo)); - AL_METHOD(int, rec_cap_parm, (int rate, int bits, int stereo)); - AL_METHOD(int, rec_source, (int source)); - AL_METHOD(int, rec_start, (int rate, int bits, int stereo)); - AL_METHOD(void, rec_stop, (void)); - AL_METHOD(int, rec_read, (void *buf)); -} DIGI_DRIVER; - -AL_ARRAY(_DRIVER_INFO, _digi_driver_list); - -/* macros for constructing the driver lists */ -#define BEGIN_DIGI_DRIVER_LIST \ - _DRIVER_INFO _digi_driver_list[] = \ - { - -#define END_DIGI_DRIVER_LIST \ - { 0, NULL, 0 } \ - }; - -AL_VAR(DIGI_DRIVER *, digi_driver); - -AL_VAR(DIGI_DRIVER *, digi_input_driver); - -AL_VAR(int, digi_card); - -AL_VAR(int, digi_input_card); - -AL_FUNC(int, detect_digi_driver, (int driver_id)); - - -AL_FUNC(SAMPLE *, load_sample, (AL_CONST char *filename)); -AL_FUNC(SAMPLE *, load_wav, (AL_CONST char *filename)); -AL_FUNC(SAMPLE *, load_wav_pf, (struct PACKFILE *f)); -AL_FUNC(SAMPLE *, load_voc, (AL_CONST char *filename)); -AL_FUNC(SAMPLE *, load_voc_pf, (struct PACKFILE *f)); -AL_FUNC(int, save_sample, (AL_CONST char *filename, SAMPLE *spl)); -AL_FUNC(SAMPLE *, create_sample, (int bits, int stereo, int freq, int len)); -AL_FUNC(void, destroy_sample, (SAMPLE *spl)); - -AL_FUNC(int, play_sample, (AL_CONST SAMPLE *spl, int vol, int pan, int freq, int loop)); -AL_FUNC(void, stop_sample, (AL_CONST SAMPLE *spl)); -AL_FUNC(void, adjust_sample, (AL_CONST SAMPLE *spl, int vol, int pan, int freq, int loop)); - -AL_FUNC(int, allocate_voice, (AL_CONST SAMPLE *spl)); -AL_FUNC(void, deallocate_voice, (int voice)); -AL_FUNC(void, reallocate_voice, (int voice, AL_CONST SAMPLE *spl)); -AL_FUNC(void, release_voice, (int voice)); -AL_FUNC(void, voice_start, (int voice)); -AL_FUNC(void, voice_stop, (int voice)); -AL_FUNC(void, voice_set_priority, (int voice, int priority)); -AL_FUNC(SAMPLE *, voice_check, (int voice)); - -#define PLAYMODE_PLAY 0 -#define PLAYMODE_LOOP 1 -#define PLAYMODE_FORWARD 0 -#define PLAYMODE_BACKWARD 2 -#define PLAYMODE_BIDIR 4 - -AL_FUNC(void, voice_set_playmode, (int voice, int playmode)); - -AL_FUNC(int, voice_get_position, (int voice)); -AL_FUNC(void, voice_set_position, (int voice, int position)); - -AL_FUNC(int, voice_get_volume, (int voice)); -AL_FUNC(void, voice_set_volume, (int voice, int volume)); -AL_FUNC(void, voice_ramp_volume, (int voice, int tyme, int endvol)); -AL_FUNC(void, voice_stop_volumeramp, (int voice)); - -AL_FUNC(int, voice_get_frequency, (int voice)); -AL_FUNC(void, voice_set_frequency, (int voice, int frequency)); -AL_FUNC(void, voice_sweep_frequency, (int voice, int tyme, int endfreq)); -AL_FUNC(void, voice_stop_frequency_sweep, (int voice)); - -AL_FUNC(int, voice_get_pan, (int voice)); -AL_FUNC(void, voice_set_pan, (int voice, int pan)); -AL_FUNC(void, voice_sweep_pan, (int voice, int tyme, int endpan)); -AL_FUNC(void, voice_stop_pan_sweep, (int voice)); - -AL_FUNC(void, voice_set_echo, (int voice, int strength, int delay)); -AL_FUNC(void, voice_set_tremolo, (int voice, int rate, int depth)); -AL_FUNC(void, voice_set_vibrato, (int voice, int rate, int depth)); - -#define SOUND_INPUT_MIC 1 -#define SOUND_INPUT_LINE 2 -#define SOUND_INPUT_CD 3 - -AL_FUNC(int, get_sound_input_cap_bits, (void)); -AL_FUNC(int, get_sound_input_cap_stereo, (void)); -AL_FUNC(int, get_sound_input_cap_rate, (int bits, int stereo)); -AL_FUNC(int, get_sound_input_cap_parm, (int rate, int bits, int stereo)); -AL_FUNC(int, set_sound_input_source, (int source)); -AL_FUNC(int, start_sound_input, (int rate, int bits, int stereo)); -AL_FUNC(void, stop_sound_input, (void)); -AL_FUNC(int, read_sound_input, (void *buffer)); - -AL_FUNCPTR(void, digi_recorder, (void)); - -AL_FUNC(void, lock_sample, (struct SAMPLE *spl)); - -AL_FUNC(void, register_sample_file_type, (AL_CONST char *ext, AL_METHOD(struct SAMPLE *, load, (AL_CONST char *filename)), AL_METHOD(int, save, (AL_CONST char *filename, struct SAMPLE *spl)))); - -#ifdef __cplusplus - } -#endif - -#endif /* ifndef ALLEGRO_DIGI_H */ - - diff --git a/src/allegro/include/allegro/internal/aintern.h b/src/allegro/include/allegro/internal/aintern.h index c65ef3265..c8aecd7c3 100644 --- a/src/allegro/include/allegro/internal/aintern.h +++ b/src/allegro/include/allegro/internal/aintern.h @@ -1005,96 +1005,6 @@ AL_FUNC(void, _poly_zbuf_ptex_mask_trans32, (uintptr_t addr, int w, POLYGON_SEGM #endif -/* sound lib stuff */ -AL_VAR(MIDI_DRIVER, _midi_none); -AL_VAR(int, _digi_volume); -AL_VAR(int, _midi_volume); -AL_VAR(int, _sound_flip_pan); -AL_VAR(int, _sound_hq); -AL_VAR(int, _sound_stereo); -AL_VAR(int, _sound_bits); -AL_VAR(int, _sound_freq); -AL_VAR(int, _sound_port); -AL_VAR(int, _sound_dma); -AL_VAR(int, _sound_irq); - -AL_VAR(int, _sound_installed); -AL_VAR(int, _sound_input_installed); - -AL_FUNC(int, _midi_allocate_voice, (int min, int max)); - -AL_VAR(volatile long, _midi_tick); - -AL_FUNC(int, _digmid_find_patches, (char *dir, int dir_size, char *file, int size_of_file)); - -#define VIRTUAL_VOICES 256 - - -typedef struct /* a virtual (as seen by the user) soundcard voice */ -{ - AL_CONST SAMPLE *sample; /* which sample are we playing? (NULL = free) */ - int num; /* physical voice number (-1 = been killed off) */ - int autokill; /* set to free the voice when the sample finishes */ - long time; /* when we were started (for voice allocation) */ - int priority; /* how important are we? */ -} VOICE; - - -typedef struct /* a physical (as used by hardware) soundcard voice */ -{ - int num; /* the virtual voice currently using me (-1 = free) */ - int playmode; /* are we looping? */ - int vol; /* current volume (fixed point .12) */ - int dvol; /* volume delta, for ramping */ - int target_vol; /* target volume, for ramping */ - int pan; /* current pan (fixed point .12) */ - int dpan; /* pan delta, for sweeps */ - int target_pan; /* target pan, for sweeps */ - int freq; /* current frequency (fixed point .12) */ - int dfreq; /* frequency delta, for sweeps */ - int target_freq; /* target frequency, for sweeps */ -} PHYS_VOICE; - -AL_ARRAY(PHYS_VOICE, _phys_voice); - - -#define MIXER_DEF_SFX 8 -#define MIXER_MAX_SFX 64 - -AL_FUNC(int, _mixer_init, (int bufsize, int freq, int stereo, int is16bit, int *voices)); -AL_FUNC(void, _mixer_exit, (void)); -AL_FUNC(void, _mix_some_samples, (uintptr_t buf, unsigned short seg, int issigned)); -AL_FUNC(void, _mixer_init_voice, (int voice, AL_CONST SAMPLE *sample)); -AL_FUNC(void, _mixer_release_voice, (int voice)); -AL_FUNC(void, _mixer_start_voice, (int voice)); -AL_FUNC(void, _mixer_stop_voice, (int voice)); -AL_FUNC(void, _mixer_loop_voice, (int voice, int loopmode)); -AL_FUNC(int, _mixer_get_position, (int voice)); -AL_FUNC(void, _mixer_set_position, (int voice, int position)); -AL_FUNC(int, _mixer_get_volume, (int voice)); -AL_FUNC(void, _mixer_set_volume, (int voice, int volume)); -AL_FUNC(void, _mixer_ramp_volume, (int voice, int tyme, int endvol)); -AL_FUNC(void, _mixer_stop_volume_ramp, (int voice)); -AL_FUNC(int, _mixer_get_frequency, (int voice)); -AL_FUNC(void, _mixer_set_frequency, (int voice, int frequency)); -AL_FUNC(void, _mixer_sweep_frequency, (int voice, int tyme, int endfreq)); -AL_FUNC(void, _mixer_stop_frequency_sweep, (int voice)); -AL_FUNC(int, _mixer_get_pan, (int voice)); -AL_FUNC(void, _mixer_set_pan, (int voice, int pan)); -AL_FUNC(void, _mixer_sweep_pan, (int voice, int tyme, int endpan)); -AL_FUNC(void, _mixer_stop_pan_sweep, (int voice)); -AL_FUNC(void, _mixer_set_echo, (int voice, int strength, int delay)); -AL_FUNC(void, _mixer_set_tremolo, (int voice, int rate, int depth)); -AL_FUNC(void, _mixer_set_vibrato, (int voice, int rate, int depth)); - -AL_FUNC(void, _dummy_noop1, (int p)); -AL_FUNC(void, _dummy_noop2, (int p1, int p2)); -AL_FUNC(void, _dummy_noop3, (int p1, int p2, int p3)); -AL_FUNC(int, _dummy_load_patches, (AL_CONST char *patches, AL_CONST char *drums)); -AL_FUNC(void, _dummy_adjust_patches, (AL_CONST char *patches, AL_CONST char *drums)); -AL_FUNC(void, _dummy_key_on, (int inst, int note, int bend, int vol, int pan)); - - /* datafile ID's for compatibility with the old datafile format */ #define V1_DAT_MAGIC 0x616C6C2EL @@ -1110,8 +1020,6 @@ AL_FUNC(void, _dummy_key_on, (int inst, int note, int bend, int vol, int pan)); #define V1_DAT_FONT_PROP 9 #define V1_DAT_BITMAP 10 #define V1_DAT_PALETTE 11 -#define V1_DAT_SAMPLE 12 -#define V1_DAT_MIDI 13 #define V1_DAT_RLE_SPRITE 14 #define V1_DAT_FLI 15 #define V1_DAT_C_SPRITE 16 @@ -1146,22 +1054,11 @@ AL_FUNC(void, _construct_datafile, (DATAFILE *data)); /* for readbmp.c */ AL_FUNC(void, _register_bitmap_file_type_init, (void)); -/* for readsmp.c */ -AL_FUNC(void, _register_sample_file_type_init, (void)); - /* for readfont.c */ AL_FUNC(void, _register_font_file_type_init, (void)); /* for module linking system; see comment in allegro.c */ -struct _AL_LINKER_MIDI -{ - AL_METHOD(int, init, (void)); - AL_METHOD(void, exit, (void)); -}; - -AL_VAR(struct _AL_LINKER_MIDI *, _al_linker_midi); - struct _AL_LINKER_MOUSE { AL_METHOD(void, set_mouse_etc, (void)); diff --git a/src/allegro/include/allegro/midi.h b/src/allegro/include/allegro/midi.h deleted file mode 100644 index 26c7a81c0..000000000 --- a/src/allegro/include/allegro/midi.h +++ /dev/null @@ -1,144 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * MIDI music routines. - * - * By Shawn Hargreaves. - * - * See readme.txt for copyright information. - */ - - -#ifndef ALLEGRO_MIDI_H -#define ALLEGRO_MIDI_H - -#include "base.h" - -#ifdef __cplusplus - extern "C" { -#endif - /* Theoretical maximums: */ -#define MIDI_VOICES 64 /* actual drivers may not be */ -#define MIDI_TRACKS 32 /* able to handle this many */ - - - -typedef struct MIDI /* a midi file */ -{ - int divisions; /* number of ticks per quarter note */ - struct { - unsigned char *data; /* MIDI message stream */ - int len; /* length of the track data */ - } track[MIDI_TRACKS]; -} MIDI; - - - -#define MIDI_AUTODETECT -1 -#define MIDI_NONE 0 -#define MIDI_DIGMID AL_ID('D','I','G','I') - -typedef struct MIDI_DRIVER /* driver for playing midi music */ -{ - int id; /* driver ID code */ - AL_CONST char *name; /* driver name */ - AL_CONST char *desc; /* description string */ - AL_CONST char *ascii_name; /* ASCII format name string */ - int voices; /* available voices */ - int basevoice; /* voice number offset */ - int max_voices; /* maximum voices we can support */ - int def_voices; /* default number of voices to use */ - int xmin, xmax; /* reserved voice range */ - - /* setup routines */ - AL_METHOD(int, detect, (int input)); - AL_METHOD(int, init, (int input, int voices)); - AL_METHOD(void, exit, (int input)); - AL_METHOD(int, set_mixer_volume, (int volume)); - AL_METHOD(int, get_mixer_volume, (void)); - - /* raw MIDI output to MPU-401, etc. */ - AL_METHOD(void, raw_midi, (int data)); - - /* dynamic patch loading routines */ - AL_METHOD(int, load_patches, (AL_CONST char *patches, AL_CONST char *drums)); - AL_METHOD(void, adjust_patches, (AL_CONST char *patches, AL_CONST char *drums)); - - /* note control functions */ - AL_METHOD(void, key_on, (int inst, int note, int bend, int vol, int pan)); - AL_METHOD(void, key_off, (int voice)); - AL_METHOD(void, set_volume, (int voice, int vol)); - AL_METHOD(void, set_pitch, (int voice, int note, int bend)); - AL_METHOD(void, set_pan, (int voice, int pan)); - AL_METHOD(void, set_vibrato, (int voice, int amount)); -} MIDI_DRIVER; - - -AL_VAR(MIDI_DRIVER, midi_digmid); - -AL_ARRAY(_DRIVER_INFO, _midi_driver_list); - - -/* macros for constructing the driver lists */ -#define BEGIN_MIDI_DRIVER_LIST \ - _DRIVER_INFO _midi_driver_list[] = \ - { - -#define END_MIDI_DRIVER_LIST \ - { 0, NULL, 0 } \ - }; - -#define MIDI_DRIVER_DIGMID \ - { MIDI_DIGMID, &midi_digmid, TRUE }, - - -AL_VAR(MIDI_DRIVER *, midi_driver); - -AL_VAR(MIDI_DRIVER *, midi_input_driver); - -AL_VAR(int, midi_card); - -AL_VAR(int, midi_input_card); - -AL_VAR(volatile long, midi_pos); /* current position in the midi file, in beats */ -AL_VAR(volatile long, midi_time); /* current position in the midi file, in seconds */ - -AL_VAR(long, midi_loop_start); /* where to loop back to at EOF */ -AL_VAR(long, midi_loop_end); /* loop when we hit this position */ - -AL_FUNC(int, detect_midi_driver, (int driver_id)); - -AL_FUNC(MIDI *, load_midi, (AL_CONST char *filename)); -AL_FUNC(void, destroy_midi, (MIDI *midi)); -AL_FUNC(int, play_midi, (MIDI *midi, int loop)); -AL_FUNC(int, play_looped_midi, (MIDI *midi, int loop_start, int loop_end)); -AL_FUNC(void, stop_midi, (void)); -AL_FUNC(void, midi_pause, (void)); -AL_FUNC(void, midi_resume, (void)); -AL_FUNC(int, midi_seek, (int target)); -AL_FUNC(int, get_midi_length, (MIDI *midi)); -AL_FUNC(void, midi_out, (unsigned char *data, int length)); -AL_FUNC(int, load_midi_patches, (void)); - -AL_FUNCPTR(void, midi_msg_callback, (int msg, int byte1, int byte2)); -AL_FUNCPTR(void, midi_meta_callback, (int type, AL_CONST unsigned char *data, int length)); -AL_FUNCPTR(void, midi_sysex_callback, (AL_CONST unsigned char *data, int length)); - -AL_FUNCPTR(void, midi_recorder, (unsigned char data)); - -AL_FUNC(void, lock_midi, (struct MIDI *midi)); - -#ifdef __cplusplus - } -#endif - -#endif /* ifndef ALLEGRO_MIDI_H */ - - diff --git a/src/allegro/include/allegro/platform/aintunix.h b/src/allegro/include/allegro/platform/aintunix.h index cb2585a0f..55a2866d4 100644 --- a/src/allegro/include/allegro/platform/aintunix.h +++ b/src/allegro/include/allegro/platform/aintunix.h @@ -66,13 +66,9 @@ extern "C" { /* Dynamic driver lists, for modules */ AL_VAR(_DRIVER_INFO *, _unix_gfx_driver_list); - AL_VAR(_DRIVER_INFO *, _unix_digi_driver_list); - AL_VAR(_DRIVER_INFO *, _unix_midi_driver_list); AL_FUNC(void, _unix_driver_lists_init, (void)); AL_FUNC(void, _unix_driver_lists_shutdown, (void)); AL_FUNC(void, _unix_register_gfx_driver, (int id, GFX_DRIVER *driver, int autodetect, int priority)); - AL_FUNC(void, _unix_register_digi_driver, (int id, DIGI_DRIVER *driver, int autodetect, int priority)); - AL_FUNC(void, _unix_register_midi_driver, (int id, MIDI_DRIVER *driver, int autodetect, int priority)); /* Get size of a memory page in bytes */ AL_FUNC(size_t, _unix_get_page_size, (void)); @@ -136,12 +132,6 @@ extern "C" { #endif -#ifdef ALLEGRO_WITH_OSSDIGI - /* So the setup program can read what we detected */ - AL_VAR(int, _oss_fragsize); - AL_VAR(int, _oss_numfrags); -#endif - #ifdef __cplusplus } diff --git a/src/allegro/include/allegro/platform/aintwin.h b/src/allegro/include/allegro/platform/aintwin.h index 39623d41b..ccdb064c5 100644 --- a/src/allegro/include/allegro/platform/aintwin.h +++ b/src/allegro/include/allegro/platform/aintwin.h @@ -146,32 +146,6 @@ AL_FUNC(void, sys_directx_lock_mutex, (void *handle)); AL_FUNC(void, sys_directx_unlock_mutex, (void *handle)); -/* sound routines */ -AL_FUNC(_DRIVER_INFO *, _get_win_digi_driver_list, (void)); -AL_FUNC(void, _free_win_digi_driver_list, (void)); - -AL_FUNC(DIGI_DRIVER *, _get_dsalmix_driver, (char *name, LPGUID guid, int num)); -AL_FUNC(void, _free_win_dsalmix_name_list, (void)); -AL_FUNC(DIGI_DRIVER *, _get_woalmix_driver, (int num)); - -AL_FUNC(int, digi_directsound_capture_init, (LPGUID guid)); -AL_FUNC(void, digi_directsound_capture_exit, (void)); -AL_FUNC(int, digi_directsound_capture_detect, (LPGUID guid)); -AL_FUNC(int, digi_directsound_rec_cap_rate, (int bits, int stereo)); -AL_FUNC(int, digi_directsound_rec_cap_param, (int rate, int bits, int stereo)); -AL_FUNC(int, digi_directsound_rec_source, (int source)); -AL_FUNC(int, digi_directsound_rec_start, (int rate, int bits, int stereo)); -AL_FUNC(void, digi_directsound_rec_stop, (void)); -AL_FUNC(int, digi_directsound_rec_read, (void *buf)); - - -/* midi routines */ -AL_FUNC(_DRIVER_INFO *, _get_win_midi_driver_list, (void)); -AL_FUNC(void, _free_win_midi_driver_list, (void)); - -AL_FUNC(void, midi_switch_out, (void)); - - /* file routines */ AL_VAR(int, _al_win_unicode_filenames); diff --git a/src/allegro/include/allegro/platform/alosx.h b/src/allegro/include/allegro/platform/alosx.h index 5b8a3fea9..4cc3164ca 100644 --- a/src/allegro/include/allegro/platform/alosx.h +++ b/src/allegro/include/allegro/platform/alosx.h @@ -95,17 +95,5 @@ AL_VAR(MOUSE_DRIVER, mouse_macosx); AL_VAR(GFX_DRIVER, gfx_quartz_window); AL_VAR(GFX_DRIVER, gfx_quartz_full); -/* Digital sound drivers */ -#define DIGI_CORE_AUDIO AL_ID('D','C','A',' ') -#define DIGI_SOUND_MANAGER AL_ID('S','N','D','M') -AL_VAR(DIGI_DRIVER, digi_core_audio); -AL_VAR(DIGI_DRIVER, digi_sound_manager); - -/* MIDI music drivers */ -#define MIDI_CORE_AUDIO AL_ID('M','C','A',' ') -#define MIDI_QUICKTIME AL_ID('Q','T','M',' ') -AL_VAR(MIDI_DRIVER, midi_core_audio); -AL_VAR(MIDI_DRIVER, midi_quicktime); - #endif diff --git a/src/allegro/include/allegro/platform/alunix.h b/src/allegro/include/allegro/platform/alunix.h index 19707a8a2..9fd04398d 100644 --- a/src/allegro/include/allegro/platform/alunix.h +++ b/src/allegro/include/allegro/platform/alunix.h @@ -57,76 +57,6 @@ AL_VAR(TIMER_DRIVER, timerdrv_unix_sigalrm); -/************************************/ -/*********** Sound drivers **********/ -/************************************/ - -#define DIGI_OSS AL_ID('O','S','S','D') -#define MIDI_OSS AL_ID('O','S','S','M') -#define DIGI_ESD AL_ID('E','S','D','D') -#define DIGI_ARTS AL_ID('A','R','T','S') -#define DIGI_SGIAL AL_ID('S','G','I','A') -#define DIGI_ALSA AL_ID('A','L','S','A') -#define MIDI_ALSA AL_ID('A','M','I','D') -#define DIGI_JACK AL_ID('J','A','C','K') - - -#ifdef ALLEGRO_WITH_OSSDIGI -AL_VAR(DIGI_DRIVER, digi_oss); -#define DIGI_DRIVER_OSS \ - { DIGI_OSS, &digi_oss, TRUE }, -#endif /* ALLEGRO_WITH_OSSDIGI */ - -#ifdef ALLEGRO_WITH_OSSMIDI -AL_VAR(MIDI_DRIVER, midi_oss); -#define MIDI_DRIVER_OSS \ - { MIDI_OSS, &midi_oss, TRUE }, -#endif /* ALLEGRO_WITH_OSSMIDI */ - -#ifndef ALLEGRO_WITH_MODULES - -#ifdef ALLEGRO_WITH_ESDDIGI -AL_VAR(DIGI_DRIVER, digi_esd); -#define DIGI_DRIVER_ESD \ - { DIGI_ESD, &digi_esd, TRUE }, -#endif /* ALLEGRO_WITH_ESDDIGI */ - -#ifdef ALLEGRO_WITH_ARTSDIGI -AL_VAR(DIGI_DRIVER, digi_arts); -#define DIGI_DRIVER_ARTS \ - { DIGI_ARTS, &digi_arts, TRUE }, -#endif /* ALLEGRO_WITH_ARTSDIGI */ - -#ifdef ALLEGRO_WITH_SGIALDIGI -AL_VAR(DIGI_DRIVER, digi_sgial); -#define DIGI_DRIVER_SGIAL \ - { DIGI_SGIAL, &digi_sgial, TRUE }, -#endif /* ALLEGRO_WITH_SGIALDIGI */ - -#ifdef ALLEGRO_WITH_ALSADIGI -AL_VAR(DIGI_DRIVER, digi_alsa); -#define DIGI_DRIVER_ALSA \ - { DIGI_ALSA, &digi_alsa, TRUE }, -#endif /* ALLEGRO_WITH_ALSADIGI */ - - -#ifdef ALLEGRO_WITH_ALSAMIDI -AL_VAR(MIDI_DRIVER, midi_alsa); -#define MIDI_DRIVER_ALSA \ - { MIDI_ALSA, &midi_alsa, TRUE }, -#endif /* ALLEGRO_WITH_ALSAMIDI */ - - -#ifdef ALLEGRO_WITH_JACKDIGI -AL_VAR(DIGI_DRIVER, digi_jack); -#define DIGI_DRIVER_JACK \ - { DIGI_JACK, &digi_jack, TRUE }, -#endif /* ALLEGRO_WITH_JACKDIGI */ - -#endif - - - /************************************/ /************ X-specific ************/ /************************************/ diff --git a/src/allegro/include/allegro/platform/alwin.h b/src/allegro/include/allegro/platform/alwin.h index 34310876f..7344c2a19 100644 --- a/src/allegro/include/allegro/platform/alwin.h +++ b/src/allegro/include/allegro/platform/alwin.h @@ -116,17 +116,3 @@ AL_VAR(GFX_DRIVER, gfx_gdi); { GFX_DIRECTX_WIN, &gfx_directx_win, TRUE }, \ { GFX_DIRECTX_OVL, &gfx_directx_ovl, TRUE }, \ { GFX_GDI, &gfx_gdi, FALSE }, - - - -/********************************************/ -/*************** sound drivers **************/ -/********************************************/ -#define DIGI_DIRECTX(n) AL_ID('D','X','A'+(n),' ') -#define DIGI_DIRECTAMX(n) AL_ID('A','X','A'+(n),' ') -#define DIGI_WAVOUTID(n) AL_ID('W','O','A'+(n),' ') -#define MIDI_WIN32MAPPER AL_ID('W','3','2','M') -#define MIDI_WIN32(n) AL_ID('W','3','2','A'+(n)) -#define MIDI_WIN32_IN(n) AL_ID('W','3','2','A'+(n)) - - diff --git a/src/allegro/include/allegro/sound.h b/src/allegro/include/allegro/sound.h deleted file mode 100644 index c7bb50c83..000000000 --- a/src/allegro/include/allegro/sound.h +++ /dev/null @@ -1,60 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * Sound support routines. - * - * By Shawn Hargreaves. - * - * See readme.txt for copyright information. - */ - - -#ifndef ALLEGRO_SOUND_H -#define ALLEGRO_SOUND_H - -#include "base.h" -#include "digi.h" -#include "stream.h" -#include "midi.h" - -#ifdef __cplusplus - extern "C" { -#endif - -AL_FUNC(void, reserve_voices, (int digi_voices, int midi_voices)); -AL_FUNC(void, set_volume_per_voice, (int scale)); - -AL_FUNC(int, install_sound, (int digi, int midi, AL_CONST char *cfg_path)); -AL_FUNC(void, remove_sound, (void)); - -AL_FUNC(int, install_sound_input, (int digi, int midi)); -AL_FUNC(void, remove_sound_input, (void)); - -AL_FUNC(void, set_volume, (int digi_volume, int midi_volume)); -AL_FUNC(void, set_hardware_volume, (int digi_volume, int midi_volume)); - -AL_FUNC(void, get_volume, (int *digi_volume, int *midi_volume)); -AL_FUNC(void, get_hardware_volume, (int *digi_volume, int *midi_volume)); - -AL_FUNC(void, set_mixer_quality, (int quality)); -AL_FUNC(int, get_mixer_quality, (void)); -AL_FUNC(int, get_mixer_frequency, (void)); -AL_FUNC(int, get_mixer_bits, (void)); -AL_FUNC(int, get_mixer_channels, (void)); -AL_FUNC(int, get_mixer_voices, (void)); -AL_FUNC(int, get_mixer_buffer_length, (void)); - -#ifdef __cplusplus - } -#endif - -#endif /* ifndef ALLEGRO_SOUND_H */ - - diff --git a/src/allegro/include/allegro/stream.h b/src/allegro/include/allegro/stream.h deleted file mode 100644 index 54d3ac246..000000000 --- a/src/allegro/include/allegro/stream.h +++ /dev/null @@ -1,52 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * Streaming sound routines. - * - * By Shawn Hargreaves. - * - * See readme.txt for copyright information. - */ - - -#ifndef ALLEGRO_STREAM_H -#define ALLEGRO_STREAM_H - -#include "base.h" - -#ifdef __cplusplus - extern "C" { -#endif - -struct SAMPLE; - -typedef struct AUDIOSTREAM -{ - int voice; /* the voice we are playing on */ - struct SAMPLE *samp; /* the sample we are using */ - int len; /* buffer length */ - int bufcount; /* number of buffers per sample half */ - int bufnum; /* current refill buffer */ - int active; /* which half is currently playing */ - void *locked; /* the locked buffer */ -} AUDIOSTREAM; - -AL_FUNC(AUDIOSTREAM *, play_audio_stream, (int len, int bits, int stereo, int freq, int vol, int pan)); -AL_FUNC(void, stop_audio_stream, (AUDIOSTREAM *stream)); -AL_FUNC(void *, get_audio_stream_buffer, (AUDIOSTREAM *stream)); -AL_FUNC(void, free_audio_stream_buffer, (AUDIOSTREAM *stream)); - -#ifdef __cplusplus - } -#endif - -#endif /* ifndef ALLEGRO_STREAM_H */ - - diff --git a/src/allegro/include/allegro/system.h b/src/allegro/include/allegro/system.h index ba1239463..3d3bb7f4a 100644 --- a/src/allegro/include/allegro/system.h +++ b/src/allegro/include/allegro/system.h @@ -230,8 +230,6 @@ typedef struct SYSTEM_DRIVER AL_METHOD(void, lock_mutex, (void *handle)); AL_METHOD(void, unlock_mutex, (void *handle)); AL_METHOD(_DRIVER_INFO *, gfx_drivers, (void)); - AL_METHOD(_DRIVER_INFO *, digi_drivers, (void)); - AL_METHOD(_DRIVER_INFO *, midi_drivers, (void)); AL_METHOD(_DRIVER_INFO *, keyboard_drivers, (void)); AL_METHOD(_DRIVER_INFO *, mouse_drivers, (void)); AL_METHOD(_DRIVER_INFO *, timer_drivers, (void)); diff --git a/src/allegro/src/allegro.c b/src/allegro/src/allegro.c index 149c1bfb7..30dd39c97 100644 --- a/src/allegro/src/allegro.c +++ b/src/allegro/src/allegro.c @@ -221,7 +221,6 @@ int (*_al_trace_handler)(AL_CONST char *msg) = NULL; * linked in, then the structure pointers will be null, so we don't need * to bother with that bit of code elsewhere. */ -struct _AL_LINKER_MIDI *_al_linker_midi = NULL; struct _AL_LINKER_MOUSE *_al_linker_mouse = NULL; @@ -308,14 +307,11 @@ static int _install_allegro(int system_id, int *errno_ptr, int (*atexit_ptr)(voi #ifndef ALLEGRO_USE_CONSTRUCTOR /* call constructor functions manually */ extern void _initialize_datafile_types(); - extern void _midi_constructor(); extern void _mouse_constructor(); _initialize_datafile_types(); - _midi_constructor(); _mouse_constructor(); _register_bitmap_file_type_init(); - _register_sample_file_type_init(); _register_font_file_type_init(); #endif @@ -758,7 +754,6 @@ SYSTEM_DRIVER system_none = NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, - sys_no_driver, sys_no_driver, sys_no_driver, - sys_no_driver, sys_no_driver, sys_no_driver + sys_no_driver, sys_no_driver, sys_no_driver, sys_no_driver }; diff --git a/src/allegro/src/datafile.c b/src/allegro/src/datafile.c index 867c65bdc..d0af82411 100644 --- a/src/allegro/src/datafile.c +++ b/src/allegro/src/datafile.c @@ -25,7 +25,6 @@ -static void unload_midi(MIDI *m); static void initialise_datafile(DATAFILE *data); @@ -561,115 +560,6 @@ static RGB *read_palette(PACKFILE *f, int size) -/* read_sample: - * Reads a sample from a file. - */ -static SAMPLE *read_sample(PACKFILE *f) -{ - signed short bits; - SAMPLE *s; - - s = _AL_MALLOC(sizeof(SAMPLE)); - if (!s) { - *allegro_errno = ENOMEM; - return NULL; - } - - bits = pack_mgetw(f); - - if (bits < 0) { - s->bits = -bits; - s->stereo = TRUE; - } - else { - s->bits = bits; - s->stereo = FALSE; - } - - s->freq = pack_mgetw(f); - s->len = pack_mgetl(f); - s->priority = 128; - s->loop_start = 0; - s->loop_end = s->len; - s->param = 0; - - if (s->bits == 8) { - s->data = read_block(f, s->len * ((s->stereo) ? 2 : 1), 0); - } - else { - s->data = _AL_MALLOC_ATOMIC(s->len * sizeof(short) * ((s->stereo) ? 2 : 1)); - if (s->data) { - int i; - - for (i=0; i < (int)s->len * ((s->stereo) ? 2 : 1); i++) { - ((unsigned short *)s->data)[i] = pack_igetw(f); - } - - if (pack_ferror(f)) { - _AL_FREE(s->data); - s->data = NULL; - } - } - } - if (!s->data) { - _AL_FREE(s); - return NULL; - } - - LOCK_DATA(s, sizeof(SAMPLE)); - LOCK_DATA(s->data, s->len * ((s->bits==8) ? 1 : sizeof(short)) * ((s->stereo) ? 2 : 1)); - - return s; -} - - - -/* read_midi: - * Reads MIDI data from a datafile (this is not the same thing as the - * standard midi file format). - */ -static MIDI *read_midi(PACKFILE *f) -{ - MIDI *m; - int c; - - m = _AL_MALLOC(sizeof(MIDI)); - if (!m) { - *allegro_errno = ENOMEM; - return NULL; - } - - for (c=0; ctrack[c].len = 0; - m->track[c].data = NULL; - } - - m->divisions = pack_mgetw(f); - - for (c=0; ctrack[c].len = pack_mgetl(f); - if (m->track[c].len > 0) { - m->track[c].data = read_block(f, m->track[c].len, 0); - if (!m->track[c].data) { - unload_midi(m); - return NULL; - } - } - } - - LOCK_DATA(m, sizeof(MIDI)); - - for (c=0; ctrack[c].data) { - LOCK_DATA(m->track[c].data, m->track[c].len); - } - } - - return m; -} - - - /* read_rle_sprite: * Reads an RLE compressed sprite from a file, allocating memory for it. */ @@ -953,18 +843,6 @@ static DATAFILE *read_old_datafile(PACKFILE *f, void (*callback)(DATAFILE *)) dat[c].size = 0; break; - case V1_DAT_SAMPLE: - dat[c].type = DAT_SAMPLE; - dat[c].dat = read_sample(f); - dat[c].size = 0; - break; - - case V1_DAT_MIDI: - dat[c].type = DAT_MIDI; - dat[c].dat = read_midi(f); - dat[c].size = 0; - break; - case V1_DAT_RLE_SPRITE: dat[c].type = DAT_RLE_SPRITE; dat[c].dat = read_rle_sprite(f, 8); @@ -1040,26 +918,6 @@ static void *load_font_object(PACKFILE *f, long size) -/* load_sample_object: - * Loads a sample object from a datafile. - */ -static void *load_sample_object(PACKFILE *f, long size) -{ - return read_sample(f); -} - - - -/* load_midi_object: - * Loads a midifile object from a datafile. - */ -static void *load_midi_object(PACKFILE *f, long size) -{ - return read_midi(f); -} - - - /* load_bitmap_object: * Loads a bitmap object from a datafile. */ @@ -1108,46 +966,6 @@ static void *load_xcompiled_sprite_object(PACKFILE *f, long size) -/* unload_sample: - * Destroys a sample object. - */ -static void unload_sample(SAMPLE *s) -{ - if (s) { - if (s->data) { - UNLOCK_DATA(s->data, s->len * ((s->bits==8) ? 1 : sizeof(short)) * ((s->stereo) ? 2 : 1)); - _AL_FREE(s->data); - } - - UNLOCK_DATA(s, sizeof(SAMPLE)); - _AL_FREE(s); - } -} - - - -/* unload_midi: - * Destroys a MIDI object. - */ -static void unload_midi(MIDI *m) -{ - int c; - - if (m) { - for (c=0; ctrack[c].data) { - UNLOCK_DATA(m->track[c].data, m->track[c].len); - _AL_FREE(m->track[c].data); - } - } - - UNLOCK_DATA(m, sizeof(MIDI)); - _AL_FREE(m); - } -} - - - /* load_object: * Helper to load an object from a datafile and store it in 'obj'. * Returns 0 on success and -1 on failure. @@ -2148,8 +1966,6 @@ static void initialise_datafile(DATAFILE *data) { int c, c2, color_flag; FONT *f; - SAMPLE *s; - MIDI *m; for (c=0; data[c].type != DAT_END; c++) { @@ -2179,22 +1995,6 @@ static void initialise_datafile(DATAFILE *data) f->vtable = font_vtable_mono; } break; - - case DAT_SAMPLE: - s = data[c].dat; - LOCK_DATA(s, sizeof(SAMPLE)); - LOCK_DATA(s->data, s->len * ((s->bits==8) ? 1 : sizeof(short)) * ((s->stereo) ? 2 : 1)); - break; - - case DAT_MIDI: - m = data[c].dat; - LOCK_DATA(m, sizeof(MIDI)); - for (c2=0; c2track[c2].data) { - LOCK_DATA(m->track[c2].data, m->track[c2].len); - } - } - break; } } } @@ -2225,8 +2025,6 @@ void _initialize_datafile_types(void) { register_datafile_object(DAT_FILE, load_file_object, (void (*)(void *data))unload_datafile ); register_datafile_object(DAT_FONT, load_font_object, (void (*)(void *data))destroy_font ); - register_datafile_object(DAT_SAMPLE, load_sample_object, (void (*)(void *data))unload_sample ); - register_datafile_object(DAT_MIDI, load_midi_object, (void (*)(void *data))unload_midi ); register_datafile_object(DAT_BITMAP, load_bitmap_object, (void (*)(void *data))destroy_bitmap ); register_datafile_object(DAT_RLE_SPRITE, load_rle_sprite_object, (void (*)(void *data))destroy_rle_sprite ); register_datafile_object(DAT_C_SPRITE, load_compiled_sprite_object, (void (*)(void *data))destroy_compiled_sprite); diff --git a/src/allegro/src/digmid.c b/src/allegro/src/digmid.c deleted file mode 100644 index cf2cae32a..000000000 --- a/src/allegro/src/digmid.c +++ /dev/null @@ -1,1049 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * Digitized sample driver for the MIDI player. - * - * By Shawn Hargreaves, based on code by Tom Novelli. - * Chris Robinson added some optimizations and the digmid_set_pan method. - * - * See readme.txt for copyright information. - */ - - -#include -#include -#include - -#include "allegro.h" -#include "allegro/internal/aintern.h" - - -/* external interface to the Digmid driver */ -static int digmid_detect(int input); -static int digmid_init(int input, int voices); -static void digmid_exit(int input); -static int digmid_load_patches(AL_CONST char *patches, AL_CONST char *drums); -static void digmid_key_on(int inst, int note, int bend, int vol, int pan); -static void digmid_key_off(int voice); -static void digmid_set_volume(int voice, int vol); -static void digmid_set_pitch(int voice, int note, int bend); -static void digmid_set_pan(int voice, int pan); - - -MIDI_DRIVER midi_digmid = -{ - MIDI_DIGMID, - empty_string, - empty_string, - "DIGMID", - 0, 0, -1, 24, -1, -1, - digmid_detect, - digmid_init, - digmid_exit, - NULL, - NULL, - NULL, - digmid_load_patches, - _dummy_adjust_patches, - digmid_key_on, - digmid_key_off, - digmid_set_volume, - digmid_set_pitch, - digmid_set_pan, - _dummy_noop2 -}; - - -#define MAX_LAYERS 64 - - -typedef struct PATCH_EXTRA /* additional data for a Gravis PATCH */ -{ - int low_note; - int high_note; - int base_note; - int play_mode; - int decay_time; - int release_time; - int sustain_level; - int scale_freq; - int scale_factor; - int pan; -} PATCH_EXTRA; - - -typedef struct PATCH /* Gravis PATCH structure */ -{ - int samples; /* number of samples in this instrument */ - SAMPLE *sample[MAX_LAYERS]; /* the waveform data */ - PATCH_EXTRA *extra[MAX_LAYERS]; /* additional waveform information */ - int master_vol; /* overall volume level */ -} PATCH; - - -/* our instruments */ -static PATCH *patch[256]; - - -/* frequency table (generated by digmid_init) */ -static long ftbl[130]; - - -/* stored information about active voices */ -typedef struct DIGMID_VOICE -{ - SAMPLE *s; - PATCH_EXTRA *e; - int inst; - int vol; -} DIGMID_VOICE; - - -static DIGMID_VOICE digmid_voice[MIDI_VOICES]; - - - -/* destroy_patch: - * Frees a PATCH struct and all samples it contains. - */ -static void destroy_patch(PATCH *pat) -{ - int i; - - if (pat) { - for (i=0; i < pat->samples; i++) { - destroy_sample(pat->sample[i]); - - UNLOCK_DATA(pat->extra[i], sizeof(PATCH_EXTRA)); - _AL_FREE(pat->extra[i]); - } - - UNLOCK_DATA(pat, sizeof(PATCH)); - _AL_FREE(pat); - } -} - - - -/* scale64: - * Evalulates a*b/c using 64 bit arithmetic. This is used in an interrupt - * context, so we have to do it ourselves rather than relying on compiler - * support or floating point (it is impossible to reliably lock the - * compiler helpers that implement a 64 bit divide, and it isn't safe to - * use the i386 FPU stack in an interrupt context). Multithreaded systems - * are not bound by this restriction however, so we use the FPU there. - */ -#if !(defined ALLEGRO_MULTITHREADED) -static INLINE unsigned long scale64(unsigned long a, unsigned long b, unsigned long c) -{ - unsigned long al = a & 0xFFFF; - unsigned long ah = a >> 16; - unsigned long bl = b & 0xFFFF; - unsigned long bh = b >> 16; - unsigned long rl, rh, r, s, t, o; - - /* 64 bit multiply */ - rl = al*bl; - rh = ah*bh; - - t = al*bh; - o = rl; - rh += (t >> 16); - rl += (t << 16); - if (rl < o) - rh++; - - t = ah*bl; - o = rl; - rh += (t >> 16); - rl += (t << 16); - if (rl < o) - rh++; - - /* 64 bit divide */ - s = 0x80000000; - t = rh; - r = 0; - - while (s) { - o = t; - t -= c; - - if (t > o) - t = o; - else - r |= s; - - t <<= 1; - if (rl & s) - t |= 1; - - s >>= 1; - } - - return r << 1; -} -#else -static INLINE unsigned long scale64(unsigned long a, unsigned long b, unsigned long c) -{ - double scale = b / (double)c; - return (unsigned long)a * scale; -} -#endif - - -/* load_patch: - * Reads a GUS format patch file from disk. - */ -static PATCH *load_patch(PACKFILE *f, int drum) -{ - PATCH *p = NULL; - char buf[256]; - char mode; - int env_rate[6]; - int env_offset[6]; - int i, j; - int diff; - int odd_len; - - pack_fread(buf, 22, f); /* ID tag */ - if (memcmp(buf, "GF1PATCH110\0", 12) || memcmp(buf+12, "ID#000002\0", 10)) { - *allegro_errno = EINVAL; - goto getout; - } - - p = _AL_MALLOC(sizeof(PATCH)); - if (!p) { - *allegro_errno = ENOMEM; - goto getout; - } - - pack_fread(buf, 65, f); /* description */ - p->master_vol = pack_igetw(f); /* volume */ - - pack_fread(buf, 109, f); /* skip */ - - p->samples = pack_getc(f); /* number of samples */ - pack_fread(buf, 40, f); /* skip */ - - if (p->samples > MAX_LAYERS) - p->samples = MAX_LAYERS; - - for (i=0; isamples; i++) { /* for each sample... */ - p->sample[i] = _AL_MALLOC(sizeof(SAMPLE)); - if (!p->sample[i]) { - p->samples = i; - destroy_patch(p); - p = NULL; - *allegro_errno = ENOMEM; - goto getout; - } - - p->extra[i] = _AL_MALLOC_ATOMIC(sizeof(PATCH_EXTRA)); - if (!p->extra[i]) { - _AL_FREE(p->sample[i]); - p->samples = i; - destroy_patch(p); - p = NULL; - *allegro_errno = ENOMEM; - goto getout; - } - - pack_fread(buf, 8, f); /* layer name */ - - p->sample[i]->len = pack_igetl(f); /* sample length */ - p->sample[i]->loop_start = pack_igetl(f); /* loop start */ - p->sample[i]->loop_end = pack_igetl(f); /* loop end */ - p->sample[i]->freq = pack_igetw(f); /* sample frequency */ - - p->extra[i]->low_note = pack_igetl(f); /* key min */ - p->extra[i]->high_note = pack_igetl(f); /* key max */ - p->extra[i]->base_note = pack_igetl(f); /* base key */ - pack_igetw(f); /* skip finetune */ - - p->extra[i]->pan = pack_getc(f) * 255/15; /* pan position */ - - for (j=0; j<6; j++) /* envelope rate */ - env_rate[j] = pack_getc(f); - - for (j=0; j<6; j++) /* envelope value */ - env_offset[j] = pack_getc(f); - - pack_fread(buf, 6, f); /* skip trem and vib */ - - mode = pack_getc(f); /* sample flags */ - - p->sample[i]->bits = (mode & 1) ? 16 : 8; /* how many bits? */ - - p->sample[i]->stereo = FALSE; - - p->extra[i]->play_mode = 0; /* sort out loop flags */ - - if (mode & 4) - p->extra[i]->play_mode |= PLAYMODE_LOOP; - - if (mode & 8) - p->extra[i]->play_mode |= (PLAYMODE_BIDIR | PLAYMODE_LOOP); - - if (mode & 16) - p->extra[i]->play_mode |= (PLAYMODE_BACKWARD | PLAYMODE_LOOP); - - /* convert envelope rates (GUS uses a 2.6 floating point format) */ - for (j=0; j<6; j++) { - static int vexp[4] = { 1, 8, 64, 512 }; - int e = (env_rate[j] >> 6); - int m = (env_rate[j] & 0x3F); - env_rate[j] = ((65536 * vexp[e] / ((m) ? m : 1)) >> 12); - } - - if ((mode & 32) && (!drum)) { - /* sustained volume envelope */ - p->extra[i]->sustain_level = env_offset[2]; - p->extra[i]->decay_time = 0; - - diff = env_offset[0]; - p->extra[i]->decay_time += env_rate[0] * diff / 256; - - diff = ABS(env_offset[1] - env_offset[0]); - p->extra[i]->decay_time += env_rate[1] * diff / 256; - - diff = ABS(env_offset[2] - env_offset[1]); - p->extra[i]->decay_time += env_rate[2] * diff / 256; - - j = 3; - } - else { - /* one-shot volume envelope */ - p->extra[i]->decay_time = 0; - p->extra[i]->sustain_level = 0; - - for (j=0; j<6; j++) { - diff = ABS(env_offset[j] - ((j) ? env_offset[j-1] : 0)); - p->extra[i]->decay_time += env_rate[j] * diff / 256; - if (env_offset[j] < 16) { - j++; - break; - } - } - } - - /* measure release time */ - p->extra[i]->release_time = 0; - - while (j < 6) { - diff = ABS(env_offset[j] - env_offset[j-1]); - p->extra[i]->release_time += env_rate[j] * diff / 256; - if (env_offset[j] < 16) - break; - j++; - } - - /* clamp very large/small sustain levels to zero or maximum */ - if (p->extra[i]->sustain_level < 16) - p->extra[i]->sustain_level = 0; - else if (p->extra[i]->sustain_level > 192) - p->extra[i]->sustain_level = 255; - - if (p->extra[i]->release_time < 10) - p->extra[i]->release_time = 0; - - if ((p->extra[i]->sustain_level == 0) && - (p->extra[i]->decay_time == 0)) { - p->extra[i]->sustain_level = 255; - p->extra[i]->play_mode &= ~PLAYMODE_LOOP; - } - - p->extra[i]->scale_freq = pack_igetw(f); /* scale values */ - p->extra[i]->scale_factor = pack_igetw(f); - - /* drums use a fixed frequency */ - if(drum) { - unsigned long freq = scale64(ftbl[drum-1], p->sample[i]->freq, p->extra[i]->base_note); - - /* frequency scaling */ - if (p->extra[i]->scale_factor != 1024) { - unsigned long f1 = scale64(p->sample[i]->freq, p->extra[i]->scale_freq, 60); - freq -= f1; - freq = scale64(freq, p->extra[i]->scale_factor, 1024); - freq += f1; - } - - /* lower by an octave if we are going to overflow */ - while (freq >= (1<<19)-1) - freq /= 2; - - p->sample[i]->freq = freq; - } - - pack_fread(buf, 36, f); /* skip reserved */ - - if (p->sample[i]->bits == 16) { /* adjust 16 bit loops */ - odd_len = (p->sample[i]->len & 1); - p->sample[i]->len /= 2; - p->sample[i]->loop_start /= 2; - p->sample[i]->loop_end /= 2; - } - else - odd_len = FALSE; - - p->sample[i]->priority = 128; /* set some defaults */ - p->sample[i]->param = 0; - - p->sample[i]->data = _AL_MALLOC_ATOMIC(p->sample[i]->len*((p->sample[i]->bits==8) ? 1 : sizeof(short))); - if (!p->sample[i]->data) { - _AL_FREE(p->sample[i]); - _AL_FREE(p->extra[i]); - p->samples = i; - destroy_patch(p); - p = NULL; - *allegro_errno = ENOMEM; - goto getout; - } - - if (p->sample[i]->bits == 8) { - /* read 8 bit sample data */ - pack_fread(p->sample[i]->data, p->sample[i]->len, f); - if (!(mode & 2)) { - /* signed data - convert to unsigned */ - for (j=0; j<(int)p->sample[i]->len; j++) - ((unsigned char *)p->sample[i]->data)[j] ^= 0x80; - } - } - else { - /* read 16 bit sample data */ - for (j=0; j<(int)p->sample[i]->len; j++) { - ((unsigned short *)p->sample[i]->data)[j] = pack_igetw(f); - } - if (!(mode & 2)) { - /* signed data - convert to unsigned */ - for (j=0; j<(int)p->sample[i]->len; j++) - ((unsigned short *)p->sample[i]->data)[j] ^= 0x8000; - } - if (odd_len) - pack_getc(f); - } - } - - getout: - - /* lock the data into physical memory */ - if (p) { - LOCK_DATA(p, sizeof(PATCH)); - - for (i=0; isamples; i++) { - lock_sample(p->sample[i]); - LOCK_DATA(p->extra[i], sizeof(PATCH_EXTRA)); - } - } - - return p; -} - - - -/* _digmid_find_patches: - * Tries to locate the GUS patch set directory and index file (default.cfg). - */ -int _digmid_find_patches(char *dir, int dir_size, char *file, int file_size) -{ - char filename[1024], tmp1[64], tmp2[64], tmp3[64], tmp4[64]; - AL_CONST char *name; - char *datafile, *objectname, *envvar, *subdir, *s; - - name = get_config_string(uconvert_ascii("sound", tmp1), uconvert_ascii("patches", tmp2), NULL); - datafile = uconvert_ascii("patches.dat", tmp1); - objectname = uconvert_ascii("default.cfg", tmp2); - envvar = uconvert_ascii("ULTRADIR", tmp3); - subdir = uconvert_ascii("midi", tmp4); - - if (find_allegro_resource(filename, name, NULL, datafile, objectname, envvar, subdir, sizeof(filename)) != 0) - return FALSE; - - if (dir && file) { - s = ustrrchr(filename, '#'); - if(s == NULL) - s = get_filename(filename); - else - s += ustrlen("#"); - ustrzcpy(file, file_size, s); - - usetc(s, 0); - ustrzcpy(dir, dir_size, filename); - } - - return TRUE; -} - - - -/* parse_string: - * Splits a string into component parts, storing them in the argv pointers. - * Returns the number of components. - */ -static int parse_string(char *buf, char *argv[]) -{ - int c = 0; - - while (ugetc(buf) && (c<16)) { - while ((ugetc(buf) == ' ') || (ugetc(buf) == '\t') || (ugetc(buf) == '=')) - buf += uwidth(buf); - - if (ugetc(buf) == '#') - return c; - - if (ugetc(buf)) - argv[c++] = buf; - - while (ugetc(buf) && (ugetc(buf) != ' ') && (ugetc(buf) != '\t') && (ugetc(buf) != '=')) - buf += uwidth(buf); - - if (ugetc(buf)) - buf += usetc(buf, 0); - } - - return c; -} - - - -/* digmid_load_patches: - * Reads the patches that are required by a particular song. - */ -static int digmid_load_patches(AL_CONST char *patches, AL_CONST char *drums) -{ - PACKFILE *f; - char dir[1024], file[1024], buf[1024], filename[1024]; - char todo[256][1024]; - char *argv[16], *p; - char tmp[128]; - int argc; - int patchnum, flag_num; - int drum_mode = FALSE; - int override_mode = FALSE; - int drum_start = 0; - int type, size; - int i, j, c; - - if (!_digmid_find_patches(dir, sizeof(dir), file, sizeof(file))) - return -1; - - for (i=0; i<256; i++) - usetc(todo[i], 0); - - ustrzcpy(buf, sizeof(buf), dir); - ustrzcat(buf, sizeof(buf), file); - - f = pack_fopen(buf, F_READ); - if (!f) - return -1; - - while (pack_fgets(buf, sizeof(buf), f) != 0) { - argc = parse_string(buf, argv); - - if (argc > 0) { - /* is first word all digits? */ - flag_num = TRUE; - p = argv[0]; - while ((c = ugetx(&p)) != 0) { - if ((!uisdigit(c)) && (c != '-')) { - flag_num = FALSE; - break; - } - } - - if ((flag_num) && (argc >= 2)) { - if (ustricmp(argv[1], uconvert_ascii("begin_multipatch", tmp)) == 0) { - /* start the block of percussion instruments */ - drum_start = ustrtol(argv[0], NULL, 10) - 1; - drum_mode = TRUE; - } - else if (ustricmp(argv[1], uconvert_ascii("override_patch", tmp)) == 0) { - /* ignore patch overrides */ - override_mode = TRUE; - } - else if (!override_mode) { - /* must be a patch number */ - patchnum = ustrtol(argv[0], NULL, 10); - - if (!drum_mode) - patchnum--; - - if ((patchnum >= 0) && (patchnum < 128) && - (((drum_mode) && (drums[patchnum])) || - ((!drum_mode) && (patches[patchnum])))) { - - if (drum_mode) - patchnum += drum_start; - - if (!patch[patchnum]) { - /* need to load this sample */ - ustrzcpy(todo[patchnum], sizeof(todo[patchnum]), argv[1]); - } - } - } - } - else { - /* handle other keywords */ - if (ustricmp(argv[0], uconvert_ascii("end_multipatch", tmp)) == 0) { - drum_mode = FALSE; - override_mode = FALSE; - } - } - } - } - - pack_fclose(f); - - if (ustrchr(dir, '#')) { - /* read from a datafile */ - if ((ustrlen(dir) > 1) && (ugetat(dir, -1) == '#')) - usetat(dir, -1, 0); - - f = pack_fopen(dir, F_READ_PACKED); - if (!f) - return -1; - - if (((ugetc(dir) == '#') && (ustrlen(dir) == 1)) || (!ustrchr(dir, '#'))) { - type = pack_mgetl(f); - if (type != DAT_MAGIC) { - pack_fclose(f); - return -1; - } - } - - pack_mgetl(f); - - usetc(filename, 0); - - /* scan through the file */ - while (!pack_feof(f)) { - type = pack_mgetl(f); - - if (type == DAT_PROPERTY) { - type = pack_mgetl(f); - size = pack_mgetl(f); - - if (type == DAT_ID('N','A','M','E')) { - /* store name property */ - pack_fread(buf, size, f); - buf[size] = 0; - do_uconvert(buf, U_ASCII, filename, U_CURRENT, sizeof(filename)); - } - else { - /* skip other properties */ - pack_fseek(f, size); - } - } - else if (type == DAT_PATCH) { - /* do we want this patch? */ - for (i=0; i<256; i++) - if (ugetc(todo[i]) && (ustricmp(filename, todo[i]) == 0)) - break; - - if (i < 256) { - /* load this patch */ - f = pack_fopen_chunk(f, FALSE); - patch[i] = load_patch(f, ((i > 127) ? (i - 127) : 0)); - f = pack_fclose_chunk(f); - - for (j=i+1; j<256; j++) { - /* share multiple copies of the instrument */ - if (ustricmp(todo[i], todo[j]) == 0) { - patch[j] = patch[i]; - usetc(todo[j], 0); - } - } - - usetc(todo[i], 0); - } - else { - /* skip unwanted patch */ - size = pack_mgetl(f); - pack_fseek(f, size+4); - } - } - else { - /* skip unwanted object */ - size = pack_mgetl(f); - pack_fseek(f, size+4); - } - } - } - else { - /* read from regular disk files */ - for (i=0; i<256; i++) { - if (ugetc(todo[i])) { - if (is_relative_filename(todo[i])) { - ustrzcpy(filename, sizeof(filename), dir); - ustrzcat(filename, sizeof(filename), todo[i]); - } else - ustrzcpy(filename, sizeof(filename), todo[i]); - - if (ugetc(get_extension(filename)) == 0) - ustrzcat(filename, sizeof(filename), uconvert_ascii(".pat", tmp)); - - f = pack_fopen(filename, F_READ); - if (f) { - patch[i] = load_patch(f, ((i > 127) ? (i - 127) : 0)); - pack_fclose(f); - } - - for (j=i+1; j<256; j++) { - /* share multiple copies of the instrument */ - if (ustricmp(todo[i], todo[j]) == 0) { - patch[j] = patch[i]; - usetc(todo[j], 0); - } - } - } - } - } - - return 0; -} - - - -/* digmid_freq: - * Helper for converting note numbers to sample frequencies. - */ -static int digmid_freq(int inst, SAMPLE *s, PATCH_EXTRA *e, int note, int bend) -{ - unsigned long freq, f1, f2, sfreq, base_note; - - sfreq = s->freq; - base_note = e->base_note; - - /* calculate frequency */ - if(bend) { - f1 = scale64(ftbl[note], sfreq, base_note); - f2 = scale64(ftbl[note+1], sfreq, base_note); - - /* quick pitch bend method - ~.035% error - acceptable? */ - freq = ((f1*(4096-bend)) + (f2*bend)) / 4096; - } - else - freq = scale64(ftbl[note], sfreq, base_note); - - /* frequency scaling */ - if (e->scale_factor != 1024) { - f1 = scale64(sfreq, e->scale_freq, 60); - freq -= f1; - freq = scale64(freq, e->scale_factor, 1024); - freq += f1; - } - - /* lower by an octave if we are going to overflow */ - while (freq >= (1<<19)-1) - freq /= 2; - - return freq; -} - -END_OF_STATIC_FUNCTION(digmid_freq); - - - -/* digmid_trigger: - * Helper for activating a specific sample layer. - */ -static void digmid_trigger(int inst, int snum, int note, int bend, int vol, int pan) -{ - int freq, voice; - DIGMID_VOICE *info; - PATCH_EXTRA *e; - SAMPLE *s; - - voice = _midi_allocate_voice(-1, -1); - if (voice < 0) - return; - - s = patch[inst]->sample[snum]; - e = patch[inst]->extra[snum]; - - if (inst > 127) { - pan = e->pan; - freq = s->freq; - } - else - freq = digmid_freq(inst, s, e, note, bend); - - /* store note information for later use */ - info = &digmid_voice[voice - midi_digmid.basevoice]; - info->s = s; - info->e = e; - info->inst = inst; - info->vol = vol; - - /* play the note */ - reallocate_voice(voice, s); - voice_set_playmode(voice, e->play_mode); - voice_set_volume(voice, vol); - voice_set_frequency(voice, freq); - voice_set_pan(voice, pan); - - if (e->sustain_level < 255) - voice_ramp_volume(voice, e->decay_time, e->sustain_level*vol/255); - - voice_start(voice); -} - -END_OF_STATIC_FUNCTION(digmid_trigger); - - - -/* digmid_key_on: - * Triggers the specified voice. The instrument is specified as a GM - * patch number, pitch as a midi note number, and volume from 0-127. - * The bend parameter is _not_ expressed as a midi pitch bend value. - * It ranges from 0 (no pitch change) to 0xFFF (almost a semitone sharp). - * Drum sounds are indicated by passing an instrument number greater than - * 128, in which case the sound is GM percussion key #(inst-128). - */ -static void digmid_key_on(int inst, int note, int bend, int vol, int pan) -{ - PATCH_EXTRA *e; - long freq; - int best, best_diff; - int diff; - int i, c; - - /* quit if instrument is not available */ - if ((!patch[inst]) || (patch[inst]->samples < 1)) - return; - - /* adjust volume and pan ranges */ - vol *= 2; - pan *= 2; - - if (patch[inst]->samples == 1) { - /* only one sample to choose from */ - digmid_trigger(inst, 0, note, bend, vol, pan); - } - else { - /* find the sample(s) with best frequency range */ - best = -1; - best_diff = INT_MAX; - c = 0; - - for (i=0; isamples; i++) { - freq = ftbl[note]; - e = patch[inst]->extra[i]; - - if ((freq >= e->low_note) && (freq <= e->high_note)) { - digmid_trigger(inst, i, note, bend, vol, pan); - c++; - if (c > 4) - break; - } - else { - diff = MIN(ABS(freq - e->low_note), ABS(freq - e->high_note)); - if (diff < best_diff) { - best_diff = diff; - best = i; - } - } - } - - if ((c <= 0) && (best >= 0)) - digmid_trigger(inst, best, note, bend, vol, pan); - } -} - -END_OF_STATIC_FUNCTION(digmid_key_on); - - - -/* digmid_key_off: - * Hey, guess what this does :-) - */ -static void digmid_key_off(int voice) -{ - DIGMID_VOICE *info = &digmid_voice[voice - midi_digmid.basevoice]; - - if (info->inst > 127) - return; - - if (info->e->release_time > 0) - voice_ramp_volume(voice, info->e->release_time, 0); - else - voice_stop(voice); -} - -END_OF_STATIC_FUNCTION(digmid_key_off); - - - -/* digmid_set_volume: - * Sets the volume of the specified voice (vol range 0-127). - */ -static void digmid_set_volume(int voice, int vol) -{ - DIGMID_VOICE *info = &digmid_voice[voice - midi_digmid.basevoice]; - int v; - - if (info->inst > 127) - return; - - vol *= 2; - - if (info->e->sustain_level < 255) { - /* adjust for volume ramping */ - int current = voice_get_volume(voice); - int target = info->e->sustain_level*info->vol/255; - int start = info->vol; - - if (ABS(current - target) < 8) { - /* ramp has finished */ - voice_set_volume(voice, vol*info->e->sustain_level/255); - } - else { - /* in the middle of a ramp */ - int mu; - - if (start > target) - mu = CLAMP(0, (current-target) * 256 / (start-target), 256); - else - mu = 0; - - v = mu+info->e->sustain_level*(256-mu)/256; - v = CLAMP(0, vol*v/255, 255); - - voice_set_volume(voice, v); - voice_ramp_volume(voice, info->e->decay_time*mu/256, info->e->sustain_level*vol/255); - } - } - else { - /* no ramp */ - voice_set_volume(voice, vol); - } - - info->vol = vol; -} - -END_OF_STATIC_FUNCTION(digmid_set_volume); - - - -/* digmid_set_pitch: - * Sets the pitch of the specified voice. - */ -static void digmid_set_pitch(int voice, int note, int bend) -{ - DIGMID_VOICE *info = &digmid_voice[voice - midi_digmid.basevoice]; - int freq; - - if (info->inst > 127) - return; - - freq = digmid_freq(info->inst, info->s, info->e, note, bend); - - voice_set_frequency(voice, freq); -} - -END_OF_STATIC_FUNCTION(digmid_set_pitch); - - - -static void digmid_set_pan(int voice, int pan) -{ - DIGMID_VOICE *info = &digmid_voice[voice - midi_digmid.basevoice]; - - if (info->inst > 127) - return; - - pan *= 2; - voice_set_pan(voice, pan); -} - -END_OF_STATIC_FUNCTION(digmid_set_pan); - - - -/* digmid_detect: - * Have we got a sensible looking patch set? - */ -static int digmid_detect(int input) -{ - if (input) - return FALSE; - - if (!_digmid_find_patches(NULL, 0, NULL, 0)) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("DIGMID patch set not found")); - return FALSE; - } - - return TRUE; -} - - - -/* digmid_init: - * Setup the digmid driver. - */ -static int digmid_init(int input, int voices) -{ - float f; - int i; - - midi_digmid.desc = get_config_text("Software wavetable synth"); - - for (i=0; i<256; i++) - patch[i] = NULL; - - midi_digmid.voices = voices; - - /* A10 = 14080.000 hz */ - ftbl[129] = 14080000; - f = ftbl[129]; - - /* create frequency table */ - for (i=128; i>=0; i--) { - f /= pow(2.0, 1.0/12.0); - ftbl[i] = f; - } - - LOCK_VARIABLE(midi_digmid); - LOCK_VARIABLE(patch); - LOCK_VARIABLE(ftbl); - LOCK_VARIABLE(digmid_voice); - LOCK_FUNCTION(digmid_freq); - LOCK_FUNCTION(digmid_trigger); - LOCK_FUNCTION(digmid_key_on); - LOCK_FUNCTION(digmid_key_off); - LOCK_FUNCTION(digmid_set_volume); - LOCK_FUNCTION(digmid_set_pitch); - LOCK_FUNCTION(digmid_set_pan); - - return 0; -} - - - -/* digmid_exit: - * Cleanup when we are finished. - */ -static void digmid_exit(int input) -{ - int i, j; - - for (i=0; i<256; i++) { - if (patch[i]) { - for (j=i+1; j<256; j++) { - if (patch[j] == patch[i]) - patch[j] = NULL; - } - destroy_patch(patch[i]); - patch[i] = NULL; - } - } -} - - diff --git a/src/allegro/src/macosx/cadigi.m b/src/allegro/src/macosx/cadigi.m deleted file mode 100644 index cda8cce4c..000000000 --- a/src/allegro/src/macosx/cadigi.m +++ /dev/null @@ -1,272 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * MacOS X Core Audio digital sound driver. - * - * By Angelo Mottola. - * - * See readme.txt for copyright information. - */ - -#include "allegro.h" -#include "allegro/internal/aintern.h" -#include "allegro/platform/aintosx.h" - -#ifndef ALLEGRO_MACOSX -#error something is wrong with the makefile -#endif - - -static int ca_detect(int); -static int ca_init(int, int); -static void ca_exit(int); -static int ca_buffer_size(); -static int ca_set_mixer_volume(int); - - -static AUGraph graph; -static AudioUnit output_unit, converter_unit; -static int audio_buffer_size = 0; -static char ca_desc[512] = EMPTY_STRING; - - -DIGI_DRIVER digi_core_audio = -{ - DIGI_CORE_AUDIO, - empty_string, - empty_string, - "CoreAudio", - 0, - 0, - MIXER_MAX_SFX, - MIXER_DEF_SFX, - - ca_detect, - ca_init, - ca_exit, - ca_set_mixer_volume, - NULL, - - NULL, - NULL, - ca_buffer_size, - _mixer_init_voice, - _mixer_release_voice, - _mixer_start_voice, - _mixer_stop_voice, - _mixer_loop_voice, - - _mixer_get_position, - _mixer_set_position, - - _mixer_get_volume, - _mixer_set_volume, - _mixer_ramp_volume, - _mixer_stop_volume_ramp, - - _mixer_get_frequency, - _mixer_set_frequency, - _mixer_sweep_frequency, - _mixer_stop_frequency_sweep, - - _mixer_get_pan, - _mixer_set_pan, - _mixer_sweep_pan, - _mixer_stop_pan_sweep, - - _mixer_set_echo, - _mixer_set_tremolo, - _mixer_set_vibrato, - 0, 0, - 0, - 0, - 0, - 0, - 0, - 0 -}; - - - -static OSStatus render_callback(void *inRefCon, AudioUnitRenderActionFlags *inActionFlags, - const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumFrames, AudioBufferList *ioData) -{ - _mix_some_samples((unsigned long)ioData->mBuffers[0].mData, 0, TRUE); - return 0; -} - - - -static int ca_detect(int input) -{ - if (input) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Input is not supported")); - return FALSE; - } - if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_1) - return FALSE; - return TRUE; -} - - - -static int ca_init(int input, int voices) -{ - AudioDeviceID audio_device; - ComponentDescription desc; - AUNode output_node, converter_node; - AURenderCallbackStruct render_cb; - UInt32 property_size, buffer_size; - AudioStreamBasicDescription input_format_desc, output_format_desc; - char device_name[64], manufacturer[64]; - UInt32 device_name_size, manufacturer_size; - char tmp1[256], tmp2[256], tmp3[256]; - - if (input) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Input is not supported")); - return -1; - } - if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_1) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("MacOS X.2 or newer required by this driver")); - return -1; - } - - NewAUGraph(&graph); - - desc.componentType = kAudioUnitType_FormatConverter; - desc.componentSubType = kAudioUnitSubType_AUConverter; - desc.componentManufacturer = kAudioUnitManufacturer_Apple; - desc.componentFlags = 0; - desc.componentFlagsMask = 0; - AUGraphNewNode(graph, &desc, 0, NULL, &converter_node); - - desc.componentType = kAudioUnitType_Output; - desc.componentSubType = kAudioUnitSubType_DefaultOutput; - desc.componentManufacturer = kAudioUnitManufacturer_Apple; - desc.componentFlags = 0; - desc.componentFlagsMask = 0; - AUGraphNewNode(graph, &desc, 0, NULL, &output_node); - - AUGraphOpen(graph); - AUGraphInitialize(graph); - - AUGraphGetNodeInfo(graph, output_node, NULL, NULL, NULL, &output_unit); - AUGraphGetNodeInfo(graph, converter_node, NULL, NULL, NULL, &converter_unit); - - property_size = sizeof(output_format_desc); - if (AudioUnitGetProperty(output_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &output_format_desc, &property_size)) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Cannot detect output audio format")); - ca_exit(FALSE); - return -1; - } - - input_format_desc.mSampleRate = output_format_desc.mSampleRate; - input_format_desc.mFormatID = kAudioFormatLinearPCM; -#ifdef ALLEGRO_BIG_ENDIAN - input_format_desc.mFormatFlags = kAudioFormatFlagIsBigEndian | kAudioFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked; -#else - input_format_desc.mFormatFlags = kAudioFormatFlagIsSignedInteger | kLinearPCMFormatFlagIsPacked; -#endif - input_format_desc.mBytesPerPacket = 4; - input_format_desc.mFramesPerPacket = 1; - input_format_desc.mBytesPerFrame = 4; - input_format_desc.mChannelsPerFrame = 2; - input_format_desc.mBitsPerChannel = 16; - - if (AudioUnitSetProperty(converter_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Output, 0, &output_format_desc, sizeof(output_format_desc)) || - AudioUnitSetProperty(converter_unit, kAudioUnitProperty_StreamFormat, kAudioUnitScope_Input, 0, &input_format_desc, sizeof(input_format_desc))) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Cannot configure format converter audio unit")); - ca_exit(FALSE); - return -1; - } - - _sound_bits = 16; - _sound_stereo = TRUE; - _sound_freq = (int)output_format_desc.mSampleRate; - - AUGraphConnectNodeInput(graph, converter_node, 0, output_node, 0); - - render_cb.inputProc = render_callback; - render_cb.inputProcRefCon = NULL; - if (AudioUnitSetProperty(converter_unit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &render_cb, sizeof(render_cb))) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Cannot set audio rendering callback")); - ca_exit(FALSE); - return -1; - } - - property_size = sizeof(audio_device); - if (AudioUnitGetProperty(output_unit, kAudioOutputUnitProperty_CurrentDevice, kAudioUnitScope_Output, 0, &audio_device, &property_size)) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Cannot get CoreAudio device")); - ca_exit(FALSE); - return -1; - } - - property_size = sizeof(buffer_size); - if (AudioDeviceGetProperty(audio_device, 0, false, kAudioDevicePropertyBufferSize, &property_size, &buffer_size)) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Cannot get CoreAudio device buffer size")); - ca_exit(FALSE); - return -1; - } - audio_buffer_size = buffer_size / sizeof(float) * sizeof(short); - digi_core_audio.voices = voices; - if (_mixer_init(audio_buffer_size / sizeof(short), _sound_freq, _sound_stereo, TRUE, &digi_core_audio.voices)) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Error initializing mixer")); - ca_exit(FALSE); - return -1; - } - - AUGraphStart(graph); - - device_name_size = sizeof(device_name); - manufacturer_size = sizeof(manufacturer); - if (!AudioDeviceGetProperty(audio_device, 0, false, kAudioDevicePropertyDeviceName, &device_name_size, device_name) && - !AudioDeviceGetProperty(audio_device, 0, false, kAudioDevicePropertyDeviceManufacturer, &manufacturer_size, manufacturer)) { - uszprintf(ca_desc, sizeof(ca_desc), get_config_text("%s (%s), 16 bits (%d real), %d bps, %s"), - uconvert_ascii(device_name, tmp1), uconvert_ascii(manufacturer, tmp2), output_format_desc.mBitsPerChannel, - _sound_freq, uconvert_ascii(_sound_stereo ? "stereo" : "mono", tmp3)); - } - else { - uszprintf(ca_desc, sizeof(ca_desc), get_config_text("16 bits (%d real), %d bps, %s"), output_format_desc.mBitsPerChannel, - _sound_freq, uconvert_ascii(_sound_stereo ? "stereo" : "mono", tmp3)); - } - digi_core_audio.desc = ca_desc; - - return 0; -} - - - -static void ca_exit(int input) -{ - if (input) - return; - AUGraphStop(graph); - AUGraphUninitialize(graph); - AUGraphClose(graph); - DisposeAUGraph(graph); - _mixer_exit(); -} - - - -static int ca_buffer_size() -{ - return audio_buffer_size; -} - - - -static int ca_set_mixer_volume(int volume) -{ - float value = (float)volume / 255.0; - - return AudioUnitSetParameter(converter_unit, kAudioUnitParameterUnit_LinearGain, kAudioUnitScope_Output, 0, value, 0); -} - diff --git a/src/allegro/src/macosx/camidi.m b/src/allegro/src/macosx/camidi.m deleted file mode 100644 index bd0f71216..000000000 --- a/src/allegro/src/macosx/camidi.m +++ /dev/null @@ -1,187 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * CoreAudio MIDI driver routines for MacOS X. - * - * By Angelo Mottola. - * - * See readme.txt for copyright information. - */ - -#include "allegro.h" -#include "allegro/internal/aintern.h" -#include "allegro/platform/aintosx.h" - -#ifndef ALLEGRO_MACOSX -#error something is wrong with the makefile -#endif - - -static int ca_detect(int); -static int ca_init(int, int); -static void ca_exit(int); -static int ca_set_mixer_volume(int); -static void ca_raw_midi(int); - - -static AUGraph graph; -static AudioUnit synth_unit; -static int command, data_pos, data_buffer[2]; -static char driver_desc[256]; - - -MIDI_DRIVER midi_core_audio = -{ - MIDI_CORE_AUDIO, /* driver ID code */ - empty_string, /* driver name */ - empty_string, /* description string */ - "CoreAudio", /* ASCII format name string */ - 16, /* available voices */ - 0, /* voice number offset */ - 16, /* maximum voices we can support */ - 0, /* default number of voices to use */ - 10, 10, /* reserved voice range */ - ca_detect, /* AL_METHOD(int, detect, (int input)); */ - ca_init, /* AL_METHOD(int, init, (int input, int voices)); */ - ca_exit, /* AL_METHOD(void, exit, (int input)); */ - ca_set_mixer_volume, /* AL_METHOD(int, mixer_set_volume, (int volume)); */ - NULL, /* AL_METHOD(int, mixer_get_volume, (void)); */ - ca_raw_midi, /* AL_METHOD(void, raw_midi, (int data)); */ - _dummy_load_patches, /* AL_METHOD(int, load_patches, (AL_CONST char *patches, AL_CONST char *drums)); */ - _dummy_adjust_patches, /* AL_METHOD(void, adjust_patches, (AL_CONST char *patches, AL_CONST char *drums)); */ - _dummy_key_on, /* AL_METHOD(void, key_on, (int inst, int note, int bend, int vol, int pan)); */ - _dummy_noop1, /* AL_METHOD(void, key_off, (int voice)); */ - _dummy_noop2, /* AL_METHOD(void, set_volume, (int voice, int vol)); */ - _dummy_noop3, /* AL_METHOD(void, set_pitch, (int voice, int note, int bend)); */ - _dummy_noop2, /* AL_METHOD(void, set_pan, (int voice, int pan)); */ - _dummy_noop2, /* AL_METHOD(void, set_vibrato, (int voice, int amount)); */ -}; - - - -static int ca_detect(int input) -{ - if (input) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Input is not supported")); - return FALSE; - } - if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_1) - return FALSE; - return TRUE; -} - - - -static int ca_init(int input, int voices) -{ - char tmp[128], tmp1[128], tmp2[128]; - char *sound = uconvert_ascii("sound", tmp); - ComponentDescription desc; - AUNode synth_node, output_node; - UInt32 quality, reverb_type; - int reverb; - struct { - UInt32 type; - char *name; - } reverb_info[6] = { { kReverbRoomType_SmallRoom, "small room" }, - { kReverbRoomType_MediumRoom, "medium room" }, - { kReverbRoomType_LargeRoom, "large room" }, - { kReverbRoomType_MediumHall, "medium hall" }, - { kReverbRoomType_LargeHall, "large hall" }, - { kReverbRoomType_Plate, "plate" } }; - - if (input) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Input is not supported")); - return -1; - } - if (floor(NSAppKitVersionNumber) <= NSAppKitVersionNumber10_1) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("MacOS X.2 or newer required by this driver")); - return -1; - } - - NewAUGraph(&graph); - - desc.componentType = kAudioUnitType_MusicDevice; - desc.componentSubType = kAudioUnitSubType_DLSSynth; - desc.componentManufacturer = kAudioUnitManufacturer_Apple; - desc.componentFlags = 0; - desc.componentFlagsMask = 0; - AUGraphNewNode(graph, &desc, 0, NULL, &synth_node); - - desc.componentType = kAudioUnitType_Output; - desc.componentSubType = kAudioUnitSubType_DefaultOutput; - desc.componentManufacturer = kAudioUnitManufacturer_Apple; - desc.componentFlags = 0; - desc.componentFlagsMask = 0; - AUGraphNewNode(graph, &desc, 0, NULL, &output_node); - - AUGraphConnectNodeInput(graph, synth_node, 0, output_node, 0); - - AUGraphOpen(graph); - AUGraphInitialize(graph); - - AUGraphGetNodeInfo(graph, synth_node, NULL, NULL, NULL, &synth_unit); - - quality = CLAMP(0, get_config_int(sound, uconvert_ascii("ca_midi_quality", tmp), 127), 127); - AudioUnitSetProperty(synth_unit, kAudioUnitProperty_RenderQuality, kAudioUnitScope_Output, 0, &quality, sizeof(quality)); - - reverb = CLAMP(0, get_config_int(sound, uconvert_ascii("ca_midi_reverb", tmp), 0), 5); - reverb_type = reverb_info[reverb].type; - AudioUnitSetProperty(synth_unit, kAudioUnitProperty_ReverbRoomType, kAudioUnitScope_Output, 0, &reverb_type, sizeof(reverb_type)); - - AUGraphStart(graph); - - uszprintf(driver_desc, sizeof(driver_desc), uconvert_ascii("DLSMusicDevice unit, %s quality, %s reverb", tmp), - (quality < 32 ? uconvert_ascii("low", tmp1) : (quality >= 96 ? uconvert_ascii("high", tmp1) : uconvert_ascii("medium", tmp1))), - uconvert_ascii(reverb_info[reverb].name, tmp2)); - midi_core_audio.desc = driver_desc; - - command = -1; - - return 0; -} - - - -static void ca_exit(int input) -{ - if (input) - return; - AUGraphStop(graph); - AUGraphUninitialize(graph); - AUGraphClose(graph); - DisposeAUGraph(graph); -} - - - -static int ca_set_mixer_volume(int volume) -{ - float value = (float)volume / 255.0; - - return AudioUnitSetParameter(synth_unit, kAudioUnitParameterUnit_LinearGain, kAudioUnitScope_Output, 0, value, 0); -} - - - -static void ca_raw_midi(int data) -{ - if (command == -1) { - data_buffer[0] = data_buffer[1] = 0; - data_pos = 0; - command = data; - return; - } - data_buffer[data_pos++] = data; - if (((data_pos == 1) && (((command >> 4) == 0xC) || ((command >> 4) == 0xD))) || (data_pos == 2)) { - MusicDeviceMIDIEvent(synth_unit, command, data_buffer[0], data_buffer[1], 0); - command = -1; - } -} diff --git a/src/allegro/src/macosx/drivers.m b/src/allegro/src/macosx/drivers.m index 16e29bf54..f3fd159ac 100644 --- a/src/allegro/src/macosx/drivers.m +++ b/src/allegro/src/macosx/drivers.m @@ -50,15 +50,3 @@ BEGIN_GFX_DRIVER_LIST { GFX_QUARTZ_FULLSCREEN, &gfx_quartz_full, TRUE }, { GFX_QUARTZ_WINDOW, &gfx_quartz_window, TRUE }, END_GFX_DRIVER_LIST - - -BEGIN_DIGI_DRIVER_LIST -{ DIGI_CORE_AUDIO, &digi_core_audio, TRUE }, -{ DIGI_SOUND_MANAGER, &digi_sound_manager, TRUE }, -END_DIGI_DRIVER_LIST - - -BEGIN_MIDI_DRIVER_LIST -{ MIDI_CORE_AUDIO, &midi_core_audio, TRUE }, -{ MIDI_QUICKTIME, &midi_quicktime, TRUE }, -END_MIDI_DRIVER_LIST diff --git a/src/allegro/src/macosx/qtmidi.m b/src/allegro/src/macosx/qtmidi.m deleted file mode 100644 index 075bf59c9..000000000 --- a/src/allegro/src/macosx/qtmidi.m +++ /dev/null @@ -1,273 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * QuickTime MIDI driver routines for MacOS X. - * - * By Ronaldo Hideki Yamada. - * - * See readme.txt for copyright information. - */ - -#include "allegro.h" -#include "allegro/internal/aintern.h" -#include "allegro/platform/aintosx.h" - -#ifndef ALLEGRO_MACOSX -#error something is wrong with the makefile -#endif - - -typedef struct MIDI_VOICE -{ - NoteChannel channel; - int note; - int bend; - int inst; - int vol; - int pan; -} MIDI_VOICE; - - -static NoteAllocator note_allocator = NULL; -static MIDI_VOICE voice[17]; -static char driver_desc[256]; - - -static int osx_midi_detect(int input); -static int osx_midi_init(int input, int voices); -static void osx_midi_exit(int input); -static int osx_midi_set_mixer_volume(int volume); -static void osx_midi_key_on(int inst, int note, int bend, int vol, int pan); -static void osx_midi_key_off(int voice); -static void osx_midi_set_volume(int voice, int vol); -static void osx_midi_set_pitch(int voice, int note, int bend); -static void osx_midi_set_pan(int voice, int pan); - - -MIDI_DRIVER midi_quicktime = -{ - MIDI_QUICKTIME, /* driver ID code */ - empty_string, /* driver name */ - empty_string, /* description string */ - "QuickTime MIDI", /* ASCII format name string */ - 16, /* available voices */ - 0, /* voice number offset */ - 16, /* maximum voices we can support */ - 0, /* default number of voices to use */ - 10, 10, /* reserved voice range */ - osx_midi_detect, /* AL_METHOD(int, detect, (int input)); */ - osx_midi_init, /* AL_METHOD(int, init, (int input, int voices)); */ - osx_midi_exit, /* AL_METHOD(void, exit, (int input)); */ - osx_midi_set_mixer_volume, /* AL_METHOD(int, set_mixer_volume, (int volume)); */ - NULL, /* AL_METHOD(int, get_mixer_volume, (void)); */ - NULL, /* AL_METHOD(void, raw_midi, (int data)); */ - _dummy_load_patches, /* AL_METHOD(int, load_patches, (AL_CONST char *patches, AL_CONST char *drums)); */ - _dummy_adjust_patches, /* AL_METHOD(void, adjust_patches, (AL_CONST char *patches, AL_CONST char *drums)); */ - osx_midi_key_on, /* AL_METHOD(void, key_on, (int inst, int note, int bend, int vol, int pan)); */ - osx_midi_key_off, /* AL_METHOD(void, key_off, (int voice)); */ - osx_midi_set_volume, /* AL_METHOD(void, set_volume, (int voice, int vol)); */ - osx_midi_set_pitch, /* AL_METHOD(void, set_pitch, (int voice, int note, int bend)); */ - osx_midi_set_pan, /* AL_METHOD(void, set_pan, (int voice, int pan)); */ - _dummy_noop2, /* AL_METHOD(void, set_vibrato, (int voice, int amount)); */ -}; - - - -/* osx_midi_detect: - * QuickTime Music MIDI detection. - */ -static int osx_midi_detect(int input) -{ - if (input) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Input is not supported")); - return FALSE; - } - note_allocator = OpenDefaultComponent(kNoteAllocatorComponentType, 0); - if (!note_allocator) - return FALSE; - CloseComponent(note_allocator); - return TRUE; -} - - - -/* osx_midi_init: - * Initializes the QuickTime Music MIDI driver. - */ -static int osx_midi_init(int input, int voices) -{ - NoteRequest note_request; - ComponentResult result; - char tmp[256]; - int i; - - if (input) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Input is not supported")); - return -1; - } - note_allocator = OpenDefaultComponent(kNoteAllocatorComponentType, 0); - if(!note_allocator) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Cannot open the NoteAllocator QuickTime component")); - return -1; - } - memset(voice, 0, 17 * sizeof(MIDI_VOICE)); - for(i = 1; i <= 16; i++) { - voice[i].note = -1; - voice[i].bend = -1; - voice[i].inst = -1; - voice[i].vol = -1; - voice[i].pan = -1; - memset(¬e_request, 0, sizeof(note_request)); - #if TARGET_RT_BIG_ENDIAN - note_request.info.polyphony = 8; - note_request.info.typicalPolyphony = 0x00010000; - #else - note_request.info.polyphony.bigEndianValue = EndianU16_NtoB(8); - note_request.info.typicalPolyphony.bigEndianValue = EndianS32_NtoB(X2Fix(1.0)); - #endif - result = NAStuffToneDescription(note_allocator, 1, ¬e_request.tone); - result |= NANewNoteChannel(note_allocator, ¬e_request, &voice[i].channel); - result |= NAResetNoteChannel(note_allocator, voice[i].channel); - if ((result) || (!voice[i].channel)) { - osx_midi_exit(input); - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Failed initializing MIDI channels")); - return -1; - } - } - - uszprintf(driver_desc, sizeof(driver_desc), uconvert_ascii("QuickTime Music MIDI synthesizer", tmp)); - midi_quicktime.desc = driver_desc; - - return 0; -} - - - -/* osx_midi_exit: - * Shuts down QuickTime Music MIDI subsystem. - */ -static void osx_midi_exit(int input) -{ - int i; - - if (input) - return; - - if (note_allocator) { - for(i = 1; i <= 16; i++) { - if (voice[i].channel) { - NAPlayNote(note_allocator, voice[i].channel, voice[i].note, 0); - NADisposeNoteChannel(note_allocator, voice[i].channel); - voice[i].channel = 0; - } - } - CloseComponent(note_allocator); - } -} - - - -/* osx_midi_set_mixer_volume: - * Sets QuickTime Music MIDI volume multiplier for all channels. - */ -static int osx_midi_set_mixer_volume(int volume) -{ - int i; - - for (i = 1; i <= 16; i++) { - if (NASetNoteChannelVolume(note_allocator, voice[i].channel, volume << 8)) - return -1; - } - return 0; -} - - - -/* osx_midi_key_on: - * Triggers a specified voice. - */ -static void osx_midi_key_on(int inst, int note, int bend, int vol, int pan) -{ - int voice_id; - NoteChannel channel; - - if (inst > 127) { - /* Percussion */ - note = inst - 128; - inst = kFirstDrumkit + 1; - } - else - inst = kFirstGMInstrument + inst; - voice_id = _midi_allocate_voice(1, 16); - if (voice_id < 0) - return; - channel = voice[voice_id].channel; - if (voice[voice_id].inst != inst) { - if (NASetInstrumentNumber(note_allocator, channel, inst) != noErr) - return; - voice[voice_id].inst = inst; - } - NAPlayNote(note_allocator, channel, voice[voice_id].note, 0); - if (NAPlayNote(note_allocator, channel, note, vol) != noErr) - return; - voice[voice_id].note = note; - osx_midi_set_pitch(voice_id, note, bend); - osx_midi_set_pan(voice_id, pan); -} - - - -/* osx_midi_key_off: - * Turns off specified voice. - */ -static void osx_midi_key_off(int voice_id) -{ - NAPlayNote(note_allocator, voice[voice_id].channel, voice[voice_id].note, 0); -} - - - -/* osx_midi_set_volume: - * Sets volume for a specified voice. - */ -static void osx_midi_set_volume(int voice_id, int vol) -{ - if (voice[voice_id].vol != vol) { - if (NASetController(note_allocator, voice[voice_id].channel, kControllerVolume, vol << 7) == noErr) - voice[voice_id].vol = vol; - } -} - - - -/* osx_midi_set_pitch: - * Sets pitch of specified voice. - */ -static void osx_midi_set_pitch(int voice_id, int note, int bend) -{ - bend >>= 5; - if (voice[voice_id].bend != bend) { - if (NASetController(note_allocator, voice[voice_id].channel, kControllerPitchBend, bend) == noErr) - voice[voice_id].bend = bend; - } -} - - - -/* osx_midi_set_pan: - * Sets pan value on specified voice. - */ -static void osx_midi_set_pan(int voice_id, int pan) -{ - if (voice[voice_id].pan != pan) { - if (NASetNoteChannelBalance(note_allocator, voice[voice_id].channel, pan - 127) == noErr) - voice[voice_id].pan = pan; - } -} diff --git a/src/allegro/src/macosx/soundman.m b/src/allegro/src/macosx/soundman.m deleted file mode 100644 index ff853a837..000000000 --- a/src/allegro/src/macosx/soundman.m +++ /dev/null @@ -1,293 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * MacOS X Sound Manager digital sound driver. - * - * By Angelo Mottola. - * - * See readme.txt for copyright information. - */ - -#include "allegro.h" -#include "allegro/internal/aintern.h" -#include "allegro/platform/aintosx.h" - -#ifndef ALLEGRO_MACOSX -#error something is wrong with the makefile -#endif - - -#define SAMPLES_PER_BUFFER 4096 - - -static int osx_digi_sound_detect(int); -static int osx_digi_sound_init(int, int); -static void osx_digi_sound_exit(int); -static int osx_digi_sound_buffer_size(); -static int osx_digi_sound_set_mixer_volume(int); - - -static SndChannel *sound_channel = NULL; -static ExtSoundHeader sound_header; -static unsigned char *sound_buffer[2] = { NULL, NULL }; -static char sound_desc[256]; - - -DIGI_DRIVER digi_sound_manager = -{ - DIGI_SOUND_MANAGER, - empty_string, - empty_string, - "Sound Manager", - 0, - 0, - MIXER_MAX_SFX, - MIXER_DEF_SFX, - - osx_digi_sound_detect, - osx_digi_sound_init, - osx_digi_sound_exit, - osx_digi_sound_set_mixer_volume, - NULL, - - NULL, - NULL, - osx_digi_sound_buffer_size, - _mixer_init_voice, - _mixer_release_voice, - _mixer_start_voice, - _mixer_stop_voice, - _mixer_loop_voice, - - _mixer_get_position, - _mixer_set_position, - - _mixer_get_volume, - _mixer_set_volume, - _mixer_ramp_volume, - _mixer_stop_volume_ramp, - - _mixer_get_frequency, - _mixer_set_frequency, - _mixer_sweep_frequency, - _mixer_stop_frequency_sweep, - - _mixer_get_pan, - _mixer_set_pan, - _mixer_sweep_pan, - _mixer_stop_pan_sweep, - - _mixer_set_echo, - _mixer_set_tremolo, - _mixer_set_vibrato, - 0, 0, - 0, - 0, - 0, - 0, - 0, - 0 -}; - - - -/* sound_callback: - * Sound Manager channel callback to update sound data. - */ -static void sound_callback(SndChannel *channel, SndCommand *command) -{ - SndCommand new_command; - - /* Send mixed buffer to sound card */ - sound_header.samplePtr = (Ptr)sound_buffer[command->param1]; - new_command.cmd = bufferCmd; - new_command.param1 = 0; - new_command.param2 = (long)&sound_header; - if (SndDoCommand(channel, &new_command, FALSE) != noErr) - return; - - /* Mix the other buffer */ - command->param1 ^= 1; - _mix_some_samples((unsigned long)sound_buffer[command->param1], 0, (_sound_bits == 16) ? TRUE : FALSE); - - /* Reissue the callback */ - new_command.cmd = callBackCmd; - new_command.param1 = command->param1; - SndDoCommand(channel, &new_command, FALSE); -} - - - -/* osx_digi_sound_detect. - * Returns TRUE if Sound Manager 3.x or newer is available. - */ -static int osx_digi_sound_detect(int input) -{ - NumVersion version; - - if (input) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Input is not supported")); - return FALSE; - } - version = SndSoundManagerVersion(); - if (version.majorRev < 3) - return FALSE; - return TRUE; -} - - - -/* osx_digi_sound_init: - * Initializes the sound driver. - */ -static int osx_digi_sound_init(int input, int voices) -{ - SndCommand command; - NumVersion version; - long sound_caps = 0; - char tmp[128]; - int i; - - if (input) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Input is not supported")); - return -1; - } - - version = SndSoundManagerVersion(); - if (version.majorRev < 3) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Sound Manager version 3.0 or newer required")); - return -1; - } - Gestalt(gestaltSoundAttr, &sound_caps); - - if (_sound_stereo >= 0) { - if (_sound_stereo && (sound_caps & (1 << gestaltStereoCapability))) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Stereo output not supported")); - return -1; - } - } - else - _sound_stereo = (sound_caps & (1 << gestaltStereoCapability)) ? TRUE : FALSE; - if (_sound_bits >= 0) { - if (_sound_bits != ((sound_caps & (1 << gestalt16BitAudioSupport)) ? 16 : 8)) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("16 bit output not supported")); - return -1; - } - } - else - _sound_bits = (sound_caps & (1 << gestalt16BitAudioSupport)) ? 16 : 8; - if (_sound_freq <= 0) - _sound_freq = 44100; - - memset(&sound_header, 0, sizeof(sound_header)); - sound_header.numChannels = (_sound_stereo) ? 2 : 1; - sound_header.sampleRate = _sound_freq << 16; - sound_header.encode = extSH; - sound_header.numFrames = SAMPLES_PER_BUFFER; - sound_header.sampleSize = _sound_bits; - - for (i = 0; i < 2; i++) { - sound_buffer[i] = (unsigned char *)calloc(1, SAMPLES_PER_BUFFER * (_sound_bits / 8) * (_sound_stereo ? 2 : 1)); - if (!sound_buffer[i]) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Not enough memory")); - osx_digi_sound_exit(input); - return -1; - } - } - - digi_sound_manager.voices = voices; - if (_mixer_init(SAMPLES_PER_BUFFER * (_sound_stereo ? 2 : 1), _sound_freq, _sound_stereo, ((_sound_bits == 16) ? TRUE: FALSE), &digi_sound_manager.voices)) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Error initializing mixer")); - osx_digi_sound_exit(input); - return -1; - } - - sound_channel = (SndChannel *)malloc(sizeof(SndChannel)); - if (!sound_channel) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Not enough memory")); - osx_digi_sound_exit(input); - return -1; - } - sound_channel->qLength = 128; - - if (SndNewChannel(&sound_channel, sampledSynth, (_sound_stereo ? initStereo : initMono), sound_callback) != noErr) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Failed creating sound channel")); - free(sound_channel); - return -1; - } - - command.cmd = callBackCmd; - command.param1 = 0; - SndDoCommand(sound_channel, &command, FALSE); - - uszprintf(sound_desc, sizeof(sound_desc), get_config_text("Sound Manager version %d.%d, %d bits, %d bps, %s"), - ((version.majorRev / 16) * 10) + (version.majorRev & 0xf), - (version.minorAndBugRev / 16), _sound_bits, _sound_freq, - uconvert_ascii(_sound_stereo ? "stereo" : "mono", tmp)); - digi_sound_manager.desc = sound_desc; - - return 0; -} - - - -/* osx_digi_sound_exit: - * Shuts down the sound driver. - */ -static void osx_digi_sound_exit(int input) -{ - int i; - - if (input) - return; - - if (sound_channel) { - SndDisposeChannel(sound_channel, TRUE); - free(sound_channel); - sound_channel = NULL; - } - - for (i = 0; i < 2; i++) { - if (sound_buffer[i]) { - free(sound_buffer[i]); - sound_buffer[i] = NULL; - } - } - - _mixer_exit(); -} - - - -/* osx_digi_sound_buffer_size: - * Returns the mixing buffer size, for use by the audiostream code. - */ -static int osx_digi_sound_buffer_size() -{ - return SAMPLES_PER_BUFFER; -} - - - -/* osx_digi_sound_set_mixer_volume: - * Sets the sound channel volume. - */ -static int osx_digi_sound_set_mixer_volume(int volume) -{ - SndCommand command; - - if (!sound_channel) - return -1; - - command.cmd = volumeCmd; - command.param1 = 0; - command.param2 = (volume << 16) | volume; - return (SndDoCommand(sound_channel, &command, FALSE) != noErr); -} diff --git a/src/allegro/src/macosx/system.m b/src/allegro/src/macosx/system.m index 830f7092c..374734517 100644 --- a/src/allegro/src/macosx/system.m +++ b/src/allegro/src/macosx/system.m @@ -121,8 +121,6 @@ SYSTEM_DRIVER system_macosx = _unix_lock_mutex, _unix_unlock_mutex, NULL, /* AL_METHOD(_DRIVER_INFO *, gfx_drivers, (void)); */ - NULL, /* AL_METHOD(_DRIVER_INFO *, digi_drivers, (void)); */ - NULL, /* AL_METHOD(_DRIVER_INFO *, midi_drivers, (void)); */ NULL, /* AL_METHOD(_DRIVER_INFO *, keyboard_drivers, (void)); */ NULL, /* AL_METHOD(_DRIVER_INFO *, mouse_drivers, (void)); */ NULL, /* AL_METHOD(_DRIVER_INFO *, timer_drivers, (void)); */ diff --git a/src/allegro/src/midi.c b/src/allegro/src/midi.c deleted file mode 100644 index 5ed4d1c3e..000000000 --- a/src/allegro/src/midi.c +++ /dev/null @@ -1,1619 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * The core MIDI file player. - * - * By Shawn Hargreaves. - * - * Pause and seek functions by George Foot. - * - * get_midi_length by Elias Pschernig. - * - * See readme.txt for copyright information. - */ - - -#include -#include - -#include "allegro.h" -#include "allegro/internal/aintern.h" - - - -/* maximum number of layers in a single voice */ -#define MIDI_LAYERS 4 - -/* how often the midi callback gets called maximally / second */ -#define MIDI_TIMER_FREQUENCY 40 - - -typedef struct MIDI_TRACK /* a track in the MIDI file */ -{ - unsigned char *pos; /* position in track data */ - long timer; /* time until next event */ - unsigned char running_status; /* last MIDI event */ -} MIDI_TRACK; - - -typedef struct MIDI_CHANNEL /* a MIDI channel */ -{ - int patch; /* current sound */ - int volume; /* volume controller */ - int pan; /* pan position */ - int pitch_bend; /* pitch bend position */ - int new_volume; /* cached volume change */ - int new_pitch_bend; /* cached pitch bend */ - int note[128][MIDI_LAYERS]; /* status of each note */ -} MIDI_CHANNEL; - - -typedef struct MIDI_VOICE /* a voice on the soundcard */ -{ - int channel; /* MIDI channel */ - int note; /* note (-1 = off) */ - int volume; /* note velocity */ - long time; /* when note was triggered */ -} MIDI_VOICE; - - -typedef struct WAITING_NOTE /* a stored note-on request */ -{ - int channel; - int note; - int volume; -} WAITING_NOTE; - - -typedef struct PATCH_TABLE /* GM -> external synth */ -{ - int bank1; /* controller #0 */ - int bank2; /* controller #32 */ - int prog; /* program change */ - int pitch; /* pitch shift */ -} PATCH_TABLE; - - -volatile long midi_pos = -1; /* current position in MIDI file */ -volatile long midi_time = 0; /* current position in seconds */ -static volatile long midi_timers; /* current position in allegro-timer-ticks */ -static long midi_pos_counter; /* delta for midi_pos */ - -volatile long _midi_tick = 0; /* counter for killing notes */ - -static void midi_player(void); /* core MIDI player routine */ -static void prepare_to_play(MIDI *midi); -static void midi_lock_mem(void); - -static MIDI *midifile = NULL; /* the file that is playing */ - -static int midi_loop = 0; /* repeat at eof? */ - -long midi_loop_start = -1; /* where to loop back to */ -long midi_loop_end = -1; /* loop at this position */ - -static int midi_semaphore = 0; /* reentrancy flag */ -static int midi_loaded_patches = FALSE; /* loaded entire patch set? */ - -static long midi_timer_speed; /* midi_player's timer speed */ -static int midi_pos_speed; /* MIDI delta -> midi_pos */ -static int midi_speed; /* MIDI delta -> timer */ -static int midi_new_speed; /* for tempo change events */ - -static int old_midi_volume = -1; /* stored global volume */ - -static int midi_alloc_channel; /* so _midi_allocate_voice */ -static int midi_alloc_note; /* knows which note the */ -static int midi_alloc_vol; /* sound is associated with */ - -static MIDI_TRACK midi_track[MIDI_TRACKS]; /* the active tracks */ -static MIDI_VOICE midi_voice[MIDI_VOICES]; /* synth voice status */ -static MIDI_CHANNEL midi_channel[16]; /* MIDI channel info */ -static WAITING_NOTE midi_waiting[MIDI_VOICES]; /* notes still to be played */ -static PATCH_TABLE patch_table[128]; /* GM -> external synth */ - -static int midi_seeking; /* set during seeks */ -static int midi_looping; /* set during loops */ - -/* hook functions */ -void (*midi_msg_callback)(int msg, int byte1, int byte2) = NULL; -void (*midi_meta_callback)(int type, AL_CONST unsigned char *data, int length) = NULL; -void (*midi_sysex_callback)(AL_CONST unsigned char *data, int length) = NULL; - - - -/* lock_midi: - * Locks a MIDI file into physical memory. Pretty important, since they - * are mostly accessed inside interrupt handlers. - */ -void lock_midi(MIDI *midi) -{ - int c; - ASSERT(midi); - - LOCK_DATA(midi, sizeof(MIDI)); - - for (c=0; ctrack[c].data) { - LOCK_DATA(midi->track[c].data, midi->track[c].len); - } - } -} - - - -/* load_midi: - * Loads a standard MIDI file, returning a pointer to a MIDI structure, - * or NULL on error. - */ -MIDI *load_midi(AL_CONST char *filename) -{ - int c; - char buf[4]; - long data; - PACKFILE *fp; - MIDI *midi; - int num_tracks; - ASSERT(filename); - - fp = pack_fopen(filename, F_READ); /* open the file */ - if (!fp) - return NULL; - - midi = _AL_MALLOC(sizeof(MIDI)); /* get some memory */ - if (!midi) { - pack_fclose(fp); - return NULL; - } - - for (c=0; ctrack[c].data = NULL; - midi->track[c].len = 0; - } - - pack_fread(buf, 4, fp); /* read midi header */ - - /* Is the midi inside a .rmi file? */ - if (memcmp(buf, "RIFF", 4) == 0) { /* check for RIFF header */ - pack_mgetl(fp); - - while (!pack_feof(fp)) { - pack_fread(buf, 4, fp); /* RMID chunk? */ - if (memcmp(buf, "RMID", 4) == 0) break; - - pack_fseek(fp, pack_igetl(fp)); /* skip to next chunk */ - } - - if (pack_feof(fp)) goto err; - - pack_mgetl(fp); - pack_mgetl(fp); - pack_fread(buf, 4, fp); /* read midi header */ - } - - if (memcmp(buf, "MThd", 4)) - goto err; - - pack_mgetl(fp); /* skip header chunk length */ - - data = pack_mgetw(fp); /* MIDI file type */ - if ((data != 0) && (data != 1)) - goto err; - - num_tracks = pack_mgetw(fp); /* number of tracks */ - if ((num_tracks < 1) || (num_tracks > MIDI_TRACKS)) - goto err; - - data = pack_mgetw(fp); /* beat divisions */ - midi->divisions = ABS(data); - - for (c=0; ctrack[c].len = data; - - midi->track[c].data = _AL_MALLOC_ATOMIC(data); /* allocate memory */ - if (!midi->track[c].data) - goto err; - /* finally, read track data */ - if (pack_fread(midi->track[c].data, data, fp) != data) - goto err; - } - - pack_fclose(fp); - lock_midi(midi); - return midi; - - /* oh dear... */ - err: - pack_fclose(fp); - destroy_midi(midi); - return NULL; -} - - - -/* destroy_midi: - * Frees the memory being used by a MIDI file. - */ -void destroy_midi(MIDI *midi) -{ - int c; - - if (midi == midifile) - stop_midi(); - - if (midi) { - for (c=0; ctrack[c].data) { - UNLOCK_DATA(midi->track[c].data, midi->track[c].len); - _AL_FREE(midi->track[c].data); - } - } - - UNLOCK_DATA(midi, sizeof(MIDI)); - _AL_FREE(midi); - } -} - - - -/* parse_var_len: - * The MIDI file format is a strange thing. Time offsets are only 32 bits, - * yet they are compressed in a weird variable length format. This routine - * reads a variable length integer from a MIDI data stream. It returns the - * number read, and alters the data pointer according to the number of - * bytes it used. - */ -static unsigned long parse_var_len(AL_CONST unsigned char **data) -{ - unsigned long val = **data & 0x7F; - - while (**data & 0x80) { - (*data)++; - val <<= 7; - val += (**data & 0x7F); - } - - (*data)++; - return val; -} - -END_OF_STATIC_FUNCTION(parse_var_len); - - - -/* global_volume_fix: - * Converts a note volume, adjusting it according to the global - * _midi_volume variable. - */ -static INLINE int global_volume_fix(int vol) -{ - if (_midi_volume >= 0) - return (vol * _midi_volume) / 256; - - return vol; -} - - - -/* sort_out_volume: - * Converts a note volume, adjusting it according to the channel volume - * and the global _midi_volume variable. - */ -static INLINE int sort_out_volume(int c, int vol) -{ - return global_volume_fix((vol * midi_channel[c].volume) / 128); -} - - - -/* raw_program_change: - * Sends a program change message to a device capable of handling raw - * MIDI data, using patch mapping tables. Assumes that midi_driver->raw_midi - * isn't NULL, so check before calling it! - */ -static void raw_program_change(int channel, int patch) -{ - if (channel != 9) { - /* bank change #1 */ - if (patch_table[patch].bank1 >= 0) { - midi_driver->raw_midi(0xB0+channel); - midi_driver->raw_midi(0); - midi_driver->raw_midi(patch_table[patch].bank1); - } - - /* bank change #2 */ - if (patch_table[patch].bank2 >= 0) { - midi_driver->raw_midi(0xB0+channel); - midi_driver->raw_midi(32); - midi_driver->raw_midi(patch_table[patch].bank2); - } - - /* program change */ - midi_driver->raw_midi(0xC0+channel); - midi_driver->raw_midi(patch_table[patch].prog); - - /* update volume */ - midi_driver->raw_midi(0xB0+channel); - midi_driver->raw_midi(7); - midi_driver->raw_midi(global_volume_fix(midi_channel[channel].volume-1)); - } -} - -END_OF_STATIC_FUNCTION(raw_program_change); - - - -/* midi_note_off: - * Processes a MIDI note-off event. - */ -static void midi_note_off(int channel, int note) -{ - int done = FALSE; - int voice, layer; - int c; - - /* can we send raw MIDI data? */ - if (midi_driver->raw_midi) { - if (channel != 9) - note += patch_table[midi_channel[channel].patch].pitch; - - midi_driver->raw_midi(0x80+channel); - midi_driver->raw_midi(note); - midi_driver->raw_midi(0); - return; - } - - /* oh well, have to do it the long way... */ - for (layer=0; layer= 0) { - midi_driver->key_off(voice + midi_driver->basevoice); - midi_voice[voice].note = -1; - midi_voice[voice].time = _midi_tick; - midi_channel[channel].note[note][layer] = -1; - done = TRUE; - } - } - - /* if the note isn't playing, it must still be in the waiting room */ - if (!done) { - for (c=0; c= 0x1000) { - (*note)++; - (*bend) -= 0x1000; - } -} - - - -/* _midi_allocate_voice: - * Allocates a MIDI voice in the range min-max (inclusive). This is - * intended to be called by the key_on() handlers in the MIDI driver, - * and shouldn't be used by any other code. - */ -int _midi_allocate_voice(int min, int max) -{ - int c; - int layer; - int voice = -1; - long best_time = LONG_MAX; - - if (min < 0) - min = 0; - - if (max < 0) - max = midi_driver->voices-1; - - /* which layer can we use? */ - for (layer=0; layer= MIDI_LAYERS) - return -1; - - /* find a free voice */ - for (c=min; c<=max; c++) { - if ((midi_voice[c].note < 0) && - (midi_voice[c].time < best_time) && - ((c < midi_driver->xmin) || (c > midi_driver->xmax))) { - voice = c; - best_time = midi_voice[c].time; - } - } - - /* if there are no free voices, kill a note to make room */ - if (voice < 0) { - voice = -1; - best_time = LONG_MAX; - for (c=min; c<=max; c++) { - if ((midi_voice[c].time < best_time) && - ((c < midi_driver->xmin) || (c > midi_driver->xmax))) { - voice = c; - best_time = midi_voice[c].time; - } - } - if (voice >= 0) - midi_note_off(midi_voice[voice].channel, midi_voice[voice].note); - else - return -1; - } - - /* ok, we got it... */ - midi_voice[voice].channel = midi_alloc_channel; - midi_voice[voice].note = midi_alloc_note; - midi_voice[voice].volume = midi_alloc_vol; - midi_voice[voice].time = _midi_tick; - midi_channel[midi_alloc_channel].note[midi_alloc_note][layer] = voice; - - return voice + midi_driver->basevoice; -} - -END_OF_FUNCTION(_midi_allocate_voice); - - - -/* midi_note_on: - * Processes a MIDI note-on event. Tries to find a free soundcard voice, - * and if it can't either cuts off an existing note, or if 'polite' is - * set, just stores the channel, note and volume in the waiting list. - */ -static void midi_note_on(int channel, int note, int vol, int polite) -{ - int c, layer, inst, bend, corrected_note; - - /* it's easy if the driver can handle raw MIDI data */ - if (midi_driver->raw_midi) { - if (channel != 9) - note += patch_table[midi_channel[channel].patch].pitch; - - midi_driver->raw_midi(0x90+channel); - midi_driver->raw_midi(note); - midi_driver->raw_midi(vol); - return; - } - - /* if the note is already on, turn it off */ - for (layer=0; layer= 0) { - midi_note_off(channel, note); - return; - } - } - - /* if zero volume and the note isn't playing, we can just ignore it */ - if (vol == 0) - return; - - if (channel != 9) { - /* are there any free voices? */ - for (c=0; cvoices; c++) - if ((midi_voice[c].note < 0) && - ((c < midi_driver->xmin) || (c > midi_driver->xmax))) - break; - - /* if there are no free voices, remember the note for later */ - if ((c >= midi_driver->voices) && (polite)) { - for (c=0; ckey_on(inst, corrected_note, bend, - sort_out_volume(channel, vol), - midi_channel[channel].pan); -} - -END_OF_STATIC_FUNCTION(midi_note_on); - - - -/* all_notes_off: - * Turns off all active notes. - */ -static void all_notes_off(int channel) -{ - if (midi_driver->raw_midi) { - midi_driver->raw_midi(0xB0+channel); - midi_driver->raw_midi(123); - midi_driver->raw_midi(0); - return; - } - else { - int note, layer; - - for (note=0; note<128; note++) - for (layer=0; layer= 0) - midi_note_off(channel, note); - } -} - -END_OF_STATIC_FUNCTION(all_notes_off); - - - -/* all_sound_off: - * Turns off sound. - */ -static void all_sound_off(int channel) -{ - if (midi_driver->raw_midi) { - midi_driver->raw_midi(0xB0+channel); - midi_driver->raw_midi(120); - midi_driver->raw_midi(0); - return; - } -} - -END_OF_STATIC_FUNCTION(all_sound_off); - - - -/* reset_controllers: - * Resets volume, pan, pitch bend, etc, to default positions. - */ -static void reset_controllers(int channel) -{ - midi_channel[channel].new_volume = 128; - midi_channel[channel].new_pitch_bend = 0x2000; - - if (midi_driver->raw_midi) { - midi_driver->raw_midi(0xB0+channel); - midi_driver->raw_midi(121); - midi_driver->raw_midi(0); - } - - switch (channel % 3) { - case 0: midi_channel[channel].pan = ((channel/3) & 1) ? 60 : 68; break; - case 1: midi_channel[channel].pan = 104; break; - case 2: midi_channel[channel].pan = 24; break; - } - - if (midi_driver->raw_midi) { - midi_driver->raw_midi(0xB0+channel); - midi_driver->raw_midi(10); - midi_driver->raw_midi(midi_channel[channel].pan); - } -} - -END_OF_STATIC_FUNCTION(reset_controllers); - - - -/* update_controllers: - * Checks cached controller information and updates active voices. - */ -static void update_controllers(void) -{ - int c, c2, vol, bend, note; - - for (c=0; c<16; c++) { - /* check for volume controller change */ - if ((midi_channel[c].volume != midi_channel[c].new_volume) || (old_midi_volume != _midi_volume)) { - midi_channel[c].volume = midi_channel[c].new_volume; - if (midi_driver->raw_midi) { - midi_driver->raw_midi(0xB0+c); - midi_driver->raw_midi(7); - midi_driver->raw_midi(global_volume_fix(midi_channel[c].volume-1)); - } - else { - for (c2=0; c2= 0)) { - vol = sort_out_volume(c, midi_voice[c2].volume); - midi_driver->set_volume(c2 + midi_driver->basevoice, vol); - } - } - } - } - - /* check for pitch bend change */ - if (midi_channel[c].pitch_bend != midi_channel[c].new_pitch_bend) { - midi_channel[c].pitch_bend = midi_channel[c].new_pitch_bend; - if (midi_driver->raw_midi) { - midi_driver->raw_midi(0xE0+c); - midi_driver->raw_midi(midi_channel[c].pitch_bend & 0x7F); - midi_driver->raw_midi(midi_channel[c].pitch_bend >> 7); - } - else { - for (c2=0; c2= 0)) { - bend = midi_channel[c].pitch_bend; - note = midi_voice[c2].note; - sort_out_pitch_bend(&bend, ¬e); - midi_driver->set_pitch(c2 + midi_driver->basevoice, note, bend); - } - } - } - } - } - - old_midi_volume = _midi_volume; -} - -END_OF_STATIC_FUNCTION(update_controllers); - - - -/* process_controller: - * Deals with a MIDI controller message on the specified channel. - */ -static void process_controller(int channel, int ctrl, int data) -{ - switch (ctrl) { - - case 7: /* main volume */ - midi_channel[channel].new_volume = data+1; - break; - - case 10: /* pan */ - midi_channel[channel].pan = data; - if (midi_driver->raw_midi) { - midi_driver->raw_midi(0xB0+channel); - midi_driver->raw_midi(10); - midi_driver->raw_midi(data); - } - break; - - case 120: /* all sound off */ - all_sound_off(channel); - break; - - case 121: /* reset all controllers */ - reset_controllers(channel); - break; - - case 123: /* all notes off */ - case 124: /* omni mode off */ - case 125: /* omni mode on */ - case 126: /* poly mode off */ - case 127: /* poly mode on */ - all_notes_off(channel); - break; - - default: - if (midi_driver->raw_midi) { - midi_driver->raw_midi(0xB0+channel); - midi_driver->raw_midi(ctrl); - midi_driver->raw_midi(data); - } - break; - } -} - -END_OF_STATIC_FUNCTION(process_controller); - - - -/* process_meta_event: - * Processes the next meta-event on the specified track. - */ -static void process_meta_event(AL_CONST unsigned char **pos, long *timer) -{ - unsigned char metatype = *((*pos)++); - long length = parse_var_len(pos); - long tempo; - - if (midi_meta_callback) - midi_meta_callback(metatype, *pos, length); - - if (metatype == 0x2F) { /* end of track */ - *pos = NULL; - *timer = LONG_MAX; - return; - } - - if (metatype == 0x51) { /* tempo change */ - tempo = (*pos)[0] * 0x10000L + (*pos)[1] * 0x100 + (*pos)[2]; - midi_new_speed = (tempo/1000) * (TIMERS_PER_SECOND/1000); - midi_new_speed /= midifile->divisions; - } - - (*pos) += length; -} - -END_OF_STATIC_FUNCTION(process_meta_event); - - - -/* process_midi_event: - * Processes the next MIDI event on the specified track. - */ -static void process_midi_event(AL_CONST unsigned char **pos, unsigned char *running_status, long *timer) -{ - unsigned char byte1, byte2; - int channel; - unsigned char event; - long l; - - event = *((*pos)++); - - if (event & 0x80) { /* regular message */ - /* no running status for sysex and meta-events! */ - if ((event != 0xF0) && (event != 0xF7) && (event != 0xFF)) - *running_status = event; - byte1 = (*pos)[0]; - byte2 = (*pos)[1]; - } - else { /* use running status */ - byte1 = event; - byte2 = (*pos)[0]; - event = *running_status; - (*pos)--; - } - - /* program callback? */ - if ((midi_msg_callback) && - (event != 0xF0) && (event != 0xF7) && (event != 0xFF)) - midi_msg_callback(event, byte1, byte2); - - channel = event & 0x0F; - - switch (event>>4) { - - case 0x08: /* note off */ - midi_note_off(channel, byte1); - (*pos) += 2; - break; - - case 0x09: /* note on */ - midi_note_on(channel, byte1, byte2, 1); - (*pos) += 2; - break; - - case 0x0A: /* note aftertouch */ - (*pos) += 2; - break; - - case 0x0B: /* control change */ - process_controller(channel, byte1, byte2); - (*pos) += 2; - break; - - case 0x0C: /* program change */ - midi_channel[channel].patch = byte1; - if (midi_driver->raw_midi) - raw_program_change(channel, byte1); - (*pos) += 1; - break; - - case 0x0D: /* channel aftertouch */ - (*pos) += 1; - break; - - case 0x0E: /* pitch bend */ - midi_channel[channel].new_pitch_bend = byte1 + (byte2<<7); - (*pos) += 2; - break; - - case 0x0F: /* special event */ - switch (event) { - case 0xF0: /* sysex */ - case 0xF7: - l = parse_var_len(pos); - if (midi_sysex_callback) - midi_sysex_callback(*pos, l); - (*pos) += l; - break; - - case 0xF2: /* song position */ - (*pos) += 2; - break; - - case 0xF3: /* song select */ - (*pos)++; - break; - - case 0xFF: /* meta-event */ - process_meta_event(pos, timer); - break; - - default: - /* the other special events don't have any data bytes, - so we don't need to bother skipping past them */ - break; - } - break; - - default: - /* something has gone badly wrong if we ever get to here */ - break; - } -} - -END_OF_STATIC_FUNCTION(process_midi_event); - - - -/* midi_player: - * The core MIDI player: to be used as a timer callback. - */ -static void midi_player(void) -{ - int c; - long l; - int active; - - if (!midifile) - return; - - if (midi_semaphore) { - midi_timer_speed += BPS_TO_TIMER(MIDI_TIMER_FREQUENCY); - install_int_ex(midi_player, BPS_TO_TIMER(MIDI_TIMER_FREQUENCY)); - return; - } - - midi_semaphore = TRUE; - _midi_tick++; - - midi_timers += midi_timer_speed; - midi_time = midi_timers / TIMERS_PER_SECOND; - - do_it_all_again: - - for (c=0; c 0) { - for (c=0; cdivisions; - midi_new_speed = -1; - } - - /* figure out how long until we need to be called again */ - active = 0; - midi_timer_speed = LONG_MAX; - for (c=0; c 0) && (midi_pos >= midi_loop_end))) { - if ((midi_loop) && (!midi_looping)) { - if (midi_loop_start > 0) { - remove_int(midi_player); - midi_semaphore = FALSE; - midi_looping = TRUE; - if (midi_seek(midi_loop_start) != 0) { - midi_looping = FALSE; - stop_midi(); - return; - } - midi_looping = FALSE; - midi_semaphore = TRUE; - goto do_it_all_again; - } - else { - for (c=0; c<16; c++) { - all_notes_off(c); - all_sound_off(c); - } - prepare_to_play(midifile); - goto do_it_all_again; - } - } - else { - stop_midi(); - midi_semaphore = FALSE; - return; - } - } - - /* reprogram the timer */ - if (midi_timer_speed < BPS_TO_TIMER(MIDI_TIMER_FREQUENCY)) - midi_timer_speed = BPS_TO_TIMER(MIDI_TIMER_FREQUENCY); - - if (!midi_seeking) - install_int_ex(midi_player, midi_timer_speed); - - /* controller changes are cached and only processed here, so we can - condense streams of controller data into just a few voice updates */ - update_controllers(); - - /* and deal with any notes that are still waiting to be played */ - for (c=0; c= 0) - midi_note_on(midi_waiting[c].channel, midi_waiting[c].note, - midi_waiting[c].volume, 0); - - midi_semaphore = FALSE; -} - -END_OF_STATIC_FUNCTION(midi_player); - - - -/* midi_init: - * Sets up the MIDI player ready for use. Returns non-zero on failure. - */ -static int midi_init(void) -{ - int c, c2, c3; - char **argv; - int argc; - char buf[32], tmp[64]; - - midi_loaded_patches = FALSE; - - midi_lock_mem(); - - for (c=0; c<16; c++) { - midi_channel[c].volume = midi_channel[c].new_volume = 128; - midi_channel[c].pitch_bend = midi_channel[c].new_pitch_bend = 0x2000; - - for (c2=0; c2<128; c2++) - for (c3=0; c3track[c].data; - end = p + midi->track[c].len; - running_status = 0; - - while (p < end) { /* work through data stream */ -#if defined ALLEGRO_BEOS || defined ALLEGRO_HAIKU - /* Is there a bug in this routine, or in gcc under BeOS/x86? --PW */ - { int i; for (i=1; i; i--); } -#endif - event = *p; - if (event & 0x80) { /* regular message */ - p++; - if ((event != 0xF0) && (event != 0xF7) && (event != 0xFF)) - running_status = event; - } - else /* use running status */ - event = running_status; - - switch (event>>4) { - - case 0x0C: /* program change! */ - patches[*p] = TRUE; - p++; - break; - - case 0x09: /* note on, is it a drum? */ - if ((event & 0x0F) == 9) - drums[*p] = TRUE; - p += 2; - break; - - case 0x08: /* note off */ - case 0x0A: /* note aftertouch */ - case 0x0B: /* control change */ - case 0x0E: /* pitch bend */ - p += 2; - break; - - case 0x0D: /* channel aftertouch */ - p += 1; - break; - - case 0x0F: /* special event */ - switch (event) { - case 0xF0: /* sysex */ - case 0xF7: - l = parse_var_len((AL_CONST unsigned char**) &p); - p += l; - break; - - case 0xF2: /* song position */ - p += 2; - break; - - case 0xF3: /* song select */ - p++; - break; - - case 0xFF: /* meta-event */ - p++; - l = parse_var_len((AL_CONST unsigned char**) &p); - p += l; - break; - - default: - /* the other special events don't have any data bytes, - so we don't need to bother skipping past them */ - break; - } - break; - - default: - /* something has gone badly wrong if we ever get to here */ - break; - } - - if (p < end) /* skip time offset */ - parse_var_len((AL_CONST unsigned char**) &p); - } - } - - /* tell the driver to do its stuff */ - return midi_driver->load_patches(patches, drums); -} - - - -/* prepare_to_play: - * Sets up all the global variables needed to play the specified file. - */ -static void prepare_to_play(MIDI *midi) -{ - int c; - ASSERT(midi); - - for (c=0; c<16; c++) - reset_controllers(c); - - update_controllers(); - - midifile = midi; - midi_pos = 0; - midi_timers = 0; - midi_time = 0; - midi_pos_counter = 0; - midi_speed = TIMERS_PER_SECOND / 2 / midifile->divisions; /* 120 bpm */ - midi_new_speed = -1; - midi_pos_speed = midi_speed * midifile->divisions; - midi_timer_speed = 0; - midi_seeking = 0; - midi_looping = 0; - - for (c=0; c<16; c++) { - midi_channel[c].patch = 0; - if (midi_driver->raw_midi) - raw_program_change(c, 0); - } - - for (c=0; ctrack[c].data) { - midi_track[c].pos = midi->track[c].data; - midi_track[c].timer = parse_var_len((AL_CONST unsigned char**) &midi_track[c].pos); - midi_track[c].timer *= midi_speed; - } - else { - midi_track[c].pos = NULL; - midi_track[c].timer = LONG_MAX; - } - midi_track[c].running_status = 0; - } -} - -END_OF_STATIC_FUNCTION(prepare_to_play); - - - -/* play_midi: - * Starts playing the specified MIDI file. If loop is set, the MIDI file - * will be repeated until replaced with something else, otherwise it will - * stop at the end of the file. Passing a NULL MIDI file will stop whatever - * music is currently playing: allegro.h defines the macro stop_midi() to - * be play_midi(NULL, FALSE); Returns non-zero if an error occurs (this - * may happen if a patch-caching wavetable driver is unable to load the - * required samples). - */ -int play_midi(MIDI *midi, int loop) -{ - int c; - - remove_int(midi_player); - - for (c=0; c<16; c++) { - all_notes_off(c); - all_sound_off(c); - } - - if (midi) { - if (!midi_loaded_patches) - if (load_patches(midi) != 0) - return -1; - - midi_loop = loop; - midi_loop_start = -1; - midi_loop_end = -1; - - prepare_to_play(midi); - - /* arbitrary speed, midi_player() will adjust it */ - install_int(midi_player, 20); - } - else { - midifile = NULL; - - if (midi_pos > 0) - midi_pos = -midi_pos; - else if (midi_pos == 0) - midi_pos = -1; - } - - return 0; -} - -END_OF_FUNCTION(play_midi); - - - -/* play_looped_midi: - * Like play_midi(), but the file loops from the specified end position - * back to the specified start position (the end position can be -1 to - * indicate the end of the file). - */ -int play_looped_midi(MIDI *midi, int loop_start, int loop_end) -{ - if (play_midi(midi, TRUE) != 0) - return -1; - - midi_loop_start = loop_start; - midi_loop_end = loop_end; - - return 0; -} - - - -/* stop_midi: - * Stops whatever MIDI file is currently playing. - */ -void stop_midi(void) -{ - play_midi(NULL, FALSE); -} - -END_OF_FUNCTION(stop_midi); - - - -/* midi_pause: - * Pauses the currently playing MIDI file. - */ -void midi_pause(void) -{ - int c; - - if (!midifile) - return; - - remove_int(midi_player); - - for (c=0; c<16; c++) { - all_notes_off(c); - all_sound_off(c); - } -} - -END_OF_FUNCTION(midi_pause); - - - -/* midi_resume: - * Resumes playing a paused MIDI file. - */ -void midi_resume(void) -{ - if (!midifile) - return; - - install_int_ex(midi_player, midi_timer_speed); -} - -END_OF_FUNCTION(midi_resume); - - - -/* midi_seek: - * Seeks to the given midi_pos in the current MIDI file. If the target - * is earlier in the file than the current midi_pos it seeks from the - * beginning; otherwise it seeks from the current position. Returns zero - * if successful, non-zero if it hit the end of the file (1 means it - * stopped playing, 2 means it looped back to the start). - */ -int midi_seek(int target) -{ - int old_midi_loop; - MIDI *old_midifile; - MIDI_DRIVER *old_driver; - int old_patch[16]; - int old_volume[16]; - int old_pan[16]; - int old_pitch_bend[16]; - int c; - - if (!midifile) - return -1; - - /* first stop the player */ - midi_pause(); - - /* store current settings */ - for (c=0; c<16; c++) { - old_patch[c] = midi_channel[c].patch; - old_volume[c] = midi_channel[c].volume; - old_pan[c] = midi_channel[c].pan; - old_pitch_bend[c] = midi_channel[c].pitch_bend; - } - - /* save some variables and give temporary values */ - old_driver = midi_driver; - midi_driver = &_midi_none; - old_midi_loop = midi_loop; - midi_loop = 0; - old_midifile = midifile; - - /* set flag to tell midi_player not to reinstall itself */ - midi_seeking = 1; - - /* are we seeking backwards? If so, skip back to the start of the file */ - if (target <= midi_pos) - prepare_to_play(midifile); - - /* now sit back and let midi_player get to the position */ - while ((midi_pos < target) && (midi_pos >= 0)) { - int mmpc = midi_pos_counter; - int mmp = midi_pos; - - mmpc -= midi_timer_speed; - while (mmpc <= 0) { - mmpc += midi_pos_speed; - mmp++; - } - - if (mmp >= target) - break; - - midi_player(); - } - - /* restore previously saved variables */ - midi_loop = old_midi_loop; - midi_driver = old_driver; - midi_seeking = 0; - - if (midi_pos >= 0) { - /* refresh the driver with any changed parameters */ - if (midi_driver->raw_midi) { - for (c=0; c<16; c++) { - /* program change (this sets the volume as well) */ - if ((midi_channel[c].patch != old_patch[c]) || - (midi_channel[c].volume != old_volume[c])) - raw_program_change(c, midi_channel[c].patch); - - /* pan */ - if (midi_channel[c].pan != old_pan[c]) { - midi_driver->raw_midi(0xB0+c); - midi_driver->raw_midi(10); - midi_driver->raw_midi(midi_channel[c].pan); - } - - /* pitch bend */ - if (midi_channel[c].pitch_bend != old_pitch_bend[c]) { - midi_driver->raw_midi(0xE0+c); - midi_driver->raw_midi(midi_channel[c].pitch_bend & 0x7F); - midi_driver->raw_midi(midi_channel[c].pitch_bend >> 7); - } - } - } - - /* if we didn't hit the end of the file, continue playing */ - if (!midi_looping) - install_int(midi_player, 20); - - return 0; - } - - if ((midi_loop) && (!midi_looping)) { /* was file looped? */ - prepare_to_play(old_midifile); - install_int(midi_player, 20); - return 2; /* seek past EOF => file restarted */ - } - - return 1; /* seek past EOF => file stopped */ -} - -END_OF_FUNCTION(midi_seek); - - - -/* get_midi_length: - * Returns the length, in seconds, of the specified midi. This will stop any - * currently playing midi. Don't call it too often, since it simulates playing - * all of the midi to get the time even if the midi contains tempo changes. - */ -int get_midi_length(MIDI *midi) -{ - play_midi(midi, 0); - while (midi_pos < 0); /* Without this, midi_seek won't work. */ - midi_seek(INT_MAX); - return midi_time; -} - - - -/* midi_out: - * Inserts MIDI command bytes into the output stream, in realtime. - */ -void midi_out(unsigned char *data, int length) -{ - unsigned char *pos = data; - unsigned char running_status = 0; - long timer = 0; - ASSERT(data); - - midi_semaphore = TRUE; - _midi_tick++; - - while (pos < data+length) - process_midi_event((AL_CONST unsigned char**) &pos, &running_status, &timer); - - update_controllers(); - - midi_semaphore = FALSE; -} - - - -/* load_midi_patches: - * Tells the MIDI driver to preload the entire sample set. - */ -int load_midi_patches(void) -{ - char patches[128], drums[128]; - int c, ret; - - for (c=0; c<128; c++) - patches[c] = drums[c] = TRUE; - - midi_semaphore = TRUE; - ret = midi_driver->load_patches(patches, drums); - midi_semaphore = FALSE; - - midi_loaded_patches = TRUE; - - return ret; -} - - - -/* midi_lock_mem: - * Locks all the memory that the midi player touches inside the timer - * interrupt handler (which is most of it). - */ -static void midi_lock_mem(void) -{ - LOCK_VARIABLE(midi_pos); - LOCK_VARIABLE(midi_time); - LOCK_VARIABLE(midi_timers); - LOCK_VARIABLE(midi_pos_counter); - LOCK_VARIABLE(_midi_tick); - LOCK_VARIABLE(midifile); - LOCK_VARIABLE(midi_semaphore); - LOCK_VARIABLE(midi_loop); - LOCK_VARIABLE(midi_loop_start); - LOCK_VARIABLE(midi_loop_end); - LOCK_VARIABLE(midi_timer_speed); - LOCK_VARIABLE(midi_pos_speed); - LOCK_VARIABLE(midi_speed); - LOCK_VARIABLE(midi_new_speed); - LOCK_VARIABLE(old_midi_volume); - LOCK_VARIABLE(midi_alloc_channel); - LOCK_VARIABLE(midi_alloc_note); - LOCK_VARIABLE(midi_alloc_vol); - LOCK_VARIABLE(midi_track); - LOCK_VARIABLE(midi_voice); - LOCK_VARIABLE(midi_channel); - LOCK_VARIABLE(midi_waiting); - LOCK_VARIABLE(patch_table); - LOCK_VARIABLE(midi_msg_callback); - LOCK_VARIABLE(midi_meta_callback); - LOCK_VARIABLE(midi_sysex_callback); - LOCK_VARIABLE(midi_seeking); - LOCK_VARIABLE(midi_looping); - LOCK_FUNCTION(parse_var_len); - LOCK_FUNCTION(raw_program_change); - LOCK_FUNCTION(midi_note_off); - LOCK_FUNCTION(_midi_allocate_voice); - LOCK_FUNCTION(midi_note_on); - LOCK_FUNCTION(all_notes_off); - LOCK_FUNCTION(all_sound_off); - LOCK_FUNCTION(reset_controllers); - LOCK_FUNCTION(update_controllers); - LOCK_FUNCTION(process_controller); - LOCK_FUNCTION(process_meta_event); - LOCK_FUNCTION(process_midi_event); - LOCK_FUNCTION(midi_player); - LOCK_FUNCTION(prepare_to_play); - LOCK_FUNCTION(play_midi); - LOCK_FUNCTION(stop_midi); - LOCK_FUNCTION(midi_pause); - LOCK_FUNCTION(midi_resume); - LOCK_FUNCTION(midi_seek); -} - - - -/* midi_constructor: - * Register my functions with the code in sound.c. - */ -#ifdef ALLEGRO_USE_CONSTRUCTOR - CONSTRUCTOR_FUNCTION(void _midi_constructor(void)); -#endif - -static struct _AL_LINKER_MIDI midi_linker = { - midi_init, - midi_exit -}; - -void _midi_constructor(void) -{ - _al_linker_midi = &midi_linker; -} - diff --git a/src/allegro/src/mixer.c b/src/allegro/src/mixer.c deleted file mode 100644 index d14d574f3..000000000 --- a/src/allegro/src/mixer.c +++ /dev/null @@ -1,1579 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * Sample mixing code. - * - * By Shawn Hargreaves. - * - * Proper 16 bit sample support added by Salvador Eduardo Tropea. - * - * Ben Davis provided the set_volume_per_voice() functionality, - * programmed the silent mixer so that silent voices don't freeze, - * and fixed a few minor bugs elsewhere. - * - * Synchronization added by Sam Hocevar. - * - * Chris Robinson included functions to report the mixer's settings, - * switched to signed 24-bit mixing, and cleaned up some of the mess the - * code had gathered. - * - * See readme.txt for copyright information. - */ - - -#include - -#include "allegro.h" -#include "allegro/internal/aintern.h" - - - -typedef struct MIXER_VOICE -{ - int playing; /* are we active? */ - int channels; /* # of chaanels for input data? */ - int bits; /* sample bit-depth */ - union { - unsigned char *u8; /* data for 8 bit samples */ - unsigned short *u16; /* data for 16 bit samples */ - void *buffer; /* generic data pointer */ - } data; - long pos; /* fixed point position in sample */ - long diff; /* fixed point speed of play */ - long len; /* fixed point sample length */ - long loop_start; /* fixed point loop start position */ - long loop_end; /* fixed point loop end position */ - int lvol; /* left channel volume */ - int rvol; /* right channel volume */ -} MIXER_VOICE; - - -/* MIX_FIX_SHIFT must be <= (sizeof(int)*8)-24 */ -#define MIX_FIX_SHIFT 8 -#define MIX_FIX_SCALE (1< 2)) - quality = 2; - if(mix_channels == 1) - quality = 0; - - _sound_hq = quality; -} - -END_OF_FUNCTION(set_mixer_quality); - - - -/* get_mixer_quality: - * Returns the current mixing quality, as loaded by the 'quality' config - * variable, or a previous call to set_mixer_quality. - */ -int get_mixer_quality(void) -{ - return _sound_hq; -} - -END_OF_FUNCTION(get_mixer_quality); - - - -/* get_mixer_frequency: - * Returns the mixer frequency, in Hz. - */ -int get_mixer_frequency(void) -{ - return mix_freq; -} - -END_OF_FUNCTION(get_mixer_frequency); - - - -/* get_mixer_bits: - * Returns the mixer bitdepth. - */ -int get_mixer_bits(void) -{ - return mix_bits; -} - -END_OF_FUNCTION(get_mixer_bits); - - - -/* get_mixer_channels: - * Returns the number of output channels. - */ -int get_mixer_channels(void) -{ - return mix_channels; -} - -END_OF_FUNCTION(get_mixer_channels); - - - -/* get_mixer_voices: - * Returns the number of voices allocated to the mixer. - */ -int get_mixer_voices(void) -{ - return mix_voices; -} - -END_OF_FUNCTION(get_mixer_voices); - - - -/* get_mixer_buffer_length: - * Returns the number of samples per channel in the mixer buffer. - */ -int get_mixer_buffer_length(void) -{ - return mix_size; -} - -END_OF_FUNCTION(get_mixer_buffer_length); - - - -/* clamp_volume: - * Clamps an integer between 0 and the specified (positive!) value. - */ -static INLINE int clamp_val(int i, int max) -{ - /* Clamp to 0 */ - i &= (~i) >> 31; - - /* Clamp to max */ - i -= max; - i &= i >> 31; - i += max; - - return i; -} - - -/* set_volume_per_voice: - * Enables the programmer (not the end-user) to alter the maximum volume of - * each voice: - * - pass -1 for Allegro to work as it did before this option was provided - * (volume dependent on number of voices), - * - pass 0 if you want a single centred sample to be as loud as possible - * without distorting, - * - pass 1 if you want to pan a full-volume sample to one side without - * distortion, - * - each time the scale parameter increases by 1, the volume halves. - */ -static void update_mixer_volume(MIXER_VOICE *mv, PHYS_VOICE *pv); -void set_volume_per_voice(int scale) -{ - int i; - - if(scale < 0) { - /* Work out the # of voices and the needed scale */ - scale = 1; - for(i = 1;i < mix_voices;i <<= 1) - scale++; - - /* Backwards compatiblity with 3.12 */ - if(scale < 2) - scale = 2; - } - - /* Update the mixer voices' volumes */ -#ifdef ALLEGRO_MULTITHREADED - if(mixer_mutex) - system_driver->lock_mutex(mixer_mutex); -#endif - voice_volume_scale = scale; - - for(i = 0;i < mix_voices;++i) - update_mixer_volume(mixer_voice+i, _phys_voice+i); -#ifdef ALLEGRO_MULTITHREADED - if(mixer_mutex) - system_driver->unlock_mutex(mixer_mutex); -#endif -} - -END_OF_FUNCTION(set_volume_per_voice); - - - -/* _mixer_init: - * Initialises the sample mixing code, returning 0 on success. You should - * pass it the number of samples you want it to mix each time the refill - * buffer routine is called, the sample rate to mix at, and two flags - * indicating whether the mixing should be done in stereo or mono and with - * eight or sixteen bits. The bufsize parameter is the number of samples, - * not bytes. It should take into account whether you are working in stereo - * or not (eg. double it if in stereo), but it should not be affected by - * whether each sample is 8 or 16 bits. - */ -int _mixer_init(int bufsize, int freq, int stereo, int is16bit, int *voices) -{ - int i, j; - - if((_sound_hq < 0) || (_sound_hq > 2)) - _sound_hq = 2; - - mix_voices = *voices; - if(mix_voices > MIXER_MAX_SFX) - *voices = mix_voices = MIXER_MAX_SFX; - - mix_freq = freq; - mix_channels = (stereo ? 2 : 1); - mix_bits = (is16bit ? 16 : 8); - mix_size = bufsize / mix_channels; - - for (i=0; icreate_mutex(); - if (!mixer_mutex) { - _AL_FREE(mix_buffer); - mix_buffer = NULL; - mix_size = 0; - mix_freq = 0; - mix_channels = 0; - mix_bits = 0; - return -1; - } -#endif - - return 0; -} - - - -/* _mixer_exit: - * Cleans up the sample mixer code when you are done with it. - */ -void _mixer_exit(void) -{ -#ifdef ALLEGRO_MULTITHREADED - system_driver->destroy_mutex(mixer_mutex); - mixer_mutex = NULL; -#endif - - if (mix_buffer) - _AL_FREE(mix_buffer); - mix_buffer = NULL; - - mix_size = 0; - mix_freq = 0; - mix_channels = 0; - mix_bits = 0; - mix_voices = 0; -} - - -/* update_mixer_volume: - * Called whenever the voice volume or pan changes, to update the mixer - * amplification table indexes. - */ -static void update_mixer_volume(MIXER_VOICE *mv, PHYS_VOICE *pv) -{ - int vol, pan, lvol, rvol; - - /* now use full 16 bit volume ranges */ - vol = pv->vol>>12; - pan = pv->pan>>12; - - lvol = vol * (255-pan); - rvol = vol * pan; - - /* Adjust for 255*255 < 256*256-1 */ - lvol += lvol >> 7; - rvol += rvol >> 7; - - /* Apply voice volume scale and clamp */ - mv->lvol = clamp_val((lvol<<1) >> voice_volume_scale, 65535); - mv->rvol = clamp_val((rvol<<1) >> voice_volume_scale, 65535); - - if (!_sound_hq) { - /* Scale 16-bit -> table size */ - mv->lvol = mv->lvol * MIX_VOLUME_LEVELS / 65536; - mv->rvol = mv->rvol * MIX_VOLUME_LEVELS / 65536; - } -} - -END_OF_STATIC_FUNCTION(update_mixer_volume); - - - -/* update_mixer_freq: - * Called whenever the voice frequency changes, to update the sample - * delta value. - */ -static INLINE void update_mixer_freq(MIXER_VOICE *mv, PHYS_VOICE *pv) -{ - mv->diff = (pv->freq >> (12 - MIX_FIX_SHIFT)) / mix_freq; - - if (pv->playmode & PLAYMODE_BACKWARD) - mv->diff = -mv->diff; -} - - - -/* update_mixer: - * Helper for updating the volume ramp and pitch/pan sweep status. - */ -static void update_mixer(MIXER_VOICE *spl, PHYS_VOICE *voice, int len) -{ - if ((voice->dvol) || (voice->dpan)) { - /* update volume ramp */ - if (voice->dvol) { - voice->vol += voice->dvol; - if (((voice->dvol > 0) && (voice->vol >= voice->target_vol)) || - ((voice->dvol < 0) && (voice->vol <= voice->target_vol))) { - voice->vol = voice->target_vol; - voice->dvol = 0; - } - } - - /* update pan sweep */ - if (voice->dpan) { - voice->pan += voice->dpan; - if (((voice->dpan > 0) && (voice->pan >= voice->target_pan)) || - ((voice->dpan < 0) && (voice->pan <= voice->target_pan))) { - voice->pan = voice->target_pan; - voice->dpan = 0; - } - } - - update_mixer_volume(spl, voice); - } - - /* update frequency sweep */ - if (voice->dfreq) { - voice->freq += voice->dfreq; - if (((voice->dfreq > 0) && (voice->freq >= voice->target_freq)) || - ((voice->dfreq < 0) && (voice->freq <= voice->target_freq))) { - voice->freq = voice->target_freq; - voice->dfreq = 0; - } - - update_mixer_freq(spl, voice); - } -} - -END_OF_STATIC_FUNCTION(update_mixer); - -/* update_silent_mixer: - * Another helper for updating the volume ramp and pitch/pan sweep status. - * This version is designed for the silent mixer, and it is called just once - * per buffer. The len parameter is used to work out how much the values - * must be adjusted. - */ -static void update_silent_mixer(MIXER_VOICE *spl, PHYS_VOICE *voice, int len) -{ - len >>= UPDATE_FREQ_SHIFT; - - /* update pan sweep */ - if (voice->dpan) { - voice->pan += voice->dpan * len; - if (((voice->dpan > 0) && (voice->pan >= voice->target_pan)) || - ((voice->dpan < 0) && (voice->pan <= voice->target_pan))) { - voice->pan = voice->target_pan; - voice->dpan = 0; - } - } - - /* update frequency sweep */ - if (voice->dfreq) { - voice->freq += voice->dfreq * len; - if (((voice->dfreq > 0) && (voice->freq >= voice->target_freq)) || - ((voice->dfreq < 0) && (voice->freq <= voice->target_freq))) { - voice->freq = voice->target_freq; - voice->dfreq = 0; - } - - update_mixer_freq(spl, voice); - } -} - -END_OF_STATIC_FUNCTION(update_silent_mixer); - - - -/* helper for constructing the body of a sample mixing routine */ -#define MIXER() \ -{ \ - if ((voice->playmode & PLAYMODE_LOOP) && \ - (spl->loop_start < spl->loop_end)) { \ - \ - if (voice->playmode & PLAYMODE_BACKWARD) { \ - /* mix a backward looping sample */ \ - while (len--) { \ - MIX(); \ - spl->pos += spl->diff; \ - if (spl->pos < spl->loop_start) { \ - if (voice->playmode & PLAYMODE_BIDIR) { \ - spl->diff = -spl->diff; \ - /* however far the sample has overshot, move it the same */\ - /* distance from the loop point, within the loop section */\ - spl->pos = (spl->loop_start << 1) - spl->pos; \ - voice->playmode ^= PLAYMODE_BACKWARD; \ - } \ - else \ - spl->pos += (spl->loop_end - spl->loop_start); \ - } \ - if ((len & (UPDATE_FREQ-1)) == 0) \ - update_mixer(spl, voice, len); \ - } \ - } \ - else { \ - /* mix a forward looping sample */ \ - while (len--) { \ - MIX(); \ - spl->pos += spl->diff; \ - if (spl->pos >= spl->loop_end) { \ - if (voice->playmode & PLAYMODE_BIDIR) { \ - spl->diff = -spl->diff; \ - /* however far the sample has overshot, move it the same */\ - /* distance from the loop point, within the loop section */\ - spl->pos = ((spl->loop_end - 1) << 1) - spl->pos; \ - voice->playmode ^= PLAYMODE_BACKWARD; \ - } \ - else \ - spl->pos -= (spl->loop_end - spl->loop_start); \ - } \ - if ((len & (UPDATE_FREQ-1)) == 0) \ - update_mixer(spl, voice, len); \ - } \ - } \ - } \ - else { \ - /* mix a non-looping sample */ \ - while (len--) { \ - MIX(); \ - spl->pos += spl->diff; \ - if ((unsigned long)spl->pos >= (unsigned long)spl->len) { \ - /* note: we don't need a different version for reverse play, */ \ - /* as this will wrap and automatically do the Right Thing */ \ - spl->playing = FALSE; \ - return; \ - } \ - if ((len & (UPDATE_FREQ-1)) == 0) \ - update_mixer(spl, voice, len); \ - } \ - } \ -} - - -/* mix_silent_samples: - * This is used when the voice is silent, instead of the other - * mix_*_samples() functions. It just extrapolates the sample position, - * and stops the sample if it reaches the end and isn't set to loop. - * Since no mixing is necessary, this function is much faster than - * its friends. In addition, no buffer parameter is required, - * and the same function can be used for all sample types. - * - * There is a catch. All the mix_stereo_*_samples() and - * mix_hq?_*_samples() functions (those which write to a stereo mixing - * buffer) divide len by 2 before using it in the MIXER() macro. - * Therefore, all the mix_silent_samples() for stereo buffers must divide - * the len parameter by 2. - */ -static void mix_silent_samples(MIXER_VOICE *spl, PHYS_VOICE *voice, int len) -{ - if ((voice->playmode & PLAYMODE_LOOP) && - (spl->loop_start < spl->loop_end)) { - - if (voice->playmode & PLAYMODE_BACKWARD) { - /* mix a backward looping sample */ - spl->pos += spl->diff * len; - if (spl->pos < spl->loop_start) { - if (voice->playmode & PLAYMODE_BIDIR) { - do { - spl->diff = -spl->diff; - spl->pos = (spl->loop_start << 1) - spl->pos; - voice->playmode ^= PLAYMODE_BACKWARD; - if (spl->pos < spl->loop_end) break; - spl->diff = -spl->diff; - spl->pos = ((spl->loop_end - 1) << 1) - spl->pos; - voice->playmode ^= PLAYMODE_BACKWARD; - } while (spl->pos < spl->loop_start); - } - else { - do { - spl->pos += (spl->loop_end - spl->loop_start); - } while (spl->pos < spl->loop_start); - } - } - update_silent_mixer(spl, voice, len); - } - else { - /* mix a forward looping sample */ - spl->pos += spl->diff * len; - if (spl->pos >= spl->loop_end) { - if (voice->playmode & PLAYMODE_BIDIR) { - do { - spl->diff = -spl->diff; - spl->pos = ((spl->loop_end - 1) << 1) - spl->pos; - voice->playmode ^= PLAYMODE_BACKWARD; - if (spl->pos >= spl->loop_start) break; - spl->diff = -spl->diff; - spl->pos = (spl->loop_start << 1) - spl->pos; - voice->playmode ^= PLAYMODE_BACKWARD; - } while (spl->pos >= spl->loop_end); - } - else { - do { - spl->pos -= (spl->loop_end - spl->loop_start); - } while (spl->pos >= spl->loop_end); - } - } - update_silent_mixer(spl, voice, len); - } - } - else { - /* mix a non-looping sample */ - spl->pos += spl->diff * len; - if ((unsigned long)spl->pos >= (unsigned long)spl->len) { - /* note: we don't need a different version for reverse play, */ - /* as this will wrap and automatically do the Right Thing */ - spl->playing = FALSE; - return; - } - update_silent_mixer(spl, voice, len); - } -} - -END_OF_STATIC_FUNCTION(mix_silent_samples); - - - -/* mix_mono_8x1_samples: - * Mixes from an eight bit sample into a mono buffer, until either len - * samples have been mixed or until the end of the sample is reached. - */ -static void mix_mono_8x1_samples(MIXER_VOICE *spl, PHYS_VOICE *voice, signed int *buf, int len) -{ - signed int *lvol = (int *)(mix_vol_table + (spl->lvol>>1)); - signed int *rvol = (int *)(mix_vol_table + (spl->rvol>>1)); - - #define MIX() \ - *(buf) += lvol[spl->data.u8[spl->pos>>MIX_FIX_SHIFT]]; \ - *(buf++) += rvol[spl->data.u8[spl->pos>>MIX_FIX_SHIFT]]; - - MIXER(); - - #undef MIX -} - -END_OF_STATIC_FUNCTION(mix_mono_8x1_samples); - - - -/* mix_mono_8x2_samples: - * Mixes from an eight bit stereo sample into a mono buffer, until either - * len samples have been mixed or until the end of the sample is reached. - */ -static void mix_mono_8x2_samples(MIXER_VOICE *spl, PHYS_VOICE *voice, signed int *buf, int len) -{ - signed int *lvol = (int *)(mix_vol_table + (spl->lvol>>1)); - signed int *rvol = (int *)(mix_vol_table + (spl->rvol>>1)); - - #define MIX() \ - *(buf) += lvol[spl->data.u8[(spl->pos>>MIX_FIX_SHIFT)*2 ]]; \ - *(buf++) += rvol[spl->data.u8[(spl->pos>>MIX_FIX_SHIFT)*2+1]]; - - MIXER(); - - #undef MIX -} - -END_OF_STATIC_FUNCTION(mix_mono_8x2_samples); - - - -/* mix_mono_16x1_samples: - * Mixes from a 16 bit sample into a mono buffer, until either len samples - * have been mixed or until the end of the sample is reached. - */ -static void mix_mono_16x1_samples(MIXER_VOICE *spl, PHYS_VOICE *voice, signed int *buf, int len) -{ - signed int *lvol = (int *)(mix_vol_table + (spl->lvol>>1)); - signed int *rvol = (int *)(mix_vol_table + (spl->rvol>>1)); - - #define MIX() \ - *(buf) += lvol[(spl->data.u16[spl->pos>>MIX_FIX_SHIFT])>>8]; \ - *(buf++) += rvol[(spl->data.u16[spl->pos>>MIX_FIX_SHIFT])>>8]; - - MIXER(); - - #undef MIX -} - -END_OF_STATIC_FUNCTION(mix_mono_16x1_samples); - - - -/* mix_mono_16x2_samples: - * Mixes from a 16 bit stereo sample into a mono buffer, until either len - * samples have been mixed or until the end of the sample is reached. - */ -static void mix_mono_16x2_samples(MIXER_VOICE *spl, PHYS_VOICE *voice, signed int *buf, int len) -{ - signed int *lvol = (int *)(mix_vol_table + (spl->lvol>>1)); - signed int *rvol = (int *)(mix_vol_table + (spl->rvol>>1)); - - #define MIX() \ - *(buf) += lvol[(spl->data.u16[(spl->pos>>MIX_FIX_SHIFT)*2 ])>>8]; \ - *(buf++) += rvol[(spl->data.u16[(spl->pos>>MIX_FIX_SHIFT)*2+1])>>8]; - - MIXER(); - - #undef MIX -} - -END_OF_STATIC_FUNCTION(mix_mono_16x2_samples); - - - -/* mix_stereo_8x1_samples: - * Mixes from an eight bit sample into a stereo buffer, until either len - * samples have been mixed or until the end of the sample is reached. - */ -static void mix_stereo_8x1_samples(MIXER_VOICE *spl, PHYS_VOICE *voice, signed int *buf, int len) -{ - signed int *lvol = (int *)(mix_vol_table + spl->lvol); - signed int *rvol = (int *)(mix_vol_table + spl->rvol); - - #define MIX() \ - *(buf++) += lvol[spl->data.u8[spl->pos>>MIX_FIX_SHIFT]]; \ - *(buf++) += rvol[spl->data.u8[spl->pos>>MIX_FIX_SHIFT]]; - - MIXER(); - - #undef MIX -} - -END_OF_STATIC_FUNCTION(mix_stereo_8x1_samples); - - - -/* mix_stereo_8x2_samples: - * Mixes from an eight bit stereo sample into a stereo buffer, until either - * len samples have been mixed or until the end of the sample is reached. - */ -static void mix_stereo_8x2_samples(MIXER_VOICE *spl, PHYS_VOICE *voice, signed int *buf, int len) -{ - signed int *lvol = (int *)(mix_vol_table + spl->lvol); - signed int *rvol = (int *)(mix_vol_table + spl->rvol); - - #define MIX() \ - *(buf++) += lvol[spl->data.u8[(spl->pos>>MIX_FIX_SHIFT)*2 ]]; \ - *(buf++) += rvol[spl->data.u8[(spl->pos>>MIX_FIX_SHIFT)*2+1]]; - - MIXER(); - - #undef MIX -} - -END_OF_STATIC_FUNCTION(mix_stereo_8x2_samples); - - - -/* mix_stereo_16x1_samples: - * Mixes from a 16 bit sample into a stereo buffer, until either len samples - * have been mixed or until the end of the sample is reached. - */ -static void mix_stereo_16x1_samples(MIXER_VOICE *spl, PHYS_VOICE *voice, signed int *buf, int len) -{ - signed int *lvol = (int *)(mix_vol_table + spl->lvol); - signed int *rvol = (int *)(mix_vol_table + spl->rvol); - - #define MIX() \ - *(buf++) += lvol[(spl->data.u16[spl->pos>>MIX_FIX_SHIFT])>>8]; \ - *(buf++) += rvol[(spl->data.u16[spl->pos>>MIX_FIX_SHIFT])>>8]; - - MIXER(); - - #undef MIX -} - -END_OF_STATIC_FUNCTION(mix_stereo_16x1_samples); - - - -/* mix_stereo_16x2_samples: - * Mixes from a 16 bit stereo sample into a stereo buffer, until either len - * samples have been mixed or until the end of the sample is reached. - */ -static void mix_stereo_16x2_samples(MIXER_VOICE *spl, PHYS_VOICE *voice, signed int *buf, int len) -{ - signed int *lvol = (int *)(mix_vol_table + spl->lvol); - signed int *rvol = (int *)(mix_vol_table + spl->rvol); - - #define MIX() \ - *(buf++) += lvol[(spl->data.u16[(spl->pos>>MIX_FIX_SHIFT)*2 ])>>8]; \ - *(buf++) += rvol[(spl->data.u16[(spl->pos>>MIX_FIX_SHIFT)*2+1])>>8]; - - MIXER(); - - #undef MIX -} - -END_OF_STATIC_FUNCTION(mix_stereo_16x2_samples); - -/* mix_hq1_8x1_samples: - * Mixes from a mono 8 bit sample into a high quality stereo buffer, - * until either len samples have been mixed or until the end of the - * sample is reached. - */ -static void mix_hq1_8x1_samples(MIXER_VOICE *spl, PHYS_VOICE *voice, signed int *buf, int len) -{ - int lvol = spl->lvol; - int rvol = spl->rvol; - - #define MIX() \ - *(buf++) += (spl->data.u8[spl->pos>>MIX_FIX_SHIFT]-0x80) * lvol; \ - *(buf++) += (spl->data.u8[spl->pos>>MIX_FIX_SHIFT]-0x80) * rvol; - - MIXER(); - - #undef MIX -} - -END_OF_STATIC_FUNCTION(mix_hq1_8x1_samples); - - - -/* mix_hq1_8x2_samples: - * Mixes from a stereo 8 bit sample into a high quality stereo buffer, - * until either len samples have been mixed or until the end of the - * sample is reached. - */ -static void mix_hq1_8x2_samples(MIXER_VOICE *spl, PHYS_VOICE *voice, signed int *buf, int len) -{ - int lvol = spl->lvol; - int rvol = spl->rvol; - - #define MIX() \ - *(buf++) += (spl->data.u8[(spl->pos>>MIX_FIX_SHIFT)*2 ]-0x80) * lvol; \ - *(buf++) += (spl->data.u8[(spl->pos>>MIX_FIX_SHIFT)*2+1]-0x80) * rvol; - - MIXER(); - - #undef MIX -} - -END_OF_STATIC_FUNCTION(mix_hq1_8x2_samples); - - - -/* mix_hq1_16x1_samples: - * Mixes from a mono 16 bit sample into a high-quality stereo buffer, - * until either len samples have been mixed or until the end of the sample - * is reached. - */ -static void mix_hq1_16x1_samples(MIXER_VOICE *spl, PHYS_VOICE *voice, signed int *buf, int len) -{ - int lvol = spl->lvol; - int rvol = spl->rvol; - - #define MIX() \ - *(buf++) += ((spl->data.u16[spl->pos>>MIX_FIX_SHIFT]-0x8000)*lvol)>>8; \ - *(buf++) += ((spl->data.u16[spl->pos>>MIX_FIX_SHIFT]-0x8000)*rvol)>>8; - - MIXER(); - - #undef MIX -} - -END_OF_STATIC_FUNCTION(mix_hq1_16x1_samples); - - - -/* mix_hq1_16x2_samples: - * Mixes from a stereo 16 bit sample into a high-quality stereo buffer, - * until either len samples have been mixed or until the end of the sample - * is reached. - */ -static void mix_hq1_16x2_samples(MIXER_VOICE *spl, PHYS_VOICE *voice, signed int *buf, int len) -{ - int lvol = spl->lvol; - int rvol = spl->rvol; - - #define MIX() \ - *(buf++) += ((spl->data.u16[(spl->pos>>MIX_FIX_SHIFT)*2 ]-0x8000)*lvol)>>8;\ - *(buf++) += ((spl->data.u16[(spl->pos>>MIX_FIX_SHIFT)*2+1]-0x8000)*rvol)>>8; - - MIXER(); - - #undef MIX -} - -END_OF_STATIC_FUNCTION(mix_hq1_16x2_samples); - - -/* Helper to apply a 16-bit volume to a 24-bit sample */ -#define MULSC(a, b) ((int)((LONG_LONG)((a) << 4) * ((b) << 12) >> 32)) - -/* mix_hq2_8x1_samples: - * Mixes from a mono 8 bit sample into an interpolated stereo buffer, - * until either len samples have been mixed or until the end of the - * sample is reached. - */ -static void mix_hq2_8x1_samples(MIXER_VOICE *spl, PHYS_VOICE *voice, signed int *buf, int len) -{ - int lvol = spl->lvol; - int rvol = spl->rvol; - int v, v1, v2; - - #define MIX() \ - v = spl->pos>>MIX_FIX_SHIFT; \ - \ - v1 = (spl->data.u8[v]<<16) - 0x800000; \ - \ - if (spl->pos >= spl->len-MIX_FIX_SCALE) { \ - if ((voice->playmode & (PLAYMODE_LOOP | \ - PLAYMODE_BIDIR)) == PLAYMODE_LOOP && \ - spl->loop_start < spl->loop_end && spl->loop_end == spl->len) \ - v2 = (spl->data.u8[spl->loop_start>>MIX_FIX_SHIFT]<<16)-0x800000;\ - else \ - v2 = 0; \ - } \ - else \ - v2 = (spl->data.u8[v+1]<<16) - 0x800000; \ - \ - v = spl->pos & (MIX_FIX_SCALE-1); \ - v = ((v2*v) + (v1*(MIX_FIX_SCALE-v))) >> MIX_FIX_SHIFT; \ - \ - *(buf++) += MULSC(v, lvol); \ - *(buf++) += MULSC(v, rvol); - - MIXER(); - - #undef MIX -} - -END_OF_STATIC_FUNCTION(mix_hq2_8x1_samples); - - - -/* mix_hq2_8x2_samples: - * Mixes from a stereo 8 bit sample into an interpolated stereo buffer, - * until either len samples have been mixed or until the end of the - * sample is reached. - */ -static void mix_hq2_8x2_samples(MIXER_VOICE *spl, PHYS_VOICE *voice, signed int *buf, int len) -{ - int lvol = spl->lvol; - int rvol = spl->rvol; - int v, va, v1a, v2a, vb, v1b, v2b; - - #define MIX() \ - v = (spl->pos>>MIX_FIX_SHIFT) << 1; /* x2 for stereo */ \ - \ - v1a = (spl->data.u8[v]<<16) - 0x800000; \ - v1b = (spl->data.u8[v+1]<<16) - 0x800000; \ - \ - if (spl->pos >= spl->len-MIX_FIX_SCALE) { \ - if ((voice->playmode & (PLAYMODE_LOOP | \ - PLAYMODE_BIDIR)) == PLAYMODE_LOOP && \ - spl->loop_start < spl->loop_end && spl->loop_end == spl->len) { \ - v2a = (spl->data.u8[((spl->loop_start>>MIX_FIX_SHIFT)<<1)]<<16) - 0x800000;\ - v2b = (spl->data.u8[((spl->loop_start>>MIX_FIX_SHIFT)<<1)+1]<<16) - 0x800000;\ - } \ - else \ - v2a = v2b = 0; \ - } \ - else { \ - v2a = (spl->data.u8[v+2]<<16) - 0x800000; \ - v2b = (spl->data.u8[v+3]<<16) - 0x800000; \ - } \ - \ - v = spl->pos & (MIX_FIX_SCALE-1); \ - va = ((v2a*v) + (v1a*(MIX_FIX_SCALE-v))) >> MIX_FIX_SHIFT; \ - vb = ((v2b*v) + (v1b*(MIX_FIX_SCALE-v))) >> MIX_FIX_SHIFT; \ - \ - *(buf++) += MULSC(va, lvol); \ - *(buf++) += MULSC(vb, rvol); - - MIXER(); - - #undef MIX -} - -END_OF_STATIC_FUNCTION(mix_hq2_8x2_samples); - - - -/* mix_hq2_16x1_samples: - * Mixes from a mono 16 bit sample into an interpolated stereo buffer, - * until either len samples have been mixed or until the end of the sample - * is reached. - */ -static void mix_hq2_16x1_samples(MIXER_VOICE *spl, PHYS_VOICE *voice, signed int *buf, int len) -{ - int lvol = spl->lvol; - int rvol = spl->rvol; - int v, v1, v2; - - #define MIX() \ - v = spl->pos>>MIX_FIX_SHIFT; \ - \ - v1 = (spl->data.u16[v]<<8) - 0x800000; \ - \ - if (spl->pos >= spl->len-MIX_FIX_SCALE) { \ - if ((voice->playmode & (PLAYMODE_LOOP | \ - PLAYMODE_BIDIR)) == PLAYMODE_LOOP && \ - spl->loop_start < spl->loop_end && spl->loop_end == spl->len) \ - v2 = (spl->data.u16[spl->loop_start>>MIX_FIX_SHIFT]<<8)-0x800000;\ - else \ - v2 = 0; \ - } \ - else \ - v2 = (spl->data.u16[v+1]<<8) - 0x800000; \ - \ - v = spl->pos & (MIX_FIX_SCALE-1); \ - v = ((v2*v) + (v1*(MIX_FIX_SCALE-v))) >> MIX_FIX_SHIFT; \ - \ - *(buf++) += MULSC(v, lvol); \ - *(buf++) += MULSC(v, rvol); - - MIXER(); - - #undef MIX -} - -END_OF_STATIC_FUNCTION(mix_hq2_16x1_samples); - - - -/* mix_hq2_16x2_samples: - * Mixes from a stereo 16 bit sample into an interpolated stereo buffer, - * until either len samples have been mixed or until the end of the sample - * is reached. - */ -static void mix_hq2_16x2_samples(MIXER_VOICE *spl, PHYS_VOICE *voice, signed int *buf, int len) -{ - int lvol = spl->lvol; - int rvol = spl->rvol; - int v, va, v1a, v2a, vb, v1b, v2b; - - #define MIX() \ - v = (spl->pos>>MIX_FIX_SHIFT) << 1; /* x2 for stereo */ \ - \ - v1a = (spl->data.u16[v]<<8) - 0x800000; \ - v1b = (spl->data.u16[v+1]<<8) - 0x800000; \ - \ - if (spl->pos >= spl->len-MIX_FIX_SCALE) { \ - if ((voice->playmode & (PLAYMODE_LOOP | \ - PLAYMODE_BIDIR)) == PLAYMODE_LOOP && \ - spl->loop_start < spl->loop_end && spl->loop_end == spl->len) { \ - v2a = (spl->data.u16[((spl->loop_start>>MIX_FIX_SHIFT)<<1)]<<8) - 0x800000;\ - v2b = (spl->data.u16[((spl->loop_start>>MIX_FIX_SHIFT)<<1)+1]<<8) - 0x800000;\ - } \ - else \ - v2a = v2b = 0; \ - } \ - else { \ - v2a = (spl->data.u16[v+2]<<8) - 0x800000; \ - v2b = (spl->data.u16[v+3]<<8) - 0x800000; \ - } \ - \ - v = spl->pos & (MIX_FIX_SCALE-1); \ - va = ((v2a*v) + (v1a*(MIX_FIX_SCALE-v))) >> MIX_FIX_SHIFT; \ - vb = ((v2b*v) + (v1b*(MIX_FIX_SCALE-v))) >> MIX_FIX_SHIFT; \ - \ - *(buf++) += MULSC(va, lvol); \ - *(buf++) += MULSC(vb, rvol); - - MIXER(); - - #undef MIX -} - -END_OF_STATIC_FUNCTION(mix_hq2_16x2_samples); - - - -#define MAX_24 (0x00FFFFFF) - -/* _mix_some_samples: - * Mixes samples into a buffer in memory (the buf parameter should be a - * linear offset into the specified segment), using the buffer size, sample - * frequency, etc, set when you called _mixer_init(). This should be called - * by the audio driver to get the next buffer full of samples. - */ -void _mix_some_samples(uintptr_t buf, unsigned short seg, int issigned) -{ - signed int *p = mix_buffer; - int i; - - /* clear mixing buffer */ - memset(p, 0, mix_size*mix_channels * sizeof(*p)); - -#ifdef ALLEGRO_MULTITHREADED - system_driver->lock_mutex(mixer_mutex); -#endif - - for (i=0; i 0) || (_phys_voice[i].dvol > 0)) { - /* Interpolated mixing */ - if (_sound_hq >= 2) { - /* stereo input -> interpolated output */ - if (mixer_voice[i].channels != 1) { - if (mixer_voice[i].bits == 8) - mix_hq2_8x2_samples(mixer_voice+i, _phys_voice+i, p, mix_size); - else - mix_hq2_16x2_samples(mixer_voice+i, _phys_voice+i, p, mix_size); - } - /* mono input -> interpolated output */ - else { - if (mixer_voice[i].bits == 8) - mix_hq2_8x1_samples(mixer_voice+i, _phys_voice+i, p, mix_size); - else - mix_hq2_16x1_samples(mixer_voice+i, _phys_voice+i, p, mix_size); - } - } - /* high quality mixing */ - else if (_sound_hq) { - /* stereo input -> high quality output */ - if (mixer_voice[i].channels != 1) { - if (mixer_voice[i].bits == 8) - mix_hq1_8x2_samples(mixer_voice+i, _phys_voice+i, p, mix_size); - else - mix_hq1_16x2_samples(mixer_voice+i, _phys_voice+i, p, mix_size); - } - /* mono input -> high quality output */ - else { - if (mixer_voice[i].bits == 8) - mix_hq1_8x1_samples(mixer_voice+i, _phys_voice+i, p, mix_size); - else - mix_hq1_16x1_samples(mixer_voice+i, _phys_voice+i, p, mix_size); - } - } - /* low quality (fast?) stereo mixing */ - else if (mix_channels != 1) { - /* stereo input -> stereo output */ - if (mixer_voice[i].channels != 1) { - if (mixer_voice[i].bits == 8) - mix_stereo_8x2_samples(mixer_voice+i, _phys_voice+i, p, mix_size); - else - mix_stereo_16x2_samples(mixer_voice+i, _phys_voice+i, p, mix_size); - } - /* mono input -> stereo output */ - else { - if (mixer_voice[i].bits == 8) - mix_stereo_8x1_samples(mixer_voice+i, _phys_voice+i, p, mix_size); - else - mix_stereo_16x1_samples(mixer_voice+i, _phys_voice+i, p, mix_size); - } - } - /* low quality (fast?) mono mixing */ - else { - /* stereo input -> mono output */ - if (mixer_voice[i].channels != 1) { - if (mixer_voice[i].bits == 8) - mix_mono_8x2_samples(mixer_voice+i, _phys_voice+i, p, mix_size); - else - mix_mono_16x2_samples(mixer_voice+i, _phys_voice+i, p, mix_size); - } - /* mono input -> mono output */ - else { - if (mixer_voice[i].bits == 8) - mix_mono_8x1_samples(mixer_voice+i, _phys_voice+i, p, mix_size); - else - mix_mono_16x1_samples(mixer_voice+i, _phys_voice+i, p, mix_size); - } - } - } - else - mix_silent_samples(mixer_voice+i, _phys_voice+i, mix_size); - } - } - -#ifdef ALLEGRO_MULTITHREADED - system_driver->unlock_mutex(mixer_mutex); -#endif - - _farsetsel(seg); - - /* transfer to the audio driver's buffer */ - if (mix_bits == 16) { - if (issigned) { - for (i=mix_size*mix_channels; i>0; i--) { - _farnspokew(buf, (clamp_val((*p)+0x800000, MAX_24) >> 8) ^ 0x8000); - buf += 2; - p++; - } - } - else { - for (i=mix_size*mix_channels; i>0; i--) { - _farnspokew(buf, clamp_val((*p)+0x800000, MAX_24) >> 8); - buf += 2; - p++; - } - } - } - else { - if(issigned) { - for (i=mix_size*mix_channels; i>0; i--) { - _farnspokeb(buf, (clamp_val((*p)+0x800000, MAX_24) >> 16) ^ 0x80); - buf++; - p++; - } - } - else { - for (i=mix_size*mix_channels; i>0; i--) { - _farnspokeb(buf, clamp_val((*p)+0x800000, MAX_24) >> 16); - buf++; - p++; - } - } - } -} - -END_OF_FUNCTION(_mix_some_samples); - - - -/* _mixer_init_voice: - * Initialises the specificed voice ready for playing a sample. - */ -void _mixer_init_voice(int voice, AL_CONST SAMPLE *sample) -{ - mixer_voice[voice].playing = FALSE; - mixer_voice[voice].channels = (sample->stereo ? 2 : 1); - mixer_voice[voice].bits = sample->bits; - mixer_voice[voice].pos = 0; - mixer_voice[voice].len = sample->len << MIX_FIX_SHIFT; - mixer_voice[voice].loop_start = sample->loop_start << MIX_FIX_SHIFT; - mixer_voice[voice].loop_end = sample->loop_end << MIX_FIX_SHIFT; - - mixer_voice[voice].data.buffer = sample->data; - - update_mixer_volume(mixer_voice+voice, _phys_voice+voice); - update_mixer_freq(mixer_voice+voice, _phys_voice+voice); -} - -END_OF_FUNCTION(_mixer_init_voice); - - - -/* _mixer_release_voice: - * Releases a voice when it is no longer required. - */ -void _mixer_release_voice(int voice) -{ -#ifdef ALLEGRO_MULTITHREADED - system_driver->lock_mutex(mixer_mutex); -#endif - - mixer_voice[voice].playing = FALSE; - mixer_voice[voice].data.buffer = NULL; - -#ifdef ALLEGRO_MULTITHREADED - system_driver->unlock_mutex(mixer_mutex); -#endif -} - -END_OF_FUNCTION(_mixer_release_voice); - - - -/* _mixer_start_voice: - * Activates a voice, with the currently selected parameters. - */ -void _mixer_start_voice(int voice) -{ - if (mixer_voice[voice].pos >= mixer_voice[voice].len) - mixer_voice[voice].pos = 0; - - mixer_voice[voice].playing = TRUE; -} - -END_OF_FUNCTION(_mixer_start_voice); - - - -/* _mixer_stop_voice: - * Stops a voice from playing. - */ -void _mixer_stop_voice(int voice) -{ - mixer_voice[voice].playing = FALSE; -} - -END_OF_FUNCTION(_mixer_stop_voice); - - - -/* _mixer_loop_voice: - * Sets the loopmode for a voice. - */ -void _mixer_loop_voice(int voice, int loopmode) -{ - update_mixer_freq(mixer_voice+voice, _phys_voice+voice); -} - -END_OF_FUNCTION(_mixer_loop_voice); - - - -/* _mixer_get_position: - * Returns the current play position of a voice, or -1 if it has finished. - */ -int _mixer_get_position(int voice) -{ - if ((!mixer_voice[voice].playing) || - (mixer_voice[voice].pos >= mixer_voice[voice].len)) - return -1; - - return (mixer_voice[voice].pos >> MIX_FIX_SHIFT); -} - -END_OF_FUNCTION(_mixer_get_position); - - - -/* _mixer_set_position: - * Sets the current play position of a voice. - */ -void _mixer_set_position(int voice, int position) -{ - if (position < 0) - position = 0; - - mixer_voice[voice].pos = (position << MIX_FIX_SHIFT); - if (mixer_voice[voice].pos >= mixer_voice[voice].len) - mixer_voice[voice].playing = FALSE; -} - -END_OF_FUNCTION(_mixer_set_position); - - - -/* _mixer_get_volume: - * Returns the current volume of a voice. - */ -int _mixer_get_volume(int voice) -{ - return (_phys_voice[voice].vol >> 12); -} - -END_OF_FUNCTION(_mixer_get_volume); - - - -/* _mixer_set_volume: - * Sets the volume of a voice. - */ -void _mixer_set_volume(int voice, int volume) -{ - update_mixer_volume(mixer_voice+voice, _phys_voice+voice); -} - -END_OF_FUNCTION(_mixer_set_volume); - - - -/* _mixer_ramp_volume: - * Starts a volume ramping operation. - */ -void _mixer_ramp_volume(int voice, int time, int endvol) -{ - int d = (endvol << 12) - _phys_voice[voice].vol; - time = MAX(time * (mix_freq / UPDATE_FREQ) / 1000, 1); - - _phys_voice[voice].target_vol = endvol << 12; - _phys_voice[voice].dvol = d / time; -} - -END_OF_FUNCTION(_mixer_ramp_volume); - - - -/* _mixer_stop_volume_ramp: - * Ends a volume ramp operation. - */ -void _mixer_stop_volume_ramp(int voice) -{ - _phys_voice[voice].dvol = 0; -} - -END_OF_FUNCTION(_mixer_stop_volume_ramp); - - - -/* _mixer_get_frequency: - * Returns the current frequency of a voice. - */ -int _mixer_get_frequency(int voice) -{ - return (_phys_voice[voice].freq >> 12); -} - -END_OF_FUNCTION(_mixer_get_frequency); - - - -/* _mixer_set_frequency: - * Sets the frequency of a voice. - */ -void _mixer_set_frequency(int voice, int frequency) -{ - update_mixer_freq(mixer_voice+voice, _phys_voice+voice); -} - -END_OF_FUNCTION(_mixer_set_frequency); - - - -/* _mixer_sweep_frequency: - * Starts a frequency sweep. - */ -void _mixer_sweep_frequency(int voice, int time, int endfreq) -{ - int d = (endfreq << 12) - _phys_voice[voice].freq; - time = MAX(time * (mix_freq / UPDATE_FREQ) / 1000, 1); - - _phys_voice[voice].target_freq = endfreq << 12; - _phys_voice[voice].dfreq = d / time; -} - -END_OF_FUNCTION(_mixer_sweep_frequency); - - - -/* _mixer_stop_frequency_sweep: - * Ends a frequency sweep. - */ -void _mixer_stop_frequency_sweep(int voice) -{ - _phys_voice[voice].dfreq = 0; -} - -END_OF_FUNCTION(_mixer_stop_frequency_sweep); - - - -/* _mixer_get_pan: - * Returns the current pan position of a voice. - */ -int _mixer_get_pan(int voice) -{ - return (_phys_voice[voice].pan >> 12); -} - -END_OF_FUNCTION(_mixer_get_pan); - - - -/* _mixer_set_pan: - * Sets the pan position of a voice. - */ -void _mixer_set_pan(int voice, int pan) -{ - update_mixer_volume(mixer_voice+voice, _phys_voice+voice); -} - -END_OF_FUNCTION(_mixer_set_pan); - - - -/* _mixer_sweep_pan: - * Starts a pan sweep. - */ -void _mixer_sweep_pan(int voice, int time, int endpan) -{ - int d = (endpan << 12) - _phys_voice[voice].pan; - time = MAX(time * (mix_freq / UPDATE_FREQ) / 1000, 1); - - _phys_voice[voice].target_pan = endpan << 12; - _phys_voice[voice].dpan = d / time; -} - -END_OF_FUNCTION(_mixer_sweep_pan); - - - -/* _mixer_stop_pan_sweep: - * Ends a pan sweep. - */ -void _mixer_stop_pan_sweep(int voice) -{ - _phys_voice[voice].dpan = 0; -} - -END_OF_FUNCTION(_mixer_stop_pan_sweep); - - - -/* _mixer_set_echo: - * Sets the echo parameters for a voice. - */ -void _mixer_set_echo(int voice, int strength, int delay) -{ - /* not implemented */ -} - -END_OF_FUNCTION(_mixer_set_echo); - - - -/* _mixer_set_tremolo: - * Sets the tremolo parameters for a voice. - */ -void _mixer_set_tremolo(int voice, int rate, int depth) -{ - /* not implemented */ -} - -END_OF_FUNCTION(_mixer_set_tremolo); - - - -/* _mixer_set_vibrato: - * Sets the amount of vibrato for a voice. - */ -void _mixer_set_vibrato(int voice, int rate, int depth) -{ - /* not implemented */ -} - -END_OF_FUNCTION(_mixer_set_vibrato); - - - -/* mixer_lock_mem: - * Locks memory used by the functions in this file. - */ -static void mixer_lock_mem(void) -{ - LOCK_VARIABLE(mixer_voice); - LOCK_VARIABLE(mix_buffer); - LOCK_VARIABLE(mix_vol_table); - LOCK_VARIABLE(mix_voices); - LOCK_VARIABLE(mix_size); - LOCK_VARIABLE(mix_freq); - LOCK_VARIABLE(mix_channels); - LOCK_VARIABLE(mix_bits); - LOCK_FUNCTION(set_mixer_quality); - LOCK_FUNCTION(get_mixer_quality); - LOCK_FUNCTION(get_mixer_buffer_length); - LOCK_FUNCTION(get_mixer_frequency); - LOCK_FUNCTION(get_mixer_bits); - LOCK_FUNCTION(get_mixer_channels); - LOCK_FUNCTION(get_mixer_voices); - LOCK_FUNCTION(set_volume_per_voice); - LOCK_FUNCTION(mix_silent_samples); - LOCK_FUNCTION(mix_mono_8x1_samples); - LOCK_FUNCTION(mix_mono_8x2_samples); - LOCK_FUNCTION(mix_mono_16x1_samples); - LOCK_FUNCTION(mix_mono_16x2_samples); - LOCK_FUNCTION(mix_stereo_8x1_samples); - LOCK_FUNCTION(mix_stereo_8x2_samples); - LOCK_FUNCTION(mix_stereo_16x1_samples); - LOCK_FUNCTION(mix_stereo_16x2_samples); - LOCK_FUNCTION(mix_hq1_8x1_samples); - LOCK_FUNCTION(mix_hq1_8x2_samples); - LOCK_FUNCTION(mix_hq1_16x1_samples); - LOCK_FUNCTION(mix_hq1_16x2_samples); - LOCK_FUNCTION(mix_hq2_8x1_samples); - LOCK_FUNCTION(mix_hq2_8x2_samples); - LOCK_FUNCTION(mix_hq2_16x1_samples); - LOCK_FUNCTION(mix_hq2_16x2_samples); - LOCK_FUNCTION(update_mixer_volume); - LOCK_FUNCTION(update_mixer); - LOCK_FUNCTION(update_silent_mixer); - LOCK_FUNCTION(_mix_some_samples); - LOCK_FUNCTION(_mixer_init_voice); - LOCK_FUNCTION(_mixer_release_voice); - LOCK_FUNCTION(_mixer_start_voice); - LOCK_FUNCTION(_mixer_stop_voice); - LOCK_FUNCTION(_mixer_loop_voice); - LOCK_FUNCTION(_mixer_get_position); - LOCK_FUNCTION(_mixer_set_position); - LOCK_FUNCTION(_mixer_get_volume); - LOCK_FUNCTION(_mixer_set_volume); - LOCK_FUNCTION(_mixer_ramp_volume); - LOCK_FUNCTION(_mixer_stop_volume_ramp); - LOCK_FUNCTION(_mixer_get_frequency); - LOCK_FUNCTION(_mixer_set_frequency); - LOCK_FUNCTION(_mixer_sweep_frequency); - LOCK_FUNCTION(_mixer_stop_frequency_sweep); - LOCK_FUNCTION(_mixer_get_pan); - LOCK_FUNCTION(_mixer_set_pan); - LOCK_FUNCTION(_mixer_sweep_pan); - LOCK_FUNCTION(_mixer_stop_pan_sweep); - LOCK_FUNCTION(_mixer_set_echo); - LOCK_FUNCTION(_mixer_set_tremolo); - LOCK_FUNCTION(_mixer_set_vibrato); -} diff --git a/src/allegro/src/readsmp.c b/src/allegro/src/readsmp.c deleted file mode 100644 index f6ad37457..000000000 --- a/src/allegro/src/readsmp.c +++ /dev/null @@ -1,197 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * Top level sample type registration routines. - * - * By Vincent Penquerc'h. - * - * See readme.txt for copyright information. - */ - - -#include - -#include "allegro.h" -#include "allegro/internal/aintern.h" - - - -typedef struct SAMPLE_TYPE_INFO -{ - char *ext; - SAMPLE *(*load)(AL_CONST char *filename); - int (*save)(AL_CONST char *filename, SAMPLE *smp); - struct SAMPLE_TYPE_INFO *next; -} SAMPLE_TYPE_INFO; - -static SAMPLE_TYPE_INFO *sample_type_list = NULL; - - - -/* register_sample_file_type: - * Informs Allegro of a new sample file type, telling it how to load and - * save files of this format (either function may be NULL). - */ -void register_sample_file_type(AL_CONST char *ext, SAMPLE *(*load)(AL_CONST char *filename), int (*save)(AL_CONST char *filename, SAMPLE *smp)) -{ - char tmp[32], *aext; - SAMPLE_TYPE_INFO *iter = sample_type_list; - ASSERT(ext); - - aext = uconvert_toascii(ext, tmp); - if (strlen(aext) == 0) return; - - if (!iter) - iter = sample_type_list = _AL_MALLOC(sizeof(struct SAMPLE_TYPE_INFO)); - else { - for (iter = sample_type_list; iter->next; iter = iter->next); - iter = iter->next = _AL_MALLOC(sizeof(struct SAMPLE_TYPE_INFO)); - } - - if (iter) { - iter->load = load; - iter->save = save; - iter->ext = _al_strdup(aext); - iter->next = NULL; - } -} - - - -/* load_sample: - * Loads a sample from disk. - */ -SAMPLE *load_sample(AL_CONST char *filename) -{ - char tmp[32], *aext; - SAMPLE_TYPE_INFO *iter; - ASSERT(filename); - - aext = uconvert_toascii(get_extension(filename), tmp); - - for (iter = sample_type_list; iter; iter = iter->next) { - if (stricmp(iter->ext, aext) == 0) { - if (iter->load) - return iter->load(filename); - return NULL; - } - } - - return NULL; -} - - - -/* save_sample: - * Writes a sample to disk. - */ -int save_sample(AL_CONST char *filename, SAMPLE *smp) -{ - char tmp[32], *aext; - SAMPLE_TYPE_INFO *iter; - ASSERT(filename); - ASSERT(smp); - - aext = uconvert_toascii(get_extension(filename), tmp); - - for (iter = sample_type_list; iter; iter = iter->next) { - if (stricmp(iter->ext, aext) == 0) { - if (iter->save) - return iter->save(filename, smp); - return 1; - } - } - - return 1; -} - - - -/* register_sample_file_type_exit: - * Free list of registered sample file types. - */ -static void register_sample_file_type_exit(void) -{ - SAMPLE_TYPE_INFO *iter = sample_type_list, *next; - - while (iter) { - next = iter->next; - _AL_FREE(iter->ext); - _AL_FREE(iter); - iter = next; - } - - sample_type_list = NULL; - - /* If we are using a destructor, then we only want to prune the list - * down to valid modules. So we clean up as usual, but then reinstall - * the internal modules. - */ - #ifdef ALLEGRO_USE_CONSTRUCTOR - _register_sample_file_type_init(); - #endif - - _remove_exit_func(register_sample_file_type_exit); -} - - - -/* _register_sample_file_type_init: - * Register built-in sample file types. - */ -void _register_sample_file_type_init(void) -{ - char buf[32]; - - _add_exit_func(register_sample_file_type_exit, - "register_sample_file_type_exit"); - - register_sample_file_type(uconvert_ascii("wav", buf), load_wav, NULL); - register_sample_file_type(uconvert_ascii("voc", buf), load_voc, NULL); -} - - - -#ifdef ALLEGRO_USE_CONSTRUCTOR - CONSTRUCTOR_FUNCTION(static void sample_filetype_constructor(void)); - DESTRUCTOR_FUNCTION(static void sample_filetype_destructor(void)); - - /* sample_filetype_constructor: - * Register sample filetype functions if this object file is linked - * in. This isn't called if the load_sample() and save_sample() - * functions aren't used in a program, thus saving a little space - * in statically linked programs. - */ - static void sample_filetype_constructor(void) - { - _register_sample_file_type_init(); - } - - /* sample_filetype_destructor: - * Since we only want to destroy the whole list when we *actually* - * quit, not just when allegro_exit() is called, we need to use a - * destructor to accomplish this. - */ - static void sample_filetype_destructor(void) - { - SAMPLE_TYPE_INFO *iter = sample_type_list, *next; - - while (iter) { - next = iter->next; - _AL_FREE(iter->ext); - _AL_FREE(iter); - iter = next; - } - - sample_type_list = NULL; - - _remove_exit_func(register_sample_file_type_exit); - } -#endif diff --git a/src/allegro/src/sound.c b/src/allegro/src/sound.c deleted file mode 100644 index 4f4671bfe..000000000 --- a/src/allegro/src/sound.c +++ /dev/null @@ -1,2134 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * Sound setup routines and API framework functions. - * - * By Shawn Hargreaves. - * - * Input routines added by Ove Kaaven. - * - * See readme.txt for copyright information. - */ - - -#include - -#include "allegro.h" -#include "allegro/internal/aintern.h" - - - -static DIGI_DRIVER digi_none; - - - -/* dummy functions for the nosound drivers */ -int _dummy_detect(int input) { return TRUE; } -int _dummy_init(int input, int voices) { digi_none.desc = _midi_none.desc = get_config_text("The sound of silence"); return 0; } -void _dummy_exit(int input) { } -int _dummy_set_mixer_volume(int volume) { return 0; } -int _dummy_get_mixer_volume(void) { return -1; } -void _dummy_init_voice(int voice, AL_CONST SAMPLE *sample) { } -void _dummy_noop1(int p) { } -void _dummy_noop2(int p1, int p2) { } -void _dummy_noop3(int p1, int p2, int p3) { } -int _dummy_get_position(int voice) { return -1; } -int _dummy_get(int voice) { return 0; } -void _dummy_raw_midi(int data) { } -int _dummy_load_patches(AL_CONST char *patches, AL_CONST char *drums) { return 0; } -void _dummy_adjust_patches(AL_CONST char *patches, AL_CONST char *drums) { } -void _dummy_key_on(int inst, int note, int bend, int vol, int pan) { } - -/* put this after all the dummy functions, so they will all get locked */ -END_OF_FUNCTION(_dummy_detect); - - - -static DIGI_DRIVER digi_none = -{ - DIGI_NONE, - empty_string, - empty_string, - "No sound", - 0, 0, 0xFFFF, 0, - _dummy_detect, - _dummy_init, - _dummy_exit, - _dummy_set_mixer_volume, - _dummy_get_mixer_volume, - NULL, - NULL, - NULL, - _dummy_init_voice, - _dummy_noop1, - _dummy_noop1, - _dummy_noop1, - _dummy_noop2, - _dummy_get_position, - _dummy_noop2, - _dummy_get, - _dummy_noop2, - _dummy_noop3, - _dummy_noop1, - _dummy_get, - _dummy_noop2, - _dummy_noop3, - _dummy_noop1, - _dummy_get, - _dummy_noop2, - _dummy_noop3, - _dummy_noop1, - _dummy_noop3, - _dummy_noop3, - _dummy_noop3, - 0, 0, - NULL, NULL, NULL, NULL, NULL, NULL -}; - - -MIDI_DRIVER _midi_none = -{ - MIDI_NONE, - empty_string, - empty_string, - "No sound", - 0, 0, 0xFFFF, 0, -1, -1, - _dummy_detect, - _dummy_init, - _dummy_exit, - _dummy_set_mixer_volume, - _dummy_get_mixer_volume, - _dummy_raw_midi, - _dummy_load_patches, - _dummy_adjust_patches, - _dummy_key_on, - _dummy_noop1, - _dummy_noop2, - _dummy_noop3, - _dummy_noop2, - _dummy_noop2 -}; - - -int digi_card = DIGI_AUTODETECT; /* current driver ID numbers */ -int midi_card = MIDI_AUTODETECT; - -int digi_input_card = DIGI_AUTODETECT; -int midi_input_card = MIDI_AUTODETECT; - -DIGI_DRIVER *digi_driver = &digi_none; /* these things do all the work */ -MIDI_DRIVER *midi_driver = &_midi_none; - -DIGI_DRIVER *digi_input_driver = &digi_none; -MIDI_DRIVER *midi_input_driver = &_midi_none; - -void (*digi_recorder)(void) = NULL; -void (*midi_recorder)(unsigned char data) = NULL; - -int _sound_installed = FALSE; /* are we installed? */ -int _sound_input_installed = FALSE; - -static int digi_reserve = -1; /* how many voices to reserve */ -static int midi_reserve = -1; - -static VOICE virt_voice[VIRTUAL_VOICES]; /* list of active samples */ - -PHYS_VOICE _phys_voice[DIGI_VOICES]; /* physical -> virtual voice map */ - -int _digi_volume = -1; /* current volume settings */ -int _midi_volume = -1; - -int _sound_flip_pan = FALSE; /* reverse l/r sample panning? */ -int _sound_hq = 2; /* mixer speed vs. quality */ - -int _sound_freq = -1; /* common hardware parameters */ -int _sound_stereo = -1; -int _sound_bits = -1; -int _sound_port = -1; -int _sound_dma = -1; -int _sound_irq = -1; - -#define SWEEP_FREQ 50 - -static void update_sweeps(void); -static void sound_lock_mem(void); - - - -/* read_sound_config: - * Helper for reading the sound hardware configuration data. - */ -static void read_sound_config(void) -{ - char tmp1[64], tmp2[64]; - char *sound = uconvert_ascii("sound", tmp1); - - _sound_flip_pan = get_config_int(sound, uconvert_ascii("flip_pan", tmp2), FALSE); - _sound_hq = get_config_int(sound, uconvert_ascii("quality", tmp2), _sound_hq); - _sound_port = get_config_hex(sound, uconvert_ascii("sound_port", tmp2), -1); - _sound_dma = get_config_int(sound, uconvert_ascii("sound_dma", tmp2), -1); - _sound_irq = get_config_int(sound, uconvert_ascii("sound_irq", tmp2), -1); - _sound_freq = get_config_int(sound, uconvert_ascii("sound_freq", tmp2), -1); - _sound_bits = get_config_int(sound, uconvert_ascii("sound_bits", tmp2), -1); - _sound_stereo = get_config_int(sound, uconvert_ascii("sound_stereo", tmp2), -1); - _digi_volume = get_config_int(sound, uconvert_ascii("digi_volume", tmp2), -1); - _midi_volume = get_config_int(sound, uconvert_ascii("midi_volume", tmp2), -1); -} - - - -/* detect_digi_driver: - * Detects whether the specified digital sound driver is available, - * returning the maximum number of voices that it can provide, or - * zero if the device is not present. This function must be called - * _before_ install_sound(). - */ -int detect_digi_driver(int driver_id) -{ - _DRIVER_INFO *digi_drivers; - int i, ret; - - if (_sound_installed) - return 0; - - read_sound_config(); - - if (system_driver->digi_drivers) - digi_drivers = system_driver->digi_drivers(); - else - digi_drivers = _digi_driver_list; - - for (i=0; digi_drivers[i].id; i++) { - if (digi_drivers[i].id == driver_id) { - digi_driver = digi_drivers[i].driver; - digi_driver->name = digi_driver->desc = get_config_text(digi_driver->ascii_name); - digi_card = driver_id; - midi_card = MIDI_AUTODETECT; - - if (digi_driver->detect(FALSE)) - ret = digi_driver->max_voices; - else - ret = 0; - - digi_driver = &digi_none; - return ret; - } - } - - return digi_none.max_voices; -} - - - -/* detect_midi_driver: - * Detects whether the specified MIDI sound driver is available, - * returning the maximum number of voices that it can provide, or - * zero if the device is not present. If this routine returns -1, - * it is a note-stealing MIDI driver, which shares voices with the - * current digital driver. In this situation you can use the - * reserve_voices() function to specify how the available voices are - * divided between the digital and MIDI playback routines. This function - * must be called _before_ install_sound(). - */ -int detect_midi_driver(int driver_id) -{ - _DRIVER_INFO *midi_drivers; - int i, ret; - - if (_sound_installed) - return 0; - - read_sound_config(); - - if (system_driver->midi_drivers) - midi_drivers = system_driver->midi_drivers(); - else - midi_drivers = _midi_driver_list; - - for (i=0; midi_drivers[i].id; i++) { - if (midi_drivers[i].id == driver_id) { - midi_driver = midi_drivers[i].driver; - midi_driver->name = midi_driver->desc = get_config_text(midi_driver->ascii_name); - digi_card = DIGI_AUTODETECT; - midi_card = driver_id; - - if (midi_driver->detect(FALSE)) - ret = midi_driver->max_voices; - else - ret = 0; - - midi_driver = &_midi_none; - return ret; - } - } - - return _midi_none.max_voices; -} - - - -/* reserve_voices: - * Reserves a number of voices for the digital and MIDI sound drivers - * respectively. This must be called _before_ install_sound(). If you - * attempt to reserve too many voices, subsequent calls to install_sound() - * will fail. Note that depending on the driver you may actually get - * more voices than you reserve: these values just specify the minimum - * that is appropriate for your application. Pass a negative reserve value - * to use the default settings. - */ -void reserve_voices(int digi_voices, int midi_voices) -{ - digi_reserve = digi_voices; - midi_reserve = midi_voices; -} - - - -/* install_sound: - * Initialises the sound module, returning zero on success. The two card - * parameters should use the DIGI_* and MIDI_* constants defined in - * allegro.h. Pass DIGI_AUTODETECT and MIDI_AUTODETECT if you don't know - * what the soundcard is. - */ -int install_sound(int digi, int midi, AL_CONST char *cfg_path) -{ - char tmp1[64], tmp2[64]; - char *sound = uconvert_ascii("sound", tmp1); - _DRIVER_INFO *digi_drivers, *midi_drivers; - int digi_voices, midi_voices; - int c; - - if (_sound_installed) - return 0; - - for (c=0; cinit() != 0) - return -1; - - usetc(allegro_error, 0); - - register_datafile_object(DAT_SAMPLE, NULL, (void (*)(void *))destroy_sample); - - digi_card = digi; - midi_card = midi; - - /* read config information */ - if (digi_card == DIGI_AUTODETECT) - digi_card = get_config_id(sound, uconvert_ascii("digi_card", tmp2), DIGI_AUTODETECT); - - if (midi_card == MIDI_AUTODETECT) - midi_card = get_config_id(sound, uconvert_ascii("midi_card", tmp2), MIDI_AUTODETECT); - - if (digi_reserve < 0) - digi_reserve = get_config_int(sound, uconvert_ascii("digi_voices", tmp2), -1); - - if (midi_reserve < 0) - midi_reserve = get_config_int(sound, uconvert_ascii("midi_voices", tmp2), -1); - - read_sound_config(); - - sound_lock_mem(); - - /* set up digital sound driver */ - if (system_driver->digi_drivers) - digi_drivers = system_driver->digi_drivers(); - else - digi_drivers = _digi_driver_list; - - for (c=0; digi_drivers[c].driver; c++) { - digi_driver = digi_drivers[c].driver; - digi_driver->name = digi_driver->desc = get_config_text(digi_driver->ascii_name); - } - - digi_driver = NULL; - - /* search table for a specific digital driver */ - for (c=0; digi_drivers[c].driver; c++) { - if (digi_drivers[c].id == digi_card) { - digi_driver = digi_drivers[c].driver; - if (!digi_driver->detect(FALSE)) { - digi_driver = &digi_none; - if (_al_linker_midi) - _al_linker_midi->exit(); - if (!ugetc(allegro_error)) - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Digital sound driver not found")); - return -1; - } - break; - } - } - - if (digi_card == DIGI_NONE) - digi_driver = &digi_none; - - /* autodetect digital driver */ - if (!digi_driver) { - for (c=0; digi_drivers[c].driver; c++) { - if (digi_drivers[c].autodetect) { - digi_card = digi_drivers[c].id; - digi_driver = digi_drivers[c].driver; - if (digi_driver->detect(FALSE)) - break; - digi_driver = NULL; - } - } - - if (!digi_driver) { - digi_card = DIGI_NONE; - digi_driver = &digi_none; - } - } - - /* set up midi sound driver */ - if (system_driver->midi_drivers) - midi_drivers = system_driver->midi_drivers(); - else - midi_drivers = _midi_driver_list; - - for (c=0; midi_drivers[c].driver; c++) { - midi_driver = midi_drivers[c].driver; - midi_driver->name = midi_driver->desc = get_config_text(midi_driver->ascii_name); - } - - midi_driver = NULL; - - /* search table for a specific MIDI driver */ - for (c=0; midi_drivers[c].driver; c++) { - if (midi_drivers[c].id == midi_card) { - midi_driver = midi_drivers[c].driver; - if (!midi_driver->detect(FALSE)) { - digi_driver = &digi_none; - midi_driver = &_midi_none; - if (_al_linker_midi) - _al_linker_midi->exit(); - if (!ugetc(allegro_error)) - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("MIDI music driver not found")); - return -1; - } - break; - } - } - - if (midi_card == MIDI_NONE) - midi_driver = &_midi_none; - - /* autodetect MIDI driver */ - if (!midi_driver) { - for (c=0; midi_drivers[c].driver; c++) { - if (midi_drivers[c].autodetect) { - midi_card = midi_drivers[c].id; - midi_driver = midi_drivers[c].driver; - if (midi_driver->detect(FALSE)) - break; - midi_driver = NULL; - } - } - - if (!midi_driver) { - midi_card = MIDI_NONE; - midi_driver = &_midi_none; - } - } - - /* work out how many voices to allocate for each driver */ - if (digi_reserve >= 0) - digi_voices = digi_reserve; - else - digi_voices = digi_driver->def_voices; - - if (midi_driver->max_voices < 0) { - /* MIDI driver steals voices from the digital player */ - if (midi_reserve >= 0) - midi_voices = midi_reserve; - else - midi_voices = CLAMP(0, digi_driver->max_voices - digi_voices, midi_driver->def_voices); - - digi_voices += midi_voices; - } - else { - /* MIDI driver has voices of its own */ - if (midi_reserve >= 0) - midi_voices = midi_reserve; - else - midi_voices = midi_driver->def_voices; - } - - /* make sure this is a reasonable number of voices to use */ - if ((digi_voices > DIGI_VOICES) || (midi_voices > MIDI_VOICES)) { - uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Insufficient %s voices available"), - (digi_voices > DIGI_VOICES) ? get_config_text("digital") : get_config_text("MIDI")); - digi_driver = &digi_none; - midi_driver = &_midi_none; - if (_al_linker_midi) - _al_linker_midi->exit(); - return -1; - } - - /* initialise the digital sound driver */ - if (digi_driver->init(FALSE, digi_voices) != 0) { - digi_driver = &digi_none; - midi_driver = &_midi_none; - if (_al_linker_midi) - _al_linker_midi->exit(); - if (!ugetc(allegro_error)) - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Failed to init digital sound driver")); - return -1; - } - - /* initialise the MIDI driver */ - if (midi_driver->init(FALSE, midi_voices) != 0) { - digi_driver->exit(FALSE); - digi_driver = &digi_none; - midi_driver = &_midi_none; - if (_al_linker_midi) - _al_linker_midi->exit(); - if (!ugetc(allegro_error)) - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Failed to init MIDI music driver")); - return -1; - } - - digi_driver->voices = MIN(digi_driver->voices, DIGI_VOICES); - midi_driver->voices = MIN(midi_driver->voices, MIDI_VOICES); - - /* check that we actually got enough voices */ - if ((digi_driver->voices < digi_voices) || - ((midi_driver->voices < midi_voices) && (!midi_driver->raw_midi))) { - uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Insufficient %s voices available"), - (digi_driver->voices < digi_voices) ? get_config_text("digital") : get_config_text("MIDI")); - midi_driver->exit(FALSE); - digi_driver->exit(FALSE); - digi_driver = &digi_none; - midi_driver = &_midi_none; - if (_al_linker_midi) - _al_linker_midi->exit(); - return -1; - } - - /* adjust for note-stealing MIDI drivers */ - if (midi_driver->max_voices < 0) { - midi_voices += (digi_driver->voices - digi_voices) * 3/4; - digi_driver->voices -= midi_voices; - midi_driver->basevoice = VIRTUAL_VOICES - midi_voices; - midi_driver->voices = midi_voices; - - for (c=0; cbasevoice+c].num = digi_driver->voices+c; - _phys_voice[digi_driver->voices+c].num = midi_driver->basevoice+c; - } - } - - /* simulate ramp/sweep effects for drivers that don't do it directly */ - if ((!digi_driver->ramp_volume) || - (!digi_driver->sweep_frequency) || - (!digi_driver->sweep_pan)) - install_int_ex(update_sweeps, BPS_TO_TIMER(SWEEP_FREQ)); - - /* set the global sound volume */ - if ((_digi_volume >= 0) || (_midi_volume >= 0)) - set_volume(_digi_volume, _midi_volume); - - _add_exit_func(remove_sound, "remove_sound"); - _sound_installed = TRUE; - return 0; -} - - - -/* install_sound_input: - * Initialises the sound recorder module, returning zero on success. The - * two card parameters should use the DIGI_* and MIDI_* constants defined - * in allegro.h. Pass DIGI_AUTODETECT and MIDI_AUTODETECT if you don't know - * what the soundcard is. - */ -int install_sound_input(int digi, int midi) -{ - char tmp1[64], tmp2[64]; - char *sound = uconvert_ascii("sound", tmp1); - _DRIVER_INFO *digi_drivers, *midi_drivers; - int c; - - if (_sound_input_installed) - return 0; - - if (!_sound_installed) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Sound system not installed")); - return -1; - } - - digi_recorder = NULL; - midi_recorder = NULL; - - digi_input_card = digi; - midi_input_card = midi; - - /* read config information */ - if (digi_input_card == DIGI_AUTODETECT) - digi_input_card = get_config_id(sound, uconvert_ascii("digi_input_card", tmp2), DIGI_AUTODETECT); - - if (midi_input_card == MIDI_AUTODETECT) - midi_input_card = get_config_id(sound, uconvert_ascii("midi_input_card", tmp2), MIDI_AUTODETECT); - - /* search table for a good digital input driver */ - usetc(allegro_error, 0); - - if (system_driver->digi_drivers) - digi_drivers = system_driver->digi_drivers(); - else - digi_drivers = _digi_driver_list; - - for (c=0; digi_drivers[c].driver; c++) { - if ((digi_drivers[c].id == digi_input_card) || (digi_input_card == DIGI_AUTODETECT)) { - digi_input_driver = digi_drivers[c].driver; - if (digi_input_driver->detect(TRUE)) { - digi_input_card = digi_drivers[c].id; - break; - } - else { - digi_input_driver = &digi_none; - if (digi_input_card != DIGI_AUTODETECT) { - if (!ugetc(allegro_error)) - uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("%s does not support audio input"), - ((DIGI_DRIVER *)digi_drivers[c].driver)->name); - break; - } - } - } - } - - /* did we find one? */ - if ((digi_input_driver == &digi_none) && (digi_input_card != DIGI_NONE)) { - if (!ugetc(allegro_error)) - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Digital input driver not found")); - return -1; - } - - /* search table for a good MIDI input driver */ - usetc(allegro_error, 0); - - if (system_driver->midi_drivers) - midi_drivers = system_driver->midi_drivers(); - else - midi_drivers = _midi_driver_list; - - for (c=0; midi_drivers[c].driver; c++) { - if ((midi_drivers[c].id == midi_input_card) || (midi_input_card == MIDI_AUTODETECT)) { - midi_input_driver = midi_drivers[c].driver; - if (midi_input_driver->detect(TRUE)) { - midi_input_card = midi_drivers[c].id; - break; - } - else { - midi_input_driver = &_midi_none; - if (midi_input_card != MIDI_AUTODETECT) { - if (!ugetc(allegro_error)) - uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("%s does not support MIDI input"), - ((MIDI_DRIVER *)midi_drivers[c].driver)->name); - break; - } - } - } - } - - /* did we find one? */ - if ((midi_input_driver == &_midi_none) && (midi_input_card != MIDI_NONE)) { - digi_input_driver = &digi_none; - if (!ugetc(allegro_error)) - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("MIDI input driver not found")); - return -1; - } - - /* initialise the digital input driver */ - if (digi_input_driver->init(TRUE, 0) != 0) { - digi_input_driver = &digi_none; - midi_input_driver = &_midi_none; - if (!ugetc(allegro_error)) - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Failed to init digital input driver")); - return -1; - } - - /* initialise the MIDI input driver */ - if (midi_input_driver->init(TRUE, 0) != 0) { - digi_input_driver->exit(TRUE); - digi_input_driver = &digi_none; - midi_input_driver = &_midi_none; - if (!ugetc(allegro_error)) - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Failed to init MIDI input driver")); - return -1; - } - - _sound_input_installed = TRUE; - return 0; -} - - - -/* remove_sound: - * Sound module cleanup routine. - */ -void remove_sound(void) -{ - int c; - - if (_sound_installed) { - remove_sound_input(); - - remove_int(update_sweeps); - - for (c=0; cexit(); - - midi_driver->exit(FALSE); - midi_driver = &_midi_none; - - digi_driver->exit(FALSE); - digi_driver = &digi_none; - - _remove_exit_func(remove_sound); - _sound_installed = FALSE; - } -} - - - -/* remove_sound_input: - * Sound input module cleanup routine. - */ -void remove_sound_input(void) -{ - if (_sound_input_installed) { - digi_input_driver->exit(TRUE); - digi_input_driver = &digi_none; - - midi_input_driver->exit(TRUE); - midi_input_driver = &_midi_none; - - digi_recorder = NULL; - midi_recorder = NULL; - - _sound_input_installed = FALSE; - } -} - - - -/* set_volume: - * Alters the global sound output volume. Specify volumes for both digital - * samples and MIDI playback, as integers from 0 to 255. This routine will - * not alter the volume of the hardware mixer if it exists. - */ -void set_volume(int digi_volume, int midi_volume) -{ - int *voice_vol; - int i; - - if (digi_volume >= 0) { - voice_vol = _AL_MALLOC_ATOMIC(sizeof(int)*VIRTUAL_VOICES); - - /* Retrieve the (relative) volume of each voice. */ - for (i=0; i= 0) - voice_set_volume(i, voice_vol[i]); - } - - _AL_FREE(voice_vol); - } - - if (midi_volume >= 0) - _midi_volume = CLAMP(0, midi_volume, 255); -} - - - -/* get_volume: - * Retrieves the global sound output volume, both for digital samples and MIDI - * playback, as integers from 0 to 255. Parameters digi_volume and midi_volume - * must be valid pointers to int, or NULL if not interested in specific value. - */ -void get_volume(int *digi_volume, int *midi_volume) -{ - if (digi_volume) - (*digi_volume) = _digi_volume; - if (midi_volume) - (*midi_volume) = _midi_volume; -} - - - -/* set_hardware_volume: - * Alters the hardware sound output volume. Specify volumes for both digital - * samples and MIDI playback, as integers from 0 to 255. This routine will - * use the hardware mixer to control the volume if it exists, or do nothing. - */ -void set_hardware_volume(int digi_volume, int midi_volume) -{ - if (digi_volume >= 0) { - digi_volume = CLAMP(0, digi_volume, 255); - - if (digi_driver->set_mixer_volume) - digi_driver->set_mixer_volume(digi_volume); - } - - if (midi_volume >= 0) { - midi_volume = CLAMP(0, midi_volume, 255); - - if (midi_driver->set_mixer_volume) - midi_driver->set_mixer_volume(midi_volume); - } -} - - - -/* get_hardware_volume: - * Retrieves the hardware sound output volume, both for digital samples and MIDI - * playback, as integers from 0 to 255, or -1 if the information is not - * available. Parameters digi_volume and midi_volume must be valid pointers to - * int, or NULL if not interested in specific value. - */ -void get_hardware_volume(int *digi_volume, int *midi_volume) -{ - if (digi_volume) { - if (digi_driver->get_mixer_volume) { - (*digi_volume) = digi_driver->get_mixer_volume(); - } - else { - (*digi_volume) = -1; - } - } - - if (midi_volume) { - if (midi_driver->get_mixer_volume) { - (*midi_volume) = midi_driver->get_mixer_volume(); - } - else { - (*midi_volume) = -1; - } - } -} - - - -/* lock_sample: - * Locks a SAMPLE struct into physical memory. Pretty important, since - * they are mostly accessed inside interrupt handlers. - */ -void lock_sample(SAMPLE *spl) -{ - ASSERT(spl); - LOCK_DATA(spl, sizeof(SAMPLE)); - LOCK_DATA(spl->data, spl->len * ((spl->bits==8) ? 1 : sizeof(short)) * ((spl->stereo) ? 2 : 1)); -} - - - -/* load_voc: - * Reads a mono VOC format sample file, returning a SAMPLE structure, - * or NULL on error. - */ -SAMPLE *load_voc(AL_CONST char *filename) -{ - PACKFILE *f; - SAMPLE *spl; - ASSERT(filename); - - f = pack_fopen(filename, F_READ); - if (!f) - return NULL; - - spl = load_voc_pf(f); - - pack_fclose(f); - - return spl; -} - - - -/* load_voc_pf: - * Reads a mono VOC format sample from the packfile given, returning a - * SAMPLE structure, or NULL on error. If successful the offset into the - * file will be left just after the sample data. If unsuccessful the offset - * into the file is unspecified, i.e. you must either reset the offset to - * some known place or close the packfile. The packfile is not closed by - * this function. - */ -SAMPLE *load_voc_pf(PACKFILE *f) -{ - char buffer[30]; - int freq = 22050; - int bits = 8; - SAMPLE *spl = NULL; - int len; - int x, ver; - int s; - ASSERT(f); - - memset(buffer, 0, sizeof buffer); - - pack_fread(buffer, 0x16, f); - - if (memcmp(buffer, "Creative Voice File", 0x13)) - goto getout; - - ver = pack_igetw(f); - if (ver != 0x010A && ver != 0x0114) /* version: should be 0x010A or 0x0114 */ - goto getout; - - ver = pack_igetw(f); - if (ver != 0x1129 && ver != 0x111f) /* subversion: should be 0x1129 or 0x111f */ - goto getout; - - ver = pack_getc(f); - if (ver != 0x01 && ver != 0x09) /* sound data: should be 0x01 or 0x09 */ - goto getout; - - len = pack_igetw(f); /* length is three bytes long: two */ - x = pack_getc(f); /* .. and one byte */ - x <<= 16; - len += x; - - if (ver == 0x01) { /* block type 1 */ - len -= 2; /* sub. size of the rest of block header */ - x = pack_getc(f); /* one byte of frequency */ - freq = 1000000 / (256-x); - - x = pack_getc(f); /* skip one byte */ - - spl = create_sample(8, FALSE, freq, len); - - if (spl) { - if (pack_fread(spl->data, len, f) < len) { - destroy_sample(spl); - spl = NULL; - } - } - } - else { /* block type 9 */ - len -= 12; /* sub. size of the rest of block header */ - freq = pack_igetw(f); /* two bytes of frequency */ - - x = pack_igetw(f); /* skip two bytes */ - - bits = pack_getc(f); /* # of bits per sample */ - if (bits != 8 && bits != 16) - goto getout; - - x = pack_getc(f); - if (x != 1) /* # of channels: should be mono */ - goto getout; - - pack_fread(buffer, 0x6, f); /* skip 6 bytes of unknown data */ - - spl = create_sample(bits, FALSE, freq, len*8/bits); - - if (spl) { - if (bits == 8) { - if (pack_fread(spl->data, len, f) < len) { - destroy_sample(spl); - spl = NULL; - } - } - else { - len /= 2; - for (x=0; xdata)[x] = (signed short)s^0x8000; - } - } - } - } - - getout: - return spl; -} - - - -/* load_wav: - * Reads a RIFF WAV format sample file, returning a SAMPLE structure, - * or NULL on error. - */ -SAMPLE *load_wav(AL_CONST char *filename) -{ - PACKFILE *f; - SAMPLE *spl; - ASSERT(filename); - - f = pack_fopen(filename, F_READ); - if (!f) - return NULL; - - spl = load_wav_pf(f); - - pack_fclose(f); - - return spl; -} - - - -/* load_wav_pf: - * Reads a RIFF WAV format sample from the packfile given, returning a - * SAMPLE structure, or NULL on error. - * - * Note that the loader does not stop reading bytes from the PACKFILE until - * it sees the EOF. If you want to embed a WAV file into another file, you - * will have to implement your own chunking system that stops reading at the - * end of the chunk. - * - * If unsuccessful the offset into the file is unspecified, i.e. you must - * either reset the offset to some known place or close the packfile. The - * packfile is not closed by this function. - */ -SAMPLE *load_wav_pf(PACKFILE *f) -{ - char buffer[25]; - int i; - int length, len; - int freq = 22050; - int bits = 8; - int channels = 1; - int s; - SAMPLE *spl = NULL; - ASSERT(f); - - memset(buffer, 0, sizeof buffer); - - pack_fread(buffer, 12, f); /* check RIFF header */ - if (memcmp(buffer, "RIFF", 4) || memcmp(buffer+8, "WAVE", 4)) - goto getout; - - while (TRUE) { - if (pack_fread(buffer, 4, f) != 4) - break; - - length = pack_igetl(f); /* read chunk length */ - - if (memcmp(buffer, "fmt ", 4) == 0) { - i = pack_igetw(f); /* should be 1 for PCM data */ - length -= 2; - if (i != 1) - goto getout; - - channels = pack_igetw(f); /* mono or stereo data */ - length -= 2; - if ((channels != 1) && (channels != 2)) - goto getout; - - freq = pack_igetl(f); /* sample frequency */ - length -= 4; - - pack_igetl(f); /* skip six bytes */ - pack_igetw(f); - length -= 6; - - bits = pack_igetw(f); /* 8 or 16 bit data? */ - length -= 2; - if ((bits != 8) && (bits != 16)) - goto getout; - } - else if (memcmp(buffer, "data", 4) == 0) { - if (channels == 2) { - /* allocate enough space even if length is odd for some reason */ - len = (length + 1) / 2; - } - else { - ASSERT(channels == 1); - len = length; - } - - if (bits == 16) - len /= 2; - - spl = create_sample(bits, ((channels == 2) ? TRUE : FALSE), freq, len); - - if (spl) { - if (bits == 8) { - if (pack_fread(spl->data, length, f) < length) { - destroy_sample(spl); - spl = NULL; - } - } - else { - for (i=0; idata)[i] = (signed short)s^0x8000; - } - } - - length = 0; - } - } - - while (length > 0) { /* skip the remainder of the chunk */ - if (pack_getc(f) == EOF) - break; - - length--; - } - } - - getout: - return spl; -} - - - -/* create_sample: - * Constructs a new sample structure of the specified type. - */ -SAMPLE *create_sample(int bits, int stereo, int freq, int len) -{ - SAMPLE *spl; - ASSERT(freq > 0); - ASSERT(len > 0); - - spl = _AL_MALLOC(sizeof(SAMPLE)); - if (!spl) - return NULL; - - spl->bits = bits; - spl->stereo = stereo; - spl->freq = freq; - spl->priority = 128; - spl->len = len; - spl->loop_start = 0; - spl->loop_end = len; - spl->param = 0; - - spl->data = _AL_MALLOC_ATOMIC(len * ((bits==8) ? 1 : sizeof(short)) * ((stereo) ? 2 : 1)); - if (!spl->data) { - _AL_FREE(spl); - return NULL; - } - - lock_sample(spl); - return spl; -} - - - -/* destroy_sample: - * Frees a SAMPLE struct, checking whether the sample is currently playing, - * and stopping it if it is. - */ -void destroy_sample(SAMPLE *spl) -{ - if (spl) { - stop_sample(spl); - - if (spl->data) { - UNLOCK_DATA(spl->data, spl->len * ((spl->bits==8) ? 1 : sizeof(short)) * ((spl->stereo) ? 2 : 1)); - _AL_FREE(spl->data); - } - - UNLOCK_DATA(spl, sizeof(SAMPLE)); - _AL_FREE(spl); - } -} - - - -/* absolute_freq: - * Converts a pitch from the relative 1000 = original format to an absolute - * value in hz. - */ -static INLINE int absolute_freq(int freq, AL_CONST SAMPLE *spl) -{ - ASSERT(spl); - if (freq == 1000) - return spl->freq; - else - return (spl->freq * freq) / 1000; -} - - - -/* play_sample: - * Triggers a sample at the specified volume, pan position, and frequency. - * The volume and pan range from 0 (min/left) to 255 (max/right), although - * the resolution actually used by the playback routines is likely to be - * less than this. Frequency is relative rather than absolute: 1000 - * represents the frequency that the sample was recorded at, 2000 is - * twice this, etc. If loop is true the sample will repeat until you call - * stop_sample(), and can be manipulated while it is playing by calling - * adjust_sample(). - */ -int play_sample(AL_CONST SAMPLE *spl, int vol, int pan, int freq, int loop) -{ - int voice; - ASSERT(spl); - ASSERT(vol >= 0 && vol <= 255); - ASSERT(pan >= 0 && pan <= 255); - ASSERT(freq > 0); - - voice = allocate_voice(spl); - if (voice >= 0) { - voice_set_volume(voice, vol); - voice_set_pan(voice, pan); - voice_set_frequency(voice, absolute_freq(freq, spl)); - voice_set_playmode(voice, (loop ? PLAYMODE_LOOP : PLAYMODE_PLAY)); - voice_start(voice); - release_voice(voice); - } - - return voice; -} - -END_OF_FUNCTION(play_sample); - - - -/* adjust_sample: - * Alters the parameters of a sample while it is playing, useful for - * manipulating looped sounds. You can alter the volume, pan, and - * frequency, and can also remove the looping flag, which will stop - * the sample when it next reaches the end of its loop. If there are - * several copies of the same sample playing, this will adjust the - * first one it comes across. If the sample is not playing it has no - * effect. - */ -void adjust_sample(AL_CONST SAMPLE *spl, int vol, int pan, int freq, int loop) -{ - int c; - ASSERT(spl); - - for (c=0; cvoices; c++) - if (_phys_voice[c].num < 0) - return c; - - /* look for an autokill voice that has stopped */ - for (c=0; cvoices; c++) { - voice = virt_voice + _phys_voice[c].num; - if ((voice->autokill) && (digi_driver->get_position(c) < 0)) { - digi_driver->release_voice(c); - voice->sample = NULL; - voice->num = -1; - _phys_voice[c].num = -1; - return c; - } - } - - /* ok, we're going to have to get rid of something to make room... */ - for (c=0; cvoices; c++) { - voice = virt_voice + _phys_voice[c].num; - - /* sort by voice priorities */ - if (voice->priority <= priority) { - score = 65536 - voice->priority * 256; - - /* bias with a least-recently-used counter */ - score += CLAMP(0, retrace_count - voice->time, 32768); - - /* bias according to whether the voice is looping or not */ - if (!(_phys_voice[c].playmode & PLAYMODE_LOOP)) - score += 32768; - - if (score > best_score) { - best = c; - best_score = score; - } - } - } - - if (best >= 0) { - /* kill off the old voice */ - digi_driver->stop_voice(best); - digi_driver->release_voice(best); - virt_voice[_phys_voice[best].num].num = -1; - _phys_voice[best].num = -1; - return best; - } - - return -1; -} - - - -/* allocate_virtual_voice: - * Allocates a virtual voice. This doesn't need to worry about killing off - * others to make room, as we allow up to 256 virtual voices to be used - * simultaneously. - */ -static INLINE int allocate_virtual_voice(void) -{ - int num_virt_voices, c; - - num_virt_voices = VIRTUAL_VOICES; - if (midi_driver->max_voices < 0) - num_virt_voices -= midi_driver->voices; - - /* look for a free voice */ - for (c=0; cget_position(virt_voice[c].num) < 0) { - digi_driver->release_voice(virt_voice[c].num); - _phys_voice[virt_voice[c].num].num = -1; - virt_voice[c].sample = NULL; - virt_voice[c].num = -1; - return c; - } - } - } - } - - return -1; -} - - - -/* allocate_voice: - * Allocates a voice ready for playing the specified sample, returning - * the voice number (note this is not the same as the physical voice - * number used by the sound drivers, and must only be used with the other - * voice functions, _not_ passed directly to the driver routines). - * Returns -1 if there is no voice available (this should never happen, - * since there are 256 virtual voices and anyone who needs more than that - * needs some urgent repairs to their brain :-) - */ -int allocate_voice(AL_CONST SAMPLE *spl) -{ - int phys, virt; - ASSERT(spl); - - phys = allocate_physical_voice(spl->priority); - virt = allocate_virtual_voice(); - - if (virt >= 0) { - virt_voice[virt].sample = spl; - virt_voice[virt].num = phys; - virt_voice[virt].autokill = FALSE; - virt_voice[virt].time = retrace_count; - virt_voice[virt].priority = spl->priority; - - if (phys >= 0) { - _phys_voice[phys].num = virt; - _phys_voice[phys].playmode = 0; - _phys_voice[phys].vol = ((_digi_volume >= 0) ? _digi_volume : 255) << 12; - _phys_voice[phys].pan = 128 << 12; - _phys_voice[phys].freq = spl->freq << 12; - _phys_voice[phys].dvol = 0; - _phys_voice[phys].dpan = 0; - _phys_voice[phys].dfreq = 0; - - digi_driver->init_voice(phys, spl); - } - } - - return virt; -} - -END_OF_FUNCTION(allocate_voice); - - - -/* deallocate_voice: - * Releases a voice that was previously returned by allocate_voice(). - */ -void deallocate_voice(int voice) -{ - ASSERT(voice >= 0 && voice < VIRTUAL_VOICES); - - if (virt_voice[voice].num >= 0) { - digi_driver->stop_voice(virt_voice[voice].num); - digi_driver->release_voice(virt_voice[voice].num); - _phys_voice[virt_voice[voice].num].num = -1; - virt_voice[voice].num = -1; - } - - virt_voice[voice].sample = NULL; -} - -END_OF_FUNCTION(deallocate_voice); - - - -/* reallocate_voice: - * Switches an already-allocated voice to use a different sample. - */ -void reallocate_voice(int voice, AL_CONST SAMPLE *spl) -{ - int phys; - ASSERT(spl); - ASSERT(voice >= 0 && voice < VIRTUAL_VOICES); - - phys = virt_voice[voice].num; - - if (phys >= 0) { - digi_driver->stop_voice(phys); - digi_driver->release_voice(phys); - } - - virt_voice[voice].sample = spl; - virt_voice[voice].autokill = FALSE; - virt_voice[voice].time = retrace_count; - virt_voice[voice].priority = spl->priority; - - if (phys >= 0) { - _phys_voice[phys].playmode = 0; - _phys_voice[phys].vol = ((_digi_volume >= 0) ? _digi_volume : 255) << 12; - _phys_voice[phys].pan = 128 << 12; - _phys_voice[phys].freq = spl->freq << 12; - _phys_voice[phys].dvol = 0; - _phys_voice[phys].dpan = 0; - _phys_voice[phys].dfreq = 0; - - digi_driver->init_voice(phys, spl); - } -} - -END_OF_FUNCTION(reallocate_voice); - - - -/* release_voice: - * Flags that a voice is no longer going to be updated, so it can - * automatically be freed as soon as the sample finishes playing. - */ -void release_voice(int voice) -{ - ASSERT(voice >= 0 && voice < VIRTUAL_VOICES); - virt_voice[voice].autokill = TRUE; -} - -END_OF_FUNCTION(release_voice); - - - -/* voice_start: - * Starts a voice playing. - */ -void voice_start(int voice) -{ - ASSERT(voice >= 0 && voice < VIRTUAL_VOICES); - if (virt_voice[voice].num >= 0) - digi_driver->start_voice(virt_voice[voice].num); - - virt_voice[voice].time = retrace_count; -} - -END_OF_FUNCTION(voice_start); - - - -/* voice_stop: - * Stops a voice from playing. - */ -void voice_stop(int voice) -{ - ASSERT(voice >= 0 && voice < VIRTUAL_VOICES); - if (virt_voice[voice].num >= 0) - digi_driver->stop_voice(virt_voice[voice].num); -} - -END_OF_FUNCTION(voice_stop); - - - -/* voice_set_priority: - * Adjusts the priority of a voice (0-255). - */ -void voice_set_priority(int voice, int priority) -{ - ASSERT(voice >= 0 && voice < VIRTUAL_VOICES); - ASSERT(priority >= 0 && priority <= 255); - virt_voice[voice].priority = priority; -} - -END_OF_FUNCTION(voice_set_priority); - - - -/* voice_check: - * Checks whether a voice is playing, returning the sample if it is, - * or NULL if it has finished or been preempted by a different sound. - */ -SAMPLE *voice_check(int voice) -{ - ASSERT(voice >= 0 && voice < VIRTUAL_VOICES); - if (virt_voice[voice].sample) { - if (virt_voice[voice].num < 0) - return NULL; - - if (virt_voice[voice].autokill) - if (voice_get_position(voice) < 0) - return NULL; - - return (SAMPLE*)virt_voice[voice].sample; - } - else - return NULL; -} - -END_OF_FUNCTION(voice_check); - - - -/* voice_get_position: - * Returns the current play position of a voice, or -1 if that cannot - * be determined (because it has finished or been preempted by a - * different sound). - */ -int voice_get_position(int voice) -{ - ASSERT(voice >= 0 && voice < VIRTUAL_VOICES); - if (virt_voice[voice].num >= 0) - return digi_driver->get_position(virt_voice[voice].num); - else - return -1; -} - -END_OF_FUNCTION(voice_get_position); - - - -/* voice_set_position: - * Sets the play position of a voice. - */ -void voice_set_position(int voice, int position) -{ - ASSERT(voice >= 0 && voice < VIRTUAL_VOICES); - if (virt_voice[voice].num >= 0) - digi_driver->set_position(virt_voice[voice].num, position); -} - -END_OF_FUNCTION(voice_set_position); - - - -/* voice_set_playmode: - * Sets the loopmode of a voice. - */ -void voice_set_playmode(int voice, int playmode) -{ - ASSERT(voice >= 0 && voice < VIRTUAL_VOICES); - if (virt_voice[voice].num >= 0) { - _phys_voice[virt_voice[voice].num].playmode = playmode; - digi_driver->loop_voice(virt_voice[voice].num, playmode); - - if (playmode & PLAYMODE_BACKWARD) - digi_driver->set_position(virt_voice[voice].num, virt_voice[voice].sample->len-1); - } -} - -END_OF_FUNCTION(voice_set_playmode); - - - -/* voice_get_volume: - * Returns the current volume of a voice, or -1 if that cannot - * be determined (because it has finished or been preempted by a - * different sound). - */ -int voice_get_volume(int voice) -{ - int vol; - ASSERT(voice >= 0 && voice < VIRTUAL_VOICES); - - if (virt_voice[voice].num >= 0) - vol = digi_driver->get_volume(virt_voice[voice].num); - else - vol = -1; - - if ((vol >= 0) && (_digi_volume >= 0)) { - if (_digi_volume > 0) - vol = CLAMP(0, (vol * 255) / _digi_volume, 255); - else - vol = 0; - } - - return vol; -} - -END_OF_FUNCTION(voice_get_volume); - - - -/* voice_set_volume: - * Sets the current volume of a voice. - */ -void voice_set_volume(int voice, int volume) -{ - ASSERT(voice >= 0 && voice < VIRTUAL_VOICES); - ASSERT(volume >= 0 && volume <= 255); - - if (_digi_volume >= 0) - volume = (volume * _digi_volume) / 255; - - if (virt_voice[voice].num >= 0) { - _phys_voice[virt_voice[voice].num].vol = volume << 12; - _phys_voice[virt_voice[voice].num].dvol = 0; - - digi_driver->set_volume(virt_voice[voice].num, volume); - } -} - -END_OF_FUNCTION(voice_set_volume); - - - -/* voice_ramp_volume: - * Begins a volume ramp operation. - */ -void voice_ramp_volume(int voice, int time, int endvol) -{ - ASSERT(voice >= 0 && voice < VIRTUAL_VOICES); - ASSERT(endvol >= 0 && endvol <= 255); - ASSERT(time >= 0); - - if (_digi_volume >= 0) - endvol = (endvol * _digi_volume) / 255; - - if (virt_voice[voice].num >= 0) { - if (digi_driver->ramp_volume) { - digi_driver->ramp_volume(virt_voice[voice].num, time, endvol); - } - else { - int d = (endvol << 12) - _phys_voice[virt_voice[voice].num].vol; - time = MAX(time * SWEEP_FREQ / 1000, 1); - _phys_voice[virt_voice[voice].num].target_vol = endvol << 12; - _phys_voice[virt_voice[voice].num].dvol = d / time; - } - } -} - -END_OF_FUNCTION(voice_ramp_volume); - - - -/* voice_stop_volumeramp: - * Ends a volume ramp operation. - */ -void voice_stop_volumeramp(int voice) -{ - ASSERT(voice >= 0 && voice < VIRTUAL_VOICES); - if (virt_voice[voice].num >= 0) { - _phys_voice[virt_voice[voice].num].dvol = 0; - - if (digi_driver->stop_volume_ramp) - digi_driver->stop_volume_ramp(virt_voice[voice].num); - } -} - -END_OF_FUNCTION(voice_stop_volumeramp); - - - -/* voice_get_frequency: - * Returns the current frequency of a voice, or -1 if that cannot - * be determined (because it has finished or been preempted by a - * different sound). - */ -int voice_get_frequency(int voice) -{ - ASSERT(voice >= 0 && voice < VIRTUAL_VOICES); - if (virt_voice[voice].num >= 0) - return digi_driver->get_frequency(virt_voice[voice].num); - else - return -1; -} - -END_OF_FUNCTION(voice_get_frequency); - - - -/* voice_set_frequency: - * Sets the pitch of a voice. - */ -void voice_set_frequency(int voice, int frequency) -{ - ASSERT(voice >= 0 && voice < VIRTUAL_VOICES); - ASSERT(frequency > 0); - - if (virt_voice[voice].num >= 0) { - _phys_voice[virt_voice[voice].num].freq = frequency << 12; - _phys_voice[virt_voice[voice].num].dfreq = 0; - - digi_driver->set_frequency(virt_voice[voice].num, frequency); - } -} - -END_OF_FUNCTION(voice_set_frequency); - - - -/* voice_sweep_frequency: - * Begins a frequency sweep (glissando) operation. - */ -void voice_sweep_frequency(int voice, int time, int endfreq) -{ - ASSERT(voice >= 0 && voice < VIRTUAL_VOICES); - ASSERT(endfreq > 0); - ASSERT(time >= 0); - - if (virt_voice[voice].num >= 0) { - if (digi_driver->sweep_frequency) { - digi_driver->sweep_frequency(virt_voice[voice].num, time, endfreq); - } - else { - int d = (endfreq << 12) - _phys_voice[virt_voice[voice].num].freq; - time = MAX(time * SWEEP_FREQ / 1000, 1); - _phys_voice[virt_voice[voice].num].target_freq = endfreq << 12; - _phys_voice[virt_voice[voice].num].dfreq = d / time; - } - } -} - -END_OF_FUNCTION(voice_sweep_frequency); - - - -/* voice_stop_frequency_sweep: - * Ends a frequency sweep. - */ -void voice_stop_frequency_sweep(int voice) -{ - ASSERT(voice >= 0 && voice < VIRTUAL_VOICES); - if (virt_voice[voice].num >= 0) { - _phys_voice[virt_voice[voice].num].dfreq = 0; - - if (digi_driver->stop_frequency_sweep) - digi_driver->stop_frequency_sweep(virt_voice[voice].num); - } -} - -END_OF_FUNCTION(voice_stop_frequency_sweep); - - - -/* voice_get_pan: - * Returns the current pan position of a voice, or -1 if that cannot - * be determined (because it has finished or been preempted by a - * different sound). - */ -int voice_get_pan(int voice) -{ - int pan; - ASSERT(voice >= 0 && voice < VIRTUAL_VOICES); - - if (virt_voice[voice].num >= 0) - pan = digi_driver->get_pan(virt_voice[voice].num); - else - pan = -1; - - if ((pan >= 0) && (_sound_flip_pan)) - pan = 255 - pan; - - return pan; -} - -END_OF_FUNCTION(voice_get_pan); - - - -/* voice_set_pan: - * Sets the pan position of a voice. - */ -void voice_set_pan(int voice, int pan) -{ - ASSERT(voice >= 0 && voice < VIRTUAL_VOICES); - ASSERT(pan >= 0 && pan <= 255); - if (_sound_flip_pan) - pan = 255 - pan; - - if (virt_voice[voice].num >= 0) { - _phys_voice[virt_voice[voice].num].pan = pan << 12; - _phys_voice[virt_voice[voice].num].dpan = 0; - - digi_driver->set_pan(virt_voice[voice].num, pan); - } -} - -END_OF_FUNCTION(voice_set_pan); - - - -/* voice_sweep_pan: - * Begins a pan sweep (left <-> right movement) operation. - */ -void voice_sweep_pan(int voice, int time, int endpan) -{ - ASSERT(voice >= 0 && voice < VIRTUAL_VOICES); - ASSERT(endpan >= 0 && endpan <= 255); - ASSERT(time >= 0); - - if (_sound_flip_pan) - endpan = 255 - endpan; - - if (virt_voice[voice].num >= 0) { - if (digi_driver->sweep_pan) { - digi_driver->sweep_pan(virt_voice[voice].num, time, endpan); - } - else { - int d = (endpan << 12) - _phys_voice[virt_voice[voice].num].pan; - time = MAX(time * SWEEP_FREQ / 1000, 1); - _phys_voice[virt_voice[voice].num].target_pan = endpan << 12; - _phys_voice[virt_voice[voice].num].dpan = d / time; - } - } -} - -END_OF_FUNCTION(voice_sweep_pan); - - - -/* voice_stop_pan_sweep: - * Ends a pan sweep. - */ -void voice_stop_pan_sweep(int voice) -{ - ASSERT(voice >= 0 && voice < VIRTUAL_VOICES); - if (virt_voice[voice].num >= 0) { - _phys_voice[virt_voice[voice].num].dpan = 0; - - if (digi_driver->stop_pan_sweep) - digi_driver->stop_pan_sweep(virt_voice[voice].num); - } -} - -END_OF_FUNCTION(voice_stop_pan_sweep); - - - -/* voice_set_echo: - * Sets the echo parameters of a voice. - */ -void voice_set_echo(int voice, int strength, int delay) -{ - ASSERT(voice >= 0 && voice < VIRTUAL_VOICES); - if ((virt_voice[voice].num >= 0) && (digi_driver->set_echo)) - digi_driver->set_echo(virt_voice[voice].num, strength, delay); -} - -END_OF_FUNCTION(voice_set_echo); - - - -/* voice_set_tremolo: - * Sets the tremolo parameters of a voice. - */ -void voice_set_tremolo(int voice, int rate, int depth) -{ - ASSERT(voice >= 0 && voice < VIRTUAL_VOICES); - if ((virt_voice[voice].num >= 0) && (digi_driver->set_tremolo)) - digi_driver->set_tremolo(virt_voice[voice].num, rate, depth); -} - -END_OF_FUNCTION(voice_set_tremolo); - - - -/* voice_set_vibrato: - * Sets the vibrato parameters of a voice. - */ -void voice_set_vibrato(int voice, int rate, int depth) -{ - ASSERT(voice >= 0 && voice < VIRTUAL_VOICES); - if ((virt_voice[voice].num >= 0) && (digi_driver->set_vibrato)) - digi_driver->set_vibrato(virt_voice[voice].num, rate, depth); -} - -END_OF_FUNCTION(voice_set_vibrato); - - - -/* update_sweeps: - * Timer callback routine used to implement volume/frequency/pan sweep - * effects, for those drivers that can't do them directly. - */ -static void update_sweeps(void) -{ - int phys_voices, i; - - phys_voices = digi_driver->voices; - if (midi_driver->max_voices < 0) - phys_voices += midi_driver->voices; - - for (i=0; i= 0) { - /* update volume ramp */ - if ((!digi_driver->ramp_volume) && (_phys_voice[i].dvol)) { - _phys_voice[i].vol += _phys_voice[i].dvol; - - if (((_phys_voice[i].dvol > 0) && (_phys_voice[i].vol >= _phys_voice[i].target_vol)) || - ((_phys_voice[i].dvol < 0) && (_phys_voice[i].vol <= _phys_voice[i].target_vol))) { - _phys_voice[i].vol = _phys_voice[i].target_vol; - _phys_voice[i].dvol = 0; - } - - digi_driver->set_volume(i, _phys_voice[i].vol >> 12); - } - - /* update frequency sweep */ - if ((!digi_driver->sweep_frequency) && (_phys_voice[i].dfreq)) { - _phys_voice[i].freq += _phys_voice[i].dfreq; - - if (((_phys_voice[i].dfreq > 0) && (_phys_voice[i].freq >= _phys_voice[i].target_freq)) || - ((_phys_voice[i].dfreq < 0) && (_phys_voice[i].freq <= _phys_voice[i].target_freq))) { - _phys_voice[i].freq = _phys_voice[i].target_freq; - _phys_voice[i].dfreq = 0; - } - - digi_driver->set_frequency(i, _phys_voice[i].freq >> 12); - } - - /* update pan sweep */ - if ((!digi_driver->sweep_pan) && (_phys_voice[i].dpan)) { - _phys_voice[i].pan += _phys_voice[i].dpan; - - if (((_phys_voice[i].dpan > 0) && (_phys_voice[i].pan >= _phys_voice[i].target_pan)) || - ((_phys_voice[i].dpan < 0) && (_phys_voice[i].pan <= _phys_voice[i].target_pan))) { - _phys_voice[i].pan = _phys_voice[i].target_pan; - _phys_voice[i].dpan = 0; - } - - digi_driver->set_pan(i, _phys_voice[i].pan >> 12); - } - } - } -} - -END_OF_STATIC_FUNCTION(update_sweeps); - - - -/* get_sound_input_cap_bits: - * Recording capabilities: number of bits - */ -int get_sound_input_cap_bits(void) -{ - return digi_input_driver->rec_cap_bits; -} - - - -/* get_sound_input_cap_stereo: - * Recording capabilities: stereo - */ -int get_sound_input_cap_stereo(void) -{ - return digi_input_driver->rec_cap_stereo; -} - - - -/* get_sound_input_cap_rate: - * Recording capabilities: maximum sampling rate - */ -int get_sound_input_cap_rate(int bits, int stereo) -{ - if (digi_input_driver->rec_cap_rate) - return digi_input_driver->rec_cap_rate(bits, stereo); - else - return 0; -} - - - -/* get_sound_input_cap_parm: - * Checks whether given parameters can be set. - */ -int get_sound_input_cap_parm(int rate, int bits, int stereo) -{ - if (digi_input_driver->rec_cap_parm) - return digi_input_driver->rec_cap_parm(rate, bits, stereo); - else - return 0; -} - - - -/* set_sound_input_source: - * Selects the sampling source for audio recording. - */ -int set_sound_input_source(int source) -{ - if (digi_input_driver->rec_source) - return digi_input_driver->rec_source(source); - else - return -1; -} - - - -/* start_sound_input: - * Starts recording, and returns recording buffer size. - */ -int start_sound_input(int rate, int bits, int stereo) -{ - if (digi_input_driver->rec_start) - return digi_input_driver->rec_start(rate, bits, stereo); - else - return 0; -} - - - -/* stop_sound_input: - * Ends recording. - */ -void stop_sound_input(void) -{ - if (digi_input_driver->rec_stop) - digi_input_driver->rec_stop(); -} - - - -/* read_sound_input: - * Reads audio data. - */ -int read_sound_input(void *buffer) -{ - if (digi_input_driver->rec_read) - return digi_input_driver->rec_read(buffer); - else - return 0; -} - -END_OF_FUNCTION(read_sound_input); - - - -/* sound_lock_mem: - * Locks memory used by the functions in this file. - */ -static void sound_lock_mem(void) -{ - LOCK_VARIABLE(digi_none); - LOCK_VARIABLE(_midi_none); - LOCK_VARIABLE(digi_card); - LOCK_VARIABLE(midi_card); - LOCK_VARIABLE(digi_driver); - LOCK_VARIABLE(midi_driver); - LOCK_VARIABLE(digi_recorder); - LOCK_VARIABLE(midi_recorder); - LOCK_VARIABLE(virt_voice); - LOCK_VARIABLE(_phys_voice); - LOCK_VARIABLE(_digi_volume); - LOCK_VARIABLE(_midi_volume); - LOCK_VARIABLE(_sound_flip_pan); - LOCK_VARIABLE(_sound_hq); - LOCK_FUNCTION(_dummy_detect); - LOCK_FUNCTION(play_sample); - LOCK_FUNCTION(adjust_sample); - LOCK_FUNCTION(stop_sample); - LOCK_FUNCTION(allocate_voice); - LOCK_FUNCTION(deallocate_voice); - LOCK_FUNCTION(reallocate_voice); - LOCK_FUNCTION(voice_start); - LOCK_FUNCTION(voice_stop); - LOCK_FUNCTION(voice_set_priority); - LOCK_FUNCTION(voice_check); - LOCK_FUNCTION(voice_get_position); - LOCK_FUNCTION(voice_set_position); - LOCK_FUNCTION(voice_set_playmode); - LOCK_FUNCTION(voice_get_volume); - LOCK_FUNCTION(voice_set_volume); - LOCK_FUNCTION(voice_ramp_volume); - LOCK_FUNCTION(voice_stop_volumeramp); - LOCK_FUNCTION(voice_get_frequency); - LOCK_FUNCTION(voice_set_frequency); - LOCK_FUNCTION(voice_sweep_frequency); - LOCK_FUNCTION(voice_stop_frequency_sweep); - LOCK_FUNCTION(voice_get_pan); - LOCK_FUNCTION(voice_set_pan); - LOCK_FUNCTION(voice_sweep_pan); - LOCK_FUNCTION(voice_stop_pan_sweep); - LOCK_FUNCTION(voice_set_echo); - LOCK_FUNCTION(voice_set_tremolo); - LOCK_FUNCTION(voice_set_vibrato); - LOCK_FUNCTION(update_sweeps); - LOCK_FUNCTION(read_sound_input); -} - diff --git a/src/allegro/src/stream.c b/src/allegro/src/stream.c deleted file mode 100644 index 59757732e..000000000 --- a/src/allegro/src/stream.c +++ /dev/null @@ -1,196 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * Audio stream functions. - * - * By Shawn Hargreaves (original version by Andrew Ellem). - * - * See readme.txt for copyright information. - */ - - -#include "allegro.h" -#include "allegro/internal/aintern.h" - - - -/* play_audio_stream: - * Creates a new audio stream and starts it playing. The length is the - * size of each transfer buffer. - */ -AUDIOSTREAM *play_audio_stream(int len, int bits, int stereo, int freq, int vol, int pan) -{ - AUDIOSTREAM *stream; - int i, bufcount; - ASSERT(len > 0); - ASSERT(bits > 0); - ASSERT(freq > 0); - - /* decide how many buffer fragments we will need */ - if ((digi_driver) && (digi_driver->buffer_size)) - i = digi_driver->buffer_size(); - else - i = 2048; - - if (len >= i) - bufcount = 1; - else - bufcount = (i + len-1) / len; - - /* create the stream structure */ - stream = _AL_MALLOC(sizeof(AUDIOSTREAM)); - if (!stream) - return NULL; - - stream->len = len; - stream->bufcount = bufcount; - stream->bufnum = 0; - stream->active = 1; - stream->locked = NULL; - - /* create the underlying sample */ - stream->samp = create_sample(bits, stereo, freq, len*bufcount*2); - if (!stream->samp) { - _AL_FREE(stream); - return NULL; - } - - /* fill with silence */ - if (bits == 16) { - unsigned short *p = stream->samp->data; - for (i=0; i < len*bufcount*2 * ((stereo) ? 2 : 1); i++) - p[i] = 0x8000; - } - else { - unsigned char *p = stream->samp->data; - for (i=0; i < len*bufcount*2 * ((stereo) ? 2 : 1); i++) - p[i] = 0x80; - } - - LOCK_DATA(stream, sizeof(AUDIOSTREAM)); - - /* play the sample in looped mode */ - stream->voice = allocate_voice(stream->samp); - if (stream->voice < 0) { - destroy_sample(stream->samp); - UNLOCK_DATA(stream, sizeof(AUDIOSTREAM)); - _AL_FREE(stream); - return NULL; - } - - voice_set_playmode(stream->voice, PLAYMODE_LOOP); - voice_set_volume(stream->voice, vol); - voice_set_pan(stream->voice, pan); - - return stream; -} - - - -/* stop_audio_stream: - * Destroys an audio stream when it is no longer required. - */ -void stop_audio_stream(AUDIOSTREAM *stream) -{ - ASSERT(stream); - - if ((stream->locked) && (digi_driver->unlock_voice)) - digi_driver->unlock_voice(stream->voice); - - voice_stop(stream->voice); - deallocate_voice(stream->voice); - - destroy_sample(stream->samp); - - UNLOCK_DATA(stream, sizeof(AUDIOSTREAM)); - _AL_FREE(stream); -} - - - -/* get_audio_stream_buffer: - * Returns a pointer to the next audio buffer, or NULL if the previous - * data is still playing. This must be called at regular intervals while - * the stream is playing, and you must fill the return address with the - * appropriate number (the same length that you specified when you create - * the stream) of samples. Call free_audio_stream_buffer() after loading - * the new samples, to indicate that the data is now valid. - */ -void *get_audio_stream_buffer(AUDIOSTREAM *stream) -{ - int pos; - char *data = NULL; - ASSERT(stream); - - if (stream->bufnum == stream->active * stream->bufcount) { - /* waiting for the sample to switch halves */ - pos = voice_get_position(stream->voice); - - if (stream->active == 0) { - if (pos < stream->len*stream->bufcount) - return NULL; - } - else { - if (pos >= stream->len*stream->bufcount) - return NULL; - } - - stream->active = 1-stream->active; - } - - /* make sure we got access to the right bit of sample data */ - if (!stream->locked) { - pos = (1-stream->active) * stream->bufcount * stream->len; - - if (digi_driver->lock_voice) - data = digi_driver->lock_voice(stream->voice, pos, pos+stream->bufcount*stream->len); - - if (data) - stream->locked = data; - else - stream->locked = (char *)stream->samp->data + (pos * ((stream->samp->bits==8) ? 1 : sizeof(short)) * ((stream->samp->stereo) ? 2 : 1)); - } - - return (char *)stream->locked + ((stream->bufnum % stream->bufcount) * - stream->len * - ((stream->samp->bits==8) ? 1 : sizeof(short)) * - ((stream->samp->stereo) ? 2 : 1)); -} - - - -/* free_audio_stream_buffer: - * Indicates that a sample buffer previously returned by a call to - * get_audio_stream_buffer() has now been filled with valid data. - */ -void free_audio_stream_buffer(AUDIOSTREAM *stream) -{ - ASSERT(stream); - - /* flip buffers */ - stream->bufnum++; - - if (stream->bufnum >= stream->bufcount*2) - stream->bufnum = 0; - - /* unlock old waveform region */ - if ((stream->locked) && - ((stream->bufnum == 0) || (stream->bufnum == stream->bufcount))) { - - if (digi_driver->unlock_voice) - digi_driver->unlock_voice(stream->voice); - - stream->locked = NULL; - } - - /* start playing if it wasn't already */ - if (voice_get_position(stream->voice) == -1) - voice_start(stream->voice); -} diff --git a/src/allegro/src/unix/alsa5.c b/src/allegro/src/unix/alsa5.c deleted file mode 100644 index 00f411f28..000000000 --- a/src/allegro/src/unix/alsa5.c +++ /dev/null @@ -1,409 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * ALSA 0.5 sound driver. - * - * By Peter Wang (based heavily on uoss.c) - * - * See readme.txt for copyright information. - */ - - -#include "allegro.h" - -#if (ALLEGRO_ALSA_VERSION == 5) && (defined ALLEGRO_WITH_ALSADIGI) && ((!defined ALLEGRO_WITH_MODULES) || (defined ALLEGRO_MODULE)) - -#include "allegro/internal/aintern.h" -#ifdef ALLEGRO_QNX -#include "allegro/platform/aintqnx.h" -#else -#include "allegro/platform/aintunix.h" -#endif - -#ifndef SCAN_DEPEND - #include - #include -#endif - - -#ifndef SND_PCM_SFMT_S16_NE - #ifdef ALLEGRO_BIG_ENDIAN - #define SND_PCM_SFMT_S16_NE SND_PCM_SFMT_S16_BE - #else - #define SND_PCM_SFMT_S16_NE SND_PCM_SFMT_S16_LE - #endif -#endif -#ifndef SND_PCM_SFMT_U16_NE - #ifdef ALLEGRO_BIG_ENDIAN - #define SND_PCM_SFMT_U16_NE SND_PCM_SFMT_U16_BE - #else - #define SND_PCM_SFMT_U16_NE SND_PCM_SFMT_U16_LE - #endif -#endif - - -#define ALSA_DEFAULT_NUMFRAGS 16 - - -static snd_pcm_t *pcm_handle; -static int alsa_bufsize; -static unsigned char *alsa_bufdata; -static int alsa_bits, alsa_signed, alsa_rate, alsa_stereo; -static int alsa_fragments; - -static char alsa_desc[256] = EMPTY_STRING; - - - -static int alsa_detect(int input); -static int alsa_init(int input, int voices); -static void alsa_exit(int input); -static int alsa_set_mixer_volume(int volume); -static int alsa_buffer_size(void); - - - -DIGI_DRIVER digi_alsa = -{ - DIGI_ALSA, - empty_string, - empty_string, - "ALSA", - 0, - 0, - MIXER_MAX_SFX, - MIXER_DEF_SFX, - - alsa_detect, - alsa_init, - alsa_exit, - alsa_set_mixer_volume, - NULL, - - NULL, - NULL, - alsa_buffer_size, - _mixer_init_voice, - _mixer_release_voice, - _mixer_start_voice, - _mixer_stop_voice, - _mixer_loop_voice, - - _mixer_get_position, - _mixer_set_position, - - _mixer_get_volume, - _mixer_set_volume, - _mixer_ramp_volume, - _mixer_stop_volume_ramp, - - _mixer_get_frequency, - _mixer_set_frequency, - _mixer_sweep_frequency, - _mixer_stop_frequency_sweep, - - _mixer_get_pan, - _mixer_set_pan, - _mixer_sweep_pan, - _mixer_stop_pan_sweep, - - _mixer_set_echo, - _mixer_set_tremolo, - _mixer_set_vibrato, - 0, 0, - 0, - 0, - 0, - 0, - 0, - 0 -}; - - - -/* alsa_buffer_size: - * Returns the current DMA buffer size, for use by the audiostream code. - */ -static int alsa_buffer_size(void) -{ - return alsa_bufsize * alsa_fragments / (alsa_bits / 8) / (alsa_stereo ? 2 : 1); -} - - - -/* alsa_update: - * Update data. - */ -static void alsa_update(int threaded) -{ - int i; - - for (i = 0; i < alsa_fragments; i++) { - if (snd_pcm_write(pcm_handle, alsa_bufdata, alsa_bufsize) != alsa_bufsize) - break; - _mix_some_samples((uintptr_t) alsa_bufdata, 0, alsa_signed); - } -} - - - -/* alsa_detect: - * Detect driver presence. - */ -static int alsa_detect(int input) -{ - snd_pcm_t *handle; - snd_pcm_info_t info; - int card, device; - char tmp1[128], tmp2[128]; - int ret = FALSE; - - card = get_config_int(uconvert_ascii("sound", tmp1), - uconvert_ascii("alsa_card", tmp2), - snd_defaults_card()); - - device = get_config_int(uconvert_ascii("sound", tmp1), - uconvert_ascii("alsa_pcmdevice", tmp2), - snd_defaults_pcm_device()); - - if (snd_pcm_open(&handle, card, device, (SND_PCM_OPEN_PLAYBACK - | SND_PCM_OPEN_NONBLOCK)) == 0) { - if ((snd_pcm_info(handle, &info) == 0) - && (info.flags & SND_PCM_INFO_PLAYBACK)) - ret = TRUE; - - snd_pcm_close(handle); - } - - return ret; -} - - - -/* alsa_init: - * ALSA init routine. - */ -static int alsa_init(int input, int voices) -{ - int card, device; - int format, bps, fragsize, numfrags; - snd_pcm_channel_params_t params; - snd_pcm_channel_setup_t setup; - char tmp1[128], tmp2[128]; - - if (input) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Input is not supported")); - return -1; - } - - /* Load config. */ - card = get_config_int(uconvert_ascii("sound", tmp1), - uconvert_ascii("alsa_card", tmp2), - snd_defaults_card()); - - device = get_config_int(uconvert_ascii("sound", tmp1), - uconvert_ascii("alsa_pcmdevice", tmp2), - snd_defaults_pcm_device()); - - fragsize = get_config_int(uconvert_ascii("sound", tmp1), - uconvert_ascii("alsa_fragsize", tmp2), - -1); - - numfrags = get_config_int(uconvert_ascii("sound", tmp1), - uconvert_ascii("alsa_numfrags", tmp2), - ALSA_DEFAULT_NUMFRAGS); - - /* Open PCM device. */ - if (snd_pcm_open(&pcm_handle, card, device, (SND_PCM_OPEN_PLAYBACK - | SND_PCM_OPEN_NONBLOCK)) < 0) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not open card/pcm device")); - goto error; - } - - /* Set format variables. */ - alsa_bits = (_sound_bits == 8) ? 8 : 16; - alsa_stereo = (_sound_stereo) ? 1 : 0; - alsa_rate = (_sound_freq > 0) ? _sound_freq : 44100; - - format = ((alsa_bits == 16) ? SND_PCM_SFMT_S16_NE : SND_PCM_SFMT_U8); - - alsa_signed = 0; - bps = alsa_rate * (alsa_stereo ? 2 : 1); - switch (format) { - case SND_PCM_SFMT_S8: - alsa_signed = 1; - case SND_PCM_SFMT_U8: - alsa_bits = 8; - break; - case SND_PCM_SFMT_S16_NE: - alsa_signed = 1; - case SND_PCM_SFMT_U16_NE: - alsa_bits = 16; - bps <<= 1; - if (sizeof(short) != 2) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported sample format")); - goto error; - } - break; - default: - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported sample format")); - goto error; - } - - if (fragsize < 0) { - bps >>= 9; - if (bps < 16) - bps = 16; - fragsize = 1; - while ((fragsize << 1) < bps) - fragsize <<= 1; - } - else { - fragsize = fragsize * (alsa_bits / 8) * (alsa_stereo ? 2 : 1); - } - - /* Set PCM channel format. */ - memset(¶ms, 0, sizeof(params)); - params.mode = SND_PCM_MODE_BLOCK; - params.channel = SND_PCM_CHANNEL_PLAYBACK; - params.start_mode = SND_PCM_START_FULL; - params.stop_mode = SND_PCM_STOP_ROLLOVER; - params.format.interleave = 1; - params.format.format = format; - params.format.rate = alsa_rate; - params.format.voices = alsa_stereo + 1; - params.buf.block.frag_size = fragsize; - params.buf.block.frags_min = 1; - params.buf.block.frags_max = numfrags; - - if (snd_pcm_channel_params(pcm_handle, ¶ms) < 0) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not set channel parameters")); - goto error; - } - - snd_pcm_channel_prepare(pcm_handle, SND_PCM_CHANNEL_PLAYBACK); - - /* Read back fragments information. */ - memset(&setup, 0, sizeof(setup)); - setup.mode = SND_PCM_MODE_BLOCK; - setup.channel = SND_PCM_CHANNEL_PLAYBACK; - - if (snd_pcm_channel_setup(pcm_handle, &setup) < 0) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not get channel setup")); - goto error; - } - - alsa_fragments = numfrags; - alsa_bufsize = setup.buf.block.frag_size; - - /* Allocate mixing buffer. */ - alsa_bufdata = _AL_MALLOC_ATOMIC(alsa_bufsize); - if (!alsa_bufdata) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not allocate audio buffer")); - goto error; - } - - /* Initialise mixer. */ - digi_alsa.voices = voices; - - if (_mixer_init(alsa_bufsize / (alsa_bits / 8), alsa_rate, - alsa_stereo, ((alsa_bits == 16) ? 1 : 0), - &digi_alsa.voices) != 0) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not init software mixer")); - goto error; - } - - _mix_some_samples((uintptr_t) alsa_bufdata, 0, alsa_signed); - - /* Add audio interrupt. */ - _unix_bg_man->register_func(alsa_update); - - uszprintf(alsa_desc, sizeof(alsa_desc), - get_config_text("Alsa 0.5, Card #%d, device #%d: %d bits, %s, %d bps, %s"), - card, device, alsa_bits, - uconvert_ascii((alsa_signed ? "signed" : "unsigned"), tmp1), - alsa_rate, - uconvert_ascii((alsa_stereo ? "stereo" : "mono"), tmp2)); - - digi_driver->desc = alsa_desc; - - return 0; - - error: - - if (pcm_handle) { - snd_pcm_close(pcm_handle); - pcm_handle = NULL; - } - - return -1; -} - - - -/* alsa_exit: - * Shutdown ALSA driver. - */ -static void alsa_exit(int input) -{ - if (input) { - return; - } - - _unix_bg_man->unregister_func(alsa_update); - - _AL_FREE(alsa_bufdata); - alsa_bufdata = NULL; - - _mixer_exit(); - - snd_pcm_close(pcm_handle); -} - - - -/* alsa_set_mixer_volume: - * Set mixer volume (0-255) - */ -static int alsa_set_mixer_volume(int volume) -{ - /* TODO */ -#if 0 - snd_mixer_t *handle; - int card, device; - - if (snd_mixer_open(&handle, card, device) == 0) { - /* do something special */ - snd_mixer_close(handle); - return 0; - } - - return -1; -#else - return 0; -#endif -} - - - -#ifdef ALLEGRO_MODULE - -/* _module_init: - * Called when loaded as a dynamically linked module. - */ -void _module_init(int system_driver) -{ - _unix_register_digi_driver(DIGI_ALSA, &digi_alsa, TRUE, TRUE); -} - -#endif - -#endif - diff --git a/src/allegro/src/unix/alsa9.c b/src/allegro/src/unix/alsa9.c deleted file mode 100644 index e3b00cf83..000000000 --- a/src/allegro/src/unix/alsa9.c +++ /dev/null @@ -1,561 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * ALSA 0.9 sound driver. - * - * By Thomas Fjellstrom. - * - * Extensively modified by Elias Pschernig. - * - * See readme.txt for copyright information. - */ - - -#include "allegro.h" - -#if (ALLEGRO_ALSA_VERSION == 9) && (defined ALLEGRO_WITH_ALSADIGI) && ((!defined ALLEGRO_WITH_MODULES) || (defined ALLEGRO_MODULE)) - -#include "allegro/internal/aintern.h" -#ifdef ALLEGRO_QNX -#include "allegro/platform/aintqnx.h" -#else -#include "allegro/platform/aintunix.h" -#endif - -#ifndef SCAN_DEPEND - #include - #define ALSA_PCM_NEW_HW_PARAMS_API 1 - #include - #include -#endif - - -#ifndef SND_PCM_FORMAT_S16_NE - #ifdef ALLEGRO_BIG_ENDIAN - #define SND_PCM_FORMAT_S16_NE SND_PCM_FORMAT_S16_BE - #else - #define SND_PCM_FORMAT_S16_NE SND_PCM_FORMAT_S16_LE - #endif -#endif -#ifndef SND_PCM_FORMAT_U16_NE - #ifdef ALLEGRO_BIG_ENDIAN - #define SND_PCM_FORMAT_U16_NE SND_PCM_FORMAT_U16_BE - #else - #define SND_PCM_FORMAT_U16_NE SND_PCM_FORMAT_U16_LE - #endif -#endif - -#define ALSA9_CHECK(a) do { \ - int err = (a); \ - if (err<0) { \ - uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, "ALSA: %s : %s", #a, get_config_text(snd_strerror(err))); \ - goto Error; \ - } \ -} while(0) - - -#define PREFIX_I "al-alsa9 INFO: " -#define PREFIX_W "al-alsa9 WARNING: " -#define PREFIX_E "al-alsa9 ERROR: " - -static char const *alsa_device = "default"; -static char const *alsa_mixer_device = "default"; -static snd_pcm_hw_params_t *hwparams = NULL; -static snd_pcm_sw_params_t *swparams = NULL; -static snd_output_t *snd_output = NULL; -static snd_pcm_uframes_t alsa_bufsize; -static snd_mixer_t *alsa_mixer = NULL; -static snd_mixer_elem_t *alsa_mixer_elem = NULL; -static long alsa_mixer_elem_min, alsa_mixer_elem_max; -static double alsa_mixer_allegro_ratio = 0.0; - -#define ALSA_DEFAULT_BUFFER_MS 100 -#define ALSA_DEFAULT_NUMFRAGS 5 - -static snd_pcm_t *pcm_handle; -static unsigned char *alsa_bufdata; -static int alsa_bits, alsa_signed, alsa_stereo; -static unsigned int alsa_rate; -static unsigned int alsa_fragments; -static int alsa_sample_size; - -static struct pollfd *ufds = NULL; -static int pdc = 0; -static int poll_next; - -static char alsa_desc[256] = EMPTY_STRING; - -static int alsa_detect(int input); -static int alsa_init(int input, int voices); -static void alsa_exit(int input); -static int alsa_set_mixer_volume(int volume); -static int alsa_get_mixer_volume(void); -static int alsa_buffer_size(void); - - - -DIGI_DRIVER digi_alsa = -{ - DIGI_ALSA, - empty_string, - empty_string, - "ALSA", - 0, - 0, - MIXER_MAX_SFX, - MIXER_DEF_SFX, - - alsa_detect, - alsa_init, - alsa_exit, - alsa_set_mixer_volume, - alsa_get_mixer_volume, - - NULL, - NULL, - alsa_buffer_size, - _mixer_init_voice, - _mixer_release_voice, - _mixer_start_voice, - _mixer_stop_voice, - _mixer_loop_voice, - - _mixer_get_position, - _mixer_set_position, - - _mixer_get_volume, - _mixer_set_volume, - _mixer_ramp_volume, - _mixer_stop_volume_ramp, - - _mixer_get_frequency, - _mixer_set_frequency, - _mixer_sweep_frequency, - _mixer_stop_frequency_sweep, - - _mixer_get_pan, - _mixer_set_pan, - _mixer_sweep_pan, - _mixer_stop_pan_sweep, - - _mixer_set_echo, - _mixer_set_tremolo, - _mixer_set_vibrato, - 0, 0, - 0, - 0, - 0, - 0, - 0, - 0 -}; - - - -/* alsa_buffer_size: - * Returns the current DMA buffer size, for use by the audiostream code. - */ -static int alsa_buffer_size(void) -{ - return alsa_bufsize; -} - -/* xrun_recovery: - * Underrun and suspend recovery - */ -static int xrun_recovery(snd_pcm_t *handle, int err) -{ - if (err == -EPIPE) { /* under-run */ - err = snd_pcm_prepare(pcm_handle); - if (err < 0) - fprintf(stderr, "Can't recovery from underrun, prepare failed: %s\n", snd_strerror(err)); - return 0; - } - /* TODO: Can't wait here like that - we are inside an 'interrupt' after all. */ -#if 0 - else if (err == -ESTRPIPE) { - while ((err = snd_pcm_resume(pcm_handle)) == -EAGAIN) - sleep(1); /* wait until the suspend flag is released */ - - if (err < 0) { - err = snd_pcm_prepare(pcm_handle); - if (err < 0) - fprintf(stderr, "Can't recovery from suspend, prepare failed: %s\n", snd_strerror(err)); - } - return 0; - } -#endif - - return err; -} - - - -/* alsa_mix - * Mix and send some samples to ALSA. - */ -static void alsa_mix(void) -{ - int ret, samples = alsa_bufsize; - unsigned char *ptr = alsa_bufdata; - - while (samples > 0) { - ret = snd_pcm_writei(pcm_handle, ptr, samples); - if (ret == -EAGAIN) - continue; - - if (ret < 0) { - if (xrun_recovery(pcm_handle, ret) < 0) - fprintf(stderr, "Write error: %s\n", snd_strerror(ret)); - poll_next = 0; - break; /* skip one period */ - } - if (snd_pcm_state(pcm_handle) == SND_PCM_STATE_RUNNING) - poll_next = 1; - samples -= ret; - ptr += ret * alsa_sample_size; - } - - _mix_some_samples((uintptr_t)alsa_bufdata, 0, alsa_signed); -} - - - -/* alsa_update: - * Updates main buffer in case ALSA is ready. - */ -static void alsa_update(int threaded) -{ - unsigned short revents; - - if (poll_next) { - poll(ufds, pdc, 0); - snd_pcm_poll_descriptors_revents(pcm_handle, ufds, pdc, &revents); - if (revents & POLLERR) { - if (snd_pcm_state(pcm_handle) == SND_PCM_STATE_XRUN || - snd_pcm_state(pcm_handle) == SND_PCM_STATE_SUSPENDED) { - int err = snd_pcm_state(pcm_handle) == SND_PCM_STATE_XRUN ? -EPIPE : -ESTRPIPE; - if (xrun_recovery(pcm_handle, err) < 0) { - fprintf(stderr, "Write error: %s\n", snd_strerror(err)); - } - poll_next = 0; - } - else { - fprintf(stderr, "Wait for poll failed\n"); - } - return; - } - if (!(revents & POLLOUT)) - return; - } - alsa_mix(); -} - - - -/* alsa_detect: - * Detects driver presence. - */ -static int alsa_detect(int input) -{ - int ret = FALSE; - char tmp1[128], tmp2[128]; - - alsa_device = get_config_string(uconvert_ascii("sound", tmp1), - uconvert_ascii("alsa_device", tmp2), - alsa_device); - - ret = snd_pcm_open(&pcm_handle, alsa_device, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); - if (ret < 0) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not open card/pcm device")); - return FALSE; - } - - snd_pcm_close(pcm_handle); - pcm_handle = NULL; - return TRUE; -} - - - -/* alsa_init: - * ALSA init routine. - */ -static int alsa_init(int input, int voices) -{ - int ret = 0; - char tmp1[128], tmp2[128]; - int format = 0; - unsigned int numfrags = 0; - snd_pcm_uframes_t fragsize; - - if (input) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Input is not supported")); - return -1; - } - - ALSA9_CHECK(snd_output_stdio_attach(&snd_output, stdout, 0)); - - alsa_device = get_config_string(uconvert_ascii("sound", tmp1), - uconvert_ascii("alsa_device", tmp2), - alsa_device); - - alsa_mixer_device = get_config_string(uconvert_ascii("sound", tmp1), - uconvert_ascii("alsa_mixer_device", tmp2), - alsa_mixer_device); - - fragsize = get_config_int(uconvert_ascii("sound", tmp1), - uconvert_ascii("alsa_fragsize", tmp2), 0); - - numfrags = get_config_int(uconvert_ascii("sound", tmp1), - uconvert_ascii("alsa_numfrags", tmp2), - ALSA_DEFAULT_NUMFRAGS); - - ret = snd_pcm_open(&pcm_handle, alsa_device, SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK); - if (ret < 0) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not open card/pcm device")); - return -1; - } - - snd_mixer_open(&alsa_mixer, 0); - - if (alsa_mixer - && snd_mixer_attach(alsa_mixer, alsa_mixer_device) >= 0 - && snd_mixer_selem_register (alsa_mixer, NULL, NULL) >= 0 - && snd_mixer_load(alsa_mixer) >= 0) { - const char *alsa_mixer_elem_name = get_config_string(uconvert_ascii("sound", tmp1), - uconvert_ascii("alsa_mixer_elem", tmp2), - "PCM"); - - alsa_mixer_elem = snd_mixer_first_elem(alsa_mixer); - - while (alsa_mixer_elem) { - const char *name = snd_mixer_selem_get_name(alsa_mixer_elem); - - if (strcasecmp(name, alsa_mixer_elem_name) == 0) { - snd_mixer_selem_get_playback_volume_range(alsa_mixer_elem, &alsa_mixer_elem_min, &alsa_mixer_elem_max); - alsa_mixer_allegro_ratio = (double) (alsa_mixer_elem_max - alsa_mixer_elem_min) / (double) 255; - break; - } - - alsa_mixer_elem = snd_mixer_elem_next(alsa_mixer_elem); - } - } - - /* Set format variables. */ - alsa_bits = (_sound_bits == 8) ? 8 : 16; - alsa_stereo = (_sound_stereo) ? 1 : 0; - alsa_rate = (_sound_freq > 0) ? _sound_freq : 44100; - - snd_pcm_hw_params_malloc(&hwparams); - ALSA9_CHECK(snd_pcm_hw_params_any(pcm_handle, hwparams)); - - if (alsa_bits == 8) { - if (snd_pcm_hw_params_test_format(pcm_handle, hwparams, SND_PCM_FORMAT_U8) == 0) { - format = SND_PCM_FORMAT_U8; - alsa_signed = 0; - } - else if (snd_pcm_hw_params_test_format(pcm_handle, hwparams, SND_PCM_FORMAT_S8) == 0) { - format = SND_PCM_FORMAT_S8; - alsa_signed = 1; - } - else { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported sample format")); - goto Error; - } - } - else if (alsa_bits == 16) { - if (sizeof(short) != 2) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported sample format")); - goto Error; - } - - if (snd_pcm_hw_params_test_format(pcm_handle, hwparams, SND_PCM_FORMAT_U16_NE) == 0) { - format = SND_PCM_FORMAT_U16_NE; - alsa_signed = 0; - } - else if (snd_pcm_hw_params_test_format(pcm_handle, hwparams, SND_PCM_FORMAT_S16_NE) == 0) { - format = SND_PCM_FORMAT_S16_NE; - alsa_signed = 1; - } - else { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported sample format")); - goto Error; - } - } - - alsa_sample_size = (alsa_bits / 8) * (alsa_stereo ? 2 : 1); - - if (fragsize == 0) { - unsigned int size = alsa_rate * ALSA_DEFAULT_BUFFER_MS / 1000 / numfrags; - fragsize = 1; - while (fragsize < size) - fragsize <<= 1; - } - - ALSA9_CHECK(snd_pcm_hw_params_set_access(pcm_handle, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED)); - ALSA9_CHECK(snd_pcm_hw_params_set_format(pcm_handle, hwparams, format)); - ALSA9_CHECK(snd_pcm_hw_params_set_channels(pcm_handle, hwparams, alsa_stereo + 1)); - - ALSA9_CHECK(snd_pcm_hw_params_set_rate_near(pcm_handle, hwparams, &alsa_rate, NULL)); - ALSA9_CHECK(snd_pcm_hw_params_set_period_size_near(pcm_handle, hwparams, &fragsize, NULL)); - ALSA9_CHECK(snd_pcm_hw_params_set_periods_near(pcm_handle, hwparams, &numfrags, NULL)); - - ALSA9_CHECK(snd_pcm_hw_params(pcm_handle, hwparams)); - - ALSA9_CHECK(snd_pcm_hw_params_get_period_size(hwparams, &alsa_bufsize, NULL)); - ALSA9_CHECK(snd_pcm_hw_params_get_periods(hwparams, &alsa_fragments, NULL)); - - TRACE (PREFIX_I "alsa_bufsize = %ld, alsa_fragments = %d\n", alsa_bufsize, alsa_fragments); - - snd_pcm_sw_params_malloc(&swparams); - ALSA9_CHECK(snd_pcm_sw_params_current(pcm_handle, swparams)); - ALSA9_CHECK(snd_pcm_sw_params_set_start_threshold(pcm_handle, swparams, alsa_bufsize)); - ALSA9_CHECK(snd_pcm_sw_params_set_avail_min(pcm_handle, swparams, fragsize)); - ALSA9_CHECK(snd_pcm_sw_params(pcm_handle, swparams)); - - /* Allocate mixing buffer. */ - alsa_bufdata = _AL_MALLOC_ATOMIC(alsa_bufsize * alsa_sample_size); - if (!alsa_bufdata) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not allocate audio buffer")); - goto Error; - } - - /* Initialise mixer. */ - digi_alsa.voices = voices; - - if (_mixer_init(alsa_bufsize * (alsa_stereo ? 2 : 1), alsa_rate, - alsa_stereo, ((alsa_bits == 16) ? 1 : 0), - &digi_alsa.voices) != 0) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not init software mixer")); - goto Error; - } - - snd_pcm_prepare(pcm_handle); - pdc = snd_pcm_poll_descriptors_count (pcm_handle); - if (pdc <= 0) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Invalid poll descriptors count")); - goto Error; - } - - ufds = _AL_MALLOC(sizeof(struct pollfd) * pdc); - if (ufds == NULL) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Not enough memory for poll descriptors")); - goto Error; - } - ALSA9_CHECK(snd_pcm_poll_descriptors(pcm_handle, ufds, pdc)); - - poll_next = 0; - - _mix_some_samples((uintptr_t) alsa_bufdata, 0, alsa_signed); - - /* Add audio interrupt. */ - _unix_bg_man->register_func(alsa_update); - - uszprintf(alsa_desc, sizeof(alsa_desc), - get_config_text - ("Alsa 0.9, Device '%s': %d bits, %s, %d bps, %s"), - alsa_device, alsa_bits, - uconvert_ascii((alsa_signed ? "signed" : "unsigned"), tmp1), - alsa_rate, uconvert_ascii((alsa_stereo ? "stereo" : "mono"), tmp2)); - - digi_driver->desc = alsa_desc; - return 0; - - Error: - if (pcm_handle) { - snd_pcm_close(pcm_handle); - pcm_handle = NULL; - } - - return -1; -} - - - -/* alsa_exit: - * Shuts down ALSA driver. - */ -static void alsa_exit(int input) -{ - if (input) - return; - - _unix_bg_man->unregister_func(alsa_update); - - _AL_FREE(alsa_bufdata); - alsa_bufdata = NULL; - - _mixer_exit(); - - if (alsa_mixer) - snd_mixer_close(alsa_mixer); - - snd_pcm_close(pcm_handle); - - snd_pcm_hw_params_free(hwparams); - snd_pcm_sw_params_free(swparams); -} - - - -/* alsa_set_mixer_volume: - * Set mixer volume (0-255) - */ -static int alsa_set_mixer_volume(int volume) -{ - if (alsa_mixer && alsa_mixer_elem) { - snd_mixer_selem_set_playback_volume(alsa_mixer_elem, 0, volume * alsa_mixer_allegro_ratio); - snd_mixer_selem_set_playback_volume(alsa_mixer_elem, 1, volume * alsa_mixer_allegro_ratio); - } - return 0; -} - - - -/* alsa_get_mixer_volume: - * Return mixer volume (0-255) - */ -static int alsa_get_mixer_volume(void) -{ - if (alsa_mixer && alsa_mixer_elem) { - long vol1, vol2; - - snd_mixer_handle_events(alsa_mixer); - - if (snd_mixer_selem_get_playback_volume(alsa_mixer_elem, 0, &vol1) < 0) - return -1; - if (snd_mixer_selem_get_playback_volume(alsa_mixer_elem, 1, &vol2) < 0) - return -1; - - vol1 /= alsa_mixer_allegro_ratio; - vol2 /= alsa_mixer_allegro_ratio; - - return (vol1 + vol2) / 2; - } - - return -1; -} - - - -#ifdef ALLEGRO_MODULE - -/* _module_init: - * Called when loaded as a dynamically linked module. - */ -void _module_init(int system_driver) -{ - _unix_register_digi_driver(DIGI_ALSA, &digi_alsa, TRUE, TRUE); -} - -#endif - -#endif diff --git a/src/allegro/src/unix/alsamidi.c b/src/allegro/src/unix/alsamidi.c deleted file mode 100644 index 9f91722c9..000000000 --- a/src/allegro/src/unix/alsamidi.c +++ /dev/null @@ -1,266 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * ALSA RawMIDI Sound driver. - * - * By Thomas Fjellstrom. - * - * See readme.txt for copyright information. - */ - -#include "allegro.h" - -#if (defined ALLEGRO_WITH_ALSAMIDI) && ((!defined ALLEGRO_WITH_MODULES) || (defined ALLEGRO_MODULE)) - -#include "allegro/internal/aintern.h" - -#ifdef ALLEGRO_QNX -#include "allegro/platform/aintqnx.h" -#else -#include "allegro/platform/aintunix.h" -#endif - -#ifndef SCAN_DEPEND - #include - #include - #include - #include - - #if ALLEGRO_ALSA_VERSION == 9 - #define ALSA_PCM_NEW_HW_PARAMS_API 1 - #include - #else /* ALLEGRO_ALSA_VERSION == 5 */ - #include - #endif - -#endif - - -#define ALSA_RAWMIDI_MAX_ERRORS 3 - - -static int alsa_rawmidi_detect(int input); -static int alsa_rawmidi_init(int input, int voices); -static void alsa_rawmidi_exit(int input); -static void alsa_rawmidi_output(int data); - -static char alsa_rawmidi_desc[256]; - -static snd_rawmidi_t *rawmidi_handle = NULL; -static int alsa_rawmidi_errors = 0; - - -MIDI_DRIVER midi_alsa = -{ - MIDI_ALSA, /* id */ - empty_string, /* name */ - empty_string, /* desc */ - "ALSA RawMIDI", /* ASCII name */ - 0, /* voices */ - 0, /* basevoice */ - 0xFFFF, /* max_voices */ - 0, /* def_voices */ - -1, /* xmin */ - -1, /* xmax */ - alsa_rawmidi_detect, /* detect */ - alsa_rawmidi_init, /* init */ - alsa_rawmidi_exit, /* exit */ - NULL, /* set_mixer_volume */ - NULL, /* get_mixer_volume */ - alsa_rawmidi_output, /* raw_midi */ - _dummy_load_patches, /* load_patches */ - _dummy_adjust_patches, /* adjust_patches */ - _dummy_key_on, /* key_on */ - _dummy_noop1, /* key_off */ - _dummy_noop2, /* set_volume */ - _dummy_noop3, /* set_pitch */ - _dummy_noop2, /* set_pan */ - _dummy_noop2 /* set_vibrato */ -}; - - - -/* alsa_rawmidi_detect: - * ALSA RawMIDI detection. - */ -static int alsa_rawmidi_detect(int input) -{ -#if ALLEGRO_ALSA_VERSION == 9 - const char *device = NULL; -#else /* ALLEGRO_ALSA_VERSION == 5 */ - int card = -1; - int device = -1; -#endif - int ret = FALSE, err; - char tmp1[128], tmp2[128], temp[256]; - snd_rawmidi_t *handle = NULL; - - if (input) { - ret = FALSE; - } - else { -#if ALLEGRO_ALSA_VERSION == 9 - device = get_config_string(uconvert_ascii("sound", tmp1), - uconvert_ascii("alsa_rawmidi_device", tmp2), - "default"); - - err = snd_rawmidi_open(NULL, &handle, device, 0); -#else /* ALLEGRO_ALSA_VERSION == 5 */ - card = get_config_int(uconvert_ascii("sound", tmp1), - uconvert_ascii("alsa_rawmidi_card", tmp2), - snd_defaults_rawmidi_card()); - - device = get_config_int(uconvert_ascii("sound", tmp1), - uconvert_ascii("alsa_rawmidi_device", tmp2), - snd_defaults_rawmidi_device()); - - err = snd_rawmidi_open(&handle, card, device, SND_RAWMIDI_OPEN_OUTPUT_APPEND); -#endif - if (err) { - snprintf(temp, sizeof(temp), "Could not open card/rawmidi device: %s", snd_strerror(err)); - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text(temp)); - ret = FALSE; - } - else { - snd_rawmidi_close(handle); - ret = TRUE; - } - } - - return ret; -} - - - -/* alsa_rawmidi_init: - * Inits the ALSA RawMIDI interface. - */ -static int alsa_rawmidi_init(int input, int voices) -{ - int ret = -1, err; - char tmp1[128], tmp2[128], temp[256]; -#if ALLEGRO_ALSA_VERSION == 9 - snd_rawmidi_info_t *info; - const char *device = NULL; -#else /* ALLEGRO_ALSA_VERSION == 5 */ - snd_rawmidi_info_t info; - int card = -1; - int device = -1; -#endif - - if (input) { - ret = -1; - } - else { -#if ALLEGRO_ALSA_VERSION == 9 - device = get_config_string(uconvert_ascii("sound", tmp1), - uconvert_ascii("alsa_rawmidi_device", tmp2), - "default"); - - err = snd_rawmidi_open(NULL, &rawmidi_handle, device, 0); -#else /* ALLEGRO_ALSA_VERSION == 5 */ - card = get_config_int(uconvert_ascii("sound", tmp1), - uconvert_ascii("alsa_rawmidi_card", tmp2), - snd_defaults_rawmidi_card()); - - device = get_config_int(uconvert_ascii("sound", tmp1), - uconvert_ascii("alsa_rawmidi_device", tmp2), - snd_defaults_rawmidi_device()); - - err = snd_rawmidi_open(&rawmidi_handle, card, device, SND_RAWMIDI_OPEN_OUTPUT_APPEND); -#endif - if (err) { - snprintf(temp, sizeof(temp), "Could not open card/rawmidi device: %s", snd_strerror(err)); - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text(temp)); - ret = -1; - } - - ret = 0; - } - - if (rawmidi_handle) { -#if ALLEGRO_ALSA_VERSION == 9 - snd_rawmidi_nonblock(rawmidi_handle, 0); - snd_rawmidi_info_malloc(&info); - snd_rawmidi_info(rawmidi_handle, info); - _al_sane_strncpy(alsa_rawmidi_desc, snd_rawmidi_info_get_name(info), sizeof(alsa_rawmidi_desc)); -#else /* ALLEGRO_ALSA_VERSION == 5 */ - snd_rawmidi_block_mode(rawmidi_handle, 1); - snd_rawmidi_info(rawmidi_handle, &info); - _al_sane_strncpy(alsa_rawmidi_desc, info.name, sizeof(alsa_rawmidi_desc)); -#endif - midi_alsa.desc = alsa_rawmidi_desc; - alsa_rawmidi_errors = 0; - } - - return ret; -} - - - -/* alsa_rawmidi_exit: - * Cleans up. - */ -static void alsa_rawmidi_exit(int input) -{ - if (rawmidi_handle) { -#if ALLEGRO_ALSA_VERSION == 9 - snd_rawmidi_drain(rawmidi_handle); -#else /* ALLEGRO_ALSA_VERSION == 5 */ - snd_rawmidi_output_drain(rawmidi_handle); -#endif - snd_rawmidi_close(rawmidi_handle); - } - - rawmidi_handle = NULL; -} - - - -/* alsa_rawmidi_output: - * Outputs MIDI data. - */ -static void alsa_rawmidi_output(int data) -{ - int err; - - /* If there are too many errors, just give up. Otherwise the calling thread - * can end up consuming CPU time for no reason. It probably means the user - * hasn't configured ALSA properly. - */ - if (alsa_rawmidi_errors > ALSA_RAWMIDI_MAX_ERRORS) { - return; - } - - err = snd_rawmidi_write(rawmidi_handle, &data, sizeof(char)); - if (err) { - alsa_rawmidi_errors++; - if (alsa_rawmidi_errors == ALSA_RAWMIDI_MAX_ERRORS) { - TRACE("al-alsamidi: too many errors, giving up\n"); - } - } -} - - - -#ifdef ALLEGRO_MODULE - -/* _module_init: - * Called when loaded as a dynamically linked module. - */ -void _module_init(int system_driver) -{ - _unix_register_midi_driver(MIDI_ALSA, &midi_alsa, TRUE, TRUE); -} - -#endif /* ALLEGRO_MODULE */ - -#endif /* MIDI_ALSA */ - diff --git a/src/allegro/src/unix/arts.c b/src/allegro/src/unix/arts.c deleted file mode 100644 index 7e50bb31d..000000000 --- a/src/allegro/src/unix/arts.c +++ /dev/null @@ -1,317 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * aRts sound driver (using artsc). - * - * By Peter Wang. - * - * See readme.txt for copyright information. - */ - - -#include "allegro.h" - -#if (defined ALLEGRO_WITH_ARTSDIGI) && ((!defined ALLEGRO_WITH_MODULES) || (defined ALLEGRO_MODULE)) - -#include "allegro/internal/aintern.h" -#include "allegro/platform/aintunix.h" - -#include - -#ifdef ALLEGRO_MODULE -int _module_has_registered_via_atexit = 0; -#endif - -static int _al_arts_bits, _al_arts_rate, _al_arts_stereo; -#define _al_arts_signed (TRUE) - -static arts_stream_t _al_arts_stream = NULL; -static int _al_arts_bufsize; -static int _al_arts_fragments; -static unsigned char *_al_arts_bufdata = NULL; - -static int _al_arts_detect(int input); -static int _al_arts_init(int input, int voices); -static void _al_arts_exit(int input); -static int _al_arts_buffer_size(void); - -static char _al_arts_desc[256] = EMPTY_STRING; - -DIGI_DRIVER digi_arts = -{ - DIGI_ARTS, - empty_string, - empty_string, - "aRts", - 0, - 0, - MIXER_MAX_SFX, - MIXER_DEF_SFX, - - _al_arts_detect, - _al_arts_init, - _al_arts_exit, - NULL, - NULL, - - NULL, - NULL, - _al_arts_buffer_size, - _mixer_init_voice, - _mixer_release_voice, - _mixer_start_voice, - _mixer_stop_voice, - _mixer_loop_voice, - - _mixer_get_position, - _mixer_set_position, - - _mixer_get_volume, - _mixer_set_volume, - _mixer_ramp_volume, - _mixer_stop_volume_ramp, - - _mixer_get_frequency, - _mixer_set_frequency, - _mixer_sweep_frequency, - _mixer_stop_frequency_sweep, - - _mixer_get_pan, - _mixer_set_pan, - _mixer_sweep_pan, - _mixer_stop_pan_sweep, - - _mixer_set_echo, - _mixer_set_tremolo, - _mixer_set_vibrato, - 0, 0, - 0, - 0, - 0, - 0, - 0, - 0 -}; - - - -/* _al_arts_buffer_size: - * Returns the current DMA buffer size, for use by the audiostream code. - */ -static int _al_arts_buffer_size(void) -{ - return _al_arts_bufsize / (_al_arts_bits / 8) / (_al_arts_stereo ? 2 : 1); -} - - - -/* _al_arts_update: - * Update data. - */ -static void _al_arts_update(int threaded) -{ - int i; - - for (i = 0; i < _al_arts_fragments; i++) { - if (arts_write(_al_arts_stream, _al_arts_bufdata, _al_arts_bufsize) - < _al_arts_bufsize) - break; - _mix_some_samples((uintptr_t) _al_arts_bufdata, 0, _al_arts_signed); - } -} - - - -#define copy_error_text(code, tmp) \ -ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, \ - uconvert_ascii(arts_error_text(code), (tmp))); - - - -/* _al_arts_detect: - * Detect driver presence. - */ -static int _al_arts_detect(int input) -{ - char tmp[ALLEGRO_ERROR_SIZE]; - int code; - - if (input) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, - get_config_text("Input is not supported")); - return FALSE; - } - - code = arts_init(); - if (code != 0) { - copy_error_text(code, tmp); - return FALSE; - } - - arts_free(); - return TRUE; -} - - - -/* _al_arts_init: - * Init routine. - */ -static int _al_arts_init(int input, int voices) -{ - char tmp1[ALLEGRO_ERROR_SIZE]; - char tmp2[128]; - int code; - - if (input) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, - get_config_text("Input is not supported")); - return -1; - } - - /* Initialise artsc library. */ - code = arts_init(); - if (code != 0) { - copy_error_text(code, tmp1); - return -1; - } - -#ifdef ALLEGRO_MODULE - /* A side-effect of arts_init() is that it will register an - * atexit handler. See umodules.c for this problem. - * ??? this seems to be the case only for recent versions. - */ - _module_has_registered_via_atexit = 1; -#endif - - /* Make a copy of the global sound settings. */ - _al_arts_bits = (_sound_bits == 8) ? 8 : 16; - _al_arts_stereo = (_sound_stereo) ? 1 : 0; - _al_arts_rate = (_sound_freq > 0) ? _sound_freq : 44100; - - /* Open a stream for playback. */ - _al_arts_stream = arts_play_stream(_al_arts_rate, _al_arts_bits, - _al_arts_stereo ? 2 : 1, - "allegro"); - if (!_al_arts_stream) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, - get_config_text("Can not open audio stream")); - goto error; - } - - /* Need non-blocking writes. */ - code = arts_stream_set(_al_arts_stream, ARTS_P_BLOCKING, 0); - if (code != 0) { - copy_error_text(code, tmp1); - goto error; - } - - /* Try to reduce the latency of our stream. */ - if (arts_stream_get(_al_arts_stream, ARTS_P_BUFFER_TIME) > 100) - arts_stream_set(_al_arts_stream, ARTS_P_BUFFER_TIME, 100); - - /* Read buffer parameters and allocate buffer space. */ - _al_arts_bufsize = arts_stream_get(_al_arts_stream, ARTS_P_PACKET_SIZE); - _al_arts_fragments = arts_stream_get(_al_arts_stream, ARTS_P_PACKET_COUNT); - _al_arts_bufdata = _AL_MALLOC_ATOMIC(_al_arts_bufsize); - if (!_al_arts_bufdata) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, - get_config_text("Can not allocate audio buffer")); - goto error; - } - - /* Start up mixer. */ - digi_arts.voices = voices; - - if (_mixer_init(_al_arts_bufsize / (_al_arts_bits / 8), _al_arts_rate, - _al_arts_stereo, ((_al_arts_bits == 16) ? 1 : 0), - &digi_arts.voices) != 0) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, - get_config_text("Can not init software mixer")); - goto error; - } - - _mix_some_samples((uintptr_t) _al_arts_bufdata, 0, _al_arts_signed); - - /* Add audio interrupt. */ - _unix_bg_man->register_func(_al_arts_update); - - /* Decribe ourself. */ - uszprintf(_al_arts_desc, sizeof(_al_arts_desc), - get_config_text("%s: %d bits, %s, %d bps, %s"), - "aRts", _al_arts_bits, - uconvert_ascii("signed", tmp1), _al_arts_rate, - uconvert_ascii((_al_arts_stereo ? "stereo" : "mono"), tmp2)); - digi_driver->desc = _al_arts_desc; - - return 0; - - error: - - if (_al_arts_bufdata) { - _AL_FREE(_al_arts_bufdata); - _al_arts_bufdata = NULL; - } - - if (_al_arts_stream) { - arts_close_stream(_al_arts_stream); - _al_arts_stream = NULL; - } - - arts_free(); - - return -1; -} - - - -/* _al_arts_exit: - * Shutdown routine. - */ -static void _al_arts_exit(int input) -{ - if (input) - return; - - _unix_bg_man->unregister_func(_al_arts_update); - - _mixer_exit(); - - _AL_FREE(_al_arts_bufdata); - _al_arts_bufdata = NULL; - - /* Do not call the cleanup routines if we are being - * called by the exit mechanism because they may have - * already been called by it (see above). - */ - if (!_allegro_in_exit) { - arts_close_stream(_al_arts_stream); - _al_arts_stream = NULL; - - arts_free(); - } -} - - - -#ifdef ALLEGRO_MODULE - -/* _module_init: - * Called when loaded as a dynamically linked module. - */ -void _module_init(int system_driver) -{ - _unix_register_digi_driver(DIGI_ARTS, &digi_arts, TRUE, TRUE); -} - -#endif - -#endif - diff --git a/src/allegro/src/unix/jack.c b/src/allegro/src/unix/jack.c deleted file mode 100644 index 5a03db62b..000000000 --- a/src/allegro/src/unix/jack.c +++ /dev/null @@ -1,336 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * Jack sound driver. - * - * By Elias Pschernig. - * - * See readme.txt for copyright information. - */ - - -#include "allegro.h" - -#if (defined ALLEGRO_WITH_JACKDIGI) && ((!defined ALLEGRO_WITH_MODULES) || (defined ALLEGRO_MODULE)) - -#include "allegro/internal/aintern.h" -#include "allegro/platform/aintunix.h" - -#ifndef SCAN_DEPEND - #include -#endif - -/* This still uses Allegro's mixer, and mixes into an intermediate buffer, which - * then is transferred to Jack. Another possibility would be to completely - * circumvent Allegro's mixer and send each single voice to jack, letting Jack - * take care of the mixing. I didn't care about some things in the Jack docs, - * like the possibility of buffer sizes changing, or that no mutex_lock function - * should be called (inside mix_some_samples). - */ -#define JACK_DEFAULT_BUFFER_SIZE -1 -#define JACK_DEFAULT_CLIENT_NAME "allegro" -#define AMP16 ((sample_t) 32768) -#define AMP8 ((sample_t) 128) - -#define PREFIX_I "al-jack INFO: " -#define PREFIX_W "al-jack WARNING: " -#define PREFIX_E "al-jack ERROR: " - -typedef jack_default_audio_sample_t sample_t; - -static int jack_bufsize = JACK_DEFAULT_BUFFER_SIZE; -static char const *jack_client_name = JACK_DEFAULT_CLIENT_NAME; -static int jack_16bit; -static int jack_stereo; -static int jack_signed; -static jack_nframes_t jack_rate; -static char jack_desc[256] = EMPTY_STRING; -static jack_client_t *jack_client = NULL; -static jack_port_t *output_left, *output_right; -static void *jack_buffer; - -static int jack_detect(int input); -static int jack_init(int input, int voices); -static void jack_exit(int input); -static int jack_buffer_size(void); -static int jack_set_mixer_volume(int volume); - -DIGI_DRIVER digi_jack = -{ - DIGI_JACK, - empty_string, - empty_string, - "JACK", - 0, - 0, - MIXER_MAX_SFX, - MIXER_DEF_SFX, - - jack_detect, - jack_init, - jack_exit, - jack_set_mixer_volume, - NULL, - - NULL, - NULL, - jack_buffer_size, - _mixer_init_voice, - _mixer_release_voice, - _mixer_start_voice, - _mixer_stop_voice, - _mixer_loop_voice, - - _mixer_get_position, - _mixer_set_position, - - _mixer_get_volume, - _mixer_set_volume, - _mixer_ramp_volume, - _mixer_stop_volume_ramp, - - _mixer_get_frequency, - _mixer_set_frequency, - _mixer_sweep_frequency, - _mixer_stop_frequency_sweep, - - _mixer_get_pan, - _mixer_set_pan, - _mixer_sweep_pan, - _mixer_stop_pan_sweep, - - _mixer_set_echo, - _mixer_set_tremolo, - _mixer_set_vibrato, - 0, 0, - 0, - 0, - 0, - 0, - 0, - 0 -}; - - - -/* jack_buffer_size: - * Returns the current buffer size, for use by the audiostream code. - */ -static int jack_buffer_size(void) -{ - return jack_bufsize; -} - - - -/* jack_process: - * The JACK processing functions. - */ -static int jack_process (jack_nframes_t nframes, void *arg) -{ - jack_nframes_t i; - /* TODO: Should be uint16_t and uint8_t? Endianess? */ - unsigned short *buffer16 = jack_buffer; - unsigned char *buffer8 = jack_buffer; - jack_default_audio_sample_t *out_left; - - _mix_some_samples((uintptr_t) jack_buffer, 0, jack_signed); - - out_left = (jack_default_audio_sample_t *) - jack_port_get_buffer (output_left, nframes); - - if (jack_stereo) { - jack_default_audio_sample_t *out_right = (jack_default_audio_sample_t *) - jack_port_get_buffer (output_right, nframes); - - if (jack_16bit) { - for (i = 0; i < nframes; i++) { - out_left[i] = ((sample_t) buffer16[i * 2] - AMP16) / AMP16; - out_right[i] = ((sample_t) buffer16[i * 2 + 1] - AMP16) / AMP16; - } - } - else { - for (i = 0; i < nframes; i++) { - out_left[i] = ((sample_t) buffer8[i * 2] - AMP8) / (sample_t) AMP8; - out_right[i] = ((sample_t) buffer8[i * 2 + 1] - AMP8) / (sample_t) AMP8; - } - } - } - else - { - if (jack_16bit) { - for (i = 0; i < nframes; i++) { - out_left[i] = ((sample_t) buffer16[i] - AMP16) / AMP16; - } - } - else { - for (i = 0; i < nframes; i++) { - out_left[i] = ((sample_t) buffer8[i] - AMP8) / AMP8; - } - } - } - - return 0; -} - - - -/* jack_detect: - * Detects driver presence. - */ -static int jack_detect(int input) -{ - if (input) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text( - "Input is not supported")); - return FALSE; - } - - if (!jack_client) - { - jack_client_name = get_config_string("sound", "jack_client_name", - jack_client_name); - jack_client = jack_client_new(jack_client_name); - if (!jack_client) - return FALSE; - } - return TRUE; -} - - - -/* jack_init: - * JACK init routine. - */ -static int jack_init(int input, int voices) -{ - const char **ports; - char tmp[128]; - - if (!jack_detect(input)) - return -1; - - jack_bufsize = get_config_int("sound", "jack_buffer_size", - jack_bufsize); - - if (jack_bufsize == -1) - jack_bufsize = jack_get_buffer_size (jack_client); - - /* Those are already read in from the config file by Allegro. */ - jack_16bit = (_sound_bits == 16 ? 1 : 0); - jack_stereo = (_sound_stereo ? 1 : 0); - - /* Let Allegro mix in its native unsigned format. */ - jack_signed = 0; - - jack_set_process_callback (jack_client, jack_process, NULL); - - output_left = jack_port_register (jack_client, jack_stereo ? "left" : "mono", - JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); - - if (jack_stereo) - output_right = jack_port_register (jack_client, "right", - JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); - - jack_rate = jack_get_sample_rate (jack_client); - - jack_buffer = _AL_MALLOC_ATOMIC(jack_bufsize * (1 + jack_16bit) * (1 + jack_stereo)); - if (!jack_buffer) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text( - "Cannot allocate audio buffer")); - jack_exit (input); - return -1; - } - - digi_jack.voices = voices; - - if (_mixer_init(jack_bufsize * (1 + jack_stereo), jack_rate, - jack_stereo, jack_16bit, &digi_jack.voices)) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text( - "Cannot init software mixer")); - jack_exit (input); - return -1; - } - - _mix_some_samples((uintptr_t) jack_buffer, 0, jack_signed); - - if (jack_activate (jack_client)) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text( - "Cannot activate Jack client")); - jack_exit (input); - return 1; - } - - /* Try to connect the ports. Failure to connect is not critical, since with - * JACK, users may connect/disconnect ports anytime, without Allegro caring. - */ - if ((ports = jack_get_ports (jack_client, NULL, NULL, - JackPortIsPhysical|JackPortIsInput)) == NULL) { - TRACE (PREFIX_I "Cannot find any physical playback ports"); - } - - if (ports) { - if (ports[0]) { - if (jack_connect (jack_client, jack_port_name (output_left), ports[0]) == 0) - TRACE (PREFIX_I "Connected left playback port to %s", ports[0]); - } - if (jack_stereo && ports[1]) { - if (jack_connect (jack_client, jack_port_name (output_right), ports[1]) == 0) - TRACE (PREFIX_I "Connected right playback port to %s", ports[1]); - } - _AL_FREE (ports); - } - - uszprintf(jack_desc, sizeof(jack_desc), - get_config_text ("Jack, client '%s': %d bits, %s, %d bps, %s"), - jack_client_name, jack_16bit ? 16 : 8, - uconvert_ascii((jack_signed ? "signed" : "unsigned"), tmp), - jack_rate, uconvert_ascii((jack_stereo ? "stereo" : "mono"), tmp)); - - return 0; -} - - - -/* jack_exit: - * Shuts down the JACK driver. - */ -static void jack_exit(int input) -{ - jack_client_close (jack_client); - jack_client = NULL; -} - - - -/* jack_set_mixer_volume: - * Set mixer volume (0-255) - */ -static int jack_set_mixer_volume(int volume) -{ - /* Not implemented */ - return 0; -} - - - -#ifdef ALLEGRO_MODULE - -/* _module_init: - * Called when loaded as a dynamically linked module. - */ -void _module_init(int system_driver) -{ - _unix_register_digi_driver(DIGI_JACK, &digi_jack, TRUE, TRUE); -} - -#endif - -#endif diff --git a/src/allegro/src/unix/sgial.c b/src/allegro/src/unix/sgial.c deleted file mode 100644 index 7d9a387c6..000000000 --- a/src/allegro/src/unix/sgial.c +++ /dev/null @@ -1,326 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * SGI AL sound driver. - * - * By Lisa Parratt. - * - * See readme.txt for copyright information. - */ - - -#include "allegro.h" - -#if (defined ALLEGRO_WITH_SGIALDIGI) && ((!defined ALLEGRO_WITH_MODULES) || (defined ALLEGRO_MODULE)) - -#include "allegro/internal/aintern.h" -#include "allegro/platform/aintunix.h" - -#include -#include -#include -#include - -#ifdef ALLEGRO_HAVE_LIBPTHREAD -#include -#endif - -#define _AL_SGIAL_PORTSIZE 12288 -#ifdef ALLEGRO_HAVE_LIBPTHREAD - #define _AL_SGIAL_BUFFERSIZE 2048 -#else - #define _AL_SGIAL_BUFFERSIZE 4096 -#endif - -static ALconfig _al_sgial_config; -static ALport _al_sgial_port; -static int _al_sgial_bufsize; -static unsigned char *_al_sgial_bufdata; -static int _al_sgial_signed; - -static int _al_sgial_detect(int input); -static int _al_sgial_init(int input, int voices); -static void _al_sgial_exit(int input); -static int _al_sgial_mixer_volume(int volume); -static int _al_sgial_buffer_size(void); - -static char _al_sgial_desc[256] = EMPTY_STRING; - -#ifdef ALLEGRO_HAVE_LIBPTHREAD -static pthread_t thread; -#endif - -DIGI_DRIVER digi_sgial = -{ - DIGI_SGIAL, - empty_string, - empty_string, - "Silicon Graphics Audio", - 0, - 0, - MIXER_MAX_SFX, - MIXER_DEF_SFX, - - _al_sgial_detect, - _al_sgial_init, - _al_sgial_exit, - _al_sgial_mixer_volume, - NULL, - - NULL, - NULL, - _al_sgial_buffer_size, - _mixer_init_voice, - _mixer_release_voice, - _mixer_start_voice, - _mixer_stop_voice, - _mixer_loop_voice, - - _mixer_get_position, - _mixer_set_position, - - _mixer_get_volume, - _mixer_set_volume, - _mixer_ramp_volume, - _mixer_stop_volume_ramp, - - _mixer_get_frequency, - _mixer_set_frequency, - _mixer_sweep_frequency, - _mixer_stop_frequency_sweep, - - _mixer_get_pan, - _mixer_set_pan, - _mixer_sweep_pan, - _mixer_stop_pan_sweep, - - _mixer_set_echo, - _mixer_set_tremolo, - _mixer_set_vibrato, - 0, 0, - 0, - 0, - 0, - 0, - 0, - 0 -}; - - - -/* _al_sgial_buffer_size: - * Returns the current DMA buffer size, for use by the audiostream code. - */ -static int _al_sgial_buffer_size(void) -{ - return _al_sgial_bufsize; -} - - - -#ifdef ALLEGRO_HAVE_LIBPTHREAD - -/* _al_sgial_puller_thread_func: [dedicated thread] - * We have threads, therefore we can use a thread to pull sound data - * as required. - */ -static void *_al_sgial_puller_thread_func(void *arg) -{ - int fd; - fd_set fds; - fd = alGetFD(_al_sgial_port); - - while (1) { - alSetFillPoint(_al_sgial_port, _AL_SGIAL_PORTSIZE - _AL_SGIAL_BUFFERSIZE); - FD_ZERO(&fds); - FD_SET(fd, &fds); - select(FD_SETSIZE, NULL, &fds, NULL, NULL); - alWriteFrames(_al_sgial_port, _al_sgial_bufdata, _al_sgial_bufsize); - _mix_some_samples((uintptr_t) _al_sgial_bufdata, 0, _al_sgial_signed); - } -} - -#else - -/* _al_sgial_update: [SIGALRM callback] - * Updates data. - */ -static void _al_sgial_update(int threaded) -{ - if (alGetFillable(_al_sgial_port) > _al_sgial_bufsize) { - alWriteFrames(_al_sgial_port, _al_sgial_bufdata, _al_sgial_bufsize); - _mix_some_samples((uintptr_t) _al_sgial_bufdata, 0, _al_sgial_signed); - } -} - -#endif - - - -/* _al_sgial_detect: - * Detects driver presence. - */ -static int _al_sgial_detect(int input) -{ - if (input) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Input is not supported")); - return FALSE; - } - - /* A link error would have occured if the audio library was unavailable */ - return TRUE; -} - - - -/* _al_sgial_init: - * SGI AL init routine. - * This is different from many systems. Whilst SGI AL supports simultaneous - * output, it is assumed that all streams will be at the same sample rate. - * This driver is well behaved - as such it does *not* honour requested sample - * rates, and always uses the system sample rate. - */ -static int _al_sgial_init(int input, int voices) -{ - char tmp1[128], tmp2[128]; - ALpv pv; - int _al_sgial_bits; - int _al_sgial_stereo; - int _al_sgial_rate; - - if (input) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Input is not supported")); - return -1; - } - - /* SGI AL will down/up mix as appropriate. This is a crying waste of - * Silicon Graphics audio hardware - in all likelihood it will be - * upmixing to 24 bits. - */ - _al_sgial_bits = (_sound_bits == 8) ? AL_SAMPLE_8: AL_SAMPLE_16; - _al_sgial_stereo = (_sound_stereo) ? AL_STEREO : AL_MONO; - _al_sgial_signed = 1; - - pv.param = AL_RATE; - if (alGetParams(AL_DEFAULT_OUTPUT, &pv, 1) < 0) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not read SGI AL parameters")); - return -1; - } - - _al_sgial_rate = (int)alFixedToDouble(pv.value.ll); - if (_al_sgial_rate < 0) { - /* SGI AL couldn't tell us the sample rate: assume 44100 */ - _al_sgial_rate = 44100; - } - - _al_sgial_config = alNewConfig(); - alSetSampFmt(_al_sgial_config, AL_SAMPFMT_TWOSCOMP); - alSetQueueSize(_al_sgial_config, _AL_SGIAL_PORTSIZE); - alSetWidth(_al_sgial_config, _al_sgial_bits); - alSetChannels(_al_sgial_config, _al_sgial_stereo); - - _al_sgial_port = alOpenPort("Allegro", "w", _al_sgial_config); - if (!_al_sgial_port) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not open SGI AL port")); - return -1; - } - - _al_sgial_bufsize = _AL_SGIAL_BUFFERSIZE; - _al_sgial_bufdata = _AL_MALLOC_ATOMIC(_al_sgial_bufsize*((_al_sgial_bits==AL_SAMPLE_16) ? 2 : 1)*((_al_sgial_stereo==AL_STEREO) ? 2 : 1)); - if (!_al_sgial_bufdata) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not allocate audio buffer")); - alClosePort(_al_sgial_port); - alFreeConfig(_al_sgial_config); - return -1; - } - - digi_sgial.voices = voices; - - if (_mixer_init(_al_sgial_bufsize*((_al_sgial_stereo==AL_STEREO) ? 2 :1 ), _al_sgial_rate, - ((_al_sgial_stereo == AL_STEREO) ? 1 : 0), ((_al_sgial_bits == AL_SAMPLE_16) ? 1 : 0), - &digi_sgial.voices) != 0) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not init software mixer")); - _AL_FREE(_al_sgial_bufdata); - alClosePort(_al_sgial_port); - alFreeConfig(_al_sgial_config); - return -1; - } - - _mix_some_samples((uintptr_t) _al_sgial_bufdata, 0, _al_sgial_signed); - -#ifdef ALLEGRO_HAVE_LIBPTHREAD - /* Add audio thread. */ - pthread_create(&thread, NULL, _al_sgial_puller_thread_func, NULL); -#else - /* Add audio interrupt. */ - _unix_bg_man->register_func(_al_sgial_update); -#endif - - uszprintf(_al_sgial_desc, sizeof(_al_sgial_desc), get_config_text("SGI AL: %d bits, %s, %d bps, %s"), - _al_sgial_bits, - uconvert_ascii((_al_sgial_signed ? "signed" : "unsigned"), tmp1), _al_sgial_rate, - uconvert_ascii((_al_sgial_stereo ? "stereo" : "mono"), tmp2)); - - digi_driver->desc = _al_sgial_desc; - - return 0; -} - - - -/* _al_sgial_exit: - * Shutdown SGI AL driver. - */ -static void _al_sgial_exit(int input) -{ - if (input) - return; - -#ifdef ALLEGRO_HAVE_LIBPTHREAD - pthread_cancel(thread); -#else - _unix_bg_man->unregister_func(_al_sgial_update); -#endif - - _AL_FREE(_al_sgial_bufdata); - _al_sgial_bufdata = NULL; - - _mixer_exit(); - - alClosePort(_al_sgial_port); - alFreeConfig(_al_sgial_config); -} - - - -/* _al_sgial_mixer_volume: - * Set mixer volume. - */ -static int _al_sgial_mixer_volume(int volume) -{ - return 0; -} - - - -#ifdef ALLEGRO_MODULE - -/* _module_init: - * Called when loaded as a dynamically linked module. - */ -void _module_init(int system_driver) -{ - _unix_register_digi_driver(DIGI_SGIAL, &digi_sgial, TRUE, TRUE); -} - -#endif - -#endif - diff --git a/src/allegro/src/unix/udrvlist.c b/src/allegro/src/unix/udrvlist.c index e7e12e9e8..64a8eb131 100644 --- a/src/allegro/src/unix/udrvlist.c +++ b/src/allegro/src/unix/udrvlist.c @@ -23,8 +23,6 @@ _DRIVER_INFO *_unix_gfx_driver_list = 0; -_DRIVER_INFO *_unix_digi_driver_list = 0; -_DRIVER_INFO *_unix_midi_driver_list = 0; @@ -36,14 +34,6 @@ void _unix_driver_lists_init(void) _unix_gfx_driver_list = _create_driver_list(); if (_unix_gfx_driver_list) _driver_list_append_list(&_unix_gfx_driver_list, _gfx_driver_list); - - _unix_digi_driver_list = _create_driver_list(); - if (_unix_digi_driver_list) - _driver_list_append_list(&_unix_digi_driver_list, _digi_driver_list); - - _unix_midi_driver_list = _create_driver_list(); - if (_unix_midi_driver_list) - _driver_list_append_list(&_unix_midi_driver_list, _midi_driver_list); } @@ -57,16 +47,6 @@ void _unix_driver_lists_shutdown(void) _destroy_driver_list(_unix_gfx_driver_list); _unix_gfx_driver_list = 0; } - - if (_unix_digi_driver_list) { - _destroy_driver_list(_unix_digi_driver_list); - _unix_digi_driver_list = 0; - } - - if (_unix_midi_driver_list) { - _destroy_driver_list(_unix_midi_driver_list); - _unix_midi_driver_list = 0; - } } @@ -81,30 +61,3 @@ void _unix_register_gfx_driver(int id, GFX_DRIVER *driver, int autodetect, int p else _driver_list_append_driver(&_unix_gfx_driver_list, id, driver, autodetect); } - - - -/* _unix_register_digi_driver: - * Used by modules to register digital sound drivers. - */ -void _unix_register_digi_driver(int id, DIGI_DRIVER *driver, int autodetect, int priority) -{ - if (priority) - _driver_list_prepend_driver(&_unix_digi_driver_list, id, driver, autodetect); - else - _driver_list_append_driver(&_unix_digi_driver_list, id, driver, autodetect); -} - - - -/* _unix_register_midi_driver: - * Used by modules to register MIDI drivers. - */ -void _unix_register_midi_driver(int id, MIDI_DRIVER *driver, int autodetect, int priority) -{ - if (priority) - _driver_list_prepend_driver(&_unix_midi_driver_list, id, driver, autodetect); - else - _driver_list_append_driver(&_unix_midi_driver_list, id, driver, autodetect); -} - diff --git a/src/allegro/src/unix/uesd.c b/src/allegro/src/unix/uesd.c deleted file mode 100644 index f9b0a3748..000000000 --- a/src/allegro/src/unix/uesd.c +++ /dev/null @@ -1,290 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * ESD sound driver. - * - * By Michael Bukin. - * - * Bug fixes by Peter Wang and Eduard Bloch. - * - * See readme.txt for copyright information. - */ - - -#include "allegro.h" - -#if (defined ALLEGRO_WITH_ESDDIGI) && ((!defined ALLEGRO_WITH_MODULES) || (defined ALLEGRO_MODULE)) - -#include "allegro/internal/aintern.h" -#include "allegro/platform/aintunix.h" - -#include -#include -#include -#include -#include - -static int _al_esd_fd; -static int _al_esd_bufsize; -static unsigned char *_al_esd_bufdata; -static int _al_esd_bits, _al_esd_signed, _al_esd_rate, _al_esd_stereo; -static esd_format_t _al_esd_format; - -static int _al_esd_detect(int input); -static int _al_esd_init(int input, int voices); -static void _al_esd_exit(int input); -static int _al_esd_set_mixer_volume(int volume); -static int _al_esd_buffer_size(void); - -static char _al_esd_desc[256] = EMPTY_STRING; - -DIGI_DRIVER digi_esd = -{ - DIGI_ESD, - empty_string, - empty_string, - "Enlightened Sound Daemon", - 0, - 0, - MIXER_MAX_SFX, - MIXER_DEF_SFX, - - _al_esd_detect, - _al_esd_init, - _al_esd_exit, - _al_esd_set_mixer_volume, - NULL, - - NULL, - NULL, - _al_esd_buffer_size, - _mixer_init_voice, - _mixer_release_voice, - _mixer_start_voice, - _mixer_stop_voice, - _mixer_loop_voice, - - _mixer_get_position, - _mixer_set_position, - - _mixer_get_volume, - _mixer_set_volume, - _mixer_ramp_volume, - _mixer_stop_volume_ramp, - - _mixer_get_frequency, - _mixer_set_frequency, - _mixer_sweep_frequency, - _mixer_stop_frequency_sweep, - - _mixer_get_pan, - _mixer_set_pan, - _mixer_sweep_pan, - _mixer_stop_pan_sweep, - - _mixer_set_echo, - _mixer_set_tremolo, - _mixer_set_vibrato, - 0, 0, - 0, - 0, - 0, - 0, - 0, - 0 -}; - - - -/* _al_esd_buffer_size: - * Returns the current DMA buffer size, for use by the audiostream code. - */ -static int _al_esd_buffer_size(void) -{ - return _al_esd_bufsize / (_al_esd_bits / 8) / (_al_esd_stereo ? 2 : 1); -} - - - -/* _al_esd_update: - * Update data. - */ -static void _al_esd_update(int threaded) -{ - fd_set wfds; - struct timeval timeout; - - FD_ZERO(&wfds); - FD_SET(_al_esd_fd, &wfds); - timeout.tv_sec = 0; - timeout.tv_usec = 0; - - if (select(_al_esd_fd+1, NULL, &wfds, NULL, &timeout) > 0) { - write(_al_esd_fd, _al_esd_bufdata, _al_esd_bufsize); - _mix_some_samples((uintptr_t) _al_esd_bufdata, 0, _al_esd_signed); - } -} - - - -/* _al_esd_detect: - * Detect driver presence. - */ -static int _al_esd_detect(int input) -{ - int fd; - AL_CONST char *server; - char tmp1[128], tmp2[128], tmp3[16]; - char s[256]; - - if (input) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Input is not supported")); - return FALSE; - } - - /* We don't want esdlib to spawn ESD while we are detecting it. */ - putenv("ESD_NO_SPAWN=1"); - - /* Get ESD server name. */ - server = get_config_string(uconvert_ascii("sound", tmp1), - uconvert_ascii("esd_server", tmp2), - uconvert_ascii("", tmp3)); - - /* Try to open ESD server. */ - fd = esd_open_sound(uconvert_toascii(server, s)); - if (fd < 0) { - uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("%s: can not open"), - (ugetc(server) ? server : get_config_text("No server"))); - return FALSE; - } - - esd_close(fd); - return TRUE; -} - - - -/* _al_esd_init: - * ESD init routine. - */ -static int _al_esd_init(int input, int voices) -{ - AL_CONST char *server; - char tmp1[128], tmp2[128], tmp3[16]; - char s[256]; - - if (input) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Input is not supported")); - return -1; - } - - server = get_config_string(uconvert_ascii("sound", tmp1), - uconvert_ascii("esd_server", tmp2), - uconvert_ascii("", tmp3)); - - _al_esd_bits = (_sound_bits == 8) ? 8 : 16; - _al_esd_stereo = (_sound_stereo) ? 1 : 0; - _al_esd_rate = (_sound_freq > 0) ? _sound_freq : ESD_DEFAULT_RATE; - _al_esd_signed = 1; - - _al_esd_format = (((_al_esd_bits == 16) ? ESD_BITS16 : ESD_BITS8) - | (_al_esd_stereo ? ESD_STEREO : ESD_MONO) - | ESD_STREAM | ESD_PLAY); - - _al_esd_fd = esd_play_stream_fallback(_al_esd_format, _al_esd_rate, - uconvert_toascii(server, s), NULL); - if (_al_esd_fd < 0) { - uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("%s: can not open"), - (ugetc(server) ? server : get_config_text("No server"))); - return -1; - } - - _al_esd_bufsize = ESD_BUF_SIZE; - _al_esd_bufdata = _AL_MALLOC_ATOMIC(_al_esd_bufsize); - if (_al_esd_bufdata == 0) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not allocate audio buffer")); - close(_al_esd_fd); - return -1; - } - - digi_esd.voices = voices; - - if (_mixer_init(_al_esd_bufsize / (_al_esd_bits / 8), _al_esd_rate, - _al_esd_stereo, ((_al_esd_bits == 16) ? 1 : 0), - &digi_esd.voices) != 0) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not init software mixer")); - _AL_FREE(_al_esd_bufdata); - _al_esd_bufdata = 0; - close(_al_esd_fd); - return -1; - } - - _mix_some_samples((uintptr_t) _al_esd_bufdata, 0, _al_esd_signed); - - /* Add audio interrupt. */ - _unix_bg_man->register_func(_al_esd_update); - - uszprintf(_al_esd_desc, sizeof(_al_esd_desc), get_config_text("%s: %d bits, %s, %d bps, %s"), - server, _al_esd_bits, - uconvert_ascii((_al_esd_signed ? "signed" : "unsigned"), tmp1), _al_esd_rate, - uconvert_ascii((_al_esd_stereo ? "stereo" : "mono"), tmp2)); - - digi_driver->desc = _al_esd_desc; - - return 0; -} - - - -/* _al_esd_exit: - * Shutdown ESD driver. - */ -static void _al_esd_exit(int input) -{ - if (input) { - return; - } - - _unix_bg_man->unregister_func(_al_esd_update); - - _AL_FREE(_al_esd_bufdata); - _al_esd_bufdata = 0; - - _mixer_exit(); - - close(_al_esd_fd); -} - - - -/* _al_esd_set_mixer_volume: - * Set mixer volume. - */ -static int _al_esd_set_mixer_volume(int volume) -{ - return 0; -} - - - -#ifdef ALLEGRO_MODULE - -/* _module_init: - * Called when loaded as a dynamically linked module. - */ -void _module_init(int system_driver) -{ - _unix_register_digi_driver(DIGI_ESD, &digi_esd, TRUE, TRUE); -} - -#endif - -#endif - diff --git a/src/allegro/src/unix/uoss.c b/src/allegro/src/unix/uoss.c deleted file mode 100644 index 015bca38b..000000000 --- a/src/allegro/src/unix/uoss.c +++ /dev/null @@ -1,615 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * Open Sound System driver. Supports for /dev/dsp and /dev/audio. - * - * By Joshua Heyer. - * - * Modified by Michael Bukin. - * - * Input code by Peter Wang. - * - * See readme.txt for copyright information. - */ - - -#include "allegro.h" - -#ifdef ALLEGRO_WITH_OSSDIGI - -#include "allegro/internal/aintern.h" -#include "allegro/platform/aintunix.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#if defined(ALLEGRO_HAVE_SOUNDCARD_H) - #include -#elif defined(ALLEGRO_HAVE_SYS_SOUNDCARD_H) - #include -#elif defined(ALLEGRO_HAVE_MACHINE_SOUNDCARD_H) - #include -#elif defined(ALLEGRO_HAVE_LINUX_SOUNDCARD_H) - #include -#endif -#include - - -#ifndef AFMT_S16_NE - #ifdef ALLEGRO_BIG_ENDIAN - #define AFMT_S16_NE AFMT_S16_BE - #else - #define AFMT_S16_NE AFMT_S16_LE - #endif -#endif -#ifndef AFMT_U16_NE - #ifdef ALLEGRO_BIG_ENDIAN - #define AFMT_U16_NE AFMT_U16_BE - #else - #define AFMT_U16_NE AFMT_U16_LE - #endif -#endif - - -#define OSS_DEFAULT_FRAGBITS 9 -#define OSS_DEFAULT_NUMFRAGS 8 - -int _oss_fragsize; -int _oss_numfrags; - -char _oss_driver[256] = EMPTY_STRING; -static char _oss_mixer_driver[256] = EMPTY_STRING; - -static int oss_fd; -static int oss_bufsize; -static unsigned char *oss_bufdata; -static int oss_signed, oss_format; - -static int oss_save_bits, oss_save_stereo, oss_save_freq; -static int oss_rec_bufsize; - -static int oss_detect(int input); -static int oss_init(int input, int voices); -static void oss_exit(int input); -static int oss_set_mixer_volume(int volume); -static int oss_get_mixer_volume(void); -static int oss_buffer_size(void); -static int oss_rec_cap_rate(int bits, int stereo); -static int oss_rec_cap_parm(int rate, int bits, int stereo); -static int oss_rec_source(int source); -static int oss_rec_start(int rate, int bits, int stereo); -static void oss_rec_stop(void); -static int oss_rec_read(void *buf); - -static char oss_desc[256] = EMPTY_STRING; - -DIGI_DRIVER digi_oss = -{ - DIGI_OSS, - empty_string, - empty_string, - "Open Sound System", - 0, - 0, - MIXER_MAX_SFX, - MIXER_DEF_SFX, - - oss_detect, - oss_init, - oss_exit, - oss_set_mixer_volume, - oss_get_mixer_volume, - - NULL, - NULL, - oss_buffer_size, - _mixer_init_voice, - _mixer_release_voice, - _mixer_start_voice, - _mixer_stop_voice, - _mixer_loop_voice, - - _mixer_get_position, - _mixer_set_position, - - _mixer_get_volume, - _mixer_set_volume, - _mixer_ramp_volume, - _mixer_stop_volume_ramp, - - _mixer_get_frequency, - _mixer_set_frequency, - _mixer_sweep_frequency, - _mixer_stop_frequency_sweep, - - _mixer_get_pan, - _mixer_set_pan, - _mixer_sweep_pan, - _mixer_stop_pan_sweep, - - _mixer_set_echo, - _mixer_set_tremolo, - _mixer_set_vibrato, - 0, 0, - oss_rec_cap_rate, - oss_rec_cap_parm, - oss_rec_source, - oss_rec_start, - oss_rec_stop, - oss_rec_read -}; - - - -/* oss_buffer_size: - * Returns the current DMA buffer size, for use by the audiostream code. - */ -static int oss_buffer_size(void) -{ - return oss_bufsize / (_sound_bits / 8) / (_sound_stereo ? 2 : 1); -} - - - -/* oss_update: - * Update data. - */ -static void oss_update(int threaded) -{ - int i; - audio_buf_info bufinfo; - - if (ioctl(oss_fd, SNDCTL_DSP_GETOSPACE, &bufinfo) != -1) { - /* Write fragments. */ - for (i = 0; i < bufinfo.fragments; i++) { - write(oss_fd, oss_bufdata, oss_bufsize); - _mix_some_samples((uintptr_t) oss_bufdata, 0, oss_signed); - } - } -} - - - -/* open_oss_device: - * Shared helper for the detect and init functions, which opens the - * audio device and sets the sample mode parameters. - */ -static int open_oss_device(int input) -{ - char tmp1[128], tmp2[128], tmp3[128]; - int fragsize, fragbits, bits, stereo, freq; - - ustrzcpy(_oss_driver, sizeof(_oss_driver), get_config_string(uconvert_ascii("sound", tmp1), - uconvert_ascii("oss_driver", tmp2), - uconvert_ascii("/dev/dsp", tmp3))); - - ustrzcpy(_oss_mixer_driver, sizeof(_oss_mixer_driver), get_config_string(uconvert_ascii("sound", tmp1), - uconvert_ascii("oss_mixer_driver", tmp2), - uconvert_ascii("/dev/mixer", tmp3))); - - oss_fd = open(uconvert_toascii(_oss_driver, tmp1), (input ? O_RDONLY : O_WRONLY) | O_NONBLOCK); - - if (oss_fd < 0) { - uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("%s: %s"), _oss_driver, ustrerror(errno)); - return -1; - } - - _oss_fragsize = get_config_int(uconvert_ascii("sound", tmp1), - uconvert_ascii("oss_fragsize", tmp2), - -1); - - _oss_numfrags = get_config_int(uconvert_ascii("sound", tmp1), - uconvert_ascii("oss_numfrags", tmp2), - -1); - - if (_oss_fragsize < 0) - _oss_fragsize = 1 << OSS_DEFAULT_FRAGBITS; - - if (_oss_numfrags < 0) - _oss_numfrags = OSS_DEFAULT_NUMFRAGS; - - /* try to detect whether the DSP can do 16 bit sound or not */ - if (_sound_bits == -1) { - /* ask supported formats */ - if (ioctl(oss_fd, SNDCTL_DSP_GETFMTS, &oss_format) != -1) { - if (oss_format & AFMT_S16_NE) _sound_bits = 16; - else if (oss_format & AFMT_U16_NE) _sound_bits = 16; - else if (oss_format & AFMT_S8) _sound_bits = 8; - else if (oss_format & AFMT_U8) _sound_bits = 8; - else { - /* ask current format */ - oss_format = 0; - if (ioctl(oss_fd, SNDCTL_DSP_SETFMT, &oss_format) != -1) { - switch (oss_format) { - case AFMT_S16_NE: - case AFMT_U16_NE: - _sound_bits = 16; - break; - case AFMT_S8: - case AFMT_U8: - _sound_bits = 8; - break; - } - } - } - } - } - - bits = (_sound_bits == 8) ? 8 : 16; - stereo = (_sound_stereo) ? 1 : 0; - freq = (_sound_freq > 0) ? _sound_freq : 45454; - - /* fragment size is specified in samples, not in bytes */ - fragsize = _oss_fragsize * (bits / 8) * (stereo ? 2 : 1); - fragsize += fragsize - 1; - - for (fragbits = 0; (fragbits < 16) && (fragsize > 1); fragbits++) - fragsize /= 2; - - fragbits = CLAMP(4, fragbits, 16); - _oss_numfrags = CLAMP(2, _oss_numfrags, 0x7FFF); - - fragsize = (_oss_numfrags << 16) | fragbits; - - if (ioctl(oss_fd, SNDCTL_DSP_SETFRAGMENT, &fragsize) == -1) { - uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Setting fragment size: %s"), ustrerror(errno)); - close(oss_fd); - return -1; - } - - _oss_fragsize = (1 << (fragsize & 0xFFFF)) / (bits / 8) / (stereo ? 2 : 1); - _oss_numfrags = fragsize >> 16; - - oss_format = ((bits == 16) ? AFMT_S16_NE : AFMT_U8); - - if ((ioctl(oss_fd, SNDCTL_DSP_SETFMT, &oss_format) == -1) || - (ioctl(oss_fd, SNDCTL_DSP_STEREO, &stereo) == -1) || - (ioctl(oss_fd, SNDCTL_DSP_SPEED, &freq) == -1)) { - uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Setting DSP parameters: %s"), ustrerror(errno)); - close(oss_fd); - return -1; - } - - oss_signed = 0; - - switch (oss_format) { - - case AFMT_S8: - oss_signed = 1; - /* fallthrough */ - - case AFMT_U8: - bits = 8; - break; - - case AFMT_S16_NE: - oss_signed = 1; - /* fallthrough */ - - case AFMT_U16_NE: - bits = 16; - if (sizeof(short) != 2) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported sample format")); - close(oss_fd); - return -1; - } - break; - - default: - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Unsupported sample format")); - close(oss_fd); - return -1; - } - - if ((stereo != 0) && (stereo != 1)) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Not in stereo or mono mode")); - close(oss_fd); - return -1; - } - - _sound_bits = bits; - _sound_stereo = stereo; - _sound_freq = freq; - - return 0; -} - - - -/* oss_detect: - * Detect driver presence. - */ -static int oss_detect(int input) -{ - if (input) { - if (digi_driver != digi_input_driver) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("OSS output driver must be installed before input can be read")); - return FALSE; - } - return TRUE; - } - - if (open_oss_device(0) != 0) - return FALSE; - - close(oss_fd); - return TRUE; -} - - - -/* oss_init: - * OSS init routine. - */ -static int oss_init(int input, int voices) -{ - char tmp1[128], tmp2[128]; - audio_buf_info bufinfo; - - if (input) { - digi_driver->rec_cap_bits = 16; - digi_driver->rec_cap_stereo = TRUE; - return 0; - } - - if (open_oss_device(0) != 0) - return -1; - - if (ioctl(oss_fd, SNDCTL_DSP_GETOSPACE, &bufinfo) == -1) { - uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Getting buffer size: %s"), ustrerror(errno)); - close(oss_fd); - return -1; - } - - oss_bufsize = bufinfo.fragsize; - oss_bufdata = _AL_MALLOC_ATOMIC(oss_bufsize); - - if (oss_bufdata == 0) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not allocate audio buffer")); - close(oss_fd); - return -1; - } - - digi_oss.voices = voices; - - if (_mixer_init(oss_bufsize / (_sound_bits / 8), _sound_freq, - _sound_stereo, ((_sound_bits == 16) ? 1 : 0), - &digi_oss.voices) != 0) { - - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Can not init software mixer")); - close(oss_fd); - return -1; - } - - _mix_some_samples((uintptr_t) oss_bufdata, 0, oss_signed); - - /* Add audio interrupt. */ - _unix_bg_man->register_func(oss_update); - - uszprintf(oss_desc, sizeof(oss_desc), get_config_text("%s: %d bits, %s, %d bps, %s"), - _oss_driver, _sound_bits, - uconvert_ascii((oss_signed ? "signed" : "unsigned"), tmp1), _sound_freq, - uconvert_ascii((_sound_stereo ? "stereo" : "mono"), tmp2)); - - digi_driver->desc = oss_desc; - - return 0; -} - - - -/* oss_exit: - * Shutdown OSS driver. - */ -static void oss_exit(int input) -{ - if (input) { - return; - } - - _unix_bg_man->unregister_func(oss_update); - - _AL_FREE(oss_bufdata); - oss_bufdata = 0; - - _mixer_exit(); - - close(oss_fd); -} - - - -/* oss_set_mixer_volume: - * Set mixer volume. - */ -static int oss_set_mixer_volume(int volume) -{ - int fd, vol, ret; - char tmp[128]; - - fd = open(uconvert_toascii(_oss_mixer_driver, tmp), O_WRONLY); - if (fd < 0) - return -1; - - vol = (volume * 100) / 255; - vol = (vol << 8) | (vol); - ret = ioctl(fd, MIXER_WRITE(SOUND_MIXER_PCM), &vol); - close(fd); - - return ret; -} - - - -/* oss_get_mixer_volume: - * Return mixer volume. - */ -static int oss_get_mixer_volume(void) -{ - int fd, vol; - char tmp[128]; - - fd = open(uconvert_toascii(_oss_mixer_driver, tmp), O_RDONLY); - if (fd < 0) - return -1; - - if (ioctl(fd, MIXER_READ(SOUND_MIXER_PCM), &vol) != 0) - return -1; - close(fd); - - vol = ((vol & 0xff) + (vol >> 8)) / 2; - vol = vol * 255 / 100; - return vol; -} - - - -/* oss_rec_cap_rate: - * Returns maximum input sampling rate. - */ -static int oss_rec_cap_rate(int bits, int stereo) -{ - return 44100; -} - - - -/* oss_rec_cap_parm: - * Returns whether the specified parameters can be set. - */ -static int oss_rec_cap_parm(int rate, int bits, int stereo) -{ - return 1; -} - - - -/* oss_rec_source: - * Sets the sampling source for audio recording. - */ -static int oss_rec_source(int source) -{ - int fd, src, ret; - char tmp[128]; - - fd = open(uconvert_toascii(_oss_mixer_driver, tmp), O_WRONLY); - if (fd < 0) - return -1; - - switch (source) { - case SOUND_INPUT_MIC: - src = SOUND_MASK_MIC; - break; - - case SOUND_INPUT_LINE: - src = SOUND_MASK_LINE; - break; - - case SOUND_INPUT_CD: - src = SOUND_MASK_CD; - break; - - default: - return -1; - } - - ret = ioctl(fd, SOUND_MIXER_WRITE_RECSRC, &src); - close(fd); - - return ret; -} - - - -/* oss_rec_start: - * Re-opens device with read-mode and starts recording (half-duplex). - * Returns the DMA buffer size if successful. - */ - -static int oss_rec_start(int rate, int bits, int stereo) -{ - audio_buf_info bufinfo; - - /* Save current settings, and close playback device. */ - oss_save_bits = _sound_bits; - oss_save_stereo = _sound_stereo; - oss_save_freq = _sound_freq; - - _unix_bg_man->unregister_func(oss_update); - - close(oss_fd); - - /* Reopen device for recording. */ - _sound_bits = bits; - _sound_stereo = stereo; - _sound_freq = rate; - - if (open_oss_device(1) != 0) - return 0; - - if (ioctl(oss_fd, SNDCTL_DSP_GETISPACE, &bufinfo) == -1) { - uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Getting buffer size: %s"), ustrerror(errno)); - close(oss_fd); - return 0; - } - - oss_rec_bufsize = bufinfo.fragsize; - return oss_rec_bufsize; -} - - - -/* oss_rec_stop: - * Stops recording and switches the device back to the original mode. - */ -static void oss_rec_stop(void) -{ - close(oss_fd); - - /* Reopen for playback with saved settings. */ - _sound_bits = oss_save_bits; - _sound_stereo = oss_save_stereo; - _sound_freq = oss_save_freq; - - open_oss_device(0); - - _unix_bg_man->register_func(oss_update); -} - - - -/* oss_rec_read: - * Retrieves the just recorded buffer, if there is one. - */ -static int oss_rec_read(void *buf) -{ - char *p; - int i; - - if (read(oss_fd, buf, oss_rec_bufsize) != oss_rec_bufsize) - return 0; - - /* Convert signedness. */ - if ((_sound_bits == 16) && (oss_signed)) { - p = buf; - for (i = 0; i < oss_rec_bufsize; i++) - p[i] ^= 0x80; - } - - return 1; -} - - -#endif diff --git a/src/allegro/src/unix/uossmidi.c b/src/allegro/src/unix/uossmidi.c deleted file mode 100644 index e207039e8..000000000 --- a/src/allegro/src/unix/uossmidi.c +++ /dev/null @@ -1,591 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * Open Sound System sequencer support. - * - * By Peter Wang. - * - * See readme.txt for copyright information. - */ - -#include "allegro.h" - -#ifdef ALLEGRO_WITH_OSSMIDI - -#include "allegro/internal/aintern.h" -#include "allegro/platform/aintunix.h" - -#include -#include -#include -#include -#if defined(ALLEGRO_HAVE_SOUNDCARD_H) - #include -#elif defined(ALLEGRO_HAVE_SYS_SOUNDCARD_H) - #include -#elif defined(ALLEGRO_HAVE_MACHINE_SOUNDCARD_H) - #include -#elif defined(ALLEGRO_HAVE_LINUX_SOUNDCARD_H) - #include -#endif -#include - -#if defined(ALLEGRO_HAVE_LINUX_AWE_VOICE_H) -#include -#define UOSSMIDI_HAVE_AWE32 -#endif - - -/* our patch data */ -#include "../misc/fm_instr.h" -#include "../misc/fm_emu.h" - - - -static int oss_midi_detect(int input); -static int oss_midi_init(int input, int voices); -static void oss_midi_exit(int input); -static int oss_midi_set_mixer_volume(int volume); -static int oss_midi_get_mixer_volume(void); -static void oss_midi_key_on(int inst, int note, int bend, int vol, int pan); -static void oss_midi_key_off(int voice); -static void oss_midi_set_volume(int voice, int vol); -static void oss_midi_set_pitch(int voice, int note, int bend); - - - -#define MAX_VOICES 256 - -static int seq_fd = -1; -static int seq_device; -static int seq_synth_type, seq_synth_subtype; -static int seq_patch[MAX_VOICES]; -static int seq_note[MAX_VOICES]; -static int seq_drum_start; -static char seq_desc[256] = EMPTY_STRING; - -static char seq_driver[256] = EMPTY_STRING; -static char mixer_driver[256] = EMPTY_STRING; - -SEQ_DEFINEBUF(2048); - - - -MIDI_DRIVER midi_oss = -{ - MIDI_OSS, - empty_string, - empty_string, - "Open Sound System", - 0, 0, 0xFFFF, 0, -1, -1, - oss_midi_detect, - oss_midi_init, - oss_midi_exit, - oss_midi_set_mixer_volume, - oss_midi_get_mixer_volume, - NULL, - _dummy_load_patches, - _dummy_adjust_patches, - oss_midi_key_on, - oss_midi_key_off, - oss_midi_set_volume, - oss_midi_set_pitch, - _dummy_noop2, /* TODO */ - _dummy_noop2 /* TODO */ -}; - - - -/* as required by the OSS API */ -void seqbuf_dump(void) -{ - if (_seqbufptr) { - write(seq_fd, _seqbuf, _seqbufptr); - _seqbufptr = 0; - } -} - - - -/* attempt to open sequencer device */ -static int seq_attempt_open(void) -{ - char tmp1[128], tmp2[128], tmp3[128]; - int fd; - - ustrzcpy(seq_driver, sizeof(seq_driver), get_config_string(uconvert_ascii("sound", tmp1), - uconvert_ascii("oss_midi_driver", tmp2), - uconvert_ascii("/dev/sequencer", tmp3))); - - fd = open(uconvert_toascii(seq_driver, tmp1), O_WRONLY); - if (fd < 0) - uszprintf(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("%s: %s"), seq_driver, ustrerror(errno)); - - return fd; -} - - - -/* find the best (supported) synth type for device */ -static int seq_find_synth(int fd) -{ - struct synth_info info; - int num_synths, i; - char *s; - char tmp1[64], tmp2[256]; - int score = 0, best_score, best_device; - - if (ioctl(fd, SNDCTL_SEQ_NRSYNTHS, &num_synths) == -1) - return 0; - - best_device = -1; - best_score = 0; - - /* Detect the best device */ - for (i = 0; i < num_synths; i++) { - info.device = i; - if (ioctl(fd, SNDCTL_SYNTH_INFO, &info) == -1) - return 0; - - switch (info.synth_type) { - - case SYNTH_TYPE_FM: - /* FM synthesis is kind of ok */ - score = 2; - break; - - case SYNTH_TYPE_SAMPLE: - /* Wavetable MIDI is cool! */ - score = 3; - break; - - case SYNTH_TYPE_MIDI: - /* Only weird people want to use the MIDI out port... */ - /* ... so we don't accept it yet, this can be fixed when - * we've got a config file option to select the MIDI device - * so then we'll only select this if people specifically - * ask for it */ - score = 0; - break; - } - - if (score > best_score) { - best_score = score; - best_device = i; - } - } - - if (best_score == 0) { - return 0; - } - - /* Cool, we got a decent synth type */ - seq_device = best_device; - - /* Now get more information */ - info.device = seq_device; - if (ioctl(fd, SNDCTL_SYNTH_INFO, &info) == -1) - return 0; - - seq_synth_type = info.synth_type; - seq_synth_subtype = info.synth_subtype; - - midi_oss.voices = info.nr_voices; - if (midi_oss.voices > MAX_VOICES) midi_oss.voices = MAX_VOICES; - - - switch (seq_synth_type) { - - case SYNTH_TYPE_FM: - switch (seq_synth_subtype) { - case FM_TYPE_ADLIB: - s = uconvert_ascii("Adlib", tmp1); - break; - case FM_TYPE_OPL3: - s = uconvert_ascii("OPL3", tmp1); - break; - default: - s = uconvert_ascii("FM (unknown)", tmp1); - break; - } - break; - - case SYNTH_TYPE_SAMPLE: - switch (seq_synth_subtype) { -#ifdef UOSSMIDI_HAVE_AWE32 - case SAMPLE_TYPE_AWE32: - s = uconvert_ascii("AWE32", tmp1); - break; -#endif - default: - s = uconvert_ascii("sample (unknown)", tmp1); - break; - } - break; - - case SYNTH_TYPE_MIDI: - s = uconvert_ascii("MIDI out", tmp1); - break; - - default: - s = uconvert_ascii("Unknown synth", tmp1); - break; - } - - uszprintf(seq_desc, sizeof(seq_desc), uconvert_ascii("Open Sound System (%s)", tmp2), s); - midi_driver->desc = seq_desc; - - return 1; -} - - - -/* FM synth: load our instrument patches */ -static void seq_set_fm_patches(int fd) -{ - struct sbi_instrument ins; - int i; - - ins.device = seq_device; - ins.key = FM_PATCH; - memset(ins.operators, 0, sizeof(ins.operators)); - - /* instruments */ - for (i=0; i<128; i++) { - ins.channel = i; - memcpy(&ins.operators, &fm_instrument[i], sizeof(FM_INSTRUMENT)); - write(fd, &ins, sizeof(ins)); - } - - /* (emulated) drums */ - for (i=0; i<47; i++) { - ins.channel = 128+i; - memset(ins.operators, 0, sizeof(ins.operators)); - memcpy(&ins.operators, &fm_emulated_drum[i], sizeof(FM_INSTRUMENT)); - write(fd, &ins, sizeof(ins)); - } -} - - - -/* FM synth setup */ -static void seq_setup_fm (void) -{ - seq_set_fm_patches(seq_fd); - seq_drum_start = midi_oss.voices - 5; -} - - - -#ifdef UOSSMIDI_HAVE_AWE32 -/* AWE32 synth setup */ -static void seq_setup_awe32 (void) -{ - int bits = 0, drums; - - seq_drum_start = midi_oss.voices; - if (seq_drum_start > 32) seq_drum_start = 32; - - /* These non-32 cases probably never happen, since the AWE32 has - * 32 voices and anything higher needs a new interface... */ - if (midi_oss.voices <= 1) { - drums = 0; - } else if (midi_oss.voices <= 4) { - drums = 1; - } else if (midi_oss.voices <= 32) { - drums = midi_oss.voices / 8; - } else { - drums = 4; - } - -#if 0 // I think I got this wrong - /* Set the top 'drums' bits of bitfield and decrement seq_drum_start */ - while (drums--) bits |= (1 << --seq_drum_start); -#else - /* The AWE driver seems to like receiving all percussion on MIDI channel - * 10 (OSS channel 9) */ - bits = (1<<9); - seq_drum_start -= drums; -#endif - - /* Tell the AWE which channels are drum channels. No, I don't know - * what 'multi' mode is or how to play drums in the other modes. - * This is just what playmidi does (except I'm using AWE_PLAY_MULTI - * instead of its value, 1). */ - AWE_SET_CHANNEL_MODE(seq_device, AWE_PLAY_MULTI); - AWE_DRUM_CHANNELS(seq_device, bits); -} -#endif - - - -/* oss_midi_detect: - * Sequencer detection routine. - */ -static int oss_midi_detect(int input) -{ - if (input) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Input is not supported")); - return FALSE; - } - - seq_fd = seq_attempt_open(); - if (seq_fd < 0) - return FALSE; - - close(seq_fd); - return TRUE; -} - - - -/* oss_midi_init: - * Init the driver. - */ -static int oss_midi_init(int input, int voices) -{ - char tmp1[128], tmp2[128], tmp3[128]; - unsigned int i; - - if (input) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Input is not supported")); - return -1; - } - - seq_fd = seq_attempt_open(); - if (seq_fd < 0) - return -1; - - if (!seq_find_synth(seq_fd)) { - close(seq_fd); - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("No supported synth type found")); - return -1; - } - - ioctl(seq_fd, SNDCTL_SEQ_RESET); - - /* Driver-specific setup */ - if (seq_synth_type == SYNTH_TYPE_FM) { - - seq_setup_fm(); - - } else if (seq_synth_type == SYNTH_TYPE_SAMPLE) { - -#ifdef UOSSMIDI_HAVE_AWE32 - if (seq_synth_subtype == SAMPLE_TYPE_AWE32) { - - seq_setup_awe32(); - - } -#endif - - } - - - for (i = 0; i < (sizeof(seq_patch) / sizeof(int)); i++) { - seq_patch[i] = -1; - seq_note[i] = -1; - } - - /* for the mixer routine */ - ustrzcpy(mixer_driver, sizeof(mixer_driver), get_config_string(uconvert_ascii("sound", tmp1), - uconvert_ascii("oss_mixer_driver", tmp2), - uconvert_ascii("/dev/mixer", tmp3))); - - return 0; -} - - - -/* oss_midi_set_mixer_volume: - * Sets the mixer volume for output. - */ -static int oss_midi_set_mixer_volume(int volume) -{ - int fd, vol, ret; - char tmp[128]; - - fd = open(uconvert_toascii(mixer_driver, tmp), O_WRONLY); - if (fd < 0) - return -1; - - vol = (volume * 100) / 255; - vol = (vol << 8) | (vol); - ret = ioctl(fd, MIXER_WRITE(SOUND_MIXER_SYNTH), &vol); - close(fd); - - return ((ret == -1) ? -1 : 0); -} - - - -/* oss_midi_get_mixer_volume: - * Returns mixer volume. - */ -static int oss_midi_get_mixer_volume(void) -{ - int fd, vol; - char tmp[128]; - - fd = open(uconvert_toascii(mixer_driver, tmp), O_RDONLY); - if (fd < 0) - return -1; - - if (ioctl(fd, MIXER_READ(SOUND_MIXER_SYNTH), &vol) != 0) - return -1; - close(fd); - - vol = ((vol & 0xff) + (vol >> 8)) / 2; - vol = vol * 255 / 100; - return vol; -} - - - -/* get_hardware_voice: - * Get the hardware voice corresponding to this virtual voice. The - * hardware may support more than one note per voice, in which case - * you don't want to terminate old notes on reusing a voice, but when - * Allegro reuses a voice it forgets the old note and won't ever send - * a keyoff. So we should use more virtual (Allegro) voices than the - * channels the hardware provides, and map them down to actual - * hardware channels here. - * - * We also swap voices 9 and 15 (MIDI 10 and 16). This is necessary - * because _midi_allocate_voice can only allocate in continuous ranges - * -- so we use voices [0,seq_drum_start) for melody and for the - * percussion [seq_drum_start,max_voices), as far as Allegro is - * concerned. But hardware likes percussion on MIDI 10, so we need to - * remap it. - */ -static int get_hardware_voice (int voice) -{ - int hwvoice = voice; - - /* FIXME: is this OK/useful for other things than AWE32? */ - if (seq_synth_type != SYNTH_TYPE_FM && seq_drum_start > 0) { - - /* map drums >= 15, everything else < 15 */ - hwvoice = hwvoice * 15 / seq_drum_start; - - /* fix up so drums are on MIDI channel 10 */ - if (hwvoice >= 15) - hwvoice = 9; - else if (hwvoice == 9) - hwvoice = 15; - - } - - return hwvoice; -} - - - -/* oss_midi_key_on: - * Triggers the specified voice. - */ -static void oss_midi_key_on(int inst, int note, int bend, int vol, int pan) -{ - int voice, hwvoice; - int is_percussion = 0; - - /* percussion? */ - if (inst > 127) { - voice = _midi_allocate_voice(seq_drum_start, midi_driver->voices-1); - /* TODO: Peter's code decrements inst by 35; but the AWE driver - * ignores inst completely, using note instead, as God (well, GM) - * intended. Does the FM driver ignore note? If so then we're OK. */ - note = inst-128; - inst -= 35; - is_percussion = 1; - } - else - voice = _midi_allocate_voice(0, seq_drum_start-1); - - if (voice < 0) - return; - - /* Get the hardware voice corresponding to this virtual voice. */ - hwvoice = get_hardware_voice (voice); - - /* FIXME: should we do this or not for FM? */ - if (seq_synth_type != SYNTH_TYPE_FM) { - /* Stop any previous note on this voice -- but not if it's percussion */ - if (!is_percussion && seq_note[voice] != -1) { - SEQ_STOP_NOTE(seq_device, hwvoice, seq_note[voice], 64); - } - } - seq_note[voice] = note; - - /* make sure the (hardware) voice is set up with the right sound */ - if (inst != seq_patch[hwvoice]) { - SEQ_SET_PATCH(seq_device, hwvoice, inst); - seq_patch[hwvoice] = inst; - } - - SEQ_CONTROL(seq_device, hwvoice, CTL_PAN, pan); - SEQ_BENDER(seq_device, hwvoice, 8192 + bend); - SEQ_START_NOTE(seq_device, hwvoice, note, vol); - SEQ_DUMPBUF(); -} - - - -/* oss_midi_key_off: - * Insert witty remark about this line being unhelpful. - */ -static void oss_midi_key_off(int voice) -{ - /* Get the hardware voice corresponding to this virtual voice. */ - int hwvoice = get_hardware_voice (voice); - - SEQ_STOP_NOTE(seq_device, hwvoice, seq_note[voice], 64); - SEQ_DUMPBUF(); - - seq_note[voice] = -1; -} - - - -/* oss_midi_set_volume: - * Sets the volume of the specified voice. - */ -static void oss_midi_set_volume(int voice, int vol) -{ - SEQ_CONTROL(seq_device, voice, CTL_MAIN_VOLUME, vol); -} - - - -/* oss_midi_set_pitch: - * Sets the pitch of the specified voice. - */ -static void oss_midi_set_pitch(int voice, int note, int bend) -{ - SEQ_CONTROL(seq_device, voice, CTRL_PITCH_BENDER, 8192 + bend); -} - - - -/* oss_midi_exit: - * Cleanup when we are finished. - */ -static void oss_midi_exit(int input) -{ - if (input) - return; - - if (seq_fd > 0) { - close(seq_fd); - seq_fd = -1; - } -} - -#endif diff --git a/src/allegro/src/unix/usnddrv.c b/src/allegro/src/unix/usnddrv.c deleted file mode 100644 index fef830744..000000000 --- a/src/allegro/src/unix/usnddrv.c +++ /dev/null @@ -1,54 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * List of Unix sound drivers. - * - * By Michael Bukin. - * - * See readme.txt for copyright information. - */ - - -#include "allegro.h" - - - -BEGIN_DIGI_DRIVER_LIST -#if (defined ALLEGRO_WITH_JACKDIGI) && (!defined ALLEGRO_WITH_MODULES) - DIGI_DRIVER_JACK -#endif -#if (defined ALLEGRO_WITH_SGIALDIGI) && (!defined ALLEGRO_WITH_MODULES) - DIGI_DRIVER_SGIAL -#endif -#if (defined ALLEGRO_WITH_ARTSDIGI) && (!defined ALLEGRO_WITH_MODULES) - DIGI_DRIVER_ARTS -#endif -#if (defined ALLEGRO_WITH_ESDDIGI) && (!defined ALLEGRO_WITH_MODULES) - DIGI_DRIVER_ESD -#endif -#if (defined ALLEGRO_WITH_ALSADIGI) && (!defined ALLEGRO_WITH_MODULES) - DIGI_DRIVER_ALSA -#endif -#if (defined ALLEGRO_WITH_OSSDIGI) - DIGI_DRIVER_OSS -#endif -END_DIGI_DRIVER_LIST - - -BEGIN_MIDI_DRIVER_LIST - MIDI_DRIVER_DIGMID -#if (defined ALLEGRO_WITH_ALSAMIDI) && (!defined ALLEGRO_WITH_MODULES) - MIDI_DRIVER_ALSA -#endif -#if (defined ALLEGRO_WITH_OSSMIDI) - MIDI_DRIVER_OSS -#endif -END_MIDI_DRIVER_LIST - diff --git a/src/allegro/src/win/wdispsw.c b/src/allegro/src/win/wdispsw.c index 8f4c214e1..a0232b772 100644 --- a/src/allegro/src/win/wdispsw.c +++ b/src/allegro/src/win/wdispsw.c @@ -149,8 +149,6 @@ void _win_switch_out(void) key_dinput_unacquire(); mouse_dinput_unacquire(); - midi_switch_out(); - if (win_gfx_driver && win_gfx_driver->switch_out) win_gfx_driver->switch_out(); diff --git a/src/allegro/src/win/wdsinput.c b/src/allegro/src/win/wdsinput.c deleted file mode 100644 index cdd2795ea..000000000 --- a/src/allegro/src/win/wdsinput.c +++ /dev/null @@ -1,610 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * DirectSound input driver. - * - * By Nick Kochakian. - * - * API compliance improvements, enhanced format detection - * and bugfixes by Javier Gonzalez. - * - * See readme.txt for copyright information. - */ - - -#define DIRECTSOUND_VERSION 0x0500 - -#include "allegro.h" -#include "allegro/internal/aintern.h" -#include "allegro/platform/aintwin.h" - -#ifndef SCAN_DEPEND - #ifdef ALLEGRO_MINGW32 - #undef MAKEFOURCC - #endif - - #include - #include - #include - - #ifdef ALLEGRO_MSVC - #include - #endif -#endif - -#ifndef ALLEGRO_WINDOWS -#error something is wrong with the makefile -#endif - -#define PREFIX_I "al-dsinput INFO: " -#define PREFIX_W "al-dsinput WARNING: " -#define PREFIX_E "al-dsinput ERROR: " - - -/* sound driver globals */ -static LPDIRECTSOUNDCAPTURE ds_capture = NULL; -static LPDIRECTSOUNDCAPTUREBUFFER ds_capture_buf = NULL; -static WAVEFORMATEX dsc_buf_wfx; -static unsigned long int ds_capture_buffer_size; -static unsigned long int last_capture_pos, input_wave_bytes_read; -static unsigned char *input_wave_data = NULL; - - - -/* ds_err: - * Returns a DirectSound error string. - */ -#ifdef DEBUGMODE -static char *ds_err(long err) -{ - static char err_str[64]; - - switch (err) { - - case DS_OK: - _al_sane_strncpy(err_str, "DS_OK", sizeof(err_str)); - break; - - case DSERR_ALLOCATED: - _al_sane_strncpy(err_str, "DSERR_ALLOCATED", sizeof(err_str)); - break; - - case DSERR_BADFORMAT: - _al_sane_strncpy(err_str, "DSERR_BADFORMAT", sizeof(err_str)); - break; - - case DSERR_INVALIDPARAM: - _al_sane_strncpy(err_str, "DSERR_INVALIDPARAM", sizeof(err_str)); - break; - - case DSERR_NOAGGREGATION: - _al_sane_strncpy(err_str, "DSERR_NOAGGREGATION", sizeof(err_str)); - break; - - case DSERR_OUTOFMEMORY: - _al_sane_strncpy(err_str, "DSERR_OUTOFMEMORY", sizeof(err_str)); - break; - - case DSERR_UNINITIALIZED: - _al_sane_strncpy(err_str, "DSERR_UNINITIALIZED", sizeof(err_str)); - break; - - case DSERR_UNSUPPORTED: - _al_sane_strncpy(err_str, "DSERR_UNSUPPORTED", sizeof(err_str)); - break; - - default: - _al_sane_strncpy(err_str, "DSERR_UNKNOWN", sizeof(err_str)); - break; - } - - return err_str; -} -#else -#define ds_err(hr) "\0" -#endif - - - -/* create_test_capture_buffer: - * Helper function that tries to create a capture buffer with - * the specified format and deletes it immediatly. - */ -static int create_test_capture_buffer(WAVEFORMATEX *wfx) -{ - LPDIRECTSOUNDCAPTUREBUFFER dsc_trybuf; - DSCBUFFERDESC dsc_trybuf_desc; - HRESULT hr; - - /* create the capture buffer */ - ZeroMemory(&dsc_trybuf_desc, sizeof(DSCBUFFERDESC)); - dsc_trybuf_desc.dwSize = sizeof(DSCBUFFERDESC); - dsc_trybuf_desc.dwFlags = 0; - dsc_trybuf_desc.dwBufferBytes = 1024; - dsc_trybuf_desc.dwReserved = 0; - dsc_trybuf_desc.lpwfxFormat = wfx; - - hr = IDirectSoundCapture_CreateCaptureBuffer(ds_capture, &dsc_trybuf_desc, &dsc_trybuf, NULL); - - if (FAILED(hr)) - return -1; - - IDirectSoundCaptureBuffer_Release(dsc_trybuf); - return 0; -} - - - -/* get_capture_format_support: - * Helper function to see if the specified input device - * can support a combination of capture settings. - */ -static int get_capture_format_support(int bits, int stereo, int rate, - int autodetect, WAVEFORMATEX *wfx) -{ - int i; - DSCCAPS dsCaps; - HRESULT hr; - WAVEFORMATEX *test_wfx; - - struct { - unsigned long int type; - unsigned long int freq; - unsigned char bits; - unsigned char channels; - BOOL stereo; - } ds_formats[] = { - { WAVE_FORMAT_4S16, 44100, 16, 2, TRUE }, - { WAVE_FORMAT_2S16, 22050, 16, 2, TRUE }, - { WAVE_FORMAT_1S16, 11025, 16, 2, TRUE }, - - { WAVE_FORMAT_4M16, 44100, 16, 1, FALSE }, - { WAVE_FORMAT_2M16, 22050, 16, 1, FALSE }, - { WAVE_FORMAT_1M16, 11025, 16, 1, FALSE }, - - { WAVE_FORMAT_4S08, 44100, 8, 2, TRUE }, - { WAVE_FORMAT_2S08, 22050, 8, 2, TRUE }, - { WAVE_FORMAT_1S08, 11025, 8, 2, TRUE }, - - { WAVE_FORMAT_4M08, 44100, 8, 1, FALSE }, - { WAVE_FORMAT_2M08, 22050, 8, 1, FALSE }, - { WAVE_FORMAT_1M08, 11025, 8, 1, FALSE }, - - { WAVE_INVALIDFORMAT, 0, 0, 0, FALSE } - }; - - if (!ds_capture) - return -1; - - /* if we have already a capture buffer working - * we return its format as the only valid one - */ - if (ds_capture_buf) { - if (!autodetect) { - /* we must check that everything that cares is - * the same as in the capture buffer settings - */ - if (((bits > 0) && (dsc_buf_wfx.wBitsPerSample != bits)) || - ( stereo && (dsc_buf_wfx.nChannels != 2)) || - (!stereo && (dsc_buf_wfx.nChannels != 1)) || - ((rate > 0) && (dsc_buf_wfx.nSamplesPerSec != (unsigned int) rate))) - return -1; - } - - /* return the actual capture buffer settings */ - if (wfx) - memcpy(wfx, &dsc_buf_wfx, sizeof(WAVEFORMATEX)); - - return 0; - } - - /* we use a two-level checking process: - * - the normal check of exposed capabilities, - * - the actual creation of the capture buffer, - * because of the single frequency limitation on some - * sound cards (e.g SB16 ISA) in full duplex mode. - */ - dsCaps.dwSize = sizeof(DSCCAPS); - hr = IDirectSoundCapture_GetCaps(ds_capture, &dsCaps); - if (FAILED(hr)) { - _TRACE(PREFIX_E "Can't get input device caps (%s).\n", ds_err(hr)); - return -1; - } - - if (wfx) - test_wfx = wfx; - else - test_wfx = _AL_MALLOC(sizeof(WAVEFORMATEX)); - - for (i=0; ds_formats[i].type != WAVE_INVALIDFORMAT; i++) - /* if the current format is supported */ - if (dsCaps.dwFormats & ds_formats[i].type) { - if (!autodetect) { - /* we must check that everything that cares is - * the same as in the capture buffer settings - */ - if (((bits > 0) && (ds_formats[i].bits != bits)) || - (stereo && !ds_formats[i].stereo) || - (!stereo && ds_formats[i].stereo) || - ((rate > 0) && (ds_formats[i].freq != (unsigned int) rate))) - continue; /* go to next format */ - } - - test_wfx->wFormatTag = WAVE_FORMAT_PCM; - test_wfx->nChannels = ds_formats[i].channels; - test_wfx->nSamplesPerSec = ds_formats[i].freq; - test_wfx->wBitsPerSample = ds_formats[i].bits; - test_wfx->nBlockAlign = test_wfx->nChannels * (test_wfx->wBitsPerSample / 8); - test_wfx->nAvgBytesPerSec = test_wfx->nSamplesPerSec * test_wfx->nBlockAlign; - test_wfx->cbSize = 0; - - if (create_test_capture_buffer(test_wfx) == 0) { - if (!wfx) - _AL_FREE(test_wfx); - return 0; - } - } - - if (!wfx) - _AL_FREE(test_wfx); - - _TRACE(PREFIX_W "No valid recording formats found.\n"); - return -1; -} - - - -/* digi_directsound_capture_init: - */ -int digi_directsound_capture_init(LPGUID guid) -{ - DSCCAPS dsCaps; - WAVEFORMATEX wfx; - HRESULT hr; - LPVOID temp; - - /* the DirectSoundCapture interface is not part of DirectX 3 */ - if (_dx_ver < 0x0500) - return -1; - - /* create the device: - * we use CoCreateInstance() instead of DirectSoundCaptureCreate() to avoid - * the dll loader blocking the start of Allegro under DirectX 3. - */ - - hr = CoCreateInstance(&CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER, - &IID_IDirectSoundCapture, &temp); - if (FAILED(hr)) { - _TRACE(PREFIX_E "Can't create DirectSoundCapture interface (%s).\n", ds_err(hr)); - goto Error; - } - - ds_capture = temp; - - /* initialize the device */ - hr = IDirectSoundCapture_Initialize(ds_capture, guid); - - if (FAILED(hr)) { - hr = IDirectSoundCapture_Initialize(ds_capture, NULL); - if (FAILED(hr)) { - _TRACE(PREFIX_E "Can't initialize DirectSoundCapture interface (%s).\n", ds_err(hr)); - goto Error; - } - } - - /* get the device caps */ - dsCaps.dwSize = sizeof(DSCCAPS); - hr = IDirectSoundCapture_GetCaps(ds_capture, &dsCaps); - if (FAILED(hr)) { - _TRACE(PREFIX_E "Can't get input device caps (%s).\n", ds_err(hr)); - goto Error; - } - - /* cool little 'autodetection' process :) */ - if (get_capture_format_support(0, FALSE, 0, TRUE, &wfx) != 0) { - _TRACE(PREFIX_E "The DirectSound hardware doesn't support any capture types.\n"); - goto Error; - } - - /* set capabilities */ - digi_input_driver->rec_cap_bits = wfx.wBitsPerSample; - digi_input_driver->rec_cap_stereo = (wfx.nChannels == 2) ? 1 : 0; - - return 0; - - Error: - /* shutdown DirectSoundCapture */ - digi_directsound_capture_exit(); - - return -1; -} - - - -/* digi_directsound_capture_exit: - */ -void digi_directsound_capture_exit(void) -{ - /* destroy capture buffer */ - digi_directsound_rec_stop(); - - /* shutdown DirectSoundCapture */ - if (ds_capture) { - IDirectSoundCapture_Release(ds_capture); - ds_capture = NULL; - } -} - - - -/* digi_directsound_capture_detect: - */ -int digi_directsound_capture_detect(LPGUID guid) -{ - HRESULT hr; - LPVOID temp; - - /* the DirectSoundCapture interface is not part of DirectX 3 */ - if (_dx_ver < 0x500) - return 0; - - if (!ds_capture) { - /* create the device: - * we use CoCreateInstance() instead of DirectSoundCaptureCreate() to avoid - * the dll loader blocking the start of Allegro under DirectX 3. - */ - hr = CoCreateInstance(&CLSID_DirectSoundCapture, NULL, CLSCTX_INPROC_SERVER, - &IID_IDirectSoundCapture, &temp); - - if (FAILED(hr)) { - _TRACE(PREFIX_E "DirectSoundCapture interface creation failed during detect (%s).\n", ds_err(hr)); - return 0; - } - - ds_capture = temp; - - /* initialize the device */ - hr = IDirectSoundCapture_Initialize(ds_capture, guid); - - if (FAILED(hr)) { - hr = IDirectSoundCapture_Initialize(ds_capture, NULL); - if (FAILED(hr)) { - _TRACE(PREFIX_E "DirectSoundCapture interface initialization failed during detect (%s).\n", ds_err(hr)); - return 0; - } - } - - _TRACE(PREFIX_I "DirectSoundCapture interface successfully created.\n"); - - /* release DirectSoundCapture interface */ - IDirectSoundCapture_Release(ds_capture); - ds_capture = NULL; - } - - return 1; -} - - - -/* digi_directsound_rec_cap_rate: - * Gets the maximum input frequency for the specified parameters. - */ -int digi_directsound_rec_cap_rate(int bits, int stereo) -{ - WAVEFORMATEX wfx; - - if (get_capture_format_support(bits, stereo, 0, FALSE, &wfx) != 0) - return 0; - - return wfx.nSamplesPerSec; -} - - - -/* digi_directsound_rec_cap_param: - * Determines if the combination of provided parameters can be - * used for recording. - */ -int digi_directsound_rec_cap_param(int rate, int bits, int stereo) -{ - if (get_capture_format_support(bits, stereo, rate, FALSE, NULL) == 0) - return 2; - - if (get_capture_format_support(bits, stereo, 44100, FALSE, NULL) == 0) - return -44100; - - if (get_capture_format_support(bits, stereo, 22050, FALSE, NULL) == 0) - return -22050; - - if (get_capture_format_support(bits, stereo, 11025, FALSE, NULL) == 0) - return -11025; - - return 0; -} - - - -/* digi_directsound_rec_source: - * Sets the source for the audio recording. - */ -int digi_directsound_rec_source(int source) -{ - /* since DirectSoundCapture doesn't allow us to - * select a input source manually, we return -1 - */ - return -1; -} - - - -/* digi_directsound_rec_start: - * Start recording with the specified parameters. - */ -int digi_directsound_rec_start(int rate, int bits, int stereo) -{ - DSCBUFFERDESC dscBufDesc; - HRESULT hr; - - if (!ds_capture || ds_capture_buf) - return 0; - - /* check if we support the desired format */ - if ((bits <= 0) || (rate <= 0)) - return 0; - - if (get_capture_format_support(bits, stereo, rate, FALSE, &dsc_buf_wfx) != 0) - return 0; - - digi_driver->rec_cap_bits = dsc_buf_wfx.wBitsPerSample; - digi_driver->rec_cap_stereo = (dsc_buf_wfx.nChannels == 2) ? 1 : 0; - - /* create the capture buffer */ - ZeroMemory(&dscBufDesc, sizeof(DSCBUFFERDESC)); - dscBufDesc.dwSize = sizeof(DSCBUFFERDESC); - dscBufDesc.dwFlags = 0; - dscBufDesc.dwBufferBytes = dsc_buf_wfx.nAvgBytesPerSec; - dscBufDesc.dwReserved = 0; - dscBufDesc.lpwfxFormat = &dsc_buf_wfx; - ds_capture_buffer_size = dscBufDesc.dwBufferBytes; - - hr = IDirectSoundCapture_CreateCaptureBuffer(ds_capture, &dscBufDesc, &ds_capture_buf, NULL); - if (FAILED(hr)) { - _TRACE(PREFIX_E "Can't create the DirectSound capture buffer (%s).\n", ds_err(hr)); - return 0; - } - - hr = IDirectSoundCaptureBuffer_Start(ds_capture_buf, DSCBSTART_LOOPING); - if (FAILED(hr)) { - IDirectSoundCaptureBuffer_Release(ds_capture_buf); - ds_capture_buf = NULL; - - _TRACE(PREFIX_E "Can't start the DirectSound capture buffer (%s).\n", ds_err(hr)); - return 0; - } - - last_capture_pos = 0; - input_wave_data = _AL_MALLOC(ds_capture_buffer_size); - input_wave_bytes_read = 0; - - return ds_capture_buffer_size; -} - - - -/* digi_directsound_rec_stop: - * Stops recording. - */ -void digi_directsound_rec_stop(void) -{ - if (ds_capture_buf) { - IDirectSoundCaptureBuffer_Stop(ds_capture_buf); - IDirectSoundCaptureBuffer_Release(ds_capture_buf); - ds_capture_buf = NULL; - } - - if (input_wave_data) { - _AL_FREE(input_wave_data); - input_wave_data = NULL; - } -} - - - -/* digi_directsound_rec_read: - * Reads the input buffer. - */ -int digi_directsound_rec_read(void *buf) -{ - unsigned char *input_ptr1, *input_ptr2, *linear_input_ptr; - unsigned long int input_bytes1, input_bytes2, bytes_to_lock; - unsigned long int capture_pos; - HRESULT hr; - BOOL buffer_filled = FALSE; - LPVOID temp1, temp2; - - if (!ds_capture || !ds_capture_buf || !input_wave_data) - return 0; - - IDirectSoundCaptureBuffer_GetCurrentPosition(ds_capture_buf, &capture_pos, NULL); - - /* check if we are not still in the same capture position */ - if (last_capture_pos == capture_pos) - return 0; - - /* check how many bytes we need to lock since last check */ - if (capture_pos > last_capture_pos) { - bytes_to_lock = capture_pos - last_capture_pos; - } - else { - bytes_to_lock = ds_capture_buffer_size - last_capture_pos; - bytes_to_lock += capture_pos; - } - - hr = IDirectSoundCaptureBuffer_Lock(ds_capture_buf, last_capture_pos, - bytes_to_lock, &temp1, - &input_bytes1, &temp2, - &input_bytes2, 0); - if (FAILED(hr)) - return 0; - - input_ptr1 = temp1; - input_ptr2 = temp2; - - /* let's get the data aligned linearly */ - linear_input_ptr = _AL_MALLOC(bytes_to_lock); - memcpy(linear_input_ptr, input_ptr1, input_bytes1); - - if (input_ptr2) - memcpy(linear_input_ptr + input_bytes1, input_ptr2, input_bytes2); - - IDirectSoundCaptureBuffer_Unlock(ds_capture_buf, input_ptr1, - input_bytes1, input_ptr2, input_bytes2); - - if ((input_wave_bytes_read + bytes_to_lock) >= ds_capture_buffer_size) { - /* we fill the buffer */ - long int bytes_left_to_fill = ds_capture_buffer_size - input_wave_bytes_read; - long int bytes_to_internal = bytes_to_lock - bytes_left_to_fill; - - /* copy old buffer to user buffer */ - memcpy((char*)buf, input_wave_data, input_wave_bytes_read); - - /* and the rest of bytes we would need to fill in the buffer */ - memcpy((char*)buf + input_wave_bytes_read, linear_input_ptr, bytes_left_to_fill); - - /* and the rest of the data to the internal buffer */ - input_wave_bytes_read = bytes_to_internal; - memcpy(input_wave_data, linear_input_ptr + bytes_left_to_fill, bytes_to_internal); - - buffer_filled = TRUE; - - /* if we are using 16-bit data, we need to convert it to unsigned format */ - if (digi_driver->rec_cap_bits == 16) { - unsigned int i; - unsigned short *buf16 = (unsigned short *)buf; - - for (i = 0; i < ds_capture_buffer_size/2; i++) - buf16[i] ^= 0x8000; - } - } - else { - /* we won't fill the buffer */ - memcpy(input_wave_data + input_wave_bytes_read, linear_input_ptr, bytes_to_lock); - input_wave_bytes_read += bytes_to_lock; - } - - _AL_FREE(linear_input_ptr); - - last_capture_pos = capture_pos; - - if (buffer_filled) - return 1; - else - return 0; -} diff --git a/src/allegro/src/win/wdsndmix.c b/src/allegro/src/win/wdsndmix.c deleted file mode 100644 index a3244f644..000000000 --- a/src/allegro/src/win/wdsndmix.c +++ /dev/null @@ -1,752 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * Allegro mixer to DirectSound driver. - * - * By Robin Burrows. - * - * Based on original src/win/wdsound.c by Stefan Schimanski - * and src/unix/oss.c by Joshua Heyer. - * - * Bugfixes by Javier Gonzalez. - * - * See readme.txt for copyright information. - */ - - -#define DIRECTSOUND_VERSION 0x0300 - -#include "allegro.h" -#include "allegro/internal/aintern.h" -#include "allegro/platform/aintwin.h" - -#ifndef SCAN_DEPEND - #ifdef ALLEGRO_MINGW32 - #undef MAKEFOURCC - #endif - - #include - #include - #include - - #ifdef ALLEGRO_MSVC - #include - #endif -#endif - -#ifndef ALLEGRO_WINDOWS -#error something is wrong with the makefile -#endif - -#define PREFIX_I "al-dsndmix INFO: " -#define PREFIX_W "al-dsndmix WARNING: " -#define PREFIX_E "al-dsndmix ERROR: " - - -static int digi_dsoundmix_detect(int input); -static int digi_dsoundmix_init(int input, int voices); -static void digi_dsoundmix_exit(int input); -static int digi_dsoundmix_set_mixer_volume(int volume); -static int digi_dsoundmix_get_mixer_volume(void); -static int digi_dsoundmix_buffer_size(void); - - -/* template driver: will be cloned for each device */ -static DIGI_DRIVER digi_dsoundmix = -{ - 0, - empty_string, - empty_string, - empty_string, - 0, // available voices - 0, // voice number offset - MIXER_MAX_SFX, // maximum voices we can support - MIXER_DEF_SFX, // default number of voices to use - - /* setup routines */ - digi_dsoundmix_detect, - digi_dsoundmix_init, - digi_dsoundmix_exit, - digi_dsoundmix_set_mixer_volume, - digi_dsoundmix_get_mixer_volume, - - /* audiostream locking functions */ - NULL, // AL_METHOD(void *, lock_voice, (int voice, int start, int end)); - NULL, // AL_METHOD(void, unlock_voice, (int voice)); - digi_dsoundmix_buffer_size, - - /* voice control functions */ - _mixer_init_voice, - _mixer_release_voice, - _mixer_start_voice, - _mixer_stop_voice, - _mixer_loop_voice, - - /* position control functions */ - _mixer_get_position, - _mixer_set_position, - - /* volume control functions */ - _mixer_get_volume, - _mixer_set_volume, - _mixer_ramp_volume, - _mixer_stop_volume_ramp, - - /* pitch control functions */ - _mixer_get_frequency, - _mixer_set_frequency, - _mixer_sweep_frequency, - _mixer_stop_frequency_sweep, - - /* pan control functions */ - _mixer_get_pan, - _mixer_set_pan, - _mixer_sweep_pan, - _mixer_stop_pan_sweep, - - /* effect control functions */ - _mixer_set_echo, - _mixer_set_tremolo, - _mixer_set_vibrato, - - /* input functions */ - 0, // int rec_cap_bits; - 0, // int rec_cap_stereo; - digi_directsound_rec_cap_rate, - digi_directsound_rec_cap_param, - digi_directsound_rec_source, - digi_directsound_rec_start, - digi_directsound_rec_stop, - digi_directsound_rec_read -}; - - -#define MAX_DRIVERS 16 -static char *driver_names[MAX_DRIVERS]; -static LPGUID driver_guids[MAX_DRIVERS]; - - -#define USE_NEW_CODE 0 - -/* sound driver globals */ -static LPDIRECTSOUND directsound = NULL; -static LPDIRECTSOUNDBUFFER prim_buf = NULL; -static LPDIRECTSOUNDBUFFER alleg_buf = NULL; -static long int initial_volume; -static int _freq, _bits, _stereo; -static int alleg_to_dsound_volume[256]; -static unsigned int digidsbufsize; -static unsigned char *digidsbufdata; -#if !USE_NEW_CODE -static unsigned int bufdivs = 16, digidsbufpos; -#else -static int digidsbufdirty; -#endif -static int alleg_buf_paused = FALSE; -static int alleg_buf_vol; - - - -/* ds_err: - * Returns a DirectSound error string. - */ -#ifdef DEBUGMODE -static char *ds_err(long err) -{ - static char err_str[64]; - - switch (err) { - - case DS_OK: - _al_sane_strncpy(err_str, "DS_OK", sizeof(err_str)); - break; - - case DSERR_ALLOCATED: - _al_sane_strncpy(err_str, "DSERR_ALLOCATED", sizeof(err_str)); - break; - - case DSERR_BADFORMAT: - _al_sane_strncpy(err_str, "DSERR_BADFORMAT", sizeof(err_str)); - break; - - case DSERR_INVALIDPARAM: - _al_sane_strncpy(err_str, "DSERR_INVALIDPARAM", sizeof(err_str)); - break; - - case DSERR_NOAGGREGATION: - _al_sane_strncpy(err_str, "DSERR_NOAGGREGATION", sizeof(err_str)); - break; - - case DSERR_OUTOFMEMORY: - _al_sane_strncpy(err_str, "DSERR_OUTOFMEMORY", sizeof(err_str)); - break; - - case DSERR_UNINITIALIZED: - _al_sane_strncpy(err_str, "DSERR_UNINITIALIZED", sizeof(err_str)); - break; - - case DSERR_UNSUPPORTED: - _al_sane_strncpy(err_str, "DSERR_UNSUPPORTED", sizeof(err_str)); - break; - - default: - _al_sane_strncpy(err_str, "DSERR_UNKNOWN", sizeof(err_str)); - break; - } - - return err_str; -} -#else -#define ds_err(hr) "\0" -#endif - - - -/* _get_dsalmix_driver: - * System driver hook for listing the available sound drivers. This - * generates the device list at runtime, to match whatever DirectSound - * devices are available. - */ -DIGI_DRIVER *_get_dsalmix_driver(char *name, LPGUID guid, int num) -{ - DIGI_DRIVER *driver; - - driver = _AL_MALLOC(sizeof(DIGI_DRIVER)); - if (!driver) - return NULL; - - memcpy(driver, &digi_dsoundmix, sizeof(DIGI_DRIVER)); - - driver->id = DIGI_DIRECTAMX(num); - - driver_names[num] = _AL_MALLOC_ATOMIC(strlen(name)+10); - if (driver_names[num]) { - _al_sane_strncpy(driver_names[num], "Allegmix ", strlen(name)+10); - _al_sane_strncpy(driver_names[num]+9, name, strlen(name)+1); - driver->ascii_name = driver_names[num]; - } - - driver_guids[num] = guid; - - return driver; -} - - - -/* _free_win_dsalmix_name_list - * Helper function for freeing dynamically generated driver names. - */ -void _free_win_dsalmix_name_list(void) -{ - int i = 0; - for (i = 0; i < MAX_DRIVERS; i++) { - if (driver_names[i]) _AL_FREE(driver_names[i]); - } -} - - - -/* create_dsound_buffer: - * Worker function for creating a DirectSound buffer. - */ -static LPDIRECTSOUNDBUFFER create_dsound_buffer(int len, int freq, int bits, int stereo, int vol) -{ - LPDIRECTSOUNDBUFFER snd_buf; - WAVEFORMATEX wf; - DSBUFFERDESC dsbdesc; - HRESULT hr; - - /* setup wave format structure */ - memset(&wf, 0, sizeof(WAVEFORMATEX)); - wf.wFormatTag = WAVE_FORMAT_PCM; - wf.nChannels = stereo ? 2 : 1; - wf.nSamplesPerSec = freq; - wf.wBitsPerSample = bits; - wf.nBlockAlign = bits * (stereo ? 2 : 1) / 8; - wf.nAvgBytesPerSec = wf.nSamplesPerSec * wf.nBlockAlign; - - /* setup DSBUFFERDESC structure */ - memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); - dsbdesc.dwSize = sizeof(DSBUFFERDESC); - - /* need volume control and global focus */ - dsbdesc.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_GLOBALFOCUS | - DSBCAPS_GETCURRENTPOSITION2; - - dsbdesc.dwBufferBytes = len * (bits / 8) * (stereo ? 2 : 1); - dsbdesc.lpwfxFormat = &wf; - - /* create buffer */ - hr = IDirectSound_CreateSoundBuffer(directsound, &dsbdesc, &snd_buf, NULL); - if (FAILED(hr)) { - _TRACE(PREFIX_E "create_directsound_buffer() failed (%s).\n", ds_err(hr)); - _TRACE(PREFIX_E " - %d Hz, %s, %d bits\n", freq, stereo ? "stereo" : "mono", bits); - return NULL; - } - - /* set volume */ - IDirectSoundBuffer_SetVolume(snd_buf, alleg_to_dsound_volume[CLAMP(0, vol, 255)]); - - return snd_buf; -} - - - -/* digi_dsoundmix_mixer_callback: - * Callback function to update sound in the DS buffer. - */ -static void digi_dsoundmix_mixer_callback(void) -{ - LPVOID lpvPtr1, lpvPtr2; - DWORD dwBytes1, dwBytes2; - DWORD playcurs, writecurs; - HRESULT hr; - int switch_mode; - - /* handle display switchs */ - switch_mode = get_display_switch_mode(); - - if (alleg_buf_paused) { - if (_win_app_foreground || - (switch_mode == SWITCH_BACKGROUND) || (switch_mode == SWITCH_BACKAMNESIA)) { - /* get current state of the sound buffer */ - hr = IDirectSoundBuffer_GetStatus(alleg_buf, &dwBytes1); - if ((hr == DS_OK) && (dwBytes1 & DSBSTATUS_BUFFERLOST)) { - if(IDirectSoundBuffer_Restore(alleg_buf) != DS_OK) - return; - IDirectSoundBuffer_SetVolume(alleg_buf, alleg_buf_vol); - } - - alleg_buf_paused = FALSE; - IDirectSoundBuffer_Play(alleg_buf, 0, 0, DSBPLAY_LOOPING); - } - else - return; - } - else { - if (!_win_app_foreground && - ((switch_mode == SWITCH_PAUSE) || (switch_mode == SWITCH_AMNESIA))) { - alleg_buf_paused = TRUE; - IDirectSoundBuffer_Stop(alleg_buf); - return; - } - } - -#if USE_NEW_CODE /* this should work, dammit */ - /* write data into the buffer */ - if (digidsbufdirty) { - _mix_some_samples((uintptr_t)digidsbufdata, 0, TRUE); - digidsbufdirty = FALSE; - } - - hr = IDirectSoundBuffer_GetCurrentPosition(alleg_buf, &playcurs, &writecurs); - if (FAILED(hr)) - return; - - if (((playcurs-writecurs)%(digidsbufsize*2)) < digidsbufsize) - return; - - /* Consider the buffer used. Even if the buffer was lost, mark the data as old - so the mixer doesn't stall */ - digidsbufdirty = TRUE; - - hr = IDirectSoundBuffer_Lock(alleg_buf, 0, digidsbufsize, - &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, - DSBLOCK_FROMWRITECURSOR); - - /* only try to restore the buffer once. don't wait around forever */ - if (hr == DSERR_BUFFERLOST) { - if(IDirectSoundBuffer_Restore(alleg_buf) != DS_OK) - return; - - IDirectSoundBuffer_Play(alleg_buf, 0, 0, DSBPLAY_LOOPING); - IDirectSoundBuffer_SetVolume(alleg_buf, alleg_buf_vol); - hr = IDirectSoundBuffer_Lock(alleg_buf, 0, digidsbufsize, - &lpvPtr1, &dwBytes1, &lpvPtr2, &dwBytes2, - DSBLOCK_FROMWRITECURSOR); - } - - if (FAILED(hr)) - return; - - /* if the first buffer has enough room, put it all there */ - if(dwBytes1 >= digidsbufsize) { - dwBytes1 = digidsbufsize; - memcpy(lpvPtr1, digidsbufdata, dwBytes1); - dwBytes2 = 0; - } - /* else, sput the first part into the first buffer, and the rest into the - second */ - else { - memcpy(lpvPtr1, digidsbufdata, dwBytes1); - dwBytes2 = digidsbufsize-dwBytes1; - memcpy(lpvPtr2, digidsbufdata+dwBytes1, dwBytes2); - } - - IDirectSoundBuffer_Unlock(alleg_buf, lpvPtr1, dwBytes1, lpvPtr2, dwBytes2); -#else - hr = IDirectSoundBuffer_GetCurrentPosition(alleg_buf, &playcurs, &writecurs); - if (FAILED(hr)) - return; - - writecurs /= (digidsbufsize/bufdivs); - writecurs += 8; - - while (writecurs > (bufdivs-1)) - writecurs -= bufdivs; - - /* avoid locking the buffer if no data to write */ - if (writecurs == digidsbufpos) - return; - - hr = IDirectSoundBuffer_Lock(alleg_buf, 0, 0, - &lpvPtr1, &dwBytes1, - &lpvPtr2, &dwBytes2, - DSBLOCK_FROMWRITECURSOR | DSBLOCK_ENTIREBUFFER); - - if (FAILED(hr)) - return; - - /* write data into the buffer */ - while (writecurs != digidsbufpos) { - if (lpvPtr2) { - memcpy((char*)lpvPtr2 + (((dwBytes1+dwBytes2)/bufdivs)*digidsbufpos), - digidsbufdata + (((dwBytes1+dwBytes2)/bufdivs)*digidsbufpos), - (dwBytes1+dwBytes2)/bufdivs); - } - else { - memcpy((char*)lpvPtr1 + (((dwBytes1)/bufdivs)*digidsbufpos), - digidsbufdata + (((dwBytes1)/bufdivs)*digidsbufpos), - (dwBytes1)/bufdivs); - } - - if (++digidsbufpos > (bufdivs-1)) - digidsbufpos = 0; - - _mix_some_samples((uintptr_t) (digidsbufdata+(((dwBytes1+dwBytes2)/bufdivs)*digidsbufpos)), 0, TRUE); - } - - IDirectSoundBuffer_Unlock(alleg_buf, lpvPtr1, dwBytes1, lpvPtr2, dwBytes2); -#endif -} - - - -/* digi_dsoundmix_detect: - */ -static int digi_dsoundmix_detect(int input) -{ - HRESULT hr; - int id; - - /* deduce our device number from the driver ID code */ - id = ((digi_driver->id >> 8) & 0xFF) - 'A'; - - if (input) - return digi_directsound_capture_detect(driver_guids[id]); - - if (!directsound) { - /* initialize DirectSound interface */ - hr = DirectSoundCreate(driver_guids[id], &directsound, NULL); - if (FAILED(hr)) { - _TRACE(PREFIX_E "DirectSound interface creation failed during detect (%s)\n", ds_err(hr)); - return 0; - } - - _TRACE(PREFIX_I "DirectSound interface successfully created\n"); - - /* release DirectSound */ - IDirectSound_Release(directsound); - directsound = NULL; - } - - return 1; -} - - - -/* digi_dsoundmix_init: - */ -static int digi_dsoundmix_init(int input, int voices) -{ - LPVOID lpvPtr1, lpvPtr2; - DWORD dwBytes1, dwBytes2; - HRESULT hr; - DSCAPS dscaps; - DSBUFFERDESC desc; - WAVEFORMATEX format; - HWND allegro_wnd = win_get_window(); - char tmp1[128], tmp2[128]; - int v, id; - - /* deduce our device number from the driver ID code */ - id = ((digi_driver->id >> 8) & 0xFF) - 'A'; - - if (input) - return digi_directsound_capture_init(driver_guids[id]); - - digi_driver->voices = voices; - - /* initialize DirectSound interface */ - hr = DirectSoundCreate(driver_guids[id], &directsound, NULL); - if (FAILED(hr)) { - _TRACE(PREFIX_E "Can't create DirectSound interface (%s)\n", ds_err(hr)); - goto Error; - } - - /* set cooperative level */ - hr = IDirectSound_SetCooperativeLevel(directsound, allegro_wnd, DSSCL_PRIORITY); - if (FAILED(hr)) - _TRACE(PREFIX_W "Can't set DirectSound cooperative level (%s)\n", ds_err(hr)); - else - _TRACE(PREFIX_I "DirectSound cooperation level set to DSSCL_PRIORITY\n"); - - /* get hardware capabilities */ - dscaps.dwSize = sizeof(DSCAPS); - hr = IDirectSound_GetCaps(directsound, &dscaps); - if (FAILED(hr)) { - _TRACE(PREFIX_E "Can't get DirectSound caps (%s)\n", ds_err(hr)); - goto Error; - } - - /* For some reason the audio driver on my machine doesn't seem to set either - * PRIMARY16BIT or PRIMARY8BIT; of course it actually does support 16-bit - * sound. - */ - if (((dscaps.dwFlags & DSCAPS_PRIMARY16BIT) || !(dscaps.dwFlags & DSCAPS_PRIMARY8BIT)) - && ((_sound_bits >= 16) || (_sound_bits <= 0))) - _bits = 16; - else - _bits = 8; - - if ((dscaps.dwFlags & DSCAPS_PRIMARYSTEREO) && _sound_stereo) - _stereo = 1; - else - _stereo = 0; - - /* Try to set the requested frequency */ - if ((dscaps.dwMaxSecondarySampleRate > (DWORD)_sound_freq) && (_sound_freq > 0)) - _freq = _sound_freq; - /* If no frequency is specified, make sure it's clamped to a reasonable value - by default */ - else if ((_sound_freq <= 0) && (dscaps.dwMaxSecondarySampleRate > 44100)) - _freq = 44100; - else - _freq = dscaps.dwMaxSecondarySampleRate; - - _TRACE(PREFIX_I "DirectSound caps: %u bits, %s, %uHz\n", _bits, _stereo ? "stereo" : "mono", _freq); - - memset(&desc, 0, sizeof(DSBUFFERDESC)); - desc.dwSize = sizeof(DSBUFFERDESC); - desc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_GLOBALFOCUS;// | DSBCAPS_CTRLVOLUME | DSBCAPS_STICKYFOCUS; - - hr = IDirectSound_CreateSoundBuffer(directsound, &desc, &prim_buf, NULL); - if (FAILED(hr)) - _TRACE(PREFIX_W "Can't create primary buffer (%s)\nGlobal volume control won't be available\n", ds_err(hr)); - - if (prim_buf) { - hr = IDirectSoundBuffer_GetFormat(prim_buf, &format, sizeof(format), NULL); - if (FAILED(hr)) { - _TRACE(PREFIX_W "Can't get primary buffer format (%s)\n", ds_err(hr)); - } - else { - format.nChannels = (_stereo ? 2 : 1); - format.nSamplesPerSec = _freq; - format.wBitsPerSample = _bits; - format.nBlockAlign = (format.wBitsPerSample * format.nChannels) >> 3; - format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign; - - hr = IDirectSoundBuffer_SetFormat(prim_buf, &format); - if (FAILED(hr)) - _TRACE(PREFIX_W "Can't set primary buffer format (%s)\n", ds_err(hr)); - - hr = IDirectSoundBuffer_GetFormat(prim_buf, &format, sizeof(format), NULL); - if (FAILED(hr)) { - _TRACE(PREFIX_W "Can't get primary buffer format (%s)\n", ds_err(hr)); - } - else { - _TRACE(PREFIX_I "primary format:\n"); - _TRACE(PREFIX_I " %u channels\n %u Hz\n %u AvgBytesPerSec\n %u BlockAlign\n %u bits\n %u size\n", - format.nChannels, format.nSamplesPerSec, format.nAvgBytesPerSec, - format.nBlockAlign, format.wBitsPerSample, format.cbSize); - } - } - } - - /* setup volume lookup table */ - alleg_to_dsound_volume[0] = DSBVOLUME_MIN; - for (v = 1; v < 256; v++) { - int dB = DSBVOLUME_MAX + 2000.0*log10(v/255.0); - alleg_to_dsound_volume[v] = MAX(DSBVOLUME_MIN, dB); - } - - /* create the sound buffer to mix into */ - alleg_buf = create_dsound_buffer(get_config_int(uconvert_ascii("sound", tmp1), - uconvert_ascii("dsound_numfrags", tmp2), - 6) * 1024, - _freq, _bits, _stereo, 255); - if(!alleg_buf) { - _TRACE(PREFIX_E "Can't create mixing buffer\n"); - return -1; - } - - /* fill the sound buffer with zeros */ - hr = IDirectSoundBuffer_Lock(alleg_buf, 0, 0, &lpvPtr1, &dwBytes1, - &lpvPtr2, &dwBytes2, DSBLOCK_ENTIREBUFFER); - - if (FAILED(hr)) { - _TRACE(PREFIX_E "Can't lock sound buffer (%s)\n", ds_err(hr)); - return -1; - } - - memset(lpvPtr1, 0, dwBytes1); - digidsbufsize = dwBytes1; - - if (lpvPtr2) { - _TRACE(PREFIX_E "Second buffer set when locking buffer. Error?\n"); - memset(lpvPtr2, 0, dwBytes2); - digidsbufsize += dwBytes2; - } - - IDirectSoundBuffer_Unlock(alleg_buf, lpvPtr1, dwBytes1, lpvPtr2, dwBytes2); - - _TRACE(PREFIX_I "Sound buffer length is %u\n", digidsbufsize); - - /* shouldn't ever happen */ - if (digidsbufsize&1023) { - _TRACE(PREFIX_E "Sound buffer is not multiple of 1024, failed\n"); - return -1; - } - -#if USE_NEW_CODE - digidsbufsize /= 2; -#endif - digidsbufdata = _AL_MALLOC_ATOMIC(digidsbufsize); - if (!digidsbufdata) { - _TRACE(PREFIX_E "Can't create temp buffer\n"); - return -1; - } - -#if USE_NEW_CODE - if (_mixer_init(digidsbufsize / (_bits /8), _freq, _stereo, - ((_bits == 16) ? 1 : 0), &digi_driver->voices) != 0) { - _TRACE(PREFIX_E "Can't init software mixer\n"); - return -1; - } -#else - bufdivs = digidsbufsize/1024; - if (_mixer_init((digidsbufsize / (_bits /8)) / bufdivs, _freq, - _stereo, ((_bits == 16) ? 1 : 0), &digi_driver->voices) != 0) { - _TRACE(PREFIX_E "Can't init software mixer\n"); - return -1; - } - - _mix_some_samples((uintptr_t)digidsbufdata, 0, TRUE); -#endif - - /* get primary buffer volume */ - IDirectSoundBuffer_GetVolume(alleg_buf, &initial_volume); - alleg_buf_vol = initial_volume; - - /* mark the buffer as paused, so the mixer callback will start it */ - alleg_buf_paused = TRUE; -#if USE_NEW_CODE - digidsbufdirty = TRUE; -#endif - install_int(digi_dsoundmix_mixer_callback, 20); /* 50 Hz */ - - return 0; - - Error: - _TRACE(PREFIX_E "digi_directsound_init() failed\n"); - digi_dsoundmix_exit(0); - return -1; -} - - - -/* digi_dsoundmix_exit: - */ -static void digi_dsoundmix_exit(int input) -{ - if (input) { - digi_directsound_capture_exit(); - return; - } - - /* stop playing */ - remove_int(digi_dsoundmix_mixer_callback); - - if (digidsbufdata) { - _AL_FREE(digidsbufdata); - digidsbufdata = NULL; - } - - /* destroy mixer buffer */ - if (alleg_buf) { - IDirectSoundBuffer_Release(alleg_buf); - alleg_buf = NULL; - } - - /* destroy primary buffer */ - if (prim_buf) { - /* restore primary buffer initial volume */ - IDirectSoundBuffer_SetVolume(prim_buf, initial_volume); - - IDirectSoundBuffer_Release(prim_buf); - prim_buf = NULL; - } - - /* shutdown DirectSound */ - if (directsound) { - IDirectSound_Release(directsound); - directsound = NULL; - } -} - - - -/* digi_dsoundmix_set_mixer_volume: - */ -static int digi_dsoundmix_set_mixer_volume(int volume) -{ - if (prim_buf) { - alleg_buf_vol = alleg_to_dsound_volume[CLAMP(0, volume, 255)]; - IDirectSoundBuffer_SetVolume(alleg_buf, alleg_buf_vol); - } - - return 0; -} - - - -/* digi_dsoundmix_get_mixer_volume: - */ -static int digi_dsoundmix_get_mixer_volume(void) -{ - LONG vol; - - if (!prim_buf) - return -1; - - IDirectSoundBuffer_GetVolume(alleg_buf, &vol); - vol = CLAMP(0, pow(10, (vol/2000.0))*255.0 - DSBVOLUME_MAX, 255); - - return vol; -} - - - -/* digi_dsoundmix_buffer_size: - */ -static int digi_dsoundmix_buffer_size(void) -{ - return digidsbufsize / (_bits / 8) / (_stereo ? 2 : 1); -} diff --git a/src/allegro/src/win/wdsound.c b/src/allegro/src/win/wdsound.c deleted file mode 100644 index cca3483db..000000000 --- a/src/allegro/src/win/wdsound.c +++ /dev/null @@ -1,1195 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * DirectSound sound driver. - * - * By Stefan Schimanski. - * - * Various bugfixes by Patrick Hogan. - * - * Custom loop points support added by Eric Botcazou. - * - * Backward playing support, bidirectional looping support - * and bugfixes by Javier Gonzalez. - * - * See readme.txt for copyright information. - */ - - -#define DIRECTSOUND_VERSION 0x0300 - -#include "allegro.h" -#include "allegro/internal/aintern.h" -#include "allegro/platform/aintwin.h" - -#ifndef SCAN_DEPEND - #ifdef ALLEGRO_MINGW32 - #undef MAKEFOURCC - #endif - - #include - #include - #include - - #ifdef ALLEGRO_MSVC - #include - #endif -#endif - -#ifndef ALLEGRO_WINDOWS -#error something is wrong with the makefile -#endif - -#define PREFIX_I "al-dsound INFO: " -#define PREFIX_W "al-dsound WARNING: " -#define PREFIX_E "al-dsound ERROR: " - - -static int digi_directsound_detect(int input); -static int digi_directsound_init(int input, int voices); -static void digi_directsound_exit(int input); -static int digi_directsound_set_mixer_volume(int volume); -static int digi_directsound_get_mixer_volume(void); - -static void digi_directsound_init_voice(int voice, AL_CONST SAMPLE * sample); -static void digi_directsound_release_voice(int voice); -static void digi_directsound_start_voice(int voice); -static void digi_directsound_stop_voice(int voice); -static void digi_directsound_loop_voice(int voice, int playmode); - -static void *digi_directsound_lock_voice(int voice, int start, int end); -static void digi_directsound_unlock_voice(int voice); - -static int digi_directsound_get_position(int voice); -static void digi_directsound_set_position(int voice, int position); - -static int digi_directsound_get_volume(int voice); -static void digi_directsound_set_volume(int voice, int volume); - -static int digi_directsound_get_frequency(int voice); -static void digi_directsound_set_frequency(int voice, int frequency); - -static int digi_directsound_get_pan(int voice); -static void digi_directsound_set_pan(int voice, int pan); - - -/* template driver: will be cloned for each device */ -static DIGI_DRIVER digi_directsound = -{ - 0, - empty_string, - empty_string, - empty_string, - 0, // available voices - 0, // voice number offset - 16, // maximum voices we can support - 4, // default number of voices to use - - /* setup routines */ - digi_directsound_detect, - digi_directsound_init, - digi_directsound_exit, - digi_directsound_set_mixer_volume, - digi_directsound_get_mixer_volume, - - /* audiostream locking functions */ - digi_directsound_lock_voice, - digi_directsound_unlock_voice, - NULL, // AL_METHOD(int, buffer_size, (void)); - - /* voice control functions */ - digi_directsound_init_voice, - digi_directsound_release_voice, - digi_directsound_start_voice, - digi_directsound_stop_voice, - digi_directsound_loop_voice, - - /* position control functions */ - digi_directsound_get_position, - digi_directsound_set_position, - - /* volume control functions */ - digi_directsound_get_volume, - digi_directsound_set_volume, - NULL, // AL_METHOD(void, ramp_volume, (int voice, int time, int endvol)); - NULL, // AL_METHOD(void, stop_volume_ramp, (int voice)); - - /* pitch control functions */ - digi_directsound_get_frequency, - digi_directsound_set_frequency, - NULL, // AL_METHOD(void, sweep_frequency, (int voice, int time, int endfreq)); - NULL, // AL_METHOD(void, stop_frequency_sweep, (int voice)); - - /* pan control functions */ - digi_directsound_get_pan, - digi_directsound_set_pan, - NULL, // AL_METHOD(void, sweep_pan, (int voice, int time, int endpan)); - NULL, // AL_METHOD(void, stop_pan_sweep, (int voice)); - - /* effect control functions */ - NULL, // AL_METHOD(void, set_echo, (int voice, int strength, int delay)); - NULL, // AL_METHOD(void, set_tremolo, (int voice, int rate, int depth)); - NULL, // AL_METHOD(void, set_vibrato, (int voice, int rate, int depth)); - - /* input functions */ - 0, /* int rec_cap_bits; */ - 0, /* int rec_cap_stereo; */ - digi_directsound_rec_cap_rate, - digi_directsound_rec_cap_param, - digi_directsound_rec_source, - digi_directsound_rec_start, - digi_directsound_rec_stop, - digi_directsound_rec_read -}; - - -/* sound driver globals */ -static LPDIRECTSOUND directsound = NULL; -static LPDIRECTSOUNDBUFFER prim_buf = NULL; -static long int initial_volume; -static int _freq, _bits, _stereo; -static int alleg_to_dsound_volume[256]; -static int alleg_to_dsound_pan[256]; - - -/* internal driver representation of a voice */ -struct DIRECTSOUND_VOICE { - int bits; - int bytes_per_sample; - int freq, pan, vol; - int stereo; - int reversed; - int bidir; - int len; - unsigned char *data; - int loop_offset; - int loop_len; - int looping; - void *lock_buf_a; - long lock_size_a; - LPDIRECTSOUNDBUFFER ds_buffer; - LPDIRECTSOUNDBUFFER ds_loop_buffer; - LPDIRECTSOUNDBUFFER ds_locked_buffer; -}; - -static struct DIRECTSOUND_VOICE *ds_voices; - - -/* dynamically generated driver list */ -static _DRIVER_INFO *driver_list = NULL; - -#define MAX_DRIVERS 16 -static int num_drivers = 0; -static char *driver_names[MAX_DRIVERS]; -static LPGUID driver_guids[MAX_DRIVERS]; - - - -/* DSEnumCallback: - * Callback function for enumerating the available DirectSound drivers. - */ -static BOOL CALLBACK DSEnumCallback(LPGUID lpGuid, LPCSTR lpcstrDescription, LPCSTR lpcstrModule, LPVOID lpContext) -{ - if (lpGuid) { - driver_guids[num_drivers] = lpGuid; - driver_names[num_drivers] = _AL_MALLOC_ATOMIC(strlen(lpcstrDescription)+1); - if(driver_names[num_drivers]) - { - _al_sane_strncpy(driver_names[num_drivers], lpcstrDescription, strlen(lpcstrDescription)+1); - num_drivers++; - } - } - - return (num_drivers < MAX_DRIVERS); -} - - - -/* _get_win_digi_driver_list: - * System driver hook for listing the available sound drivers. This - * generates the device list at runtime, to match whatever DirectSound - * devices are available. - */ -_DRIVER_INFO *_get_win_digi_driver_list(void) -{ - DIGI_DRIVER *driver; - HRESULT hr; - int i; - - if (!driver_list) { - driver_list = _create_driver_list(); - - /* enumerate the DirectSound drivers */ - hr = DirectSoundEnumerate(DSEnumCallback, NULL); - - if (hr == DS_OK) { - /* Allegro mixer to DirectSound drivers */ - for (i=0; iid, driver, TRUE); - } - - /* pure DirectSound drivers */ - for (i=0; iid = DIGI_DIRECTX(i); - driver->ascii_name = driver_names[i]; - - _driver_list_append_driver(&driver_list, driver->id, driver, TRUE); - } - } - - /* Allegro mixer to WaveOut drivers */ - for (i=0; i<2; i++) { - driver = _get_woalmix_driver(i); - - _driver_list_append_driver(&driver_list, driver->id, driver, TRUE); - } - } - - return driver_list; -} - - - -/* _free_win_digi_driver_list: - * Helper function for freeing the dynamically generated driver list. - */ -void _free_win_digi_driver_list(void) -{ - int i = 0; - - if (driver_list) { - while (driver_list[i].driver) { - _AL_FREE(driver_list[i].driver); - i++; - } - - _destroy_driver_list(driver_list); - driver_list = NULL; - } - - for (i = 0; i < num_drivers; i++) { - _AL_FREE(driver_names[i]); - } - - _free_win_dsalmix_name_list(); -} - - - -/* ds_err: - * Returns a DirectSound error string. - */ -#ifdef DEBUGMODE -static char *ds_err(long err) -{ - static char err_str[64]; - - switch (err) { - - case DS_OK: - _al_sane_strncpy(err_str, "DS_OK", sizeof(err_str)); - break; - - case DSERR_ALLOCATED: - _al_sane_strncpy(err_str, "DSERR_ALLOCATED", sizeof(err_str)); - break; - - case DSERR_BADFORMAT: - _al_sane_strncpy(err_str, "DSERR_BADFORMAT", sizeof(err_str)); - break; - - case DSERR_INVALIDPARAM: - _al_sane_strncpy(err_str, "DSERR_INVALIDPARAM", sizeof(err_str)); - break; - - case DSERR_NOAGGREGATION: - _al_sane_strncpy(err_str, "DSERR_NOAGGREGATION", sizeof(err_str)); - break; - - case DSERR_OUTOFMEMORY: - _al_sane_strncpy(err_str, "DSERR_OUTOFMEMORY", sizeof(err_str)); - break; - - case DSERR_UNINITIALIZED: - _al_sane_strncpy(err_str, "DSERR_UNINITIALIZED", sizeof(err_str)); - break; - - case DSERR_UNSUPPORTED: - _al_sane_strncpy(err_str, "DSERR_UNSUPPORTED", sizeof(err_str)); - break; - - default: - _al_sane_strncpy(err_str, "DSERR_UNKNOWN", sizeof(err_str)); - break; - } - - return err_str; -} -#else -#define ds_err(hr) "\0" -#endif - - - -/* digi_directsound_detect: - */ -static int digi_directsound_detect(int input) -{ - HRESULT hr; - int id; - - /* deduce our device number from the driver ID code */ - id = ((digi_driver->id >> 8) & 0xFF) - 'A'; - - if (input) - return digi_directsound_capture_detect(driver_guids[id]); - - if (!directsound) { - /* initialize DirectSound interface */ - hr = DirectSoundCreate(driver_guids[id], &directsound, NULL); - if (FAILED(hr)) { - _TRACE(PREFIX_E "DirectSound interface creation failed during detect (%s).\n", ds_err(hr)); - return 0; - } - - _TRACE(PREFIX_I "DirectSound interface successfully created.\n"); - - /* release DirectSound interface */ - IDirectSound_Release(directsound); - directsound = NULL; - } - - return 1; -} - - - -/* digi_directsound_init: - */ -static int digi_directsound_init(int input, int voices) -{ - HRESULT hr; - DSCAPS dscaps; - DSBUFFERDESC desc; - WAVEFORMATEX format; - int v, id; - HWND allegro_wnd = win_get_window(); - - /* deduce our device number from the driver ID code */ - id = ((digi_driver->id >> 8) & 0xFF) - 'A'; - - if (input) - return digi_directsound_capture_init(driver_guids[id]); - - digi_driver->voices = voices; - - /* initialize DirectSound interface */ - hr = DirectSoundCreate(driver_guids[id], &directsound, NULL); - if (FAILED(hr)) { - _TRACE(PREFIX_E "Can't create DirectSound interface (%s).\n", ds_err(hr)); - goto Error; - } - - /* set cooperative level */ - hr = IDirectSound_SetCooperativeLevel(directsound, allegro_wnd, DSSCL_PRIORITY); - if (FAILED(hr)) - _TRACE(PREFIX_W "Can't set DirectSound cooperative level (%s).\n", ds_err(hr)); - else - _TRACE(PREFIX_I "DirectSound cooperation level set to PRIORITY.\n"); - - /* get hardware capabilities */ - dscaps.dwSize = sizeof(DSCAPS); - hr = IDirectSound_GetCaps(directsound, &dscaps); - if (FAILED(hr)) { - _TRACE(PREFIX_E "Can't get DirectSound caps (%s).\n", ds_err(hr)); - goto Error; - } - - /* For some reason the audio driver on my machine doesn't seem to set either - * PRIMARY16BIT or PRIMARY8BIT; of course it actually does support 16-bit - * sound. - */ - if (((dscaps.dwFlags & DSCAPS_PRIMARY16BIT) || !(dscaps.dwFlags & DSCAPS_PRIMARY8BIT)) - && ((_sound_bits >= 16) || (_sound_bits <= 0))) - _bits = 16; - else - _bits = 8; - - if ((dscaps.dwFlags & DSCAPS_PRIMARYSTEREO) && _sound_stereo) - _stereo = 1; - else - _stereo = 0; - - if ((dscaps.dwMaxSecondarySampleRate > (DWORD)_sound_freq) && (_sound_freq > 0)) - _freq = _sound_freq; - else - _freq = dscaps.dwMaxSecondarySampleRate; - - _TRACE(PREFIX_I "DirectSound caps: %u bits, %s, %uHz\n", _bits, _stereo ? "stereo" : "mono", _freq); - - /* create primary buffer */ - memset(&desc, 0, sizeof(DSBUFFERDESC)); - desc.dwSize = sizeof(DSBUFFERDESC); - desc.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRLVOLUME; - - hr = IDirectSound_CreateSoundBuffer(directsound, &desc, &prim_buf, NULL); - if (hr != DS_OK) { - _TRACE(PREFIX_W "Can't create primary buffer (%s)\nGlobal volume control won't be available.\n", ds_err(hr)); - } - - /* get current format */ - if (prim_buf) { - hr = IDirectSoundBuffer_GetFormat(prim_buf, &format, sizeof(format), NULL); - if (FAILED(hr)) { - _TRACE(PREFIX_W "Can't get primary buffer format (%s).\n", ds_err(hr)); - } - else { - format.nChannels = _stereo ? 2 : 1; - format.nSamplesPerSec = _freq; - format.wBitsPerSample = _bits; - format.nBlockAlign = (format.wBitsPerSample * format.nChannels) >> 3; - format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign; - - hr = IDirectSoundBuffer_SetFormat(prim_buf, &format); - if (FAILED(hr)) { - _TRACE(PREFIX_W "Can't set primary buffer format (%s).\n", ds_err(hr)); - } - - /* output primary format */ - hr = IDirectSoundBuffer_GetFormat(prim_buf, &format, sizeof(format), NULL); - if (FAILED(hr)) { - _TRACE(PREFIX_W "Can't get primary buffer format (%s).\n", ds_err(hr)); - } - else { - _TRACE(PREFIX_I "primary format:\n"); - _TRACE(PREFIX_I " %u channels\n %u Hz\n %u AvgBytesPerSec\n %u BlockAlign\n %u bits\n %u size\n", - format.nChannels, format.nSamplesPerSec, format.nAvgBytesPerSec, - format.nBlockAlign, format.wBitsPerSample, format.cbSize); - } - } - - /* get primary buffer (global) volume */ - IDirectSoundBuffer_GetVolume(prim_buf, &initial_volume); - } - - /* initialize physical voices */ - ds_voices = (struct DIRECTSOUND_VOICE *)_AL_MALLOC(sizeof(struct DIRECTSOUND_VOICE) * voices); - for (v = 0; v < digi_driver->voices; v++) { - ds_voices[v].ds_buffer = NULL; - ds_voices[v].ds_loop_buffer = NULL; - ds_voices[v].ds_locked_buffer = NULL; - } - - /* setup volume lookup table */ - alleg_to_dsound_volume[0] = DSBVOLUME_MIN; - for (v = 1; v < 256; v++) - alleg_to_dsound_volume[v] = MAX(DSBVOLUME_MIN, DSBVOLUME_MAX + 2000.0*log10(v/255.0)); - - /* setup pan lookup table */ - alleg_to_dsound_pan[0] = DSBPAN_LEFT; - for (v = 1; v < 128; v++) - alleg_to_dsound_pan[v] = MAX(DSBPAN_LEFT, DSBPAN_CENTER + 2000.0*log10(v/127.0)); - - alleg_to_dsound_pan[255] = DSBPAN_RIGHT; - for (v = 128; v < 255; v++) - alleg_to_dsound_pan[v] = MIN(DSBPAN_RIGHT, DSBPAN_CENTER - 2000.0*log10((255.0-v)/127.0)); - - return 0; - - Error: - _TRACE(PREFIX_E "digi_directsound_init() failed.\n"); - digi_directsound_exit(FALSE); - return -1; -} - - - -/* digi_directsound_exit: - */ -static void digi_directsound_exit(int input) -{ - int v; - - if (input) { - digi_directsound_capture_exit(); - return; - } - - /* destroy physical voices */ - for (v = 0; v < digi_driver->voices; v++) - digi_directsound_release_voice(v); - - _AL_FREE(ds_voices); - ds_voices = NULL; - - /* destroy primary buffer */ - if (prim_buf) { - /* restore primary buffer initial volume */ - IDirectSoundBuffer_SetVolume(prim_buf, initial_volume); - - IDirectSoundBuffer_Release(prim_buf); - prim_buf = NULL; - } - - /* shutdown DirectSound */ - if (directsound) { - IDirectSound_Release(directsound); - directsound = NULL; - } -} - - - -/* digi_directsound_set_mixer_volume: - */ -static int digi_directsound_set_mixer_volume(int volume) -{ - int ds_vol; - - if (prim_buf) { - ds_vol = alleg_to_dsound_volume[CLAMP(0, volume, 255)]; - IDirectSoundBuffer_SetVolume(prim_buf, ds_vol); - } - - return 0; -} - - - -/* digi_directsound_get_mixer_volume: - */ -static int digi_directsound_get_mixer_volume(void) -{ - LONG vol; - - if (!prim_buf) - return -1; - - IDirectSoundBuffer_GetVolume(prim_buf, &vol); - vol = CLAMP(0, pow(10, (vol/2000.0))*255.0 - DSBVOLUME_MAX, 255); - - return vol; -} - - - -/********************************************************/ -/*********** voice management functions *****************/ -/********************************************************/ - - -/* create_dsound_buffer: - * Worker function for creating a DirectSound buffer. - */ -static LPDIRECTSOUNDBUFFER create_dsound_buffer(int len, int freq, int bits, int stereo, int vol, int pan) -{ - LPDIRECTSOUNDBUFFER snd_buf; - WAVEFORMATEX wf; - DSBUFFERDESC dsbdesc; - HRESULT hr; - int switch_mode; - - /* setup wave format structure */ - memset(&wf, 0, sizeof(WAVEFORMATEX)); - wf.wFormatTag = WAVE_FORMAT_PCM; - wf.nChannels = stereo ? 2 : 1; - wf.nSamplesPerSec = freq; - wf.wBitsPerSample = bits; - wf.nBlockAlign = bits * (stereo ? 2 : 1) / 8; - wf.nAvgBytesPerSec = wf.nSamplesPerSec * wf.nBlockAlign; - - /* setup DSBUFFERDESC structure */ - memset(&dsbdesc, 0, sizeof(DSBUFFERDESC)); - dsbdesc.dwSize = sizeof(DSBUFFERDESC); - - /* need default controls (pan, volume, frequency) */ - dsbdesc.dwFlags = DSBCAPS_CTRLPAN | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLFREQUENCY; - - switch_mode = get_display_switch_mode(); - if ((switch_mode == SWITCH_BACKAMNESIA) || (switch_mode == SWITCH_BACKGROUND)) - dsbdesc.dwFlags |= DSBCAPS_GLOBALFOCUS; - - dsbdesc.dwBufferBytes = len * (bits / 8) * (stereo ? 2 : 1); - dsbdesc.lpwfxFormat = &wf; - - /* create buffer */ - hr = IDirectSound_CreateSoundBuffer(directsound, &dsbdesc, &snd_buf, NULL); - if (FAILED(hr)) { - _TRACE(PREFIX_E "create_directsound_buffer() failed (%s).\n", ds_err(hr)); - _TRACE(PREFIX_E " - %d Hz, %s, %d bits\n", freq, stereo ? "stereo" : "mono", bits); - return NULL; - } - - /* set volume */ - IDirectSoundBuffer_SetVolume(snd_buf, alleg_to_dsound_volume[CLAMP(0, vol, 255)]); - - /* set pan */ - IDirectSoundBuffer_SetPan(snd_buf, alleg_to_dsound_pan[CLAMP(0, pan, 255)]); - - return snd_buf; -} - - - -/* fill_dsound_buffer: - * Worker function for copying data to a DirectSound buffer. - */ -static int fill_dsound_buffer(LPDIRECTSOUNDBUFFER snd_buf, int offset, int len, int bits, int stereo, int reversed, unsigned char *data) -{ - void *buf_a; - unsigned long int size, size_a; - HRESULT hr; - - /* transform from samples to bytes */ - size = len * (bits / 8) * (stereo ? 2 : 1); - offset = offset * (bits / 8) * (stereo ? 2 : 1); - - /* lock the buffer portion */ - hr = IDirectSoundBuffer_Lock(snd_buf, offset, size, &buf_a, &size_a, NULL, NULL, 0); - - /* if buffer lost, restore and retry lock */ - if (hr == DSERR_BUFFERLOST) { - IDirectSoundBuffer_Restore(snd_buf); - - hr = IDirectSoundBuffer_Lock(snd_buf, offset, size, &buf_a, &size_a, NULL, NULL, 0); - if (FAILED(hr)) { - _TRACE(PREFIX_E "fill_dsound_buffer() failed (%s).\n", ds_err(hr)); - return -1; - } - } - - if (reversed) { - if (stereo) { - if (bits == 8) { - /* 8-bit stereo */ - unsigned short *read_p = (unsigned short *)data + len - 1; - unsigned short *write_p = (unsigned short *)buf_a; - - while (len--) - *write_p++ = *read_p--; - } - else if (bits == 16) { - /* 16-bit stereo (conversion needed) */ - unsigned long *read_p = (unsigned long *)data + len - 1; - unsigned long *write_p = (unsigned long *)buf_a; - - while (len--) - *write_p++ = *read_p-- ^ 0x80008000; - } - } - else { - if (bits == 8) { - /* 8-bit mono */ - unsigned char *read_p = (unsigned char *)data + len - 1; - unsigned char *write_p = (unsigned char *)buf_a; - - while (len--) - *write_p++ = *read_p--; - } - else { - /* 16-bit mono (conversion needed) */ - unsigned short *read_p = (unsigned short *)data + len - 1; - unsigned short *write_p = (unsigned short *)buf_a; - - while (len--) - *write_p++ = *read_p-- ^ 0x8000; - } - } - } - else { - if (bits == 8) { - /* 8-bit mono and stereo */ - memcpy(buf_a, data, size); - } - else if (bits == 16) { - /* 16-bit mono and stereo (conversion needed) */ - unsigned short *read_p = (unsigned short *)data; - unsigned short *write_p = (unsigned short *)buf_a; - - size >>= 1; - - while (size--) - *write_p++ = *read_p++ ^ 0x8000; - } - } - - /* unlock the buffer */ - IDirectSoundBuffer_Unlock(snd_buf, buf_a, size_a, NULL, 0); - - return 0; -} - - - -/* digi_directsound_init_voice: - */ -static void digi_directsound_init_voice(int voice, AL_CONST SAMPLE *sample) -{ - ds_voices[voice].bits = sample->bits; - ds_voices[voice].bytes_per_sample = (sample->bits/8) * (sample->stereo ? 2 : 1); - ds_voices[voice].freq = sample->freq; - ds_voices[voice].pan = 128; - ds_voices[voice].vol = 255; - ds_voices[voice].stereo = sample->stereo; - ds_voices[voice].reversed = FALSE; - ds_voices[voice].bidir = FALSE; - ds_voices[voice].len = sample->len; - ds_voices[voice].data = (unsigned char *)sample->data; - ds_voices[voice].loop_offset = sample->loop_start; - ds_voices[voice].loop_len = sample->loop_end - sample->loop_start; - ds_voices[voice].looping = FALSE; - ds_voices[voice].lock_buf_a = NULL; - ds_voices[voice].lock_size_a = 0; - ds_voices[voice].ds_locked_buffer = NULL; - ds_voices[voice].ds_loop_buffer = NULL; - ds_voices[voice].ds_buffer = create_dsound_buffer(ds_voices[voice].len, - ds_voices[voice].freq, - ds_voices[voice].bits, - ds_voices[voice].stereo, - ds_voices[voice].vol, - ds_voices[voice].pan); - if (!ds_voices[voice].ds_buffer) - return; - - fill_dsound_buffer(ds_voices[voice].ds_buffer, - 0, /* offset */ - ds_voices[voice].len, - ds_voices[voice].bits, - ds_voices[voice].stereo, - ds_voices[voice].reversed, - ds_voices[voice].data); -} - - - -/* digi_directsound_release_voice: - */ -static void digi_directsound_release_voice(int voice) -{ - /* just in case */ - digi_directsound_unlock_voice(voice); - - if (ds_voices[voice].ds_buffer) { - IDirectSoundBuffer_Release(ds_voices[voice].ds_buffer); - ds_voices[voice].ds_buffer = NULL; - } - - if (ds_voices[voice].ds_loop_buffer) { - IDirectSoundBuffer_Release(ds_voices[voice].ds_loop_buffer); - ds_voices[voice].ds_loop_buffer = NULL; - } -} - - - -/* digi_directsound_start_voice: - */ -static void digi_directsound_start_voice(int voice) -{ - if (ds_voices[voice].looping && ds_voices[voice].ds_loop_buffer) { - IDirectSoundBuffer_Play(ds_voices[voice].ds_loop_buffer, 0, 0, DSBPLAY_LOOPING); - } - else if (ds_voices[voice].ds_buffer) { - IDirectSoundBuffer_Play(ds_voices[voice].ds_buffer, 0, 0, - ds_voices[voice].looping ? DSBPLAY_LOOPING : 0); - } -} - - - -/* digi_directsound_stop_voice: - */ -static void digi_directsound_stop_voice(int voice) -{ - if (ds_voices[voice].looping && ds_voices[voice].ds_loop_buffer) { - IDirectSoundBuffer_Stop(ds_voices[voice].ds_loop_buffer); - } - else if (ds_voices[voice].ds_buffer) { - IDirectSoundBuffer_Stop(ds_voices[voice].ds_buffer); - } -} - - - -/* update_voice_buffers: - * Worker function for updating the voice buffers with the current - * parameters. - */ -static void update_voice_buffers(int voice, int reversed, int bidir, int loop) -{ - int update_main_buffer = FALSE; - int update_loop_buffer = FALSE; - int update_reversed = (ds_voices[voice].reversed != reversed); - int update_loop = (ds_voices[voice].looping != loop); - int update_bidir = (ds_voices[voice].bidir != bidir); - - /* no work to do? */ - if (!update_reversed && !update_bidir && !update_loop) - return; - - /* we need to change looping or bidir? */ - if (update_loop || update_bidir) { - ds_voices[voice].looping = loop; - ds_voices[voice].bidir = bidir; - - if (!loop && ds_voices[voice].ds_loop_buffer) { - /* we don't need a loop buffer anymore, destroy it */ - if (ds_voices[voice].ds_locked_buffer == ds_voices[voice].ds_loop_buffer) - digi_directsound_unlock_voice(voice); - IDirectSoundBuffer_Release(ds_voices[voice].ds_loop_buffer); - ds_voices[voice].ds_loop_buffer = NULL; - } - else if (loop && !ds_voices[voice].ds_loop_buffer) { - /* we haven't got one, create it */ - ds_voices[voice].ds_loop_buffer = create_dsound_buffer(ds_voices[voice].loop_len * (bidir ? 2 : 1), - ds_voices[voice].freq, - ds_voices[voice].bits, - ds_voices[voice].stereo, - ds_voices[voice].vol, - ds_voices[voice].pan); - update_loop_buffer = TRUE; - } - else if (update_bidir) { - /* we need to resize the loop buffer */ - if (ds_voices[voice].ds_locked_buffer == ds_voices[voice].ds_loop_buffer) - digi_directsound_unlock_voice(voice); - IDirectSoundBuffer_Release(ds_voices[voice].ds_loop_buffer); - ds_voices[voice].ds_loop_buffer = create_dsound_buffer(ds_voices[voice].loop_len * (bidir ? 2 : 1), - ds_voices[voice].freq, - ds_voices[voice].bits, - ds_voices[voice].stereo, - ds_voices[voice].vol, - ds_voices[voice].pan); - update_loop_buffer = TRUE; - } - } - - /* we need to change the order? */ - if (update_reversed) { - ds_voices[voice].reversed = reversed; - - update_main_buffer = TRUE; - update_loop_buffer = TRUE; - } - - /* we need to update the main buffer? */ - if (update_main_buffer) { - fill_dsound_buffer(ds_voices[voice].ds_buffer, - 0, /* offset */ - ds_voices[voice].len, - ds_voices[voice].bits, - ds_voices[voice].stereo, - ds_voices[voice].reversed, - ds_voices[voice].data); - } - - /* we need to update the loop buffer? */ - if (update_loop_buffer && ds_voices[voice].ds_loop_buffer) { - fill_dsound_buffer(ds_voices[voice].ds_loop_buffer, - 0, /* offset */ - ds_voices[voice].loop_len, - ds_voices[voice].bits, - ds_voices[voice].stereo, - ds_voices[voice].reversed, - ds_voices[voice].data + ds_voices[voice].loop_offset * ds_voices[voice].bytes_per_sample); - - if (ds_voices[voice].bidir) - fill_dsound_buffer(ds_voices[voice].ds_loop_buffer, - ds_voices[voice].loop_len, - ds_voices[voice].loop_len, - ds_voices[voice].bits, - ds_voices[voice].stereo, - !ds_voices[voice].reversed, - ds_voices[voice].data + ds_voices[voice].loop_offset * ds_voices[voice].bytes_per_sample); - - /* rewind the buffer */ - IDirectSoundBuffer_SetCurrentPosition(ds_voices[voice].ds_loop_buffer, 0); - } -} - - - -/* digi_directsound_loop_voice: - */ -static void digi_directsound_loop_voice(int voice, int playmode) -{ - int reversed = (playmode & PLAYMODE_BACKWARD ? TRUE : FALSE); - int bidir = (playmode & PLAYMODE_BIDIR ? TRUE : FALSE); - int loop = (playmode & PLAYMODE_LOOP ? TRUE : FALSE); - - /* update the voice buffers */ - update_voice_buffers(voice, reversed, bidir, loop); -} - - - -/* digi_directsound_lock_voice: - */ -static void *digi_directsound_lock_voice(int voice, int start, int end) -{ - LPDIRECTSOUNDBUFFER ds_locked_buffer; - unsigned long size_a; - void *buf_a; - HRESULT hr; - - /* just in case */ - digi_directsound_unlock_voice(voice); - - if (ds_voices[voice].looping && ds_voices[voice].ds_loop_buffer) - ds_locked_buffer = ds_voices[voice].ds_loop_buffer; - else - ds_locked_buffer = ds_voices[voice].ds_buffer; - - start = start * ds_voices[voice].bytes_per_sample; - end = end * ds_voices[voice].bytes_per_sample; - - hr = IDirectSoundBuffer_Lock(ds_locked_buffer, start, end - start, &buf_a, &size_a, NULL, NULL, 0); - - /* if buffer lost, restore and retry lock */ - if (hr == DSERR_BUFFERLOST) { - IDirectSoundBuffer_Restore(ds_locked_buffer); - - hr = IDirectSoundBuffer_Lock(ds_locked_buffer, start, end - start, &buf_a, &size_a, NULL, NULL, 0); - if (FAILED(hr)) { - _TRACE(PREFIX_E "digi_directsound_lock_voice() failed (%s).\n", ds_err(hr)); - return NULL; - } - } - - ds_voices[voice].ds_locked_buffer = ds_locked_buffer; - ds_voices[voice].lock_buf_a = buf_a; - ds_voices[voice].lock_size_a = size_a; - - return buf_a; -} - - - -/* digi_directsound_unlock_voice: - */ -static void digi_directsound_unlock_voice(int voice) -{ - HRESULT hr; - int lock_bytes; - - if (ds_voices[voice].ds_locked_buffer && ds_voices[voice].lock_buf_a) { - - if (ds_voices[voice].bits == 16) { - unsigned short *p = (unsigned short *)ds_voices[voice].lock_buf_a; - - lock_bytes = ds_voices[voice].lock_size_a >> 1; - - while (lock_bytes--) - *p++ ^= 0x8000; - } - - hr = IDirectSoundBuffer_Unlock(ds_voices[voice].ds_locked_buffer, - ds_voices[voice].lock_buf_a, - ds_voices[voice].lock_size_a, - NULL, - 0); - - if (FAILED(hr)) { - _TRACE(PREFIX_E "digi_directsound_unlock_voice() failed (%s).\n", ds_err(hr)); - } - - ds_voices[voice].ds_locked_buffer = NULL; - ds_voices[voice].lock_buf_a = NULL; - ds_voices[voice].lock_size_a = 0; - } -} - - - -/* digi_directsound_get_position: - */ -static int digi_directsound_get_position(int voice) -{ - HRESULT hr; - unsigned long int play_cursor; - unsigned long int write_cursor; - unsigned long int status; - int pos; - - if (ds_voices[voice].looping && ds_voices[voice].ds_loop_buffer) { - /* is buffer playing? */ - hr = IDirectSoundBuffer_GetStatus(ds_voices[voice].ds_loop_buffer, &status); - if (FAILED(hr) || !(status & DSBSTATUS_PLAYING)) - return -1; - - hr = IDirectSoundBuffer_GetCurrentPosition(ds_voices[voice].ds_loop_buffer, - &play_cursor, &write_cursor); - if (FAILED(hr)) { - _TRACE(PREFIX_E "digi_directsound_get_position() failed (%s).\n", ds_err(hr)); - return -1; - } - - pos = play_cursor / ds_voices[voice].bytes_per_sample; - - /* handle bidir data */ - if (ds_voices[voice].bidir && (pos >= ds_voices[voice].loop_len)) - pos = (ds_voices[voice].loop_len - 1) - (pos - ds_voices[voice].loop_len); - - /* handle reversed data */ - if (ds_voices[voice].reversed) - pos = ds_voices[voice].loop_len - 1 - pos; - - return ds_voices[voice].loop_offset + pos; - } - else if (ds_voices[voice].ds_buffer) { - /* is buffer playing? */ - hr = IDirectSoundBuffer_GetStatus(ds_voices[voice].ds_buffer, &status); - if (FAILED(hr) || !(status & DSBSTATUS_PLAYING)) - return -1; - - hr = IDirectSoundBuffer_GetCurrentPosition(ds_voices[voice].ds_buffer, - &play_cursor, &write_cursor); - if (FAILED(hr)) { - _TRACE(PREFIX_E "digi_directsound_get_position() failed (%s).\n", ds_err(hr)); - return -1; - } - - pos = play_cursor / ds_voices[voice].bytes_per_sample; - - /* handle reversed data */ - if (ds_voices[voice].reversed) - pos = ds_voices[voice].len - 1 - pos; - - return pos; - } - else - return -1; -} - - - -/* digi_directsound_set_position: - */ -static void digi_directsound_set_position(int voice, int position) -{ - HRESULT hr; - int pos; - - if (ds_voices[voice].ds_loop_buffer) { - pos = CLAMP(0, position - ds_voices[voice].loop_offset, ds_voices[voice].loop_len-1); - - /* handle bidir data: todo? */ - - /* handle reversed data */ - if (ds_voices[voice].reversed) - pos = ds_voices[voice].loop_len - 1 - pos; - - hr = IDirectSoundBuffer_SetCurrentPosition(ds_voices[voice].ds_loop_buffer, - pos * ds_voices[voice].bytes_per_sample); - if (FAILED(hr)) { - _TRACE(PREFIX_E "digi_directsound_set_position() failed (%s).\n", ds_err(hr)); - } - } - - if (ds_voices[voice].ds_buffer) { - pos = position; - - /* handle reversed data */ - if (ds_voices[voice].reversed) - pos = ds_voices[voice].len - 1 - pos; - - hr = IDirectSoundBuffer_SetCurrentPosition(ds_voices[voice].ds_buffer, - pos * ds_voices[voice].bytes_per_sample); - if (FAILED(hr)) { - _TRACE(PREFIX_E "digi_directsound_set_position() failed (%s).\n", ds_err(hr)); - } - } -} - - - -/* digi_directsound_get_volume: - */ -static int digi_directsound_get_volume(int voice) -{ - return ds_voices[voice].vol; -} - - - -/* digi_directsound_set_volume: - */ -static void digi_directsound_set_volume(int voice, int volume) -{ - int ds_vol; - - ds_voices[voice].vol = volume; - - if (ds_voices[voice].ds_buffer) { - ds_vol = alleg_to_dsound_volume[CLAMP(0, volume, 255)]; - IDirectSoundBuffer_SetVolume(ds_voices[voice].ds_buffer, ds_vol); - - if (ds_voices[voice].ds_loop_buffer) - IDirectSoundBuffer_SetVolume(ds_voices[voice].ds_loop_buffer, ds_vol); - } -} - - - -/* digi_directsound_get_frequency: - */ -static int digi_directsound_get_frequency(int voice) -{ - return ds_voices[voice].freq; -} - - - -/* digi_directsound_set_frequency: - */ -static void digi_directsound_set_frequency(int voice, int frequency) -{ - ds_voices[voice].freq = frequency; - - if (ds_voices[voice].ds_buffer) { - IDirectSoundBuffer_SetFrequency(ds_voices[voice].ds_buffer, frequency); - - if (ds_voices[voice].ds_loop_buffer) - IDirectSoundBuffer_SetFrequency(ds_voices[voice].ds_loop_buffer, frequency); - } -} - - - -/* digi_directsound_get_pan: - */ -static int digi_directsound_get_pan(int voice) -{ - return ds_voices[voice].pan; -} - - - -/* digi_directsound_set_pan: - */ -static void digi_directsound_set_pan(int voice, int pan) -{ - int ds_pan; - - ds_voices[voice].pan = pan; - - if (ds_voices[voice].ds_buffer) { - ds_pan = alleg_to_dsound_pan[CLAMP(0, pan, 255)]; - IDirectSoundBuffer_SetPan(ds_voices[voice].ds_buffer, ds_pan); - - if (ds_voices[voice].ds_loop_buffer) - IDirectSoundBuffer_SetPan(ds_voices[voice].ds_loop_buffer, ds_pan); - } -} - diff --git a/src/allegro/src/win/wmidi.c b/src/allegro/src/win/wmidi.c deleted file mode 100644 index e066aba96..000000000 --- a/src/allegro/src/win/wmidi.c +++ /dev/null @@ -1,365 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * Windows midi driver. - * - * By Stefan Schimanski. - * - * Midi input added by Daniel Verkamp. - * - * See readme.txt for copyright information. - */ - - -#include "allegro.h" -#include "allegro/internal/aintern.h" -#include "allegro/platform/aintwin.h" - -#ifndef SCAN_DEPEND - #ifdef ALLEGRO_MINGW32 - #undef MAKEFOURCC - #endif - - #include - - #ifdef ALLEGRO_MSVC - #include - #endif -#endif - -#ifndef ALLEGRO_WINDOWS -#error something is wrong with the makefile -#endif - -#define PREFIX_I "al-wmidi INFO: " -#define PREFIX_W "al-wmidi WARNING: " -#define PREFIX_E "al-wmidi ERROR: " - - -int midi_win32_detect(int input); -int midi_win32_init(int input, int voices); -void midi_win32_exit(int input); -int midi_win32_set_mixer_volume(int volume); -int midi_win32_get_mixer_volume(void); -void midi_win32_raw_midi(int data); - -int midi_win32_in_detect(int input); -int midi_win32_in_init(int input, int voices); -void midi_win32_in_exit(int input); -static void CALLBACK midi_in_proc(HMIDIIN, UINT, DWORD, DWORD, DWORD); - - -/* driver globals */ -static HMIDIOUT midi_device = NULL; -static HMIDIIN midi_in_device = NULL; - - -/* dynamically generated driver list */ -static _DRIVER_INFO *driver_list = NULL; - - -/* MIDI recording callback */ -static void CALLBACK midi_in_proc(HMIDIIN hMidiIn, UINT wMsg, DWORD dwInstance, - DWORD dwParam1, DWORD dwParam2) -{ - if ((midi_in_device == NULL) || (midi_recorder == NULL)) return; - midi_recorder((unsigned char)(dwParam1 & 0xff)); /* status byte */ - midi_recorder((unsigned char)((dwParam1 >> 8) & 0xff)); /* data byte 1 */ - midi_recorder((unsigned char)((dwParam1 >> 16) & 0xff)); /* data byte 2 */ -} - - -/* _get_win_midi_driver_list: - * System driver hook for listing the available MIDI drivers. This generates - * the device list at runtime, to match whatever Windows devices are - * available. - */ -_DRIVER_INFO *_get_win_midi_driver_list(void) -{ - MIDI_DRIVER *driver; - MIDIOUTCAPS caps; - MIDIINCAPS caps_in; - int num_drivers, i; - - if (!driver_list) { - num_drivers = midiOutGetNumDevs(); - - /* include the MIDI mapper (id == -1) */ - if (num_drivers) - num_drivers++; - - driver_list = _create_driver_list(); - - /* MidiOut drivers */ - for (i=0; iid = MIDI_WIN32MAPPER; - else - driver->id = MIDI_WIN32(i-1); - - midiOutGetDevCaps(i-1, &caps, sizeof(caps)); - - driver->ascii_name = strdup(caps.szPname); - - driver->detect = midi_win32_detect; - driver->init = midi_win32_init; - driver->exit = midi_win32_exit; - driver->set_mixer_volume = midi_win32_set_mixer_volume; - driver->get_mixer_volume = midi_win32_get_mixer_volume; - driver->raw_midi = midi_win32_raw_midi; - - _driver_list_append_driver(&driver_list, driver->id, driver, TRUE); - } - - /* MidiIn drivers */ - num_drivers = midiInGetNumDevs(); - for (i=0; iid = MIDI_WIN32_IN(i); /* added MIDI_WIN32_IN to alwin.h */ - - midiInGetDevCaps(i, &caps_in, sizeof(caps_in)); - - driver->ascii_name = strdup(caps_in.szPname); - - driver->detect = midi_win32_in_detect; - driver->init = midi_win32_in_init; - driver->exit = midi_win32_in_exit; - - _driver_list_append_driver(&driver_list, driver->id, driver, TRUE); - } - - /* cross-platform DIGital MIDi driver */ - _driver_list_append_driver(&driver_list, MIDI_DIGMID, &midi_digmid, TRUE); - } - - return driver_list; -} - - - -/* _free_win_midi_driver_list: - * Helper function for freeing the dynamically generated driver list. - */ -void _free_win_midi_driver_list(void) -{ - int i = 0; - - if (driver_list) { - while (driver_list[i].driver) { - if (driver_list[i].id != MIDI_DIGMID) { - _AL_FREE((char*)((MIDI_DRIVER*)driver_list[i].driver)->ascii_name); - _AL_FREE(driver_list[i].driver); - } - i++; - } - - _destroy_driver_list(driver_list); - driver_list = NULL; - } -} - - - -/* midi_win32_detect: - */ -int midi_win32_detect(int input) -{ - /* the input drivers are separate from the output drivers */ - if (input) - return FALSE; - - return TRUE; -} - - - -/* midi_win32_in_detect: - */ -int midi_win32_in_detect(int input) -{ - if (input) - return TRUE; - - return FALSE; -} - - - -/* midi_win32_init: - */ -int midi_win32_init(int input, int voices) -{ - MMRESULT hr; - int id; - - /* deduce our device number from the driver ID code */ - if ((midi_driver->id & 0xFF) == 'M') - /* we are using the midi mapper (driver id is WIN32M) */ - id = MIDI_MAPPER; - else - /* actual driver */ - id = (midi_driver->id & 0xFF) - 'A'; - - /* open midi mapper */ - hr = midiOutOpen(&midi_device, id, 0, 0, CALLBACK_NULL); - if (hr != MMSYSERR_NOERROR) { - _TRACE(PREFIX_E "midiOutOpen failed (%x)\n", hr); - goto Error; - } - - /* resets midi mapper */ - midiOutReset(midi_device); - - return 0; - - Error: - midi_win32_exit(input); - return -1; -} - - - -/* midi_win32_in_init: - */ -int midi_win32_in_init(int input, int voices) -{ - MMRESULT hr; - int id; - - /* deduce our device number from the driver ID code */ - id = (midi_input_driver->id & 0xFF) - 'A'; - - /* open midi input device */ - hr = midiInOpen(&midi_in_device, id, (DWORD)midi_in_proc, - (DWORD)NULL, CALLBACK_FUNCTION); - if (hr != MMSYSERR_NOERROR) { - _TRACE(PREFIX_E "midiInOpen failed (%x)\n", hr); - midi_win32_in_exit(input); - return -1; - } - - - midiInReset(midi_in_device); - midiInStart(midi_in_device); - - return 0; -} - - - -/* midi_win32_exit: - */ -void midi_win32_exit(int input) -{ - /* close midi stream and release device */ - if (midi_device != NULL) { - midiOutReset(midi_device); - - midiOutClose(midi_device); - midi_device = NULL; - } -} - - - -/* midi_win32_in_exit: - */ -void midi_win32_in_exit(int input) -{ - if (midi_in_device != NULL) { - midiInStop(midi_in_device); - midiInReset(midi_in_device); - midiInClose(midi_in_device); - midi_in_device = NULL; - } -} - - - -/* midi_win32_set_mixer_volume: - */ -int midi_win32_set_mixer_volume(int volume) -{ - unsigned long win32_midi_vol = (volume << 8) + (volume << 24); - midiOutSetVolume(midi_device, win32_midi_vol); - return 1; -} - - - -/* midi_win32_get_mixer_volume: - */ -int midi_win32_get_mixer_volume(void) -{ - DWORD vol; - - if (!midi_device) - return -1; - - if (midiOutGetVolume(midi_device, &vol) != MMSYSERR_NOERROR) - return -1; - - vol &= 0xffff; - return vol / (0xffff / 255); -} - - - -/* midi_switch_out: - */ -void midi_switch_out(void) -{ - if (midi_device) - midiOutReset(midi_device); -} - - -/* midi_win32_raw_midi: - */ -void midi_win32_raw_midi(int data) -{ - static int msg_lengths[8] = - {3, 3, 3, 3, 2, 2, 3, 0}; - static unsigned long midi_msg; - static int midi_msg_len; - static int midi_msg_pos; - - if (data >= 0x80) { - midi_msg_len = msg_lengths[(data >> 4) & 0x07]; - midi_msg = 0; - midi_msg_pos = 0; - } - - if (midi_msg_len > 0) { - midi_msg |= ((unsigned long)data) << (midi_msg_pos * 8); - midi_msg_pos++; - - if (midi_msg_pos == midi_msg_len) { - if (midi_device != NULL) { - switch (get_display_switch_mode()) { - case SWITCH_AMNESIA: - case SWITCH_PAUSE: - if (_win_app_foreground) - midiOutShortMsg(midi_device, midi_msg); - else - midiOutReset(midi_device); - break; - default: - midiOutShortMsg(midi_device, midi_msg); - } - } - } - } -} diff --git a/src/allegro/src/win/wsnddrv.c b/src/allegro/src/win/wsnddrv.c deleted file mode 100644 index 1963b55f4..000000000 --- a/src/allegro/src/win/wsnddrv.c +++ /dev/null @@ -1,35 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * List of Windows sound drivers, kept in a seperate file so that - * they can be overriden by user programs. - * - * By Shawn Hargreaves. - * - * See readme.txt for copyright information. - */ - - -#include "allegro.h" - -#ifndef ALLEGRO_WINDOWS -#error something is wrong with the makefile -#endif - - - -BEGIN_DIGI_DRIVER_LIST -/* nothing here: the driver list is dynamically generated */ -END_DIGI_DRIVER_LIST - - -BEGIN_MIDI_DRIVER_LIST -/* nothing here: the driver list is dynamically generated */ -END_MIDI_DRIVER_LIST diff --git a/src/allegro/src/win/wsndwo.c b/src/allegro/src/win/wsndwo.c deleted file mode 100644 index 80096f3b9..000000000 --- a/src/allegro/src/win/wsndwo.c +++ /dev/null @@ -1,402 +0,0 @@ -/* ______ ___ ___ - * /\ _ \ /\_ \ /\_ \ - * \ \ \L\ \\//\ \ \//\ \ __ __ _ __ ___ - * \ \ __ \ \ \ \ \ \ \ /'__`\ /'_ `\/\`'__\/ __`\ - * \ \ \/\ \ \_\ \_ \_\ \_/\ __//\ \L\ \ \ \//\ \L\ \ - * \ \_\ \_\/\____\/\____\ \____\ \____ \ \_\\ \____/ - * \/_/\/_/\/____/\/____/\/____/\/___L\ \/_/ \/___/ - * /\____/ - * \_/__/ - * - * Allegro mixer to WaveOut driver. - * - * By Robin Burrows. - * - * Based on original src/unix/uoss.c by Joshua Heyer. - * - * See readme.txt for copyright information. - */ - - -#include "allegro.h" -#include "allegro/internal/aintern.h" -#include "allegro/platform/aintwin.h" - -#ifndef SCAN_DEPEND - #ifdef ALLEGRO_MINGW32 - #undef MAKEFOURCC - #endif - - #include - #include - - #ifdef ALLEGRO_MSVC - #include - #endif -#endif - -#ifndef ALLEGRO_WINDOWS -#error something is wrong with the makefile -#endif - -#define PREFIX_I "al-wsnd INFO: " -#define PREFIX_W "al-wsnd WARNING: " -#define PREFIX_E "al-wsnd ERROR: " - - -static int digi_waveout_detect(int input); -static int digi_waveout_init(int input, int voices); -static void digi_waveout_exit(int input); -static int digi_waveout_set_mixer_volume(int volume); -static int digi_waveout_get_mixer_volume(void); -static int digi_waveout_buffer_size(void); - - -/* template driver: will be cloned for each device */ -static DIGI_DRIVER digi_waveout = -{ - 0, - empty_string, - empty_string, - empty_string, - 0, // available voices - 0, // voice number offset - MIXER_MAX_SFX, // maximum voices we can support - MIXER_DEF_SFX, // default number of voices to use - - /* setup routines */ - digi_waveout_detect, - digi_waveout_init, - digi_waveout_exit, - digi_waveout_set_mixer_volume, - digi_waveout_get_mixer_volume, - - /* audiostream locking functions */ - NULL, // AL_METHOD(void *, lock_voice, (int voice, int start, int end)); - NULL, // AL_METHOD(void, unlock_voice, (int voice)); - digi_waveout_buffer_size, - - /* voice control functions */ - _mixer_init_voice, - _mixer_release_voice, - _mixer_start_voice, - _mixer_stop_voice, - _mixer_loop_voice, - - /* position control functions */ - _mixer_get_position, - _mixer_set_position, - - /* volume control functions */ - _mixer_get_volume, - _mixer_set_volume, - _mixer_ramp_volume, - _mixer_stop_volume_ramp, - - /* pitch control functions */ - _mixer_get_frequency, - _mixer_set_frequency, - _mixer_sweep_frequency, - _mixer_stop_frequency_sweep, - - /* pan control functions */ - _mixer_get_pan, - _mixer_set_pan, - _mixer_sweep_pan, - _mixer_stop_pan_sweep, - - /* effect control functions */ - _mixer_set_echo, - _mixer_set_tremolo, - _mixer_set_vibrato, - - /* input functions */ - 0, // int rec_cap_bits; - 0, // int rec_cap_stereo; - NULL, // AL_METHOD(int, rec_cap_rate, (int bits, int stereo)); - NULL, // AL_METHOD(int, rec_cap_parm, (int rate, int bits, int stereo)); - NULL, // AL_METHOD(int, rec_source, (int source)); - NULL, // AL_METHOD(int, rec_start, (int rate, int bits, int stereo)); - NULL, // AL_METHOD(void, rec_stop, (void)); - NULL // AL_METHOD(int, rec_read, (void *buf)); -}; - - -/* sound driver globals */ -static HWAVEOUT hWaveOut = NULL; -static LPWAVEHDR lpWaveHdr = NULL; -static unsigned long int initial_volume; -static int digiwobufsize, digiwobufdivs, digiwobufpos; -static char * digiwobufdata = NULL; -static int _freq, _bits, _stereo; -static int waveout_paused = FALSE; - - - -/* _get_woalmix_driver: - * System driver hook for listing the available sound drivers. This - * generates the device list at runtime, to match whatever WaveOut - * devices are available. - */ -DIGI_DRIVER *_get_woalmix_driver(int num) -{ - DIGI_DRIVER *driver; - - driver = _AL_MALLOC(sizeof(DIGI_DRIVER)); - if (!driver) - return NULL; - - memcpy(driver, &digi_waveout, sizeof(DIGI_DRIVER)); - - driver->id = DIGI_WAVOUTID(num); - - if (num == 0) - driver->ascii_name = "WaveOut 44100hz 16bit stereo"; - else - driver->ascii_name = "WaveOut 22050hz 8bit mono"; - - return driver; -} - - - -/* digi_waveout_mixer_callback: - * Callback function to update sound in WaveOut buffer. - */ -static void digi_waveout_mixer_callback(void) -{ - MMTIME mmt; - MMRESULT mmr; - int writecurs; - int switch_mode; - - /* handle display switchs */ - switch_mode = get_display_switch_mode(); - - if (waveout_paused) { - if (_win_app_foreground || - (switch_mode == SWITCH_BACKGROUND) || (switch_mode == SWITCH_BACKAMNESIA)) { - waveout_paused = FALSE; - waveOutRestart(hWaveOut); - } - else - return; - } - else { - if (!_win_app_foreground && - ((switch_mode == SWITCH_PAUSE) || (switch_mode == SWITCH_AMNESIA))) { - waveout_paused = TRUE; - waveOutPause(hWaveOut); - return; - } - } - - /* get current state of buffer */ - memset(&mmt, 0, sizeof(MMTIME)); - mmt.wType = TIME_BYTES; - - mmr = waveOutGetPosition(hWaveOut, &mmt, sizeof(MMTIME)); - if (mmr != MMSYSERR_NOERROR) - return; - - writecurs = (int) mmt.u.cb; - - writecurs /= (digiwobufsize/digiwobufdivs); - writecurs += 8; - - while (writecurs > (digiwobufdivs-1)) - writecurs -= digiwobufdivs; - - /* write data into the buffer */ - while (writecurs != digiwobufpos) { - if (++digiwobufpos > (digiwobufdivs-1)) - digiwobufpos = 0; - - _mix_some_samples((unsigned long) (digiwobufdata+((digiwobufsize/digiwobufdivs)*digiwobufpos)), 0, TRUE); - } -} - - - -/* digi_waveout_detect: - */ -static int digi_waveout_detect(int input) -{ - if (input) - return 0; - - /* always present */ - return 1; -} - - - -/* digi_waveout_init: - */ -static int digi_waveout_init(int input, int voices) -{ - MMRESULT mmr; - WAVEFORMATEX format; - int id; - - if (input) { - ustrzcpy(allegro_error, ALLEGRO_ERROR_SIZE, get_config_text("Input is not supported")); - return -1; - } - - /* deduce our device number from the driver ID code */ - id = ((digi_driver->id >> 8) & 0xFF) - 'A'; - - digi_driver->voices = voices; - - /* get hardware capabilities */ - digiwobufdivs = 32; - digiwobufpos = 0; - - if (id == 0) { - _bits = 16; - _freq = 44100; - _stereo = 1; - digiwobufsize = digiwobufdivs * 1024; - } - else { - _bits = 8; - _freq = 22050; - _stereo = 0; - digiwobufsize = digiwobufdivs * 512; - } - - digiwobufdata = _AL_MALLOC_ATOMIC(digiwobufsize); - if (!digiwobufdata) { - _TRACE (PREFIX_E "_AL_MALLOC_ATOMIC() failed\n"); - goto Error; - } - - format.wFormatTag = WAVE_FORMAT_PCM; - format.nChannels = _stereo ? 2 : 1; - format.nSamplesPerSec = _freq; - format.wBitsPerSample = _bits; - format.nBlockAlign = (format.wBitsPerSample * format.nChannels) >> 3; - format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign; - - mmr = waveOutOpen(&hWaveOut, WAVE_MAPPER, &format, 0, 0, CALLBACK_NULL); - if (mmr != MMSYSERR_NOERROR) { - _TRACE (PREFIX_E "Can't open WaveOut\n"); - goto Error; - } - - lpWaveHdr = _AL_MALLOC(sizeof(WAVEHDR)); - lpWaveHdr->lpData = digiwobufdata; - lpWaveHdr->dwBufferLength = digiwobufsize; - lpWaveHdr->dwFlags = WHDR_BEGINLOOP | WHDR_ENDLOOP; - lpWaveHdr->dwLoops = 0x7fffffffL; - - mmr = waveOutPrepareHeader(hWaveOut, lpWaveHdr, sizeof(WAVEHDR)); - if (mmr != MMSYSERR_NOERROR) { - _TRACE (PREFIX_E "waveOutPrepareHeader() failed\n"); - goto Error; - } - - mmr = waveOutWrite(hWaveOut, lpWaveHdr, sizeof(WAVEHDR)); - if (mmr != MMSYSERR_NOERROR) { - _TRACE (PREFIX_E "waveOutWrite() failed\n" ); - goto Error; - } - - if (_mixer_init((digiwobufsize / (_bits /8)) / digiwobufdivs, _freq, - _stereo, ((_bits == 16) ? 1 : 0), &digi_driver->voices) != 0) { - _TRACE(PREFIX_E "Can't init software mixer\n"); - goto Error; - } - - _mix_some_samples((unsigned long) digiwobufdata, 0, TRUE); - - /* get volume */ - waveOutGetVolume(hWaveOut, &initial_volume); - - /* start playing */ - install_int(digi_waveout_mixer_callback, 20); /* 50 Hz */ - - return 0; - - Error: - _TRACE(PREFIX_E "digi_waveout_init() failed\n"); - digi_waveout_exit(0); - return -1; -} - - - -/* digi_waveout_exit: - */ -static void digi_waveout_exit(int input) -{ - /* stop playing */ - remove_int(digi_waveout_mixer_callback); - - if (hWaveOut) { - waveOutReset(hWaveOut); - - /* restore initial volume */ - waveOutSetVolume(hWaveOut, initial_volume); - - waveOutUnprepareHeader(hWaveOut, lpWaveHdr, sizeof(WAVEHDR)); - waveOutClose(hWaveOut); - hWaveOut = NULL; - } - - if (lpWaveHdr) { - _AL_FREE(lpWaveHdr); - lpWaveHdr = NULL; - } - - if (digiwobufdata) { - _AL_FREE(digiwobufdata); - digiwobufdata = NULL; - } -} - - - -/* digi_waveout_set_mixer_volume: - */ -static int digi_waveout_set_mixer_volume(int volume) -{ - DWORD realvol; - - if (hWaveOut) { - realvol = (DWORD) volume; - realvol |= realvol<<8; - realvol |= realvol<<16; - waveOutSetVolume(hWaveOut, realvol); - } - - return 0; -} - - - -/* digi_waveout_get_mixer_volume: - */ -static int digi_waveout_get_mixer_volume(void) -{ - DWORD vol; - - if (!hWaveOut) - return -1; - - if (waveOutGetVolume(hWaveOut, &vol) != MMSYSERR_NOERROR) - return -1; - - vol &= 0xffff; - return vol / (0xffff / 255); -} - - - -/* digi_waveout_buffer_size: - */ -static int digi_waveout_buffer_size(void) -{ - return digiwobufsize / (_bits / 8) / (_stereo ? 2 : 1); -} diff --git a/src/allegro/src/win/wsystem.c b/src/allegro/src/win/wsystem.c index a3008386d..f9e976f58 100644 --- a/src/allegro/src/win/wsystem.c +++ b/src/allegro/src/win/wsystem.c @@ -91,8 +91,6 @@ SYSTEM_DRIVER system_directx = sys_directx_lock_mutex, sys_directx_unlock_mutex, NULL, /* AL_METHOD(_DRIVER_INFO *, gfx_drivers, (void)); */ - _get_win_digi_driver_list, /* AL_METHOD(_DRIVER_INFO *, digi_drivers, (void)); */ - _get_win_midi_driver_list, /* AL_METHOD(_DRIVER_INFO *, midi_drivers, (void)); */ NULL, /* AL_METHOD(_DRIVER_INFO *, keyboard_drivers, (void)); */ NULL, /* AL_METHOD(_DRIVER_INFO *, mouse_drivers, (void)); */ NULL /* AL_METHOD(_DRIVER_INFO *, timer_drivers, (void)); */ @@ -214,10 +212,6 @@ static int sys_directx_init(void) */ static void sys_directx_exit(void) { - /* free allocated resources */ - _free_win_digi_driver_list(); - _free_win_midi_driver_list(); - /* unhook or close window */ exit_directx_window(); diff --git a/src/allegro/src/win/wwnd.c b/src/allegro/src/win/wwnd.c index eb1aafb9d..d421e9e43 100644 --- a/src/allegro/src/win/wwnd.c +++ b/src/allegro/src/win/wwnd.c @@ -76,12 +76,6 @@ static UINT msg_suicide = 0; struct WINDOW_MODULES { int keyboard; int mouse; - int sound; - int digi_card; - int midi_card; - int sound_input; - int digi_input_card; - int midi_input_card; }; /* Used in adjust_window(). */ @@ -107,12 +101,6 @@ static int init_window_modules(struct WINDOW_MODULES *wm) if (wm->mouse) install_mouse(); - if (wm->sound) - install_sound(wm->digi_card, wm->midi_card, NULL); - - if (wm->sound_input) - install_sound_input(wm->digi_input_card, wm->midi_input_card); - return 0; } @@ -122,8 +110,6 @@ static int init_window_modules(struct WINDOW_MODULES *wm) * Removes the modules that depend upon the main window: * - keyboard (DirectInput), * - mouse (DirectInput), - * - sound (DirectSound), - * - sound input (DirectSoundCapture). * If WM is not NULL, record which modules are really removed. */ static void exit_window_modules(struct WINDOW_MODULES *wm) @@ -144,26 +130,6 @@ static void exit_window_modules(struct WINDOW_MODULES *wm) remove_mouse(); } - - if (_sound_installed) { - if (wm) { - wm->sound = TRUE; - wm->digi_card = digi_card; - wm->midi_card = midi_card; - } - - remove_sound(); - } - - if (_sound_input_installed) { - if (wm) { - wm->sound_input = TRUE; - wm->digi_input_card = digi_input_card; - wm->midi_input_card = midi_input_card; - } - - remove_sound_input(); - } } diff --git a/src/allegro/src/x/xsystem.c b/src/allegro/src/x/xsystem.c index a362135bd..ada601977 100644 --- a/src/allegro/src/x/xsystem.c +++ b/src/allegro/src/x/xsystem.c @@ -45,8 +45,6 @@ static int _xwin_sysdrv_desktop_color_depth(void); static int _xwin_sysdrv_get_desktop_resolution(int *width, int *height); static void _xwin_sysdrv_get_gfx_safe_mode(int *driver, struct GFX_MODE *mode); static _DRIVER_INFO *_xwin_sysdrv_gfx_drivers(void); -static _DRIVER_INFO *_xwin_sysdrv_digi_drivers(void); -static _DRIVER_INFO *_xwin_sysdrv_midi_drivers(void); static _DRIVER_INFO *_xwin_sysdrv_keyboard_drivers(void); static _DRIVER_INFO *_xwin_sysdrv_mouse_drivers(void); static _DRIVER_INFO *_xwin_sysdrv_timer_drivers(void); @@ -95,8 +93,6 @@ SYSTEM_DRIVER system_xwin = NULL, /* unlock_mutex */ #endif _xwin_sysdrv_gfx_drivers, - _xwin_sysdrv_digi_drivers, - _xwin_sysdrv_midi_drivers, _xwin_sysdrv_keyboard_drivers, _xwin_sysdrv_mouse_drivers, _xwin_sysdrv_timer_drivers @@ -343,26 +339,6 @@ static _DRIVER_INFO *_xwin_sysdrv_gfx_drivers(void) -/* _xwin_sysdrv_digi_drivers: - * Get the list of digital sound drivers. - */ -static _DRIVER_INFO *_xwin_sysdrv_digi_drivers(void) -{ - return _unix_digi_driver_list; -} - - - -/* _xwin_sysdrv_midi_drivers: - * Get the list of MIDI drivers. - */ -static _DRIVER_INFO *_xwin_sysdrv_midi_drivers(void) -{ - return _unix_midi_driver_list; -} - - - /* _xwin_sysdrv_keyboard_drivers: * Get the list of keyboard drivers. */