Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(207)

Unified Diff: linux/audio_output_alsa.cc

Issue 6299025: dmazzoni's fixes to ALSA for speech_synthesis (Closed) Base URL: ssh://git@gitrw.chromium.org:9222/speech_synthesis.git@master
Patch Set: Created 9 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | tts_service.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: linux/audio_output_alsa.cc
diff --git a/linux/audio_output_alsa.cc b/linux/audio_output_alsa.cc
index dc763ba46024157c64509916161204e043e12c5a..fdf4c6e811c63c7b0c6aea49fa17b7f7662fe98b 100644
--- a/linux/audio_output_alsa.cc
+++ b/linux/audio_output_alsa.cc
@@ -13,6 +13,57 @@
#include "log.h"
#include "threading.h"
+namespace {
+
+bool isDeviceReady() {
+ snd_ctl_card_info_t *card_info;
+ snd_ctl_card_info_alloca(&card_info);
+
+ snd_pcm_info_t *pcm_info;
+ snd_pcm_info_alloca(&pcm_info);
+
+ int valid_playback_devices = 0;
+ int card_index = -1;
+
+ while(snd_card_next(&card_index) == 0 && card_index >= 0) {
+ char card_name[20];
+ snprintf(card_name, sizeof(card_name), "hw:%d", card_index);
+ LOG(INFO) << "Checking ALSA sound card " << card_name;
+
+ snd_ctl_t *ctl;
+ if(snd_ctl_open(&ctl, card_name, 0) < 0)
+ continue;
+
+ snd_ctl_card_info(ctl, card_info);
+
+ int dev_index = -1;
+ while (snd_ctl_pcm_next_device(ctl, &dev_index) == 0 && dev_index >= 0) {
+ char device_name[30];
+ snprintf(device_name, sizeof(device_name),
+ "hw:%d,%d", card_index, dev_index);
+ LOG(INFO) << "Checking ALSA sound device " << device_name;
+
+ /* Obtain info about this particular device */
+ snd_pcm_info_set_device(pcm_info, dev_index);
+ snd_pcm_info_set_subdevice(pcm_info, 0);
+ snd_pcm_info_set_stream(pcm_info, SND_PCM_STREAM_PLAYBACK);
+ if (snd_ctl_pcm_info(ctl, pcm_info) >= 0) {
+ LOG(INFO) << " Valid playback device: " << device_name;
+ valid_playback_devices++;
+ }
+ }
+ snd_ctl_close(ctl);
+ }
+
+ LOG(INFO) << "Total valid playback devices: " << valid_playback_devices;
+ if (valid_playback_devices == 0) {
+ return false;
+ }
+ return true;
+}
+
+}
+
namespace speech_synthesis {
class LinuxAlsaAudioOutput : public AudioOutput, public Runnable {
@@ -32,93 +83,44 @@ class LinuxAlsaAudioOutput : public AudioOutput, public Runnable {
return true;
}
+ if (!isDeviceReady()) {
+ return false;
+ }
+
int err;
if ((err = snd_pcm_open(&pcm_out_handle_,
- "plughw:0,0",
+ "default",
SND_PCM_STREAM_PLAYBACK,
0)) < 0) {
LOG(INFO) << "Can't open wave output: " << snd_strerror(err) << "\n";
return false;
}
- snd_pcm_hw_params_t *hw_params;
- if ((err = snd_pcm_hw_params_malloc(&hw_params)) < 0) {
- LOG(INFO) << "Can't alloc sound hardware struct " <<
- snd_strerror(err) << "\n";
- return false;
- }
-
- if ((err = snd_pcm_hw_params_any(pcm_out_handle_, hw_params)) < 0) {
- LOG(INFO) << "Can't init sound hardware struct: " <<
- snd_strerror(err) << "\n";
- return false;
- }
-
- if ((err = snd_pcm_hw_params_set_access(
- pcm_out_handle_, hw_params, SND_PCM_ACCESS_RW_INTERLEAVED)) < 0) {
- LOG(INFO) << "Can't set access: " << snd_strerror(err) << "\n";
- return false;
- }
-
- if ((err = snd_pcm_hw_params_set_format(pcm_out_handle_,
- hw_params,
- SND_PCM_FORMAT_S16_LE)) < 0) {
- LOG(INFO) << "Can't set 16-bit: " << snd_strerror(err) << "\n";
- return false;
- }
-
- if ((err = snd_pcm_hw_params_set_rate(pcm_out_handle_,
- hw_params,
- 44100,
- 0)) < 0) {
- LOG(INFO) << "Can't set rate to 44100: " << snd_strerror(err) << "\n";
- return false;
- }
-
- if ((err = snd_pcm_hw_params_set_channels(pcm_out_handle_,
- hw_params,
- 1)) < 0) {
- LOG(INFO) << "Can't set channels to 1: " << snd_strerror(err) << "\n";
- return false;
- }
-
- int dir = 0;
- snd_pcm_uframes_t desired_period = 512;
- if ((err = snd_pcm_hw_params_set_period_size_near(
- pcm_out_handle_, hw_params, &desired_period, &dir)) < 0) {
- LOG(INFO) << "Can't set period size: " << snd_strerror(err) << "\n";
+ sample_rate_ = 44100;
+ channel_count_ = 1;
+ int soft_resample = 1;
+ unsigned int latency_us = 50000;
+ if ((err = snd_pcm_set_params(pcm_out_handle_,
+ SND_PCM_FORMAT_S16_LE,
+ SND_PCM_ACCESS_RW_INTERLEAVED,
+ channel_count_,
+ sample_rate_,
+ soft_resample,
+ latency_us)) < 0) {
+ LOG(INFO) << "Can't set pcm parameters " << snd_strerror(err);
return false;
}
- snd_pcm_uframes_t period_size;
- snd_pcm_hw_params_get_period_size(hw_params, &period_size, &dir);
- chunk_size_ = static_cast<int>(period_size);
-
- snd_pcm_uframes_t desired_buffer_size = period_size * 4;
- if ((err = snd_pcm_hw_params_set_buffer_size(
- pcm_out_handle_, hw_params, desired_buffer_size)) < 0) {
- LOG(INFO) << "Can't set buffer size: " << snd_strerror(err) << "\n";
- return false;
- }
-
- snd_pcm_uframes_t buffer_size;
- snd_pcm_hw_params_get_buffer_size(hw_params, &buffer_size);
- total_buffer_size_ = static_cast<int>(buffer_size);
-
- unsigned int rate;
- snd_pcm_hw_params_get_rate(hw_params, &rate, &dir);
- sample_rate_ = rate;
-
- unsigned int channels;
- snd_pcm_hw_params_get_channels(hw_params, &channels);
- channel_count_ = channels;
-
- if ((err = snd_pcm_hw_params(pcm_out_handle_, hw_params)) < 0) {
- LOG(INFO) << "Can't set hardware params: " << snd_strerror(err) << "\n";
+ snd_pcm_uframes_t buffer_size = 0;
+ snd_pcm_uframes_t period_size = 0;
+ if ((err = snd_pcm_get_params(pcm_out_handle_, &buffer_size, &period_size))
+ < 0) {
+ LOG(INFO) << "Can't get pcm parameters: " << snd_strerror(err);
return false;
}
- snd_pcm_hw_params_free(hw_params);
+ chunk_size_ = period_size;
+ total_buffer_size_ = buffer_size;
if ((err = snd_pcm_prepare(pcm_out_handle_)) < 0) {
LOG(INFO) << "Can't prepare: " << snd_strerror(err) << "\n";
@@ -185,7 +187,11 @@ class LinuxAlsaAudioOutput : public AudioOutput, public Runnable {
static_cast<snd_pcm_uframes_t>(chunk_size));
if (err < 0) {
LOG(INFO) << "Write error: " << err << snd_strerror(err) << "\n";
- return;
+ do {
+ sleep(1);
+ LOG(INFO) << "Attempting to recover audio";
+ } while (keep_running_ &&
+ 0 != snd_pcm_recover(pcm_out_handle_, err, 0));
}
}
« no previous file with comments | « no previous file | tts_service.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698