Remove sound/digi/midi/sample related stuff from Allegro code.

This commit is contained in:
David Capello 2010-10-17 11:10:18 -07:00
parent 1b4ce4cf9b
commit f9aa176c09
49 changed files with 1 additions and 16003 deletions

View File

@ -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

View File

@ -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"

View File

@ -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',' ')

View File

@ -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 */

View File

@ -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));

View File

@ -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 */

View File

@ -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
}

View File

@ -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);

View File

@ -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

View File

@ -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 ************/
/************************************/

View File

@ -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))

View File

@ -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 */

View File

@ -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 */

View File

@ -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));

View File

@ -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
};

View File

@ -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; c<MIDI_TRACKS; c++) {
m->track[c].len = 0;
m->track[c].data = NULL;
}
m->divisions = pack_mgetw(f);
for (c=0; c<MIDI_TRACKS; c++) {
m->track[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; c<MIDI_TRACKS; c++) {
if (m->track[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; c<MIDI_TRACKS; c++) {
if (m->track[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; c2<MIDI_TRACKS; c2++) {
if (m->track[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);

File diff suppressed because it is too large Load Diff

View File

@ -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);
}

View File

@ -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;
}
}

View File

@ -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

View File

@ -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(&note_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, &note_request.tone);
result |= NANewNoteChannel(note_allocator, &note_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;
}
}

View File

@ -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);
}

View File

@ -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)); */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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 <string.h>
#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

File diff suppressed because it is too large Load Diff

View File

@ -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);
}

View File

@ -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 <string.h>
#include <sys/asoundlib.h>
#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(&params, 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, &params) < 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

View File

@ -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 <string.h>
#define ALSA_PCM_NEW_HW_PARAMS_API 1
#include <alsa/asoundlib.h>
#include <math.h>
#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

View File

@ -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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#if ALLEGRO_ALSA_VERSION == 9
#define ALSA_PCM_NEW_HW_PARAMS_API 1
#include <alsa/asoundlib.h>
#else /* ALLEGRO_ALSA_VERSION == 5 */
#include <sys/asoundlib.h>
#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 */

View File

@ -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 <artsc.h>
#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

View File

@ -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 <jack/jack.h>
#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

View File

@ -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 <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <dmedia/audio.h>
#ifdef ALLEGRO_HAVE_LIBPTHREAD
#include <pthread.h>
#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

View File

@ -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);
}

View File

@ -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 <sys/time.h>
#include <sys/types.h>
#include <string.h>
#include <unistd.h>
#include <esd.h>
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

View File

@ -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 <stdlib.h>
#include <stdio.h>
#include <limits.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#if defined(ALLEGRO_HAVE_SOUNDCARD_H)
#include <soundcard.h>
#elif defined(ALLEGRO_HAVE_SYS_SOUNDCARD_H)
#include <sys/soundcard.h>
#elif defined(ALLEGRO_HAVE_MACHINE_SOUNDCARD_H)
#include <machine/soundcard.h>
#elif defined(ALLEGRO_HAVE_LINUX_SOUNDCARD_H)
#include <linux/soundcard.h>
#endif
#include <sys/ioctl.h>
#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

View File

@ -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 <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#if defined(ALLEGRO_HAVE_SOUNDCARD_H)
#include <soundcard.h>
#elif defined(ALLEGRO_HAVE_SYS_SOUNDCARD_H)
#include <sys/soundcard.h>
#elif defined(ALLEGRO_HAVE_MACHINE_SOUNDCARD_H)
#include <machine/soundcard.h>
#elif defined(ALLEGRO_HAVE_LINUX_SOUNDCARD_H)
#include <linux/soundcard.h>
#endif
#include <sys/ioctl.h>
#if defined(ALLEGRO_HAVE_LINUX_AWE_VOICE_H)
#include <linux/awe_voice.h>
#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

View File

@ -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

View File

@ -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();

View File

@ -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 <mmsystem.h>
#include <dsound.h>
#include <math.h>
#ifdef ALLEGRO_MSVC
#include <mmreg.h>
#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;
}

View File

@ -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 <mmsystem.h>
#include <dsound.h>
#include <math.h>
#ifdef ALLEGRO_MSVC
#include <mmreg.h>
#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);
}

File diff suppressed because it is too large Load Diff

View File

@ -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 <mmsystem.h>
#ifdef ALLEGRO_MSVC
#include <mmreg.h>
#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; i<num_drivers; i++) {
driver = _AL_MALLOC(sizeof(MIDI_DRIVER));
memcpy(driver, &_midi_none, sizeof(MIDI_DRIVER));
if (i == 0)
driver->id = 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; i<num_drivers; i++) {
driver = _AL_MALLOC(sizeof(MIDI_DRIVER));
memcpy(driver, &_midi_none, sizeof(MIDI_DRIVER));
driver->id = 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);
}
}
}
}
}

View File

@ -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

View File

@ -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 <mmsystem.h>
#include <math.h>
#ifdef ALLEGRO_MSVC
#include <mmreg.h>
#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);
}

View File

@ -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();

View File

@ -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();
}
}

View File

@ -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.
*/