mcu mcu - 3 months ago 26
Vb.net Question

Creating a WAV file with an arbitrary bits per sample value?

Do WAV files allow any number of

bitsPerSample
?

I have failed to get it to work with anything less than 8. I am not sure how to define the
blockAlign
for one thing.

Imports System.Speech

Module Module1

Sub Main()
Dim wavFile As String
Dim info As Speech.AudioFormat.SpeechAudioFormatInfo
Dim ss As New Speech.Synthesis.SpeechSynthesizer
ss.Volume = 100
ss.SelectVoiceByHints(Synthesis.VoiceGender.Female, Synthesis.VoiceAge.Adult)
Try
wavFile = "TEST8.wav"
info = New Speech.AudioFormat.SpeechAudioFormatInfo(AudioFormat.EncodingFormat.Pcm, 5000, 8, 1, 5000, 1, Nothing) ' FAILS
ss.SetOutputToWaveFile(wavFile, info)
ss.Speak("I am 8 bit.")
My.Computer.Audio.Play(wavFile, AudioPlayMode.WaitToComplete)
Console.WriteLine("8 bit succeeded.")
Catch ex As Exception
Console.WriteLine(String.Format("8 bit failed: '{0}'", ex.Message))
End Try

Try
wavFile = "TEST4.wav"
info = New Speech.AudioFormat.SpeechAudioFormatInfo(AudioFormat.EncodingFormat.Pcm, 5000, 4, 1, 2500, 1, Nothing) ' FAILS
ss.SetOutputToWaveFile(wavFile, info)
ss.Speak("I am 4 bit.")
My.Computer.Audio.Play(wavFile, AudioPlayMode.WaitToComplete)
Console.WriteLine("4 bit succeeded.")
Catch ex As Exception
Console.WriteLine(String.Format("4 bit failed: '{0}'", ex.Message))
End Try

' 8 bit succeeded.
' 4 bit failed: 'One of the identified items was in an invalid format.'

ss.Dispose()
Console.Write("Press ENTER to exit.")
Console.ReadLine()
End Sub

End Module

Answer

AFAIK no, 4-bit PCM format is undefined, it wouldn't make much sense to have 16 volume levels of audio; quality would be horrible.

While technically possible, I know no decent software (e.g. Wavelab) that supports it, your very own player could though.

Formula: blockAlign = channels * (bitsPerSample / 8)

So for a mono 4-bit it would be : blockAlign = 1 * ((double)4 / 8) = 0.5

Note the usage of double being necessary to not end up with 0.

But if you look at the block align definition below, it really does not make much sense to have an alignment of 0.5 bytes, one would have to work at the bit-level (painful and useless because at this quality, non-compressed PCM would just sound horrible):

wBlockAlign

The block alignment (in bytes) of the waveform data. Playback software needs to process a multiple of wBlockAlign bytes of data at a time, so the value of wBlockAlign can be used for buffer alignment.

Reference:

http://www-mmsp.ece.mcgill.ca/Documents/AudioFormats/WAVE/Docs/riffmci.pdf page 59

Workaround:

If you really need 4-bit, switch to ADPCM format.