Code archives/Audio/.wav samples value
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
Load a .wav audio file with :sound = WaveLoad("music.wav") Then you can access to any sample value with the function : value = WaveSample(time) Time is the time in millisecs from the beginning of the wav file. An optional channel parameter let you choose wich channel sample you want. It only works with 16bits or 8bits stereo or mono PCM .wav files ! Blitz3D doesn't handle 24 and 32 bits audio, and doesn't work well with more than 2 channels. | |||||
Graphics 800,600,32,2 SetBuffer BackBuffer() ; variables Global wavBank Global wavChannels Global wavFrequency Global wavBytePerSec Global wavBytePerBloc Global wavBits Global wavDataSize Print "Loading .wav...":Flip Global wavSound = WaveLoad("test16bits.wav") ; ONLY WORKS WITH MONO AND STEREO WAV 8 OR 16 BITS PlaySound wavSound wavStartTime = MilliSecs() ;------------------------------------------------------------------------------------; While Not KeyHit(1) Cls ; waveform wavCurrentTime = MilliSecs()-wavStartTime For channel = 0 To wavChannels-1 For i = 0 To 800 Plot i,75+channel*150+WaveSample(wavCurrentTime+i,channel)/500 Next Next Flip 0 Wend ;------------------------------------------------------------------------------------; FreeSound wavSound FreeBank wavBank End ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function WaveLoad(wavPath$) If FileType(wavPath) = 1 wavBank = CreateBank(FileSize(wavPath)) wavFile = OpenFile(wavPath) ReadBytes wavBank,wavFile,0,FileSize(wavPath) CloseFile wavFile Else Return 0 EndIf If Chr(PeekByte(wavBank,0)) + Chr(PeekByte(wavBank,1)) + Chr(PeekByte(wavBank,2)) + Chr(PeekByte(wavBank,3)) = "RIFF" If PeekInt(wavBank,4)+8 = FileSize(wavPath) ; file size If Chr(PeekByte(wavBank,8)) + Chr(PeekByte(wavBank,9)) + Chr(PeekByte(wavBank,10)) + Chr(PeekByte(wavBank,11)) = "WAVE" If Chr(PeekByte(wavBank,12)) + Chr(PeekByte(wavBank,13)) + Chr(PeekByte(wavBank,14)) + Chr(PeekByte(wavBank,15)) = "fmt " If PeekInt(wavBank,16) = 16 ; bloc Size If PeekShort(wavBank,20) = 1 ; PCM If Chr(PeekByte(wavBank,36)) + Chr(PeekByte(wavBank,37)) + Chr(PeekByte(wavBank,38)) + Chr(PeekByte(wavBank,39)) = "data" wavChannels = PeekShort(wavBank,22) wavFrequency = PeekInt(wavBank,24) wavBytePerSec = PeekInt(wavBank,28) wavBytePerBloc = PeekShort(wavBank,32) wavBits = PeekShort(wavBank,34) wavDataSize = PeekInt(wavBank,40) If wavBits <= 16 And wavChannels <= 2 wavSound = LoadSound(wavPath) Return wavSound Else Return 0 EndIf EndIf EndIf EndIf EndIf EndIf EndIf EndIf End Function ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Function WaveSample(time,channel=0) offset = time*Float(wavBytePerSec)/1000/wavChannels/(wavBits/8) If offset > wavDataSize/wavChannels/(wavBits/8) Or offset < 0 Then Return 0 Select wavBits Case 8 sample = (PeekByte(wavBank,offset*wavChannels+channel)-128)*128 Case 16 sample = PeekShort(wavBank,offset*wavChannels*2+channel*2) If sample > 32768 Then sample = sample - 65535 End Select Return sample End Function |
Comments
| ||
very nice!, thank's for share, here an example of a filter: for a smoothed oval, define a variable: local alpha#=0.025 ;1=no smooth, 0.025 very! and in the main loop, just after your oval insert Oval 300-radius,300-radius,radius*2,radius*2,1 ;just a smoothed one smoothRadius# = Float(targetRadius) * alpha# + (smoothRadius# * ( 1.0 - alpha#)) Oval 500-smoothRadius,300-smoothRadius,smoothRadius*2,smoothRadius*2,1 note that i shift your oval to the left somewhat to place my oval somewhat to the right (to not overlap each other) here a test1.wav for playing: https://dl.dropboxusercontent.com/u/78894295/tmp1/test1.wav and the exe, just in case: https://dl.dropboxusercontent.com/u/78894295/tmp1/waveload.zip modified source code: https://dl.dropboxusercontent.com/u/78894295/tmp1/waveload.bb Juan |
| ||
Thanks for the addition, I tried to do it at first but it didn't work very well. |
| ||
Good one Flanker ^^ Just a small thing : - A loaded file should not generate runtime errors, it should just return "0" if failed I know it can relevant to generate errors, but to be consistent with blitz3d stuff, you might not want to introduice different behaviors who could lead to headackes to remember which function required to check the file exists before trying to load from the ones who returns a "0" to check. |
| ||
Yes you're right bobysait, it should return 0 instead of generating a runtime error. It's just there because before it was a function the code was in the main program and I forgot to remove that ^^ I will update the code when I'm back on my computer, so it can work with both mono and stereo and 8 or 16bits. It seems that wav files with more than 2 channels are not well supported with blitz3d, same with 32bits samples. |
| ||
Code updated so it works with 8 and 16 bits, stereo or mono PCM waves, and no need anymore for an array, it works directly from the bank so it's faster to load and takes less memory. Blitz3D doesn't work with 24 and 32bits wav audio, and when there is more than 2 channels, it needs ChannelPitch to play the audio at the original speed. |
Code Archives Forum