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

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

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

Octaveは、数値解析のための高レベルのプログラミング言語です。主に理工系の技術者・研究者が使用しており、フリーで使うことが可能。線形もしくは非線形問題を数値的に解くCLIを提供します。

MATLAB

MATLABはMathWorksで開発された数値計算や数値の視覚化のための高水準の対話型プログラミング環境です。

Q&A

解決済

2回答

1510閲覧

波形をフーリエ変換し、加算合成し同じ波形を作りたいです。

sobasei

総合スコア10

Octave

Octaveは、数値解析のための高レベルのプログラミング言語です。主に理工系の技術者・研究者が使用しており、フリーで使うことが可能。線形もしくは非線形問題を数値的に解くCLIを提供します。

MATLAB

MATLABはMathWorksで開発された数値計算や数値の視覚化のための高水準の対話型プログラミング環境です。

0グッド

0クリップ

投稿2019/02/19 16:48

前提・実現したいこと

gnu octaveで一周期の波形(16bit/44.1khz/wav)をフーリエ解析し、解析した値をもとに加算合成し、waveファイルとして書き出したのですが、元の波形と微妙に違う結果となってしまいます。何か間違っていますか?
上が元の波形、下が再合成した波形

発生している問題・エラーメッセージ

該当のソースコード

GNU OCTAVE ver.4.4
ソースコード
clear all;

FS = 44100;
y =audioread('00.wav');
sml = length(y); #sample length
z =fft(y);

sinefft = -1 *(imag(z)/(sml/2)); #sine波 
cosinefft = real(z)/(sml/2); #cosine波

data_s = sinefft(2:129); #サイン波の第1倍音から第128倍音まで
data_c = cosinefft(2:129); #コサイン波の第1倍音から第128倍音まで

partial = sml / 2;

for k = 1: partial
AS(:,k) = sin(linspace(0, 2kpi, sml)) .* data_s(k);
AC(:,k) = cos(linspace(0, 2kpi, sml)) .* data_c(k);
end

Additive = sum(AS,2) + sum(AC,2) + (cosinefft(1)/2); #サイン波の合計とコサイン波の合計とDCOffset

audiowrite('resynth.wav', Additive, FS);

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

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

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

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

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

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

y_waiwai

2019/02/19 23:46

FFTして逆FFTしても全く同じ波形が出るわけもないですが、微妙に違うとは具体的にどう違うんでしょうか
sobasei

2019/02/20 01:58

すいません、自己解決しました。生成するサンプルの長さの倍数を変えて比較してみたら、サンプルが長いほど元の波形に近づいていきました。
guest

回答2

0

画像の上が元で下が出力でしょうか。
右端で1サンプル分ズレているのを見るに、n-1であるべきところnにしているたぐいの間違いかと思います。
出力サンプル数を増やすと改善するのはズレが相対的に小さくなるためでしょう。

投稿2019/02/20 04:48

ikadzuchi

総合スコア3047

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

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

sobasei

2019/02/20 08:48

上が元で、下が出力です。 ありがとうございます。ご指摘の通りでした。一周期のサイン波の長さを間違っていました。欲しいサンプルの長さプラス1して出力すれば解決しました。例えば、一周期256サンプルの長さのサイン波を出力したいときは、257サンプルに設定し、出力するときに256サンプルで出力するという感じです。
guest

0

自己解決

サンプルの長さプラス1する

for k = 1: partial
AS(:,k) = sin(linspace(0, 2kpi, sml +1)) .* data_s(k);
AC(:,k) = cos(linspace(0, 2kpi, sml +1)) .* data_c(k);
end

Additive = sum(AS,2) + sum(AC,2) + (cosinefft(1)/2);
Add2 = Additive(1:sml)

audiowrite('resynth.wav', Add2, FS);

投稿2019/02/20 02:05

編集2019/02/20 08:37
sobasei

総合スコア10

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問