~
Globo 4
Común
Digicam
Audiogen
SSTV
weeCam
Pruebas
Enlaces
Brújula
Sensors
Navegación
La generación de audio se hace en tres pasos:
Ya que no disponemos de cálculos de punto flotante en nuestro controlador, tenemos que buscar una forma de hacer el cálculo con 8 bits. No hay instrucciones de multiplicaciones, entonces por el reducido tiempo disponible, todos los cáculos se debe limitar a sumas/restas!
En lo que sigue, suponemos (con bastante buen criterio) que la frecuencia de actualización de la señal de salida será 10 kHz, y que la tabla de la senusoide tendrá 32 entradas ('lookup-table').
|
Frecuencia | Período | NroMuest | PasoTabla |
Fsinc | 1200 | 0.0008333 | 8.3333 | 3.84 |
Fnegro | 1500 | 0.0006667 | 6.6667 | 4.8 |
Fgris | 1900 | 0.0005263 | 5.3632 | 6.08 |
Fblanco | 2300 | 0.0004348 | 4.3478 | 7.36 |
En la tabla vemos para diferentes frecuencias a generar, cual es el período correspondiente, y luego cuantos 'intervalos' de 10kHz eso significa.
Ya que la tabla tiene 32 valores, podemos calcular cual es el 'incremento de fase' necesario, expresado en 'pasos en la tabla'. Claro que no podemos incremente un puntero 3.84 lugares, tendremos que incrementarlo 3 o 4. Eso introduce momentáneamente un error de fase, que lo podemos corregir en siguientes pasos, si nos acordamos de la parte decimal. Como implementar esto en una forma compacta?
El incremento mínimo parece de 3.84, el máximo de 5.44. Si lo consideramos, el valor máximo es menos de 8, asi que lo podemos codificar con 3 bits. Si usamos los 3 más significativos de un byte, y los 5 restantes para la parte 'decimal', logramos ya una precisión aceptable:
|
Frecuencia | Período | PasoTabla | dFase | FreqLograda |
Fsinc | 1200 | 0.0008333 | 3.84 | 123 | 1201.17 |
Fnegro | 1500 | 0.0006667 | 4.8 | 154 | 1503.91 |
Fgris | 1900 | 0.0005263 | 6.08 | 195 | 1904.30 |
Fblanco | 2300 | 0.0004348 | 7.36 | 236 | 2304.69 |
El error en todos los casos es menos de 0.3%! No está mal para un algoritmo tan sencillo. Sin embargo, variando un poco los parámetros podemos ganar aún mejor calidad, con muy poco costo en términos de programación. Considermos que siempre hay que sumar 3 (de 3.84), entonces podemos codificar la suma del '3' fijo en las rutinas, y restar 3 de la columna 'PasoTabla'. El valor máximo ahora es 7.36 - 3 = 4.36. Todavía necesitamos 3 bits para codificar el 4, así que no ganamos nada.
Pero si modificamos un poco la frecuencia de muestreo (aumentar), entonces podemos bajar el valor, sin que 3.84 baje de 3. Con 11905 Hz de muestreo (1 MHz/84):
|
Frecuencia | Período | PasoTabla | -3 | dFase | FreqLograda |
Fsinc | 1200 | 0.0008333 | 3.226 | 0.226 | 14 | 1197.48 |
Fnegro | 1500 | 0.0006667 | 4.032 | 1.032 | 66 | 1499.75 |
Fgris | 1900 | 0.0005263 | 5.107 | 2.107 | 135 | 1900.85 |
Fblanco | 2300 | 0.0004348 | 6.182 | 3.182 | 204 | 2301.94 |
Ahora necesitamos solo 2 bits para el incremento, y nos quedan 6 bits para la parte decimal. El error máximo bajó a 0.2%, pero quizás aún más importante, tenemos un rango de 66 a 204 para variar los tonos de la imagen, o sea, 138 niveles de grises que se pueden representar. En el caso anterior, habia solo 82 niveles de grises.
Lo único que tenemos que hacer, es reprogramar el timer del PIC para generar los 11905 Hz, y no olvidarse de sumar 3 a cada incremento del offset en la tabla.
El algoritmo de generación del audio será entonces:
Y abajo un gráfico de la señal generada, considerando que la tabla tiene simplemente un senos codificado con 3 bits (bloques color violeta). Al lado (azúl), está el valor correcto (calculado con el senos exacto). Se puede notar que el resultado es bastante bueno! Con las funciones de Walsh tendría que mejorar algo mas todavía.
Aqui un ejemplo de la generación de 1900 Hz:
Paso Accu Carry AccuR Ptr 0 0 0 0 0 1 135 0 135 5 2 270 1 14 9 3 405 0 149 14 4 540 1 28 18 5 675 0 163 23 6 810 1 42 27 7 945 0 177 0 8 1080 1 56 4 9 1215 0 191 9 10 1350 1 70 14 11 1485 0 205 20 12 1620 1 84 25 13 1755 0 219 31 14 1890 1 98 4 15 2025 0 233 10 16 2160 1 112 15 17 2295 0 247 21 18 2430 1 126 26 19 2565 1 5 30 20 2700 0 140 3
Vínculo | Idioma | Descripción | Fuente |
Walsh functions: A digital Fourier series | Inglés | Funciones de Walsh: Muy buen artículo | John |
Applications of Walsh Functions in Communications | Inglés | Aplicaciones de funciones de Walsh en comunicaciones | John |
(c) John Coppens ON6JC/LW3HAZ | correo |