Differenze tra le versioni di "Visualizzare la forma d'onda di un file WAV"
Da Gambas-it.org - Wikipedia.
(23 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>[[[#Note|nota 1]]]</sup> |
− | + | 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''. | |
+ | 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 | + | Private cc As Short[] |
− | + | 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 | ||
+ | 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 | 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 | + | If Even(fine.Value) Then fine.Value -= 1 |
− | |||
− | |||
− | fl | + | <FONT Color=gray>' ''Ci si sposta al byte impostato dei dati audio grezzi:''</font> |
− | + | 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 | 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 | |
− | For i = 0 To | + | ii = cc[i] / 10 |
− | |||
− | |||
− | |||
− | If | ||
− | If | ||
− | If | ||
− | |||
− | |||
v = ii | v = ii | ||
r = 1 | r = 1 | ||
Riga 59: | 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, | + | .MoveTo(i / spin2.Value, DrawingArea1.H / 2) |
− | .RelLineTo(0, ii * | + | .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" | ||
− | + | End | |
− | |||
− | |||
− | |||
− | |||
− | |||
− | + | =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.