diff --git a/extra/sigmund~/sigmund~.c b/extra/sigmund~/sigmund~.c index 03e4ab550d9b7a38b95a362acac23acb3812a8f3..776696019db1b356ce625f24726b6752e77f8518 100644 --- a/extra/sigmund~/sigmund~.c +++ b/extra/sigmund~/sigmund~.c @@ -1457,7 +1457,7 @@ static void *sigmund_new(t_symbol *s, long ac, t_atom *av) dsp_setup((t_pxobject *)x, 1); object_obex_store(x, gensym("dumpout"), outlet_new(x, NULL)); - for (i = 0; i < ac; i++) FIXME + for (i = 0; i < ac; i++) if (av[i].a_type == A_SYM) { char *s = av[i].a_w.w_sym->s_name; diff --git a/src/s_audio_alsa.c b/src/s_audio_alsa.c index 6733182da80a338c907432396d7328d618126a76..dad2c86f5213592b3e92874cd612131243361d06 100644 --- a/src/s_audio_alsa.c +++ b/src/s_audio_alsa.c @@ -25,6 +25,7 @@ #include <sched.h> #include <sys/mman.h> #include "s_audio_alsa.h" +#include <endian.h> /* Defines */ #define DEBUG(x) x @@ -117,17 +118,33 @@ static int alsaio_setup(t_alsa_dev *dev, int out, int *channels, int *rate, if (err < 0) return (-1); check_error(err, "snd_pcm_hw_params_set_access"); +#if 0 /* enable this to print out which formats are available */ + { + int i; + for (i = 0; i <= SND_PCM_FORMAT_LAST; i++) + fprintf(stderr, "%d -> %d\n", + i, snd_pcm_hw_params_test_format(dev->a_handle, hw_params, i)); + } +#endif /* Try to set 32 bit format first */ err = snd_pcm_hw_params_set_format(dev->a_handle, hw_params, SND_PCM_FORMAT_S32); if (err < 0) { /* fprintf(stderr, - "PD-ALSA: 32 bit format not available - using 16\n"); */ + "PD-ALSA: 32 bit format not available - trying 24\n"); */ err = snd_pcm_hw_params_set_format(dev->a_handle, hw_params, - SND_PCM_FORMAT_S16); - check_error(err, "snd_pcm_hw_params_set_format"); - dev->a_sampwidth = 2; + SND_PCM_FORMAT_S24_3LE); + if (err < 0) + { + /* fprintf(stderr, + "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(err, "snd_pcm_hw_params_set_format"); + dev->a_sampwidth = 2; + } + else dev->a_sampwidth = 3; } else dev->a_sampwidth = 4; @@ -436,7 +453,32 @@ int alsa_send_dacs(void) for (j = ch, k = DEFDACBLKSIZE; k--; j += thisdevchans) ((t_alsa_sample32 *)alsa_snd_buf)[j] = 0; } - else + else if (alsa_outdev[iodev].a_sampwidth == 3) + { + for (i = 0; i < chans; i++, ch++, fp1 += DEFDACBLKSIZE) + for (j = ch, k = DEFDACBLKSIZE, fp2 = fp1; k--; + j += thisdevchans, fp2++) + { + int s = *fp2 * 8388352.; + if (s > 8388351) + s = 8388351; + else if (s < -8388351) + s = -8388351; +#if BYTE_ORDER == LITTLE_ENDIAN + ((char *)(alsa_snd_buf))[3*j] = (s & 255); + ((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"); +#endif + } + for (; i < thisdevchans; i++, ch++) + for (j = ch, k = DEFDACBLKSIZE; k--; j += thisdevchans) + ((char *)(alsa_snd_buf))[3*j] = + ((char *)(alsa_snd_buf))[3*j+1] = + ((char *)(alsa_snd_buf))[3*j+2] = 0; + } + else /* 16 bit samples */ { for (i = 0; i < chans; i++, ch++, fp1 += DEFDACBLKSIZE) for (j = ch, k = DEFDACBLKSIZE, fp2 = fp1; k--; @@ -525,6 +567,23 @@ int alsa_send_dacs(void) * (1./ INT32_MAX); } } + else if (alsa_indev[iodev].a_sampwidth == 3) + { +#if BYTE_ORDER == LITTLE_ENDIAN + for (i = 0; i < chans; i++, ch++, fp1 += DEFDACBLKSIZE) + { + for (j = ch, k = DEFDACBLKSIZE, fp2 = fp1; k--; + j += thisdevchans, fp2++) + *fp2 = ((float) ( + (((unsigned char *)alsa_snd_buf)[3*j] << 8) + | (((unsigned char *)alsa_snd_buf)[3*j+1] << 16) + | (((unsigned char *)alsa_snd_buf)[3*j+2] << 24))) + * (1./ INT32_MAX); + } +#else + fprintf(stderr("big endian 24-bit not supported"); +#endif + } else { for (i = 0; i < chans; i++, ch++, fp1 += DEFDACBLKSIZE) diff --git a/src/s_audio_pa.c b/src/s_audio_pa.c index e02cbc9e1f6ba91f1f7c5bdcc053b4693757aaba..4ceeb6c6aa7423524a7a8a77ea7af2091c1237b9 100644 --- a/src/s_audio_pa.c +++ b/src/s_audio_pa.c @@ -11,6 +11,7 @@ #include "s_stuff.h" #include <stdio.h> #include <stdlib.h> +#include <unistd.h> #include <portaudio.h> #include "s_audio_pablio.h" @@ -29,6 +30,34 @@ static t_audiocallback pa_callback; int pa_foo; +static void pa_init(void) +{ + static int initialized; + if (!initialized) + { + /* Initialize PortAudio */ + /* for some reason Pa_Initialize(0 closes file descriptor 1. + As a workaround, dup it to another number and dup2 it back + afterward. */ + int newfd = dup(1); + int err = Pa_Initialize(); + if (newfd >= 0) + { + dup2(newfd, 1); + close(newfd); + } + if ( err != paNoError ) + { + fprintf( stderr, + "Error number %d occured initializing portaudio\n", + err); + fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); + return; + } + initialized = 1; + } +} + static int pa_lowlevel_callback(const void *inputBuffer, void *outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo *outTime, PaStreamCallbackFlags myflags, @@ -155,25 +184,11 @@ int pa_open_audio(int inchans, int outchans, int rate, t_sample *soundin, int indeviceno, int outdeviceno, t_audiocallback callbackfn) { PaError err; - static int initialized; int j, devno, pa_indev = 0, pa_outdev = 0; pa_callback = callbackfn; /* fprintf(stderr, "open callback %d\n", (callbackfn != 0)); */ - if (!initialized) - { - /* Initialize PortAudio */ - int err = Pa_Initialize(); - if ( err != paNoError ) - { - fprintf( stderr, - "Error number %d occured initializing portaudio\n", - err); - fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) ); - return (1); - } - initialized = 1; - } + pa_init(); /* post("in %d out %d rate %d device %d", inchans, outchans, rate, deviceno); */ if (inchans > MAX_PA_CHANS) { @@ -349,7 +364,7 @@ void pa_listdevs(void) /* lifted from pa_devs.c in portaudio */ int numDevices; const PaDeviceInfo *pdi; PaError err; - Pa_Initialize(); + pa_init(); numDevices = Pa_GetDeviceCount(); if( numDevices < 0 ) { @@ -390,7 +405,7 @@ void pa_getdevs(char *indevlist, int *nindevs, int i, nin = 0, nout = 0, ndev; *canmulti = 1; /* one dev each for input and output */ - Pa_Initialize(); + pa_init(); ndev = Pa_GetDeviceCount(); for (i = 0; i < ndev; i++) {