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

📄 pa_dsound.c

📁 julius version 4.12.about sound recognition.
💻 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 + -