如何在C ++中在Linux上播放或录制音频(.WAV)? [英] How do you play or record audio (to .WAV) on Linux in C++?

查看:2263
本文介绍了如何在C ++中在Linux上播放或录制音频(.WAV)?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

录制音频在Linux(最好是Ubuntu)系统上,我一直在寻找一种方法。我目前正在使用语音识别工具包的前端,自动执行几个为 PocketSphinx Julius 调整语音模型所需的步骤。


音频输入/输出的替代方法的建议是欢迎,以及修复<



这是目前为止使用的代码,用来播放 .WAV file:

  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,为'%s'从'%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\\\
,strerror(errno));
goto finish;
}

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

close(audioStream);

pulseConnection = pa_simple_new(NULL,AudioPush,PA_STREAM_PLAYBACK,NULL,openMary C ++,& simpleSpecs,NULL,NULL和&

for(int i = 0 ;; i ++){
const int bufferSize = 1024;
uint8_t audioBuffer [bufferSize];
ssize_t r;
eprintf(E_MESSAGE,Buffering%d ..,i);
/ *读取一些数据... * /
if((r = read(STDIN_FILENO,audioBuffer,sizeof(audioBuffer)))< = 0){
if(r == 0)/ * EOF * /
break;

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

}

/ * ...并播放* /
if(pa_simple_write(pulseConnection,audioBuffer,(size_t)r,& error) 0){
fprintf(stderr,__FILE__:pa_simple_write()failed:%s\\\
,pa_strerror(error));
if(pulseConnection)
pa_simple_free(pulseConnection);

}

usleep(2);

}
/ *确保播放每个单独的样本* /
if(pa_simple_drain(pulseConnection,& error)< 0){
fprintf stderr,__FILE__:pa_simple_drain()failed:%s\\\
,pa_strerror(error));
if(pulseConnection)
pa_simple_free(pulseConnection);
}
}

注意:如果你想要剩下的代码此文件,您可以下载它这里直接从Launchpad。



更新:我尝试使用 GStreamermm ,这将无法工作: / p>

  Glib :: RefPtr< Pipeline>管道; 
Glib :: RefPtr< Element>水槽,过滤器,源
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!,我们有一个问题。
return;
}
pipeline-> add(source) - > add(filter) - > add
source-> link(sink);

pipeline-> set_state(Gst :: STATE_PLAYING);
showInformation(关闭此停止录制);
pipeline-> set_state(Gst :: STATE_PAUSED);


解决方案

GStreamer文档中的Hello World应用程序显示了如何播放Ogg / Vorbis文件。要使这个工作与WAV文件,你可以简单地用wavparse替换oggdemux和身份替换vorbisdec(身份插件什么也不做 - 它只是一个占位符)。



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

  sudo apt-get install libgstreamer0 .10-dev 

您需要在gcc命令行中使用以下命令才能启用GStreamer库...

  $(pkg-config --cflags --libs gstreamer-0.10)

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

##播放
gst-launch-0.10 filesrc location = temp.wav! wavparse! autoaudiosink

GStreamer对语音识别有用的一个功能是,过滤器进入管道 - 因此,您可以,例如,减少可能在录音中的噪音。指向GStreamer好插件列表的指针为这里



还有趣的是,PocketSphinx(似乎与您的项目相关)已经有一些GStreamer集成。请参见使用PocketSphinx与GStreamer和Python


Hello, I've been looking for a way to play and record audio on a Linux (preferably Ubuntu) system. I'm currently working on a front-end to a voice recognition toolkit that'll automate a few steps required to adapt a voice model for PocketSphinx and Julius.

Suggestions of alternative means of audio input/output are welcome, as well as a fix to the bug shown below.

Here is the current code I've used so far to play a .WAV file:

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 );
    }    
}

NOTE: If you want the rest of the code to this file, you can download it here directly from Launchpad.

Update: I tried using GStreamermm, and this won't work:

    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);

解决方案

The "Hello World" application in the GStreamer documentation shows how to play an Ogg/Vorbis file. To make this work with WAV files, you can simply replace "oggdemux" with "wavparse" and replace "vorbisdec" with "identity" (the identity plugin does nothing -- it's just a placeholder).

To install development support for GStreamer (on Ubuntu)...

sudo apt-get install libgstreamer0.10-dev

You need the following on the gcc command-line to enable the use of GStreamer libraries...

$(pkg-config --cflags --libs gstreamer-0.10)

By the way, you may find it useful to use "gst-launch" for prototyping GStreamer pipelines before writing the code.

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

## playback
gst-launch-0.10 filesrc location=temp.wav ! wavparse ! autoaudiosink

A feature of GStreamer that may be useful for voice recognition is that it is easy to insert audio quality filters into a pipeline -- so you could, for example, reduce noise that might otherwise be in the recording. A pointer to a list of the GStreamer "good" plugins is here.

Also of interest, "PocketSphinx" (which seems to be related to your project) already has some GStreamer integration. See Using PocketSphinx with GStreamer and Python

这篇关于如何在C ++中在Linux上播放或录制音频(.WAV)?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆