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

📄 pa_linux_alsa.c

📁 一个开源的sip源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        numHostChannels = PA_MAX( parameters->channelCount, StreamDirection_In == streamDir ?                devInfo->minInputChannels : devInfo->minOutputChannels );    }    else        numHostChannels = parameters->channelCount;    PA_ENSURE( AlsaOpen( hostApi, parameters, streamDir, &pcm ) );    snd_pcm_hw_params_any( pcm, hwParams );    if( SetApproximateSampleRate( pcm, hwParams, sampleRate ) < 0 )    {        result = paInvalidSampleRate;        goto error;    }    if( snd_pcm_hw_params_set_channels( pcm, hwParams, numHostChannels ) < 0 )    {        result = paInvalidChannelCount;        goto error;    }    /* See if we can find a best possible match */    availableFormats = GetAvailableFormats( pcm );    PA_ENSURE( hostFormat = PaUtil_SelectClosestAvailableFormat( availableFormats, parameters->sampleFormat ) );    ENSURE_( snd_pcm_hw_params_set_format( pcm, hwParams, Pa2AlsaFormat( hostFormat ) ), paUnanticipatedHostError );    {        /* It happens that this call fails because the device is busy */        int ret = 0;        if( (ret = snd_pcm_hw_params( pcm, hwParams )) < 0)        {            if( -EINVAL == ret )            {                /* Don't know what to return here */                result = paBadIODeviceCombination;                goto error;            }            else if( -EBUSY == ret )            {                result = paDeviceUnavailable;                PA_DEBUG(( "%s: Device is busy\n", __FUNCTION__ ));            }            else            {                result = paUnanticipatedHostError;            }            ENSURE_( ret, result );        }    }end:    if( pcm )    {        snd_pcm_close( pcm );    }    return result;error:    goto end;}static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,                                  const PaStreamParameters *inputParameters,                                  const PaStreamParameters *outputParameters,                                  double sampleRate ){    int inputChannelCount = 0, outputChannelCount = 0;    PaSampleFormat inputSampleFormat, outputSampleFormat;    PaError result = paFormatIsSupported;    if( inputParameters )    {        PA_ENSURE( ValidateParameters( inputParameters, hostApi, StreamDirection_In ) );        inputChannelCount = inputParameters->channelCount;        inputSampleFormat = inputParameters->sampleFormat;    }    if( outputParameters )    {        PA_ENSURE( ValidateParameters( outputParameters, hostApi, StreamDirection_Out ) );        outputChannelCount = outputParameters->channelCount;        outputSampleFormat = outputParameters->sampleFormat;    }    if( inputChannelCount )    {        if( (result = TestParameters( hostApi, inputParameters, sampleRate, StreamDirection_In ))                != paNoError )            goto error;    }    if ( outputChannelCount )    {        if( (result = TestParameters( hostApi, outputParameters, sampleRate, StreamDirection_Out ))                != paNoError )            goto error;    }    return paFormatIsSupported;error:    return result;}static PaError PaAlsaStreamComponent_Initialize( PaAlsaStreamComponent *self, PaAlsaHostApiRepresentation *alsaApi,        const PaStreamParameters *params, StreamDirection streamDir, int callbackMode ){    PaError result = paNoError;    PaSampleFormat userSampleFormat = params->sampleFormat, hostSampleFormat;    assert( params->channelCount > 0 );    /* Make sure things have an initial value */    memset( self, 0, sizeof (PaAlsaStreamComponent) );    if( NULL == params->hostApiSpecificStreamInfo )    {        const PaAlsaDeviceInfo *devInfo = GetDeviceInfo( &alsaApi->baseHostApiRep, params->device );        self->numHostChannels = PA_MAX( params->channelCount, StreamDirection_In == streamDir ? devInfo->minInputChannels                : devInfo->minOutputChannels );    }    else    {        /* We're blissfully unaware of the minimum channelCount */        self->numHostChannels = params->channelCount;    }    self->device = params->device;    PA_ENSURE( AlsaOpen( &alsaApi->baseHostApiRep, params, streamDir, &self->pcm ) );    self->nfds = snd_pcm_poll_descriptors_count( self->pcm );    hostSampleFormat = PaUtil_SelectClosestAvailableFormat( GetAvailableFormats( self->pcm ), userSampleFormat );    self->hostSampleFormat = hostSampleFormat;    self->nativeFormat = Pa2AlsaFormat( hostSampleFormat );    self->hostInterleaved = self->userInterleaved = !(userSampleFormat & paNonInterleaved);    self->numUserChannels = params->channelCount;    self->streamDir = streamDir;    if( !callbackMode && !self->userInterleaved )    {        /* Pre-allocate non-interleaved user provided buffers */        PA_UNLESS( self->userBuffers = PaUtil_AllocateMemory( sizeof (void *) * self->numUserChannels ),                paInsufficientMemory );    }error:    return result;}static void PaAlsaStreamComponent_Terminate( PaAlsaStreamComponent *self ){    snd_pcm_close( self->pcm );    if( self->userBuffers )        PaUtil_FreeMemory( self->userBuffers );}/*static int nearbyint_(float value) {    if(  value - (int)value > .5 )        return (int)ceil( value );    return (int)floor( value );}*//** Initiate configuration, preparing for determining a period size suitable for both capture and playback components. * */static PaError PaAlsaStreamComponent_InitialConfigure( PaAlsaStreamComponent *self, const PaStreamParameters *params,        int primeBuffers, snd_pcm_hw_params_t *hwParams, double *sampleRate ){    /* 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.     */    PaError result = paNoError;    snd_pcm_access_t accessMode, alternateAccessMode;    int dir = 0;    snd_pcm_t *pcm = self->pcm;    double sr = *sampleRate;    unsigned int minPeriods = 2;    /* self->framesPerBuffer = framesPerHostBuffer; */    /* ... fill up the configuration space with all possibile     * combinations of parameters this device will accept */    ENSURE_( snd_pcm_hw_params_any( pcm, hwParams ), paUnanticipatedHostError );    ENSURE_( snd_pcm_hw_params_set_periods_integer( pcm, hwParams ), paUnanticipatedHostError );    /* I think there should be at least 2 periods (even though ALSA doesn't appear to enforce this) */    dir = 0;    ENSURE_( snd_pcm_hw_params_set_periods_min( pcm, hwParams, &minPeriods, &dir ), paUnanticipatedHostError );    if( self->userInterleaved )    {        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 )    {        int err = 0;        if( (err = snd_pcm_hw_params_set_access( pcm, hwParams, alternateAccessMode )) < 0)        {            result = paUnanticipatedHostError;            if( -EINVAL == err )            {                PaUtil_SetLastHostErrorInfo( paALSA, err, "PA ALSA requires that a device supports mmap access" );            }            else            {                PaUtil_SetLastHostErrorInfo( paALSA, err, snd_strerror( err ) );            }            goto error;        }        /* Flip mode */        self->hostInterleaved = !self->userInterleaved;    }    ENSURE_( snd_pcm_hw_params_set_format( pcm, hwParams, self->nativeFormat ), paUnanticipatedHostError );    ENSURE_( SetApproximateSampleRate( pcm, hwParams, sr ), paInvalidSampleRate );    ENSURE_( GetExactSampleRate( hwParams, &sr ), paUnanticipatedHostError );    /* reject if there's no sample rate within 1% of the one requested */    if( (fabs( *sampleRate - sr ) / *sampleRate) > 0.01 )    {        PA_DEBUG(("%s: Wanted %f, closest sample rate was %d\n", __FUNCTION__, sampleRate, sr ));                         PA_ENSURE( paInvalidSampleRate );    }    ENSURE_( snd_pcm_hw_params_set_channels( pcm, hwParams, self->numHostChannels ), paInvalidChannelCount );    *sampleRate = sr;end:    return result;error:    /* No particular action */    goto end;}/** Finish the configuration of the component's ALSA device. * * As part of this method, the component's bufferSize attribute will be set. * @param latency: The latency for this component. */static PaError PaAlsaStreamComponent_FinishConfigure( PaAlsaStreamComponent *self, snd_pcm_hw_params_t* hwParams,        const PaStreamParameters *params, int primeBuffers, double sampleRate, PaTime* latency ){    PaError result = paNoError;    snd_pcm_sw_params_t* swParams;    snd_pcm_uframes_t bufSz = 0;    *latency = -1.;    snd_pcm_sw_params_alloca( &swParams );    bufSz = (params->suggestedLatency * sampleRate) + self->framesPerBuffer;    /* One period does not count as latency */    ENSURE_( snd_pcm_hw_params_set_buffer_size_near( self->pcm, hwParams, &bufSz ), paUnanticipatedHostError );    /* Set the parameters! */    ENSURE_( snd_pcm_hw_params( self->pcm, hwParams ), paUnanticipatedHostError );    ENSURE_( snd_pcm_hw_params_get_buffer_size( hwParams, &self->bufferSize ), paUnanticipatedHostError );    /* Latency in seconds, one period is not counted as latency */    *latency = (self->bufferSize - self->framesPerBuffer) / sampleRate;    /* Now software parameters... */    ENSURE_( snd_pcm_sw_params_current( self->pcm, swParams ), paUnanticipatedHostError );    ENSURE_( snd_pcm_sw_params_set_start_threshold( self->pcm, swParams, self->framesPerBuffer ), paUnanticipatedHostError );    ENSURE_( snd_pcm_sw_params_set_stop_threshold( self->pcm, swParams, self->bufferSize ), paUnanticipatedHostError );    /* Silence buffer in the case of underrun */    if( !primeBuffers ) /* XXX: Make sense? */    {        snd_pcm_uframes_t boundary;        ENSURE_( snd_pcm_sw_params_get_boundary( swParams, &boundary ), paUnanticipatedHostError );        ENSURE_( snd_pcm_sw_params_set_silence_threshold( self->pcm, swParams, 0 ), paUnanticipatedHostError );        ENSURE_( snd_pcm_sw_params_set_silence_size( self->pcm, swParams, boundary ), paUnanticipatedHostError );    }            ENSURE_( snd_pcm_sw_params_set_avail_min( self->pcm, swParams, self->framesPerBuffer ), paUnanticipatedHostError );    ENSURE_( snd_pcm_sw_params_set_xfer_align( self->pcm, swParams, 1 ), paUnanticipatedHostError );    ENSURE_( snd_pcm_sw_params_set_tstamp_mode( self->pcm, swParams, SND_PCM_TSTAMP_MMAP ), paUnanticipatedHostError );    /* Set the parameters! */    ENSURE_( snd_pcm_sw_params( self->pcm, swParams ), paUnanticipatedHostError );error:    return result;}static PaError PaAlsaStream_Initialize( PaAlsaStream *self, PaAlsaHostApiRepresentation *alsaApi, const PaStreamParameters *inParams,        const PaStreamParameters *outParams, double sampleRate, unsigned long framesPerUserBuffer, PaStreamCallback callback,        PaStreamFlags streamFlags, void *userData ){    PaError result = paNoError;    assert( self );    memset( self, 0, sizeof (PaAlsaStream) );    if( NULL != callback )    {        PaUtil_InitializeStreamRepresentation( &self->streamRepresentation,                                               &alsaApi->callbackStreamInterface,                                               callback, userData );        self->callbackMode = 1;    }    else    {        PaUtil_InitializeStreamRepresentation( &self->streamRepresentation,                                               &alsaApi->blockingStreamInterface,                                               NULL, userData );    }    self->framesPerUserBuffer = framesPerUserBuffer;    self->neverDropInput = streamFlags & paNeverDropInput;    /* XXX: Ignore paPrimeOutputBuffersUsingStreamCallback untill buffer priming is fully supported in pa_process.c */    /*    if( outParams & streamFlags & paPrimeOutputBuffersUsingStreamCallback )        self->primeBuffers = 1;        */    memset( &self->capture, 0, sizeof (PaAlsaStreamComponent) );    memset( &self->playback, 0, sizeof (PaAlsaStreamComponent) );    if( inParams )    {        PA_ENSURE( PaAlsaStreamComponent_Initialize( &self->capture, alsaApi, inParams, StreamDirection_In, NULL != callback ) );    }    if( outParams )    {        PA_ENSURE( PaAlsaStreamComponent_Initialize( &self->playback, alsaApi, outParams, StreamDirection_Out, NULL != callback ) );    }    assert( self->capture.nfds || self->playback.nfds );

⌨️ 快捷键说明

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