1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef CHROME_BROWSER_CHROMEOS_AUDIO_MIXER_ALSA_H_
6 #define CHROME_BROWSER_CHROMEOS_AUDIO_MIXER_ALSA_H_
11 #include "base/basictypes.h"
12 #include "base/compiler_specific.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/synchronization/lock.h"
15 #include "base/synchronization/waitable_event.h"
16 #include "base/threading/thread.h"
17 #include "chrome/browser/chromeos/audio_mixer.h"
21 struct _snd_mixer_elem
;
26 // Simple wrapper around ALSA's mixer functions.
27 // Interaction with ALSA takes place on a background thread.
28 class AudioMixerAlsa
: public AudioMixer
{
31 virtual ~AudioMixerAlsa();
33 // AudioMixer implementation.
34 virtual void Init() OVERRIDE
;
35 virtual bool IsInitialized() OVERRIDE
;
36 virtual void GetVolumeLimits(double* min_volume_db
,
37 double* max_volume_db
) OVERRIDE
;
38 virtual double GetVolumeDb() OVERRIDE
;
39 virtual void SetVolumeDb(double volume_db
) OVERRIDE
;
40 virtual bool IsMuted() OVERRIDE
;
41 virtual void SetMuted(bool muted
) OVERRIDE
;
43 // Registers volume and mute preferences.
44 // TODO(derat): Move prefs into AudioHandler.
45 static void RegisterPrefs(PrefService
* local_state
);
48 // Tries to connect to ALSA. On failure, posts a delayed Connect() task to
52 // Helper method called by Connect(). On success, initializes
53 // |min_volume_db_|, |max_volume_db_|, |alsa_mixer_|, and |element_*| and
55 bool ConnectInternal();
57 // Disconnects from ALSA if currently connected and signals
58 // |disconnected_event_|.
61 // Updates |alsa_mixer_| for current values of |volume_db_| and |is_muted_|.
62 // No-op if not connected.
65 // Finds the element named |element_name|. Returns NULL on failure.
66 _snd_mixer_elem
* FindElementWithName(_snd_mixer
* handle
,
67 const std::string
& element_name
) const;
69 // Queries |element|'s current volume, copying it to |new_volume_db|.
70 // Returns true on success.
71 bool GetElementVolume(_snd_mixer_elem
* element
, double* current_volume_db
);
73 // Sets |element|'s volume. Since volume is done in steps, we may not get the
74 // exact volume asked for. |rounding_bias| is added in before rounding to the
75 // nearest volume step (use 0.5 to round to nearest).
76 bool SetElementVolume(_snd_mixer_elem
* element
,
78 double rounding_bias
);
80 // Mutes or unmutes |element|.
81 void SetElementMuted(_snd_mixer_elem
* element
, bool mute
);
83 // Guards |min_volume_db_|, |max_volume_db_|, |volume_db_|, |is_muted_|, and
84 // |apply_is_pending_|.
87 // Volume range limits are computed once in ConnectInternal().
88 double min_volume_db_
;
89 double max_volume_db_
;
91 // Most recently requested volume, in decibels. This variable is updated
92 // immediately by GetVolumeDb(); the actual mixer volume is updated later on
93 // |thread_| by ApplyState().
96 // Most recently requested muting state.
99 // Is there already a pending call to ApplyState() scheduled on |thread_|?
100 bool apply_is_pending_
;
102 // Connection to ALSA. NULL if not connected.
103 _snd_mixer
* alsa_mixer_
;
106 _snd_mixer_elem
* master_element_
;
108 // PCM mixer. May be NULL if the driver doesn't expose one.
109 _snd_mixer_elem
* pcm_element_
;
113 // Signalled after Disconnect() finishes (which is itself invoked by the
115 base::WaitableEvent disconnected_event_
;
117 // Background thread used for interacting with ALSA.
118 scoped_ptr
<base::Thread
> thread_
;
120 // Number of times that we've attempted to connect to ALSA. Just used to keep
121 // us from spamming the logs.
122 int num_connection_attempts_
;
124 DISALLOW_COPY_AND_ASSIGN(AudioMixerAlsa
);
127 } // namespace chromeos
129 #endif // CHROME_BROWSER_CHROMEOS_AUDIO_MIXER_ALSA_H_