Has anyone done a function to save Wav's in Max?

BlitzMax Forums/BlitzMax Programming/Has anyone done a function to save Wav's in Max?

sswift(Posted 2006) [#1]
I know there's some BB code in the code archives to do it, but I'm sure there'll be some complciations doing the conversion and maybe someone has done some better ones that handle 16 bit and stero and frequency properly?

The reason I'm looking for this is cause I suspect that Wav files will load much faster than their Ogg counterparts, even though there's more data to load. So I had the idea to decompress the Ogg files the first time the game runs so the download is small but the load times are still short.


Ghost Dancer(Posted 2006) [#2]
I am also planning to do the same thing since it will make a massive difference to the filesize.

I've not found any existing code for this so I'm going to have a crack at it myself.


ozak(Posted 2006) [#3]
Actually, loading compressed files and unpacking them in memory is way faster, than loading a huge wav.
Now, I don't know how the ogg loader does it, but just zip compressing the wavs should give a much faster (just unpack them in memory).


Ghost Dancer(Posted 2006) [#4]
ozak, I think what sswift means is that loading oggs takes way too long - changing a track in my game takes between 5 and 10 seconds (during which the game "freezes"). Loading a big wav takes no time at all.

Anyway, I have written an ogg to wav converter/saver. It was actually easier than I thought it would be which was a pleasant surprise :)

Strict

Local oggFile$ = RequestFile$("Load Ogg...", "Ogg Files:ogg")
Local wavFile$ = RequestFile$("Save as...", "Wav files:wav", True)

If oggToWav(oggFile$, wavFile$)
	Print "Wav file created."
Else
	Print "Error, could not create wav file."
End If

End

Function oggToWav(oggFile$, wavFile$)
	Local sndSample:TAudioSample, sampleSize, sndBank:TBank, fileStream:TStream, channels, bitRate, blockAlign
	
	'load the sound
	sndSample = LoadAudioSample(oggFile$)
	
	'determine mono/stero
	If sndSample.format = SF_MONO8 Or sndSample.format = SF_MONO16LE Or sndSample.format = SF_MONO16BE Then
		channels = 1
	Else
		channels = 2
	End If
		
	'determine bitrate & calculate size
	If sndSample.format = SF_MONO8 Or sndSample.format = SF_STEREO8 Then
		bitRate = 8
		sampleSize = sndSample.length * channels
	Else
		bitRate = 16
		sampleSize = sndSample.length * channels * 2
	End If
	
	blockAlign = channels * bitRate / 8
	
	
	'create a bank from the loaded sound
	sndBank = CreateStaticBank(sndSample.samples, sampleSize)
	
	'create a stream to save data
	fileStream = WriteStream(wavFile$)
	
	If fileStream Then
		'write wav header info
		fileStream.writeString("RIFF")						'"RIFF" file description header (4 bytes)
		fileStream.writeInt(sampleSize + 40)				'file size - 8 (4 bytes)
		fileStream.writeString("WAVE")						'"WAVE" description header (4 bytes)
		fileStream.writeString("fmt ")						'"fmt " description header (4 bytes)
		fileStream.writeInt(16)								'size of WAVE section chunk (4 bytes)
		fileStream.writeShort(1)							'WAVE type format (2 bytes)
		fileStream.writeShort(channels)						'mono/stereo (2 bytes)
		fileStream.writeInt(sndSample.hertz)				'sample rate (4 bytes)
		fileStream.writeInt(sndSample.hertz * blockAlign)	'avg bytes/sec (4 bytes)
		fileStream.writeShort(blockAlign)					'Block alignment (2 bytes)
		fileStream.writeShort(bitRate)						'Bits/sample (2 bytes)
		fileStream.writeString("data")						'"data" description header (4 bytes)
		fileStream.writeInt(sampleSize)						'size of data chunk (4 bytes)
		
		'write wav sound data
		sndBank.Write(fileStream, 0, sampleSize)
		
		'close the stream
		CloseStream fileStream
		
		Return True
	Else
		Return False
	End If
	
	'free up mem
	fileStream = Null
	sndBank = Null
	sndSample = Null
End Function


I'll stick it in the code archives as well