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

📄 pa_linux_alsa.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 5 页
字号:
    {        if( outputParameters->device != paUseHostApiSpecificDeviceSpecification )        {            assert( outputParameters->device < hostApi->info.deviceCount );            outputDeviceInfo = (PaAlsaDeviceInfo *)hostApi->deviceInfos[ outputParameters->device ];        }        else            outputStreamInfo = outputParameters->hostApiSpecificStreamInfo;        PA_ENSURE( ValidateParameters( outputParameters, outputDeviceInfo, streamOut, outputStreamInfo ) );        outputChannelCount = outputParameters->channelCount;        outputSampleFormat = outputParameters->sampleFormat;    }    /*        IMPLEMENT ME:            - if a full duplex stream is requested, check that the combination                of input and output parameters is supported if necessary            - check that the device supports sampleRate        Because the buffer adapter handles conversion between all standard        sample formats, the following checks are only required if paCustomFormat        is implemented, or under some other unusual conditions.            - check that input device can support inputSampleFormat, or that                we have the capability to convert from outputSampleFormat to                a native format            - check that output device can support outputSampleFormat, or that                we have the capability to convert from outputSampleFormat to                a native format    */    if( inputChannelCount )    {        PA_ENSURE( TestParameters( inputParameters, inputDeviceInfo, inputStreamInfo, sampleRate, SND_PCM_STREAM_CAPTURE ) );    }    if ( outputChannelCount )    {        PA_ENSURE( TestParameters( outputParameters, outputDeviceInfo, outputStreamInfo, sampleRate, SND_PCM_STREAM_PLAYBACK ) );    }    return paFormatIsSupported;error:    return result;}/* see pa_hostapi.h for a list of validity guarantees made about OpenStream parameters */static PaError ConfigureStream( snd_pcm_t *pcm, int channels, int *interleaved, double *sampleRate,                                PaSampleFormat paFormat, unsigned long framesPerBuffer, snd_pcm_uframes_t                                *bufferSize, PaTime *latency, int primeBuffers, int callbackMode ){    /*    int numPeriods;    if( getenv("PA_NUMPERIODS") != NULL )        numPeriods = atoi( getenv("PA_NUMPERIODS") );    else        numPeriods = ( (*latency * sampleRate) / *framesPerBuffer ) + 1;    PA_DEBUG(( "latency: %f, rate: %f, framesPerBuffer: %d\n", *latency, sampleRate, *framesPerBuffer ));    if( numPeriods <= 1 )        numPeriods = 2;    */    /* configuration consists of setting all of ALSA's parameters.     * These parameters come in two flavors: hardware parameters     * and software paramters.  Hardware parameters will affect     * the way the device is initialized, software parameters     * affect the way ALSA interacts with me, the user-level client. */    snd_pcm_hw_params_t *hwParams;    snd_pcm_sw_params_t *swParams;    PaError result = paNoError;    snd_pcm_access_t accessMode, alternateAccessMode;    snd_pcm_format_t alsaFormat;    unsigned int numPeriods;    snd_pcm_hw_params_alloca( &hwParams );    snd_pcm_sw_params_alloca( &swParams );    /* ... fill up the configuration space with all possibile     * combinations of parameters this device will accept */    ENSURE( snd_pcm_hw_params_any( pcm, hwParams ), paUnanticipatedHostError );    if( *interleaved )    {        accessMode = SND_PCM_ACCESS_MMAP_INTERLEAVED;        alternateAccessMode = SND_PCM_ACCESS_MMAP_NONINTERLEAVED;    }    else    {        accessMode = SND_PCM_ACCESS_MMAP_NONINTERLEAVED;        alternateAccessMode = SND_PCM_ACCESS_MMAP_INTERLEAVED;    }    /* If requested access mode fails, try alternate mode */    if( snd_pcm_hw_params_set_access( pcm, hwParams, accessMode ) < 0 ) {        ENSURE( snd_pcm_hw_params_set_access( pcm, hwParams, alternateAccessMode ), paUnanticipatedHostError );        *interleaved = !(*interleaved);     /* Flip mode */    }    /* set the format based on what the user selected */    alsaFormat = Pa2AlsaFormat( paFormat );    assert( alsaFormat != SND_PCM_FORMAT_UNKNOWN );    ENSURE( snd_pcm_hw_params_set_format( pcm, hwParams, alsaFormat ), paUnanticipatedHostError );    /* ... set the sample rate */    ENSURE( SetApproximateSampleRate( pcm, hwParams, *sampleRate ), paInvalidSampleRate );    ENSURE( GetExactSampleRate( hwParams, sampleRate ), paUnanticipatedHostError );    /* ... set the number of channels */    ENSURE( snd_pcm_hw_params_set_channels( pcm, hwParams, channels ), paInvalidChannelCount );    /* Set buffer size */    ENSURE( snd_pcm_hw_params_set_periods_integer( pcm, hwParams ), paUnanticipatedHostError );    ENSURE( snd_pcm_hw_params_set_period_size_integer( pcm, hwParams ), paUnanticipatedHostError );    ENSURE( snd_pcm_hw_params_set_period_size( pcm, hwParams, framesPerBuffer, 0 ), paUnanticipatedHostError );    /* Find an acceptable number of periods */    numPeriods = (*latency * *sampleRate) / framesPerBuffer + 1;    numPeriods = MAX( numPeriods, 2 );  /* Should be at least 2 periods I think? */    ENSURE( snd_pcm_hw_params_set_periods_near( pcm, hwParams, &numPeriods, NULL ), paUnanticipatedHostError );    /*    PA_DEBUG(( "numperiods: %d\n", numPeriods ));    if( snd_pcm_hw_params_set_periods ( pcm, hwParams, numPeriods, 0 ) < 0 )    {        int i;        for( i = numPeriods; i >= 2; i-- )        {            if( snd_pcm_hw_params_set_periods( pcm, hwParams, i, 0 ) >= 0 )            {                PA_DEBUG(( "settled on %d periods\n", i ));                break;            }        }    }    */    /* Set the parameters! */    ENSURE( snd_pcm_hw_params( pcm, hwParams ), paUnanticipatedHostError );    ENSURE( snd_pcm_hw_params_get_buffer_size( hwParams, bufferSize ), paUnanticipatedHostError );    /* Latency in seconds, one period is not counted as latency */    *latency = (numPeriods - 1) * framesPerBuffer / *sampleRate;    /* Now software parameters... */    ENSURE( snd_pcm_sw_params_current( pcm, swParams ), paUnanticipatedHostError );    ENSURE( snd_pcm_sw_params_set_start_threshold( pcm, swParams, framesPerBuffer ), paUnanticipatedHostError );    ENSURE( snd_pcm_sw_params_set_stop_threshold( pcm, swParams, *bufferSize ), paUnanticipatedHostError );    /* Silence buffer in the case of underrun */    if( !primeBuffers )    {        ENSURE( snd_pcm_sw_params_set_silence_threshold( pcm, swParams, 0 ), paUnanticipatedHostError );        ENSURE( snd_pcm_sw_params_set_silence_size( pcm, swParams, INT_MAX ), paUnanticipatedHostError );    }            ENSURE( snd_pcm_sw_params_set_avail_min( pcm, swParams, framesPerBuffer ), paUnanticipatedHostError );    ENSURE( snd_pcm_sw_params_set_xfer_align( pcm, swParams, 1 ), paUnanticipatedHostError );    ENSURE( snd_pcm_sw_params_set_tstamp_mode( pcm, swParams, SND_PCM_TSTAMP_MMAP ), paUnanticipatedHostError );    /* Set the parameters! */    ENSURE( snd_pcm_sw_params( pcm, swParams ), paUnanticipatedHostError );end:    return result;error:    goto end;   /* No particular action */}static void InitializeStream( PaAlsaStream *stream, int callback, PaStreamFlags streamFlags ){    assert( stream );    stream->pcm_capture = NULL;    stream->pcm_playback = NULL;    stream->callback_finished = 0;    stream->callback_mode = callback;    stream->capture_nfds = 0;    stream->playback_nfds = 0;    stream->pfds = NULL;    stream->pollTimeout = 0;    stream->pcmsSynced = 0;    stream->callbackAbort = 0;    stream->isActive = 0;    stream->startThreshold = 0;    pthread_mutex_init( &stream->stateMtx, NULL );    pthread_mutex_init( &stream->startMtx, NULL );    pthread_cond_init( &stream->startCond, NULL );    stream->neverDropInput = 0;    stream->underrun = stream->overrun = 0.0;}static PaError OpenStream( struct PaUtilHostApiRepresentation *hostApi,                           PaStream** s,                           const PaStreamParameters *inputParameters,                           const PaStreamParameters *outputParameters,                           double sampleRate,                           unsigned long framesPerBuffer,                           PaStreamFlags streamFlags,                           PaStreamCallback *callback,                           void *userData ){    PaError result = paNoError;    PaAlsaHostApiRepresentation *alsaHostApi = (PaAlsaHostApiRepresentation*)hostApi;    const PaAlsaDeviceInfo *inputDeviceInfo = 0, *outputDeviceInfo = 0;    PaAlsaStream *stream = 0;    PaSampleFormat hostInputSampleFormat = 0, hostOutputSampleFormat = 0;    int numInputChannels = 0, numOutputChannels = 0;    PaSampleFormat inputSampleFormat = 0, outputSampleFormat = 0;    unsigned long framesPerHostBuffer = framesPerBuffer;    PaAlsaStreamInfo *inputStreamInfo = NULL, *outputStreamInfo = NULL;    PaTime inputLatency, outputLatency;    if( inputParameters )    {        if( inputParameters->device != paUseHostApiSpecificDeviceSpecification )        {            assert( inputParameters->device < hostApi->info.deviceCount );            inputDeviceInfo = (PaAlsaDeviceInfo*)hostApi->deviceInfos[ inputParameters->device ];        }        else            inputStreamInfo = inputParameters->hostApiSpecificStreamInfo;        PA_ENSURE( ValidateParameters( inputParameters, inputDeviceInfo, streamIn, inputStreamInfo ) );        numInputChannels = inputParameters->channelCount;        inputSampleFormat = inputParameters->sampleFormat;    }    if( outputParameters )    {        if( outputParameters->device != paUseHostApiSpecificDeviceSpecification )        {            assert( outputParameters->device < hostApi->info.deviceCount );            outputDeviceInfo = (PaAlsaDeviceInfo*)hostApi->deviceInfos[ outputParameters->device ];        }        else            outputStreamInfo = outputParameters->hostApiSpecificStreamInfo;        PA_ENSURE( ValidateParameters( outputParameters, outputDeviceInfo, streamOut, outputStreamInfo ) );        /*        outputDeviceInfo = (PaAlsaDeviceInfo*)hostApi->deviceInfos[ outputParameters->device ];        PA_ENSURE( ValidateParameters( outputParameters, outputDeviceInfo->commonDeviceInfo.maxOutputChannels ) );        */        numOutputChannels = outputParameters->channelCount;        outputSampleFormat = outputParameters->sampleFormat;    }    /* validate platform specific flags */    if( (streamFlags & paPlatformSpecificFlags) != 0 )        return paInvalidFlag; /* unexpected platform specific flag */    /* allocate and do basic initialization of the stream structure */    UNLESS( stream = (PaAlsaStream*)PaUtil_AllocateMemory( sizeof(PaAlsaStream) ), paInsufficientMemory );    InitializeStream( stream, (int) callback, streamFlags );    /* Initialize structure */    if( callback )    {        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,                                               &alsaHostApi->callbackStreamInterface,                                               callback, userData );    }    else    {        PaUtil_InitializeStreamRepresentation( &stream->streamRepresentation,                                               &alsaHostApi->blockingStreamInterface,                                               callback, userData );    }    PaUtil_InitializeCpuLoadMeasurer( &stream->cpuLoadMeasurer, sampleRate );    /* open the devices now, so we can obtain info about the available formats */    if( numInputChannels > 0 )    {        PA_ENSURE( AlsaOpen( &stream->pcm_capture, inputDeviceInfo, inputStreamInfo, SND_PCM_STREAM_CAPTURE ) );        stream->capture_nfds = snd_pcm_poll_descriptors_count( stream->pcm_capture );        hostInputSampleFormat =            PaUtil_SelectClosestAvailableFormat( GetAvailableFormats( stream->pcm_capture ),                                                 inputSampleFormat );    }    if( numOutputChannels > 0 )    {        PA_ENSURE( AlsaOpen( &stream->pcm_playback, outputDeviceInfo, outputStreamInfo, SND_PCM_STREAM_PLAYBACK ) );        stream->playback_nfds = snd_pcm_poll_descriptors_count( stream->pcm_playback );        hostOutputSampleFormat =            PaUtil_SelectClosestAvailableFormat( GetAvailableFormats( stream->pcm_playback ),                                                 outputSampleFormat );        stream->playbackNativeFormat = Pa2AlsaFormat( hostOutputSampleFormat );    }    /* If the number of frames per buffer is unspecified, we have to come up with     * one.  This is both a blessing and a curse: a blessing because we can optimize     * the number to best meet the requirements, but a curse because that's really     * hard to do well.  For this reason we also support an interface where the user     * specifies these by setting environment variables. */    if( framesPerBuffer == paFramesPerBufferUnspecified )    {        if( getenv("PA_ALSA_PERIODSIZE") != NULL )            framesPerHostBuffer = atoi( getenv("PA_ALSA_PERIODSIZE") );        else        {            /* We need to determine how many frames per host buffer to use.  Our             * goals are to provide the best possible performance, but also to             * most closely honor the requested latency settings.  Therefore this             * decision is based on:             *             *   - the period sizes that playback and/or capture support.  The             *     host buffer size has to be one of these.             *   - the number of periods that playback and/or capture support.             *             * We want to make period_size*(num_periods-1) to be as close as possible             * to latency*rate for both playback and capture.             *             * This is one of those blocks of code that will just take a lot of             * refinement to be any good.             */            if( stream->pcm_capture && stream->pcm_playback )            {                snd_pcm_uframes_t desiredLatency, e;                snd_pcm_uframes_t minPeriodSize, minPlayback, minCapture, maxPeriodSize, maxPlayback, maxCapture,                    optimalPeriodSize, periodSize;                int dir;                snd_pcm_t *pcm;                snd_pcm_hw_params_t *hwParamsPlayback, *hwParamsCapture;

⌨️ 快捷键说明

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