Xin chào, tôi đã tìm kiếm cách để phát và ghi â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
PocketSphinx
vàJulius
.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);
Đây sẽ là câu hỏi hay hơn về [stackoverflow] (http://stackoverflow.com/). –
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
@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