From a50598add03c0cd7e90b555d1a39647ef4a31302 Mon Sep 17 00:00:00 2001 From: darkeye Date: Thu, 28 Mar 2002 16:45:46 +0000 Subject: [PATCH] added functions strToD(), conv8(), conv16() and conv() --- darkice/trunk/src/Util.cpp | 210 +++++++++++++++++++++++++++++++++++++ darkice/trunk/src/Util.h | 89 ++++++++++++++++ 2 files changed, 299 insertions(+) diff --git a/darkice/trunk/src/Util.cpp b/darkice/trunk/src/Util.cpp index c3ad0e6..6977eb0 100644 --- a/darkice/trunk/src/Util.cpp +++ b/darkice/trunk/src/Util.cpp @@ -51,6 +51,12 @@ #error need limits.h #endif +#ifdef HAVE_MATH_H +#include +#else +#error need math.h +#endif + #include "Util.h" @@ -180,12 +186,216 @@ Util :: strToL( const char * str, } +/*------------------------------------------------------------------------------ + * Convert a string to a double + *----------------------------------------------------------------------------*/ +double +Util :: strToD( const char * str ) throw ( Exception ) +{ + double val; + char * s; + + if ( !str ) { + throw Exception( __FILE__, __LINE__, "no str"); + } + + val = strtod( str, &s); + if ( s == str || val == HUGE_VAL ) { + throw Exception( __FILE__, __LINE__, "number conversion error"); + } + + return val; +} + + +/*------------------------------------------------------------------------------ + * Convert an unsigned char buffer holding 8 or 16 bit PCM values with + * channels interleaved to a short int buffer, still with channels interleaved + *----------------------------------------------------------------------------*/ +void +Util :: conv ( unsigned int bitsPerSample, + unsigned char * pcmBuffer, + unsigned int lenPcmBuffer, + short int * outBuffer, + bool isBigEndian ) throw ( Exception ) +{ + if ( bitsPerSample == 8 ) { + unsigned int i, j; + + for ( i = 0, j = 0; i < lenPcmBuffer; ) { + outBuffer[j] = pcmBuffer[i++]; + ++j; + } + } else if ( bitsPerSample == 16 ) { + + if ( isBigEndian ) { + unsigned int i, j; + + for ( i = 0, j = 0; i < lenPcmBuffer; ) { + short int value; + + value = pcmBuffer[i++] << 8; + value |= pcmBuffer[i++]; + outBuffer[j] = value; + ++j; + } + } else { + unsigned int i, j; + + for ( i = 0, j = 0; i < lenPcmBuffer; ) { + short int value; + + value = pcmBuffer[i++]; + value |= pcmBuffer[i++] << 8; + outBuffer[j] = value; + ++j; + } + } + } else { + throw Exception( __FILE__, __LINE__, + "this number of bits per sample not supported", + bitsPerSample); + } +} + + +/*------------------------------------------------------------------------------ + * Convert a short buffer holding PCM values with channels interleaved + * to one or more float buffers, one for each channel + *----------------------------------------------------------------------------*/ +void +Util :: conv ( short int * shortBuffer, + unsigned int lenShortBuffer, + float ** floatBuffers, + unsigned int channels ) throw ( Exception ) +{ + unsigned int i, j; + + for ( i = 0, j = 0; i < lenShortBuffer; ) { + for ( unsigned int c = 0; c < channels; ++c ) { + floatBuffers[c][j] = ((float) shortBuffer[i++]) / 32768.f; + } + ++j; + } +} + + +/*------------------------------------------------------------------------------ + * Convert an unsigned char buffer holding 8 bit PCM values with channels + * interleaved to two short int buffers (one for each channel) + *----------------------------------------------------------------------------*/ +void +Util :: conv8 ( unsigned char * pcmBuffer, + unsigned int lenPcmBuffer, + short int * leftBuffer, + short int * rightBuffer, + unsigned int channels ) +{ + if ( channels == 1 ) { + unsigned int i, j; + + for ( i = 0, j = 0; i < lenPcmBuffer; ) { + unsigned short int value; + + value = pcmBuffer[i++]; + leftBuffer[j] = (short int) value; + ++j; + } + } else { + unsigned int i, j; + + for ( i = 0, j = 0; i < lenPcmBuffer; ) { + unsigned short int value; + + value = pcmBuffer[i++]; + leftBuffer[j] = (short int) value; + value = pcmBuffer[i++]; + rightBuffer[j] = (short int) value; + ++j; + } + } +} + + +/*------------------------------------------------------------------------------ + * Convert an unsigned char buffer holding 16 bit PCM values with channels + * interleaved to two short int buffers (one for each channel) + *----------------------------------------------------------------------------*/ +void +Util :: conv16 ( unsigned char * pcmBuffer, + unsigned int lenPcmBuffer, + short int * leftBuffer, + short int * rightBuffer, + unsigned int channels, + bool isBigEndian ) +{ + if ( isBigEndian ) { + if ( channels == 1 ) { + unsigned int i, j; + + for ( i = 0, j = 0; i < lenPcmBuffer; ) { + unsigned short int value; + + value = pcmBuffer[i++] << 8; + value |= pcmBuffer[i++]; + leftBuffer[j] = (short int) value; + ++j; + } + } else { + unsigned int i, j; + + for ( i = 0, j = 0; i < lenPcmBuffer; ) { + unsigned short int value; + + value = pcmBuffer[i++] << 8; + value |= pcmBuffer[i++]; + leftBuffer[j] = (short int) value; + value = pcmBuffer[i++] << 8; + value |= pcmBuffer[i++]; + rightBuffer[j] = (short int) value; + ++j; + } + } + } else { + if ( channels == 1 ) { + unsigned int i, j; + + for ( i = 0, j = 0; i < lenPcmBuffer; ) { + unsigned short int value; + + value = pcmBuffer[i++]; + value |= pcmBuffer[i++] << 8; + leftBuffer[j] = (short int) value; + ++j; + } + } else { + unsigned int i, j; + + for ( i = 0, j = 0; i < lenPcmBuffer; ) { + unsigned short int value; + + value = pcmBuffer[i++]; + value |= pcmBuffer[i++] << 8; + leftBuffer[j] = (short int) value; + value = pcmBuffer[i++]; + value |= pcmBuffer[i++] << 8; + rightBuffer[j] = (short int) value; + ++j; + } + } + } +} + + /*------------------------------------------------------------------------------ $Source$ $Log$ + Revision 1.7 2002/03/28 16:45:46 darkeye + added functions strToD(), conv8(), conv16() and conv() + Revision 1.6 2001/08/30 17:25:56 darkeye renamed configure.h to config.h diff --git a/darkice/trunk/src/Util.h b/darkice/trunk/src/Util.h index 0dbf7a9..c22b241 100644 --- a/darkice/trunk/src/Util.h +++ b/darkice/trunk/src/Util.h @@ -187,6 +187,92 @@ class Util static long int strToL ( const char * str, int base = 10 ) throw ( Exception ); + + /** + * Convert a string to double. + * + * @param str the string to convert. + * @return the value of str as a double + * @exception Exception + */ + static double + strToD ( const char * str ) throw ( Exception ); + + /** + * Convert an unsigned char buffer holding 8 or 16 bit PCM values + * with channels interleaved to a short int buffer, still + * with channels interleaved. + * + * @param bitsPerSample the number of bits per sample in the input + * @param pcmBuffer the input buffer + * @param lenPcmBuffer the number of samples total in pcmBuffer + * (e.g. if 2 channel input, this is twice the + * number of sound samples) + * @param outBuffer the output buffer, must be big enough + * @param isBigEndian true if the input is big endian, false otherwise + */ + static void + conv ( unsigned int bitsPerSample, + unsigned char * pcmBuffer, + unsigned int lenPcmBuffer, + short int * outBuffer, + bool isBigEndian = true ) throw ( Exception ); + + + /** + * Convert a short buffer holding PCM values with channels interleaved + * to one or more float buffers, one for each channel + * + * @param shortBuffer the input buffer + * @param lenShortBuffer total length of the input buffer + * @param floatBuffers an array of float buffers, each + * (lenShortBuffer / channels) long + * @param channels number of channels to separate the input to + */ + static void + conv ( short int * shortBuffer, + unsigned int lenShortBuffer, + float ** floatBuffers, + unsigned int channels ) throw ( Exception ); + + /** + * Convert a char buffer holding 8 bit PCM values to a short buffer + * + * @param pcmBuffer buffer holding 8 bit PCM audio values, + * channels are interleaved + * @param lenPcmBuffer length of pcmBuffer + * @param leftBuffer put the left channel here (must be big enough) + * @param rightBuffer put the right channel here (not touched if mono, + * must be big enough) + * @param channels number of channels (1 = mono, 2 = stereo) + */ + static void + conv8 ( unsigned char * pcmBuffer, + unsigned int lenPcmBuffer, + short int * leftBuffer, + short int * rightBuffer, + unsigned int channels ); + + /** + * Convert a char buffer holding 16 bit PCM values to a short buffer + * + * @param pcmBuffer buffer holding 16 bit PCM audio values, + * channels are interleaved + * @param lenPcmBuffer length of pcmBuffer + * @param leftBuffer put the left channel here (must be big enough) + * @param rightBuffer put the right channel here (not touched if mono, + * must be big enough) + * @param channels number of channels (1 = mono, 2 = stereo) + * @param isBigEndian true if input is big endian, false otherwise + */ + static void + conv16 ( unsigned char * pcmBuffer, + unsigned int lenPcmBuffer, + short int * leftBuffer, + short int * rightBuffer, + unsigned int channels, + bool isBigEndian ); + }; @@ -205,6 +291,9 @@ class Util $Source$ $Log$ + Revision 1.5 2002/03/28 16:45:46 darkeye + added functions strToD(), conv8(), conv16() and conv() + Revision 1.4 2000/11/12 13:31:40 darkeye added kdoc-style documentation comments