web-dev-qa-db-ja.com

Linuxパイプオーディオファイルからマイク入力へ

サードパーティのアプリケーション(arecordなど)またはChromiumの「音声で検索」するときに、ファイルからマイクにオーディオデータをフィードする方法を探しています"機能)オーディオ入力にマイクを使用し、代わりにファイルからオーディオデータを受信します。

これが私のシナリオです:私が作成したアプリケーションは、(ALSAを使用して)マイクからオーディオデータを録音し、ファイル(audioFile0.raw)に保存します。将来の不明な時点で、不明なサードパーティアプリケーション(たとえば、私が開発したものではないため、Chromium Webブラウザの「音声検索」機能など、開発を制御できない)は、マイクを使用してオーディオデータを取得します。サードパーティアプリケーションが収集しているオーディオデータは、実際のマイク自体ではなく、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ファイルを使用していますが、デフォルトのデバイスを仮想に変更しました。ファイル/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

2044はすべて同じPIDを持っています。ALSAを経由せずに、pulseaudioデーモンを使用しています。

私の質問:デフォルトで仮想オーディオをPulseAudioで使用するには、オーディオ入力にPulseAudioを使用するすべてのアプリケーションで、マイクではなくファイルからオーディオデータを取得する方法を教えてください。

12
cheerupcharlie

多くの骨の折れる時間の後、私はようやく許容できるものを得ました。 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ファイルを非常に大きくしました)、完璧ではありませんが、今のところはそれで十分です。

誰かがより良い解決策を見つけたら私に知らせてください!

14
cheerupcharlie