HEX error in WAV file (advanced)
Blitz3D Forums/Blitz3D Programming/HEX error in WAV file (advanced)
| ||
| Only execute this code if you have at least 512meg of memory. This is my wav file creation code. If anyone else here knows the WAV header well, maybe they could point out where I'm making a mistake here. :) Basically - although the WAV plays, it creates a major buffer overflow. Blitz is assigning over 100 megs of RAM for the WAV, even though its only about 42kb. The HEX header for the wav: Offset | Hex
0 | 52 49 46 46 ac 58 01 00 57 41 56 45 66 6d 74 20
16 | 10 00 00 00 01 00 01 00 44 ac 00 00 88 58 01 00
32 | 08 00 10 00 64 61 74 61 88 00 00 The source:
exists=OpenFile("test.wav")
If exists Then CloseFile exists:DeleteFile("test.wav")
wave=WriteFile("test.wav")
;Choose our settings
Length = 1
SampleRate = 44100
NumChannels = 1
BitsPerSample = 16
frequency=60
;Do Some calcs
NumSamples = SampleRate * Length
SubChunkSize = (NumSamples * NumChannels * BitsPerSample / 8) + 36
;Write RIFF Chunk Descriptor
WriteByte wave,82
WriteByte wave,73
WriteByte wave,70
WriteByte wave,70
WriteInt wave,SubChunkSize
WriteByte wave,87
WriteByte wave,65
WriteByte wave,86
WriteByte wave,69
;Write FMT subchunk
WriteByte wave,102
WriteByte wave,109
WriteByte wave,116
WriteByte wave,32
WriteInt wave,16
WriteByte wave,1
WriteByte wave,0
WriteByte wave,NumChannels
WriteByte wave,0
WriteInt wave,Samplerate
WriteInt wave,Samplerate * Numchannels * BitsPerSample / 8
WriteByte wave,NumChannels * BitsPerSample / 2
WriteByte wave,0
WriteByte wave,BitsPerSample
WriteByte wave,0
;Write DATA subchunk
WriteByte wave,100
WriteByte wave,97
WriteByte wave,116
WriteByte wave,97
WriteByte wave,NumSamples * NumChannels * BitsPerSample / 8
For i = 0 To 44100
sample#=Pi*frequency*i/(44100/frequency)
WriteByte wave,sample#
Next
CloseFile wave
Print "Test.Wav created"
Print "Press ESC to quit or any key to play."
wave=LoadSound("test.wav")
While Not KeyHit(1)
WaitKey()
PlaySound wave
Wend
End+BlackD |
| ||
| most of the fields in the wav header are not byte sized so you can't use writebyte, check out: http://www.blitzbasic.com/codearcs/codearcs.php?code=1111 |
| ||
| That's right.. in fact, none are byte-sized. They're all either 2 bytes or 4 bytes. And 4 bytes are only used because the number is large. Hence, for each descriptor which needs 2 bytes, I've written out the first byte, then a 00, and for the 4 byte sections where its an INT, I write it out as a 4-Byte INT, and where the four words are ("RIFF", "WAVE", "fmt " and "data") I write them out individually. |
| ||
| hehe.. and while writing that post, I found the bug.. The last line of byte writing - SubChunk2Size - was writing a byte rather than an INT. This means the first two bytes of sample data were being recorded as part of the SubChunk2Size nibble (4-Bytes). So, rather than Blitz reading SubChunk2Size = 42102, it was reading 167000008 or something like that. :) Fixed with this: WriteInt wave,NumSamples * NumChannels * BitsPerSample / 8 instead of: WriteByte wave,NumSamples * NumChannels * BitsPerSample / 8 So simple.. hehe. :) (feels dumb.. again). +BlackD |
| ||
| And just corrected it so it plays the correct frequency: frequency=100 volume=50 sample#=volume*Sin(Pi*frequency*i/(NumSamples/frequency)) |
| ||
| Glad we could help. =] |