Partilhar via


Tipos de mídia de áudio não compactado

Para criar um tipo de áudio não comprimido completo, defina pelo menos os seguintes atributos no IMFMediaType ponteiro da interface.

Atributo Descrição
MF_MT_MAJOR_TYPE Tipo principal. Defina como MFMediaType_Audio.
MF_MT_SUBTYPE Subtipo. Consulte GUIDs de subtipo de áudio.
MF_MT_AUDIO_NUM_CHANNELS Número de canais de áudio.
MF_MT_AUDIO_SAMPLES_PER_SECOND Número de amostras de áudio por segundo.
MF_MT_AUDIO_BLOCK_ALIGNMENT Alinhamento de blocos.
MF_MT_AUDIO_AVG_BYTES_PER_SECOND Número médio de bytes por segundo.
MF_MT_AUDIO_BITS_PER_SAMPLE Número de bits por amostra de áudio.
MF_MT_ALL_SAMPLES_INDEPENDENT Especifica se cada amostra de áudio é independente. Defina como TRUE para formatos MFAudioFormat_PCM e MFAudioFormat_Float.

 

Além disso, os seguintes atributos são necessários para alguns formatos de áudio.

Atributo Descrição
MF_MT_AUDIO_VALID_BITS_PER_SAMPLE Número de bits válidos de dados de áudio em cada amostra de áudio. Defina esse atributo se as amostras de áudio tiverem preenchimento, ou seja, se o número de bits válidos em cada amostra de áudio for menor que o tamanho da amostra.
MF_MT_AUDIO_CHANNEL_MASK A atribuição de canais de áudio para posições de alto-falante. Defina esse atributo para fluxos de áudio multicanal, como 5.1. Este atributo não é necessário para áudio mono ou estéreo.

 

Código de exemplo

O código a seguir mostra como criar um tipo de mídia para áudio PCM não compactado.

HRESULT CreatePCMAudioType(
    UINT32 sampleRate,        // Samples per second
    UINT32 bitsPerSample,     // Bits per sample
    UINT32 cChannels,         // Number of channels
    IMFMediaType **ppType     // Receives a pointer to the media type.
    )
{
    HRESULT hr = S_OK;

    IMFMediaType *pType = NULL;

    // Calculate derived values.
    UINT32 blockAlign = cChannels * (bitsPerSample / 8);
    UINT32 bytesPerSecond = blockAlign * sampleRate;

    // Create the empty media type.
    hr = MFCreateMediaType(&pType);
    if (FAILED(hr))
    {
        goto done;
    }

    // Set attributes on the type.
    hr = pType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pType->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, cChannels);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pType->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, sampleRate);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pType->SetUINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, blockAlign);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pType->SetUINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, bytesPerSecond);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pType->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, bitsPerSample);
    if (FAILED(hr))
    {
        goto done;
    }

    hr = pType->SetUINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, TRUE);
    if (FAILED(hr))
    {
        goto done;
    }

    // Return the type to the caller.
    *ppType = pType;
    (*ppType)->AddRef();

done:
    SafeRelease(&pType);
    return hr;
}

O próximo exemplo usa um formato de áudio codificado como entrada e cria um tipo de áudio PCM correspondente. Este tipo seria adequado para definir em um codificador ou decodificador, por exemplo.

//-------------------------------------------------------------------
// ConvertAudioTypeToPCM
//
// Given an audio media type (which might describe a compressed audio
// format), returns a media type that describes the equivalent
// uncompressed PCM format.
//-------------------------------------------------------------------

HRESULT ConvertAudioTypeToPCM(
    IMFMediaType *pType,        // Pointer to an encoded audio type.
    IMFMediaType **ppType       // Receives a matching PCM audio type.
    )
{
    HRESULT hr = S_OK;

    GUID majortype = { 0 };
    GUID subtype = { 0 };

    UINT32 cChannels = 0;
    UINT32 samplesPerSec = 0;
    UINT32 bitsPerSample = 0;

    hr = pType->GetMajorType(&majortype);
    if (FAILED(hr)) 
    { 
        return hr;
    }

    if (majortype != MFMediaType_Audio)
    {
        return MF_E_INVALIDMEDIATYPE;
    }

    // Get the audio subtype.
    hr = pType->GetGUID(MF_MT_SUBTYPE, &subtype);
    if (FAILED(hr)) 
    { 
        return hr;
    }

    if (subtype == MFAudioFormat_PCM)
    {
        // This is already a PCM audio type. Return the same pointer.

        *ppType = pType;
        (*ppType)->AddRef();

        return S_OK;
    }

    // Get the sample rate and other information from the audio format.

    cChannels = MFGetAttributeUINT32(pType, MF_MT_AUDIO_NUM_CHANNELS, 0);
    samplesPerSec = MFGetAttributeUINT32(pType, MF_MT_AUDIO_SAMPLES_PER_SECOND, 0);
    bitsPerSample = MFGetAttributeUINT32(pType, MF_MT_AUDIO_BITS_PER_SAMPLE, 16);

    // Note: Some encoded audio formats do not contain a value for bits/sample.
    // In that case, use a default value of 16. Most codecs will accept this value.

    if (cChannels == 0 || samplesPerSec == 0)
    {
        return MF_E_INVALIDTYPE;
    }

    // Create the corresponding PCM audio type.
    hr = CreatePCMAudioType(samplesPerSec, bitsPerSample, cChannels, ppType);

    return hr;
}

Tipos de mídia de áudio