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

📄 pa_jack.c

📁 一个开源的sip源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
        PaUtil_SetNonInterleavedOutputChannel( &stream->bufferProcessor,                chn,                channel_buf );    }    framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor,            &stream->callbackResult );    /* We've specified a host buffer size mode where every frame should be consumed by the buffer processor */    assert( framesProcessed == frames );    PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed );end:    return result;}/* Alter the processing queue if necessary */static PaError UpdateQueue( PaJackHostApiRepresentation *hostApi ){    PaError result = paNoError;    int queueModified = 0;    const double jackSr = jack_get_sample_rate( hostApi->jack_client );    int err;    if( (err = pthread_mutex_trylock( &hostApi->mtx )) != 0 )    {        assert( err == EBUSY );        return paNoError;    }    if( hostApi->toAdd )    {        if( hostApi->processQueue )        {            PaJackStream *node = hostApi->processQueue;            /* Advance to end of queue */            while( node->next )                node = node->next;            node->next = hostApi->toAdd;        }        else            hostApi->processQueue = (PaJackStream *)hostApi->toAdd;        /* If necessary, update stream state */        if( hostApi->toAdd->streamRepresentation.streamInfo.sampleRate != jackSr )            UpdateSampleRate( hostApi->toAdd, jackSr );        hostApi->toAdd = NULL;        queueModified = 1;    }    if( hostApi->toRemove )    {        int removed = 0;        PaJackStream *node = hostApi->processQueue, *prev = NULL;        assert( hostApi->processQueue );        while( node )        {            if( node == hostApi->toRemove )            {                if( prev )                    prev->next = node->next;                else                    hostApi->processQueue = (PaJackStream *)node->next;                removed = 1;                break;            }            prev = node;            node = node->next;        }        UNLESS( removed, paInternalError );        hostApi->toRemove = NULL;        PA_DEBUG(( "%s: Removed stream from processing queue\n", __FUNCTION__ ));        queueModified = 1;    }    if( queueModified )    {        /* Signal that we've done what was asked of us */        ASSERT_CALL( pthread_cond_signal( &hostApi->cond ), 0 );    }error:    ASSERT_CALL( pthread_mutex_unlock( &hostApi->mtx ), 0 );    return result;}static int JackCallback( jack_nframes_t frames, void *userData ){    PaError result = paNoError;    PaJackHostApiRepresentation *hostApi = (PaJackHostApiRepresentation *)userData;    PaJackStream *stream = NULL;    int xrun = hostApi->xrun;    hostApi->xrun = 0;    assert( hostApi );    ENSURE_PA( UpdateQueue( hostApi ) );    /* Process each stream */    stream = hostApi->processQueue;    for( ; stream; stream = stream->next )    {        if( xrun )  /* Don't override if already set */            stream->xrun = 1;        /* See if this stream is to be started */        if( stream->doStart )        {            /* If we can't obtain a lock, we'll try next time */            int err = pthread_mutex_trylock( &stream->hostApi->mtx );            if( !err )            {                if( stream->doStart )   /* Could potentially change before obtaining the lock */                {                    stream->is_active = 1;                    stream->doStart = 0;                    PA_DEBUG(( "%s: Starting stream\n", __FUNCTION__ ));                    ASSERT_CALL( pthread_cond_signal( &stream->hostApi->cond ), 0 );                    stream->callbackResult = paContinue;                    stream->isSilenced = 0;                }                ASSERT_CALL( pthread_mutex_unlock( &stream->hostApi->mtx ), 0 );            }            else                assert( err == EBUSY );        }        else if( stream->doStop || stream->doAbort )    /* Should we stop/abort stream? */        {            if( stream->callbackResult == paContinue )     /* Ok, make it stop */            {                PA_DEBUG(( "%s: Stopping stream\n", __FUNCTION__ ));                stream->callbackResult = stream->doStop ? paComplete : paAbort;            }        }        if( stream->is_active )            ENSURE_PA( RealProcess( stream, frames ) );        /* If we have just entered inactive state, silence output */        if( !stream->is_active && !stream->isSilenced )        {            int i;            /* Silence buffer after entering inactive state */            PA_DEBUG(( "Silencing the output\n" ));            for( i = 0; i < stream->num_outgoing_connections; ++i )            {                jack_default_audio_sample_t *buffer = jack_port_get_buffer( stream->local_output_ports[i], frames );                memset( buffer, 0, sizeof (jack_default_audio_sample_t) * frames );            }            stream->isSilenced = 1;        }        if( stream->doStop || stream->doAbort )        {            /* See if RealProcess has acted on the request */            if( !stream->is_active )   /* Ok, signal to the main thread that we've carried out the operation */            {                /* If we can't obtain a lock, we'll try next time */                int err = pthread_mutex_trylock( &stream->hostApi->mtx );                if( !err )                {                    stream->doStop = stream->doAbort = 0;                    ASSERT_CALL( pthread_cond_signal( &stream->hostApi->cond ), 0 );                    ASSERT_CALL( pthread_mutex_unlock( &stream->hostApi->mtx ), 0 );                }                else                    assert( err == EBUSY );            }        }    }    return 0;error:    return -1;}static PaError StartStream( PaStream *s ){    PaError result = paNoError;    PaJackStream *stream = (PaJackStream*)s;    int i;    /* Ready the processor */    PaUtil_ResetBufferProcessor( &stream->bufferProcessor );    /* connect the ports */    /* NOTE: I would rather use jack_port_connect which uses jack_port_t's     * instead of port names, but it is not implemented yet. */    if( stream->num_incoming_connections > 0 )    {        for( i = 0; i < stream->num_incoming_connections; i++ )            UNLESS( jack_connect( stream->jack_client,                    jack_port_name( stream->remote_output_ports[i] ),                    jack_port_name( stream->local_input_ports[i] ) ) == 0, paUnanticipatedHostError );    }    if( stream->num_outgoing_connections > 0 )    {        for( i = 0; i < stream->num_outgoing_connections; i++ )            UNLESS( jack_connect( stream->jack_client,                    jack_port_name( stream->local_output_ports[i] ),                    jack_port_name( stream->remote_input_ports[i] ) ) == 0, paUnanticipatedHostError );    }    stream->xrun = FALSE;    /* Enable processing */    ASSERT_CALL( pthread_mutex_lock( &stream->hostApi->mtx ), 0 );    stream->doStart = 1;    /* Wait for stream to be started */    result = WaitCondition( stream->hostApi );    /*    do    {        err = pthread_cond_timedwait( &stream->hostApi->cond, &stream->hostApi->mtx, &ts );    } while( !stream->is_active && !err );    */    if( result != paNoError )   /* Something went wrong, call off the stream start */    {        stream->doStart = 0;        stream->is_active = 0;  /* Cancel any processing */    }    ASSERT_CALL( pthread_mutex_unlock( &stream->hostApi->mtx ), 0 );    ENSURE_PA( result );    stream->is_running = TRUE;    PA_DEBUG(( "%s: Stream started\n", __FUNCTION__ ));error:    return result;}static PaError RealStop( PaJackStream *stream, int abort ){    PaError result = paNoError;    int i;    if( stream->isBlockingStream )        BlockingWaitEmpty ( stream );    ASSERT_CALL( pthread_mutex_lock( &stream->hostApi->mtx ), 0 );    if( abort )        stream->doAbort = 1;    else        stream->doStop = 1;    /* Wait for stream to be stopped */    result = WaitCondition( stream->hostApi );    ASSERT_CALL( pthread_mutex_unlock( &stream->hostApi->mtx ), 0 );    ENSURE_PA( result );    UNLESS( !stream->is_active, paInternalError );        PA_DEBUG(( "%s: Stream stopped\n", __FUNCTION__ ));error:    stream->is_running = FALSE;    /* Disconnect ports belonging to this stream */    if( !stream->hostApi->jackIsDown )  /* XXX: Well? */    {        for( i = 0; i < stream->num_incoming_connections; i++ )        {            UNLESS( !jack_port_lock( stream->jack_client, stream->local_input_ports[i] ),                    paUnanticipatedHostError );            if( jack_port_connected( stream->local_input_ports[i] ) )            {                UNLESS( !jack_port_disconnect( stream->jack_client, stream->local_input_ports[i] ),                        paUnanticipatedHostError );            }            UNLESS( !jack_port_unlock( stream->jack_client, stream->local_input_ports[i] ),                    paUnanticipatedHostError );        }        for( i = 0; i < stream->num_outgoing_connections; i++ )        {            UNLESS( !jack_port_lock( stream->jack_client, stream->local_output_ports[i] ),                    paUnanticipatedHostError );            if( jack_port_connected( stream->local_output_ports[i] ) )            {                UNLESS( !jack_port_disconnect( stream->jack_client, stream->local_output_ports[i] ),                        paUnanticipatedHostError );            }            UNLESS( !jack_port_unlock( stream->jack_client, stream->local_output_ports[i] ),                    paUnanticipatedHostError );        }    }    return result;}static PaError StopStream( PaStream *s ){    assert(s);    return RealStop( (PaJackStream *)s, 0 );}static PaError AbortStream( PaStream *s ){    assert(s);    return RealStop( (PaJackStream *)s, 1 );}static PaError IsStreamStopped( PaStream *s ){    PaJackStream *stream = (PaJackStream*)s;    return !stream->is_running;}static PaError IsStreamActive( PaStream *s ){    PaJackStream *stream = (PaJackStream*)s;    return stream->is_active;}static PaTime GetStreamTime( PaStream *s ){    PaJackStream *stream = (PaJackStream*)s;    /* A: Is this relevant?? --> TODO: what if we're recording-only? */    return (jack_frame_time( stream->jack_client ) - stream->t0) / (PaTime)jack_get_sample_rate( stream->jack_client );}static double GetStreamCpuLoad( PaStream* s ){    PaJackStream *stream = (PaJackStream*)s;    return PaUtil_GetCpuLoad( &stream->cpuLoadMeasurer );}

⌨️ 快捷键说明

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