Page 2 of 2

Re: WavForm of a sound in WAV format

Posted: Thu Aug 08, 2013 9:33 pm
by eddy
kvitaliy wrote:Doesn't support Unicode :(
Updated
- fixed structure : I replaced .s{4} by .a[4] (ASCII properties)
- added methods to manipulate ASCII string : ReadWavString / WriteWavString

Re: WavForm of a sound in WAV format

Posted: Thu Aug 08, 2013 11:35 pm
by gally
Hello,

Here is a small correction to the real-time play. The code :

Code: Select all

      ;
      ; DECLARATION.
      ;
      Protected fpos.f
      ;
      ; THE CORRECTION.
      ;
      If play
        i    = GetSoundPosition(0, #PB_Sound_Frame)
        j    = SoundLength (0, #PB_Sound_Frame)
        fpos = w / j
        DrawingMode(#PB_2DDrawing_AlphaBlend)
        Box((fpos * (i * z)) - p - 2, 0, 4, h, RGBA(0, 0, 200, 100))
        DrawingMode(#PB_2DDrawing_Transparent)
        DrawText(6, 1, FormatDate("%hh:%ii:%ss", GetSoundPosition(0, #PB_Sound_Millisecond)  / 1000), $000000)
      EndIf
Best Regards,
GallyHC

Re: WavForm of a sound in WAV format

Posted: Fri Aug 09, 2013 2:41 pm
by gally
Juste a moving form to real play :)

Code: Select all

; +======================================================+
; | ROUTINE DE CHARGEMENT DU FORMAT WAV (SPECTRE DU SON) |
; +------------------------------------------------------+
; | COPYRIGHT(C)2007-2012, ALL RIGHT RESERVED KOAKDESIGN |
; +--------------+---------------------------------------+
; | Program type | PUREBASIC 5.2b8                        |
; +--------------+---------------------------------------+
; | VER & REV    | 0.0.4                                 |
; +--------------+---------------------------------------+
; | Comments:    | unicode supported, realtime scroll    |
; +--------------+                                       |
; |                                                      |
; +======================================================+

; +======================================================+
; | Original Version: 0.0.3                              |
; +--------------+---------------------------------------+
; | Created by   | GallyHomeCorp                         |
; | Graphix by   | GallyHomeCorp                         |
; +--------------+---------------------------------------+
; | Comments:    |                                       |
; +--------------+                                       |
; |                                                      |
; +======================================================+

; +======================================================+
; | OS System
; +--------------+---------------------------------------+
; | Window       | Oui                                   |
; | Linux        | Oui                                   |
; | MacOS        | Oui                                   |
; +======================================================+

; ****************************************************************************
; ****************************************************************************

EnableExplicit

; ****************************************************************************
; ****************************************************************************

Declare.b OpenWAVFile(filename.s, x, y, w, h, z = 1)
Declare.b DrawWAVFile(x, y, w, h, z = 1, p = 0, play.b = #False)
Declare ScrollWAVImage()

; ****************************************************************************
; ****************************************************************************

Structure WaveFileHeader
   chunkid.a[4]
   chunksize.l
   format.a[4]
   fmtchunkid.a[4]
   fmtchunksize.l
   audioformat.u
   numchannels.u
   samplerate.l
   byterate.l
   blockalign.u
   bitspersample.u
   datachunkid.a[4]
   datachunksize.l
EndStructure

Global sFileName.s
Global Dim tabWaveLenA.a(1)
Global Dim tabWaveLenB.w(1)
Global tabWaveFile.WaveFileHeader

; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************

; +--------------------------------------------------------------------------+
; |                                                                          |
; +--------------------------------------------------------------------------+

Macro ReadWavString(structProperty)
   LSet(PeekS(@structProperty, 4, #PB_Ascii), 4, " ")
EndMacro
Macro WriteWavString(structProperty, value)
   PokeS(@structProperty, value, 4, #PB_Ascii)
EndMacro 

Procedure.b OpenWAVFile(filename.s, x, y, w, h, z = 1)
   ; ROUTINE DE CHARGEMENT DU HEADER DU WAV.
   Protected i
   Protected file
   Protected flen
   Protected dlen
   Protected load.b = #False
   Protected lDataChunk
   Protected datachunkid.s{4}
   
   file = ReadFile(#PB_Any, filename)
   If file <> 0
      sFileName = filename
      flen = Lof(file)
      ReadData(file, tabWaveFile, SizeOf(WaveFileHeader))
      If ReadWavString(tabWaveFile\datachunkid) <> "data"
         For i = 0 To 2048 Step 2
            FileSeek(file, (SizeOf(WaveFileHeader)- 6)+ i)
            ReadData(file, @datachunkid, 4)
            If datachunkid = "data"
               lDataChunk = i + 2
               WriteWavString(tabWaveFile\datachunkid, "data")
               tabWaveFile\datachunksize = ReadLong(file)
               Break
            EndIf
         Next i
      EndIf
      ReDim tabWaveLenA(1)
      ReDim tabWaveLenB(1)
      If ReadWavString(tabWaveFile\chunkid) = "RIFF" And
         ReadWavString(tabWaveFile\format) = "WAVE" And
         ReadWavString(tabWaveFile\fmtchunkid) = "fmt " And
         ReadWavString(tabWaveFile\datachunkid) = "data" And tabWaveFile\DataChunkSize > 44
         dlen = tabWaveFile\DataChunkSize / tabWaveFile\BlockAlign
         Select tabWaveFile\BitsPerSample
            Case 8
               Select tabWaveFile\NumChannels
                  Case 1
                     load = #True
                     ReDim tabWaveLenA(dlen)
                  Case 2
                     load = #True
                     ReDim tabWaveLenA(dlen * 2)
               EndSelect
               If load = #True
                  FileSeek(file, SizeOf(WaveFileHeader)+ lDataChunk)
                  If ReadData(file, @tabWaveLenA(), tabWaveFile\DataChunkSize)= tabWaveFile\DataChunkSize
                     DrawWAVFile(x, y, w, h, z)
                  EndIf
               EndIf
            Case 16
               Select tabWaveFile\NumChannels
                  Case 1
                     load = #True
                     ReDim tabWaveLenB(dlen)
                  Case 2
                     load = #True
                     ReDim tabWaveLenB(dlen * 2)
               EndSelect
               If load = #True
                  FileSeek(file, SizeOf(WaveFileHeader)+ lDataChunk)
                  If ReadData(file, @tabWaveLenB(), tabWaveFile\DataChunkSize)= tabWaveFile\DataChunkSize
                     DrawWAVFile(x, y, w, h, z)
                  EndIf
               EndIf
         EndSelect
      EndIf
      CloseFile(file)
   EndIf
   ProcedureReturn #True
   
EndProcedure

Procedure.s GetWAVTime()
   ; ROUTINE DE RECUPERATION DU TEMPS DU WAV.
   ProcedureReturn FormatDate("%hh:%ii:%ss", Round((tabWaveFile\DataChunkSize / tabWaveFile\ByteRate)- 0.3, #PB_Round_Nearest))
   
EndProcedure

Procedure.l ParseWavTime(date.s, val)
   ; ROUTINE DE DECOUPAGE DU TEMPS DU WAV.
   If val < 1
      val = 1
   EndIf
   If val > 3
      val = 3
   EndIf
   ProcedureReturn Val(StringField(date, val, ":"))
   
EndProcedure

Procedure GetWavInformation()
   ; ROUTINE DE DECOUPAGE DU TEMPS DU WAV.
   Protected stemp.s
   stemp = "ChunkID : " + tabWaveFile\chunkid +
           #CRLF$ + "ChunkSize : " + Str(tabWaveFile\ChunkSize)+ " Octets" +
           #CRLF$ + "Format : " + ReadWavString(tabWaveFile\Format) +
           #CRLF$ + "fmtChunkID : " + ReadWavString(tabWaveFile\fmtChunkID) +
           #CRLF$ + "FmtChunkSize : " + Str(tabWaveFile\FmtChunkSize)+ " Octets" +
           #CRLF$ + "Format : " + Str(tabWaveFile\AudioFormat)+
           #CRLF$ + "Channels : " + Str(tabWaveFile\NumChannels)+
           #CRLF$ + "SampleRate : " + Str(tabWaveFile\SampleRate)+ " Hz" +
           #CRLF$ + "BitsRate : " + Str(tabWaveFile\ByteRate)+
           #CRLF$ + "BlockAlign : " + Str(tabWaveFile\BlockAlign)+
           #CRLF$ + "BitsPerSample : " + Str(tabWaveFile\BitsPerSample)+
           #CRLF$ + "DataChunkID : " + ReadWavString(tabWaveFile\DataChunkID) +
           #CRLF$ + "DataChunkSize : " + Str(tabWaveFile\DataChunkSize)+ " Octets" +
           #CRLF$ + #CRLF$ + "Temps Total : " + GetWAVTime()
   MessageRequester("PureWav", stemp, #PB_MessageRequester_Ok)
   
EndProcedure

Procedure.b DrawWAVFile(x, y, w, h, z = 1, p = 0, play.b = #False)
   ; ROUTINE DE TRACAGE DU SPECTRE DU WAV.
   Protected i
   Protected j
   Protected dlen
   Protected lpas
   Protected ysav
   Protected zsav
   Protected lpos
   Protected fpos.f
   Protected time.s = GetWAVTime()
   Protected lsec.f = w / ((ParseWavTime(time, 1) * 3600) + (ParseWavTime(time, 2) * 60) + ParseWavTime(time, 3))
   
   If z < 1
      z = 1
   EndIf
   If z > 16
      z = 16
   EndIf
   If ReadWavString(tabWaveFile\chunkid)<> "RIFF" Or
      ReadWavString(tabWaveFile\format)<> "WAVE" Or
      ReadWavString(tabWaveFile\fmtchunkid) <> "fmt "
      ProcedureReturn #False
   EndIf
   If tabWaveFile\DataChunkSize < 1
      ProcedureReturn #False
   EndIf
   
   ;
   ; (Test) Moving real play
   ;
      If play
        i    = GetSoundPosition(0, #PB_Sound_Frame)
        j    = SoundLength (0, #PB_Sound_Frame)
        fpos = w / j
        If fpos * (i * z) - p => w / 2 And GetGadgetAttribute(1, #PB_ScrollBar_Maximum) > 1 And GetGadgetAttribute(1, #PB_ScrollBar_Maximum) > GetGadgetState(1)
          
          Debug GetGadgetAttribute(1, #PB_ScrollBar_Maximum)
          Debug GetGadgetState(1)
          Debug "------------------"
          
          SetGadgetState(1, GetGadgetState(1) + 1)
          ScrollWAVImage()
          ProcedureReturn #False
        EndIf
      EndIf
   ;
   ; (Test) Moving real play
   ;
   
   
   If StartDrawing(CanvasOutput(0))
      Box(0, 0, w, h, $FFFFFF)
      dlen = tabWaveFile\DataChunkSize / tabWaveFile\BlockAlign
      Select tabWaveFile\NumChannels
         Case 1
            lpas =(dlen / w)/ z
            lpos =((dlen / lpas)- w)
            If p > lpos
               p = lpos
            EndIf
            Select tabWaveFile\BitsPerSample
               Case 8
                  ysav = tabWaveLenA(0)- 128
                  LineXY(0, (h / 6), w, (h / 6), $BBBBBB)
                  LineXY(0, h -(h / 6), w, h -(h / 6), $BBBBBB)
                  For i = 0 To w
                     For j = 1 To lpas Step 1
                        j +(128 -(z * 4))
                        If ((i + p)* lpas)+ j < dlen - 1
                           LineXY(i, (h / 2)- ysav, i, (h / 2)-(tabWaveLenA(((i + p)* lpas)+ j)- 128), $e8a200 +((i * 255)/ w))
                           ysav =(tabWaveLenA(((i + p)* lpas)+ j)- 128)
                        EndIf
                     Next j
                     LineXY(i, (h / 2), i, (h / 2), $CC8E00 +((i * 255)/ w))
                  Next i
               Case 16
                  ysav = tabWaveLenB(0)/(h / 1.5)
                  LineXY(0, (h / 6), w, (h / 6), $BBBBBB)
                  LineXY(0, h -(h / 6), w, h -(h / 6), $BBBBBB)
                  For i = 0 To w
                     For j = 1 To lpas Step 1
                        j +(128 -(z * 4))
                        If ((i + p)* lpas)+ j < dlen - 1
                           LineXY(i, (h / 2)- ysav, i, (h / 2)-(tabWaveLenB(((i + p)* lpas)+ j)/(h / 1.5)), $e8a200 +((i * 255)/ w))
                           ysav = tabWaveLenB(((i + p)* lpas)+ j)/(h / 1.5)
                        EndIf
                     Next j
                     LineXY(i, (h / 2), i, (h / 2), $CC8E00 +((i * 255)/ w))
                  Next i
            EndSelect
         Case 2
            lpas =((dlen / w)* 2)/ z
            lpos =((dlen / lpas)* 2)- w
            If p > lpos
               p = lpos
            EndIf
            Select tabWaveFile\BitsPerSample
               Case 8
                  ysav = tabWaveLenA(1)- 128
                  ysav = tabWaveLenA(0)- 128
                  LineXY(0, (h / 12), w, (h / 12), $BBBBBB)
                  LineXY(0, (h / 2)-(h / 12), w, (h / 2)-(h / 12), $BBBBBB)
                  LineXY(0, (h / 2)+(h / 12), w, (h / 2)+(h / 12), $BBBBBB)
                  LineXY(0, h -(h / 12), w, h -(h / 12), $BBBBBB)
                  For i = 0 To w
                     For j = 1 To lpas Step 1
                        j + (128 - (z * 4))
                        If ((i + p)* lpas)+ j <(dlen * 2)- 1
                           LineXY(i, (h / 4)- ysav, i, (h / 4)-(tabWaveLenA(((i + p)* lpas)+ j + 1)- 128), $e8a200 +((i * 255)/ w))
                           ysav =(tabWaveLenA(((i + p)* lpas)+ j + 1)- 128)
                           LineXY(i, h -(h / 4)- zsav, i, h -(h / 4)-(tabWaveLenA(((i + p)* lpas)+ j)- 128), $e8a200 +((i * 255)/ w))
                           zsav =(tabWaveLenA(((i + p)* lpas)+ j)- 128)
                        EndIf
                     Next j
                     LineXY(i, (h / 4), i, (h / 4), $CC8E00 +((i * 255)/ w))
                     LineXY(i, h -(h / 4), i, h -(h / 4), $CC8E00 +((i * 255)/ w))
                  Next i
                  LineXY(0, (h / 2), w, (h / 2), $222222)
               Case 16
                  ysav = tabWaveLenB(1)/(h / 0.9)
                  zsav = tabWaveLenB(0)/(h / 0.9)
                  LineXY(0, (h / 12), w, (h / 12), $BBBBBB)
                  LineXY(0, (h / 2)-(h / 12), w, (h / 2)-(h / 12), $BBBBBB)
                  LineXY(0, (h / 2)+(h / 12), w, (h / 2)+(h / 12), $BBBBBB)
                  LineXY(0, h -(h / 12), w, h -(h / 12), $BBBBBB)
                  For i = 0 To w
                     For j = 1 To lpas Step 1
                        j +(128 -(z * 4))
                        If ((i + p)* lpas)+ j <(dlen * 2)- 1
                           LineXY(i, (h / 4)- ysav, i, (h / 4)-(tabWaveLenB(((i + p)* lpas)+ j + 1)/(h / 0.6)), $e8a200 +((i * 255)/ w))
                           ysav = tabWaveLenB(((i + p)* lpas)+ j + 1)/(h / 0.6)
                           LineXY(i, h -(h / 4)- zsav, i, h -(h / 4)-(tabWaveLenB(((i + p)* lpas)+ j)/(h / 0.6)), $e8a200 +((i * 255)/ w))
                           zsav = tabWaveLenB(((i + p)* lpas)+ j)/(h / 0.6)
                        EndIf
                     Next j
                     LineXY(i, (h / 4), i, (h / 4), $CC8E00 +((i * 255)/ w))
                     LineXY(i, h -(h / 4), i, h -(h / 4), $CC8E00 +((i * 255)/ w))
                  Next i
                  LineXY(0, (h / 2), w, (h / 2), $222222)
            EndSelect
      EndSelect
      If play
        i    = GetSoundPosition(0, #PB_Sound_Frame)
        j    = SoundLength (0, #PB_Sound_Frame)
        fpos = w / j
        DrawingMode(#PB_2DDrawing_AlphaBlend)
        Box((fpos * (i * z)) - p - 2, 0, 4, h, RGBA(0, 0, 200, 100))
        DrawingMode(#PB_2DDrawing_Transparent)
        DrawText(6, 1, FormatDate("%hh:%ii:%ss", GetSoundPosition(0, #PB_Sound_Millisecond)  / 1000), $000000)
      EndIf
      j = 0
      DrawingMode(#PB_2DDrawing_Transparent)
      If Round((tabWaveFile\DataChunkSize / tabWaveFile\ByteRate)- 0.3, #PB_Round_Nearest)> 1
         For i = 1 To(w * z)
            j + 1
            i + (lsec * 30) * z
            If i - p => 0 And i - p <= w
               LineXY(i - p, 0, i - p, h, $0000AA)
               DrawText((i - p)- 60, h - 15, FormatDate("%hh:%ii:%ss", (j * 30)), $0000AA)
            EndIf
         Next i
      EndIf
      DrawText(w - 60, 1, time, $000000)
      StopDrawing()
      If z = 1
         SetGadgetState(1, 0)
      EndIf
      SetGadgetAttribute(1, #PB_ScrollBar_Maximum, lpos)
      ProcedureReturn #True
   EndIf
   
   
EndProcedure

; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************

; +--------------------------------------------------------------------------+
; |                                                                          |
; +--------------------------------------------------------------------------+

If Not InitSound()
   MessageRequester("Initialize the sound environment", "No sound supported!")
   End
EndIf

; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************

; +--------------------------------------------------------------------------+
; |                                                                          |
; +--------------------------------------------------------------------------+

Global zoom.l = 1
Global pos.l = 0
Global play.b = #False

Procedure ScrollWAVImage()
   pos = GetGadgetState(1)
   DrawWAVFile(0, 0, 800, 256, zoom, pos, play)
 EndProcedure
 
Procedure ZoomWAVImage()
   Select EventGadget()
      Case 5
         zoom - 1
         If zoom < 2
            pos = 0
         EndIf
         If zoom < 1
            zoom = 1
         EndIf
      Case 6
         zoom + 1
         If zoom > 16
            zoom = 16
         EndIf
   EndSelect
   DrawWAVFile(0, 0, 800, 256, zoom, pos)
EndProcedure
Procedure LoadAndPlayWAVSound()
   Select EventGadget()
      Case 2
         OpenWAVFile(OpenFileRequester("Ouvrir un archive Wav", "", "Musique Wav|*.wav", 0), 0, 0, 800, 256, zoom)
         GetWavInformation()
      Case 3
         If LoadSound(0, sFileName)
            PlaySound(0)
         EndIf
      Case 4
         If IsSound(0)
            StopSound(0)
         EndIf
   EndSelect
EndProcedure

If OpenWindow(0, 0, 0, 800, 400, "PureWav", #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
   CanvasGadget(0, 0, 0, 800, 256, 0)
   ScrollBarGadget(1, 0, 257, 800, 18, 1, 1, 1000)
   ButtonGadget(2, 10, 300, 100, 32, "Fichier Wav")
   ButtonGadget(3, 120, 300, 100, 32, "Play")
   ButtonGadget(4, 230, 300, 100, 32, "Stop")
   ButtonGadget(5, 10, 340, 100, 32, "Zoom -")
   ButtonGadget(6, 120, 340, 100, 32, "Zoom +")
   BindGadgetEvent(1, @ScrollWAVImage())
   BindGadgetEvent(2, @LoadAndPlayWAVSound())
   BindGadgetEvent(3, @LoadAndPlayWAVSound())
   BindGadgetEvent(4, @LoadAndPlayWAVSound())
   BindGadgetEvent(5, @ZoomWAVImage())
   BindGadgetEvent(6, @ZoomWAVImage())
   Repeat      
      play=Bool(IsSound(0) And SoundStatus(0)=#PB_Sound_Playing)
      DrawWAVFile(0, 0, 800, 256, zoom, pos, play)      
   Until WaitWindowEvent(1)= #PB_Event_CloseWindow
EndIf
Best Regards,
GallyHC

Re: WavForm of a sound in WAV format

Posted: Sat Aug 10, 2013 4:39 am
by kvitaliy
gally wrote: ; | Program type | PUREBASIC 5.2b8 |
; +--------------+---------------------------------------+
; | VER & REV | 0.0.4 |
; +--------------+---------------------------------------+
; | Comments: | unicode supported, realtime scroll |
;
unicode mode on : Error line 282, Array index out of bounds
unicode mode off: Ok!

Re: WavForm of a sound in WAV format

Posted: Sat Aug 10, 2013 5:05 am
by IdeasVacuum
Seems to be working fine, compiled Unicode, PB5.20 Beta8, WinXP x86.

Re: WavForm of a sound in WAV format

Posted: Mon Aug 12, 2013 2:36 pm
by gally
Hello,

Just a little correction...

Code: Select all

; +======================================================+
; | ROUTINE DE CHARGEMENT DU FORMAT WAV (SPECTRE DU SON) |
; +------------------------------------------------------+
; | COPYRIGHT(C)2007-2012, ALL RIGHT RESERVED KOAKDESIGN |
; +--------------+---------------------------------------+
; | Program type | PUREBASIC 5.2b8                        |
; +--------------+---------------------------------------+
; | VER & REV    | 0.0.3                                 |
; +--------------+---------------------------------------+
; | Comments:    | unicode supported, realtime scroll    |
; +--------------+                                       |
; |                                                      |
; +======================================================+

; +======================================================+
; | Original Version: 0.0.2                              |
; +--------------+---------------------------------------+
; | Created by   | GallyHomeCorp                         |
; | Graphix by   | GallyHomeCorp                         |
; +--------------+---------------------------------------+
; | Comments:    |                                       |
; +--------------+                                       |
; |                                                      |
; +======================================================+

; +======================================================+
; | OS System
; +--------------+---------------------------------------+
; | Window       | Oui                                   |
; | Linux        | Oui                                   |
; | MacOS        | Oui                                   |
; +======================================================+

; ****************************************************************************
; ****************************************************************************

EnableExplicit

; ****************************************************************************
; ****************************************************************************

Declare.b OpenWAVFile(filename.s, x, y, w, h, z = 1)
Declare.b DrawWAVFile(x, y, w, h, z = 1, p = 0, play.b = #False)
Declare ScrollWAVImage()

; ****************************************************************************
; ****************************************************************************

Structure WaveFileHeader
   chunkid.a[4]
   chunksize.l
   format.a[4]
   fmtchunkid.a[4]
   fmtchunksize.l
   audioformat.u
   numchannels.u
   samplerate.l
   byterate.l
   blockalign.u
   bitspersample.u
   CompilerIf #PB_Compiler_Unicode = 1
      bitformatextra.u
   CompilerEndIf
   datachunkid.a[4]
   datachunksize.l
EndStructure

Global sFileName.s
Global Dim tabWaveLenA.a(1)
Global Dim tabWaveLenB.w(1)
Global tabWaveFile.WaveFileHeader

; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************

; +--------------------------------------------------------------------------+
; |                                                                          |
; +--------------------------------------------------------------------------+

Macro ReadWavString(structProperty)
   LSet(PeekS(@structProperty, 4, #PB_Ascii), 4, " ")
EndMacro
Macro WriteWavString(structProperty, value)
   PokeS(@structProperty, value, 4, #PB_Ascii)
EndMacro 

Procedure.b OpenWAVFile(filename.s, x, y, w, h, z = 1)
   ; ROUTINE DE CHARGEMENT DU HEADER DU WAV.
   Protected i
   Protected file
   Protected flen
   Protected dlen
   Protected load.b = #False
   Protected lDataChunk
   Protected datachunkid.s{4}
   
   file = ReadFile(#PB_Any, filename)
   If file <> 0
      sFileName = filename
      flen = Lof(file)
      ReadData(file, tabWaveFile, SizeOf(WaveFileHeader))
      If ReadWavString(tabWaveFile\datachunkid) <> "data"
         For i = 0 To 2048 Step 2
            FileSeek(file, (SizeOf(WaveFileHeader)- 6)+ i)
            ReadData(file, @datachunkid, 4)
            If datachunkid = "data"
               lDataChunk = i + 2
               WriteWavString(tabWaveFile\datachunkid, "data")
               tabWaveFile\datachunksize = ReadLong(file)
               Break
            EndIf
         Next i
      EndIf
      ReDim tabWaveLenA(1)
      ReDim tabWaveLenB(1)
      If ReadWavString(tabWaveFile\chunkid) = "RIFF" And
         ReadWavString(tabWaveFile\format) = "WAVE" And
         ReadWavString(tabWaveFile\fmtchunkid) = "fmt " And
         ReadWavString(tabWaveFile\datachunkid) = "data" And tabWaveFile\DataChunkSize > 44
         dlen = tabWaveFile\DataChunkSize / tabWaveFile\BlockAlign
         Select tabWaveFile\BitsPerSample
            Case 8
               Select tabWaveFile\NumChannels
                  Case 1
                     load = #True
                     ReDim tabWaveLenA(dlen)
                  Case 2
                     load = #True
                     ReDim tabWaveLenA(dlen * 2)
               EndSelect
               If load = #True
                  FileSeek(file, SizeOf(WaveFileHeader)+ lDataChunk)
                  If ReadData(file, @tabWaveLenA(), tabWaveFile\DataChunkSize)= tabWaveFile\DataChunkSize
                     DrawWAVFile(x, y, w, h, z)
                  EndIf
               EndIf
            Case 16
               Select tabWaveFile\NumChannels
                  Case 1
                     load = #True
                     ReDim tabWaveLenB(dlen)
                  Case 2
                     load = #True
                     ReDim tabWaveLenB(dlen * 2)
               EndSelect
               If load = #True
                  FileSeek(file, SizeOf(WaveFileHeader)+ lDataChunk)
                  If ReadData(file, @tabWaveLenB(), tabWaveFile\DataChunkSize)= tabWaveFile\DataChunkSize
                     DrawWAVFile(x, y, w, h, z)
                  EndIf
               EndIf
         EndSelect
      EndIf
      CloseFile(file)
   EndIf
   ProcedureReturn #True
   
EndProcedure

Procedure.s GetWAVTime()
   ; ROUTINE DE RECUPERATION DU TEMPS DU WAV.
   ProcedureReturn FormatDate("%hh:%ii:%ss", Round((tabWaveFile\DataChunkSize / tabWaveFile\ByteRate)- 0.3, #PB_Round_Nearest))
   
EndProcedure

Procedure.l ParseWavTime(date.s, val)
   ; ROUTINE DE DECOUPAGE DU TEMPS DU WAV.
   If val < 1
      val = 1
   EndIf
   If val > 3
      val = 3
   EndIf
   ProcedureReturn Val(StringField(date, val, ":"))
   
EndProcedure

Procedure GetWavInformation()
   ; ROUTINE DE DECOUPAGE DU TEMPS DU WAV.
   Protected stemp.s
   stemp = "ChunkID : " + tabWaveFile\chunkid +
           #CRLF$ + "ChunkSize : " + Str(tabWaveFile\ChunkSize)+ " Octets" +
           #CRLF$ + "Format : " + ReadWavString(tabWaveFile\Format) +
           #CRLF$ + "fmtChunkID : " + ReadWavString(tabWaveFile\fmtChunkID) +
           #CRLF$ + "FmtChunkSize : " + Str(tabWaveFile\FmtChunkSize)+ " Octets" +
           #CRLF$ + "Format : " + Str(tabWaveFile\AudioFormat)+
           #CRLF$ + "Channels : " + Str(tabWaveFile\NumChannels)+
           #CRLF$ + "SampleRate : " + Str(tabWaveFile\SampleRate)+ " Hz" +
           #CRLF$ + "BitsRate : " + Str(tabWaveFile\ByteRate)+
           #CRLF$ + "BlockAlign : " + Str(tabWaveFile\BlockAlign)+
           #CRLF$ + "BitsPerSample : " + Str(tabWaveFile\BitsPerSample)+
           #CRLF$ + "DataChunkID : " + ReadWavString(tabWaveFile\DataChunkID) +
           #CRLF$ + "DataChunkSize : " + Str(tabWaveFile\DataChunkSize)+ " Octets" +
           #CRLF$ + #CRLF$ + "Temps Total : " + GetWAVTime()
   MessageRequester("PureWav", stemp, #PB_MessageRequester_Ok)
   
EndProcedure

Procedure.b DrawWAVFile(x, y, w, h, z = 1, p = 0, play.b = #False)
   ; ROUTINE DE TRACAGE DU SPECTRE DU WAV.
   Protected i
   Protected j
   Protected dlen
   Protected lpas
   Protected ysav
   Protected zsav
   Protected lpos
   Protected fpos.f
   Protected time.s = GetWAVTime()
   Protected lsec.f = w / ((ParseWavTime(time, 1) * 3600) + (ParseWavTime(time, 2) * 60) + ParseWavTime(time, 3))
   
   If z < 1
     z = 1
     ProcedureReturn #False
   EndIf
   If z > 16
      z = 16
     ProcedureReturn #False
   EndIf
   If ReadWavString(tabWaveFile\chunkid)<> "RIFF" Or
      ReadWavString(tabWaveFile\format)<> "WAVE" Or
      ReadWavString(tabWaveFile\fmtchunkid) <> "fmt " Or
      ReadWavString(tabWaveFile\datachunkid) <> "data"
      ProcedureReturn #False
   EndIf
   If tabWaveFile\DataChunkSize < 1
      ProcedureReturn #False
   EndIf
   
   ;
   ; (Test) Moving real play
   ;
  If play
    i    = GetSoundPosition(0, #PB_Sound_Frame)
    j    = SoundLength (0, #PB_Sound_Frame)
    fpos = w / j
    If fpos * (i * z) - p => w / 2 And GetGadgetAttribute(1, #PB_ScrollBar_Maximum) > 1 And GetGadgetAttribute(1, #PB_ScrollBar_Maximum) > GetGadgetState(1)
      SetGadgetState(1, GetGadgetState(1) + 1)
      ScrollWAVImage()
      ProcedureReturn #False
    EndIf
  EndIf
   ;
   ; (Test) Moving real play
   ;
   
   
   If StartDrawing(CanvasOutput(0))
      Box(0, 0, w, h, $FFFFFF)
      dlen = tabWaveFile\DataChunkSize / tabWaveFile\BlockAlign
      Select tabWaveFile\NumChannels
         Case 1
            lpas =(dlen / w)/ z
            lpos =((dlen / lpas)- w)
            If p > lpos
               p = lpos
            EndIf
            Select tabWaveFile\BitsPerSample
               Case 8
                  ysav = tabWaveLenA(0)- 128
                  LineXY(0, (h / 6), w, (h / 6), $BBBBBB)
                  LineXY(0, h -(h / 6), w, h -(h / 6), $BBBBBB)
                  For i = 0 To w
                     For j = 1 To lpas Step 4
                        j + (128 - (z * 4))
                        If ((i + p) * lpas) + j < dlen - 1
                           LineXY(i, (h / 2) - ysav, i, (h / 2) - (tabWaveLenA(((i + p) * lpas) + j) - 128), $e8a200 + ((i * 255) / w))
                           ysav =(tabWaveLenA(((i + p) * lpas) + j) - 128)
                        EndIf
                     Next j
                     LineXY(i, h / 2, i, h / 2, $CC8E00 + ((i * 255)/ w))
                  Next i
               Case 16
                  ysav = tabWaveLenB(0)/(h / 1.5)
                  LineXY(0, (h / 6), w, (h / 6), $BBBBBB)
                  LineXY(0, h - (h / 6), w, h - (h / 6), $BBBBBB)
                  For i = 0 To w
                     For j = 1 To lpas Step 4
                        j + (128 -(z * 4))
                        If ((i + p) * lpas) + j < dlen - 1
                           LineXY(i, (h / 2) - ysav, i, (h / 2) - (tabWaveLenB(((i + p) * lpas) + j) / (h / 1.5)), $e8a200 + ((i * 255)/ w))
                           ysav = tabWaveLenB(((i + p) * lpas) + j) / (h / 1.5)
                        EndIf
                     Next j
                     LineXY(i, h / 2, i, h / 2, $CC8E00 + ((i * 255)/ w))
                  Next i
            EndSelect
         Case 2
            lpas = ((dlen / w) * 2) / z
            lpos = ((dlen / lpas)* 2) - w
            If p > lpos
               p = lpos
            EndIf
            Select tabWaveFile\BitsPerSample
               Case 8
                  ysav = tabWaveLenA(1)- 128
                  ysav = tabWaveLenA(0)- 128
                  LineXY(0, (h / 12), w, (h / 12), $BBBBBB)
                  LineXY(0, (h / 2) - (h / 12), w, (h / 2) - (h / 12), $BBBBBB)
                  LineXY(0, (h / 2) + (h / 12), w, (h / 2) + (h / 12), $BBBBBB)
                  LineXY(0, h - (h / 12), w, h - (h / 12), $BBBBBB)
                  For i = 0 To w
                     For j = 1 To lpas Step 4
                        j + (128 - (z * 4))
                        If ((i + p) * lpas) + j < (dlen * 2) - 1
                           LineXY(i, (h / 4) - ysav, i, (h / 4) - (tabWaveLenA(((i + p) * lpas) + j + 1) - 128), $e8a200 + ((i * 255) / w))
                           ysav = (tabWaveLenA(((i + p) * lpas) + j + 1) - 128)
                           LineXY(i, h - (h / 4) - zsav, i, h - (h / 4) - (tabWaveLenA(((i + p) * lpas) + j)- 128), $e8a200 + ((i * 255) / w))
                           zsav = (tabWaveLenA(((i + p) * lpas) + j) - 128)
                        EndIf
                     Next j
                     LineXY(i, h / 4, i, h / 4, $CC8E00 + ((i * 255)/ w))
                     LineXY(i, h - (h / 4), i, h - (h / 4), $CC8E00 + ((i * 255)/ w))
                  Next i
                  LineXY(0, (h / 2), w, (h / 2), $222222)
               Case 16
                  ysav = tabWaveLenB(1)/(h / 0.9)
                  zsav = tabWaveLenB(0)/(h / 0.9)
                  LineXY(0, (h / 12), w, (h / 12), $BBBBBB)
                  LineXY(0, (h / 2) - (h / 12), w, (h / 2) - (h / 12), $BBBBBB)
                  LineXY(0, (h / 2) + (h / 12), w, (h / 2) + (h / 12), $BBBBBB)
                  LineXY(0, h -(h / 12), w, h - (h / 12), $BBBBBB)
                  For i = 0 To w
                     For j = 1 To lpas Step 4
                        j + (128 - (z * 4))
                        If ((i + p) * lpas) + j < (dlen * 2) - 1
                           LineXY(i, (h / 4) - ysav, i, (h / 4) - (tabWaveLenB(((i + p) * lpas) + j + 1) / (h / 0.6)), $e8a200 + ((i * 255) / w))
                           ysav = tabWaveLenB(((i + p)* lpas) + j + 1)/(h / 0.6)
                           LineXY(i, h - (h / 4) - zsav, i, h - (h / 4) - (tabWaveLenB(((i + p) * lpas) + j) / (h / 0.6)), $e8a200 + ((i * 255) / w))
                           zsav = tabWaveLenB(((i + p) * lpas) + j) / (h / 0.6)
                        EndIf
                     Next j
                     LineXY(i, h / 4, i, h / 4, $CC8E00 + ((i * 255) / w))
                     LineXY(i, h - (h / 4), i, h - (h / 4), $CC8E00 + ((i * 255) / w))
                  Next i
                  LineXY(0, (h / 2), w, (h / 2), $222222)
            EndSelect
      EndSelect
      If play
        i    = GetSoundPosition(0, #PB_Sound_Frame)
        j    = SoundLength (0, #PB_Sound_Frame)
        fpos = w / j
        DrawingMode(#PB_2DDrawing_AlphaBlend)
        Box((fpos * (i * z)) - p - 2, 0, 4, h, RGBA(200, 0, 0, 100))
        DrawingMode(#PB_2DDrawing_Transparent)
        DrawText(6, 1, FormatDate("%hh:%ii:%ss", GetSoundPosition(0, #PB_Sound_Millisecond)  / 1000), $000000)
      EndIf
      j = 0
      DrawingMode(#PB_2DDrawing_Transparent)
      If Round((tabWaveFile\DataChunkSize / tabWaveFile\ByteRate)- 0.3, #PB_Round_Nearest)> 1
         For i = 1 To(w * z)
            j + 1
            i + (lsec * 30) * z
            If i - p => 0 And i - p <= w
               LineXY(i - p, 0, i - p, h, $0000AA)
               DrawText((i - p)- 60, h - 15, FormatDate("%hh:%ii:%ss", (j * 30)), $0000AA)
            EndIf
         Next i
      EndIf
      DrawText(w - 60, 1, time, $000000)
      StopDrawing()
      If z = 1
         SetGadgetState(1, 0)
      EndIf
      SetGadgetAttribute(1, #PB_ScrollBar_Maximum, lpos)
      ProcedureReturn #True
   EndIf
   
   
EndProcedure

; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************

; +--------------------------------------------------------------------------+
; |                                                                          |
; +--------------------------------------------------------------------------+

If Not InitSound()
   MessageRequester("Initialize the sound environment", "No sound supported!")
   End
EndIf

; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************

; +--------------------------------------------------------------------------+
; |                                                                          |
; +--------------------------------------------------------------------------+

Global zoom.l = 1
Global pos.l = 0
Global play.b = #False

Procedure ScrollWAVImage()
   pos = GetGadgetState(1)
   DrawWAVFile(0, 0, 800, 256, zoom, pos, play)
 EndProcedure
 
Procedure ZoomWAVImage()
   Select EventGadget()
      Case 5
         zoom - 1
         If zoom < 2
            pos = 0
         EndIf
         If zoom < 1
            zoom = 1
         EndIf
      Case 6
         zoom + 1
         If zoom > 16
            zoom = 16
         EndIf
   EndSelect
   DrawWAVFile(0, 0, 800, 256, zoom, pos)
EndProcedure
Procedure LoadAndPlayWAVSound()
   Select EventGadget()
      Case 2
         OpenWAVFile(OpenFileRequester("Ouvrir un archive Wav", "", "Musique Wav|*.wav", 0), 0, 0, 800, 256, zoom)
         GetWavInformation()
       Case 3
         If sFileName <> #NULL$
           If LoadSound(0, sFileName)
              PlaySound(0)
           EndIf
         EndIf
      Case 4
         If IsSound(0)
            StopSound(0)
         EndIf
   EndSelect
EndProcedure

If OpenWindow(0, 0, 0, 800, 400, "PureWave", #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
   CanvasGadget(0, 0, 0, 800, 256, 0)
   ScrollBarGadget(1, 0, 257, 800, 18, 1, 1, 1000)
   ButtonGadget(2, 10, 300, 100, 32, "Fichier Wav")
   ButtonGadget(3, 120, 300, 100, 32, "Play")
   ButtonGadget(4, 230, 300, 100, 32, "Stop")
   ButtonGadget(5, 10, 340, 100, 32, "Zoom -")
   ButtonGadget(6, 120, 340, 100, 32, "Zoom +")
   BindGadgetEvent(1, @ScrollWAVImage())
   BindGadgetEvent(1, @ScrollWAVImage())
   BindGadgetEvent(2, @LoadAndPlayWAVSound())
   BindGadgetEvent(3, @LoadAndPlayWAVSound())
   BindGadgetEvent(4, @LoadAndPlayWAVSound())
   BindGadgetEvent(5, @ZoomWAVImage())
   BindGadgetEvent(6, @ZoomWAVImage())
   Repeat      
      play = Bool(IsSound(0) And SoundStatus(0)=#PB_Sound_Playing)
      DrawWAVFile(0, 0, 800, 256, zoom, pos, play)      
   Until WaitWindowEvent(1)= #PB_Event_CloseWindow
EndIf
Best Regards,
GallyHC

Re: WavForm of a sound in WAV format

Posted: Mon Aug 12, 2013 4:21 pm
by kvitaliy
unicode mode on: Ok!
thank you :D

Re: WavForm of a sound in WAV format

Posted: Wed Jun 18, 2014 11:38 am
by Niffo
Does not work in Unicode if the DataChunk is not the first one after the FormatChunk in the WAV file.

You have to change ligne 108 to : If ReadWavString(datachunkid) = "data"

I had to comment the following line in the WaveFileHeader too :

;CompilerIf #PB_Compiler_Unicode = 1
; bitformatextra.u
;CompilerEndIf


Regards.

Re: WavForm of a sound in WAV format

Posted: Wed Jun 18, 2014 4:58 pm
by gally
Hello and thank you for the correction.

The code is available on my website (in french language at the moment). has the address "http://www.pbfrance.com/?url=source&cmd=viewer&val=16".

Click "Code-source" (parser PureBasic) or "Télécharger" for download source.

Regards,
GallyHC

Re: WavForm of a sound in WAV format

Posted: Thu Jun 19, 2014 11:40 am
by gally
The source code :

Code: Select all

; +======================================================+
; | ROUTINE DE CHARGEMENT DU FORMAT WAV (SPECTRE DU SON) |
; +------------------------------------------------------+
; | COPYRIGHT(C)2007-2012, ALL RIGHT RESERVED KOAKDESIGN |
; +--------------+---------------------------------------+
; | Program type | PUREBASIC 5.2b8                        |
; +--------------+---------------------------------------+
; | VER & REV    | 0.0.3                                 |
; +--------------+---------------------------------------+
; | Comments:    | unicode supported, realtime scroll    |
; +--------------+                                       |
; |                                                      |
; +======================================================+

; +======================================================+
; | Original Version: 0.0.2                              |
; +--------------+---------------------------------------+
; | Created by   | GallyHomeCorp                         |
; | Graphix by   | GallyHomeCorp                         |
; +--------------+---------------------------------------+
; | Comments:    |                                       |
; +--------------+                                       |
; |                                                      |
; +======================================================+

; +======================================================+
; | OS System
; +--------------+---------------------------------------+
; | Window       | Oui                                   |
; | Linux        | Oui                                   |
; | MacOS        | Oui                                   |
; +======================================================+

EnableExplicit

; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************

; +--------------------------------------------------------------------------+
; |                                                                          |
; +--------------------------------------------------------------------------+

Declare.b OpenWAVFile(filename.s, x, y, w, h, z = 1)
Declare.b DrawWAVFile(x, y, w, h, z = 1, p = 0, play.b = #False)
Declare ScrollWAVImage()

; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************

; +--------------------------------------------------------------------------+
; |                                                                          |
; +--------------------------------------------------------------------------+

Structure WaveFileHeader
  chunkid.a[4]
  chunksize.l
  format.a[4]
  fmtchunkid.a[4]
  fmtchunksize.l
  audioformat.u
  numchannels.u
  samplerate.l
  byterate.l
  blockalign.u
  bitspersample.u
  datachunkid.a[4]
  datachunksize.l
EndStructure

Global sFileName.s
Global Dim tabWaveLenA.a(1)
Global Dim tabWaveLenB.w(1)
Global tabWaveFile.WaveFileHeader

; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************

; +--------------------------------------------------------------------------+
; |                                                                          |
; +--------------------------------------------------------------------------+

Macro ReadWavString(structProperty)
   LSet(PeekS(@structProperty, 4, #PB_Ascii), 4, " ")
EndMacro
Macro WriteWavString(structProperty, value)
   PokeS(@structProperty, value, 4, #PB_Ascii)
EndMacro 

Procedure.b OpenWAVFile(filename.s, x, y, w, h, z = 1)
   ; ROUTINE DE CHARGEMENT DU HEADER DU WAV.
   Protected i
   Protected file
   Protected flen
   Protected dlen
   Protected load.b = #False
   Protected lDataChunk
   Protected datachunkid.s{4}
   
   file = ReadFile(#PB_Any, filename)
   If file <> 0
      sFileName = filename
      flen = Lof(file)
      ReadData(file, tabWaveFile, SizeOf(WaveFileHeader))
      If ReadWavString(tabWaveFile\datachunkid) <> "data"
         For i = 0 To 2048 Step 2
            FileSeek(file, (SizeOf(WaveFileHeader)- 6)+ i)
            ReadData(file, @datachunkid, 4)
            If ReadWavString(datachunkid) = "data"
               lDataChunk = i + 2
               WriteWavString(tabWaveFile\datachunkid, "data")
               tabWaveFile\datachunksize = ReadLong(file)
               Break
            EndIf
         Next i
      EndIf
      ReDim tabWaveLenA(1)
      ReDim tabWaveLenB(1)
      If ReadWavString(tabWaveFile\chunkid) = "RIFF" And ReadWavString(tabWaveFile\format) = "WAVE" And ReadWavString(tabWaveFile\fmtchunkid) = "fmt " And ReadWavString(tabWaveFile\datachunkid) = "data" And tabWaveFile\DataChunkSize > 44
         dlen = tabWaveFile\DataChunkSize / tabWaveFile\BlockAlign
         Select tabWaveFile\BitsPerSample
            Case 8
               Select tabWaveFile\NumChannels
                  Case 1
                     load = #True
                     ReDim tabWaveLenA(dlen)
                  Case 2
                     load = #True
                     ReDim tabWaveLenA(dlen * 2)
               EndSelect
               If load = #True
                  FileSeek(file, SizeOf(WaveFileHeader)+ lDataChunk)
                  If ReadData(file, @tabWaveLenA(), tabWaveFile\DataChunkSize)= tabWaveFile\DataChunkSize
                     DrawWAVFile(x, y, w, h, z)
                  EndIf
               EndIf
            Case 16
               Select tabWaveFile\NumChannels
                  Case 1
                     load = #True
                     ReDim tabWaveLenB(dlen)
                  Case 2
                     load = #True
                     ReDim tabWaveLenB(dlen * 2)
               EndSelect
               If load = #True
                  FileSeek(file, SizeOf(WaveFileHeader)+ lDataChunk)
                  If ReadData(file, @tabWaveLenB(), tabWaveFile\DataChunkSize)= tabWaveFile\DataChunkSize
                     DrawWAVFile(x, y, w, h, z)
                  EndIf
               EndIf
         EndSelect
      EndIf
      CloseFile(file)
   EndIf
   ProcedureReturn #True
   
EndProcedure

Procedure.s GetWAVTime()
   ; ROUTINE DE RECUPERATION DU TEMPS DU WAV.
   ProcedureReturn FormatDate("%hh:%ii:%ss", Round((tabWaveFile\DataChunkSize / tabWaveFile\ByteRate)- 0.3, #PB_Round_Nearest))
   
EndProcedure

Procedure.l ParseWavTime(date.s, val)
   ; ROUTINE DE DECOUPAGE DU TEMPS DU WAV.
   If val < 1
      val = 1
   EndIf
   If val > 3
      val = 3
   EndIf
   ProcedureReturn Val(StringField(date, val, ":"))
   
EndProcedure

Procedure GetWavInformation()
   ; ROUTINE DE DECOUPAGE DU TEMPS DU WAV.
   Protected stemp.s
   stemp = "ChunkID : " + tabWaveFile\chunkid +
           #CRLF$ + "ChunkSize : " + Str(tabWaveFile\ChunkSize)+ " Octets" +
           #CRLF$ + "Format : " + ReadWavString(tabWaveFile\Format) +
           #CRLF$ + "fmtChunkID : " + ReadWavString(tabWaveFile\fmtChunkID) +
           #CRLF$ + "FmtChunkSize : " + Str(tabWaveFile\FmtChunkSize)+ " Octets" +
           #CRLF$ + "Format : " + Str(tabWaveFile\AudioFormat)+
           #CRLF$ + "Channels : " + Str(tabWaveFile\NumChannels)+
           #CRLF$ + "SampleRate : " + Str(tabWaveFile\SampleRate)+ " Hz" +
           #CRLF$ + "BitsRate : " + Str(tabWaveFile\ByteRate)+
           #CRLF$ + "BlockAlign : " + Str(tabWaveFile\BlockAlign)+
           #CRLF$ + "BitsPerSample : " + Str(tabWaveFile\BitsPerSample)+
           #CRLF$ + "DataChunkID : " + ReadWavString(tabWaveFile\DataChunkID) +
           #CRLF$ + "DataChunkSize : " + Str(tabWaveFile\DataChunkSize)+ " Octets" +
           #CRLF$ + #CRLF$ + "Temps Total : " + GetWAVTime()
   MessageRequester("PureWav", stemp, #PB_MessageRequester_Ok)
   
EndProcedure

Procedure.b DrawWAVFile(x, y, w, h, z = 1, p = 0, play.b = #False)
   ; ROUTINE DE TRACAGE DU SPECTRE DU WAV.
   Protected i
   Protected j
   Protected dlen
   Protected lpas
   Protected ysav
   Protected zsav
   Protected lpos
   Protected fpos.f
   Protected time.s = GetWAVTime()
   Protected lsec.f = w / ((ParseWavTime(time, 1) * 3600) + (ParseWavTime(time, 2) * 60) + ParseWavTime(time, 3))
   
   If play.b = #False
     ProcedureReturn
   EndIf
   
   If z < 1
     z = 1
     ProcedureReturn #False
   EndIf
   If z > 16
      z = 16
     ProcedureReturn #False
   EndIf
   If ReadWavString(tabWaveFile\chunkid)<> "RIFF" Or ReadWavString(tabWaveFile\format)<> "WAVE" Or ReadWavString(tabWaveFile\fmtchunkid) <> "fmt " Or ReadWavString(tabWaveFile\datachunkid) <> "data"
      ProcedureReturn #False
   EndIf
   If tabWaveFile\DataChunkSize < 1
      ProcedureReturn #False
   EndIf
   
   ;
   ; (Test) Moving real play
   ;
  If play
    i    = GetSoundPosition(0, #PB_Sound_Frame)
    j    = SoundLength (0, #PB_Sound_Frame)
    fpos = w / j
    If fpos * (i * z) - p => w / 2 And GetGadgetAttribute(1, #PB_ScrollBar_Maximum) > 1 And GetGadgetAttribute(1, #PB_ScrollBar_Maximum) > GetGadgetState(1)
      SetGadgetState(1, GetGadgetState(1) + 1)
      ScrollWAVImage()
      ProcedureReturn #False
    EndIf
  EndIf
   ;
   ; (Test) Moving real play
   ;
   
   
   If StartDrawing(CanvasOutput(0)) 
      Box(0, 0, w, h, $FFFFFF)
      dlen = tabWaveFile\DataChunkSize / tabWaveFile\BlockAlign
      Select tabWaveFile\NumChannels
         Case 1
            lpas =(dlen / w) / z
            lpos =((dlen / lpas)- w)
            If p > lpos
               p = lpos
            EndIf
            Select tabWaveFile\BitsPerSample
               Case 8
                  ysav = tabWaveLenA(0)- 128
                  LineXY(0, (h / 6), w, (h / 6), $BBBBBB)
                  LineXY(0, h -(h / 6), w, h -(h / 6), $BBBBBB)
                  For i = 0 To w
                     For j = 1 To lpas Step 4
                        j + (128 - (z * 4))
                        If ((i + p) * lpas) + j < dlen - 1
                           LineXY(i, (h / 2) - ysav, i, (h / 2) - (tabWaveLenA(((i + p) * lpas) + j) - 128), $e8a200 + ((i * 255) / w))
                           ysav =(tabWaveLenA(((i + p) * lpas) + j) - 128)
                        EndIf
                     Next j
                     LineXY(i, h / 2, i, h / 2, $CC8E00 + ((i * 255)/ w))
                  Next i
               Case 16
                  ysav = tabWaveLenB(0)/(h / 1.5)
                  LineXY(0, (h / 6), w, (h / 6), $BBBBBB)
                  LineXY(0, h - (h / 6), w, h - (h / 6), $BBBBBB)
                  For i = 0 To w
                     For j = 1 To lpas Step 4
                        j + (128 -(z * 4))
                        If ((i + p) * lpas) + j < dlen - 1
                           LineXY(i, (h / 2) - ysav, i, (h / 2) - (tabWaveLenB(((i + p) * lpas) + j) / (h / 1.5)), $e8a200 + ((i * 255)/ w))
                           ysav = tabWaveLenB(((i + p) * lpas) + j) / (h / 1.5)
                        EndIf
                     Next j
                     LineXY(i, h / 2, i, h / 2, $CC8E00 + ((i * 255)/ w))
                  Next i
            EndSelect
         Case 2
            lpas = ((dlen / w) * 2) / z
            lpos = ((dlen / lpas)* 2) - w
            If p > lpos
               p = lpos
            EndIf
            Select tabWaveFile\BitsPerSample
               Case 8
                  ysav = tabWaveLenA(1)- 128
                  ysav = tabWaveLenA(0)- 128
                  LineXY(0, (h / 12), w, (h / 12), $BBBBBB)
                  LineXY(0, (h / 2) - (h / 12), w, (h / 2) - (h / 12), $BBBBBB)
                  LineXY(0, (h / 2) + (h / 12), w, (h / 2) + (h / 12), $BBBBBB)
                  LineXY(0, h - (h / 12), w, h - (h / 12), $BBBBBB)
                  For i = 0 To w
                     For j = 1 To lpas Step 1
                        j + (128 - (z * 4))
                        If ((i + p) * lpas) + j < (dlen * 2) - 1
                           LineXY(i, (h / 4) - ysav, i, (h / 4) - (tabWaveLenA(((i + p) * lpas) + j + 1) - 128), $e8a200 + ((i * 255) / w))
                           ysav = (tabWaveLenA(((i + p) * lpas) + j + 1) - 128)
                           LineXY(i, h - (h / 4) - zsav, i, h - (h / 4) - (tabWaveLenA(((i + p) * lpas) + j)- 128), $e8a200 + ((i * 255) / w))
                           zsav = (tabWaveLenA(((i + p) * lpas) + j) - 128)
                        EndIf
                     Next j
                     LineXY(i, h / 4, i, h / 4, $CC8E00 + ((i * 255)/ w))
                     LineXY(i, h - (h / 4), i, h - (h / 4), $CC8E00 + ((i * 255)/ w))
                  Next i
                  LineXY(0, (h / 2), w, (h / 2), $222222)
               Case 16
                  ysav = tabWaveLenB(1)/(h / 0.9)
                  zsav = tabWaveLenB(0)/(h / 0.9)
                  LineXY(0, (h / 12), w, (h / 12), $BBBBBB)
                  LineXY(0, (h / 2) - (h / 12), w, (h / 2) - (h / 12), $BBBBBB)
                  LineXY(0, (h / 2) + (h / 12), w, (h / 2) + (h / 12), $BBBBBB)
                  LineXY(0, h -(h / 12), w, h - (h / 12), $BBBBBB)
                  For i = 0 To w
                     For j = 1 To lpas Step 1
                        j + (128 - (z * 4))
                        If ((i + p) * lpas) + j < (dlen * 2) - 1
                           LineXY(i, (h / 4) - ysav, i, (h / 4) - (tabWaveLenB(((i + p) * lpas) + j + 1) / (h / 0.6)), $e8a200 + ((i * 255) / w))
                           ysav = tabWaveLenB(((i + p)* lpas) + j + 1)/(h / 0.6)
                           LineXY(i, h - (h / 4) - zsav, i, h - (h / 4) - (tabWaveLenB(((i + p) * lpas) + j) / (h / 0.6)), $e8a200 + ((i * 255) / w))
                           zsav = tabWaveLenB(((i + p) * lpas) + j) / (h / 0.6)
                        EndIf
                     Next j
                     LineXY(i, h / 4, i, h / 4, $CC8E00 + ((i * 255) / w))
                     LineXY(i, h - (h / 4), i, h - (h / 4), $CC8E00 + ((i * 255) / w))
                  Next i
                  LineXY(0, (h / 2), w, (h / 2), $222222)
            EndSelect
      EndSelect
      If play
        ;
        ;
        ;
        Define.i x, y
        ;
        ;
        ;
        i    = GetSoundPosition(0, #PB_Sound_Frame)
        j    = SoundLength (0, #PB_Sound_Frame)
        fpos = w / j
        ;
        ; DESSINE LA PARTIE EN ROUGE (VOLUME).
        ;
        DrawingMode(#PB_2DDrawing_Transparent)
        For y=1 To h - 1
          For x=(fpos*(i*z))-p-2 To (fpos*(i* z))-p
            If x >= 0
            If Point(x, y) <> $ffffff
              LineXY(x, y, x+1, y, $0000ff)
            EndIf
            EndIf
          Next x
        Next y        
        ;
        ; DESSINE LA PARTIE EN ROUGE (VOLUME).
        ;
        DrawingMode(#PB_2DDrawing_AlphaBlend)
        Box((fpos * (i * z)) - p - 2, 0, 4, h, RGBA(0, 0, 255, 20))
        ;
        ;
        ;
        DrawingMode(#PB_2DDrawing_Transparent)
        DrawText(6, 1, FormatDate("%hh:%ii:%ss", GetSoundPosition(0, #PB_Sound_Millisecond)  / 1000), $000000)
      EndIf
      j = 0
      If Round((tabWaveFile\DataChunkSize / tabWaveFile\ByteRate) - 0.3, #PB_Round_Nearest) > 1
        DrawingMode(#PB_2DDrawing_Transparent)
         For i = 1 To(w * z)
            j + 1
            i + (lsec * 30) * z
            If i - p => 0 And i - p <= w
               LineXY(i - p, 0, i - p, h, $0000AA)
               DrawText((i - p)- 60, h - 15, FormatDate("%hh:%ii:%ss", (j * 30)), $0000AA)
            EndIf
         Next i
      EndIf
      DrawText(w - 60, 1, time, $000000)
  
      StopDrawing()
      If z = 1
         SetGadgetState(1, 0)
      EndIf
      SetGadgetAttribute(1, #PB_ScrollBar_Maximum, lpos)
      ProcedureReturn #True
   EndIf
      
EndProcedure

; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************

; +--------------------------------------------------------------------------+
; |                                                                          |
; +--------------------------------------------------------------------------+

If Not InitSound()
   MessageRequester("Initialize the sound environment", "No sound supported!")
   End
EndIf

; ****************************************************************************
; ****************************************************************************
; ****************************************************************************
; ****************************************************************************

; +--------------------------------------------------------------------------+
; |                                                                          |
; +--------------------------------------------------------------------------+

Global zoom.l = 1
Global pos.l = 0
Global play.b = #False

Procedure ScrollWAVImage()
   pos = GetGadgetState(1)
   DrawWAVFile(0, 0, 800, 256, zoom, pos, play)
 EndProcedure
 
Procedure ZoomWAVImage()
   Select EventGadget()
      Case 5
         zoom - 1
         If zoom < 2
            pos = 0
         EndIf
         If zoom < 1
            zoom = 1
         EndIf
      Case 6
         zoom + 1
         If zoom > 16
            zoom = 16
         EndIf
   EndSelect
   DrawWAVFile(0, 0, 800, 256, zoom, pos)
EndProcedure
Procedure LoadAndPlayWAVSound()
   Select EventGadget()
      Case 2
         OpenWAVFile(OpenFileRequester("Ouvrir un archive Wav", "", "Musique Wav|*.wav", 0), 0, 0, 800, 256, zoom)
         GetWavInformation()
       Case 3
         If sFileName <> #NULL$
           If LoadSound(0, sFileName)
              PlaySound(0)
           EndIf
         EndIf
      Case 4
         If IsSound(0)
            StopSound(0)
         EndIf
   EndSelect
EndProcedure

If OpenWindow(0, 0, 0, 800, 400, "PureWave", #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget | #PB_Window_SizeGadget | #PB_Window_ScreenCentered)
   CanvasGadget(0, 0, 0, 800, 256, 0)
   ScrollBarGadget(1, 0, 257, 800, 18, 1, 1, 1000)
   ButtonGadget(2, 10, 300, 100, 32, "Fichier Wav")
   ButtonGadget(3, 120, 300, 100, 32, "Play")
   ButtonGadget(4, 230, 300, 100, 32, "Stop")
   ButtonGadget(5, 10, 340, 100, 32, "Zoom -")
   ButtonGadget(6, 120, 340, 100, 32, "Zoom +")
   BindGadgetEvent(1, @ScrollWAVImage())
   BindGadgetEvent(1, @ScrollWAVImage())
   BindGadgetEvent(2, @LoadAndPlayWAVSound())
   BindGadgetEvent(3, @LoadAndPlayWAVSound())
   BindGadgetEvent(4, @LoadAndPlayWAVSound())
   BindGadgetEvent(5, @ZoomWAVImage())
   BindGadgetEvent(6, @ZoomWAVImage())
   Repeat      
      play = Bool(IsSound(0) And SoundStatus(0)=#PB_Sound_Playing)
      DrawWAVFile(0, 0, 800, 256, zoom, pos, play)      
   Until WaitWindowEvent(1)= #PB_Event_CloseWindow
EndIf
GallyHC