質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

フィルタ

フィルタとは、特定の条件に合わせてデータへのアクセスをブロックするプログラムやルーチンを指します。

Q&A

解決済

5回答

2064閲覧

c言語による音声信号のFFT処理について

genius

総合スコア5

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

アルゴリズム

アルゴリズムとは、定められた目的を達成するために、プログラムの理論的な動作を定義するものです。

フィルタ

フィルタとは、特定の条件に合わせてデータへのアクセスをブロックするプログラムやルーチンを指します。

0グッド

0クリップ

投稿2020/06/23 20:34

お世話になっております。

c言語を使って音声処理をしようと考えております。

目標としては生活音を取得し、その中の3kHz以下の音声を削除するハイパスフィルタのようなものを作成したいです。

ただし、フィルタ係数等を使ったフィルタ作成ではなく、FFTを用いて特定の周波数のスペクトルを削除するといった手順のフィルタです。これを厳密にフィルタとは呼ばないかもしれませんが、テストとして実際に出来るのかどうかを確かめたいです。

手順としては以下の通りです。

1.音声信号をサンプリング周波数32kHzで256点取得

2.窓関数をかけ、FFTを用いて周波数毎のスペクトルに分解し、結果を256要素の配列に格納

3.周波数3kHz以下のスペクトルを全削除
今回の条件ではFFT結果の両端24要素を削除すれば良いことになります。

4.位相を使って実数、虚数成分にそれぞれ分解して逆変換、その後音を出力

結果としては音が割れます。
正直聞いていられないレベルで割れています。
明らかに該当スペクトルを一気に0にした事が問題ですが、解決策がよくわかりません。
逆変換後の波形と元の波形を比較すると、処理後の方が結構ギザギザしていました。

ただ、3本程度の周波数が離れた正弦波で同様の事をした場合はうまくいきました。

やはり生活音のような複雑な周波数分布の音声はことような処理は適切ではないのでしょうか?

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Penpen7

2020/06/23 20:42

どういうコードを書いたのですか?
guest

回答5

0

他人の書いたやつですが
高効率音声符号化―MP3詳解―

単純にフィルタリングすると境界付近で大きなズレが生じ違和感を感じます。

投稿2020/06/24 22:21

asm

総合スコア15147

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

FFTは時間領域のデータを周波数領域のデータに置き換えるやり方ですが、得られた周波数スペクトルからは時間の過渡特性が削除されてしまうように思いました。例えば正弦波やその足し合わせであればうまくいくが、人間の発話などのように、破裂音がありそのあと一定期間一定した周期の波形が出て減衰するような波形においてはうまくいかないことが多いと思います。音声データは時間でサンプリングされているのでz変換を用いたデジタルフィルタを使用することができます。あとは窓付きFFTやウェーブレット変換を使うことでしょうか。音声データを扱うのは案外と難しいものです。

投稿2020/06/24 14:39

anndonut

総合スコア667

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

ベストアンサー

「割れている」だけなら係数を掛けてレベルを落としてやればよさそうな気はしますが。
データがオーバーフローしていないかどうか、とかは調べているのですよね?

私もその辺は結構忘れていますが、窓関数とかの存在理由を考えるに、ある周波数を境に0/1が切り替わるような特性を実現しようというのがそもそも無茶なことなんじゃないか、という気はします。

3本程度の周波数が離れた正弦波で同様の事をした場合はうまくいきました。

カットオフ周波数帯の正弦波を入力した結果は全ゼロ出力になるでしょうか?

投稿2020/06/23 23:20

thkana

総合スコア7610

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

genius

2020/06/24 03:00

ありがとうございます。 オーバーフローはしていないと承知しております。 また、カットオフ周波数帯を入力した場合は全て0出力になります。 1つ疑問ですが、音声のとある周波数の音を消すのではなく、例えば増幅させる場合は、単に計算結果の該当周波数の数値を上げ、そのデータを実部虚部に分解して逆変換という方法で理論的には問題ないのでしょうか? 周波数を一気に0にするのは何とも説明できませんが、感覚的にまずいとは思います。 しかし、増幅させる場合に関して正直私にはこれで正しいように思えるのですが…
thkana

2020/06/24 09:40

時間軸上で、ステップ関数は無限の周波数成分を含みますからサンプリングしたらナイキスト周波数以上の成分を含んで破綻しますよね。 FFTとIFFTは対称形ですから、周波数軸上でのステップ関数をIFFTしたらこれも破綻しそう、というのが「感じ」なのですが。理論の話はもう記憶の彼方で... 逆に言えば、急峻でない変化ならそういう破綻はないだろう、というのは同意します。
guest

0

その中の3kHz以下の音声を削除する

標準"ラ"が440Hzでしょ、3kHzつーとそれより3オクターブ上。
そっから下をばっさり削るとかなりの高域成分だけが残ることになるわけで...

投稿2020/06/23 22:45

episteme

総合スコア16614

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

genius

2020/06/23 23:04

ありがとうございます。 今回質問には3kHzと書かせていただきましたが、カットオフ周波数を低い数値では250Hzから、高い数値は10kHz程度まで、いろいろ試してみましたが全パターンで音は割れました。 episteme様としては私が書いた方法をちゃんとコードとして書けていればフィルタは実現できるという予想でしょうか? そうであれば私としても希望が見えるのですが……
episteme

2020/06/23 23:11

”音声信号をサンプリング周波数32kHzで256点取得” てことはサンプリング時間はたったの0.008秒. これって妥当なんすかね?
guest

0

まずは、フィルタせずに、FFT>そのまま逆FFT で音がどうなるのかみてみればどうでしょう

投稿2020/06/23 22:34

y_waiwai

総合スコア87719

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

genius

2020/06/23 22:59

ありがとうございます。 FFT→何もせずにIFFTの場合はそれはそれは綺麗に出力されました…
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問