Hay una secuencia de muestras
x0,x1,x2, puntos.$ Además, como ya se mencionó, hay dos parámetros iniciales
y0 y
s0 . Necesita obtener una nueva secuencia de muestra
y0,y1,y2 puntos. . Como ya puede adivinar, la primera muestra de salida ya se conoce: coincide con uno de los parámetros iniciales
y0 . Esto es algo más que un "desplazamiento inicial". Vale la pena señalar que las muestras de entrada (fuente) están codificadas en cuatro bits. Para los tipos con signo, los enteros de -8 a 7, inclusive, se incluyen en la codificación. El bit más significativo, de hecho, es responsable del signo del número. Las muestras PCM de salida, que se obtienen después de la decodificación, tienen un formato estándar de 16 bits con signo.
Analizando el código del algoritmo en C, puede ver dos tablas. Se enumeran a continuación.
int ima_index_table[] = { -1, -1, -1, -1, 2, 4, 6, 8 };
int ima_step_table[] = { 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 130, 143, 157, 173, 190, 209, 230, 253, 279, 307, 337, 371, 408, 449, 494, 544, 598, 658, 724, 796, 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358, 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 };
Se puede decir que estos dos conjuntos "mágicos" son funciones tabulares, en cuyos argumentos se sustituyen los mismos dos parámetros iniciales. Durante la iteración, con cada paso, los parámetros se recalculan y sustituyen en estas tablas nuevamente. Primero, veamos cómo se implementa esto en el código.
Declaramos lo necesario, incluidas las variables auxiliares.
int current1; int step; int stepindex1; int diff; int current; int stepindex; int value;
Antes de comenzar la iteración, debe asignar el parámetro inicial a la variable actual
y0 , y la variable stepindex es
s0 . Esto se hace fuera del algoritmo en cuestión, por lo que no lo reflejo con el código. Las siguientes son las transformaciones que se realizan en un círculo (en un bucle).
value = read(input_sample);
En el paso de la variable auxiliar de la matriz ima_step_table, se escribe el valor en el índice stepindex1. Para la primera iteración, este es el parámetro inicial
s0 , para futuras iteraciones, este es un parámetro recalculado
si . Luego, el valor de esta matriz se divide por 8 (aparentemente, completamente) por la operación del desplazamiento de bits a la derecha, y la variable diff se inicializa como resultado de esta división. Luego, se analizan los tres bits menos significativos del valor de la muestra de entrada y, según sus estados, la variable diff se puede ajustar en tres términos. Los términos son una división entera similar del valor diff por 4 (>> 2), 2 (>> 1) o diff sin cambios (dejemos que sea una división por 1 para generalización). Luego, se analiza el bit más significativo (con signo) del valor de la muestra de entrada. Dependiendo de su estado, la variable diff que se generó antes de esto se agrega o resta a la variable current1. Este será el valor de la muestra de salida. Para la corrección, los valores están limitados a la parte superior e inferior. Luego, stepindex1 se ajusta agregando el valor de la matriz ima_index_table por el índice del valor de la muestra de entrada con el bit de signo restablecido a cero. Los valores de Stepindex1 también están sujetos a un límite. Al final, antes de repetir este algoritmo, a los valores actuales y stepindex se les asignan los valores recuentos de current1 y stepindex1, y el algoritmo se repite nuevamente.
Puede intentar resolverlo para comprender aproximadamente cómo se forma la variable diff. Dejar
fi=f(si) . Estos son los valores de la variable de paso en cada i-ésimo paso de la iteración, como los valores de la función (matriz) del argumento
si donde
i=0,1,2, puntos . Por conveniencia, denotamos la variable diff como
d . Siguiendo la lógica del razonamiento descrito anteriormente, tenemos:
di= fracfi8+x(0)i fracfi4+x(1)i fracfi2+x(2)ifi,
donde
x(0)i,x(1)i,x(2)i - bajo 3 bits de un número
xi . Llevando a un denominador común, transformamos esta expresión a una forma más conveniente:
di= fracfi8 Bigg(1+2x(0)i+4x(1)i+8x(2)i Bigg)=
= fracfi8 Bigg(1+2 Big(x(0)i+2x(1)i+4x(2)i Big) Bigg)= fracfi8(2xi+1).
La última conversión se basa en el hecho de que, en cierto sentido, los menos tres bits (0 o 1) de un número
xi con los coeficientes presentados hay algo más que escribir el valor absoluto de este número, y el bit más significativo del número
xi coincidirá con el signo de toda la expresión. Además de acuerdo con la fórmula
yi+1=yi+di
Se calcula un nuevo valor de muestra basado en el anterior. Además, se calcula un nuevo valor variable.
s :
si+1=si+t(|xi|).
El módulo en la fórmula indica que la variable
xi entra en funcionamiento
t excluyendo el bit de signo más significativo, que se refleja en el código. Una función
t Es el valor de la matriz ima_index_table con el índice correspondiente al argumento.
En la descripción de las fórmulas, descuidé las operaciones de restricción arriba y abajo. El esquema iterativo total se parece a esto:
y0; s0; x0,x1,x2, dots
di= fracf(si)8 big(2xi+1 big)
yi+1=yi+di
si+1=si+t(|xi|)
i=0,1,2, puntos.
Muy profundamente en la teoría de codificación / decodificación de ADPCM en la que no profundicé. Sin embargo, los valores de la tabla de la matriz ima_step_table (de 89 piezas), a juzgar por su reflejo en el gráfico (ver la figura a continuación), describen la distribución probabilística de las muestras en relación con la línea cero. En la práctica, este suele ser el caso: cuanto más cerca está la muestra de la línea cero, más ocurre. Por lo tanto, ADPCM se basa en un modelo probabilístico y de ninguna manera cualquier conjunto fuente de muestras PCM de 16 bits se puede convertir correctamente en muestras ADPCM de 4 bits. En términos generales, ADPCM es PCM con un paso de cuantificación variable. Simplemente, aparentemente, este gráfico refleja este paso muy variable. Es elegido correctamente, en base a la ley de distribución de datos de audio en la práctica.
