1

I captured raw audio data stream together with its WAVEFORMATEXTENSIBLE struct. WAVEFORMATEXTENSIBLE is shown in the figure below:

The WAVEFORMATEXTENSIBLE struct

Following the standard of wav file, I tried to write the raw bits into a wav file. What I do is:

  1. write "RIFF".

  2. write a DWORD. (filesize - sizeof("RIFF") - sizeof(DWORD)).

=== WaveFormat Chunk ===

  1. write "WAVEfmt "

  2. write a DWORD. (size of the WAVEFORMATEXTENSIBLE struct)

  3. write the WAVEFORMATEXTENSIBLE struct.

=== Fact Chunk ===

  1. write "fact"

  2. write a DWORD. ( 4 )

  3. write a DWORD. ( num of samples in the stream, which should be sizeof(rawdata)*8/wBitsPerSample ).

=== Data Chunk ===

  1. write "data"

  2. write a DWORD (size of rawdata)

  3. write the raw data.

After getting the wav file from the above steps, I played the wav file with media player, there is no sound, playing with audacity will give me a distorted sound, I can hear that it is the correct audio I want, but the sound is distorted with noise.

The raw data can be find here

The wav file I generate is here

It is very confusing to me, because when I use the same method to convert IEEE-float data to wav file, it works just fine.

Min Lin
  • 3,177
  • 2
  • 19
  • 32
  • are you sure your raw data is 32 bit? – Mark Heath Dec 13 '12 at 07:24
  • It should be, coz the WAVEFORMATEX structure say it is, and the WAVEFORMATEX is obtained from the IAudioClient. – Min Lin Dec 13 '12 at 07:49
  • but is it 32 bit int or 32 bit float? that might account for the problem. You need to check your subtype GUID is correct (PCM or FLOAT) – Mark Heath Dec 13 '12 at 10:47
  • I don't quite understand, these data are captured by hooking into the IAudioRenderClient, and intercept the getBuffer and releaseBuffer method. I get the WAVEFORMATEX structure from the coressponding IAudioClient, I think I should assume the WAVEFORMATEX is correct and use as it is. – Min Lin Dec 13 '12 at 12:14
  • I'm not sure why initialize method on IAudioClient needs a waveformatex parameter, isn't it readily available from the GetMixFormat method? Sample codes always obtain waveformatex from GetMixFormat of IAudioClient, and pass it back to the initialize method of IAudioClient. – Min Lin Dec 13 '12 at 12:24
  • because in theory it could accept other formats but in practice it tends to be very fussy. – Mark Heath Dec 13 '12 at 12:31
  • OK, I figured this out, it seems the getbuffer releasebuffer cycle is putting raw data that has the format same as that passed into the initialize method. GetMixFormat in my case here is different from the format passed into the initialize method. I think IAudioClient is responsible for the conversion of format. I intercept the initialize method, get the format, and it works like a charm. – Min Lin Dec 13 '12 at 12:58
  • Thanks Mark, I saw you answering many audio related questions. I've got no response for this question after I post it yesterday, and I was waiting for you to come. – Min Lin Dec 13 '12 at 13:01

2 Answers2

0

I figured this out, it seems the getbuffer releasebuffer cycle in IAudioRenderClient is putting raw data that has the format same as that passed into the initialize method of the IAudioClient.

The GetMixFormat in IAudioClient in my case is different from the format passed into the initialize method. I think GetMixFormat gets the format that the device supports.

IAudioClient should have done the conversion of format from the initialized format to the mixformat. I intercept the initialize method, get the format, and it works like a charm.

Min Lin
  • 3,177
  • 2
  • 19
  • 32
0

I'm intercepting WASAPI to access the audio data and face the exact same issue where the generated audio file from the data sounds like the correct content but is very noisy somehow although the frame rate, sample width, number of channels etc. are set properly.

The SubFormat field of WAVEFORMATEXTENSIBLE shows that the data is actually KSDATAFORMAT_SUBTYPE_IEEE_FLOAT, while I originally treat it as integers. According to this page, KSDATAFORMAT_SUBTYPE_IEEE_FLOAT is equivalent to WAVE_FORMAT_IEEE_FLOAT in WAVEFORMATEX. Hence, setting the "audio format" in the wav file's fmt chunk(normally starts in the 20th position) to WAVE_FORMAT_IEEE_FLOAT(which is 3) solved the problem. Remember to put it in little endian.

  • Original value of audio format enter image description here
  • After modification enter image description here
KMint
  • 33
  • 1
  • 5