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

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

Issue 2475453003: Support floating-point audio output for Windows7+ (Closed)
Patch Set: git cl format 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 "base/command_line.h" 9 #include "base/command_line.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/macros.h" 11 #include "base/macros.h"
12 #include "base/metrics/histogram.h" 12 #include "base/metrics/histogram.h"
13 #include "base/strings/utf_string_conversions.h" 13 #include "base/strings/utf_string_conversions.h"
14 #include "base/time/time.h" 14 #include "base/time/time.h"
15 #include "base/trace_event/trace_event.h" 15 #include "base/trace_event/trace_event.h"
16 #include "base/win/scoped_propvariant.h" 16 #include "base/win/scoped_propvariant.h"
17 #include "media/audio/audio_device_description.h" 17 #include "media/audio/audio_device_description.h"
18 #include "media/audio/win/audio_manager_win.h" 18 #include "media/audio/win/audio_manager_win.h"
19 #include "media/audio/win/avrt_wrapper_win.h" 19 #include "media/audio/win/avrt_wrapper_win.h"
20 #include "media/audio/win/core_audio_util_win.h" 20 #include "media/audio/win/core_audio_util_win.h"
21 #include "media/base/audio_sample_types.h"
21 #include "media/base/limits.h" 22 #include "media/base/limits.h"
22 #include "media/base/media_switches.h" 23 #include "media/base/media_switches.h"
23 24
24 using base::win::ScopedComPtr; 25 using base::win::ScopedComPtr;
25 using base::win::ScopedCOMInitializer; 26 using base::win::ScopedCOMInitializer;
26 using base::win::ScopedCoMem; 27 using base::win::ScopedCoMem;
27 28
28 namespace media { 29 namespace media {
29 30
30 // static 31 // static
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
65 opened_(false), 66 opened_(false),
66 volume_(1.0), 67 volume_(1.0),
67 packet_size_frames_(0), 68 packet_size_frames_(0),
68 packet_size_bytes_(0), 69 packet_size_bytes_(0),
69 endpoint_buffer_size_frames_(0), 70 endpoint_buffer_size_frames_(0),
70 device_id_(device_id), 71 device_id_(device_id),
71 device_role_(device_role), 72 device_role_(device_role),
72 share_mode_(GetShareMode()), 73 share_mode_(GetShareMode()),
73 num_written_frames_(0), 74 num_written_frames_(0),
74 source_(NULL), 75 source_(NULL),
75 audio_bus_(AudioBus::Create(params)) { 76 audio_bus_(AudioBus::Create(AudioParameters(
77 params.format(),
78 params.channel_layout(),
79 params.sample_rate(),
80 // Ignore the given bits per sample; we want 32 because
81 // we're outputting floats.
82 32,
83 params.frames_per_buffer()))) {
76 DCHECK(manager_); 84 DCHECK(manager_);
77 85
78 // The empty string is used to indicate a default device and the 86 // The empty string is used to indicate a default device and the
79 // |device_role_| member controls whether that's the default or default 87 // |device_role_| member controls whether that's the default or default
80 // communications device. 88 // communications device.
81 DCHECK_NE(device_id_, AudioDeviceDescription::kDefaultDeviceId); 89 DCHECK_NE(device_id_, AudioDeviceDescription::kDefaultDeviceId);
82 DCHECK_NE(device_id_, AudioDeviceDescription::kCommunicationsDeviceId); 90 DCHECK_NE(device_id_, AudioDeviceDescription::kCommunicationsDeviceId);
83 91
84 DVLOG(1) << "WASAPIAudioOutputStream::WASAPIAudioOutputStream()"; 92 DVLOG(1) << "WASAPIAudioOutputStream::WASAPIAudioOutputStream()";
85 DVLOG_IF(1, share_mode_ == AUDCLNT_SHAREMODE_EXCLUSIVE) 93 DVLOG_IF(1, share_mode_ == AUDCLNT_SHAREMODE_EXCLUSIVE)
86 << "Core Audio (WASAPI) EXCLUSIVE MODE is enabled."; 94 << "Core Audio (WASAPI) EXCLUSIVE MODE is enabled.";
87 95
88 // Load the Avrt DLL if not already loaded. Required to support MMCSS. 96 // Load the Avrt DLL if not already loaded. Required to support MMCSS.
89 bool avrt_init = avrt::Initialize(); 97 bool avrt_init = avrt::Initialize();
90 DCHECK(avrt_init) << "Failed to load the avrt.dll"; 98 DCHECK(avrt_init) << "Failed to load the avrt.dll";
91 99
92 // Set up the desired render format specified by the client. We use the 100 // Set up the desired render format specified by the client. We use the
93 // WAVE_FORMAT_EXTENSIBLE structure to ensure that multiple channel ordering 101 // WAVE_FORMAT_EXTENSIBLE structure to ensure that multiple channel ordering
94 // and high precision data can be supported. 102 // and high precision data can be supported.
95 103
96 // Begin with the WAVEFORMATEX structure that specifies the basic format. 104 // Begin with the WAVEFORMATEX structure that specifies the basic format.
97 WAVEFORMATEX* format = &format_.Format; 105 WAVEFORMATEX* format = &format_.Format;
98 format->wFormatTag = WAVE_FORMAT_EXTENSIBLE; 106 format->wFormatTag = WAVE_FORMAT_EXTENSIBLE;
99 format->nChannels = params.channels(); 107 format->nChannels = params.channels();
100 format->nSamplesPerSec = params.sample_rate(); 108 format->nSamplesPerSec = params.sample_rate();
101 format->wBitsPerSample = params.bits_per_sample(); 109 // Always want 32 bits because we're using floats.
110 format->wBitsPerSample = 32;
tommi (sloooow) - chröme 2016/11/02 20:23:04 nit: Add a constant at the top of the file for thi
Raymond Toy 2016/11/02 21:26:14 Done. Please up choose a good name if you don't li
102 format->nBlockAlign = (format->wBitsPerSample / 8) * format->nChannels; 111 format->nBlockAlign = (format->wBitsPerSample / 8) * format->nChannels;
103 format->nAvgBytesPerSec = format->nSamplesPerSec * format->nBlockAlign; 112 format->nAvgBytesPerSec = format->nSamplesPerSec * format->nBlockAlign;
104 format->cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX); 113 format->cbSize = sizeof(WAVEFORMATEXTENSIBLE) - sizeof(WAVEFORMATEX);
105 114
106 // Add the parts which are unique to WAVE_FORMAT_EXTENSIBLE. 115 // Add the parts which are unique to WAVE_FORMAT_EXTENSIBLE.
107 format_.Samples.wValidBitsPerSample = params.bits_per_sample(); 116 format_.Samples.wValidBitsPerSample = 32;
108 format_.dwChannelMask = CoreAudioUtil::GetChannelConfig(device_id, eRender); 117 format_.dwChannelMask = CoreAudioUtil::GetChannelConfig(device_id, eRender);
109 format_.SubFormat = KSDATAFORMAT_SUBTYPE_PCM; 118 format_.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;
tommi (sloooow) - chröme 2016/11/02 20:23:04 that's it? :-|
Raymond Toy 2016/11/02 21:26:14 I think so. :-) I can hear output now that wasn't
110 119
111 // Store size (in different units) of audio packets which we expect to 120 // Store size (in different units) of audio packets which we expect to
112 // get from the audio endpoint device in each render event. 121 // get from the audio endpoint device in each render event.
113 packet_size_frames_ = params.frames_per_buffer(); 122 packet_size_frames_ = params.frames_per_buffer();
114 packet_size_bytes_ = params.GetBytesPerBuffer(); 123 packet_size_bytes_ = params.GetBytesPerBuffer();
115 DVLOG(1) << "Number of bytes per audio frame : " << format->nBlockAlign; 124 DVLOG(1) << "Number of bytes per audio frame : " << format->nBlockAlign;
116 DVLOG(1) << "Number of audio frames per packet: " << packet_size_frames_; 125 DVLOG(1) << "Number of audio frames per packet: " << packet_size_frames_;
117 DVLOG(1) << "Number of bytes per packet : " << packet_size_bytes_; 126 DVLOG(1) << "Number of bytes per packet : " << packet_size_bytes_;
118 DVLOG(1) << "Number of milliseconds per packet: " 127 DVLOG(1) << "Number of milliseconds per packet: "
119 << params.GetBufferDuration().InMillisecondsF(); 128 << params.GetBufferDuration().InMillisecondsF();
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
542 int frames_filled = 551 int frames_filled =
543 source_->OnMoreData(delay, delay_timestamp, 0, audio_bus_.get()); 552 source_->OnMoreData(delay, delay_timestamp, 0, audio_bus_.get());
544 uint32_t num_filled_bytes = frames_filled * format_.Format.nBlockAlign; 553 uint32_t num_filled_bytes = frames_filled * format_.Format.nBlockAlign;
545 DCHECK_LE(num_filled_bytes, packet_size_bytes_); 554 DCHECK_LE(num_filled_bytes, packet_size_bytes_);
546 555
547 // Note: If this ever changes to output raw float the data must be 556 // Note: If this ever changes to output raw float the data must be
548 // clipped and sanitized since it may come from an untrusted 557 // clipped and sanitized since it may come from an untrusted
549 // source such as NaCl. 558 // source such as NaCl.
550 const int bytes_per_sample = format_.Format.wBitsPerSample >> 3; 559 const int bytes_per_sample = format_.Format.wBitsPerSample >> 3;
551 audio_bus_->Scale(volume_); 560 audio_bus_->Scale(volume_);
552 audio_bus_->ToInterleaved( 561 audio_bus_->ToInterleaved<Float32SampleTypeTraits>(
553 frames_filled, bytes_per_sample, audio_data); 562 frames_filled, reinterpret_cast<float*>(audio_data));
554 563
555 // Release the buffer space acquired in the GetBuffer() call. 564 // Release the buffer space acquired in the GetBuffer() call.
556 // Render silence if we were not able to fill up the buffer totally. 565 // Render silence if we were not able to fill up the buffer totally.
557 DWORD flags = (num_filled_bytes < packet_size_bytes_) ? 566 DWORD flags = (num_filled_bytes < packet_size_bytes_) ?
558 AUDCLNT_BUFFERFLAGS_SILENT : 0; 567 AUDCLNT_BUFFERFLAGS_SILENT : 0;
559 audio_render_client_->ReleaseBuffer(packet_size_frames_, flags); 568 audio_render_client_->ReleaseBuffer(packet_size_frames_, flags);
560 569
561 num_written_frames_ += packet_size_frames_; 570 num_written_frames_ += packet_size_frames_;
562 } 571 }
563 572
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
657 666
658 // Ensure that we don't quit the main thread loop immediately next 667 // Ensure that we don't quit the main thread loop immediately next
659 // time Start() is called. 668 // time Start() is called.
660 ResetEvent(stop_render_event_.Get()); 669 ResetEvent(stop_render_event_.Get());
661 } 670 }
662 671
663 source_ = NULL; 672 source_ = NULL;
664 } 673 }
665 674
666 } // namespace media 675 } // 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