Differenze tra le versioni di "Calcolare la potenza di picco e di ampiezza di un file WAV con le funzioni esterne del API di Libaudiofile"
Da Gambas-it.org - Wikipedia.
(Creata pagina con 'La libreria '''Libaudiofile''' consente la lettura e la scrittura di file audio in diversi formati comuni, astraendo i dettagli di formati di file e di formati di dati. Per p...') |
|||
(8 versioni intermedie di uno stesso utente non sono mostrate) | |||
Riga 1: | Riga 1: | ||
− | La libreria '''Libaudiofile''' consente la lettura e la scrittura di file audio in diversi formati comuni, astraendo i dettagli | + | La libreria '''Libaudiofile''' consente la lettura e la scrittura di file audio in diversi formati comuni, astraendo i dettagli dei formati di file AIFC, AIFF, AU, VOC, WAV e altri. |
− | |||
− | |||
+ | Per poter fruire in Gambas delle risorse di questa libreria, sarà necessario installare la libreria condivisa: "''libaudiofile.so.1.0.0'' ". | ||
Mostriamo di seguito un esempio per calcolare la potenza di picco e di ampiezza di un file WAV: | Mostriamo di seguito un esempio per calcolare la potenza di picco e di ampiezza di un file WAV: | ||
Public Struct smooth | Public Struct smooth | ||
buf As Float[] | buf As Float[] | ||
− | + | lungh As Integer | |
start As Integer | start As Integer | ||
n As Integer | n As Integer | ||
Riga 47: | Riga 46: | ||
− | + | Public Sub Main() | |
− | + | Dim nomefile As String | |
− | + | Dim fl As Pointer | |
− | + | Dim canali, windowSize, frameCount As Integer | |
− | + | Dim i, c, winStart, winEnd, fine As Integer | |
− | + | Dim powsmooth As New Smooth[] | |
− | + | Dim lastWindow As Boolean | |
− | + | Dim frames, sums As Float[] | |
− | + | Dim frequenza, sample, pow, maxpow, durata As Float | |
− | + | Dim livello, picco, minSample, maxSample As Float | |
− | nomefile = "''/percorso/del/file.wav''" | + | nomefile = "<FONT Color=darkgreen>''/percorso/del/file.wav''</font>" |
minSample = 1 | minSample = 1 | ||
maxSample = -1 | maxSample = -1 | ||
fl = afOpenFile(nomefile, "r", 0) | fl = afOpenFile(nomefile, "r", 0) | ||
− | If | + | If fl == 0 Then Error.Raise("Impossibile aprire il file audio !") |
canali = afGetChannels(fl, AF_DEFAULT_TRACK) | canali = afGetChannels(fl, AF_DEFAULT_TRACK) | ||
frequenza = afGetRate(fl, AF_DEFAULT_TRACK) | frequenza = afGetRate(fl, AF_DEFAULT_TRACK) | ||
+ | |||
+ | durata = afGetFrameCount(fl, AF_DEFAULT_TRACK) / afGetRate(fl, AF_DEFAULT_TRACK) | ||
windowSize = CInt(frequenza / 100) | windowSize = CInt(frequenza / 100) | ||
Riga 81: | Riga 82: | ||
For c = 0 To canali - 1 | For c = 0 To canali - 1 | ||
With powsmooth[c] = New Smooth | With powsmooth[c] = New Smooth | ||
− | . | + | .lungh = 100 |
− | .buf = New Float[powsmooth[c]. | + | .buf = New Float[powsmooth[c].lungh * SizeOf(gb.Float)] |
.start = 0 | .start = 0 | ||
.n = 0 | .n = 0 | ||
Riga 107: | Riga 108: | ||
Next | Next | ||
Next | Next | ||
+ | |||
<FONT Color=gray>' ''Calcola la potenza di ciascun canale:''</font> | <FONT Color=gray>' ''Calcola la potenza di ciascun canale:''</font> | ||
For c = 0 To canali - 1 | For c = 0 To canali - 1 | ||
pow = sums[c] / (winEnd - winStart) | pow = sums[c] / (winEnd - winStart) | ||
− | fine = (powsmooth[c].start + powsmooth[c].n) % powsmooth[c]. | + | fine = (powsmooth[c].start + powsmooth[c].n) % powsmooth[c].lungh |
powsmooth[c].buf[fine] = pow | powsmooth[c].buf[fine] = pow | ||
− | If powsmooth[c].n = powsmooth[c]. | + | If powsmooth[c].n = powsmooth[c].lungh Then |
− | powsmooth[c].start = (powsmooth[c].start + 1) % powsmooth[c]. | + | powsmooth[c].start = (powsmooth[c].start + 1) % powsmooth[c].lungh |
− | pow = | + | pow = Dati_Attenuati(powsmooth[c]) |
If pow > maxpow Then maxpow = pow | If pow > maxpow Then maxpow = pow | ||
Else | Else | ||
Riga 125: | Riga 127: | ||
For c = 0 To canali - 1 | For c = 0 To canali - 1 | ||
− | pow = | + | pow = Dati_Attenuati(powsmooth[c]) |
If pow > maxpow Then maxpow = pow | If pow > maxpow Then maxpow = pow | ||
Next | Next | ||
Riga 134: | Riga 136: | ||
Print "File audio: "; Null, nomefile | Print "File audio: "; Null, nomefile | ||
− | Print "Frequenza: "; Null, frequenza | + | Print "Frequenza: "; Null, "Hz ";frequenza |
Print "Canali: "; Null, canali | Print "Canali: "; Null, canali | ||
+ | Print "Durata: "; Null, Cstr(Date(0, 0, 0, 0, 0, 0, durata * 1000)) | ||
Print "Livello (dB): "; Null, 20 * Log10(livello) | Print "Livello (dB): "; Null, 20 * Log10(livello) | ||
Print "Picco-: "; Null, minSample | Print "Picco-: "; Null, minSample | ||
Riga 146: | Riga 149: | ||
Print "Picco (dB): "; Null, 20 * Log10(picco) | Print "Picco (dB): "; Null, 20 * Log10(picco) | ||
− | + | End | |
− | + | Private Function Dati_Attenuati(s As Smooth) As Float | |
− | + | Dim i As Integer | |
− | + | Dim attenuato As Float | |
− | + | attenuato = 0 | |
For i = 0 To s.n - 1 | For i = 0 To s.n - 1 | ||
− | + | attenuato += s.buf[i] | |
Next | Next | ||
− | + | attenuato = attenuato / s.n | |
+ | |||
+ | Return attenuato | ||
− | + | End | |
− | |||
− | |||
− | |||
Versione attuale delle 07:57, 30 ott 2024
La libreria Libaudiofile consente la lettura e la scrittura di file audio in diversi formati comuni, astraendo i dettagli dei formati di file AIFC, AIFF, AU, VOC, WAV e altri.
Per poter fruire in Gambas delle risorse di questa libreria, sarà necessario installare la libreria condivisa: "libaudiofile.so.1.0.0 ".
Mostriamo di seguito un esempio per calcolare la potenza di picco e di ampiezza di un file WAV:
Public Struct smooth buf As Float[] lungh As Integer start As Integer n As Integer End Struct Library "libaudiofile:1.0.0" Private Const AF_DEFAULT_TRACK As Integer = 1001 Private Const AF_SAMPFMT_DOUBLE As Integer = 404 ' AFfilehandle afOpenFile (const char *filename, const char *mode, AFfilesetup setup) ' Opens a specified audio file and creates a file handle structure. Private Extern afOpenFile(filename As String, mode As String, setup As Pointer) As Pointer ' int afGetChannels (AFfilehandle, int track) ' Get the number of interleaved track from an AFfilehandle structure for an audio track. Private Extern afGetChannels(AFfile As Pointer, track As Integer) As Integer ' double afGetRate(AFfilehandle file, int track) ' Get the track sample rate for a specified audio track from an AFfilehandle structure. Private Extern afGetRate(AFfile As Pointer, track As Integer) As Float ' AFframecount afGetFrameCount (AFfilehandle file, int track) ' Get the total sample frame count for a specified audio track from an AFfilehandle structure. Private Extern afGetFrameCount(AFfile As Pointer, track As Integer) As Long ' int afSetVirtualSampleFormat (AFfilehandle, int track, int sampleFormat, int sampleWidth) ' Set the virtual data format for a specified audio track. Private Extern afSetVirtualSampleFormat(AFfile As Pointer, track As Integer, sampleFormat As Integer, sampleWidth As Integer) As Integer ' int afReadFrames (AFfilehandle, int track, void *buffer, int frameCount) ' Read sample frames from a track in an audio file. Private Extern afReadFrames(AFfile As Pointer, track As Integer, buffer As Float[], frameCount As Integer) As Integer ' int afCloseFile (AFfilehandle file) ' Closes an open audio file, updating the file if it was opened for writing. Private Extern afCloseFile(AFfile As Pointer) As Integer Public Sub Main() Dim nomefile As String Dim fl As Pointer Dim canali, windowSize, frameCount As Integer Dim i, c, winStart, winEnd, fine As Integer Dim powsmooth As New Smooth[] Dim lastWindow As Boolean Dim frames, sums As Float[] Dim frequenza, sample, pow, maxpow, durata As Float Dim livello, picco, minSample, maxSample As Float nomefile = "/percorso/del/file.wav" minSample = 1 maxSample = -1 fl = afOpenFile(nomefile, "r", 0) If fl == 0 Then Error.Raise("Impossibile aprire il file audio !") canali = afGetChannels(fl, AF_DEFAULT_TRACK) frequenza = afGetRate(fl, AF_DEFAULT_TRACK) durata = afGetFrameCount(fl, AF_DEFAULT_TRACK) / afGetRate(fl, AF_DEFAULT_TRACK) windowSize = CInt(frequenza / 100) frameCount = CInt(afGetFrameCount(fl, AF_DEFAULT_TRACK)) afSetVirtualSampleFormat(fl, AF_DEFAULT_TRACK, AF_SAMPFMT_DOUBLE, SizeOf(gb.Float)) powsmooth = New Smooth[canali] For c = 0 To canali - 1 With powsmooth[c] = New Smooth .lungh = 100 .buf = New Float[powsmooth[c].lungh * SizeOf(gb.Float)] .start = 0 .n = 0 End With Next Repeat winEnd = winStart + windowSize If winEnd >= frameCount Then winEnd = frameCount lastWindow = True Endif frames = New Float[canali * windowSize] afReadFrames(fl, AF_DEFAULT_TRACK, frames, windowSize) sums = New Float[canali] For c = 0 To canali - 1 sums[c] = 0 For i = 0 To (winEnd - winStart) - 1 sample = frames[i * canali + c] sums[c] += sample * sample If (sample > maxSample) Then maxSample = sample If (sample < minSample) Then minSample = sample Next Next ' Calcola la potenza di ciascun canale: For c = 0 To canali - 1 pow = sums[c] / (winEnd - winStart) fine = (powsmooth[c].start + powsmooth[c].n) % powsmooth[c].lungh powsmooth[c].buf[fine] = pow If powsmooth[c].n = powsmooth[c].lungh Then powsmooth[c].start = (powsmooth[c].start + 1) % powsmooth[c].lungh pow = Dati_Attenuati(powsmooth[c]) If pow > maxpow Then maxpow = pow Else Inc powsmooth[c].n Endif Next winStart += windowSize Until lastWindow For c = 0 To canali - 1 pow = Dati_Attenuati(powsmooth[c]) If pow > maxpow Then maxpow = pow Next livello = Sqr(maxpow) afCloseFile(fl) Print "File audio: "; Null, nomefile Print "Frequenza: "; Null, "Hz ";frequenza Print "Canali: "; Null, canali Print "Durata: "; Null, Cstr(Date(0, 0, 0, 0, 0, 0, durata * 1000)) Print "Livello (dB): "; Null, 20 * Log10(livello) Print "Picco-: "; Null, minSample Print "Picco+: "; Null, maxSample picco = Abs(minSample) If picco < Abs(maxSample) Then picco = Abs(maxSample) Print "Picco (dB): "; Null, 20 * Log10(picco) End Private Function Dati_Attenuati(s As Smooth) As Float Dim i As Integer Dim attenuato As Float attenuato = 0 For i = 0 To s.n - 1 attenuato += s.buf[i] Next attenuato = attenuato / s.n Return attenuato End