[PD-cvs] pd/src s_audio_pa.c, 1.4.4.2, 1.4.4.3 s_audio.c, 1.5.4.12, 1.5.4.13 s_stuff.h, 1.5.4.5, 1.5.4.6
Tim Blechmann
timblech at users.sourceforge.net
Wed May 11 16:32:11 CEST 2005
Update of /cvsroot/pure-data/pd/src
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv30038
Modified Files:
Tag: devel_0_38
s_audio_pa.c s_audio.c s_stuff.h
Log Message:
callback based scheduling for portaudio v19
Index: s_audio_pa.c
===================================================================
RCS file: /cvsroot/pure-data/pd/src/s_audio_pa.c,v
retrieving revision 1.4.4.2
retrieving revision 1.4.4.3
diff -C2 -d -r1.4.4.2 -r1.4.4.3
*** s_audio_pa.c 26 Nov 2004 10:03:41 -0000 1.4.4.2
--- s_audio_pa.c 11 May 2005 14:32:07 -0000 1.4.4.3
***************
*** 4,10 ****
/* 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. */
#include "m_pd.h"
--- 4,11 ----
/* 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 "m_pd.h"
***************
*** 13,66 ****
#include <stdlib.h>
#include <portaudio.h>
! #include "s_audio_pablio.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
! /* LATER try to figure out how to handle default devices in portaudio;
! the way s_audio.c handles them isn't going to work here. */
! /* public interface declared in m_imp.h */
- /* implementation */
- static PABLIO_Stream *pa_stream;
static int pa_inchans, pa_outchans;
! static float *pa_soundin, *pa_soundout;
! #define MAX_PA_CHANS 32
! #ifndef PA19
! #define Pa_GetDeviceCount Pa_CountDevices
! #endif
int pa_open_audio(int inchans, int outchans, int rate, t_sample *soundin,
! t_sample *soundout, int framesperbuf, int nbuffers,
! int indeviceno, int outdeviceno)
{
PaError err;
- static int initialized;
int j, devno, pa_indev = 0, pa_outdev = 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;
! }
/* post("in %d out %d rate %d device %d", inchans, outchans, rate, deviceno); */
if (inchans > MAX_PA_CHANS)
--- 14,69 ----
#include <stdlib.h>
#include <portaudio.h>
! #include <errno.h>
#ifdef MSW
! #include "pthread.h" /* for ETIMEDOUT */
#endif
! #define MAX_PA_CHANS 32
! #define PA19
! /* portaudio's blocking api is not working, yet: */
! /* #define PABLOCKING */
static int pa_inchans, pa_outchans;
! static float *pa_soundin[MAX_PA_CHANS], *pa_soundout[MAX_PA_CHANS];
! static PaStream *pa_stream;
! static PaStreamCallback *pa_callback = NULL;
! int process (const void *input, void *output, unsigned long frameCount,
! const PaStreamCallbackTimeInfo* timeInfo,
! PaStreamCallbackFlags statusFlags, void *userData);
int pa_open_audio(int inchans, int outchans, int rate, t_sample *soundin,
! t_sample *soundout, int advance,
! int indeviceno, int outdeviceno, int schedmode)
{
PaError err;
int j, devno, pa_indev = 0, pa_outdev = 0;
! #ifndef PABLOCKING
! schedmode = 1;
! #endif
!
! if (schedmode == 1)
! pa_callback = process;
! else
! pa_callback = NULL;
!
! sys_keepsched = 0;
! sys_callbackscheduler = schedmode;
!
! /* Initialize PortAudio */
! 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);
! }
!
/* post("in %d out %d rate %d device %d", inchans, outchans, rate, deviceno); */
if (inchans > MAX_PA_CHANS)
***************
*** 90,94 ****
}
}
! }
if (outchans > 0)
--- 93,97 ----
}
}
! }
if (outchans > 0)
***************
*** 107,111 ****
}
}
! }
if (sys_verbose)
--- 110,114 ----
}
}
! }
if (sys_verbose)
***************
*** 113,128 ****
post("input device %d, channels %d", pa_indev, inchans);
post("output device %d, channels %d", pa_outdev, outchans);
! post("framesperbuf %d, nbufs %d", framesperbuf, nbuffers);
}
if (inchans || outchans)
! err = OpenAudioStream( &pa_stream, rate, paFloat32,
! inchans, outchans, framesperbuf, nbuffers,
! pa_indev, pa_outdev);
! else err = 0;
! if ( err != paNoError )
{
! fprintf( stderr, "Error number %d occured opening portaudio stream\n",
! err);
! fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
Pa_Terminate();
sys_inchannels = sys_outchannels = 0;
--- 116,155 ----
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)
! {
! 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, (inchans ? &inputParameters : 0),
! (outchans ? &outputParameters : 0),
! rate,
! sys_dacblocksize,
! paClipOff, /* tb: we should be faster ;-) */
! pa_callback, NULL);
! }
! else
! err = 0;
!
! if ( err != paNoError )
{
! post("Error number %d occured opening portaudio stream\n",
! err);
! post("Error message: %s\n", Pa_GetErrorText( err ) );
Pa_Terminate();
sys_inchannels = sys_outchannels = 0;
***************
*** 133,228 ****
pa_inchans = inchans;
pa_outchans = outchans;
! pa_soundin = soundin;
! pa_soundout = soundout;
return (0);
}
void pa_close_audio( void)
{
if (pa_inchans || pa_outchans)
! CloseAudioStream( pa_stream );
pa_inchans = pa_outchans = 0;
}
int pa_send_dacs(void)
{
! 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 && GetAudioStreamReadable(pa_stream) < sys_dacblocksize) ||
! (pa_outchans && GetAudioStreamWriteable(pa_stream) < sys_dacblocksize))
! {
! if (pa_inchans && pa_outchans)
! {
! int synced = 0;
! while (GetAudioStreamWriteable(pa_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;
! WriteAudioStream(pa_stream, samples, sys_dacblocksize);
! }
! while (GetAudioStreamReadable(pa_stream) > 2*sys_dacblocksize)
! {
! synced = 1;
! ReadAudioStream(pa_stream, samples, sys_dacblocksize);
! }
! /* if (synced)
! post("sync"); */
! }
! return (SENDDACS_NO);
! }
! if (pa_inchans)
! {
! ReadAudioStream(pa_stream, samples, sys_dacblocksize);
! for (j = 0, fp1 = pa_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 0
! {
! static int nread;
! if (nread == 0)
! {
! post("it's %f %f %f %f",
! pa_soundin[0], pa_soundin[1], pa_soundin[2], pa_soundin[3]);
! nread = 1000;
! }
! nread--;
! }
! #endif
! if (pa_outchans)
! {
! for (j = 0, fp1 = pa_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;
! }
! WriteAudioStream(pa_stream, samples, sys_dacblocksize);
! }
! if (sys_getrealtime() > timebefore + 0.002)
! {
! /* post("slept"); */
! return (SENDDACS_SLEPT);
! }
! else return (SENDDACS_YES);
}
void pa_listdevs(void) /* lifted from pa_devs.c in portaudio */
{
--- 160,331 ----
pa_inchans = inchans;
pa_outchans = outchans;
!
! err = Pa_StartStream(pa_stream);
! if ( err != paNoError )
! {
! post("Error number %d occured starting portaudio stream\n",
! err);
! post("Error message: %s\n", Pa_GetErrorText(err));
! Pa_Terminate();
! sys_inchannels = sys_outchannels = 0;
! return (1);
! }
!
! post("successfully started");
!
! for (j = 0; j != MAX_PA_CHANS; ++j)
! {
! if (j < inchans)
! pa_soundin[j] = sys_soundin + j * sys_dacblocksize;
! else
! pa_soundin[j] = 0;
!
! if (j < outchans)
! pa_soundout[j] = sys_soundout + j * sys_dacblocksize;
! else
! pa_soundout[j] = 0;
! }
!
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 */
+ return 0;
+
+ #if 0
+ for (i = 0; i < frameCount / sys_dacblocksize; ++i)
+ {
+ for (j = 0; j < sys_inchannels; j++)
+ {
+ t_sample * in = ((t_sample**)input)[j];
+ copyvec(sys_soundin + j * sys_dacblocksize,
+ in + i * sys_dacblocksize,
+ sys_dacblocksize);
+ }
+
+ sched_tick(sys_time + sys_time_per_dsp_tick);
+
+ for (j = 0; j < sys_outchannels; j++)
+ {
+ t_sample * out = ((t_sample**)output)[j];
+ copyvec(out + i * sys_dacblocksize,
+ sys_soundout + j * sys_dacblocksize,
+ sys_dacblocksize);
+ }
+ /* update peak meters */
+ if (sys_meters)
+ sys_peakmeters();
+
+ /* clear the output buffer */
+ zerovec_simd(sys_soundout, pa_outchans * sys_dacblocksize);
+ }
+ #else
+ for (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 (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_simd(sys_soundout, pa_outchans * sys_dacblocksize);
+
+ #endif
+ sys_unlock();
+
+ return 0;
+
+ }
+
void pa_close_audio( void)
{
+ post("closing portaudio");
if (pa_inchans || pa_outchans)
! {
! Pa_StopStream(pa_stream);
! Pa_CloseStream(pa_stream);
! }
! post("portaudio closed");
pa_inchans = pa_outchans = 0;
}
+
+ /* for blocked IO */
int pa_send_dacs(void)
{
! #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, pa_soundout, sys_dacblocksize);
! if (pa_inchans)
! Pa_ReadStream(pa_stream, pa_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, pa_soundout, sys_dacblocksize);
! if (pa_inchans)
! Pa_ReadStream(pa_stream, pa_soundin, sys_dacblocksize);
! zerovec(sys_soundout, pa_inchans * sys_dacblocksize);
!
! sched_tick(sys_time + sys_time_per_dsp_tick);
! }
!
! if ((timenow = sys_getrealtime()) - timebefore > sys_sleepgrain * 1e-6)
! {
! return SENDDACS_SLEPT;
! }
! else
! return SENDDACS_YES;
! #else
! /* we should never reach this point */
! return 0;
! #endif
}
+
void pa_listdevs(void) /* lifted from pa_devs.c in portaudio */
{
***************
*** 242,247 ****
for( i=0; i<numDevices; i++ )
{
! pdi = Pa_GetDeviceInfo( i );
! fprintf(stderr, "device %d:", i+1 );
fprintf(stderr, " %s;", pdi->name );
fprintf(stderr, "%d inputs, ", pdi->maxInputChannels );
--- 345,351 ----
for( i=0; i<numDevices; i++ )
{
! PaDeviceInfo * pdi = Pa_GetDeviceInfo( i );
! post ("device %s", pdi->name);
! fprintf(stderr, "device %d:", i+1 );
fprintf(stderr, " %s;", pdi->name );
fprintf(stderr, "%d inputs, ", pdi->maxInputChannels );
***************
*** 265,269 ****
error:
! fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
--- 369,373 ----
error:
! fprintf( stderr, "An error occured while using the portaudio stream\n" );
fprintf( stderr, "Error number: %d\n", err );
fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( err ) );
***************
*** 271,275 ****
}
! /* scanning for devices */
void pa_getdevs(char *indevlist, int *nindevs,
char *outdevlist, int *noutdevs, int *canmulti,
--- 375,380 ----
}
!
! /* scanning for devices */
void pa_getdevs(char *indevlist, int *nindevs,
char *outdevlist, int *noutdevs, int *canmulti,
Index: s_audio.c
===================================================================
RCS file: /cvsroot/pure-data/pd/src/s_audio.c,v
retrieving revision 1.5.4.12
retrieving revision 1.5.4.13
diff -C2 -d -r1.5.4.12 -r1.5.4.13
*** s_audio.c 10 May 2005 11:16:03 -0000 1.5.4.12
--- s_audio.c 11 May 2005 14:32:08 -0000 1.5.4.13
***************
*** 332,338 ****
int blksize = (sys_blocksize ? sys_blocksize : 64);
pa_open_audio(inchans, outchans, rate, sys_soundin, sys_soundout,
! blksize, sys_advance_samples/blksize,
! (naudiooutdev > 0 ? audioindev[0] : 0),
! (naudiooutdev > 0 ? audiooutdev[0] : 0));
}
else
--- 332,339 ----
int blksize = (sys_blocksize ? sys_blocksize : 64);
pa_open_audio(inchans, outchans, rate, sys_soundin, sys_soundout,
! advance,
! (naudiooutdev > 0 ? audioindev[0] : 0),
! (naudiooutdev > 0 ? audiooutdev[0] : 0),
! schedmode);
}
else
Index: s_stuff.h
===================================================================
RCS file: /cvsroot/pure-data/pd/src/s_stuff.h,v
retrieving revision 1.5.4.5
retrieving revision 1.5.4.6
diff -C2 -d -r1.5.4.5 -r1.5.4.6
*** s_stuff.h 8 Apr 2005 12:45:25 -0000 1.5.4.5
--- s_stuff.h 11 May 2005 14:32:09 -0000 1.5.4.6
***************
*** 202,207 ****
int pa_open_audio(int inchans, int outchans, int rate, t_sample *soundin,
! t_sample *soundout, int framesperbuf, int nbuffers,
! int indeviceno, int outdeviceno);
void pa_close_audio(void);
int pa_send_dacs(void);
--- 202,207 ----
int pa_open_audio(int inchans, int outchans, int rate, t_sample *soundin,
! t_sample *soundout, int advance,
! int indeviceno, int outdeviceno, int schedmode)
void pa_close_audio(void);
int pa_send_dacs(void);
More information about the Pd-cvs
mailing list