如何在C ++的Linux上播放或录制audio(到.WAV)?

你好,我一直在寻找一种方式来播放录制在Linux(最好是Ubuntu)系统上的audio。 目前,我正在开发一个语音识别工具包的前端,它将自动执行一些步骤,以便为PocketSphinxJulius调整语音模型。

对于audioinput/输出的替代方法的build议是值得欢迎的 ,以及修复下面显示错误

这里是目前我用来播放.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 ); } } 

注意:如果你想要其他的代码到这个文件,你可以直接从Launchpad下载。

更新:我尝试使用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); 

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”来创建GStreamer管道原型是有用的。

 ## recording gst-launch-0.10 autoaudiosrc ! wavenc ! filesink location=temp.wav ## playback gst-launch-0.10 filesrc location=temp.wav ! wavparse ! autoaudiosink 

GStreamer的一个功能可能对语音识别非常有用,它可以很容易地将音频质量过滤器插入流水线,例如,可以减少录制过程中可能出现的噪音。 指向GStreamer“好”插件列表的指针在这里 。

另外感兴趣的是,“PocketSphinx”(似乎与您的项目有关)已经有一些GStreamer集成。 请参阅使用GStreamer和Python使用PocketSphinx

GStreamer / Pulse / JACK棒极了。 对于简单和快速的事情,你可以使用SoX http://sox.sourceforge.net/