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

Da Gambas-it.org - Wikipedia.
 
(16 versioni intermedie di uno stesso utente non sono mostrate)
Riga 1: Riga 1:
E' possibile visualizzare, seppur in modo <SPAN style="text-decoration:underline">approssimativo</span>, con le sole funzioni di Gambas la forma d'onda di un file audio WAV.
+
E' possibile visualizzare, seppur in modo <SPAN style="text-decoration:underline">approssimativo</span>, con le sole funzioni di Gambas la forma d'onda di un file audio WAV. <SUP>&#091;[[#Note|nota 1]]&#093;</sup>
  
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.
+
Nel semplice esempio che segue si supporrà che il file sia a <SPAN style="text-decoration:underline">due canali</span> e a <SPAN style="text-decoration:underline">16bit</span>, ma sarà mostrata l'onda di un solo canale.
 
<BR>Porremo inoltre sul ''Form'' una ''DrawingArea''.
 
<BR>Porremo inoltre sul ''Form'' una ''DrawingArea''.
  Private Const ZOOM As Short = <FONT Color=#B22222>256</font> <FONT color=gray>' ''Imposta lo zoom visivo dell'onda disegnata''</font>
+
  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 fl As File
 
  Private fileWAV As String
 
  Private fileWAV As String
  Private ini As Integer
+
  Private cc As Short[]
 
   
 
   
 
   
 
   
  '''Public''' Sub Form_Open()
+
  Public Sub Form_Open()
 
   
 
   
 
   With Me
 
   With Me
 +
    .W = Screen.AvailableWidth
 +
    .H = Screen.AvailableHeight
 +
    .Show
 +
  End With
 +
  With DrawingArea1 = New DrawingArea(Me) As "DrawingArea1"
 +
    .X = 0
 +
    .Y = Me.H * 0.1
 
     .W = Desktop.W
 
     .W = Desktop.W
 
     .H = Desktop.H
 
     .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
 
   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 c As Short
 +
 +
  fileWAV = InputBox("Inserire il percorso del file WAV:")
 +
 +
  If IsNull(fileWAV) Or (Not Exist(fileWAV)) Then
 +
    Message.Error("Il file caricato è inesistente !")
 +
    Return
 +
  Endif
 +
  If InStr(File.Load(fileWAV), "RIFF") == 0 Then
 +
    Message.Error("Il file caricato non è un file 'WAV' !")
 +
    Return
 +
  Endif
 +
  If fine.Value == 0 Then
 +
    Message.Warning("Il byte finale deve essere superiore a zero !")
 +
    Return
 +
  Endif
 +
 +
  fl = Open fileWAV For Read
 +
  seek #fl, 22
 +
  Read #fl, c
 +
  If c <> 2 then
 +
    Message.Warning("Il file wav non è stereo !")
 +
    fl.Close
 +
    Return
 +
  Endif
 +
  Seek #fl, 34
 +
  Read #fl, c
 +
  If c <> 16 Then
 +
    Message.Warning("Il file wav non è a 16 bit !")
 +
    fl.Close
 +
    Return
 +
  Endif
 
    
 
    
   With DrawingArea1
+
   c = InStr(File.Load(fileWAV), "data")
    .W = Desktop.W
 
    .H = Desktop.H
 
  End With
 
 
    
 
    
   fileWAV = "<FONT color=gray>''/percorso/del/file.wav''</font>"
+
   If Not Even(inizio.Value) Then inizio.Value += 1
   If InStr(fileWAV, "RIFF") == 0 Then
+
   If Even(fine.Value) Then fine.Value -= 1
    Message.Error("Il file caricato non è un file 'WAV' o è inesistente !")
 
  Endif 
 
 
    
 
    
   fl = Open fileWAV For Read
+
<FONT Color=gray>' ''Ci si sposta al byte impostato dei dati audio grezzi:''</font>
   
+
   Seek #fl, inizio.Value + (c + 7)
   ini = Val(InputBox("Inserire il byte iniziale:"))
+
 
 +
   With cc = New Short[(Lof(fl) - Seek(fl)) / SizeOf(gb.Short)]
 +
    .Read(fl, 0, cc.Count)
 +
  End With
 
    
 
    
  '''End'''
+
  End
 +
 
   
 
   
 +
Public Sub Spin_Change()
 
   
 
   
  '''Public''' Sub DrawingArea1_Draw()
+
  DrawingArea1.Refresh
 +
 +
End
 +
 +
 +
  Public Sub DrawingArea1_Draw()
 
   
 
   
  Dim d, sh As Short
 
 
   Dim i, ii, r, v As Integer
 
   Dim i, ii, r, v As Integer
 
   
 
   
   d = InStr(File.Load(fileWAV), "data")
+
   If Not Object.IsValid(cc) Then Return
 
+
   
  If ini And 1 Then ini += 1
+
   For i = 0 To (fine.Value - inizio.Value) / SizeOf(gb.Short) Step 2
 
+
  <FONT color=gray>' ''Ci si sposta al byte impostato dei dati audio grezzi:''</font>
+
     If cc[i] = 0 Then ii = 1
  Seek #fl, ini + (d + 7)
+
     If cc[i] < 0 Then ii = cc[i] / 10
 
+
     If cc[i] > 0 Then
   For i = 0 To 99999
+
      ii = cc[i] / 10
    Seek #fl, Seek(fl) + SizeOf(gb.Short)
 
    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
 
 
       v = ii
 
       v = ii
 
       r = 1
 
       r = 1
Riga 60: Riga 176:
 
       r = ii
 
       r = ii
 
     Endif
 
     Endif
   
+
 
     With Paint
 
     With Paint
 
       .Begin(DrawingArea1)
 
       .Begin(DrawingArea1)
 
       .Brush = Paint.Color(Color.RGB(r, v, 0))
 
       .Brush = Paint.Color(Color.RGB(r, v, 0))
       .MoveTo(i / ZOOM, DrawingArea1.H / 2)
+
       .MoveTo(i / spin2.Value, DrawingArea1.H / 2)
       .RelLineTo(0, ii * 0.3)
+
       .RelLineTo(0, ii * (spin1.Value / 100))
 
       .Stroke
 
       .Stroke
 
       .End
 
       .End
 
     End With
 
     End With
 +
 +
  Next
 +
 +
  Me.Title = "Letti in totale " & CStr(Seek(fl) / SizeOf(gb.Short)) & " byte"
 
      
 
      
  Next
+
  End
   
 
  Print "\nLetti in totale "; Seek(fl); " byte"
 
 
 
  '''End'''
 
 
 
  
  
  
Invece, per ottenere un risultato più preciso e soddisfcente, gli <SPAN Stle= "text-decoration:underline">iscritti</span> al forum ''www.gambas-it.org'' possono scaricare [http://www.gambas-it.org/smf/index.php?topic=3294.msg34448#new in questa discussione] il sorgente di un programma molto più complesso che fa uso delle risorse esterne della libreria di ''sndfile'' e di ''Cairo''.
+
=Note=
 +
[1] Per ottenere un risultato più preciso e soddisfacente, gli <SPAN Stle= "text-decoration:underline">iscritti</span> al forum ''www.gambas-it.org'' possono scaricare [http://www.gambas-it.org/smf/index.php?topic=3294.msg34448#new in questa discussione] il sorgente di un programma molto più complesso che fa uso delle risorse esterne della libreria di ''sndfile'' e di ''Cairo''.

Versione attuale delle 16:36, 19 dic 2023

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

Nel semplice 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 cc As Short[]


Public Sub Form_Open()

 With Me
   .W = Screen.AvailableWidth
   .H = Screen.AvailableHeight
   .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 c As Short

 fileWAV = InputBox("Inserire il percorso del file WAV:")

 If IsNull(fileWAV) Or (Not Exist(fileWAV)) Then
   Message.Error("Il file caricato è inesistente !")
   Return
 Endif
 If InStr(File.Load(fileWAV), "RIFF") == 0 Then 
   Message.Error("Il file caricato non è un file 'WAV' !")
   Return 
 Endif
 If fine.Value == 0 Then
   Message.Warning("Il byte finale deve essere superiore a zero !")
   Return
 Endif

 fl = Open fileWAV For Read
 seek #fl, 22
 Read #fl, c
 If c <> 2 then
   Message.Warning("Il file wav non è stereo !")
   fl.Close
   Return
 Endif
 Seek #fl, 34
 Read #fl, c
 If c <> 16 Then
   Message.Warning("Il file wav non è a 16 bit !")
   fl.Close
   Return
 Endif
 
 c = 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 + (c + 7)
  
 With cc = New Short[(Lof(fl) - Seek(fl)) / SizeOf(gb.Short)]
   .Read(fl, 0, cc.Count)
 End With
 
End


Public Sub Spin_Change()

 DrawingArea1.Refresh

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.Title = "Letti in totale " & CStr(Seek(fl) / SizeOf(gb.Short)) & " byte"
   
End


Note

[1] 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.