diff --git a/extra/pd~/pdsched.c b/extra/pd~/pdsched.c index 6c6060c14a22b3fbd44591d0e24bfe6756854541..235d9dc614e086e6f29d3e2b99a5b8ab59faee2b 100644 --- a/extra/pd~/pdsched.c +++ b/extra/pd~/pdsched.c @@ -42,8 +42,8 @@ int pd_extern_sched(char *flags) t_binbuf *b = binbuf_new(); sys_get_audio_params(&naudioindev, audioindev, chindev, - &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback, - &blocksize); + &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback); //, + // &blocksize); chin = (naudioindev < 1 ? 0 : chindev[0]); chout = (naudiooutdev < 1 ? 0 : choutdev[0]); diff --git a/src/m_pd.h b/src/m_pd.h index d7481dfd395e354138b717dc96819c1b254bad04..9a1dd1ae2d428725cfcf348499646b467c56183a 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 6 -#define PD_TEST_VERSION "extended-l2ork-20121005" +#define PD_TEST_VERSION "extended-l2ork-20121007" #define PDL2ORK /* old name for "MSW" flag -- we have to take it for the sake of many old diff --git a/src/pd.tk b/src/pd.tk index 58ceffa5b49f1a253a76d7f00f2dae6f417422bf..dce2f69b6ef10b8509e63923240ff0af9cd5267e 100644 --- a/src/pd.tk +++ b/src/pd.tk @@ -6358,6 +6358,7 @@ proc pdtk_audio_dialog {id indev1 indev2 indev3 indev4 \ set audio_sr $sr set audio_advance $advance set audio_callback $callback + toplevel $id -class [winfo class .] match_linux_wm [list $id configure] wm title $id {Audio Settings} @@ -6389,6 +6390,7 @@ proc pdtk_audio_dialog {id indev1 indev2 indev3 indev4 \ match_linux_wm [list label $id.srf.l2 -text "delay (msec):"] match_linux_wm [list entry $id.srf.x2 -textvariable audio_advance -width 4] pack $id.srf.l1 $id.srf.x1 $id.srf.l2 $id.srf.x2 -side left -pady 3 + if {$audio_callback >= 0} { match_linux_wm [list checkbutton $id.srf.x3 -variable audio_callback \ -text {use callbacks} -anchor e] diff --git a/src/s_audio.c b/src/s_audio.c index bff3c3abc095295e7d484b63c52dbc72f6ed13e3..cfd2c64ea47bbfc009d8888e73dfdc601ae7637b 100644 --- a/src/s_audio.c +++ b/src/s_audio.c @@ -6,21 +6,23 @@ audio settings from argparse routine and from dialog window. */ +#include "config.h" + #include "m_pd.h" #include "s_stuff.h" #include <stdio.h> -#ifdef _WIN32 -#include <time.h> -#else +#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 /* _WIN32 */ +#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) @@ -38,6 +40,7 @@ static void audio_getdevs(char *indevlist, int *nindevs, 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 */ @@ -64,15 +67,19 @@ static int audio_naudiooutdev = -1; static int audio_audiooutdev[MAXAUDIOOUTDEV]; static int audio_audiochoutdev[MAXAUDIOOUTDEV]; static int audio_rate; -static int audio_advance = -1; +static int audio_advance; static int audio_callback; -static int audio_blocksize; 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); +#ifdef USEAPI_JACK + /* needed to fix srate when using jack, inclded in s_audio_jack.c */ +extern int jack_get_srate(void); +#endif /* JACK */ + static int audio_isopen(void) { return (audio_state && @@ -83,7 +90,7 @@ static int audio_isopen(void) void sys_get_audio_params( int *pnaudioindev, int *paudioindev, int *chindev, int *pnaudiooutdev, int *paudiooutdev, int *choutdev, - int *prate, int *padvance, int *pcallback, int *pblocksize) + int *prate, int *padvance, int *pcallback) { int i; *pnaudioindev = audio_naudioindev; @@ -93,17 +100,23 @@ void sys_get_audio_params( *pnaudiooutdev = audio_naudiooutdev; for (i = 0; i < MAXAUDIOOUTDEV; i++) paudiooutdev[i] = audio_audiooutdev[i], - choutdev[i] = audio_audiochoutdev[i]; + choutdev[i] = audio_audiochoutdev[i]; +#ifdef USEAPI_JACK + if (sys_audioapiopened == API_JACK) { + if (jack_get_srate()) { + audio_rate = jack_get_srate(); + } + } +#endif /* JACK */ *prate = audio_rate; *padvance = audio_advance; *pcallback = audio_callback; - *pblocksize = audio_blocksize; } void sys_save_audio_params( int naudioindev, int *audioindev, int *chindev, int naudiooutdev, int *audiooutdev, int *choutdev, - int rate, int advance, int callback, int blocksize) + int rate, int advance, int callback) { int i; audio_naudioindev = naudioindev; @@ -117,7 +130,6 @@ void sys_save_audio_params( audio_rate = rate; audio_advance = advance; audio_callback = callback; - audio_blocksize = blocksize; } /* init routines for any API which needs to set stuff up before @@ -159,8 +171,8 @@ void sys_setchsr(int chin, int chout, int sr) sys_outchannels = chout; sys_dacsr = sr; sys_advance_samples = (sys_schedadvance * sys_dacsr) / (1000000.); - if (sys_advance_samples < DEFDACBLKSIZE) - sys_advance_samples = DEFDACBLKSIZE; + if (sys_advance_samples < 3 * DEFDACBLKSIZE) + sys_advance_samples = 3 * DEFDACBLKSIZE; sys_soundin = (t_sample *)getbytes(inbytes); memset(sys_soundin, 0, inbytes); @@ -183,7 +195,7 @@ void sys_setchsr(int chin, int chout, int sr) 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 blocksize) + int *choutdev, int rate, int advance, int callback) { int i, *ip; int defaultchannels = SYS_DEFAULTCH; @@ -198,10 +210,8 @@ void sys_set_audio_settings(int naudioindev, int *audioindev, int nchindev, if (rate < 1) rate = DEFAULTSRATE; - if (advance < 0) + if (advance <= 0) advance = DEFAULTADVANCE; - if (blocksize != (1 << ilog2(blocksize)) || blocksize < DEFDACBLKSIZE) - blocksize = DEFDACBLKSIZE; audio_init(); /* Since the channel vector might be longer than the audio device vector, or vice versa, we fill the shorter one @@ -329,8 +339,7 @@ void sys_set_audio_settings(int naudioindev, int *audioindev, int nchindev, audio_nextinchans = inchans; audio_nextoutchans = outchans; sys_save_audio_params(nrealindev, realindev, realinchans, - nrealoutdev, realoutdev, realoutchans, rate, advance, callback, - blocksize); + nrealoutdev, realoutdev, realoutchans, rate, advance, callback); } void sys_close_audio(void) @@ -365,21 +374,6 @@ void sys_close_audio(void) if (sys_audioapiopened == API_MMIO) mmio_close_audio(); else -#endif -#ifdef USEAPI_AUDIOUNIT - if (sys_audioapiopened == API_AUDIOUNIT) - audiounit_close_audio(); - else -#endif -#ifdef USEAPI_ESD - if (sys_audioapiopened == API_ESD) - esd_close_audio(); - else -#endif -#ifdef USEAPI_DUMMY - if (sys_audioapiopened == API_DUMMY) - dummy_close_audio(); - else #endif post("sys_close_audio: unknown API %d", sys_audioapiopened); sys_inchannels = sys_outchannels = 0; @@ -387,8 +381,6 @@ void sys_close_audio(void) sched_set_using_audio(SCHED_AUDIO_NONE); audio_state = 0; audio_callback_is_open = 0; - - sys_vgui("set pd_whichapi 0\n"); } /* open audio using whatever parameters were last used */ @@ -396,10 +388,9 @@ void sys_reopen_audio( void) { int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV]; int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV]; - int rate, advance, callback, blocksize, outcome = 0; + int rate, advance, callback, outcome = 0; sys_get_audio_params(&naudioindev, audioindev, chindev, - &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback, - &blocksize); + &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback); sys_setchsr(audio_nextinchans, audio_nextoutchans, rate); if (!naudioindev && !naudiooutdev) { @@ -409,9 +400,7 @@ void sys_reopen_audio( void) #ifdef USEAPI_PORTAUDIO if (sys_audioapi == API_PORTAUDIO) { - int blksize = (audio_blocksize ? audio_blocksize : 64); - if (sys_verbose) - fprintf(stderr, "blksize %d, advance %d\n", blksize, sys_advance_samples/blksize); + 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, @@ -424,16 +413,14 @@ void sys_reopen_audio( void) #ifdef USEAPI_JACK if (sys_audioapi == API_JACK) outcome = jack_open_audio((naudioindev > 0 ? chindev[0] : 0), - (naudioindev > 0 ? choutdev[0] : 0), rate, - (callback ? sched_audio_callbackfn : 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, - audio_blocksize); + chindev, naudiooutdev, audiooutdev, naudiooutdev, choutdev, rate); else #endif #ifdef USEAPI_ALSA @@ -441,32 +428,13 @@ void sys_reopen_audio( void) 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, - audio_blocksize); + 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, - audio_blocksize); - else -#endif -#ifdef USEAPI_AUDIOUNIT - if (sys_audioapi == API_AUDIOUNIT) - outcome = audiounit_open_audio((naudioindev > 0 ? chindev[0] : 0), - (naudioindev > 0 ? choutdev[0] : 0), rate); - else -#endif -#ifdef USEAPI_ESD - if (sys_audioapi == API_ALSA) - outcome = esd_open_audio(naudioindev, audioindev, naudioindev, chindev, naudiooutdev, audiooutdev, naudiooutdev, choutdev, rate); - else -#endif -#ifdef USEAPI_DUMMY - if (sys_audioapi == API_DUMMY) - outcome = dummy_open_audio(naudioindev, naudiooutdev, rate); else #endif if (sys_audioapi == API_NONE) @@ -539,21 +507,6 @@ int sys_send_dacs(void) if (sys_audioapi == API_MMIO) return (mmio_send_dacs()); else -#endif -#ifdef USEAPI_AUDIOUNIT - if (sys_audioapi == API_AUDIOUNIT) - return (audiounit_send_dacs()); - else -#endif -#ifdef USEAPI_ESD - if (sys_audioapi == API_ESD) - return (esd_send_dacs()); - else -#endif -#ifdef USEAPI_DUMMY - if (sys_audioapi == API_DUMMY) - return (dummy_send_dacs()); - else #endif post("unknown API"); return (0); @@ -611,7 +564,6 @@ static void audio_getdevs(char *indevlist, int *nindevs, { jack_getdevs(indevlist, nindevs, outdevlist, noutdevs, canmulti, maxndev, devdescsize); - *cancallback = 1; } else #endif @@ -638,28 +590,6 @@ static void audio_getdevs(char *indevlist, int *nindevs, maxndev, devdescsize); } else -#endif -#ifdef USEAPI_AUDIOUNIT - if (sys_audioapi == API_AUDIOUNIT) - { - } - else -#endif -#ifdef USEAPI_ESD - if (sys_audioapi == API_ESD) - { - esd_getdevs(indevlist, nindevs, outdevlist, noutdevs, canmulti, - maxndev, devdescsize); - } - else -#endif -#ifdef USEAPI_DUMMY - if (sys_audioapi == API_DUMMY) - { - dummy_getdevs(indevlist, nindevs, outdevlist, noutdevs, canmulti, - maxndev, devdescsize); - } - else #endif { /* this shouldn't happen once all the above get filled in. */ @@ -720,7 +650,7 @@ void glob_audio_properties(t_pd *dummy, t_floatarg flongform) audioinchan1, audioinchan2, audioinchan3, audioinchan4, audiooutdev1, audiooutdev2, audiooutdev3, audiooutdev4, audiooutchan1, audiooutchan2, audiooutchan3, audiooutchan4; - int rate, advance, callback, blocksize; + 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; @@ -739,8 +669,13 @@ void glob_audio_properties(t_pd *dummy, t_floatarg flongform) outdevlist + i * DEVDESCSIZE); sys_get_audio_params(&naudioindev, audioindev, chindev, - &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback, - &blocksize); + &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback); + +#ifdef USEAPI_JACK + if (sys_audioapiopened == API_JACK) { + sys_setchsr(audio_nextinchans, audio_nextoutchans, rate); + } +#endif /* JACK */ /* post("naudioindev %d naudiooutdev %d longform %f", naudioindev, naudiooutdev, flongform); */ @@ -767,13 +702,13 @@ void glob_audio_properties(t_pd *dummy, t_floatarg flongform) "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 %d\n", +%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), blocksize); + (flongform != 0)); gfxstub_deleteforkey(0); gfxstub_new(&glob_pdobject, (void *)glob_audio_properties, buf); } @@ -792,7 +727,6 @@ void glob_audio_dialog(t_pd *dummy, t_symbol *s, int argc, t_atom *argv) int newrate = atom_getintarg(16, argc, argv); int newadvance = atom_getintarg(17, argc, argv); int newcallback = atom_getintarg(18, argc, argv); - int newblocksize = atom_getintarg(19, argc, argv); for (i = 0; i < 4; i++) { @@ -825,27 +759,14 @@ void glob_audio_dialog(t_pd *dummy, t_symbol *s, int argc, t_atom *argv) } } - sys_set_audio_settings_reopen(nindev, newaudioindev, nindev, newaudioinchan, - noutdev, newaudiooutdev, noutdev, newaudiooutchan, - newrate, newadvance, newcallback, newblocksize); -} - -void sys_set_audio_settings_reopen(int naudioindev, int *audioindev, int nchindev, - int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev, - int *choutdev, int rate, int advance, int callback, int newblocksize) -{ - if (callback < 0) - callback = 0; - if (newblocksize != (1<<ilog2(newblocksize)) || - newblocksize < DEFDACBLKSIZE || newblocksize > 2048) - newblocksize = DEFDACBLKSIZE; - - if (!audio_callback_is_open && !callback) + if (newcallback < 0) + newcallback = 0; + if (!audio_callback_is_open && !newcallback) sys_close_audio(); - sys_set_audio_settings(naudioindev, audioindev, nchindev, chindev, - naudiooutdev, audiooutdev, nchoutdev, choutdev, - rate, advance, (callback >= 0 ? callback : 0), newblocksize); - if (!audio_callback_is_open && !callback) + 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(); } @@ -876,35 +797,20 @@ void sys_listdevs(void ) if (sys_audioapi == API_MMIO) sys_listaudiodevs(); else -#endif -#ifdef USEAPI_AUDIOUNIT - if (sys_audioapi == API_AUDIOUNIT) - sys_listaudiodevs(); - else -#endif -#ifdef USEAPI_ESD - if (sys_audioapi == API_ESD) - sys_listaudiodevs(); - else -#endif -#ifdef USEAPI_DUMMY - if (sys_audioapi == API_DUMMY) - sys_listaudiodevs(); - else #endif post("unknown API"); sys_listmididevs(); } -void sys_get_audio_devs(char *indevlist, int *nindevs, - char *outdevlist, int *noutdevs, int *canmulti, int *cancallback, - int maxndev, int devdescsize) +void sys_setblocksize(int n) { - audio_getdevs(indevlist, nindevs, - outdevlist, noutdevs, - canmulti, cancallback, - maxndev, devdescsize); + 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) @@ -986,15 +892,6 @@ void sys_get_audio_apis(char *buf) #endif #ifdef USEAPI_JACK sprintf(buf + strlen(buf), "{jack %d} ", API_JACK); n++; -#endif -#ifdef USEAPI_AUDIOUNIT - sprintf(buf + strlen(buf), "{AudioUnit %d} ", API_AUDIOUNIT); n++; -#endif -#ifdef USEAPI_ESD - sprintf(buf + strlen(buf), "{ESD %d} ", API_ESD); n++; -#endif -#ifdef USEAPI_DUMMY - sprintf(buf + strlen(buf), "{dummy %d} ", API_DUMMY); n++; #endif strcat(buf, "}"); /* then again, if only one API (or none) we don't offer any choice. */ diff --git a/src/s_audio_alsa.c b/src/s_audio_alsa.c index cf731109156dff7bdab17da6543fc791e65f2d12..a5034c8dc4a8550dbb8900d4a096745a17f810b9 100644 --- a/src/s_audio_alsa.c +++ b/src/s_audio_alsa.c @@ -90,17 +90,9 @@ static int alsaio_canmmap(t_alsa_dev *dev) return ((err1 < 0) && (err2 >= 0)); } -static void check_setup_error(int err, int out, const char *why) { - char bf[256]; - snprintf(bf, sizeof bf, "%s (%s)", why, out ? "output" : "input"); - check_error(err, bf); -} - static int alsaio_setup(t_alsa_dev *dev, int out, int *channels, int *rate, int nfrags, int frag_size) { -#define CHECK_ERROR(why_) check_setup_error(err, out, why_) - int bufsizeforthis, err; snd_pcm_hw_params_t* hw_params; unsigned int tmp_uint; @@ -118,14 +110,14 @@ static int alsaio_setup(t_alsa_dev *dev, int out, int *channels, int *rate, /* get the default params */ err = snd_pcm_hw_params_any(dev->a_handle, hw_params); - CHECK_ERROR("snd_pcm_hw_params_any"); + check_error(err, "snd_pcm_hw_params_any"); /* try to set interleaved access */ err = snd_pcm_hw_params_set_access(dev->a_handle, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED); if (err < 0) return (-1); - CHECK_ERROR("snd_pcm_hw_params_set_access"); + check_error(err, "snd_pcm_hw_params_set_access"); #if 0 /* enable this to print out which formats are available */ { int i; @@ -149,7 +141,7 @@ static int alsaio_setup(t_alsa_dev *dev, int out, int *channels, int *rate, "PD-ALSA: 32/24 bit format not available - using 16\n"); */ err = snd_pcm_hw_params_set_format(dev->a_handle, hw_params, SND_PCM_FORMAT_S16); - CHECK_ERROR("_pcm_hw_params_set_format"); + check_error(err, "snd_pcm_hw_params_set_format"); dev->a_sampwidth = 2; } else dev->a_sampwidth = 3; @@ -162,22 +154,22 @@ static int alsaio_setup(t_alsa_dev *dev, int out, int *channels, int *rate, /* set the subformat */ err = snd_pcm_hw_params_set_subformat(dev->a_handle, hw_params, SND_PCM_SUBFORMAT_STD); - CHECK_ERROR("snd_pcm_hw_params_set_subformat"); + check_error(err, "snd_pcm_hw_params_set_subformat"); /* set the number of channels */ tmp_uint = *channels; err = snd_pcm_hw_params_set_channels_min(dev->a_handle, hw_params, &tmp_uint); - CHECK_ERROR("snd_pcm_hw_params_set_channels"); + check_error(err, "snd_pcm_hw_params_set_channels"); if (tmp_uint != (unsigned)*channels) post("ALSA: set %s channels to %d", (out?"output":"input"), tmp_uint); *channels = tmp_uint; dev->a_channels = *channels; /* set the sampling rate */ - err = snd_pcm_hw_params_set_rate_near(dev->a_handle, hw_params, + err = snd_pcm_hw_params_set_rate_min(dev->a_handle, hw_params, (unsigned int *)rate, 0); - CHECK_ERROR("snd_pcm_hw_params_set_rate_min"); + check_error(err, "snd_pcm_hw_params_set_rate_min (input)"); #if 0 err = snd_pcm_hw_params_get_rate(hw_params, &subunitdir); post("input sample rate %d", err); @@ -193,7 +185,7 @@ static int alsaio_setup(t_alsa_dev *dev, int out, int *channels, int *rate, err = snd_pcm_hw_params_set_period_size_near(dev->a_handle, hw_params, &tmp_snd_pcm_uframes, 0); #endif - CHECK_ERROR("snd_pcm_hw_params_set_period_size_near"); + check_error(err, "snd_pcm_hw_params_set_period_size_near (input)"); /* set the buffer size */ #ifdef ALSAAPI9 @@ -204,10 +196,10 @@ static int alsaio_setup(t_alsa_dev *dev, int out, int *channels, int *rate, err = snd_pcm_hw_params_set_buffer_size_near(dev->a_handle, hw_params, &tmp_snd_pcm_uframes); #endif - CHECK_ERROR("snd_pcm_hw_params_set_buffer_size_near"); + check_error(err, "snd_pcm_hw_params_set_buffer_size_near (input)"); err = snd_pcm_hw_params(dev->a_handle, hw_params); - CHECK_ERROR("snd_pcm_hw_params"); + check_error(err, "snd_pcm_hw_params (input)"); /* set up the buffer */ bufsizeforthis = DEFDACBLKSIZE * dev->a_sampwidth * *channels; @@ -235,19 +227,18 @@ static int alsaio_setup(t_alsa_dev *dev, int out, int *channels, int *rate, alsa_snd_bufsize = bufsizeforthis; } return (1); -#undef CHECK_ERROR } /* return 0 on success */ int alsa_open_audio(int naudioindev, int *audioindev, int nchindev, int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev, - int *choutdev, int rate, int blocksize) + int *choutdev, int rate) { int err, inchans = 0, outchans = 0, subunitdir; char devname[512]; snd_output_t* out; - int frag_size = (blocksize ? blocksize : ALSA_DEFFRAGSIZE); + int frag_size = (sys_blocksize ? sys_blocksize : ALSA_DEFFRAGSIZE); int nfrags, i, iodev, dev2; int wantinchans, wantoutchans, device; @@ -301,7 +292,7 @@ int alsa_open_audio(int naudioindev, int *audioindev, int nchindev, if (alsa_usemmap) { post("using mmap audio interface"); - if (alsamm_open_audio(rate, blocksize)) + if (alsamm_open_audio(rate)) goto blewit; else return (0); } @@ -478,7 +469,7 @@ int alsa_send_dacs(void) ((char *)(alsa_snd_buf))[3*j+1] = ((s>>8) & 255); ((char *)(alsa_snd_buf))[3*j+2] = ((s>>16) & 255); #else - fprintf(stderr, "big endian 24-bit not supported"); + fprintf(stderr("big endian 24-bit not supported"); #endif } for (; i < thisdevchans; i++, ch++) @@ -590,7 +581,7 @@ int alsa_send_dacs(void) * (1./ INT32_MAX); } #else - fprintf(stderr, "big endian 24-bit not supported"); + fprintf(stderr("big endian 24-bit not supported"); #endif } else diff --git a/src/s_audio_alsa.h b/src/s_audio_alsa.h index f59cff3c2bca40702695db653aa284bb5077710f..813be2114e8ec73b52bc67f4bef8da239e268abd 100644 --- a/src/s_audio_alsa.h +++ b/src/s_audio_alsa.h @@ -35,6 +35,6 @@ extern t_alsa_dev alsa_outdev[ALSA_MAXDEV]; extern int alsa_nindev; extern int alsa_noutdev; -int alsamm_open_audio(int rate, int blocksize); +int alsamm_open_audio(int rate); void alsamm_close_audio(void); int alsamm_send_dacs(void); diff --git a/src/s_audio_alsamm.c b/src/s_audio_alsamm.c index abcb0a85e703bfd17b65c0d858e60313090b83d3..3bc4b36925e05f51abfb560593043ed5f54812b6 100644 --- a/src/s_audio_alsamm.c +++ b/src/s_audio_alsamm.c @@ -182,7 +182,7 @@ static void check_error(int err, const char *why) error("%s: %s\n", why, snd_strerror(err)); } -int alsamm_open_audio(int rate, int blocksize) +int alsamm_open_audio(int rate) { int err; char devname[80]; @@ -238,16 +238,16 @@ int alsamm_open_audio(int rate, int blocksize) /* set the asked buffer time (alsa buffertime in us)*/ alsamm_buffertime = alsamm_buffersize = 0; - if(blocksize == 0) + if(sys_blocksize == 0) alsamm_buffertime = sys_schedadvance; else - alsamm_buffersize = blocksize; + alsamm_buffersize = sys_blocksize; if(sys_verbose) post("syschedadvance=%d us(%d Samples)so buffertime max should be this=%d" "or sys_blocksize=%d (samples) to use buffersize=%d", sys_schedadvance,sys_advance_samples,alsamm_buffertime, - blocksize,alsamm_buffersize); + sys_blocksize,alsamm_buffersize); alsamm_periods = 0; /* no one wants periods setting from command line ;-) */ diff --git a/src/s_audio_jack.c b/src/s_audio_jack.c index 79d4692eeb73b377d78be53a7479cecea0647221..5f793061d634e7128d28942bd8084627e007fd8b 100644 --- a/src/s_audio_jack.c +++ b/src/s_audio_jack.c @@ -11,140 +11,88 @@ #include <jack/jack.h> #include <regex.h> + #define MAX_CLIENTS 100 -#define MAX_JACK_PORTS 128 /* seems like higher values give bad xrun problems */ +#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; -static t_sample *jack_inbuf; +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[MAX_JACK_PORTS]; -static jack_port_t *output_port[MAX_JACK_PORTS]; +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; -static t_audiocallback jack_callback; + pthread_mutex_t jack_mutex; pthread_cond_t jack_sem; +int jack_get_srate(void) +{ + if (jack_client) return jack_get_sample_rate (jack_client); + else return 0; +} static int process (jack_nframes_t nframes, void *arg) { - int j; - jack_default_audio_sample_t *out, *in; - - pthread_mutex_lock(&jack_mutex); - 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\n"); - /* 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++) + 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)) { - *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++) + 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 { - *data++=*in++; + 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 + j * BUF_JACK, 0, BUF_JACK * sizeof(t_sample)); + 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; } - jack_filled = 0; - } - pthread_cond_broadcast(&jack_sem); - pthread_mutex_unlock(&jack_mutex); - return 0; -} - -static int callbackprocess(jack_nframes_t nframes, void *arg) -{ - int chan, j, k; - unsigned int n; - jack_default_audio_sample_t *out[MAX_JACK_PORTS], *in[MAX_JACK_PORTS], *jp; - - if (nframes % DEFDACBLKSIZE) - { - fprintf(stderr, "jack: nframes %d not a multiple of blocksize %d\n", - nframes, DEFDACBLKSIZE); - nframes -= (nframes % DEFDACBLKSIZE); - } - for (chan = 0; chan < sys_inchannels; chan++) - in[chan] = jack_port_get_buffer(input_port[chan], nframes); - for (chan = 0; chan < sys_outchannels; chan++) - out[chan] = jack_port_get_buffer(output_port[chan], nframes); - for (n = 0; n < nframes; n += DEFDACBLKSIZE) - { - t_sample *fp; - for (chan = 0; chan < sys_inchannels; chan++) - { - for (fp = sys_soundin + chan*DEFDACBLKSIZE, - jp = in[chan] + n, j=0; j < DEFDACBLKSIZE; j++) - *fp++ = *jp++; - } - for (chan = 0; chan < sys_outchannels; chan++) - { - for (fp = sys_soundout + chan*DEFDACBLKSIZE, - j = 0; j < DEFDACBLKSIZE; j++) - *fp++ = 0; - } - (*jack_callback)(); - for (chan = 0; chan < sys_outchannels; chan++) - { - for (fp = sys_soundout + chan*DEFDACBLKSIZE, jp = out[chan] + n, - j=0; j < DEFDACBLKSIZE; j++) - *jp++ = *fp++; - } - } - return 0; + pthread_cond_broadcast(&jack_sem); + return 0; } static int @@ -154,22 +102,16 @@ jack_srate (jack_nframes_t srate, void *arg) return 0; } - -void glob_audio_setapi(void *dummy, t_floatarg f); - static void jack_shutdown (void *arg) { - error("JACK: server shut down"); - - jack_deactivate (jack_client); - //jack_client_close(jack_client); /* likely to hang if the server shut down */ + verbose(1, "JACK-server shut down"); + sys_close_audio(); jack_client = NULL; - - glob_audio_setapi(NULL, API_NONE); // set pd_whichapi 0 } static int jack_xrun(void* arg) { + verbose(1, "JACK-server xrun"); jack_dio_error = 1; return 0; } @@ -187,55 +129,55 @@ static char** jack_get_clients(void) 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]; - - if(num_clients>=MAX_CLIENTS)break; - - - /* 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( "alsa_pcm", 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++; - } - } + if (jack_ports != NULL) { + 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]); */ @@ -263,7 +205,7 @@ static int jack_connect_ports(char* client) 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])); + error("JACK: cannot connect input ports %s -> %s", jack_ports[i],jack_port_name (input_port[i])); @@ -272,7 +214,7 @@ static int jack_connect_ports(char* client) 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]); + error("JACK: cannot connect output ports %s -> %s", jack_port_name (output_port[i]),jack_ports[i]); @@ -281,244 +223,200 @@ static int jack_connect_ports(char* client) } -static void pd_jack_error_callback(const char *desc) { - error("JACKerror: %s", desc); +void jack_error(const char *desc) { + error("JACK error: %s", desc); return; } -int -jack_open_audio(int inchans, int outchans, int rate, t_audiocallback callback) -{ - int j; - char port_name[80] = ""; - char client_name[80] = ""; - int client_iterator = 0; - int new_jack = 0; - int srate; - jack_status_t status; - - if (NULL==jack_client_new) - { - fprintf(stderr,"JACK framework not available\n"); - return 1; - } - - jack_dio_error = 0; +int +jack_open_audio(int inchans, int outchans, int rate) - if ((inchans == 0) && (outchans == 0)) return 0; +{ + int j; + char port_name[80] = ""; + int client_iterator = 0; + int new_jack = 0; + int srate; + jack_status_t status; - if (outchans > MAX_JACK_PORTS) { - error("JACK: %d output ports not supported, setting to %d", - outchans, MAX_JACK_PORTS); - outchans = MAX_JACK_PORTS; - } + jack_dio_error = 0; + + if ((inchans == 0) && (outchans == 0)) return 0; - if (inchans > MAX_JACK_PORTS) { - error("JACK: %d input ports not supported, setting to %d", - inchans, MAX_JACK_PORTS); - inchans = MAX_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(client_name,"pure_data_%d",client_iterator); - client_iterator++; - jack_client = jack_client_open (client_name, JackNullOption, &status, NULL); - if (status & JackServerFailed) { - error("JACK: unable to connect to JACK server"); - jack_client=NULL; - break; - } - } while (status & JackNameNotUnique); + if (outchans > NUM_JACK_PORTS) { + error("JACK: %d output ports not supported, setting to %d",outchans, NUM_JACK_PORTS); + outchans = NUM_JACK_PORTS; + } - if(status) { - if (status & JackServerStarted) { - verbose(1, "JACK: started server"); - } else { - error("JACK: server returned status %d", status); - } + if (inchans > NUM_JACK_PORTS) { + error("JACK: %d input ports not supported, setting to %d",inchans, NUM_JACK_PORTS); + inchans = NUM_JACK_PORTS; } - verbose(1, "JACK: started server as '%s'", client_name); + /* 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) { - /* jack spits out enough messages already, do not warn */ + 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; - } - - sys_inchannels = inchans; - sys_outchannels = outchans; - if (jack_inbuf) - free(jack_inbuf); - if (sys_inchannels) - jack_inbuf = calloc(sizeof(t_sample), sys_inchannels * BUF_JACK); - if (jack_outbuf) - free(jack_outbuf); - if (sys_outchannels) - jack_outbuf = calloc(sizeof(t_sample), sys_outchannels * BUF_JACK); - - jack_get_clients(); - - /* tell the JACK server to call `process()' whenever - there is work to be done. - */ - jack_callback = callback; - jack_set_process_callback (jack_client, - (callback? callbackprocess : process), 0); - - jack_set_error_function (pd_jack_error_callback); - + } + + 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); + 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<sys_inchannels; j++) - input_port[j]=NULL; - for (j=0; j<sys_outchannels; j++) - 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; + + /* 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; } - } - 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; + /* 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; + } } - } - outport_count = outchans; - /* tell the JACK server that we are ready to roll */ + 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; - if (new_jack) { - if (jack_activate (jack_client)) { - error("cannot activate client"); + /* 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; - } - - for (j = 0; j < outchans; j++) - memset(jack_outbuf + j * BUF_JACK, 0, - BUF_JACK * sizeof(t_sample)); - - if (jack_client_names[0]) + } + + 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; + pthread_mutex_init(&jack_mutex,NULL); + pthread_cond_init(&jack_sem,NULL); + } + return 0; } void jack_close_audio(void) -{ - if (jack_client){ - jack_deactivate (jack_client); - jack_client_close(jack_client); - } - - jack_client=NULL; - jack_started = 0; - pthread_cond_broadcast(&jack_sem); - - pthread_cond_destroy(&jack_sem); - pthread_mutex_destroy(&jack_mutex); - if (jack_inbuf) - free(jack_inbuf), jack_inbuf = 0; - if (jack_outbuf) - free(jack_outbuf), jack_outbuf = 0; - +{ + jack_started = 0; + pthread_cond_broadcast(&jack_sem); } 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; - } - pthread_mutex_lock(&jack_mutex); - if (jack_filled >= jack_out_max) - pthread_cond_wait(&jack_sem,&jack_mutex); - - if (!jack_client) - { - pthread_mutex_unlock(&jack_mutex); - return SENDDACS_NO; - } - jack_started = 1; + 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; + } - 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; - } - jack_filled += DEFDACBLKSIZE; - pthread_mutex_unlock(&jack_mutex); + if ((timenow = sys_getrealtime()) - timeref > 0.002) + { + rtnval = SENDDACS_SLEPT; + } - if ((timenow = sys_getrealtime()) - timeref > 0.002) - { - rtnval = SENDDACS_SLEPT; - } - memset(sys_soundout, 0, DEFDACBLKSIZE*sizeof(t_sample)*sys_outchannels); - return rtnval; + memset(sys_soundout,0,DEFDACBLKSIZE*sizeof(t_sample)*sys_outchannels); + jack_filled += DEFDACBLKSIZE; + return rtnval; } void jack_getdevs(char *indevlist, int *nindevs, @@ -538,7 +436,7 @@ void jack_getdevs(char *indevlist, int *nindevs, void jack_listdevs( void) { - post("device listing not implemented for jack yet\n"); + error("device listing not implemented for jack yet"); } #endif /* JACK */ diff --git a/src/s_audio_oss.c b/src/s_audio_oss.c index 10329fed9f4973d0dcd4e84897809bbba9064bac..73f916ce2f6f1fb78bdc7f662f3dadc87bb8fede 100644 --- a/src/s_audio_oss.c +++ b/src/s_audio_oss.c @@ -5,11 +5,7 @@ /* this file inputs and outputs audio using the OSS API available on linux. */ -#if defined(__FreeBSD_kernel__) -# include <sys/soundcard.h> -#else -# include <linux/soundcard.h> -#endif +#include <linux/soundcard.h> #include "m_pd.h" #include "s_stuff.h" @@ -49,7 +45,7 @@ static int linux_meters; /* true if we're metering */ static t_sample linux_inmax; /* max input amplitude */ static t_sample linux_outmax; /* max output amplitude */ static int linux_fragsize = 0; /* for block mode; block size (sample frames) */ -extern int audio_blocksize; /* stolen from s_audio.c */ + /* our device handles */ typedef struct _oss_dev @@ -125,8 +121,7 @@ int oss_reset(int fd) { return err; } -void oss_configure(t_oss_dev *dev, int srate, int dac, int skipblocksize, - int suggestedblocksize) +void oss_configure(t_oss_dev *dev, int srate, int dac, int skipblocksize) { int orig, param, nblk, fd = dev->d_fd, wantformat; int nchannels = dev->d_nchannels; @@ -158,7 +153,7 @@ void oss_configure(t_oss_dev *dev, int srate, int dac, int skipblocksize, { int fragbytes, logfragsize, nfragment; /* setting fragment count and size. */ - linux_fragsize = suggestedblocksize; + linux_fragsize = sys_blocksize; if (!linux_fragsize) { linux_fragsize = OSS_DEFFRAGSIZE; @@ -261,8 +256,7 @@ whynot: #define O_AUDIOFLAG O_NDELAY int oss_open_audio(int nindev, int *indev, int nchin, int *chin, - int noutdev, int *outdev, int nchout, int *chout, int rate, - int blocksize) + int noutdev, int *outdev, int nchout, int *chout, int rate) { int capabilities = 0; int inchannels = 0, outchannels = 0; @@ -364,7 +358,7 @@ int oss_open_audio(int nindev, int *indev, int nchin, int *chin, { linux_dacs[linux_noutdevs].d_nchannels = gotchans; linux_dacs[linux_noutdevs].d_fd = fd; - oss_configure(linux_dacs+linux_noutdevs, rate, 1, 0, blocksize); + oss_configure(linux_dacs+linux_noutdevs, rate, 1, 0); linux_noutdevs++; outchannels += gotchans; @@ -439,8 +433,7 @@ int oss_open_audio(int nindev, int *indev, int nchin, int *chin, linux_adcs[linux_nindevs].d_nchannels = gotchans; - oss_configure(linux_adcs+linux_nindevs, rate, 0, alreadyopened, - blocksize); + oss_configure(linux_adcs+linux_nindevs, rate, 0, alreadyopened); inchannels += gotchans; linux_nindevs++; diff --git a/src/s_file.c b/src/s_file.c index 7d4ddb6fa3654529e7e85960cd71ac45bc390de2..7fe081a508c6ebc8028cfd97a0c3bc78f6f7de7b 100644 --- a/src/s_file.c +++ b/src/s_file.c @@ -322,8 +322,7 @@ void sys_loadpreferences( void) int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV]; int nmidiindev, midiindev[MAXMIDIINDEV]; int nmidioutdev, midioutdev[MAXMIDIOUTDEV]; - int i, rate = 0, advance = -1, callback = 0, blocksize = 0, - api, nolib, maxi; + int i, rate = 0, advance = 0, callback = 0, api, nolib, maxi; char prefbuf[MAXPDSTRING], keybuf[80]; sys_initloadpreferences(); @@ -374,11 +373,9 @@ void sys_loadpreferences( void) sscanf(prefbuf, "%d", &advance); if (sys_getpreference("callback", prefbuf, MAXPDSTRING)) sscanf(prefbuf, "%d", &callback); - if (sys_getpreference("blocksize", prefbuf, MAXPDSTRING)) - sscanf(prefbuf, "%d", &blocksize); sys_set_audio_settings(naudioindev, audioindev, naudioindev, chindev, naudiooutdev, audiooutdev, naudiooutdev, choutdev, rate, advance, - callback, blocksize); + callback); /* load MIDI preferences */ /* JMZ/MB: brackets for initializing */ @@ -463,7 +460,7 @@ void glob_savepreferences(t_pd *dummy) { int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV]; int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV]; - int i, rate, advance, callback, blocksize; + int i, rate, advance, callback; char buf1[MAXPDSTRING], buf2[MAXPDSTRING]; int nmidiindev, midiindev[MAXMIDIINDEV]; int nmidioutdev, midioutdev[MAXMIDIOUTDEV]; @@ -476,8 +473,7 @@ void glob_savepreferences(t_pd *dummy) sys_putpreference("audioapi", buf1); sys_get_audio_params(&naudioindev, audioindev, chindev, - &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback, - &blocksize); + &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback); sys_putpreference("noaudioin", (naudioindev <= 0 ? "True" : "False")); for (i = 0; i < naudioindev; i++) @@ -503,9 +499,6 @@ void glob_savepreferences(t_pd *dummy) sprintf(buf1, "%d", callback); sys_putpreference("callback", buf1); - sprintf(buf1, "%d", blocksize); - sys_putpreference("blocksize", buf1); - /* MIDI settings */ sys_get_midi_params(&nmidiindev, midiindev, &nmidioutdev, midioutdev); sys_putpreference("nomidiin", (nmidiindev <= 0 ? "True" : "False")); diff --git a/src/s_main.c b/src/s_main.c index af13585c03b2e7dd9cc381b7976799dfa9d26266..7f4079e49bdd8e36684e3abfa852fea81fcb349e 100644 --- a/src/s_main.c +++ b/src/s_main.c @@ -73,7 +73,6 @@ char sys_fontweight[] = "normal"; /* currently only used for iemguis */ static int sys_main_srate; static int sys_main_advance; static int sys_main_callback; -static int sys_main_blocksize; static int sys_listplease; int sys_externalschedlib; @@ -583,7 +582,7 @@ int sys_argparse(int argc, char **argv) } else if (!strcmp(*argv, "-blocksize")) { - sys_main_blocksize = atoi(argv[1]); + sys_setblocksize(atoi(argv[1])); argc -= 2; argv += 2; } else if (!strcmp(*argv, "-sleepgrain") && (argc > 1)) @@ -929,7 +928,7 @@ static void sys_afterargparse(void) int i; int naudioindev, audioindev[MAXAUDIOINDEV], chindev[MAXAUDIOINDEV]; int naudiooutdev, audiooutdev[MAXAUDIOOUTDEV], choutdev[MAXAUDIOOUTDEV]; - int nchindev, nchoutdev, rate, advance, callback, blocksize; + int nchindev, nchoutdev, rate, advance, callback; int nmidiindev = 0, midiindev[MAXMIDIINDEV]; int nmidioutdev = 0, midioutdev[MAXMIDIOUTDEV]; /* add "extra" library to path */ @@ -965,8 +964,7 @@ static void sys_afterargparse(void) else are the default. Overwrite them with any results of argument parsing, and store them again. */ sys_get_audio_params(&naudioindev, audioindev, chindev, - &naudiooutdev, audiooutdev, choutdev, &rate, &advance, - &callback, &blocksize); + &naudiooutdev, audiooutdev, choutdev, &rate, &advance, &callback); if (sys_nchin >= 0) { nchindev = sys_nchin; @@ -1014,11 +1012,9 @@ static void sys_afterargparse(void) rate = sys_main_srate; if (sys_main_callback) callback = sys_main_callback; - if (sys_main_blocksize) - blocksize = sys_main_blocksize; sys_set_audio_settings(naudioindev, audioindev, nchindev, chindev, naudiooutdev, audiooutdev, nchoutdev, choutdev, rate, advance, - callback, blocksize); + callback); sys_open_midi(nmidiindev, midiindev, nmidioutdev, midioutdev, 0); } diff --git a/src/s_stuff.h b/src/s_stuff.h index 18e602abcd534b4735533f5d1d0c3eb8731e7347..ceec125ffc33cbc5d1e2522bb90a1b247d730675 100644 --- a/src/s_stuff.h +++ b/src/s_stuff.h @@ -78,17 +78,12 @@ extern int sys_blocksize; /* audio I/O block size in sample frames */ extern t_float sys_dacsr; extern int sys_schedadvance; extern int sys_sleepgrain; -EXTERN void sys_set_audio_settings(int naudioindev, int *audioindev, +void sys_set_audio_settings(int naudioindev, int *audioindev, int nchindev, int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev, - int srate, int advance, int callback, int blocksize); -/* the same as above, but reopens the audio subsystem if needed */ -EXTERN void sys_set_audio_settings_reopen(int naudioindev, int *audioindev, - int nchindev, int *chindev, - int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev, - int srate, int advance, int callback, int blocksize); -EXTERN void sys_reopen_audio( void); -EXTERN void sys_close_audio(void); + int srate, int advance, int callback); +void sys_reopen_audio( void); +void sys_close_audio(void); int sys_send_dacs(void); @@ -241,7 +236,7 @@ void pa_getdevs(char *indevlist, int *nindevs, int oss_open_audio(int naudioindev, int *audioindev, int nchindev, int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev, - int *choutdev, int rate, int blocksize); + int *choutdev, int rate); void oss_close_audio(void); int oss_send_dacs(void); void oss_reportidle(void); @@ -251,7 +246,7 @@ void oss_getdevs(char *indevlist, int *nindevs, int alsa_open_audio(int naudioindev, int *audioindev, int nchindev, int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev, - int *choutdev, int rate, int blocksize); + int *choutdev, int rate); void alsa_close_audio(void); int alsa_send_dacs(void); void alsa_reportidle(void); @@ -259,8 +254,7 @@ void alsa_getdevs(char *indevlist, int *nindevs, char *outdevlist, int *noutdevs, int *canmulti, int maxndev, int devdescsize); -int jack_open_audio(int wantinchans, int wantoutchans, int srate, - t_audiocallback callback); +int jack_open_audio(int wantinchans, int wantoutchans, int srate); void jack_close_audio(void); int jack_send_dacs(void); void jack_reportidle(void); @@ -271,7 +265,7 @@ void jack_listdevs(void); int mmio_open_audio(int naudioindev, int *audioindev, int nchindev, int *chindev, int naudiooutdev, int *audiooutdev, - int nchoutdev, int *choutdev, int rate, int blocksize); + int nchoutdev, int *choutdev, int rate); void mmio_close_audio( void); void mmio_reportidle(void); int mmio_send_dacs(void); @@ -279,33 +273,6 @@ void mmio_getdevs(char *indevlist, int *nindevs, char *outdevlist, int *noutdevs, int *canmulti, int maxndev, int devdescsize); -int audiounit_open_audio(int naudioindev, int *audioindev, int nchindev, - int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev, - int *choutdev, int rate); -void audiounit_close_audio(void); -int audiounit_send_dacs(void); -void audiounit_listdevs(void); -void audiounit_getdevs(char *indevlist, int *nindevs, - char *outdevlist, int *noutdevs, int *canmulti, - int maxndev, int devdescsize); - -int esd_open_audio(int naudioindev, int *audioindev, int nchindev, - int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev, - int *choutdev, int rate); -void esd_close_audio(void); -int esd_send_dacs(void); -void esd_listdevs(void); -void esd_getdevs(char *indevlist, int *nindevs, - char *outdevlist, int *noutdevs, int *canmulti, - int maxndev, int devdescsize); - -int dummy_open_audio(int nin, int nout, int sr); -int dummy_close_audio( void); -int dummy_send_dacs( void); -void dummy_getdevs(char *indevlist, int *nindevs, char *outdevlist, - int *noutdevs, int *canmulti, int maxndev, int devdescsize); -void dummy_listdevs( void); - void sys_listmididevs(void); void sys_set_midi_api(int whichapi); void sys_set_audio_api(int whichapi); @@ -317,14 +284,14 @@ void sys_set_audio_state(int onoff); void oss_set32bit( void); void linux_alsa_devname(char *devname); -EXTERN void sys_get_audio_params( +void sys_get_audio_params( int *pnaudioindev, int *paudioindev, int *chindev, int *pnaudiooutdev, int *paudiooutdev, int *choutdev, - int *prate, int *padvance, int *callback, int *blocksize); + int *prate, int *padvance, int *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 blocksize); + int rate, int advance, int callback); /* s_file.c */