Nevcairiel / LAVFilters

LAV Filters - Open-Source DirectShow Media Splitter and Decoders
GNU General Public License v2.0
7.34k stars 789 forks source link

Multichannel WAV not supported #483

Closed tebasuna51 closed 2 years ago

tebasuna51 commented 2 years ago

From past century the multichannel WAV's must use the header WAVE_FORMAT_EXTENSIBLE (wformat = 0xfffe) to include the MaskChannel info.

The LAV audio filter 0.76.1 included in mpc-hc seems ignore that info and play wav files 2/2 (FL FR SL SR) like 3/0.1 (FL FR FC LFE) for instance.

More info https://forum.doom9.org/showthread.php?p=1966828#post1966828

tebasuna51 commented 2 years ago

Like DirectShow Filters I have a old version (0.74.1.0, 19/Mar/2019) of LAV-Filters and have the same problem.

Can you say me where are the source code than read the wav header to suggest a change? I can't locate it.

I think the default channelmask is assigned in media.cpp. See some comment about this: https://forum.doom9.org/showthread.php?p=1967075#post1967075

tebasuna51 commented 2 years ago

In LAVFilters-0.76.1\demuxer\Demuxers\LAVFStreamInfo.cpp there are:

        else if ((mtype.subtype == MEDIASUBTYPE_PCM || mtype.subtype == MEDIASUBTYPE_IEEE_FLOAT) &&
                 avstream->codecpar->codec_tag != WAVE_FORMAT_EXTENSIBLE)
        {
            // Create raw PCM media type
            mtype.pbFormat = (BYTE *)g_AudioHelper.CreateWFMTEX_RAW_PCM(avstream, &mtype.cbFormat, mtype.subtype,
                                                                        &mtype.lSampleSize);
        }

I suggest:

        else if ((mtype.subtype == MEDIASUBTYPE_PCM || mtype.subtype == MEDIASUBTYPE_IEEE_FLOAT))
        {
            // Create raw PCM media type
            mtype.pbFormat = (BYTE *)g_AudioHelper.CreateWFMTEX_RAW_PCM(avstream, &mtype.cbFormat, mtype.subtype,
                                                                        &mtype.lSampleSize);
        }

For what exclude PCM INT/FLOAT WAVE_FORMAT_EXTENSIBLE header by managed by CreateWFMTEX_RAW_PCM? Only in this subrutine (LAVFilters-0.76.1\demuxer\Demuxers\LAVAudioHelper.cpp) is read the dwChannelMask:

dwChannelMask = (DWORD)avstream->codecpar->channel_layout;

Without dwChannelMask defined the default is assigned in LAVFilters-0.76.1\decoder\LAVAudio\Media.cpp:

static const scmap_t m_scmap_default[] = {
  //    FL  FR  FC  LFe BL  BR  FLC FRC
  {1, 0},               // Mono                 M1, 0
  {2, 0},               // Stereo               FL, FR
  {3, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER},                                                                                                // 3/0      FL, FR, FC
  {4, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY},                                                                          // 3/1      FL, FR, FC, Surround
  {5, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT},                                                           // 3/2      FL, FR, FC, BL, BR
  {6, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_SIDE_LEFT|SPEAKER_SIDE_RIGHT},                                     // 3/2+LFe  FL, FR, FC, BL, BR, LFe
  {7, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT|SPEAKER_BACK_CENTER},                 // 3/4      FL, FR, FC, BL, Bls, Brs, BR
  {8, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_SIDE_LEFT|SPEAKER_SIDE_RIGHT|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT},// 3/4+LFe  FL, FR, FC, BL, Bls, Brs, BR, LFe
};

Where I suggest replace the defaults:

  {4, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_SIDE_LEFT|SPEAKER_SIDE_RIGHT},                                                                                // 2/2      FL, FR, SL, SR
  {5, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_SIDE_LEFT|SPEAKER_SIDE_RIGHT},                                                           // 3/2      FL, FR, FC, SL, SR
  {6, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_SIDE_LEFT|SPEAKER_SIDE_RIGHT},                                     // 3/2+LFe  FL, FR, FC, LFE, SL, SR
  {7, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_SIDE_LEFT|SPEAKER_SIDE_RIGHT|SPEAKER_BACK_CENTER},                 // 3/3+LFe  FL, FR, FC, LFE, BC, SL, SR
  {8, SPEAKER_FRONT_LEFT|SPEAKER_FRONT_RIGHT|SPEAKER_FRONT_CENTER|SPEAKER_LOW_FREQUENCY|SPEAKER_SIDE_LEFT|SPEAKER_SIDE_RIGHT|SPEAKER_BACK_LEFT|SPEAKER_BACK_RIGHT},// 3/4+LFe  FL, FR, FC, LFE, BL, BR, SL, SR
ale5000-git commented 2 years ago

It seems it now use the channel mask from WAVEFORMATEXTENSIBLE: https://github.com/Nevcairiel/LAVFilters/commit/8e18dcb3275b296090222717c0b0725cb15b97bc