• ベストアンサー

フーリエ 音を1オクターブ上げるにはスペクトルをどういじる?

周波数が倍になると1オクターブ音程が上がるという話を聞いたことがあります。 そこで、フーリエ変換をしたスペクトルデータをいろいろいじってみたのですが、どうしても1オクターブ音程が上がるということが実現できません(逆フーリエ変換をかけて音を確認)。 実際に1オクターブ音程を上げるにはどのようにスペクトル(絶対値・位相(もしくは実部・虚部))を変化させればよいのでしょうか? (音程だけ変化させて、音の速度は変化しないようにしたい)

質問者が選んだベストアンサー

  • ベストアンサー
  • tatsumi01
  • ベストアンサー率30% (976/3185)
回答No.8

No. 1,2,3,6 です。 経験者というのは信号処理 (FFT 含む) ということで、スペクトル移動を実際には試していません。最初の投稿で「原理の話で・・・」と書きました。 ここでの応答では jyuzou さんの症状についてこれ以上わかりません。私の書いた原理を実現しているのであれば、No. 7 さんのエイリアシングは出ないと思います。 ただ、何回も書いているように、スペクトルとは無限時間を仮定しています。言ってみれば周期関数が相手です。音声や音楽信号は完全な周期関数ではない、ということを考慮して下さい。

jyuzou
質問者

お礼

回答どうもありがとうございます。 おっしゃる通りもう少し考える必要があると思います。 また他の案があれば、回答よろしくお願いします。

その他の回答 (8)

  • rabbit_cat
  • ベストアンサー率40% (829/2062)
回答No.9

単純にいうと、#6さんのようにして、間を0で埋めると、ドレミファソが、ドレミファソドレミファソ(2回繰り返し)になるだけです。 (間を0ではなくて、内挿して補間した場合は、#6のお礼にあるように、音どうしが重なります。) ドーレーミーファーソーにしたいなら、FFTする前に|ド|レ|ミ|ファ|ソ|と区間で区切って、それぞれの区間ごとに#6さんのようなことをして、くっつけるといった処理が必要です。 さらに、きれいにやるには、区間をどんどん短くしていってやる必要がありますが、そうするとFFTの精度が悪くなってしまいます。あと、区間同士をどうつなげるかも問題ですね。 "phase vocoder"とかで検索するとよいのでは。

jyuzou
質問者

お礼

お礼が大変遅くなり、申し訳ありません。 忙しく、なかなかこれにとりかかれていないのですが、ちょっとやった感じではアドバイスの方法でもうまくいかなそうです。 単に私のやり方がまずいだけかもしれません。 いずれにしてもアドバイスどうもありがとうございました。

  • ion12wat
  • ベストアンサー率33% (9/27)
回答No.7

>複数の音が重なったような音になってしまします。 エイリアシングが発生しているのではないでしょうか? サンプリング周波数はFFT後のオクターブシフト分を 考えて十分に取っていますか?

jyuzou
質問者

お礼

回答どうもありがとうございます。 サンプリング周波数を復元したい周波数の数倍でとっており、エイリアシングに起因するものではないと思います。

  • tatsumi01
  • ベストアンサー率30% (976/3185)
回答No.6

No. 1, 2, 3 ですが補足します。 ある波形を FFT しますと次のようになります。 □○○○○○○△△△△△△■▲▲▲▲▲▲●●●●●● ■を中心として左右に対称(振幅は等しく位相は逆)です。 これの周波数を2倍にしたいなら、高周波分をカットし □○○○○○○■●●●●●● これを IFFT します。すると、周波数は確かに2倍になりますが、持続時間は半分になります。元の波形で言えば録音した波形を2倍の速度で再生したのと同じですね。 持続時間が同じで周波数を倍にしたいなら □_○_○_○_○_○_○■_●_●_●_●_●_● とすれば良いのですが、上で「_」にしたところの成分が抜けています。No. 1 で補間する必要がある、と書いたのはその意味です。 そもそも最初の意図ですが、周波数領域で処理することに疑問があります。No. 1 で書いたように、本来のスペクトルは無限時間で考えています。短時間スペクトルは波形を短時間区間に区切っていますから、信号の時間変化と区間長の相互作用による歪みが出ます。さらに周波数領域で細工して元に戻すと区間の接続部で不連続が出ます。それらをどう細工するかでしょう。

jyuzou
質問者

お礼

度重なる回答本当にどうもありがとうございます。 tatsumi01さんの言わている意図は理解できたつもりです(きちんと補間もしています)。 ただ、アドバイス通り実行すると、再生速度も倍になり(同じ音が2回繰り返される)、しかも複数の音が重なったような音になってしまします。 区間のつなぎ部で不連続になり、歪みがでるとのことですが、現在はまだそのステップまでたどり着いていないため、その問題はまだ発生していません(この問題が解決したら次はその問題を考える必要があるのかもしれませんが)。 現在の工程 5秒分FFT→スペクトルの加工→5秒分IFFT ところで、tatsumi01さんは「経験者」とのことですが、この方法でうまくいっているのでしょうか?

  • ion12wat
  • ベストアンサー率33% (9/27)
回答No.5

こんばんは。 先ほど投稿したものは,図が見づらくなっていたので 再度投稿します。 f→2f後の波形は時間的に半分になってしまうのが”音の速度を変化しない”の際に問題ですね。 どのような入力信号で,どのようなフレーム幅でFFTを しているのかが不明ですが,下図のような出力波形になったとしたら, 方法(1)入力フレームをオーバーラップさせ,入力と出力の時間を合わせる 方法(2)出力波形を単純に時間フレームの半分で切って,同じものを後半にくっ付ける どちらにしても,どうつなぐかがやはり問題になりそうです。 カラオケなどの”キーコントロール”などは参考にならないのでしょうか。 すみません,にわか知識で。。。 入力波形|vvvv|--| FFT |---| IFFT |--|ww |出力波形

jyuzou
質問者

お礼

回答どうもありがとうございます。 「どのような入力信号で,どのようなフレーム幅でFFTをしているのかが不明ですが」 現在のところは暫定で、「音楽信号」を、「5秒間」、FFTしています。 5秒をつなげて10秒にするということは、現時点ではまだ行っていません。 (1フレーム5秒間のみを実験的に試している段階) ご提案頂いた方法につきまして。 「方法(1)入力フレームをオーバーラップさせ,入力と出力の時間を合わせる」 言われている意味が当方の知識不足でいまいち理解はできないのですが、とりあえず現時点では入力フレームが1なので関係ないのではないでしょうか? 「方法(2)出力波形を単純に時間フレームの半分で切って,同じものを後半にくっ付ける」 これも当方の知識不足でいまいち理解はできませんでした。 ただ、スペクトル(周波数領域)ではなく、出力波形(時間領域)レベルで音を加工すれば、音の速度と音程はセットで変化してしまうと思いますので、当方の実現したい音程のみを変化させるということは実現できないように思います。 「カラオケなどの”キーコントロール”などは参考にならないのでしょうか。」 カラオケのキーコントロールやフリーソフト等になる音程変換ソフトはどのようにして実現しているのでしょうね。 フリーソフトの音程変換ソフトを使って音程を変化させた波形をスペクトルにし、元スペクトルと比較させてみたのですが、スペクトルをどのように加工しているかまでは読み取れませんでした。 何か良い書籍とかないでしょうか?

  • ion12wat
  • ベストアンサー率33% (9/27)
回答No.4

こんばんは。 f→2f後の波形は半分になってしまうのが”音の速度を変化しない”の際に問題ですね。 どのような入力信号で,どのようなフレーム幅でFFTを しているのかが不明ですが,下図のような出力波形になったとしたら, 方法(1)入力フレームをオーバーラップさせ,入力と出力の時間を合わせる 方法(2)出力波形を単純に時間フレームの半分で切って,同じものを後半にくっ付ける どちらにしても,どうつなぐかがやはり問題になりそうです。 カラオケなどの”キーコントロール”などは参考にならないのでしょうか。 すみません,にわか知識で。。。 入力波形 出力波形 ------ ------- -------- ------ |vvvv| ---| FFT |-------| IFFT |--- |ww | ------ ------- f→2f ------- ------

  • tatsumi01
  • ベストアンサー率30% (976/3185)
回答No.3

No. 1 で説明不十分な表現がありました。 元データの半分を捨てるところですが、No. 2 で説明したような FFT だとします。 捨てるのは [N/4, N/2-1] と [N/2+1, 3N/4-1] の部分です。N/2 を挟む両側の部分は高周波成分ですから捨てます。 高周波成分を捨ててしまっていいかと言うといいんです。低周波成分の周波数を2倍にした値で埋められますから (これがやりたかったことですね)

  • tatsumi01
  • ベストアンサー率30% (976/3185)
回答No.2

No. 1 への「お礼」ですが、議論している前提が違うかも知れません。 普通の FFT プログラムでは、[0, N-1] のデータを変換すると [0, N-1] に値が入って返ってきます。そのとき、[1, N/2-1] が正の周波数の値で、[N/2+1, N-1] が負の周波数の値です。0 のところが直流分 (音楽信号ならほとんど 0)、N/2 のところがサンプリング周波数の半分ですが直流分に対応する値です。 変換した値は N/2 を中心として上下に対称です。つまり、N/2 から等しい距離は同じ周波数です (N/2 から高くなるほど周波数が「下がり」ます)。対称な二つの点では、振幅は等しく位相は 180°逆です。複素数で考えると共役複素数になります。 FFT の結果を処理するときは以上に気をつけて下さい。ただし、プログラムによっては [-N/2, N/2] の配列にフーリエ変換を返すものがあるかも知れません。 位相ですが、FFT → 位相変化 → IFFT を行う際、上記の対称性に注意して下さい。たとえば F(1) と F(N-1) は周波数が等しく、振幅は同じで位相が 180°違います。位相を変えるときはその性質を保ったまま変更する必要があります。周波数の対応関係と共役複素数の性質がなりたつように変化させることに注意すれば、持続音では同じように聞こえる筈です。 昔から all pass network といって、各周波数の振幅は変えず位相だけ変えるフィルタがありますが、それによって持続音は変化しない、というのが定説です (太鼓の音のようなスパイク性の音は別です)。

  • tatsumi01
  • ベストアンサー率30% (976/3185)
回答No.1

原理の話で、実行するといろいろ問題があります。 FFT したデータは N/2 のところが0周波数です。ここを中心にして F のところのデータを 2F に移動すればできます。ただし、奇数番目 (2F+1) には元データがありませんから補間して埋める必要があります。また、元データの半分以上は2倍するとはみ出してしまうので捨てる必要があります。 位相の問題は重要ですが、定常的な部分では無視しても構わないでしょう。 ただし、これでは「音程だけ変化させて、音の速度は変化しない」という目的は実現できません。 スペクトルというのは元々は無限時間を仮定していますから、音楽のように時々刻々変化する音の解析には向いていません。実際には、ある時間長のデータを切り出して FFT を求めています(短時間スペクトル)。 音楽でも音声でも同じですが、一定時間ごとに切り出したデータをどうつなぐかが問題になります。つなぎ目の不連続のために多分うまくいきません。

jyuzou
質問者

お礼

回答がつきづらいと思われる質問に回答頂きまして大変感謝しています。 回答頂いた内容で 「FFT したデータはN/2 のところが0周波数です。」 と書かれていますが、n=N/2のあたりは高周波帯のスペクトル(サンプリング100kHzなら50kHz近辺)であると思うのですが、違うのでしょうか? 「ここを中心にして F のところのデータを 2F に移動すればできます。 元データの半分以上は2倍するとはみ出してしまうので捨てる必要があります。」 n=N/2から遠い部分を捨てるということは低周波帯域を捨てるということになり、音声の1kHz付近も捨てることにはならないでしょうか? 「位相の問題は重要ですが、定常的な部分では無視しても構わないでしょう。」 位相処理も含めてを考えないと、音がぐちゃぐちゃになってしまうような気がするのですが、当方認識が間違っているのでしょうか? 例えば単にFFT→IFFTをすれば音は復元されますが、FFTとIFFFTの間に位相(のみ)を変化させる処理を入れれば、音は復元されなくなります。

関連するQ&A

専門家に質問してみよう