locked
PCM format whose sampling rate was 16000 needed for microphone recording RRS feed

  • Question

  • I've a scenario where I need to record PCM format audio whose sampling rate was 16000.  I have already know that MediaCapture don't support the RIFF file format or the PCM codec. So I've used the Com Interface to  save the data in Pcm format myself.

    Firstly, I use the MediaCapture to record a mp3 audio in this way.

    Windows.Media.Capture.MediaCapture m_mediaCaptureMgr = new Windows.Media.Capture.MediaCapture();
    await m_mediaCaptureMgr.InitializeAsync(captureInitSettings);
    MediaEncodingProfile recordProfile = null;
    recordProfile = MediaEncodingProfile.CreateMp3(Windows.Media.MediaProperties.AudioEncodingQuality.Medium);
    Windows.Storage.Streams.IRandomAccessStream randomStream = new Windows.Storage.Streams.InMemoryRandomAccessStream();
    await m_mediaCaptureMgr.StartRecordToStreamAsync(recordProfile, randomStream);
    


    Then, I use the IMFSourceReader to decode the mp3 format audio into pcm format audio whose sampling rate was 16000.


    ComPtr<IMFSourceReader> m_pSourceReader;
    ComPtr<IMFByteStream> pMFByteStream = nullptr
    MFCreateMFByteStreamOnStreamEx((IUnknown*)readStream, &pMFByteStream);
    MFCreateSourceReaderFromByteStream(pMFByteStream.Get(), nullptr, &(m_pSourceReader))
    ComPtr<IMFMediaType> pInMediaType = nullptr;   
    ComPtr<IMFMediaType> pActualMediaType = nullptr;
    this->m_pSourceReader->SetStreamSelection((DWORD)MF_SOURCE_READER_ALL_STREAMS, false)
    this->m_pSourceReader->SetStreamSelection((DWORD)MF_SOURCE_READER_FIRST_AUDIO_STREAM, true)
    MFCreateMediaType(&pInMediaType)
    pInMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Audio)
    pInMediaType->SetGUID(MF_MT_SUBTYPE, MFAudioFormat_PCM)
    pInMediaType->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND, 22050)
    pInMediaType->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS, 1)
    pInMediaType->SetUINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 32000)
    pInMediaType->SetUINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT, 2)
    pInMediaType->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE, 16)
    


    But when I finished this and got a pcm format audio, I found that the quality of the audio was so bad. So, could anyone tell me why I cann't get high quality audio in this way. Thank you!

    Wednesday, August 22, 2012 4:08 AM

Answers

  • Hello Lisztian,

    While your solution for obtaining PCM audio in WinRT is very creative it is certainly not recommended. Going from a compressed format and down-sampling to a lower sample rate is likely the reason for the degradation in audio quality. However without listening to the captured MP3 and captured WAV I would not be able to confirm.

    Again your solution while creative is totally unnecessary. Is there a particular reason why you aren't using WASAPI to capture the raw PCM audio?

    Thanks,

    James


    Windows Media SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    Friday, August 24, 2012 9:44 PM
    Moderator

All replies

  • I'm going to send this post to our media guru.

    Matt Small - Microsoft Escalation Engineer - Forum Moderator
    If my reply answers your question, please mark this post as answered.

    If I ask for code, please provide something that I can drop directly into a project and run (including XAML), or an actual application project. I'm trying to help a lot of people, so I don't have time to figure out weird snippets with undefined objects and unknown namespaces.

    Thursday, August 23, 2012 3:45 PM
    Moderator
  • Hello Lisztian,

    While your solution for obtaining PCM audio in WinRT is very creative it is certainly not recommended. Going from a compressed format and down-sampling to a lower sample rate is likely the reason for the degradation in audio quality. However without listening to the captured MP3 and captured WAV I would not be able to confirm.

    Again your solution while creative is totally unnecessary. Is there a particular reason why you aren't using WASAPI to capture the raw PCM audio?

    Thanks,

    James


    Windows Media SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    Friday, August 24, 2012 9:44 PM
    Moderator
  • @James Dailey

    Perhaps the reason is because there aren't any good pointers on how to use WASAPI in a sample.

    I'm originally a C++ programmer and wrote RIP Vinyl (http://www.ripvinyl.com) which uses many audio API's.

    In Metro style apps, it's not apparent how to bridge the C++/C# gap.

    Is there a pointer to any good documentation on an example, so I can learn?


    Anthony Wieser | Wieser Software Ltd | www.wieser-software.com

    Saturday, August 25, 2012 7:20 AM
  • Hello James,

    As @Anthony said, there aren't any good pointers on how to use WASAPI in a sample. On the other hand, my application was developed in C#. If I use WASAPI to capture the raw PCM audio, I have to change a lot of previous design.

    But if there isn't good method which could resolve the degradation in audio quality. I have to use WASAPI to capture the raw PCM audio. So, is there any example?

    Thanks!

    Monday, August 27, 2012 7:43 AM
  • Hello Anthony,

    The best way to bridge your C# front end and C++ back end is to crate a C++ WinRT component. You can then load this component in your C# app and call it like you would any other WinRT API. Just remember to keep the communications between components as quiet and as asyncronous as possible. Since WASAPI is available on the desktop as well there are a number of good WASAPI samples for the desktop that can be leveraged for WinRT.

    ActivateAudioInterfaceAsync function

    http://msdn.microsoft.com/en-us/library/windows/desktop/jj128298(v=vs.85).aspx

    I hope this helps,

    James


    Windows Media SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    Tuesday, August 28, 2012 9:06 PM
    Moderator
  • @Anthony Wieser

    I have already used WASAPI to capture the PCM audio. There is an example which tell you how to use IAudioClient.

    http://code.msdn.microsoft.com/windowsapps/Windows-Audio-Session-22dcab6b

    @James Dailey

    Thanks for you help, your answer help me a lot!

    Friday, August 31, 2012 6:34 AM
  • Hello,

    Here is a different approach.

    MediaStreamSource media extension sample

    http://code.msdn.microsoft.com/windowsapps/MediaStreamSource-media-dfd55dff

    I hope this helps,

    James


    Windows Media SDK Technologies - Microsoft Developer Services - http://blogs.msdn.com/mediasdkstuff/

    Monday, September 10, 2012 11:20 PM
    Moderator
  • How to generate PCM data by using MediaCaptureElement.?

    Or is there any way to generate FLAc file?

    Monday, October 8, 2012 11:29 AM
  • Hi,I had succeed to run the sample,but I want to record PCM audio with low sample rate and single channel ,I run the sample failed when I set the sample rate with 16000.Please tips! Thanks!
    Thursday, November 15, 2012 1:37 AM
  • Hi,I had succeed to run the sample,but I want to record PCM audio with low sample rate and single channel ,I run the sample failed when I set the sample rate with 16000.Please tips! Thanks!
    Thursday, November 15, 2012 1:38 AM
  • OK.  Just about built my WinRT component in C++, but now not sure how to package it for the store.

    I posted a question about that here:
    http://social.msdn.microsoft.com/Forums/en-US/winappswithnativecode/thread/fd67a4f4-b4d4-445b-9925-f5aaa055ce89

    Also, there's a question further down about how to sample more slowly.

    Using wasapi, it seems I get 48 KHz.  If I request 24 or 12 Khz, I get an error.

    I've read elsewhere about using the Resampler MFT.  Is that the suggested way for getting a non-simple divisor? (clearly if I really want 1/2 I can just throw away half the points)


    Anthony Wieser | Wieser Software Ltd | www.wieser-software.com

    Wednesday, November 21, 2012 11:07 PM