Hi. You can know this program from my Youtube channel. Of course, I improved it a bit, I added a frequency analyzer and offered this source code. Again, I came across several limits that I want to mention. First...
For everyone who uses ON TIMER in programming, I would like to write my experience here. The command works great, but it is such a C ++ god for QB64, because it is essentially driven by time, as the name implies. I needed to define the way the program ran so that one part of it was processed every one twentieth per second. After editing, the program started making unprecedented errors. I had to write out the contents of the fields to screen, because the caused errors was not logic. By doing so, I found out that ON TIMER simply call the subroutine even in the middle of a loop that is not complete, and then causes such errors. After I added a value validity test in the subroutine before it was processed, the program finally began to behave as expected.
That's one piece of information for everyone. One more information - 
sad for developers:. _SNDRAWLEN only works correctly if left or left and right channels are used. If I use just right channel or twice right chnnel, then _SNDRAW work not. Try it on row 152, 153 in attached example. Please use WAV file, 16 bit, stereo or attached link.
Next limit is inability to redefine the field type as needed (this is probably impossible in Basic and thus QB64 for compatibility).
It is a great pity. If it worked as expected, I'd like to. This is shown in lines 120-127.
What a pity, it is SNDRAW and its stereo which does not play as stereo. Please let developers get directions, I have minimal knowledge, but I assume that somewhere in C ++ code there will be some thing that does this. Where can I find the source code for SNDRAW? At worst, it will still be the same ...
-   
-   
- _TITLE "Celebrate your programming language with music!" 
-   
-   
-   
- INPUT "Insert WAV audio file (16 bit, stereo) name:"- ; file$ 
 
- CONST-  CACHE  = 441 '             minimal detected frequency for analyzer is 100 Hz, so this is enought value (with 44100 biterate)
 
-     subchunksize  AS LONG '      4 bytes  (lo / hi), $00000010 for PCM audio
-     format  AS STRING * 2 '      2 bytes  (0001 = standard PCM, 0101 = IBM mu-law, 0102 = IBM a-law, 0103 = IBM AVC ADPCM)
-     channels  AS INTEGER '       2 bytes  (1 = mono, 2 = stereo)
-     rate  AS LONG '              4 bytes  (sample rate, standard is 44100)
-     ByteRate  AS LONG '          4 bytes  (= sample rate * number of channels * (bits per channel /8))
-     Block  AS INTEGER '          2 bytes  (block align = number of channels * bits per sample /8)
-     Bits  AS INTEGER '           2 bytes  (bits per sample. 8 = 8, 16 = 16)
-     subchunk2  AS STRING * 4 '   4 bytes  ("data")  contains begin audio samples
-   
-   
-   
-   
-   
-   
-   
-   
-   
-   
-   
- 'REDIM scache(CACHE) AS ....  FLOAT can not be used, because is for decimaly numbers only, but program need integer values OR decimaly values! 
-   
-     'next for analyzer use 
-   
- REDIM-  sour (62) AS-  Sour  ' for visualisation
 
-   
-   
-   
- block = H.Block 
- RATE = H.rate 
- chan = H.channels 
- bits = H.Bits 
-   
- IF-  bits  <> 16 OR-  chan  <> 2 THEN BEEP- :  PRINT "QB64 limit: Your WAV format is "- ; bits;  " bits and "- ; chan;  " channels. For replaying it comment row 106 and set valid type on row 77."- :  SLEEP 3- :  SYSTEM
 
- 'STUPID BASIC LIMITS... 
-   
-   
-   
-   
- ToScreen = 1 / 1256 '3140 
-   
-   
- '---- This work NOT under QB64v1.3-------------------------  Please comment row 77 for verify! 
- '---------------------------------------------------------- 
-   
-     FrekvLeft = 0 
-     FrekvRight = 0 
-         f = f + 1 
-         lef = scache(P).Left 
-         IF-  chan  = 1 THEN-  righ  =-  lef  ELSE-  righ  =-  scache (- P )- .Right 
 
-                 lef = lef / 256 
-                 righ = righ / 256 
-                 lef = lef / RATE 
-                 righ = righ / RATE 
-             CASE 32 'values are the same (tested) 
-   
-         IF-  RATE  > 44100 THEN-  frekvence  =-  RATE  ELSE-  frekvence  = 44100
 
-         FOR-  plll  = 1 TO-  frekvence  /-  RATE 
 
-   
-         CurrentMovementL = WaveMovement(lef, lf) 
-         CurrentMovementR = WaveMovement(righ, rf) 
-         IF-  OldMovementL  = 0 THEN-  OldMovementL  =-  CurrentMovementL 
 
-         IF-  OldMovementR  = 0 THEN-  OldMovementR  =-  CurrentMovementR 
 
-         IF-  OldMovementL  <>-  CurrentMovementL  THEN-  OldMovementL  =-  CurrentMovementL: FrekvLeft  =-  FrekvLeft  + 1
 
-         IF-  OldMovementR  <>-  CurrentMovementR  THEN-  OldMovementR  =-  CurrentMovementR: FrekvRight  =-  FrekvRight  + 1
 
-   
-         lf = lef 
-         rf = righ 
-   
-   
-   
-   
- DrawTo: 
- IF-  lef  >= -1 AND-  lef  <= 1 THEN 'comment this two IF conditions for show, what ON TIMER then do.
 
-   
-             k = 0 
-             COLOR &HFFFFFF00 ', &HFFAA56D7 
-                 LINE (- EqL  + 700, 600)-(- EqL  + 708, 700), _RGB32(255),-  B  'right
 
-                 lenght = U(ff).L1 
-                 lenght2 = U(ff).L2 
-   
-                 IF-  lenght  > 95 THEN-  lenght  = 95
 
-                 IF-  lenght2  > 95 THEN-  lenght2  = 95
 
-   
-                 U(ff).L1 = 0 
-                 U(ff).L2 = 0 
-   
-                 IF-  lenght  >-  U (- ff )- .max1  THEN-  U (- ff )- .max1  =-  lenght 
 
-                 IF-  lenght  >-  U (- ff )- .X  THEN-  U (- ff )- .X  =-  lenght 
 
-                 IF-  lenght2  >-  U (- ff )- .max2  THEN-  U (- ff )- .max2  =-  lenght2 
 
-                 IF-  lenght2  >-  U (- ff )- .Y  THEN-  U (- ff )- .Y  =-  lenght2 
 
-   
-   
-                     IF-  U (- ff )- .X  <= 0 THEN-  U (- ff )- .X  = 0- : U (- ff )- .t  = 0- : U (- ff )- .max1  = 0
 
-                     IF-  U (- ff )- .max1  --  U (- ff )- .X  > 6 THEN-  U (- ff )- .max1  = 0
 
-                     IF-  U (- ff )- .Y  <= 0 THEN-  U (- ff )- .Y  = 0- : U (- ff )- .t2  = 0- : U (- ff )- .max2  = 0
 
-                     IF-  U (- ff )- .max2  --  U (- ff )- .Y  > 6 THEN-  U (- ff )- .max2  = 0
 
-   
-   
-   
-                 IF-  U (- ff )- .X  > 0 AND-  U (- ff )- .max1  THEN LINE (100 +-  ff  * 10, 700 --  U (- ff )- .max1  - 5)-(100 + (- ff  * 10) + 8, 700 --  U (- ff )- .max1 ), &HFFFF0000,-  BF 
 
-                 IF-  U (- ff )- .Y  > 0 AND-  U (- ff )- .max2  THEN LINE (800 +-  ff  * 10, 700 --  U (- ff )- .max2  - 5)-(800 + (- ff  * 10) + 8, 700 --  U (- ff )- .max2 ), &HFFFF0000,-  BF 
 
-   
-                 LINE (100 +-  ff  * 10, 700)-(100 + (- ff  * 10) + 8, 700 --  U (- ff )- .X ), ,-  BF 
 
-                 LINE (800 +-  ff  * 10, 700)-(800 + (- ff  * 10) + 8, 700 --  U (- ff )- .Y ), ,-  BF 
 
-             I = 0 
-   
-   
-   
-         lfV = (lef * 150) 
-         riV = (righ * 150) 
-   
-         X  =-  MiddleX  + SIN(- k ) *-  Radius  +-  lfV 
-         Y  =-  MiddleY  + COS(- k ) *-  Radius  +-  riV 
-         sour(I).X = X 
-         sour(I).Y = Y 
-         I = I + 1 
-   
-                     oX = sour(D - 1).X 
-                     oY = sour(D - 1).Y 
-                     nX = sour(D).X 
-                     nY = sour(D).Y 
-                 oX = sour(0).X 
-                 oY = sour(0).Y 
-                 nX = sour(62).X 
-                 nY = sour(62).Y 
-                     oX = sour(D - 1).X 
-                     oY = sour(D - 1).Y 
-                     nX = sour(D).X 
-                     nY = sour(D).Y 
-   
-                     iiX  =-  mIx  + SIN(- D  / 10) *-  mIx 
-                     iiY  =-  mIh  + COS(- D  / 10) *-  mIh 
-                     oiX  =-  mIx  + SIN((- D  - 1) / 10) *-  mIx 
-                     oiY  =-  mIh  + COS((- D  - 1) / 10) *-  mIh 
-                     _MAPTRIANGLE (- iiX ,-  iiY )-(- oiX ,-  oiY )-(- mIx ,-  mIh ),-  image&  TO(- oX ,-  oY )-(- nX ,-  nY )-(- mmIx ,-  mmiY ),-  Virtual& 
 
-                 oX = sour(0).X 
-                 oY = sour(0).Y 
-                 nX = sour(62).X 
-                 nY = sour(62).Y 
-   
-                 oiX  =-  mIx  + SIN(6.2) *-  mIx 
-                 oiY  =-  mIh  + COS(6.2) *-  mIh 
-                 _MAPTRIANGLE (- iiX ,-  iiY )-(- oiX ,-  oiY )-(- mIx ,-  mIh ),-  image&  TO(- oX ,-  oY )-(- nX ,-  nY )-(- mmIx ,-  mmiY ),-  Virtual& 
 
-   
-   
-         text$ = "Example how visualise music in QB64.    Writed Petr Preclik." 
-   
-   
- analyzer: 
- FrekvL = FrekvLeft * 100: lf = 0 
- FrekvR = FrekvRight * 100: rf = 0 
-   
- U(sh).L1 = U(sh).L1 + .09 
-   
-   
- U(sh2).L2 = U(sh2).L2 + .09 
-   
- FUNCTION-  WaveMovement  (- New_Value ,-  Old_Value ) ' Tested with WAV from 100 Hz to 20 KHz and return correct outputs (see row 156 to 164, previous signal values on row 163, 164 are needed)
 
-     IF-  New_Value  >-  Old_Value  THEN-  WaveMovement  = 1
 
-     IF-  New_Value  <-  Old_Value  THEN-  WaveMovement  = -1
 
-   
If you need, download WAV file from 
https://drive.google.com/file/d/10HBu8_QD_fBRc_JO3P3K_iPZVSE-7O-_/view?usp=sharing