Update of /cvsroot/pure-data/pd/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv23843/src
Modified Files: Tag: devel_0_39 s_audio.c SConscript m_glob.c Added Files: Tag: devel_0_39 s_audio_portaudio.c Log Message: importing new portaudio implementation more message-based access to the audio api
Index: SConscript =================================================================== RCS file: /cvsroot/pure-data/pd/src/Attic/SConscript,v retrieving revision 1.1.4.44 retrieving revision 1.1.4.45 diff -C2 -d -r1.1.4.44 -r1.1.4.45 *** SConscript 17 Dec 2005 00:04:37 -0000 1.1.4.44 --- SConscript 20 Apr 2006 13:32:33 -0000 1.1.4.45 *************** *** 13,51 ****
opt.AddOptions( ! BoolOption('debug', 'Build with debugging symbols', False), ! BoolOption('simd', 'Build with simd instructions', True), ! BoolOption('daz', 'Build using DAZ flag on x86-SSE2 cpus (must be set to False for AMD cpus)', False), ! BoolOption('portaudio', 'Build with portaudio', True), ! ('portaudiopath', 'Path to portaudio','../portaudio'), ! BoolOption('threadedsf', 'Build with threaded soundfiler', False), ! BoolOption('atomic', 'Build with atomic operations', False), ! BoolOption('newhash', 'Build with 16 bit symbol hash table', True), [...1025 lines suppressed...]
Export("pdenv") --- 624,640 ----
if pdenv['pdlib']: ! if pdenv['PLATFORM'] == 'win32': ! envint.Append(LINKFLAGS=["/EXPORT:sys_main","/PDB:./bin/pd-dll.pdb"])
! pdlib = envint.SharedLibrary('../bin/pd', sources) ! pd = pdenv.Program('../bin/pd', 's_entry.c', LIBS=['./bin/pd']) ! Default(pdsend, pdreceive, pdgui, pdlib, pd, pdtk) else: ! pdlib = None ! pd = envint.Program('../bin/pd', ['s_entry.c'] + sources) ! Default(pdsend, pdreceive, pdgui, pd, pdtk)
if pdenv['PLATFORM'] != 'win32': ! Default(pdwatchdog)
Export("pdenv")
Index: s_audio.c =================================================================== RCS file: /cvsroot/pure-data/pd/src/s_audio.c,v retrieving revision 1.5.4.16.2.14 retrieving revision 1.5.4.16.2.15 diff -C2 -d -r1.5.4.16.2.14 -r1.5.4.16.2.15 *** s_audio.c 14 Apr 2006 18:37:52 -0000 1.5.4.16.2.14 --- s_audio.c 20 Apr 2006 13:32:28 -0000 1.5.4.16.2.15 *************** *** 1345,1348 **** --- 1345,1387 ---- }
+ void glob_audio_getaudioindevinfo(t_pd * dummy, t_float f) + { + #ifdef USEAPI_PORTAUDIO + #ifndef PABLIO + if (sys_audioapi == API_PORTAUDIO) + pa_getaudioindevinfo(f); + #endif + #endif + } + + void glob_audio_getaudiooutdevinfo(t_pd * dummy, t_float f) + { + #ifdef USEAPI_PORTAUDIO + #ifndef PABLIO + if (sys_audioapi == API_PORTAUDIO) + pa_getaudiooutdevinfo(f); + #endif + #endif + } + + void glob_audio_testaudiosetting(t_pd * dummy, t_symbol *s, int ac, t_atom *av) + { + #ifdef USEAPI_PORTAUDIO + #ifndef PABLIO + if (sys_audioapi == API_PORTAUDIO) + pa_test_setting (ac, av); + #endif + #endif + } + + void glob_audio_getcurrent_devices(void) + { + #ifdef USEAPI_PORTAUDIO + #ifndef PABLIO + if (sys_audioapi == API_PORTAUDIO) + pa_getcurrent_devices(); + #endif + #endif + }
/* tb } */
--- NEW FILE: s_audio_portaudio.c --- /* Copyright (c) 2001 Miller Puckette and others. * Copyright (c) 2005-2006 Tim Blechmann * supported by vibrez.net * 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 "m_pd.h" #include "s_stuff.h" #include <stdio.h> #include <string.h> #include <stdlib.h> #include <portaudio.h> #include <errno.h>
#include "assert.h"
#ifdef MSW # include <malloc.h> #else # include <alloca.h> #endif
#include "pthread.h"
/* for M_PI */ #if defined(_MSC_VER) && !defined(_USE_MATH_DEFINES) #define _USE_MATH_DEFINES #endif #include <math.h>
#define MAX_PA_CHANS 32
static int pa_inchans, pa_outchans; static int pa_blocksize;
static PaStream *pa_stream; /* Initialize PortAudio */ PaError pa_status = -1; int pa_initialized = 0;
void pa_initialize() { if (!pa_initialized) { pa_status = Pa_Initialize(); if ( pa_status!= paNoError ) { fprintf( stderr, "Error number %d occured initializing portaudio\n", pa_status); fprintf( stderr, "Error message: %s\n", Pa_GetErrorText( pa_status ) ); return; } pa_initialized = 1; } }
static float* pa_inbuffer[MAX_PA_CHANS]; static float* pa_outbuffer[MAX_PA_CHANS]; static int pa_bufferpos;
int process (const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData);
static int patestCallback(const void* inputBuffer, void* outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void* userData);
static int pa_indev = -1, pa_outdev = -1;
int pa_open_audio(int inchans, int outchans, int rate, int advance, int indeviceno, int outdeviceno, int schedmode) { PaError err; int j, devno;
schedmode = 1; /* we don't support blocking io */
pa_initialize();
sys_setscheduler(schedmode);
if (indeviceno != outdeviceno) { post("portaudio supports only one device for i/o"); 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 (1/* 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) { int blocksize; PaStreamParameters inputParameters, outputParameters;
const PaDeviceInfo* pdi = Pa_GetDeviceInfo(pa_indev); const PaDeviceInfo* pdo = Pa_GetDeviceInfo(pa_outdev);
assert(pdi);
/* 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;
/* set block size */ blocksize = sys_advance_samples;
if (blocksize > 8192) blocksize = 8192; else if (blocksize < sys_dacblocksize) blocksize = sys_dacblocksize;
if (blocksize != (1 << ilog2(blocksize))) { blocksize = (1 << ilog2(blocksize)); }
post("using blocksize %d", blocksize);
pa_blocksize = blocksize;
/* initialize io buffer */ for (j=0; j != MAX_PA_CHANS;++j) { if (pa_inbuffer[j]) freealignedbytes(pa_inbuffer[j], 0);
if (pa_outbuffer[j]) freealignedbytes(pa_outbuffer[j], 0);
pa_inbuffer[j] = getalignedbytes((blocksize + sys_dacblocksize) * sizeof (float)); pa_outbuffer[j] = getalignedbytes((blocksize + sys_dacblocksize) * sizeof (float)); } pa_bufferpos = 0;
/* report to portaudio */ err = Pa_OpenStream(&pa_stream, ( (pa_indev != -1) ? &inputParameters : 0), ( (pa_outdev != -1) ? &outputParameters : 0), rate, pa_blocksize, paClipOff, /* tb: we should be faster ;-) */ process /* patestCallback */, NULL);
if (err == paNoError) { const PaStreamInfo * streaminfo = Pa_GetStreamInfo (pa_stream); t_atom atoms[2];
t_symbol * pd = gensym("pd"); t_symbol * latency = gensym("latency"); t_symbol * selector1 = gensym("audioindev"); t_symbol * selector2 = gensym("audiooutdev");
sys_schedadvance = 1e-6 * streaminfo->outputLatency; SETSYMBOL(atoms, latency);
SETFLOAT(atoms+1, streaminfo->inputLatency); typedmess(pd->s_thing, selector1, 2, atoms);
SETFLOAT(atoms+1, streaminfo->outputLatency); typedmess(pd->s_thing, selector2, 2, atoms); } } else err = 0;
if ( err != paNoError ) { post("Error number %d occured opening portaudio stream\n", err); post("Error message: %s\n", Pa_GetErrorText( err ) ); sys_inchannels = sys_outchannels = 0; return (1); } else if (sys_verbose) post("... opened OK."); 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)); 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 */
static int patestCallback(const void* inputBuffer, void* outputBuffer, unsigned long framesPerBuffer, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void* userData) { int frameIndex, channelIndex, i; float** outputs = (float**)outputBuffer; static float phase;
for( frameIndex=0; frameIndex<(int)framesPerBuffer; frameIndex++ ) { int c; /* Output sine wave on every channel. */ outputs[0][frameIndex] = (float) sin(phase); outputs[1][frameIndex] = (float) sin(phase); phase += 0.05; if( phase >= (2.0 * M_PI) ) phase -= (2.0 * M_PI);
} for (i = 0; i != framesPerBuffer / sys_dacblocksize; ++i) { sched_tick(sys_time + sys_time_per_dsp_tick); }
return 0; }
void run_all_idle_callbacks(void);
int process (const void *input, void *output, unsigned long frameCount, const PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags statusFlags, void *userData) { static started = 0;
int i; int timeout = (float)frameCount / (float) sys_dacsr * 1e6;
if (statusFlags) post("statusFlags %p", statusFlags);
if (sys_timedlock(timeout) == ETIMEDOUT) /* we're late */ { post("timeout %d", timeout); sys_log_error(ERR_SYSLOCK); return 0; }
for (i = 0; i != frameCount / sys_dacblocksize; ++i) { int j; for (j = 0; j < sys_inchannels; j++) { t_sample * in = ((t_sample**)input)[j] + i * sys_dacblocksize; 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] + i * sys_dacblocksize; 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); }
run_all_idle_callbacks(); sys_unlock();
return 0; }
void pa_close_audio( void) { post("closing portaudio"); if (pa_inchans || pa_outchans) { if (pa_stream) { int status = Pa_StopStream(pa_stream);
if (status) post("error closing audio: %d", status);
Pa_CloseStream(pa_stream); pa_stream = NULL; } } sys_setscheduler(0);
post("portaudio closed"); pa_inchans = pa_outchans = 0; pa_indev = pa_outdev = -1; }
/* for blocked IO */ int pa_send_dacs(void) { /* we don't support blocking i/o */ return SENDDACS_NO; }
void pa_listdevs(void) /* lifted from pa_devs.c in portaudio */ { int i,j; int numDevices; const PaDeviceInfo *pdi; PaError err; pa_initialize();
numDevices = Pa_GetDeviceCount(); if( numDevices < 0 ) { fprintf(stderr, "ERROR: Pa_GetDeviceCount returned %d\n", numDevices ); err = numDevices; goto error; } fprintf(stderr, "Audio Devices:\n"); for( i=0; i<numDevices; i++ ) { const 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 ); fprintf(stderr, "%d outputs", pdi->maxOutputChannels ); if ( i == Pa_GetDefaultInputDevice() ) fprintf(stderr, " (Default Input)"); if ( i == Pa_GetDefaultOutputDevice() ) fprintf(stderr, " (Default Output)"); fprintf(stderr, "\n"); }
fprintf(stderr, "\n"); return;
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 ) );
}
/* 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) { PaHostApiIndex api = pdi->hostApi; const PaHostApiInfo * info = Pa_GetHostApiInfo (api); const char * apiName = info->name; unsigned int apiNameLen = strlen(apiName); strcpy(indevlist + nin * devdescsize, apiName); indevlist[nin * devdescsize + apiNameLen] = '/'; strcpy(indevlist + nin * devdescsize + apiNameLen + 1, pdi->name); nin++; } if (pdi->maxOutputChannels > 0 && nout < maxndev) { PaHostApiIndex api = pdi->hostApi; const PaHostApiInfo * info = Pa_GetHostApiInfo (api); const char * apiName = info->name; unsigned int apiNameLen = strlen(apiName); strcpy(outdevlist + nout * devdescsize, apiName);
outdevlist[nout * devdescsize + apiNameLen] = '/'; strcpy(outdevlist + nout * devdescsize + apiNameLen + 1, pdi->name); nout++; } } *nindevs = nin; *noutdevs = nout; }
void pa_getaudioindevinfo(t_float f) { int i = (int)f; const PaDeviceInfo * pdi;
pa_initialize(); pdi = Pa_GetDeviceInfo (i);
if (pdi) { t_symbol * selector = gensym("audioindevinfo"); t_symbol * pd = gensym("pd"); t_atom argv[4]; SETFLOAT(argv, pdi->maxInputChannels); SETFLOAT(argv+1, pdi->defaultSampleRate); SETFLOAT(argv+2, pdi->defaultLowInputLatency); SETFLOAT(argv+3, pdi->defaultHighInputLatency); typedmess(pd->s_thing, selector, 4, argv); } }
void pa_getaudiooutdevinfo(t_float f) { int i = (int)f; const PaDeviceInfo * pdi;
pa_initialize(); pdi = Pa_GetDeviceInfo (i);
if (pdi) { t_symbol * selector = gensym("audiooutdevinfo"); t_symbol * pd = gensym("pd"); t_atom argv[4]; SETFLOAT(argv, pdi->maxOutputChannels); SETFLOAT(argv+1, pdi->defaultSampleRate); SETFLOAT(argv+2, pdi->defaultLowOutputLatency); SETFLOAT(argv+3, pdi->defaultHighOutputLatency); typedmess(pd->s_thing, selector, 4, argv); } }
void pa_getcurrent_devices(void) { t_symbol * pd = gensym("pd"); t_symbol * selector = gensym("audiodevice"); t_atom argv[2]; SETFLOAT(argv, pa_indev); SETFLOAT(argv+1, pa_outdev); typedmess(pd->s_thing, selector, 2, argv); }
void pa_test_setting (int ac, t_atom *av) { int indev = atom_getfloatarg(0, ac, av); int outdev = atom_getfloatarg(1, ac, av); int samplerate = atom_getfloatarg(2, ac, av); int inchans = atom_getfloatarg(3, ac, av); int outchans = atom_getfloatarg(4, ac, av); int advance = atom_getfloatarg(5, ac, av); int blocksize = (advance * samplerate) / (1000000.); t_symbol * pd = gensym("pd"); t_symbol * selector = gensym("testaudiosettingresult"); t_atom argv[1]; int ret; PaStreamParameters inputParameters, outputParameters;
if ((pa_indev == -1) && (pa_outdev == -1)) { pa_initialize();
inputParameters.device = indev; inputParameters.channelCount = inchans; inputParameters.sampleFormat = paFloat32 | paNonInterleaved; inputParameters.suggestedLatency = advance * 0.001; inputParameters.hostApiSpecificStreamInfo = NULL;
outputParameters.device = outdev; outputParameters.channelCount = outchans; outputParameters.sampleFormat = paFloat32 | paNonInterleaved; outputParameters.suggestedLatency = advance * 0.001; outputParameters.hostApiSpecificStreamInfo = NULL;
ret = Pa_IsFormatSupported(&inputParameters, &outputParameters, samplerate);
SETFLOAT(argv, ret); typedmess(pd->s_thing, selector, 1, argv); } }
Index: m_glob.c =================================================================== RCS file: /cvsroot/pure-data/pd/src/m_glob.c,v retrieving revision 1.4.4.2.2.4 retrieving revision 1.4.4.2.2.5 diff -C2 -d -r1.4.4.2.2.4 -r1.4.4.2.2.5 *** m_glob.c 27 Mar 2006 12:08:57 -0000 1.4.4.2.2.4 --- m_glob.c 20 Apr 2006 13:32:33 -0000 1.4.4.2.2.5 *************** *** 34,39 **** void glob_tooltips(t_pd *dummy, t_float f); /* tb: message-based audio configuration { */ ! void glob_audio_getaudioindevices(t_pd * dummy, t_float f); ! void glob_audio_getaudiooutdevices(t_pd * dummy, t_float f); void glob_audio_samplerate(t_pd * dummy, t_float f); void glob_audio_delay(t_pd * dummy, t_float f); --- 34,42 ---- void glob_tooltips(t_pd *dummy, t_float f); /* tb: message-based audio configuration { */ ! void glob_audio_testaudiosetting(t_pd * dummy, t_symbol *s, int ac, t_atom *av); ! void glob_audio_getaudioindevices(t_pd * dummy, t_symbol *s, int ac, t_atom *av); ! void glob_audio_getaudiooutdevices(t_pd * dummy, t_symbol *s, int ac, t_atom *av); ! void glob_audio_getaudioindevinfo(t_pd * dummy, t_float f); ! void glob_audio_getaudiooutdevinfo(t_pd * dummy, t_float f); void glob_audio_samplerate(t_pd * dummy, t_float f); void glob_audio_delay(t_pd * dummy, t_float f); *************** *** 43,46 **** --- 46,50 ---- void glob_audio_device_in(t_pd * dummy, t_symbol *s, int argc, t_atom *argv); void glob_audio_device_out(t_pd * dummy, t_symbol *s, int argc, t_atom *argv); + void glob_audio_getcurrent_devices(void); /* tb } */
*************** *** 70,73 **** --- 74,85 ---- if (s == gensym("audiooutdev")) return; + if (s == gensym("audioindevinfo")) + return; + if (s == gensym("audiooutdevinfo")) + return; + if (s == gensym("testaudiosettingresult")) + return; + if (s == gensym("audiodevice")) + return;
startpost("%s: unknown message %s ", class_getname(pd_class(x)), *************** *** 132,155 **** gensym("save-preferences"), 0); class_addmethod(glob_pdobject, (t_method)glob_tooltips, ! gensym("tooltips"), A_DEFFLOAT, 0); /* tb: message-based audio configuration { */ class_addmethod(glob_pdobject, (t_method)glob_audio_samplerate, gensym("audio-samplerate"), A_DEFFLOAT, 0); class_addmethod(glob_pdobject, (t_method)glob_audio_delay, ! gensym("audio-delay"), A_DEFFLOAT, 0); class_addmethod(glob_pdobject, (t_method)glob_audio_dacblocksize, gensym("audio-dacblocksize"), A_DEFFLOAT, 0); class_addmethod(glob_pdobject, (t_method)glob_audio_scheduler, ! gensym("audio-scheduler"), A_DEFFLOAT, 0); class_addmethod(glob_pdobject, (t_method)glob_audio_device, ! gensym("audio-device"), A_GIMME, 0); class_addmethod(glob_pdobject, (t_method)glob_audio_device_in, ! gensym("audio-device-in"), A_GIMME, 0); class_addmethod(glob_pdobject, (t_method)glob_audio_device_out, ! gensym("audio-device-out"), A_GIMME, 0); class_addmethod(glob_pdobject, (t_method)glob_audio_getaudioindevices, ! gensym("getaudioindev"), A_GIMME, 0); class_addmethod(glob_pdobject, (t_method)glob_audio_getaudiooutdevices, ! gensym("getaudiooutdev"), A_GIMME, 0); /* tb } */ #ifdef UNIX --- 144,175 ---- gensym("save-preferences"), 0); class_addmethod(glob_pdobject, (t_method)glob_tooltips, ! gensym("tooltips"), A_DEFFLOAT, 0); /* tb: message-based audio configuration { */ class_addmethod(glob_pdobject, (t_method)glob_audio_samplerate, gensym("audio-samplerate"), A_DEFFLOAT, 0); class_addmethod(glob_pdobject, (t_method)glob_audio_delay, ! gensym("audio-delay"), A_DEFFLOAT, 0); class_addmethod(glob_pdobject, (t_method)glob_audio_dacblocksize, gensym("audio-dacblocksize"), A_DEFFLOAT, 0); class_addmethod(glob_pdobject, (t_method)glob_audio_scheduler, ! gensym("audio-scheduler"), A_DEFFLOAT, 0); class_addmethod(glob_pdobject, (t_method)glob_audio_device, ! gensym("audio-device"), A_GIMME, 0); class_addmethod(glob_pdobject, (t_method)glob_audio_device_in, ! gensym("audio-device-in"), A_GIMME, 0); class_addmethod(glob_pdobject, (t_method)glob_audio_device_out, ! gensym("audio-device-out"), A_GIMME, 0); class_addmethod(glob_pdobject, (t_method)glob_audio_getaudioindevices, ! gensym("getaudioindev"), A_GIMME, 0); class_addmethod(glob_pdobject, (t_method)glob_audio_getaudiooutdevices, ! gensym("getaudiooutdev"), A_GIMME, 0); ! class_addmethod(glob_pdobject, (t_method)glob_audio_getaudioindevinfo, ! gensym("getaudioindevinfo"), A_FLOAT, 0); ! class_addmethod(glob_pdobject, (t_method)glob_audio_getaudiooutdevinfo, ! gensym("getaudiooutdevinfo"), A_FLOAT, 0); ! class_addmethod(glob_pdobject, (t_method)glob_audio_testaudiosetting, ! gensym("testaudiosetting"), A_GIMME, 0); ! class_addmethod(glob_pdobject, (t_method)glob_audio_getcurrent_devices, ! gensym("getaudiodevice"), 0); /* tb } */ #ifdef UNIX