diff options
author | Thomas Grill <xovo@users.sourceforge.net> | 2003-09-23 00:21:28 +0000 |
---|---|---|
committer | Thomas Grill <xovo@users.sourceforge.net> | 2003-09-23 00:21:28 +0000 |
commit | 64fdb009695828b788fce074135b20a5e52c5fc4 (patch) | |
tree | a05144197dd339721b6d4a3a0927f7596e8872b6 /pd/src/s_audio.c | |
parent | a30193fcd726552364de74984b200be2c30723e7 (diff) |
imported version 0.37-0
svn path=/trunk/; revision=1016
Diffstat (limited to 'pd/src/s_audio.c')
-rw-r--r-- | pd/src/s_audio.c | 603 |
1 files changed, 528 insertions, 75 deletions
diff --git a/pd/src/s_audio.c b/pd/src/s_audio.c index ca5e34c6..23c2197e 100644 --- a/pd/src/s_audio.c +++ b/pd/src/s_audio.c @@ -6,7 +6,6 @@ audio settings from argparse routine and from dialog window. */ - #include "m_pd.h" #include "s_stuff.h" #include <stdio.h> @@ -27,12 +26,11 @@ typedef long t_pa_sample; #define SYS_BYTESPERCHAN (DEFDACBLKSIZE * SYS_SAMPLEWIDTH) #define SYS_XFERSAMPS (SYS_DEFAULTCH*DEFDACBLKSIZE) #define SYS_XFERSIZE (SYS_SAMPLEWIDTH * SYS_XFERSAMPS) -#define MAXAUDIODEV 4 int sys_inchannels; int sys_outchannels; int sys_advance_samples; /* scheduler advance in samples */ -int sys_blocksize = 256; /* audio I/O block size in sample frames */ +int sys_blocksize = 0; /* audio I/O block size in sample frames */ int sys_audioapi = API_DEFAULT; static int sys_meters; /* true if we're metering */ @@ -40,24 +38,94 @@ static float sys_inmax; /* max input amplitude */ static float sys_outmax; /* max output amplitude */ /* exported variables */ -#ifdef MSW -#define DEFAULTADVANCE 70000 -#else -#define DEFAULTADVANCE 50000 -#endif -int sys_schedadvance = DEFAULTADVANCE; /* scheduler advance in microseconds */ +int sys_schedadvance; /* scheduler advance in microseconds */ float sys_dacsr; int sys_hipriority = 0; t_sample *sys_soundout; t_sample *sys_soundin; + /* the "state" is normally one if we're open and zero otherwise; + but if the state is one, we still haven't necessarily opened the + audio hardware; see audio_isopen() below. */ +static int audio_state; + + /* last requested parameters */ +static int audio_naudioindev; +static int audio_audioindev[MAXAUDIOINDEV]; +static int audio_audiochindev[MAXAUDIOINDEV]; +static int audio_naudiooutdev; +static int audio_audiooutdev[MAXAUDIOOUTDEV]; +static int audio_audiochoutdev[MAXAUDIOOUTDEV]; +static int audio_rate; +static int audio_advance; + +static int audio_isopen(void) +{ + return (audio_state && + ((audio_naudioindev > 0 && audio_audiochindev[0] > 0) + || (audio_naudiooutdev > 0 && audio_audiochoutdev[0] > 0))); +} + +static void sys_get_audio_params( + int *pnaudioindev, int *paudioindev, int *chindev, + int *pnaudiooutdev, int *paudiooutdev, int *choutdev, + int *prate, int *padvance) +{ + int i; + *pnaudioindev = audio_naudioindev; + for (i = 0; i < MAXAUDIOINDEV; i++) + paudioindev[i] = audio_audioindev[i], + chindev[i] = audio_audiochindev[i]; + *pnaudiooutdev = audio_naudiooutdev; + for (i = 0; i < MAXAUDIOOUTDEV; i++) + paudiooutdev[i] = audio_audiooutdev[i], + choutdev[i] = audio_audiochoutdev[i]; + *prate = audio_rate; + *padvance = audio_advance; +} + +static void sys_save_audio_params( + int naudioindev, int *audioindev, int *chindev, + int naudiooutdev, int *audiooutdev, int *choutdev, + int rate, int advance) +{ + int i; + audio_naudioindev = naudioindev; + for (i = 0; i < MAXAUDIOINDEV; i++) + audio_audioindev[i] = audioindev[i], + audio_audiochindev[i] = chindev[i]; + audio_naudiooutdev = naudiooutdev; + for (i = 0; i < MAXAUDIOOUTDEV; i++) + audio_audiooutdev[i] = audiooutdev[i], + audio_audiochoutdev[i] = choutdev[i]; + audio_rate = rate; + audio_advance = advance; +} + + /* init routines for any API which needs to set stuff up before + any other API gets used. This is only true of OSS so far. */ +#ifdef USEAPI_OSS +void oss_init(void); +#endif + +static void audio_init( void) +{ + static int initted = 0; + if (initted) + return; + initted = 1; +#ifdef USEAPI_OSS + oss_init(); +#endif +} + /* set channels and sample rate. */ static void sys_setchsr(int chin, int chout, int sr) { int nblk; - int inbytes = chin * (DEFDACBLKSIZE*sizeof(float)); - int outbytes = chout * (DEFDACBLKSIZE*sizeof(float)); + int inbytes = (chin ? chin : 2) * (DEFDACBLKSIZE*sizeof(float)); + int outbytes = (chout ? chout : 2) * (DEFDACBLKSIZE*sizeof(float)); sys_inchannels = chin; sys_outchannels = chout; @@ -79,49 +147,32 @@ static void sys_setchsr(int chin, int chout, int sr) if (sys_verbose) post("input channels = %d, output channels = %d", sys_inchannels, sys_outchannels); + canvas_resume_dsp(canvas_suspend_dsp()); } /* ----------------------- public routines ----------------------- */ -#if 0 -void sys_open_audio(int naudioindev, int *audioindev, int nchindev, - int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev, - int *choutdev, int rate) /* IOhannes */ -{ - int inchans= - (nchindev > 0 ? chindev[0] : (nchindev == 0 ? 0 : SYS_DEFAULTCH)); - int outchans= - (nchoutdev > 0 ? choutdev[0] : (nchoutdev == 0 ? 0 : SYS_DEFAULTCH)); - int soundindev = (naudioindev <= 0 ? -1 : (audioindev[0]-1)); - int soundoutdev = (naudiooutdev <= 0 ? -1 : (audiooutdev[0]-1)); - int sounddev = (inchans > 0 ? soundindev : soundoutdev); - if (naudioindev > 1 || nchindev > 1 || naudiooutdev > 1 || nchoutdev > 1) - post("sorry, only one portaudio device can be open at once.\n"); - /* post("nindev %d, noutdev %d", naudioindev, naudiooutdev); - post("soundindev %d, soundoutdev %d", soundindev, soundoutdev); */ - if (sys_verbose) - post("channels in %d, out %d", inchans, outchans); - if (rate < 1) - rate = SYS_DEFAULTSRATE; - sys_setchsr(inchans, outchans, rate); - pa_open_audio(inchans, outchans, rate, sys_soundin, sys_soundout, - sys_blocksize, sys_advance_samples/sys_blocksize, - soundindev, soundoutdev); -} -#endif + /* open audio devices (after cleaning up the specified device and channel + vectors). The audio devices are "zero based" (i.e. "0" means the first + one.) We also save the cleaned-up device specification so that we + can later re-open audio and/or show the settings on a dialog window. */ void sys_open_audio(int naudioindev, int *audioindev, int nchindev, int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev, - int *choutdev, int rate) /* IOhannes */ + int *choutdev, int rate, int advance, int enable) { int i, *ip; int defaultchannels = SYS_DEFAULTCH; int inchans, outchans; if (rate < 1) rate = SYS_DEFAULTSRATE; - + audio_init(); + /* Since the channel vector might be longer than the + audio device vector, or vice versa, we fill the shorter one + in to match the longer one. Also, if both are empty, we fill in + one device (the default) and two channels. */ if (naudioindev == -1) - { /* not set */ + { /* no input audio devices specified */ if (nchindev == -1) { nchindev=1; @@ -131,7 +182,7 @@ void sys_open_audio(int naudioindev, int *audioindev, int nchindev, } else { - for (i = 0; i < MAXAUDIODEV; i++) + for (i = 0; i < MAXAUDIOINDEV; i++) audioindev[i] = i+1; naudioindev = nchindev; } @@ -177,7 +228,7 @@ void sys_open_audio(int naudioindev, int *audioindev, int nchindev, } else { - for (i = 0; i < MAXAUDIODEV; i++) + for (i = 0; i < MAXAUDIOOUTDEV; i++) audiooutdev[i] = i+1; naudiooutdev = nchoutdev; } @@ -211,52 +262,89 @@ void sys_open_audio(int naudioindev, int *audioindev, int nchindev, naudiooutdev = nchoutdev; } } + + /* count total number of input and output channels */ for (i = inchans = 0; i < naudioindev; i++) inchans += chindev[i]; for (i = outchans = 0; i < naudiooutdev; i++) outchans += choutdev[i]; - + /* if no input or output devices seem to have been specified, + this really means just disable audio, which we now do. Meanwhile, + we can set audio input and output devices to their defaults. */ + if (!inchans && !outchans) + { + enable = 0; + naudioindev = nchindev = naudiooutdev = nchoutdev = 1; + audioindev[0] = audiooutdev[0] = DEFAULTAUDIODEV; + chindev[0] = choutdev[0] = 0; + } + sys_schedadvance = advance * 1000; sys_setchsr(inchans, outchans, rate); + sys_log_error(ERR_NOTHING); + + if (enable && (inchans > 0 || outchans > 0)) + { +#ifdef USEAPI_PORTAUDIO + if (sys_audioapi == API_PORTAUDIO) + { + int blksize = (sys_blocksize ? sys_blocksize : 64); + pa_open_audio(inchans, outchans, rate, sys_soundin, sys_soundout, + blksize, sys_advance_samples/blksize, + (naudiooutdev > 0 ? audioindev[0] : 0), + (naudiooutdev > 0 ? audiooutdev[0] : 0)); + } +else +#endif +#ifdef USEAPI_JACK + if (sys_audioapi == API_JACK) + jack_open_audio((naudioindev > 0 ? chindev[0] : 0), + (naudiooutdev > 0 ? choutdev[0] : 0), rate); + + else +#endif #ifdef USEAPI_OSS - if (sys_audioapi == API_OSS) - oss_open_audio(naudioindev, audioindev, nchindev, chindev, - naudiooutdev, audiooutdev, nchoutdev, choutdev, rate); - else + if (sys_audioapi == API_OSS) + oss_open_audio(naudioindev, audioindev, nchindev, chindev, + naudiooutdev, audiooutdev, nchoutdev, choutdev, rate); + else #endif #ifdef USEAPI_ALSA - /* for alsa, the "device numbers" are ignored; they are sent - straight to the alsa code via linux_alsa_devname(). Only one - device is supported for each of input, output. */ - if (sys_audioapi == API_ALSA) - alsa_open_audio((naudioindev > 0 ? chindev[0] : 0), - (naudiooutdev > 0 ? choutdev[0] : 0), rate); - else -#endif -#ifdef USEAPI_PORTAUDIO - if (sys_audioapi == API_PORTAUDIO) - pa_open_audio(inchans, outchans, rate, sys_soundin, sys_soundout, - sys_blocksize, sys_advance_samples/sys_blocksize, - (naudiooutdev > 0 ? audioindev[0] : 0), - (naudiooutdev > 0 ? audiooutdev[0] : 0)); - else + /* for alsa, only one device is supported; it may + be open for both input and output. */ + if (sys_audioapi == API_ALSA) + alsa_open_audio(naudioindev, audioindev, nchindev, chindev, + naudiooutdev, audiooutdev, nchoutdev, choutdev, rate); + else #endif #ifdef USEAPI_MMIO - if (sys_audioapi == API_MMIO) - mmio_open_audio(naudioindev, audioindev, nchindev, chindev, - naudiooutdev, audiooutdev, nchoutdev, choutdev, rate); - else + if (sys_audioapi == API_MMIO) + mmio_open_audio(naudioindev, audioindev, nchindev, chindev, + naudiooutdev, audiooutdev, nchoutdev, choutdev, rate); + else #endif - post("unknown audio API specified"); + post("unknown audio API specified"); + } + sys_save_audio_params(naudioindev, audioindev, chindev, + naudiooutdev, audiooutdev, choutdev, rate, advance); + audio_state = enable; + sys_vgui("set pd_whichapi %d\n", (audio_isopen() ? sys_audioapi : 0)); + sched_set_using_dacs(enable); } void sys_close_audio(void) { - + if (!audio_isopen()) + return; #ifdef USEAPI_PORTAUDIO if (sys_audioapi == API_PORTAUDIO) pa_close_audio(); else #endif +#ifdef USEAPI_JACK + if (sys_audioapi == API_JACK) + jack_close_audio(); + else +#endif #ifdef USEAPI_OSS if (sys_audioapi == API_OSS) oss_close_audio(); @@ -266,14 +354,26 @@ void sys_close_audio(void) if (sys_audioapi == API_ALSA) alsa_close_audio(); else +#endif #ifdef USEAPI_MMIO if (sys_audioapi == API_MMIO) mmio_close_audio(); else #endif -#endif - post("unknown API"); + post("sys_close_audio: unknown API %d", sys_audioapi); + sys_inchannels = sys_outchannels = 0; +} + /* open audio using whatever parameters were last used */ +void sys_reopen_audio( void) +{ + int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV]; + int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV]; + int rate, advance; + sys_get_audio_params(&naudioindev, audioindev, chindev, + &naudiooutdev, audiooutdev, choutdev, &rate, &advance); + sys_open_audio(naudioindev, audioindev, naudioindev, chindev, + naudiooutdev, audiooutdev, naudiooutdev, choutdev, rate, advance, 1); } int sys_send_dacs(void) @@ -305,6 +405,11 @@ int sys_send_dacs(void) return (pa_send_dacs()); else #endif +#ifdef USEAPI_JACK + if (sys_audioapi == API_JACK) + return (jack_send_dacs()); + else +#endif #ifdef USEAPI_OSS if (sys_audioapi == API_OSS) return (oss_send_dacs()); @@ -364,26 +469,249 @@ void sys_reportidle(void) { } +#define MAXNDEV 20 +#define DEVDESCSIZE 80 + +static void audio_getdevs(char *indevlist, int *nindevs, + char *outdevlist, int *noutdevs, int *canmulti, + int maxndev, int devdescsize) +{ + audio_init(); +#ifdef USEAPI_OSS + if (sys_audioapi == API_OSS) + { + oss_getdevs(indevlist, nindevs, outdevlist, noutdevs, canmulti, + maxndev, devdescsize); + } + else +#endif +#ifdef USEAPI_ALSA + if (sys_audioapi == API_ALSA) + { + alsa_getdevs(indevlist, nindevs, outdevlist, noutdevs, canmulti, + maxndev, devdescsize); + } + else +#endif +#ifdef USEAPI_PORTAUDIO + if (sys_audioapi == API_PORTAUDIO) + { + pa_getdevs(indevlist, nindevs, outdevlist, noutdevs, canmulti, + maxndev, devdescsize); + } + else +#endif +#ifdef USEAPI_MMIO + if (sys_audioapi == API_MMIO) + { + mmio_getdevs(indevlist, nindevs, outdevlist, noutdevs, canmulti, + maxndev, devdescsize); + } + else +#endif + { + /* this shouldn't happen once all the above get filled in. */ + int i; + *nindevs = *noutdevs = 3; + for (i = 0; i < 3; i++) + { + sprintf(indevlist + i * devdescsize, "input device #%d", i+1); + sprintf(outdevlist + i * devdescsize, "output device #%d", i+1); + } + *canmulti = 0; + } +} + +#ifdef MSW +#define DEVONSET 0 /* microsoft device list starts at 0 (the "mapper"). */ +#else /* (see also MSW ifdef in sys_parsedevlist(), s_main.c) */ +#define DEVONSET 1 /* To agree with command line flags, normally start at 1 */ +#endif + +static void sys_listaudiodevs(void ) +{ + char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE]; + int nindevs = 0, noutdevs = 0, i, canmulti = 0; + + audio_getdevs(indevlist, &nindevs, outdevlist, &noutdevs, &canmulti, + MAXNDEV, DEVDESCSIZE); + + if (!nindevs) + post("no audio input devices found"); + else + { + post("input devices:"); + for (i = 0; i < nindevs; i++) + post("%d. %s", i+1, indevlist + i * DEVDESCSIZE); + } + if (!noutdevs) + post("no audio output devices found"); + else + { + post("output devices:"); + for (i = 0; i < noutdevs; i++) + post("%d. %s", i + DEVONSET, outdevlist + i * DEVDESCSIZE); + } + post("API number %d\n", sys_audioapi); +} + + /* start an audio settings dialog window */ +void glob_audio_properties(t_pd *dummy, t_floatarg flongform) +{ + char buf[1024 + 2 * MAXNDEV*(DEVDESCSIZE+4)]; + /* these are the devices you're using: */ + int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV]; + int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV]; + int audioindev1, audioindev2, audioindev3, audioindev4, + audioinchan1, audioinchan2, audioinchan3, audioinchan4, + audiooutdev1, audiooutdev2, audiooutdev3, audiooutdev4, + audiooutchan1, audiooutchan2, audiooutchan3, audiooutchan4; + int rate, advance; + /* these are all the devices on your system: */ + char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE]; + int nindevs = 0, noutdevs = 0, canmulti = 0, i; + + char indevliststring[MAXNDEV*(DEVDESCSIZE+4)+80], + outdevliststring[MAXNDEV*(DEVDESCSIZE+4)+80]; + + audio_getdevs(indevlist, &nindevs, outdevlist, &noutdevs, &canmulti, + MAXNDEV, DEVDESCSIZE); + + strcpy(indevliststring, "{"); + for (i = 0; i < nindevs; i++) + { + strcat(indevliststring, "\""); + strcat(indevliststring, indevlist + i * DEVDESCSIZE); + strcat(indevliststring, "\" "); + } + strcat(indevliststring, "}"); + + strcpy(outdevliststring, "{"); + for (i = 0; i < noutdevs; i++) + { + strcat(outdevliststring, "\""); + strcat(outdevliststring, outdevlist + i * DEVDESCSIZE); + strcat(outdevliststring, "\" "); + } + strcat(outdevliststring, "}"); + + sys_get_audio_params(&naudioindev, audioindev, chindev, + &naudiooutdev, audiooutdev, choutdev, &rate, &advance); + + /* post("naudioindev %d naudiooutdev %d longform %f", + naudioindev, naudiooutdev, flongform); */ + if (naudioindev > 1 || naudiooutdev > 1) + flongform = 1; + + + audioindev1 = (naudioindev > 0 && audioindev[0]>= 0 ? audioindev[0] : 0); + audioindev2 = (naudioindev > 1 && audioindev[1]>= 0 ? audioindev[1] : 0); + audioindev3 = (naudioindev > 2 && audioindev[2]>= 0 ? audioindev[2] : 0); + audioindev4 = (naudioindev > 3 && audioindev[3]>= 0 ? audioindev[3] : 0); + audioinchan1 = (naudioindev > 0 ? chindev[0] : 0); + audioinchan2 = (naudioindev > 1 ? chindev[1] : 0); + audioinchan3 = (naudioindev > 2 ? chindev[2] : 0); + audioinchan4 = (naudioindev > 3 ? chindev[3] : 0); + audiooutdev1 = (naudiooutdev > 0 && audiooutdev[0]>=0 ? audiooutdev[0] : 0); + audiooutdev2 = (naudiooutdev > 1 && audiooutdev[1]>=0 ? audiooutdev[1] : 0); + audiooutdev3 = (naudiooutdev > 2 && audiooutdev[2]>=0 ? audiooutdev[2] : 0); + audiooutdev4 = (naudiooutdev > 3 && audiooutdev[3]>=0 ? audiooutdev[3] : 0); + audiooutchan1 = (naudiooutdev > 0 ? choutdev[0] : 0); + audiooutchan2 = (naudiooutdev > 1 ? choutdev[1] : 0); + audiooutchan3 = (naudiooutdev > 2 ? choutdev[2] : 0); + audiooutchan4 = (naudiooutdev > 3 ? choutdev[3] : 0); + sprintf(buf, +"pdtk_audio_dialog %%s \ +%s %d %d %d %d %d %d %d %d \ +%s %d %d %d %d %d %d %d %d \ +%d %d %d %d\n", + indevliststring, + audioindev1, audioindev2, audioindev3, audioindev4, + audioinchan1, audioinchan2, audioinchan3, audioinchan4, + outdevliststring, + audiooutdev1, audiooutdev2, audiooutdev3, audiooutdev4, + audiooutchan1, audiooutchan2, audiooutchan3, audiooutchan4, + rate, advance, canmulti, (flongform != 0)); + gfxstub_deleteforkey(0); + gfxstub_new(&glob_pdobject, glob_audio_properties, buf); +} + + /* new values from dialog window */ +void glob_audio_dialog(t_pd *dummy, t_symbol *s, int argc, t_atom *argv) +{ + int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV]; + int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV]; + int rate, advance, audioon, i, nindev, noutdev; + int audioindev1, audioinchan1, audiooutdev1, audiooutchan1; + int newaudioindev[4], newaudioinchan[4], + newaudiooutdev[4], newaudiooutchan[4]; + /* the new values the dialog came back with: */ + int newrate = atom_getintarg(16, argc, argv); + int newadvance = atom_getintarg(17, argc, argv); + int statewas; + + for (i = 0; i < 4; i++) + { + newaudioindev[i] = atom_getintarg(i, argc, argv); + newaudioinchan[i] = atom_getintarg(i+4, argc, argv); + newaudiooutdev[i] = atom_getintarg(i+8, argc, argv); + newaudiooutchan[i] = atom_getintarg(i+12, argc, argv); + } + + for (i = 0, nindev = 0; i < 4; i++) + { + if (newaudioinchan[i] > 0) + { + newaudioindev[nindev] = newaudioindev[i]; + newaudioinchan[nindev] = newaudioinchan[i]; + /* post("in %d %d %d", nindev, + newaudioindev[nindev] , newaudioinchan[nindev]); */ + nindev++; + } + } + for (i = 0, noutdev = 0; i < 4; i++) + { + if (newaudiooutchan[i] > 0) + { + newaudiooutdev[noutdev] = newaudiooutdev[i]; + newaudiooutchan[noutdev] = newaudiooutchan[i]; + /* post("out %d %d %d", noutdev, + newaudiooutdev[noutdev] , newaudioinchan[noutdev]); */ + noutdev++; + } + } + + sys_close_audio(); + sys_open_audio(nindev, newaudioindev, nindev, newaudioinchan, + noutdev, newaudiooutdev, noutdev, newaudiooutchan, + newrate, newadvance, 1); +} + void sys_listdevs(void ) { #ifdef USEAPI_PORTAUDIO if (sys_audioapi == API_PORTAUDIO) - pa_listdevs(); + sys_listaudiodevs(); else #endif +#ifdef USEAPI_JACK + if (sys_audioapi == API_JACK) + jack_listdevs(); + else +#endif #ifdef USEAPI_OSS if (sys_audioapi == API_OSS) - oss_listdevs(); + sys_listaudiodevs(); else #endif #ifdef USEAPI_MMIO if (sys_audioapi == API_MMIO) - mmio_listdevs(); + sys_listaudiodevs(); else #endif #ifdef USEAPI_ALSA if (sys_audioapi == API_ALSA) - alsa_listdevs(); + sys_listaudiodevs(); else #endif post("unknown API"); @@ -401,10 +729,135 @@ void sys_setblocksize(int n) sys_blocksize = n; } -void sys_set_sound_api(int which) +void sys_set_audio_api(int which) { sys_audioapi = which; if (sys_verbose) post("sys_audioapi %d", sys_audioapi); } +void glob_audio_setapi(void *dummy, t_floatarg f) +{ + int newapi = f; + if (newapi) + { + if (newapi == sys_audioapi) + { + if (!audio_isopen()) + sys_reopen_audio(); + } + else + { + sys_close_audio(); + sys_audioapi = newapi; + /* bash device params back to default */ + audio_naudioindev = audio_naudiooutdev = 1; + audio_audioindev[0] = audio_audiooutdev[0] = DEFAULTAUDIODEV; + audio_audiochindev[0] = audio_audiochoutdev[0] = SYS_DEFAULTCH; + sys_reopen_audio(); + } + glob_audio_properties(0, 0); + } + else if (audio_isopen()) + { + sys_close_audio(); + audio_state = 0; + sched_set_using_dacs(0); + } +} + + /* start or stop the audio hardware */ +void sys_set_audio_state(int onoff) +{ + if (onoff) /* start */ + { + if (!audio_isopen()) + sys_reopen_audio(); + } + else + { + if (audio_isopen()) + { + sys_close_audio(); + sched_set_using_dacs(0); + } + } + audio_state = onoff; +} + +void sys_get_audio_apis(char *buf) +{ + int n = 0; + strcpy(buf, "{ "); +#ifdef USEAPI_OSS + sprintf(buf + strlen(buf), "{OSS %d} ", API_OSS); n++; +#endif +#ifdef USEAPI_MMIO + sprintf(buf + strlen(buf), "{\"standard (MMIO)\" %d} ", API_MMIO); n++; +#endif +#ifdef USEAPI_ALSA + sprintf(buf + strlen(buf), "{ALSA %d} ", API_ALSA); n++; +#endif +#ifdef USEAPI_PORTAUDIO +#ifdef MSW + sprintf(buf + strlen(buf), + "{\"ASIO (via portaudio)\" %d} ", API_PORTAUDIO); +#else +#ifdef OSX + sprintf(buf + strlen(buf), + "{\"standard (portaudio)\" %d} ", API_PORTAUDIO); +#else + sprintf(buf + strlen(buf), "{portaudio %d} ", API_PORTAUDIO); +#endif +#endif + n++; +#endif +#ifdef USEAPI_JACK + sprintf(buf + strlen(buf), "{jack %d} ", API_JACK); n++; +#endif + strcat(buf, "}"); + /* then again, if only one API (or none) we don't offer any choice. */ + if (n < 2) + strcpy(buf, "{}"); + +} + +#ifdef USEAPI_ALSA +void alsa_putzeros(int n); +void alsa_getzeros(int n); +void alsa_printstate( void); +#endif + + /* debugging */ +void glob_foo(void *dummy, t_symbol *s, int argc, t_atom *argv) +{ + t_symbol *arg = atom_getsymbolarg(0, argc, argv); + if (arg == gensym("restart")) + { + int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV]; + int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV]; + int rate, advance; + sys_get_audio_params(&naudioindev, audioindev, chindev, + &naudiooutdev, audiooutdev, choutdev, &rate, &advance); + sys_close_audio(); + sys_open_audio(naudioindev, audioindev, naudioindev, chindev, + naudiooutdev, audiooutdev, naudiooutdev, choutdev, rate, advance, + 1); + } +#ifdef USEAPI_ALSA + else if (arg == gensym("alsawrite")) + { + int n = atom_getintarg(1, argc, argv); + alsa_putzeros(n); + } + else if (arg == gensym("alsaread")) + { + int n = atom_getintarg(1, argc, argv); + alsa_getzeros(n); + } + else if (arg == gensym("print")) + { + alsa_printstate(); + } +#endif +} |