/* Copyright (c) 2003, Miller Puckette and others. * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */ /* machine-independent (well, mostly!) audio layer. Stores and recalls audio settings from argparse routine and from dialog window. LATER: save audio settings for various APIs for easier switching */ #include "m_pd.h" #include "s_stuff.h" #include <stdio.h> #ifdef _WIN32 #include <time.h> #else #include <unistd.h> #include <sys/time.h> #include <sys/resource.h> #endif /* _WIN32 */ #include <string.h> #include <math.h> #include "m_private_utils.h" #define SYS_DEFAULTCH … #define MAXNDEV … #define DEVDESCSIZE … #define MAXBLOCKSIZE … /* exported variables */ int sys_schedadvance; /* scheduler advance in microseconds */ static int sys_audioapiopened; /* what API is open, API_NONE if none */ /* current parameters (if an API is open) or requested ones otherwise: */ static t_audiosettings audio_nextsettings; void sched_audio_callbackfn(void); int audio_isopen(void) { … } static int audio_isfixedsr(int api) { … } static int audio_isfixedblocksize(int api) { … } #ifdef USEAPI_JACK int jack_get_blocksize(void); #endif static int audio_getfixedblocksize(int api) { … } /* inform rest of Pd of current channels and sample rate. Do this when opening audio device. This is also called from alsamm but I think that is no longer in use, so in principle this could be static. */ void sys_setchsr(int chin, int chout, int sr) { … } static void audio_make_sane(int *ndev, int *devvec, int *nchan, int *chanvec, int maxdev) { … } /* compact the list of audio devices by skipping those whose channel counts are zero, and add up all channel counts. Assumes you've already called make_sane above */ static void audio_compact_and_count_channels(int *ndev, int *devvec, int *chanvec, int *totalchans, int maxdev) { … } /* ----------------------- public routines ----------------------- */ static int initted = …; void sys_get_audio_settings(t_audiosettings *a) { … } /* 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. This function can leave number of channels at zero which is appropriate for the dialog window but before starting audio we also call audio_compact_and_count_channels below.*/ /* set audio device settings (after cleaning up the specified device and channel vectors). The audio devices are "zero based" (i.e. "0" means the first one.) We can later re-open audio and/or show the settings on a dialog window. */ void sys_set_audio_settings(t_audiosettings *a) { … } /* close the audio device. Must not be called from a Pd message! */ void sys_do_close_audio(void) { … } void sys_init_audio(void) { … } /* open audio using currently requested parameters. Must not be called from a Pd message! */ void sys_do_reopen_audio(void) { … } /* called by the scheduler if the audio system appears to be stuck */ int sys_try_reopen_audio(void) { … } int sys_send_dacs(void) { … } t_float sys_getsr(void) { … } int sys_get_outchannels(void) { … } int sys_get_inchannels(void) { … } /* this could later be set by a preference but for now it seems OK to just keep jack audio open but close unused audio devices for any other API */ int audio_shouldkeepopen(void) { … } /* get names of available audio devices for the specified API */ void sys_get_audio_devs(char *indevlist, int *nindevs, char *outdevlist, int *noutdevs, int *canmulti, int *cancallback, int maxndev, int devdescsize, int api) { … } void sys_gui_audiopreferences(void) { … } /* start an audio settings dialog window */ void glob_audio_properties(t_pd *dummy, t_floatarg flongform) { … } /* new values from dialog window */ void glob_audio_dialog(t_pd *dummy, t_symbol *s, int argc, t_atom *argv) { … } void sys_listdevs(void) { … } void glob_audio_setapi(void *dummy, t_floatarg f) { … } #define MAXAPIENTRY … t_apientry; static t_apientry audio_apilist[] = …; void sys_get_audio_apis(char *buf) { … } /* convert a device name to a (1-based) device number. (Output device if 'output' parameter is true, otherwise input device). Negative on failure. */ int sys_audiodevnametonumber(int output, const char *name) { … } /* convert a (1-based) device number to a device name. (Output device if 'output' parameter is true, otherwise input device). Empty string on failure. */ void sys_audiodevnumbertoname(int output, int devno, char *name, int namesize) { … }