libspark/audio_mixer: load alsa-lib temporarily only

This commit is contained in:
martii
2013-05-26 10:56:08 +02:00
parent 151fd39d45
commit c09fc914a4
2 changed files with 45 additions and 11 deletions

View File

@@ -18,6 +18,7 @@
*/
#include <audio_mixer.h>
#include <dlfcn.h>
mixerVolume::mixerVolume(const char *name, const char *card, long volume) {
sid = NULL;
@@ -27,6 +28,23 @@ mixerVolume::mixerVolume(const char *name, const char *card, long volume) {
max = 100;
char cardId[10];
alsaLib = dlopen("/lib/libasound.so.2", RTLD_NOW);
if (!alsaLib)
return;
if (!(this->snd_card_get_index = (int (*)(const char *))dlsym(alsaLib, "snd_card_get_index"))
|| !(this->snd_mixer_open = (int (*)(snd_mixer_t **, int)) dlsym(alsaLib, "snd_mixer_open"))
|| !(this->snd_mixer_attach = (int (*)(snd_mixer_t *, const char *)) dlsym(alsaLib, "snd_mixer_attach"))
|| !(this->snd_mixer_selem_register = (int (*)(snd_mixer_t *, struct snd_mixer_selem_regopt *, snd_mixer_class_t **)) dlsym(alsaLib, "snd_mixer_selem_register"))
|| !(this->snd_mixer_load = (int (*)(snd_mixer_t *)) dlsym(alsaLib, "snd_mixer_load"))
|| !(this->snd_mixer_selem_id_set_index = (void (*)(snd_mixer_selem_id_t *, unsigned int)) dlsym(alsaLib, "snd_mixer_selem_id_set_index"))
|| !(this->snd_mixer_selem_id_set_name = (void (*)(snd_mixer_selem_id_t *, const char *)) dlsym(alsaLib, "snd_mixer_selem_id_set_name"))
|| !(this->snd_mixer_find_selem = (snd_mixer_elem_t *(*)(snd_mixer_t *, const snd_mixer_selem_id_t *)) dlsym(alsaLib, "snd_mixer_find_selem"))
|| !(this->snd_mixer_selem_get_playback_volume_range = (int (*)(snd_mixer_elem_t *, long *, long *)) dlsym(alsaLib, "snd_mixer_selem_get_playback_volume_range"))
|| !(this->snd_mixer_close = (int (*)(snd_mixer_t *)) dlsym(alsaLib, "snd_mixer_close"))
|| !(this->snd_mixer_selem_id_free = (void (*)(snd_mixer_selem_id_t *)) dlsym(alsaLib, "snd_mixer_selem_id_free"))
|| !(this->snd_mixer_selem_set_playback_volume_all = (int (*)(snd_mixer_elem_t *, long)) dlsym(alsaLib, "snd_mixer_selem_set_playback_volume_all")))
return;
if (!name || !card)
return;
@@ -35,36 +53,38 @@ mixerVolume::mixerVolume(const char *name, const char *card, long volume) {
return;
snprintf(cardId, sizeof(cardId), "hw:%i", cx);
if (0 > snd_mixer_open(&handle, 0))
if (0 > this->snd_mixer_open(&handle, 0))
return;
if (0 > snd_mixer_attach(handle, cardId))
if (0 > this->snd_mixer_attach(handle, cardId))
return;
if (0 > snd_mixer_selem_register(handle, NULL, NULL))
if (0 > this->snd_mixer_selem_register(handle, NULL, NULL))
return;
if (0 > snd_mixer_load(handle))
if (0 > this->snd_mixer_load(handle))
return;
snd_mixer_selem_id_alloca(&sid);
if (!sid)
return;
snd_mixer_selem_id_set_index(sid, 0);
snd_mixer_selem_id_set_name(sid, name);
elem = snd_mixer_find_selem(handle, sid);
this->snd_mixer_selem_id_set_index(sid, 0);
this->snd_mixer_selem_id_set_name(sid, name);
elem = this->snd_mixer_find_selem(handle, sid);
if (elem) {
snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
this->snd_mixer_selem_get_playback_volume_range(elem, &min, &max);
setVolume(volume);
}
}
mixerVolume::~mixerVolume()
{
if (handle)
snd_mixer_close(handle);
this->snd_mixer_close(handle);
if (sid)
snd_mixer_selem_id_free(sid);
this->snd_mixer_selem_id_free(sid);
if (alsaLib)
dlclose(alsaLib);
}
bool mixerVolume::setVolume(long volume) {
return elem
&& (volume > -1)
&& (volume < 101)
&& !snd_mixer_selem_set_playback_volume_all(elem, min + volume * (max - min)/100);
&& !this->snd_mixer_selem_set_playback_volume_all(elem, min + volume * (max - min)/100);
}

View File

@@ -28,6 +28,20 @@ class mixerVolume
snd_mixer_t *handle;
snd_mixer_elem_t* elem;
snd_mixer_selem_id_t *sid;
void *alsaLib;
int (*snd_card_get_index)(const char *name);
int (*snd_mixer_open)(snd_mixer_t **mixer, int mode);
int (*snd_mixer_attach)(snd_mixer_t *mixer, const char *name);
int (*snd_mixer_selem_register)(snd_mixer_t *mixer, struct snd_mixer_selem_regopt *options, snd_mixer_class_t **classp);
int (*snd_mixer_load)(snd_mixer_t *mixer);
void (*snd_mixer_selem_id_set_index)(snd_mixer_selem_id_t *obj, unsigned int val);
void (*snd_mixer_selem_id_set_name)(snd_mixer_selem_id_t *obj, const char *val);
snd_mixer_elem_t *(*snd_mixer_find_selem)(snd_mixer_t *mixer, const snd_mixer_selem_id_t *id);
int (*snd_mixer_selem_get_playback_volume_range)(snd_mixer_elem_t *elem, long *min, long *max);
int (*snd_mixer_close)(snd_mixer_t *mixer);
void (*snd_mixer_selem_id_free)(snd_mixer_selem_id_t *obj);
int (*snd_mixer_selem_set_playback_volume_all)(snd_mixer_elem_t *elem, long value);
public:
mixerVolume(const char *selem_name, const char *Card, long volume = -1);
~mixerVolume(void);