2011-02-08 17 views
7

こんにちは、私はの再生のレコードのオーディオをLinux(好ましくはUbuntu)システムで再生する方法を探していました。私は現在voice recognition toolkitのフロントエンドで、PocketSphinxJuliusの音声モデルを適応させるために必要ないくつかのステップを自動化しています。オーディオ入力/出力の代替手段のどのようにしてC++でLinux上で(.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); 
    }  
} 

注:このファイルへのコードの残りの部分をしたい場合は、ランチパッドから直接hereをダウンロードすることができます。ここ

は私が.WAVファイルを再生するために、これまで使用してきた現在のコードです。

アップデート:私は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); 
+0

これは[stackoverflow](http://stackoverflow.com/)のためのよりよい質問です。 –

+1

私は再生と録音のためのgstreamerライブラリを考えています。しかし、私はPulseにも録音オプションがあるはずだと思いますか? – Petriborg

+0

@Michael私はそれがプログラミング関連のものだと思ったので、私はそれをプログラミングのものに投稿しました。 @Petriborgこれを行う手段、またはそうする方法についての**良い**リンクを実証できますか? GStreamerはOGGのみをサポートすると思われ、CMUSphinxはWAVファイルを必要とします。 – jackyalcine

答えて

4

The "Hello World" application in the GStreamer documentationはオッグ/ Vorbisのファイルを再生する方法を示しています。これをWAVファイルで動作させるには、単に "oggdemux"を "wavparse"に置き換え、 "vorbisdec"を "identity"に置き換えることができます(IDプラグインは何もしません - 単にプレースホルダです)。 (Ubuntuの上)のGStreamerの開発サポートをインストールするには

...

sudo apt-get install libgstreamer0.10-dev 

あなたはGStreamerのライブラリの使用を可能にするために、gccのコマンドラインで、次の必要があります...

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

ところで、コードを書く前に、GStreamerパイプラインのプロトタイプ作成に "gst-launch"を使うと便利です。

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

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

音声認識のために有用である可能性があるのGStreamerの特徴は、パイプラインにオーディオ品質のフィルタを挿入することが容易であることである - ので、あなたは、例えば、それ以外の場合は記録にあるかもしれないノイズを減らすことができます。 GStreamerの「良い」プラグインのリストへのポインタはhereです。

また、「PocketSphinx」(あなたのプロジェクトに関連していると思われる)にはすでにGStreamerとの統合があります。 Using PocketSphinx with GStreamer and Python

+0

私はこのアプリケーションのためのPythonを使用していない;これは主にC++のコードですが、私が最もよく知っている言語ですが、あなたはすばらしい助けになりました。 – jackyalcine

+0

また、私は、PocketSphinx/CMUSphinxのボイスモデルを適応させるための簡単な方法を実装しようとしています。 – jackyalcine

+0

@ジャッキー:幸運! – nobar

1

GStreamer/Pulse/JACKは素晴らしいです。 シンプルで速いもののためには、あなたはSoXを使うかもしれませんhttp://sox.sourceforge.net/

+0

彼らはAPIを持っていますか?私はコマンドラインを使用することはできません。私も音量をコントロールできる必要があります。 – jackyalcine

+1

@Jacky Alcine:libsoxは、サウンドサンプルファイル形式のリーダ/ライタとサウンドエフェクトプロセッサのライブラリです。これは主にSoXで使用するために開発されましたが、あらゆるサウンドアプリケーションに役立ちます。 はい、SoXもlibとして使うことができます - 詳細はアーカイブ内のllok –

関連する問題