Domanda

Questo è il mio "weekend" problema di hobby.

Ho alcune forme d'onda a ciclo singolo molto amate dalle ROM di un sintetizzatore classico.

Questi sono campioni a 8 bit (256 possibili valori).

Poiché sono solo 8 bit, il rumore di fondo è piuttosto alto. Ciò è dovuto all'errore di quantizzazione. L'errore di quantizzazione è piuttosto strano. Incasina un po 'tutte le frequenze.

Mi piacerebbe prendere questi cicli e rendere " clean " Versioni a 16 bit. (Sì, so che le persone adorano le versioni sporche, quindi permetterò all'utente di interpolare tra sporco e pulito a qualsiasi livello gli piaccia.)

Sembra impossibile, giusto, perché ho perso gli 8 bit bassi per sempre, giusto? Ma questo è stato nella parte posteriore della mia testa per un po ', e sono abbastanza sicuro di poterlo fare.

Ricorda che si tratta di forme d'onda a ciclo singolo che si ripetono ripetutamente per la riproduzione, quindi questo è un caso speciale. (Naturalmente, il synth fa ogni genere di cose per rendere interessante il suono, inclusi inviluppi, modulazioni, dissolvenza incrociata dei filtri, ecc.)

Per ogni singolo campione di byte, quello che so davvero è che è uno dei 256 valori nella versione a 16 bit. (Immagina il processo inverso, in cui il valore a 16 bit viene troncato o arrotondato a 8 bit.)

La mia funzione di valutazione sta cercando di ottenere il rumore minimo. Dovrei essere in grado di giudicarlo con uno o più FFT.

I test esaustivi richiederebbero probabilmente un'eternità, quindi potrei fare un primo passaggio a bassa risoluzione. O semplicemente spingo casualmente i valori scelti casualmente (all'interno dei valori noti che manterrebbero la stessa versione a 8 bit) e faccio la valutazione e mantengo la versione più pulita? O c'è qualcosa di più veloce che posso fare? Sono in pericolo di cadere nei minimi locali quando potrebbero esserci dei minimi migliori altrove nello spazio di ricerca? L'ho fatto accadere in altre situazioni simili.

Ci sono delle ipotesi iniziali che posso fare, forse guardando i valori vicini?


Modifica: diverse persone hanno sottolineato che il problema è più semplice se rimuovo il requisito che la nuova forma d'onda campionasse sull'originale. È vero. In effetti, se sto solo cercando suoni più puliti, la soluzione è banale.

È stato utile?

Soluzione

Seguendo l'approccio nella tua domanda, suggerirei di esaminare algoritmi di arrampicata in collina e simili.

http://en.wikipedia.org/wiki/Hill_climbing contiene più informazioni e la sidebox contiene collegamenti ad altri algoritmi che potrebbero essere più adatti.

L'intelligenza artificiale è come l'alchimia: non abbiamo mai raggiunto l'obiettivo finale, ma lungo il cammino sono uscite molte cose buone.

Altri suggerimenti

È possibile inserire il campione esistente a 8 bit nel byte di ordine superiore del nuovo campione a 16 bit, quindi utilizzare il byte di ordine inferiore in interpolazione lineare alcuni nuovi punti dati a 16 bit tra ciascun campione originale a 8 bit.

Ciò essenzialmente collegherebbe una linea retta a 16 bit tra ciascuno dei tuoi campioni originali a 8 bit, usando diversi nuovi campioni. Sembrerebbe molto più silenzioso di quello che hai ora, che è un improvviso salto di 8 bit tra i due campioni originali.

Puoi anche provare ad applicare alcuni filtro passa-basso .

Bene, mi aspetto un po 'di filtro FIR (IIR se hai davvero bisogno di cicli di elaborazione, ma FIR può dare risultati migliori senza instabilità) per ripulire il rumore. Dovresti giocarci per ottenere l'effetto che desideri, ma il problema di base è appianare i bordi nitidi dell'audio creato campionandolo con risoluzioni a 8 bit. Darei una grande nascita alla frequenza centrale dell'audio e farei un filtro passa-basso, quindi ascolterei per assicurarmi di non farlo sembrare "piatto". con il filtro che ho scelto.

È difficile, c'è solo così tanto che puoi fare, gli 8 bit inferiori vengono persi, il meglio che puoi fare è approssimarlo.

È quasi impossibile sbarazzarsi del rumore che assomiglia al tuo segnale. Se inizi a cercare cose nella tua banda di frequenza, questo eliminerà il segnale di interesse.

Per l'upsampling, poiché stai già utilizzando un FFT, puoi aggiungere zeri alla fine del segnale del dominio della frequenza ed eseguire un FFT inverso. Ciò preserva completamente la frequenza e le informazioni di fase del segnale originale, sebbene diffonda la stessa energia su più campioni. Se si sposta 8 bit per essere prima un campione a 16 bit, questo non sarà un grosso problema. Ma di solito lo sollevo con un fattore di guadagno intero prima di eseguire la trasformazione.

Pete

Modifica: I commenti stanno diventando un po 'lunghi, quindi ne sposterò alcuni alla risposta.

I picchi nell'uscita FFT sono picchi armonici causati dalla quantizzazione. Tendo a pensarli in modo diverso rispetto al rumore di fondo. Puoi menzionare qualcuno come menzionato ed eliminare l'ampiezza delle punte armoniche e appiattire il rumore di fondo, ma perdi tutto il segnale al rumore sulla parte piatta del rumore di fondo. Per quanto riguarda la FFT. Quando interpoli usando questo metodo, conserva la stessa energia e si diffonde su più campioni, ciò riduce l'ampiezza. Quindi, prima di fare l'inverso, dai al tuo segnale più energia moltiplicando per un fattore di guadagno.

I segnali sono sinusoidi semplici / complessi o hanno bordi duri? cioè triangolo, onde quadrate, ecc. Sto assumendo che abbiano continuità da un ciclo all'altro, è valido? In tal caso, puoi anche aumentare la risoluzione FFT per individuare con precisione le frequenze aumentando il numero di cicli di forme d'onda trasmessi al tuo FFT. Se riesci a identificare con precisione le frequenze utilizzate, supponendo che siano in qualche modo discrete, potresti essere in grado di ricreare completamente il segnale desiderato.

I requisiti da 16 a 8 bit tramite troncamento produrranno risultati che non corrispondono alla fonte originale. (In questo modo è più difficile trovare una risposta ottimale.) Generalmente si produrrebbe una forma d'onda a punto fisso tentando di "ottenere la corrispondenza più vicina". ciò significa arrotondare al numero più vicino (il trunking è un'operazione da pavimento). Questo è molto probabilmente il modo in cui sono stati originariamente generati. L'aggiunta di 0,5 (in questo caso 0,5 è 128) e quindi il trunking dell'output consentirebbe di generare risultati più accurati. Se questo non è un problema, ok, ma sicuramente avrà un effetto negativo sulla precisione.

AGGIORNAMENTO: Perché? Perché l'obiettivo del campionamento di un segnale è quello di essere in grado di riprodurre il segnale il più vicino possibile. Se la soglia di conversione è impostata male sul campionamento, tutto ciò che si è verificato è su un lato del segnale e non ben distribuito e centrato su zero. Su tali sistemi in genere si tenta di massimizzare l'utilizzo della gamma dinamica disponibile, in particolare se si dispone di una bassa risoluzione come un ADC a 8 bit.

Versioni a banda limitata? Se sono filtrati a frequenze diverse, sospetto che sia stato per consentirti di riprodurre lo stesso suono senza distorsioni quando sei andato troppo lontano dall'altra variazione. Un po 'come mipmapping nella grafica. Ho il sospetto che i due siano lo stesso segnale con diversi filtri di aliasing applicati, questo può essere utile per riprodurre l'originale. Dovrebbero essere lo stesso segnale di base con diverse convoluzioni applicate.

Potrebbe esserci un approccio semplice che sfrutta la periodicità delle forme d'onda. Che ne dici se tu:

  1. Crea una forma d'onda a 16 bit in cui i byte alti sono la forma d'onda e i byte bassi sono zero - chiamala x [n].

  2. Calcola la trasformata discreta di Fourier di x [n] = X [w].

  3. Crea un segnale Y [w] = (dBMag (X [w]) > Soglia)? X [w]: 0, dove dBMag (k) = 10 * log10 (real (k) ^ 2 + imag (k) ^ 2) e la soglia è forse 40 dB, in base a 8 bit che si trovano a circa 48 dB di gamma dinamica, e consentendo ~ 1,5 bit di rumore.

  4. Trasforma inversa Y [w] per ottenere y [n], la tua nuova forma d'onda a 16 bit.

  5. Se y [n] non suona bene, esegui un rumore di livello molto basso.

Note:

A. Questa tecnica funziona solo nelle forme d'onda originali sono esattamente periodiche!

B. Il passaggio 5 potrebbe essere sostituito con l'impostazione di " 0 " valori di rumore casuale in Y [w] al punto 3, dovresti sperimentare un po 'per vedere cosa funziona meglio.

Questo sembra più facile (almeno per me) di un approccio di ottimizzazione. Ma troncato y [n] probabilmente non sarà uguale alle forme d'onda originali. Non sono sicuro di quanto sia importante quel vincolo. Sento che questo approccio genererà forme d'onda che suonano bene.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top