The significant code is the following:
CODE
Private Stream As IO.FileStream
'...
Public Shared Function ToLittleEndian(ByVal Value As Int32, ByVal BitSize As Byte) As Byte()
If BitSize <> 8 And BitSize <> 16 And BitSize <> 24 And BitSize <> 32 Then
Throw New ArgumentException("BitSize deve essere 8, 16, 24 o 32.")
End If
Dim Result(BitSize / 8 - 1) As Byte
Dim Temp As Byte
For I As Byte = 0 To Result.Length - 1
For J As Byte = 0 To 7
Temp = 2 ^ (7 - J) * If((Value And (2 ^ (8 * I + 7 - J))) = 2 ^ (8 * I + 7 - J), 1, 0)
Result(I) += Temp
Value -= Temp
Next
Next
Return Result
End Function
'...
Public Sub New(ByVal Samples()() As Int32, ByVal SampleRate As Int32, ByVal SignificantBitsPerSample As Int16)
Stream = New IO.FileStream(IO.Path.GetRandomFileName(), IO.FileMode.Create)
_SampleRate = SampleRate
_SignificantBitsPerSample = SignificantBitsPerSample
_ChannelsNumber = Samples(0).Length
_SamplesNumber = Samples.Length
_CompressionMode = CompressionCode.PcmUncompressed
WriteMainHeader()
WriteFormatChunk()
WriteDataChunkHeader()
DataStartIndex = Stream.Position
DataSize = Me.SamplesNumber * Me.BlockAlign
For I As Int64 = 0 To Samples.LongLength - 1
For J As Byte = 0 To Me.ChannelsNumber - 1
Stream.Write(ToLittleEndian(Samples(I)(J), Me.SignificantBitsPerSample), 0, Me.SignificantBitsPerSample / 8)
Next
Next
Stream.Position = 0
End Sub
Public Sub New(ByVal BaseWave As Wave, ByVal SampleIndex As Int32, ByVal Length As Int32)
Me.New(BaseWave.ReadSamples(SampleIndex, Length), BaseWave.SampleRate, BaseWave.SignificantBitsPerSample)
End Sub
'...
Private Shared Sub WriteMainHeader(ByVal WaveStream As IO.FileStream, ByVal FileSize As Int32)
WaveStream.Position = 0
With WaveStream
.Write(ASCIIEncoding.ASCII.GetBytes("RIFF"), 0, 4)
.Write(ToLittleEndian(FileSize, 32), 0, 4)
.Write(ASCIIEncoding.ASCII.GetBytes("WAVE"), 0, 4)
End With
End Sub
Private Sub WriteMainHeader(ByVal WaveStream As IO.FileStream)
WriteMainHeader(WaveStream, Me.SamplesNumber * Me.BlockAlign + 44 - 8)
End Sub
Private Sub WriteMainHeader()
WriteMainHeader(Stream)
End Sub
Private Shared Sub WriteFormatChunk(ByVal WaveStream As IO.FileStream, ByVal CompressionMode As CompressionCode, _
ByVal ChannelsNumber As Int16, ByVal SampleRate As Int32, ByVal SignificantBitsPerSample As Int16)
Dim Writer As New IO.BinaryWriter(WaveStream)
Dim BlockAlign As Int16 = ChannelsNumber * SignificantBitsPerSample / 8
Dim BytesPerSecond As Int32 = SampleRate * BlockAlign
With Writer
.Write(New Char() {"f", "m", "t", " "})
.Write(ToLittleEndian(16, 32))
.Write(ToLittleEndian(CompressionMode, 16))
.Write(ToLittleEndian(ChannelsNumber, 16))
.Write(ToLittleEndian(SampleRate, 32))
.Write(ToLittleEndian(BytesPerSecond, 32))
.Write(ToLittleEndian(BlockAlign, 16))
.Write(ToLittleEndian(SignificantBitsPerSample, 16))
End With
Writer = Nothing
End Sub
Private Sub WriteFormatChunk(ByVal WaveStream As IO.FileStream)
WriteFormatChunk(WaveStream, Me.CompressionMode, Me.ChannelsNumber, Me.SampleRate, Me.SignificantBitsPerSample)
End Sub
Private Sub WriteFormatChunk()
WriteFormatChunk(Stream)
End Sub
Private Shared Sub WriteDataChunkHeader(ByVal WaveStream As IO.FileStream, ByVal DataSize As Int32)
WaveStream.Write(System.Text.ASCIIEncoding.ASCII.GetBytes("data"), 0, 4)
WaveStream.Write(ToLittleEndian(DataSize, 32), 0, 4)
End Sub
Private Sub WriteDataChunkHeader(ByVal WaveStream As IO.FileStream)
WriteDataChunkHeader(WaveStream, Me.SamplesNumber * Me.BlockAlign)
End Sub
Private Sub WriteDataChunkHeader()
WriteDataChunkHeader(Stream)
End Sub
'...
Public Sub Save(ByVal FileName As String)
Dim Writer As New IO.FileStream(FileName, IO.FileMode.Create)
Dim Buffer(Stream.Length - 1) As Byte
Stream.Position = 0
Stream.Read(Buffer, 0, Stream.Length)
Writer.Write(Buffer, 0, Buffer.Length)
Stream.Position = 0
Writer.Close()
Buffer = Nothing
End Sub
'...
Public Shared Function ToLittleEndian(ByVal Value As Int32, ByVal BitSize As Byte) As Byte()
If BitSize <> 8 And BitSize <> 16 And BitSize <> 24 And BitSize <> 32 Then
Throw New ArgumentException("BitSize deve essere 8, 16, 24 o 32.")
End If
Dim Result(BitSize / 8 - 1) As Byte
Dim Temp As Byte
For I As Byte = 0 To Result.Length - 1
For J As Byte = 0 To 7
Temp = 2 ^ (7 - J) * If((Value And (2 ^ (8 * I + 7 - J))) = 2 ^ (8 * I + 7 - J), 1, 0)
Result(I) += Temp
Value -= Temp
Next
Next
Return Result
End Function
'...
Public Sub New(ByVal Samples()() As Int32, ByVal SampleRate As Int32, ByVal SignificantBitsPerSample As Int16)
Stream = New IO.FileStream(IO.Path.GetRandomFileName(), IO.FileMode.Create)
_SampleRate = SampleRate
_SignificantBitsPerSample = SignificantBitsPerSample
_ChannelsNumber = Samples(0).Length
_SamplesNumber = Samples.Length
_CompressionMode = CompressionCode.PcmUncompressed
WriteMainHeader()
WriteFormatChunk()
WriteDataChunkHeader()
DataStartIndex = Stream.Position
DataSize = Me.SamplesNumber * Me.BlockAlign
For I As Int64 = 0 To Samples.LongLength - 1
For J As Byte = 0 To Me.ChannelsNumber - 1
Stream.Write(ToLittleEndian(Samples(I)(J), Me.SignificantBitsPerSample), 0, Me.SignificantBitsPerSample / 8)
Next
Next
Stream.Position = 0
End Sub
Public Sub New(ByVal BaseWave As Wave, ByVal SampleIndex As Int32, ByVal Length As Int32)
Me.New(BaseWave.ReadSamples(SampleIndex, Length), BaseWave.SampleRate, BaseWave.SignificantBitsPerSample)
End Sub
'...
Private Shared Sub WriteMainHeader(ByVal WaveStream As IO.FileStream, ByVal FileSize As Int32)
WaveStream.Position = 0
With WaveStream
.Write(ASCIIEncoding.ASCII.GetBytes("RIFF"), 0, 4)
.Write(ToLittleEndian(FileSize, 32), 0, 4)
.Write(ASCIIEncoding.ASCII.GetBytes("WAVE"), 0, 4)
End With
End Sub
Private Sub WriteMainHeader(ByVal WaveStream As IO.FileStream)
WriteMainHeader(WaveStream, Me.SamplesNumber * Me.BlockAlign + 44 - 8)
End Sub
Private Sub WriteMainHeader()
WriteMainHeader(Stream)
End Sub
Private Shared Sub WriteFormatChunk(ByVal WaveStream As IO.FileStream, ByVal CompressionMode As CompressionCode, _
ByVal ChannelsNumber As Int16, ByVal SampleRate As Int32, ByVal SignificantBitsPerSample As Int16)
Dim Writer As New IO.BinaryWriter(WaveStream)
Dim BlockAlign As Int16 = ChannelsNumber * SignificantBitsPerSample / 8
Dim BytesPerSecond As Int32 = SampleRate * BlockAlign
With Writer
.Write(New Char() {"f", "m", "t", " "})
.Write(ToLittleEndian(16, 32))
.Write(ToLittleEndian(CompressionMode, 16))
.Write(ToLittleEndian(ChannelsNumber, 16))
.Write(ToLittleEndian(SampleRate, 32))
.Write(ToLittleEndian(BytesPerSecond, 32))
.Write(ToLittleEndian(BlockAlign, 16))
.Write(ToLittleEndian(SignificantBitsPerSample, 16))
End With
Writer = Nothing
End Sub
Private Sub WriteFormatChunk(ByVal WaveStream As IO.FileStream)
WriteFormatChunk(WaveStream, Me.CompressionMode, Me.ChannelsNumber, Me.SampleRate, Me.SignificantBitsPerSample)
End Sub
Private Sub WriteFormatChunk()
WriteFormatChunk(Stream)
End Sub
Private Shared Sub WriteDataChunkHeader(ByVal WaveStream As IO.FileStream, ByVal DataSize As Int32)
WaveStream.Write(System.Text.ASCIIEncoding.ASCII.GetBytes("data"), 0, 4)
WaveStream.Write(ToLittleEndian(DataSize, 32), 0, 4)
End Sub
Private Sub WriteDataChunkHeader(ByVal WaveStream As IO.FileStream)
WriteDataChunkHeader(WaveStream, Me.SamplesNumber * Me.BlockAlign)
End Sub
Private Sub WriteDataChunkHeader()
WriteDataChunkHeader(Stream)
End Sub
'...
Public Sub Save(ByVal FileName As String)
Dim Writer As New IO.FileStream(FileName, IO.FileMode.Create)
Dim Buffer(Stream.Length - 1) As Byte
Stream.Position = 0
Stream.Read(Buffer, 0, Stream.Length)
Writer.Write(Buffer, 0, Buffer.Length)
Stream.Position = 0
Writer.Close()
Buffer = Nothing
End Sub