yamamoto2002
yamamoto2002
オーディオ関連のフリーソフトウェアを作っています。 Amazon.co.jpのyamamoto2002さんは別人です。 楽天オークションのyamamoto2002さんも別人です。 Twitt…

マイルーム

yamamoto2002のページ
yamamoto2002のページ
yamamoto2002のページです。
所有製品

レビュー/コメント

カレンダー

          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

最新のレス

日記
製品レビュー/コメント

製品レビュー/コメントへのレスはありません

お気に入り製品

お気に入り製品はありません

日記

PlayPcmWin DoP再生シーク時のつなぎ処理

このエントリーをはてなブックマークに追加
2017年09月03日

DoP再生中に再生位置スライダーをつまんで動かすとブチブチ音が鳴る問題を修正した。

シーク時に、シーク前位置の音声とシーク後位置の音声を一旦PCMに変換し、クロスフェードし、1ビットSDMに戻したものを再生してシーク前後の2つの音を滑らかにつなげる(図1)。

SDM to PCM変換処理を作るにあたって歪み率0.1%、可聴域のF特が0~20kHzで大体+0,-3dB位という大まかな目標を掲げて作ったが達成していないと思う。(詳しく調べていないwwww)

低CPU負荷の高速処理を意識して設計したつもりである(処理に長い時間がかかると音飛びが発生するので)。しかし通常再生よりは重い。再生シークすると一時的にPlayPcmWinのCPU使用率が上昇する。

PlayPcmWin画面右の出力レイテンシー設定を大体100ms以上の値にするとクロスフェードが良い感じに動作する。

図1 シーク前の音声とシーク後の音声をクロスフェードする。(図をクリックすると拡大) 図1右のフローチャートはCaduceusを連想する形状だなと思ったが、画像を検索し形状を改めて見比べるとあまり似ていない。

図2 Sinc4 16分の1ダウンサンプル。2.8MHz 1ビットSDM信号を入力すると、16分の1にダウンサンプルされ出力から176.4kHz 16ビットPCM信号が出てくる。(16ビットというのは出力から-32768 ≤ v < +32767の範囲の整数値が出てくるという意味。) z^-1と書かれた四角いものはディレイメモリであり入力データ値を1サンプル蓄積し、次のデータが入力に入って来たとき1サンプル過去に入力された値を出力に出す。

図3 ハーフバンド FIRフィルターダウンサンプラー。係数の数23個のFIRローパスフィルター処理が乗算7回と加算7回で出来るので効率が良い。このフィルターで176.4kHz PCMを88.2kHz PCMに変換する。z^-5は5サンプル遅延するディレイメモリ。左にあるスイッチみたいなものは1サンプル入力するごとに上下に回路を切り替える。

図4 ハーフバンドFIRフィルターダウンサンプラーの係数の数47個。このフィルターで88.2kHz PCMを44.1kHz PCMに変換する。係数47個バージョンのハーフバンドフィルターの構造は係数23個バージョンの上段のディレイ+加算+係数をかける処理を追加し、下段のディレイ量を2倍にした物。

図5 ハーフバンドFIRフィルターアップサンプラー。係数47個のもので44.1kHz PCMを88.2kHz PCMに変換し、係数23個のもので88.2kHz PCMを176.4kHz PCMに変換する。

図6 ハーフバンドFIRフィルターアップサンプラーの係数47個。Sinc関数の値を90度ごとに計算したものにKaiser窓(α=9)を掛けたもの。

図7 Sinc4 CIC 16倍アップサンプラーの構造。単純で効率的。176.4kHz PCMを2.8MHz PCMに変換する。

図8 CRFBループフィルター。2.8MHz 32bit PCMを 2.8MHz 1bit SDMに変換する。右端の量子化器Qは浮動小数点数値を入力し1ビットの整数値に変換し出力する。具体的には入力値が0以上の時1を出力し0未満の時0を出力する。

図9 作った2.8MHz to 44.1kHz PCM ローパスフィルターの性能 (シミュレーション)。イメージ雑音は0.1%(-60dB)以下になっている。 図1のクロスフェード処理の雑音は、これに加えてPCM to SDM変換の雑音とCRFBループフィルターの雑音が乗るので図9よりも悪くなる。

このプログラムを応用すると、たとえば11.3MHz 1bit SDMが再生できないDACのために11.3MHz 1bit SDMを176.4kHz PCMに(現実的な待ち時間で)変換して再生するといった事が出来ると思う。そのときは以下のような設定項目を設定画面に作ることになるだろう。

┌ SDM to PCM変換 ───────────┐
│□2.8MHz 1bit SDMを44.1kHz PCMに変換
│☑5.6MHz 1bit SDMを88.2kHz PCMに変換
│☑11.3MHz 1bit SDMを176.4kHz PCMに変換
└───────────────────┘

■2017年9月9日追記

PlayPcmWinにSDMのPCM変換再生を導入することについて検討した。

上図SDM to PCM変換設定画面は混乱をもたらすと思う。PlayPcmWinのWASAPI排他モード再生はこれまでリサンプルを行わないという方針でやってきた。この機能の導入によってリサンプルが発生する場合が一部発生する事に心理的抵抗がある。“PlayPcmWinの排他モード再生はファイルに記録されている音声データを無加工でWASAPI排他モードに渡す。従って再生に使用するハードウェアが対応していない形式の音声データは再生ができない。”という排他モード選択時動作の潔さ(?)は維持して機能を足していきたいと思う。

これを踏まえて考えるとPlayPcmWinにPCM変換再生を導入するとしたら

・WASAPI排他モード選択時は変換再生は一切行わない。
・WASAPI共有モード選択時はSDMは必ずPCMに変換して再生する。

という感じで導入するするのが良いと思った。

Sinc4 CIC16分の1ダウンサンプラーを少し最適化した(10%改善)。

最適化の内容は以下。些細なものに見えるが、繰り返し回数が最も多い部分なので効果があった。この改善はPlayPcmWin 5.0.46に入る予定。

  int32_t v = 0;
 
  for (int bit = 0; bit < 16; ++bit) {
    v = 1 & (inSdm >> (15 - bit));
    ...

  for (int bit = 15; 0 <= bit; --bit) {
    v = 1 & (inSdm >> bit);
    ...

■2017年9月11日追記

PlayPcmWin 5.0.46でWASAPI共有モード再生時はDSDをPCMに変換して再生するようにした。

■2017年9月18日追記

ループフィルターが出力するSDM 1ビットデータをメモリに格納するとき、DoPは1バイト内のビットの並びをビッグエンディアンビットオーダーで並べる必要があるが間違ってリトルエンディアンビットオーダーで並べたためにブルーノイズ様の雑音が出る問題をバージョン5.0.47で修正。

■作ったプログラムの配布

PlayPcmWinのページ: https://sourceforge.net/p/playpcmwin/wiki/PlayPcmWinJp/

ソースコード置き場: https://sourceforge.net/p/playpcmwin/code/HEAD/tree/PlayPcmWin/WWDspCpp/

■関連記事

DoP再生シーク時の直線補間処理。この処理は、その後バグが入って正常に動作しなくなっていた。
http://community.phileweb.com/mypage/entry/2721/20130126/35106/

PCM再生シークのクロスフェード処理
http://community.phileweb.com/mypage/entry/2721/20120617/31372/

CRFBループフィルター
http://community.phileweb.com/mypage/entry/2721/20170528/55889/

ハーフバンドフィルター
http://community.phileweb.com/mypage/entry/2721/20140615/42959/

CICフィルター
http://community.phileweb.com/mypage/entry/2721/20140608/42858/

次回の日記→

←前回の日記

レスを書く

レスを書くにはログインする必要があります
ログインする