Update of /cvsroot/pure-data/pd/src
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv1114
Modified Files:
Tag: devel_0_38
s_audio_asio.cpp
Log Message:
some improvements
Index: s_audio_asio.cpp
===================================================================
RCS file: /cvsroot/pure-data/pd/src/Attic/s_audio_asio.cpp,v
retrieving revision 1.1.4.1
retrieving revision 1.1.4.2
diff -C2 -d -r1.1.4.1 -r1.1.4.2
*** s_audio_asio.cpp 5 Nov 2004 13:33:19 -0000 1.1.4.1
--- s_audio_asio.cpp 6 Nov 2004 15:22:54 -0000 1.1.4.2
***************
*** 24,27 ****
--- 24,34 ----
#include "stdio.h" /* for sprintf */
+ /* fast float to integer conversion adapted from Erik de Castro Lopo */
+ #define _ISOC9X_SOURCE 1
+ #define _ISOC99_SOURCE 1
+ #define __USE_ISOC9X 1
+ #define __USE_ISOC99 1
+ #include "math.h"
+
#define ASIODEBUG
***************
*** 43,53 ****
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);
--- 50,54 ----
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);
***************
*** 56,59 ****
--- 57,84 ----
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);
+ typedef void converter_in_t(void* inbuffer, float* outbuffer, long frames);
+
+ /* sample converting helper functions:
+ * - 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 */
***************
*** 267,277 ****
}
! 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 */
--- 292,308 ----
}
! asio_converter = (void **)getbytes(channels * sizeof (void *));
!
! for (i = 0; i != sys_outchannels + sys_inchannels; ++i)
{
asio_channelinfo[i].channel = asio_bufferinfo[i].channelNum;
asio_channelinfo[i].isInput = asio_bufferinfo[i].isInput;
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);
+ }
/* get latencies */
***************
*** 330,334 ****
{
ASIOError status;
! int channels = asio_inchannels + asio_outchannels;
int i;
--- 361,365 ----
{
ASIOError status;
! int channels = sys_inchannels + sys_outchannels;
int i;
***************
*** 350,353 ****
--- 381,387 ----
asio_channelinfo = NULL;
+ if(asio_converter) freebytes(asio_converter, channels * sizeof (void *));
+ asio_converter = NULL;
+
ASIOExit();
freebytes(asio_driver, sizeof (ASIODriverInfo));
***************
*** 482,500 ****
* 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);
--- 516,535 ----
* todo: improve input latency
*/
!
! for (i = 0; i < sys_outchannels + sys_inchannels; i++)
{
+ if(asio_converter[i])
if (asio_bufferinfo[i].isInput != ASIOTrue)
{
! ((converter_out_t *)asio_converter[i])(asio_ringbuffer[i]+asio_ringbuffer_outoffset,
! (void*) asio_bufferinfo[i].buffers[db_idx],
! asio_bufsize);
}
else /* these are the input channels */
{
! ((converter_in_t *)asio_converter[i])((void*)asio_bufferinfo[i].buffers[db_idx],
! asio_ringbuffer[i]+asio_ringbuffer_outoffset,
! asio_bufsize);
}
}
pthread_cond_broadcast(&asio_ringbuf_cond);
***************
*** 524,528 ****
/* sample converting helper functions */
! void asio_convert_and_send(t_sample* source, void* dest, ASIOSampleType format, long bufsize)
{
--- 559,563 ----
/* sample converting helper functions */
! void *asio_converter_send(ASIOSampleType format)
{
***************
*** 533,548 ****
{
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);
! break;
case ASIOSTInt32LSB:
! float32toInt32(source, dest, bufsize);
! break;
case ASIOSTFloat64LSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture
--- 568,585 ----
{
case ASIOSTInt16LSB:
! return float32toInt16;
case ASIOSTFloat32LSB: // IEEE 754 32 bit float, as found on Intel x86 architecture
! return float32copy;
case ASIOSTInt24LSB: // used for 20 bits as well
! return float32toInt24;
case ASIOSTInt32LSB:
! return float32toInt32;
!
! case ASIOSTInt16MSB:
! return float32toInt16_S;
! case ASIOSTInt24MSB: // used for 20 bits as well
! return float32toInt24_S;
! case ASIOSTInt32MSB:
! return float32toInt32_S;
case ASIOSTFloat64LSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture
***************
*** 555,564 ****
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
--- 592,595 ----
***************
*** 570,584 ****
case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment
case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment
! {
! static int written = 0;
! if(written < 3) {
! post("Output sample Type %d not supported, yet!!!",format);
! ++written;
! }
! }
}
}
! void asio_convert_and_receive (void* source, t_sample* dest, ASIOSampleType format, long bufsize)
{
#ifdef ASIODEBUG
--- 601,611 ----
case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment
case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment
! default:
! post("Output sample Type %d not supported, yet!!!",format);
! return NULL;
}
}
! void *asio_converter_receive (ASIOSampleType format)
{
#ifdef ASIODEBUG
***************
*** 589,603 ****
{
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
--- 616,633 ----
{
case ASIOSTInt16LSB:
! return Int16tofloat32;
case ASIOSTFloat32LSB: // IEEE 754 32 bit float, as found on Intel x86 architecture
! return float32copy;
case ASIOSTInt24LSB: // used for 20 bits as well
! return Int24tofloat32;
case ASIOSTInt32LSB:
! return Int32tofloat32;
!
! case ASIOSTInt16MSB:
! return Int16tofloat32_S;
! case ASIOSTInt24MSB: // used for 20 bits as well
! return Int24tofloat32_S;
! case ASIOSTInt32MSB:
! return Int32tofloat32_S;
case ASIOSTFloat64LSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture
***************
*** 610,616 ****
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
--- 640,643 ----
***************
*** 622,632 ****
case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment
case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment
! {
! static int written = 0;
! if(written < 3) {
post("Input sample Type %d not supported, yet!!!",format);
! ++written;
! }
! }
}
--- 649,655 ----
case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment
case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment
! default:
post("Input sample Type %d not supported, yet!!!",format);
! return NULL;
}
***************
*** 639,642 ****
--- 662,670 ----
#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)
{
***************
*** 644,648 ****
while (frames--)
{
! *out++ = (short)(*inbuffer++ * SCALE_INT16);
}
}
--- 672,687 ----
while (frames--)
{
! float o = (*inbuffer++ * SCALE_INT16);
! #ifdef __GNUC__
! *out++ = (short)lrintf(o);
! #else
! short srt;
! __asm
! {
! fld o
! fistp srt
! };
! *out++ = srt;
! #endif
}
}
***************
*** 662,666 ****
while (frames--)
{
! *out++ = (int)(*inbuffer * SCALE_INT24);
}
}
--- 701,716 ----
while (frames--)
{
! float o = (*inbuffer * SCALE_INT24);
! #ifdef __GNUC__
! *out++ = (int)lrintf(o);
! #else
! int intg;
! __asm
! {
! fld o
! fistp intg
! };
! *out++ = intg;
! #endif
}
}
***************
*** 680,684 ****
while (frames--)
{
! *out++ = (long)(*inbuffer * SCALE_INT32);
}
}
--- 730,745 ----
while (frames--)
{
! float o = (*inbuffer * SCALE_INT32);
! #ifdef __GNUC__
! *out++ = lrintf(o);
! #else
! long lng;
! __asm
! {
! fld o
! fistp lng
! };
! *out++ = lng;
! #endif
}
}
***************
*** 693,696 ****
--- 754,869 ----
}
+ void float32toInt16_S(float* inbuffer, void* outbuffer, long frames)
+ {
+ char* out = (char*)outbuffer;
+ while (frames--)
+ {
+ float o = (*inbuffer++ * SCALE_INT16);
+ #ifdef __GNUC__
+ short reverse = (short)lrintf(o);
+ #else
+ short reverse;
+ __asm
+ {
+ fld o
+ fistp reverse
+ };
+ #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);
+ #else
+ int reverse;
+ __asm
+ {
+ fld o
+ fistp reverse
+ };
+ #endif
+ out[2] = ((char *)&reverse)[0];
+ out[1] = ((char *)&reverse)[1];
+ out[0] = ((char *)&reverse)[2];
+ out += 3;
+ }
+ }
+
+ void Int24tofloat32_S(void* inbuffer, float* outbuffer, long frames)
+ {
+ char* in = (char*)inbuffer;
+ long d = 0;
+ while (frames--)
+ {
+ ((char *)&d)[1] = in[2];
+ ((char *)&d)[2] = in[1];
+ ((char *)&d)[3] = in[0];
+ *outbuffer++ = (float)(d * (1.f / SCALE_INT24));
+ in += 3;
+ }
+ }
+
+ 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);
+ #else
+ long reverse;
+ __asm
+ {
+ fld o
+ fistp reverse
+ };
+ #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;
+ }
+ }
+
+
/* some local helper functions */
inline void prepare_asio_drivernames(void)