2017-04-18 176 views
2

我正在尋找將文件中的音頻數據饋送到麥克風的方式,因此當第三方應用程序(例如或Chromium的「按語音搜索」功能)使用麥克風對於音頻輸入,它們會從文件接收音頻數據。Linux管道音頻文件到麥克風輸入

這是我的場景:我寫的應用程序記錄了麥克風(使用ALSA)的音頻數據並將其保存到文件(audioFile0.raw)。在將來某個未知的時間點,某些未知的第三方應用程序(如我沒有開發的東西,因此我沒有開發控制權,例如Chromium網絡瀏覽器的「通過語音搜索」功能)將使用麥克風獲取音頻數據。我希望第三方應用程序收集的音頻數據來自audioFile.raw,而不是實際的麥克風本身。

我在想,如果有可能將默認音頻輸入設備更改爲音頻文件,或者可能是命名管道,並執行類似cat audioFile0.raw > mypipe(因爲我不知道另一個應用程序何時會嘗試從麥克風讀取)。也許有一個更簡單的方法來做到這一點?

我希望我提供了足夠的細節和清晰度。請讓我知道,如果有什麼不清楚。


編輯: 所以我想通了如何使虛擬麥克風在我的主目錄創建以下文件.asoundrc:

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 
} 

我那麼從命令行調用arecord test.raw -c 1 -f S16_LE -r 16000 -t raw -D virtmic和我可以將audioFile0.raw中的音頻數據記錄到test.raw

我現在的目標是用我的虛擬麥克風替換默認設備,因此任何訪問麥克風的應用程序都將讀取audioFile0.raw中的音頻數據,而不是實際的麥克風本身。所以我編輯我.asoundrc文件,如下所示:

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 
} 

那時,我便在命令行arecord test.raw -c 1 -f S16_LE -r 16000 -t raw。然後我播放了test.raw,但它似乎是從麥克風本身錄製的,而不是audioFile0.raw

我在做什麼錯?如何更改默認捕獲設備,以便從audioFile0.raw中讀取數據,而不是從麥克風輸入數據?


編輯2:好了,所以我是在正確的軌道上。我在我的主目錄中使用了相同的.asoundrc文件,這是我之前在其中將默認設備更改爲virtmic的地方。我需要更改文件/usr/share/alsa/alsa.conf.d/pulse.conf所以它看起來是這樣的:

# 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 
    } 
] 

我做的唯一的事情就是註釋掉"/usr/share/alsa/pulse-alsa.conf""/home/charles/.asoundrc"代替它,因此插件的pulseaudio不使用ALSA應用程序的默認,而是使用我的虛擬麥克風作爲默認設置。這可能不是最好的解決方案,但它可行。

這個工作,當我做arecord test.raw -t raw -c 1 -f S16_LE -r 16000。它從audiofile0.raw獲得數據而不是麥克風!我使用命令lsof /dev/snd/*來查看arecord命令運行時訪問音頻設備的確切時間。輸出如下:

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 

然後我使用Chromium瀏覽器的功能,試圖「語音搜索」,發現我不能讓它從audioFile0.raw記錄。然後,我使用lsof /dev/snd/*來查看訪問音頻設備的確切時間。

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 

我看到它們都具有相同的PID,2044.它們都使用pulseaudio守護進程,而不是通過ALSA。

我的問題:我如何獲得的PulseAudio用我的虛擬麥克風在默認情況下,這樣的pulseaudio通過對音頻輸入去的所有應用程序反而會從我的文件,而不是麥克風的音頻數據?

+2

[管道輸出從aplay到centos中的arecord]的可能重複(http://stackoverflow.com/questions/42843128/piping-output-from-aplay-to-arecord-in-centos) –

+0

@CL。糾正我,如果我錯了,但在這種情況下,似乎記錄應用程序已知(_arecord test.raw -r 8000 -t raw_)。就我而言,我無法控制哪個應用程序將訪問麥克風。我希望任何將從麥克風讀取的應用程序從我的文件中讀取。 – cheerupcharlie

+1

請注意,'arecord'調用不指定設備名稱並使用默認設備。 (程序總是可以明確使用不同的設備名稱。) –

回答

5

經過許多艱苦的工作,我終於得到了可以接受的工作。我解開了我使用ALSA所做的所有事情(因爲默認情況下ALSA使用PulseAudio,而我最初將其替換)。我創建了一個簡單的bash腳本install_virtmic.sh,以創建一個「虛擬麥克風」的pulseaudio的使用以及pulseaudio的客戶:

#!/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 

用於撫平一切由安裝腳本進行的快速腳本uninstall_virtmic.sh

#!/bin/bash 

# Uninstall the virtual microphone. 

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

然後,我啓動了Chromium並單擊了麥克風以使用其語音搜索功能,並且它工作正常!我也試過arecord test.raw -t raw -f S16_LE -c 1 -r 16000,它也工作!這並不完美,因爲我一直在腳本的無限循環中寫入命名管道virtmic(這很快使我的test.raw文件變得非常大),但現在它會完成。

請隨時讓我知道如果有人在那裏找到更好的解決方案!