MOC ausblenden, wenn eine andere Anwendung etwas abspielt

MOC ausblenden, wenn eine andere Anwendung etwas abspielt

Ich muss einen guten Weg finden, die Tonwiedergabe eines Moc-Daemons zu verlangsamen

Ich habe folgendes Szenario:

Ich verwende eine kleine Ubuntu 12.04-Serverbox mit einem MOC-Daemon (Musiconconsole) und einer benutzerdefinierten Ruby-Anwendung.

Die Ruby-Anwendung spielt gelegentlich in periodischen oder ereignisgesteuerten Szenarien eine WAV- oder andere Sounddatei ab. Beispielsweise wird um 19:00 Uhr „store_is_closing.mp3“ oder etwas Ähnliches abgespielt.

Außerdem habe ich einen MOC-Daemon mit einer MP3-Wiedergabeliste laufen, der den ganzen Tag Musik abspielt.

Zum Mischen verwende ich ALSA.

Alles funktioniert einwandfrei, aber ein Punkt fehlt mir.

Wenn beispielsweise MOC ein Lied abspielt und die Ruby-App eine Sounddatei abspielt, ist (offensichtlich) alles auf der gleichen Tonebene. Sie können also nichts von der Sounddatei verstehen, die von der Ruby-App abgespielt wird.

Ich muss einen Weg finden, den MOC-Daemon zu zwingen, die Wiedergabe des Songs auf einen bestimmten Prozentsatz (sagen wir 10 % der ursprünglichen Lautstärke) herunterzufahren. Nachdem die Ruby-App die Sounddatei abgespielt hat, sollte MOC wieder auf die ursprüngliche Lautstärke zurückgeschaltet werden.

Antwort1

Der MOC-Daemon kann nur mit dem mocpClient gesteuert werden.

Wenn Sie PulseAudio verwenden, können Sie pacmddie Lautstärke des MOC ändern.

Wenn Sie MOC durch ersetzenMPD, können Sie mpcdie Lautstärke von MPD ändern.

Wenn Sie dies wirklich mit ALSA machen möchten, können Sie Folgendes eingeben /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
    }
}

und konfigurieren Sie MOC so, dass der ALSA-Gerätename moc_with_volumeanstelle von verwendet wird default.


Wenn Ihr Lautstärkereglerprogramm die Konfiguration des Mischpultreglers nicht zulässt, müssen Sie den anderen Mischpultregler überwachen und dessen Wert in den MOC-Mischpultregler kopieren. Dies kann mit einem Programm wie diesem erfolgen:

#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));
        }
}

(Verwenden Sie dies amixer controls, um die tatsächlichen Steuerelementnamen zu überprüfen.)

verwandte Informationen