Log in

View Full Version : Can Avisynth output WAVE_FORMAT_EXTENSIBLE?


Pages : [1] 2

zambelli
24th April 2007, 04:50
Is there any way to make Avisynth return audio in WAVE_FORMAT_EXTENSIBLE format for multichannel audio?

When I construct a 6ch audio stream within Avisynth by loading individual mono WAVs and merging them with MergeChannels(), Avisynth returns this:

Audio: PCM 48000Hz 6ch 4608Kbps

AM_MEDIA_TYPE:
majortype: MEDIATYPE_Audio {73647561-0000-0010-8000-00AA00389B71}
subtype: MEDIASUBTYPE_PCM {00000001-0000-0010-8000-00AA00389B71}
formattype: FORMAT_WaveFormatEx {05589F81-C356-11CE-BF01-00AA0055595A}
bFixedSizeSamples: 1
bTemporalCompression: 0
lSampleSize: 12
cbFormat: 18

WAVEFORMATEX:
wFormatTag: 0x0001
nChannels: 6
nSamplesPerSec: 48000
nAvgBytesPerSec: 576000
nBlockAlign: 12
wBitsPerSample: 16
cbSize: 0 (extra bytes)


If I take the Mono to Multichannel Wave Combiner (http://download.microsoft.com/download/f/9/3/f93c49aa-1644-4a82-b6ee-6624c55e3010/wavavimux_setup.exe) tool and make an AVI out of it, it returns this:

Audio: WAVE_FORMAT_EXTENSIBLE 48000Hz 6ch 4608Kbps

AM_MEDIA_TYPE:
majortype: MEDIATYPE_Audio {73647561-0000-0010-8000-00AA00389B71}
subtype: MEDIASUBTYPE_PCM {00000001-0000-0010-8000-00AA00389B71}
formattype: FORMAT_WaveFormatEx {05589F81-C356-11CE-BF01-00AA0055595A}
bFixedSizeSamples: 1
bTemporalCompression: 0
lSampleSize: 12
cbFormat: 40

WAVEFORMATEX:
wFormatTag: 0xfffe
nChannels: 6
nSamplesPerSec: 48000
nAvgBytesPerSec: 576000
nBlockAlign: 12
wBitsPerSample: 16
cbSize: 22 (extra bytes)

WAVEFORMATEXTENSIBLE:
wValidBitsPerSample: 16
dwChannelMask: 0x0000003f
SubFormat: {00000001-0000-0010-8000-00AA00389B71

The difference between the two is that the former requires an audio decoder such as Ffdshow to interpret the audio, whereas the latter just plays without any additional decoders needed.

Is there a way to make Avisynth output the same format as the latter?

Pookie
24th April 2007, 06:11
No go with Soundout ?

I wish I had a large enough file to pre-test it, but perhaps WavNotEx.exe can
patch the output file so it can be played...

http://forum.doom9.org/showthread.php?p=886080#post886080

zambelli
24th April 2007, 06:38
No go with Soundout ?
I looked at Soundout before posting and I didn't think it'd be applicable, but perhaps I misunderstood it. SoundOut saves output to files only, no? I'm looking for a way to make Avisynth scripts return WAVE_FORMAT_EXTENSIBLE audio when rendered.

I wish I had a large enough file to pre-test it, but perhaps WavNotEx.exe can
patch the output file so it can be played...
The problem is not the audio format being read into Avisynth, but the audio format being output out of Avisynth when rendering the .avs in DirectShow.

Pookie
24th April 2007, 08:42
Gotcha. Sorry about that.

Ebobtron
24th April 2007, 13:35
Hello,
I believe the simple answer to your question is no. Note that I said believe, some future version of AviSynth may well support this. The difference between the two formats can be just the structure of the header files and I think the debate about this would center on what is an AVI file and what should the header provided by AviSynth look like.The data is or I should say could be the same, the issue is how to describe it.The difference between the two is that the former requires an audio decoder such as Ffdshow to interpret the audio, whereas the latter just plays without any additional decoders needed.Is it not true that even the simplest of wave files would use ffdshow on your system as it is configured?
I have to guess because.Direct show makes everything an installation specific issue. :( I hope the path is brighter. :) Rob

sh0dan
25th April 2007, 09:44
By adding global OPT_UseWaveExtensible = true to your script, AviSynth 2.5.7 should output WAVE_FORMAT_EXTENSIBLE. Not sure how much it is tested, though.

IanB
25th April 2007, 10:59
@sh0dan, snap.

If you add this line to the top of your scriptglobal OPT_UseWaveExtensible=True
...Avisynth will almost do as you want. I added the feature in 2.5.7 but left it undocumented because I couldn't make it work and didn't have the time to fix it. Looking at the code now I can see what has been wrong.

From src\core\main.cpp@1216 if (!lpFormat) {
*lpcbFormat = fAudio ? sizeof(WAVEFORMATEX) : sizeof(BITMAPINFOHEADER);
return S_OK;
}I need to be returning sizeof(WAVEFORMATEXTENSIBLE). I can put up a patched version for you to test and report on if you like.

The code that fill the structure is here. Please let me know if any of the values is going to be incorrect. From src\core\main.cpp@1240wfxt.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
wfxt.Format.nChannels = vi->AudioChannels();
wfxt.Format.nSamplesPerSec = vi->SamplesPerSecond();
wfxt.Format.wBitsPerSample = vi->BytesPerChannelSample() * 8;
wfxt.Format.nBlockAlign = vi->BytesPerAudioSample();
wfxt.Format.nAvgBytesPerSec = wfxt.Format.nSamplesPerSec * wfxt.Format.nBlockAlign;
wfxt.Format.cbSize = sizeof(wfxt) - sizeof(wfxt.Format);
wfxt.Samples.wValidBitsPerSample = wfxt.Format.wBitsPerSample;
wfxt.dwChannelMask = SPEAKER_ALL;
wfxt.SubFormat = vi->IsSampleType(SAMPLE_FLOAT) ?
KSDATAFORMAT_SUBTYPE_IEEE_FLOAT :
KSDATAFORMAT_SUBTYPE_PCM;

IanB
25th April 2007, 15:55
Try this one http://avisynth2.sourceforge.net/avisynth2571.zip (replace avisynth.dll with the one in the .zip)

It seems to do more or less what I expected.

Ebobtron
25th April 2007, 17:32
Try this one http://avisynth2.sourceforge.net/avisynth2571.zipSorry, not working for me.
I created Extensible sources using both audacity and sh0dan's soundout. Both play fine using MPC or FilmCutter.
An avisynth script using "global OPT_UseWaveExtensible = true" with MPC prompts me that it cannot render some pins
C:\Documents and Settings\HP_Administrator\
My Documents\VidScripts\2soundout.avs::Avisynth audio #1

Media Type 0:
--------------------------
Audio: WAVE_FORMAT_EXTENSIBLE 48000Hz stereo 1536Kbps

AM_MEDIA_TYPE:
majortype: MEDIATYPE_Audio {73647561-0000-0010-8000-00AA00389B71}
subtype: Unknown GUID Name {0000FFFE-0000-0010-8000-00AA00389B71}
formattype: FORMAT_WaveFormatEx {05589F81-C356-11CE-BF01-00AA0055595A}
bFixedSizeSamples: 1
bTemporalCompression: 0
lSampleSize: 4
cbFormat: 40

WAVEFORMATEX:
wFormatTag: 0xfffe
nChannels: 2
nSamplesPerSec: 48000
nAvgBytesPerSec: 192000
nBlockAlign: 4
wBitsPerSample: 16
cbSize: 22 (extra bytes)

WAVEFORMATEXTENSIBLE:
wValidBitsPerSample: 16
dwChannelMask: 0x80000000
SubFormat: {00000001-0000-0010-8000-00AA00389B71}

pbFormat:
0000: fe ff 02 00 80 bb 00 00 00 ee 02 00 04 00 10 00 þÿ..€»...î......
0010: 16 00 10 00 00 00 00 80 01 00 00 00 00 00 10 00 .......€........
0020: 80 00 00 aa 00 38 9b 71 €..ª.8›q
"dwChannelMask: 0x80000000" looks wrong
both two channel sources I describe above listed
"dwChannelMask: 0x00000003"
????

@zambelli
See, I was right, that I could be wrong.

zambelli
25th April 2007, 18:21
Try this one http://avisynth2.sourceforge.net/avisynth2571.zip (replace avisynth.dll with the one in the .zip)

It seems to do more or less what I expected.
:thanks:
Ian, you rock! Thanks for chiming in on this one - I nearly thought it was a lost cause. :)

I tried out the modified DLL and even though the scripts are now returning WAVE_FORMAT_EXTENSIBLE, I'm getting no sound - so I'm guessing something in the format definition is not quite right yet.

Here's the output pin I'm seeing:

Audio: WAVE_FORMAT_EXTENSIBLE 48000Hz 6ch 4608Kbps

AM_MEDIA_TYPE:
majortype: MEDIATYPE_Audio {73647561-0000-0010-8000-00AA00389B71}
subtype: Unknown GUID Name {0000FFFE-0000-0010-8000-00AA00389B71}
formattype: FORMAT_WaveFormatEx {05589F81-C356-11CE-BF01-00AA0055595A}
bFixedSizeSamples: 1
bTemporalCompression: 0
lSampleSize: 12
cbFormat: 40

WAVEFORMATEX:
wFormatTag: 0xfffe
nChannels: 6
nSamplesPerSec: 48000
nAvgBytesPerSec: 576000
nBlockAlign: 12
wBitsPerSample: 16
cbSize: 22 (extra bytes)

WAVEFORMATEXTENSIBLE:
wValidBitsPerSample: 16
dwChannelMask: 0x80000000
SubFormat: {00000001-0000-0010-8000-00AA00389B71}


What I would expect would be more like this:
Audio: WAVE_FORMAT_EXTENSIBLE 48000Hz 6ch 4608Kbps

AM_MEDIA_TYPE:
majortype: MEDIATYPE_Audio {73647561-0000-0010-8000-00AA00389B71}
subtype: MEDIASUBTYPE_PCM {00000001-0000-0010-8000-00AA00389B71}
formattype: FORMAT_WaveFormatEx {05589F81-C356-11CE-BF01-00AA0055595A}
bFixedSizeSamples: 1
bTemporalCompression: 0
lSampleSize: 12
cbFormat: 40

WAVEFORMATEX:
wFormatTag: 0xfffe
nChannels: 6
nSamplesPerSec: 48000
nAvgBytesPerSec: 576000
nBlockAlign: 12
wBitsPerSample: 16
cbSize: 22 (extra bytes)

WAVEFORMATEXTENSIBLE:
wValidBitsPerSample: 16
dwChannelMask: 0x0000003f
SubFormat: {00000001-0000-0010-8000-00AA00389B71

So as Ebobtron pointed out, it seems that dwChannelMask is not right.

zambelli
25th April 2007, 20:59
Looks like the code needs to set the dwChannelMask based on this scheme:

http://msdn2.microsoft.com/en-us/library/ms790436.aspx

This article seems useful too:

http://msdn2.microsoft.com/en-us/library/ms789988.aspx

IanB
26th April 2007, 05:18
So for dwChannelMask you are advocating something like ((unsigned int)-1)>>(32-nChannels)In the context of where this is being defined I thought SPEAKER_ALL(=0x80000000) was a reasonable guess. I could always let the user spec it thru anotherglobal OPT_WaveExtensibleChannelMask=<int>
The issue would seem to be:- subtype: Unknown GUID Name {0000FFFE-0000-0010-8000-00AA00389B71}
versus
subtype: MEDIASUBTYPE_PCM {00000001-0000-0010-8000-00AA00389B71}
The AM_MEDIA_TYPE header, I do not specify this, some Microsoft software is creating this. I return a WAVEFORMATEXTENSIBLE structure to the AVI...ReadFormat call, what happens next I cannot see how to control. Thoughts???

I included the source of main.cpp, the code of interest is at the bottom, thoughts please....

IanB
26th April 2007, 05:44
Question?

Does an intermediate wave file created from this, have the same AM_MEDIA_TYPE header as that directly created from the .AVS file?

Ebobtron
26th April 2007, 06:24
Question?

Does an intermediate wave file created from this, have the same AM_MEDIA_TYPE header as that directly created from the .AVS file?

not sure I understand your question
Below is the data from a avs with vid and audio
AM_MEDIA_TYPE:
majortype: MEDIATYPE_Video {73646976-0000-0010-8000-00AA00389B71}
subtype: MEDIASUBTYPE_YV12 {32315659-0000-0010-8000-00AA00389B71}
formattype: FORMAT_VideoInfo {05589F80-C356-11CE-BF01-00AA0055595A}
bFixedSizeSamples: 1
bTemporalCompression: 0
lSampleSize: 518400
cbFormat: 88
below is audio only (above with killvideo())AM_MEDIA_TYPE:
majortype: MEDIATYPE_Audio {73647561-0000-0010-8000-00AA00389B71}
subtype: MEDIASUBTYPE_PCM {00000001-0000-0010-8000-00AA00389B71}
formattype: FORMAT_WaveFormatEx {05589F81-C356-11CE-BF01-00AA0055595A}
bFixedSizeSamples: 1
bTemporalCompression: 0
lSampleSize: 4
cbFormat: 18

wouldn't SPEAKER_ALL equal 0x0003ffff or 262143 int or am I confused? Again.Speaker position Flag bit

SPEAKER_FRONT_LEFT 0x1
SPEAKER_FRONT_RIGHT 0x2
SPEAKER_FRONT_CENTER 0x4
SPEAKER_LOW_FREQUENCY 0x8
SPEAKER_BACK_LEFT 0x10
SPEAKER_BACK_RIGHT 0x20
SPEAKER_FRONT_LEFT_OF_CENTER 0x40
SPEAKER_FRONT_RIGHT_OF_CENTER 0x80
SPEAKER_BACK_CENTER 0x100
SPEAKER_SIDE_LEFT 0x200
SPEAKER_SIDE_RIGHT 0x400
SPEAKER_TOP_CENTER 0x800
SPEAKER_TOP_FRONT_LEFT 0x1000
SPEAKER_TOP_FRONT_CENTER 0x2000
SPEAKER_TOP_FRONT_RIGHT 0x4000
SPEAKER_TOP_BACK_LEFT 0x8000
SPEAKER_TOP_BACK_CENTER 0x10000
SPEAKER_TOP_BACK_RIGHT 0x20000

Yes, user definable mask. I can not think of another way, that makes real sense. default could equal nchannels 2 = 0x03 6 = 0x3f
Rob :)

IanB
26th April 2007, 10:00
@Ebobtron,

I am asking if the result is different for a WAVE file that has the same WaveFormatEx header compared to directly accessing the .AVS file.

And this looks to be correctAM_MEDIA_TYPE:
majortype: MEDIATYPE_Audio {73647561-0000-0010-8000-00AA00389B71}
subtype: MEDIASUBTYPE_PCM {00000001-0000-0010-8000-00AA00389B71}
...Which is not what Zambelli was seeing...

And SPEAKER_ALL is Microsoft's constant, not mine. It just seemed like the one to use when you had no idea as to the speaker configuration. It is supposed to just use the default mapping for the number of channels currently provided, which is exactly what I thought would be required.

zambelli
26th April 2007, 10:45
And SPEAKER_ALL is Microsoft's constant, not mine. It just seemed like the one to use when you had no idea as to the speaker configuration. It is supposed to just use the default mapping for the number of channels currently provided, which is exactly what I thought would be required.
Shouldn't the dwChannelMask just match the number of channels returned in the Avisynth script? If 2 channels are returned, then set it to 0x3... If 4 channels are returned, then set it to 0x33... If 6 channels are returned, set it to 0x3f... And so on. Sure, you could make it user configurable, but it seems like the 4 basic speaker configurations (2.0, 4.0, 5.1, 7.1) should be pretty easy to guess by default.

Ebobtron
26th April 2007, 14:01
@Ebobtron,

And SPEAKER_ALL is Microsoft's constant, not mine. It just seemed like the one to use when you had no idea as to the speaker configuration. It is supposed to just use the default mapping for the number of channels currently provided, which is exactly what I thought would be required.Ok, I have never run accross that value. I was never sure that was the trouble anyway, it just was something that looked odd to me.

I am asking if the result is different for a WAVE file that has the same WaveFormatEx header compared to directly accessing the .AVS file.

And this looks to be correctAM_MEDIA_TYPE:
majortype: MEDIATYPE_Audio {73647561-0000-0010-8000-00AA00389B71}
subtype: MEDIASUBTYPE_PCM {00000001-0000-0010-8000-00AA00389B71}
...Which is not what Zambelli was seeing...


When it fails I see this
subtype: Unknown GUID Name {0000FFFE-0000-0010-8000-00AA00389B71}
doesn't appear to be what you want

const GUID KSDATAFORMAT_SUBTYPE_PCM =
{0x00000001, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
const GUID KSDATAFORMAT_SUBTYPE_IEEE_FLOAT =
{0x00000003, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71}};
If this was something I had written I would assume that something was overwritting my data. I don't have the AM_MEDIA_TYPE data uncovered in my interface, but I can, and I can then see the GUID.
But maybe you get lucky and somebody tell you what is wrong.

Ebobtron
26th April 2007, 19:00
@IanB
More info or maybe no info.
I don't want to start a debate about a WAVEFORMAT structure as a subset of WAVEFORMATEX, reading some or even most of this stuff gives me a headache.

Am I correct that in the RIFF header for a WAV file that bytes 15 and 16 contain the "wFormatTag"? Am I correct that those two bytes of data will contain the wFormatTag for a WAVEFORMAT, WAVEFORMATEX, WAVEFORMATEXTENSIBLE?

If I am correct for both(I think I am), my save wave function which uses the VFW AVI file functions to read the AviSynth streams should see header data at bytes 15 and 16 and the wFormatTag should equal "fffe", I am getting "0x00".

My AVI functions do read a WAVEFORMATEXTENSIBLE header at least as far as I have carried this out.

So my question is what does avisynth put out for you, I get 0x01 for WAVE_FORMAT_PCM, 0x03 for WAVE_FORMAT_IEEE_FLOAT and 0x00 for WAVE_FORMAT_EXTENSIBLE, where is my "FFFE"

Below is "can not render pin" info from MPC about an audio only script using global OPT_UseWaveExtensible=True. WAVE_FORMAT_EXTENSIBLE is there
Media Type 0:
--------------------------
Audio: WAVE_FORMAT_EXTENSIBLE 48000Hz stereo 1536Kbps

AM_MEDIA_TYPE:
majortype: MEDIATYPE_Audio {73647561-0000-0010-8000-00AA00389B71}
subtype: Unknown GUID Name {0000FFFE-0000-0010-8000-00AA00389B71}
formattype: FORMAT_WaveFormatEx {05589F81-C356-11CE-BF01-00AA0055595A}
bFixedSizeSamples: 1
bTemporalCompression: 0
lSampleSize: 4
cbFormat: 40


Rob :)
P.S. Hi, how are you

Leak
26th April 2007, 19:07
where is my "FFFE"
I'd say it landed smack in the middle of the GUID and b0rked it thusly:

subtype: Unknown GUID Name {0000FFFE-0000-0010-8000-00AA00389B71}

Ebobtron
26th April 2007, 21:06
If it was a snake,

@Leak
Well you win the booby prize, we should give you the whole boob. Instead I can say thank you for uncovering the fact that the fffe made it all the way to byte 45.

:thanks:

Thanks
Rob

IanB
27th April 2007, 04:44
There seems to be general confusion about setting dwChannelMask. From my initial reading months ago when I first played with this, SPEAKER_ALL seemed to be the obvious default to use. Fundamentally if you were not in a position to know about speaker assignment this should have been the value to use! Unfortunatly most software authors seem to have ignored this value in their drivers and only handle explicit speaker assignment. So I will go with the flow and copy what others seem to be doing.

For example WavPackDSDecoder.cpp does this...
switch(pwfxin->nChannels)
{
case 1:
wfex.dwChannelMask = KSAUDIO_SPEAKER_MONO; break;
case 2:
wfex.dwChannelMask = KSAUDIO_SPEAKER_STEREO; break;
case 3:
wfex.dwChannelMask = KSAUDIO_SPEAKER_STEREO | SPEAKER_FRONT_CENTER; break;
case 4:
wfex.dwChannelMask = KSAUDIO_SPEAKER_QUAD; break;
case 5:
wfex.dwChannelMask = KSAUDIO_SPEAKER_QUAD | SPEAKER_FRONT_CENTER; break;
case 6:
wfex.dwChannelMask = KSAUDIO_SPEAKER_5POINT1; break;
default:
wfex.dwChannelMask = KSAUDIO_SPEAKER_DIRECTOUT; break; // XXX : or SPEAKER_ALL ??
}However note in Microsofts KsMedia.h there is room for confusion, QUAD and SURROUND are two alternates for 4 channels. And for DVD there is an implication TOP_CENTER=0x800 rather than FRONT_CENTER=0x4 should be used....
// Speaker Positions:
#define SPEAKER_FRONT_LEFT 0x1
#define SPEAKER_FRONT_RIGHT 0x2
#define SPEAKER_FRONT_CENTER 0x4
#define SPEAKER_LOW_FREQUENCY 0x8
#define SPEAKER_BACK_LEFT 0x10
#define SPEAKER_BACK_RIGHT 0x20
#define SPEAKER_FRONT_LEFT_OF_CENTER 0x40
#define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80
#define SPEAKER_BACK_CENTER 0x100
#define SPEAKER_SIDE_LEFT 0x200
#define SPEAKER_SIDE_RIGHT 0x400
#define SPEAKER_TOP_CENTER 0x800
#define SPEAKER_TOP_FRONT_LEFT 0x1000
#define SPEAKER_TOP_FRONT_CENTER 0x2000
#define SPEAKER_TOP_FRONT_RIGHT 0x4000
#define SPEAKER_TOP_BACK_LEFT 0x8000
#define SPEAKER_TOP_BACK_CENTER 0x10000
#define SPEAKER_TOP_BACK_RIGHT 0x20000

// Bit mask locations reserved for future use
#define SPEAKER_RESERVED 0x7FFC0000

// Used to specify that any possible permutation of speaker configurations
#define SPEAKER_ALL 0x80000000

// DirectSound Speaker Config
#define KSAUDIO_SPEAKER_DIRECTOUT 0
#define KSAUDIO_SPEAKER_MONO (SPEAKER_FRONT_CENTER)
#define KSAUDIO_SPEAKER_STEREO (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT)
#define KSAUDIO_SPEAKER_QUAD (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \
SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT)
#define KSAUDIO_SPEAKER_SURROUND (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \
SPEAKER_FRONT_CENTER | SPEAKER_BACK_CENTER)
#define KSAUDIO_SPEAKER_5POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \
SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | \
SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT)
#define KSAUDIO_SPEAKER_7POINT1 (SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT | \
SPEAKER_FRONT_CENTER | SPEAKER_LOW_FREQUENCY | \
SPEAKER_BACK_LEFT | SPEAKER_BACK_RIGHT | \
SPEAKER_FRONT_LEFT_OF_CENTER | \
SPEAKER_FRONT_RIGHT_OF_CENTER)

// DVD Speaker Positions
#define KSAUDIO_SPEAKER_GROUND_FRONT_LEFT SPEAKER_FRONT_LEFT
#define KSAUDIO_SPEAKER_GROUND_FRONT_CENTER SPEAKER_FRONT_CENTER
#define KSAUDIO_SPEAKER_GROUND_FRONT_RIGHT SPEAKER_FRONT_RIGHT
#define KSAUDIO_SPEAKER_GROUND_REAR_LEFT SPEAKER_BACK_LEFT
#define KSAUDIO_SPEAKER_GROUND_REAR_RIGHT SPEAKER_BACK_RIGHT
#define KSAUDIO_SPEAKER_TOP_MIDDLE SPEAKER_TOP_CENTER
#define KSAUDIO_SPEAKER_SUPER_WOOFER SPEAKER_LOW_FREQUENCY
...Thoughts?

zambelli
27th April 2007, 05:23
However note in Microsofts KsMedia.h there is room for confusion, QUAD and SURROUND are two alternates for 4 channels. And for DVD there is an implication TOP_CENTER=0x800 rather than FRONT_CENTER=0x4 should be used.[code]...
The QUAD configuration is the common one. I can't imagine anyone using the SURROUND configuration for 4.0 sources. The likelihood of someone having a front and back center speker but no surrounds seems very slim.

As for DVD... I think you might be misreading it. Note that GROUND_FRONT_CENTER is mapped to SPEAKER_FRONT_CENTER. That looks to me like a 5.1 EX configuration, where the matrixed 7th channel is typically a side surround or rear center speaker. 7 speakers is the most you can get out of DVD audio. Once again - I think that's a rare case. 5.1 EX decoders are rare and so are 7 speaker configurations - particularly in a PC environment.

IanB
27th April 2007, 07:10
... I think that's a rare case. 5.1 EX decoders are rare and so are 7 speaker configurations - particularly in a PC environment.And that is the rub, AviSynth is NOT a PC Media Player. I still believe SPEAKER_ALL is the correct value for Avisynth, but I also understand that most code can't cope with it.


Enough of the obvious, how are we doing with the dud AM_MEDIA_TYPE headers.

I believe quartz.dll is incorrectly constructing it from the WAVEFORMATEXTENSIBLE structure it has been given. It should be copying the SubFormat field to the subtype field if (wFormatTag == WAVE_FORMAT_EXTENSIBLE), not building a GUID from the wFormatTag as it appears to be doing.

tebasuna51
27th April 2007, 16:56
I still believe SPEAKER_ALL is the correct value for Avisynth, but I also understand that most code can't cope with it.
My vote for assign default values based in nChannels like WavPackDSDecoder.cpp, maybe we can add:
case 7:
wfex.dwChannelMask = KSAUDIO_SPEAKER_5POINT1 | SPEAKER_BACK_CENTER; break;
case 8:
wfex.dwChannelMask = KSAUDIO_SPEAKER_7POINT1; break;

For instance, the last FLAC v1.1.4 only accept multichannel wav input with WAVE_FORMAT_EXTENSIBLE and a valid dwChannelMask.

I think is better modify the exceptions than always fail. You can see my comments to sh0dan in SoundOut thread (http://forum.doom9.org/showthread.php?p=951530#post951530) about ChannelMask default values and ac3 multichannel options.

Ebobtron
27th April 2007, 18:36
@IanB

Enough of the obvious, how are we doing with the dud AM_MEDIA_TYPE headers.

I believe quartz.dll is incorrectly constructing it from the WAVEFORMATEXTENSIBLE structure it has been given. It should be copying the SubFormat field to the subtype field if (wFormatTag == WAVE_FORMAT_EXTENSIBLE), not building a GUID from the wFormatTag as it appears to be doing.

Which quartz.dll functions you talking about.
Sorry, you lose me after.
*lpcbFormat = min(*lpcbFormat, sizeof(wfxt));
memcpy(lpFormat, &wfxt, size_t(*lpcbFormat));
The wave format header data is outputed wrong. Wish I had the skill to help more.
Rob
P.S. I'm working on it.

IanB
28th April 2007, 09:03
@tebasuna51,

SPEAKER_ALL is a valid dwChannelMask value, and you should report it not being correctly implemented to any software authors that don't corrrectly handle it. But I will add mask mapping, watch this space ;)

@Ebobtron,The wave format header data is outputed wrong.Hmm, and how is it wrong?

The code you highlighted, will copy all the structure or as much as will fit in the buffer. The length parameter is updated to specify how much data was actually copied. Entry code zero fills the entire buffer. The original code was not giving the correct length of the required buffer to the caller, this is what I fixed.


The quartz.dll function is the "AVI/WAV File Source", using this DirectShow filter to load an .AVI, .AVS or .WAV file with (wFormatTag == WAVE_FORMAT_EXTENSIBLE) does get a dud AM_MEDIA_TYPE header. I could find no code to handle this in this routine.

Loading .AVI or .WAV files using the "File Source (Async.)" does get a correct AM_MEDIA_TYPE header. There is code to detect WAVE_FORMAT_EXTENSIBLE and act appropriately. Unfortunatly this routine cannot handle .AVS files, but does seem to handle Fake .AVI's.

IanB
28th April 2007, 10:36
New version http://avisynth2.sourceforge.net/avisynth2571.zip (same URL)

dwChannelMask is now mapped based on channel count.

Ebobtron
28th April 2007, 15:46
@ IanB
Hello
The code you highlighted, will copy all the structure or as much as will fit in the buffer. The length parameter is updated to specify how much data was actually copied. Entry code zero fills the entire buffer. The original code was not giving the correct length of the required buffer to the caller, this is what I fixed.I said, "Sorry, you lose me after."Hmm, and how is it wrong?Well I have been trying to tell you that when I access the audio stream using other that Direct show the information is wrong. Byte 21 and 22 (decimal, last time I gave the hex values of 0x15 and 0x16, my bad) must be " FFFE ". I would be happy to be incorrect about this, the first 25 bytes of header data provided must be the same for both formats WAVEFORMEX and WAVEFOREXTENSIBLE.

Reading avisynth script using avsFilmCutter (http://avsfilmcutter.com)
Normal avisynth script wFormatTag = 0x0001
32float avisynth script wFormatTag = 0x0003
extensible avisynth script wFormatTag = 0x0000

0x0000 is incorrect, if direct show thinks this is wrong also, more the better because it should.
FilmCutter's (http://forum.doom9.org/showthread.php?t=97438) direct show viewer / player just displays the video, acts as if audio is not present.

You see sir, I don't understand how y'all fake the wave format data from the buffer to the input of my application. I do know the data is wrong.

??? :( . wish I knew why.

:)
Rob
P.S. Asked an old friend VirtualDubMod, it can see the tag ???

IanB
29th April 2007, 00:54
As I said above in "The quartz.dll function is the "AVI/WAV File Source", ...." The DirectShow component is broken! The version I debugged has no code to deal with WAVE_FORMAT_EXTENSIBLE at all. The version you are using is getting different results so may well now have some code but it is still obviously wrong.

As far as I can see I am returning the correct data to the API. Until Microsoft fix it you cannot correctly read a WAVE_FORMAT_EXTENSIBLE audio stream from Avisynth thru Directshow. You have 2 options use the AVIFile interface directly or write special Directshow code to understand the error in the API and work around it. Understand there appear to be at least 2 different manifestations of this error so any workaround code must be able to handle all cases.

Ebobtron
30th April 2007, 04:41
@IanB

Ok, I get it, maybe.

My information was faulty, my conclusions inaccurate.
I at least get a code rewrite for FilmCutter that will be more correct than it was and more up-to-date.

To clarify on the matter of the Unknown GUID
I'd say it landed smack in the middle of the GUID and b0rked it thusly:
Quote:
subtype: Unknown GUID Name {0000FFFE-0000-0010-8000-00AA00389B71}

From what I can gather 0000-0010-8000-00AA00389B71 is a constant, the source filter creates the GUID by adding the wFormatTag to the beginning thusly. {wFormatTag, 0000-0010-8000-00AA00389B71} :)

When is sees WAVE_FORMAT_EXTENSIBLE it should use the subformat for the GUID.

@IanB

Starting over from scratch.

Load an extensible audio script into VDM and saving the resultant avi, begs still another question.

What is the difference between xx.avi and aviSynth output?

I ask because my VDM generated avi plays sound in FilmCutter, renders in GraphEdit and even plays in window's media player eleven. Plays in winDVD too.

MPC still fails to render the audio pin and displays the same famous message.
:thanks:

rob

IanB
30th April 2007, 10:17
reread http://forum.doom9.org/showthread.php?p=995597#post995597

"AVI/WAV File Source" versus "File Source (Async.)"

Ebobtron
30th April 2007, 14:47
@IanB
Yes, I saw that, I was hoping (for me a rare occasion) you could explain why.

:)
Rob

IanB
1st May 2007, 00:43
Reconstructed pseudo code from assembler in quartz.dll. Note in the first case the simplistic code that just build the subtype GUID, this is the only module that can handle .AVS files. In the second what I have written as an if is probably a big complicated case statement or many nested if's but I simplified it to illustrates the point. I am naming the modules using their GraphEdit DirectShow display names.

AVI/WAV File Source...
long length=0;
AVIStreamReadFormat(pavi, lpos, 0, &length);
WAVEFORMATEX* w = new char[length];
AVIStreamReadFormat(pavi, lpos, w, &length);
AM_MEDIA_TYPE* p = new AM_MEDIA_TYPE;
p->majortype = MEDIATYPE_Audio;
p->subtype = GUID({00000000-0000-0010-8000-00AA00389B71})
p->subtype.Data1 = w->wFormatTag;
p->formattype = FORMAT_WaveFormatEx;
p->cbFormat = length;
p->pbFormat = w;
...
File Source (Async.) + Avi Splitter...
long length=0;
AVIStreamReadFormat(pavi, lpos, 0, &length);
WAVEFORMATEXTENSIBLE* w = new char[length];
AVIStreamReadFormat(pavi, lpos, w, &length);
AM_MEDIA_TYPE* p = new AM_MEDIA_TYPE;
p->majortype = MEDIATYPE_Audio;
if (w->Format.wFormatTag == WAVE_FORMAT_EXTENSIBLE) {
...
p->subtype = w->SubFormat;
...
} else {
p->subtype = GUID({00000000-0000-0010-8000-00AA00389B71})
p->subtype.Data1 = w->Format.wFormatTag;
...
}
p->formattype = FORMAT_WaveFormatEx;
p->cbFormat = length;
p->pbFormat = w;
...Now as to why, I can only guess that "AVI/WAV File Source" is old, predating WAVEFORMATEXTENSIBLE and someone forgot to add the new code.

zambelli
1st May 2007, 03:03
Which one is the default filter for building graphs from AVI sources?

IanB
1st May 2007, 05:04
"AVI/WAV File Source"

It is the only one that will successfully read .AVS's, all the others either give a polite No! or crash and burn.

Haali
1st May 2007, 17:23
I think using subtype=FOURCCMap(WAVE_FORMAT_PCM) is ok, I'm using that for quite some time in my splitter for PCM data, and never had a problem with that.

Also there is a component to read avisynth scripts in my splitter, I use it in my DShow based encoding app. It's not registered anywhere, but you can insert the splitter filter in the graph and open avs scripts when prompted for a source file. The default AVIFile wrapper for DShow had some problems that I don't remember now, so I've added my own one. It still goes via IAVIStream/IAVIFile to open scripts, to avoid avisynth dll dependencies, but calls the avisynth object directly, without using AVIFile library.

Ebobtron
1st May 2007, 19:58
Now as to why, I can only guess that "AVI/WAV File Source" is old, predating WAVEFORMATEXTENSIBLE and someone forgot to add the new code.Thank you.

vfw.h had a file date of 3/26/2003
I think the extensible support had holes everywhere before the R2, which is still riddled with problems, like this.

I just updated to the latest free PSDK for last version of FilmCutter and using WAVEFORMATEXTENSILBE seem ok now. So I'm up for another rewrite, only this time I will not be so trusting.
AVIStreamReadFormat() does not fail when reading an extensible avs script, it just fills the structure with NULLS or leaves them. It fails when reading an extensible wav file but fills the structure with correct data.WAVFORMATEXTENSIBLE seems backward compatible though, which is good.
Took me a while to see the junk data I was getting.

What comes to mind is an old way of thinking that seems to apply to this.
"It is not a matter of " if " you will test the return values from a Microsoft function, it is a matter of when."
:)
Thanks againRob

jmnk
5th August 2007, 19:35
hi,

after following this thread for awhile I'm still a bit lost - does it work or not? I have a simple script:
movie = mpeg2source("C:\dgindexFiles\test.d2v")
audio = DirectShowSource("C:\temp\audio.wav")
audiodub(audio,movie)

where audio.wav is (per mediainfo):
Codec : Extensible
Codec/Info : Extensible wave format
Bit rate : 4608 Kbps
Channel(s) : 6 channels
Sampling rate : 48 KHz
Resolution : 16 bits

I can play it in mpc, but with no audio. Video is fine. If I feed it to wmcmd.vbs to encode to multichannel wma it comes back with an error - invalid format.
If, in MPC, I try play just a video from avs, and specify the very same audio file separately - I have both video and audio just fine (
in MPC fileOpen dialog I give the following in the Openfield: location to avs, where avs is just mpeg2source("C:\dgindexFiles\test.d2v"), and in Dub field I just specify the location of audio.wav)
Ultimately, I want to easily feed video+multichannel audio combined in avs script to wmcmd.vbs. Is that doable? Any tricks I should try?

Ebobtron
5th August 2007, 23:18
@ jmnk
Yes and no :)

Yes:AviSynth outputs WaveFormatExtensible (WAVEFORMATEXTENSILBE )No:Any application that loads AviSynth scripts with DirectShow filters such as MPC will not load the audio portion of the script.
Is that doable? Any tricks I should try?
Try it with normal six channel sound, works with most things for me.

?? what is the source of your six channel wave (what application).

ta :)

jmnk
6th August 2007, 00:12
@ jmnk
Yes and no :)

Yes:AviSynth outputs WaveFormatExtensible (WAVEFORMATEXTENSILBE )No:Any application that loads AviSynth scripts with DirectShow filters such as MPC will not load the audio portion of the script.

Try it with normal six channel sound, works with most things for me.

?? what is the source of your six channel wave (what application).

ta :)
'yes and no' - I was afraid that is the answer. :) On the practical side, the questiom stems from AutoMKV claim that it supports encoding to multichannel wma. AutoMKV shapes as a very nice program but it looks like this multichannel wma does not quite work yet. It converts ac3 to wav via soundout, and the resulting wav is a multichannel one, with extensible thingy set. Then AutoMKV makes an avs file using video open via, for example, mpeg2source, and the created audio via directshowsource, and combines them with audiodub. Finally than this avs is fed to wmcmd.vbs - which quickly returns an error complaining about 'bad/incompatible format'. Which is not suprising given this thread, yet no one on AutoMKV thread seems to be complaining, so I was thinking I'm doing something wrong.
And yes, if I feed this audio file to wvcmd.vbs using -a_input parameter, and avs file contains video only, all is good. I suppose author of AutoMKV, otherwise a pretty good application, needs to rethink how to handle multichannel wma encoding.

IanB
6th August 2007, 00:45
More sussinctly, any DirectShow app that uses a broken "AVI/WAV File Source" component in its graph.

Haali mentioned he had an alternative in his splitter package.

If you have the disk space, building a temporary intermediate AVI can also work around the problem.

Ebobtron
6th August 2007, 04:50
@Ian
Can you point me to an unbroken one.

jmnk
6th August 2007, 04:57
More sussinctly, any DirectShow app that uses a broken "AVI/WAV File Source" component in its graph.
and as I understand - the 'unbroken' does not exist, right?

Haali mentioned he had an alternative in his splitter package.
Yah, he indeed mentioned it? is it usable in avisynth? Any script example please?

If you have the disk space, building a temporary intermediate AVI can also work around the problem.I actually tried to convert avs to avi (via ffdshow avs2avi utility, but it did not help much). But you mean convert to (create) a 'real' avi file, right? I suppose it could work, but probably it would do "wonders" for the encoding time.....

foxyshadis
6th August 2007, 05:09
Just install Haali's splitter, and make sure you check AVI. It'll raise itself above the system default AVI splitter, and should output the audio properly.

jmnk
6th August 2007, 06:47
Just install Haali's splitter, and make sure you check AVI. It'll raise itself above the system default AVI splitter, and should output the audio properly.
thanks. Could you elaborate? The issue is how to make avs script, where audio is wav file with this WAVE_FORMAT_EXTENSIBLE flag, that would be accepted by wmcmd.vbs. Are you saying that after I install haali as suggested, the 'regular' script:
movie = mpeg2source("C:\path\to\test.d2v")
audio = DirectShowSource("C:\path\to\audio.wav")
audiodub(movie,audio)
will 'just work' and will be accepted by wmcmd.vbs? Because it still does not work here... Is there a way to force directshowsource to use haali's filter, or is my reasoning completely off?

tebasuna51
6th August 2007, 09:45
This thread is for AviSynth WAVE_FORMAT_EXTENSIBLE output, waiting for support the input in WavSource you can use:

1) audio = DirectShowSource("C:\path\to\audio.wav")
with audio ffdshow configured to accept Codecs -> Uncompressed -> All supported

2) audio = BassAudioSource("C:\path\to\audio.wav")
You need BassAudio.dll and Bass.dll AviSynth plugins (actually in shon3i BeHappy package)

3) audio = WavSource("C:\path\to\audio.wav")
If previously you patch the WAVE_FORMAT_EXTENSIBLE header with WinHex, or other tool. I can explain this method if there are any interested.

jmnk
6th August 2007, 22:18
This thread is for AviSynth WAVE_FORMAT_EXTENSIBLE output, waiting for support the input in WavSource you can use:

1) audio = DirectShowSource("C:\path\to\audio.wav")
with audio ffdshow configured to accept Codecs -> Uncompressed -> All supported

2) audio = BassAudioSource("C:\path\to\audio.wav")
You need BassAudio.dll and Bass.dll AviSynth plugins (actually in shon3i BeHappy package)

3) audio = WavSource("C:\path\to\audio.wav")
If previously you patch the WAVE_FORMAT_EXTENSIBLE header with WinHex, or other tool. I can explain this method if there are any interested.
I'm confused?? My wav file appears to have the WAVE_FORMAT_EXTENSIBLE header set correctly - but that is judging on the following (which may/may not mean anything):
- output from mediaifo
- when wav file is loaded into MPC (as a separate audio file, --not-- as part of the avs script) MPC shows it is indeed 5.1 channel audio
- when I feed just wav audio to wmcmd.vbs using '-a_input' option that the resulting wma file is indeed 5.1 and the conversion process actually completes without any error.
So I would think that yes, there are ways to open that file and have it play as 5.1. But as you noted as well, the point is to have it opened in the avs script so it can be combined with video, --and-- than passed to the encoding application (or MPC, just for testing). So trying to open it in avs using method 1) you mentioned results in:
- error if passed to wmcmd.vbs, or
- no audio when played in MPC

I --think-- I've tried using wavsource, and that did not work either (but I have to re-try).
Never tried with bassaudiosource. Would you hope opening it that way would make avs script pass this WAVE_FORMAT_EXTENSIBLE header to whatever is accepting this avs script?

IanB
6th August 2007, 23:44
As I said, unless you do something to bypass the broken "AVI/WAV File Source" Directshow component, you cannot directly access any .AVS 5.1 audio output thru the WAVE_FORMAT_EXTENSIBLE modes. Sorry.

Add an Info().KillAudio() to the end of your script to see what the input source is actually delivering to your script. As far as I am aware all the above input sources correctly deliver WAVE_FORMAT_EXTENSIBLE data into an .AVS script.

VirtualDub in direct audio stream copy mode makes a correct 5.1 WAVE_FORMAT_EXTENSIBLE audio stream for both .AVI and .WAV. This file can then subsequently be correctly read with DirectShow using "Async File Source".

NorthPole
4th February 2009, 17:45
If I use:

global OPT_UseWaveExtensible = true

in may avs file and use "Async File Source" to start my directshow filter chain, Can I output a Wave_format_extensible audio stream with AVISynth v2.5.7?

IanB
4th February 2009, 21:36
No!Loading .AVI or .WAV files using the "File Source (Async.)" does get a correct AM_MEDIA_TYPE header. There is code to detect WAVE_FORMAT_EXTENSIBLE and act appropriately. Unfortunatly this routine cannot handle .AVS files, but does seem to handle Fake .AVI's.But!Just install Haali's splitter, and make sure you check AVI. It'll raise itself above the system default AVI splitter, and should output the audio properly.