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
|
// Copyright (c) 2010 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 CHROME_BROWSER_CHROMEOS_PULSE_AUDIO_MIXER_H_
#define CHROME_BROWSER_CHROMEOS_PULSE_AUDIO_MIXER_H_
#include "base/basictypes.h"
#include "base/callback.h"
#include "base/lock.h"
#include "base/scoped_ptr.h"
#include "base/thread.h"
struct pa_context;
struct pa_cvolume;
struct pa_threaded_mainloop;
struct pa_operation;
struct pa_sink_info;
namespace chromeos {
class PulseAudioMixer {
public:
enum State {
UNINITIALIZED = 0,
INITIALIZING,
READY,
SHUTTING_DOWN,
IN_ERROR
};
PulseAudioMixer();
~PulseAudioMixer();
// Non-blocking, connect to PulseAudio and find a default device, and call
// callback when complete with success code.
typedef Callback1<bool>::Type InitDoneCallback;
bool Init(InitDoneCallback* callback);
// Blocking init call guarantees PulseAudio is started before returning.
bool InitSync();
// Blocking call. Returns a default of -inf on error.
double GetVolumeDb() const;
// Non-blocking, volume sent in as first param to callback
typedef Callback2<double, void*>::Type GetVolumeCallback;
void GetVolumeDbAsync(GetVolumeCallback* callback, void* user);
// Non-blocking call.
void SetVolumeDb(double vol_db);
// Gets the mute state of the default device (true == mute). Blocking call.
// Returns a default of false on error.
bool IsMute() const;
// Non-Blocking call.
void SetMute(bool mute);
// Returns READY if we have a valid working connection to PulseAudio.
// This can return IN_ERROR if we lose the connection, even after an original
// successful init. Non-blocking call.
State CheckState() const;
private:
struct AudioInfo;
// These are the tasks to be run in the background on the worker thread.
void DoInit(InitDoneCallback* callback);
void DoGetVolume(GetVolumeCallback* callback, void* user);
static void ConnectToPulseCallbackThunk(pa_context* c, void* userdata);
void OnConnectToPulseCallback(pa_context* c, bool* connect_done);
// Helper function to just get our messsage loop thread going
bool InitThread();
// This goes through sequence of connecting to the default PulseAudio server.
// We will block until we either have a valid connection or something failed.
// If a connection is lost for some reason, delete and recreate the object.
bool PulseAudioInit();
// PulseAudioFree. Disconnect from server.
void PulseAudioFree();
// Iterates the PA mainloop and only returns once an operation has completed
// (successfully or unsuccessfully). This call only blocks the worker thread.
void CompleteOperationAndUnlock(pa_operation* pa_op) const;
// For now, this just gets the first device returned from the enumeration
// request. This will be the 'default' or 'master' device that all further
// actions are taken on. Blocking call.
void GetDefaultPlaybackDevice();
static void EnumerateDevicesCallback(pa_context* unused,
const pa_sink_info* sink_info,
int eol,
void* userdata);
void OnEnumerateDevices(const pa_sink_info* sink_info, int eol);
// Get the info we're interested in from the default device. Currently this
// is an array of volumes, and the mute state. Blocking call.
void GetAudioInfo(AudioInfo* info) const;
static void GetAudioInfoCallback(pa_context* unused,
const pa_sink_info* sink_info,
int eol,
void* userdata);
void set_mixer_state(State state) {
AutoLock lock(mixer_state_lock_);
mixer_state_ = state;
}
// The PulseAudio index of the main device being used.
mutable int device_id_;
// Set to the number of channels on the main device.
int last_channels_;
mutable Lock mixer_state_lock_;
mutable State mixer_state_;
// Cached contexts for use in PulseAudio calls.
pa_context* pa_context_;
pa_threaded_mainloop* pa_mainloop_;
scoped_ptr<base::Thread> thread_;
DISALLOW_COPY_AND_ASSIGN(PulseAudioMixer);
};
} // namespace chromeos
DISABLE_RUNNABLE_METHOD_REFCOUNT(chromeos::PulseAudioMixer);
#endif // CHROME_BROWSER_CHROMEOS_PULSE_AUDIO_MIXER_H_
|