none
xWMA形式ファイルの演奏時間計算

    質問

  • お世話になります。

    XAudio2を使用し、xWMA形式ファイルの再生プログラムを作成しています。
    下記サイト(※1)のWave形式の時と同じようにxWMAファイルの演奏時間を取得したいのですが、
    現状同じように、WAVEFORMATEX構造体のnAvgBytesPerSecと音楽データサイズを用いて
    算出した演奏時間がWave形式の時と異なっています。

    ※2、※3はこちらで用意した音楽ファイルのWAVEFORMATEX構造体の値と
    データサイズ(datachunk.cksize)になります。

    xWMAファイルは下記のxWMAEncode(※4)を用いてWaveを変換したものです。

    xWMA形式での演奏時間算出方法をご存知の方、または、
    参考サイトがありましたらご教示頂きたいです。

    よろしくお願いします。

    ■Wave形式演奏時間取得(※1)
    https://msdn.microsoft.com/ja-jp/library/cc352338.aspx?f=255&MSPPError=-2147217396


    ■Wave形式(※2)
    wFormatTag = 65534
    nChannels = 2
    nSamplesPerSec = 48000
    nAvgBytesPerSec = 288000
    nBlockAlign = 6
    wBitsPerSample = 24
    cbSize = 22

    datachunk.cksize = 12736326

    ■xWMA形式(※3)
    wFormatTag = 65534
    nChannels = 2
    nSamplesPerSec = 48000
    nAvgBytesPerSec = 6000
    nBlockAlign = 1008
    wBitsPerSample = 16
    cbSize = 22

    datachunk.cksize = 348768

    ■xWMA コマンド ライン エンコーダー (xWMAEncode)(※4)
    https://msdn.microsoft.com/ja-jp/library/cc308027(v=vs.85).aspx

    ■開発環境
    Visual Studio 2017 pro
    DirectX(June 2010)
    WindowsSDK 10.0.16299.0

    XAudio2 v2.7
    2018年2月20日 11:06

回答

  • 自己解決しました。

    xWMAを読み込む際にdpdsチャンクから読み込んだ、XAUDIO2_BUFFER_WMAのnPacketCount、
    aDecodedPacketCumulativeBytes、WAVEFORMATEXのnChannels、nSamplesPerSecなどで求められるようです。

    前述のWaveファイル、xWMAファイルで試したところ、
    Waveファイル44.22秒、xWMAファイル44.24秒になりました。

    演奏時間に若干の差が出るのは、xWMAファイルが変換の際に、末尾に無音期間が
    挿入されるためだと思われます(※1)

    下記は実装部分になります。

    ■ソース抜粋
    XAUDIO2_BUFFER_WMA xbw = { 0 };
    mmckinfo.ckid = mmioFOURCC('d', 'p', 'd', 's');
    mmioDescend(hmmio, &mmckinfo, &riffchunk, MMIO_FINDCHUNK);

    xbw.nPacketCount = mmckinfo.cksize / sizeof(UINT32);
    xbw.aDecodedPacketCumulativeBytes = new UINT32[xbw.nPacketCount];

    float v = 0.0f;//演奏時間
    if(xbw.aDecodedPacketCumulativeBytes != NULL && xbw.nPacketCount > 0){
    int t = int(xbw.nPacketCount - 1);
    UINT32 v2 = xbw.aDecodedPacketCumulativeBytes[t] / UINT32(2 * pwfx.Format.nChannels);
    v = (float)v2 / (float)pwfx.Format.nSamplesPerSec;
    }

    ■xWMA概要(※1)
    https://msdn.microsoft.com/ja-jp/library/ee415832%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
    • 回答としてマーク gama55 2018年2月21日 9:34
    2018年2月21日 9:34

すべての返信

  • gama55 さん、こんにちは。フォーラム オペレーターの立花です。
    MSDN フォーラムへのご投稿ありがとうございます。

    使用されている言語は VC++ でよろしいでしょうか。
    Windows クライアント開発 フォーラムより、 VC++ フォーラムの方が
    情報が集まりやすいと思いますので移動をさせていただきますね。

    Visual Studio Development > Visual C++

    もし言語が違いましたらご返信お願いいたします。

    XAudio2でのxWMA形式コールバック再生時のXAUDIO2_BUFFER_WMAの設定値
    こちらのご投稿も同様にさせていただきます。

    フォーラム利用時の注意点のお知らせです。

    ご利用の際は、下記内容をお守りいただきますと
    情報が寄せられやすくなりますので、ぜひご一読ください。
    フォーラムでご質問頂くにあたっての注意点
    フォーラムのご利用方法(質問の投稿)について
    フォーラムへの回答に関するガイドラインおよびフォーラム運営について(再掲)
    ご意見、ご要望はこちらのフォーラムまで。
    各種設定方法はフォーラム内を [かんたん フォーラム ガイド] で検索してみてください。


    参考になった投稿には回答としてマークの設定にご協力ください
    MSDN/TechNet Community Support 立花楓

    2018年2月21日 0:14
    モデレータ
  • 自己解決しました。

    xWMAを読み込む際にdpdsチャンクから読み込んだ、XAUDIO2_BUFFER_WMAのnPacketCount、
    aDecodedPacketCumulativeBytes、WAVEFORMATEXのnChannels、nSamplesPerSecなどで求められるようです。

    前述のWaveファイル、xWMAファイルで試したところ、
    Waveファイル44.22秒、xWMAファイル44.24秒になりました。

    演奏時間に若干の差が出るのは、xWMAファイルが変換の際に、末尾に無音期間が
    挿入されるためだと思われます(※1)

    下記は実装部分になります。

    ■ソース抜粋
    XAUDIO2_BUFFER_WMA xbw = { 0 };
    mmckinfo.ckid = mmioFOURCC('d', 'p', 'd', 's');
    mmioDescend(hmmio, &mmckinfo, &riffchunk, MMIO_FINDCHUNK);

    xbw.nPacketCount = mmckinfo.cksize / sizeof(UINT32);
    xbw.aDecodedPacketCumulativeBytes = new UINT32[xbw.nPacketCount];

    float v = 0.0f;//演奏時間
    if(xbw.aDecodedPacketCumulativeBytes != NULL && xbw.nPacketCount > 0){
    int t = int(xbw.nPacketCount - 1);
    UINT32 v2 = xbw.aDecodedPacketCumulativeBytes[t] / UINT32(2 * pwfx.Format.nChannels);
    v = (float)v2 / (float)pwfx.Format.nSamplesPerSec;
    }

    ■xWMA概要(※1)
    https://msdn.microsoft.com/ja-jp/library/ee415832%28v=vs.85%29.aspx?f=255&MSPPError=-2147217396
    • 回答としてマーク gama55 2018年2月21日 9:34
    2018年2月21日 9:34