⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pa_asio.cpp

📁 ppciaxclient softphone
💻 CPP
📖 第 1 页 / 共 5 页
字号:
/*
 * $Id: pa_asio.cpp,v 1.7.4.5 2003/06/30 16:27:10 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 <Devices.h> and <Timer.h> : 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 
       	   		 
         TO DO :
        
        - Check Pa_StopSteam and Pa_AbortStream
        - Optimization for Input only or Ouput only (really necessary ??)
*/


#include <stdio.h>
#include <assert.h>
#include <string.h>

#include "portaudio.h"
#include "pa_host.h"
#include "pa_trace.h"

#include "asiosys.h"
#include "asio.h"
#include "asiodrivers.h"


#if MAC
#include <Devices.h>
#include <Timer.h>
#include <Math64.h>
#else
#include <math.h>
#include <windows.h>
#include <mmsystem.h>
#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);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -