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

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: . 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
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 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 // Since we expect to only be able to wake up with a resolution of 175 // Since we expect to only be able to wake up with a resolution of
176 // kSleepErrorMilliseconds, double that for our minimum required latency. 176 // kSleepErrorMilliseconds, double that for our minimum required latency.
177 const uint32 AlsaPcmOutputStream::kMinLatencyMicros = 177 const uint32 AlsaPcmOutputStream::kMinLatencyMicros =
178 kSleepErrorMilliseconds * 2 * 1000; 178 kSleepErrorMilliseconds * 2 * 1000;
179 179
180 AlsaPcmOutputStream::AlsaPcmOutputStream(const std::string& device_name, 180 AlsaPcmOutputStream::AlsaPcmOutputStream(const std::string& device_name,
181 const AudioParameters& params, 181 const AudioParameters& params,
182 AlsaWrapper* wrapper, 182 AlsaWrapper* wrapper,
183 AudioManagerLinux* manager) 183 AudioManagerLinux* manager)
184 : requested_device_name_(device_name), 184 : requested_device_name_(device_name),
185 pcm_format_(alsa_util::BitsToFormat(params.bits_per_sample)), 185 pcm_format_(alsa_util::BitsToFormat(params.bits_per_sample())),
186 channels_(params.channels), 186 channels_(params.channels()),
187 sample_rate_(params.sample_rate), 187 sample_rate_(params.sample_rate()),
188 bytes_per_sample_(params.bits_per_sample / 8), 188 bytes_per_sample_(params.bits_per_sample() / 8),
189 bytes_per_frame_(channels_ * params.bits_per_sample / 8), 189 bytes_per_frame_(channels_ * params.bits_per_sample() / 8),
190 should_downmix_(false), 190 should_downmix_(false),
191 packet_size_(params.GetPacketSize()), 191 packet_size_(params.GetBytesPerBuffer()),
192 micros_per_packet_(FramesToMicros( 192 micros_per_packet_(FramesToMicros(
193 params.samples_per_packet, sample_rate_)), 193 params.frames_per_buffer(), sample_rate_)),
194 latency_micros_(std::max(AlsaPcmOutputStream::kMinLatencyMicros, 194 latency_micros_(std::max(AlsaPcmOutputStream::kMinLatencyMicros,
195 micros_per_packet_ * 2)), 195 micros_per_packet_ * 2)),
196 bytes_per_output_frame_(bytes_per_frame_), 196 bytes_per_output_frame_(bytes_per_frame_),
197 alsa_buffer_frames_(0), 197 alsa_buffer_frames_(0),
198 stop_stream_(false), 198 stop_stream_(false),
199 wrapper_(wrapper), 199 wrapper_(wrapper),
200 manager_(manager), 200 manager_(manager),
201 playback_handle_(NULL), 201 playback_handle_(NULL),
202 frames_per_packet_(packet_size_ / bytes_per_frame_), 202 frames_per_packet_(packet_size_ / bytes_per_frame_),
203 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)), 203 ALLOW_THIS_IN_INITIALIZER_LIST(weak_factory_(this)),
204 state_(kCreated), 204 state_(kCreated),
205 volume_(1.0f), 205 volume_(1.0f),
206 source_callback_(NULL) { 206 source_callback_(NULL) {
207 DCHECK(IsOnAudioThread()); 207 DCHECK(IsOnAudioThread());
208 208
209 // Sanity check input values. 209 // Sanity check input values.
210 if ((params.sample_rate > kAlsaMaxSampleRate) || (params.sample_rate <= 0)) { 210 if (params.sample_rate() > kAlsaMaxSampleRate ||
211 params.sample_rate() <= 0) {
211 LOG(WARNING) << "Unsupported audio frequency."; 212 LOG(WARNING) << "Unsupported audio frequency.";
212 TransitionTo(kInError); 213 TransitionTo(kInError);
213 } 214 }
214 215
215 if (AudioParameters::AUDIO_PCM_LINEAR != params.format && 216 if (AudioParameters::AUDIO_PCM_LINEAR != params.format() &&
216 AudioParameters::AUDIO_PCM_LOW_LATENCY != params.format) { 217 AudioParameters::AUDIO_PCM_LOW_LATENCY != params.format()) {
217 LOG(WARNING) << "Unsupported audio format"; 218 LOG(WARNING) << "Unsupported audio format";
218 TransitionTo(kInError); 219 TransitionTo(kInError);
219 } 220 }
220 221
221 if (pcm_format_ == SND_PCM_FORMAT_UNKNOWN) { 222 if (pcm_format_ == SND_PCM_FORMAT_UNKNOWN) {
222 LOG(WARNING) << "Unsupported bits per sample: " << params.bits_per_sample; 223 LOG(WARNING) << "Unsupported bits per sample: " << params.bits_per_sample();
223 TransitionTo(kInError); 224 TransitionTo(kInError);
224 } 225 }
225 } 226 }
226 227
227 AlsaPcmOutputStream::~AlsaPcmOutputStream() { 228 AlsaPcmOutputStream::~AlsaPcmOutputStream() {
228 InternalState current_state = state(); 229 InternalState current_state = state();
229 DCHECK(current_state == kCreated || 230 DCHECK(current_state == kCreated ||
230 current_state == kIsClosed || 231 current_state == kIsClosed ||
231 current_state == kInError); 232 current_state == kInError);
232 DCHECK(!playback_handle_); 233 DCHECK(!playback_handle_);
(...skipping 16 matching lines...) Expand all
249 // transition out from under us. 250 // transition out from under us.
250 TransitionTo(kIsOpened); 251 TransitionTo(kIsOpened);
251 252
252 // Try to open the device. 253 // Try to open the device.
253 if (requested_device_name_ == kAutoSelectDevice) { 254 if (requested_device_name_ == kAutoSelectDevice) {
254 playback_handle_ = AutoSelectDevice(latency_micros_); 255 playback_handle_ = AutoSelectDevice(latency_micros_);
255 if (playback_handle_) 256 if (playback_handle_)
256 DVLOG(1) << "Auto-selected device: " << device_name_; 257 DVLOG(1) << "Auto-selected device: " << device_name_;
257 } else { 258 } else {
258 device_name_ = requested_device_name_; 259 device_name_ = requested_device_name_;
259 playback_handle_ = alsa_util::OpenPlaybackDevice(wrapper_, 260 playback_handle_ = alsa_util::OpenPlaybackDevice(
260 device_name_.c_str(), 261 wrapper_, device_name_.c_str(), channels_, sample_rate_,
261 channels_, sample_rate_, 262 pcm_format_, latency_micros_);
262 pcm_format_,
263 latency_micros_);
264 } 263 }
265 264
266 // Finish initializing the stream if the device was opened successfully. 265 // Finish initializing the stream if the device was opened successfully.
267 if (playback_handle_ == NULL) { 266 if (playback_handle_ == NULL) {
268 stop_stream_ = true; 267 stop_stream_ = true;
269 TransitionTo(kInError); 268 TransitionTo(kInError);
270 return false; 269 return false;
271 } else { 270 } else {
272 bytes_per_output_frame_ = should_downmix_ ? 2 * bytes_per_sample_ : 271 bytes_per_output_frame_ = should_downmix_ ? 2 * bytes_per_sample_ :
273 bytes_per_frame_; 272 bytes_per_frame_;
(...skipping 331 matching lines...) Expand 10 before | Expand all | Expand 10 after
605 // base/metrics/histogram.h. 604 // base/metrics/histogram.h.
606 manager_->GetMessageLoop()->PostDelayedTask( 605 manager_->GetMessageLoop()->PostDelayedTask(
607 FROM_HERE, 606 FROM_HERE,
608 base::Bind(&AlsaPcmOutputStream::WriteTask, 607 base::Bind(&AlsaPcmOutputStream::WriteTask,
609 weak_factory_.GetWeakPtr()), 608 weak_factory_.GetWeakPtr()),
610 base::TimeDelta::FromMilliseconds(next_fill_time_ms)); 609 base::TimeDelta::FromMilliseconds(next_fill_time_ms));
611 } 610 }
612 } 611 }
613 } 612 }
614 613
615 uint32 AlsaPcmOutputStream::FramesToMicros(uint32 frames, uint32 sample_rate) { 614 uint32 AlsaPcmOutputStream::FramesToMicros(uint32 frames,
615 uint32 sample_rate) {
616 return frames * base::Time::kMicrosecondsPerSecond / sample_rate; 616 return frames * base::Time::kMicrosecondsPerSecond / sample_rate;
617 } 617 }
618 618
619 uint32 AlsaPcmOutputStream::FramesToMillis(uint32 frames, uint32 sample_rate) { 619 uint32 AlsaPcmOutputStream::FramesToMillis(uint32 frames,
620 uint32 sample_rate) {
620 return frames * base::Time::kMillisecondsPerSecond / sample_rate; 621 return frames * base::Time::kMillisecondsPerSecond / sample_rate;
621 } 622 }
622 623
623 std::string AlsaPcmOutputStream::FindDeviceForChannels(uint32 channels) { 624 std::string AlsaPcmOutputStream::FindDeviceForChannels(uint32 channels) {
624 // Constants specified by the ALSA API for device hints. 625 // Constants specified by the ALSA API for device hints.
625 static const int kGetAllDevices = -1; 626 static const int kGetAllDevices = -1;
626 static const char kPcmInterfaceName[] = "pcm"; 627 static const char kPcmInterfaceName[] = "pcm";
627 static const char kIoHintName[] = "IOID"; 628 static const char kIoHintName[] = "IOID";
628 static const char kNameHintName[] = "NAME"; 629 static const char kNameHintName[] = "NAME";
629 630
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
755 // 756 //
756 // TODO(ajwong): We need a SupportsFolding() function. 757 // TODO(ajwong): We need a SupportsFolding() function.
757 uint32 default_channels = channels_; 758 uint32 default_channels = channels_;
758 if (default_channels > 2 && default_channels <= 8) { 759 if (default_channels > 2 && default_channels <= 8) {
759 should_downmix_ = true; 760 should_downmix_ = true;
760 default_channels = 2; 761 default_channels = 2;
761 } 762 }
762 763
763 // Step 3. 764 // Step 3.
764 device_name_ = kDefaultDevice; 765 device_name_ = kDefaultDevice;
765 if ((handle = alsa_util::OpenPlaybackDevice(wrapper_, device_name_.c_str(), 766 if ((handle = alsa_util::OpenPlaybackDevice(
766 default_channels, sample_rate_, 767 wrapper_, device_name_.c_str(), default_channels, sample_rate_,
767 pcm_format_, latency)) != NULL) { 768 pcm_format_, latency)) != NULL) {
768 return handle; 769 return handle;
769 } 770 }
770 771
771 // Step 4. 772 // Step 4.
772 device_name_ = kPlugPrefix + device_name_; 773 device_name_ = kPlugPrefix + device_name_;
773 if ((handle = alsa_util::OpenPlaybackDevice(wrapper_, device_name_.c_str(), 774 if ((handle = alsa_util::OpenPlaybackDevice(
774 default_channels, sample_rate_, 775 wrapper_, device_name_.c_str(), default_channels, sample_rate_,
775 pcm_format_, latency)) != NULL) { 776 pcm_format_, latency)) != NULL) {
776 return handle; 777 return handle;
777 } 778 }
778 779
779 // Unable to open any device. 780 // Unable to open any device.
780 device_name_.clear(); 781 device_name_.clear();
781 return NULL; 782 return NULL;
782 } 783 }
783 784
784 bool AlsaPcmOutputStream::CanTransitionTo(InternalState to) { 785 bool AlsaPcmOutputStream::CanTransitionTo(InternalState to) {
785 switch (state_) { 786 switch (state_) {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
844 if (source_callback_) 845 if (source_callback_)
845 source_callback_->OnError(this, code); 846 source_callback_->OnError(this, code);
846 } 847 }
847 848
848 // Changes the AudioSourceCallback to proxy calls to. Pass in NULL to 849 // Changes the AudioSourceCallback to proxy calls to. Pass in NULL to
849 // release ownership of the currently registered callback. 850 // release ownership of the currently registered callback.
850 void AlsaPcmOutputStream::set_source_callback(AudioSourceCallback* callback) { 851 void AlsaPcmOutputStream::set_source_callback(AudioSourceCallback* callback) {
851 DCHECK(IsOnAudioThread()); 852 DCHECK(IsOnAudioThread());
852 source_callback_ = callback; 853 source_callback_ = callback;
853 } 854 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698