2011-02-08 11 views
7

Xin chào, tôi đã tìm kiếm cách để phátghi âm âm thanh trên hệ thống Linux (tốt hơn là Ubuntu). Tôi hiện đang làm việc trên giao diện người dùng với một số voice recognition toolkit sẽ tự động thực hiện một vài bước cần thiết để điều chỉnh mẫu giọng nói cho PocketSphinxJulius.Làm thế nào để bạn phát hoặc ghi âm thanh (vào .WAV) trên Linux trong C++?

Gợi ý của phương tiện thay thế đầu vào/đầu ra âm thanh là đón, cũng như sửa chữa để các lỗi hiển thị dưới đây.

Đây là mã hiện tại tôi đã sử dụng cho đến nay để đóng một tập tin .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); 
    }  
} 

Chú ý: Nếu bạn muốn phần còn lại của mã để tập tin này, bạn có thể tải nó here trực tiếp từ Launchpad .

Cập nhật: Tôi cố gắng sử dụng GStreamermm, và điều này sẽ không làm việc:

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

Đây sẽ là câu hỏi hay hơn về [stackoverflow] (http://stackoverflow.com/). –

+1

Tôi sẽ xem xét thư viện gstreamer để chơi và ghi âm. Nhưng tôi cho rằng Pulse cũng nên có một lựa chọn ghi âm? – Petriborg

+0

@Michael Tôi đã đăng nó lên chương trình, bởi vì tôi cho rằng nó liên quan đến lập trình. @Petriborg Bạn có thể chứng minh phương tiện làm việc đó hoặc liên kết ** tốt ** về cách thực hiện điều đó không? GStreamer dường như chỉ hỗ trợ OGG và CMUSphinx cần các tệp WAV. – jackyalcine

Trả lời

4

The "Hello World" application in the GStreamer documentation cho thấy làm thế nào để đóng một tập tin Ogg/Vorbis. Để thực hiện công việc này với các tệp WAV, bạn có thể chỉ cần thay thế "oggdemux" bằng "wavparse" và thay thế "vorbisdec" bằng "identity" (plugin nhận dạng không có gì - chỉ là trình giữ chỗ).

Để cài đặt hỗ trợ phát triển cho GStreamer (trên Ubuntu) ...

sudo apt-get install libgstreamer0.10-dev 

Bạn cần sau trên dòng lệnh gcc để cho phép việc sử dụng các thư viện GStreamer ...

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

Nhân tiện, bạn có thể thấy hữu ích khi sử dụng "gst-launch" để tạo mẫu các đường ống GStreamer trước khi viết mã.

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

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

Một tính năng của GStreamer có thể hữu ích cho nhận dạng giọng nói là nó rất dễ dàng để chèn bộ lọc chất lượng âm thanh vào một đường ống dẫn - vì vậy bạn có thể, ví dụ, giảm tiếng ồn mà nếu không có thể là trong buổi ghi hình. Một con trỏ tới danh sách các plugin "tốt" của GStreamer là here.

Cũng quan tâm, "PocketSphinx" (có vẻ như liên quan đến dự án của bạn) đã có một số tích hợp GStreamer. Xem Using PocketSphinx with GStreamer and Python

+0

Tôi đã không sử dụng Python cho ứng dụng này; nó chủ yếu là mã trong C++, vì nó là ngôn ngữ tôi biết rõ nhất, nhưng bạn đã giúp đỡ rất nhiều và tôi sẽ trả lời với trạng thái của tôi. – jackyalcine

+0

Ngoài ra, tôi đang cố gắng thực hiện một cách siêu đơn giản để thích ứng với các mẫu giọng nói cho PocketSphinx/CMUSphinx. – jackyalcine

+0

@ Jacky: Chúc may mắn! – nobar

1

GStreamer/Pulse/JACK thật tuyệt. Đối với những điều đơn giản và nhanh chóng, bạn có thể sử dụng SoX http://sox.sourceforge.net/

+0

Họ có API không? Tôi không thể sử dụng dòng lệnh; Tôi cần để có thể kiểm soát âm lượng là tốt. – jackyalcine

+1

@Jacky Alcine: libsox là một thư viện gồm các trình đọc/ghi văn bản mẫu âm thanh và bộ xử lý hiệu ứng âm thanh. Nó chủ yếu được phát triển để sử dụng bởi SoX nhưng rất hữu ích cho bất kỳ ứng dụng âm thanh nào. Có, SoX cũng có thể được sử dụng làm thư viện - chỉ cần llok trong kho lưu trữ để biết chi tiết –