Update of /cvsroot/pure-data/pd/src In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv19361/src
Modified Files: Tag: devel_0_37 s_audio_asio.cpp Log Message: bug fixes for converter functions force silence on driver shutdown
Index: s_audio_asio.cpp =================================================================== RCS file: /cvsroot/pure-data/pd/src/Attic/s_audio_asio.cpp,v retrieving revision 1.1.2.4 retrieving revision 1.1.2.5 diff -C2 -d -r1.1.2.4 -r1.1.2.5 *** s_audio_asio.cpp 6 Nov 2004 15:22:38 -0000 1.1.2.4 --- s_audio_asio.cpp 6 Nov 2004 21:30:35 -0000 1.1.2.5 *************** *** 24,27 **** --- 24,31 ---- #include "stdio.h" /* for sprintf */
+ #include "assert.h" + #define ASSERT assert + + /* fast float to integer conversion adapted from Erik de Castro Lopo */ #define _ISOC9X_SOURCE 1 *************** *** 31,35 **** --- 35,41 ---- #include "math.h"
+ #ifdef PD_DEBUG #define ASIODEBUG + #endif
/* public function prototypes */ *************** *** 44,70 ****
/* 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);
! void float32copy(float* inbuffer, float* outbuffer, long frames); ! void float32toInt16(float* inbuffer, void* outbuffer, long frames); ! void Int16tofloat32(void* inbuffer, float* outbuffer, long frames); ! void float32toInt24(float* inbuffer, void* outbuffer, long frames); ! void Int24tofloat32(void* inbuffer, float* outbuffer, long frames); ! void float32toInt32(float* inbuffer, void* outbuffer, long frames); ! void Int32tofloat32(void* inbuffer, float* outbuffer, long frames); ! void float32toInt16_S(float* inbuffer, void* outbuffer, long frames); ! void Int16tofloat32_S(void* inbuffer, float* outbuffer, long frames); ! void float32toInt24_S(float* inbuffer, void* outbuffer, long frames); ! void Int24tofloat32_S(void* inbuffer, float* outbuffer, long frames); ! void float32toInt32_S(float* inbuffer, void* outbuffer, long frames); ! void Int32tofloat32_S(void* inbuffer, float* outbuffer, long frames);
/* Swap LSB to MSB and vice versa */ ! #define SwapLong(v) ((((v)>>24)&0xFF)|(((v)>>8)&0xFF00)|(((v)&0xFF00)<<8)|(((v)&0xFF)<<24)) ; ! #define SwapShort(v) ((((v)>>8)&0xFF)|(((v)&0xFF)<<8)) ;
typedef void converter_out_t(float* inbuffer, void* outbuffer, long frames); --- 50,76 ----
/* asio callback prototypes */ ! static void asio_bufferSwitch(long db_idx, ASIOBool directprocess); ! static void asio_sampleRateDidChange(ASIOSampleRate srate); ! static long asio_messages(long selector, long value, void* message, double* opt); ! static ASIOTime *asio_bufferSwitchTimeInfo(ASIOTime *params, long db_idx, ASIOBool directprocess);
! static void float32copy(float* inbuffer, float* outbuffer, long frames); ! static void float32toInt16(float* inbuffer, void* outbuffer, long frames); ! static void Int16tofloat32(void* inbuffer, float* outbuffer, long frames); ! static void float32toInt24(float* inbuffer, void* outbuffer, long frames); ! static void Int24tofloat32(void* inbuffer, float* outbuffer, long frames); ! static void float32toInt32(float* inbuffer, void* outbuffer, long frames); ! static void Int32tofloat32(void* inbuffer, float* outbuffer, long frames); ! static void float32toInt16_S(float* inbuffer, void* outbuffer, long frames); ! static void Int16tofloat32_S(void* inbuffer, float* outbuffer, long frames); ! static void float32toInt24_S(float* inbuffer, void* outbuffer, long frames); ! static void Int24tofloat32_S(void* inbuffer, float* outbuffer, long frames); ! static void float32toInt32_S(float* inbuffer, void* outbuffer, long frames); ! static void Int32tofloat32_S(void* inbuffer, float* outbuffer, long frames);
/* Swap LSB to MSB and vice versa */ ! #define SWAPLONG(v) ((((v)>>24)&0xFF)|(((v)>>8)&0xFF00)|(((v)&0xFF00)<<8)|(((v)&0xFF)<<24)) ! #define SWAPSHORT(v) ((((v)>>8)&0xFF)|(((v)&0xFF)<<8))
typedef void converter_out_t(float* inbuffer, void* outbuffer, long frames); *************** *** 74,87 **** * - global send / receive functions * - sample conversion functions (adapted from ASIOConvertSamples.cpp */ ! void *asio_converter_send (ASIOSampleType format); ! void *asio_converter_receive (ASIOSampleType format);
/* pointers to the converter functions of each channel are stored here */ static void **asio_converter = NULL;
/* some local helper functions */ ! inline void prepare_asio_drivernames(void);
/* system dependent helper functions */ --- 80,100 ---- * - global send / receive functions * - sample conversion functions (adapted from ASIOConvertSamples.cpp */ ! static void *asio_converter_send (ASIOSampleType format); ! static void *asio_converter_receive (ASIOSampleType format);
/* pointers to the converter functions of each channel are stored here */ static void **asio_converter = NULL;
+ /* function to get sample width of data according to ASIOSampleType */ + static int asio_samplewidth(ASIOSampleType format); + + /* that's the sample width in bytes (per output channel) - + it's only for silence when stopping the driver.... (please find a better solution) + */ + static int *asio_out_samplewidth = NULL;
/* some local helper functions */ ! static void prepare_asio_drivernames(void);
/* system dependent helper functions */ *************** *** 89,119 ****
/* 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 */ --- 102,132 ----
/* global storage */ ! static ASIODriverInfo * asio_driver = NULL; ! static ASIOBufferInfo * asio_bufferinfo; ! static ASIOChannelInfo* asio_channelinfo; ! static AsioTimeInfo * asio_timerinfo; ! static ASIOCallbacks asio_callbacks; extern AsioDrivers * asioDrivers; /* declared in asiodrivers.cpp */
! static char ** asio_drivernames = NULL;
! static ASIOSampleRate asio_srate; ! static long asio_inchannels; ! static long asio_outchannels;
! static long asio_minbufsize; ! static long asio_maxbufsize; ! static long asio_prefbufsize; ! static long asio_granularity; ! static unsigned char asio_useoutputready; ! static long asio_inputlatency; ! static long asio_outputlatency;
! static long asio_bufsize;
unsigned long sys_reftime;
/* ringbuffer stuff */ ! static 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 */ *************** *** 206,210 ****
/* query driver */ ! ASIOGetChannels(&asio_inchannels, &asio_outchannels); post ("ASIOGetChannels\tinputs: %d, outputs: %d", asio_inchannels, asio_outchannels); --- 219,224 ----
/* query driver */ ! status = ASIOGetChannels(&asio_inchannels, &asio_outchannels); ! ASSERT(status == ASE_OK); post ("ASIOGetChannels\tinputs: %d, outputs: %d", asio_inchannels, asio_outchannels); *************** *** 216,221 ****
! 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, --- 230,236 ----
! status = ASIOGetBufferSize(&asio_minbufsize, &asio_maxbufsize, &asio_prefbufsize, &asio_granularity); + ASSERT(status == ASE_OK); post ("ASIOGetBufferSize\tmin: %d, max: %d, preferred: %d, granularity: " "%d", asio_minbufsize, asio_maxbufsize, asio_prefbufsize, *************** *** 226,230 ****
/* set sample rate */ ! if (ASIOCanSampleRate( asio_srate ) != ASE_OK) { error ("Samplerate not supported, using default"); --- 241,245 ----
/* set sample rate */ ! if(ASIOCanSampleRate( asio_srate ) != ASE_OK) { error ("Samplerate not supported, using default"); *************** *** 236,243 **** srate=44100; } ! ASIOSetSampleRate( asio_srate ); post ("ASIOSetSampleRate\t %d", srate); ! if (ASIOOutputReady() == ASE_OK) asio_useoutputready = 1; else --- 251,260 ---- srate=44100; } ! ! status = ASIOSetSampleRate( asio_srate ); ! ASSERT(status == ASE_OK); post ("ASIOSetSampleRate\t %d", srate); ! if(ASIOOutputReady() == ASE_OK) asio_useoutputready = 1; else *************** *** 293,296 **** --- 310,314 ----
asio_converter = (void **)getbytes(channels * sizeof (void *)); + asio_out_samplewidth = (int *)getbytes(sys_outchannels * sizeof (int));
for (i = 0; i != sys_outchannels + sys_inchannels; ++i) *************** *** 300,305 **** ASIOGetChannelInfo(&asio_channelinfo[i]);
! if (i < sys_outchannels) asio_converter[i] = asio_converter_send(asio_channelinfo[i].type); else asio_converter[i] = asio_converter_receive(asio_channelinfo[i].type); --- 318,325 ---- ASIOGetChannelInfo(&asio_channelinfo[i]);
! if (i < sys_outchannels) { asio_converter[i] = asio_converter_send(asio_channelinfo[i].type); + asio_out_samplewidth[i] = asio_samplewidth(asio_channelinfo[i].type); + } else asio_converter[i] = asio_converter_receive(asio_channelinfo[i].type); *************** *** 346,352 ****
if (ASIOStart() == ASE_OK) - { post("ASIO: started"); - } else post("ASIO: couldn't start"); --- 366,370 ---- *************** *** 364,370 **** int i;
! pthread_cond_broadcast(&asio_ringbuf_cond);
! ASIOStop();
if (asio_driver) --- 382,414 ---- int i;
! // pthread_cond_broadcast(&asio_ringbuf_cond);
! if(asio_useoutputready) ! { ! // the DMA buffers would be playing past ASIOStop ! // -> clear output buffers and notify driver ! #if 0 ! // slow method ! for(i = 0; i != sys_outchannels; ++i) ! memset(asio_ringbuffer[i], 0, asio_ringbuffer_length * sizeof (t_sample)); ! // wait for bufferswitch to process silence (twice) ! pthread_cond_wait(&asio_ringbuf_cond, &asio_ringbuf_mutex); ! for(i = 0; i != sys_outchannels; ++i) ! memset(asio_ringbuffer[i], 0, asio_ringbuffer_length * sizeof (t_sample)); ! pthread_cond_wait(&asio_ringbuf_cond, &asio_ringbuf_mutex); ! #else ! // direct method - clear both hardware buffers ! for(i = 0; i < sys_outchannels; ++i) { ! long bytes = asio_bufsize*asio_out_samplewidth[i]; ! memset(asio_bufferinfo[i].buffers[0],0,bytes); ! memset(asio_bufferinfo[i].buffers[1],0,bytes); ! } ! // notify driver ! ASIOOutputReady(); ! #endif ! } ! ! status = ASIOStop(); ! ASSERT(status == ASE_OK);
if (asio_driver) *************** *** 375,379 **** freebytes(asio_bufferinfo, channels * sizeof (ASIOBufferInfo)); freebytes(asio_channelinfo, channels * sizeof (ASIOChannelInfo)); ! ASIODisposeBuffers(); asio_ringbuffer = NULL; --- 419,424 ---- freebytes(asio_bufferinfo, channels * sizeof (ASIOBufferInfo)); freebytes(asio_channelinfo, channels * sizeof (ASIOChannelInfo)); ! status = ASIODisposeBuffers(); ! ASSERT(status == ASE_OK); asio_ringbuffer = NULL; *************** *** 383,388 **** if(asio_converter) freebytes(asio_converter, channels * sizeof (void *)); asio_converter = NULL;
- ASIOExit(); freebytes(asio_driver, sizeof (ASIODriverInfo)); asio_driver = NULL; --- 428,437 ---- if(asio_converter) freebytes(asio_converter, channels * sizeof (void *)); asio_converter = NULL; + if(asio_out_samplewidth) freebytes(asio_out_samplewidth, sys_outchannels * sizeof (int)); + asio_out_samplewidth = NULL; + + status = ASIOExit(); + ASSERT(status == ASE_OK);
freebytes(asio_driver, sizeof (ASIODriverInfo)); asio_driver = NULL; *************** *** 474,478 ****
/* buffer switch callback */ ! void asio_bufferSwitch(long db_idx, ASIOBool directprocess) { ASIOTime time; --- 523,527 ----
/* buffer switch callback */ ! static void asio_bufferSwitch(long db_idx, ASIOBool directprocess) { ASIOTime time; *************** *** 483,487 ****
/* sample rate change callback */ ! void asio_sampleRateDidChange(ASIOSampleRate srate) { asio_srate = srate; --- 532,536 ----
/* sample rate change callback */ ! static void asio_sampleRateDidChange(ASIOSampleRate srate) { asio_srate = srate; *************** *** 492,496 ****
/* asio messaging callback */ ! long asio_messages(long selector, long value, void* message, double* opt) { /* todo */ --- 541,545 ----
/* asio messaging callback */ ! static long asio_messages(long selector, long value, void* message, double* opt) { /* todo */ *************** *** 498,502 **** }
! ASIOTime *asio_bufferSwitchTimeInfo(ASIOTime *params, long db_idx, ASIOBool directprocess) { --- 547,551 ---- }
! static ASIOTime *asio_bufferSwitchTimeInfo(ASIOTime *params, long db_idx, ASIOBool directprocess) { *************** *** 537,544 **** if(asio_useoutputready) ASIOOutputReady(); - -
! return 0L; /* time info!!! */ }
--- 586,591 ---- if(asio_useoutputready) ASIOOutputReady();
! return 0L; /* time info!!! */ }
*************** *** 559,567 ****
/* sample converting helper functions */ ! void *asio_converter_send(ASIOSampleType format) {
#ifdef ASIODEBUG ! /* post("ASIO: Sample Type %d", format); */ #endif switch (format) --- 606,614 ----
/* sample converting helper functions */ ! static void *asio_converter_send(ASIOSampleType format) {
#ifdef ASIODEBUG ! /* post("ASIO: Sample Type %d", format); */ #endif switch (format) *************** *** 607,614 **** }
! void *asio_converter_receive (ASIOSampleType format) { #ifdef ASIODEBUG ! /* post("ASIO: Sample Type %d", format); */ #endif
--- 654,661 ---- }
! static void *asio_converter_receive (ASIOSampleType format) { #ifdef ASIODEBUG ! /* post("ASIO: Sample Type %d", format); */ #endif
*************** *** 656,659 **** --- 703,750 ---- }
+ static int asio_samplewidth(ASIOSampleType format) + { + switch (format) + { + case ASIOSTInt16LSB: + case ASIOSTInt16MSB: + return 2; + case ASIOSTFloat32LSB: // IEEE 754 32 bit float, as found on Intel x86 architecture + case ASIOSTFloat32MSB: // IEEE 754 32 bit float, as found on Intel x86 architecture + return 4; + case ASIOSTInt24LSB: // used for 20 bits as well + case ASIOSTInt24MSB: // used for 20 bits as well + return 3; + case ASIOSTInt32LSB: + case ASIOSTInt32MSB: + return 4; + + // 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 + + // 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 + + return 4; + + case ASIOSTFloat64MSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture + case ASIOSTFloat64LSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture + return 8; + + default: + post("Input sample Type %d not supported, yet!!!",format); + return 0; + } + + } + /* sample conversion functions */
*************** *** 662,671 **** #define SCALE_INT32 2147483647.f /* (- (expt 2 31) 1) */
! void float32copy(float* inbuffer, float* outbuffer, long frames) { memcpy (outbuffer, inbuffer, frames* sizeof (float)); /* check */ }
! void float32toInt16(float* inbuffer, void* outbuffer, long frames) { short* out = (short*)outbuffer; --- 753,762 ---- #define SCALE_INT32 2147483647.f /* (- (expt 2 31) 1) */
! static void float32copy(float* inbuffer, float* outbuffer, long frames) { memcpy (outbuffer, inbuffer, frames* sizeof (float)); /* check */ }
! static void float32toInt16(float* inbuffer, void* outbuffer, long frames) { short* out = (short*)outbuffer; *************** *** 687,691 **** }
! void Int16tofloat32(void* inbuffer, float* outbuffer, long frames) { short* in = (short*)inbuffer; --- 778,782 ---- }
! static void Int16tofloat32(void* inbuffer, float* outbuffer, long frames) { short* in = (short*)inbuffer; *************** *** 696,705 **** }
! void float32toInt24(float* inbuffer, void* outbuffer, long frames) { int* out = (int*)outbuffer; while (frames--) { ! float o = (*inbuffer * SCALE_INT24); #ifdef __GNUC__ *out++ = (int)lrintf(o); --- 787,796 ---- }
! static void float32toInt24(float* inbuffer, void* outbuffer, long frames) { int* out = (int*)outbuffer; while (frames--) { ! float o = (*inbuffer++ * SCALE_INT24); #ifdef __GNUC__ *out++ = (int)lrintf(o); *************** *** 716,720 **** }
! void Int24tofloat32(void* inbuffer, float* outbuffer, long frames) { int* in = (int*)inbuffer; --- 807,811 ---- }
! static void Int24tofloat32(void* inbuffer, float* outbuffer, long frames) { int* in = (int*)inbuffer; *************** *** 725,734 **** }
! void float32toInt32(float* inbuffer, void* outbuffer, long frames) { long* out = (long*)outbuffer; while (frames--) { ! float o = (*inbuffer * SCALE_INT32); #ifdef __GNUC__ *out++ = lrintf(o); --- 816,825 ---- }
! static void float32toInt32(float* inbuffer, void* outbuffer, long frames) { long* out = (long*)outbuffer; while (frames--) { ! float o = (*inbuffer++ * SCALE_INT32); #ifdef __GNUC__ *out++ = lrintf(o); *************** *** 745,749 **** }
! void Int32tofloat32(void* inbuffer, float* outbuffer, long frames) { long* in = (long*)inbuffer; --- 836,840 ---- }
! static void Int32tofloat32(void* inbuffer, float* outbuffer, long frames) { long* in = (long*)inbuffer; *************** *** 754,760 **** }
! void float32toInt16_S(float* inbuffer, void* outbuffer, long frames) { ! char* out = (char*)outbuffer; while (frames--) { --- 845,851 ---- }
! static void float32toInt16_S(float* inbuffer, void* outbuffer, long frames) { ! short* out = (short*)outbuffer; while (frames--) { *************** *** 770,798 **** }; #endif ! out[1] = ((char *)&reverse)[0]; ! out[0] = ((char *)&reverse)[1]; ! out += 2; } }
! void Int16tofloat32_S(void* inbuffer, float* outbuffer, long frames) { ! char* in = (char*)inbuffer; ! short d; while (frames--) { ! ((char *)&d)[0] = in[1]; ! ((char *)&d)[1] = in[0]; ! *outbuffer++ = (float)(d * (1.f / SCALE_INT16)); ! in += 2; } }
! void float32toInt24_S(float* inbuffer, void* outbuffer, long frames) { char* out = (char*)outbuffer; while (frames--) { ! int o = (*inbuffer * SCALE_INT24); #ifdef __GNUC__ int reverse = (int)lrintf(o); --- 861,884 ---- }; #endif ! *out++ = SWAPSHORT(reverse); } }
! static void Int16tofloat32_S(void* inbuffer, float* outbuffer, long frames) { ! short* in = (short*)inbuffer; while (frames--) { ! short shin = *in++; ! *outbuffer++ = (float)(SWAPSHORT(shin) * (1.f / SCALE_INT16)); } }
! static void float32toInt24_S(float* inbuffer, void* outbuffer, long frames) { char* out = (char*)outbuffer; while (frames--) { ! float o = (*inbuffer++ * SCALE_INT24); #ifdef __GNUC__ int reverse = (int)lrintf(o); *************** *** 812,816 **** }
! void Int24tofloat32_S(void* inbuffer, float* outbuffer, long frames) { char* in = (char*)inbuffer; --- 898,902 ---- }
! static void Int24tofloat32_S(void* inbuffer, float* outbuffer, long frames) { char* in = (char*)inbuffer; *************** *** 826,835 **** }
! void float32toInt32_S(float* inbuffer, void* outbuffer, long frames) { ! char* out = (char*)outbuffer; while (frames--) { ! float o = (*inbuffer * SCALE_INT32); #ifdef __GNUC__ long reverse = (long)lrintf(o); --- 912,921 ---- }
! static void float32toInt32_S(float* inbuffer, void* outbuffer, long frames) { ! long* out = (long*)outbuffer; while (frames--) { ! float o = (*inbuffer++ * SCALE_INT32); #ifdef __GNUC__ long reverse = (long)lrintf(o); *************** *** 842,865 **** }; #endif ! out[3] = ((char *)&reverse)[0]; ! out[2] = ((char *)&reverse)[1]; ! out[1] = ((char *)&reverse)[2]; ! out[0] = ((char *)&reverse)[3]; ! out += 4; } }
! void Int32tofloat32_S(void* inbuffer, float* outbuffer, long frames) { ! char* in = (char*)inbuffer; long d; while (frames--) { ! ((char *)&d)[0] = in[3]; ! ((char *)&d)[1] = in[2]; ! ((char *)&d)[2] = in[1]; ! ((char *)&d)[3] = in[0]; ! *outbuffer++ = (float)(d * (1.f / SCALE_INT32)); ! in += 3; } } --- 928,943 ---- }; #endif ! *out++ = SWAPLONG(reverse); } }
! static void Int32tofloat32_S(void* inbuffer, float* outbuffer, long frames) { ! long* in = (long*)inbuffer; long d; while (frames--) { ! long lgin = *in++; ! *outbuffer++ = (float)(SWAPLONG(lgin) * (1.f / SCALE_INT32)); } } *************** *** 867,871 ****
/* some local helper functions */ ! inline void prepare_asio_drivernames(void) { if (asio_drivernames == NULL) --- 945,949 ----
/* some local helper functions */ ! static void prepare_asio_drivernames(void) { if (asio_drivernames == NULL)