📄 pa_asio.cpp
字号:
*converter = 0; switch (type) { case ASIOSTInt16MSB: /* src: paInt16, no conversion necessary, possible byte swap*/ #ifdef PA_LSB_IS_NATIVE_ *converter = Swap16; #endif break; case ASIOSTInt16LSB: /* src: paInt16, no conversion necessary, possible byte swap*/ #ifdef PA_MSB_IS_NATIVE_ *converter = Swap16; #endif break; case ASIOSTFloat32MSB: /* src: paFloat32, no conversion necessary, possible byte swap*/ #ifdef PA_LSB_IS_NATIVE_ *converter = Swap32; #endif break; case ASIOSTFloat32LSB: /* src: paFloat32, no conversion necessary, possible byte swap*/ #ifdef PA_MSB_IS_NATIVE_ *converter = Swap32; #endif break; case ASIOSTFloat64MSB: /* src: paFloat32, in-place conversion to/from float32, possible byte swap*/ #ifdef PA_LSB_IS_NATIVE_ *converter = ConvertFloat32ToFloat64Swap64; #else *converter = ConvertFloat32ToFloat64; #endif break; case ASIOSTFloat64LSB: /* src: paFloat32, in-place conversion to/from float32, possible byte swap*/ #ifdef PA_MSB_IS_NATIVE_ *converter = ConvertFloat32ToFloat64Swap64; #else *converter = ConvertFloat32ToFloat64; #endif break; case ASIOSTInt32MSB: /* src: paInt32, no conversion necessary, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = Swap32; #endif break; case ASIOSTInt32LSB: /* src: paInt32, no conversion necessary, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = Swap32; #endif break; case ASIOSTInt32MSB16: /* src: paInt32, 16 bit shift, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = ShiftRightSwap32; #else *converter = ShiftRight32; #endif *shift = 16; break; case ASIOSTInt32MSB18: /* src: paInt32, 14 bit shift, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = ShiftRightSwap32; #else *converter = ShiftRight32; #endif *shift = 14; break; case ASIOSTInt32MSB20: /* src: paInt32, 12 bit shift, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = ShiftRightSwap32; #else *converter = ShiftRight32; #endif *shift = 12; break; case ASIOSTInt32MSB24: /* src: paInt32, 8 bit shift, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = ShiftRightSwap32; #else *converter = ShiftRight32; #endif *shift = 8; break; case ASIOSTInt32LSB16: /* src: paInt32, 16 bit shift, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = ShiftRightSwap32; #else *converter = ShiftRight32; #endif *shift = 16; break; case ASIOSTInt32LSB18: /* src: paInt32, 14 bit shift, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = ShiftRightSwap32; #else *converter = ShiftRight32; #endif *shift = 14; break; case ASIOSTInt32LSB20: /* src: paInt32, 12 bit shift, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = ShiftRightSwap32; #else *converter = ShiftRight32; #endif *shift = 12; break; case ASIOSTInt32LSB24: /* src: paInt32, 8 bit shift, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = ShiftRightSwap32; #else *converter = ShiftRight32; #endif *shift = 8; break; case ASIOSTInt24MSB: /* src: paInt24, no conversion necessary, possible byte swap */ #ifdef PA_LSB_IS_NATIVE_ *converter = Swap24; #endif break; case ASIOSTInt24LSB: /* src: paInt24, no conversion necessary, possible byte swap */ #ifdef PA_MSB_IS_NATIVE_ *converter = Swap24; #endif break; }}typedef struct PaAsioDeviceInfo{ PaDeviceInfo commonDeviceInfo; long minBufferSize; long maxBufferSize; long preferredBufferSize; long bufferGranularity; ASIOChannelInfo *asioChannelInfos;}PaAsioDeviceInfo;PaError PaAsio_GetAvailableLatencyValues( PaDeviceIndex device, long *minLatency, long *maxLatency, long *preferredLatency, long *granularity ){ PaError result; PaUtilHostApiRepresentation *hostApi; PaDeviceIndex hostApiDevice; result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO ); if( result == paNoError ) { result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, device, hostApi ); if( result == paNoError ) { PaAsioDeviceInfo *asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[hostApiDevice]; *minLatency = asioDeviceInfo->minBufferSize; *maxLatency = asioDeviceInfo->maxBufferSize; *preferredLatency = asioDeviceInfo->preferredBufferSize; *granularity = asioDeviceInfo->bufferGranularity; } } return result;}/* load the asio driver named by <driverName> and return statistics about the driver in info. If no error occurred, the driver will remain open and must be closed by the called by calling ASIOExit() - if an error is returned the driver will already be closed.*/static PaError LoadAsioDriver( const char *driverName, PaAsioDriverInfo *driverInfo, void *systemSpecific ){ PaError result = paNoError; ASIOError asioError; int asioIsInitialized = 0; if( !loadAsioDriver( const_cast<char*>(driverName) ) ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_HOST_ERROR( 0, "Failed to load ASIO driver" ); goto error; } memset( &driverInfo->asioDriverInfo, 0, sizeof(ASIODriverInfo) ); driverInfo->asioDriverInfo.asioVersion = 2; driverInfo->asioDriverInfo.sysRef = systemSpecific; if( (asioError = ASIOInit( &driverInfo->asioDriverInfo )) != ASE_OK ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); goto error; } else { asioIsInitialized = 1; } if( (asioError = ASIOGetChannels(&driverInfo->inputChannelCount, &driverInfo->outputChannelCount)) != ASE_OK ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); goto error; } if( (asioError = ASIOGetBufferSize(&driverInfo->bufferMinSize, &driverInfo->bufferMaxSize, &driverInfo->bufferPreferredSize, &driverInfo->bufferGranularity)) != ASE_OK ) { result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); goto error; } if( ASIOOutputReady() == ASE_OK ) driverInfo->postOutput = true; else driverInfo->postOutput = false; return result;error: if( asioIsInitialized ) ASIOExit(); return result;}#define PA_DEFAULTSAMPLERATESEARCHORDER_COUNT_ 13 /* must be the same number of elements as in the array below */static ASIOSampleRate defaultSampleRateSearchOrder_[] = {44100.0, 48000.0, 32000.0, 24000.0, 22050.0, 88200.0, 96000.0, 192000.0, 16000.0, 12000.0, 11025.0, 9600.0, 8000.0 };PaError PaAsio_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ){ PaError result = paNoError; int i, driverCount; PaAsioHostApiRepresentation *asioHostApi; PaAsioDeviceInfo *deviceInfoArray; char **names; PaAsioDriverInfo paAsioDriverInfo; asioHostApi = (PaAsioHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaAsioHostApiRepresentation) ); if( !asioHostApi ) { result = paInsufficientMemory; goto error; } asioHostApi->allocations = PaUtil_CreateAllocationGroup(); if( !asioHostApi->allocations ) { result = paInsufficientMemory; goto error; } asioHostApi->systemSpecific = 0; asioHostApi->openAsioDeviceIndex = paNoDevice; *hostApi = &asioHostApi->inheritedHostApiRep; (*hostApi)->info.structVersion = 1; (*hostApi)->info.type = paASIO; (*hostApi)->info.name = "ASIO"; (*hostApi)->info.deviceCount = 0; #ifdef WINDOWS /* use desktop window as system specific ptr */ asioHostApi->systemSpecific = GetDesktopWindow(); CoInitialize(NULL); #endif /* MUST BE CHECKED : to force fragments loading on Mac */ loadAsioDriver( "dummy" ); /* driverCount is the number of installed drivers - not necessarily the number of installed physical devices. */ #if MAC driverCount = asioDrivers->getNumFragments(); #elif WINDOWS driverCount = asioDrivers->asioGetNumDev(); #endif if( driverCount > 0 ) { names = GetAsioDriverNames( asioHostApi->allocations, driverCount ); if( !names ) { result = paInsufficientMemory; goto error; } /* allocate enough space for all drivers, even if some aren't installed */ (*hostApi)->deviceInfos = (PaDeviceInfo**)PaUtil_GroupAllocateMemory( asioHostApi->allocations, sizeof(PaDeviceInfo*) * driverCount ); if( !(*hostApi)->deviceInfos ) { result = paInsufficientMemory; goto error; } /* allocate all device info structs in a contiguous block */ deviceInfoArray = (PaAsioDeviceInfo*)PaUtil_GroupAllocateMemory( asioHostApi->allocations, sizeof(PaAsioDeviceInfo) * driverCount ); if( !deviceInfoArray ) { result = paInsufficientMemory; goto error; } for( i=0; i < driverCount; ++i ) { PA_DEBUG(("ASIO names[%d]:%s\n",i,names[i])); // Since portaudio opens ALL ASIO drivers, and no one else does that, // we face fact that some drivers were not meant for it, drivers which act // like shells on top of REAL drivers, for instance. // so we get duplicate handles, locks and other problems. // so lets NOT try to load any such wrappers. // The ones i [davidv] know of so far are: if ( strcmp (names[i],"ASIO DirectX Full Duplex Driver") == 0 || strcmp (names[i],"ASIO Multimedia Driver") == 0 || strncmp(names[i],"Premiere",8) == 0 //"Premiere Elements Windows Sound 1.0" || strncmp(names[i],"Adobe",5) == 0 //"Adobe Default Windows Sound 1.5" || strncmp(names[i],"ReaRoute ASIO",13) == 0) //Reaper www.reaper.fm <- fix your stuff man. { PA_DEBUG(("BLACKLISTED!!!\n")); continue; } /* Attempt to load the asio driver... */ if( LoadAsioDriver( names[i], &paAsioDriverInfo, asioHostApi->systemSpecific ) == paNoError ) { PaAsioDeviceInfo *asioDeviceInfo = &deviceInfoArray[ (*hostApi)->info.deviceCount ]; PaDeviceInfo *deviceInfo = &asioDeviceInfo->commonDeviceInfo; deviceInfo->structVersion = 2; deviceInfo->hostApi = hostApiIndex; deviceInfo->name = names[i]; PA_DEBUG(("PaAsio_Initialize: drv:%d name = %s\n", i,deviceInfo->name)); PA_DEBUG(("PaAsio_Initialize: drv:%d inputChannels = %d\n", i, paAsioDriverInfo.inputChannelCount)); PA_DEBUG(("PaAsio_Initialize: drv:%d outputChannels = %d\n", i, paAsioDriverInfo.outputChannelCount)); PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMinSize = %d\n", i, paAsioDriverInfo.bufferMinSize)); PA_DEBUG(("PaAsio_Initialize: drv:%d bufferMaxSize = %d\n", i, paAsioDriverInfo.bufferMaxSize)); PA_DEBUG(("PaAsio_Initialize: drv:%d bufferPreferredSize = %d\n", i, paAsioDriverInfo.bufferPreferredSize)); PA_DEBUG(("PaAsio_Initialize: drv:%d bufferGranularity = %d\n", i, paAsioDriverInfo.bufferGranularity));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -