[PD-cvs] pd/src s_audio_asio.cpp,1.1.2.3,1.1.2.4

Tim Blechmann timblech at users.sourceforge.net
Sat Nov 6 16:22:40 CET 2004


Update of /cvsroot/pure-data/pd/src
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv935

Modified Files:
      Tag: devel_0_37
	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.2.3
retrieving revision 1.1.2.4
diff -C2 -d -r1.1.2.3 -r1.1.2.4
*** s_audio_asio.cpp	4 Nov 2004 23:28:25 -0000	1.1.2.3
--- s_audio_asio.cpp	6 Nov 2004 15:22:38 -0000	1.1.2.4
***************
*** 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)





More information about the Pd-cvs mailing list