Update of /cvsroot/pure-data/pd/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv31290
Modified Files: Tag: devel_0_37 s_stuff.h s_audio.c s_main.c makefile.nt Added Files: Tag: devel_0_37 s_audio_asio.cpp Log Message: native asio support
Index: s_audio.c =================================================================== RCS file: /cvsroot/pure-data/pd/src/s_audio.c,v retrieving revision 1.1.1.1.2.11 retrieving revision 1.1.1.1.2.12 diff -C2 -d -r1.1.1.1.2.11 -r1.1.1.1.2.12 *** s_audio.c 9 Oct 2004 11:58:22 -0000 1.1.1.1.2.11 --- s_audio.c 4 Nov 2004 20:22:44 -0000 1.1.1.1.2.12 *************** *** 331,334 **** --- 331,340 ---- else #endif + #ifdef USEAPI_ASIO + if (sys_audioapi == API_ASIO) + asio_open_audio(naudioindev, audioindev, nchindev, chindev, + naudiooutdev, audiooutdev, nchoutdev, choutdev, rate); + else + #endif post("unknown audio API specified"); } *************** *** 371,374 **** --- 377,385 ---- else #endif + #ifdef USEAPI_ASIO + if (sys_audioapi == API_ASIO) + asio_close_audio(); + else + #endif post("sys_close_audio: unknown API %d", sys_audioapi); sys_inchannels = sys_outchannels = 0; *************** *** 436,439 **** --- 447,455 ---- else #endif + #ifdef USEAPI_ASIO + if (sys_audioapi == API_ASIO) + return (asio_send_dacs()); + else + #endif post("unknown API"); return (0); *************** *** 528,531 **** --- 544,555 ---- else #endif + #ifdef USEAPI_ASIO + if (sys_audioapi == API_ASIO) + { + asio_getdevs(indevlist, nindevs, outdevlist, noutdevs, canmulti, + maxndev, devdescsize); + } + else + #endif { /* this shouldn't happen once all the above get filled in. */ *************** *** 811,814 **** --- 835,841 ---- sprintf(buf + strlen(buf), "{OSS %d} ", API_OSS); n++; #endif + #ifdef USEAPI_ASIO + sprintf(buf + strlen(buf), "{ASIO %d} ", API_ASIO); n++; + #endif #ifdef USEAPI_MMIO sprintf(buf + strlen(buf), "{"standard (MMIO)" %d} ", API_MMIO); n++;
--- NEW FILE: s_audio_asio.cpp --- /* Copyright (c) 2004, Tim Blechmann and others * For information on usage and redistribution, and for a DISCLAIMER OF ALL * WARRANTIES, see the file, "LICENSE.txt" in this distribution. */
/* native ASIO interface for windows and mac osx * adapted from hostsample.cpp (ASIO SDK) */
#ifdef USEAPI_ASIO
#ifdef MSW #include "windows.h" /* for application window handle */ #define IEEE754_64FLOAT 1 #endif
#include "m_pd.h" extern "C" { #include "s_stuff.h" } #include "asio.h" /* steinberg's header file */ #include "asiodrivers.h" /* ASIODrivers class */ #include "asiosys.h" #include "pthread.h" #include "stdio.h" /* for sprintf */
#define ASIODEBUG
/* public function prototypes */ extern "C" void asio_open_audio(int naudioindev, int *audioindev, int nchindev, int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev, int srate); extern "C" void asio_close_audio(void); extern "C" void asio_getdevs(char *indevlist, int *nindevs, char *outdevlist, int *noutdevs, int *canmulti, int maxndev, int devdescsize); extern "C" int asio_send_dacs(void);
/* asio callback prototypes */ void asio_bufferSwitch(long db_idx, ASIOBool directprocess); void asio_sampleRateDidChange(ASIOSampleRate srate); long asio_messages(long selector, long value, void* message, double* opt); ASIOTime *asio_bufferSwitchTimeInfo(ASIOTime *params, long db_idx, ASIOBool directprocess);
/* sample converting helper functions: * - global send / receive functions * - sample conversion functions (adapted from ASIOConvertSamples.cpp */ void asio_convert_and_send (t_sample* source, void* dest, ASIOSampleType format, long asio_bufsize); void asio_convert_and_receive (void* source, t_sample* dest, ASIOSampleType format, long asio_bufsize); void float32toInt16(float* inbuffer, void* outbuffer, long frames); void Int16tofloat32(void* inbuffer, float* outbuffer, long frames); void float32toInt32(float* inbuffer, void* outbuffer, long frames); void Int32tofloat32(void* inbuffer, float* outbuffer, long frames);
/* some local helper functions */ inline void prepare_asio_drivernames(void);
/* system dependent helper functions */ static unsigned long get_sys_reference_time(void);
/* global storage */ ASIODriverInfo * asio_driver = NULL; ASIOBufferInfo * asio_bufferinfo; ASIOChannelInfo* asio_channelinfo; AsioTimeInfo * asio_timerinfo; ASIOCallbacks asio_callbacks; extern AsioDrivers * asioDrivers; /* declared in asiodrivers.cpp */
char ** asio_drivernames = NULL;
ASIOSampleRate asio_srate; long asio_inchannels; long asio_outchannels;
long asio_minbufsize; long asio_maxbufsize; long asio_prefbufsize; long asio_granularity; unsigned char asio_useoutputready; long asio_inputlatency; long asio_outputlatency;
long asio_bufsize;
unsigned long sys_reftime;
/* ringbuffer stuff */ t_sample ** asio_ringbuffer; /* ringbuffers */ static int asio_ringbuffer_inoffset; /* ringbuffer(in) pointer offset for dac */ static int asio_ringbuffer_outoffset; /* ringbuffer(out) pointer offset */ static int asio_ringbuffer_length; /* latency - hardware latency in samples*/
/* i hope we can remove this to use callback based dsp scheduling */ static pthread_mutex_t asio_ringbuf_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t asio_ringbuf_cond = PTHREAD_COND_INITIALIZER;
/* definitions from s_audio.c ... it should be save to use them */ #define DEVDESCSIZE 80 #define MAXNDEV 20
/* open asio interface */ /* todo: some more error messages */ void asio_open_audio(int naudioindev, int *audioindev, int nchindev, int *chindev, int naudiooutdev, int *audiooutdev, int nchoutdev, int *choutdev, int srate) { ASIOError status; ASIOBufferInfo * buffers; int i; int channels;
#ifdef IEEE754_64FLOAT asio_srate=(ASIOSampleRate)srate; #else sprintf(asio_srate,"%d",srate); #endif
/* check, if we use the first asio device */ prepare_asio_drivernames(); /* load the driver */ if (!asioDrivers) asioDrivers = new AsioDrivers(); /* check, if the driver is still running */ if (asio_driver) asio_close_audio();
asioDrivers->getDriverNames(asio_drivernames,MAXNDEV);
asioDrivers->loadDriver(asio_drivernames[*audioindev]);
/* initialize ASIO */ asio_driver = (ASIODriverInfo*) getbytes (sizeof(ASIODriverInfo)); asio_driver->asioVersion = 2; /* i hope we are compatible with asio 2 */ #ifdef MSW asio_driver->sysRef = GetDesktopWindow(); #else asio_driver->sysRef = 0; #endif status = ASIOInit(asio_driver); #ifdef ASIODEBUG post("sysRef: %x", asio_driver->sysRef); post("asioversion: %d", asio_driver->asioVersion); post("driverversion: %d", asio_driver->driverVersion); post("name: %s", asio_driver->name); post("error: %s", asio_driver->errorMessage); #endif
switch (status) { case ASE_NotPresent: error("ASIO: ASE_NotPresent"); freebytes(asio_driver, sizeof (ASIODriverInfo)); asio_driver = NULL; return; case ASE_NoMemory: error("ASIO: ASE_NoMemory"); freebytes(asio_driver, sizeof (ASIODriverInfo)); asio_driver = NULL; return; case ASE_HWMalfunction: error("ASIO: ASE_HWMalfunction"); freebytes(asio_driver, sizeof (ASIODriverInfo)); asio_driver = NULL; return; } post("ASIO initialized successfully");
/* query driver */ ASIOGetChannels(&asio_inchannels, &asio_outchannels); post ("ASIOGetChannels\tinputs: %d, outputs: %d", asio_inchannels, asio_outchannels);
/* tb: todo: channel count hardcoded to asio hardware */ sys_inchannels = *chindev <= asio_inchannels ? *chindev : asio_inchannels; sys_outchannels = *choutdev <= asio_outchannels ? *choutdev : asio_outchannels; channels = sys_inchannels + sys_outchannels;
ASIOGetBufferSize(&asio_minbufsize, &asio_maxbufsize, &asio_prefbufsize, &asio_granularity); post ("ASIOGetBufferSize\tmin: %d, max: %d, preferred: %d, granularity: " "%d", asio_minbufsize, asio_maxbufsize, asio_prefbufsize, asio_granularity);
/* todo: buffer size hardcoded to asio hardware */ asio_bufsize = asio_prefbufsize;
/* set sample rate */ if (ASIOCanSampleRate( asio_srate ) != ASE_OK) { error ("Samplerate not supported, using default"); #ifdef IEEE754_64FLOAT asio_srate = (ASIOSampleRate)44100.0; #else sprintf(&asio_srate,"%d",44100); #endif srate=44100; } ASIOSetSampleRate( asio_srate ); post ("ASIOSetSampleRate\t %d", srate); if (ASIOOutputReady() == ASE_OK) asio_useoutputready = 1; else asio_useoutputready = 0;
/* set callbacks */ asio_callbacks.bufferSwitch = &asio_bufferSwitch; asio_callbacks.sampleRateDidChange = &asio_sampleRateDidChange; asio_callbacks.asioMessage = &asio_messages; asio_callbacks.bufferSwitchTimeInfo = &asio_bufferSwitchTimeInfo;
/* prepare, create and set up buffers */ asio_bufferinfo = (ASIOBufferInfo*) getbytes (channels * sizeof (ASIOBufferInfo)); asio_channelinfo = (ASIOChannelInfo*) getbytes(channels * sizeof (ASIOChannelInfo)); if (!(asio_bufferinfo && asio_channelinfo)) { error("ASIO: couldn't allocate buffer or channel info"); if (asio_bufferinfo) freebytes(asio_bufferinfo, channels * sizeof (ASIOBufferInfo)); if (asio_channelinfo) freebytes(asio_channelinfo, channels * sizeof (ASIOChannelInfo)); return; }
for (i = 0; i != sys_inchannels + sys_outchannels; ++i) { if (i < sys_outchannels) { asio_bufferinfo[i].isInput = ASIOFalse; asio_bufferinfo[i].channelNum = i; asio_bufferinfo[i].buffers[0] = asio_bufferinfo[i].buffers[1] = 0; } else { asio_bufferinfo[i].isInput = ASIOTrue; asio_bufferinfo[i].channelNum = i - sys_outchannels; } } if (ASIOCreateBuffers(asio_bufferinfo, sys_inchannels + sys_outchannels, asio_bufsize, &asio_callbacks) == ASE_OK) { post("ASIO: buffers allocated"); } else { error("ASIO: couldn't allocate buffers"); return; }
for (i = 0; i != sys_inchannels + sys_outchannels; ++i) { asio_channelinfo[i].channel = asio_bufferinfo[i].channelNum; asio_channelinfo[i].isInput = asio_bufferinfo[i].isInput; ASIOGetChannelInfo(&asio_channelinfo[i]); }
/* get latencies */ ASIOGetLatencies(&asio_inputlatency, &asio_outputlatency); #ifdef ASIODEBUG post("ASIO: input latency: %d, output latency: %d",asio_inputlatency, asio_outputlatency); #endif
/* calculate ringbuffer length */ asio_ringbuffer_length = asio_bufsize * DEFDACBLKSIZE; /* a strange way to find the least common multiple, * but works, since DEFDACBLKSIZE (expt 2 x) */ while ( !(asio_ringbuffer_length % DEFDACBLKSIZE) && !(asio_ringbuffer_length % asio_bufsize)) { asio_ringbuffer_length /= 2; } asio_ringbuffer_length *= 2;
#ifdef ASIODEBUG post("ASIO: ringbuffer size: %d",asio_ringbuffer_length); #endif /* allocate ringbuffer */ asio_ringbuffer = (t_sample**) getbytes (channels * sizeof (t_sample*)); for (i = 0; i != channels; ++i) { asio_ringbuffer[i] = (t_sample*)getbytes(asio_ringbuffer_length * sizeof (t_sample)); if (!asio_ringbuffer[i]) error("ASIO: couldn't allocate ASIO ringbuffer"); memset(asio_ringbuffer[i], 0, asio_ringbuffer_length * sizeof (t_sample)); }
/* initialize ringbuffer stuff */ asio_ringbuffer_inoffset = asio_ringbuffer_outoffset = 0;
if (ASIOStart() == ASE_OK) { post("ASIO: started"); } else post("ASIO: couldn't start"); return; }
/* stop asio, free buffers and close asio interface */ void asio_close_audio(void) { ASIOError status; int channels = asio_inchannels + asio_outchannels; int i;
pthread_cond_broadcast(&asio_ringbuf_cond);
ASIOStop();
if (asio_driver) { for (i = 0; i != channels; i++) freebytes(asio_ringbuffer[i], asio_ringbuffer_length * sizeof (t_sample)); freebytes(asio_ringbuffer, channels * sizeof (t_sample *)); freebytes(asio_bufferinfo, channels * sizeof (ASIOBufferInfo)); freebytes(asio_channelinfo, channels * sizeof (ASIOChannelInfo)); ASIODisposeBuffers(); asio_ringbuffer = NULL; asio_bufferinfo = NULL; asio_channelinfo = NULL; ASIOExit(); freebytes(asio_driver, sizeof (ASIODriverInfo)); asio_driver = NULL; } return; }
void asio_getdevs(char *indevlist, int *nindevs, char *outdevlist, int *noutdevs, int *canmulti, int maxndev, int devdescsize) { prepare_asio_drivernames();
*canmulti = 0; /* we will only support one asio device */ *nindevs = *noutdevs = (int)asioDrivers->getDriverNames(asio_drivernames, maxndev); for(int i = 0; i!= *nindevs; ++i) { sprintf(indevlist + i * devdescsize, "%s", asio_drivernames[i]); sprintf(outdevlist + i * devdescsize, "%s", asio_drivernames[i]); } }
/* called on every dac~ send * todo: * - use vectorized functions * - function pointer to avoid segfaults */ int asio_send_dacs(void) { t_sample * sp; /* sample pointer */ int i, j; int timenow; int timeref = sys_getrealtime(); #ifdef ASIODEBUG if (!asio_driver) { error("ASIO not running"); return SENDDACS_NO; } #endif
/* send sound to ringbuffer */ sp = sys_soundout; for (i = 0; i < sys_outchannels; i++) { memcpy(asio_ringbuffer[i] + asio_ringbuffer_inoffset, sp, DEFDACBLKSIZE*sizeof(t_sample)); memset(sp, 0, DEFDACBLKSIZE*sizeof(t_sample)); sp+=DEFDACBLKSIZE; } /* get sound from ringbuffer */ sp = sys_soundin; for (j = 0; j < sys_inchannels; j++) { memcpy(sp, asio_ringbuffer[i+j] + asio_ringbuffer_inoffset, DEFDACBLKSIZE*sizeof(t_sample)); sp+=DEFDACBLKSIZE; } asio_ringbuffer_inoffset += DEFDACBLKSIZE;
if (asio_ringbuffer_inoffset >= asio_ringbuffer_outoffset + asio_bufsize) { pthread_cond_wait(&asio_ringbuf_cond, &asio_ringbuf_mutex); if (asio_ringbuffer_inoffset == asio_ringbuffer_length) { asio_ringbuffer_outoffset = 0; asio_ringbuffer_inoffset = 0; } else asio_ringbuffer_outoffset += asio_bufsize; } if ((timenow = sys_getrealtime()) - timeref > 0.002) { return SENDDACS_SLEPT; } return SENDDACS_YES; }
/* buffer switch callback */ void asio_bufferSwitch(long db_idx, ASIOBool directprocess) { ASIOTime time; memset (&time, 0, sizeof (time)); /* todo: do we need to syncronize with other media ??? */ asio_bufferSwitchTimeInfo(&time, db_idx, directprocess); }
/* sample rate change callback */ void asio_sampleRateDidChange(ASIOSampleRate srate) { asio_srate = srate; #ifdef ASIODEBUG post("sample rate changed"); #endif }
/* asio messaging callback */ long asio_messages(long selector, long value, void* message, double* opt) { /* todo */ return 0L; }
ASIOTime *asio_bufferSwitchTimeInfo(ASIOTime *params, long db_idx, ASIOBool directprocess) { long i, j;
// todo: store the timeInfo for later use
/* todo: i'm not sure if we'll have to synchronize with other media ... * probably yes ... */ /* sys_reftime = get_sys_reference_time(); */
/* perform the processing * todo: improve input latency */ for (i = 0; i < asio_outchannels + asio_inchannels; i++) { if (asio_bufferinfo[i].isInput != ASIOTrue) { asio_convert_and_send(asio_ringbuffer[i]+asio_ringbuffer_outoffset, (void*) asio_bufferinfo[i].buffers[db_idx], asio_channelinfo[i].type, asio_bufsize); } else /* these are the input channels */ { asio_convert_and_receive((void*)asio_bufferinfo[i].buffers[db_idx], asio_ringbuffer[i]+asio_ringbuffer_outoffset, asio_channelinfo[i].type, asio_bufsize); } } pthread_cond_broadcast(&asio_ringbuf_cond);
if(asio_useoutputready) ASIOOutputReady();
return 0L; /* time info!!! */ }
/* get system reference time on both platforms */ static unsigned long get_sys_reference_time() { #if WINDOWS return timeGetTime(); #elif MAC static const double twoRaisedTo32 = 4294967296.; UnsignedWide ys; Microseconds(&ys); double r = ((double)ys.hi * twoRaisedTo32 + (double)ys.lo); return (unsigned long)(r / 1000.); #endif }
/* sample converting helper functions */ void asio_convert_and_send(t_sample* source, void* dest, ASIOSampleType format, long bufsize) {
#ifdef ASIODEBUG /* post("ASIO: Sample Type %d", format); */ #endif switch (format) { case ASIOSTInt16LSB: /* e.g. m audio quattro */ float32toInt16(source, dest, bufsize); break; case ASIOSTFloat32LSB: // IEEE 754 32 bit float, as found on Intel x86 architecture memcpy (dest, source, bufsize * sizeof (float)); /* check */ break; case ASIOSTInt24LSB: // used for 20 bits as well float32toInt24(source, dest, bufsize);
case ASIOSTInt32LSB: float32toInt32(source, dest, bufsize);
case ASIOSTFloat64LSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture
// these are used for 32 bit data buffer, with different alignment of the data inside // 32 bit PCI bus systems can more easily used with these case ASIOSTInt32LSB16: // 32 bit data with 18 bit alignment case ASIOSTInt32LSB18: // 32 bit data with 18 bit alignment case ASIOSTInt32LSB20: // 32 bit data with 20 bit alignment case ASIOSTInt32LSB24: // 32 bit data with 24 bit alignment
case ASIOSTInt16MSB:
case ASIOSTInt24MSB: // used for 20 bits as well
case ASIOSTInt32MSB:
case ASIOSTFloat32MSB: // IEEE 754 32 bit float, as found on Intel x86 architecture
case ASIOSTFloat64MSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture // these are used for 32 bit data buffer, with different alignment of the data inside // 32 bit PCI bus systems can more easily used with these case ASIOSTInt32MSB16: // 32 bit data with 18 bit alignment case ASIOSTInt32MSB18: // 32 bit data with 18 bit alignment case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment post("Sample Type %d not supported, yet"); } }
void asio_convert_and_receive (void* source, t_sample* dest, ASIOSampleType format, long bufsize) { #ifdef ASIODEBUG /* post("ASIO: Sample Type %d", format); */ #endif
switch (format) { case ASIOSTInt16LSB: Int16tofloat32(source, dest, bufsize); break; case ASIOSTFloat32LSB: // IEEE 754 32 bit float, as found on Intel x86 architecture memcpy (dest, source, bufsize * sizeof (float)); /* check */ break; case ASIOSTInt24LSB: // used for 20 bits as well Int24tofloat32(source, dest, bufsize); break; case ASIOSTInt32LSB: Int32tofloat32(source, dest, bufsize); break
case ASIOSTFloat64LSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture
// these are used for 32 bit data buffer, with different alignment of the data inside // 32 bit PCI bus systems can more easily used with these case ASIOSTInt32LSB16: // 32 bit data with 18 bit alignment case ASIOSTInt32LSB18: // 32 bit data with 18 bit alignment case ASIOSTInt32LSB20: // 32 bit data with 20 bit alignment case ASIOSTInt32LSB24: // 32 bit data with 24 bit alignment
case ASIOSTInt16MSB: case ASIOSTInt24MSB: // used for 20 bits as well case ASIOSTInt32MSB: case ASIOSTFloat32MSB: // IEEE 754 32 bit float, as found on Intel x86 architecture case ASIOSTFloat64MSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture
// these are used for 32 bit data buffer, with different alignment of the data inside // 32 bit PCI bus systems can more easily used with these case ASIOSTInt32MSB16: // 32 bit data with 18 bit alignment case ASIOSTInt32MSB18: // 32 bit data with 18 bit alignment case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment post("Sample Type %d not supported, yet"); }
}
/* sample conversion functions */
#define SCALE_INT16 32767.f /* (- (expt 2 15) 1) */ #define SCALE_INT32 8388607.f /* (- (expt 2 23) 1) */ #define SCALE_INT32 2147483647.f /* (- (expt 2 31) 1) */
void float32toInt16(float* inbuffer, void* outbuffer, long frames) { short* out = (short*)outbuffer; while (frames--) { *out++ = (short)(*inbuffer++ * SCALE_INT16); } }
void Int16tofloat32(void* inbuffer, float* outbuffer, long frames) { short* in = (short*)inbuffer; while (frames--) { *outbuffer++ = (float)(*in++ * (1.f / SCALE_INT16)); } }
void float32toInt24(float* inbuffer, void* outbuffer, long frames) { long* out = (int*)outbuffer; while (frames--) { *out++ = (int)(*inbuffer * SCALE_INT24); } }
void Int32tofloat24(void* inbuffer, float* outbuffer, long frames) { long* in = (int*)inbuffer; while (frames--) { *outbuffer++ = (float)(*in++ * (1.f / SCALE_INT24)); } }
void float32toInt32(float* inbuffer, void* outbuffer, long frames) { long* out = (long*)outbuffer; while (frames--) { *out++ = (long)(*inbuffer * SCALE_INT32); } }
void Int32tofloat32(void* inbuffer, float* outbuffer, long frames) { long* in = (long*)inbuffer; while (frames--) { *outbuffer++ = (float)(*in++ * (1.f / SCALE_INT32)); } }
/* some local helper functions */ inline void prepare_asio_drivernames(void) { if (asio_drivernames == NULL) { asio_drivernames = (char**)getbytes(MAXNDEV * sizeof(char*)); for (int i = 0; i!= MAXNDEV; ++i) { asio_drivernames[i] = (char*)getbytes (32 * sizeof(char)); } } return; }
#endif /* USEAPI_ASIO */
Index: s_stuff.h =================================================================== RCS file: /cvsroot/pure-data/pd/src/s_stuff.h,v retrieving revision 1.1.1.1.2.6 retrieving revision 1.1.1.1.2.7 diff -C2 -d -r1.1.1.1.2.6 -r1.1.1.1.2.7 *** s_stuff.h 7 Oct 2004 23:11:56 -0000 1.1.1.1.2.6 --- s_stuff.h 4 Nov 2004 20:22:44 -0000 1.1.1.1.2.7 *************** *** 132,135 **** --- 132,136 ---- #define API_PORTAUDIO 4 #define API_JACK 5 + #define API_ASIO 6
#ifdef __linux__ *************** *** 138,143 **** #endif #if defined(MSW) || defined(__CYGWIN__) ! #define API_DEFAULT API_MMIO ! #define API_DEFSTRING "MMIO" #endif #ifdef MACOSX --- 139,144 ---- #endif #if defined(MSW) || defined(__CYGWIN__) ! #define API_DEFAULT API_ASIO ! #define API_DEFSTRING "ASIO" #endif #ifdef MACOSX *************** *** 209,212 **** --- 210,222 ---- int maxndev, int devdescsize);
+ void asio_open_audio(int naudioindev, int *audioindev, int nchindev, + int *chindev, int naudiooutdev, int *audiooutdev, + int nchoutdev, int *choutdev, int srate); + void asio_close_audio(void); + void asio_getdevs(char *indevlist, int *nindevs, + char *outdevlist, int *noutdevs, int *canmulti, + int maxndev, int devdescsize); + int asio_send_dacs(void); + void sys_listmididevs(void); void sys_set_audio_api(int whichapi);
Index: s_main.c =================================================================== RCS file: /cvsroot/pure-data/pd/src/s_main.c,v retrieving revision 1.1.1.4.2.21 retrieving revision 1.1.1.4.2.22 diff -C2 -d -r1.1.1.4.2.21 -r1.1.1.4.2.22 *** s_main.c 23 Oct 2004 10:22:08 -0000 1.1.1.4.2.21 --- s_main.c 4 Nov 2004 20:22:44 -0000 1.1.1.4.2.22 *************** *** 309,312 **** --- 309,313 ---- #ifdef DAZ #include <xmmintrin.h> + ; #define _MM_DENORM_ZERO_ON 0x0040 _mm_setcsr(_MM_FLUSH_ZERO_ON | _MM_MASK_UNDERFLOW | _mm_getcsr()); *************** *** 356,359 **** --- 357,364 ---- #endif
+ #ifdef USEAPI_ASIO + "-asio_native -- use native ASIO API\n", + #endif + #ifdef USEAPI_PORTAUDIO #ifdef MSW *************** *** 661,664 **** --- 666,677 ---- } #endif + #ifdef USEAPI_ASIO + else if (!strcmp(*argv, "-asio_native")) + { + sys_set_audio_api(API_ASIO); + sys_mmio = 0; + argc--; argv++; + } + #endif #ifdef USEAPI_MMIO else if (!strcmp(*argv, "-mmio"))
Index: makefile.nt =================================================================== RCS file: /cvsroot/pure-data/pd/src/makefile.nt,v retrieving revision 1.1.1.3.2.4 retrieving revision 1.1.1.3.2.5 diff -C2 -d -r1.1.1.3.2.4 -r1.1.1.3.2.5 *** makefile.nt 29 Oct 2004 07:32:02 -0000 1.1.1.3.2.4 --- makefile.nt 4 Nov 2004 20:22:44 -0000 1.1.1.3.2.5 *************** *** 82,86 **** !else # the trailing slash is important!! ! LDIR = $(VC)\lib\ !endif
--- 82,86 ---- !else # the trailing slash is important!! ! LDIR = $(VC)\lib\ !endif
*************** *** 140,143 **** --- 140,149 ---- cl /c $(ALLCF) /Tc$*.c
+ ASIOBJ: + cl /c $(ALLCF) $(ASIOINC) s_audio_asio.cpp + cl /c $(ALLCF) $(ASIOINC) asio/asio.cpp + cl /c $(ALLCF) $(ASIOINC) asio/pc/asiolist.cpp + cl /c $(ALLCF) $(ASIOINC) asio/asiodrivers.cpp + pd: ..\bin\pd.exe
*************** *** 148,152 **** ..\bin\pd.lib $(LIBS)
! ..\bin\pd.dll ..\bin\pd.lib: $(OBJC) $(OBJASIO) link $(LFLAGS) /dll /export:sys_main /out:..\bin\pd.dll $(OBJC) \ $(OBJASIO) $(LIBS) --- 154,158 ---- ..\bin\pd.lib $(LIBS)
! ..\bin\pd.dll ..\bin\pd.lib: $(OBJC) ASIOBJ link $(LFLAGS) /dll /export:sys_main /out:..\bin\pd.dll $(OBJC) \ $(OBJASIO) $(LIBS)