Мне нужно найти хороший способ заставить проигрывать звук moc-демона.
У меня следующий сценарий:
У меня работает небольшая серверная коробка Ubuntu 12.04 с MOC (musiconconsole) демон и пользовательское приложение ruby.
Приложение ruby иногда воспроизводит wav или другой звуковой файл в периодических или событийных сценариях. например в 7 часов вечера. он играет "store_is_closing.mp3" или что-то в этом роде.
У меня также есть демон MOC, работающий со списком воспроизведения mp3, который воспроизводит музыку в течение всего дня.
Я использую ALSA для микширования.
Все работает хорошо, но мне не хватает одного очка.
Если, скажем, MOC воспроизводит песню, а приложение ruby воспроизводит звуковой файл, все находится на одном уровне звука (очевидно). поэтому вы ничего не можете понять из звукового файла, воспроизводимого приложением ruby.
Мне нужно найти способ заставить демона MOC снизить его воспроизведение песни до определенного процента (скажем, 10% от исходного уровня звука), и после того, как приложение ruby воспроизведет звуковой файл, moc должен быть вернулся к исходному уровню звука.
Демон MOC может управляться только с клиентом mocp
.
Если бы вы использовали PulseAudio, вы могли бы использовать pacmd
для изменения громкости MOC.
Если вы заменили MOC на MPD , вы можете использовать mpc
для изменения громкости MPD.
Если вы действительно хотите сделать это с ALSA, вы можете поместить следующее в /etc/asound.conf
:
pcm.moc_with_volume {
type softvol
slave.pcm "default" # or whatever you're using in MOC
control {
name "MOC Playback Volume"
count 1
}
}
и настроить MOC на использование имени устройства ALSA moc_with_volume
вместо default
.
Если ваша программа, изменяющая громкость, не позволяет сконфигурировать свой элемент управления микшером, вы должны отслеживать другой элемент управления микшером и копировать его значение в элемент управления микшера MOC. Это можно сделать с помощью такой программы:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <alsa/asoundlib.h>
#define CHECK(fn) check((fn), #fn)
static void check(int err, const char *fn)
{
if (err < 0) {
fprintf(stderr, "%s failed: %s\n", fn, snd_strerror(err));
exit(EXIT_FAILURE);
}
}
int main()
{
snd_ctl_t *ctl;
snd_ctl_event_t *event;
snd_ctl_elem_id_t *id_src, *id_dst;
snd_ctl_elem_value_t *value;
unsigned int mask;
long raw, db;
CHECK(snd_ctl_open(&ctl, "hw:0", 0));
CHECK(snd_ctl_subscribe_events(ctl, 1));
snd_ctl_event_alloca(&event);
snd_ctl_elem_id_alloca(&id_src);
snd_ctl_elem_id_alloca(&id_dst);
snd_ctl_elem_value_alloca(&value);
snd_ctl_elem_id_set_interface(id_dst, SND_CTL_ELEM_IFACE_MIXER);
snd_ctl_elem_id_set_name(id_dst, "MOC Playback Volume");
for (;;) {
CHECK(snd_ctl_read(ctl, event));
if (snd_ctl_event_get_type(event) != SND_CTL_EVENT_ELEM)
continue;
mask = snd_ctl_event_elem_get_mask(event);
if (mask == SND_CTL_EVENT_MASK_REMOVE ||
!(mask & SND_CTL_EVENT_MASK_VALUE) ||
strcmp(snd_ctl_event_elem_get_name(event),
"Some Mic Capture Volume"))
continue;
snd_ctl_event_elem_get_id(event, id_src);
snd_ctl_elem_value_set_id(value, id_src);
CHECK(snd_ctl_elem_read(ctl, value));
raw = snd_ctl_elem_value_get_integer(value, 0);
CHECK(snd_ctl_convert_to_dB(ctl, id_src, raw, &db));
CHECK(snd_ctl_convert_from_dB(ctl, id_dst, db, &raw, 0));
snd_ctl_elem_value_set_id(value, id_dst);
snd_ctl_elem_value_set_integer(value, 0, raw);
snd_ctl_elem_value_set_integer(value, 1, raw);
CHECK(snd_ctl_elem_write(ctl, value));
}
}
(используйте amixer controls
для проверки фактических имен элементов управления.)