2017-04-18 1 views
2

Ich bin auf der Suche nach einer Möglichkeit, Audiodaten aus einer Datei in das Mikrofon zu füttern, wenn 3rd-Party-Anwendungen (arecord oder Chromium "Suche nach Stimme" -Funktion) das Mikrofon verwenden Bei der Audioeingabe erhalten sie stattdessen die Audiodaten aus der Datei.Linux Pipe Audiodatei zum Mikrofon Eingang

Hier ist mein Szenario: Eine Anwendung I Aufzeichnungen Audiodaten aus dem Mikrofon schrieb (mit ALSA) und speichert sie in einer Datei (audioFile0.raw). Zu einem unbekannten Zeitpunkt in der Zukunft wird eine unbekannte Anwendung von Drittanbietern (wie in etwas, das ich nicht entwickelt habe, so dass ich keine Entwicklungskontrolle habe, wie die "Suche nach Sprache" -Funktion des Chromium-Webbrowsers), das Mikrofon verwenden Erhalte Audiodaten. Ich möchte, dass die Audiodaten, die die Drittanbieter-Anwendung sammelt, von audioFile.raw und nicht vom eigentlichen Mikrofon selbst stammen.

Ich dachte, wenn es möglich wäre, das Standard-Audio-Eingabegerät in eine Audiodatei oder vielleicht eine Named Pipe zu ändern und etwas wie cat audioFile0.raw > mypipe zu tun (da ich nicht weiß, wenn eine andere Anwendung versucht, aus dem Mikrofon zu lesen)). Vielleicht gibt es einen einfacheren Weg, dies zu tun?

Ich hoffe, ich habe genug Detail und Klarheit zur Verfügung gestellt. Bitte lassen Sie mich wissen, wenn etwas unklar ist.


EDIT: Also, wie ich herausgefunden ein virtuelles Mikrofon zu machen, indem die folgende .asoundrc Datei in meinem Home-Verzeichnis zu erstellen:

pcm.!virtmic { 
    type file 
    slave.pcm "hw:0,0" 
    file /dev/null 
    infile "/home/charles/audioFiles/audioFile0.raw" 
} 

pcm.!default { 
    type hw 
    card 0 
} 

ctl.!default { 
    type hw 
    card 0 
} 

Ich rufe dann arecord test.raw -c 1 -f S16_LE -r 16000 -t raw -D virtmic von der Kommandozeile und Ich kann die Audiodaten in audioFile0.raw bis test.raw aufnehmen.

Mein Ziel ist es jetzt, das Standardgerät durch mein virtuelles Mikrofon zu ersetzen, so dass jede Anwendung, die auf das Mikrofon zugreift, die Audiodaten in audioFile0.raw anstelle des eigentlichen Mikrofons liest. So bearbeitete ich meine .asoundrc-Datei wie folgt aussehen:

pcm.!virtmic { 
    type file 
    slave.pcm "hw:0,0" 
    file /dev/null 
    infile "/home/charles/audioFiles/audioFile0.raw" 
} 

pcm.!default { 
    type asym 
    playback.pcm { 
     type hw 
     card 0 
    } 
    capture.pcm { 
     type plug 
     slave.pcm "virtmic" 
    } 
} 

ctl.!default { 
    type hw 
    card 0 
} 

Dann rief ich arecord test.raw -c 1 -f S16_LE -r 16000 -t raw von der Kommandozeile. Ich habe dann test.raw abgespielt, aber es schien vom Mikrofon selbst aufzunehmen und nicht audioFile0.raw.

Was mache ich falsch? Wie genau ändere ich das Standard-Aufnahmegerät, so dass es die Daten von audioFile0.raw statt der Eingabe vom Mikrofon liest?


EDIT 2: Okay, so war ich auf dem richtigen Weg. Ich verwende die gleiche .asoundrc-Datei in meinem Home-Verzeichnis, die ich zuvor gezeigt habe, wo ich das Standard-Gerät zu dem virtuellen geändert habe. Ich brauchte die Datei zu ändern /usr/share/alsa/alsa.conf.d/pulse.conf, so dass es wie folgt aussieht:

# PulseAudio alsa plugin configuration file to set the pulseaudio plugin as 
# default output for applications using alsa when pulseaudio is running. 
hook_func.pulse_load_if_running { 
    lib "libasound_module_conf_pulse.so" 
    func "conf_pulse_hook_load_if_running" 
} 

@hooks [ 
    { 
     func pulse_load_if_running 
     files [ 
#   "/usr/share/alsa/pulse-alsa.conf" 
      "/home/charles/.asoundrc" 
     ] 
     errors false 
    } 
] 

Das einzige, was ich war "/usr/share/alsa/pulse-alsa.conf" die Linie tat Kommentar aus und ersetzte sie durch "/home/charles/.asoundrc" so die Pulseaudio-Plugin ist nicht der Standard für Anwendungen mit ALSA, Verwenden Sie stattdessen mein virtuelles Mikrofon als Standard. Dies ist möglicherweise nicht die beste Lösung, aber es funktioniert.

Dies funktionierte, als ich arecord test.raw -t raw -c 1 -f S16_LE -r 16000 tat.Es hat die Daten von audiofile0.raw anstelle des Mikrofons! Ich habe den Befehl lsof /dev/snd/* verwendet, um zu sehen, was genau auf das Audiogerät zugegriffen hat, während der Befehl arecord ausgeführt wurde. Der Ausgang war wie folgt:

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME 
pulseaudi 2044 charles 22u CHR 116,6  0t0 8977 /dev/snd/controlC0 
pulseaudi 2044 charles 29u CHR 116,6  0t0 8977 /dev/snd/controlC0 
arecord 4051 charles mem CHR 116,5   8976 /dev/snd/pcmC0D0c 
arecord 4051 charles 4u CHR 116,5  0t0 8976 /dev/snd/pcmC0D0c 

Ich habe dann versucht Chromium Browser mit Feature „von Stimme suchen“ und sah, dass ich es nicht von audioFile0.raw aufnehmen bekommen konnte. Ich habe dann lsof /dev/snd/* verwendet, um zu sehen, was genau auf das Audiogerät zugegriffen hat.

COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME 
pulseaudi 2044 charles mem CHR 116,5   8976 /dev/snd/pcmC0D0c 
pulseaudi 2044 charles 22u CHR 116,6  0t0 8977 /dev/snd/controlC0 
pulseaudi 2044 charles 29u CHR 116,6  0t0 8977 /dev/snd/controlC0 
pulseaudi 2044 charles 30r CHR 116,33  0t0 7992 /dev/snd/timer 
pulseaudi 2044 charles 31u CHR 116,5  0t0 8976 /dev/snd/pcmC0D0c 

ich sehe, dass sie alle haben die gleiche PID, 2044. Sie sind alle Pulseaudio Daemon mit, nicht durch ALSA gehen.

Meine Frage: Wie bekomme ich pulseaudio, um mein virtuelles Mikrofon standardmäßig zu verwenden, so dass alle Anwendungen, die durch Pulseaudio für Audio-Eingang gehen, stattdessen die Audiodaten aus meiner Datei anstelle des Mikrofons erhalten?

+2

Mögliches Duplikat von [Piping-Ausgabe von aplay zu arecord in centos] (http://stackoverflow.com/questions/42843128/piping-output-from-applay-to-arecord-in-centos) –

+0

@CL. Korrigiere mich, wenn ich falsch liege, aber in diesem Fall scheint es, dass die Aufnahmeanwendung bekannt ist (_arecord test.raw -r 8000 -t raw_). In meinem Fall habe ich keine Kontrolle darüber, welche Anwendung auf das Mikrofon zugreifen wird. Ich möchte, dass eine Anwendung, die aus dem Mikrofon liest, stattdessen aus meiner Datei liest. – cheerupcharlie

+1

Bitte beachten Sie, dass dieser 'Arecord'-Anruf keinen Gerätenamen angibt und das Standardgerät verwendet. (Und es ist immer möglich, dass ein Programm explizit einen anderen Gerätenamen verwendet.) –

Antwort

5

Nach vielen mühsamen Stunden bekam ich endlich etwas akzeptables Arbeiten. Ich habe alles, was ich mit ALSA gemacht habe, rückgängig gemacht (da ALSA standardmäßig stattdessen PulseAudio verwendet, das ich anfangs übersteuert habe). Ich habe einen einfachen Bash-Skript install_virtmic.sh ein „virtuelles Mikrofon“ zu schaffen für Pulseaudio sowie Pulseaudio-Clients zu verwenden:

#!/bin/bash 

# This script will create a virtual microphone for PulseAudio to use and set it as the default device. 

# Load the "module-pipe-source" module to read audio data from a FIFO special file. 
echo "Creating virtual microphone." 
pactl load-module module-pipe-source source_name=virtmic file=/home/charles/audioFiles/virtmic format=s16le rate=16000 channels=1 

# Set the virtmic as the default source device. 
echo "Set the virtual microphone as the default device." 
pactl set-default-source virtmic 

# Create a file that will set the default source device to virtmic for all 
PulseAudio client applications. 
echo "default-source = virtmic" > /home/charles/.config/pulse/client.conf 

# Write the audio file to the named pipe virtmic. This will block until the named pipe is read. 
echo "Writing audio file to virtual microphone." 
while true; do 
    cat audioFile0.raw > /home/charles/audioFiles/virtmic 
done 

Eine schnelle Skript uninstall_virtmic.sh für alles durch das Installationsskript getan Verhängnis:

#!/bin/bash 

# Uninstall the virtual microphone. 

pactl unload-module module-pipe-source 
rm /home/charles/.config/pulse/client.conf 

Dann habe ich Chrom angezündet und das Mikrofon geklickt, um seine Sprachsuche zu benutzen und es hat funktioniert! Ich habe es auch mit arecord test.raw -t raw -f S16_LE -c 1 -r 16000 versucht und es hat auch funktioniert! Es ist nicht perfekt, weil ich weiter schreibe an die Named Pipe virtmic in einer Endlosschleife im Skript (die schnell meine test.raw Datei wahnsinnig groß gemacht), aber es wird für jetzt tun.

Bitte zögern Sie nicht mich wissen zu lassen, wenn jemand da draußen eine bessere Lösung findet!

Verwandte Themen