Desaparece o MOC se outro aplicativo começar a reproduzir alguma coisa

Desaparece o MOC se outro aplicativo começar a reproduzir alguma coisa

Preciso encontrar uma boa maneira de forçar o fade down na reprodução do som de um daemon moc

Eu tenho o seguinte cenário:

Eu estou executando uma pequena caixa de servidor Ubuntu 12.04 com um daemon MOC (musiconconsole) e um aplicativo Ruby personalizado.

O aplicativo Ruby ocasionalmente reproduz um wav ou outro arquivo de som em cenários periódicos ou orientados a eventos. por exemplo, às 19h toca "store_is_closing.mp3" ou algo parecido.

Também tenho um daemon MOC rodando com uma playlist de mp3, que toca música o dia todo.

Estou usando ALSA para fazer a mixagem.

Tudo funciona bem, mas estou faltando um ponto.

Se, digamos que o MOC esteja tocando uma música e o aplicativo Ruby reproduza um arquivo de som, tudo estará no mesmo nível de som (obviamente). então, você não consegue entender nada do arquivo de som reproduzido pelo aplicativo Ruby.

Eu preciso encontrar uma maneira de forçar o daemon MOC a diminuir a reprodução da música para uma porcentagem definida (digamos 10% do nível de som original) e depois que o aplicativo Ruby reproduziu o arquivo de som, o moc deve ser alternado de volta ao nível sonoro de origem.

Responder1

O daemon MOC pode ser controlado apenas com o mocpcliente.

Se você estivesse usando o PulseAudio, poderia usar pacmdpara alterar o volume do MOC.

Se você substituiu o MOC porMPD, você pode usar mpcpara alterar o volume do MPD.

Se você realmente quiser fazer isso com ALSA, você pode colocar o seguinte em /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
    }
}

e configure o MOC para usar o nome do dispositivo ALSA moc_with_volumeem vez de default.


Se o seu programa de alteração de volume não permitir configurar o controle do mixer, você deverá monitorar o outro controle do mixer e copiar seu valor para o controle do mixer MOC. Isso poderia ser feito com um 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));
        }
}

(Use amixer controlspara verificar os nomes reais dos controles.)

informação relacionada