为提供Wav音频数据的DirectShow过滤器更正媒体类型设置?

时间:2011-10-26 23:03:58

标签: delphi audio filter directshow wav

我正在使用Delphi 6 Pro和DSPACK DirectShow组件库来创建DirectShow过滤器,该过滤器从自定义音频源提供Wav格式的数据。为了清楚起见,我将原始PCM音频样本作为字节数据提供。没有涉及Wave文件,但我的过滤器图中下游的其他过滤器期望输出引脚以字节形式提供标准WAV格式样本数据。

注意:当我从自定义音频源获取数据时,我将其格式化为所需的通道数,采样率和每个采样的位数,并将其存储在我创建的TWaveFile对象中。此对象具有格式正确的TWaveFormatEx数据成员,该成员已正确设置以反映我存储的数据的基础格式。

我不知道如何在GetMediaType()调用期间正确设置MediaType参数:

    function TBCPushPinPlayAudio.GetMediaType(MediaType: PAMMediaType): HResult;

    .......

    with FWaveFile.WaveFormatEx do
    begin
        MediaType.majortype                 := (1)
        MediaType.subtype                   := (2)
        MediaType.formattype                := (3)
        MediaType.bTemporalCompression      := False;
        MediaType.bFixedSizeSamples         := True;
        MediaType.pbFormat                  := (4)
        // Number of bytes per sample is the number of channels in the
        //  Wave audio data times the number of bytes per sample
        //  (wBitsPerSample div 8);
        MediaType.lSampleSize := nChannels * (wBitsPerSample div 8);
    end;

(1),(2)和(3)的正确值是多少?我知道MEDIATYPE_Audio,MEDIATYPE_Stream和MEDIASUBTYPE_WAVE GUID常量,但我不确定究竟是什么。

另外,我假设我需要将我的FWaveFile对象中的WaveFormatEx结构/记录复制到pbFormat指针(4)。我有两个问题:

1)我假设应该使用CoTaskMemAlloc()来创建一个新的TWaveFormatEx对象并将我的FWaveFile对象的TWaveFormatEx对象复制到它上面,然后再将pbFormat指针赋给它,是否正确?

2)TWaveFormatEx是否传递正确的结构?以下是TWaveFormatEx的定义方式:

tWAVEFORMATEX = packed record
    wFormatTag: Word;       { format type }
    nChannels: Word;        { number of channels (i.e. mono, stereo, etc.) }
    nSamplesPerSec: DWORD;  { sample rate }
    nAvgBytesPerSec: DWORD; { for buffer estimation }
    nBlockAlign: Word;      { block size of data }
    wBitsPerSample: Word;   { number of bits per sample of mono data }
    cbSize: Word;           { the count in bytes of the size of }

端;

更新时间:11-12-2011

我想强调@Roman R附加到他接受的回复中的一条评论,他告诉我使用 MEDIASUBTYPE_PCM 作为子类型,因为它非常重要。我失去了大量时间追逐DirectShow“没有中间过滤器组合”错误,因为我忘了将该值用于子类型并使用(错误) MEDIASUBTYPE_WAVE 相反。 MEDIASUBTYPE_WAVE与许多其他过滤器(如系统捕获过滤器)不兼容,这是失败的根本原因。这里更大的教训是,如果您正在调试过滤器间媒体格式协商错误,请确保所连接的引脚之间的格式完全相等。我在初始调试期间犯了错误,只是比较了引脚之间相同的WAV格式参数(格式标签,通道数,每个样本的比特数,采样率)。但是,由于我不正确地使用MEDIASUBTYPE_WAVE导致子类型的差异导致引脚连接失败。一旦我将子类型更改为MEDIASUBTYPE_PCM,就像Roman建议问题消失一样。

1 个答案:

答案 0 :(得分:4)

(1)是MEDIATYPE_Audio

(2)通常是从FOURCC代码到GUID的映射,请参阅Media Types音频媒体类型部分。

(3)是FORMAT_WaveFormatEx

(4)是指向WAVEFORMATEX结构的指针(通常由COM任务内存分配器API分配)。

1) - 是的,您应该通过直接复制或初始化来分配内存,将有效数据放入其中,并将此指针指向pbFormat并将结构大小放入cbFormat

2) - 是的它看起来不错,首先定义如下:WAVEFORMATEX structure