* Clean up whitespace in src/common in preparation for .editorconfig. Convert tabs to 4 spaces. Indent by 4 spaces. Strip trailing whitespace.
*/
/*
- * The text above constitutes the entire PortAudio license; however,
+ * The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version. It is also
- * requested that these non-binding requests be included along with the
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
* license above.
*/
{
struct PaUtilAllocationGroupLink *result;
int i;
-
+
result = (struct PaUtilAllocationGroupLink *)PaUtil_AllocateMemory(
sizeof(struct PaUtilAllocationGroupLink) * count );
if( result )
}
result[count-1].next = nextSpare;
}
-
+
return result;
}
{
struct PaUtilAllocationGroupLink *links, *link;
void *result = 0;
-
+
/* allocate more links if necessary */
if( !group->spareLinks )
{
}
}
- return result;
+ return result;
}
break;
}
-
+
previous = current;
current = current->next;
}
*/
/*
- * The text above constitutes the entire PortAudio license; however,
+ * The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version. It is also
- * requested that these non-binding requests be included along with the
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
* license above.
*/
@brief Allocation Group prototypes. An Allocation Group makes it easy to
allocate multiple blocks of memory and free them all at once.
-
+
An allocation group is useful for keeping track of multiple blocks
of memory which are allocated at the same time (such as during initialization)
and need to be deallocated at the same time. The allocation group maintains
*/
/*
- * The text above constitutes the entire PortAudio license; however,
+ * The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version. It is also
- * requested that these non-binding requests be included along with the
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
* license above.
*/
@ingroup common_src
@brief Conversion function implementations.
-
+
If the C9x function lrintf() is available, define PA_USE_C99_LRINTF to use it
@todo Consider whether functions which dither but don't clip should exist,
V18 automatically enabled clipping whenever dithering was selected. Perhaps
- we should do the same.
+ we should do the same.
see: "require clipping for dithering sample conversion functions?"
http://www.portaudio.com/trac/ticket/112
@todo implement the converters marked IMPLEMENT ME: Int32_To_Int24_Dither,
- Int32_To_UInt8_Dither, Int24_To_Int16_Dither, Int24_To_Int8_Dither,
+ Int32_To_UInt8_Dither, Int24_To_Int16_Dither, Int24_To_Int8_Dither,
Int24_To_UInt8_Dither, Int16_To_Int8_Dither, Int16_To_UInt8_Dither
see: "some conversion functions are not implemented in pa_converters.c"
http://www.portaudio.com/trac/ticket/35
format &= ~paNonInterleaved;
availableFormats &= ~paNonInterleaved;
-
+
if( (format & availableFormats) == 0 )
{
/* NOTE: this code depends on the sample format constants being in
{
result = 0;
}
-
+
if( result == 0 ){
/* scan for worse formats */
result = format;
if( (result & availableFormats) == 0 )
result = paSampleFormatNotSupported;
}
-
+
}else{
result = format;
}
0, /* PaUtilConverter *Int24_To_Int8_Dither; */
0, /* PaUtilConverter *Int24_To_UInt8; */
0, /* PaUtilConverter *Int24_To_UInt8_Dither; */
-
+
0, /* PaUtilConverter *Int16_To_Float32; */
0, /* PaUtilConverter *Int16_To_Int32; */
0, /* PaUtilConverter *Int16_To_Int24; */
*dest = lrintf(scaled-0.5f);
#else
double scaled = *src * 0x7FFFFFFF;
- *dest = (PaInt32) scaled;
+ *dest = (PaInt32) scaled;
#endif
-
+
src += sourceStride;
dest += destinationStride;
}
float *src = (float*)sourceBuffer;
PaInt32 *dest = (PaInt32*)destinationBuffer;
(void) ditherGenerator; /* unused parameter */
-
+
while( count-- )
{
/* REVIEW */
PaInt32 temp;
(void) ditherGenerator; /* unused parameter */
-
+
while( count-- )
{
/* convert to 32 bit and drop the low 8 bits */
double scaled = (double)(*src) * 2147483647.0;
temp = (PaInt32) scaled;
-
+
#if defined(PA_LITTLE_ENDIAN)
dest[0] = (unsigned char)(temp >> 8);
dest[1] = (unsigned char)(temp >> 16);
double dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
/* use smaller scaler to prevent overflow when we add the dither */
double dithered = ((double)*src * (2147483646.0)) + dither;
-
+
temp = (PaInt32) dithered;
#if defined(PA_LITTLE_ENDIAN)
PaInt32 temp;
(void) ditherGenerator; /* unused parameter */
-
+
while( count-- )
{
/* convert to 32 bit and drop the low 8 bits */
float *src = (float*)sourceBuffer;
unsigned char *dest = (unsigned char*)destinationBuffer;
PaInt32 temp;
-
+
while( count-- )
{
/* convert to 32 bit and drop the low 8 bits */
-
+
double dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
/* use smaller scaler to prevent overflow when we add the dither */
double dithered = ((double)*src * (2147483646.0)) + dither;
PA_CLIP_( dithered, -2147483648., 2147483647. );
-
+
temp = (PaInt32) dithered;
#if defined(PA_LITTLE_ENDIAN)
{
float *src = (float*)sourceBuffer;
signed char *dest = (signed char*)destinationBuffer;
-
+
while( count-- )
{
float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
{
float *src = (float*)sourceBuffer;
unsigned char *dest = (unsigned char*)destinationBuffer;
-
+
while( count-- )
{
float dither = PaUtil_GenerateFloatTriangularDither( ditherGenerator );
float dithered = (*src * (126.0f)) + dither;
PaInt32 samp = (PaInt32) dithered;
*dest = (unsigned char) (128 + samp);
-
+
src += sourceStride;
dest += destinationStride;
}
PaInt32 *src = (PaInt32*)sourceBuffer;
unsigned char *dest = (unsigned char*)destinationBuffer;
(void) ditherGenerator; /* unused parameter */
-
- while( count-- )
+
+ while( count-- )
{
- /* REVIEW */
+ /* REVIEW */
#if defined(PA_LITTLE_ENDIAN)
dest[0] = (unsigned char)(*src >> 8);
dest[1] = (unsigned char)(*src >> 16);
while( count-- )
{
- (*dest) = (unsigned char)(((*src) >> 24) + 128);
+ (*dest) = (unsigned char)(((*src) >> 24) + 128);
src += sourceStride;
dest += destinationStride;
PaInt32 temp;
(void) ditherGenerator; /* unused parameter */
-
+
while( count-- )
{
#if defined(PA_LITTLE_ENDIAN)
- temp = (((PaInt32)src[0]) << 8);
+ temp = (((PaInt32)src[0]) << 8);
temp = temp | (((PaInt32)src[1]) << 16);
temp = temp | (((PaInt32)src[2]) << 24);
#elif defined(PA_BIG_ENDIAN)
PaInt32 temp;
(void) ditherGenerator; /* unused parameter */
-
+
while( count-- )
{
#if defined(PA_LITTLE_ENDIAN)
- temp = (((PaInt32)src[0]) << 8);
+ temp = (((PaInt32)src[0]) << 8);
temp = temp | (((PaInt32)src[1]) << 16);
temp = temp | (((PaInt32)src[2]) << 24);
#elif defined(PA_BIG_ENDIAN)
{
unsigned char *src = (unsigned char*)sourceBuffer;
PaInt16 *dest = (PaInt16*)destinationBuffer;
-
+
PaInt16 temp;
(void) ditherGenerator; /* unused parameter */
-
+
while( count-- )
{
-
+
#if defined(PA_LITTLE_ENDIAN)
- /* src[0] is discarded */
+ /* src[0] is discarded */
temp = (((PaInt16)src[1]));
temp = temp | (PaInt16)(((PaInt16)src[2]) << 8);
#elif defined(PA_BIG_ENDIAN)
- /* src[2] is discarded */
+ /* src[2] is discarded */
temp = (PaInt16)(((PaInt16)src[0]) << 8);
temp = temp | (((PaInt16)src[1]));
#endif
{
#if defined(PA_LITTLE_ENDIAN)
- temp = (((PaInt32)src[0]) << 8);
+ temp = (((PaInt32)src[0]) << 8);
temp = temp | (((PaInt32)src[1]) << 16);
temp = temp | (((PaInt32)src[2]) << 24);
#elif defined(PA_BIG_ENDIAN)
{
unsigned char *src = (unsigned char*)sourceBuffer;
signed char *dest = (signed char*)destinationBuffer;
-
+
(void) ditherGenerator; /* unused parameter */
-
+
while( count-- )
- {
-
+ {
+
#if defined(PA_LITTLE_ENDIAN)
- /* src[0] is discarded */
- /* src[1] is discarded */
+ /* src[0] is discarded */
+ /* src[1] is discarded */
*dest = src[2];
#elif defined(PA_BIG_ENDIAN)
- /* src[2] is discarded */
- /* src[1] is discarded */
- *dest = src[0];
+ /* src[2] is discarded */
+ /* src[1] is discarded */
+ *dest = src[0];
#endif
src += sourceStride * 3;
{
unsigned char *src = (unsigned char*)sourceBuffer;
signed char *dest = (signed char*)destinationBuffer;
-
+
PaInt32 temp, dither;
while( count-- )
{
#if defined(PA_LITTLE_ENDIAN)
- temp = (((PaInt32)src[0]) << 8);
+ temp = (((PaInt32)src[0]) << 8);
temp = temp | (((PaInt32)src[1]) << 16);
temp = temp | (((PaInt32)src[2]) << 24);
#elif defined(PA_BIG_ENDIAN)
{
unsigned char *src = (unsigned char*)sourceBuffer;
unsigned char *dest = (unsigned char*)destinationBuffer;
-
+
(void) ditherGenerator; /* unused parameter */
-
+
while( count-- )
{
-
+
#if defined(PA_LITTLE_ENDIAN)
- /* src[0] is discarded */
- /* src[1] is discarded */
+ /* src[0] is discarded */
+ /* src[1] is discarded */
*dest = (unsigned char)(src[2] + 128);
#elif defined(PA_BIG_ENDIAN)
*dest = (unsigned char)(src[0] + 128);
- /* src[1] is discarded */
- /* src[2] is discarded */
+ /* src[1] is discarded */
+ /* src[2] is discarded */
#endif
src += sourceStride * 3;
/* REVIEW: we should consider something like
(*src << 16) | (*src & 0xFFFF)
*/
-
+
*dest = *src << 16;
src += sourceStride;
PaInt16 temp;
(void) ditherGenerator; /* unused parameter */
-
+
while( count-- )
{
temp = *src;
-
+
#if defined(PA_LITTLE_ENDIAN)
dest[0] = 0;
dest[1] = (unsigned char)(temp);
while( count-- )
{
- (*dest) = (unsigned char)(((*src) >> 8) + 128);
+ (*dest) = (unsigned char)(((*src) >> 8) + 128);
src += sourceStride;
dest += destinationStride;
while( count-- )
{
- (*dest) = (*src) << 24;
+ (*dest) = (*src) << 24;
src += sourceStride;
dest += destinationStride;
while( count-- )
{
- (*dest) = (*src - 128) << 24;
+ (*dest) = (*src - 128) << 24;
src += sourceStride;
dest += destinationStride;
void *sourceBuffer, signed int sourceStride,
unsigned int count, struct PaUtilTriangularDitherGenerator *ditherGenerator )
{
- unsigned char *src = (unsigned char*)sourceBuffer;
+ unsigned char *src = (unsigned char*)sourceBuffer;
unsigned char *dest = (unsigned char*)destinationBuffer;
(void) ditherGenerator; /* unused parameters */
-
- while( count-- )
+
+ while( count-- )
{
#if defined(PA_LITTLE_ENDIAN)
dest[1] = 0;
dest[2] = 0;
#endif
-
+
src += sourceStride;
- dest += destinationStride * 3;
- }
+ dest += destinationStride * 3;
+ }
}
/* -------------------------------------------------------------------------- */
{
unsigned char *src = (unsigned char*)sourceBuffer;
unsigned char *dest = (unsigned char*)destinationBuffer;
-
+
(void) ditherGenerator; /* unused parameter */
while( count-- )
{
PaUint16 *src = (PaUint16 *)sourceBuffer;
PaUint16 *dest = (PaUint16 *)destinationBuffer;
-
+
(void) ditherGenerator; /* unused parameter */
-
+
while( count-- )
{
*dest = *src;
unsigned char *dest = (unsigned char*)destinationBuffer;
(void) ditherGenerator; /* unused parameter */
-
+
while( count-- )
{
dest[0] = src[0];
PaUint32 *src = (PaUint32 *)sourceBuffer;
(void) ditherGenerator; /* unused parameter */
-
+
while( count-- )
{
*dest = *src;
Float32_To_Int24_Dither, /* PaUtilConverter *Float32_To_Int24_Dither; */
Float32_To_Int24_Clip, /* PaUtilConverter *Float32_To_Int24_Clip; */
Float32_To_Int24_DitherClip, /* PaUtilConverter *Float32_To_Int24_DitherClip; */
-
+
Float32_To_Int16, /* PaUtilConverter *Float32_To_Int16; */
Float32_To_Int16_Dither, /* PaUtilConverter *Float32_To_Int16_Dither; */
Float32_To_Int16_Clip, /* PaUtilConverter *Float32_To_Int16_Clip; */
*/
/*
- * The text above constitutes the entire PortAudio license; however,
+ * The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version. It is also
- * requested that these non-binding requests be included along with the
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
* license above.
*/
typedef void PaUtilZeroer(
void *destinationBuffer, signed int destinationStride, unsigned int count );
-
+
/** Find a buffer zeroer function for the given destination format.
@return
A pointer to a PaUtilZeroer which will perform the requested
PaUtilConverter *Float32_To_Int24_Dither;
PaUtilConverter *Float32_To_Int24_Clip;
PaUtilConverter *Float32_To_Int24_DitherClip;
-
+
PaUtilConverter *Float32_To_Int16;
PaUtilConverter *Float32_To_Int16_Dither;
PaUtilConverter *Float32_To_Int16_Clip;
PaUtilConverter *Int8_To_Int24;
PaUtilConverter *Int8_To_Int16;
PaUtilConverter *Int8_To_UInt8;
-
+
PaUtilConverter *UInt8_To_Float32;
PaUtilConverter *UInt8_To_Int32;
PaUtilConverter *UInt8_To_Int24;
*/
/*
- * The text above constitutes the entire PortAudio license; however,
+ * The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version. It is also
- * requested that these non-binding requests be included along with the
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
* license above.
*/
#define LOWPASS_COEFFICIENT_1 (0.99999 - LOWPASS_COEFFICIENT_0)
measurer->averageLoad = (LOWPASS_COEFFICIENT_0 * measurer->averageLoad) +
- (LOWPASS_COEFFICIENT_1 * measuredLoad);
+ (LOWPASS_COEFFICIENT_1 * measuredLoad);
}
}
*/
/*
- * The text above constitutes the entire PortAudio license; however,
+ * The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version. It is also
- * requested that these non-binding requests be included along with the
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
* license above.
*/
#ifdef __cplusplus
}
-#endif /* __cplusplus */
+#endif /* __cplusplus */
#endif /* PA_CPULOAD_H */
@brief Implements log function.
PaUtil_SetLogPrintFunction can be user called to replace the provided
- DefaultLogPrint function, which writes to stderr.
- One can NOT pass var_args across compiler/dll boundaries as it is not
- "byte code/abi portable". So the technique used here is to allocate a local
- a static array, write in it, then callback the user with a pointer to its
- start.
+ DefaultLogPrint function, which writes to stderr.
+ One can NOT pass var_args across compiler/dll boundaries as it is not
+ "byte code/abi portable". So the technique used here is to allocate a local
+ a static array, write in it, then callback the user with a pointer to its
+ start.
*/
#include <stdio.h>
// for OutputDebugStringA
#if defined(_MSC_VER) && defined(PA_ENABLE_MSVC_DEBUG_OUTPUT)
- #define WIN32_LEAN_AND_MEAN // exclude rare headers
- #include "windows.h"
+ #define WIN32_LEAN_AND_MEAN // exclude rare headers
+ #include "windows.h"
#endif
// User callback
VERY dangerous alternative, vsprintf (with no n)
*/
#if _MSC_VER
- /* Some Windows Mobile SDKs don't define vsnprintf but all define _vsnprintf (hopefully).
- According to MSDN "vsnprintf is identical to _vsnprintf". So we use _vsnprintf with MSC.
- */
- #define VSNPRINTF _vsnprintf
+ /* Some Windows Mobile SDKs don't define vsnprintf but all define _vsnprintf (hopefully).
+ According to MSDN "vsnprintf is identical to _vsnprintf". So we use _vsnprintf with MSC.
+ */
+ #define VSNPRINTF _vsnprintf
#else
- #define VSNPRINTF vsnprintf
+ #define VSNPRINTF vsnprintf
#endif
#define PA_LOG_BUF_SIZE 2048
void PaUtil_DebugPrint( const char *format, ... )
{
- // Optional logging into Output console of Visual Studio
+ // Optional logging into Output console of Visual Studio
#if defined(_MSC_VER) && defined(PA_ENABLE_MSVC_DEBUG_OUTPUT)
- {
- char buf[PA_LOG_BUF_SIZE];
- va_list ap;
- va_start(ap, format);
- VSNPRINTF(buf, sizeof(buf), format, ap);
- buf[sizeof(buf)-1] = 0;
- OutputDebugStringA(buf);
- va_end(ap);
- }
+ {
+ char buf[PA_LOG_BUF_SIZE];
+ va_list ap;
+ va_start(ap, format);
+ VSNPRINTF(buf, sizeof(buf), format, ap);
+ buf[sizeof(buf)-1] = 0;
+ OutputDebugStringA(buf);
+ va_end(ap);
+ }
#endif
- // Output to User-Callback
+ // Output to User-Callback
if (userCB != NULL)
{
char strdump[PA_LOG_BUF_SIZE];
va_end(ap);
}
else
- // Standard output to stderr
+ // Standard output to stderr
{
va_list ap;
va_start(ap, format);
#ifdef PA_LOG_API_CALLS
-#define PA_LOGAPI(x) PaUtil_DebugPrint x
+#define PA_LOGAPI(x) PaUtil_DebugPrint x
#define PA_LOGAPI_ENTER(functionName) PaUtil_DebugPrint( functionName " called.\n" )
#define PA_LOGAPI_EXIT(functionName) PaUtil_DebugPrint( functionName " returned.\n" )
#define PA_LOGAPI_EXIT_PAERROR( functionName, result ) \
- PaUtil_DebugPrint( functionName " returned:\n" ); \
- PaUtil_DebugPrint("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )
+ PaUtil_DebugPrint( functionName " returned:\n" ); \
+ PaUtil_DebugPrint("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )
#define PA_LOGAPI_EXIT_T( functionName, resultFormatString, result ) \
- PaUtil_DebugPrint( functionName " returned:\n" ); \
- PaUtil_DebugPrint("\t" resultFormatString "\n", result )
+ PaUtil_DebugPrint( functionName " returned:\n" ); \
+ PaUtil_DebugPrint("\t" resultFormatString "\n", result )
#define PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( functionName, positiveResultFormatString, result ) \
- PaUtil_DebugPrint( functionName " returned:\n" ); \
- if( result > 0 ) \
+ PaUtil_DebugPrint( functionName " returned:\n" ); \
+ if( result > 0 ) \
PaUtil_DebugPrint("\t" positiveResultFormatString "\n", result ); \
else \
PaUtil_DebugPrint("\tPaError: %d ( %s )\n", result, Pa_GetErrorText( result ) )
#define PA_LOGAPI_EXIT_PAERROR_OR_T_RESULT( functionName, positiveResultFormatString, result )
#endif
-
+
typedef void (*PaUtilLogCallback ) (const char *log);
/**
*/
/*
- * The text above constitutes the entire PortAudio license; however,
+ * The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version. It is also
- * requested that these non-binding requests be included along with the
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
* license above.
*/
/* 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.
+ * Also shift an extra bit for the high pass filter.
*/
#define DITHER_SHIFT_ ((sizeof(PaInt32)*8 - PA_DITHER_BITS_) + 1)
-
+
current = (((PaInt32)state->randSeed1)>>DITHER_SHIFT_) +
(((PaInt32)state->randSeed2)>>DITHER_SHIFT_);
/* 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.
+ * Also shift an extra bit for the high pass filter.
*/
current = (((PaInt32)state->randSeed1)>>DITHER_SHIFT_) +
(((PaInt32)state->randSeed2)>>DITHER_SHIFT_);
float s1, s2; //error feedback buffers
float s = 0.5f; //set to 0.0f for no noise shaping
float w = pow(2.0,bits-1); //word length (usually bits=16)
- float wi= 1.0f/w;
+ float wi= 1.0f/w;
float d = wi / RAND_MAX; //dither amplitude (2 lsb)
float o = wi * 0.5f; //remove dc offset
float in, tmp;
r2=r1; //can make HP-TRI dither by
r1=rand(); //subtracting previous rand()
-
+
in += s * (s1 + s1 - s2); //error feedback
- tmp = in + o + d * (float)(r1 - r2); //dc offset and dither
-
+ tmp = in + o + d * (float)(r1 - r2); //dc offset and dither
+
out = (int)(w * tmp); //truncate downwards
if(tmp<0.0f) out--; //this is faster than floor()
- s2 = s1;
+ s2 = s1;
s1 = in - wi * (float)out; //error
---
+--
paul.kellett@maxim.abel.co.uk
http://www.maxim.abel.co.uk
*/
Type : First order error feedforward dithering code
References : Posted by Jon Watte
-Notes :
+Notes :
This is about as simple a dithering algorithm as you can implement, but it's
likely to sound better than just truncating to N bits.
Last, if sound quality is paramount (such as when going from > 16 bits to 16
bits) you probably want to use a higher-order dither function found elsewhere
-on this site.
-
-
-Code :
-// This code will down-convert and dither a 16-bit signed short
-// mono signal into an 8-bit unsigned char signal, using a first
-// order forward-feeding error term dither.
-
-#define uchar unsigned char
-
-void dither_one_channel_16_to_8( short * input, uchar * output, int count, int * memory )
-{
- int m = *memory;
- while( count-- > 0 ) {
- int i = *input++;
- i += m;
- int j = i + 32768 - 128;
- uchar o;
- if( j < 0 ) {
- o = 0;
- }
- else if( j > 65535 ) {
- o = 255;
- }
- else {
- o = (uchar)((j>>8)&0xff);
- }
- m = ((j-32768+128)-i);
- *output++ = o;
- }
- *memory = m;
-}
+on this site.
+
+
+Code :
+// This code will down-convert and dither a 16-bit signed short
+// mono signal into an 8-bit unsigned char signal, using a first
+// order forward-feeding error term dither.
+
+#define uchar unsigned char
+
+void dither_one_channel_16_to_8( short * input, uchar * output, int count, int * memory )
+{
+ int m = *memory;
+ while( count-- > 0 ) {
+ int i = *input++;
+ i += m;
+ int j = i + 32768 - 128;
+ uchar o;
+ if( j < 0 ) {
+ o = 0;
+ }
+ else if( j > 65535 ) {
+ o = 255;
+ }
+ else {
+ o = (uchar)((j>>8)&0xff);
+ }
+ m = ((j-32768+128)-i);
+ *output++ = o;
+ }
+ *memory = m;
+}
*/
*/
/*
- * The text above constitutes the entire PortAudio license; however,
+ * The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version. It is also
- * requested that these non-binding requests be included along with the
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
* license above.
*/
*/
/*
- * The text above constitutes the entire PortAudio license; however,
+ * The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version. It is also
- * requested that these non-binding requests be included along with the
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
* license above.
*/
#if defined(__APPLE__)
/* we need to do some endian detection that is sensitive to hardware arch */
#if defined(__LITTLE_ENDIAN__)
- #if !defined( PA_LITTLE_ENDIAN )
- #define PA_LITTLE_ENDIAN
- #endif
- #if defined( PA_BIG_ENDIAN )
- #undef PA_BIG_ENDIAN
- #endif
+ #if !defined( PA_LITTLE_ENDIAN )
+ #define PA_LITTLE_ENDIAN
+ #endif
+ #if defined( PA_BIG_ENDIAN )
+ #undef PA_BIG_ENDIAN
+ #endif
#else
- #if !defined( PA_BIG_ENDIAN )
- #define PA_BIG_ENDIAN
- #endif
- #if defined( PA_LITTLE_ENDIAN )
- #undef PA_LITTLE_ENDIAN
- #endif
+ #if !defined( PA_BIG_ENDIAN )
+ #define PA_BIG_ENDIAN
+ #endif
+ #if defined( PA_LITTLE_ENDIAN )
+ #undef PA_LITTLE_ENDIAN
+ #endif
#endif
#else
/* this is not an apple, so first check the existing defines, and, failing that,
case paIncompatibleStreamHostApi: result = "Incompatible stream host API"; break;
case paBadBufferPtr: result = "Bad buffer pointer"; break;
default:
- if( errorCode > 0 )
- result = "Invalid error code (value greater than zero)";
+ if( errorCode > 0 )
+ result = "Invalid error code (value greater than zero)";
else
- result = "Invalid error code";
+ result = "Invalid error code";
break;
}
return result;
}
- return info;
+ return info;
}
PaDeviceIndex *hostApiInputDevice,
PaDeviceIndex *hostApiOutputDevice )
{
- int inputHostApiIndex = -1, /* Suppress uninitialised var warnings: compiler does */
- outputHostApiIndex = -1; /* not see that if inputParameters and outputParame- */
- /* ters are both nonzero, these indices are set. */
+ int inputHostApiIndex = -1; /* Suppress uninitialised var warnings: compiler does */
+ int outputHostApiIndex = -1; /* not see that if inputParameters and outputParameters */
+ /* are both nonzero, these indices are set. */
if( (inputParameters == NULL) && (outputParameters == NULL) )
{
{
/* must be a callback stream */
if( !streamCallback )
- return paInvalidFlag;
+ return paInvalidFlag;
/* must be a full duplex stream */
if( (inputParameters == NULL) || (outputParameters == NULL) )
if( inputChannelCount > 0 )
{
hostApiInputParameters.device = Pa_GetDefaultInputDevice();
- if( hostApiInputParameters.device == paNoDevice )
- return paDeviceUnavailable;
+ if( hostApiInputParameters.device == paNoDevice )
+ return paDeviceUnavailable;
hostApiInputParameters.channelCount = inputChannelCount;
hostApiInputParameters.sampleFormat = sampleFormat;
if( outputChannelCount > 0 )
{
hostApiOutputParameters.device = Pa_GetDefaultOutputDevice();
- if( hostApiOutputParameters.device == paNoDevice )
- return paDeviceUnavailable;
+ if( hostApiOutputParameters.device == paNoDevice )
+ return paDeviceUnavailable;
hostApiOutputParameters.channelCount = outputChannelCount;
hostApiOutputParameters.sampleFormat = sampleFormat;
*/
/*
- * The text above constitutes the entire PortAudio license; however,
+ * The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version. It is also
- * requested that these non-binding requests be included along with the
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
* license above.
*/
/** @file
@ingroup common_src
- @brief Interfaces and representation structures used by pa_front.c
+ @brief Interfaces and representation structures used by pa_front.c
to manage and communicate with host API implementations.
*/
/**
The PA_NO_* host API macros are now deprecated in favor of PA_USE_* macros.
PA_USE_* indicates whether a particular host API will be initialized by PortAudio.
-An undefined or 0 value indicates that the host API will not be used. A value of 1
-indicates that the host API will be used. PA_USE_* macros should be left undefined
+An undefined or 0 value indicates that the host API will not be used. A value of 1
+indicates that the host API will be used. PA_USE_* macros should be left undefined
or defined to either 0 or 1.
The code below ensures that PA_USE_* macros are always defined and have value
-0 or 1. Undefined symbols are defaulted to 0. Symbols that are neither 0 nor 1
+0 or 1. Undefined symbols are defaulted to 0. Symbols that are neither 0 nor 1
are defaulted to 1.
*/
#elif (PA_USE_SKELETON != 0) && (PA_USE_SKELETON != 1)
#undef PA_USE_SKELETON
#define PA_USE_SKELETON 1
-#endif
+#endif
#if defined(PA_NO_ASIO) || defined(PA_NO_DS) || defined(PA_NO_WMME) || defined(PA_NO_WASAPI) || defined(PA_NO_WDMKS)
#error "Portaudio: PA_NO_<APINAME> is no longer supported, please remove definition and use PA_USE_<APINAME> instead"
#elif (PA_USE_ASIO != 0) && (PA_USE_ASIO != 1)
#undef PA_USE_ASIO
#define PA_USE_ASIO 1
-#endif
+#endif
#ifndef PA_USE_DS
#define PA_USE_DS 0
#elif (PA_USE_DS != 0) && (PA_USE_DS != 1)
#undef PA_USE_DS
#define PA_USE_DS 1
-#endif
+#endif
#ifndef PA_USE_WMME
#define PA_USE_WMME 0
#elif (PA_USE_WMME != 0) && (PA_USE_WMME != 1)
#undef PA_USE_WMME
#define PA_USE_WMME 1
-#endif
+#endif
#ifndef PA_USE_WASAPI
#define PA_USE_WASAPI 0
#elif (PA_USE_WASAPI != 0) && (PA_USE_WASAPI != 1)
#undef PA_USE_WASAPI
#define PA_USE_WASAPI 1
-#endif
+#endif
#ifndef PA_USE_WDMKS
#define PA_USE_WDMKS 0
#elif (PA_USE_WDMKS != 0) && (PA_USE_WDMKS != 1)
#undef PA_USE_WDMKS
#define PA_USE_WDMKS 1
-#endif
+#endif
/* Set default values for Unix based APIs. */
#if defined(PA_NO_OSS) || defined(PA_NO_ALSA) || defined(PA_NO_JACK) || defined(PA_NO_COREAUDIO) || defined(PA_NO_SGI) || defined(PA_NO_ASIHPI)
#elif (PA_USE_OSS != 0) && (PA_USE_OSS != 1)
#undef PA_USE_OSS
#define PA_USE_OSS 1
-#endif
+#endif
#ifndef PA_USE_ALSA
#define PA_USE_ALSA 0
#elif (PA_USE_ALSA != 0) && (PA_USE_ALSA != 1)
#undef PA_USE_ALSA
#define PA_USE_ALSA 1
-#endif
+#endif
#ifndef PA_USE_JACK
#define PA_USE_JACK 0
#elif (PA_USE_JACK != 0) && (PA_USE_JACK != 1)
#undef PA_USE_JACK
#define PA_USE_JACK 1
-#endif
+#endif
#ifndef PA_USE_SGI
#define PA_USE_SGI 0
#elif (PA_USE_SGI != 0) && (PA_USE_SGI != 1)
#undef PA_USE_SGI
#define PA_USE_SGI 1
-#endif
+#endif
#ifndef PA_USE_COREAUDIO
#define PA_USE_COREAUDIO 0
#elif (PA_USE_COREAUDIO != 0) && (PA_USE_COREAUDIO != 1)
#undef PA_USE_COREAUDIO
#define PA_USE_COREAUDIO 1
-#endif
+#endif
#ifndef PA_USE_ASIHPI
#define PA_USE_ASIHPI 0
#elif (PA_USE_ASIHPI != 0) && (PA_USE_ASIHPI != 1)
#undef PA_USE_ASIHPI
#define PA_USE_ASIHPI 1
-#endif
+#endif
#ifdef __cplusplus
extern "C"
The inputParameters and outputParameters pointers should not be saved
as they will not remain valid after OpenStream is called.
-
+
The following guarantees are made about parameters to (*OpenStream)():
[NOTE: the following list up to *END PA FRONT VALIDATIONS* should be
kept in sync with the one for ValidateOpenStreamParameters and
Pa_OpenStream in pa_front.c]
-
+
PaHostApiRepresentation *hostApi
- is valid for this implementation
- if inputParameters & outputParmeters are both valid, that
inputParameters->device & outputParmeters->device both use the same host api
-
+
PaDeviceIndex inputParameters->device
- is within range (0 to Pa_CountDevices-1) Or:
- is paUseHostApiSpecificDeviceSpecification and
int inputParameters->numChannels
- if inputParameters->device is not paUseHostApiSpecificDeviceSpecification, numInputChannels is > 0
- upper bound is NOT validated against device capabilities
-
+
PaSampleFormat inputParameters->sampleFormat
- is one of the sample formats defined in portaudio.h
void *inputParameters->hostApiSpecificStreamInfo
- if supplied its hostApi field matches the input device's host Api
-
+
PaDeviceIndex outputParmeters->device
- is within range (0 to Pa_CountDevices-1)
-
+
int outputParmeters->numChannels
- if inputDevice is valid, numInputChannels is > 0
- upper bound is NOT validated against device capabilities
-
+
PaSampleFormat outputParmeters->sampleFormat
- is one of the sample formats defined in portaudio.h
-
+
void *outputParmeters->hostApiSpecificStreamInfo
- if supplied its hostApi field matches the output device's host Api
-
+
double sampleRate
- is not an 'absurd' rate (less than 1000. or greater than 384000.)
- sampleRate is NOT validated against device capabilities
-
+
PaStreamFlags streamFlags
- unused platform neutral flags are zero
- paNeverDropInput is only used for full-duplex callback streams
The following validations MUST be performed by (*OpenStream)():
- check that input device can support numInputChannels
-
+
- check that input device can support inputSampleFormat, or that
we have the capability to convert from outputSampleFormat to
a native format
or return an error if no inputStreamInfo is expected
- check that output device can support numOutputChannels
-
+
- check that output device can support outputSampleFormat, or that
we have the capability to convert from outputSampleFormat to
a native format
/** Prototype for the initialization function which must be implemented by every
host API.
-
- This function should only return an error other than paNoError if it encounters
- an unexpected and fatal error (memory allocation error for example). In general,
- there may be conditions under which it returns a NULL interface pointer and also
- returns paNoError. For example, if the ASIO implementation detects that ASIO is
+
+ This function should only return an error other than paNoError if it encounters
+ an unexpected and fatal error (memory allocation error for example). In general,
+ there may be conditions under which it returns a NULL interface pointer and also
+ returns paNoError. For example, if the ASIO implementation detects that ASIO is
not installed, it should return a NULL interface, and paNoError.
@see paHostApiInitializers
/** paHostApiInitializers is a NULL-terminated array of host API initialization
functions. These functions are called by pa_front.c to initialize the host APIs
- when the client calls Pa_Initialize().
-
+ when the client calls Pa_Initialize().
+
The initialization functions are invoked in order.
- The first successfully initialized host API that has a default input *or* output
+ The first successfully initialized host API that has a default input *or* output
device is used as the default PortAudio host API. This is based on the logic that
there is only one default host API, and it must contain the default input and output
devices (if defined).
*/
/*
- * The text above constitutes the entire PortAudio license; however,
+ * The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version. It is also
- * requested that these non-binding requests be included along with the
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
* license above.
*/
#elif defined(__GNUC__)
/* GCC >= 4.1 has built-in intrinsics. We'll use those */
# if (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 1)
-# define PaUtil_FullMemoryBarrier() __sync_synchronize()
-# define PaUtil_ReadMemoryBarrier() __sync_synchronize()
-# define PaUtil_WriteMemoryBarrier() __sync_synchronize()
+# define PaUtil_FullMemoryBarrier() __sync_synchronize()
+# define PaUtil_ReadMemoryBarrier() __sync_synchronize()
+# define PaUtil_WriteMemoryBarrier() __sync_synchronize()
/* as a fallback, GCC understands volatile asm and "memory" to mean it
* should not reorder memory read/writes */
/* Note that it is not clear that any compiler actually defines __PPC__,
* it can probably removed safely. */
# elif defined( __ppc__ ) || defined( __powerpc__) || defined( __PPC__ )
-# define PaUtil_FullMemoryBarrier() asm volatile("sync":::"memory")
-# define PaUtil_ReadMemoryBarrier() asm volatile("sync":::"memory")
-# define PaUtil_WriteMemoryBarrier() asm volatile("sync":::"memory")
+# define PaUtil_FullMemoryBarrier() asm volatile("sync":::"memory")
+# define PaUtil_ReadMemoryBarrier() asm volatile("sync":::"memory")
+# define PaUtil_WriteMemoryBarrier() asm volatile("sync":::"memory")
# elif defined( __i386__ ) || defined( __i486__ ) || defined( __i586__ ) || \
- defined( __i686__ ) || defined( __x86_64__ )
-# define PaUtil_FullMemoryBarrier() asm volatile("mfence":::"memory")
-# define PaUtil_ReadMemoryBarrier() asm volatile("lfence":::"memory")
-# define PaUtil_WriteMemoryBarrier() asm volatile("sfence":::"memory")
+ defined( __i686__ ) || defined( __x86_64__ )
+# define PaUtil_FullMemoryBarrier() asm volatile("mfence":::"memory")
+# define PaUtil_ReadMemoryBarrier() asm volatile("lfence":::"memory")
+# define PaUtil_WriteMemoryBarrier() asm volatile("sfence":::"memory")
# else
-# ifdef ALLOW_SMP_DANGERS
-# warning Memory barriers not defined on this system or system unknown
-# warning For SMP safety, you should fix this.
-# define PaUtil_FullMemoryBarrier()
-# define PaUtil_ReadMemoryBarrier()
-# define PaUtil_WriteMemoryBarrier()
-# else
-# error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed.
-# endif
+# ifdef ALLOW_SMP_DANGERS
+# warning Memory barriers not defined on this system or system unknown
+# warning For SMP safety, you should fix this.
+# define PaUtil_FullMemoryBarrier()
+# define PaUtil_ReadMemoryBarrier()
+# define PaUtil_WriteMemoryBarrier()
+# else
+# error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed.
+# endif
# endif
#elif (_MSC_VER >= 1400) && !defined(_WIN32_WCE)
# include <intrin.h>
# define PaUtil_WriteMemoryBarrier() _asm { lock add [esp], 0 }
#else
# ifdef ALLOW_SMP_DANGERS
-# warning Memory barriers not defined on this system or system unknown
-# warning For SMP safety, you should fix this.
-# define PaUtil_FullMemoryBarrier()
-# define PaUtil_ReadMemoryBarrier()
-# define PaUtil_WriteMemoryBarrier()
+# warning Memory barriers not defined on this system or system unknown
+# warning For SMP safety, you should fix this.
+# define PaUtil_FullMemoryBarrier()
+# define PaUtil_ReadMemoryBarrier()
+# define PaUtil_WriteMemoryBarrier()
# else
-# error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed.
+# error Memory barriers are not defined on this system. You can still compile by defining ALLOW_SMP_DANGERS, but SMP safety will not be guaranteed.
# endif
#endif
*/
/*
- * The text above constitutes the entire PortAudio license; however,
+ * The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version. It is also
- * requested that these non-binding requests be included along with the
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
* license above.
*/
}
else /* unknown host buffer size */
{
- bp->framesPerTempBuffer = PA_FRAMES_PER_TEMP_BUFFER_WHEN_HOST_BUFFER_SIZE_IS_UNKNOWN_;
+ bp->framesPerTempBuffer = PA_FRAMES_PER_TEMP_BUFFER_WHEN_HOST_BUFFER_SIZE_IS_UNKNOWN_;
}
}
else
bp->framesInTempInputBuffer = bp->initialFramesInTempInputBuffer;
bp->framesInTempOutputBuffer = bp->initialFramesInTempOutputBuffer;
-
+
if( inputChannelCount > 0 )
{
bytesPerSample = Pa_GetSampleSize( hostInputSampleFormat );
}
/* Under the assumption that no ADC in existence delivers better than 24bits resolution,
- we disable dithering when host input format is paInt32 and user format is paInt24,
+ we disable dithering when host input format is paInt32 and user format is paInt24,
since the host samples will just be padded with zeros anyway. */
tempInputStreamFlags = streamFlags;
PaUtil_SelectConverter( hostInputSampleFormat, userInputSampleFormat, tempInputStreamFlags );
bp->inputZeroer = PaUtil_SelectZeroer( userInputSampleFormat );
-
+
bp->userInputIsInterleaved = (userInputSampleFormat & paNonInterleaved)?0:1;
-
+
bp->hostInputIsInterleaved = (hostInputSampleFormat & paNonInterleaved)?0:1;
bp->userInputSampleFormatIsEqualToHost = ((userInputSampleFormat & ~paNonInterleaved) == (hostInputSampleFormat & ~paNonInterleaved));
tempInputBufferSize =
bp->framesPerTempBuffer * bp->bytesPerUserInputSample * inputChannelCount;
-
+
bp->tempInputBuffer = PaUtil_AllocateMemory( tempInputBufferSize );
if( bp->tempInputBuffer == 0 )
{
result = paInsufficientMemory;
goto error;
}
-
+
if( bp->framesInTempInputBuffer > 0 )
memset( bp->tempInputBuffer, 0, tempInputBufferSize );
if( bp->framesInTempOutputBuffer > 0 )
memset( bp->tempOutputBuffer, 0, tempOutputBufferSize );
-
+
if( userOutputSampleFormat & paNonInterleaved )
{
bp->tempOutputBufferPtrs =
bp->hostOutputChannels[0] = (PaUtilChannelDescriptor*)
PaUtil_AllocateMemory( sizeof(PaUtilChannelDescriptor)*outputChannelCount * 2 );
if( bp->hostOutputChannels[0] == 0 )
- {
+ {
result = paInsufficientMemory;
goto error;
}
if( bp->hostInputChannels[0] )
PaUtil_FreeMemory( bp->hostInputChannels[0] );
-
+
if( bp->tempOutputBuffer )
PaUtil_FreeMemory( bp->tempOutputBuffer );
}
if( bp->framesInTempOutputBuffer > 0 )
- {
+ {
tempOutputBufferSize =
bp->framesPerTempBuffer * bp->bytesPerUserOutputSample * bp->outputChannelCount;
memset( bp->tempOutputBuffer, 0, tempOutputBufferSize );
else
bp->hostInputFrameCount[0] = frameCount;
}
-
+
void PaUtil_SetNoInput( PaUtilBufferProcessor* bp )
{
unsigned int channel, void *data, unsigned int stride )
{
assert( channel < bp->inputChannelCount );
-
+
bp->hostInputChannels[0][channel].data = data;
bp->hostInputChannels[0][channel].stride = stride;
}
{
assert( channel < bp->inputChannelCount );
assert( !bp->hostInputIsInterleaved );
-
+
bp->hostInputChannels[0][channel].data = data;
bp->hostInputChannels[0][channel].stride = 1;
}
assert( firstChannel < bp->inputChannelCount );
assert( firstChannel + channelCount <= bp->inputChannelCount );
assert( bp->hostInputIsInterleaved );
-
+
for( i=0; i< channelCount; ++i )
{
bp->hostInputChannels[1][channel+i].data = p;
}
}
-
+
void PaUtil_Set2ndNonInterleavedInputChannel( PaUtilBufferProcessor* bp,
unsigned int channel, void *data )
{
assert( channel < bp->inputChannelCount );
assert( !bp->hostInputIsInterleaved );
-
+
bp->hostInputChannels[1][channel].data = data;
bp->hostInputChannels[1][channel].stride = 1;
}
assert( firstChannel < bp->outputChannelCount );
assert( firstChannel + channelCount <= bp->outputChannelCount );
assert( bp->hostOutputIsInterleaved );
-
+
for( i=0; i< channelCount; ++i )
{
PaUtil_SetOutputChannel( bp, channel + i, p, channelCount );
assert( firstChannel < bp->outputChannelCount );
assert( firstChannel + channelCount <= bp->outputChannelCount );
assert( bp->hostOutputIsInterleaved );
-
+
for( i=0; i< channelCount; ++i )
{
PaUtil_Set2ndOutputChannel( bp, channel + i, p, channelCount );
}
}
-
+
void PaUtil_Set2ndNonInterleavedOutputChannel( PaUtilBufferProcessor* bp,
unsigned int channel, void *data )
{
assert( channel < bp->outputChannelCount );
assert( !bp->hostOutputIsInterleaved );
-
+
PaUtil_Set2ndOutputChannel( bp, channel, data, 1 );
}
/* the first streamCallback will be called to process samples which are
currently in the input buffer before the ones starting at the timeInfo time */
-
+
bp->timeInfo->inputBufferAdcTime -= bp->framesInTempInputBuffer * bp->samplePeriod;
-
+
/* We just pass through timeInfo->currentTime provided by the caller. This is
- not strictly conformant to the word of the spec, since the buffer processor
+ not strictly conformant to the word of the spec, since the buffer processor
might call the callback multiple times, and we never refresh currentTime. */
/* the first streamCallback will be called to generate samples which will be
}
else /* there are input channels */
{
-
+
destBytePtr = (unsigned char *)bp->tempInputBuffer;
if( bp->userInputIsInterleaved )
i * bp->bytesPerUserInputSample * frameCount;
}
}
-
+
userInput = bp->tempInputBufferPtrs;
}
}
}
else
- {
+ {
if( skipInputConvert )
{
for( i=0; i<bp->inputChannelCount; ++i )
/* process host buffer directly, or use temp buffer if formats differ or host buffer non-interleaved,
* or if num channels differs between the host (set in stride) and the user (eg with some Alsa hw:) */
if( bp->userOutputSampleFormatIsEqualToHost && bp->hostOutputIsInterleaved
- && bp->outputChannelCount == hostOutputChannels[0].stride )
+ && bp->outputChannelCount == hostOutputChannels[0].stride )
{
userOutput = hostOutputChannels[0].data;
skipOutputConvert = 1;
userOutput = bp->tempOutputBufferPtrs;
}
}
-
+
*streamCallbackResult = bp->streamCallback( userInput, userOutput,
frameCount, bp->timeInfo, bp->callbackStatusFlags, bp->userData );
bp->timeInfo->outputBufferDacTime += frameCount * bp->samplePeriod;
/* convert output data (user -> host) */
-
+
if( bp->outputChannelCount != 0 && bp->hostOutputChannels[0][0].data )
{
if( skipOutputConvert )
- {
- for( i=0; i<bp->outputChannelCount; ++i )
- {
- /* advance dest ptr for next iteration */
- hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
- frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
- }
- }
- else
- {
-
- srcBytePtr = (unsigned char *)bp->tempOutputBuffer;
-
- if( bp->userOutputIsInterleaved )
- {
- srcSampleStrideSamples = bp->outputChannelCount;
- srcChannelStrideBytes = bp->bytesPerUserOutputSample;
- }
- else /* user output is not interleaved */
- {
- srcSampleStrideSamples = 1;
- srcChannelStrideBytes = frameCount * bp->bytesPerUserOutputSample;
- }
-
- for( i=0; i<bp->outputChannelCount; ++i )
- {
- bp->outputConverter( hostOutputChannels[i].data,
- hostOutputChannels[i].stride,
- srcBytePtr, srcSampleStrideSamples,
- frameCount, &bp->ditherGenerator );
-
- srcBytePtr += srcChannelStrideBytes; /* skip to next source channel */
-
- /* advance dest ptr for next iteration */
- hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
- frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
- }
- }
+ {
+ for( i=0; i<bp->outputChannelCount; ++i )
+ {
+ /* advance dest ptr for next iteration */
+ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
+ frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
+ }
+ }
+ else
+ {
+
+ srcBytePtr = (unsigned char *)bp->tempOutputBuffer;
+
+ if( bp->userOutputIsInterleaved )
+ {
+ srcSampleStrideSamples = bp->outputChannelCount;
+ srcChannelStrideBytes = bp->bytesPerUserOutputSample;
+ }
+ else /* user output is not interleaved */
+ {
+ srcSampleStrideSamples = 1;
+ srcChannelStrideBytes = frameCount * bp->bytesPerUserOutputSample;
+ }
+
+ for( i=0; i<bp->outputChannelCount; ++i )
+ {
+ bp->outputConverter( hostOutputChannels[i].data,
+ hostOutputChannels[i].stride,
+ srcBytePtr, srcSampleStrideSamples,
+ frameCount, &bp->ditherGenerator );
+
+ srcBytePtr += srcChannelStrideBytes; /* skip to next source channel */
+
+ /* advance dest ptr for next iteration */
+ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
+ frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
+ }
+ }
}
-
+
framesProcessed += frameCount;
framesToGo -= frameCount;
unsigned long frameCount;
unsigned long framesToGo = framesToProcess;
unsigned long framesProcessed = 0;
-
+
userOutput = 0;
do
destBytePtr = ((unsigned char*)bp->tempInputBuffer) +
bp->bytesPerUserInputSample * bp->inputChannelCount *
bp->framesInTempInputBuffer;
-
+
destSampleStrideSamples = bp->inputChannelCount;
destChannelStrideBytes = bp->bytesPerUserInputSample;
bp->tempInputBufferPtrs[i] = ((unsigned char*)bp->tempInputBuffer) +
i * bp->bytesPerUserInputSample * bp->framesPerUserBuffer;
}
-
+
userInput = bp->tempInputBufferPtrs;
}
bp->timeInfo->inputBufferAdcTime += bp->framesPerUserBuffer * bp->samplePeriod;
}
-
+
bp->framesInTempInputBuffer = 0;
}
}
bp->timeInfo->inputBufferAdcTime = 0;
-
+
*streamCallbackResult = bp->streamCallback( userInput, userOutput,
bp->framesPerUserBuffer, bp->timeInfo,
bp->callbackStatusFlags, bp->userData );
srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) +
bp->bytesPerUserOutputSample *
(bp->framesPerUserBuffer - bp->framesInTempOutputBuffer);
-
+
srcSampleStrideSamples = 1;
srcChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserOutputSample;
}
frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
}
}
-
+
framesProcessed += frameCount;
-
+
framesToGo -= frameCount;
}while( framesToGo > 0 );
}
/* CopyTempOutputBuffersToHostOutputBuffers is called from AdaptingProcess to copy frames from
- tempOutputBuffer to hostOutputChannels. This includes data conversion
- and interleaving.
+ tempOutputBuffer to hostOutputChannels. This includes data conversion
+ and interleaving.
*/
static void CopyTempOutputBuffersToHostOutputBuffers( PaUtilBufferProcessor *bp)
{
unsigned int srcChannelStrideBytes; /* stride from one channel to the next, in bytes */
unsigned int i;
- /* copy frames from user to host output buffers */
- while( bp->framesInTempOutputBuffer > 0 &&
- ((bp->hostOutputFrameCount[0] + bp->hostOutputFrameCount[1]) > 0) )
- {
- maxFramesToCopy = bp->framesInTempOutputBuffer;
-
- /* select the output buffer set (1st or 2nd) */
- if( bp->hostOutputFrameCount[0] > 0 )
- {
- hostOutputChannels = bp->hostOutputChannels[0];
- frameCount = PA_MIN_( bp->hostOutputFrameCount[0], maxFramesToCopy );
- }
- else
- {
- hostOutputChannels = bp->hostOutputChannels[1];
- frameCount = PA_MIN_( bp->hostOutputFrameCount[1], maxFramesToCopy );
- }
-
- if( bp->userOutputIsInterleaved )
- {
- srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) +
- bp->bytesPerUserOutputSample * bp->outputChannelCount *
- (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer);
-
- srcSampleStrideSamples = bp->outputChannelCount;
- srcChannelStrideBytes = bp->bytesPerUserOutputSample;
- }
- else /* user output is not interleaved */
- {
- srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) +
- bp->bytesPerUserOutputSample *
- (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer);
-
- srcSampleStrideSamples = 1;
- srcChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserOutputSample;
- }
-
- for( i=0; i<bp->outputChannelCount; ++i )
- {
- assert( hostOutputChannels[i].data != NULL );
- bp->outputConverter( hostOutputChannels[i].data,
- hostOutputChannels[i].stride,
- srcBytePtr, srcSampleStrideSamples,
- frameCount, &bp->ditherGenerator );
-
- srcBytePtr += srcChannelStrideBytes; /* skip to next source channel */
-
- /* advance dest ptr for next iteration */
- hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
- frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
- }
-
- if( bp->hostOutputFrameCount[0] > 0 )
- bp->hostOutputFrameCount[0] -= frameCount;
- else
- bp->hostOutputFrameCount[1] -= frameCount;
-
- bp->framesInTempOutputBuffer -= frameCount;
- }
+ /* copy frames from user to host output buffers */
+ while( bp->framesInTempOutputBuffer > 0 &&
+ ((bp->hostOutputFrameCount[0] + bp->hostOutputFrameCount[1]) > 0) )
+ {
+ maxFramesToCopy = bp->framesInTempOutputBuffer;
+
+ /* select the output buffer set (1st or 2nd) */
+ if( bp->hostOutputFrameCount[0] > 0 )
+ {
+ hostOutputChannels = bp->hostOutputChannels[0];
+ frameCount = PA_MIN_( bp->hostOutputFrameCount[0], maxFramesToCopy );
+ }
+ else
+ {
+ hostOutputChannels = bp->hostOutputChannels[1];
+ frameCount = PA_MIN_( bp->hostOutputFrameCount[1], maxFramesToCopy );
+ }
+
+ if( bp->userOutputIsInterleaved )
+ {
+ srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) +
+ bp->bytesPerUserOutputSample * bp->outputChannelCount *
+ (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer);
+
+ srcSampleStrideSamples = bp->outputChannelCount;
+ srcChannelStrideBytes = bp->bytesPerUserOutputSample;
+ }
+ else /* user output is not interleaved */
+ {
+ srcBytePtr = ((unsigned char*)bp->tempOutputBuffer) +
+ bp->bytesPerUserOutputSample *
+ (bp->framesPerUserBuffer - bp->framesInTempOutputBuffer);
+
+ srcSampleStrideSamples = 1;
+ srcChannelStrideBytes = bp->framesPerUserBuffer * bp->bytesPerUserOutputSample;
+ }
+
+ for( i=0; i<bp->outputChannelCount; ++i )
+ {
+ assert( hostOutputChannels[i].data != NULL );
+ bp->outputConverter( hostOutputChannels[i].data,
+ hostOutputChannels[i].stride,
+ srcBytePtr, srcSampleStrideSamples,
+ frameCount, &bp->ditherGenerator );
+
+ srcBytePtr += srcChannelStrideBytes; /* skip to next source channel */
+
+ /* advance dest ptr for next iteration */
+ hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
+ frameCount * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
+ }
+
+ if( bp->hostOutputFrameCount[0] > 0 )
+ bp->hostOutputFrameCount[0] -= frameCount;
+ else
+ bp->hostOutputFrameCount[1] -= frameCount;
+
+ bp->framesInTempOutputBuffer -= frameCount;
+ }
}
/*
unsigned int destSampleStrideSamples; /* stride from one sample to the next within a channel, in samples */
unsigned int destChannelStrideBytes; /* stride from one channel to the next, in bytes */
unsigned int i, j;
-
+
framesAvailable = bp->hostInputFrameCount[0] + bp->hostInputFrameCount[1];/* this is assumed to be the same as the output buffer's frame count */
endProcessingMinFrameCount = (bp->framesPerUserBuffer - 1);
/* Fill host output with remaining frames in user output (tempOutputBuffer) */
- CopyTempOutputBuffersToHostOutputBuffers( bp );
+ CopyTempOutputBuffersToHostOutputBuffers( bp );
- while( framesAvailable > endProcessingMinFrameCount )
+ while( framesAvailable > endProcessingMinFrameCount )
{
if( bp->framesInTempOutputBuffer == 0 && *streamCallbackResult != paContinue )
if( frameCount > 0 )
{
hostOutputChannels = bp->hostOutputChannels[i];
-
+
for( j=0; j<bp->outputChannelCount; ++j )
{
bp->outputZeroer( hostOutputChannels[j].data,
bp->hostOutputFrameCount[i] = 0;
}
}
- }
+ }
/* copy frames from host to user input buffers */
bp->hostInputFrameCount[0] -= frameCount;
else
bp->hostInputFrameCount[1] -= frameCount;
-
+
bp->framesInTempInputBuffer += frameCount;
/* update framesAvailable and framesProcessed based on input consumed
}
}
- /* copy frames from user (tempOutputBuffer) to host output buffers (hostOutputChannels)
+ /* copy frames from user (tempOutputBuffer) to host output buffers (hostOutputChannels)
Means to process the user output provided by the callback. Has to be called after
each callback. */
- CopyTempOutputBuffersToHostOutputBuffers( bp );
+ CopyTempOutputBuffersToHostOutputBuffers( bp );
}
-
+
return framesProcessed;
}
{
unsigned long framesToProcess, framesToGo;
unsigned long framesProcessed = 0;
-
+
if( bp->inputChannelCount != 0 && bp->outputChannelCount != 0
&& bp->hostInputChannels[0][0].data /* input was supplied (see PaUtil_SetNoInput) */
&& bp->hostOutputChannels[0][0].data /* output was supplied (see PaUtil_SetNoOutput) */ )
*hostOutputFrameCount );
assert( framesToProcess != 0 );
-
+
framesProcessedThisIteration = NonAdaptingProcess( bp, streamCallbackResult,
hostInputChannels, hostOutputChannels,
- framesToProcess );
+ framesToProcess );
*hostInputFrameCount -= framesProcessedThisIteration;
*hostOutputFrameCount -= framesProcessedThisIteration;
framesProcessed += framesProcessedThisIteration;
framesToGo -= framesProcessedThisIteration;
-
+
}while( framesToGo > 0 );
}
else
framesToProcess );
/* process second buffer if provided */
-
+
framesToProcess = (bp->inputChannelCount != 0)
? bp->hostInputFrameCount[1]
: bp->hostOutputFrameCount[1];
if( bp->inputChannelCount != 0 && bp->outputChannelCount != 0 )
{
/* full duplex */
-
+
if( bp->hostBufferSizeMode == paUtilVariableHostBufferSizePartialUsageAllowed )
{
framesProcessed = AdaptingProcess( bp, streamCallbackResult,
int PaUtil_IsBufferProcessorOutputEmpty( PaUtilBufferProcessor* bp )
{
return (bp->framesInTempOutputBuffer) ? 0 : 1;
-}
+}
unsigned long PaUtil_CopyInput( PaUtilBufferProcessor* bp,
if( bp->userInputIsInterleaved )
{
destBytePtr = (unsigned char*)*buffer;
-
+
destSampleStrideSamples = bp->inputChannelCount;
destChannelStrideBytes = bp->bytesPerUserInputSample;
else
{
/* user input is not interleaved */
-
+
nonInterleavedDestPtrs = (void**)*buffer;
destSampleStrideSamples = 1;
-
+
for( i=0; i<bp->inputChannelCount; ++i )
{
destBytePtr = (unsigned char*)nonInterleavedDestPtrs[i];
/* advance callers dest pointer (nonInterleavedDestPtrs[i]) */
destBytePtr += bp->bytesPerUserInputSample * framesToCopy;
nonInterleavedDestPtrs[i] = destBytePtr;
-
+
/* advance source ptr for next iteration */
hostInputChannels[i].data = ((unsigned char*)hostInputChannels[i].data) +
framesToCopy * hostInputChannels[i].stride * bp->bytesPerHostInputSample;
}
bp->hostInputFrameCount[0] -= framesToCopy;
-
+
return framesToCopy;
}
if( bp->userOutputIsInterleaved )
{
srcBytePtr = (unsigned char*)*buffer;
-
+
srcSampleStrideSamples = bp->outputChannelCount;
srcChannelStrideBytes = bp->bytesPerUserOutputSample;
else
{
/* user output is not interleaved */
-
+
nonInterleavedSrcPtrs = (void**)*buffer;
srcSampleStrideSamples = 1;
-
+
for( i=0; i<bp->outputChannelCount; ++i )
{
srcBytePtr = (unsigned char*)nonInterleavedSrcPtrs[i];
-
+
bp->outputConverter( hostOutputChannels[i].data,
hostOutputChannels[i].stride,
srcBytePtr, srcSampleStrideSamples,
/* advance callers source pointer (nonInterleavedSrcPtrs[i]) */
srcBytePtr += bp->bytesPerUserOutputSample * framesToCopy;
nonInterleavedSrcPtrs[i] = srcBytePtr;
-
+
/* advance dest ptr for next iteration */
hostOutputChannels[i].data = ((unsigned char*)hostOutputChannels[i].data) +
framesToCopy * hostOutputChannels[i].stride * bp->bytesPerHostOutputSample;
}
bp->hostOutputFrameCount[0] += framesToCopy;
-
+
return framesToCopy;
}
}
bp->hostOutputFrameCount[0] += framesToZero;
-
+
return framesToZero;
}
*/
/*
- * The text above constitutes the entire PortAudio license; however,
+ * The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version. It is also
- * requested that these non-binding requests be included along with the
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
* license above.
*/
-
+
/** @file
@ingroup common_src
The following sections provide an overview of how to use the buffer processor.
Interested readers are advised to consult the host API implementations for
examples of buffer processor usage.
-
+
<h4>Initialization, resetting and termination</h4>
When the buffer processor is no longer used call
PaUtil_TerminateBufferProcessor.
-
+
<h4>Using the buffer processor for a callback stream</h4>
The buffer processor's role in a callback stream is to take host input buffers
host buffer(s), so the above steps need to be repeated until the user
buffer(s) are full.
-
+
To copy data to the host output buffer from the user buffers(s) supplied
to Pa_WriteStream use the following calling sequence.
-# Call PaUtil_CopyOutput with the user buffer pointer (or a copy of the
array of buffer pointers for a non-interleaved stream) passed to
Pa_WriteStream, along with the number of frames in the user buffer(s).
- Be careful to pass a <i>copy</i> of the user buffer pointers to
+ Be careful to pass a <i>copy</i> of the user buffer pointers to
PaUtil_CopyOutput because PaUtil_CopyOutput advances the pointers to
the start of the next region to copy.
- PaUtil_CopyOutput will not copy more data than fits in the host buffer(s),
int userInputIsInterleaved;
PaUtilConverter *inputConverter;
PaUtilZeroer *inputZeroer;
-
+
unsigned int outputChannelCount;
unsigned int bytesPerHostOutputSample;
unsigned int bytesPerUserOutputSample;
@param userInputSampleFormat Format of user input samples, as passed to
Pa_OpenStream. This parameter is ignored for ouput-only streams.
-
+
@param hostInputSampleFormat Format of host input samples. This parameter is
ignored for output-only streams. See note about host buffer interleave below.
@param userOutputSampleFormat Format of user output samples, as passed to
Pa_OpenStream. This parameter is ignored for input-only streams.
-
+
@param hostOutputSampleFormat Format of host output samples. This parameter is
ignored for input-only streams. See note about host buffer interleave below.
@param sampleRate Sample rate of the stream. The more accurate this is the
better - it is used for updating time stamps when adapting buffers.
-
+
@param streamFlags Stream flags as passed to Pa_OpenStream, this parameter is
used for selecting special sample conversion options such as clipping and
dithering.
-
+
@param framesPerUserBuffer Number of frames per user buffer, as requested
by the framesPerBuffer parameter to Pa_OpenStream. This parameter may be
zero to indicate that the user will accept any (and varying) buffer sizes.
@param hostBufferSizeMode A mode flag indicating the size variability of
host buffers that will be passed to the buffer processor. See
PaUtilHostBufferSizeMode for further details.
-
+
@param streamCallback The user stream callback passed to Pa_OpenStream.
@param userData The user data field passed to Pa_OpenStream.
-
+
@note The interleave flag is ignored for host buffer formats. Host
interleave is determined by the use of different SetInput and SetOutput
functions.
@return An error code indicating whether the initialization was successful.
If the error code is not PaNoError, the buffer processor was not initialized
and should not be used.
-
+
@see Pa_OpenStream, PaUtilHostBufferSizeMode, PaUtil_TerminateBufferProcessor
*/
PaError PaUtil_InitializeBufferProcessor( PaUtilBufferProcessor* bufferProcessor,
/** Terminate a buffer processor's representation. Deallocates any temporary
buffers allocated by PaUtil_InitializeBufferProcessor.
-
+
@param bufferProcessor The buffer processor structure to terminate.
@see PaUtil_InitializeBufferProcessor.
Functions to set host input and output buffers, used by both callback streams
and blocking read/write streams.
*/
-/*@{*/
+/*@{*/
/** Set the number of frames in the input host buffer(s) specified by the
void PaUtil_SetInputFrameCount( PaUtilBufferProcessor* bufferProcessor,
unsigned long frameCount );
-
+
/** Indicate that no input is available. This function should be used when
priming the output of a full-duplex stream opened with the
paPrimeOutputBuffersUsingStreamCallback flag. Note that it is not necessary
void PaUtil_Set2ndNonInterleavedInputChannel( PaUtilBufferProcessor* bufferProcessor,
unsigned int channel, void *data );
-
+
/** Set the number of frames in the output host buffer(s) specified by the
PaUtil_Set*OutputChannel functions.
void PaUtil_SetInterleavedOutputChannels( PaUtilBufferProcessor* bufferProcessor,
unsigned int firstChannel, void *data, unsigned int channelCount );
-
+
/** Provide the buffer processor with a pointer to one non-interleaved host
output channel.
void PaUtil_BeginBufferProcessing( PaUtilBufferProcessor* bufferProcessor,
PaStreamCallbackTimeInfo* timeInfo, PaStreamCallbackFlags callbackStatusFlags );
-
+
/** Finish processing a host buffer (or a pair of host buffers in the
full-duplex case) for a callback stream.
@param bufferProcessor The buffer processor.
-
+
@param callbackResult On input, indicates a previous callback result, and on
exit, the result of the user stream callback, if it is called.
On entry callbackResult should contain one of { paContinue, paComplete, or
a callbackResult of paComplete.
@param bufferProcessor The buffer processor.
-
+
@return Returns non-zero when callback generated output remains in the internal
buffer and zero (0) when there internal buffer contains no callback generated
data.
@param bufferProcessor The buffer processor.
@param frameCount The maximum number of frames to zero.
-
+
@return The number of frames zeroed.
*/
unsigned long PaUtil_ZeroOutput( PaUtilBufferProcessor* bufferProcessor,
* modified for SMP safety on Mac OS X by Bjorn Roche
* modified for SMP safety on Linux by Leland Lucius
* also, allowed for const where possible
- * modified for multiple-byte-sized data elements by Sven Fischer
+ * modified for multiple-byte-sized data elements by Sven Fischer
*
* Note that this is safe only for a single-thread reader and a
* single-thread writer.
*/
/*
- * The text above constitutes the entire PortAudio license; however,
+ * The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version. It is also
- * requested that these non-binding requests be included along with the
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
* license above.
*/
*/
ring_buffer_size_t PaUtil_AdvanceRingBufferWriteIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount )
{
- /* ensure that previous writes are seen before we update the write index
+ /* ensure that previous writes are seen before we update the write index
(write after write)
*/
PaUtil_WriteMemoryBarrier();
*dataPtr2 = NULL;
*sizePtr2 = 0;
}
-
+
if( available )
PaUtil_ReadMemoryBarrier(); /* (read-after-read) => read barrier */
*/
ring_buffer_size_t PaUtil_AdvanceRingBufferReadIndex( PaUtilRingBuffer *rbuf, ring_buffer_size_t elementCount )
{
- /* ensure that previous reads (copies out of the ring buffer) are always completed before updating (writing) the read index.
+ /* ensure that previous reads (copies out of the ring buffer) are always completed before updating (writing) the read index.
(write-after-read) => full barrier
*/
PaUtil_FullMemoryBarrier();
* Author: Phil Burk, http://www.softsynth.com
* modified for SMP safety on OS X by Bjorn Roche.
* also allowed for const where possible.
- * modified for multiple-byte-sized data elements by Sven Fischer
+ * modified for multiple-byte-sized data elements by Sven Fischer
*
* Note that this is safe only for a single-thread reader
* and a single-thread writer.
*/
/*
- * The text above constitutes the entire PortAudio license; however,
+ * The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version. It is also
- * requested that these non-binding requests be included along with the
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
* license above.
*/
a single reader and a single writer (ie. one thread or callback writes
to the ring buffer, another thread or callback reads from it).
- The PaUtilRingBuffer structure manages a ring buffer containing N
- elements, where N must be a power of two. An element may be any size
+ The PaUtilRingBuffer structure manages a ring buffer containing N
+ elements, where N must be a power of two. An element may be any size
(specified in bytes).
- The memory area used to store the buffer elements must be allocated by
+ The memory area used to store the buffer elements must be allocated by
the client prior to calling PaUtil_InitializeRingBuffer() and must outlive
the use of the ring buffer.
-
- @note The ring buffer functions are not normally exposed in the PortAudio libraries.
+
+ @note The ring buffer functions are not normally exposed in the PortAudio libraries.
If you want to call them then you will need to add pa_ringbuffer.c to your application source code.
*/
*/
/*
- * The text above constitutes the entire PortAudio license; however,
+ * The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version. It is also
- * requested that these non-binding requests be included along with the
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
* license above.
*/
*/
/*
- * The text above constitutes the entire PortAudio license; however,
+ * The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version. It is also
- * requested that these non-binding requests be included along with the
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
* license above.
*/
PaUtilStreamInterface *streamInterface,
PaStreamCallback *streamCallback,
void *userData );
-
+
/** Clean up a PaUtilStreamRepresentation structure previously initialized
by a call to PaUtil_InitializeStreamRepresentation.
PA_STREAM_REP( (stream) )->streamInterface
-
+
#ifdef __cplusplus
}
#endif /* __cplusplus */
*/
/*
- * The text above constitutes the entire PortAudio license; however,
+ * The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version. It is also
- * requested that these non-binding requests be included along with the
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
* license above.
*/
*/
int PaUtil_TraceStubToSatisfyLinker(void)
{
- return 0;
+ return 0;
}
#endif /* TRACE_REALTIME_EVENTS */
*/
/*
- * The text above constitutes the entire PortAudio license; however,
+ * The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version. It is also
- * requested that these non-binding requests be included along with the
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
* license above.
*/
@brief Real-time safe event trace logging facility for debugging.
Allows data to be logged to a fixed size trace buffer in a real-time
- execution context (such as at interrupt time). Each log entry consists
- of a message comprising a string pointer and an int. The trace buffer
+ execution context (such as at interrupt time). Each log entry consists
+ of a message comprising a string pointer and an int. The trace buffer
may be dumped to stdout later.
This facility is only active if PA_TRACE_REALTIME_EVENTS is set to 1,
@fn PaUtil_AddTraceMessage
@brief Add a message to the trace buffer. A message consists of string and an int.
- @param msg The string pointer must remain valid until PaUtil_DumpTraceMessages
- is called. As a result, usually only string literals should be passed as
+ @param msg The string pointer must remain valid until PaUtil_DumpTraceMessages
+ is called. As a result, usually only string literals should be passed as
the msg parameter.
@fn PaUtil_DumpTraceMessages
#endif
#ifndef PA_MAX_TRACE_RECORDS
-#define PA_MAX_TRACE_RECORDS (2048) /**< Maximum number of records stored in trace buffer */
+#define PA_MAX_TRACE_RECORDS (2048) /**< Maximum number of records stored in trace buffer */
#endif
#ifdef __cplusplus
#ifndef PA_TYPES_H
#define PA_TYPES_H
-/*
+/*
* Portable Audio I/O Library
* integer type definitions
*
*/
/*
- * The text above constitutes the entire PortAudio license; however,
+ * The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version. It is also
- * requested that these non-binding requests be included along with the
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
* license above.
*/
*/
/*
- * The text above constitutes the entire PortAudio license; however,
+ * The text above constitutes the entire PortAudio license; however,
* the PortAudio community also makes the following non-binding requests:
*
* Any person wishing to distribute modifications to the Software is
* requested to send the modifications to the original developer so that
- * they can be incorporated into the canonical version. It is also
- * requested that these non-binding requests be included along with the
+ * they can be incorporated into the canonical version. It is also
+ * requested that these non-binding requests be included along with the
* license above.
*/
const char *errorText );
-
+
/* the following functions are implemented in a platform platform specific
.c file
*/