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.
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 | + | 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() | |
− | + | 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 <FONT Color=gray>' ''= buffer''</font> | |
− | + | Dim st As Stream | |
− | + | 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 134: | Riga 134: | ||
Free(dati) | 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) | dimen = SizeOf(gb.Short) | ||
ultimum = Alloc(dimen) | ultimum = Alloc(dimen) | ||
− | If | + | If ultimum == 0 Then Error.Raise("Errore nell'allocazione di memoria !") |
While nb | While nb | ||
Riga 167: | Riga 167: | ||
Wend | Wend | ||
− | + | 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