Differenze tra le versioni di "Modificare il volume e la frequenza di campionamento di file audio WAV e AIFF con l'API di Libaudio"

Da Gambas-it.org - Wikipedia.
 
(Una versione intermedia di uno stesso utente non è mostrata)
Riga 1: Riga 1:
 
La libreria '''Libaudio''', appartenente al protoccolo audio ''Network Audio System'' (NAS), consente di gestire alcuni formati di file audio.
 
La libreria '''Libaudio''', appartenente al protoccolo audio ''Network Audio System'' (NAS), consente di gestire alcuni formati di file audio.
  
Per poter fruire delle risorse di ''Libaudio'', è necessario installare nel sistema e richiamare nel programma Gambas la libreria dinamica condivisa: "''libaudio.so.2.4''"
+
Per poter fruire delle risorse di ''Libaudio'', è necessario installare nel sistema e richiamare nel programma Gambas la libreria condivisa: "''libaudio.so.2.4'' ".
  
  
Riga 59: Riga 59:
 
   
 
   
 
   
 
   
  '''Public''' Sub Main()
+
  Public Sub Main()
 
   
 
   
  Dim inFl, exFl As String
+
  Dim inFl, exFl As String
  Dim sndIn, sndOut As New Sound
+
  Dim sndIn, sndOut As New Sound
  Dim frequenza, numBytes, err As Integer
+
  Dim frequenza, numBytes, err As Integer
  Dim volume, conto, outputDataFormat, fileFormat As Integer
+
  Dim volume, conto, outputDataFormat, fileFormat As Integer
  Dim dati As Pointer    <FONT Color=gray>' ''= buffer''</font>
+
  Dim dati As Pointer    <FONT Color=gray>' ''= buffer''</font>
  Dim st As Stream
+
  Dim st As Stream
  Dim sh As Short
+
  Dim sh As Short
 
    
 
    
   inFl = "''/percorso/del/file/audio/da/modificare''"
+
   inFl = "<FONT Color=darkgreen>''/percorso/del/file/audio/da/modificare''</font>"
   exFl = "''/percorso/del/nuovo/file/come/modificato''"
+
   exFl = "<FONT Color=darkgreen>''/percorso/del/nuovo/file/come/modificato''</font>"
 
    
 
    
 
   sndIn = SoundOpenFileForReading(inFl)
 
   sndIn = SoundOpenFileForReading(inFl)
Riga 80: Riga 80:
 
   volume = 20
 
   volume = 20
 
    
 
    
  <FONT Color=gray>' ''Modifichiamo la frequenza di campionamento''</font>
+
  <FONT Color=gray>' ''Modifichiamo la frequenza originaria di campionamento dei dati audio dimezzandola:''</font>
   frequenza = 22050 'sndIn.sampleRate
+
   frequenza = sndIn.sampleRate / 2
 
      
 
      
 
   If (volume = 100) And (frequenza = sndIn.sampleRate) Then
 
   If (volume = 100) And (frequenza = sndIn.sampleRate) Then
Riga 134: Riga 134:
 
   Free(dati)
 
   Free(dati)
 
    
 
    
  '''End'''
+
  End
 
   
 
   
 
   
 
   
  '''Private''' Procedure rateConvert(soIn As Sound, soOut As Sound, nb As Integer, data As Pointer)
+
  Private Procedure rateConvert(soIn As Sound, soOut As Sound, nb As Integer, data As Pointer)
 
 
  Dim dimen, phase, err As Integer
 
  Dim ultimum As Pointer
 
 
    
 
    
 +
  Dim dimen, phase, err As Integer
 +
  Dim ultimum As Pointer
 +
 
   dimen = SizeOf(gb.Short)
 
   dimen = SizeOf(gb.Short)
 
    
 
    
 
   ultimum = Alloc(dimen)
 
   ultimum = Alloc(dimen)
   If IsNull(ultimum) Then Error.Raise("Errore nell'allocazione di memoria !")
+
   If ultimum == 0 Then Error.Raise("Errore nell'allocazione di memoria !")
 
    
 
    
 
   While nb
 
   While nb
Riga 167: Riga 167:
 
   Wend
 
   Wend
 
    
 
    
  '''End'''
+
  End
 
 
  
  

Versione attuale delle 08:28, 19 giu 2024

La libreria Libaudio, appartenente al protoccolo audio Network Audio System (NAS), consente di gestire alcuni formati di file audio.

Per poter fruire delle risorse di Libaudio, è necessario installare nel sistema e richiamare nel programma Gambas la libreria condivisa: "libaudio.so.2.4 ".


Mostriamo un esempio per modificare il volume e/o la frequenza di campionamento di un file audio di formato WAV o AIFF:

Library "libaudio:2.4"

Public Struct Sound
  fileFormat As Integer
  dataFormat As Integer
  numTracks As Integer
  sampleRate As Integer
  numSamples As Integer
  comment As String
  formatInfo As Pointer
End Struct

Private Const SoundUnknownNumSamples As Integer = &FFFFFFFF

' Sound SoundOpenFileForReading(const char * filename)
' Open an audio file for reading.
Private Extern SoundOpenFileForReading(filename As String) As Sound

' int SoundReadFile(char * buffer, int num_bytes, Sound sound)
' Read audio data from an audio file.
Private Extern SoundReadFile(buffer As Pointer, bytes As Integer, Ssound As Sound) As Integer

' int AuConvertDataToShort(int data_format, int num_bytes, AuPointer data)
' Convert audio data from the specified format to signed short integer.
Private Extern AuConvertDataToShort(Sformat As Integer, bytes As Integer, buffer As Pointer) As Integer

' int SoundValidDataFormat(int _f, int _d)
Private Extern SoundValidDataFormat(S_f As Integer, S_d As Integer) As Integer

' Sound SoundCreate(int file_format, int data_format, int num_tracks, int sample_rate, int num_samples, char * comment)
' Create a description of an audio file.
Private Extern SoundCreate(file_format As Integer, data_format As Integer, num_tracks As Integer, sample_rate As Integer, num_samples As Integer, comment As String) As Sound

' int AuConvertShortToData(int format, int num_bytes, AuPointer data)
' Convert signed short integers to the specified format.
Private Extern AuConvertShortToData(file_format As Integer, bytes As Integer, buffer As Pointer) As Integer

' Sound SoundOpenFileForWriting(char *filename, Sound sound)
' Open an audio file for writing.
Private Extern SoundOpenFileForWriting(filename As String, Ssound As Sound) As Sound

' int SoundWriteFile(char *buffer, int num_bytes, Sound sound)
' Write audio data to an audio file.
Private Extern SoundWriteFile(buffer As Pointer, bytes As Integer, Ssound As Sound) As Integer

' int SoundCloseFile(Sound sound)
' Close an audio file description.
Private Extern SoundCloseFile(Ssound As Sound) As Integer

' void bcopy(const void *src, void *dest, size_t n)
' Copy byte sequence.
Private Extern bcopy(src As Pointer, dest As Pointer, n As Integer) In "libc:6"


Public Sub Main()

  Dim inFl, exFl As String
  Dim sndIn, sndOut As New Sound
  Dim frequenza, numBytes, err As Integer
  Dim volume, conto, outputDataFormat, fileFormat As Integer
  Dim dati As Pointer     ' = buffer
  Dim st As Stream
  Dim sh As Short
 
  inFl = "/percorso/del/file/audio/da/modificare"
  exFl = "/percorso/del/nuovo/file/come/modificato"
  
  sndIn = SoundOpenFileForReading(inFl)
  If IsNull(sndIn) Then Error.Raise("Impossibile aprire il file '" & inFl & "' !")
   
  numBytes = sndIn.numSamples * sndIn.numTracks * SizeOf(gb.Short)
   
' Modifichiamo il volume: il valore va inteso in percentuale rispetto al volume originario
  volume = 20
  
' Modifichiamo la frequenza originaria di campionamento dei dati audio dimezzandola:
  frequenza = sndIn.sampleRate / 2
   
  If (volume = 100) And (frequenza = sndIn.sampleRate) Then
    Print "\nPoiché non si intende effettuare alcuna variazione, il programma verrà terminato !"
    Quit
  Endif
   
  dati = Alloc(numBytes)
   
  If SoundReadFile(dati, numBytes, sndIn) <> numBytes Then Error.Raise("Errore di lettura del file audio d'ingresso !")
  
  err = AuConvertDataToShort(sndIn.dataFormat, numBytes, dati)
  If err <> 0 Then Error.Raise("Errore nella conversione dei dati di Entrata !")
   
' Effettua la modifica del volume:
  If volume < 100 Then
     
' Per scrivere i nuovi valori dei dati audio nell'area di memoria puntata da "Puntatore" usiamo i "Memory Stream":
    st = Memory dati For Read Write
     
    For conto = 0 To (numBytes / SizeOf(gb.Short)) - 1
      Read #st, sh
      sh *= CSingle(volume / 100)
      Seek #st, Seek(st) - 2       ' Torniamo dietro di 2 byte, perché si tratta di uno Short
      Write #st, sh As Short
    Next
    st.Close
     
  Endif
      
  err = SoundValidDataFormat(sndIn.fileFormat, sndIn.dataFormat)
  If Not err Then Error.Raise("Formato di file non supportato !")
     
  sndOut = SoundCreate(sndIn.fileFormat, sndIn.dataFormat, sndIn.numTracks, frequenza, SoundUnknownNumSamples, Null)
  If IsNull(sndOut) Then Error.Raise("Impossibile creare il file sonoro di Uscita !")
     
  err = AuConvertShortToData(sndIn.dataFormat, numBytes, dati)
  If err <> 0 Then Error.Raise("Errore di conversione dei dati audio in Uscita !")
     
  If Not SoundOpenFileForWriting(exFl, sndOut) Then Error.Raise("Impossibile aprire il file in scrittura dati !")
   
' Effettua la modifica della frequenza di campionamento:
  If sndIn.sampleRate = sndOut.sampleRate Then
    err = SoundWriteFile(dati, numBytes, sndOut)
    If err <> numBytes Then Error.Raise("Errore nella scrittura del file audio in Uscita !")
  Else
    rateConvert(sndIn, sndOut, numBytes, dati)
  Endif
   
  If SoundCloseFile(sndOut) Then Error.Raise("Impossibile chiudere il file audio di Uscita !")
   
  Free(dati)
  
End


Private Procedure rateConvert(soIn As Sound, soOut As Sound, nb As Integer, data As Pointer)
 
  Dim dimen, phase, err As Integer
  Dim ultimum As Pointer

  dimen = SizeOf(gb.Short)
  
  ultimum = Alloc(dimen)
  If ultimum == 0 Then Error.Raise("Errore nell'allocazione di memoria !")
  
  While nb
     
    While phase >= 0
      If nb = 0 Then
        Free(ultimum)
        Return
      Endif
      phase -= soOut.sampleRate
      bcopy(data, ultimum, dimen)
      data += dimen
      nb -= dimen
    Wend
     
    phase += soIn.sampleRate
  
    err = SoundWriteFile(ultimum, dimen, soOut)
    If err <> dimen Then Error.Raise("Errore nella scrittura del file audio in Uscita !")
  
  Wend
 
End


Riferimenti