summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--media/audio/audio_output.h9
-rw-r--r--media/audio/linux/alsa_output.cc521
-rw-r--r--media/audio/linux/alsa_output.h165
-rw-r--r--media/audio/linux/audio_manager_linux.cc67
-rw-r--r--media/audio/linux/audio_manager_linux.h32
-rw-r--r--media/media.gyp8
6 files changed, 4 insertions, 798 deletions
diff --git a/media/audio/audio_output.h b/media/audio/audio_output.h
index 4793e71..289b2af 100644
--- a/media/audio/audio_output.h
+++ b/media/audio/audio_output.h
@@ -43,11 +43,9 @@ class AudioOutputStream {
public:
enum State {
STATE_CREATED = 0, // The output stream is created.
- STATE_OPENED, // The output stream is opened.
STATE_STARTED, // The output stream is started.
STATE_PAUSED, // The output stream is paused.
STATE_STOPPED, // The output stream is stopped.
- STATE_CLOSING, // The output stream is being closed.
STATE_CLOSED, // The output stream is closed.
STATE_ERROR, // The output stream is in error state.
};
@@ -84,9 +82,6 @@ class AudioOutputStream {
// two buffers of |packet_size| size are created, one will be locked for
// playback and one will be ready to be filled in the call to
// AudioSourceCallback::OnMoreData().
- //
- // TODO(ajwong): Streams are not reusable, so try to move packet_size into the
- // constructor.
virtual bool Open(size_t packet_size) = 0;
// Starts playing audio and generating AudioSourceCallback::OnMoreData().
@@ -94,11 +89,9 @@ class AudioOutputStream {
// after calling this method initial buffers are fetched. User of this
// object should prepare |AudioOutputStream::GetNumBuffers()| before calling
// AudioOutputStream::Start().
- //
- // The output stream does not take ownership of this callback.
virtual void Start(AudioSourceCallback* callback) = 0;
- // Stops playing audio. Effect might not be instantaneous as the hardware
+ // Stops playing audio. Effect might no be instantaneous as the hardware
// might have locked audio data that is processing.
virtual void Stop() = 0;
diff --git a/media/audio/linux/alsa_output.cc b/media/audio/linux/alsa_output.cc
deleted file mode 100644
index 0dc9ca9..0000000
--- a/media/audio/linux/alsa_output.cc
+++ /dev/null
@@ -1,521 +0,0 @@
-// Copyright (c) 2009 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.
-//
-// The audio stream implementation is made difficult because different methods
-// are available for calling depending on what state the stream is. Here is the
-// state transition table for the stream.
-//
-// STATE_CREATED -> Open() -> STATE_OPENED
-// STATE_OPENED -> Start() -> STATE_STARTED
-// STATE_OPENED -> Close() -> STATE_CLOSED
-// STATE_STARTED -> Stop() -> STATE_STOPPED
-// STATE_STARTED -> Close() -> STATE_CLOSING | STATE_CLOSED
-// STATE_STOPPED -> Close() -> STATE_CLOSING | STATE_CLOSED
-// STATE_CLOSING -> [automatic] -> STATE_CLOSED
-//
-// Error states and resource management:
-//
-// Entrance into STATE_STOPPED signals schedules a call to ReleaseResources().
-//
-// Any state may transition to STATE_ERROR. On transitioning into STATE_ERROR,
-// the function doing the transition is reponsible for scheduling a call to
-// ReleaseResources() or otherwise ensuring resources are cleaned (eg., as is
-// done in Open()). This should be done while holding the lock to avoid a
-// destruction race condition where the stream is deleted via ref-count before
-// the ReleaseResources() task is scheduled. In particular, be careful of
-// resource management in a transtiion from STATE_STOPPED -> STATE_ERROR if
-// that becomes necessary in the future.
-//
-// STATE_ERROR may transition to STATE_CLOSED. In this situation, no further
-// resource management is done because it is assumed that the resource
-// reclaimation was executed at the point of the state transition into
-// STATE_ERROR.
-//
-// Entrance into STATE_CLOSED implies a transition through STATE_STOPPED, which
-// triggers the resource management code.
-//
-// The destructor is not responsible for ultimate cleanup of resources.
-// Instead, it only checks that the stream is in a state where all resources
-// have been cleaned up. These states are STATE_CREATED, STATE_CLOSED,
-// STATE_ERROR.
-//
-// TODO(ajwong): This incorrectly handles the period size for filling of the
-// ALSA device buffer. Currently the period size is hardcoded, and not
-// reported to the sound device. Also, there are options that let the device
-// wait until the buffer is minimally filled before playing. Those should be
-// explored. Also consider doing the device interactions either outside of the
-// class lock, or under a different lock to avoid unecessarily blocking other
-// threads.
-
-#include "media/audio/linux/alsa_output.h"
-
-#include <algorithm>
-
-#include "base/logging.h"
-#include "base/stl_util-inl.h"
-#include "base/time.h"
-
-// Require 10ms latency from the audio device. Taken from ALSA documentation
-// example.
-// TODO(ajwong): Figure out what this parameter actually does, and what a good
-// value would be.
-static const unsigned int kTargetLatencyMicroseconds = 10000;
-
-// Minimal amount of time to sleep. If any future event is expected to
-// execute within this timeframe, treat it as if it should execute immediately.
-//
-// TODO(ajwong): Determine if there is a sensible minimum sleep resolution and
-// adjust accordingly.
-static const int64 kMinSleepMilliseconds = 10L;
-
-const char* AlsaPCMOutputStream::kDefaultDevice = "plug:default";
-
-AlsaPCMOutputStream::AlsaPCMOutputStream(const std::string& device_name,
- int min_buffer_ms,
- AudioManager::Format format,
- int channels,
- int sample_rate,
- char bits_per_sample)
- : state_(STATE_CREATED),
- device_name_(device_name),
- playback_handle_(NULL),
- source_callback_(NULL),
- playback_thread_("PlaybackThread"),
- channels_(channels),
- sample_rate_(sample_rate),
- bits_per_sample_(bits_per_sample),
- min_buffer_frames_((min_buffer_ms * sample_rate_) /
- base::Time::kMillisecondsPerSecond),
- packet_size_(0),
- device_write_suspended_(true), // Start suspended.
- resources_released_(false) {
- CHECK(channels_ == 2) << "Only 2-channel audio is supported right now.";
- CHECK(AudioManager::AUDIO_PCM_LINEAR == format)
- << "Only linear PCM supported.";
- CHECK(bits_per_sample % 8 == 0) << "Only allow byte-aligned samples";
-
- // Reference self to avoid accidental deletion before the message loop is
- // done.
- AddRef();
-
- switch (bits_per_sample) {
- case 8:
- pcm_format_ = SND_PCM_FORMAT_S8;
- break;
-
- case 16:
- pcm_format_ = SND_PCM_FORMAT_S16;
- break;
-
- case 24:
- pcm_format_ = SND_PCM_FORMAT_S24;
- break;
-
- case 32:
- pcm_format_ = SND_PCM_FORMAT_S32;
- break;
-
- default:
- LOG(DFATAL) << "Unsupported bits per sample: " << bits_per_sample_;
- state_ = STATE_ERROR;
- break;
- }
-
- // Interleaved audio is expected, so each frame has one sample per channel.
- bytes_per_frame_ = channels_ * (bits_per_sample_ / 8);
-}
-
-AlsaPCMOutputStream::~AlsaPCMOutputStream() {
- AutoLock l(lock_);
- // In STATE_CREATED, STATE_CLOSED, and STATE_ERROR, resources are guaranteed
- // to be released.
- CHECK(state_ == STATE_CREATED ||
- state_ == STATE_CLOSED ||
- state_ == STATE_ERROR);
-}
-
-bool AlsaPCMOutputStream::Open(size_t packet_size) {
- AutoLock l(lock_);
-
- // Check that stream is coming from the correct state and early out if not.
- if (state_ == STATE_ERROR) {
- return false;
- }
- if (state_ != STATE_CREATED) {
- NOTREACHED() << "Stream must be in STATE_CREATED on Open. Instead in: "
- << state_;
- return false;
- }
-
- // Open the device and set the parameters.
- // TODO(ajwong): Can device open block? Probably. If yes, we need to move
- // the open call into a different thread.
- int error = snd_pcm_open(&playback_handle_, device_name_.c_str(),
- SND_PCM_STREAM_PLAYBACK, 0);
- if (error < 0) {
- LOG(ERROR) << "Cannot open audio device (" << device_name_ << "): "
- << snd_strerror(error);
- EnterStateError_Locked();
- return false;
- }
- if ((error = snd_pcm_set_params(playback_handle_,
- pcm_format_,
- SND_PCM_ACCESS_RW_INTERLEAVED,
- channels_,
- sample_rate_,
- 1, // soft_resample -- let ALSA resample
- kTargetLatencyMicroseconds)) < 0) {
- LOG(ERROR) << "Unable to set PCM parameters: " << snd_strerror(error);
- if (!CloseDevice_Locked()) {
- LOG(WARNING) << "Unable to close audio device. Leaking handle.";
- }
- playback_handle_ = NULL;
- EnterStateError_Locked();
- return false;
- }
-
- // Configure the buffering.
- packet_size_ = packet_size;
- DCHECK_EQ(0U, packet_size_ % bytes_per_frame_)
- << "Buffers should end on a frame boundary. Frame size: "
- << bytes_per_frame_;
-
- // Everything is okay. Stream is officially STATE_OPENED for business.
- state_ = STATE_OPENED;
-
- return true;
-}
-
-void AlsaPCMOutputStream::Start(AudioSourceCallback* callback) {
- AutoLock l(lock_);
-
- // Check that stream is coming from the correct state and early out if not.
- if (state_ == STATE_ERROR) {
- return;
- }
- if (state_ != STATE_OPENED) {
- NOTREACHED() << "Can only be started from STATE_OPEN. Current state: "
- << state_;
- return;
- }
-
- source_callback_ = callback;
-
- playback_thread_.Start();
- playback_thread_.message_loop()->PostTask(FROM_HERE,
- NewRunnableMethod(this, &AlsaPCMOutputStream::BufferPackets));
-
- state_ = STATE_STARTED;
-}
-
-void AlsaPCMOutputStream::Stop() {
- AutoLock l(lock_);
- // If the stream is in STATE_ERROR, it is effectively stopped already.
- if (state_ == STATE_ERROR) {
- return;
- }
- StopInternal_Locked();
-}
-
-void AlsaPCMOutputStream::StopInternal_Locked() {
- // Check the lock is held in a debug build.
- DCHECK((lock_.AssertAcquired(), true));
-
- if (state_ != STATE_STARTED) {
- NOTREACHED() << "Stream must be in STATE_STARTED to Stop. Instead in: "
- << state_;
- return;
- }
-
- // Move immediately to STATE_STOPPED to signal that all functions should cease
- // working at this point. Then post a task to the playback thread to release
- // resources.
- state_ = STATE_STOPPED;
-
- playback_thread_.message_loop()->PostTask(
- FROM_HERE,
- NewRunnableMethod(this, &AlsaPCMOutputStream::ReleaseResources));
-}
-
-void AlsaPCMOutputStream::EnterStateError_Locked() {
- // Check the lock is held in a debug build.
- DCHECK((lock_.AssertAcquired(), true));
-
- state_ = STATE_ERROR;
- resources_released_ = true;
-
- // TODO(ajwong): Call OnError() on source_callback_.
-}
-
-void AlsaPCMOutputStream::Close() {
- AutoLock l(lock_);
-
- // If in STATE_ERROR, all asynchronous resource reclaimation is finished, so
- // just change states and release this instance to delete ourself.
- if (state_ == STATE_ERROR) {
- Release();
- state_ = STATE_CLOSED;
- return;
- }
-
- // Otherwise, cleanup as necessary.
- if (state_ == STATE_CLOSED || state_ == STATE_CLOSING) {
- NOTREACHED() << "Attempting to close twice.";
- return;
- }
-
- // If the stream is still running, stop it.
- if (state_ == STATE_STARTED) {
- StopInternal_Locked();
- }
-
- // If it is stopped (we may have just transitioned here in the previous if
- // block), check if the resources have been released. If they have,
- // transition immediately to STATE_CLOSED. Otherwise, move to
- // STATE_CLOSING, and the ReleaseResources() task will move to STATE_CLOSED
- // for us.
- //
- // If the stream has been stopped, close.
- if (state_ == STATE_STOPPED) {
- if (resources_released_) {
- state_ = STATE_CLOSED;
- } else {
- state_ = STATE_CLOSING;
- }
- } else {
- // TODO(ajwong): Can we safely handle state_ == STATE_CREATED?
- NOTREACHED() << "Invalid state on close: " << state_;
- // In release, just move to STATE_ERROR, and hope for the best.
- EnterStateError_Locked();
- }
-}
-
-bool AlsaPCMOutputStream::CloseDevice_Locked() {
- // Check the lock is held in a debug build.
- DCHECK((lock_.AssertAcquired(), true));
-
- int error = snd_pcm_close(playback_handle_);
- if (error < 0) {
- LOG(ERROR) << "Cannot close audio device (" << device_name_ << "): "
- << snd_strerror(error);
- return false;
- }
-
- return true;
-}
-
-void AlsaPCMOutputStream::ReleaseResources() {
- AutoLock l(lock_);
-
- // Shutdown the audio device.
- if (!CloseDevice_Locked()) {
- LOG(WARNING) << "Unable to close audio device. Leaking handle.";
- playback_handle_ = NULL;
- }
-
- // Delete all the buffers.
- STLDeleteElements(&buffered_packets_);
-
- // Release the source callback.
- source_callback_->OnClose(this);
-
- // Shutdown the thread.
- DCHECK_EQ(PlatformThread::CurrentId(), playback_thread_.thread_id());
- playback_thread_.message_loop()->Quit();
-
- // TODO(ajwong): Do we need to join the playback thread?
-
- // If the stream is closing, then this function has just completed the last
- // bit needed before closing. Transition to STATE_CLOSED.
- if (state_ == STATE_CLOSING) {
- state_ = STATE_CLOSED;
- }
-
- // TODO(ajwong): Currently, the stream is leaked after the |playback_thread_|
- // is stopped. Find a way to schedule its deletion on another thread, maybe
- // using a DestructionObserver.
-}
-
-snd_pcm_sframes_t AlsaPCMOutputStream::GetFramesOfDelay_Locked() {
- // Check the lock is held in a debug build.
- DCHECK((lock_.AssertAcquired(), true));
-
- // Find the number of frames queued in the sound device.
- snd_pcm_sframes_t delay_frames = 0;
- int error = snd_pcm_delay(playback_handle_, &delay_frames);
- if (error < 0) {
- error = snd_pcm_recover(playback_handle_,
- error /* Original error. */,
- 0 /* Silenty recover. */);
- }
- if (error < 0) {
- LOG(ERROR) << "Could not query sound device for delay. Assuming 0: "
- << snd_strerror(error);
- }
-
- for (std::deque<Packet*>::const_iterator it = buffered_packets_.begin();
- it != buffered_packets_.end();
- ++it) {
- delay_frames += ((*it)->size - (*it)->used) / bytes_per_frame_;
- }
-
- return delay_frames;
-}
-
-void AlsaPCMOutputStream::BufferPackets() {
- AutoLock l(lock_);
-
- // Handle early outs for errored, stopped, or closing streams.
- if (state_ == STATE_ERROR ||
- state_ == STATE_STOPPED ||
- state_ == STATE_CLOSING) {
- return;
- }
- if (state_ != STATE_STARTED) {
- NOTREACHED() << "Invalid stream state while buffering. "
- << "Expected STATE_STARTED. Current state: " << state_;
- return;
- }
-
- // Early out if the buffer is already full.
- snd_pcm_sframes_t delay_frames = GetFramesOfDelay_Locked();
- if (delay_frames < min_buffer_frames_) {
- // Grab one packet. Drop the lock for the synchronous call. This will
- // still stall the playback thread, but at least it will not block any
- // other threads.
- //
- // TODO(ajwong): Move to cpu@'s non-blocking audio source.
- scoped_ptr<Packet> packet;
- size_t capacity = packet_size_; // Snag it for non-locked usage.
- {
- AutoUnlock synchronous_data_fetch(lock_);
- packet.reset(new Packet(capacity));
- size_t used = source_callback_->OnMoreData(this, packet->buffer.get(),
- packet->capacity);
- CHECK(used <= capacity) << "Data source overran buffer. Aborting.";
- packet->size = used;
- // TODO(ajwong): Do more buffer validation here, like checking that the
- // packet is correctly aligned to frames, etc.
- }
- // After reacquiring the lock, recheck state to make sure it is still
- // STATE_STARTED.
- if (state_ != STATE_STARTED) {
- return;
- }
- buffered_packets_.push_back(packet.release());
-
- // Recalculate delay frames.
- delay_frames = GetFramesOfDelay_Locked();
- }
-
- // Since the current implementation of OnMoreData() blocks, only try to grab
- // one packet per task. If the buffer is still too low, post another
- // BufferPackets() task immediately. Otherwise, calculate when the buffer is
- // likely to need filling and schedule a poll for the future.
- int next_fill_time_ms = (delay_frames - min_buffer_frames_) / sample_rate_;
- if (next_fill_time_ms <= kMinSleepMilliseconds) {
- playback_thread_.message_loop()->PostTask(
- FROM_HERE,
- NewRunnableMethod(this, &AlsaPCMOutputStream::BufferPackets));
- } else {
- // TODO(ajwong): Measure the reliability of the delay interval. Use
- // base/histogram.h.
- playback_thread_.message_loop()->PostDelayedTask(
- FROM_HERE,
- NewRunnableMethod(this, &AlsaPCMOutputStream::BufferPackets),
- next_fill_time_ms);
- }
-
- // If the |device_write_suspended_|, the audio device write tasks have
- // stopped scheduling themselves due to an underrun of the in-memory buffer.
- // Post a new task to restart it since we now have data.
- if (device_write_suspended_) {
- device_write_suspended_ = false;
- playback_thread_.message_loop()->PostTask(
- FROM_HERE,
- NewRunnableMethod(this, &AlsaPCMOutputStream::FillAlsaDeviceBuffer));
- }
-}
-
-void AlsaPCMOutputStream::FillAlsaDeviceBuffer() {
- // TODO(ajwong): Try to move some of this code out from underneath the lock.
- AutoLock l(lock_);
-
- // Find the number of frames that the device can accept right now.
- snd_pcm_sframes_t device_buffer_frames_avail =
- snd_pcm_avail_update(playback_handle_);
-
- // Write up to |device_buffer_frames_avail| frames to the ALSA device.
- while (device_buffer_frames_avail > 0) {
- if (buffered_packets_.empty()) {
- device_write_suspended_ = true;
- break;
- }
-
- Packet* current_packet = buffered_packets_.front();
-
- // Only process non 0-lengthed packets.
- if (current_packet->used < current_packet->size) {
- // Calculate the number of frames we have to write.
- char* buffer_pos = current_packet->buffer.get() + current_packet->used;
- snd_pcm_sframes_t buffer_frames =
- (current_packet->size - current_packet->used) /
- bytes_per_frame_;
- snd_pcm_sframes_t frames_to_write =
- std::min(buffer_frames, device_buffer_frames_avail);
-
- // Check that device_buffer_frames_avail isn't < 0.
- DCHECK_GT(frames_to_write, 0);
-
- // Write it to the device.
- int frames_written =
- snd_pcm_writei(playback_handle_, buffer_pos, frames_to_write);
- if (frames_written < 0) {
- // Recover from EINTR, EPIPE (overrun/underrun), ESTRPIPE (stream
- // suspended).
- //
- // TODO(ajwong): Check that we do not need to loop on recover, here and
- // anywhere else we use recover.
- frames_written = snd_pcm_recover(playback_handle_,
- frames_written /* Original error. */,
- 0 /* Silenty recover. */);
- }
- if (frames_written < 0) {
- LOG(ERROR) << "Failed to write to pcm device: "
- << snd_strerror(frames_written);
- ReleaseResources();
- EnterStateError_Locked();
- break;
- } else {
- current_packet->used += frames_written * bytes_per_frame_;
- DCHECK_LE(current_packet->used, current_packet->size);
- }
- }
-
- if (current_packet->used >= current_packet->size) {
- delete current_packet;
- buffered_packets_.pop_front();
- }
- }
-
- // If the memory buffer was not underrun, schedule another fill in the future.
- if (!device_write_suspended_) {
- playback_thread_.message_loop()->PostDelayedTask(
- FROM_HERE,
- NewRunnableMethod(this, &AlsaPCMOutputStream::FillAlsaDeviceBuffer),
- kTargetLatencyMicroseconds / base::Time::kMicrosecondsPerMillisecond);
- }
-}
-
-void AlsaPCMOutputStream::SetVolume(double left_level, double right_level) {
- NOTIMPLEMENTED();
-}
-
-void AlsaPCMOutputStream::GetVolume(double* left_level, double* right_level) {
- NOTIMPLEMENTED();
-}
-
-size_t AlsaPCMOutputStream::GetNumBuffers() {
- return 0;
-}
diff --git a/media/audio/linux/alsa_output.h b/media/audio/linux/alsa_output.h
deleted file mode 100644
index b6d405b..0000000
--- a/media/audio/linux/alsa_output.h
+++ /dev/null
@@ -1,165 +0,0 @@
-// Copyright (c) 2009 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.
-//
-// Creates an output stream based on the ALSA PCM interface. The current
-// implementation creates one thread per ALSA playback handle that is
-// responsible for synchronously pulling data from the audio data source.
-//
-// This output stream buffers in two places:
-// (1) In the ALSA device
-// (2) In an in-memory buffer.
-//
-// The ALSA device buffer is kept as full as possible. The in-memory buffer
-// attempts to keep enough extra data so that |min_buffer_ms| worth of data
-// is available between the in-memory buffer and the device buffer. Requests
-// to the audio data source are made if the total amount buffered falls below
-// |min_buffer_ms|.
-//
-// On device write failure, the stream will move into an invalid state. No
-// more data will be pulled from the data source, and the playback thread will
-// be stopped.
-//
-// If the stream is successfully opened, Close() must be called before the
-// stream is deleted.
-
-#ifndef MEDIA_AUDIO_LINUX_ALSA_OUTPUT_H_
-#define MEDIA_AUDIO_LINUX_ALSA_OUTPUT_H_
-
-#include <alsa/asoundlib.h>
-
-#include <deque>
-#include <string>
-
-#include "base/lock.h"
-#include "base/ref_counted.h"
-#include "base/scoped_ptr.h"
-#include "base/thread.h"
-#include "media/audio/audio_output.h"
-
-class Thread;
-
-class AlsaPCMOutputStream :
- public AudioOutputStream,
- public base::RefCountedThreadSafe<AlsaPCMOutputStream> {
- public:
- // Set to "plug:default" which should allow ALSA to do whatever is
- // necessary to simulate an audio device capable of handling our PCMs.
- static const char* kDefaultDevice;
-
- // Create a PCM Output stream for the ALSA device identified by
- // |device_name|. If unsure of hte device_name, use kDefaultDevice.
- AlsaPCMOutputStream(const std::string& device_name,
- int min_buffer_ms,
- AudioManager::Format format,
- int channels,
- int sample_rate,
- char bits_per_sample);
- virtual ~AlsaPCMOutputStream();
-
- // Implementation of AudioOutputStream.
- virtual bool Open(size_t packet_size);
- virtual void Close();
- virtual void Start(AudioSourceCallback* callback);
- virtual void Stop();
- virtual void SetVolume(double left_level, double right_level);
- virtual void GetVolume(double* left_level, double* right_level);
- virtual size_t GetNumBuffers();
-
- private:
- // Closes the playback handle, reporting errors if any occur. Returns true
- // if the device was successfully closed.
- bool CloseDevice_Locked();
-
- // Stops playback, ignoring state checks.
- void StopInternal_Locked();
-
- // Moves the stream into the error state, setting the correct internal flags.
- // Ensure that all resources are cleaned up before executing this function.
- void EnterStateError_Locked();
-
- // Releases all the resources in the audio stream. This method will also
- // terminate the playback thread itself.
- //
- // This method must be run in the |playback_thead_|.
- void ReleaseResources();
-
- // Retrieve the total number of frames buffered in both memory and in the
- // audio device. Use this to determine if more data should be requested from
- // the audio source.
- snd_pcm_sframes_t GetFramesOfDelay_Locked();
-
- // Buffer more packets from data source if necessary.
- //
- // This function must be run in the |playback_thread_|.
- void BufferPackets();
-
- // Returns true if our buffer is underfull.
- bool ShouldBufferMore_NoLock();
-
- // Write as many buffered packets into the device as there is room in the
- // device buffer.
- //
- // This function must be run in the |playback_thread_|.
- void FillAlsaDeviceBuffer();
-
- // State of the stream.
- State state_;
-
- // The ALSA device name to use.
- std::string device_name_;
-
- // Handle to the actual PCM playback device.
- snd_pcm_t* playback_handle_;
-
- // Period size for ALSA ring-buffer. Basically, how long to wait between
- // writes.
- snd_pcm_sframes_t period_size_;
-
- // Callback used to request more data from the data source.
- AudioSourceCallback* source_callback_;
-
- // Playback thread.
- base::Thread playback_thread_;
-
- // Lock for field access to this object.
- Lock lock_;
-
- // Sample format configuration.
- snd_pcm_format_t pcm_format_;
- const int channels_;
- const int sample_rate_;
- const char bits_per_sample_;
- char bytes_per_frame_;
-
- // In-memory buffer to hold sound samples before pushing to the sound device.
- // TODO(ajwong): There are now about 3 buffer queue implementations. Factor
- // them out.
- struct Packet {
- explicit Packet(int new_capacity)
- : capacity(new_capacity),
- size(0),
- used(0),
- buffer(new char[capacity]) {
- }
- size_t capacity;
- size_t size;
- size_t used;
- scoped_array<char> buffer;
- };
- int min_buffer_frames_;
- std::deque<Packet*> buffered_packets_;
- size_t packet_size_;
-
- // Flag indiciating the device write tasks have stopped scheduling
- // themselves. This should only be modified by the BufferPackets() and
- // FillAlsaDeviceBuffer() methods.
- bool device_write_suspended_;
-
- // Flag indicating that the resources are already cleaned.
- bool resources_released_;
-
- DISALLOW_COPY_AND_ASSIGN(AlsaPCMOutputStream);
-};
-
-#endif // MEDIA_AUDIO_LINUX_ALSA_OUTPUT_H_
diff --git a/media/audio/linux/audio_manager_linux.cc b/media/audio/linux/audio_manager_linux.cc
index afe1c3c..15a13b2 100644
--- a/media/audio/linux/audio_manager_linux.cc
+++ b/media/audio/linux/audio_manager_linux.cc
@@ -2,70 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "media/audio/linux/audio_manager_linux.h"
-
-#include "base/at_exit.h"
-#include "base/logging.h"
-#include "media/audio/linux/alsa_output.h"
-
-namespace {
-AudioManagerLinux* g_audio_manager = NULL;
-} // namespace
-
-// Implementation of AudioManager.
-bool AudioManagerLinux::HasAudioDevices() {
- // TODO(ajwong): Make this actually query audio devices.
- return true;
-}
-
-AudioOutputStream* AudioManagerLinux::MakeAudioStream(Format format,
- int channels,
- int sample_rate,
- char bits_per_sample) {
- // TODO(ajwong): Do we want to be able to configure the device? plug:default
- // should work correctly for all mono/stereo, but not surround, which needs
- // surround40, surround51, etc.
- //
- // http://0pointer.de/blog/projects/guide-to-sound-apis.html
- AlsaPCMOutputStream* stream =
- new AlsaPCMOutputStream(AlsaPCMOutputStream::kDefaultDevice,
- 100 /* 100ms minimal buffer */,
- format, channels, sample_rate, bits_per_sample);
- return stream;
-}
-
-AudioManagerLinux::AudioManagerLinux() {
-}
-
-AudioManagerLinux::~AudioManagerLinux() {
-}
-
-void AudioManagerLinux::MuteAll() {
- // TODO(ajwong): Implement.
- NOTIMPLEMENTED();
-}
-
-void AudioManagerLinux::UnMuteAll() {
- // TODO(ajwong): Implement.
- NOTIMPLEMENTED();
-}
-
-const void* AudioManagerLinux::GetLastMockBuffer() {
- // TODO(ajwong): Implement.
- NOTIMPLEMENTED();
- return NULL;
-}
-
-// TODO(ajwong): Collapse this with the windows version.
-void DestroyAudioManagerLinux(void* not_used) {
- delete g_audio_manager;
- g_audio_manager = NULL;
-}
+#include "media/audio/audio_output.h"
+// TODO(hclam): Do something more useful than returning NULL.
AudioManager* AudioManager::GetAudioManager() {
- if (!g_audio_manager) {
- g_audio_manager = new AudioManagerLinux();
- base::AtExitManager::RegisterCallback(&DestroyAudioManagerLinux, NULL);
- }
- return g_audio_manager;
+ return NULL;
}
diff --git a/media/audio/linux/audio_manager_linux.h b/media/audio/linux/audio_manager_linux.h
deleted file mode 100644
index 5b369a1..0000000
--- a/media/audio/linux/audio_manager_linux.h
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright (c) 2009 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.
-
-#ifndef MEDIA_AUDIO_LINUX_AUDIO_MANAGER_LINUX_H_
-#define MEDIA_AUDIO_LINUX_AUDIO_MANAGER_LINUX_H_
-
-#include "base/thread.h"
-#include "media/audio/audio_output.h"
-
-class AudioManagerLinux : public AudioManager {
- public:
- AudioManagerLinux();
-
- // Implementation of AudioManager.
- virtual bool HasAudioDevices();
- virtual AudioOutputStream* MakeAudioStream(Format format, int channels,
- int sample_rate,
- char bits_per_sample);
- virtual void MuteAll();
- virtual void UnMuteAll();
- virtual const void* GetLastMockBuffer();
-
- private:
- // Friend function for invoking the private destructor at exit.
- friend void DestroyAudioManagerLinux(void*);
- virtual ~AudioManagerLinux();
-
- DISALLOW_COPY_AND_ASSIGN(AudioManagerLinux);
-};
-
-#endif // MEDIA_AUDIO_LINUX_AUDIO_MANAGER_LINUX_H_
diff --git a/media/media.gyp b/media/media.gyp
index a905b4e..8f95715 100644
--- a/media/media.gyp
+++ b/media/media.gyp
@@ -31,9 +31,6 @@
'sources': [
'audio/audio_output.h',
'audio/linux/audio_manager_linux.cc',
- 'audio/linux/audio_manager_linux.h',
- 'audio/linux/alsa_output.cc',
- 'audio/linux/alsa_output.h',
'audio/mac/audio_manager_mac.cc',
'audio/mac/audio_manager_mac.h',
'audio/mac/audio_output_mac.cc',
@@ -110,11 +107,6 @@
['OS =="linux"', {
'sources/': [ ['exclude', '_(mac|win)\\.cc$'],
['exclude', '\\.mm?$' ] ],
- 'link_settings': {
- 'libraries': [
- '-lasound',
- ],
- },
}],
['OS =="mac"', {
'link_settings': {