1 /* Copyright (c) 2001 Miller Puckette and others.
2 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
3 * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
5 /* this file calls Ross Bencina's and Phil Burk's Portaudio package. It's
6 the main way in for Mac OS and, with Michael Casey's help, also into
14 #include "portaudio.h"
15 #include "pablio_pd.h"
17 /* LATER try to figure out how to handle default devices in portaudio;
18 the way s_audio.c handles them isn't going to work here. */
20 #if defined(MACOSX) || defined(MSW)
21 #define Pa_GetDefaultInputDevice Pa_GetDefaultInputDeviceID
22 #define Pa_GetDefaultOutputDevice Pa_GetDefaultOutputDeviceID
25 /* public interface declared in m_imp.h */
28 static PABLIO_Stream
*pa_stream
;
29 static int pa_inchans
, pa_outchans
;
30 static float *pa_soundin
, *pa_soundout
;
32 #define MAX_PA_CHANS 32
33 #define MAX_SAMPLES_PER_FRAME MAX_PA_CHANS * DEFDACBLKSIZE
35 int pa_open_audio(int inchans
, int outchans
, int rate
, t_sample
*soundin
,
36 t_sample
*soundout
, int framesperbuf
, int nbuffers
,
37 int indeviceno
, int outdeviceno
)
40 static int initialized
;
41 int j
, devno
, pa_indev
= 0, pa_outdev
= 0;
45 /* Initialize PortAudio */
46 int err
= Pa_Initialize();
47 if ( err
!= paNoError
)
50 "Error number %d occured initializing portaudio\n",
52 fprintf( stderr
, "Error message: %s\n", Pa_GetErrorText( err
) );
57 /* post("in %d out %d rate %d device %d", inchans, outchans, rate, deviceno); */
58 if (inchans
!= 0 && outchans
!= 0 && inchans
!= outchans
)
59 error("portaudio: number of input and output channels must match");
60 if (inchans
> MAX_PA_CHANS
)
62 post("input channels reduced to maximum %d", MAX_PA_CHANS
);
63 inchans
= MAX_PA_CHANS
;
65 if (outchans
> MAX_PA_CHANS
)
67 post("output channels reduced to maximum %d", MAX_PA_CHANS
);
68 outchans
= MAX_PA_CHANS
;
73 for (j
= 0, devno
= 0; j
< Pa_CountDevices(); j
++)
75 const PaDeviceInfo
*info
= Pa_GetDeviceInfo(j
);
76 if (info
->maxInputChannels
> 0)
78 if (devno
== indeviceno
)
90 for (j
= 0, devno
= 0; j
< Pa_CountDevices(); j
++)
92 const PaDeviceInfo
*info
= Pa_GetDeviceInfo(j
);
93 if (info
->maxOutputChannels
> 0)
95 if (devno
== outdeviceno
)
107 post("input device %d, channels %d", pa_indev
, inchans
);
108 post("output device %d, channels %d", pa_outdev
, outchans
);
109 post("framesperbuf %d, nbufs %d", framesperbuf
, nbuffers
);
111 if (inchans
&& outchans
)
112 err
= OpenAudioStream( &pa_stream
, rate
, paFloat32
,
113 PABLIO_READ_WRITE
, inchans
, framesperbuf
, nbuffers
,
114 pa_indev
, pa_outdev
);
116 err
= OpenAudioStream( &pa_stream
, rate
, paFloat32
,
117 PABLIO_READ
, inchans
, framesperbuf
, nbuffers
,
118 pa_indev
, pa_outdev
);
120 err
= OpenAudioStream( &pa_stream
, rate
, paFloat32
,
121 PABLIO_WRITE
, outchans
, framesperbuf
, nbuffers
,
122 pa_indev
, pa_outdev
);
124 if ( err
!= paNoError
)
126 fprintf( stderr
, "Error number %d occured opening portaudio stream\n",
128 fprintf( stderr
, "Error message: %s\n", Pa_GetErrorText( err
) );
130 sys_inchannels
= sys_outchannels
= 0;
133 else if (sys_verbose
)
134 post("... opened OK.");
135 pa_inchans
= inchans
;
136 pa_outchans
= outchans
;
137 pa_soundin
= soundin
;
138 pa_soundout
= soundout
;
142 void pa_close_audio( void)
144 if (pa_inchans
|| pa_outchans
)
145 CloseAudioStream( pa_stream
);
146 pa_inchans
= pa_outchans
= 0;
149 int pa_send_dacs(void)
151 float samples
[MAX_SAMPLES_PER_FRAME
], *fp1
, *fp2
;
155 timebefore
= sys_getrealtime();
156 if ((pa_inchans
&& GetAudioStreamReadable(pa_stream
) < DEFDACBLKSIZE
) ||
157 (pa_outchans
&& GetAudioStreamWriteable(pa_stream
) < DEFDACBLKSIZE
))
159 if (pa_inchans
&& pa_outchans
)
162 while (GetAudioStreamWriteable(pa_stream
) > 2*DEFDACBLKSIZE
)
164 for (j
= 0; j
< pa_outchans
; j
++)
165 for (i
= 0, fp2
= samples
+ j
; i
< DEFDACBLKSIZE
; i
++,
171 WriteAudioStream(pa_stream
, samples
, DEFDACBLKSIZE
);
173 while (GetAudioStreamReadable(pa_stream
) > 2*DEFDACBLKSIZE
)
176 ReadAudioStream(pa_stream
, samples
, DEFDACBLKSIZE
);
181 return (SENDDACS_NO
);
185 ReadAudioStream(pa_stream
, samples
, DEFDACBLKSIZE
);
186 for (j
= 0, fp1
= pa_soundin
; j
< pa_inchans
; j
++, fp1
+= DEFDACBLKSIZE
)
187 for (i
= 0, fp2
= samples
+ j
; i
< DEFDACBLKSIZE
; i
++,
198 post("it's %f %f %f %f",
199 pa_soundin
[0], pa_soundin
[1], pa_soundin
[2], pa_soundin
[3]);
207 for (j
= 0, fp1
= pa_soundout
; j
< pa_outchans
; j
++,
208 fp1
+= DEFDACBLKSIZE
)
209 for (i
= 0, fp2
= samples
+ j
; i
< DEFDACBLKSIZE
; i
++,
215 WriteAudioStream(pa_stream
, samples
, DEFDACBLKSIZE
);
218 if (sys_getrealtime() > timebefore
+ 0.002)
221 return (SENDDACS_SLEPT
);
223 else return (SENDDACS_YES
);
227 void pa_listdevs(void) /* lifted from pa_devs.c in portaudio */
231 const PaDeviceInfo
*pdi
;
234 numDevices
= Pa_CountDevices();
237 fprintf(stderr
, "ERROR: Pa_CountDevices returned 0x%x\n", numDevices
);
241 fprintf(stderr
, "Audio Devices:\n");
242 for( i
=0; i
<numDevices
; i
++ )
244 pdi
= Pa_GetDeviceInfo( i
);
245 fprintf(stderr
, "device %d:", i
+1 );
246 fprintf(stderr
, " %s;", pdi
->name
);
247 fprintf(stderr
, "%d inputs, ", pdi
->maxInputChannels
);
248 fprintf(stderr
, "%d outputs", pdi
->maxOutputChannels
);
249 if ( i
== Pa_GetDefaultInputDevice() )
250 fprintf(stderr
, " (Default Input)");
251 if ( i
== Pa_GetDefaultOutputDevice() )
252 fprintf(stderr
, " (Default Output)");
253 fprintf(stderr
, "\n");
256 fprintf(stderr
, "\n");
260 fprintf( stderr
, "An error occured while using the portaudio stream\n" );
261 fprintf( stderr
, "Error number: %d\n", err
);
262 fprintf( stderr
, "Error message: %s\n", Pa_GetErrorText( err
) );
266 /* scanning for devices */
267 void pa_getdevs(char *indevlist
, int *nindevs
,
268 char *outdevlist
, int *noutdevs
, int *canmulti
,
269 int maxndev
, int devdescsize
)
271 int i
, nin
= 0, nout
= 0, ndev
;
272 *canmulti
= 1; /* one dev each for input and output */
275 ndev
= Pa_CountDevices();
276 for (i
= 0; i
< ndev
; i
++)
278 const PaDeviceInfo
*pdi
= Pa_GetDeviceInfo(i
);
279 if (pdi
->maxInputChannels
> 0 && nin
< maxndev
)
281 strcpy(indevlist
+ nin
* devdescsize
, pdi
->name
);
284 if (pdi
->maxOutputChannels
> 0 && nout
< maxndev
)
286 strcpy(outdevlist
+ nout
* devdescsize
, pdi
->name
);
293 /* Copyright (c) 2001 Miller Puckette and others.
294 * For information on usage and redistribution, and for a DISCLAIMER OF ALL
295 * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
297 /* this file calls Ross Bencina's and Phil Burk's Portaudio package. It's
298 the main way in for Mac OS and, with Michael Casey's help, also into
306 #include "portaudio.h"
307 #include "pablio_pd.h"
309 /* LATER try to figure out how to handle default devices in portaudio;
310 the way s_audio.c handles them isn't going to work here. */
312 #if defined(MACOSX) || defined(MSW)
313 #define Pa_GetDefaultInputDevice Pa_GetDefaultInputDeviceID
314 #define Pa_GetDefaultOutputDevice Pa_GetDefaultOutputDeviceID
317 /* public interface declared in m_imp.h */
320 static PABLIO_Stream
*pa_stream
;
321 static int pa_inchans
, pa_outchans
;
322 static float *pa_soundin
, *pa_soundout
;
324 #define MAX_PA_CHANS 32
325 #define MAX_SAMPLES_PER_FRAME MAX_PA_CHANS * DEFDACBLKSIZE
327 int pa_open_audio(int inchans
, int outchans
, int rate
, t_sample
*soundin
,
328 t_sample
*soundout
, int framesperbuf
, int nbuffers
,
329 int indeviceno
, int outdeviceno
)
332 static int initialized
;
333 int j
, devno
, pa_indev
= 0, pa_outdev
= 0;
337 /* Initialize PortAudio */
338 int err
= Pa_Initialize();
339 if ( err
!= paNoError
)
342 "Error number %d occured initializing portaudio\n",
344 fprintf( stderr
, "Error message: %s\n", Pa_GetErrorText( err
) );
349 /* post("in %d out %d rate %d device %d", inchans, outchans, rate, deviceno); */
350 if (inchans
!= 0 && outchans
!= 0 && inchans
!= outchans
)
351 error("portaudio: number of input and output channels must match");
352 if (inchans
> MAX_PA_CHANS
)
354 post("input channels reduced to maximum %d", MAX_PA_CHANS
);
355 inchans
= MAX_PA_CHANS
;
357 if (outchans
> MAX_PA_CHANS
)
359 post("output channels reduced to maximum %d", MAX_PA_CHANS
);
360 outchans
= MAX_PA_CHANS
;
365 for (j
= 0, devno
= 0; j
< Pa_CountDevices(); j
++)
367 const PaDeviceInfo
*info
= Pa_GetDeviceInfo(j
);
368 if (info
->maxInputChannels
> 0)
370 if (devno
== indeviceno
)
382 for (j
= 0, devno
= 0; j
< Pa_CountDevices(); j
++)
384 const PaDeviceInfo
*info
= Pa_GetDeviceInfo(j
);
385 if (info
->maxOutputChannels
> 0)
387 if (devno
== outdeviceno
)
399 post("input device %d, channels %d", pa_indev
, inchans
);
400 post("output device %d, channels %d", pa_outdev
, outchans
);
401 post("framesperbuf %d, nbufs %d", framesperbuf
, nbuffers
);
403 if (inchans
&& outchans
)
404 err
= OpenAudioStream( &pa_stream
, rate
, paFloat32
,
405 PABLIO_READ_WRITE
, inchans
, framesperbuf
, nbuffers
,
406 pa_indev
, pa_outdev
);
408 err
= OpenAudioStream( &pa_stream
, rate
, paFloat32
,
409 PABLIO_READ
, inchans
, framesperbuf
, nbuffers
,
410 pa_indev
, pa_outdev
);
412 err
= OpenAudioStream( &pa_stream
, rate
, paFloat32
,
413 PABLIO_WRITE
, outchans
, framesperbuf
, nbuffers
,
414 pa_indev
, pa_outdev
);
416 if ( err
!= paNoError
)
418 fprintf( stderr
, "Error number %d occured opening portaudio stream\n",
420 fprintf( stderr
, "Error message: %s\n", Pa_GetErrorText( err
) );
422 sys_inchannels
= sys_outchannels
= 0;
425 else if (sys_verbose
)
426 post("... opened OK.");
427 pa_inchans
= inchans
;
428 pa_outchans
= outchans
;
429 pa_soundin
= soundin
;
430 pa_soundout
= soundout
;
434 void pa_close_audio( void)
436 if (pa_inchans
|| pa_outchans
)
437 CloseAudioStream( pa_stream
);
438 pa_inchans
= pa_outchans
= 0;
441 int pa_send_dacs(void)
443 float samples
[MAX_SAMPLES_PER_FRAME
], *fp1
, *fp2
;
447 timebefore
= sys_getrealtime();
448 if ((pa_inchans
&& GetAudioStreamReadable(pa_stream
) < DEFDACBLKSIZE
) ||
449 (pa_outchans
&& GetAudioStreamWriteable(pa_stream
) < DEFDACBLKSIZE
))
451 if (pa_inchans
&& pa_outchans
)
454 while (GetAudioStreamWriteable(pa_stream
) > 2*DEFDACBLKSIZE
)
456 for (j
= 0; j
< pa_outchans
; j
++)
457 for (i
= 0, fp2
= samples
+ j
; i
< DEFDACBLKSIZE
; i
++,
463 WriteAudioStream(pa_stream
, samples
, DEFDACBLKSIZE
);
465 while (GetAudioStreamReadable(pa_stream
) > 2*DEFDACBLKSIZE
)
468 ReadAudioStream(pa_stream
, samples
, DEFDACBLKSIZE
);
473 return (SENDDACS_NO
);
477 ReadAudioStream(pa_stream
, samples
, DEFDACBLKSIZE
);
478 for (j
= 0, fp1
= pa_soundin
; j
< pa_inchans
; j
++, fp1
+= DEFDACBLKSIZE
)
479 for (i
= 0, fp2
= samples
+ j
; i
< DEFDACBLKSIZE
; i
++,
490 post("it's %f %f %f %f",
491 pa_soundin
[0], pa_soundin
[1], pa_soundin
[2], pa_soundin
[3]);
499 for (j
= 0, fp1
= pa_soundout
; j
< pa_outchans
; j
++,
500 fp1
+= DEFDACBLKSIZE
)
501 for (i
= 0, fp2
= samples
+ j
; i
< DEFDACBLKSIZE
; i
++,
507 WriteAudioStream(pa_stream
, samples
, DEFDACBLKSIZE
);
510 if (sys_getrealtime() > timebefore
+ 0.002)
513 return (SENDDACS_SLEPT
);
515 else return (SENDDACS_YES
);
519 void pa_listdevs(void) /* lifted from pa_devs.c in portaudio */
523 const PaDeviceInfo
*pdi
;
526 numDevices
= Pa_CountDevices();
529 fprintf(stderr
, "ERROR: Pa_CountDevices returned 0x%x\n", numDevices
);
533 fprintf(stderr
, "Audio Devices:\n");
534 for( i
=0; i
<numDevices
; i
++ )
536 pdi
= Pa_GetDeviceInfo( i
);
537 fprintf(stderr
, "device %d:", i
+1 );
538 fprintf(stderr
, " %s;", pdi
->name
);
539 fprintf(stderr
, "%d inputs, ", pdi
->maxInputChannels
);
540 fprintf(stderr
, "%d outputs", pdi
->maxOutputChannels
);
541 if ( i
== Pa_GetDefaultInputDevice() )
542 fprintf(stderr
, " (Default Input)");
543 if ( i
== Pa_GetDefaultOutputDevice() )
544 fprintf(stderr
, " (Default Output)");
545 fprintf(stderr
, "\n");
548 fprintf(stderr
, "\n");
552 fprintf( stderr
, "An error occured while using the portaudio stream\n" );
553 fprintf( stderr
, "Error number: %d\n", err
);
554 fprintf( stderr
, "Error message: %s\n", Pa_GetErrorText( err
) );
558 /* scanning for devices */
559 void pa_getdevs(char *indevlist
, int *nindevs
,
560 char *outdevlist
, int *noutdevs
, int *canmulti
,
561 int maxndev
, int devdescsize
)
563 int i
, nin
= 0, nout
= 0, ndev
;
564 *canmulti
= 1; /* one dev each for input and output */
567 ndev
= Pa_CountDevices();
568 for (i
= 0; i
< ndev
; i
++)
570 const PaDeviceInfo
*pdi
= Pa_GetDeviceInfo(i
);
571 if (pdi
->maxInputChannels
> 0 && nin
< maxndev
)
573 strcpy(indevlist
+ nin
* devdescsize
, pdi
->name
);
576 if (pdi
->maxOutputChannels
> 0 && nout
< maxndev
)
578 strcpy(outdevlist
+ nout
* devdescsize
, pdi
->name
);