Differenze tra le versioni di "Codificare e decodificare un flusso audio Opus mediante la libreria Libopus"
Riga 2: | Riga 2: | ||
<BR>''Opus'' è in grado di gestire un'ampia gamma di applicazioni audio, tra cui ''Voice over IP'', videoconferenze, ''chat in-game'' e persino esibizioni di musica dal vivo in remoto. Può passare dal parlato, a banda stretta, a basso bitrate a musica stereo di altissima qualità. | <BR>''Opus'' è in grado di gestire un'ampia gamma di applicazioni audio, tra cui ''Voice over IP'', videoconferenze, ''chat in-game'' e persino esibizioni di musica dal vivo in remoto. Può passare dal parlato, a banda stretta, a basso bitrate a musica stereo di altissima qualità. | ||
− | E' necessario avere installata nel sistema e richiamare in Gambas la libreria condivisa: "''libopus.so.0. | + | E' necessario avere installata nel sistema e richiamare in Gambas la libreria condivisa: "''libopus.so.0.9.0'' ". |
Vediamo di seguito un breve esempio di codifica e decodifica audio usando ''Opus'', per mostrare semplicemente come questa libreria funziona. In particolare da un file wav si otterrà un flusso audio codificato con ''Opus'', e si decodificherà tale flusso codificato nuovamente in un file di tipo wav. | Vediamo di seguito un breve esempio di codifica e decodifica audio usando ''Opus'', per mostrare semplicemente come questa libreria funziona. In particolare da un file wav si otterrà un flusso audio codificato con ''Opus'', e si decodificherà tale flusso codificato nuovamente in un file di tipo wav. | ||
Riga 10: | Riga 10: | ||
Private Const FRAME_SIZE As Integer = 960 | Private Const FRAME_SIZE As Integer = 960 | ||
− | Library "libopus:0. | + | Library "libopus:0.9.0" |
Private Const OPUS_APPLICATION_VOIP As Integer = 2048 | Private Const OPUS_APPLICATION_VOIP As Integer = 2048 | ||
Riga 41: | Riga 41: | ||
− | + | Public Sub Main() | |
Dim wav As String | Dim wav As String | ||
Riga 52: | Riga 52: | ||
Dim pcm As Byte[] | Dim pcm As Byte[] | ||
− | wav = "<FONT Color= | + | wav = "<FONT Color=darkgreen>''/percorso/del/file.wav''</font>" |
<FONT Color=gray>' ''Crea il codificatore in formato "opus":''</font>" | <FONT Color=gray>' ''Crea il codificatore in formato "opus":''</font>" | ||
Riga 66: | Riga 66: | ||
deco = opus_decoder_create(48000, CANALI, VarPtr(i)) | deco = opus_decoder_create(48000, CANALI, VarPtr(i)) | ||
If deco = 0 Then Error.Raise("Errore: " & opus_strerror(i)) | If deco = 0 Then Error.Raise("Errore: " & opus_strerror(i)) | ||
− | + | ||
Repeat | Repeat | ||
pcm = New Byte[MAX_FRAME_SIZE * CANALI * SizeOf(gb.Short)] | pcm = New Byte[MAX_FRAME_SIZE * CANALI * SizeOf(gb.Short)] | ||
Riga 105: | Riga 105: | ||
opus_encoder_destroy(enco) | opus_encoder_destroy(enco) | ||
− | + | End | |
− | + | Private Procedure HeaderWav() <FONT Color=gray>' ''Crea l'header del file wav''</font> | |
Dim hdr As Byte[] | Dim hdr As Byte[] | ||
Riga 130: | Riga 130: | ||
File.Save("/tmp/file_finale.wav", hdr.ToString(0, hdr.Count) & s) | File.Save("/tmp/file_finale.wav", hdr.ToString(0, hdr.Count) & s) | ||
− | + | End | |
− | |||
Versione attuale delle 06:51, 16 gen 2024
Opus è un codec audio totalmente aperto, esente da diritti e altamente versatile.
Opus è in grado di gestire un'ampia gamma di applicazioni audio, tra cui Voice over IP, videoconferenze, chat in-game e persino esibizioni di musica dal vivo in remoto. Può passare dal parlato, a banda stretta, a basso bitrate a musica stereo di altissima qualità.
E' necessario avere installata nel sistema e richiamare in Gambas la libreria condivisa: "libopus.so.0.9.0 ".
Vediamo di seguito un breve esempio di codifica e decodifica audio usando Opus, per mostrare semplicemente come questa libreria funziona. In particolare da un file wav si otterrà un flusso audio codificato con Opus, e si decodificherà tale flusso codificato nuovamente in un file di tipo wav.
Private Const CANALI As Integer = 2 Private Const MAX_PACKET_SIZE As Integer = 3828 Private Const MAX_FRAME_SIZE As Integer = 5760 Private Const FRAME_SIZE As Integer = 960 Library "libopus:0.9.0" Private Const OPUS_APPLICATION_VOIP As Integer = 2048 Private Const OPUS_APPLICATION_AUDIO As Integer = 2049 Private Const OPUS_APPLICATION_RESTRICTED_LOWDELAY As Integer = 2051 ' OpusEncoder *opus_encoder_create( opus_int32 Fs, int channels, int application, int *error ) ' Allocates and initializes an encoder state. Private Extern opus_encoder_create(Fs As Integer, channels As Integer, _application As Integer, _error As Pointer) As Pointer ' const char *opus_strerror(int error) ' Converts an opus error code into a human readable string. Private Extern opus_strerror(_error As Integer) As String ' opus_int32 opus_encode( OpusEncoder *st, const opus_int16 *pcm, int buffer, unsigned char *data, opus_int32 max_data_bytes) ' Encodes an Opus frame. Private Extern opus_encode(st As Pointer, pcm As Pointer, buffer As Integer, data As Pointer, max_data_bytes As Integer) As Integer ' OpusDecoder *opus_decoder_create( opus_int32 Fs, int channels, int *error ) ' Allocates and initializes a decoder state. Private Extern opus_decoder_create(Fs As Integer, channels As Integer, _error As Pointer) As Pointer ' int opus_decode( OpusDecoder *st, const unsigned char *data, opus_int32 len, opus_int16 *pcm, int frame_size, int decode_fec) ' Decode an Opus packet. Private Extern opus_decode(st As Pointer, data As Pointer, _len As Integer, pcm As Pointer, frame_size As Integer, decode_fec As Integer) As Integer ' void opus_encoder_destroy(OpusEncoder *st) ' Frees an OpusEncoder allocated by opus_encoder_create(). Private Extern opus_encoder_destroy(st As Pointer) Public Sub Main() Dim wav As String Dim enco, deco As Pointer Dim i, nb, frames As Integer Dim fen, fex As File Dim buffen As New Short[FRAME_SIZE * CANALI] Dim buffex As New Short[MAX_FRAME_SIZE * CANALI] Dim cbits As New Byte[MAX_PACKET_SIZE] Dim pcm As Byte[] wav = "/percorso/del/file.wav" ' Crea il codificatore in formato "opus":" enco = opus_encoder_create(48000, CANALI, OPUS_APPLICATION_AUDIO, VarPtr(i)) If enco = 0 Then Error.Raise("Errore: " & opus_strerror(i)) fen = Open wav For Read pcm = New Byte[MAX_FRAME_SIZE * CANALI * SizeOf(gb.Short)] ' Crea il file finale wav che dovrà contenere i dati audio del flusso "opus" ri-decodificato:: fex = Open "/tmp/dati" For Write Append ' Crea il decodificatore: deco = opus_decoder_create(48000, CANALI, VarPtr(i)) If deco = 0 Then Error.Raise("Errore: " & opus_strerror(i)) Repeat pcm = New Byte[MAX_FRAME_SIZE * CANALI * SizeOf(gb.Short)] ''''' Fase di codifica audio Opus ''''' ' Legge i dati audio dal file wav iniziale: pcm.Read(fen, 0, (FRAME_SIZE * CANALI) * SizeOf(gb.Short)) ' Effettua la conversione dall'ordine Little-Endian: For i = 0 To (CANALI * FRAME_SIZE) - 1 buffen[i] = (pcm[2 * i + 1] * CInt(2 ^ 8)) Or pcm[2 * i] Next nb = opus_encode(enco, buffen.Data, FRAME_SIZE, cbits.Data, MAX_PACKET_SIZE) If nb < 0 Then Error.Raise("Errore: " & opus_strerror(nb)) ''''' Fase di decodifica audio da Opus in PCM grezzi ''''' ' Decodifica i dati. In questo esempio, frame_size sarà costante poiché l'encoder utilizza una dimensione di frame costante. ' Tuttavia, potrebbe non essere il caso per tutti gli encoder, quindi il decoder deve sempre controllare la dimensione del frame restituita. frames = opus_decode(deco, cbits.Data, nb, buffex.Data, MAX_FRAME_SIZE, 0) If frames < 0 Then Error.Raise("Errore: " & opus_strerror(frames)) For i = 0 To frames * CANALI - 1 Write #fex, buffex[i] And &FF As Byte Write #fex, (buffex[i] \ CInt(2 ^ 8)) And &FF As Byte Next Until Lof(fen) - Seek(fen) < FRAME_SIZE fen.Close fex.Close HeaderWav() opus_encoder_destroy(deco) opus_encoder_destroy(enco) End Private Procedure HeaderWav() ' Crea l'header del file wav Dim hdr As Byte[] Dim b As Byte Dim s As String ' Imposta i dati principali dell'header del file WAV finale: hdr = [&52, &49, &46, &46, &00, &00, &00, &00, &57, &41, &56, &45, &66, &6D, &74, &20, &10, &00, &00, &00, &01, &00, &02, &00, &44, &AC, &00, &00, &10, &B1, &02, &00, &04, &00, &10, &00, &64, &61, &74, &61, &00, &00, &00, &00] s = File.Load("/tmp/dati") ' Determina i valori a 32-bit, relativi alla dimensione del file wav, richiesti al 5° e al 41° byte dell'header: For b = 0 To 3 hdr[4 + b] = Shr(Len(s) + 38, 8 * b) And &FF hdr[40 + b] = Shr(Len(s), 8 * b) And &FF Next ' Genera il file finale di tipo WAV dai dati Opus riconvertiti in PCM grezzi: File.Save("/tmp/file_finale.wav", hdr.ToString(0, hdr.Count) & s) End