aboutsummaryrefslogtreecommitdiff
path: root/desiredata/src/s_audio_pa.c
diff options
context:
space:
mode:
authorN.N. <matju@users.sourceforge.net>2010-01-05 22:49:36 +0000
committerN.N. <matju@users.sourceforge.net>2010-01-05 22:49:36 +0000
commit8dbec761cf858ea65900c8a094599857208d8c3a (patch)
tree3228c023f87f23a354da3b57fdc2afe5b7052032 /desiredata/src/s_audio_pa.c
parent529e59635598e2d90a7a49f6b4c676f8366109ba (diff)
svn path=/trunk/; revision=12907
Diffstat (limited to 'desiredata/src/s_audio_pa.c')
-rw-r--r--desiredata/src/s_audio_pa.c332
1 files changed, 0 insertions, 332 deletions
diff --git a/desiredata/src/s_audio_pa.c b/desiredata/src/s_audio_pa.c
deleted file mode 100644
index d6a086b3..00000000
--- a/desiredata/src/s_audio_pa.c
+++ /dev/null
@@ -1,332 +0,0 @@
-/* Copyright (c) 2001 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. */
-
-/* this file calls Ross Bencina's and Phil Burk's Portaudio package. It's
- the main way in for Mac OS and, with Michael Casey's help, also into ASIO in Windows. */
-
-/* tb: requires portaudio >= V19 */
-
-#include "desire.h"
-#include <stdio.h>
-#include <string.h>
-#include <stdlib.h>
-#include <portaudio.h>
-#include <errno.h>
-
-#ifdef MSW
-/* jmz thinks that we have to include:
- * on Windows: <malloc.h> (probably this is already included?)
- * on linux: <alloca.h> (might be true for osX too, no way to check right now...)
- */
-# include <malloc.h>
-#else
-# include <alloca.h>
-#endif
-
-#ifdef MSW
-#include "pthread.h" /* for ETIMEDOUT */
-#endif
-
-#define MAX_PA_CHANS 32
-
-/* portaudio's blocking api is not working, yet: */
-/* #define PABLOCKING */
-
-//#ifndef PABLOCKING
-#include "s_audio_pablio.h"
-//#endif
-
-static int pa_inchans, pa_outchans;
-
-static PaStream *pa_stream;
-static PABLIO_Stream *pablio_stream;
-static PaStreamCallback *pa_callback = NULL;
-
-int process (const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo,
-PaStreamCallbackFlags statusFlags, void *userData);
-
-/*int naudioindev, int * audioindev, int nchindev, int * chindev,
-int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev, int rate, int dummy*/
-int pa_open_audio(int inchans, int outchans, int rate, int advance, int indeviceno, int outdeviceno, int schedmode) {
- PaError err;
- int j, devno, pa_indev = -1, pa_outdev = -1;
- pa_callback = schedmode==1 ? process : NULL;
- sys_setscheduler(schedmode);
- /* Initialize PortAudio */
- err = Pa_Initialize();
- if (err != paNoError) {
- error("Error number %d occured initializing portaudio: %s", err, Pa_GetErrorText(err));
- return 1;
- }
- /* post("in %d out %d rate %d device %d", inchans, outchans, rate, deviceno); */
- if ( inchans > MAX_PA_CHANS) {post( "input channels reduced to maximum %d", MAX_PA_CHANS); inchans = MAX_PA_CHANS;}
- if (outchans > MAX_PA_CHANS) {post("output channels reduced to maximum %d", MAX_PA_CHANS); outchans = MAX_PA_CHANS;}
- if (inchans > 0) {
- for (j = 0, devno = 0; j < Pa_GetDeviceCount(); j++) {
- const PaDeviceInfo *info = Pa_GetDeviceInfo(j);
- int maxchans = info->maxInputChannels;
- if (maxchans > 0) {
- if (devno == indeviceno) {
- if (maxchans < inchans) inchans = maxchans;
- pa_indev = j;
- break;
- }
- devno++;
- }
- }
- }
- if (outchans > 0) {
- for (j = 0, devno = 0; j < Pa_GetDeviceCount(); j++) {
- const PaDeviceInfo *info = Pa_GetDeviceInfo(j);
- int maxchans = info->maxOutputChannels;
- if (maxchans > 0) {
- if (devno == outdeviceno) {
- if (maxchans < outchans) outchans = maxchans;
- pa_outdev = j;
- break;
- }
- devno++;
- }
- }
- }
- if (sys_verbose) {
- post( "input device %d, channels %d", pa_indev, inchans);
- post("output device %d, channels %d", pa_outdev, outchans);
- post("latency advance %d", advance);
- }
- if (inchans || outchans) {
-#ifndef PABLOCKING
- if (schedmode == 1) {
-#endif
- PaStreamParameters inputParameters, outputParameters;
- /* initialize input */
- inputParameters.device = pa_indev ;
- inputParameters.channelCount = inchans;
- inputParameters.sampleFormat = paFloat32 | paNonInterleaved;
- inputParameters.suggestedLatency = advance * 0.001;
- inputParameters.hostApiSpecificStreamInfo = NULL;
- /* initialize output */
- outputParameters.device = pa_outdev;
- outputParameters.channelCount = outchans;
- outputParameters.sampleFormat = paFloat32 | paNonInterleaved;
- outputParameters.suggestedLatency = advance * 0.001;
- outputParameters.hostApiSpecificStreamInfo = NULL;
- /* report to portaudio */
- err = Pa_OpenStream(&pa_stream,
- ( pa_indev!=-1 ? &inputParameters : 0),
- (pa_outdev!=-1 ? &outputParameters : 0),
- rate, sys_dacblocksize, paClipOff, /* tb: we should be faster ;-) */ pa_callback, NULL);
- if (err == paNoError) {
- const PaStreamInfo * streaminfo = Pa_GetStreamInfo (pa_stream);
- sys_schedadvance = 1e6 * streaminfo->outputLatency;
- }
-#ifndef PABLOCKING
- } else {
- int nbuffers = sys_advance_samples / sys_dacblocksize;
- err = PD_OpenAudioStream( &pablio_stream, rate, paFloat32,
- inchans, outchans, sys_dacblocksize, nbuffers, pa_indev, pa_outdev);
- }
-#endif
- } else err = 0;
- if (err != paNoError) {
- post("Error number %d occured opening portaudio stream", err);
- post("Error message: %s", Pa_GetErrorText(err));
- Pa_Terminate();
- sys_inchannels = sys_outchannels = 0;
- return 1;
- } else if (sys_verbose) post("... opened OK.");
- pa_inchans = inchans;
- pa_outchans = outchans;
-#ifndef PABLOCKING
- if (schedmode)
-#endif
- err = Pa_StartStream(pa_stream);
- if (err != paNoError) {
- post("Error number %d occured starting portaudio stream", err);
- post("Error message: %s", Pa_GetErrorText(err));
- Pa_Terminate();
- sys_inchannels = sys_outchannels = 0;
- return 1;
- }
- post("successfully started");
- return 0;
-}
-
-void sys_peakmeters(void);
-extern int sys_meters; /* true if we're metering */
-
-int process (const void *input, void *output, unsigned long frameCount,
-const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData) {
- int i,j;
- int timeout = (float)frameCount / (float) sys_dacsr * 1e6;
- if (sys_timedlock(timeout) == ETIMEDOUT) /* we're late */ {
- post("timeout %d", timeout);
- sys_log_error(ERR_SYSLOCK);
- return 0;
- }
- for (int j=0; j<sys_inchannels; j++) {
- t_sample * in = ((t_sample**)input)[j];
- copyvec( sys_soundin + j * sys_dacblocksize,in,sys_dacblocksize);
- }
- sched_tick(sys_time + sys_time_per_dsp_tick);
- for (int j=0; j<sys_outchannels; j++) {
- t_sample *out = ((t_sample**)output)[j];
- copyvec(out,sys_soundout + j * sys_dacblocksize, sys_dacblocksize);
- }
- /* update peak meters */
- if (sys_meters) sys_peakmeters();
- /* clear the output buffer */
- zerovec(sys_soundout, pa_outchans * sys_dacblocksize);
- sys_unlock();
- return 0;
-}
-
-void pa_close_audio() {
- post("closing portaudio");
- if (pa_inchans || pa_outchans) {
- if (pa_stream) {
- Pa_StopStream(pa_stream);
- Pa_CloseStream(pa_stream);
- pa_stream = NULL;
- }
- if (pablio_stream) {
- PD_CloseAudioStream(pablio_stream);
- pablio_stream = NULL;
- }
- }
- post("portaudio closed");
- pa_inchans = pa_outchans = 0;
-}
-
-/* for blocked IO */
-int pa_send_dacs() {
-#ifdef PABLOCKING /* tb: blocking IO isn't really working for v19 yet */
- double timenow, timebefore;
- if (( pa_inchans && Pa_GetStreamReadAvailable(pa_stream) < sys_dacblocksize*0.8) &&
- (pa_outchans && Pa_GetStreamWriteAvailable(pa_stream) < sys_dacblocksize*0.8)) {
- /* we can't transfer data ... wait in the scheduler */
- return SENDDACS_NO;
- }
- timebefore = sys_getrealtime();
- if (pa_outchans) Pa_WriteStream(pa_stream, &sys_soundout, sys_dacblocksize);
- if ( pa_inchans) Pa_ReadStream(pa_stream, &sys_soundin, sys_dacblocksize);
- zerovec(sys_soundout, pa_inchans * sys_dacblocksize);
- while (( pa_inchans && Pa_GetStreamReadAvailable(pa_stream) < sys_dacblocksize*0.8) &&
- (pa_outchans && Pa_GetStreamWriteAvailable(pa_stream) < sys_dacblocksize*0.8)) {
- if (pa_outchans) Pa_WriteStream(pa_stream, &sys_soundout, sys_dacblocksize);
- if ( pa_inchans) Pa_ReadStream(pa_stream, &sys_soundin, sys_dacblocksize);
- zerovec(sys_soundout, pa_inchans * sys_dacblocksize);
- sched_tick(sys_time + sys_time_per_dsp_tick);
- }
- if (sys_getrealtime() > timebefore + sys_sleepgrain * 1e-6) {
- return SENDDACS_SLEPT;
- } else return SENDDACS_YES;
-#else /* for now we're using pablio */
- float *samples, *fp1, *fp2;
- int i, j;
- double timebefore;
- samples=(float*)alloca(sizeof(float) * MAX_PA_CHANS * sys_dacblocksize);
- timebefore = sys_getrealtime();
- if ((pa_inchans && PD_GetAudioStreamReadable(pablio_stream) < sys_dacblocksize) ||
- (pa_outchans && PD_GetAudioStreamWriteable(pablio_stream) < sys_dacblocksize)) {
- if (pa_inchans && pa_outchans) {
- int synced = 0;
- while (PD_GetAudioStreamWriteable(pablio_stream) > 2*sys_dacblocksize) {
- for (j = 0; j < pa_outchans; j++)
- for (i = 0, fp2 = samples + j; i < sys_dacblocksize; i++, fp2 += pa_outchans)
- *fp2 = 0;
- synced = 1;
- PD_WriteAudioStream(pablio_stream, samples, sys_dacblocksize);
- }
- while (PD_GetAudioStreamReadable(pablio_stream) > 2*sys_dacblocksize) {
- synced = 1;
- PD_ReadAudioStream(pablio_stream, samples, sys_dacblocksize);
- }
-/* if (synced) post("sync"); */
- }
- return SENDDACS_NO;
- }
- if (pa_inchans) {
- PD_ReadAudioStream(pablio_stream, samples, sys_dacblocksize);
- for (j = 0, fp1 = sys_soundin; j < pa_inchans; j++, fp1 += sys_dacblocksize)
- for (i = 0, fp2 = samples + j; i < sys_dacblocksize; i++, fp2 += pa_inchans)
- fp1[i] = *fp2;
- }
- if (pa_outchans) {
- for (j = 0, fp1 = sys_soundout; j < pa_outchans; j++, fp1 += sys_dacblocksize)
- for (i = 0, fp2 = samples + j; i < sys_dacblocksize; i++, fp2 += pa_outchans) {
- *fp2 = fp1[i];
- fp1[i] = 0;
- }
- PD_WriteAudioStream(pablio_stream, samples, sys_dacblocksize);
- }
- if (sys_getrealtime() > timebefore + sys_sleepgrain * 1e-6) {
- /* post("slept"); */
- return SENDDACS_SLEPT;
- } else return SENDDACS_YES;
-#endif
-}
-
-void pa_listdevs() /* lifted from pa_devs.c in portaudio */ {
- int j, numDevices;
- const PaDeviceInfo *pdi;
- PaError err;
- Pa_Initialize();
- numDevices = Pa_GetDeviceCount();
- if (numDevices<0) {
- error("ERROR: Pa_GetDeviceCount returned %d", numDevices);
- err = numDevices;
- goto error;
- }
- post("Audio Devices:");
- for (int i=0; i<numDevices; i++) {
- const PaDeviceInfo *pdi = Pa_GetDeviceInfo(i);
- post("device %s", pdi->name);
- post("device %d:", i+1);
- post(" %s;", pdi->name);
- post("%d inputs, ", pdi->maxInputChannels);
- post("%d outputs", pdi->maxOutputChannels);
-#ifdef PA19
- if (i == Pa_GetDefaultInputDevice ()) post(" (Default Input)");
- if (i == Pa_GetDefaultOutputDevice()) post(" (Default Output)");
-#else
- if (i == Pa_GetDefaultInputDeviceID ()) post(" (Default Input)");
- if (i == Pa_GetDefaultOutputDeviceID()) post(" (Default Output)");
-#endif
- post("");
- }
- post("");
- return;
-error:
- error("An error occured while using the portaudio stream: #%d: %s",err,Pa_GetErrorText(err));
-}
-/* scanning for devices */
-void pa_getdevs(char *indevlist, int *nindevs, char *outdevlist, int *noutdevs, int *canmulti, int maxndev, int devdescsize) {
- int i, nin = 0, nout = 0, ndev;
- *canmulti = 1; /* one dev each for input and output */
- Pa_Initialize();
- ndev = Pa_GetDeviceCount();
- for (i = 0; i < ndev; i++) {
- const PaDeviceInfo *pdi = Pa_GetDeviceInfo(i);
- if (pdi->maxInputChannels > 0 && nin < maxndev) {
- sprintf(indevlist + nin * devdescsize, "(%d)%s", pdi->hostApi,pdi->name);
- /* strcpy(indevlist + nin * devdescsize, pdi->name); */
- nin++;
- }
- if (pdi->maxOutputChannels > 0 && nout < maxndev) {
- sprintf(outdevlist + nout * devdescsize, "(%d)%s", pdi->hostApi,pdi->name);
- /* strcpy(outdevlist + nout * devdescsize, pdi->name); */
- nout++;
- }
- }
- *nindevs = nin;
- *noutdevs = nout;
-}
-
-t_audioapi pa_api = {
- pa_open_audio,
- pa_close_audio,
- pa_send_dacs,
- pa_getdevs,
-};