- ベストアンサー
オーディオデータの22050hzから44100hzへの変換
教えてください 手始めに簡単なオーディオデータのサンプルレートコンバータを作成しています 16bit整数モノラル22050hzから16bit整数モノラル44100hzです。 処理は現在のフレームと次のフレームの合計を2で割って 出た値を現在のフレームと次のフレームの間に挿入しています 大体以下のようにしています short int currentFrame; short int nextFrame; short int insertFrame; long long int average; short int chunk[2]; //オーディオファイルからの読込みは省略しています average = ( currentFrame + nextFrame ) / 2; insertFrame = (short int)average; chunk[0] = currentFrame; chunk[1] = insertFrame; //後処理も省略しています 挿入するデータの計算は平均値であっているでしょうか?
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
基本方針というか正当派の手法としては ANo.2 のやり方でいいと思いますが、 「サンプル変換」と「フィルタ処理」を個別にやるのは無駄が多いので、 両方を同時にやってしまう「lanczos」ってアルゴリズムがあります。 lanczos は画像の解像度変換で有名ですが、「サンプリング変換」という点では画像も音声も処理は同じです。音声での利用については http://blog.jyoken.net/?eid=773796 が参考になるかもしれません。 lanczosの実際の処理方法自体は、ANo.1 で挙げられている3次スプラインとはパラメータが違うだけでほとんど同じなのですが、 そのパラメータの意味に理論的裏付けがある分高品質です。 たとえば、2次のlanczosだと、 lanczos2(-1.5)=lanczos2(1.5)=-0.063684352 lanczos2(-0.5)=lanczos2(0.5)= 0.573159168 になるので、前後4サンプルから average=( -0.063684352 * previousFrame + 0.573159168 * currentFrame + 0.573159168 * nextFrame + -0.063684352 * nextnextFrame) / 1.018949632 という式で補間結果が求まります。
その他の回答 (2)
- Tacosan
- ベストアンサー率23% (3656/15482)
どう計算しても (それではうまくいかないデータが存在しうるという意味で) 本質的には間違いなんだけど, ようは「アップサンプラ」だから数学的には「とりあえず 0 で補間してから適切な低域通過フィルタをかける」という処理でしょう.
- chie65536
- ベストアンサー率41% (2512/6032)
>挿入するデータの計算は平均値であっているでしょうか? 厳密に言うと合ってない。 44100Hzの正弦波を、1つ飛ばしに間引いて、22050Hzの正弦波にして、それを「平均値で補間」して44100Hzに戻すと、近い波形にはなるが、元の正弦波には戻らない。 より近い波形を得るには、3次スプライン変換などを用い、近似を取るなどの工夫が必要。 とはいえ「普通に聞く」だけなら、平均値でも、音に差は出ない。 >long long int average; ここは long int average; で十分。32ビット保証すれば「16ビット同士の加算の答え」は保持出来る。 >average = ( currentFrame + nextFrame ) / 2; この式の「currentFrame + nextFrame」の部分はintで計算される。 intが32ビットの処理系では問題無いが、intが16ビットの処理系では「加算した瞬間にオーバーフローする」ので注意。 公的には、intの保証値は-32768~32767であり、short int同士の加算の答えを保持出来る保証は無い。 ここは average = ( (long int)currentFrame + (long int)nextFrame ) / 2L; とし、すべての項目をlong int、つまり、32ビットに「拡張してから計算」しなければならない。 繰り返すが「拡張してから計算」するのが肝心で、「計算してから拡張」では手遅れになる。