Necesito encontrar una buena manera de forzar la atenuación de la reproducción de sonido de un demonio moc.
Tengo el siguiente escenario:
Tengo un pequeño servidor Ubuntu 12.04 con un demonio MOC (musiconconsole) y una aplicación Ruby personalizada.
La aplicación Ruby ocasionalmente reproduce un wav u otro archivo de sonido en escenarios periódicos o controlados por eventos. por ejemplo, a las 7 pm reproduce "store_is_closing.mp3" o algo así.
También tengo un demonio MOC ejecutándose con una lista de reproducción de mp3, que reproduce música todo el día.
Estoy usando ALSA para hacer la mezcla.
Todo funciona bien pero me falta un punto.
Si, digamos que MOC está reproduciendo una canción y la aplicación Ruby reproduce un archivo de sonido, todo está en el mismo nivel de sonido (obviamente). Por lo tanto, no puedes entender nada del archivo de sonido reproducido por la aplicación Ruby.
Necesito encontrar una manera de forzar al demonio MOC a disminuir la reproducción de la canción a un porcentaje definido (digamos 10% del nivel de sonido original) y después de que la aplicación Ruby reproduzca el archivo de sonido, se debe volver a activar moc. al nivel sonoro de origen.
Respuesta1
El demonio MOC sólo se puede controlar con el mocp
cliente.
Si estuviera usando PulseAudio, podría usarlo pacmd
para cambiar el volumen de MOC.
Si reemplazó MOC conMPD, podrías usarlo mpc
para cambiar el volumen del MPD.
Si realmente quieres hacer esto con ALSA, puedes poner lo siguiente en /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
}
}
y configure MOC para usar el nombre del dispositivo ALSA moc_with_volume
en lugar de default
.
Si su programa de cambio de volumen no permite configurar su control del mezclador, debe monitorear el otro control del mezclador y copiar su valor al control del mezclador MOC. Esto se podría hacer con un programa como este:
#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));
}
}
(Úselo amixer controls
para verificar los nombres de control reales).