Update of /cvsroot/pure-data/pd/portaudio/pa_asio In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv8219/pa_asio
Modified Files: Tag: devel_0_38 pa_asio.cpp pa_asio.h Log Message: updating to latest portaudio snapshot
Index: pa_asio.cpp =================================================================== RCS file: /cvsroot/pure-data/pd/portaudio/pa_asio/pa_asio.cpp,v retrieving revision 1.3 retrieving revision 1.3.4.1 diff -C2 -d -r1.3 -r1.3.4.1 *** pa_asio.cpp 6 Sep 2004 21:03:00 -0000 1.3 --- pa_asio.cpp 28 Jun 2005 16:30:32 -0000 1.3.4.1 *************** *** 286,290 ****
/* the ASIO C API only allows one ASIO driver to be open at a time, ! so we kee track of whether we have the driver open here, and use this information to return errors from OpenStream if the driver is already open. --- 286,290 ----
/* the ASIO C API only allows one ASIO driver to be open at a time, ! so we keep track of whether we have the driver open here, and use this information to return errors from OpenStream if the driver is already open. *************** *** 365,368 **** --- 365,393 ---- }
+ void AsioSampleTypeLOG(ASIOSampleType type) + { + switch (type) { + case ASIOSTInt16MSB: PA_DEBUG(("ASIOSTInt16MSB\n")); break; + case ASIOSTInt16LSB: PA_DEBUG(("ASIOSTInt16LSB\n")); break; + case ASIOSTFloat32MSB:PA_DEBUG(("ASIOSTFloat32MSB\n"));break; + case ASIOSTFloat32LSB:PA_DEBUG(("ASIOSTFloat32LSB\n"));break; + case ASIOSTFloat64MSB:PA_DEBUG(("ASIOSTFloat64MSB\n"));break; + case ASIOSTFloat64LSB:PA_DEBUG(("ASIOSTFloat64LSB\n"));break; + case ASIOSTInt32MSB: PA_DEBUG(("ASIOSTInt32MSB\n")); break; + case ASIOSTInt32LSB: PA_DEBUG(("ASIOSTInt32LSB\n")); break; + case ASIOSTInt32MSB16:PA_DEBUG(("ASIOSTInt32MSB16\n"));break; + case ASIOSTInt32LSB16:PA_DEBUG(("ASIOSTInt32LSB16\n"));break; + case ASIOSTInt32MSB18:PA_DEBUG(("ASIOSTInt32MSB18\n"));break; + case ASIOSTInt32MSB20:PA_DEBUG(("ASIOSTInt32MSB20\n"));break; + case ASIOSTInt32MSB24:PA_DEBUG(("ASIOSTInt32MSB24\n"));break; + case ASIOSTInt32LSB18:PA_DEBUG(("ASIOSTInt32LSB18\n"));break; + case ASIOSTInt32LSB20:PA_DEBUG(("ASIOSTInt32LSB20\n"));break; + case ASIOSTInt32LSB24:PA_DEBUG(("ASIOSTInt32LSB24\n"));break; + case ASIOSTInt24MSB: PA_DEBUG(("ASIOSTInt24MSB\n")); break; + case ASIOSTInt24LSB: PA_DEBUG(("ASIOSTInt24LSB\n")); break; + default: PA_DEBUG(("Custom Format%d\n",type));break; + + } + }
static int BytesPerAsioSample( ASIOSampleType sampleType ) *************** *** 868,871 **** --- 893,898 ---- long preferredBufferSize; long bufferGranularity; + + ASIOChannelInfo *asioChannelInfos; } PaAsioDeviceInfo; *************** *** 971,975 **** 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, 96000.0, 8000.0 };
--- 998,1002 ---- 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 };
*************** *** 982,986 **** char **names; PaAsioDriverInfo paAsioDriverInfo; - ASIOChannelInfo asioChannelInfo;
asioHostApi = (PaAsioHostApiRepresentation*)PaUtil_AllocateMemory( sizeof(PaAsioHostApiRepresentation) ); --- 1009,1012 ---- *************** *** 1067,1077 **** deviceInfo->name = names[i]; PA_DEBUG(("PaAsio_Initialize: drv:%d name = %s\n", i,deviceInfo->name));
deviceInfo->maxInputChannels = paAsioDriverInfo.inputChannelCount; deviceInfo->maxOutputChannels = paAsioDriverInfo.outputChannelCount;
- PA_DEBUG(("PaAsio_Initialize: drv:%d inputChannels = %d\n", i, paAsioDriverInfo.inputChannelCount)); - PA_DEBUG(("PaAsio_Initialize: drv:%d outputChannels = %d\n", i, paAsioDriverInfo.outputChannelCount)); - deviceInfo->defaultSampleRate = 0.; bool foundDefaultSampleRate = false; --- 1093,1106 ---- 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));
deviceInfo->maxInputChannels = paAsioDriverInfo.inputChannelCount; deviceInfo->maxOutputChannels = paAsioDriverInfo.outputChannelCount;
deviceInfo->defaultSampleRate = 0.; bool foundDefaultSampleRate = false; *************** *** 1139,1146 ****
! /* We assume that all channels have the same SampleType, so check the first, FIXME, probably shouldn't assume that */ ! asioChannelInfo.channel = 0; ! asioChannelInfo.isInput = 1; ! ASIOGetChannelInfo( &asioChannelInfo ); /* FIXME, check return code */
--- 1168,1207 ----
! asioDeviceInfo->asioChannelInfos = (ASIOChannelInfo*)PaUtil_GroupAllocateMemory( ! asioHostApi->allocations, ! sizeof(ASIOChannelInfo) * (deviceInfo->maxInputChannels ! + deviceInfo->maxOutputChannels) ); ! if( !asioDeviceInfo->asioChannelInfos ) ! { ! result = paInsufficientMemory; ! goto error; ! } ! ! int a; ! ! for( a=0; a < deviceInfo->maxInputChannels; ++a ){ ! asioDeviceInfo->asioChannelInfos[a].channel = a; ! asioDeviceInfo->asioChannelInfos[a].isInput = ASIOTrue; ! ASIOError asioError = ASIOGetChannelInfo( &asioDeviceInfo->asioChannelInfos[a] ); ! if( asioError != ASE_OK ) ! { ! result = paUnanticipatedHostError; ! PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); ! goto error; ! } ! } ! ! for( a=0; a < deviceInfo->maxOutputChannels; ++a ){ ! int b = deviceInfo->maxInputChannels + a; ! asioDeviceInfo->asioChannelInfos[b].channel = a; ! asioDeviceInfo->asioChannelInfos[b].isInput = ASIOFalse; ! ASIOError asioError = ASIOGetChannelInfo( &asioDeviceInfo->asioChannelInfos[b] ); ! if( asioError != ASE_OK ) ! { ! result = paUnanticipatedHostError; ! PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); ! goto error; ! } ! }
*************** *** 1257,1262 ****
/* validate inputStreamInfo */ ! if( inputParameters->hostApiSpecificStreamInfo ) ! return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else --- 1318,1324 ----
/* validate inputStreamInfo */ ! /** @todo do more validation here */ ! // if( inputParameters->hostApiSpecificStreamInfo ) ! // return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else *************** *** 1284,1289 ****
/* validate outputStreamInfo */ ! if( outputParameters->hostApiSpecificStreamInfo ) ! return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else --- 1346,1352 ----
/* validate outputStreamInfo */ ! /** @todo do more validation here */ ! // if( outputParameters->hostApiSpecificStreamInfo ) ! // return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else *************** *** 1448,1452 ****
while( result < suggestedLatencyFrames ) ! result *= result;
if( result < (unsigned long)driverInfo->bufferMinSize ) --- 1511,1515 ----
while( result < suggestedLatencyFrames ) ! result *= 2;
if( result < (unsigned long)driverInfo->bufferMinSize ) *************** *** 1492,1495 **** --- 1555,1592 ----
+ /* returns channelSelectors if present */ + + static PaError ValidateAsioSpecificStreamInfo( + const PaStreamParameters *streamParameters, + const PaAsioStreamInfo *streamInfo, + int deviceChannelCount, + int **channelSelectors ) + { + if( streamInfo ) + { + if( streamInfo->size != sizeof( PaAsioStreamInfo ) + || streamInfo->version != 1 ) + { + return paIncompatibleHostApiSpecificStreamInfo; + } + + if( streamInfo->flags & paAsioUseChannelSelectors ) + *channelSelectors = streamInfo->channelSelectors; + + if( !(*channelSelectors) ) + return paIncompatibleHostApiSpecificStreamInfo; + + for( int i=0; i < streamParameters->channelCount; ++i ){ + if( (*channelSelectors)[i] < 0 + || (*channelSelectors)[i] >= deviceChannelCount ){ + return paInvalidChannelCount; + } + } + } + + return paNoError; + } + + /* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */
*************** *** 1507,1510 **** --- 1604,1608 ---- PaAsioHostApiRepresentation *asioHostApi = (PaAsioHostApiRepresentation*)hostApi; PaAsioStream *stream = 0; + PaAsioStreamInfo *inputStreamInfo, *outputStreamInfo; unsigned long framesPerHostBuffer; int inputChannelCount, outputChannelCount; *************** *** 1520,1528 **** int i; PaAsioDriverInfo *driverInfo;
/* unless we move to using lower level ASIO calls, we can only have one device open at a time */ ! if( asioHostApi->openAsioDeviceIndex != paNoDevice ) return paDeviceUnavailable;
if( inputParameters && outputParameters ) --- 1618,1630 ---- int i; PaAsioDriverInfo *driverInfo; + int *inputChannelSelectors = 0; + int *outputChannelSelectors = 0;
/* unless we move to using lower level ASIO calls, we can only have one device open at a time */ ! if( asioHostApi->openAsioDeviceIndex != paNoDevice ){ ! PA_DEBUG(("OpenStream paDeviceUnavailable\n")); return paDeviceUnavailable; + }
if( inputParameters && outputParameters ) *************** *** 1530,1536 **** /* full duplex ASIO stream must use the same device for input and output */
! if( inputParameters->device != outputParameters->device ) return paBadIODeviceCombination; }
if( inputParameters ) --- 1632,1640 ---- /* full duplex ASIO stream must use the same device for input and output */
! if( inputParameters->device != outputParameters->device ){ ! PA_DEBUG(("OpenStream paBadIODeviceCombination\n")); return paBadIODeviceCombination; } + }
if( inputParameters ) *************** *** 1538,1544 **** inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; ! suggestedInputLatencyFrames = (unsigned long)(inputParameters->suggestedLatency * sampleRate); ! ! asioDeviceIndex = inputParameters->device;
/* unless alternate device specification is supported, reject the use of --- 1642,1646 ---- inputChannelCount = inputParameters->channelCount; inputSampleFormat = inputParameters->sampleFormat; ! suggestedInputLatencyFrames = (unsigned long)((inputParameters->suggestedLatency * sampleRate)+0.5f);
/* unless alternate device specification is supported, reject the use of *************** *** 1547,1553 **** return paInvalidDevice;
/* validate hostApiSpecificStreamInfo */ ! if( inputParameters->hostApiSpecificStreamInfo ) ! return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else --- 1649,1663 ---- return paInvalidDevice;
+ asioDeviceIndex = inputParameters->device; + + PaAsioDeviceInfo *asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[asioDeviceIndex]; + /* validate hostApiSpecificStreamInfo */ ! inputStreamInfo = (PaAsioStreamInfo*)inputParameters->hostApiSpecificStreamInfo; ! result = ValidateAsioSpecificStreamInfo( inputParameters, inputStreamInfo, ! asioDeviceInfo->commonDeviceInfo.maxInputChannels, ! &inputChannelSelectors ! ); ! if( result != paNoError ) return result; } else *************** *** 1562,1568 **** outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; ! suggestedOutputLatencyFrames = (unsigned long)(outputParameters->suggestedLatency * sampleRate); ! ! asioDeviceIndex = outputParameters->device;
/* unless alternate device specification is supported, reject the use of --- 1672,1676 ---- outputChannelCount = outputParameters->channelCount; outputSampleFormat = outputParameters->sampleFormat; ! suggestedOutputLatencyFrames = (unsigned long)((outputParameters->suggestedLatency * sampleRate)+0.5f);
/* unless alternate device specification is supported, reject the use of *************** *** 1571,1577 **** return paInvalidDevice;
/* validate hostApiSpecificStreamInfo */ ! if( outputParameters->hostApiSpecificStreamInfo ) ! return paIncompatibleHostApiSpecificStreamInfo; /* this implementation doesn't use custom stream info */ } else --- 1679,1693 ---- return paInvalidDevice;
+ asioDeviceIndex = outputParameters->device; + + PaAsioDeviceInfo *asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[asioDeviceIndex]; + /* validate hostApiSpecificStreamInfo */ ! outputStreamInfo = (PaAsioStreamInfo*)outputParameters->hostApiSpecificStreamInfo; ! result = ValidateAsioSpecificStreamInfo( outputParameters, outputStreamInfo, ! asioDeviceInfo->commonDeviceInfo.maxOutputChannels, ! &outputChannelSelectors ! ); ! if( result != paNoError ) return result; } else *************** *** 1591,1596 **** if( result == paNoError ) asioIsInitialized = 1; ! else goto error;
/* check that input device can support inputChannelCount */ --- 1707,1714 ---- if( result == paNoError ) asioIsInitialized = 1; ! else{ ! PA_DEBUG(("OpenStream ERROR1\n")); goto error; + }
/* check that input device can support inputChannelCount */ *************** *** 1600,1603 **** --- 1718,1722 ---- { result = paInvalidChannelCount; + PA_DEBUG(("OpenStream ERROR2\n")); goto error; } *************** *** 1610,1624 **** { result = paInvalidChannelCount; goto error; } }
/* Set sample rate */ ! if( ASIOSetSampleRate( sampleRate ) != ASE_OK ) { result = paInvalidSampleRate; goto error; } ! /* IMPLEMENT ME: --- 1729,1747 ---- { result = paInvalidChannelCount; + PA_DEBUG(("OpenStream ERROR3\n")); goto error; } }
+ PA_DEBUG(("before ASIOSetSampleRate(%f)\n",sampleRate)); + asioError = ASIOSetSampleRate( sampleRate ); /* Set sample rate */ ! if( asioError != ASE_OK ) { result = paInvalidSampleRate; + PA_DEBUG(("ERROR: ASIOSetSampleRate: %s\n", PaAsio_GetAsioErrorText(asioError) )); goto error; } ! PA_DEBUG(("after ASIOSetSampleRate(%f)\n",sampleRate)); /* IMPLEMENT ME: *************** *** 1628,1633 ****
/* validate platform specific flags */ ! if( (streamFlags & paPlatformSpecificFlags) != 0 ) return paInvalidFlag; /* unexpected platform specific flag */
--- 1751,1758 ----
/* validate platform specific flags */ ! if( (streamFlags & paPlatformSpecificFlags) != 0 ){ ! PA_DEBUG(("OpenStream invalid flags!!\n")); return paInvalidFlag; /* unexpected platform specific flag */ + }
*************** *** 1636,1639 **** --- 1761,1765 ---- { result = paInsufficientMemory; + PA_DEBUG(("OpenStream ERROR5\n")); goto error; } *************** *** 1644,1647 **** --- 1770,1774 ---- result = paUnanticipatedHostError; PA_ASIO_SET_LAST_SYSTEM_ERROR( GetLastError() ); + PA_DEBUG(("OpenStream ERROR6\n")); goto error; } *************** *** 1673,1676 **** --- 1800,1804 ---- { result = paInsufficientMemory; + PA_DEBUG(("OpenStream ERROR7\n")); goto error; } *************** *** 1682,1686 ****
info->isInput = ASIOTrue; ! info->channelNum = i; info->buffers[0] = info->buffers[1] = 0; } --- 1810,1822 ----
info->isInput = ASIOTrue; ! ! if( inputChannelSelectors ){ ! // inputChannelSelectors values have already been validated in ! // ValidateAsioSpecificStreamInfo() above ! info->channelNum = inputChannelSelectors[i]; ! }else{ ! info->channelNum = i; ! } ! info->buffers[0] = info->buffers[1] = 0; } *************** *** 1690,1694 ****
info->isInput = ASIOFalse; ! info->channelNum = i; info->buffers[0] = info->buffers[1] = 0; } --- 1826,1838 ----
info->isInput = ASIOFalse; ! ! if( outputChannelSelectors ){ ! // outputChannelSelectors values have already been validated in ! // ValidateAsioSpecificStreamInfo() above ! info->channelNum = outputChannelSelectors[i]; ! }else{ ! info->channelNum = i; ! } ! info->buffers[0] = info->buffers[1] = 0; } *************** *** 1700,1703 **** --- 1844,1850 ---- driverInfo );
+ + PA_DEBUG(("PaAsioOpenStream: framesPerHostBuffer :%d\n", framesPerHostBuffer)); + asioError = ASIOCreateBuffers( stream->asioBufferInfos, inputChannelCount+outputChannelCount, *************** *** 1707,1710 **** --- 1854,1858 ---- && framesPerHostBuffer != (unsigned long)driverInfo->bufferPreferredSize ) { + PA_DEBUG(("ERROR: ASIOCreateBuffers: %s\n", PaAsio_GetAsioErrorText(asioError) )); /* Some buggy drivers (like the Hoontech DSP24) give incorrect *************** *** 1716,1719 **** --- 1864,1869 ---- framesPerHostBuffer = driverInfo->bufferPreferredSize;
+ PA_DEBUG(("PaAsioOpenStream: CORRECTED framesPerHostBuffer :%d\n", framesPerHostBuffer)); + ASIOError asioError2 = ASIOCreateBuffers( stream->asioBufferInfos, inputChannelCount+outputChannelCount, *************** *** 1727,1730 **** --- 1877,1881 ---- result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); + PA_DEBUG(("OpenStream ERROR9\n")); goto error; } *************** *** 1737,1740 **** --- 1888,1892 ---- { result = paInsufficientMemory; + PA_DEBUG(("OpenStream ERROR10\n")); goto error; } *************** *** 1749,1752 **** --- 1901,1905 ---- result = paUnanticipatedHostError; PA_ASIO_SET_LAST_ASIO_ERROR( asioError ); + PA_DEBUG(("OpenStream ERROR11\n")); goto error; } *************** *** 1758,1761 **** --- 1911,1915 ---- { result = paInsufficientMemory; + PA_DEBUG(("OpenStream ERROR12\n")); goto error; } *************** *** 1800,1803 **** --- 1954,1959 ---- ASIOSampleType inputType = stream->asioChannelInfos[0].type;
+ PA_DEBUG(("ASIO Input type:%d",inputType)); + AsioSampleTypeLOG(inputType); hostInputSampleFormat = AsioSampleTypeToPaNativeSampleFormat( inputType );
*************** *** 1815,1818 **** --- 1971,1976 ---- ASIOSampleType outputType = stream->asioChannelInfos[inputChannelCount].type;
+ PA_DEBUG(("ASIO Output type:%d",outputType)); + AsioSampleTypeLOG(outputType); hostOutputSampleFormat = AsioSampleTypeToPaNativeSampleFormat( outputType );
*************** *** 1831,1836 **** framesPerHostBuffer, paUtilFixedHostBufferSize, streamCallback, userData ); ! if( result != paNoError ) goto error;
--- 1989,1996 ---- framesPerHostBuffer, paUtilFixedHostBufferSize, streamCallback, userData ); ! if( result != paNoError ){ ! PA_DEBUG(("OpenStream ERROR13\n")); goto error; + }
*************** *** 1846,1856 ****
// the code below prints the ASIO latency which doesn't include the ! // buffer processor latency. ! PA_DEBUG(("PaAsio : ASIO InputLatency = %ld latency = %ld msec \n", stream->inputLatency, ! (long)((stream->inputLatency*1000)/ sampleRate))); ! PA_DEBUG(("PaAsio : ASIO OuputLatency = %ld latency = %ld msec \n", stream->outputLatency, ! (long)((stream->outputLatency*1000)/ sampleRate)));
stream->asioHostApi = asioHostApi; --- 2006,2023 ----
// the code below prints the ASIO latency which doesn't include the ! // buffer processor latency. it reports the added latency separately ! PA_DEBUG(("PaAsio : ASIO InputLatency = %ld (%ld ms), added buffProc:%ld (%ld ms)\n", stream->inputLatency, ! (long)((stream->inputLatency*1000)/ sampleRate), ! PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor), ! (long)((PaUtil_GetBufferProcessorInputLatency(&stream->bufferProcessor)*1000)/ sampleRate) ! )); ! ! PA_DEBUG(("PaAsio : ASIO OuputLatency = %ld (%ld ms), added buffProc:%ld (%ld ms)\n", stream->outputLatency, ! (long)((stream->outputLatency*1000)/ sampleRate), ! PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor), ! (long)((PaUtil_GetBufferProcessorOutputLatency(&stream->bufferProcessor)*1000)/ sampleRate) ! ));
stream->asioHostApi = asioHostApi; *************** *** 2130,2136 **** // clock as timeGetTime paTimeInfo.currentTime = (ASIO64toDouble( timeInfo->timeInfo.systemTime ) * .000000001); paTimeInfo.inputBufferAdcTime = paTimeInfo.currentTime - theAsioStream->streamRepresentation.streamInfo.inputLatency; paTimeInfo.outputBufferDacTime = paTimeInfo.currentTime + theAsioStream->streamRepresentation.streamInfo.outputLatency; ! #if 1 // detect underflows by checking inter-callback time > 2 buffer period --- 2297,2312 ---- // clock as timeGetTime paTimeInfo.currentTime = (ASIO64toDouble( timeInfo->timeInfo.systemTime ) * .000000001); + + /* patch from Paul Boege */ + paTimeInfo.inputBufferAdcTime = paTimeInfo.currentTime - + ((double)theAsioStream->inputLatency/theAsioStream->streamRepresentation.streamInfo.sampleRate); + + paTimeInfo.outputBufferDacTime = paTimeInfo.currentTime + + ((double)theAsioStream->outputLatency/theAsioStream->streamRepresentation.streamInfo.sampleRate); + + /* old version is buggy because the buffer processor also adds in its latency to the time parameters paTimeInfo.inputBufferAdcTime = paTimeInfo.currentTime - theAsioStream->streamRepresentation.streamInfo.inputLatency; paTimeInfo.outputBufferDacTime = paTimeInfo.currentTime + theAsioStream->streamRepresentation.streamInfo.outputLatency; ! */ #if 1 // detect underflows by checking inter-callback time > 2 buffer period *************** *** 2219,2223 **** theAsioStream->stopProcessing = true;
! if( PaUtil_IsBufferProcessorOuputEmpty( &theAsioStream->bufferProcessor ) ) { theAsioStream->zeroOutput = true; --- 2395,2399 ---- theAsioStream->stopProcessing = true;
! if( PaUtil_IsBufferProcessorOutputEmpty( &theAsioStream->bufferProcessor ) ) { theAsioStream->zeroOutput = true; *************** *** 2246,2249 **** --- 2422,2426 ----
(void) sRate; /* unused parameter */ + PA_DEBUG( ("sampleRateChanged : %d \n", sRate)); }
*************** *** 2257,2260 **** --- 2434,2439 ---- (void) opt;
+ PA_DEBUG( ("asioMessages : %d , %d \n", selector, value)); + switch(selector) { *************** *** 2655,2656 **** --- 2834,2901 ---- }
+ + PaError PaAsio_GetInputChannelName( PaDeviceIndex device, int channelIndex, + const char** channelName ) + { + PaError result = paNoError; + PaUtilHostApiRepresentation *hostApi; + PaDeviceIndex hostApiDevice; + PaAsioDeviceInfo *asioDeviceInfo; + + + result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO ); + if( result != paNoError ) + goto error; + + result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, device, hostApi ); + if( result != paNoError ) + goto error; + + asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[hostApiDevice]; + + if( channelIndex < 0 || channelIndex >= asioDeviceInfo->commonDeviceInfo.maxInputChannels ){ + result = paInvalidChannelCount; + goto error; + } + + *channelName = asioDeviceInfo->asioChannelInfos[channelIndex].name; + + return paNoError; + + error: + return result; + } + + + PaError PaAsio_GetOutputChannelName( PaDeviceIndex device, int channelIndex, + const char** channelName ) + { + PaError result = paNoError; + PaUtilHostApiRepresentation *hostApi; + PaDeviceIndex hostApiDevice; + PaAsioDeviceInfo *asioDeviceInfo; + + + result = PaUtil_GetHostApiRepresentation( &hostApi, paASIO ); + if( result != paNoError ) + goto error; + + result = PaUtil_DeviceIndexToHostApiDeviceIndex( &hostApiDevice, device, hostApi ); + if( result != paNoError ) + goto error; + + asioDeviceInfo = (PaAsioDeviceInfo*)hostApi->deviceInfos[hostApiDevice]; + + if( channelIndex < 0 || channelIndex >= asioDeviceInfo->commonDeviceInfo.maxOutputChannels ){ + result = paInvalidChannelCount; + goto error; + } + + *channelName = asioDeviceInfo->asioChannelInfos[ + asioDeviceInfo->commonDeviceInfo.maxInputChannels + channelIndex].name; + + return paNoError; + + error: + return result; + }
Index: pa_asio.h =================================================================== RCS file: /cvsroot/pure-data/pd/portaudio/pa_asio/pa_asio.h,v retrieving revision 1.3 retrieving revision 1.3.4.1 diff -C2 -d -r1.3 -r1.3.4.1 *** pa_asio.h 6 Sep 2004 21:03:01 -0000 1.3 --- pa_asio.h 28 Jun 2005 16:30:33 -0000 1.3.4.1 *************** *** 73,76 **** --- 73,119 ----
+ + + /** Retrieve a pointer to a string containing the name of the specified + input channel. The string is valid until Pa_Terminate is called. + + The string will be no longer than 32 characters including the null terminator. + */ + PaError PaAsio_GetInputChannelName( PaDeviceIndex device, int channelIndex, + const char** channelName ); + + + /** Retrieve a pointer to a string containing the name of the specified + input channel. The string is valid until Pa_Terminate is called. + + The string will be no longer than 32 characters including the null terminator. + */ + PaError PaAsio_GetOutputChannelName( PaDeviceIndex device, int channelIndex, + const char** channelName ); + + + #define paAsioUseChannelSelectors (0x01) + + typedef struct PaAsioStreamInfo{ + unsigned long size; /**< sizeof(PaAsioStreamInfo) */ + PaHostApiTypeId hostApiType; /**< paASIO */ + unsigned long version; /**< 1 */ + + unsigned long flags; + + /* Support for opening only specific channels of an ASIO device. + If the paAsioUseChannelSelectors flag is set, channelSelectors is a + pointer to an array of integers specifying the device channels to use. + When used, the length of the channelSelectors array must match the + corresponding channelCount parameter to Pa_OpenStream() otherwise a + crash may result. + The values in the selectors array must specify channels within the + range of supported channels for the device or paInvalidChannelCount will + result. + */ + int *channelSelectors; + }PaAsioStreamInfo; + + #ifdef __cplusplus }