Pregunta

Tengo para reducir la profundidad de bits de una señal de audio digital de 24 a 16 bits.

Tomando sólo los 16 bits más significativos (es decir truncar) de cada muestra es equivalente a hacer un cálculo proporcional (OUT = en * 0xFFFF / 0xFFFFFF)?

¿Fue útil?

Solución

Usted asume media (in * 0xFFFF) / 0xFFFFFF, en cuyo caso, sí.

Otros consejos

se obtienen mejores resultados mediante la adición de sonar una señal de ruido cuidadosamente a la señal original, justo por debajo del umbral de truncar, antes de truncar (también denominado tramado).

tramado voluntad mediante la adición de ruido en general, que dan mejores resultados. La clave para esto es la forma del ruido. El popula pow-r algoritmos de tramado tienen una forma específica que es muy popular en muchas aplicaciones de estación de trabajo de audio digital (SONAR de Cakewalk, lógica, etc.).

Si no es necesario el pleno sobre la fidelidad de POW-r, simplemente puede generar algo de ruido por lo bastante baja amplitud y mezclarlo con su señal. Encontrará esto enmascara algunos de los efectos de cuantificación.

x * 0xffff / 0xffffff es excesivamente de pedante, pero no de una manera buena si se firman sus muestras -. Y probablemente no de una manera bien en general

Sí, desea que el valor máximo en el rango de origen para que coincida con el valor máximo en el rango de destino, pero los valores utilizados no son sólo para los rangos sin firmar, y la distribución de los medios operaciones de cuantificación que va a ser muy raro que se utiliza el valor de salida más grande posible.

Si las muestras se firman a continuación el pico valores positivos serían 0x7FFF y 0x7fffff, mientras que los valores negativos máximos serían -0x8000 y -0x800000. Su primer problema es decidir si es igual a +1 0x7FFF, o -1 es igual a -0x8000. Si elige esta última, entonces es una operación simple cambio. Si se trata de tener tanto entonces deja de ser cero cero.

Después de que usted tiene un problema que las rondas de división hacia cero. Esto significa que demasiados valores se redondean a cero en comparación con otros valores. Esto provoca una distorsión.

Si desea cambiar la escala de acuerdo a los valores máximos positivos, la forma correcta sería:

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

Si usted pesca en torno a un poco probable que pueda encontrar una manera eficaz de hacer eso con aritmética de enteros y sin división.

Esta forma debe correctamente redonda al valor de salida disponible más cercano para cualquier entrada dada, y se debe asignar el mayor valor de entrada posible el mayor valor de salida posible, pero va a tener una distribución fea de operaciones de cuantificación repartidos por toda la gama .

La mayoría de la gente prefiere:

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

Esta forma hace que las cosas el más fuerte más pequeños poco, hasta el punto de que los valores positivos pueden cortar ligeramente, pero los pasos de cuantificación se distribuyen de manera uniforme.

añadir 128 rondas debido a desplazamiento a la derecha hacia el infinito negativo. El medio es error de cuantificación -128 y se añaden 128 para corregir esto para mantener 0 a 0. La prueba precisamente para el desbordamiento es necesario porque un valor de entrada de 0x7fffff de otro modo dar un resultado de 0x8000, y cuando almacenar esto en una palabra de 16 bits sería envolver alrededor dando un valor pico negativo.

C pedantes puede hacer agujeros en las suposiciones acerca de desplazamiento a la derecha y el comportamiento de la división, pero estoy con vistas a las de la claridad.

Sin embargo, como otros han señalado que en general no deben reducir la profundidad de bits de audio sin tramado, y lo ideal sería la forma de ruido. dither TPDF es como sigue:

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

Una vez más, grandes problemas con el uso de rand() la que voy a pasar por alto para mayor claridad.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top