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

📄 pa_jack.c

📁 一个开源的sip源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/* * $Id: pa_jack.c 1186 2007-04-02 17:56:26Z aknudsen $ * PortAudio Portable Real-Time Audio Library * Latest Version at: http://www.portaudio.com * JACK Implementation by Joshua Haberman * * Copyright (c) 2004 Stefan Westerfeld <stefan@space.twc.de> * Copyright (c) 2004 Arve Knudsen <aknuds-1@broadpark.no> * Copyright (c) 2002 Joshua Haberman <joshua@haberman.com> * * 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 hostaip_src*/#include <string.h>#include <regex.h>#include <stdlib.h>#include <stdio.h>#include <assert.h>#include <sys/types.h>#include <unistd.h>#include <errno.h>  /* EBUSY */#include <signal.h> /* sig_atomic_t */#include <math.h>#include <semaphore.h>#include <jack/types.h>#include <jack/jack.h>#include "pa_util.h"#include "pa_hostapi.h"#include "pa_stream.h"#include "pa_process.h"#include "pa_allocation.h"#include "pa_cpuload.h"#include "pa_ringbuffer.h"static int aErr_;static PaError paErr_;     /* For use with ENSURE_PA */static pthread_t mainThread_;static char *jackErr_ = NULL;#define STRINGIZE_HELPER(expr) #expr#define STRINGIZE(expr) STRINGIZE_HELPER(expr)/* Check PaError */#define ENSURE_PA(expr) \    do { \        if( (paErr_ = (expr)) < paNoError ) \        { \            if( (paErr_) == paUnanticipatedHostError && pthread_self() == mainThread_ ) \            { \                if (! jackErr_ ) jackErr_ = "unknown error";\                PaUtil_SetLastHostErrorInfo( paJACK, -1, jackErr_ ); \            } \            PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \            result = paErr_; \            goto error; \        } \    } while( 0 )#define UNLESS(expr, code) \    do { \        if( (expr) == 0 ) \        { \            if( (code) == paUnanticipatedHostError && pthread_self() == mainThread_ ) \            { \                if (!jackErr_) jackErr_ = "unknown error";\                PaUtil_SetLastHostErrorInfo( paJACK, -1, jackErr_ ); \            } \            PaUtil_DebugPrint(( "Expression '" #expr "' failed in '" __FILE__ "', line: " STRINGIZE( __LINE__ ) "\n" )); \            result = (code); \            goto error; \        } \    } while( 0 )#define ASSERT_CALL(expr, success) \    aErr_ = (expr); \    assert( aErr_ == success );/* * Functions that directly map to the PortAudio stream interface */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 *streamCallback,                           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 GetStreamInputLatency( PaStream *stream );*//*static PaTime GetStreamOutputLatency( PaStream *stream );*/static PaTime GetStreamTime( PaStream *stream );static double GetStreamCpuLoad( PaStream* stream );/* * Data specific to this API */struct PaJackStream;typedef struct{    PaUtilHostApiRepresentation commonHostApiRep;    PaUtilStreamInterface callbackStreamInterface;    PaUtilStreamInterface blockingStreamInterface;    PaUtilAllocationGroup *deviceInfoMemory;    jack_client_t *jack_client;    int jack_buffer_size;    PaHostApiIndex hostApiIndex;    pthread_mutex_t mtx;    pthread_cond_t cond;    unsigned long inputBase, outputBase;    /* For dealing with the process thread */    volatile int xrun;     /* Received xrun notification from JACK? */    struct PaJackStream * volatile toAdd, * volatile toRemove;    struct PaJackStream *processQueue;    volatile sig_atomic_t jackIsDown;}PaJackHostApiRepresentation;/* PaJackStream - a stream data structure specifically for this implementation */typedef struct PaJackStream{    PaUtilStreamRepresentation streamRepresentation;    PaUtilBufferProcessor bufferProcessor;    PaUtilCpuLoadMeasurer cpuLoadMeasurer;    PaJackHostApiRepresentation *hostApi;    /* our input and output ports */    jack_port_t **local_input_ports;    jack_port_t **local_output_ports;    /* the input and output ports of the client we are connecting to */    jack_port_t **remote_input_ports;    jack_port_t **remote_output_ports;    int num_incoming_connections;    int num_outgoing_connections;    jack_client_t *jack_client;    /* The stream is running if it's still producing samples.     * The stream is active if samples it produced are still being heard.     */    volatile sig_atomic_t is_running;    volatile sig_atomic_t is_active;    /* Used to signal processing thread that stream should start or stop, respectively */    volatile sig_atomic_t doStart, doStop, doAbort;    jack_nframes_t t0;    PaUtilAllocationGroup *stream_memory;    /* These are useful in the process callback */    int callbackResult;    int isSilenced;    int xrun;    /* These are useful for the blocking API */    int                     isBlockingStream;    PaUtilRingBuffer        inFIFO;    PaUtilRingBuffer        outFIFO;    volatile sig_atomic_t   data_available;    sem_t                   data_semaphore;    int                     bytesPerFrame;    int                     samplesPerFrame;    struct PaJackStream *next;}PaJackStream;#define TRUE 1#define FALSE 0/* * Functions specific to this API */static int JackCallback( jack_nframes_t frames, void *userData );/* * * Implementation * *//* ---- blocking emulation layer ---- *//* Allocate buffer. */static PaError BlockingInitFIFO( PaUtilRingBuffer *rbuf, long numFrames, long bytesPerFrame ){    long numBytes = numFrames * bytesPerFrame;    char *buffer = (char *) malloc( numBytes );    if( buffer == NULL ) return paInsufficientMemory;    memset( buffer, 0, numBytes );    return (PaError) PaUtil_InitializeRingBuffer( rbuf, numBytes, buffer );}/* Free buffer. */static PaError BlockingTermFIFO( PaUtilRingBuffer *rbuf ){    if( rbuf->buffer ) free( rbuf->buffer );    rbuf->buffer = NULL;    return paNoError;}static intBlockingCallback( const void                      *inputBuffer,                  void                            *outputBuffer,		  unsigned long                    framesPerBuffer,		  const PaStreamCallbackTimeInfo*  timeInfo,		  PaStreamCallbackFlags            statusFlags,		  void                             *userData ){    struct PaJackStream *stream = (PaJackStream *)userData;    long numBytes = stream->bytesPerFrame * framesPerBuffer;    /* This may get called with NULL inputBuffer during initial setup. */    if( inputBuffer != NULL )    {        PaUtil_WriteRingBuffer( &stream->inFIFO, inputBuffer, numBytes );    }    if( outputBuffer != NULL )    {        int numRead = PaUtil_ReadRingBuffer( &stream->outFIFO, outputBuffer, numBytes );        /* Zero out remainder of buffer if we run out of data. */        memset( (char *)outputBuffer + numRead, 0, numBytes - numRead );    }    if( !stream->data_available )    {        stream->data_available = 1;        sem_post( &stream->data_semaphore );    }    return paContinue;}static PaErrorBlockingBegin( PaJackStream *stream, int minimum_buffer_size ){    long    doRead = 0;    long    doWrite = 0;    PaError result = paNoError;    long    numFrames;    doRead = stream->local_input_ports != NULL;    doWrite = stream->local_output_ports != NULL;    /* <FIXME> */    stream->samplesPerFrame = 2;    stream->bytesPerFrame = sizeof(float) * stream->samplesPerFrame;    /* </FIXME> */    numFrames = 32;    while (numFrames < minimum_buffer_size)        numFrames *= 2;    if( doRead )    {        ENSURE_PA( BlockingInitFIFO( &stream->inFIFO, numFrames, stream->bytesPerFrame ) );    }    if( doWrite )    {        long numBytes;        ENSURE_PA( BlockingInitFIFO( &stream->outFIFO, numFrames, stream->bytesPerFrame ) );        /* Make Write FIFO appear full initially. */        numBytes = PaUtil_GetRingBufferWriteAvailable( &stream->outFIFO );        PaUtil_AdvanceRingBufferWriteIndex( &stream->outFIFO, numBytes );    }    stream->data_available = 0;    sem_init( &stream->data_semaphore, 0, 0 );error:    return result;}static voidBlockingEnd( PaJackStream *stream ){    BlockingTermFIFO( &stream->inFIFO );    BlockingTermFIFO( &stream->outFIFO );    sem_destroy( &stream->data_semaphore );}static PaError BlockingReadStream( PaStream* s, void *data, unsigned long numFrames ){    PaError result = paNoError;

⌨️ 快捷键说明

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