diff --git a/src/g_array.c b/src/g_array.c index 90eafe5c6318a4d85fe76630c50ebb4d59619ebc..2c28c355540cd350872a4a548835a2c72e919a0e 100644 --- a/src/g_array.c +++ b/src/g_array.c @@ -405,10 +405,14 @@ void glist_arraydialog(t_glist *parent, t_symbol *s, int argc, t_atom *argv) sys_vgui("pdtk_canvas_getscroll .x%lx.c\n", (long unsigned int)glist_getcanvas(parent)); } +extern void canvas_apply_setundo(t_canvas *x, t_gobj *y); + /* this is called from the properties dialog window for an existing array */ void garray_arraydialog(t_garray *x, t_symbol *name, t_floatarg fsize, t_floatarg fflags, t_floatarg deleteit) { + canvas_apply_setundo(glist_getcanvas(x->x_glist), (t_gobj *)x); + int flags = fflags; int saveit = ((flags & 1) != 0); int style = ((flags & 6) >> 1); diff --git a/src/g_editor.c b/src/g_editor.c index 52ef02b74446fc3354cabef246085a1013e27dbd..aeff3132111c019c2044d2efdf798aacddac2079 100644 --- a/src/g_editor.c +++ b/src/g_editor.c @@ -1052,7 +1052,11 @@ static t_gobj *canvas_findhitbox(t_canvas *x, int xpos, int ypos, static void canvas_rightclick(t_canvas *x, int xpos, int ypos, t_gobj *y) { int canprop, canopen, isobject; - canprop = (!y || (y && class_getpropertiesfn(pd_class(&y->g_pd)))); + /* abstractions should only allow for properties inside them + otherwise they end-up being dirty without visible notification + besides, why would one mess with their properties without + seeing what is inside them? */ + canprop = (!y || (y && class_getpropertiesfn(pd_class(&y->g_pd))) && !canvas_isabstraction( ((t_glist*)y) ) ); canopen = (y && zgetfn(&y->g_pd, gensym("menu-open"))); if (y) { isobject = 1; @@ -1341,6 +1345,13 @@ void canvas_properties(t_glist *x) static void canvas_donecanvasdialog(t_glist *x, t_symbol *s, int argc, t_atom *argv) { + /* have to figure out how the parent window is stored + in the glist, also how to deal with abstractions, + so until that happens... + for the time being we only accept undo/redos that + apply to objects on the parent window (e.g. GOPs) */ + if (glist_getcanvas(x) != x && !canvas_isabstraction(x)) + canvas_apply_setundo(glist_getcanvas(x), (t_gobj *)x); t_float xperpix, yperpix, x1, y1, x2, y2, xpix, ypix, xmargin, ymargin; int graphme, redraw = 0; diff --git a/src/m_pd.h b/src/m_pd.h index db21659656cf8cd1c863349b816be38c4c634dea..c7c297740f9e4ff3354531053ffa160f5a98e613 100644 --- a/src/m_pd.h +++ b/src/m_pd.h @@ -11,7 +11,7 @@ extern "C" { #define PD_MAJOR_VERSION 0 #define PD_MINOR_VERSION 42 #define PD_BUGFIX_VERSION 5 -#define PD_TEST_VERSION "extended-l2ork-20101228" +#define PD_TEST_VERSION "extended-l2ork-20101229" /* old name for "MSW" flag -- we have to take it for the sake of many old "nmakefiles" for externs, which will define NT and not MSW */ diff --git a/src/s_audio_jack_old.c b/src/s_audio_jack_old.c deleted file mode 100644 index 3b96e4f84a69f52fc2e1fffc70293e2c21b67b5d..0000000000000000000000000000000000000000 --- a/src/s_audio_jack_old.c +++ /dev/null @@ -1,434 +0,0 @@ - - -/* ----------------------- Experimental routines for jack -------------- */ -#ifdef USEAPI_JACK - -#include <stdio.h> -#include <stdlib.h> -#include <string.h> -#include "m_pd.h" -#include "s_stuff.h" -#include <jack/jack.h> -#include <regex.h> - - -#define MAX_CLIENTS 100 -#define NUM_JACK_PORTS 128 -#define BUF_JACK 4096 -static jack_nframes_t jack_out_max; -#define JACK_OUT_MAX 64 -static jack_nframes_t jack_filled = 0; -static t_sample jack_outbuf[NUM_JACK_PORTS*BUF_JACK]; -static t_sample jack_inbuf[NUM_JACK_PORTS*BUF_JACK]; -static int jack_started = 0; - - -static jack_port_t *input_port[NUM_JACK_PORTS]; -static jack_port_t *output_port[NUM_JACK_PORTS]; -static int outport_count = 0; -static jack_client_t *jack_client = NULL; -char *jack_client_names[MAX_CLIENTS]; -static int jack_dio_error; - - -pthread_mutex_t jack_mutex; -pthread_cond_t jack_sem; - - -static int -process (jack_nframes_t nframes, void *arg) -{ - int j; - jack_default_audio_sample_t *out, *in; - - if (nframes > JACK_OUT_MAX) jack_out_max = nframes; - else jack_out_max = JACK_OUT_MAX; - if (jack_filled >= nframes) { - if (jack_filled != nframes) fprintf(stderr,"Partial read"); - /* hmm, how to find out whether 't_sample' and 'jack_default_audio_sample_t' are actually the same type??? */ - if(sizeof(t_sample)==sizeof(jack_default_audio_sample_t)) - { - for (j = 0; j < sys_outchannels; j++) { - out = jack_port_get_buffer (output_port[j], nframes); - memcpy(out, jack_outbuf + (j * BUF_JACK), sizeof (jack_default_audio_sample_t) * nframes); - } - for (j = 0; j < sys_inchannels; j++) { - in = jack_port_get_buffer( input_port[j], nframes); - memcpy(jack_inbuf + (j * BUF_JACK), in, sizeof (jack_default_audio_sample_t) * nframes); - } - } - else - { - unsigned int frame=0; - t_sample*data; - for (j = 0; j < sys_outchannels; j++) { - out = jack_port_get_buffer (output_port[j], nframes); - data=jack_outbuf + (j * BUF_JACK); - for(frame=0; frame<nframes; frame++) { - *out++=*data++; - } - } - for (j = 0; j < sys_inchannels; j++) { - in = jack_port_get_buffer( input_port[j], nframes); - data=jack_inbuf+(j*BUF_JACK); - for(frame=0; frame<nframes; frame++) { - *data++=*in++; - } - } - } - jack_filled -= nframes; - } else { /* PD could not keep up ! */ - if (jack_started) jack_dio_error = 1; - for (j = 0; j < outport_count; j++) { - out = jack_port_get_buffer (output_port[j], nframes); - memset(out, 0, sizeof (float) * nframes); - } - memset(jack_outbuf,0,sizeof(jack_outbuf)); - jack_filled = 0; - } - pthread_cond_broadcast(&jack_sem); - return 0; -} - -static int -jack_srate (jack_nframes_t srate, void *arg) -{ - sys_dacsr = srate; - return 0; -} - -static void -jack_shutdown (void *arg) -{ - verbose(1, "JACK-server shut down"); - sys_close_audio(); - jack_client = NULL; -} - -static int jack_xrun(void* arg) { - verbose(1, "JACK-server xrun"); - jack_dio_error = 1; - return 0; -} - - -static char** jack_get_clients(void) -{ - const char **jack_ports; - int i,j; - int num_clients = 0; - regex_t port_regex; - jack_ports = jack_get_ports( jack_client, "", "", 0 ); - regcomp( &port_regex, "^[^:]*", REG_EXTENDED ); - - jack_client_names[0] = NULL; - - /* Build a list of clients from the list of ports */ - for( i = 0; jack_ports[i] != NULL; i++ ) - { - int client_seen; - regmatch_t match_info; - char tmp_client_name[100]; - - /* extract the client name from the port name, using a regex - * that parses the clientname:portname syntax */ - regexec( &port_regex, jack_ports[i], 1, &match_info, 0 ); - memcpy( tmp_client_name, &jack_ports[i][match_info.rm_so], - match_info.rm_eo - match_info.rm_so ); - tmp_client_name[ match_info.rm_eo - match_info.rm_so ] = '\0'; - - /* do we know about this port's client yet? */ - client_seen = 0; - - for( j = 0; j < num_clients; j++ ) - if( strcmp( tmp_client_name, jack_client_names[j] ) == 0 ) - client_seen = 1; - - if( client_seen == 0 ) - { - jack_client_names[num_clients] = (char*)getbytes(strlen(tmp_client_name) + 1); - - /* The alsa_pcm client should go in spot 0. If this - * is the alsa_pcm client AND we are NOT about to put - * it in spot 0 put it in spot 0 and move whatever - * was already in spot 0 to the end. */ - - if( strcmp( "system", tmp_client_name ) == 0 && num_clients > 0 ) - { - char* tmp; - /* alsa_pcm goes in spot 0 */ - tmp = jack_client_names[ num_clients ]; - jack_client_names[ num_clients ] = jack_client_names[0]; - jack_client_names[0] = tmp; - strcpy( jack_client_names[0], tmp_client_name); - } - else - { - /* put the new client at the end of the client list */ - strcpy( jack_client_names[ num_clients ], tmp_client_name ); - } - num_clients++; - - } - } - - /* for (i=0;i<num_clients;i++) post("client: %s",jack_client_names[i]); */ - - free( jack_ports ); - return jack_client_names; -} - -/* - * Wire up all the ports of one client. - * - */ - -static int jack_connect_ports(char* client) -{ - char regex_pattern[100]; /* its always the same, ... */ - int i; - const char **jack_ports; - - if (strlen(client) > 96) return -1; - - sprintf( regex_pattern, "%s:.*", client ); - - jack_ports = jack_get_ports( jack_client, regex_pattern, - NULL, JackPortIsOutput); - if (jack_ports) - for (i=0;jack_ports[i] != NULL && i < sys_inchannels;i++) - if (jack_connect (jack_client, jack_ports[i], jack_port_name (input_port[i]))) - error("JACK: cannot connect input ports %s -> %s", jack_ports[i],jack_port_name (input_port[i])); - - - - jack_ports = jack_get_ports( jack_client, regex_pattern, - NULL, JackPortIsInput); - if (jack_ports) - for (i=0;jack_ports[i] != NULL && i < sys_outchannels;i++) - if (jack_connect (jack_client, jack_port_name (output_port[i]), jack_ports[i])) - error("JACK: cannot connect output ports %s -> %s", jack_port_name (output_port[i]),jack_ports[i]); - - - - free(jack_ports); - return 0; -} - - -void jack_error(const char *desc) { - error("JACK error: %s", desc); - return; -} - - -int -jack_open_audio(int inchans, int outchans, int rate) - -{ - int j; - char port_name[80] = ""; - int client_iterator = 0; - int new_jack = 0; - int srate; - jack_status_t status; - - jack_dio_error = 0; - - if ((inchans == 0) && (outchans == 0)) return 0; - - if (outchans > NUM_JACK_PORTS) { - error("JACK: %d output ports not supported, setting to %d",outchans, NUM_JACK_PORTS); - outchans = NUM_JACK_PORTS; - } - - if (inchans > NUM_JACK_PORTS) { - error("JACK: %d input ports not supported, setting to %d",inchans, NUM_JACK_PORTS); - inchans = NUM_JACK_PORTS; - } - - /* try to become a client of the JACK server */ - /* if no JACK server exists, start a default one (jack_client_open() does that for us... */ - if (!jack_client) { - do { - sprintf(port_name,"pure_data_%d",client_iterator); - client_iterator++; - /* do not try to start the jack-server...seems to make problems... */ - jack_client = jack_client_open (port_name, JackNoStartServer, &status, NULL); - if (status & JackServerFailed) { - error("JACK: unable to connect to JACK server"); - jack_client=NULL; - break; - } - } while (status & JackNameNotUnique); - - if(status) { - if (status & JackServerStarted) { - post("JACK: started JACK server?"); - } else { - post("JACK: jack returned status %d", status); - } - } - - if (!jack_client) { // jack spits out enough messages already, do not warn - sys_inchannels = sys_outchannels = 0; - return 1; - } - - jack_get_clients(); - - /* tell the JACK server to call `process()' whenever - there is work to be done. - */ - - jack_set_process_callback (jack_client, process, 0); - - // jack_set_error_function (jack_error); - -#ifdef JACK_XRUN - jack_set_xrun_callback (jack_client, jack_xrun, NULL); -#endif - - /* tell the JACK server to call `srate()' whenever - the sample rate of the system changes. - */ - - jack_set_sample_rate_callback (jack_client, jack_srate, 0); - - - /* tell the JACK server to call `jack_shutdown()' if - it ever shuts down, either entirely, or if it - just decides to stop calling us. - */ - - jack_on_shutdown (jack_client, jack_shutdown, 0); - - for (j=0;j<NUM_JACK_PORTS;j++) { - input_port[j]=NULL; - output_port[j] = NULL; - } - - new_jack = 1; - } - - /* display the current sample rate. once the client is activated - (see below), you should rely on your own sample rate - callback (see above) for this value. - */ - - srate = jack_get_sample_rate (jack_client); - sys_dacsr = srate; - - /* create the ports */ - - for (j = 0; j < inchans; j++) { - sprintf(port_name, "input%d", j); - if (!input_port[j]) input_port[j] = jack_port_register (jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0); - if (!input_port[j]) { - error("JACK: can only register %d input ports (instead of requested %d)", j, inchans); - sys_inchannels = inchans = j; - break; - } - } - - for (j = 0; j < outchans; j++) { - sprintf(port_name, "output%d", j); - if (!output_port[j]) output_port[j] = jack_port_register (jack_client, port_name, JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0); - if (!output_port[j]) { - error("JACK: can only register %d output ports (instead of requested %d)", j, outchans); - sys_outchannels = outchans = j; - break; - } - } - outport_count = outchans; - - /* tell the JACK server that we are ready to roll */ - - if (new_jack) { - if (jack_activate (jack_client)) { - error("JACK: cannot activate client"); - sys_inchannels = sys_outchannels = 0; - return 1; - } - - memset(jack_outbuf,0,sizeof(jack_outbuf)); - - if (jack_client_names[0]) - jack_connect_ports(jack_client_names[0]); - - pthread_mutex_init(&jack_mutex,NULL); - pthread_cond_init(&jack_sem,NULL); - } - return 0; -} - -void jack_close_audio(void) - -{ - jack_started = 0; -} - -int jack_send_dacs(void) - -{ - t_sample * fp; - int j; - int rtnval = SENDDACS_YES; - int timenow; - int timeref = sys_getrealtime(); - - if (!jack_client) return SENDDACS_NO; - - if (!sys_inchannels && !sys_outchannels) return (SENDDACS_NO); - - if (jack_dio_error) { - sys_log_error(ERR_RESYNC); - jack_dio_error = 0; - } - if (jack_filled >= jack_out_max) - pthread_cond_wait(&jack_sem,&jack_mutex); - - jack_started = 1; - - fp = sys_soundout; - for (j = 0; j < sys_outchannels; j++) { - memcpy(jack_outbuf + (j * BUF_JACK) + jack_filled,fp, DEFDACBLKSIZE*sizeof(t_sample)); - fp += DEFDACBLKSIZE; - } - fp = sys_soundin; - for (j = 0; j < sys_inchannels; j++) { - memcpy(fp, jack_inbuf + (j * BUF_JACK) + jack_filled, DEFDACBLKSIZE*sizeof(t_sample)); - fp += DEFDACBLKSIZE; - } - - if ((timenow = sys_getrealtime()) - timeref > 0.002) - { - rtnval = SENDDACS_SLEPT; - } - - memset(sys_soundout,0,DEFDACBLKSIZE*sizeof(t_sample)*sys_outchannels); - jack_filled += DEFDACBLKSIZE; - return rtnval; -} - -void jack_getdevs(char *indevlist, int *nindevs, - char *outdevlist, int *noutdevs, int *canmulti, - int maxndev, int devdescsize) -{ - int i, ndev; - *canmulti = 0; /* supports multiple devices */ - ndev = 1; - for (i = 0; i < ndev; i++) - { - sprintf(indevlist + i * devdescsize, "JACK"); - sprintf(outdevlist + i * devdescsize, "JACK"); - } - *nindevs = *noutdevs = ndev; -} - -void jack_listdevs( void) -{ - error("device listing not implemented for jack yet"); -} - -#endif /* JACK */ diff --git a/src/s_audio_old.c b/src/s_audio_old.c deleted file mode 100644 index 67555ac250862ce83359bbef04be0f4409ae05af..0000000000000000000000000000000000000000 --- a/src/s_audio_old.c +++ /dev/null @@ -1,912 +0,0 @@ -/* 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. -*/ - -#include "config.h" - -#include "m_pd.h" -#include "s_stuff.h" -#include <stdio.h> -#ifdef HAVE_UNISTD_H -#include <unistd.h> -/* XXX Hack!!! These should be checked for independently of unistd.h ... */ -#include <sys/time.h> -#include <sys/resource.h> -#endif -#include <stdlib.h> -#include <string.h> -#include <errno.h> - -#define SYS_DEFAULTCH 2 -#define SYS_MAXCH 100 -typedef long t_pa_sample; -#define SYS_SAMPLEWIDTH sizeof(t_pa_sample) -#define SYS_BYTESPERCHAN (DEFDACBLKSIZE * SYS_SAMPLEWIDTH) -#define SYS_XFERSAMPS (SYS_DEFAULTCH*DEFDACBLKSIZE) -#define SYS_XFERSIZE (SYS_SAMPLEWIDTH * SYS_XFERSAMPS) -#define MAXNDEV 20 -#define DEVDESCSIZE 80 - -static void audio_getdevs(char *indevlist, int *nindevs, - char *outdevlist, int *noutdevs, int *canmulti, int *cancallback, - int maxndev, int devdescsize); - - /* these are set in this file when opening audio, but then may be reduced, - even to zero, in the system dependent open_audio routines. */ -int sys_inchannels; -int sys_outchannels; -int sys_advance_samples; /* scheduler advance in samples */ -int sys_blocksize = 0; /* audio I/O block size in sample frames */ -int sys_audioapi = API_DEFAULT; -int sys_audioapiopened = -1; /* save last API opened for later closing */ -static int sys_meters; /* true if we're metering */ -static t_sample sys_inmax; /* max input amplitude */ -static t_sample sys_outmax; /* max output amplitude */ - - /* exported variables */ -int sys_schedadvance; /* scheduler advance in microseconds */ -t_float sys_dacsr; - -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 = -1; -static int audio_audioindev[MAXAUDIOINDEV]; -static int audio_audiochindev[MAXAUDIOINDEV]; -static int audio_naudiooutdev = -1; -static int audio_audiooutdev[MAXAUDIOOUTDEV]; -static int audio_audiochoutdev[MAXAUDIOOUTDEV]; -static int audio_rate; -static int audio_advance; -static int audio_callback; - -static int audio_callback_is_open; /* reflects true actual state */ -static int audio_nextinchans, audio_nextoutchans; -void sched_audio_callbackfn(void); -void sched_reopenmeplease(void); - -static int audio_isopen(void) -{ - return (audio_state && - ((audio_naudioindev > 0 && audio_audiochindev[0] > 0) - || (audio_naudiooutdev > 0 && audio_audiochoutdev[0] > 0))); -} - -void sys_get_audio_params( - int *pnaudioindev, int *paudioindev, int *chindev, - int *pnaudiooutdev, int *paudiooutdev, int *choutdev, - int *prate, int *padvance, int *pcallback) -{ - 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; - *pcallback = audio_callback; -} - -void sys_save_audio_params( - int naudioindev, int *audioindev, int *chindev, - int naudiooutdev, int *audiooutdev, int *choutdev, - int rate, int advance, int callback) -{ - 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; - audio_callback = callback; -} - - /* 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. */ - -void sys_setchsr(int chin, int chout, int sr) -{ - int nblk; - int inbytes = (chin ? chin : 2) * - (DEFDACBLKSIZE*sizeof(t_sample)); - int outbytes = (chout ? chout : 2) * - (DEFDACBLKSIZE*sizeof(t_sample)); - - if (sys_soundin) - freebytes(sys_soundin, - (sys_inchannels? sys_inchannels : 2) * - (DEFDACBLKSIZE*sizeof(t_sample))); - if (sys_soundout) - freebytes(sys_soundout, - (sys_outchannels? sys_outchannels : 2) * - (DEFDACBLKSIZE*sizeof(t_sample))); - sys_inchannels = chin; - sys_outchannels = chout; - sys_dacsr = sr; - sys_advance_samples = (sys_schedadvance * sys_dacsr) / (1000000.); - if (sys_advance_samples < 3 * DEFDACBLKSIZE) - sys_advance_samples = 3 * DEFDACBLKSIZE; - - sys_soundin = (t_sample *)getbytes(inbytes); - memset(sys_soundin, 0, inbytes); - - sys_soundout = (t_sample *)getbytes(outbytes); - memset(sys_soundout, 0, outbytes); - - if (sys_verbose) - post("input channels = %d, output channels = %d", - sys_inchannels, sys_outchannels); - canvas_resume_dsp(canvas_suspend_dsp()); -} - -/* ----------------------- public routines ----------------------- */ - - /* 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(int naudioindev, int *audioindev, int nchindev, - int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev, - int *choutdev, int rate, int advance, int callback) -{ - int i, *ip; - int defaultchannels = SYS_DEFAULTCH; - int inchans, outchans, nrealindev, nrealoutdev; - int realindev[MAXAUDIOINDEV], realoutdev[MAXAUDIOOUTDEV]; - int realinchans[MAXAUDIOINDEV], realoutchans[MAXAUDIOOUTDEV]; - - char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE]; - int indevs = 0, outdevs = 0, canmulti = 0, cancallback = 0; - audio_getdevs(indevlist, &indevs, outdevlist, &outdevs, &canmulti, - &cancallback, MAXNDEV, DEVDESCSIZE); - - if (rate < 1) - rate = DEFAULTSRATE; - if (advance <= 0) - advance = DEFAULTADVANCE; - 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) - { /* no input audio devices specified */ - if (nchindev == -1) - { - if (indevs >= 1) - { - nchindev=1; - chindev[0] = defaultchannels; - naudioindev = 1; - audioindev[0] = DEFAULTAUDIODEV; - } - else naudioindev = nchindev = 0; - } - else - { - for (i = 0; i < MAXAUDIOINDEV; i++) - audioindev[i] = i; - naudioindev = nchindev; - } - } - else - { - if (nchindev == -1) - { - nchindev = naudioindev; - for (i = 0; i < naudioindev; i++) - chindev[i] = defaultchannels; - } - else if (nchindev > naudioindev) - { - for (i = naudioindev; i < nchindev; i++) - { - if (i == 0) - audioindev[0] = DEFAULTAUDIODEV; - else audioindev[i] = audioindev[i-1] + 1; - } - naudioindev = nchindev; - } - else if (nchindev < naudioindev) - { - for (i = nchindev; i < naudioindev; i++) - { - if (i == 0) - chindev[0] = defaultchannels; - else chindev[i] = chindev[i-1]; - } - naudioindev = nchindev; - } - } - - if (naudiooutdev == -1) - { /* not set */ - if (nchoutdev == -1) - { - if (outdevs >= 1) - { - nchoutdev=1; - choutdev[0]=defaultchannels; - naudiooutdev=1; - audiooutdev[0] = DEFAULTAUDIODEV; - } - else nchoutdev = naudiooutdev = 0; - } - else - { - for (i = 0; i < MAXAUDIOOUTDEV; i++) - audiooutdev[i] = i; - naudiooutdev = nchoutdev; - } - } - else - { - if (nchoutdev == -1) - { - nchoutdev = naudiooutdev; - for (i = 0; i < naudiooutdev; i++) - choutdev[i] = defaultchannels; - } - else if (nchoutdev > naudiooutdev) - { - for (i = naudiooutdev; i < nchoutdev; i++) - { - if (i == 0) - audiooutdev[0] = DEFAULTAUDIODEV; - else audiooutdev[i] = audiooutdev[i-1] + 1; - } - naudiooutdev = nchoutdev; - } - else if (nchoutdev < naudiooutdev) - { - for (i = nchoutdev; i < naudiooutdev; i++) - { - if (i == 0) - choutdev[0] = defaultchannels; - else choutdev[i] = choutdev[i-1]; - } - naudiooutdev = nchoutdev; - } - } - - /* count total number of input and output channels */ - for (i = nrealindev = inchans = 0; i < naudioindev; i++) - if (chindev[i] > 0) - { - realinchans[nrealindev] = chindev[i]; - realindev[nrealindev] = audioindev[i]; - inchans += chindev[i]; - nrealindev++; - } - for (i = nrealoutdev = outchans = 0; i < naudiooutdev; i++) - if (choutdev[i] > 0) - { - realoutchans[nrealoutdev] = choutdev[i]; - realoutdev[nrealoutdev] = audiooutdev[i]; - outchans += choutdev[i]; - nrealoutdev++; - } - sys_schedadvance = advance * 1000; - sys_log_error(ERR_NOTHING); - audio_nextinchans = inchans; - audio_nextoutchans = outchans; - sys_save_audio_params(nrealindev, realindev, realinchans, - nrealoutdev, realoutdev, realoutchans, rate, advance, callback); -} - -void sys_close_audio(void) -{ - if (sys_externalschedlib) - { - return; - } - if (!audio_isopen()) - return; -#ifdef USEAPI_PORTAUDIO - if (sys_audioapiopened == API_PORTAUDIO) - pa_close_audio(); - else -#endif -#ifdef USEAPI_JACK - if (sys_audioapiopened == API_JACK) - jack_close_audio(); - else -#endif -#ifdef USEAPI_OSS - if (sys_audioapiopened == API_OSS) - oss_close_audio(); - else -#endif -#ifdef USEAPI_ALSA - if (sys_audioapiopened == API_ALSA) - alsa_close_audio(); - else -#endif -#ifdef USEAPI_MMIO - if (sys_audioapiopened == API_MMIO) - mmio_close_audio(); - else -#endif - post("sys_close_audio: unknown API %d", sys_audioapiopened); - sys_inchannels = sys_outchannels = 0; - sys_audioapiopened = -1; - sched_set_using_audio(SCHED_AUDIO_NONE); - audio_state = 0; - audio_callback_is_open = 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, callback, outcome = 0; - sys_get_audio_params(&naudioindev, audioindev, chindev, - &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback); - sys_setchsr(audio_nextinchans, audio_nextoutchans, rate); - if (!naudioindev && !naudiooutdev) - { - sched_set_using_audio(SCHED_AUDIO_NONE); - return; - } -#ifdef USEAPI_PORTAUDIO - if (sys_audioapi == API_PORTAUDIO) - { - int blksize = (sys_blocksize ? sys_blocksize : 64); - outcome = pa_open_audio((naudioindev > 0 ? chindev[0] : 0), - (naudiooutdev > 0 ? choutdev[0] : 0), rate, sys_soundin, - sys_soundout, blksize, sys_advance_samples/blksize, - (naudioindev > 0 ? audioindev[0] : 0), - (naudiooutdev > 0 ? audiooutdev[0] : 0), - (callback ? sched_audio_callbackfn : 0)); - } - else -#endif -#ifdef USEAPI_JACK - if (sys_audioapi == API_JACK) - outcome = jack_open_audio((naudioindev > 0 ? chindev[0] : 0), - (naudioindev > 0 ? choutdev[0] : 0), rate); - - else -#endif -#ifdef USEAPI_OSS - if (sys_audioapi == API_OSS) - outcome = oss_open_audio(naudioindev, audioindev, naudioindev, - chindev, naudiooutdev, audiooutdev, naudiooutdev, choutdev, rate); - else -#endif -#ifdef USEAPI_ALSA - /* for alsa, only one device is supported; it may - be open for both input and output. */ - if (sys_audioapi == API_ALSA) - outcome = alsa_open_audio(naudioindev, audioindev, naudioindev, - chindev, naudiooutdev, audiooutdev, naudiooutdev, choutdev, rate); - else -#endif -#ifdef USEAPI_MMIO - if (sys_audioapi == API_MMIO) - outcome = mmio_open_audio(naudioindev, audioindev, naudioindev, - chindev, naudiooutdev, audiooutdev, naudiooutdev, choutdev, rate); - else -#endif - if (sys_audioapi == API_NONE) - ; - else post("unknown audio API specified"); - if (outcome) /* failed */ - { - audio_state = 0; - sched_set_using_audio(SCHED_AUDIO_NONE); - sys_audioapiopened = -1; - audio_callback_is_open = 0; - } - else - { - /* fprintf(stderr, "started w/callback %d\n", callback); */ - audio_state = 1; - sched_set_using_audio( - (callback ? SCHED_AUDIO_CALLBACK : SCHED_AUDIO_POLL)); - sys_audioapiopened = sys_audioapi; - audio_callback_is_open = callback; - } - sys_vgui("set pd_whichapi %d\n", (outcome == 0 ? sys_audioapi : 0)); -} - -int sys_send_dacs(void) -{ - if (sys_meters) - { - int i, n; - t_sample maxsamp; - for (i = 0, n = sys_inchannels * DEFDACBLKSIZE, maxsamp = sys_inmax; - i < n; i++) - { - t_sample f = sys_soundin[i]; - if (f > maxsamp) maxsamp = f; - else if (-f > maxsamp) maxsamp = -f; - } - sys_inmax = maxsamp; - for (i = 0, n = sys_outchannels * DEFDACBLKSIZE, maxsamp = sys_outmax; - i < n; i++) - { - t_sample f = sys_soundout[i]; - if (f > maxsamp) maxsamp = f; - else if (-f > maxsamp) maxsamp = -f; - } - sys_outmax = maxsamp; - } - -#ifdef USEAPI_PORTAUDIO - if (sys_audioapi == API_PORTAUDIO) - 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()); - else -#endif -#ifdef USEAPI_ALSA - if (sys_audioapi == API_ALSA) - return (alsa_send_dacs()); - else -#endif -#ifdef USEAPI_MMIO - if (sys_audioapi == API_MMIO) - return (mmio_send_dacs()); - else -#endif - post("unknown API"); - return (0); -} - -t_float sys_getsr(void) -{ - return (sys_dacsr); -} - -int sys_get_outchannels(void) -{ - return (sys_outchannels); -} - -int sys_get_inchannels(void) -{ - return (sys_inchannels); -} - -void sys_getmeters(t_sample *inmax, t_sample *outmax) -{ - if (inmax) - { - sys_meters = 1; - *inmax = sys_inmax; - *outmax = sys_outmax; - } - else - sys_meters = 0; - sys_inmax = sys_outmax = 0; -} - -void sys_reportidle(void) -{ -} - -static void audio_getdevs(char *indevlist, int *nindevs, - char *outdevlist, int *noutdevs, int *canmulti, int *cancallback, - int maxndev, int devdescsize) -{ - audio_init(); - *cancallback = 0; /* may be overridden by specific API implementation */ -#ifdef USEAPI_PORTAUDIO - if (sys_audioapi == API_PORTAUDIO) - { - pa_getdevs(indevlist, nindevs, outdevlist, noutdevs, canmulti, - maxndev, devdescsize); - *cancallback = 1; - } - else -#endif -#ifdef USEAPI_JACK - if (sys_audioapi == API_JACK) - { - jack_getdevs(indevlist, nindevs, outdevlist, noutdevs, canmulti, - maxndev, devdescsize); - } - else -#endif -#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_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; - } -} - - -static void sys_listaudiodevs(void ) -{ - char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE]; - int nindevs = 0, noutdevs = 0, i, canmulti = 0, cancallback = 0; - - audio_getdevs(indevlist, &nindevs, outdevlist, &noutdevs, &canmulti, - &cancallback, MAXNDEV, DEVDESCSIZE); - - if (!nindevs) - post("no audio input devices found"); - else - { - /* To agree with command line flags, normally start at 1 */ - /* But microsoft "MMIO" device list starts at 0 (the "mapper"). */ - /* (see also sys_mmio variable in s_main.c) */ - - post("audio input devices:"); - for (i = 0; i < nindevs; i++) - post("%d. %s", i + (sys_audioapi != API_MMIO), - indevlist + i * DEVDESCSIZE); - } - if (!noutdevs) - post("no audio output devices found"); - else - { - post("audio output devices:"); - for (i = 0; i < noutdevs; i++) - post("%d. %s", i + (sys_audioapi != API_MMIO), - 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, callback; - /* these are all the devices on your system: */ - char indevlist[MAXNDEV*DEVDESCSIZE], outdevlist[MAXNDEV*DEVDESCSIZE]; - int nindevs = 0, noutdevs = 0, canmulti = 0, cancallback = 0, i; - - audio_getdevs(indevlist, &nindevs, outdevlist, &noutdevs, &canmulti, - &cancallback, MAXNDEV, DEVDESCSIZE); - - sys_gui("global audio_indevlist; set audio_indevlist {}\n"); - for (i = 0; i < nindevs; i++) - sys_vgui("lappend audio_indevlist {%s}\n", - indevlist + i * DEVDESCSIZE); - - sys_gui("global audio_outdevlist; set audio_outdevlist {}\n"); - for (i = 0; i < noutdevs; i++) - sys_vgui("lappend audio_outdevlist {%s}\n", - outdevlist + i * DEVDESCSIZE); - - sys_get_audio_params(&naudioindev, audioindev, chindev, - &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback); - - /* 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 \ -%d %d %d %d %d %d %d %d \ -%d %d %d %d %d %d %d %d \ -%d %d %d %d %d\n", - audioindev1, audioindev2, audioindev3, audioindev4, - audioinchan1, audioinchan2, audioinchan3, audioinchan4, - audiooutdev1, audiooutdev2, audiooutdev3, audiooutdev4, - audiooutchan1, audiooutchan2, audiooutchan3, audiooutchan4, - rate, advance, canmulti, (cancallback ? callback : -1), - (flongform != 0)); - gfxstub_deleteforkey(0); - gfxstub_new(&glob_pdobject, (void *)glob_audio_properties, buf); -} - -extern int pa_foo; - /* 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 newcallback = atom_getintarg(18, argc, argv); - - 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]) - { - 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]) - { - newaudiooutdev[noutdev] = newaudiooutdev[i]; - newaudiooutchan[noutdev] = newaudiooutchan[i]; - /* post("out %d %d %d", noutdev, - newaudiooutdev[noutdev] , newaudioinchan[noutdev]); */ - noutdev++; - } - } - - if (newcallback < 0) - newcallback = 0; - if (!audio_callback_is_open && !newcallback) - sys_close_audio(); - sys_set_audio_settings(nindev, newaudioindev, nindev, newaudioinchan, - noutdev, newaudiooutdev, noutdev, newaudiooutchan, - newrate, newadvance, (newcallback >= 0 ? newcallback : 0)); - if (!audio_callback_is_open && !newcallback) - sys_reopen_audio(); - else sched_reopenmeplease(); -} - -void sys_listdevs(void ) -{ -#ifdef USEAPI_PORTAUDIO - if (sys_audioapi == API_PORTAUDIO) - sys_listaudiodevs(); - else -#endif -#ifdef USEAPI_JACK - if (sys_audioapi == API_JACK) - jack_listdevs(); - else -#endif -#ifdef USEAPI_OSS - if (sys_audioapi == API_OSS) - sys_listaudiodevs(); - else -#endif -#ifdef USEAPI_ALSA - if (sys_audioapi == API_ALSA) - sys_listaudiodevs(); - else -#endif -#ifdef USEAPI_MMIO - if (sys_audioapi == API_MMIO) - sys_listaudiodevs(); - else -#endif - post("unknown API"); - - sys_listmididevs(); -} - -void sys_setblocksize(int n) -{ - if (n < 1) - n = 1; - if (n != (1 << ilog2(n))) - post("warning: adjusting blocksize to power of 2: %d", - (n = (1 << ilog2(n)))); - sys_blocksize = n; -} - -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(); - } -} - - /* 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(); - } -} - -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")) - sys_reopen_audio(); -#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 -}