問題意識
- 我々の生活は情報にあふれている
- 私たちの耳は認知を回避できない
- 聞きたくないものも耳に入るし、聞きたい情報を選別することできない
- それに対して目に入るものを制限するというのは行われている(Twitterのミュート機能など)
コンセプト
もし、聞きたくない情報を減衰させることができたら面白いんじゃないか?→耳感覚減少
もし、聴きたい情報のみに耳をフォーカスすることができたら?→耳感覚増強
やりたいこと
- 会話の中で特定の言葉が聞こえたら、声が大きくなったり小さくなったりする
システム図
ユースケース
耳感覚減少(特定の言葉が聞こえたらミュートする)のユースケース
- 聞きたくない話題について情報を防げる(ネタバレ防止等)
耳感覚増強(特定の言葉が聞こえたら耳能力が高くなる)のユースケース
作ってみた
要素技術調査
- Pyaudioを使ってマイクから入力した音声をそのままスピーカーに流す
- 入力した音声からSpeech Recognitionを使って文字起こしをする
- 文字起こしの結果から、音声のフィードバックの仕方を変化させる - Pycawを使ってWindowsのマスターボリュームをPythonから操作する
Pyaudioを使ってマイクから入力した音声をそのままスピーカーに流す
- Pyaudioを使えばマイクからの音の入力を並列処理できるということらしい。常にマイクから音を取り続けていることが必要なので、スレッドを作ってそちらで常に処理を行っておく必要があるがPyaudioのノンブロッキングモードを使えば勝手にPyaudioでThreadを作ってくれて実行してくれるようだ。
- なのでStreamがOpenしている(音をマイクから収集してスピーカーに流している間)間に音声認識なり、音調変換なりを行えば良さそう
WindowsのPyaudioインストール
- Python3.7~3.9だとPyaudioがpip経由でインストールできない。非公式版だが、下記URLからPython 3.9用 Pyaudio(PyAudio‑0.2.11‑cp39‑cp39‑win_amd64.whl)をダウンロードする
- whlファイルがあるディレクトリでpip経由でインストールする
py -m pip install PyAudio-0.2.11-cp39-cp39-win_amd64.whl
linuxのPyaudioインストール
- portaudioというライブラリに依存しておりそのままだとpip経由でpyAudioインストールしようとするとエラーを吐くため
sudo apt-get install portaudio19-dev
でportaudioをインストールしてから
pip install pyaudio
でOK
実装コード
# coding: UTF-8 import speech_recognition as sr import pyaudio import time class AudioFilter(): def __init__(self):# classの初期設定 self.p = pyaudio.PyAudio() self.channels = 2 #マイクがモノラルの場合は1 self.rate = 48000 #DVDレベルなので重かったら16000 self.format = pyaudio.paInt16 self.stream = self.p.open( format = self.format, channels = self.channels, rate = self.rate, output = True, input = True, stream_callback=self.callback)#音声が流れてきた時に叩くCallBack関数を指定する # format : ストリームを読み書きするときのデータ型 # channels: ステレオかモノラルかの選択 1でモノラル 2でステレオ # rate : サンプル周波数 # output : 出力モード # コールバック関数(再生が必要なときに呼び出される) def callback(self, in_data, frame_count, time_info, status): out_data = in_data return (out_data, pyaudio.paContinue) # 音声取り込みをやめるとき def close(self): self.p.terminate() if __name__ == "__main__": #importされた場合に実行しないようにするらしい #AudioFileterのインスタンスを作る af = AudioFilter() #ストリーミングを始める af.stream.start_stream() # ノンブロッキングなのでこの中で音声認識・音の変換などを行う while af.stream.is_active(): print("なんの処理をしてもOK") #r = sr.Recognizer() #with sr.Microphone() as source: # pyaudioを使ってマイクを認識? # r.adjust_for_ambient_noise(source) # print("音声を読み取っています") # audio = r.listen(source) # try: # query = r.recognize_google(audio, language='ja-JP') # print(query) # except: # print("エラー") # ストリーミングを止める af.stream.stop_stream() af.stream.close() af.close()
結果
- 若干実際の音声に対して遅れて出力されるが、音質的には問題なさそう
参考資料
- PyAudioを用いてマイクの入力をそのまま出力する
入力した音声からSpeech Recognitionを使って文字起こしをする
実行環境
- Python 3.9
SpeechRecognitionのinstall
- SpeechRecognitionをpip経由でインストールする
pip install SpeechRecognition
実装したコード
import speech_recognition as sr import pyaudio if __name__ == "__main__": #importされた場合に実行しないようにするらしい r = sr.Recognizer() with sr.Microphone() as source: # pyaudioを使ってマイクを認識? r.adjust_for_ambient_noise(source) print("音声を読み取っています") audio = r.listen(source) try: query = r.recognize_google(audio, language='ja-JP') print(query) except: print("エラー")
実行結果
- こんにちはといった場合
まとめ
- そこそこの精度は出る。
- マイク入力の終わりを指定してないけど、何故か音声の終わりは検知している
- アホほど実装が簡単
参考資料
Pycawを使ってWindowsのマスターボリュームをPythonから操作する
設計と実装
要求
- マイクから入力した音声をそのままスピーカーに流す
- 検閲させるキーワードを設定する
- 文字起こしの内容から検閲ワードを見つける
- 検閲ワードを見つけたらマイクから得た音声に何かしらの加工をかけて(まずは簡単にP音を10秒流す)検閲ワードをユーザーに聞かせないようにする
詳細タスク
- 検閲ワードをユーザーに入力させて配列に入れる
- KeyInoutクラス key_input関数
- STTで文字起こししたセンテンスに検閲ワードが含まれていないか検索する
- AudioCensorshipクラス character_search関数
- 検閲ワードが含まれていた場合は、Pycawでスピーカーからの音量を予め設定していたボリュームに◯秒変える
- AudioControllerクラス set_enhanced_volume関数
- Timerクラス is_time_out関数
コード
できたもの
- 耳感覚を増強する例
- スパイダーマンというキーワードが出るとゲインが1.5倍になる
- わかりづらくて申し訳ないですが、画面下側のコンソールにマイクから読み取ったテキストを表示しています
- 耳感覚を減少させる(聞きたくないキーワードを検出するとゲインを下げる)例
- スパイダーマンというキーワードが出るとミュートがかかる
- ミュートしている間も画面下側のコンソールにマイクから読み取ったテキストを表示しています
感想と反省
- 耳感覚減少では、いきなり音が全く聞こえなくなるのでビビる
- 検閲ワードがあったら音がかなり小さくなるくらいでいいかも
- ただ、確かにキーワードが出てからは会話が聞こえなくなるので、聞きたくない情報をカットすることはできる
- 耳感覚増強では、誰かがキーワードを喋るといきなり外界からの音が大きくなるので、かなり恐怖を感じる
課題
- 検閲ワードを検出した瞬間の会話は防ぎようがない
- 一文字毎にテキスト化するSSTライブラリ等を使う必要がある
- 会話が一度途切れないと、テキスト化されない
- Speech Recognitionの設定で逃れられるかも
- 単純なボリュームの増減による音声加工しかできないので一部の声だけを聞こえなくする・強調する等ができない
- 音源定位技術を使って発話者の位置を特定し、特定の声だけを消すなどできるかも
- ノートPCが重い
- ラズパイに移植する
- イヤホンをつけているだけだと変換前の外の音声が聞こえてしまう
- ノイズキャンセリングイヤホンを使う