Please note that this is not perfect, not all wave files can be modified without first modifying other fileformatsubchunk fields.
'Option Strict Is Always Recommended
Option
Strict
On
Imports
System.Text
Public
Class
Form1
'Add one button to your form(make sure that the handles clause is still at the end of your sub afterwards)=Handles Button1.Click
Private
Sub
Button1_Click(
ByVal
sender
As
System.
Object
,
e
System.EventArgs)
Handles
Button1.Click
'Create a new instance of the wavefile class(provided in the technet article)
Dim
WaveFile
New
Wave
'Create a new openfiledialog
OFD
OpenFileDialog
'Set the filter for the openfiledialog
OFD.Filter =
"Wave Files|*.wav"
'make it select single files only
OFD.Multiselect =
False
'Show the dialog
If
OFD.ShowDialog = DialogResult.OK
Then
'If the user didn't cancel then load the wavefile into its wrapper
WaveFile.LoadFromFile(OFD.FileName)
'Modify the sample rate(not all speeds are compatible without adjusting other properties)
WaveFile.FileFormatSubChunk.SampleRate = Wave.WavSampleRate.hz22050
'Create a new memory stream from the bytes of the wavefile
Stream
IO.MemoryStream(WaveFile.GetBytes)
'Play the wavefile
My.Computer.Audio.Play(Stream, AudioPlayMode.Background)
End
'By Paul Ishak
'WAVE PCM soundfile format
'The Canonical WAVE file format
'As Described Here: https://ccrma.stanford.edu/courses/422/projects/WaveFormat/
'The File's Header
FileHeader
Header
'Wave File's Format Sub Chunk
FileFormatSubChunk
FormatSubChunk
'Data Subchunk
FileDataSubChunk
DataSubChunk
'This structure is an optional parameter for creating a new wave file
Structure
WaveFileOptions
SampleRate
WavSampleRate
AudioFormat
Format
BitsPerSample
NumberOfChannels
FormatSize
NumberOfSamples
UInt32
Data
Byte
()
'These are the various structures in the wave file and their description
'DATATYPE OFFSET Endian Description
Property
ChunkID
' Dword 0 Big Contains the letters "RIFF" in ASCII form(0x52494646 big-endian form).
ChunkSize
' Dword 4 Little 36 + SubChunk2Size, or more precisely: 4 + (8 + SubChunk1Size) + (8 + SubChunk2Size)
' Dword 8 Big Contains the letters "WAVE" in ASCII form (0x57415645 big-endian form).
Subchunk1ID
' Dword 12 Big Contains the letters "fmt "(0x666d7420 big-endian form).
Subchunk1Size
' Dword 16 little 16 for PCM. This is the size of the rest of the Subchunk which follows this number.
UInt16
' Word 20 little PCM = 1 (i.e. Linear quantization)Values other than 1 indicate some form of compression.
NumChannels
' Word 22 little Mono = 1, Stereo = 2, etc.
' Dword 24 little 8000, 44100, etc.
ByteRate
' Dword 28 little == SampleRate * NumChannels * BitsPerSample/8
BlockAlign
' Word 32 little == NumChannels * BitsPerSample/8
' Word 34 little 8 bits = 8, 16 bits = 16, etc.
Subchunk2ID
' Dword 36 Big Contains the letters "data"(0x64617461 big-endian form).
Subchunk2Size
' Dword 40 little == NumSamples * NumChannels * BitsPerSample/8 This is the number of bytes in the data.
' VariableLength 44 little The actual sound data.
LoadFromFile(
FileName
String
)
Not
My.Computer.FileSystem.FileExists(FileName)
Exit
FileBytes()
= My.Computer.FileSystem.ReadAllBytes(FileName)
Try
Me
.FileHeader.ChunkID = GetDataFromByteArray(FileBytes, 0, 0, 4)
.FileHeader.ChunkSize = BitConverter.ToUInt32(FileBytes, 4)
.FileHeader.Format = GetDataFromByteArray(FileBytes, 0, 8, 4)
.FileFormatSubChunk.Subchunk1ID = GetDataFromByteArray(FileBytes, 0, 12, 4)
.FileFormatSubChunk.Subchunk1Size = BitConverter.ToUInt32(FileBytes, 16)
.FileFormatSubChunk.AudioFormat = BitConverter.ToUInt16(FileBytes, 20)
.FileFormatSubChunk.NumChannels = BitConverter.ToUInt16(FileBytes, 22)
.FileFormatSubChunk.SampleRate = BitConverter.ToUInt32(FileBytes, 24)
.FileFormatSubChunk.ByteRate = BitConverter.ToUInt32(FileBytes, 28)
.FileFormatSubChunk.BlockAlign = BitConverter.ToUInt16(FileBytes, 32)
.FileFormatSubChunk.BitsPerSample = BitConverter.ToUInt16(FileBytes, 34)
.FileDataSubChunk.Subchunk2ID = GetDataFromByteArray(FileBytes, 0, 36, 4)
.FileDataSubChunk.Subchunk2Size = BitConverter.ToUInt32(FileBytes, 40)
.FileDataSubChunk.Data = GetDataFromByteArray(FileBytes, 0, 44,
.FileDataSubChunk.Subchunk2Size)
Catch
Throw
Exception(
"File Is Invalid or corrupt!"
Function
GetBytes()
Results
() =
Nothing
Results = CombineArrays(FileHeader.ChunkID, BitConverter.GetBytes(FileHeader.ChunkSize))
Results = CombineArrays(Results, FileHeader.Format)
Results = CombineArrays(Results, FileFormatSubChunk.Subchunk1ID)
Results = CombineArrays(Results, BitConverter.GetBytes(FileFormatSubChunk.Subchunk1Size))
Results = CombineArrays(Results, BitConverter.GetBytes(FileFormatSubChunk.AudioFormat))
Results = CombineArrays(Results, BitConverter.GetBytes(FileFormatSubChunk.NumChannels))
Results = CombineArrays(Results, BitConverter.GetBytes(FileFormatSubChunk.SampleRate))
Results = CombineArrays(Results, BitConverter.GetBytes(FileFormatSubChunk.ByteRate))
Results = CombineArrays(Results, BitConverter.GetBytes(FileFormatSubChunk.BlockAlign))
Results = CombineArrays(Results, BitConverter.GetBytes(FileFormatSubChunk.BitsPerSample))
Results = CombineArrays(Results, FileDataSubChunk.Subchunk2ID)
Results = CombineArrays(Results, BitConverter.GetBytes(FileDataSubChunk.Subchunk2Size))
Results = CombineArrays(Results, FileDataSubChunk.Data)
Return
CombineArrays(
Array1()
Array2()
AllResults(Array1.Length + Array2.Length - 1)
Array1.CopyTo(AllResults, 0)
Array2.CopyTo(AllResults, Array1.Length)
AllResults
GetDataFromByteArray(
ByteArray
(),
BlockOffset
Long
RangeStartOffset
DataLength
Error
Resume
Next
AnswerL
List(Of
Answer(0
To
CInt
((DataLength - 1)))
CurrentOffset
For
I = 0
UBound(ByteArray)
CurrentOffset = BlockOffset + I
CurrentOffset >= RangeStartOffset
CurrentOffset <= RangeStartOffset + DataLength
AnswerL.Add(ByteArray(I))
count
Integer
= -1
Each
bt
In
count = count + 1
Answer(count) = bt
Answer
(
Optional
Options
WaveFileOptions =
FileHeader.ChunkID = Encoding.ASCII.GetBytes(
"RIFF"
FileFormatSubChunk.Subchunk1Size = Options.FormatSize
FileFormatSubChunk.NumChannels = Options.NumberOfChannels
FileFormatSubChunk.BitsPerSample = Options.BitsPerSample
FileDataSubChunk.Subchunk2Size = CUInt(Options.NumberOfSamples * Options.NumberOfChannels * Options.BitsPerSample / 8)
FileHeader.ChunkSize = CUInt(4 + (8 + FileFormatSubChunk.Subchunk1Size) + (8 + FileDataSubChunk.Subchunk2Size))
FileHeader.Format = Encoding.ASCII.GetBytes(
"WAVE"
FileFormatSubChunk.Subchunk1ID = Encoding.ASCII.GetBytes(
"fmt "
FileFormatSubChunk.AudioFormat = Options.AudioFormat
FileFormatSubChunk.SampleRate = Options.SampleRate
FileFormatSubChunk.ByteRate = CUInt(Options.SampleRate * Options.NumberOfChannels * Options.BitsPerSample / 8)
FileFormatSubChunk.BlockAlign = CUShort(Options.NumberOfChannels * Options.BitsPerSample / 8)
FileDataSubChunk.Subchunk2ID = Encoding.ASCII.GetBytes(
"data"
FileDataSubChunk.Data = Options.Data
ex
Exception
Enum
hz8000 = 8000
hz11025 = 11025
hz16000 = 16000
hz22050 = 22050
hz32000 = 32000
hz44100 = 44100
hz48000 = 48000
hz96000 = 96000
hz192000 = 192000
Standard = 1
bps_8 = 8
bps_16 = 16
bps_32 = 32
bps_64 = 64
bps_128 = 128
bps_256 = 256
Mono = 1
Stereo = 2
PCM = 16
Please check out my other Technet Wiki articles!