音声処理のプログラム

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
s-rush

音声処理のプログラム

#1

投稿記事 by s-rush » 16年前

いつもお世話になっています。
大学の課題でつまずいてしまったので、皆さんのお力をお借りしたく質問させていただきます。

今、wave形式の音声ファイルの加工プログラムを作成しています。
データ部の読み込みを以前は1バイトならunsigned char型、2バイトならshort型で読み込んでいたのですが、
これを、2バイトでもunsigned char型で読み込んでから、little endianの仕様に従い(?)
short型に変換して読み込むという方法に変えました。
1バイトの場合でも、途中の処理はshort型として扱っています。
この方法に変えてから、今まで作ってきた加工処理を行うと、思い通りの音声が生成されなくなりました。
今まで作ってきた加工処理は
・音を半分にする
・ステレオをモノラルに変換する
・倍速にする
というものです。
デバッグとして、各値をファイル出力してみてみると、どんな音声ファイルでも(16ビット)
iが2048以降はすべて同じ値になっているので、
どうもmain関数内のfread, fwriteあたりが怪しいと思っているのですが、
どこが間違っているのかが分かりません。

ブロックサイズは8192として扱っているので、16ビットの音声ファイルだと、
実質ブロックサイズは4096になっています。
このブロックサイズを変更すると、生成された音声ファイルの問題点が明白になるので、
ブロックサイズに依存しているようです。

ソースコードをアップしておきますので、どなたかご教授お願いします。
テストの音声ファイルは
・test16_s   ステレオ 16ビット
・test16_m   モノラル 16ビット
・test8_s    ステレオ 8ビット
・test8_m    モノラル 8ビット
となっています。

Justy

Re:音声処理のプログラム

#2

投稿記事 by Justy » 16年前


>どこが間違っているのかが分かりません


・ 16bitの時の wave_data_trans()ですでに元バッファサイズの半分になった t_sizeで
ループを回しているのに、for文で i+=2をしているので処理が途中で終わってしまっており、
data_inの残りの部分が不定になっている。

・ 同様に wave_data_inv()もループの回数が足りない

・ write_flag == 1が常に trueなので、ループを通過する度にヘッダを書き込んでしまっている

 こんなところじゃないでしょうか。

s-rush

Re:音声処理のプログラム

#3

投稿記事 by s-rush » 16年前

>>Justyさん
>処理が途中で終わってしまっており
おっしゃる通りでした。
16ビットデータの時、変換後のブロックサイズに合わせてしまっていたので、
元のデータ後ろ半分が処理されていませんでした^^;
テキストデータで出力させてみると、2048以降が同じ数値だったので、
値が入れられていない(初期化になるんでしょうか?)のかな?とは睨んでいたのですが、
少し見当違いの個所をずっと修正していました。

おかげさまで、無事正常な音声ファイルが出力されるようになりました。
ありがとうございます。


もう一点だけ質問させてください。
音声を倍速かつ音(音声)が高くならないプログラムを作っているのですが、
(double_speed2関数です)
これがずっとうまくいきません。
ステレオであれば、正常な音声ファイルが出力されるのですが、
モノラルだと、変な音声ファイルが出力されています。
文章では説明しづらいので、プログラムを実行していただければ
何が問題であるのかご理解いただけると思います。
(無責任で申し訳ないです)
処理にフーリエ変換を使用しています。
dft_idft()とfft_ifft()には間違いはないと思います。
1周期分のsin波を上記2つの関数に渡したところ、正常に変換されています。
となると、周波数空間での加工部分、もしくは引数を渡す部分に間違いがある、
としか考えられません。

これもどこに問題があるのかが分かりませんorz
かれこれ1か月ほど悩んでいます。

修正版のソースをアップしておきますので、こちらの方もご教授お願いします。

Justy

Re:音声処理のプログラム

#4

投稿記事 by Justy » 16年前


>こちらの方もご教授お願いします

 いや、サウンド方面はさほど得意ってわけじゃないんですが・・・・・・。

 でもまぁ、精度を気にしないのであれば加工の部分は
[color=#d0d0ff" face="monospace]
for(i=0; i<size/2; i++){
re = t_re[2*i];
im = t_im[2*i];
}
for(; i<size; i++){
re = 0;
im = 0;
}[/color]

でいいんじゃないのでしょうか?

 ちゃんとやるなら

Pitch Shifting Using The Fourier Transform - The DSP Dimension
ttp://www.dspdimension.com/admin/pitch-shifting-using-the-ft/
 とか

SoundTouch
ttp://www.surina.net/soundtouch/

 を研究した方がいいかもしれません。

s-rush

Re:音声処理のプログラム

#5

投稿記事 by s-rush » 16年前

>>Justyさん
ありがとうございます。
おかげで解決することができました^^

配列にはa[-10]みたいに負の数がないというのを忘れていました。
なので、コンピューター内と、実際に考える周波数空間の並び方が異なっているのですね。

>Pitch Shifting Using The Fourier Transform - The DSP Dimension
>ttp://www.dspdimension.com/admin/pitch-shifting-using-the-ft/
>SoundTouch
>ttp://www.surina.net/soundtouch/
せっかく教えていただいたので、こちらの方も研究して、
さらに良い処理ができるようにしてみたいと思います。

ちなみに
>for(; i<size; i++){
iの初期値が書かれていないですけど、
for(i=size/2, i<size, i++){
でいいのですよね?

Justy

Re:音声処理のプログラム

#6

投稿記事 by Justy » 16年前


>iの初期値が書かれていないですけど、
>for(i=size/2, i<size, i++){
>でいいのですよね?

 それでもいいですし、そのままでも大丈夫ですよ。
 1つ上の forで使われた iの値をそのまま引き継いで使っていますから。

s-rush

Re:音声処理のプログラム

#7

投稿記事 by s-rush » 16年前

for(; i<size; i++){
という書き方もできるのですね。
for文の()内は必ず3つの条件を記入しなければいけないと思っていたので、知りませんでした。

おかげさまですべての問題が解決できました。
ありがとうございます。

閉鎖

“C言語何でも質問掲示板” へ戻る