📄 pa_lib.c
字号:
past->past_Usage = 0; past->past_IfLastExitValid = 0; return result;}/*************************************************************************/DLL_API PaError Pa_StreamActive( PortAudioStream *stream ){ internalPortAudioStream *past; if( stream == NULL ) return paBadStreamPtr; past = (internalPortAudioStream *) stream; return PaHost_StreamActive( past );}/*************************************************************************/DLL_API const char *Pa_GetErrorText( PaError errnum ){ const char *msg; switch(errnum) { case paNoError: msg = "Success"; break; case paHostError: msg = "Host error."; break; case paInvalidChannelCount: msg = "Invalid number of channels."; break; case paInvalidSampleRate: msg = "Invalid sample rate."; break; case paInvalidDeviceId: msg = "Invalid device ID."; break; case paInvalidFlag: msg = "Invalid flag."; break; case paSampleFormatNotSupported: msg = "Sample format not supported"; break; case paBadIODeviceCombination: msg = "Illegal combination of I/O devices."; break; case paInsufficientMemory: msg = "Insufficient memory."; break; case paBufferTooBig: msg = "Buffer too big."; break; case paBufferTooSmall: msg = "Buffer too small."; break; case paNullCallback: msg = "No callback routine specified."; break; case paBadStreamPtr: msg = "Invalid stream pointer."; break; case paTimedOut : msg = "Wait Timed Out."; break; case paInternalError: msg = "Internal PortAudio Error."; break; default: msg = "Illegal error number."; break; } return msg;}/* Get CPU Load as a fraction of total CPU time. A value of 0.5 would imply that PortAudio and the sound generating callback was consuming roughly 50% of the available CPU time. The amount may vary depending on CPU load. This function may be called from the callback function.*/DLL_API double Pa_GetCPULoad( PortAudioStream* stream){ internalPortAudioStream *past; if( stream == NULL ) return (double) paBadStreamPtr; past = (internalPortAudioStream *) stream; return past->past_Usage;}/*************************************************************** Calculate 2 LSB dither signal with a triangular distribution.** Ranged properly for adding to a 32 bit integer prior to >>15.*/#define DITHER_BITS (15)#define DITHER_SCALE (1.0f / ((1<<DITHER_BITS)-1))static long Pa_TriangularDither( void ){ static unsigned long previous = 0; static unsigned long randSeed1 = 22222; static unsigned long randSeed2 = 5555555; long current, highPass; /* Generate two random numbers. */ randSeed1 = (randSeed1 * 196314165) + 907633515; randSeed2 = (randSeed2 * 196314165) + 907633515; /* Generate triangular distribution about 0. */ current = (((long)randSeed1)>>(32-DITHER_BITS)) + (((long)randSeed2)>>(32-DITHER_BITS)); /* High pass filter to reduce audibility. */ highPass = current - previous; previous = current; return highPass;}/*************************************************************************** Called by host code.** Convert input from Int16, call user code, then convert output** to Int16 format for native use.** Assumes host native format is paInt16.** Returns result from user callback.*/long Pa_CallConvertInt16( internalPortAudioStream *past, short *nativeInputBuffer, short *nativeOutputBuffer ){ long temp; long bytesEmpty = 0; long bytesFilled = 0; int userResult; unsigned int i; void *inputBuffer = NULL; void *outputBuffer = NULL;#if SUPPORT_AUDIO_CAPTURE /* Get native data from DirectSound. */ if( (past->past_NumInputChannels > 0) && (nativeInputBuffer != NULL) ) { /* Convert from native format to PA format. */ unsigned int samplesPerBuffer = past->past_FramesPerUserBuffer * past->past_NumInputChannels; switch(past->past_InputSampleFormat) { case paFloat32: { float *inBufPtr = (float *) past->past_InputBuffer; inputBuffer = past->past_InputBuffer; for( i=0; i<samplesPerBuffer; i++ ) { inBufPtr[i] = nativeInputBuffer[i] * (1.0f / 32767.0f); } break; } case paInt32: { /* Convert 16 bit data to 32 bit integers */ int *inBufPtr = (int *) past->past_InputBuffer; inputBuffer = past->past_InputBuffer; for( i=0; i<samplesPerBuffer; i++ ) { inBufPtr[i] = nativeInputBuffer[i] << 16; } break; } case paInt16: { /* Already in correct format so don't copy. */ inputBuffer = nativeInputBuffer; break; } case paInt8: { /* Convert 16 bit data to 8 bit chars */ char *inBufPtr = (char *) past->past_InputBuffer; inputBuffer = past->past_InputBuffer; if( past->past_Flags & paDitherOff ) { for( i=0; i<samplesPerBuffer; i++ ) { inBufPtr[i] = (char)(nativeInputBuffer[i] >> 8); } } else { for( i=0; i<samplesPerBuffer; i++ ) { temp = nativeInputBuffer[i]; temp += Pa_TriangularDither() >> 7; temp = ((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp)); inBufPtr[i] = (char)(temp >> 8); } } break; } case paUInt8: { /* Convert 16 bit data to 8 bit unsigned chars */ unsigned char *inBufPtr = (unsigned char *) past->past_InputBuffer; inputBuffer = past->past_InputBuffer; if( past->past_Flags & paDitherOff ) { for( i=0; i<samplesPerBuffer; i++ ) { inBufPtr[i] = ((unsigned char)(nativeInputBuffer[i] >> 8)) + 0x80; } } else { /* If you dither then you have to clip because dithering could push the signal out of range! */ for( i=0; i<samplesPerBuffer; i++ ) { temp = nativeInputBuffer[i]; temp += Pa_TriangularDither() >> 7; temp = ((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp)); inBufPtr[i] = (unsigned char)(temp + 0x80); } } break; } default: break; } }#endif /* SUPPORT_AUDIO_CAPTURE */ /* 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 == paInt16) ? 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. */ if( outputBuffer != NULL ) { unsigned int samplesPerBuffer = past->past_FramesPerUserBuffer * past->past_NumOutputChannels; switch(past->past_OutputSampleFormat) { case paFloat32: { float *outBufPtr = (float *) past->past_OutputBuffer; if( past->past_Flags & paDitherOff ) { if( past->past_Flags & paClipOff ) /* NOTHING */ { for( i=0; i<samplesPerBuffer; i++ ) { *nativeOutputBuffer++ = (short) (outBufPtr[i] * (32767.0f)); } } else /* CLIP */ { for( i=0; i<samplesPerBuffer; i++ ) { temp = (long)(outBufPtr[i] * 32767.0f); *nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp)); } } } else { /* If you dither then you have to clip because dithering could push the signal out of range! */ for( i=0; i<samplesPerBuffer; i++ ) { float dither = Pa_TriangularDither()*DITHER_SCALE; float dithered = (outBufPtr[i] * (32767.0f)) + dither; temp = (long) (dithered); *nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp)); } } break; } case paInt32: { int *outBufPtr = (int *) past->past_OutputBuffer; if( past->past_Flags & paDitherOff ) { for( i=0; i<samplesPerBuffer; i++ ) { *nativeOutputBuffer++ = (short) (outBufPtr[i] >> 16 ); } } else { for( i=0; i<samplesPerBuffer; i++ ) { /* Shift one bit down before dithering so that we have room for overflow from add. */ temp = (outBufPtr[i] >> 1) + Pa_TriangularDither(); temp = temp >> 15; *nativeOutputBuffer++ = (short)((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp)); } } break; } case paInt8: { char *outBufPtr = (char *) past->past_OutputBuffer; for( i=0; i<samplesPerBuffer; i++ ) { *nativeOutputBuffer++ = ((short)outBufPtr[i]) << 8; } break; } case paUInt8: { unsigned char *outBufPtr = (unsigned char *) past->past_OutputBuffer; for( i=0; i<samplesPerBuffer; i++ ) { *nativeOutputBuffer++ = ((short)(outBufPtr[i] - 0x80)) << 8; } break; } default: break; } } 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;}/*************************************************************************/DLL_API PaError Pa_Initialize( void ){ if( gInitCount++ > 0 ) return paNoError; ResetTraceMessages(); return PaHost_Init();}DLL_API PaError Pa_Terminate( void ){ PaError result = paNoError; if( gInitCount == 0 ) return paNoError; else if( --gInitCount == 0 ) { result = PaHost_Term(); DumpTraceMessages(); } return result;}/*************************************************************************/DLL_API PaError Pa_GetSampleSize( PaSampleFormat format ){ int size; switch(format ) { case paUInt8: case paInt8: size = 1; break; case paInt16: size = 2; break; case paPackedInt24: size = 3; break; case paFloat32: case paInt32: case paInt24: size = 4; break; default: size = paSampleFormatNotSupported; break; } return (PaError) size;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -