Differenze tra le versioni di "Visualizzare la forma d'onda di un file WAV"

Da Gambas-it.org - Wikipedia.
Riga 15: Riga 15:
 
  Private fl As File
 
  Private fl As File
 
  Private fileWAV As String
 
  Private fileWAV As String
 +
Private fileWAV As String
 +
Private cc As Short[]
 
   
 
   
 
   
 
   
Riga 100: Riga 102:
 
   
 
   
 
  '''Public''' Sub Avvio_Click()
 
  '''Public''' Sub Avvio_Click()
 +
 
 +
  Dim d As Short
 
    
 
    
 
   fileWAV = InputBox("Inserire il percorso del file WAV:")
 
   fileWAV = InputBox("Inserire il percorso del file WAV:")
 
   
 
   
   If InStr(File.Load(fileWAV), "RIFF") == 0 Then
+
   If IsNull(fileWAV) Or InStr(File.Load(fileWAV), "RIFF") == 0 Then
 
     Message.Error("Il file caricato non è un file 'WAV' o è inesistente !")
 
     Message.Error("Il file caricato non è un file 'WAV' o è inesistente !")
 
     Me.Close
 
     Me.Close
Riga 113: Riga 117:
 
     Return
 
     Return
 
   Endif
 
   Endif
 +
 
 +
  fl = Open fileWAV For Read
 +
 
 +
  d = InStr(File.Load(fileWAV), "data")
 +
 
 +
  If Not Even(inizio.Value) Then inizio.Value += 1
 +
  If Even(fine.Value) Then fine.Value -= 1
 +
 
 +
<FONT Color=gray>' ''Ci si sposta al byte impostato dei dati audio grezzi:''</font>
 +
  Seek #fl, inizio.Value + (d + 7)
 +
 
 +
  With cc = New Short[(Lof(fl) - Seek(fl)) / SizeOf(gb.Short)]
 +
    .Read(fl, 0, cc.Count)
 +
  End With
 
    
 
    
 
  '''End'''
 
  '''End'''
Riga 125: Riga 143:
 
  '''Public''' Sub DrawingArea1_Draw()
 
  '''Public''' Sub DrawingArea1_Draw()
 
    
 
    
  Dim d, sh As Short
 
 
   Dim i, ii, r, v As Integer
 
   Dim i, ii, r, v As Integer
 
    
 
    
  If IsNull(fileWAV) Then Return
+
   If Not Object.IsValid(cc) Then Return
  fl = Open fileWAV For Read
 
 
 
  d = InStr(File.Load(fileWAV), "data")
 
 
 
   If Not Even(inizio.Value) Then inizio.Value += 1
 
  If Even(fine.Value) Then fine.Value -= 1
 
 
 
<FONT Color=gray>' ''Ci si sposta al byte impostato dei dati audio grezzi:''</font>
 
  Seek #fl, inizio.Value + (d + 7)
 
 
    
 
    
   For i = 0 To fine.Value - inizio.Value
+
   For i = 0 To (fine.Value - inizio.Value) / SizeOf(gb.Short) Step 2
    Seek #fl, Seek(fl) + SizeOf(gb.Short) <FONT Color=gray>' ''Legge solo i dati audio del primo canale''</font>
 
    Read #fl, sh
 
   
 
    If sh = 0 Then ii = 1
 
    If sh < 0 Then ii = sh / 10
 
    If sh > 0 Then ii = sh / 10
 
 
      
 
      
     If sh > 0 Then
+
     If cc[i] = 0 Then ii = 1
 +
    If cc[i] < 0 Then ii = cc[i] / 10
 +
    If cc[i] > 0 Then
 +
      ii = cc[i] / 10
 
       v = ii
 
       v = ii
 
       r = 1
 
       r = 1

Versione delle 10:23, 16 set 2020

E' possibile visualizzare, seppur in modo approssimativo, con le sole funzioni di Gambas la forma d'onda di un file audio WAV.

Nell'esempio che segue si supporrà che il file sia a due canali e a 16bit, ma sarà mostrata l'onda di un solo canale.
Porremo inoltre sul Form una DrawingArea.

Private DrawingArea1 As DrawingArea
Private inizio As ValueBox
Private fine As ValueBox
Private avvio As Button
Private label1 As Label
Private label2 As Label
Private label3 As Label
Private label4 As Label
Private spin1 As SpinBox
Private spin2 As SpinBox
Private fl As File
Private fileWAV As String

Private fileWAV As String Private cc As Short[]


Public Sub Form_Open()

 With Me
   .W = Desktop.W
   .H = Desktop.H
   .Show
 End With
 With DrawingArea1 = New DrawingArea(Me) As "DrawingArea1"
   .X = 0
   .Y = Me.H * 0.1
   .W = Desktop.W
   .H = Desktop.H
   .Background = &FFFFA0
 End With
 With inizio = New ValueBox(Me) As "Inzio"
   .X = Me.W * 0.2
   .Y = Me.H * 0.03
   .W = Me.W * 0.07
   .H = Me.H * 0.05
 End With
 With fine = New ValueBox(Me) As "Fine"
   .X = Me.W * 0.35
   .Y = Me.H * 0.03
   .W = Me.W * 0.07
   .H = Me.H * 0.05
 End With
 With label1 = New Label(Me)
   .Text = "Byte iniziale: "
   .W = .Font.TextWidth(.Text)
   .X = inizio.X - .W
   .Y = Me.H * 0.03
   .H = Me.H * 0.05
 End With
 With label2 = New Label(Me)
   .Text = "Byte finale: "
   .W = .Font.TextWidth(.Text)
   .X = fine.X - .W
   .Y = Me.H * 0.03
   .H = Me.H * 0.05
 End With
 With avvio = New Button(Me) As "Avvio"
   .Text = "File WAV"
   .W = .Font.TextWidth(.Text) + 10
   .X = (Me.W * 0.5) - (.W / 2)
   .Y = Me.H * 0.03
   .H = Me.H * 0.05
 End With
 With spin1 = New SpinBox(Me) As "Spin"
   .X = Me.W * 0.7
   .Y = Me.H * 0.03
   .W = Me.W * 0.07
   .H = Me.H * 0.05
   .MaxValue = 1024
   .MinValue = 1
   .Value = 30
 End With
 With label3 = New Label(Me)
   .Text = "Zoom verticale: "
   .W = .Font.TextWidth(.Text)
   .X = spin1.X - .W
   .Y = Me.H * 0.03
   .H = Me.H * 0.05
 End With
 With spin2 = New SpinBox(Me) As "Spin"
   .X = Me.W * 0.9
   .Y = Me.H * 0.03
   .W = Me.W * 0.07
   .H = Me.H * 0.05
   .MaxValue = 1024
   .MinValue = 1
   .Value = 256
 End With
 With label4 = New Label(Me)
   .Text = "Zoom orizzontale: "
   .W = .Font.TextWidth(.Text)
   .X = spin2.X - .W
   .Y = Me.H * 0.03
   .H = Me.H * 0.05
 End With
  
End

Public Sub Avvio_Click()
 
 Dim d As Short
 
 fileWAV = InputBox("Inserire il percorso del file WAV:")

 If IsNull(fileWAV) Or InStr(File.Load(fileWAV), "RIFF") == 0 Then
   Message.Error("Il file caricato non è un file 'WAV' o è inesistente !")
   Me.Close
   Quit
 Endif
 
 If fine.Value == 0 Then
   Message.Warning("Il byte finale deve essere superiore a zero !")
   Return
 Endif
 
 fl = Open fileWAV For Read
 
 d = InStr(File.Load(fileWAV), "data")
 
 If Not Even(inizio.Value) Then inizio.Value += 1
 If Even(fine.Value) Then fine.Value -= 1
 
' Ci si sposta al byte impostato dei dati audio grezzi:
 Seek #fl, inizio.Value + (d + 7)
  
 With cc = New Short[(Lof(fl) - Seek(fl)) / SizeOf(gb.Short)]
   .Read(fl, 0, cc.Count)
 End With
 
End

Public Sub Spin_Change()
 
 If IsNull(fileWAV) Then Return
 DrawingArea1.Clear
 
End

Public Sub DrawingArea1_Draw()
 
 Dim i, ii, r, v As Integer
 
 If Not Object.IsValid(cc) Then Return
 
 For i = 0 To (fine.Value - inizio.Value) / SizeOf(gb.Short) Step 2
   
   If cc[i] = 0 Then ii = 1
   If cc[i] < 0 Then ii = cc[i] / 10
   If cc[i] > 0 Then
     ii = cc[i] / 10
     v = ii
     r = 1
   Else
     v = 1
     r = ii
   Endif
   
   With Paint
     .Begin(DrawingArea1)
     .Brush = Paint.Color(Color.RGB(r, v, 0))
     .MoveTo(i / spin2.Value, DrawingArea1.H / 2)
     .RelLineTo(0, ii * (spin1.Value / 100))
     .Stroke
     .End
   End With
   
 Next
  
 Me.Caption = "Letti in totale " & CStr(Seek(fl) / SizeOf(gb.Short)) & " byte"
 
End



Per ottenere un risultato più preciso e soddisfacente, gli iscritti al forum www.gambas-it.org possono scaricare in questa discussione il sorgente di un programma molto più complesso che fa uso delle risorse esterne della libreria di sndfile e di Cairo.