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

📄 pa_dsound.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 3 页
字号:
        {            int i;            ERR_RPT(("Creation of requested Audio Capture 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.maxInputChannels >= past->past_NumInputChannels )                {                    PRINT(("Try device '%s' instead.\n", pad->pad_Info.name ));                    hr = DirectSoundCaptureCreate( pad->pad_lpGUID, &dsw->dsw_pDirectSoundCapture,   NULL );                    if( hr == DS_OK ) break;                }            }        }        if( hr != DS_OK )        {            ERR_RPT(("PortAudio: DirectSoundCaptureCreate() failed!\n"));            result = paHostError;            sPaHostError = hr;            goto error;        }        hr = DSW_InitInputBuffer( dsw,                                  (unsigned long) (past->past_SampleRate + 0.5),                                  past->past_NumInputChannels, numBytes );        DBUG(("DSW_InitInputBuffer() returns %x\n", hr));        if( hr != DS_OK )        {            ERR_RPT(("PortAudio: DSW_InitInputBuffer() returns %x\n", hr));            result = paHostError;            sPaHostError = hr;            goto error;        }    }#endif /* SUPPORT_AUDIO_CAPTURE */    /* Calculate scalar used in CPULoad calculation. */    {        LARGE_INTEGER frequency;        if( QueryPerformanceFrequency( &frequency ) == 0 )        {            pahsc->pahsc_InverseTicksPerUserBuffer = 0.0;        }        else        {            pahsc->pahsc_InverseTicksPerUserBuffer = past->past_SampleRate /                    ( (double)frequency.QuadPart * past->past_FramesPerUserBuffer );            DBUG(("pahsc_InverseTicksPerUserBuffer = %g\n", pahsc->pahsc_InverseTicksPerUserBuffer ));        }    }    return result;error:    PaHost_CloseStream( past );    return result;}/*************************************************************************/PaError PaHost_StartOutput( internalPortAudioStream *past ){    HRESULT          hr;    PaHostSoundControl *pahsc;    PaError          result = paNoError;    pahsc = (PaHostSoundControl *) past->past_DeviceData;    /* Give user callback a chance to pre-fill buffer. */    result = Pa_TimeSlice( past );    if( result != paNoError ) return result; // FIXME - what if finished?    hr = DSW_StartOutput( &pahsc->pahsc_DSoundWrapper );    DBUG(("PaHost_StartOutput: DSW_StartOutput returned = 0x%X.\n", hr));    if( hr != DS_OK )    {        result = paHostError;        sPaHostError = hr;        goto error;    }error:    return result;}/*************************************************************************/PaError PaHost_StartInput( internalPortAudioStream *past ){    PaError          result = paNoError;#if SUPPORT_AUDIO_CAPTURE    HRESULT          hr;    PaHostSoundControl *pahsc;    pahsc = (PaHostSoundControl *) past->past_DeviceData;    hr = DSW_StartInput( &pahsc->pahsc_DSoundWrapper );    DBUG(("Pa_StartStream: DSW_StartInput returned = 0x%X.\n", hr));    if( hr != DS_OK )    {        result = paHostError;        sPaHostError = hr;        goto error;    }error:#endif /* SUPPORT_AUDIO_CAPTURE */    return result;}/*************************************************************************/PaError PaHost_StartEngine( internalPortAudioStream *past ){    PaHostSoundControl *pahsc;    PaError          result = paNoError;    pahsc = (PaHostSoundControl *) past->past_DeviceData;    past->past_StopNow = 0;    past->past_StopSoon = 0;    past->past_IsActive = 1;    /* Create timer that will wake us up so we can fill the DSound buffer. */    {        int msecPerBuffer;        int resolution;        int bufsPerInterrupt;                DBUG(("PaHost_StartEngine: past_NumUserBuffers = %d\n", past->past_NumUserBuffers));        /* Decide how often to wake up and fill the buffers. */        if( past->past_NumUserBuffers == 2 )        {            /* Generate two timer interrupts per user buffer. */            msecPerBuffer = (500 * past->past_FramesPerUserBuffer) / (int) past->past_SampleRate;        }        else        {            if ( past->past_NumUserBuffers >= 16 ) bufsPerInterrupt = past->past_NumUserBuffers/8;             else if ( past->past_NumUserBuffers >= 8 ) bufsPerInterrupt = 2;            else bufsPerInterrupt = 1;                            msecPerBuffer = 1000 * (bufsPerInterrupt * past->past_FramesPerUserBuffer) / (int) past->past_SampleRate;            DBUG(("PaHost_StartEngine: bufsPerInterrupt = %d\n", bufsPerInterrupt));        }        DBUG(("PaHost_StartEngine: msecPerBuffer = %d\n", msecPerBuffer));        if( msecPerBuffer < 10 ) msecPerBuffer = 10;        else if( msecPerBuffer > 100 ) msecPerBuffer = 100;        DBUG(("PaHost_StartEngine: clipped msecPerBuffer = %d\n", msecPerBuffer));        resolution = msecPerBuffer/4;        pahsc->pahsc_TimerID = timeSetEvent( msecPerBuffer, resolution, (LPTIMECALLBACK) Pa_TimerCallback,                                             (DWORD) past, TIME_PERIODIC );    }    if( pahsc->pahsc_TimerID == 0 )    {        past->past_IsActive = 0;        result = paHostError;        sPaHostError = 0;        goto error;    }error:    return result;}/*************************************************************************/PaError PaHost_StopEngine( internalPortAudioStream *past, int abort ){    int timeoutMsec;    PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;    if( pahsc == NULL ) return paNoError;    if( abort ) past->past_StopNow = 1;    past->past_StopSoon = 1;    /* Set timeout at 20% beyond maximum time we might wait. */    timeoutMsec = (int) (1200.0 * pahsc->pahsc_FramesPerDSBuffer / past->past_SampleRate);    while( past->past_IsActive && (timeoutMsec > 0)  )    {        Sleep(10);        timeoutMsec -= 10;    }    if( pahsc->pahsc_TimerID != 0 )    {        timeKillEvent(pahsc->pahsc_TimerID);  /* Stop callback timer. */        pahsc->pahsc_TimerID = 0;    }    return paNoError;}/*************************************************************************/PaError PaHost_StopInput( internalPortAudioStream *past, int abort ){#if SUPPORT_AUDIO_CAPTURE    HRESULT hr;    PaHostSoundControl *pahsc = (PaHostSoundControl *) past->past_DeviceData;    if( pahsc == NULL ) return paNoError;    (void) abort;    hr = DSW_StopInput( &pahsc->pahsc_DSoundWrapper );    DBUG(("DSW_StopInput() result is %x\n", hr));#endif /* SUPPORT_AUDIO_CAPTURE */    return paNoError;}/*************************************************************************/PaError PaHost_StopOutput( internalPortAudioStream *past, int abort ){    HRESULT hr;    PaHostSoundControl *pahsc;    pahsc = (PaHostSoundControl *) past->past_DeviceData;    if( pahsc == NULL ) return paNoError;    (void) abort;    hr = DSW_StopOutput( &pahsc->pahsc_DSoundWrapper );    DBUG(("DSW_StopOutput() result is %x\n", hr));    return paNoError;}/*******************************************************************/PaError PaHost_CloseStream( internalPortAudioStream   *past ){    PaHostSoundControl *pahsc;    if( past == NULL ) return paBadStreamPtr;    pahsc = (PaHostSoundControl *) past->past_DeviceData;    if( pahsc == NULL ) return paNoError;    DSW_Term( &pahsc->pahsc_DSoundWrapper );    if( pahsc->pahsc_NativeBuffer )    {        PaHost_FreeFastMemory( pahsc->pahsc_NativeBuffer, pahsc->pahsc_BytesPerBuffer ); /* MEM */        pahsc->pahsc_NativeBuffer = NULL;    }    PaHost_FreeFastMemory( pahsc, sizeof(PaHostSoundControl) ); /* MEM */    past->past_DeviceData = NULL;    return paNoError;}/* Set minimal latency based on whether NT or Win95. * NT has higher latency. */static int PaHost_GetMinSystemLatency( void ){    int minLatencyMsec;    /* Set minimal latency based on whether NT or other OS.     * NT has higher latency.     */    OSVERSIONINFO osvi;	osvi.dwOSVersionInfoSize = sizeof( osvi );	GetVersionEx( &osvi );    DBUG(("PA - PlatformId = 0x%x\n", osvi.dwPlatformId ));    DBUG(("PA - MajorVersion = 0x%x\n", osvi.dwMajorVersion ));    DBUG(("PA - MinorVersion = 0x%x\n", osvi.dwMinorVersion ));    /* Check for NT */	if( (osvi.dwMajorVersion == 4) && (osvi.dwPlatformId == 2) )	{		minLatencyMsec = PA_WIN_NT_LATENCY;	}	else if(osvi.dwMajorVersion >= 5)	{		minLatencyMsec = PA_WIN_WDM_LATENCY;	}	else	{		minLatencyMsec = PA_WIN_9X_LATENCY;	}    return minLatencyMsec;}/*************************************************************************** Determine minimum number of buffers required for this host based** on minimum latency. Latency can be optionally set by user by setting** an environment variable. For example, to set latency to 200 msec, put:****    set PA_MIN_LATENCY_MSEC=200**** in the AUTOEXEC.BAT file and reboot.** If the environment variable is not set, then the latency will be determined** based on the OS. Windows NT has higher latency than Win95.*/#define PA_LATENCY_ENV_NAME  ("PA_MIN_LATENCY_MSEC")int Pa_GetMinNumBuffers( int framesPerBuffer, double sampleRate ){    char      envbuf[PA_ENV_BUF_SIZE];    DWORD     hresult;    int       minLatencyMsec = 0;    double    msecPerBuffer = (1000.0 * framesPerBuffer) / sampleRate;    int       minBuffers;    /* Let user determine minimal latency by setting environment variable. */    hresult = GetEnvironmentVariable( PA_LATENCY_ENV_NAME, envbuf, PA_ENV_BUF_SIZE );    if( (hresult > 0) && (hresult < PA_ENV_BUF_SIZE) )    {        minLatencyMsec = atoi( envbuf );    }    else    {        minLatencyMsec = PaHost_GetMinSystemLatency();#if PA_USE_HIGH_LATENCY        PRINT(("PA - Minimum Latency set to %d msec!\n", minLatencyMsec ));#endif    }    minBuffers = (int) (1.0 + ((double)minLatencyMsec / msecPerBuffer));    if( minBuffers < 2 ) minBuffers = 2;    return minBuffers;}/*************************************************************************/PaError PaHost_Term( void ){    int i;    /* Free names allocated during enumeration. */    for( i=0; i<sNumDevices; i++ )    {        if( sDevices[i].pad_Info.name != NULL )        {            free( (void *) sDevices[i].pad_Info.name );            sDevices[i].pad_Info.name = NULL;        }    }    if( sDevices != NULL )    {        PaHost_FreeFastMemory( sDevices, sNumDevices * sizeof(internalPortAudioDevice) ); /* MEM */        sDevices = NULL;        sNumDevices = 0;    }    return 0;}void Pa_Sleep( long msec ){    Sleep( msec );}/************************************************************************* * 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(). * Memory will be set to zero. */void *PaHost_AllocateFastMemory( long numBytes ){    void *addr = GlobalAlloc( GPTR, numBytes ); /* FIXME - do we need physical memory? Use VirtualLock() */ /* MEM */    return addr;}/************************************************************************* * 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( addr != NULL ) GlobalFree( addr ); /* MEM */}/***********************************************************************/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 ){    DSoundWrapper   *dsw;    internalPortAudioStream   *past = (internalPortAudioStream *) stream;    PaHostSoundControl *pahsc;    if( past == NULL ) return paBadStreamPtr;    pahsc = (PaHostSoundControl *) past->past_DeviceData;    dsw = &pahsc->pahsc_DSoundWrapper;    return dsw->dsw_FramesPlayed;}

⌨️ 快捷键说明

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