2016-06-15 03:32:35 +00:00
|
|
|
#pragma once
|
|
|
|
|
2016-11-30 11:46:26 +00:00
|
|
|
#include <assert.h>
|
|
|
|
#include <poll.h>
|
2016-06-15 03:32:35 +00:00
|
|
|
#include <stdio.h>
|
2016-11-30 11:46:26 +00:00
|
|
|
#include <alsa/global.h>
|
|
|
|
#include <alsa/input.h>
|
|
|
|
#include <alsa/output.h>
|
|
|
|
#include <alsa/error.h>
|
|
|
|
#include <alsa/conf.h>
|
|
|
|
#include <alsa/pcm.h>
|
|
|
|
#include <alsa/control.h>
|
|
|
|
#include <alsa/mixer.h>
|
|
|
|
|
2016-11-25 07:42:31 +00:00
|
|
|
#include <cmath>
|
2016-06-15 03:32:35 +00:00
|
|
|
#include <functional>
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
#include "common.hpp"
|
|
|
|
#include "config.hpp"
|
2016-11-25 12:55:15 +00:00
|
|
|
#include "errors.hpp"
|
2016-11-20 22:04:31 +00:00
|
|
|
#include "utils/concurrency.hpp"
|
2016-06-15 03:32:35 +00:00
|
|
|
|
2016-11-05 21:27:07 +00:00
|
|
|
#define MAX_LINEAR_DB_SCALE 24
|
|
|
|
|
2016-11-19 05:22:44 +00:00
|
|
|
POLYBAR_NS
|
2016-06-15 03:32:35 +00:00
|
|
|
|
|
|
|
DEFINE_ERROR(alsa_exception);
|
|
|
|
DEFINE_CHILD_ERROR(alsa_ctl_interface_error, alsa_exception);
|
|
|
|
DEFINE_CHILD_ERROR(alsa_mixer_error, alsa_exception);
|
|
|
|
|
|
|
|
// class definition : alsa_ctl_interface {{{
|
|
|
|
|
2016-10-16 00:21:12 +00:00
|
|
|
template <typename T>
|
2016-06-15 03:32:35 +00:00
|
|
|
void throw_exception(string&& message, int error_code) {
|
|
|
|
const char* snd_error = snd_strerror(error_code);
|
|
|
|
if (snd_error != nullptr)
|
2016-10-16 00:21:12 +00:00
|
|
|
message += ": " + string{snd_error};
|
2016-06-15 03:32:35 +00:00
|
|
|
throw T(message.c_str());
|
|
|
|
}
|
|
|
|
|
|
|
|
class alsa_ctl_interface {
|
|
|
|
public:
|
2016-11-02 19:22:45 +00:00
|
|
|
explicit alsa_ctl_interface(int numid);
|
|
|
|
~alsa_ctl_interface();
|
2016-06-15 03:32:35 +00:00
|
|
|
|
2016-11-02 19:22:45 +00:00
|
|
|
int get_numid();
|
|
|
|
bool wait(int timeout = -1);
|
|
|
|
bool test_device_plugged();
|
|
|
|
void process_events();
|
2016-06-15 03:32:35 +00:00
|
|
|
|
|
|
|
private:
|
2016-11-25 12:55:15 +00:00
|
|
|
int m_numid{0};
|
2016-10-25 06:53:55 +00:00
|
|
|
|
2016-11-25 12:55:15 +00:00
|
|
|
std::mutex m_lock;
|
2016-06-15 03:32:35 +00:00
|
|
|
|
2016-11-25 12:55:15 +00:00
|
|
|
snd_hctl_t* m_hctl{nullptr};
|
|
|
|
snd_hctl_elem_t* m_elem{nullptr};
|
2016-06-15 03:32:35 +00:00
|
|
|
|
2016-11-25 12:55:15 +00:00
|
|
|
snd_ctl_t* m_ctl{nullptr};
|
|
|
|
snd_ctl_elem_info_t* m_info{nullptr};
|
|
|
|
snd_ctl_elem_value_t* m_value{nullptr};
|
|
|
|
snd_ctl_elem_id_t* m_id{nullptr};
|
2016-06-15 03:32:35 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// }}}
|
|
|
|
// class definition : alsa_mixer {{{
|
|
|
|
|
|
|
|
class alsa_mixer {
|
|
|
|
public:
|
2016-11-25 12:55:15 +00:00
|
|
|
explicit alsa_mixer(const string& mixer_control_name);
|
2016-11-02 19:22:45 +00:00
|
|
|
~alsa_mixer();
|
2016-06-15 03:32:35 +00:00
|
|
|
|
2016-11-02 19:22:45 +00:00
|
|
|
string get_name();
|
2016-06-15 03:32:35 +00:00
|
|
|
|
2016-11-02 19:22:45 +00:00
|
|
|
bool wait(int timeout = -1);
|
|
|
|
int process_events();
|
2016-06-15 03:32:35 +00:00
|
|
|
|
2016-11-02 19:22:45 +00:00
|
|
|
int get_volume();
|
2016-11-05 21:27:07 +00:00
|
|
|
int get_normalized_volume();
|
2016-11-02 19:22:45 +00:00
|
|
|
void set_volume(float percentage);
|
2016-11-05 21:27:07 +00:00
|
|
|
void set_normalized_volume(float percentage);
|
2016-11-02 19:22:45 +00:00
|
|
|
void set_mute(bool mode);
|
|
|
|
void toggle_mute();
|
|
|
|
bool is_muted();
|
2016-06-15 03:32:35 +00:00
|
|
|
|
|
|
|
private:
|
2016-10-25 06:53:55 +00:00
|
|
|
string m_name;
|
|
|
|
|
2016-11-25 12:55:15 +00:00
|
|
|
std::mutex m_lock;
|
2016-06-15 03:32:35 +00:00
|
|
|
|
2016-11-25 12:55:15 +00:00
|
|
|
snd_mixer_t* m_hardwaremixer{nullptr};
|
|
|
|
snd_mixer_elem_t* m_mixerelement{nullptr};
|
2016-06-15 03:32:35 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// }}}
|
|
|
|
|
2016-11-19 05:22:44 +00:00
|
|
|
POLYBAR_NS_END
|