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

Side by Side Diff: media/audio/win/audio_low_latency_output_win.cc

Issue 2475953003: Support floating-point audio output for Windows7+ (Closed)
Patch Set: Created 4 years, 1 month 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
« no previous file with comments | « no previous file | no next file » | 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 #include "media/audio/win/audio_low_latency_output_win.h" 5 #include "media/audio/win/audio_low_latency_output_win.h"
6 6
7 #include <Functiondiscoverykeys_devpkey.h> 7 #include <Functiondiscoverykeys_devpkey.h>
8 8
9 #include <climits>
10
9 #include "base/command_line.h" 11 #include "base/command_line.h"
10 #include "base/logging.h" 12 #include "base/logging.h"
11 #include "base/macros.h" 13 #include "base/macros.h"
12 #include "base/metrics/histogram.h" 14 #include "base/metrics/histogram.h"
13 #include "base/strings/utf_string_conversions.h" 15 #include "base/strings/utf_string_conversions.h"
14 #include "base/time/time.h" 16 #include "base/time/time.h"
15 #include "base/trace_event/trace_event.h" 17 #include "base/trace_event/trace_event.h"
16 #include "base/win/scoped_propvariant.h" 18 #include "base/win/scoped_propvariant.h"
17 #include "media/audio/audio_device_description.h" 19 #include "media/audio/audio_device_description.h"
18 #include "media/audio/win/audio_manager_win.h" 20 #include "media/audio/win/audio_manager_win.h"
19 #include "media/audio/win/avrt_wrapper_win.h" 21 #include "media/audio/win/avrt_wrapper_win.h"
20 #include "media/audio/win/core_audio_util_win.h" 22 #include "media/audio/win/core_audio_util_win.h"
23 #include "media/base/audio_sample_types.h"
21 #include "media/base/limits.h" 24 #include "media/base/limits.h"
22 #include "media/base/media_switches.h" 25 #include "media/base/media_switches.h"
23 26
24 using base::win::ScopedComPtr; 27 using base::win::ScopedComPtr;
25 using base::win::ScopedCOMInitializer; 28 using base::win::ScopedCOMInitializer;
26 using base::win::ScopedCoMem; 29 using base::win::ScopedCoMem;
27 30
28 namespace media { 31 namespace media {
29 32
30 // static 33 // static
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
64 format_(), 67 format_(),
65 opened_(false), 68 opened_(false),
66 volume_(1.0), 69 volume_(1.0),
67 packet_size_frames_(0), 70 packet_size_frames_(0),
68 packet_size_bytes_(0), 71 packet_size_bytes_(0),
69 endpoint_buffer_size_frames_(0), 72 endpoint_buffer_size_frames_(0),
70 device_id_(device_id), 73 device_id_(device_id),
71 device_role_(device_role), 74 device_role_(device_role),
72 share_mode_(GetShareMode()), 75 share_mode_(GetShareMode()),
73 num_written_frames_(0), 76 num_written_frames_(0),
74 source_(NULL), 77 source_(NULL) {
75 audio_bus_(AudioBus::Create(params)) {
76 DCHECK(manager_); 78 DCHECK(manager_);
77 79
78 // The empty string is used to indicate a default device and the 80 // The empty string is used to indicate a default device and the
79 // |device_role_| member controls whether that's the default or default 81 // |device_role_| member controls whether that's the default or default
80 // communications device. 82 // communications device.
81 DCHECK_NE(device_id_, AudioDeviceDescription::kDefaultDeviceId); 83 DCHECK_NE(device_id_, AudioDeviceDescription::kDefaultDeviceId);
82 DCHECK_NE(device_id_, AudioDeviceDescription::kCommunicationsDeviceId); 84 DCHECK_NE(device_id_, AudioDeviceDescription::kCommunicationsDeviceId);
83 85
84 DVLOG(1) << "WASAPIAudioOutputStream::WASAPIAudioOutputStream()"; 86 DVLOG(1) << "WASAPIAudioOutputStream::WASAPIAudioOutputStream()";
85 DVLOG_IF(1, share_mode_ == AUDCLNT_SHAREMODE_EXCLUSIVE) 87 DVLOG_IF(1, share_mode_ == AUDCLNT_SHAREMODE_EXCLUSIVE)
86 << "Core Audio (WASAPI) EXCLUSIVE MODE is enabled."; 88 << "Core Audio (WASAPI) EXCLUSIVE MODE is enabled.";
87 89
88 // Load the Avrt DLL if not already loaded. Required to support MMCSS. 90 // Load the Avrt DLL if not already loaded. Required to support MMCSS.
89 bool avrt_init = avrt::Initialize(); 91 bool avrt_init = avrt::Initialize();
90 DCHECK(avrt_init) << "Failed to load the avrt.dll"; 92 DCHECK(avrt_init) << "Failed to load the avrt.dll";
91 93
94 // New set that appropriate for float output.
95 AudioParameters floatParams = AudioParameters(AudioParameters(
DaleCurtis 2016/11/07 18:54:00 float_params also you're constructing three audio
Raymond Toy 2016/11/07 19:03:20 Whoa! Don't know how that happened!
96 params.format(), params.channel_layout(), params.sample_rate(),
97 // Ignore the given bits per sample because we're outputting
98 // floats.
99 sizeof(float) * CHAR_BIT, params.frames_per_buffer()));
100
101 audio_bus_ = AudioBus::Create(floatParams);
102
92 // Set up the desired render format specified by the client. We use the 103 // Set up the desired render format specified by the client. We use the
93 // WAVE_FORMAT_EXTENSIBLE structure to ensure that multiple channel ordering 104 // WAVE_FORMAT_EXTENSIBLE structure to ensure that multiple channel ordering
94 // and high precision data can be supported. 105 // and high precision data can be supported.
95 106
96 // Begin with the WAVEFORMATEX structure that specifies the basic format. 107 // Begin with the WAVEFORMATEX structure that specifies the basic format.
97 WAVEFORMATEX* format = &format_.Format; 108 WAVEFORMATEX* format = &format_.Format;
98 format->wFormatTag = WAVE_FORMAT_EXTENSIBLE; 109 format->wFormatTag = WAVE_FORMAT_EXTENSIBLE;
99 format->nChannels = params.channels(); 110 format->nChannels = floatParams.channels();
100 format->nSamplesPerSec = params.sample_rate(); 111 format->nSamplesPerSec = floatParams.sample_rate();
101 format->wBitsPerSample = params.bits_per_sample(); 112 format->wBitsPerSample = floatParams.bits_per_sample();
102 format->nBlockAlign = (format->wBitsPerSample / 8) * format->nChannels; 113 format->nBlockAlign = (format->wBitsPerSample / 8) * format->nChannels;
103 format->nAvgBytesPerSec = format->nSamplesPerSec * format->nBlockAlign; 114 format->nAvgBytesPerSec = format->nSamplesPerSec * format->nBlockAlign;
104 format->cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); 115 format->cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
105 116
106 // Add the parts which are unique to WAVE_FORMAT_EXTENSIBLE. 117 // Add the parts which are unique to WAVE_FORMAT_EXTENSIBLE.
107 format_.Samples.wValidBitsPerSample = params.bits_per_sample(); 118 format_.Samples.wValidBitsPerSample = floatParams.bits_per_sample();
108 format_.dwChannelMask = CoreAudioUtil::GetChannelConfig(device_id, eRender); 119 format_.dwChannelMask = CoreAudioUtil::GetChannelConfig(device_id, eRender);
109 format_.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; 120 format_.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
110 121
111 // Store size (in different units) of audio packets which we expect to 122 // Store size (in different units) of audio packets which we expect to
112 // get from the audio endpoint device in each render event. 123 // get from the audio endpoint device in each render event.
113 packet_size_frames_ = params.frames_per_buffer(); 124 packet_size_frames_ = floatParams.frames_per_buffer();
114 packet_size_bytes_ = params.GetBytesPerBuffer(); 125 packet_size_bytes_ = floatParams.GetBytesPerBuffer();
115 DVLOG(1) << "Number of bytes per audio frame : " << format->nBlockAlign; 126 DVLOG(1) << "Number of bytes per audio frame : " << format->nBlockAlign;
116 DVLOG(1) << "Number of audio frames per packet: " << packet_size_frames_; 127 DVLOG(1) << "Number of audio frames per packet: " << packet_size_frames_;
117 DVLOG(1) << "Number of bytes per packet : " << packet_size_bytes_; 128 DVLOG(1) << "Number of bytes per packet : " << packet_size_bytes_;
118 DVLOG(1) << "Number of milliseconds per packet: " 129 DVLOG(1) << "Number of milliseconds per packet: "
119 << params.GetBufferDuration().InMillisecondsF(); 130 << floatParams.GetBufferDuration().InMillisecondsF();
120 131
121 // All events are auto-reset events and non-signaled initially. 132 // All events are auto-reset events and non-signaled initially.
122 133
123 // Create the event which the audio engine will signal each time 134 // Create the event which the audio engine will signal each time
124 // a buffer becomes ready to be processed by the client. 135 // a buffer becomes ready to be processed by the client.
125 audio_samples_render_event_.Set(CreateEvent(NULL, FALSE, FALSE, NULL)); 136 audio_samples_render_event_.Set(CreateEvent(NULL, FALSE, FALSE, NULL));
126 DCHECK(audio_samples_render_event_.IsValid()); 137 DCHECK(audio_samples_render_event_.IsValid());
127 138
128 // Create the event which will be set in Stop() when capturing shall stop. 139 // Create the event which will be set in Stop() when capturing shall stop.
129 stop_render_event_.Set(CreateEvent(NULL, FALSE, FALSE, NULL)); 140 stop_render_event_.Set(CreateEvent(NULL, FALSE, FALSE, NULL));
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 } 548 }
538 549
539 // Read a data packet from the registered client source and 550 // Read a data packet from the registered client source and
540 // deliver a delay estimate in the same callback to the client. 551 // deliver a delay estimate in the same callback to the client.
541 552
542 int frames_filled = 553 int frames_filled =
543 source_->OnMoreData(delay, delay_timestamp, 0, audio_bus_.get()); 554 source_->OnMoreData(delay, delay_timestamp, 0, audio_bus_.get());
544 uint32_t num_filled_bytes = frames_filled * format_.Format.nBlockAlign; 555 uint32_t num_filled_bytes = frames_filled * format_.Format.nBlockAlign;
545 DCHECK_LE(num_filled_bytes, packet_size_bytes_); 556 DCHECK_LE(num_filled_bytes, packet_size_bytes_);
546 557
547 // Note: If this ever changes to output raw float the data must be
548 // clipped and sanitized since it may come from an untrusted
549 // source such as NaCl.
550 const int bytes_per_sample = format_.Format.wBitsPerSample >> 3;
551 audio_bus_->Scale(volume_); 558 audio_bus_->Scale(volume_);
552 audio_bus_->ToInterleaved( 559 audio_bus_->ToInterleaved<Float32SampleTypeTraits>(
553 frames_filled, bytes_per_sample, audio_data); 560 frames_filled, reinterpret_cast<float*>(audio_data));
554 561
555 // Release the buffer space acquired in the GetBuffer() call. 562 // Release the buffer space acquired in the GetBuffer() call.
556 // Render silence if we were not able to fill up the buffer totally. 563 // Render silence if we were not able to fill up the buffer totally.
557 DWORD flags = (num_filled_bytes < packet_size_bytes_) ? 564 DWORD flags = (num_filled_bytes < packet_size_bytes_) ?
558 AUDCLNT_BUFFERFLAGS_SILENT : 0; 565 AUDCLNT_BUFFERFLAGS_SILENT : 0;
559 audio_render_client_->ReleaseBuffer(packet_size_frames_, flags); 566 audio_render_client_->ReleaseBuffer(packet_size_frames_, flags);
560 567
561 num_written_frames_ += packet_size_frames_; 568 num_written_frames_ += packet_size_frames_;
562 } 569 }
563 570
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 664
658 // Ensure that we don't quit the main thread loop immediately next 665 // Ensure that we don't quit the main thread loop immediately next
659 // time Start() is called. 666 // time Start() is called.
660 ResetEvent(stop_render_event_.Get()); 667 ResetEvent(stop_render_event_.Get());
661 } 668 }
662 669
663 source_ = NULL; 670 source_ = NULL;
664 } 671 }
665 672
666 } // namespace media 673 } // namespace media
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698