HEX error in WAV file (advanced)

Blitz3D Forums/Blitz3D Programming/HEX error in WAV file (advanced)

BlackD(Posted 2004) [#1]
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


skidracer(Posted 2004) [#2]
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


BlackD(Posted 2004) [#3]
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.


BlackD(Posted 2004) [#4]
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


BlackD(Posted 2004) [#5]
And just corrected it so it plays the correct frequency:

frequency=100
volume=50

sample#=volume*Sin(Pi*frequency*i/(NumSamples/frequency))


Hotcakes(Posted 2004) [#6]
Glad we could help. =]