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

📄 pa_jack.c

📁 Audacity是一款用於錄音和編輯聲音的、免費的開放源碼軟體。它可以執行於Mac OS X、Microsoft Windows、GNU/Linux和其它作業系統
💻 C
📖 第 1 页 / 共 3 页
字号:
              JACK_DEFAULT_AUDIO_TYPE, JackPortIsInput, 0 );    }    for( i = 0; i < outputChannelCount; i++ )    {        sprintf( port_string, "out_%d", i );        stream->local_output_ports[i] = jack_port_register(             jackHostApi->jack_client, port_string,             JACK_DEFAULT_AUDIO_TYPE, JackPortIsOutput, 0 );    }    /* look up the jack_port_t's for the remote ports.  We could do     * this at stream start time, but doing it here ensures the     * name lookup only happens once. */    if( inputChannelCount > 0 )    {        /* ... remote output ports (that we input from) */        sprintf( regex_pattern, "%s:.*", hostApi->deviceInfos[ inputParameters->device ]->name );        jack_ports = jack_get_ports( jackHostApi->jack_client, regex_pattern,                                     NULL, JackPortIsOutput);        for( i = 0; i < inputChannelCount && jack_ports[i]; i++ )        {            stream->remote_output_ports[i] = jack_port_by_name(                 jackHostApi->jack_client, jack_ports[i] );        }        if( i < inputChannelCount )        {            /* we found fewer ports than we expected */            return paInternalError;        }        free( jack_ports );  // XXX: this doesn't happen if we exit prematurely    }    if( outputChannelCount > 0 )    {        /* ... remote input ports (that we output to) */        sprintf( regex_pattern, "%s:.*", hostApi->deviceInfos[ outputParameters->device ]->name );        jack_ports = jack_get_ports( jackHostApi->jack_client, regex_pattern,                                     NULL, JackPortIsInput);        for( i = 0; i < outputChannelCount && jack_ports[i]; i++ )        {            stream->remote_input_ports[i] = jack_port_by_name(                 jackHostApi->jack_client, jack_ports[i] );        }        if( i < outputChannelCount )        {            /* we found fewer ports than we expected */            return paInternalError;        }        free( jack_ports );  // XXX: this doesn't happen if we exit prematurely    }    result =  PaUtil_InitializeBufferProcessor(                  &stream->bufferProcessor,                  inputChannelCount,                  inputSampleFormat,                  paFloat32,            /* hostInputSampleFormat */                  outputChannelCount,                  outputSampleFormat,                  paFloat32,            /* hostOutputSampleFormat */                  sampleRate,                  streamFlags,                  framesPerBuffer,                  jack_max_buffer_size,                  paUtilFixedHostBufferSize,                  streamCallback,                  userData );    if( result != paNoError )        goto error;    stream->is_running = FALSE;    stream->t0 = -1;/* set the first time through the callback*/    stream->total_frames_sent = 0;    jack_set_process_callback( jackHostApi->jack_client, JackCallback, stream );    *s = (PaStream*)stream;    return result;error:    if( stream )    {        if( stream->stream_memory )        {            PaUtil_FreeAllAllocations( stream->stream_memory );            PaUtil_DestroyAllocationGroup( stream->stream_memory );        }        PaUtil_FreeMemory( stream );    }    return result;#undef MALLOC#undef MEMVERIFY}static int JackCallback( jack_nframes_t frames, void *userData ){    PaJackStream *stream = (PaJackStream*)userData;    PaStreamCallbackTimeInfo timeInfo;    int callbackResult;    int chn;    int framesProcessed;    /* TODO: make this a lot more accurate */    PaTime now = GetStreamTime(stream);    timeInfo.currentTime = now;    timeInfo.outputBufferDacTime = now;    timeInfo.inputBufferAdcTime = now;    if( stream->t0 == -1 )    {        if( stream->num_outgoing_connections == 0 )        {            /* TODO: how to handle stream time for capture-only operation? */        }        else        {            /* the beginning time needs to be initialized */            stream->t0 = jack_frame_time( stream->jack_client ) -                         jack_frames_since_cycle_start( stream->jack_client) +                         jack_port_get_total_latency( stream->jack_client,                                                      stream->local_output_ports[0] );        }    }    PaUtil_BeginCpuLoadMeasurement( &stream->cpuLoadMeasurer );    PaUtil_BeginBufferProcessing( &stream->bufferProcessor, &timeInfo,            0 /* @todo pass underflow/overflow flags when necessary */ );    for( chn = 0; chn < stream->num_incoming_connections; chn++ )    {        jack_default_audio_sample_t *channel_buf;        channel_buf = (jack_default_audio_sample_t*)            jack_port_get_buffer( stream->local_input_ports[chn],                                  frames );        PaUtil_SetNonInterleavedInputChannel( &stream->bufferProcessor,                                              chn,                                              channel_buf );    }    for( chn = 0; chn < stream->num_outgoing_connections; chn++ )    {        jack_default_audio_sample_t *channel_buf;        channel_buf = (jack_default_audio_sample_t*)            jack_port_get_buffer( stream->local_output_ports[chn],                                  frames );        PaUtil_SetNonInterleavedOutputChannel( &stream->bufferProcessor,                                               chn,                                               channel_buf );    }    if( stream->num_incoming_connections > 0 )        PaUtil_SetInputFrameCount( &stream->bufferProcessor, frames );    if( stream->num_outgoing_connections > 0 )        PaUtil_SetOutputFrameCount( &stream->bufferProcessor, frames );    callbackResult = paContinue;    framesProcessed = PaUtil_EndBufferProcessing( &stream->bufferProcessor,                                                  &callbackResult );    PaUtil_EndCpuLoadMeasurement( &stream->cpuLoadMeasurer, framesProcessed );    stream->total_frames_sent += frames;    if( callbackResult == paContinue )    {        /* nothing special */    }    else if( callbackResult == paAbort )    {        /* finish playback immediately  */        /* TODO: memset 0 the outgoing samples to "cancel" them */        stream->is_active = FALSE;        /* return nonzero so we get deactivated (and the callback won't         * get called again) */        return 1;    }    else    {        /* User callback has asked us to stop with paComplete or other non-zero value. */        stream->is_active = FALSE;        /* return nonzero so we get deactivated (and the callback won't         * get called again) */        return 1;    }    return 0;}/*    When CloseStream() is called, the multi-api layer ensures that    the stream has already been stopped or aborted.*/static PaError CloseStream( PaStream* s ){    PaError result = paNoError;    PaJackStream *stream = (PaJackStream*)s;    PaUtil_TerminateStreamRepresentation( &stream->streamRepresentation );    PaUtil_FreeMemory( stream );    return result;}static PaError StartStream( PaStream *s ){    PaError result = paNoError;    PaJackStream *stream = (PaJackStream*)s;    int i;    /* start the audio thread */    jack_activate( stream->jack_client );    /* 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++ )            jack_connect( stream->jack_client,                    jack_port_name(stream->remote_output_ports[i]),                    jack_port_name(stream->local_input_ports[i] ) );    }    if( stream->num_outgoing_connections > 0 )    {        for( i = 0; i < stream->num_outgoing_connections; i++ )            jack_connect( stream->jack_client,                    jack_port_name(stream->local_output_ports[i]),                    jack_port_name(stream->remote_input_ports[i]) );    }    stream->is_running = TRUE;    stream->is_active = TRUE;    return result;}static PaError StopStream( PaStream *s ){    PaError result = paNoError;    PaJackStream *stream = (PaJackStream*)s;    /* note: this automatically disconnects all ports, since a deactivated     * client is not allowed to have any ports connected */    jack_deactivate( stream->jack_client );    stream->is_running = FALSE;    /* TODO: block until playback complete */    stream->is_active = FALSE;    return result;}static PaError AbortStream( PaStream *s ){    PaError result = paNoError;    PaJackStream *stream = (PaJackStream*)s;    /* There's no way to cancel samples already submitted, but we can     * return immediately */    /* note: this automatically disconnects all ports, since a deactivated     * client is not allowed to have any ports connected */    jack_deactivate( stream->jack_client );    stream->is_running = FALSE;    stream->is_active = FALSE;    return result;}static PaError IsStreamStopped( PaStream *s ){    PaJackStream *stream = (PaJackStream*)s;    return stream->is_running == FALSE;}static PaError IsStreamActive( PaStream *s ){    PaJackStream *stream = (PaJackStream*)s;    return stream->is_active == TRUE;}static PaTime GetStreamTime( PaStream *s ){    PaJackStream *stream = (PaJackStream*)s;    /* TODO: what if we're recording-only? */    int delta_t = jack_frame_time( stream->jack_client ) - stream->t0;    return delta_t / (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 + -