Корректные настройки Media Type для фильтра DirectShow, который доставляет аудиоданные Wav?

Я использую Delphi 6 Pro с библиотекой компонентов DSPACK DirectShow для создания фильтра DirectShow, который доставляет данные в формате Wav из пользовательского аудиоисточника. Просто чтобы прояснить ситуацию, я поставляю необработанные сэмплы PCM в виде байтовых данных. Волновые файлы не задействованы, но другие фильтры, расположенные ниже в моем графике фильтров, ожидают, что выходной контакт будет предоставлять образцы данных в стандартном формате WAV в байтовой форме.

Примечание. Когда я получаю данные из пользовательского аудиоисточника, я форматирую их для нужного количества каналов, частоты дискретизации и битов на сэмпл и сохраняю их в созданном мной объекте TWaveFile. Этот объект имеет правильно отформатированный элемент данных TWaveFormatEx, который настроен правильно, чтобы отражать основной формат данных, которые я сохранил.

Я не знаю, как правильно настроить параметр MediaType во время вызова GetMediaType():

    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)? Я знаю о константах GUID MEDIATYPE_Audio, MEDIATYPE_Stream и MEDIASUBTYPE_WAVE, но я не уверен, что и где.

Кроме того, я предполагаю, что мне нужно скопировать структуру / запись WaveFormatEx из моего объекта FWaveFile в указатель pbFormat (4). У меня есть два вопроса по этому поводу:

1) Я предполагаю, что следует использовать CoTaskMemAlloc() для создания нового объекта TWaveFormatEx и скопировать на него объект TWaveFormatEx моего объекта FWaveFile, прежде чем назначить на него указатель 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, Роман предположил, что проблема исчезла.

1 ответ

Решение

(1) MEDIATYPE_Audio,

(2) обычно представляет собой преобразование кода FOURCC в GUID, см. Раздел " Типы мультимедиа", "Типы аудиосигналов ".

(3) FORMAT_WaveFormatEx,

(4) - указатель (обычно выделяемый API-распределителем памяти для задач COM) на WAVEFORMATEX состав.

1) - да, вы должны выделить память, поместить туда правильные данные, скопировав или инициализировав напрямую, и поместив этот указатель на pbFormat и размер структуры в cbFormat,

2) - да, это выглядит хорошо, в первую очередь определяется следующим образом: структура WAVEFORMATEX.

Другие вопросы по тегам