Converting audio using MFT was error when convert WAV file to AAC

trọng chuyên đinh 6 Reputation points
2020-09-15T14:45:29.36+00:00

When I converted the wav file to AAC, noise was mixed in the audio.

I can convert successfully. However, when playing output file, sometimes i get a pulse noise or a beep.

Program details as below:


include <windows.h>

include <windowsx.h>

include <comdef.h>

include <stdio.h>

include <mfapi.h>

include <mfidl.h>

include <mfreadwrite.h>

include <Mferror.h>

include <mfplay.h>

include <codecapi.h>

include <atlcomcli.h>

pragma comment(lib, "ole32")

pragma comment(lib, "mfplat")

pragma comment(lib, "mfreadwrite")

pragma comment(lib, "mfuuid")

int main()
{
HRESULT hr = CoInitializeEx(NULL, COINIT_MULTITHREADED);
hr = MFStartup(MF_VERSION);

IMFMediaType *pMediaType;
IMFMediaType *pMediaTypeOut;
IMFSourceReader *pSourceReader;
IMFAttributes *pAttributes;
IMFSinkWriter *pSinkWriter;
IMFMediaType *pCurrentMediaType;
LONGLONG nDruration = 700000000;

// Load souce file
hr = MFCreateSourceReaderFromURL(L"in.wav", NULL, &pSourceReader );
pSourceReader->SetStreamSelection(MF_SOURCE_READER_FIRST_AUDIO_STREAM, TRUE);

// Create a partial media type that specifies uncompressed audio
IMFMediaType *pPartialType;
MFCreateMediaType(&pPartialType);
hr = pPartialType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio);
hr = pPartialType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM);
hr = pSourceReader->SetCurrentMediaType(MF_SOURCE_READER_FIRST_AUDIO_STREAM
    , nullptr
    , pPartialType);
hr = pSourceReader->GetCurrentMediaType(MF_SOURCE_READER_FIRST_AUDIO_STREAM, &pPartialType);
hr = pSourceReader->SetStreamSelection(MF_SOURCE_READER_FIRST_AUDIO_STREAM, TRUE);

// set media type for output file
hr = MFCreateMediaType(&pMediaTypeOut);

// set major type for output file
hr = pMediaTypeOut->SetGUID( MF_MT_MAJOR_TYPE, MFMediaType_Audio );

// Set subtype for output file
hr = pMediaTypeOut->SetGUID( MF_MT_SUBTYPE, MFAudioFormat_AAC );
hr = pMediaTypeOut->SetUINT32( MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100 );

// set audio number channal for output file
hr = pMediaTypeOut->SetUINT32( MF_MT_AUDIO_NUM_CHANNELS, 2 );

// set audio bit depth for output file
hr = pMediaTypeOut->SetUINT32( MF_MT_AUDIO_BITS_PER_SAMPLE, 16 );
hr = pMediaTypeOut->SetUINT32( MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 12000.5 );
hr = pMediaTypeOut->SetUINT32( MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 );
pMediaTypeOut->SetUINT32(MF_MT_AAC_AUDIO_PROFILE_LEVEL_INDICATION, 0x29);

DWORD nWriterStreamIndex = -1;
hr = MFCreateSinkWriterFromURL(L"out.mp4", NULL, NULL, &pSinkWriter);
hr = pSinkWriter->AddStream(pMediaTypeOut, &nWriterStreamIndex);
hr = pSinkWriter->SetInputMediaType(nWriterStreamIndex, pPartialType, NULL);

LONGLONG SampleDuration = 0L;
hr = pSinkWriter->BeginWriting();

for (;;)
{
    DWORD nStreamIndex, nStreamFlags;
    LONGLONG nTime;
    IMFSample *pSample;

    hr = pSourceReader->ReadSample(MF_SOURCE_READER_FIRST_AUDIO_STREAM,
        0,
        &nStreamIndex,
        &nStreamFlags,
        &nTime,
        &pSample);
    printf("FLAGS %d\n", nStreamFlags);
    printf("TIME %lld\n", nTime);

    if (nStreamFlags & MF_SOURCE_READERF_ENDOFSTREAM)
    {
        break;
    }

    //Update media type, when current media tye changed.
    if (nStreamFlags & MF_SOURCE_READERF_CURRENTMEDIATYPECHANGED) {
        pSourceReader->GetNativeMediaType(MF_SOURCE_READER_FIRST_AUDIO_STREAM, MF_SOURCE_READER_CURRENT_TYPE_INDEX, &pCurrentMediaType);
        printf("MediaType changed\n");
        pSourceReader->SetStreamSelection(MF_SOURCE_READER_FIRST_AUDIO_STREAM, TRUE);
        hr = pSinkWriter->SetInputMediaType(nWriterStreamIndex, pCurrentMediaType, NULL);
        continue;
    }
    pSample->GetSampleDuration(&SampleDuration);

    if (nTime >= nDruration)
    {
        break;
    }
    // Calculate new timestamp of sample when this sample is written on output file
    if (nTime + SampleDuration >= nDruration)
    {
        SampleDuration = nDruration - nTime;
        pSample->SetSampleDuration(SampleDuration);
    }
    pSample->SetSampleTime(nTime);

    if (FAILED(hr)) {
        printf("ReadSample Error...\n");
        return hr;
    }

    //write sample
    if (pSample)
    {
        OutputDebugString(L"Write sample...\n");
        hr = pSinkWriter->WriteSample(
            nWriterStreamIndex,
            pSample
        );
        if (FAILED(hr)) {
            pSample->Release();
            printf("WriteSample Error...\n");
            return hr;
        }
        pSample->Release();
        pSample = NULL;
    }
}
hr = pSinkWriter->Finalize();
return 0;

}

I send in.wav file, basically contains a "white noise". Link: https://drive.google.com/file/d/1Bf4fHR4xvagp-OTcDnD4ubLkoMm1wl2J/view?usp=sharing

To be more precise, It is a sequence of short "white noise" and no sound. When converting the wav file to aac, i find that the output file sounds substantially different from the input. I believe this clearly demonstrates the issue we are dealing.

Q: Can you explain the problem, is there something wrong when using AAC encoder?

Windows development Windows API - Win32
{count} vote

2 answers

Sort by: Most helpful
  1. Niklas Wenzel 21 Reputation points
    2021-10-20T16:16:00.863+00:00

    I created a Feedback Hub entry to get this fixed: https://aka.ms/AAe3i6x

    If you also experience this issue, please log into Feedback Hub with your Microsoft account, then click the above link, and upvote it.

    This will help bring it to the attention of the respective developers at Microsoft.

    1 person found this answer helpful.
    0 comments No comments

  2. Rita Han - MSFT 2,171 Reputation points
    2020-09-16T01:47:13.04+00:00

    Hello @trọng chuyên đinh ,

    I can reproduce this issue using your sample code and audio file.

    Change channel from 2 to 1 solve this issue for me. You can have a try to see if it helps.

    Updated code as below:

    // set audio number channal for output file  
    hr = pMediaTypeOut->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, 1);  
    

    Thank you!


    If the answer is helpful, please click "Accept Answer" and upvote it.

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.