blob: 4bfe3d7636dd10a15759599e2f2761cc059ee175 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
|
// Copyright (c) 2012 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_WIN_AUDIO_UNIFIED_WIN_H_
#define MEDIA_AUDIO_WIN_AUDIO_UNIFIED_WIN_H_
#include <Audioclient.h>
#include <MMDeviceAPI.h>
#include <string>
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/threading/platform_thread.h"
#include "base/threading/simple_thread.h"
#include "base/win/scoped_co_mem.h"
#include "base/win/scoped_comptr.h"
#include "base/win/scoped_handle.h"
#include "media/audio/audio_io.h"
#include "media/audio/audio_parameters.h"
#include "media/base/media_export.h"
namespace media {
class AudioManagerWin;
// Implementation of AudioOutputStream for Windows using the Core Audio API
// where both capturing and rendering takes place on the same thread to enable
// audio I/O.
//
// The user should also ensure that audio I/O is supported by calling
// HasUnifiedDefaultIO().
//
// Implementation notes:
//
// - Certain conditions must be fulfilled to support audio I/O:
// o Both capture and render side must use the same sample rate.
// o Both capture and render side must use the same channel count.
// o Both capture and render side must use the same channel configuration.
// o See HasUnifiedDefaultIO() for more details.
//
// TODO(henrika):
//
// - Add multi-channel support.
// - Add support for non-matching sample rates.
// - Add support for exclusive mode.
//
class MEDIA_EXPORT WASAPIUnifiedStream
: public AudioOutputStream,
public base::DelegateSimpleThread::Delegate {
public:
// The ctor takes all the usual parameters, plus |manager| which is the
// the audio manager who is creating this object.
WASAPIUnifiedStream(AudioManagerWin* manager,
const AudioParameters& params);
// The dtor is typically called by the AudioManager only and it is usually
// triggered by calling AudioOutputStream::Close().
virtual ~WASAPIUnifiedStream();
// Implementation of AudioOutputStream.
virtual bool Open() OVERRIDE;
virtual void Start(AudioSourceCallback* callback) OVERRIDE;
virtual void Stop() OVERRIDE;
virtual void Close() OVERRIDE;
virtual void SetVolume(double volume) OVERRIDE;
virtual void GetVolume(double* volume) OVERRIDE;
// Returns true if all conditions to support audio IO are fulfilled.
// Input and output sides of the Audio Engine must use the same native
// device period (requires e.g. identical sample rates) and have the same
// channel count.
static bool HasUnifiedDefaultIO();
bool started() const {
return audio_io_thread_.get() != NULL;
}
private:
// DelegateSimpleThread::Delegate implementation.
virtual void Run() OVERRIDE;
// Issues the OnError() callback to the |source_|.
void HandleError(HRESULT err);
// Stops and joins the audio thread in case of an error.
void StopAndJoinThread(HRESULT err);
// Converts unique endpoint ID to user-friendly device name.
std::string GetDeviceName(LPCWSTR device_id) const;
// Returns the number of channels the audio engine uses for its internal
// processing/mixing of shared-mode streams for the default endpoint device.
int endpoint_channel_count() { return format_.Format.nChannels; }
// Contains the thread ID of the creating thread.
base::PlatformThreadId creating_thread_id_;
// Our creator, the audio manager needs to be notified when we close.
AudioManagerWin* manager_;
// The sharing mode for the streams.
// Valid values are AUDCLNT_SHAREMODE_SHARED and AUDCLNT_SHAREMODE_EXCLUSIVE
// where AUDCLNT_SHAREMODE_SHARED is the default.
AUDCLNT_SHAREMODE share_mode_;
// Rendering and capturing is driven by this thread (no message loop).
// All OnMoreIOData() callbacks will be called from this thread.
scoped_ptr<base::DelegateSimpleThread> audio_io_thread_;
// Contains the desired audio format which is set up at construction.
// Extended PCM waveform format structure based on WAVEFORMATEXTENSIBLE.
// Use this for multiple channel and hi-resolution PCM data.
WAVEFORMATPCMEX format_;
// True when successfully opened.
bool opened_;
// Size in bytes of each audio frame (4 bytes for 16-bit stereo PCM).
size_t frame_size_;
// Size in audio frames of each audio packet where an audio packet
// is defined as the block of data which the source is expected to deliver
// in each OnMoreIOData() callback.
size_t packet_size_frames_;
// Length of the audio endpoint buffer.
size_t endpoint_render_buffer_size_frames_;
size_t endpoint_capture_buffer_size_frames_;
// Pointer to the client that will deliver audio samples to be played out.
AudioSourceCallback* source_;
// IMMDevice interfaces which represents audio endpoint devices.
base::win::ScopedComPtr<IMMDevice> endpoint_render_device_;
base::win::ScopedComPtr<IMMDevice> endpoint_capture_device_;
// IAudioClient interfaces which enables a client to create and initialize
// an audio stream between an audio application and the audio engine.
base::win::ScopedComPtr<IAudioClient> audio_output_client_;
base::win::ScopedComPtr<IAudioClient> audio_input_client_;
// IAudioRenderClient interfaces enables a client to write output
// data to a rendering endpoint buffer.
base::win::ScopedComPtr<IAudioRenderClient> audio_render_client_;
// IAudioCaptureClient interfaces enables a client to read input
// data from a capturing endpoint buffer.
base::win::ScopedComPtr<IAudioCaptureClient> audio_capture_client_;
// The audio engine will signal this event each time a buffer has been
// recorded.
base::win::ScopedHandle capture_event_;
// This event will be signaled when streaming shall stop.
base::win::ScopedHandle stop_streaming_event_;
// Container for retrieving data from AudioSourceCallback::OnMoreIOData().
scoped_ptr<AudioBus> render_bus_;
// Container for sending data to AudioSourceCallback::OnMoreIOData().
scoped_ptr<AudioBus> capture_bus_;
DISALLOW_COPY_AND_ASSIGN(WASAPIUnifiedStream);
};
} // namespace media
#endif // MEDIA_AUDIO_WIN_AUDIO_UNIFIED_WIN_H_
|