From fe8aa4ce5e8eebc1c6f762f4fc40328718a13e22 Mon Sep 17 00:00:00 2001 From: Miller Puckette Date: Sat, 31 Dec 2005 01:32:12 +0000 Subject: Deleted unused (?) files svn path=/trunk/; revision=4318 --- pd/portaudio_v18/pa_asio/pa_asio.cpp | 3096 ---------------------------------- 1 file changed, 3096 deletions(-) delete mode 100644 pd/portaudio_v18/pa_asio/pa_asio.cpp (limited to 'pd/portaudio_v18/pa_asio/pa_asio.cpp') diff --git a/pd/portaudio_v18/pa_asio/pa_asio.cpp b/pd/portaudio_v18/pa_asio/pa_asio.cpp deleted file mode 100644 index 717ee558..00000000 --- a/pd/portaudio_v18/pa_asio/pa_asio.cpp +++ /dev/null @@ -1,3096 +0,0 @@ -/* - * $Id: pa_asio.cpp,v 1.7.4.8 2003/08/14 06:44:25 stephane Exp $ - * Portable Audio I/O Library for ASIO Drivers - * - * Author: Stephane Letz - * Based on the Open Source API proposed by Ross Bencina - * Copyright (c) 2000-2001 Stephane Letz, Phil Burk - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files - * (the "Software"), to deal in the Software without restriction, - * including without limitation the rights to use, copy, modify, merge, - * publish, distribute, sublicense, and/or sell copies of the Software, - * and to permit persons to whom the Software is furnished to do so, - * subject to the following conditions: - * - * The above copyright notice and this permission notice shall be - * included in all copies or substantial portions of the Software. - * - * 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. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF - * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* Modification History - - 08-03-01 First version : Stephane Letz - 08-06-01 Tweaks for PC, use C++, buffer allocation, Float32 to Int32 conversion : Phil Burk - 08-20-01 More conversion, PA_StreamTime, Pa_GetHostError : Stephane Letz - 08-21-01 PaUInt8 bug correction, implementation of ASIOSTFloat32LSB and ASIOSTFloat32MSB native formats : Stephane Letz - 08-24-01 MAX_INT32_FP hack, another Uint8 fix : Stephane and Phil - 08-27-01 Implementation of hostBufferSize < userBufferSize case, better management of the ouput buffer when - the stream is stopped : Stephane Letz - 08-28-01 Check the stream pointer for null in bufferSwitchTimeInfo, correct bug in bufferSwitchTimeInfo when - the stream is stopped : Stephane Letz - 10-12-01 Correct the PaHost_CalcNumHostBuffers function: computes FramesPerHostBuffer to be the lowest that - respect requested FramesPerUserBuffer and userBuffersPerHostBuffer : Stephane Letz - 10-26-01 Management of hostBufferSize and userBufferSize of any size : Stephane Letz - 10-27-01 Improve calculus of hostBufferSize to be multiple or divisor of userBufferSize if possible : Stephane and Phil - 10-29-01 Change MAX_INT32_FP to (2147483520.0f) to prevent roundup to 0x80000000 : Phil Burk - 10-31-01 Clear the ouput buffer and user buffers in PaHost_StartOutput, correct bug in GetFirstMultiple : Stephane Letz - 11-06-01 Rename functions : Stephane Letz - 11-08-01 New Pa_ASIO_Adaptor_Init function to init Callback adpatation variables, cleanup of Pa_ASIO_Callback_Input: Stephane Letz - 11-29-01 Break apart device loading to debug random failure in Pa_ASIO_QueryDeviceInfo ; Phil Burk - 01-03-02 Desallocate all resources in PaHost_Term for cases where Pa_CloseStream is not called properly : Stephane Letz - 02-01-02 Cleanup, test of multiple-stream opening : Stephane Letz - 19-02-02 New Pa_ASIO_loadDriver that calls CoInitialize on each thread on Windows : Stephane Letz - 09-04-02 Correct error code management in PaHost_Term, removes various compiler warning : Stephane Letz - 12-04-02 Add Mac includes for and : Phil Burk - 13-04-02 Removes another compiler warning : Stephane Letz - 30-04-02 Pa_ASIO_QueryDeviceInfo bug correction, memory allocation checking, better error handling : D Viens, P Burk, S Letz - 01-12-02 Fix Pa_GetDefaultInputDeviceID and Pa_GetDefaultOuputDeviceID result when no driver are available : S Letz - 05-12-02 More debug messages : S Letz - 01-23-03 Increased max channels to 128. Fixed comparison of (OutputChannels > kMaxInputChannels) : P Burk - 02-17-03 Better termination handling : PaHost_CloseStream is called in PaHost_term is the the stream was not explicitely closed by the application : S Letz - 04-02-03 More robust ASIO driver buffer size initialization : some buggy drivers (like the Hoontech DSP24) give incorrect [min, preferred, max] values - They should work with the preferred size value, thus if Pa_ASIO_CreateBuffers fails with the hostBufferSize computed in PaHost_CalcNumHostBuffers, - we try again with the preferred size. Fix an old (never detected?) bug in the buffer adapdation code : S Letz - 30-06-03 The audio callback was not protected against reentrancy : some drivers (like the Hoontech DSP24) seems to cause this behaviour - that corrupted the buffer adapdation state and finally caused crashes. The reentrancy state is now checked in bufferSwitchTimeInfo : S Letz - 17-07-03 Correct bug in Pa_ASIO_Convert_Inter_Output : parameter past_InputSampleFormat was used instead of past_OutputSampleFormat : J Maillard, S Letz - 25-07-03 Use of atomic operations for reenterCounter management on Windows, need to be implemented on MacOS9 : S Letz - 14-08-03 OutTime value in the audio callback was not updated correctly : S Letz - - TO DO : - - - Check Pa_StopSteam and Pa_AbortStream - - Optimization for Input only or Ouput only (really necessary ??) -*/ - - -#include -#include -#include - -#include "portaudio.h" -#include "pa_host.h" -#include "pa_trace.h" - -#include "asiosys.h" -#include "asio.h" -#include "asiodrivers.h" - - -#if MAC -#include -#include -#include -#else -#include -#include -#include -#endif - -enum { - // number of input and outputs supported by the host application - // you can change these to higher or lower values - kMaxInputChannels = 128, - kMaxOutputChannels = 128 -}; - -/* ASIO specific device information. */ -typedef struct internalPortAudioDevice -{ - PaDeviceInfo pad_Info; -} internalPortAudioDevice; - - -/* ASIO driver internal data storage */ -typedef struct PaHostSoundControl -{ - // ASIOInit() - ASIODriverInfo pahsc_driverInfo; - - // ASIOGetChannels() - int32 pahsc_NumInputChannels; - int32 pahsc_NumOutputChannels; - - // ASIOGetBufferSize() - sizes in frames per buffer - int32 pahsc_minSize; - int32 pahsc_maxSize; - int32 pahsc_preferredSize; - int32 pahsc_granularity; - - // ASIOGetSampleRate() - ASIOSampleRate pahsc_sampleRate; - - // ASIOOutputReady() - bool pahsc_postOutput; - - // ASIOGetLatencies () - int32 pahsc_inputLatency; - int32 pahsc_outputLatency; - - // ASIOCreateBuffers () - ASIOBufferInfo bufferInfos[kMaxInputChannels + kMaxOutputChannels]; // buffer info's - - // ASIOGetChannelInfo() - ASIOChannelInfo pahsc_channelInfos[kMaxInputChannels + kMaxOutputChannels]; // channel info's - // The above two arrays share the same indexing, as the data in them are linked together - - // Information from ASIOGetSamplePosition() - // data is converted to double floats for easier use, however 64 bit integer can be used, too - double nanoSeconds; - double samples; - double tcSamples; // time code samples - - // bufferSwitchTimeInfo() - ASIOTime tInfo; // time info state - unsigned long sysRefTime; // system reference time, when bufferSwitch() was called - - // Signal the end of processing in this example - bool stopped; - - ASIOCallbacks pahsc_asioCallbacks; - - int32 pahsc_userInputBufferFrameOffset; // Position in Input user buffer - int32 pahsc_userOutputBufferFrameOffset; // Position in Output user buffer - int32 pahsc_hostOutputBufferFrameOffset; // Position in Output ASIO buffer - - int32 past_FramesPerHostBuffer; // Number of frames in ASIO buffer - - int32 pahsc_InputBufferOffset; // Number of null frames for input buffer alignement - int32 pahsc_OutputBufferOffset; // Number of null frames for ouput buffer alignement - -#if MAC - UInt64 pahsc_EntryCount; - UInt64 pahsc_LastExitCount; -#elif WINDOWS - LARGE_INTEGER pahsc_EntryCount; - LARGE_INTEGER pahsc_LastExitCount; -#endif - - PaTimestamp pahsc_NumFramesDone; - - internalPortAudioStream *past; - - int32 reenterCount; // Counter of audio callback reentrancy - int32 reenterError; // Counter of audio callback reentrancy detection - -} PaHostSoundControl; - - -//---------------------------------------------------------- -#define PRINT(x) { printf x; fflush(stdout); } -#define ERR_RPT(x) PRINT(x) - -#define DBUG(x) /* PRINT(x) */ -#define DBUGX(x) /* PRINT(x) */ - -/* We are trying to be compatible with CARBON but this has not been thoroughly tested. */ -#define CARBON_COMPATIBLE (0) -#define PA_MAX_DEVICE_INFO (32) - -#define MIN_INT8 (-0x80) -#define MAX_INT8 (0x7F) - -#define MIN_INT8_FP ((float)-0x80) -#define MAX_INT8_FP ((float)0x7F) - -#define MIN_INT16_FP ((float)-0x8000) -#define MAX_INT16_FP ((float)0x7FFF) - -#define MIN_INT16 (-0x8000) -#define MAX_INT16 (0x7FFF) - -#define MAX_INT32_FP (2147483520.0f) /* 0x0x7FFFFF80 - seems safe */ - -/************************************************************************************/ -/****************** Data ************************************************************/ -/************************************************************************************/ -static int sNumDevices = 0; -static internalPortAudioDevice sDevices[PA_MAX_DEVICE_INFO] = { 0 }; -static int32 sPaHostError = 0; -static int sDefaultOutputDeviceID = 0; -static int sDefaultInputDeviceID = 0; - -PaHostSoundControl asioDriverInfo = {0}; - -#ifdef MAC -static bool swap = true; -#elif WINDOWS -static bool swap = false; -#endif - -// Prototypes -static void bufferSwitch(long index, ASIOBool processNow); -static ASIOTime *bufferSwitchTimeInfo(ASIOTime *timeInfo, long index, ASIOBool processNow); -static void sampleRateChanged(ASIOSampleRate sRate); -static long asioMessages(long selector, long value, void* message, double* opt); -static void Pa_StartUsageCalculation( internalPortAudioStream *past ); -static void Pa_EndUsageCalculation( internalPortAudioStream *past ); - -static void Pa_ASIO_Convert_Inter_Input( - ASIOBufferInfo* nativeBuffer, - void* inputBuffer, - long NumInputChannels, - long NumOuputChannels, - long framePerBuffer, - long hostFrameOffset, - long userFrameOffset, - ASIOSampleType nativeFormat, - PaSampleFormat paFormat, - PaStreamFlags flags, - long index); - -static void Pa_ASIO_Convert_Inter_Output( - ASIOBufferInfo* nativeBuffer, - void* outputBuffer, - long NumInputChannels, - long NumOuputChannels, - long framePerBuffer, - long hostFrameOffset, - long userFrameOffset, - ASIOSampleType nativeFormat, - PaSampleFormat paFormat, - PaStreamFlags flags, - long index); - -static void Pa_ASIO_Clear_Output(ASIOBufferInfo* nativeBuffer, - ASIOSampleType nativeFormat, - long NumInputChannels, - long NumOuputChannels, - long index, - long hostFrameOffset, - long frames); - -static void Pa_ASIO_Callback_Input(long index); -static void Pa_ASIO_Callback_Output(long index, long framePerBuffer); -static void Pa_ASIO_Callback_End(); -static void Pa_ASIO_Clear_User_Buffers(); - -// Some external references -extern AsioDrivers* asioDrivers ; -bool loadAsioDriver(char *name); -unsigned long get_sys_reference_time(); - - -/************************************************************************************/ -/****************** Macro ************************************************************/ -/************************************************************************************/ - -#define SwapLong(v) ((((v)>>24)&0xFF)|(((v)>>8)&0xFF00)|(((v)&0xFF00)<<8)|(((v)&0xFF)<<24)) ; -#define SwapShort(v) ((((v)>>8)&0xFF)|(((v)&0xFF)<<8)) ; - -#define ClipShort(v) (((v)MAX_INT16)?MAX_INT16:(v))) -#define ClipChar(v) (((v)MAX_INT8)?MAX_INT8:(v))) -#define ClipFloat(v) (((v)<-1.0f)?-1.0f:(((v)>1.0f)?1.0f:(v))) - -#ifndef min -#define min(a,b) ((a)<(b)?(a):(b)) -#endif - -#ifndef max -#define max(a,b) ((a)>=(b)?(a):(b)) -#endif - -static bool Pa_ASIO_loadAsioDriver(char *name) -{ - #ifdef WINDOWS - CoInitialize(0); - #endif - return loadAsioDriver(name); -} - - -// Utilities for alignement buffer size computation -static int PGCD (int a, int b) {return (b == 0) ? a : PGCD (b,a%b);} -static int PPCM (int a, int b) {return (a*b) / PGCD (a,b);} - -// Takes the size of host buffer and user buffer : returns the number of frames needed for buffer adaptation -static int Pa_ASIO_CalcFrameShift (int M, int N) -{ - int res = 0; - for (int i = M; i < PPCM (M,N) ; i+=M) { res = max (res, i%N); } - return res; -} - -// We have the following relation : -// Pa_ASIO_CalcFrameShift (M,N) + M = Pa_ASIO_CalcFrameShift (N,M) + N - -/* ASIO sample type to PortAudio sample type conversion */ -static PaSampleFormat Pa_ASIO_Convert_SampleFormat(ASIOSampleType type) -{ - switch (type) { - - case ASIOSTInt16MSB: - case ASIOSTInt16LSB: - case ASIOSTInt32MSB16: - case ASIOSTInt32LSB16: - return paInt16; - - case ASIOSTFloat32MSB: - case ASIOSTFloat32LSB: - case ASIOSTFloat64MSB: - case ASIOSTFloat64LSB: - return paFloat32; - - case ASIOSTInt32MSB: - case ASIOSTInt32LSB: - case ASIOSTInt32MSB18: - case ASIOSTInt32MSB20: - case ASIOSTInt32MSB24: - case ASIOSTInt32LSB18: - case ASIOSTInt32LSB20: - case ASIOSTInt32LSB24: - return paInt32; - - case ASIOSTInt24MSB: - case ASIOSTInt24LSB: - return paInt24; - - default: - return paCustomFormat; - } -} - - - -//-------------------------------------------------------------------------------------------------------------------- -static void PaHost_CalcBufferOffset(internalPortAudioStream *past) -{ - if (asioDriverInfo.past_FramesPerHostBuffer > past->past_FramesPerUserBuffer){ - // Computes the MINIMUM value of null frames shift for the output buffer alignement - asioDriverInfo.pahsc_OutputBufferOffset = Pa_ASIO_CalcFrameShift (asioDriverInfo.past_FramesPerHostBuffer,past->past_FramesPerUserBuffer); - asioDriverInfo.pahsc_InputBufferOffset = 0; - DBUG(("PaHost_CalcBufferOffset : Minimum BufferOffset for Output = %d\n", asioDriverInfo.pahsc_OutputBufferOffset)); - }else{ - - //Computes the MINIMUM value of null frames shift for the input buffer alignement - asioDriverInfo.pahsc_InputBufferOffset = Pa_ASIO_CalcFrameShift (asioDriverInfo.past_FramesPerHostBuffer,past->past_FramesPerUserBuffer); - asioDriverInfo.pahsc_OutputBufferOffset = 0; - DBUG(("PaHost_CalcBufferOffset : Minimum BufferOffset for Input = %d\n", asioDriverInfo.pahsc_InputBufferOffset)); - } -} - -//-------------------------------------------------------------------------------------------------------------------- -/* Allocate ASIO buffers, initialise channels */ -static ASIOError Pa_ASIO_CreateBuffers (PaHostSoundControl *asioDriverInfo, long InputChannels, - long OutputChannels, long framesPerBuffer) -{ - ASIOError err; - int i; - - ASIOBufferInfo *info = asioDriverInfo->bufferInfos; - - // Check parameters - if ((InputChannels > kMaxInputChannels) || (OutputChannels > kMaxOutputChannels)) return ASE_InvalidParameter; - - for(i = 0; i < InputChannels; i++, info++){ - info->isInput = ASIOTrue; - info->channelNum = i; - info->buffers[0] = info->buffers[1] = 0; - } - - for(i = 0; i < OutputChannels; i++, info++){ - info->isInput = ASIOFalse; - info->channelNum = i; - info->buffers[0] = info->buffers[1] = 0; - } - - // Set up the asioCallback structure and create the ASIO data buffer - asioDriverInfo->pahsc_asioCallbacks.bufferSwitch = &bufferSwitch; - asioDriverInfo->pahsc_asioCallbacks.sampleRateDidChange = &sampleRateChanged; - asioDriverInfo->pahsc_asioCallbacks.asioMessage = &asioMessages; - asioDriverInfo->pahsc_asioCallbacks.bufferSwitchTimeInfo = &bufferSwitchTimeInfo; - - DBUG(("Pa_ASIO_CreateBuffers : ASIOCreateBuffers with inputChannels = %ld \n", InputChannels)); - DBUG(("Pa_ASIO_CreateBuffers : ASIOCreateBuffers with OutputChannels = %ld \n", OutputChannels)); - DBUG(("Pa_ASIO_CreateBuffers : ASIOCreateBuffers with size = %ld \n", framesPerBuffer)); - - err = ASIOCreateBuffers( asioDriverInfo->bufferInfos, InputChannels+OutputChannels, - framesPerBuffer, &asioDriverInfo->pahsc_asioCallbacks); - if (err != ASE_OK) return err; - - // Initialise buffers - for (i = 0; i < InputChannels + OutputChannels; i++) - { - asioDriverInfo->pahsc_channelInfos[i].channel = asioDriverInfo->bufferInfos[i].channelNum; - asioDriverInfo->pahsc_channelInfos[i].isInput = asioDriverInfo->bufferInfos[i].isInput; - err = ASIOGetChannelInfo(&asioDriverInfo->pahsc_channelInfos[i]); - if (err != ASE_OK) break; - } - - err = ASIOGetLatencies(&asioDriverInfo->pahsc_inputLatency, &asioDriverInfo->pahsc_outputLatency); - - DBUG(("Pa_ASIO_CreateBuffers : InputLatency = %ld latency = %ld msec \n", - asioDriverInfo->pahsc_inputLatency, - (long)((asioDriverInfo->pahsc_inputLatency*1000)/ asioDriverInfo->past->past_SampleRate))); - DBUG(("Pa_ASIO_CreateBuffers : OuputLatency = %ld latency = %ld msec \n", - asioDriverInfo->pahsc_outputLatency, - (long)((asioDriverInfo->pahsc_outputLatency*1000)/ asioDriverInfo->past->past_SampleRate))); - - return err; -} - - -/* - Query ASIO driver info : - - First we get all available ASIO drivers located in the ASIO folder, - then try to load each one. For each loaded driver, get all needed informations. -*/ -static PaError Pa_ASIO_QueryDeviceInfo( internalPortAudioDevice * ipad ) -{ - -#define NUM_STANDARDSAMPLINGRATES 3 /* 11.025, 22.05, 44.1 */ -#define NUM_CUSTOMSAMPLINGRATES 9 /* must be the same number of elements as in the array below */ -#define MAX_NUMSAMPLINGRATES (NUM_STANDARDSAMPLINGRATES+NUM_CUSTOMSAMPLINGRATES) - - ASIOSampleRate possibleSampleRates[] - = {8000.0, 9600.0, 11025.0, 12000.0, 16000.0, 22050.0, 24000.0, 32000.0, 44100.0, 48000.0, 88200.0, 96000.0}; - - ASIOChannelInfo channelInfos; - long InputChannels,OutputChannels; - double *sampleRates; - char* names[PA_MAX_DEVICE_INFO] ; - PaDeviceInfo *dev; - int i; - int numDrivers; - ASIOError asioError; - - /* Allocate names */ - for (i = 0 ; i < PA_MAX_DEVICE_INFO ; i++) { - names[i] = (char*)PaHost_AllocateFastMemory(32); - /* check memory */ - if(!names[i]) return paInsufficientMemory; - } - - /* MUST BE CHECKED : to force fragments loading on Mac */ - Pa_ASIO_loadAsioDriver("dummy"); - - /* Get names of all available ASIO drivers */ - asioDrivers->getDriverNames(names,PA_MAX_DEVICE_INFO); - - /* Check all available ASIO drivers */ -#if MAC - numDrivers = asioDrivers->getNumFragments(); -#elif WINDOWS - numDrivers = asioDrivers->asioGetNumDev(); -#endif - - DBUG(("PaASIO_QueryDeviceInfo: number of installed drivers = %d\n", numDrivers )); - - for (int driver = 0 ; driver < numDrivers ; driver++) - { - - #if WINDOWS - asioDriverInfo.pahsc_driverInfo.asioVersion = 2; // FIXME - is this right? PLB - asioDriverInfo.pahsc_driverInfo.sysRef = GetDesktopWindow(); // FIXME - is this right? PLB - #endif - - DBUG(("---------------------------------------\n")); - - DBUG(("PaASIO_QueryDeviceInfo: Driver name = %s\n", names[driver])); - - /* If the driver can be loaded : */ - if ( !Pa_ASIO_loadAsioDriver(names[driver]) ){ - DBUG(("PaASIO_QueryDeviceInfo could not loadAsioDriver %s\n", names[driver])); - } else { - - DBUG(("PaASIO_QueryDeviceInfo: loadAsioDriver OK\n")); - - if((asioError = ASIOInit(&asioDriverInfo.pahsc_driverInfo)) != ASE_OK){ - - DBUG(("PaASIO_QueryDeviceInfo: ASIOInit returned %d for %s\n", asioError, names[driver])); - - }else { - - DBUG(("PaASIO_QueryDeviceInfo: ASIOInit OK \n")); - - if(ASIOGetChannels(&InputChannels, &OutputChannels) != ASE_OK){ - - DBUG(("PaASIO_QueryDeviceInfo could not ASIOGetChannels for %s\n", names[driver])); - - }else { - - DBUG(("PaASIO_QueryDeviceInfo: ASIOGetChannels OK \n")); - - /* Gets the name */ - dev = &(ipad[sNumDevices].pad_Info); - dev->name = names[driver]; - names[driver] = 0; - - /* Gets Input and Output channels number */ - dev->maxInputChannels = InputChannels; - dev->maxOutputChannels = OutputChannels; - - DBUG(("PaASIO_QueryDeviceInfo: InputChannels = %d\n", InputChannels )); - DBUG(("PaASIO_QueryDeviceInfo: OutputChannels = %d\n", OutputChannels )); - - /* Make room in case device supports all rates. */ - sampleRates = (double*)PaHost_AllocateFastMemory(MAX_NUMSAMPLINGRATES * sizeof(double)); - /* check memory */ - if (!sampleRates) { - ASIOExit(); - return paInsufficientMemory; - } - dev->sampleRates = sampleRates; - dev->numSampleRates = 0; - - /* Loop through the possible sampling rates and check each to see if the device supports it. */ - for (int index = 0; index < MAX_NUMSAMPLINGRATES; index++) { - if (ASIOCanSampleRate(possibleSampleRates[index]) != ASE_NoClock) { - DBUG(("PaASIO_QueryDeviceInfo: possible sample rate = %d\n", (long)possibleSampleRates[index])); - dev->numSampleRates += 1; - *sampleRates = possibleSampleRates[index]; - sampleRates++; - } - } - - /* We assume that all channels have the same SampleType, so check the first */ - channelInfos.channel = 0; - channelInfos.isInput = 1; - - if ((asioError = ASIOGetChannelInfo(&channelInfos)) == ASE_NotPresent) { - DBUG(("PaASIO_QueryDeviceInfo: ASIOGetChannelInfo returned %d \n",asioError)); - } - - dev->nativeSampleFormats = Pa_ASIO_Convert_SampleFormat(channelInfos.type); - - /* unload the driver */ - if ((asioError = ASIOExit()) != ASE_OK) { - DBUG(("PaASIO_QueryDeviceInfo: ASIOExit returned %d \n",asioError)); - } - - sNumDevices++; - } - } - } - } - - /* free only unused names */ - for (i = 0 ; i < PA_MAX_DEVICE_INFO ; i++) if (names[i]) PaHost_FreeFastMemory(names[i],32); - - return paNoError; -} - -//---------------------------------------------------------------------------------- -// TAKEN FROM THE ASIO SDK: -void sampleRateChanged(ASIOSampleRate sRate) -{ - // do whatever you need to do if the sample rate changed - // usually this only happens during external sync. - // Audio processing is not stopped by the driver, actual sample rate - // might not have even changed, maybe only the sample rate status of an - // AES/EBU or S/PDIF digital input at the audio device. - // You might have to update time/sample related conversion routines, etc. -} - -//---------------------------------------------------------------------------------- -// TAKEN FROM THE ASIO SDK: -long asioMessages(long selector, long value, void* message, double* opt) -{ - // currently the parameters "value", "message" and "opt" are not used. - long ret = 0; - switch(selector) - { - case kAsioSelectorSupported: - if(value == kAsioResetRequest - || value == kAsioEngineVersion - || value == kAsioResyncRequest - || value == kAsioLatenciesChanged - // the following three were added for ASIO 2.0, you don't necessarily have to support them - || value == kAsioSupportsTimeInfo - || value == kAsioSupportsTimeCode - || value == kAsioSupportsInputMonitor) - ret = 1L; - break; - - case kAsioBufferSizeChange: - //printf("kAsioBufferSizeChange \n"); - break; - - case kAsioResetRequest: - // defer the task and perform the reset of the driver during the next "safe" situation - // You cannot reset the driver right now, as this code is called from the driver. - // Reset the driver is done by completely destruct is. I.e. ASIOStop(), ASIODisposeBuffers(), Destruction - // Afterwards you initialize the driver again. - asioDriverInfo.stopped; // In this sample the processing will just stop - ret = 1L; - break; - case kAsioResyncRequest: - // This informs the application, that the driver encountered some non fatal data loss. - // It is used for synchronization purposes of different media. - // Added mainly to work around the Win16Mutex problems in Windows 95/98 with the - // Windows Multimedia system, which could loose data because the Mutex was hold too long - // by another thread. - // However a driver can issue it in other situations, too. - ret = 1L; - break; - case kAsioLatenciesChanged: - // This will inform the host application that the drivers were latencies changed. - // Beware, it this does not mean that the buffer sizes have changed! - // You might need to update internal delay data. - ret = 1L; - //printf("kAsioLatenciesChanged \n"); - break; - case kAsioEngineVersion: - // return the supported ASIO version of the host application - // If a host applications does not implement this selector, ASIO 1.0 is assumed - // by the driver - ret = 2L; - break; - case kAsioSupportsTimeInfo: - // informs the driver wether the asioCallbacks.bufferSwitchTimeInfo() callback - // is supported. - // For compatibility with ASIO 1.0 drivers the host application should always support - // the "old" bufferSwitch method, too. - ret = 1; - break; - case kAsioSupportsTimeCode: - // informs the driver wether application is interested in time code info. - // If an application does not need to know about time code, the driver has less work - // to do. - ret = 0; - break; - } - return ret; -} - -//---------------------------------------------------------------------------------- -// Atomic increment and decrement operations -#if MAC - /* need to be implemented on Mac */ - inline long Pa_AtomicIncrement(long* v) {return ++(*v);} - inline long Pa_AtomicDecrement(long* v) {return --(*v);} -#elif WINDOWS - inline long Pa_AtomicIncrement(long* v) {return InterlockedIncrement(v);} - inline long Pa_AtomicDecrement(long* v) {return InterlockedDecrement(v);} -#endif - - -//---------------------------------------------------------------------------------- -// conversion from 64 bit ASIOSample/ASIOTimeStamp to double float -#if NATIVE_INT64 - #define ASIO64toDouble(a) (a) -#else - const double twoRaisedTo32 = 4294967296.; - #define ASIO64toDouble(a) ((a).lo + (a).hi * twoRaisedTo32) -#endif - - -static ASIOTime *bufferSwitchTimeInfo(ASIOTime *timeInfo, long index, ASIOBool processNow) -{ - // the actual processing callback. - // Beware that this is normally in a seperate thread, hence be sure that you take care - // about thread synchronization. This is omitted here for simplicity. - - // store the timeInfo for later use - asioDriverInfo.tInfo = *timeInfo; - - // get the time stamp of the buffer, not necessary if no - // synchronization to other media is required - - if (timeInfo->timeInfo.flags & kSystemTimeValid) - asioDriverInfo.nanoSeconds = ASIO64toDouble(timeInfo->timeInfo.systemTime); - else - asioDriverInfo.nanoSeconds = 0; - - if (timeInfo->timeInfo.flags & kSamplePositionValid) - asioDriverInfo.samples = ASIO64toDouble(timeInfo->timeInfo.samplePosition); - else - asioDriverInfo.samples = 0; - - if (timeInfo->timeCode.flags & kTcValid) - asioDriverInfo.tcSamples = ASIO64toDouble(timeInfo->timeCode.timeCodeSamples); - else - asioDriverInfo.tcSamples = 0; - - // get the system reference time - asioDriverInfo.sysRefTime = get_sys_reference_time(); - -#if 0 - // a few debug messages for the Windows device driver developer - // tells you the time when driver got its interrupt and the delay until the app receives - // the event notification. - static double last_samples = 0; - char tmp[128]; - sprintf (tmp, "diff: %d / %d ms / %d ms / %d samples \n", asioDriverInfo.sysRefTime - (long)(asioDriverInfo.nanoSeconds / 1000000.0), asioDriverInfo.sysRefTime, (long)(asioDriverInfo.nanoSeconds / 1000000.0), (long)(asioDriverInfo.samples - last_samples)); - OutputDebugString (tmp); - last_samples = asioDriverInfo.samples; -#endif - - // To avoid the callback accessing a desallocated stream - if (asioDriverInfo.past == NULL) return 0L; - - // Keep sample position - asioDriverInfo.pahsc_NumFramesDone = timeInfo->timeInfo.samplePosition.lo; - - // Reentrancy control - if(Pa_AtomicIncrement(&asioDriverInfo.reenterCount)) { - asioDriverInfo.reenterError++; - DBUG(("bufferSwitchTimeInfo : reentrancy detection = %d\n", asioDriverInfo.reenterError)); - return 0L; - } - - do { - - /* Has a user callback returned '1' to indicate finished at the last ASIO callback? */ - if( asioDriverInfo.past->past_StopSoon ) { - - Pa_ASIO_Clear_Output(asioDriverInfo.bufferInfos, - asioDriverInfo.pahsc_channelInfos[0].type, - asioDriverInfo.pahsc_NumInputChannels , - asioDriverInfo.pahsc_NumOutputChannels, - index, - 0, - asioDriverInfo.past_FramesPerHostBuffer); - - asioDriverInfo.past->past_IsActive = 0; - - // Finally if the driver supports the ASIOOutputReady() optimization, do it here, all data are in place - if (asioDriverInfo.pahsc_postOutput) ASIOOutputReady(); - - }else{ - - /* CPU usage */ - Pa_StartUsageCalculation(asioDriverInfo.past); - - Pa_ASIO_Callback_Input(index); - - // Finally if the driver supports the ASIOOutputReady() optimization, do it here, all data are in place - if (asioDriverInfo.pahsc_postOutput) ASIOOutputReady(); - - Pa_ASIO_Callback_End(); - - /* CPU usage */ - Pa_EndUsageCalculation(asioDriverInfo.past); - } - - } while(Pa_AtomicDecrement(&asioDriverInfo.reenterCount) >= 0); - - return 0L; -} - - -//---------------------------------------------------------------------------------- -void bufferSwitch(long index, ASIOBool processNow) -{ - // the actual processing callback. - // Beware that this is normally in a seperate thread, hence be sure that you take care - // about thread synchronization. This is omitted here for simplicity. - - // as this is a "back door" into the bufferSwitchTimeInfo a timeInfo needs to be created - // though it will only set the timeInfo.samplePosition and timeInfo.systemTime fields and the according flags - - ASIOTime timeInfo; - memset (&timeInfo, 0, sizeof (timeInfo)); - - // get the time stamp of the buffer, not necessary if no - // synchronization to other media is required - if(ASIOGetSamplePosition(&timeInfo.timeInfo.samplePosition, &timeInfo.timeInfo.systemTime) == ASE_OK) - timeInfo.timeInfo.flags = kSystemTimeValid | kSamplePositionValid; - - // Call the real callback - bufferSwitchTimeInfo (&timeInfo, index, processNow); -} - -//---------------------------------------------------------------------------------- -unsigned long get_sys_reference_time() -{ - // get the system reference time - #if WINDOWS - return timeGetTime(); - #elif MAC - static const double twoRaisedTo32 = 4294967296.; - UnsignedWide ys; - Microseconds(&ys); - double r = ((double)ys.hi * twoRaisedTo32 + (double)ys.lo); - return (unsigned long)(r / 1000.); - #endif -} - - -/************************************************************* -** 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<>(32-DITHER_BITS)) + (((long)randSeed2)>>(32-DITHER_BITS)); - /* High pass filter to reduce audibility. */ - highPass = current - previous; - previous = current; - return highPass; -} - -// TO BE COMPLETED WITH ALL SUPPORTED PA SAMPLE TYPES - -//------------------------------------------------------------------------------------------------------------------------------------------------------- -static void Input_Int16_Float32 (ASIOBufferInfo* nativeBuffer, float *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset, bool swap) -{ - long temp; - int i,j; - - for( j=0; j>16); - userBufPtr += NumInputChannels; - } - } - } - else - { - for( j=0; j> 1) + Pa_TriangularDither(); - temp = temp >> 15; - temp = (short) ClipShort(temp); - *userBufPtr = (short)temp; - userBufPtr += NumInputChannels; - } - } - - } -} - -//------------------------------------------------------------------------------------------------------------------------------------------------------- -// MUST BE TESTED -static void Input_Float32_Int16 (ASIOBufferInfo* nativeBuffer, short *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset,uint32 flags,bool swap) -{ - unsigned long temp; - int i,j; - - if( flags & paDitherOff ) - { - for( j=0; j>8); - userBufPtr += NumInputChannels; - } - } - } - else - { - for( j=0; j> 8; - temp = ClipShort(temp); - *userBufPtr = (char)(temp>>8); - userBufPtr += NumInputChannels; - } - } - } -} - -//------------------------------------------------------------------------------------------------------------------------------------------------------- -static void Input_Int32_Int8 (ASIOBufferInfo* nativeBuffer, char *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset, int userFrameOffset, uint32 flags,bool swap) -{ - long temp; - int i,j; - - if( flags & paDitherOff ) - { - for( j=0; j>24); - userBufPtr += NumInputChannels; - } - } - } - else - { - for( j=0; j>16; // Shift to get a 16 bit value, then use the 16 bits to 8 bits code (MUST BE CHECHED) - temp += Pa_TriangularDither() >> 8; - temp = ClipShort(temp); - *userBufPtr = (char)(temp >> 8); - userBufPtr += NumInputChannels; - } - } - } -} - -//------------------------------------------------------------------------------------------------------------------------------------------------------- -// MUST BE TESTED - -static void Input_Float32_Int8 (ASIOBufferInfo* nativeBuffer, char *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset, uint32 flags,bool swap) -{ - unsigned long temp; - int i,j; - - if( flags & paDitherOff ) - { - for( j=0; j>8) + 0x80); - userBufPtr += NumInputChannels; - } - } - } - else - { - for( j=0; j> 8; - temp = ClipShort(temp); - *userBufPtr = (unsigned char)((temp>>8) + 0x80); - userBufPtr += NumInputChannels; - } - } - } -} - -//------------------------------------------------------------------------------------------------------------------------------------------------------- -static void Input_Int32_IntU8 (ASIOBufferInfo* nativeBuffer, unsigned char *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset, int userFrameOffset,uint32 flags,bool swap) -{ - long temp; - int i,j; - - if( flags & paDitherOff ) - { - for( j=0; j>24) + 0x80); - userBufPtr += NumInputChannels; - } - } - } - else - { - for( j=0; j>16; // Shift to get a 16 bit value, then use the 16 bits to 8 bits code (MUST BE CHECHED) - temp += Pa_TriangularDither() >> 8; - temp = ClipShort(temp); - *userBufPtr = (unsigned char)((temp>>8) + 0x80); - userBufPtr += NumInputChannels; - } - } - } -} - -//------------------------------------------------------------------------------------------------------------------------------------------------------- -// MUST BE TESTED - -static void Input_Float32_IntU8 (ASIOBufferInfo* nativeBuffer, unsigned char *inBufPtr, int framePerBuffer, int NumInputChannels, int index, int hostFrameOffset,int userFrameOffset, uint32 flags,bool swap) -{ - unsigned long temp; - int i,j; - - if( flags & paDitherOff ) - { - for( j=0; j> 16); - if (swap) temp = SwapShort(temp); - asioBufPtr[i] = (short)temp; - userBufPtr += NumOuputChannels; - } - } - } - else - { - for (j= 0; j < NumOuputChannels; j++) - { - short *asioBufPtr = &((short*)nativeBuffer[j+NumInputChannels].buffers[index])[hostFrameOffset]; - long *userBufPtr = &outBufPtr[j+(userFrameOffset*NumOuputChannels)]; - for( i=0; i> 1) + Pa_TriangularDither(); - temp = temp >> 15; - temp = (short) ClipShort(temp); - if (swap) temp = SwapShort(temp); - asioBufPtr[i] = (short)temp; - userBufPtr += NumOuputChannels; - } - } - } -} - -//------------------------------------------------------------------------------------------------------------------------------------------------------- -static void Output_Int32_Int32(ASIOBufferInfo* nativeBuffer, long *outBufPtr, int framePerBuffer, int NumInputChannels, int NumOuputChannels, int index, int hostFrameOffset,int userFrameOffset,uint32 flags,bool swap) -{ - long temp; - int i,j; - - for (j= 0; j < NumOuputChannels; j++) - { - long *asioBufPtr = &((long*)nativeBuffer[j+NumInputChannels].buffers[index])[hostFrameOffset]; - long *userBufPtr = &outBufPtr[j+(userFrameOffset*NumOuputChannels)]; - for( i=0; ipast_FramesPerUserBuffer <= asioDriverInfo.past_FramesPerHostBuffer) { - asioDriverInfo.pahsc_hostOutputBufferFrameOffset = asioDriverInfo.pahsc_OutputBufferOffset; - asioDriverInfo.pahsc_userInputBufferFrameOffset = 0; // empty - asioDriverInfo.pahsc_userOutputBufferFrameOffset = asioDriverInfo.past->past_FramesPerUserBuffer; // empty - DBUG(("Pa_ASIO_Adaptor_Init : shift output\n")); - DBUG(("Pa_ASIO_Adaptor_Init : userInputBufferFrameOffset %d\n",asioDriverInfo.pahsc_userInputBufferFrameOffset)); - DBUG(("Pa_ASIO_Adaptor_Init : userOutputBufferFrameOffset %d\n",asioDriverInfo.pahsc_userOutputBufferFrameOffset)); - DBUG(("Pa_ASIO_Adaptor_Init : hostOutputBufferFrameOffset %d\n",asioDriverInfo.pahsc_hostOutputBufferFrameOffset)); - - }else { - asioDriverInfo.pahsc_hostOutputBufferFrameOffset = 0; // empty - asioDriverInfo.pahsc_userInputBufferFrameOffset = asioDriverInfo.pahsc_InputBufferOffset; - asioDriverInfo.pahsc_userOutputBufferFrameOffset = asioDriverInfo.past->past_FramesPerUserBuffer; // empty - DBUG(("Pa_ASIO_Adaptor_Init : shift input\n")); - DBUG(("Pa_ASIO_Adaptor_Init : userInputBufferFrameOffset %d\n",asioDriverInfo.pahsc_userInputBufferFrameOffset)); - DBUG(("Pa_ASIO_Adaptor_Init : userOutputBufferFrameOffset %d\n",asioDriverInfo.pahsc_userOutputBufferFrameOffset)); - DBUG(("Pa_ASIO_Adaptor_Init : hostOutputBufferFrameOffset %d\n",asioDriverInfo.pahsc_hostOutputBufferFrameOffset)); - } -} - -//------------------------------------------------------------------------------------------------------------------------------------------------------- -// FIXME : optimization for Input only or output only modes (really necessary ??) -static void Pa_ASIO_Callback_Input(long index) -{ - internalPortAudioStream *past = asioDriverInfo.past; - long framesInputHostBuffer = asioDriverInfo.past_FramesPerHostBuffer; // number of frames available into the host input buffer - long framesInputUserBuffer; // number of frames needed to complete the user input buffer - long framesOutputHostBuffer; // number of frames needed to complete the host output buffer - long framesOuputUserBuffer; // number of frames available into the user output buffer - long userResult; - long tmp; - - /* Fill host ASIO output with remaining frames in user output */ - framesOutputHostBuffer = asioDriverInfo.past_FramesPerHostBuffer - asioDriverInfo.pahsc_hostOutputBufferFrameOffset; - framesOuputUserBuffer = asioDriverInfo.past->past_FramesPerUserBuffer - asioDriverInfo.pahsc_userOutputBufferFrameOffset; - tmp = min(framesOutputHostBuffer, framesOuputUserBuffer); - framesOutputHostBuffer -= tmp; - Pa_ASIO_Callback_Output(index,tmp); - - /* Available frames in hostInputBuffer */ - while (framesInputHostBuffer > 0) { - - /* Number of frames needed to complete an user input buffer */ - framesInputUserBuffer = asioDriverInfo.past->past_FramesPerUserBuffer - asioDriverInfo.pahsc_userInputBufferFrameOffset; - - if (framesInputHostBuffer >= framesInputUserBuffer) { - - /* Convert ASIO input to user input */ - Pa_ASIO_Convert_Inter_Input (asioDriverInfo.bufferInfos, - past->past_InputBuffer, - asioDriverInfo.pahsc_NumInputChannels , - asioDriverInfo.pahsc_NumOutputChannels, - framesInputUserBuffer, - asioDriverInfo.past_FramesPerHostBuffer - framesInputHostBuffer, - asioDriverInfo.pahsc_userInputBufferFrameOffset, - asioDriverInfo.pahsc_channelInfos[0].type, - past->past_InputSampleFormat, - past->past_Flags, - index); - - /* Call PortAudio callback */ - userResult = asioDriverInfo.past->past_Callback(past->past_InputBuffer, past->past_OutputBuffer, - past->past_FramesPerUserBuffer,past->past_FrameCount,past->past_UserData ); - - past->past_FrameCount += (PaTimestamp) past->past_FramesPerUserBuffer; - - /* User callback has asked us to stop in the middle of the host buffer */ - if( userResult != 0) { - - /* Put 0 in the end of the output buffer */ - Pa_ASIO_Clear_Output(asioDriverInfo.bufferInfos, - asioDriverInfo.pahsc_channelInfos[0].type, - asioDriverInfo.pahsc_NumInputChannels , - asioDriverInfo.pahsc_NumOutputChannels, - index, - asioDriverInfo.pahsc_hostOutputBufferFrameOffset, - asioDriverInfo.past_FramesPerHostBuffer - asioDriverInfo.pahsc_hostOutputBufferFrameOffset); - - past->past_StopSoon = 1; - return; - } - - - /* Full user ouput buffer : write offset */ - asioDriverInfo.pahsc_userOutputBufferFrameOffset = 0; - - /* Empty user input buffer : read offset */ - asioDriverInfo.pahsc_userInputBufferFrameOffset = 0; - - /* Fill host ASIO output */ - tmp = min (past->past_FramesPerUserBuffer,framesOutputHostBuffer); - Pa_ASIO_Callback_Output(index,tmp); - - framesOutputHostBuffer -= tmp; - framesInputHostBuffer -= framesInputUserBuffer; - - }else { - - /* Convert ASIO input to user input */ - Pa_ASIO_Convert_Inter_Input (asioDriverInfo.bufferInfos, - past->past_InputBuffer, - asioDriverInfo.pahsc_NumInputChannels , - asioDriverInfo.pahsc_NumOutputChannels, - framesInputHostBuffer, - asioDriverInfo.past_FramesPerHostBuffer - framesInputHostBuffer, - asioDriverInfo.pahsc_userInputBufferFrameOffset, - asioDriverInfo.pahsc_channelInfos[0].type, - past->past_InputSampleFormat, - past->past_Flags, - index); - - /* Update pahsc_userInputBufferFrameOffset */ - asioDriverInfo.pahsc_userInputBufferFrameOffset += framesInputHostBuffer; - - /* Update framesInputHostBuffer */ - framesInputHostBuffer = 0; - } - } - -} - -//------------------------------------------------------------------------------------------------------------------------------------------------------- -static void Pa_ASIO_Callback_Output(long index, long framePerBuffer) -{ - internalPortAudioStream *past = asioDriverInfo.past; - - if (framePerBuffer > 0) { - - /* Convert user output to ASIO ouput */ - Pa_ASIO_Convert_Inter_Output (asioDriverInfo.bufferInfos, - past->past_OutputBuffer, - asioDriverInfo.pahsc_NumInputChannels, - asioDriverInfo.pahsc_NumOutputChannels, - framePerBuffer, - asioDriverInfo.pahsc_hostOutputBufferFrameOffset, - asioDriverInfo.pahsc_userOutputBufferFrameOffset, - asioDriverInfo.pahsc_channelInfos[0].type, - past->past_OutputSampleFormat, - past->past_Flags, - index); - - /* Update hostOuputFrameOffset */ - asioDriverInfo.pahsc_hostOutputBufferFrameOffset += framePerBuffer; - - /* Update userOutputFrameOffset */ - asioDriverInfo.pahsc_userOutputBufferFrameOffset += framePerBuffer; - } -} -//------------------------------------------------------------------------------------------------------------------------------------------------------- -static void Pa_ASIO_Callback_End() - { - /* Empty ASIO ouput : write offset */ - asioDriverInfo.pahsc_hostOutputBufferFrameOffset = 0; - } - -//------------------------------------------------------------------------------------------------------------------------------------------------------- -static void Pa_ASIO_Clear_User_Buffers() -{ - if( asioDriverInfo.past->past_InputBuffer != NULL ) - { - memset( asioDriverInfo.past->past_InputBuffer, 0, asioDriverInfo.past->past_InputBufferSize ); - } - if( asioDriverInfo.past->past_OutputBuffer != NULL ) - { - memset( asioDriverInfo.past->past_OutputBuffer, 0, asioDriverInfo.past->past_OutputBufferSize ); - } -} - -//------------------------------------------------------------------------------------------------------------------------------------------------------- - static void Pa_ASIO_Clear_Output(ASIOBufferInfo* nativeBuffer, - ASIOSampleType nativeFormat, - long NumInputChannels, - long NumOuputChannels, - long index, - long hostFrameOffset, - long frames) -{ - - switch (nativeFormat) { - - case ASIOSTInt16MSB: - case ASIOSTInt16LSB: - case ASIOSTInt32MSB16: - case ASIOSTInt32LSB16: - Pa_ASIO_Clear_Output_16(nativeBuffer, frames, NumInputChannels, NumOuputChannels, index, hostFrameOffset); - break; - - case ASIOSTFloat64MSB: - case ASIOSTFloat64LSB: - break; - - case ASIOSTFloat32MSB: - case ASIOSTFloat32LSB: - case ASIOSTInt32MSB: - case ASIOSTInt32LSB: - case ASIOSTInt32MSB18: - case ASIOSTInt32MSB20: - case ASIOSTInt32MSB24: - case ASIOSTInt32LSB18: - case ASIOSTInt32LSB20: - case ASIOSTInt32LSB24: - Pa_ASIO_Clear_Output_32(nativeBuffer, frames, NumInputChannels, NumOuputChannels, index, hostFrameOffset); - break; - - case ASIOSTInt24MSB: - case ASIOSTInt24LSB: - break; - - default: - break; - } -} - - -//--------------------------------------------------------------------------------------- -static void Pa_ASIO_Convert_Inter_Input( - ASIOBufferInfo* nativeBuffer, - void* inputBuffer, - long NumInputChannels, - long NumOuputChannels, - long framePerBuffer, - long hostFrameOffset, - long userFrameOffset, - ASIOSampleType nativeFormat, - PaSampleFormat paFormat, - PaStreamFlags flags, - long index) -{ - - if((NumInputChannels > 0) && (nativeBuffer != NULL)) - { - /* Convert from native format to PA format. */ - switch(paFormat) - { - case paFloat32: - { - float *inBufPtr = (float *) inputBuffer; - - switch (nativeFormat) { - case ASIOSTInt16LSB: - Input_Int16_Float32(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset, userFrameOffset, swap); - break; - case ASIOSTInt16MSB: - Input_Int16_Float32(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset, userFrameOffset,!swap); - break; - case ASIOSTInt32LSB: - Input_Int32_Float32(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset, userFrameOffset,swap); - break; - case ASIOSTInt32MSB: - Input_Int32_Float32(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset, userFrameOffset,!swap); - break; - case ASIOSTFloat32LSB: // IEEE 754 32 bit float, as found on Intel x86 architecture - Input_Float32_Float32(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset, userFrameOffset,swap); - break; - case ASIOSTFloat32MSB: // IEEE 754 32 bit float, as found on Intel x86 architecture - Input_Float32_Float32(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset, userFrameOffset,!swap); - break; - - case ASIOSTInt24LSB: // used for 20 bits as well - case ASIOSTInt24MSB: // used for 20 bits as well - - case ASIOSTFloat64LSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture - case ASIOSTFloat64MSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture - - // these are used for 32 bit data buffer, with different alignment of the data inside - // 32 bit PCI bus systems can more easily used with these - - case ASIOSTInt32LSB16: // 32 bit data with 16 bit alignment - case ASIOSTInt32LSB18: // 32 bit data with 18 bit alignment - case ASIOSTInt32LSB20: // 32 bit data with 20 bit alignment - case ASIOSTInt32LSB24: // 32 bit data with 24 bit alignment - - - case ASIOSTInt32MSB16: // 32 bit data with 16 bit alignment - case ASIOSTInt32MSB18: // 32 bit data with 18 bit alignment - case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment - case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment - DBUG(("Not yet implemented : please report the problem\n")); - break; - } - - break; - } - - case paInt32: - { - long *inBufPtr = (long *)inputBuffer; - - switch (nativeFormat) { - case ASIOSTInt16LSB: - Input_Int16_Int32(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset,userFrameOffset, swap); - break; - case ASIOSTInt16MSB: - Input_Int16_Int32(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset,userFrameOffset, !swap); - break; - case ASIOSTInt32LSB: - Input_Int32_Int32(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset,userFrameOffset, swap); - break; - case ASIOSTInt32MSB: - Input_Int32_Int32(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset,userFrameOffset, !swap); - break; - case ASIOSTFloat32LSB: // IEEE 754 32 bit float, as found on Intel x86 architecture - Input_Float32_Int32(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset,userFrameOffset, swap); - break; - case ASIOSTFloat32MSB: // IEEE 754 32 bit float, as found on Intel x86 architecture - Input_Float32_Int32(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset,userFrameOffset, !swap); - break; - - case ASIOSTInt24LSB: // used for 20 bits as well - case ASIOSTInt24MSB: // used for 20 bits as well - - case ASIOSTFloat64LSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture - case ASIOSTFloat64MSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture - - // these are used for 32 bit data buffer, with different alignment of the data inside - // 32 bit PCI bus systems can more easily used with these - - case ASIOSTInt32LSB16: // 32 bit data with 16 bit alignment - case ASIOSTInt32LSB18: // 32 bit data with 18 bit alignment - case ASIOSTInt32LSB20: // 32 bit data with 20 bit alignment - case ASIOSTInt32LSB24: // 32 bit data with 24 bit alignment - - - case ASIOSTInt32MSB16: // 32 bit data with 16 bit alignment - case ASIOSTInt32MSB18: // 32 bit data with 18 bit alignment - case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment - case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment - DBUG(("Not yet implemented : please report the problem\n")); - break; - - } - break; - } - - case paInt16: - { - short *inBufPtr = (short *) inputBuffer; - - switch (nativeFormat) { - case ASIOSTInt16LSB: - Input_Int16_Int16(nativeBuffer, inBufPtr, framePerBuffer , NumInputChannels, index , hostFrameOffset,userFrameOffset, swap); - break; - case ASIOSTInt16MSB: - Input_Int16_Int16(nativeBuffer, inBufPtr, framePerBuffer , NumInputChannels, index , hostFrameOffset,userFrameOffset, !swap); - break; - case ASIOSTInt32LSB: - Input_Int32_Int16(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset,userFrameOffset, flags,swap); - break; - case ASIOSTInt32MSB: - Input_Int32_Int16(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset,userFrameOffset, flags,!swap); - break; - case ASIOSTFloat32LSB: // IEEE 754 32 bit float, as found on Intel x86 architecture - Input_Float32_Int16(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset,userFrameOffset, flags,swap); - break; - case ASIOSTFloat32MSB: // IEEE 754 32 bit float, as found on Intel x86 architecture - Input_Float32_Int16(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset,userFrameOffset, flags,!swap); - break; - - case ASIOSTInt24LSB: // used for 20 bits as well - case ASIOSTInt24MSB: // used for 20 bits as well - - case ASIOSTFloat64LSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture - case ASIOSTFloat64MSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture - - // these are used for 32 bit data buffer, with different alignment of the data inside - // 32 bit PCI bus systems can more easily used with these - - case ASIOSTInt32LSB16: // 32 bit data with 16 bit alignment - case ASIOSTInt32LSB18: // 32 bit data with 18 bit alignment - case ASIOSTInt32LSB20: // 32 bit data with 20 bit alignment - case ASIOSTInt32LSB24: // 32 bit data with 24 bit alignment - - - case ASIOSTInt32MSB16: // 32 bit data with 16 bit alignment - case ASIOSTInt32MSB18: // 32 bit data with 18 bit alignment - case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment - case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment - DBUG(("Not yet implemented : please report the problem\n")); - break; - - } - break; - } - - case paInt8: - { - /* Convert 16 bit data to 8 bit chars */ - - char *inBufPtr = (char *) inputBuffer; - - switch (nativeFormat) { - case ASIOSTInt16LSB: - Input_Int16_Int8(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset,userFrameOffset,flags,swap); - break; - case ASIOSTInt16MSB: - Input_Int16_Int8(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset,userFrameOffset, flags,!swap); - break; - case ASIOSTInt32LSB: - Input_Int32_Int8(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset,userFrameOffset, flags,swap); - break; - case ASIOSTInt32MSB: - Input_Int32_Int8(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset,userFrameOffset, flags,!swap); - break; - case ASIOSTFloat32LSB: // IEEE 754 32 bit float, as found on Intel x86 architecture - Input_Float32_Int8(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset,userFrameOffset, flags,swap); - break; - case ASIOSTFloat32MSB: // IEEE 754 32 bit float, as found on Intel x86 architecture - Input_Float32_Int8(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset,userFrameOffset, flags,!swap); - break; - - case ASIOSTInt24LSB: // used for 20 bits as well - case ASIOSTInt24MSB: // used for 20 bits as well - - case ASIOSTFloat64LSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture - case ASIOSTFloat64MSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture - - // these are used for 32 bit data buffer, with different alignment of the data inside - // 32 bit PCI bus systems can more easily used with these - - case ASIOSTInt32LSB16: // 32 bit data with 16 bit alignment - case ASIOSTInt32LSB18: // 32 bit data with 18 bit alignment - case ASIOSTInt32LSB20: // 32 bit data with 20 bit alignment - case ASIOSTInt32LSB24: // 32 bit data with 24 bit alignment - - - case ASIOSTInt32MSB16: // 32 bit data with 16 bit alignment - case ASIOSTInt32MSB18: // 32 bit data with 18 bit alignment - case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment - case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment - DBUG(("Not yet implemented : please report the problem\n")); - break; - } - break; - } - - case paUInt8: - { - /* Convert 16 bit data to 8 bit unsigned chars */ - - unsigned char *inBufPtr = (unsigned char *)inputBuffer; - - switch (nativeFormat) { - case ASIOSTInt16LSB: - Input_Int16_IntU8(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset,userFrameOffset, flags,swap); - break; - case ASIOSTInt16MSB: - Input_Int16_IntU8(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset,userFrameOffset, flags,!swap); - break; - case ASIOSTInt32LSB: - Input_Int32_IntU8(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset,userFrameOffset,flags,swap); - break; - case ASIOSTInt32MSB: - Input_Int32_IntU8(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset,userFrameOffset, flags,!swap); - break; - case ASIOSTFloat32LSB: // IEEE 754 32 bit float, as found on Intel x86 architecture - Input_Float32_IntU8(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset,userFrameOffset,flags,swap); - break; - case ASIOSTFloat32MSB: // IEEE 754 32 bit float, as found on Intel x86 architecture - Input_Float32_IntU8(nativeBuffer, inBufPtr, framePerBuffer, NumInputChannels, index, hostFrameOffset,userFrameOffset,flags,!swap); - break; - - case ASIOSTInt24LSB: // used for 20 bits as well - case ASIOSTInt24MSB: // used for 20 bits as well - - case ASIOSTFloat64LSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture - case ASIOSTFloat64MSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture - - // these are used for 32 bit data buffer, with different alignment of the data inside - // 32 bit PCI bus systems can more easily used with these - - case ASIOSTInt32LSB16: // 32 bit data with 16 bit alignment - case ASIOSTInt32LSB18: // 32 bit data with 18 bit alignment - case ASIOSTInt32LSB20: // 32 bit data with 20 bit alignment - case ASIOSTInt32LSB24: // 32 bit data with 24 bit alignment - - - case ASIOSTInt32MSB16: // 32 bit data with 16 bit alignment - case ASIOSTInt32MSB18: // 32 bit data with 18 bit alignment - case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment - case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment - DBUG(("Not yet implemented : please report the problem\n")); - break; - - } - break; - } - - default: - break; - } - } -} - - -//--------------------------------------------------------------------------------------- -static void Pa_ASIO_Convert_Inter_Output(ASIOBufferInfo* nativeBuffer, - void* outputBuffer, - long NumInputChannels, - long NumOuputChannels, - long framePerBuffer, - long hostFrameOffset, - long userFrameOffset, - ASIOSampleType nativeFormat, - PaSampleFormat paFormat, - PaStreamFlags flags, - long index) -{ - - if((NumOuputChannels > 0) && (nativeBuffer != NULL)) - { - /* Convert from PA format to native format */ - - switch(paFormat) - { - case paFloat32: - { - float *outBufPtr = (float *) outputBuffer; - - switch (nativeFormat) { - case ASIOSTInt16LSB: - Output_Float32_Int16(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset, userFrameOffset, flags, swap); - break; - case ASIOSTInt16MSB: - Output_Float32_Int16(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset, userFrameOffset, flags,!swap); - break; - case ASIOSTInt32LSB: - Output_Float32_Int32(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset, userFrameOffset, flags,swap); - break; - case ASIOSTInt32MSB: - Output_Float32_Int32(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, flags,!swap); - break; - case ASIOSTFloat32LSB: - Output_Float32_Float32(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset,flags,swap); - break; - case ASIOSTFloat32MSB: - Output_Float32_Float32(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, flags,!swap); - break; - - case ASIOSTInt24LSB: // used for 20 bits as well - case ASIOSTInt24MSB: // used for 20 bits as well - - case ASIOSTFloat64LSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture - case ASIOSTFloat64MSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture - - // these are used for 32 bit data buffer, with different alignment of the data inside - // 32 bit PCI bus systems can more easily used with these - - case ASIOSTInt32LSB16: // 32 bit data with 16 bit alignment - case ASIOSTInt32LSB18: // 32 bit data with 18 bit alignment - case ASIOSTInt32LSB20: // 32 bit data with 20 bit alignment - case ASIOSTInt32LSB24: // 32 bit data with 24 bit alignment - - - case ASIOSTInt32MSB16: // 32 bit data with 16 bit alignment - case ASIOSTInt32MSB18: // 32 bit data with 18 bit alignment - case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment - case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment - DBUG(("Not yet implemented : please report the problem\n")); - break; - } - break; - } - - case paInt32: - { - long *outBufPtr = (long *) outputBuffer; - - switch (nativeFormat) { - case ASIOSTInt16LSB: - Output_Int32_Int16(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, flags,swap); - break; - case ASIOSTInt16MSB: - Output_Int32_Int16(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, flags,!swap); - break; - case ASIOSTInt32LSB: - Output_Int32_Int32(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, flags,swap); - break; - case ASIOSTInt32MSB: - Output_Int32_Int32(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, flags,!swap); - break; - case ASIOSTFloat32LSB: - Output_Int32_Float32(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, flags,swap); - break; - case ASIOSTFloat32MSB: - Output_Int32_Float32(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, flags,!swap); - break; - - case ASIOSTInt24LSB: // used for 20 bits as well - case ASIOSTInt24MSB: // used for 20 bits as well - - case ASIOSTFloat64LSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture - case ASIOSTFloat64MSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture - - // these are used for 32 bit data buffer, with different alignment of the data inside - // 32 bit PCI bus systems can more easily used with these - - case ASIOSTInt32LSB16: // 32 bit data with 16 bit alignment - case ASIOSTInt32LSB18: // 32 bit data with 18 bit alignment - case ASIOSTInt32LSB20: // 32 bit data with 20 bit alignment - case ASIOSTInt32LSB24: // 32 bit data with 24 bit alignment - - - case ASIOSTInt32MSB16: // 32 bit data with 16 bit alignment - case ASIOSTInt32MSB18: // 32 bit data with 18 bit alignment - case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment - case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment - DBUG(("Not yet implemented : please report the problem\n")); - break; - } - break; - } - - case paInt16: - { - short *outBufPtr = (short *) outputBuffer; - - switch (nativeFormat) { - case ASIOSTInt16LSB: - Output_Int16_Int16(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, swap); - break; - case ASIOSTInt16MSB: - Output_Int16_Int16(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, !swap); - break; - case ASIOSTInt32LSB: - Output_Int16_Int32(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, swap); - break; - case ASIOSTInt32MSB: - Output_Int16_Int32(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, !swap); - break; - case ASIOSTFloat32LSB: - Output_Int16_Float32(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, swap); - break; - case ASIOSTFloat32MSB: - Output_Int16_Float32(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, !swap); - break; - - case ASIOSTInt24LSB: // used for 20 bits as well - case ASIOSTInt24MSB: // used for 20 bits as well - - case ASIOSTFloat64LSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture - case ASIOSTFloat64MSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture - - // these are used for 32 bit data buffer, with different alignment of the data inside - // 32 bit PCI bus systems can more easily used with these - - case ASIOSTInt32LSB16: // 32 bit data with 16 bit alignment - case ASIOSTInt32LSB18: // 32 bit data with 18 bit alignment - case ASIOSTInt32LSB20: // 32 bit data with 20 bit alignment - case ASIOSTInt32LSB24: // 32 bit data with 24 bit alignment - - - case ASIOSTInt32MSB16: // 32 bit data with 16 bit alignment - case ASIOSTInt32MSB18: // 32 bit data with 18 bit alignment - case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment - case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment - DBUG(("Not yet implemented : please report the problem\n")); - break; - - } - break; - } - - - case paInt8: - { - char *outBufPtr = (char *) outputBuffer; - - switch (nativeFormat) { - case ASIOSTInt16LSB: - Output_Int8_Int16(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, swap); - break; - case ASIOSTInt16MSB: - Output_Int8_Int16(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, !swap); - break; - case ASIOSTInt32LSB: - Output_Int8_Int32(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, swap); - break; - case ASIOSTInt32MSB: - Output_Int8_Int32(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, !swap); - break; - case ASIOSTFloat32LSB: - Output_Int8_Float32(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, swap); - break; - case ASIOSTFloat32MSB: - Output_Int8_Float32(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, !swap); - break; - - case ASIOSTInt24LSB: // used for 20 bits as well - case ASIOSTInt24MSB: // used for 20 bits as well - - case ASIOSTFloat64LSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture - case ASIOSTFloat64MSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture - - // these are used for 32 bit data buffer, with different alignment of the data inside - // 32 bit PCI bus systems can more easily used with these - - case ASIOSTInt32LSB16: // 32 bit data with 16 bit alignment - case ASIOSTInt32LSB18: // 32 bit data with 18 bit alignment - case ASIOSTInt32LSB20: // 32 bit data with 20 bit alignment - case ASIOSTInt32LSB24: // 32 bit data with 24 bit alignment - - - case ASIOSTInt32MSB16: // 32 bit data with 16 bit alignment - case ASIOSTInt32MSB18: // 32 bit data with 18 bit alignment - case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment - case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment - DBUG(("Not yet implemented : please report the problem\n")); - break; - } - break; - } - - case paUInt8: - { - unsigned char *outBufPtr = (unsigned char *) outputBuffer; - - switch (nativeFormat) { - case ASIOSTInt16LSB: - Output_IntU8_Int16(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, swap); - break; - case ASIOSTInt16MSB: - Output_IntU8_Int16(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, !swap); - break; - case ASIOSTInt32LSB: - Output_IntU8_Int32(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, swap); - break; - case ASIOSTInt32MSB: - Output_IntU8_Int32(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, !swap); - break; - case ASIOSTFloat32LSB: - Output_IntU8_Float32(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, swap); - break; - case ASIOSTFloat32MSB: - Output_IntU8_Float32(nativeBuffer, outBufPtr, framePerBuffer, NumInputChannels, NumOuputChannels, index, hostFrameOffset,userFrameOffset, !swap); - break; - - case ASIOSTInt24LSB: // used for 20 bits as well - case ASIOSTInt24MSB: // used for 20 bits as well - - case ASIOSTFloat64LSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture - case ASIOSTFloat64MSB: // IEEE 754 64 bit double float, as found on Intel x86 architecture - - // these are used for 32 bit data buffer, with different alignment of the data inside - // 32 bit PCI bus systems can more easily used with these - - case ASIOSTInt32LSB16: // 32 bit data with 16 bit alignment - case ASIOSTInt32LSB18: // 32 bit data with 18 bit alignment - case ASIOSTInt32LSB20: // 32 bit data with 20 bit alignment - case ASIOSTInt32LSB24: // 32 bit data with 24 bit alignment - - - case ASIOSTInt32MSB16: // 32 bit data with 16 bit alignment - case ASIOSTInt32MSB18: // 32 bit data with 18 bit alignment - case ASIOSTInt32MSB20: // 32 bit data with 20 bit alignment - case ASIOSTInt32MSB24: // 32 bit data with 24 bit alignment - DBUG(("Not yet implemented : please report the problem\n")); - break; - } - break; - } - - default: - break; - } - } - -} - - - -/* Load a ASIO driver corresponding to the required device */ -static PaError Pa_ASIO_loadDevice (long device) -{ - PaDeviceInfo * dev = &(sDevices[device].pad_Info); - - if (!Pa_ASIO_loadAsioDriver((char *) dev->name)) return paHostError; - if (ASIOInit(&asioDriverInfo.pahsc_driverInfo) != ASE_OK) return paHostError; - if (ASIOGetChannels(&asioDriverInfo.pahsc_NumInputChannels, &asioDriverInfo.pahsc_NumOutputChannels) != ASE_OK) return paHostError; - if (ASIOGetBufferSize(&asioDriverInfo.pahsc_minSize, &asioDriverInfo.pahsc_maxSize, &asioDriverInfo.pahsc_preferredSize, &asioDriverInfo.pahsc_granularity) != ASE_OK) return paHostError; - - if(ASIOOutputReady() == ASE_OK) - asioDriverInfo.pahsc_postOutput = true; - else - asioDriverInfo.pahsc_postOutput = false; - - return paNoError; -} - -//--------------------------------------------------- -static int GetHighestBitPosition (unsigned long n) -{ - int pos = -1; - while( n != 0 ) - { - pos++; - n = n >> 1; - } - return pos; -} - -//------------------------------------------------------------------------------------------ -static int GetFirstMultiple(long min, long val ){ return ((min + val - 1) / val) * val; } - -//------------------------------------------------------------------------------------------ -static int GetFirstPossibleDivisor(long max, long val ) -{ - for (int i = 2; i < 20; i++) {if (((val%i) == 0) && ((val/i) <= max)) return (val/i); } - return val; -} - -//------------------------------------------------------------------------ -static int IsPowerOfTwo( unsigned long n ) { return ((n & (n-1)) == 0); } - -/******************************************************************* -* Determine size of native ASIO audio buffer size -* Input parameters : FramesPerUserBuffer, NumUserBuffers -* Output values : FramesPerHostBuffer, OutputBufferOffset or InputtBufferOffset -*/ - -static PaError PaHost_CalcNumHostBuffers( internalPortAudioStream *past ) -{ - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - long requestedBufferSize; - long firstMultiple, firstDivisor; - - // Compute requestedBufferSize - if( past->past_NumUserBuffers < 1 ){ - requestedBufferSize = past->past_FramesPerUserBuffer; - }else{ - requestedBufferSize = past->past_NumUserBuffers * past->past_FramesPerUserBuffer; - } - - // Adjust FramesPerHostBuffer using requestedBufferSize, ASIO minSize and maxSize, - if (requestedBufferSize < asioDriverInfo.pahsc_minSize){ - - firstMultiple = GetFirstMultiple(asioDriverInfo.pahsc_minSize, requestedBufferSize); - - if (firstMultiple <= asioDriverInfo.pahsc_maxSize) - asioDriverInfo.past_FramesPerHostBuffer = firstMultiple; - else - asioDriverInfo.past_FramesPerHostBuffer = asioDriverInfo.pahsc_minSize; - - }else if (requestedBufferSize > asioDriverInfo.pahsc_maxSize){ - - firstDivisor = GetFirstPossibleDivisor(asioDriverInfo.pahsc_maxSize, requestedBufferSize); - - if ((firstDivisor >= asioDriverInfo.pahsc_minSize) && (firstDivisor <= asioDriverInfo.pahsc_maxSize)) - asioDriverInfo.past_FramesPerHostBuffer = firstDivisor; - else - asioDriverInfo.past_FramesPerHostBuffer = asioDriverInfo.pahsc_maxSize; - }else{ - asioDriverInfo.past_FramesPerHostBuffer = requestedBufferSize; - } - - // If ASIO buffer size needs to be a power of two - if( asioDriverInfo.pahsc_granularity < 0 ){ - // Needs to be a power of two. - - if( !IsPowerOfTwo( asioDriverInfo.past_FramesPerHostBuffer ) ) - { - int highestBit = GetHighestBitPosition(asioDriverInfo.past_FramesPerHostBuffer); - asioDriverInfo.past_FramesPerHostBuffer = 1 << (highestBit + 1); - } - } - - DBUG(("----------------------------------\n")); - DBUG(("PaHost_CalcNumHostBuffers : minSize = %ld \n",asioDriverInfo.pahsc_minSize)); - DBUG(("PaHost_CalcNumHostBuffers : preferredSize = %ld \n",asioDriverInfo.pahsc_preferredSize)); - DBUG(("PaHost_CalcNumHostBuffers : maxSize = %ld \n",asioDriverInfo.pahsc_maxSize)); - DBUG(("PaHost_CalcNumHostBuffers : granularity = %ld \n",asioDriverInfo.pahsc_granularity)); - DBUG(("PaHost_CalcNumHostBuffers : User buffer size = %d\n", asioDriverInfo.past->past_FramesPerUserBuffer )); - DBUG(("PaHost_CalcNumHostBuffers : ASIO buffer size = %d\n", asioDriverInfo.past_FramesPerHostBuffer )); - - return paNoError; -} - - -/***********************************************************************/ -int Pa_CountDevices() -{ - PaError err ; - - if( sNumDevices <= 0 ) - { - /* Force loading of ASIO drivers */ - err = Pa_ASIO_QueryDeviceInfo(sDevices); - if( err != paNoError ) goto error; - } - - return sNumDevices; - -error: - PaHost_Term(); - DBUG(("Pa_CountDevices: returns %d\n", err )); - return err; -} - -/***********************************************************************/ -PaError PaHost_Init( void ) -{ - /* Have we already initialized the device info? */ - PaError err = (PaError) Pa_CountDevices(); - return ( err < 0 ) ? err : paNoError; -} - -/***********************************************************************/ -PaError PaHost_Term( void ) -{ - int i; - PaDeviceInfo *dev; - double *rates; - PaError result = paNoError; - - if (sNumDevices > 0) { - - /* Free allocated sample rate arrays and names*/ - for( i=0; isampleRates; - if ((rates != NULL)) PaHost_FreeFastMemory(rates, MAX_NUMSAMPLINGRATES * sizeof(double)); - dev->sampleRates = NULL; - if(dev->name != NULL) PaHost_FreeFastMemory((void *) dev->name, 32); - dev->name = NULL; - } - - sNumDevices = 0; - - /* If the stream has been closed with PaHost_CloseStream, asioDriverInfo.past == null, otherwise close it now */ - if(asioDriverInfo.past != NULL) Pa_CloseStream(asioDriverInfo.past); - - /* remove the loaded ASIO driver */ - asioDrivers->removeCurrentDriver(); - } - - return result; -} - -/***********************************************************************/ -PaError PaHost_OpenStream( internalPortAudioStream *past ) -{ - PaError result = paNoError; - ASIOError err; - int32 device; - - /* Check if a stream already runs */ - if (asioDriverInfo.past != NULL) return paHostError; - - /* Check the device number */ - if ((past->past_InputDeviceID != paNoDevice) - &&(past->past_OutputDeviceID != paNoDevice) - &&(past->past_InputDeviceID != past->past_OutputDeviceID)) - { - return paInvalidDeviceId; - } - - /* Allocation */ - memset(&asioDriverInfo, 0, sizeof(PaHostSoundControl)); - past->past_DeviceData = (void*) &asioDriverInfo; - - /* Reentrancy counter initialisation */ - asioDriverInfo.reenterCount = -1; - asioDriverInfo.reenterError = 0; - - /* FIXME */ - asioDriverInfo.past = past; - - /* load the ASIO device */ - device = (past->past_InputDeviceID < 0) ? past->past_OutputDeviceID : past->past_InputDeviceID; - result = Pa_ASIO_loadDevice(device); - if (result != paNoError) goto error; - - /* Check ASIO parameters and input parameters */ - if ((past->past_NumInputChannels > asioDriverInfo.pahsc_NumInputChannels) - || (past->past_NumOutputChannels > asioDriverInfo.pahsc_NumOutputChannels)) { - result = paInvalidChannelCount; - goto error; - } - - /* Set sample rate */ - if (ASIOSetSampleRate(past->past_SampleRate) != ASE_OK) { - result = paInvalidSampleRate; - goto error; - } - - /* if OK calc buffer size */ - result = PaHost_CalcNumHostBuffers( past ); - if (result != paNoError) goto error; - - - /* - Allocating input and output buffers number for the real past_NumInputChannels and past_NumOutputChannels - optimize the data transfer. - */ - - asioDriverInfo.pahsc_NumInputChannels = past->past_NumInputChannels; - asioDriverInfo.pahsc_NumOutputChannels = past->past_NumOutputChannels; - - /* Allocate ASIO buffers and callback*/ - err = Pa_ASIO_CreateBuffers(&asioDriverInfo, - asioDriverInfo.pahsc_NumInputChannels, - asioDriverInfo.pahsc_NumOutputChannels, - asioDriverInfo.past_FramesPerHostBuffer); - - - /* - Some buggy drivers (like the Hoontech DSP24) give incorrect [min, preferred, max] values - They should work with the preferred size value, thus if Pa_ASIO_CreateBuffers fails with - the hostBufferSize computed in PaHost_CalcNumHostBuffers, we try again with the preferred size. - */ - - if (err != ASE_OK) { - - DBUG(("PaHost_OpenStream : Pa_ASIO_CreateBuffers failed with the requested framesPerBuffer = %ld \n", asioDriverInfo.past_FramesPerHostBuffer)); - - err = Pa_ASIO_CreateBuffers(&asioDriverInfo, - asioDriverInfo.pahsc_NumInputChannels, - asioDriverInfo.pahsc_NumOutputChannels, - asioDriverInfo.pahsc_preferredSize); - - if (err == ASE_OK) { - // Adjust FramesPerHostBuffer to take the preferredSize instead of the value computed in PaHost_CalcNumHostBuffers - asioDriverInfo.past_FramesPerHostBuffer = asioDriverInfo.pahsc_preferredSize; - DBUG(("PaHost_OpenStream : Adjust FramesPerHostBuffer to take the preferredSize instead of the value computed in PaHost_CalcNumHostBuffers\n")); - } else { - DBUG(("PaHost_OpenStream : Pa_ASIO_CreateBuffers failed with the preferred framesPerBuffer = %ld \n", asioDriverInfo.pahsc_preferredSize)); - } - } - - /* Compute buffer adapdation offset */ - PaHost_CalcBufferOffset(past); - - if (err == ASE_OK) - return paNoError; - else if (err == ASE_NoMemory) - result = paInsufficientMemory; - else if (err == ASE_InvalidParameter) - result = paInvalidChannelCount; - else if (err == ASE_InvalidMode) - result = paBufferTooBig; - else - result = paHostError; - -error: - ASIOExit(); - return result; - -} - -/***********************************************************************/ -PaError PaHost_CloseStream( internalPortAudioStream *past ) -{ - PaHostSoundControl *pahsc; - PaError result = paNoError; - - if( past == NULL ) return paBadStreamPtr; - pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return paNoError; - - #if PA_TRACE_START_STOP - AddTraceMessage( "PaHost_CloseStream: pahsc_HWaveOut ", (int) pahsc->pahsc_HWaveOut ); - #endif - - /* Free data and device for output. */ - past->past_DeviceData = NULL; - asioDriverInfo.past = NULL; - - /* Dispose */ - if(ASIODisposeBuffers() != ASE_OK) result = paHostError; - if(ASIOExit() != ASE_OK) result = paHostError; - - return result; -} - -/***********************************************************************/ -PaError PaHost_StartOutput( internalPortAudioStream *past ) -{ - /* Clear the index 0 host output buffer */ - Pa_ASIO_Clear_Output(asioDriverInfo.bufferInfos, - asioDriverInfo.pahsc_channelInfos[0].type, - asioDriverInfo.pahsc_NumInputChannels, - asioDriverInfo.pahsc_NumOutputChannels, - 0, - 0, - asioDriverInfo.past_FramesPerHostBuffer); - - /* Clear the index 1 host output buffer */ - Pa_ASIO_Clear_Output(asioDriverInfo.bufferInfos, - asioDriverInfo.pahsc_channelInfos[0].type, - asioDriverInfo.pahsc_NumInputChannels, - asioDriverInfo.pahsc_NumOutputChannels, - 1, - 0, - asioDriverInfo.past_FramesPerHostBuffer); - - Pa_ASIO_Clear_User_Buffers(); - - Pa_ASIO_Adaptor_Init(); - - return paNoError; -} - -/***********************************************************************/ -PaError PaHost_StopOutput( internalPortAudioStream *past, int abort ) -{ - /* Nothing to do ?? */ - return paNoError; -} - -/***********************************************************************/ -PaError PaHost_StartInput( internalPortAudioStream *past ) -{ - /* Nothing to do ?? */ - return paNoError; -} - -/***********************************************************************/ -PaError PaHost_StopInput( internalPortAudioStream *past, int abort ) -{ - /* Nothing to do */ - return paNoError; -} - -/***********************************************************************/ -PaError PaHost_StartEngine( internalPortAudioStream *past ) -{ - // TO DO : count of samples - past->past_IsActive = 1; - return (ASIOStart() == ASE_OK) ? paNoError : paHostError; -} - -/***********************************************************************/ -PaError PaHost_StopEngine( internalPortAudioStream *past, int abort ) -{ - // TO DO : count of samples - past->past_IsActive = 0; - return (ASIOStop() == ASE_OK) ? paNoError : paHostError; -} - -/***********************************************************************/ -// TO BE CHECKED -PaError PaHost_StreamActive( internalPortAudioStream *past ) -{ - PaHostSoundControl *pahsc; - if( past == NULL ) return paBadStreamPtr; - pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return paInternalError; - return (PaError) past->past_IsActive; -} - -/*************************************************************************/ -PaTimestamp Pa_StreamTime( PortAudioStream *stream ) -{ - PaHostSoundControl *pahsc; - internalPortAudioStream *past = (internalPortAudioStream *) stream; - if( past == NULL ) return paBadStreamPtr; - pahsc = (PaHostSoundControl *) past->past_DeviceData; - return pahsc->pahsc_NumFramesDone; -} - -/************************************************************************* - * Allocate memory that can be accessed in real-time. - * This may need to be held in physical memory so that it is not - * paged to virtual memory. - * This call MUST be balanced with a call to PaHost_FreeFastMemory(). - */ -void *PaHost_AllocateFastMemory( long numBytes ) -{ - #if MAC - void *addr = NewPtrClear( numBytes ); - if( (addr == NULL) || (MemError () != 0) ) return NULL; - - #if (CARBON_COMPATIBLE == 0) - if( HoldMemory( addr, numBytes ) != noErr ) - { - DisposePtr( (Ptr) addr ); - return NULL; - } - #endif - return addr; - #elif WINDOWS - void *addr = malloc( numBytes ); /* FIXME - do we need physical memory? */ - if( addr != NULL ) memset( addr, 0, numBytes ); - return addr; - #endif -} - -/************************************************************************* - * Free memory that could be accessed in real-time. - * This call MUST be balanced with a call to PaHost_AllocateFastMemory(). - */ -void PaHost_FreeFastMemory( void *addr, long numBytes ) -{ - #if MAC - if( addr == NULL ) return; - #if CARBON_COMPATIBLE - (void) numBytes; - #else - UnholdMemory( addr, numBytes ); - #endif - DisposePtr( (Ptr) addr ); - #elif WINDOWS - if( addr != NULL ) free( addr ); - #endif -} - - -/*************************************************************************/ -void Pa_Sleep( long msec ) -{ - #if MAC - int32 sleepTime, endTime; - /* Convert to ticks. Round up so we sleep a MINIMUM of msec time. */ - sleepTime = ((msec * 60) + 999) / 1000; - if( sleepTime < 1 ) sleepTime = 1; - endTime = TickCount() + sleepTime; - do{ - DBUGX(("Sleep for %d ticks.\n", sleepTime )); - WaitNextEvent( 0, NULL, sleepTime, NULL ); /* Use this just to sleep without getting events. */ - sleepTime = endTime - TickCount(); - } while( sleepTime > 0 ); - #elif WINDOWS - Sleep( msec ); - #endif -} - -/*************************************************************************/ -const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id ) -{ - if( (id < 0) || ( id >= Pa_CountDevices()) ) return NULL; - return &sDevices[id].pad_Info; -} - -/*************************************************************************/ -PaDeviceID Pa_GetDefaultInputDeviceID( void ) -{ - return (sNumDevices > 0) ? sDefaultInputDeviceID : paNoDevice; -} - -/*************************************************************************/ -PaDeviceID Pa_GetDefaultOutputDeviceID( void ) -{ - return (sNumDevices > 0) ? sDefaultOutputDeviceID : paNoDevice; -} - -/*************************************************************************/ -int Pa_GetMinNumBuffers( int framesPerUserBuffer, double sampleRate ) -{ - // TO BE IMPLEMENTED : using the ASIOGetLatency call?? - return 2; -} - -/*************************************************************************/ -int32 Pa_GetHostError( void ) -{ - int32 err = sPaHostError; - sPaHostError = 0; - return err; -} - - -#ifdef MAC - -/**************************************************************************/ -static void Pa_StartUsageCalculation( internalPortAudioStream *past ) -{ - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - UnsignedWide widePad; - if( pahsc == NULL ) return; -/* Query system timer for usage analysis and to prevent overuse of CPU. */ - Microseconds( &widePad ); - pahsc->pahsc_EntryCount = UnsignedWideToUInt64( widePad ); -} -/**************************************************************************/ -static void Pa_EndUsageCalculation( internalPortAudioStream *past ) -{ - UnsignedWide widePad; - UInt64 CurrentCount; - long InsideCount; - long TotalCount; - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return; -/* Measure CPU utilization during this callback. Note that this calculation -** assumes that we had the processor the whole time. -*/ -#define LOWPASS_COEFFICIENT_0 (0.9) -#define LOWPASS_COEFFICIENT_1 (0.99999 - LOWPASS_COEFFICIENT_0) - Microseconds( &widePad ); - CurrentCount = UnsignedWideToUInt64( widePad ); - if( past->past_IfLastExitValid ) - { - InsideCount = (long) U64Subtract(CurrentCount, pahsc->pahsc_EntryCount); - TotalCount = (long) U64Subtract(CurrentCount, pahsc->pahsc_LastExitCount); -/* Low pass filter the result because sometimes we get called several times in a row. -* That can cause the TotalCount to be very low which can cause the usage to appear -* unnaturally high. So we must filter numerator and denominator separately!!! -*/ - past->past_AverageInsideCount = (( LOWPASS_COEFFICIENT_0 * past->past_AverageInsideCount) + - (LOWPASS_COEFFICIENT_1 * InsideCount)); - past->past_AverageTotalCount = (( LOWPASS_COEFFICIENT_0 * past->past_AverageTotalCount) + - (LOWPASS_COEFFICIENT_1 * TotalCount)); - past->past_Usage = past->past_AverageInsideCount / past->past_AverageTotalCount; - } - pahsc->pahsc_LastExitCount = CurrentCount; - past->past_IfLastExitValid = 1; -} - -#elif WINDOWS - -/********************************* BEGIN CPU UTILIZATION MEASUREMENT ****/ -static void Pa_StartUsageCalculation( internalPortAudioStream *past ) -{ - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return; -/* Query system timer for usage analysis and to prevent overuse of CPU. */ - QueryPerformanceCounter( &pahsc->pahsc_EntryCount ); -} - -static void Pa_EndUsageCalculation( internalPortAudioStream *past ) -{ - LARGE_INTEGER CurrentCount = { 0, 0 }; - LONGLONG InsideCount; - LONGLONG TotalCount; -/* -** Measure CPU utilization during this callback. Note that this calculation -** assumes that we had the processor the whole time. -*/ -#define LOWPASS_COEFFICIENT_0 (0.9) -#define LOWPASS_COEFFICIENT_1 (0.99999 - LOWPASS_COEFFICIENT_0) - - PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData; - if( pahsc == NULL ) return; - - if( QueryPerformanceCounter( &CurrentCount ) ) - { - if( past->past_IfLastExitValid ) - { - InsideCount = CurrentCount.QuadPart - pahsc->pahsc_EntryCount.QuadPart; - TotalCount = CurrentCount.QuadPart - pahsc->pahsc_LastExitCount.QuadPart; -/* Low pass filter the result because sometimes we get called several times in a row. - * That can cause the TotalCount to be very low which can cause the usage to appear - * unnaturally high. So we must filter numerator and denominator separately!!! - */ - past->past_AverageInsideCount = (( LOWPASS_COEFFICIENT_0 * past->past_AverageInsideCount) + - (LOWPASS_COEFFICIENT_1 * InsideCount)); - past->past_AverageTotalCount = (( LOWPASS_COEFFICIENT_0 * past->past_AverageTotalCount) + - (LOWPASS_COEFFICIENT_1 * TotalCount)); - past->past_Usage = past->past_AverageInsideCount / past->past_AverageTotalCount; - } - pahsc->pahsc_LastExitCount = CurrentCount; - past->past_IfLastExitValid = 1; - } -} - -#endif - - - - -- cgit v1.2.1