[PD-cvs] pd/src s_audio_asio.cpp,NONE,1.1.2.1 s_stuff.h,1.1.1.1.2.6,1.1.1.1.2.7 s_audio.c,1.1.1.1.2.11,1.1.1.1.2.12 s_main.c,1.1.1.4.2.21,1.1.1.4.2.22 makefile.nt,1.1.1.3.2.4,1.1.1.3.2.5
Tim Blechmann
timblech at users.sourceforge.net
Thu Nov 4 21:22:47 CET 2004
- Previous message: [PD-cvs] externals/hcs/hid TODO,NONE,1.1 hid-help.pd,1.4,1.5 hid.c,1.7,1.8 hid.h,1.4,1.5 hid_darwin.c,1.3,1.4
- Next message: [PD-cvs] externals/cxc makefile,1.4,1.5
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
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)
- Previous message: [PD-cvs] externals/hcs/hid TODO,NONE,1.1 hid-help.pd,1.4,1.5 hid.c,1.7,1.8 hid.h,1.4,1.5 hid_darwin.c,1.3,1.4
- Next message: [PD-cvs] externals/cxc makefile,1.4,1.5
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the Pd-cvs
mailing list