Scope サンプルは、オーディオを入力し、波形をウィンドウに表示するレンダラーフィルタである。Platform SDKにサンプルプログラムとして付属している。正式なフィルタ名は Oscilloscope である。フィルタのインスタンスを作成すると以下のようなウィンドウが表示される。
ところで、このフィルタは8bit/16bitのmono/stereoの無圧縮PCM形式に対応しているが、それより高解像度のデータには対応していない。ここでは 24bit PCMを受け付けるように改造する方法を紹介しする。オーディオフォーマットを表す構造体はWAVEFORMATEX
ではなくWAVEFORMATEXTENSIBLE
とする。
CheckMediaType
scope.cppのCScopeInputPin::CheckMediaType
で、入力メディアタイプを検査している。WAVEFORMATEXTENSIBLE
構造体の場合は、無圧縮PCMであってもWAVEFORMATEX::wFormatTag
がWAVE_FORMAT_PCM(==0x1)
ではなくWAVE_FORMAT_EXTENSIBLE(==0xFFFE)
となる。そこでwFormatTag
の検査コードを以下のように変更する。
1 2 3 4 5 | //変更
pwfx->Format.wFormatTag != WAVE_FORMAT_PCM)
{
return E_INVALIDARG;
}
|
SetMediaType
CScopeInputPin::SetMediaType
をWAVEFORMATEXTENSIBLE
にあうように書き換える。
1 2 3 4 5 6 7 8 9 10 11 12 13 | class
HRESULT hr = CBaseInputPin::SetMediaType(pmt);
if(SUCCEEDED(hr))
{
//以下、変更
WAVEFORMATEXTENSIBLE *pwfx=
(WAVEFORMATEXTENSIBLE *)pmt->Format();
m_pFilter->m_Window.m_nChannels = pwfx->Format.nChannels;
m_pFilter->m_Window.m_nSamplesPerSec = pwfx->Format.nSamplesPerSec;
m_pFilter->m_Window.m_nBitsPerSample = pwfx->Format.wBitsPerSample;
m_pFilter->m_Window.m_nBlockAlign = pwfx->Format.nBlockAlign;
m_pFilter->m_Window.m_MaxValue = 128;
m_pFilter->m_Window.m_nIndex = 0;
|
SetHorizScrollRange
CScopeWindow::SetHorizScrollRange
は、フィルタ独自のメソッドである。switch
文がありますが、ここに34
(※)のcaseを追加する。ここで設定した文字列がウィンドウにフォーマット情報として表示される。24bit PCMの場合、nBitPerSampleは32となるので、あえて「S-32」としている。
1 2 3 4 5 6 7 8 | 18:
16-bit
(0"));
break;
34:
32-bit
(0"));
break;
|
※ ここのswitch文はチャンネル数とサンプルあたりのビット数を加算した値で分岐している。フォーマットが 32bit 2ch の場合、 32 + 2 = 34 となる。
CopyWaveform
サンプルあたりのビット数によって値の範囲が違うわけですが、それを0-255に正規化しているのがCScopeWindow::CopyWaveform
メソッドである。正規化することにより、ウィンドウ内に波形がきっちりおさまって表示される。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | switch(m_nBitsPerSample + m_nChannels)
{
BYTE * pb;
WORD * pw;
DWORD *pdw;
// (中略)
// 追加
34:
{ 32-bit
pdw = (DWORD *)pWave;
while(nSamplesPerChan--)
{
m_pPoints1[m_nIndex].y = (24);
m_pPoints2[m_nIndex].y = (24);
if(++m_nIndex == m_nSamplesPerSec)
m_nIndex = 0;
}
break;
}
|
高解像度なWAVファイルを組み合わせて遊んでみる。
ここではWAVEFORMATEXTENSIBLE
でサポートしているマルチチャンネルには対応していない。それには、さらに追加のコーディングが必要となる。
24bit なのに 32bit?
24bitでもWAVEFORMATEXTENSIBLE::Format::wBitsPerSample
は32になることがある。つまりL/Rチャンネルを持つ場合、1つのオーディオフレームは8バイトになる。
では、24bitなのか32bitなのか判定するにはどうしたらいいのかというと、WAVEFORMATEXTENSIBLE::Samples::wValidBitsPerSample
で確認できる。
Comments
comments powered by Disqus