📄 pa_lib.c
字号:
if( result < 0 ) goto error; } if( past->past_NumInputChannels > 0 ) { result = PaHost_StopInput( past, abort ); DBUG(("Pa_StopStream: PaHost_StopInput returned = 0x%X.\n", result)); if( result != paNoError ) goto error; } if( past->past_NumOutputChannels > 0 ) { result = PaHost_StopOutput( past, abort ); DBUG(("Pa_StopStream: PaHost_StopOutput returned = 0x%X.\n", result)); if( result != paNoError ) goto error; }error: past->past_Usage = 0; past->past_IfLastExitValid = 0; return result;}/*************************************************************************/PaError Pa_StreamActive( PortAudioStream *stream ){ internalPortAudioStream *past; if( stream == NULL ) return paBadStreamPtr; past = (internalPortAudioStream *) stream; return PaHost_StreamActive( past );}/*************************************************************************/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; case paDeviceUnavailable: msg = "Device Unavailable."; 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.*/double Pa_GetCPULoad( PortAudioStream* stream){ internalPortAudioStream *past; if( stream == NULL ) return (double) paBadStreamPtr; past = (internalPortAudioStream *) stream; return past->past_Usage;}/*************************************************************************/internalPortAudioStream* PaHost_GetStreamRepresentation( PortAudioStream *stream ){ internalPortAudioStream* result = (internalPortAudioStream*) stream; if( result == NULL || result->past_Magic != PA_MAGIC ) return NULL; else return result;}/*************************************************************** Calculate 2 LSB dither signal with a triangular distribution.** Ranged properly for adding to a 32 bit integer prior to >>15.** Range of output is +/- 32767*/#define PA_DITHER_BITS (15)#define PA_DITHER_SCALE (1.0f / ((1<<PA_DITHER_BITS)-1))long PaConvert_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. * Shift before adding to prevent overflow which would skew the distribution. * Also shift an extra bit for the high pass filter. */#define DITHER_SHIFT ((32 - PA_DITHER_BITS) + 1) current = (((long)randSeed1)>>DITHER_SHIFT) + (((long)randSeed2)>>DITHER_SHIFT); /* High pass filter to reduce audibility. */ highPass = current - previous; previous = current; 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; 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 += PaConvert_TriangularDither() >> 8; /* PLB20010820 */ 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 += PaConvert_TriangularDither() >> 8; /* PLB20010820 */ temp = ((temp < -0x8000) ? -0x8000 : ((temp > 0x7FFF) ? 0x7FFF : temp)); inBufPtr[i] = (unsigned char)((temp>>8) + 0x80); /* PLB20010820 */ } } 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 = PaConvert_TriangularDither()*PA_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) + PaConvert_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;}/*************************************************************************/PaError Pa_Initialize( void ){ if( gInitCount++ > 0 ) return paNoError; //ResetTraceMessages(); return PaHost_Init();}PaError Pa_Terminate( void ){ PaError result = paNoError; if( gInitCount == 0 ) return paNoError; else if( --gInitCount == 0 ) { result = PaHost_Term(); //DumpTraceMessages(); } return result;}int PaHost_IsInitialized(){ return gInitCount;}/*************************************************************************/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 + -