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

Side by Side Diff: media/audio/linux/alsa_output.cc

Issue 9655018: Make AudioParameters a class instead of a struct (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix copyright years Created 8 years, 9 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 unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/audio/linux/alsa_input.cc ('k') | media/audio/linux/alsa_output_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 // 4 //
5 // THREAD SAFETY 5 // THREAD SAFETY
6 // 6 //
7 // AlsaPcmOutputStream object is *not* thread-safe and should only be used 7 // AlsaPcmOutputStream object is *not* thread-safe and should only be used
8 // from the audio thread. We DCHECK on this assumption whenever we can. 8 // from the audio thread. We DCHECK on this assumption whenever we can.
9 // 9 //
10 // SEMANTICS OF Close() 10 // SEMANTICS OF Close()
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 // Since we expect to only be able to wake up with a resolution of 144 // Since we expect to only be able to wake up with a resolution of
145 // kSleepErrorMilliseconds, double that for our minimum required latency. 145 // kSleepErrorMilliseconds, double that for our minimum required latency.
146 const uint32 AlsaPcmOutputStream::kMinLatencyMicros = 146 const uint32 AlsaPcmOutputStream::kMinLatencyMicros =
147 kSleepErrorMilliseconds * 2 * 1000; 147 kSleepErrorMilliseconds * 2 * 1000;
148 148
149 AlsaPcmOutputStream::AlsaPcmOutputStream(const std::string& device_name, 149 AlsaPcmOutputStream::AlsaPcmOutputStream(const std::string& device_name,
150 const AudioParameters& params, 150 const AudioParameters& params,
151 AlsaWrapper* wrapper, 151 AlsaWrapper* wrapper,
152 AudioManagerLinux* manager) 152 AudioManagerLinux* manager)
153 : requested_device_name_(device_name), 153 : requested_device_name_(device_name),
154 pcm_format_(alsa_util::BitsToFormat(params.bits_per_sample)), 154 pcm_format_(alsa_util::BitsToFormat(params.bits_per_sample())),
155 channels_(params.channels), 155 channels_(params.channels()),
156 sample_rate_(params.sample_rate), 156 sample_rate_(params.sample_rate()),
157 bytes_per_sample_(params.bits_per_sample / 8), 157 bytes_per_sample_(params.bits_per_sample() / 8),
158 bytes_per_frame_(channels_ * params.bits_per_sample / 8), 158 bytes_per_frame_(channels_ * params.bits_per_sample() / 8),
159 should_downmix_(false), 159 should_downmix_(false),
160 packet_size_(params.GetPacketSize()), 160 packet_size_(params.GetBytesPerBuffer()),
161 micros_per_packet_(FramesToMicros( 161 micros_per_packet_(FramesToMicros(
162 params.samples_per_packet, sample_rate_)), 162 params.frames_per_buffer(), sample_rate_)),
163 latency_micros_(std::max(AlsaPcmOutputStream::kMinLatencyMicros, 163 latency_micros_(std::max(AlsaPcmOutputStream::kMinLatencyMicros,
164 micros_per_packet_ * 2)), 164 micros_per_packet_ * 2)),
165 bytes_per_output_frame_(bytes_per_frame_), 165 bytes_per_output_frame_(bytes_per_frame_),
166 alsa_buffer_frames_(0), 166 alsa_buffer_frames_(0),
167 stop_stream_(false), 167 stop_stream_(false),
168 wrapper_(wrapper), 168 wrapper_(wrapper),
169 manager_(manager), 169 manager_(manager),
170 playback_handle_(NULL), 170 playback_handle_(NULL),
171 frames_per_packet_(packet_size_ / bytes_per_frame_), 171 frames_per_packet_(packet_size_ / bytes_per_frame_),
172 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), 172 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
173 state_(kCreated), 173 state_(kCreated),
174 volume_(1.0f), 174 volume_(1.0f),
175 source_callback_(NULL) { 175 source_callback_(NULL) {
176 DCHECK(IsOnAudioThread()); 176 DCHECK(IsOnAudioThread());
177 177
178 // Sanity check input values. 178 // Sanity check input values.
179 if ((params.sample_rate > kAlsaMaxSampleRate) || (params.sample_rate <= 0)) { 179 if (params.sample_rate() > kAlsaMaxSampleRate ||
180 params.sample_rate() <= 0) {
180 LOG(WARNING) << "Unsupported audio frequency."; 181 LOG(WARNING) << "Unsupported audio frequency.";
181 TransitionTo(kInError); 182 TransitionTo(kInError);
182 } 183 }
183 184
184 if (AudioParameters::AUDIO_PCM_LINEAR != params.format && 185 if (AudioParameters::AUDIO_PCM_LINEAR != params.format() &&
185 AudioParameters::AUDIO_PCM_LOW_LATENCY != params.format) { 186 AudioParameters::AUDIO_PCM_LOW_LATENCY != params.format()) {
186 LOG(WARNING) << "Unsupported audio format"; 187 LOG(WARNING) << "Unsupported audio format";
187 TransitionTo(kInError); 188 TransitionTo(kInError);
188 } 189 }
189 190
190 if (pcm_format_ == SND_PCM_FORMAT_UNKNOWN) { 191 if (pcm_format_ == SND_PCM_FORMAT_UNKNOWN) {
191 LOG(WARNING) << "Unsupported bits per sample: " << params.bits_per_sample; 192 LOG(WARNING) << "Unsupported bits per sample: " << params.bits_per_sample();
192 TransitionTo(kInError); 193 TransitionTo(kInError);
193 } 194 }
194 } 195 }
195 196
196 AlsaPcmOutputStream::~AlsaPcmOutputStream() { 197 AlsaPcmOutputStream::~AlsaPcmOutputStream() {
197 InternalState current_state = state(); 198 InternalState current_state = state();
198 DCHECK(current_state == kCreated || 199 DCHECK(current_state == kCreated ||
199 current_state == kIsClosed || 200 current_state == kIsClosed ||
200 current_state == kInError); 201 current_state == kInError);
201 DCHECK(!playback_handle_); 202 DCHECK(!playback_handle_);
(...skipping 16 matching lines...) Expand all
218 // transition out from under us. 219 // transition out from under us.
219 TransitionTo(kIsOpened); 220 TransitionTo(kIsOpened);
220 221
221 // Try to open the device. 222 // Try to open the device.
222 if (requested_device_name_ == kAutoSelectDevice) { 223 if (requested_device_name_ == kAutoSelectDevice) {
223 playback_handle_ = AutoSelectDevice(latency_micros_); 224 playback_handle_ = AutoSelectDevice(latency_micros_);
224 if (playback_handle_) 225 if (playback_handle_)
225 DVLOG(1) << "Auto-selected device: " << device_name_; 226 DVLOG(1) << "Auto-selected device: " << device_name_;
226 } else { 227 } else {
227 device_name_ = requested_device_name_; 228 device_name_ = requested_device_name_;
228 playback_handle_ = alsa_util::OpenPlaybackDevice(wrapper_, 229 playback_handle_ = alsa_util::OpenPlaybackDevice(
229 device_name_.c_str(), 230 wrapper_, device_name_.c_str(), channels_, sample_rate_,
230 channels_, sample_rate_, 231 pcm_format_, latency_micros_);
231 pcm_format_,
232 latency_micros_);
233 } 232 }
234 233
235 // Finish initializing the stream if the device was opened successfully. 234 // Finish initializing the stream if the device was opened successfully.
236 if (playback_handle_ == NULL) { 235 if (playback_handle_ == NULL) {
237 stop_stream_ = true; 236 stop_stream_ = true;
238 TransitionTo(kInError); 237 TransitionTo(kInError);
239 return false; 238 return false;
240 } else { 239 } else {
241 bytes_per_output_frame_ = should_downmix_ ? 2 * bytes_per_sample_ : 240 bytes_per_output_frame_ = should_downmix_ ? 2 * bytes_per_sample_ :
242 bytes_per_frame_; 241 bytes_per_frame_;
(...skipping 307 matching lines...) Expand 10 before | Expand all | Expand 10 after
550 // base/metrics/histogram.h. 549 // base/metrics/histogram.h.
551 manager_->GetMessageLoop()->PostDelayedTask( 550 manager_->GetMessageLoop()->PostDelayedTask(
552 FROM_HERE, 551 FROM_HERE,
553 base::Bind(&AlsaPcmOutputStream::WriteTask, 552 base::Bind(&AlsaPcmOutputStream::WriteTask,
554 weak_factory_.GetWeakPtr()), 553 weak_factory_.GetWeakPtr()),
555 base::TimeDelta::FromMilliseconds(next_fill_time_ms)); 554 base::TimeDelta::FromMilliseconds(next_fill_time_ms));
556 } 555 }
557 } 556 }
558 } 557 }
559 558
560 uint32 AlsaPcmOutputStream::FramesToMicros(uint32 frames, uint32 sample_rate) { 559 uint32 AlsaPcmOutputStream::FramesToMicros(uint32 frames,
560 uint32 sample_rate) {
561 return frames * base::Time::kMicrosecondsPerSecond / sample_rate; 561 return frames * base::Time::kMicrosecondsPerSecond / sample_rate;
562 } 562 }
563 563
564 uint32 AlsaPcmOutputStream::FramesToMillis(uint32 frames, uint32 sample_rate) { 564 uint32 AlsaPcmOutputStream::FramesToMillis(uint32 frames,
565 uint32 sample_rate) {
565 return frames * base::Time::kMillisecondsPerSecond / sample_rate; 566 return frames * base::Time::kMillisecondsPerSecond / sample_rate;
566 } 567 }
567 568
568 std::string AlsaPcmOutputStream::FindDeviceForChannels(uint32 channels) { 569 std::string AlsaPcmOutputStream::FindDeviceForChannels(uint32 channels) {
569 // Constants specified by the ALSA API for device hints. 570 // Constants specified by the ALSA API for device hints.
570 static const int kGetAllDevices = -1; 571 static const int kGetAllDevices = -1;
571 static const char kPcmInterfaceName[] = "pcm"; 572 static const char kPcmInterfaceName[] = "pcm";
572 static const char kIoHintName[] = "IOID"; 573 static const char kIoHintName[] = "IOID";
573 static const char kNameHintName[] = "NAME"; 574 static const char kNameHintName[] = "NAME";
574 575
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
700 // 701 //
701 // TODO(ajwong): We need a SupportsFolding() function. 702 // TODO(ajwong): We need a SupportsFolding() function.
702 uint32 default_channels = channels_; 703 uint32 default_channels = channels_;
703 if (default_channels > 2 && default_channels <= 8) { 704 if (default_channels > 2 && default_channels <= 8) {
704 should_downmix_ = true; 705 should_downmix_ = true;
705 default_channels = 2; 706 default_channels = 2;
706 } 707 }
707 708
708 // Step 3. 709 // Step 3.
709 device_name_ = kDefaultDevice; 710 device_name_ = kDefaultDevice;
710 if ((handle = alsa_util::OpenPlaybackDevice(wrapper_, device_name_.c_str(), 711 if ((handle = alsa_util::OpenPlaybackDevice(
711 default_channels, sample_rate_, 712 wrapper_, device_name_.c_str(), default_channels, sample_rate_,
712 pcm_format_, latency)) != NULL) { 713 pcm_format_, latency)) != NULL) {
713 return handle; 714 return handle;
714 } 715 }
715 716
716 // Step 4. 717 // Step 4.
717 device_name_ = kPlugPrefix + device_name_; 718 device_name_ = kPlugPrefix + device_name_;
718 if ((handle = alsa_util::OpenPlaybackDevice(wrapper_, device_name_.c_str(), 719 if ((handle = alsa_util::OpenPlaybackDevice(
719 default_channels, sample_rate_, 720 wrapper_, device_name_.c_str(), default_channels, sample_rate_,
720 pcm_format_, latency)) != NULL) { 721 pcm_format_, latency)) != NULL) {
721 return handle; 722 return handle;
722 } 723 }
723 724
724 // Unable to open any device. 725 // Unable to open any device.
725 device_name_.clear(); 726 device_name_.clear();
726 return NULL; 727 return NULL;
727 } 728 }
728 729
729 bool AlsaPcmOutputStream::CanTransitionTo(InternalState to) { 730 bool AlsaPcmOutputStream::CanTransitionTo(InternalState to) {
730 switch (state_) { 731 switch (state_) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
789 if (source_callback_) 790 if (source_callback_)
790 source_callback_->OnError(this, code); 791 source_callback_->OnError(this, code);
791 } 792 }
792 793
793 // Changes the AudioSourceCallback to proxy calls to. Pass in NULL to 794 // Changes the AudioSourceCallback to proxy calls to. Pass in NULL to
794 // release ownership of the currently registered callback. 795 // release ownership of the currently registered callback.
795 void AlsaPcmOutputStream::set_source_callback(AudioSourceCallback* callback) { 796 void AlsaPcmOutputStream::set_source_callback(AudioSourceCallback* callback) {
796 DCHECK(IsOnAudioThread()); 797 DCHECK(IsOnAudioThread());
797 source_callback_ = callback; 798 source_callback_ = callback;
798 } 799 }
OLDNEW
« no previous file with comments | « media/audio/linux/alsa_input.cc ('k') | media/audio/linux/alsa_output_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698