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

📄 pa_dsound.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 3 页
字号:
    if( sNumDevices <= 0 ) Pa_Initialize();    return sNumDevices;}static internalPortAudioDevice *Pa_GetInternalDevice( PaDeviceID id ){    if( (id < 0) || ( id >= Pa_CountDevices()) ) return NULL;    return &sDevices[id];}/*************************************************************************/const PaDeviceInfo* Pa_GetDeviceInfo( PaDeviceID id ){    internalPortAudioDevice *pad;    if( (id < 0) || ( id >= Pa_CountDevices()) ) return NULL;    pad = Pa_GetInternalDevice( id );    return  &pad->pad_Info ;}static PaError Pa_MaybeQueryDevices( void ){    if( sNumDevices == 0 )    {        return Pa_QueryDevices();    }    return 0;}/*************************************************************************** Returns recommended device ID.** On the PC, the recommended device can be specified by the user by** setting an environment variable. For example, to use device #1.****    set PA_RECOMMENDED_OUTPUT_DEVICE=1**** The user should first determine the available device ID by using** the supplied application "pa_devs".*/#define PA_ENV_BUF_SIZE  (32)#define PA_REC_IN_DEV_ENV_NAME  ("PA_RECOMMENDED_INPUT_DEVICE")#define PA_REC_OUT_DEV_ENV_NAME  ("PA_RECOMMENDED_OUTPUT_DEVICE")static PaDeviceID PaHost_GetEnvDefaultDeviceID( char *envName ){    DWORD   hresult;    char    envbuf[PA_ENV_BUF_SIZE];    PaDeviceID recommendedID = paNoDevice;    /* Let user determine default device by setting environment variable. */    hresult = GetEnvironmentVariable( envName, envbuf, PA_ENV_BUF_SIZE );    if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) )    {        recommendedID = atoi( envbuf );    }    return recommendedID;}PaDeviceID Pa_GetDefaultInputDeviceID( void ){    PaError result;    result = PaHost_GetEnvDefaultDeviceID( PA_REC_IN_DEV_ENV_NAME );    if( result < 0 )    {        result = Pa_MaybeQueryDevices();        if( result < 0 ) return result;        result = sDefaultInputDeviceID;    }    return result;}PaDeviceID Pa_GetDefaultOutputDeviceID( void ){    PaError result;    result = PaHost_GetEnvDefaultDeviceID( PA_REC_OUT_DEV_ENV_NAME );    if( result < 0 )    {        result = Pa_MaybeQueryDevices();        if( result < 0 ) return result;        result = sDefaultOutputDeviceID;    }    return result;}/************************************************************************ Make sure that we have queried the device capabilities.*/PaError PaHost_Init( void ){#if PA_SIMULATE_UNDERFLOW    PRINT(("WARNING - Underflow Simulation Enabled - Expect a Big Glitch!!!\n"));#endif    return Pa_MaybeQueryDevices();}static PaError Pa_TimeSlice( internalPortAudioStream   *past ){    PaError           result = 0;    long              bytesEmpty = 0;    long              bytesFilled = 0;    long              bytesToXfer = 0;    long              numChunks;    HRESULT           hresult;    PaHostSoundControl  *pahsc;    short            *nativeBufPtr;    past->past_NumCallbacks += 1;    pahsc = (PaHostSoundControl *) past->past_DeviceData;    if( pahsc == NULL ) return paInternalError;    /* How much input data is available? */#if SUPPORT_AUDIO_CAPTURE    if( past->past_NumInputChannels > 0 )    {        DSW_QueryInputFilled( &pahsc->pahsc_DSoundWrapper, &bytesFilled );        bytesToXfer = bytesFilled;    }#endif /* SUPPORT_AUDIO_CAPTURE */    /* How much output room is available? */    if( past->past_NumOutputChannels > 0 )    {        DSW_QueryOutputSpace( &pahsc->pahsc_DSoundWrapper, &bytesEmpty );        bytesToXfer = bytesEmpty;    }    AddTraceMessage( "bytesEmpty ", bytesEmpty );    /* Choose smallest value if both are active. */    if( (past->past_NumInputChannels > 0) && (past->past_NumOutputChannels > 0) )    {        bytesToXfer = ( bytesFilled < bytesEmpty ) ? bytesFilled : bytesEmpty;    }    /* printf("bytesFilled = %d, bytesEmpty = %d, bytesToXfer = %d\n",      bytesFilled, bytesEmpty, bytesToXfer);    */    /* Quantize to multiples of a buffer. */    numChunks = bytesToXfer / pahsc->pahsc_BytesPerBuffer;    if( numChunks > (long)(past->past_NumUserBuffers/2) )    {        numChunks = (long)past->past_NumUserBuffers/2;    }    else if( numChunks < 0 )    {        numChunks = 0;    }    AddTraceMessage( "numChunks ", numChunks );    nativeBufPtr = pahsc->pahsc_NativeBuffer;    if( numChunks > 0 )    {        while( numChunks-- > 0 )        {            /* Measure usage based on time to process one user buffer. */            Pa_StartUsageCalculation( past );#if SUPPORT_AUDIO_CAPTURE            /* Get native data from DirectSound. */            if( past->past_NumInputChannels > 0 )            {                hresult = DSW_ReadBlock( &pahsc->pahsc_DSoundWrapper, (char *) nativeBufPtr, pahsc->pahsc_BytesPerBuffer );                if( hresult < 0 )                {                    ERR_RPT(("DirectSound ReadBlock failed, hresult = 0x%x\n",hresult));                    sPaHostError = hresult;                    break;                }            }#endif /* SUPPORT_AUDIO_CAPTURE */            /* Convert 16 bit native data to user data and call user routine. */            result = Pa_CallConvertInt16( past, nativeBufPtr, nativeBufPtr );            if( result != 0) break;            /* Pass native data to DirectSound. */            if( past->past_NumOutputChannels > 0 )            {                /* static short DEBUGHACK = 0;                 DEBUGHACK += 0x0049;                 nativeBufPtr[0] = DEBUGHACK; /* Make buzz to see if DirectSound still running. */                hresult = DSW_WriteBlock( &pahsc->pahsc_DSoundWrapper, (char *) nativeBufPtr, pahsc->pahsc_BytesPerBuffer );                if( hresult < 0 )                {                    ERR_RPT(("DirectSound WriteBlock failed, result = 0x%x\n",hresult));                    sPaHostError = hresult;                    break;                }            }            Pa_EndUsageCalculation( past );        }    }    return result;}/*******************************************************************/static void CALLBACK Pa_TimerCallback(UINT uID, UINT uMsg, DWORD dwUser, DWORD dw1, DWORD dw2){    internalPortAudioStream   *past;    PaHostSoundControl  *pahsc;#if PA_SIMULATE_UNDERFLOW    gUnderCallbackCounter++;    if( (gUnderCallbackCounter >= UNDER_START_GAP) &&            (gUnderCallbackCounter <= UNDER_STOP_GAP) )    {        if( gUnderCallbackCounter == UNDER_START_GAP)        {            AddTraceMessage("Begin stall: gUnderCallbackCounter =======", gUnderCallbackCounter );        }        if( gUnderCallbackCounter == UNDER_STOP_GAP)        {            AddTraceMessage("End stall: gUnderCallbackCounter =======", gUnderCallbackCounter );        }        return;    }#endif    past = (internalPortAudioStream *) dwUser;    if( past == NULL ) return;    pahsc = (PaHostSoundControl *) past->past_DeviceData;    if( pahsc == NULL ) return;    if( !pahsc->pahsc_IfInsideCallback && past->past_IsActive )    {        if( past->past_StopNow )        {            past->past_IsActive = 0;        }        else if( past->past_StopSoon )        {            DSoundWrapper   *dsw = &pahsc->pahsc_DSoundWrapper;            if( past->past_NumOutputChannels > 0 )            {                DSW_ZeroEmptySpace( dsw );                AddTraceMessage("Pa_TimerCallback: waiting - written ", (int) dsw->dsw_FramesWritten );                AddTraceMessage("Pa_TimerCallback: waiting - played ", (int) dsw->dsw_FramesPlayed );                /* clear past_IsActive when all sound played */                if( dsw->dsw_FramesPlayed >= past->past_FrameCount )                {                    past->past_IsActive = 0;                }            }            else            {                past->past_IsActive = 0;            }        }        else        {            pahsc->pahsc_IfInsideCallback = 1;            if( Pa_TimeSlice( past ) != 0)  /* Call time slice independant of timing method. */            {                past->past_StopSoon = 1;            }            pahsc->pahsc_IfInsideCallback = 0;        }    }}/*******************************************************************/PaError PaHost_OpenStream( internalPortAudioStream   *past ){    HRESULT          hr;    PaError          result = paNoError;    PaHostSoundControl *pahsc;    int              numBytes, maxChannels;    unsigned int     minNumBuffers;    internalPortAudioDevice *pad;    DSoundWrapper   *dsw;    /* Allocate and initialize host data. */    pahsc = (PaHostSoundControl *) PaHost_AllocateFastMemory(sizeof(PaHostSoundControl)); /* MEM */    if( pahsc == NULL )    {        result = paInsufficientMemory;        goto error;    }    memset( pahsc, 0, sizeof(PaHostSoundControl) );    past->past_DeviceData = (void *) pahsc;    pahsc->pahsc_TimerID = 0;    dsw = &pahsc->pahsc_DSoundWrapper;    DSW_Init( dsw );    /* Allocate native buffer. */    maxChannels = ( past->past_NumOutputChannels > past->past_NumInputChannels ) ?                  past->past_NumOutputChannels : past->past_NumInputChannels;    pahsc->pahsc_BytesPerBuffer = past->past_FramesPerUserBuffer * maxChannels * sizeof(short);    if( maxChannels > 0 )    {        pahsc->pahsc_NativeBuffer = (short *) PaHost_AllocateFastMemory(pahsc->pahsc_BytesPerBuffer); /* MEM */        if( pahsc->pahsc_NativeBuffer == NULL )        {            result = paInsufficientMemory;            goto error;        }    }    else    {        result = paInvalidChannelCount;        goto error;    }    DBUG(("PaHost_OpenStream: pahsc_MinFramesPerHostBuffer = %d\n", pahsc->pahsc_MinFramesPerHostBuffer ));    minNumBuffers = Pa_GetMinNumBuffers( past->past_FramesPerUserBuffer, past->past_SampleRate );    past->past_NumUserBuffers = ( minNumBuffers > past->past_NumUserBuffers ) ? minNumBuffers : past->past_NumUserBuffers;    numBytes = pahsc->pahsc_BytesPerBuffer * past->past_NumUserBuffers;    if( numBytes < DSBSIZE_MIN )    {        result = paBufferTooSmall;        goto error;    }    if( numBytes > DSBSIZE_MAX )    {        result = paBufferTooBig;        goto error;    }    pahsc->pahsc_FramesPerDSBuffer = past->past_FramesPerUserBuffer * past->past_NumUserBuffers;    {        int msecLatency = (int) ((pahsc->pahsc_FramesPerDSBuffer * 1000) / past->past_SampleRate);        PRINT(("PortAudio on DirectSound - Latency = %d frames, %d msec\n", pahsc->pahsc_FramesPerDSBuffer, msecLatency ));    }    /* ------------------ OUTPUT */    if( (past->past_OutputDeviceID >= 0) && (past->past_NumOutputChannels > 0) )    {        DBUG(("PaHost_OpenStream: deviceID = 0x%x\n", past->past_OutputDeviceID));        pad = Pa_GetInternalDevice( past->past_OutputDeviceID );        hr = DirectSoundCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSound,   NULL );        /* If this fails, then try each output device until we find one that works. */        if( hr != DS_OK )        {            int i;            ERR_RPT(("Creation of requested Audio Output device '%s' failed.\n",                     ((pad->pad_lpGUID == NULL) ? "Default" : pad->pad_Info.name) ));            for( i=0; i<Pa_CountDevices(); i++ )            {                pad = Pa_GetInternalDevice( i );                if( pad->pad_Info.maxOutputChannels >= past->past_NumOutputChannels )                {                    DBUG(("Try device '%s' instead.\n", pad->pad_Info.name ));                    hr = DirectSoundCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSound,   NULL );                    if( hr == DS_OK )                    {                        ERR_RPT(("Using device '%s' instead.\n", pad->pad_Info.name ));                        break;                    }                }            }        }        if( hr != DS_OK )        {            ERR_RPT(("PortAudio: DirectSoundCreate() failed!\n"));            result = paHostError;            sPaHostError = hr;            goto error;        }        hr = DSW_InitOutputBuffer( dsw,                                   (unsigned long) (past->past_SampleRate + 0.5),                                   past->past_NumOutputChannels, numBytes );        DBUG(("DSW_InitOutputBuffer() returns %x\n", hr));        if( hr != DS_OK )        {            result = paHostError;            sPaHostError = hr;            goto error;        }        past->past_FrameCount = pahsc->pahsc_DSoundWrapper.dsw_FramesWritten;    }#if SUPPORT_AUDIO_CAPTURE    /* ------------------ INPUT */    if( (past->past_InputDeviceID >= 0) && (past->past_NumInputChannels > 0) )    {        pad = Pa_GetInternalDevice( past->past_InputDeviceID );        hr = DirectSoundCaptureCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSoundCapture,   NULL );        /* If this fails, then try each input device until we find one that works. */        if( hr != DS_OK )

⌨️ 快捷键说明

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