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

📄 pa_linux_alsa.c

📁 一个开源的sip源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * $Id: pa_linux_alsa.c 1196 2007-04-23 20:46:56Z aknudsen $ * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * ALSA implementation by Joshua Haberman and Arve Knudsen * * Copyright (c) 2002 Joshua Haberman <joshua@haberman.com> * Copyright (c) 2005-2006 Arve Knudsen <aknuds-1@broadpark.no> * * Based on the Open Source API proposed by Ross Bencina * Copyright (c) 1999-2002 Ross Bencina, Phil Burk * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files * (the "Software"), to deal in the Software without restriction, * including without limitation the rights to use, copy, modify, merge, * publish, distribute, sublicense, and/or sell copies of the Software, * and to permit persons to whom the Software is furnished to do so, * subject to the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *//* * The text above constitutes the entire PortAudio license; however,  * the PortAudio community also makes the following non-binding requests: * * Any person wishing to distribute modifications to the Software is * requested to send the modifications to the original developer so that * they can be incorporated into the canonical version. It is also  * requested that these non-binding requests be included along with the  * license above. *//** @file @ingroup hostapi_src*/#define ALSA_PCM_NEW_HW_PARAMS_API#define ALSA_PCM_NEW_SW_PARAMS_API#include <alsa/asoundlib.h>#undef ALSA_PCM_NEW_HW_PARAMS_API#undef ALSA_PCM_NEW_SW_PARAMS_API#include <sys/poll.h>#include <string.h> /* strlen() */#include <limits.h>#include <math.h>#include <pthread.h>#include <signal.h>#include <time.h>#include <sys/mman.h>#include <signal.h> /* For sig_atomic_t */#include "portaudio.h"#include "pa_util.h"#include "pa_unix_util.h"#include "pa_allocation.h"#include "pa_hostapi.h"#include "pa_stream.h"#include "pa_cpuload.h"#include "pa_process.h"#include "pa_endianness.h"#include "pa_linux_alsa.h"/* Check return value of ALSA function, and map it to PaError */#define ENSURE_(expr, code) \    do { \        if( UNLIKELY( (aErr_ = (expr)) < 0 ) ) \        { \            /* PaUtil_SetLastHostErrorInfo should only be used in the main thread */ \            if( (code) == paUnanticipatedHostError && pthread_equal( pthread_self(), paUnixMainThread) ) \            { \                PaUtil_SetLastHostErrorInfo( paALSA, aErr_, snd_strerror( aErr_ ) ); \            } \            PaUtil_DebugPrint( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" ); \            if( (code) == paUnanticipatedHostError ) \                PA_DEBUG(( "Host error description: %s\n", snd_strerror( aErr_ ) )); \            result = (code); \            goto error; \        } \    } while( 0 );#define ASSERT_CALL_(expr, success) \    aErr_ = (expr); \    assert( success == aErr_ );static int aErr_;               /* Used with ENSURE_ */typedef enum{    StreamDirection_In,    StreamDirection_Out} StreamDirection;typedef struct{    PaSampleFormat hostSampleFormat;    unsigned long framesPerBuffer;    int numUserChannels, numHostChannels;    int userInterleaved, hostInterleaved;    PaDeviceIndex device;     /* Keep the device index */    snd_pcm_t *pcm;    snd_pcm_uframes_t bufferSize;    snd_pcm_format_t nativeFormat;    unsigned int nfds;    int ready;  /* Marked ready from poll */    void **userBuffers;    snd_pcm_uframes_t offset;    StreamDirection streamDir;    snd_pcm_channel_area_t *channelAreas;  /* Needed for channel adaption */} PaAlsaStreamComponent;/* Implementation specific stream structure */typedef struct PaAlsaStream{    PaUtilStreamRepresentation streamRepresentation;    PaUtilCpuLoadMeasurer cpuLoadMeasurer;    PaUtilBufferProcessor bufferProcessor;    PaUnixThread thread;    unsigned long framesPerUserBuffer, maxFramesPerHostBuffer;    int primeBuffers;    int callbackMode;              /* bool: are we running in callback mode? */    int pcmsSynced;	            /* Have we successfully synced pcms */    int rtSched;    /* the callback thread uses these to poll the sound device(s), waiting     * for data to be ready/available */    struct pollfd* pfds;    int pollTimeout;    /* Used in communication between threads */    volatile sig_atomic_t callback_finished; /* bool: are we in the "callback finished" state? */    volatile sig_atomic_t callbackAbort;    /* Drop frames? */    volatile sig_atomic_t isActive;         /* Is stream in active state? (Between StartStream and StopStream || !paContinue) */    PaUnixMutex stateMtx;                   /* Used to synchronize access to stream state */    int neverDropInput;    PaTime underrun;    PaTime overrun;    PaAlsaStreamComponent capture, playback;}PaAlsaStream;/* PaAlsaHostApiRepresentation - host api datastructure specific to this implementation */typedef struct PaAlsaHostApiRepresentation{    PaUtilHostApiRepresentation baseHostApiRep;    PaUtilStreamInterface callbackStreamInterface;    PaUtilStreamInterface blockingStreamInterface;    PaUtilAllocationGroup *allocations;    PaHostApiIndex hostApiIndex;}PaAlsaHostApiRepresentation;typedef struct PaAlsaDeviceInfo{    PaDeviceInfo baseDeviceInfo;    char *alsaName;    int isPlug;    int minInputChannels;    int minOutputChannels;}PaAlsaDeviceInfo;/* prototypes for functions declared in this file */static void Terminate( struct PaUtilHostApiRepresentation *hostApi );static PaError IsFormatSupported( struct PaUtilHostApiRepresentation *hostApi,                                  const PaStreamParameters *inputParameters,                                  const PaStreamParameters *outputParameters,                                  double sampleRate );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 );static PaError CloseStream( PaStream* stream );static PaError StartStream( PaStream *stream );static PaError StopStream( PaStream *stream );static PaError AbortStream( PaStream *stream );static PaError IsStreamStopped( PaStream *s );static PaError IsStreamActive( PaStream *stream );static PaTime GetStreamTime( PaStream *stream );static double GetStreamCpuLoad( PaStream* stream );static PaError BuildDeviceList( PaAlsaHostApiRepresentation *hostApi );static int SetApproximateSampleRate( snd_pcm_t *pcm, snd_pcm_hw_params_t *hwParams, double sampleRate );static int GetExactSampleRate( snd_pcm_hw_params_t *hwParams, double *sampleRate );/* Callback prototypes */static void *CallbackThreadFunc( void *userData );/* Blocking prototypes */static signed long GetStreamReadAvailable( PaStream* s );static signed long GetStreamWriteAvailable( PaStream* s );static PaError ReadStream( PaStream* stream, void *buffer, unsigned long frames );static PaError WriteStream( PaStream* stream, const void *buffer, unsigned long frames );static const PaAlsaDeviceInfo *GetDeviceInfo( const PaUtilHostApiRepresentation *hostApi, int device ){    return (const PaAlsaDeviceInfo *)hostApi->deviceInfos[device];}static void AlsaErrorHandler(const char *file, int line, const char *function, int err, const char *fmt, ...){}PaError PaAlsa_Initialize( PaUtilHostApiRepresentation **hostApi, PaHostApiIndex hostApiIndex ){    PaError result = paNoError;    PaAlsaHostApiRepresentation *alsaHostApi = NULL;    PA_UNLESS( alsaHostApi = (PaAlsaHostApiRepresentation*) PaUtil_AllocateMemory(                sizeof(PaAlsaHostApiRepresentation) ), paInsufficientMemory );    PA_UNLESS( alsaHostApi->allocations = PaUtil_CreateAllocationGroup(), paInsufficientMemory );    alsaHostApi->hostApiIndex = hostApiIndex;    *hostApi = (PaUtilHostApiRepresentation*)alsaHostApi;    (*hostApi)->info.structVersion = 1;    (*hostApi)->info.type = paALSA;    (*hostApi)->info.name = "ALSA";    (*hostApi)->Terminate = Terminate;    (*hostApi)->OpenStream = OpenStream;    (*hostApi)->IsFormatSupported = IsFormatSupported;    ENSURE_( snd_lib_error_set_handler(AlsaErrorHandler), paUnanticipatedHostError );    PA_ENSURE( BuildDeviceList( alsaHostApi ) );    PaUtil_InitializeStreamInterface( &alsaHostApi->callbackStreamInterface,                                      CloseStream, StartStream,                                      StopStream, AbortStream,                                      IsStreamStopped, IsStreamActive,                                      GetStreamTime, GetStreamCpuLoad,                                      PaUtil_DummyRead, PaUtil_DummyWrite,                                      PaUtil_DummyGetReadAvailable,                                      PaUtil_DummyGetWriteAvailable );    PaUtil_InitializeStreamInterface( &alsaHostApi->blockingStreamInterface,                                      CloseStream, StartStream,                                      StopStream, AbortStream,                                      IsStreamStopped, IsStreamActive,                                      GetStreamTime, PaUtil_DummyGetCpuLoad,                                      ReadStream, WriteStream,                                      GetStreamReadAvailable,                                      GetStreamWriteAvailable );    PA_ENSURE( PaUnixThreading_Initialize() );    return result;error:    if( alsaHostApi )    {        if( alsaHostApi->allocations )        {            PaUtil_FreeAllAllocations( alsaHostApi->allocations );            PaUtil_DestroyAllocationGroup( alsaHostApi->allocations );        }        PaUtil_FreeMemory( alsaHostApi );    }    return result;}static void Terminate( struct PaUtilHostApiRepresentation *hostApi ){    PaAlsaHostApiRepresentation *alsaHostApi = (PaAlsaHostApiRepresentation*)hostApi;    assert( hostApi );    if( alsaHostApi->allocations )    {        PaUtil_FreeAllAllocations( alsaHostApi->allocations );        PaUtil_DestroyAllocationGroup( alsaHostApi->allocations );    }    PaUtil_FreeMemory( alsaHostApi );    snd_config_update_free_global();}/** Determine max channels and default latencies. * * This function provides functionality to grope an opened (might be opened for capture or playback) pcm device for  * traits like max channels, suitable default latencies and default sample rate. Upon error, max channels is set to zero, * and a suitable result returned. The device is closed before returning. */static PaError GropeDevice( snd_pcm_t* pcm, int isPlug, StreamDirection mode, int openBlocking,        PaAlsaDeviceInfo* devInfo, int* canMmap ){    PaError result = paNoError;    snd_pcm_hw_params_t *hwParams;    snd_pcm_uframes_t lowLatency = 512, highLatency = 2048;    unsigned int minChans, maxChans;    int* minChannels, * maxChannels;    double * defaultLowLatency, * defaultHighLatency, * defaultSampleRate =        &devInfo->baseDeviceInfo.defaultSampleRate;    double defaultSr = *defaultSampleRate;    assert( pcm );    if( StreamDirection_In == mode )    {        minChannels = &devInfo->minInputChannels;        maxChannels = &devInfo->baseDeviceInfo.maxInputChannels;        defaultLowLatency = &devInfo->baseDeviceInfo.defaultLowInputLatency;        defaultHighLatency = &devInfo->baseDeviceInfo.defaultHighInputLatency;    }    else    {        minChannels = &devInfo->minOutputChannels;        maxChannels = &devInfo->baseDeviceInfo.maxOutputChannels;        defaultLowLatency = &devInfo->baseDeviceInfo.defaultLowOutputLatency;        defaultHighLatency = &devInfo->baseDeviceInfo.defaultHighOutputLatency;    }    ENSURE_( snd_pcm_nonblock( pcm, 0 ), paUnanticipatedHostError );

⌨️ 快捷键说明

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