音信号を周波数変換するプログラムを作成しています。
FFTを使って実現しようとしているのですが、うまくいきません。
現時点で作った方法では、
(1)FFTする。結果は配列x_re[NFFT]、x_im[NFFT]に格納。(x_re:実数部 x_im:虚数部 NFFT:ポイント数、配列の内容としては周波数の低い順に結果データが並んでいる)
(2) x_re,x_imの内容をずらす。(例えば以下のように配列内容を1つずらせばIFFTをした時周波数が高くなるはず)
for(i=0;i<NFFT-1;i++){
x_re[i+1]=x_re[i];
x_im[i+1]=x_im[i];
}
(3)配列x_re[NFFT]、x_im[NFFT]に対しIFFTする。
FFT・IFFTが正しく動作するのは確認しています。
(動作実績も結構あります。(2)を省略し(1)(3)だけとすれば出力結果は入力結果と同じ(出力音声を聴いた感じで)になるので、正しく動作していると思います。)
よって(2)が間違っていると思います。
(2)をどのようにすれば周波数変換できるのか教えてください。また今の所FFTを使おうとしているのですが、別に入力信号を周波数変換できればOK(周波数を上げたり下げたりしたい)なので、その方法があれば教えてください(><)
No.3ベストアンサー
- 回答日時:
配列をずらすと周波数は高くなるでしょうが、音は不自然になるはずです。
足し算ではなく掛算で考えるべきだと思います。たとえば、1kHzと2kHzがあって、これはちょうど倍音関係(1オクターブ上)になっていますが、足し算(+0.2kHz)だと1.2kHzと2.2kHzで不協和音になりますよね。掛算(*1.2)ならば1.2kHzと2.4kHzで倍音関係は維持したままです。
僕は専門家ではないのであまり詳しくないですが、周波数シフトではいろいろ気をつけることがあるみたいです。
FFTでは周波数の間隔が一定ですので、掛算で求めた周波数はちょうどグリッド上にくることはありません。
これは、掛算する前の周波数も本当の周波数ではなくて、最寄のグリッド上にでていることを意味します。
周波数シフトのようなデリケートな処理の場合、周波数の誤差は致命的ですので、補正処理が必要です。
補正方法は、位相差計測法とかいろいろあるようです。。
No.2
- 回答日時:
FFTは単なる計算技術なのでDFTとIDFTに置き換えていうべきですがそもそもDFTを使うのは得策ではありません
計算区間の境で大きくなる誤差を生じるからです
シフトしたい周波数幅をf0とすると単純に
元の信号にexp(j・2π・f0・t)をかければいいでしょう
気をつけなければならないのは複素数になり2つのデータを管理しなければならないのです
実部のcos(2π・f0・t)との積だけや虚部のsin(2π・f0・t)との積だけにしておくと折り返しを生じてしまうのです
(サンプリング周波数fsが大きくf0が大きければこの限りで無い,ただしこの場合無駄が多い)
このほうが正確(DFTと違って基本的には計算誤差以外の誤差なし)で計算量も小さい(1サンプルに複素数1乗算だけ)のです
No.1
- 回答日時:
for(i=0;i<NFFT-1;i++){
x_re[i+1]=x_re[i];
x_im[i+1]=x_im[i];
}
だとすべてのデータがx_re[0],x_im[0]になるのでは?
解決案
for (i=NFFT-1; i>0; i--) {
x_re[i]=x_re[i-1];
x_im[i]=x_im[i-1];
}
この回答への補足
ご指摘の通りです(><)
質問登録直後に気づきましたが訂正できませんでした。
この場を借りまして訂正致します。
実際のプログラムでは、正しく配列内容を1つずらしております。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- 物理学 風力発電での音 1 2023/04/16 08:55
- 数学 フーリエ変換後の負の周波数成分の扱いについて 4 2022/09/03 10:18
- 工学 オペアンプによる増幅回路でのノイズ対策について 5 2022/03/22 16:06
- その他(コンピューター・テクノロジー) PIC16F1シリーズマイコンのNCO機能について 1 2023/04/18 08:41
- 工学 エミッタ設置増幅回路で下記の要件を満たす増幅器を設計せよ。 要件は必要要件であり、例えば、少なくとも 1 2022/12/16 10:15
- 物理学 風車から出る音(その②) 8 2023/04/17 12:25
- その他(プログラミング・Web制作) FORTRAN77の配列(除算) 2 2023/02/01 14:34
- その他(コンピューター・テクノロジー) ハードドライブのデータ記憶方法 USBメモリーなどの半導体記憶デバイスは、ビット毎の 0 or 1 1 2023/02/25 12:41
- 工学 半導体 光減衰法による少数キャリアのライフタイム測定で周波数を変えたときの検出波形(縦軸出力電圧、横 1 2023/05/16 19:15
- その他(自然科学) 風車音の測定 3 2023/04/28 07:12
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBA 変数名に変数を使用したい。
-
DBから取得した値を配列へ代入する
-
C#でbyte配列から画像を表示さ...
-
構造体配列の一部初期化!!!
-
エクセルでXY座標に並べられた...
-
VB6で、一次元配列と二次元配列...
-
定数配列の書き方
-
配列の中の最大値とそのインデ...
-
オブジェクト名を変数で参照で...
-
配列の要素がすべてカラかどう...
-
vba フィルター 複数条件 3つ以...
-
Dir関数で読み取り順を操作でき...
-
ActiveReports(アクティブレポ...
-
VB.NETの配列にExcelから読み込...
-
VBで配列に格納されているデー...
-
8bitインデックス画像の入出力方法
-
Redim とEraseの違いは?
-
VBでの配列をEXCELに出力する方法
-
EXCEL VBA 配列デー...
-
Excel2010のinputboxで複数デー...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBA 変数名に変数を使用したい。
-
vba フィルター 複数条件 3つ以...
-
C#でbyte配列から画像を表示さ...
-
Excel2010のinputboxで複数デー...
-
エクセルでXY座標に並べられた...
-
構造体配列の特定のメンバーをF...
-
定数配列の書き方
-
コンボボックスのインデックス...
-
OutOfMemoryExceptionの回避策...
-
Dir関数で読み取り順を操作でき...
-
CheckBoxの配列化
-
構造体配列内の文字列検索のよ...
-
COBOLの基本的な事なので...
-
Redim とEraseの違いは?
-
VBAで配列引数を値渡しできない...
-
2次元配列の初期値
-
配列の中の最大値とそのインデ...
-
大量の変数を定義するにはどう...
-
VB6からの移行したいけど、VB.N...
-
VB6のメモリ解放に関して
おすすめ情報