From cf24fdd1c000a59d42f558ff91ce75d5222fa490 Mon Sep 17 00:00:00 2001 From: philburk Date: Thu, 21 Mar 2002 00:32:50 +0000 Subject: [PATCH] Added support for conversion nroutines in pa_convert.c. SHifted Dither value right by one to account for high pass filter. --- pa_common/pa_host.h | 56 ++++++++++++++++++++++++++------ pa_common/pa_lib.c | 78 ++++++++++----------------------------------- 2 files changed, 63 insertions(+), 71 deletions(-) diff --git a/pa_common/pa_host.h b/pa_common/pa_host.h index 9a35261..b077f83 100644 --- a/pa_common/pa_host.h +++ b/pa_common/pa_host.h @@ -36,6 +36,8 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * */ + +#include "portaudio.h" #ifdef __cplusplus extern "C" @@ -59,6 +61,12 @@ extern "C" typedef unsigned short uint16; #endif +/* Used to convert between various sample formats. */ +typedef void (PortAudioConverter)( + void *inputBuffer, int inputStride, + void *outputBuffer, int outputStride, + int numSamples ); + #define PA_MAGIC (0x18273645) /************************************************************************************/ @@ -76,7 +84,9 @@ typedef struct internalPortAudioStream int past_NumOutputChannels; PaDeviceID past_InputDeviceID; PaDeviceID past_OutputDeviceID; + PaSampleFormat past_NativeInputSampleFormat; PaSampleFormat past_InputSampleFormat; + PaSampleFormat past_NativeOutputSampleFormat; PaSampleFormat past_OutputSampleFormat; void *past_DeviceData; PortAudioCallback *past_Callback; @@ -99,11 +109,19 @@ typedef struct internalPortAudioStream double past_AverageTotalCount; double past_Usage; int past_IfLastExitValid; + /* Format Conversion */ + /* These are setup by PaConversion_Setup() */ + PortAudioConverter *past_InputConversionProc; + int past_InputConversionSourceStride; + int past_InputConversionTargetStride; + PortAudioConverter *past_OutputConversionProc; + int past_OutputConversionSourceStride; + int past_OutputConversionTargetStride; } internalPortAudioStream; /************************************************************************************/ -/****************** Prototypes ******************************************************/ +/******** These functions must be provided by a platform implementation. ************/ /************************************************************************************/ PaError PaHost_Init( void ); @@ -120,22 +138,42 @@ PaError PaHost_StartEngine( internalPortAudioStream *past ); PaError PaHost_StopEngine( internalPortAudioStream *past, int abort ); PaError PaHost_StreamActive( internalPortAudioStream *past ); -long Pa_CallConvertInt16( internalPortAudioStream *past, - short *nativeInputBuffer, - short *nativeOutputBuffer ); - -long Pa_CallConvertFloat32( internalPortAudioStream *past, - float *nativeInputBuffer, - float *nativeOutputBuffer ); - void *PaHost_AllocateFastMemory( long numBytes ); void PaHost_FreeFastMemory( void *addr, long numBytes ); +/* This only called if PA_VALIDATE_RATE IS CALLED. */ PaError PaHost_ValidateSampleRate( PaDeviceID id, double requestedFrameRate, double *closestFrameRatePtr ); + +/**********************************************************************/ +/************ Common Utility Routines provided by PA ******************/ +/**********************************************************************/ + int PaHost_FindClosestTableEntry( double allowableError, const double *rateTable, int numRates, double frameRate ); +long Pa_CallConvertInt16( internalPortAudioStream *past, + short *nativeInputBuffer, + short *nativeOutputBuffer ); + +/* Calculate 2 LSB dither signal with a triangular distribution. +** Ranged properly for adding to a 32 bit 1.31 fixed point value prior to >>15. +** Range of output is +/- 65535 +** Multiply by PA_DITHER_SCALE to get a float between -2.0 and 2.0. */ +#define PA_DITHER_BITS (15) +#define PA_DITHER_SCALE (1.0f / ((1<past_Magic = PA_MAGIC; /* Set ID to catch bugs. */ past->past_FramesPerUserBuffer = framesPerBuffer; - past->past_NumUserBuffers = numberOfBuffers; /* NOTE - PaHost_OpenStream() NMUST CHECK FOR ZERO! */ + past->past_NumUserBuffers = numberOfBuffers; /* NOTE - PaHost_OpenStream() MUST CHECK FOR ZERO! */ past->past_Callback = callback; past->past_UserData = userData; past->past_OutputSampleFormat = outputSampleFormat; @@ -248,7 +248,7 @@ PaError Pa_OpenStream( #else past->past_SampleRate = sampleRate; #endif - /* Allocate single Input buffer. */ + /* Allocate single Input buffer for passing formatted samples to user callback. */ past->past_InputBufferSize = framesPerBuffer * numInputChannels * ((bitsPerInputSample+7) / 8); past->past_InputBuffer = PaHost_AllocateFastMemory(past->past_InputBufferSize); if( past->past_InputBuffer == NULL ) @@ -481,10 +481,11 @@ double Pa_GetCPULoad( PortAudioStream* stream) /************************************************************* ** Calculate 2 LSB dither signal with a triangular distribution. ** Ranged properly for adding to a 32 bit integer prior to >>15. +** Range of output is +/- 32767 */ -#define DITHER_BITS (15) -#define DITHER_SCALE (1.0f / ((1<>(32-DITHER_BITS)) + (((long)randSeed2)>>(32-DITHER_BITS)); + /* Generate triangular distribution about 0. + * Shift before adding to prevent overflow which would skew the distribution. + * Also shift an extra bit for the high pass filter. + */ +#define DITHER_SHIFT ((32 - PA_DITHER_BITS) + 1) + current = (((long)randSeed1)>>DITHER_SHIFT) + (((long)randSeed2)>>DITHER_SHIFT); /* High pass filter to reduce audibility. */ highPass = current - previous; previous = current; @@ -513,8 +518,6 @@ long Pa_CallConvertInt16( internalPortAudioStream *past, short *nativeOutputBuffer ) { long temp; - long bytesEmpty = 0; - long bytesFilled = 0; int userResult; unsigned int i; void *inputBuffer = NULL; @@ -576,7 +579,7 @@ long Pa_CallConvertInt16( internalPortAudioStream *past, for( i=0; i> 8; /* PLB20010820 */ + temp += PaConvert_TriangularDither() >> 8; /* PLB20010820 */ temp = ((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp)); inBufPtr[i] = (char)(temp >> 8); } @@ -602,7 +605,7 @@ long Pa_CallConvertInt16( internalPortAudioStream *past, for( i=0; i> 8; /* PLB20010820 */ + temp += PaConvert_TriangularDither() >> 8; /* PLB20010820 */ temp = ((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp)); inBufPtr[i] = (unsigned char)((temp>>8) + 0x80); /* PLB20010820 */ } @@ -669,7 +672,7 @@ long Pa_CallConvertInt16( internalPortAudioStream *past, /* If you dither then you have to clip because dithering could push the signal out of range! */ for( i=0; i 0x7FFF) ? 0x7FFF : temp)); @@ -693,7 +696,7 @@ long Pa_CallConvertInt16( internalPortAudioStream *past, for( i=0; i> 1) + Pa_TriangularDither(); + temp = (outBufPtr[i] >> 1) + PaConvert_TriangularDither(); temp = temp >> 15; *nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp)); } @@ -730,55 +733,6 @@ long Pa_CallConvertInt16( internalPortAudioStream *past, return userResult; } -/************************************************************************* -** Called by host code. -** Convert input from Float32, call user code, then convert output -** to Float32 format for native use. -** Assumes host native format is Float32. -** Returns result from user callback. -** FIXME - Unimplemented for formats other than paFloat32!!!! -*/ -long Pa_CallConvertFloat32( internalPortAudioStream *past, - float *nativeInputBuffer, - float *nativeOutputBuffer ) -{ - long bytesEmpty = 0; - long bytesFilled = 0; - int userResult; - void *inputBuffer = NULL; - void *outputBuffer = NULL; - - /* Get native data from DirectSound. */ - if( (past->past_NumInputChannels > 0) && (nativeInputBuffer != NULL) ) - { - inputBuffer = nativeInputBuffer; /* FIXME */ - } - - /* Are we doing output time? */ - if( (past->past_NumOutputChannels > 0) && (nativeOutputBuffer != NULL) ) - { - /* May already be in native format so just write directly to native buffer. */ - outputBuffer = (past->past_OutputSampleFormat == paFloat32) ? - nativeOutputBuffer : past->past_OutputBuffer; - } - /* - AddTraceMessage("Pa_CallConvertInt16: inputBuffer = ", (int) inputBuffer ); - AddTraceMessage("Pa_CallConvertInt16: outputBuffer = ", (int) outputBuffer ); - */ - /* Call user callback routine. */ - userResult = past->past_Callback( - inputBuffer, - outputBuffer, - past->past_FramesPerUserBuffer, - past->past_FrameCount, - past->past_UserData ); - - past->past_FrameCount += (PaTimestamp) past->past_FramesPerUserBuffer; - - /* Convert to native format if necessary. */ /* FIXME */ - return userResult; -} - /*************************************************************************/ PaError Pa_Initialize( void ) { -- 2.43.0