Aiuta a implementare la compressione della gamma dinamica audio


8

Sto cercando di implementare la compressione della gamma dinamica audio in JavaScript (non usando l'API audio web).

Ci sono molti articoli per i tecnici del suono e una documentazione di alto livello, ma non sono riuscito a trovare alcun riferimento utile per implementare effettivamente la compressione della gamma dinamica digitale.

Da quello che ho capito, ci sono almeno 3 passaggi nel calcolo del segnale rettificato.

  1. calcolare il livello di input
  2. calcolare il guadagno da applicare al segnale
  3. applicando il guadagno

Elaboro l'audio in blocchi, quindi per 1) stavo pensando di calcolare l'RMS di un blocco

Qualche suggerimento per un buon riferimento? O qualcuno disposto a spiegarmi un po 'i passaggi necessari per implementare questo?


1
Giusto per essere sicuri: vuoi implementare qualcosa del genere: waves.com/plugins/c1-compressor , giusto?
Deve il

si :) ma molto più semplice! I controlli di cui ho bisogno sarebbero soglia, ginocchio, rapporto, attacco, rilascio. Ma posso iniziare con ancora più semplice
sebpiq,

Risposte:


4

Ecco alcuni suggerimenti:

  • Ci sono molte implementazioni open source (Sox, Audacity, ecc.). Anche se non li capisci, potresti essere in grado di tradurre il codice da C a javascript.
  • Non sono a conoscenza di una buona spiegazione del processo online, ma ci sono molti libri sull'argomento:
    • L'elaborazione del segnale audio digitale copre questo argomento ed è ben scritta. (Come DAFX , ma DAFX è scarsamente organizzato e la copertura è meno semplice)
    • Anche l'audio digitale con Java tratta questo argomento e include un codice Java funzionante che dovrebbe essere facile da tradurre in altre lingue, come javascript. Questo libro ha molti difetti, ma è buono per qualcuno che non ha esperienza di programmazione audio.

Il principio è quello di creare un inviluppo del segnale (controllato da attacco e rilascio), modellare quell'involucro utilizzando una funzione di trasferimento (controllata da rapporto, soglia e ginocchio) e quindi applicare quel risultato al segnale originale. Segue spesso una fase di trucco.

La risposta di @ Deve suggerisce alcune possibili funzioni di trasferimento.


Il fatto è che non conosco C, e sì, questo è un grosso ostacolo quando si lavora con audio dsp, perché non riesco a controllare le implementazioni esistenti. Altrimenti, grazie per i libri, controllerò sicuramente il primo almeno.
sebpiq,

Il libro DAFX ha un codice matlab. IDK se ha il codice matlab per un compressore.
Bjorn Roche,

Per il libro "Elaborazione del segnale audio digitale", i commenti su Amazon affermano che è meglio per le persone con un background di ingegnere elettrico. Conosci qualche libro che si concentra maggiormente sugli algoritmi, il migliore sarebbe ad esempio nello pseudo-codice?
sebpiq,

1
In un modo o nell'altro, dovrai imparare alcune nuove abilità, credo.
Bjorn Roche,

Si, lo so! E io sono pronto per questo. È solo che non voglio davvero il codice matlab, ad esempio, poiché non voglio pagare per matlab per poterli testare. Ecco perché ti ho chiesto se conosci altri libri con, ad esempio, lo pseudo codice, invece di un linguaggio specifico (come Java che non mi interessa davvero imparare).
sebpiq,

2

Per un semplice inizio, userei una caratteristica non lineare g(x) che comprime il segnale di input:

y=g(x)

dove (come sottolineato da endolith nei commenti) xè l' inviluppo del segnale audio in ingresso ey è l'inviluppo di uscita che viene applicato al segnale audio effettivo. g(x)può essere qualsiasi funzione che attenua valori di input di grandi dimensioni più forti di valori di input di piccole dimensioni. La legge A eμ-Le funzioni del telefono sono state sviluppate per comprimere i segnali vocali per la telefonia, ad esempio. Non so quanto sia bello questo per la musica, però.

Un'altra funzione di compressione molto semplice sarebbe quella di attenuare tutte le ampiezze al di sopra di una certa soglia δ:

g(x)={xforxδax+(1a)δforx>δ
dove a<1è attenuazione. Ma questo non funzionerà molto bene poiché il nostro senso dell'udito è logaritmico, quindi l'attenuazione potrebbe essere troppo forte. Questo è il motivo per cui i compressori audio funzionano su una scala logaritmica e porta alla stessa funzione di cui sopra, ma tutti i valori presi logaritmici e rispetto al massimo valore possibile. Perx>0:
log(g(x))={log(x)forxδ1rlog(x)+(11r)log(δ)forx>δ

Per i compressori audio, δ è di solito espresso in dB e r è espresso come un certo rapporto, ad esempio 3: 1 (ad es r=3). Ciò produce una funzione esponenziale, se espressa in modo lineare (spero che sia corretta, si prega di controllare anchex>0):

g(x)={xforxδδ11/rx1/rforx>δ
Questa funzione ha un "ginocchio duro", nel senso che la funzione logg(x) non è differenziabile in x=δ. Per un "ginocchio morbido" avresti bisogno di una transizione graduale a quel punto. L'estensione delle funzioni sopra per negativox è semplice, basta moltiplicare per la funzione signum e assumere il valore assoluto di x.

L'attacco e il rilascio hanno un impatto su diversi suoni come calci, trappole e voce. Determinano per quanto tempo prima del raggiungimento della soglia il compressore dovrebbe iniziare a funzionare e per quanto tempo dovrebbe continuare a funzionare dopo che il segnale è sceso al di sotto della soglia. Per implementare questo dovrai usare una sorta di look-ahead.

Come tutte le ampiezze di seguito δsono attenuati, la gamma dinamica disponibile non è completamente sfruttata. Ciò è corretto dal cosiddetto "guadagno del trucco", che è solo una semplice moltiplicazione del segnale compresso con un fattore di guadagnoG>1. Riducendo dapprima la gamma dinamica e quindi amplificando i compressori di segnale, la musica può apparire "più forte".


Grazie! Ottima spiegazione Sono arrivato a una funzione di trasferimento vicina a quella che hai dato, ma la mia non includeva la soglia (ho semplificato con la soglia = 0), quindi devo ricalcolare.
sebpiq,

In realtà la funzione di trasferimento che ottengo aggiungendo la soglia è x ^ (1 / r) * 10 ^ (- sigma / (20 * r))
sebpiq,

Scusate, le mie definizioni di fucntion erano un disastro perché ho dimenticato di aggiungere il pregiudizio costante. L'ho corretto. L'ultima espressione, tuttavia, è corretta secondo me. Deve soddisfareg(δ)=δ. Non c'è un fattore 20 coinvolto qui perché stiamo prendendo il logaritmo del lato sinistro e destro in modo che qualsiasi fattore costante si annulli.
Deve il

Sembrano distorsione, non compressione. La distorsione è un cambiamento di livello che si verifica su base campione per campione, mentre la compressione è qualcosa che accade in molti cicli della forma d'onda (ognuno dei quali è composto da molti campioni). La distorsione non lineare sembrerà terribile.
endolith

@endolith Hai ragione, grazie per il suggerimento. Ho aggiornato la mia risposta di conseguenza.
Deve l'
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.