2014-10-30 14 views
5

Sto provando a disegnare una forma d'onda da un file audio grezzo. Ho demedito/decodificato un file audio usando FFmpeg e ho queste informazioni: buffer dei campioni, dimensione del buffer dei campioni, durata del file audio (in secondi), frequenza di campionamento (44100, 48000, ecc.), Dimensione del campione, campione format (uint8, int16, int32, float, double) e i dati audio originali.Algoritmo per disegnare forme d'onda dall'audio

Scavando su Internet ho trovato questo algoritmo (più here):

White Noise:

White Noise

L'algoritmo

Tutto quello che dovete fare è casuale ogni campione da -amplitude a ampiezza. Nella maggior parte dei casi non ci interessa il numero di canali, quindi riempiamo semplicemente ogni campione con un nuovo numero casuale.

Random rnd = new Random(); 
short randomValue = 0; 

for (int i = 0; i < numSamples; i++) 
{ 
    randomValue = Convert.ToInt16(rnd.Next(-amplitude, amplitude)); 
    data.shortArray[i] = randomValue; 
} 

E 'davvero buono, ma non voglio disegnare in quel modo, ma in questo modo:

audacity

Esiste un algoritmo o idea di come posso essere disegno utilizzando il informazioni che ho?

+0

Sembra che tu stia cercando di utilizzare la forma d'onda ** generando ** algoritmi quando hai già la forma d'onda. Quindi mi sembra che tu non debba fare nulla. – Galik

+0

@Galik - Cosa intendi con "hai già la forma d'onda"? L'unica cosa che ho sono le informazioni sul file raw sopra elencato, ora sto cercando un algoritmo per disegnare la forma d'onda usando quelle informazioni. – yayuj

+0

Beh, gli algoritmi che hai collegato non hanno nulla a che fare con il disegno dell'onda. Generano l'onda. Hai generato la tua onda usando ffmpeg per convertire i dati audio grezzi. Quindi non hai bisogno di un generatore. Penso che forse quello di cui hai bisogno è una specie di framework GUI che ti permetta di disegnare cose sullo schermo. – Galik

risposta

5

In primo luogo, è necessario determinare la posizione in cui ogni campione verrà visualizzato.

int x = x0 + sample_number * (xn - x0)/number_of_samples; 

Ora, per tutti i campioni con la stessa x, determinare il minimo e il massimo separatamente per valori positivi e negativi. Disegna una linea verticale, una scura da massima negativa a massima positiva, poi una luce da min negativo a min positivo sopra la parte superiore.

Modifica: pensando a questo un po 'di più, probabilmente si desidera utilizzare una media anziché il minimo per le linee interne.

1

I grafici in basso includono semplicemente un intervallo di tempo più lungo, quindi se aumenti i tuoi numSamples otterresti un grafico più stretto. Ma con il rumore bianco non vedrai i picchi e gli avvallamenti che troverai nei normali suoni/musica.

Quindi, se è possibile aumentare la dimensione del campione o almeno aumentare il periodo di campionamento (asse x) inizierete ad emulare i grafici in basso. Usane due per ottenere l'effetto stereo.

3

C'è un bel programma audiowaveform da BBC R & D che fa quello che vuoi, puoi consultare le loro fonti.

+0

Sicuramente sarà d'aiuto. Grazie. – yayuj

3

Penso che tu ti stia riferendo a una forma d'onda descritta qui.

http://manual.audacityteam.org/o/man/audacity_waveform.html

non ho letto l'intera pagina. Ma ogni barra verticale rappresenta una finestra di campioni di forma d'onda. Il blu scuro sono i valori massimo positivo e minimo negativo in quella finestra (credo). E l'azzurro è il RMS che è la radice quadrata media. http://www.mathwords.com/r/root_mean_square.htm. (in pratica si quadrano i valori all'interno di ciascuna finestra, si prende una radice media e quindi quadrata.

Spero che questo aiuti.

1

showwavespic

ffmpeg può disegnare una forma d'onda con il filtro showwavespic.

enter image description here

ffmpeg -i input -filter_complex "showwavespic=split_channels=1" output.png 

Vedi showwavespic filter documentation per le opzioni.

showwaves

Si può anche fare un video della forma d'onda in diretta con il filtro showwaves.

ffmpeg -i input -filter_complex \ 
"showwaves=s=600x240:mode=line:split_channels=1,format=yuv420p[v]" \ 
-map "[v]" -map 0:a -movflags +faststart output.mp4 

Vedere showwaves filter documentation per le opzioni.

1

La seconda forma d'onda è probabilmente un'approssimazione di colonna di un semplice grafico a zig zag.

Ogni colonna è una linea dall'ampiezza del campione precedente all'ampiezza del campione corrente.

Quindi leggi tutti i campioni in una tela o texture come un pre-test come punti, quindi, una volta che hai fatto puoi fare due casi, creare barre invece di punti, disegnare verso l'alto fino all'ultimo campione o verso l'alto per questo campione a seconda di quale era più alto, purché si disegna una linea tra due. Ciò assicura che la forma d'onda sia piccola con energie basse tra i campioni successivi e alta con energie elevate.

È possibile creare alias e misurare più campioni, dipende solo dall'hardware su cui si sta eseguendo, se si desidera leggere 1000ds di campioni e creare una rappresentazione a 2d di array gigante dell'onda e quindi renderla in un formato più piccolo visualizzabile immagine o se vuoi solo eseguire solo 512 campioni e aggiornarli velocemente. con la tela 2D nei programmi dovrebbe essere veloce per creare forme d'onda dettagliate con più di 512 campioni.

... un'opzione diversa è uguale alla forma d'onda grigia nell'altra risposta, traccia il valore assoluto come linee da + campione corrente a campione corrente.

aiuta a fare la media di più campioni, ad esempio 4 campioni o ottenere un massimo di 4 campioni per avere un grafico meno irregolare, è un ragazzino di alias veloce.

+0

Ho fatto un codice basato sull'utilizzo di un grafico a barre per approssimare un grafico a zig zag, ho trovato che le funzioni di disegno su tela sono un po 'lente per la memoria, ho scoperto che se dividete 44100 per 8 o 16, utilizzate max di ogni 16 campioni , sembra ancora molto chiaro, SR è quindi 2900 al secondo, va bene e salva la memoria ... ho scoperto che la scheda grafica era molto più veloce per visualizzare i vertici rispetto al tentativo di farlo in un textre, così ho fatto un grapy di flat poligoni come linee, nel codice della tela 2d è molto più veloce in ogni caso probabilmente vi mancherà molto rispetto all'invio di ombre grafiche per rendere polis. il codice dx11 è onunityforum – predatflaps