你如何在Linux上用C++播放或录制音频(到.WAV)?

jac*_*ine 7 c++ linux gstreamer

您好,我一直在寻找一种在Linux(最好是Ubuntu)系统上播放录制音频的方法.我目前工作的一个前端的语音识别工具包,那将自动适应的语音模型需要几个步骤PocketSphinxJulius.

欢迎提供音频输入/输出的替代方法的建议,以及对下面显示错误的修复.

这是我到目前为止用来播放.WAV文件的当前代码:

void Engine::sayText ( const string OutputText ) {
    string audioUri = "temp.wav";
    string requestUri = this->getRequestUri( OPENMARY_PROCESS , OutputText.c_str( ) );
    int error , audioStream;
    pa_simple *pulseConnection;
    pa_sample_spec simpleSpecs;
    simpleSpecs.format = PA_SAMPLE_S16LE;
    simpleSpecs.rate = 44100;
    simpleSpecs.channels = 2;

    eprintf( E_MESSAGE , "Generating audio for '%s' from '%s'..." , OutputText.c_str( ) , requestUri.c_str( ) );
    FILE* audio = this->getHttpFile( requestUri , audioUri );
    fclose(audio);
    eprintf( E_MESSAGE , "Generated audio.");

    if ( ( audioStream = open( audioUri.c_str( ) , O_RDONLY ) ) < 0 ) {
        fprintf( stderr , __FILE__": open() failed: %s\n" , strerror( errno ) );
        goto finish;
    }

    if ( dup2( audioStream , STDIN_FILENO ) < 0 ) {
        fprintf( stderr , __FILE__": dup2() failed: %s\n" , strerror( errno ) );
        goto finish;
    }

    close( audioStream );

    pulseConnection = pa_simple_new( NULL , "AudioPush" , PA_STREAM_PLAYBACK , NULL , "openMary C++" , &simpleSpecs , NULL , NULL , &error );

    for (int i = 0;;i++ ) {
        const int bufferSize = 1024;
        uint8_t audioBuffer[bufferSize];
        ssize_t r;
        eprintf( E_MESSAGE , "Buffering %d..",i);
        /* Read some data ... */
        if ( ( r = read( STDIN_FILENO , audioBuffer , sizeof (audioBuffer ) ) ) <= 0 ) {
            if ( r == 0 ) /* EOF */
                break;

            eprintf( E_ERROR , __FILE__": read() failed: %s\n" , strerror( errno ) );
    if ( pulseConnection )
        pa_simple_free( pulseConnection );

        }

        /* ... and play it */
        if ( pa_simple_write( pulseConnection , audioBuffer , ( size_t ) r , &error ) < 0 ) {
            fprintf( stderr , __FILE__": pa_simple_write() failed: %s\n" , pa_strerror( error ) );
    if ( pulseConnection )
        pa_simple_free( pulseConnection );

        }

        usleep(2);

    }
    /* Make sure that every single sample was played */
    if ( pa_simple_drain( pulseConnection , &error ) < 0 ) {
        fprintf( stderr , __FILE__": pa_simple_drain() failed: %s\n" , pa_strerror( error ) );
    if ( pulseConnection )
        pa_simple_free( pulseConnection );
    }    
}
Run Code Online (Sandbox Code Playgroud)

注意:如果你想要的代码到该文件的其余部分,你可以下载它这里直接从快速启动.

更新:我尝试使用GStreamermm,这不起作用:

    Glib::RefPtr<Pipeline> pipeline;
    Glib::RefPtr<Element> sink, filter, source;
    Glib::RefPtr<Gio::File> audioSrc = Gio::File::create_for_path(uri);

    pipeline = Pipeline::create("audio-playback");
    source = ElementFactory::create_element("alsasrc","source");
    filter = ElementFactory::create_element("identity","filter");
    sink = ElementFactory::create_element("alsasink","sink");
    //sink->get_property("file",audioSrc);
    if (!source || !filter || !sink){
        showErrorDialog("Houston!","We got a problem.");
        return;
    }
    pipeline->add(source)->add(filter)->add(sink);
    source->link(sink);

    pipeline->set_state(Gst::STATE_PLAYING);
    showInformation("Close this to stop recording");
    pipeline->set_state(Gst::STATE_PAUSED);
Run Code Online (Sandbox Code Playgroud)

nob*_*bar 4

GStreamer 文档中的“Hello World”应用程序展示了如何播放 Ogg/Vorbis 文件。要使其适用于 WAV 文件,您只需将“oggdemux”替换为“wavparse”,并将“vorbisdec”替换为“identity”(identity 插件不执行任何操作 - 它只是一个占位符)。

要安装 GStreamer 的开发支持(在 Ubuntu 上)...

sudo apt-get install libgstreamer0.10-dev
Run Code Online (Sandbox Code Playgroud)

您需要在 gcc 命令行上执行以下操作才能使用 GStreamer 库...

$(pkg-config --cflags --libs gstreamer-0.10)
Run Code Online (Sandbox Code Playgroud)

顺便说一句,您可能会发现在编写代码之前使用“gst-launch”对 GStreamer 管道进行原型设计很有用。

## recording
gst-launch-0.10 autoaudiosrc ! wavenc ! filesink location=temp.wav

## playback
gst-launch-0.10 filesrc location=temp.wav ! wavparse ! autoaudiosink
Run Code Online (Sandbox Code Playgroud)

GStreamer 的一个可能对语音识别有用的功能是,可以轻松地将音频质量过滤器插入管道中,这样您就可以减少录音中可能存在的噪音。这里有一个指向 GStreamer“好”插件列表的指针。

同样有趣的是,“PocketSphinx”(似乎与您的项目相关)已经有一些 GStreamer 集成。请参阅将 PocketSphinx 与 GStreamer 和 Python 结合使用