简体   繁体   中英

create wavefile in physical filestream works, create in memorystream fails, waveheader corrupt

I have a buffer with Wav-samples, which I want to play. Using a FileStream this works. Using a MemoryStream it fails with a System.InvalidOperationException 'The wave header is corrupt' on the soundPlayer.Play statement.

This is the sourcethat works:

 Friend Sub New(buffer() As Byte, nBytes As Integer)
    'Dim wavStream As MemoryStream = New MemoryStream(CInt(nBytes + 44))
    Dim wavStream As FileStream = New FileStream("xxf.wav", FileMode.OpenOrCreate)
    waveFormat = New WaveFormat(44100, 16, 2)
    Wwriter = New WaveWriter(wavStream, waveFormat)
    Wwriter.Write(buffer, 0, nBytes)
    CType(Wwriter, IDisposable).Dispose()
    'soundPlayer = New System.Media.SoundPlayer(wavStream)
    soundPlayer = New System.Media.SoundPlayer("xxf.wav")
    soundPlayer.Play()
    soundPlayer.Dispose()
    soundPlayer = Nothing
    wavStream.Dispose()
    wavStream.Close()
End Sub

Changing the 2 commented lines, to use MemoryStream in stead of a FileStream, I get the 'The wave header is corrupt' error. I rewrote the source in C#, with the same result. I watched the contents of the stream buffers in 3 places. After writing the Wavheader, after writing the data, after disposing. The resulting differences are only in the Chunksize:

after write of wavhdr:
 filestream   buffer(4) 12 127 26 0  (= 818970, the correct number of short samples)
 memorystream buffer(4) 36 0 0 0     (the number is there because I overwrite the same filedata)

after write of buffer:
 filestream   buffer(4) 12 127 26 0
 memorystream buffer(4) 36 0 0 0

after dispose: 
 identical  buffer(4) 12 127 26 0

I conclude that the stream is written correctly by the program, but not (yet?) written in memory by OS. But I am unable to find any Dispose or Close statements that I can add. Wwriter itself has no dispose, but if I don't dispose of the file with IDisposable the FileStream version does not fail, but does not play anything either. WavStream may only be closed after playing, as the stream would be discarded. Do you see what is my mistake?

As is written in both comments, the problem is in reading a MemoryStream, after it was written. The absence of a close by the writing procedure and an open in the procedure that processes the data can only be overcome by changing the file's Position. This needs always to be done, when a MemoryStream is used. It will be written, it will be read, in between the pointer in the data needs to be reset to 0.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM