summaryrefslogtreecommitdiffstats
path: root/media/audio/linux/alsa_util.cc
diff options
context:
space:
mode:
authorsatish@chromium.org <satish@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-02 21:48:54 +0000
committersatish@chromium.org <satish@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-09-02 21:48:54 +0000
commit8f168ea0f33a957a489227d30ba8c8b6e79b51f1 (patch)
treee5aed0b85ec73e970cf7c22d0dc15897ddf38baa /media/audio/linux/alsa_util.cc
parent87339f0bdb7fa60bad0616348a6a2aa705d4716a (diff)
downloadchromium_src-8f168ea0f33a957a489227d30ba8c8b6e79b51f1.zip
chromium_src-8f168ea0f33a957a489227d30ba8c8b6e79b51f1.tar.gz
chromium_src-8f168ea0f33a957a489227d30ba8c8b6e79b51f1.tar.bz2
Implement audio recording for Linux via ALSA.
There are no new unit tests because a cross platform unit test added in CL 3357004 covers this code. BUG=53598 TEST=media_unittests --gtest_filter=AudioInputTest.* Review URL: http://codereview.chromium.org/3299005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@58409 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/audio/linux/alsa_util.cc')
-rw-r--r--media/audio/linux/alsa_util.cc100
1 files changed, 100 insertions, 0 deletions
diff --git a/media/audio/linux/alsa_util.cc b/media/audio/linux/alsa_util.cc
new file mode 100644
index 0000000..27d0fc9
--- /dev/null
+++ b/media/audio/linux/alsa_util.cc
@@ -0,0 +1,100 @@
+// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "media/audio/linux/alsa_util.h"
+
+#include <string>
+
+#include "base/logging.h"
+#include "media/audio/linux/alsa_wrapper.h"
+
+namespace {
+
+snd_pcm_t* OpenDevice(AlsaWrapper* wrapper,
+ const char* device_name,
+ snd_pcm_stream_t type,
+ int channels,
+ int sample_rate,
+ snd_pcm_format_t pcm_format,
+ int latency_us) {
+ snd_pcm_t* handle = NULL;
+ int error = wrapper->PcmOpen(&handle, device_name, type, SND_PCM_NONBLOCK);
+ if (error < 0) {
+ LOG(WARNING) << "PcmOpen: " << device_name << ","
+ << wrapper->StrError(error);
+ return NULL;
+ }
+
+ error = wrapper->PcmSetParams(handle, pcm_format,
+ SND_PCM_ACCESS_RW_INTERLEAVED, channels,
+ sample_rate, 1, latency_us);
+ if (error < 0) {
+ LOG(WARNING) << "PcmSetParams: " << device_name << ", "
+ << wrapper->StrError(error) << " - Format: " << pcm_format
+ << " Channels: " << channels << " Latency: " << latency_us;
+ if (!alsa_util::CloseDevice(wrapper, handle)) {
+ // TODO(ajwong): Retry on certain errors?
+ LOG(WARNING) << "Unable to close audio device. Leaking handle.";
+ }
+ return NULL;
+ }
+
+ return handle;
+}
+
+} // namespace
+
+namespace alsa_util {
+
+snd_pcm_format_t BitsToFormat(int bits_per_sample) {
+ switch (bits_per_sample) {
+ case 8:
+ return SND_PCM_FORMAT_U8;
+
+ case 16:
+ return SND_PCM_FORMAT_S16;
+
+ case 24:
+ return SND_PCM_FORMAT_S24;
+
+ case 32:
+ return SND_PCM_FORMAT_S32;
+
+ default:
+ return SND_PCM_FORMAT_UNKNOWN;
+ }
+}
+
+int CloseDevice(AlsaWrapper* wrapper, snd_pcm_t* handle) {
+ std::string device_name = wrapper->PcmName(handle);
+ int error = wrapper->PcmClose(handle);
+ if (error < 0) {
+ LOG(ERROR) << "PcmClose: " << device_name << ", "
+ << wrapper->StrError(error);
+ }
+
+ return error;
+}
+
+snd_pcm_t* OpenCaptureDevice(AlsaWrapper* wrapper,
+ const char* device_name,
+ int channels,
+ int sample_rate,
+ snd_pcm_format_t pcm_format,
+ int latency_us) {
+ return OpenDevice(wrapper, device_name, SND_PCM_STREAM_CAPTURE, channels,
+ sample_rate, pcm_format, latency_us);
+}
+
+snd_pcm_t* OpenPlaybackDevice(AlsaWrapper* wrapper,
+ const char* device_name,
+ int channels,
+ int sample_rate,
+ snd_pcm_format_t pcm_format,
+ int latency_us) {
+ return OpenDevice(wrapper, device_name, SND_PCM_STREAM_PLAYBACK, channels,
+ sample_rate, pcm_format, latency_us);
+}
+
+} // namespace alsa_util