Domanda

Devo ridurre la profondità di bit di un segnale audio digitale 24-16 bit.

Prendendo solo i 16 bit più significativi (cioè troncamento) di ciascun campione è equivalente a eseguire un calcolo proporzionale (out = a * 0xFFFF / 0xFFFFFF)?

È stato utile?

Soluzione

ti assumo (in * 0xFFFF) / 0xFFFFFF media, in questo caso, sì.

Altri suggerimenti

Si andrà meglio dal suono risultati con l'aggiunta di un segnale di rumore cura artigianale al segnale originale, appena al di sotto della soglia di troncamento, prima di troncare (anche noto come il dithering).

dithering con l'aggiunta di volontà il rumore in generale, si dà risultati migliori. La chiave di questo è la forma del rumore. Il popula POW-r algoritmi di dithering hanno una forma specifica che è molto popolare in molte applicazioni workstation audio digitali (di Cakewalk Sonar, Logic, ecc).

Se non è necessario il pieno sulla fedeltà di pow-r, si può semplicemente generare qualche rumore a relativamente bassa ampiezza e mescolare nel vostro segnale. Troverete questo maschere alcuni degli effetti di quantizzazione.

x * 0xffff / 0xffffff è eccessivamente di pedante, ma non in senso buono, se sono firmate i vostri campioni -. E probabilmente non in senso buono in generale

Sì, si desidera che il valore massimo nel vostro intervallo di origine in modo che corrisponda al valore massimo nella vostra gamma di destinazione, ma i valori utilizzati ci sono solo per gli intervalli senza segno, e la distribuzione di passi di quantizzazione mezzi che sarà molto raro che si utilizza il più grande valore di uscita possibile.

Se i campioni sono firmati quindi il picco di valori positivi sarebbero 0x7FFF e 0x7fffff, mentre i valori negativi di picco sarebbe -0x8000 e -0x800000. Il tuo primo problema è decidere se +1 è uguale a 0x7FFF, o -1 è pari a -0x8000. Se si sceglie quest'ultima, allora si tratta di una semplice operazione di spostamento. Se si tenta di avere sia quindi pari a zero smette di essere pari a zero.

Dopo che hai un problema che arrotonda divisione verso lo zero. Ciò significa che troppi valori ottengono arrotondato a zero rispetto ad altri valori. Questo fa sì che la distorsione.

Se si vuole scalare in base ai valori positivi di picco, la forma corretta sarebbe:

out = rint((float)in * 0x7fff / 0x7fffff);

Se si pesca in giro un po 'si può probabilmente trovare un modo efficace per farlo con aritmetica intera e non di divisione.

Questo modulo deve correttamente intorno al valore di uscita disponibile più vicino per qualsiasi ingresso, e dovrebbe mappare il più grande valore di ingresso possibile il più grande valore di uscita possibile, ma sta andando ad avere una brutta distribuzione delle fasi di quantizzazione sparsi in tutta la gamma .

La maggior parte delle persone preferisce:

out = (in + 128) >> 8;
if (out > 0x7fff) out = 0x7fff;

Questa forma rende le cose il più piccolo po 'più forte, al punto che i valori positivi possono ritagliare un po', ma i passi di quantizzazione sono distribuiti in modo uniforme.

È aggiungere 128 perché giri destro spostamento verso l'infinito negativo. Il medio Errore di quantizzazione è -128 e si aggiungono 128 per correggere questo per mantenere 0 esattamente 0. Il test per il troppo pieno è necessario perché un valore di ingresso di 0x7fffff altrimenti dare un risultato di 0x8000, e quando di memorizzare questo in una parola a 16 bit sarebbe avvolgere intorno dando un valore di picco negativo.

C pedanti possono fare buchi delle ipotesi circa destra-shift e il comportamento di divisione, ma sto affaccia quelli per chiarezza.

Tuttavia, come altri hanno fatto notare in genere non dovrebbe ridurre la profondità di bit di audio senza dithering, e idealmente noise shaping. TPDF dithering è la seguente:

out = (in + (rand() & 255) - (rand() & 255)) >> 8;
if (out < -0x8000) out = -0x8000;
if (out > 0x7fff) out = 0x7fff;

Anche in questo caso, grandi problemi con l'utilizzo di rand() che ho intenzione di trascurare per chiarezza.

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