October 28, 2020, 06:02:57 AM

Author Topic: [bb] .wav samples value by Flanker [ 9 months ago ]  (Read 1676 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bb] .wav samples value by Flanker [ 9 months ago ]
« on: June 29, 2017, 12:28:42 AM »
Title : .wav samples value
Author : Flanker
Posted : 9 months ago

Description : Load a .wav audio file with :
Code: [Select]
sound = WaveLoad("music.wav")
Then you can access to any sample value with the function :
Code: [Select]
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. [/i]

Code :
Code: BlitzBasic
  1. Graphics 800,600,32,2
  2. SetBuffer BackBuffer()
  3.  
  4. ; variables
  5. Global wavBank
  6. Global wavChannels
  7. Global wavFrequency
  8. Global wavBytePerSec
  9. Global wavBytePerBloc
  10. Global wavBits
  11. Global wavDataSize
  12.  
  13. Print "Loading .wav...":Flip
  14. Global wavSound = WaveLoad("test16bits.wav") ; ONLY WORKS WITH MONO AND STEREO WAV 8 OR 16 BITS
  15.  
  16. PlaySound wavSound
  17. wavStartTime = MilliSecs()
  18.  
  19. ;------------------------------------------------------------------------------------;
  20. While Not KeyHit(1)
  21.  
  22.         Cls
  23.        
  24.         ; waveform
  25.         wavCurrentTime = MilliSecs()-wavStartTime
  26.         For channel = 0 To wavChannels-1
  27.                 For i = 0 To 800
  28.                         Plot i,75+channel*150+WaveSample(wavCurrentTime+i,channel)/500
  29.                 Next
  30.         Next
  31.        
  32.         Flip 0
  33.  
  34. Wend
  35. ;------------------------------------------------------------------------------------;
  36.  
  37. FreeSound wavSound
  38. FreeBank wavBank
  39.  
  40. End
  41.  
  42. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  43. Function WaveLoad(wavPath$)
  44.  
  45.         If FileType(wavPath) = 1
  46.                 wavBank = CreateBank(FileSize(wavPath))
  47.                 wavFile = OpenFile(wavPath)
  48.                 ReadBytes wavBank,wavFile,0,FileSize(wavPath)
  49.                 CloseFile wavFile
  50.         Else
  51.                 Return 0
  52.         EndIf
  53.  
  54.         If Chr(PeekByte(wavBank,0)) + Chr(PeekByte(wavBank,1)) + Chr(PeekByte(wavBank,2)) + Chr(PeekByte(wavBank,3)) = "RIFF"
  55.        
  56.                 If PeekInt(wavBank,4)+8 = FileSize(wavPath) ; file size
  57.                
  58.                         If Chr(PeekByte(wavBank,8)) + Chr(PeekByte(wavBank,9)) + Chr(PeekByte(wavBank,10)) + Chr(PeekByte(wavBank,11)) = "WAVE"
  59.                        
  60.                                 If Chr(PeekByte(wavBank,12)) + Chr(PeekByte(wavBank,13)) + Chr(PeekByte(wavBank,14)) + Chr(PeekByte(wavBank,15)) = "fmt "
  61.        
  62.                                         If PeekInt(wavBank,16) = 16 ; bloc Size
  63.                                        
  64.                                                 If PeekShort(wavBank,20) = 1 ; PCM
  65.                                                                                                        
  66.                                                         If Chr(PeekByte(wavBank,36)) + Chr(PeekByte(wavBank,37)) + Chr(PeekByte(wavBank,38)) + Chr(PeekByte(wavBank,39)) = "data"
  67.                                                        
  68.                                                                 wavChannels = PeekShort(wavBank,22)
  69.                                                                 wavFrequency = PeekInt(wavBank,24)
  70.                                                                 wavBytePerSec = PeekInt(wavBank,28)
  71.                                                                 wavBytePerBloc = PeekShort(wavBank,32)
  72.                                                                 wavBits = PeekShort(wavBank,34)
  73.                                                                                                                                
  74.                                                                 wavDataSize = PeekInt(wavBank,40)
  75.                                                                
  76.                                                                 If wavBits <= 16 And wavChannels <= 2                                                  
  77.                                                                         wavSound = LoadSound(wavPath)
  78.                                                                         Return wavSound
  79.                                                                 Else
  80.                                                                         Return 0
  81.                                                                 EndIf
  82.                                                                
  83.                                                         EndIf
  84.                                                        
  85.                                                 EndIf
  86.                                        
  87.                                         EndIf                          
  88.                                
  89.                                 EndIf
  90.                        
  91.                         EndIf
  92.                
  93.                 EndIf
  94.                
  95.         EndIf
  96.  
  97. End Function
  98.  
  99. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  100. Function WaveSample(time,channel=0)
  101.        
  102.         offset = time*Float(wavBytePerSec)/1000/wavChannels/(wavBits/8)
  103.         If offset > wavDataSize/wavChannels/(wavBits/8) Or offset < 0 Then Return 0
  104.        
  105.         Select wavBits
  106.                 Case 8
  107.                         sample = (PeekByte(wavBank,offset*wavChannels+channel)-128)*128
  108.                 Case 16
  109.                         sample = PeekShort(wavBank,offset*wavChannels*2+channel*2)
  110.                         If sample > 32768 Then sample = sample - 65535
  111.         End Select
  112.  
  113.         Return sample
  114.  
  115. End Function


Comments :


Charrua(Posted 9 months ago)

 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
Code: [Select]
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:<a href="https://dl.dropboxusercontent.com/u/78894295/tmp1/test1.wav" target="_blank">https://dl.dropboxusercontent.com/u/78894295/tmp1/test1.wav[/url]and the exe, just in case:<a href="https://dl.dropboxusercontent.com/u/78894295/tmp1/waveload.zip" target="_blank">https://dl.dropboxusercontent.com/u/78894295/tmp1/waveload.zip[/url]modified source code:<a href="https://dl.dropboxusercontent.com/u/78894295/tmp1/waveload.bb" target="_blank">https://dl.dropboxusercontent.com/u/78894295/tmp1/waveload.bb[/url]Juan


Flanker(Posted 9 months ago)

 Thanks for the addition, I tried to do it at first but it didn't work very well.


Bobysait(Posted 9 months ago)

 Good one Flanker ^^Just a small thing :- A loaded file should not generate runtime errors, it should just return "0" if failedI 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.


Flanker(Posted 8 months ago)

 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.


Flanker(Posted 8 months ago)

 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. [/i]

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal