Затухание MOC, если другое приложение начинает проигрывать что-либо

Мне нужно найти хороший способ заставить проигрывать звук moc-демона.

У меня следующий сценарий:

У меня работает небольшая серверная коробка Ubuntu 12.04 с MOC (musiconconsole) демон и пользовательское приложение ruby.

Приложение ruby ​​иногда воспроизводит wav или другой звуковой файл в периодических или событийных сценариях. например в 7 часов вечера. он играет "store_is_closing.mp3" или что-то в этом роде.

У меня также есть демон MOC, работающий со списком воспроизведения mp3, который воспроизводит музыку в течение всего дня.

Я использую ALSA для микширования.

Все работает хорошо, но мне не хватает одного очка.

Если, скажем, MOC воспроизводит песню, а приложение ruby ​​воспроизводит звуковой файл, все находится на одном уровне звука (очевидно). поэтому вы ничего не можете понять из звукового файла, воспроизводимого приложением ruby.

Мне нужно найти способ заставить демона MOC снизить его воспроизведение песни до определенного процента (скажем, 10% от исходного уровня звука), и после того, как приложение ruby ​​воспроизведет звуковой файл, moc должен быть вернулся к исходному уровню звука.

0
задан 12 November 2013 в 14:49

1 ответ

Демон 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 для проверки фактических имен элементов управления.)

0
ответ дан 12 November 2013 в 14:49

Другие вопросы по тегам:

Похожие вопросы: