Universidad ORT Uruguay

Facultad de Ingenier´ ıa Carrera de Ingenier´ en Electr´nica ıa o

Instrumento virtual

´ Entregado como requisito para la obtencion del ´ t´ ıtulo de Ingeniero en Electronica

Eliel Hojman - 147325 Isaac Ungerovich - 136216 Tutor: Ing. Gustavo Bellora

2010

Agradecimientos

Agradecemos enormemente a todas aquellas personas que hicieron posible que lleg´ramos a a este momento. Agradecemos a los que aportaron a la causa y a los que brindaron su apoyo emocional para poder sobrellevar esta dif´ tarea a lo largo de un a˜o. Agradeceıcil n mos a la gente de la Universidad ORT: personal, docentes, tutor y a los compa˜eros de n la sala de proyectos. A nuestros amigos, y especialmente a nuestras familias. Sin ellos, hubiera resultado un camino mucho m´s dif´ de recorrer. A todos ellos, gracias. a ıcil

2

Abstract En la d´cada del 20, con la creaci´n de los primeros sintetizadores comenz´ la e o o creaci´n de m´sica mediante se˜ales el´ctricas remplazando los cl´sicos instrumeno u n e a tos. En un principio los sintetizadores no fueron muy populares hasta que en 1970 gracias a los nuevos estilos musicales y al comienzo de la era digital en la m´sica su u popularidad comenz´ a crecer a grandes pasos. o En 1982 se crea el formato MIDI, el cual es un est´ndar de comunicaci´n entre a o sintetizadores e instrumentos, este fue un gran avance que permiti´ incrementar la o popularidad de los sintetizadores. La gran capacidad de procesamiento de los procesadores y microcontroladores de la d´cada del 90 y de esta d´cada signific´ una nueva frontera en el mundo de e e o la m´sica. Actualmente se puede generar pr´cticamente cualquier sonido m´sical u a u en tiempo real con procesadores extremadamente baratos cuya potencia en d´cadas e anteriores no se encontraban ni en la imaginaci´n del m´s optimista de los ingenieros. o a La capacidad de los actuales procesadores da lugar a un sin fin de nuevos proyectos e ideas que se hacen viables a un bajo costo. Este proyecto es una de esas, es un sintetizador que intenta ser un dispositivo que equilibre la gran potencia de los procesadores de ultima tecnolog´ con un bajo costo y un uso sencillo pero robusto ´ ıa y util. ´ Se busca crear un dispositivo con una entrada para que se le conecte un instrumento musical y que el dispositivo pueda reproducir las notas musicales que el usuario toca en el, haci´ndolas sonar como las notas de otro instrumento previae mente configurado. Este documento brinda un an´lisis detallado del estudio realizado, las pruebas a efectuadas, los detalles de la construcci´n del dispositivo y finalmente una conclusi´n o o del proyecto realizado.

3

´ Indice
1 Introducci´n o 1.1 14

Conceptos b´sicos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 a 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 MIDI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 Instrumento MIDI . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 Instrumentos VSTi . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 Efectos VST . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 VST Host . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 Conexi´n de un dispositivo MIDI a un PC . . . . . . . . . . . . . . 15 o Reproducci´n de un instrumento MIDI conectado al PC . . . . . . 16 o Reproducci´n de un instrumento MIDI con el programa VSTHost o V 1.45 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 Sintetizador MIDI . . . . . . . . . . . . . . . . . . . . . . . . . . . 17

1.2 1.3

Objetivo del proyecto . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 Sistemas similares existentes . . . . . . . . . . . . . . . . . . . . . . . . . . 19 1.3.1 1.3.2 Sistemas embebidos similares . . . . . . . . . . . . . . . . . . . . . 19 Generar las funciones de este proyecto con un PC . . . . . . . . . . 20 21

2 Conceptos avanzados 2.1

Instrucciones MIDI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 2.1.1 2.1.2 2.1.3 Canales MIDI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 Modos MIDI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

Instrumentos MIDI . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

2.2

Funcionamiento de los instrumentos VSTi y de los efectos VST . . . . . . . 25 2.2.1 2.2.2 Opciones de proceso . . . . . . . . . . . . . . . . . . . . . . . . . . 25 Implementaci´n de plugins VST y VSTi . . . . . . . . . . . . . . . 25 o

2.3

Archivos DLL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 2.3.1 2.3.2 Ventajas del uso de librer´ DLL . . . . . . . . . . . . . . . . . . . 26 ıas Desventajas del uso de librer´ compartidas DLL . . . . . . . . . . 26 ıas

4

2.3.3 2.3.4 2.3.5

Estructura de una DLL de 32 bits . . . . . . . . . . . . . . . . . . . 27 Llamada Est´tica a un Archivo DLL . . . . . . . . . . . . . . . . . 27 a Llamada din´mica a un archivo DLL . . . . . . . . . . . . . . . . . 28 a 29

3 Posibles sistemas de implementaci´n o 3.1 3.2

Introducci´n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 o Utilizar un sistema embebido sin sistema operativo . . . . . . . . . . . . . 29 3.2.1 3.2.2 3.2.3 Interpretaci´n de los comandos MIDI . . . . . . . . . . . . . . . . . 29 o Interpretaci´n de Instrumentos VSTi . . . . . . . . . . . . . . . . . 30 o Sistemas existentes que interpretan archivos DLL fuera de Windows 30

3.3

Utilizar un Sistema Embebido con Sistema Operativo . . . . . . . . . . . . 31 3.3.1 3.3.2 3.3.3 3.3.4 Sistema Operativo Linux . . . . . . . . . . . . . . . . . . . . . . . . 32 Sistema Operativo Windows . . . . . . . . . . . . . . . . . . . . . . 32 Utilizar sistemas operativos en tiempo real . . . . . . . . . . . . . . 32 Utilizar otros sistemas operativos . . . . . . . . . . . . . . . . . . . 33 34

4 An´lisis de las posibles formas de implementaci´n a o 4.1 4.2 4.3 4.4

Utilizar un sistema embebido sin sistema operativo . . . . . . . . . . . . . 34 Utilizar un sistema embebido que tenga el sistema operativo Windows . . . 34 Utilizar un sistema embebido que tenga el sistema operativo Linux . . . . . 34 Conclusiones . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 35 37 38

5 Replanteo del proyecto y de su implementaci´n o 6 Creaci´n de la nota musical o 6.1 6.2 6.3 6.4 6.5

Introducci´n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 o Componentes de una nota musical . . . . . . . . . . . . . . . . . . . . . . . 38 Sinusoidales puras . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 Envolvente Global . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 Envolvente particular a cada frecuencia . . . . . . . . . . . . . . . . . . . . 44 6.5.1 Introducci´n . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 44 o 5

. . . . . . . . . .1 Generaci´n de sonidos . 57 o 9. . . . . . . . . . . . . . . . . . 52 o An´lisis de la prueba . .2. 45 o e Utilizaci´n de Samples . . . . . . . . . . . . . . . 57 o Selecci´n del fabricante del DSP . . 59 o Experiencia previa . . . . . . . .5. . . . . . . . . . .3 9.6 6. . . . .2. . . . . . . . . . . . . . . . . . . . . . . . .5.2 9. . .7 Explicaci´n del m´todo para obtener la nota . . . . . 50 Construcci´n del c´digo para la prueba . . . . . . . . . . . . .5. . . . . . . . . . . . .1 8.2. . . . . . . . . . . . . . . . . . . . . . . 55 o Funcionamiento de la prueba . . . . . . . . . . . . . 55 Conclusiones de la prueba . . 53 e Multiplicaciones y divisiones . 51 8. . . . . . . . . . . . . . . .5 Conversor digital a anal´gico . . . . . . . . . . . . 58 Presentaci´n . . . . .4 8. . . . . .1 8. . . 60 9. . . . . . .2. . . . . . . . . . 60 o 62 10 Arquitectura externa del sintetizador 6 .1 9. . . . . . 52 o 8. . . . .4 8. . . . . .5. . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 6. . . . . . . . . . . . . . 51 o o Origen de los datos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2. .5. .2 8. . .5 Productos adicionales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .1 9. . . . . . . . . . . . . . . . .2 Selecci´n de la arquitectura del sistema embebido . . . . . . . . . 55 57 9 Selecci´n del sistema embebido o 9. . . . . 58 Soporte en l´ ınea . .6. . . . . . . . . . . . . . . . . . .2 8. . . . . . . . . . . . . . . . . 57 Soporte y repuestos en Uruguay . . . . .4 9. .3 8. . . . . . . . . . 54 Observaci´n . . . . . . . . . . . . . . . . . . . . . 53 a 8. 46 o Limitaciones . . . . . . . . . . . . . . . .3 Selecci´n del modelo de DSPic . . . . . . . . . . . . . . . . . . . . . 47 49 50 7 Detecci´n de comandos MIDI o 8 Prueba previa 8. . . . . . . .5. . . .3. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 Objetivo de la prueba . . . . . . .5 Operaciones trigonom´tricas . . . .

. . . . . . . . . .2.2 Utilizaci´n de los efectos digitales . . . .2. . . . . . . . . . . . . . . . . . . . . . . . 66 12. . . . . . . .4 La necesidad de tantos microcontroladores . . . .1 I 2 C . . . . . . . . . . . . 67 12. . . . . . . . . . . . 65 o 12 Arquitectura del Sistema 66 12. . . . . . . . . . . . . . 69 o 12. . . . .6 Efecto limitador ’log’ . . . . . . . . . . . . . . . 70 o 12. . . . . 65 11. . . . . . . .3. . . 63 o 11. . . . . . . . . . . . . .3. . . . . . . . . . . . . . 66 12. . . . . . . . . . .2 Entradas . . . . . . . . . . . . . . . . . . . . .2. . . . . . . . . . . . .2. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 Generaci´n de efectos . . .2 RS-232 . . . . . . . . . . . . . .3. . . . . . . . . . . . . . . . . . . . . . . . . . .2. . 64 11. . . . . . . . . . . . . . . .3. . . . . . . . . . . .2 Efecto eco . . 73 12. . . . 66 12. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 Efecto tr´molo . . . . . . . . . .3 Arquitectura Interna . . . . . 64 11. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2.3. . 74 n 13 Entorno de programaci´n de los DSPic o 76 7 . . . . . . . . . . . . . . . . . . .7 Efecto vibrato . . . . 68 12. . . . . . .1 MIDI . . . . . . . . . . . . . . . . . . . . .3. . . 63 o 11.8 Dise˜o del PCB y de los circuitos de los DSPic . . . . . .6 Saturador Anal´gico . . . . . . . . . . .5 Circuito del sumador anal´gico . . . . . . . . . . 66 a 12. . .2. .2. .1 No aplicar el efecto . .3 Efectos . . . . . . . . . . . . . . . . . . . . . . . 65 11. . . . . . . .7 Circuitos de la caja de efectos . . . . . . . . . . . . .2. . . . . . . . . . . . . . 64 11. . 66 12.3. . . . . . . . . .5 Efecto limitador ’if’ . . . . . . . . . .2 Generaci´n del Sonido . .2. . . . . . . 64 e 11.3. . . . . . . . . . . . . . . .4 Efecto Wah-Wah . . . .4 Cambio y creaci´n de instrumentos . . . . . . . . .1 Reproducci´n de instrumentos . 72 o 12. . . . . . . . . . . . . . . . . . . . 65 11. . . . . . . . . . .11 Instrucciones de uso del sintetizador 63 11. . . . . . . . . . . . . . 69 o 12. . 69 12. . . . . . . .3 Utilizaci´n del efecto anal´gico o o . . . . . . . . . . . . . 64 11. . . . . . . . . . . .1 An´lisis de la arquitectura externa . . . . . . . . . .

. . . . . . . . . . . . . . . .8 Explicaci´n del efecto vibrato . . . .1. . . . . . 84 e 15. . . . . . . . . 80 o 15. 78 14. .2 Interrupci´n MIDI . . . . . . . . . . . . . . . . . . 86 15. 79 o 15 Explicaci´n del c´digo de los esclavos o o 80 15.7 Funcionamiento del efecto limitador logar´ ıtmico . . . .2 Generaci´n de sonidos de notas . . . . . . . . . . . 78 14. . . . . . . . . . . . . . . . . . .1 Cambios en las perillas . . . . . . . 80 15. . .5. . . .6 Explicaci´n de las funciones actualizarParametrosEfectos y aplicarEfectos . . . . . .4 Funcionamiento del m´todo calcularSample() . . .3 Funcionamiento del efecto Eco . . . . . . . . . . . . . . . . . . . .4. .2. . .1. . . . . . . . . . . . . . . . 79 o 14. . . . . . . . . . . . . . . . . . . . . .4 Funcionamiento del Main . 90 15. . 91 o 15. .3 Interrupci´n PC . . . . 78 o 14. . .4. . . . .2 Explicaci´n detallada de las variables . . .1 Funcionamiento de la comunicaci´n I 2 C . . . . . . . . . . 82 o 15. . . . . .3 Funci´n quitarNota() . . .4 Funci´n cargarNuevoPrograma() . 90 15. . . . . . . . . . . . . . . . . . . . . . . . .2 Funcionamiento detallado . . .1 Funcionamiento general . . . . . . . 84 e 15.1 Funcionamiento del I 2 C . . . . .5. . . .14 Explicaci´n del c´digo del Maestro o o 77 14. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 77 14. .4 Funcionamiento del efecto tr´molo . . . . . . . . . . 80 15. . . . . . . 86 15. . . . . . . . . . . . . 83 o 15. . . . . . . . . . . . . 88 e 15. . . . . . . . . . . . . . . . . . . . . . . . . . 89 15. . 77 o 14. . . . .5. . . . . . . . . . . . .2 Explicaci´n del m´todo inicarEf ectos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2. . . . . . . . . . . .5. . . .5 Funcionamiento de los efectos . . . . . . . . . .5 Funcionamiento del efecto wah-wah . . . .5. 87 15. . . . . . . . . . . . . . . . . .1 Funcionamiento general de los efectos . . . .6 Funcionamiento del efecto limitador if . . . . . . . . . .3 Funcionamiento del m´todo agregarN ota() . . 77 o 14. . . . . . . . . . . . .5. . 82 o 15. .5. . .2 Funci´n agregarNota() . 87 o e 15. . . . . . . . . . . . . . . . .4. . . .5. . . . . . . . . . . . . .1 Explicaci´n general del funcionamiento . . . . . . . . . . . . . . . . .4. . 91 o 8 . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . .5. . . . . . . . . . . . . . . . . .1 Crear una nueva envolvente de forma simple . 101 17. . . . . . . . . . . . . . . . . . . . 99 17. . . . . 105 18 Explicaci´n de los c´digos de Scilab o o 108 18. . . . . . . . . . . . . . . . . . . . . . . . . . . . . .3 Edici´n com´n a todas las envolventes . . .15. . .8 Formato de los archivos para enviarle al sintetizador . . . . . . . . . . .5 Uso de la ventana “Manejo de envolventes” .3 Aspectos t´cnicos del programa . . . . . 96 17. . . . . . . . . . . . . . . . . . . . . . .2 Editar cada envolvente . . . .4 Abrir instrumentos . . . . . . . .4 Guardar envolventes . . 95 17. . . . .1 Introducci´n a los programas de Scilab . . . . . . . . . 93 16. . . 104 17. . . . . .1 Introducci´n al manejo del programa interfaz . . . . . . .5. .2 Ingreso al modo Manejo de Envolventes . . . . . . . . . . . . . . . . . . . . . . . .6 Manejo del modo transmisi´n de instrumentos . . . . . . . . . . . . . . . . .1 Barra superior . . . . 97 o 17. . . . . . . . . . . . . . . . . . . . . . . . . . . . 95 17. . . 99 17. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102 17. . .2 Caracter´ ısticas extras . . . . . . . . 101 17. . . . . . . . . . . . . .7 Funcionamiento del m´todo main . . . . . . 98 ´ o 17. . . . . . . . 97 17.5. . . . . . .7. .3 Crear un instrumento nuevo . . . . . . . . . . 93 17 Manual de instrucciones del programa interfaz de comunicaci´n o 95 17. 93 o 16. . .3. . . . . . . . . . . .5. . . . . 92 e 16 Documentaci´n del programa interfaz o 93 16. . . . . . . . . . . . . . . . . . 103 o u 17. . . . .5.7. . . . . 96 17. 93 e 16. . . . . .2 Crear envolventes mediante extrapolaci´n de otras envolventes . . . . . . .7. .2 Estructura del programa . .5 Abrir envolventes . . . . . . . . . . . . .3. . . . . .3 Herramientas utiles para la creaci´n de envolventes . . . . . . . . . . . . 100 o 17. . . . . . . . . . . .1 Lenguaje utilizado . . . . . .7. .1 Comenzando con el programa .7 Ventana Manejo del instrumento . .4 Probar las notas generadas . . . . . . . . . . . . . . . 108 o 9 . . . . . 95 17. . . . . . . . . . . . . . . . . . . . . . 93 16. . . . . . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122 10 . . . . . . . . . . . . . 112 18. . . . . .6 Utilizar interfaz USB . . . . . . . . .8 M´ltiples instrumentos conectados a un solo sintetizador . . .1 Posibles mejoras en el sintetizador . . . 119 21. . . . . . . . .8 Programa “haceGraficas” . . . . .1. 121 o o 21. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .6 Programa “copiaNota” . . . . . . . . .1. . . . . . . . . . . . . . . .4 Programa “fourierFacilDetectaPicos” . . . . . . . 118 21. . 118 o ´ 21. . .1. . . 110 18. . . . . . 109 18. . . . . . 113 18. . . . . . . . . . . . . . . . . . . . . . . . . . . .2 Aumento de los controles internos .1. . . . . 121 u 21. . . . .midi . . . . . . . .10 Opci´n de grabaci´n . . . . . . . . 111 18. . . . . . . .10Programa “envolventeComun” . .1 Alimentaci´n con una unica fuente .7 Almacenar m´ltiples instrumentos virtuales en un solo sintetizador 120 u 21. . . . 108 18. . .1. . . . . . . . . . . . . . .7 Programa “copiaSonido” . . . . . . .1. . . 113 18. . . . . . . . .5 Modificaci´n din´mica de los instrumentos . . . . . . . . 114 o 18. .9 Programa “sinusoidalesPuras” .1. . . . . . . . . . . .3 Detecci´n autom´tica de esclavos que est´n fallando . . . . . . . . . . 118 21.5 Programa “fourierPartes” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .2 Programa “graficaFacil” . . . . . . . . . . 118 o a a 21. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 19 Herramienta para reducir im´genes a 20 Protocolo para Transmitir un Nuevo Instrumento 21 Posibles mejoras y complementos 115 116 118 21. . . . . .3 Programa “acortaSonido” . . . . . . . . 122 21. 108 18. . . .1. . . . . . . . . . . 120 o a 21. . 120 21. . . . . . . .9 Ampliar la cantidad de tipos de instrumentos que se pueden generar 121 21. . . . . .18.4 Mejora de la frecuencia de salida . . . . . . . . . . . . .1.1. . . . . . . . . . . .12Programas que generan efectos . .2 Posibles mejoras en el software de PC . . . . . . . . . . . .11 Reproducir archivos . . . . . . 111 18. . . . . . . . . .11Observaci´n general . . . . . . . . . . . .1. . . . . . . . .

. . . . . . .2. . . . . . .3 Carpeta “Imitaciones Generadas Mediante Envolvente Individual” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .21. . . . . . teorema de Nyquist-Shannon . . . . .2. . . . . . . . . . . .h’ . . . . . . . . . . . . . .2. . . . . . .2 Carpeta “Ejemplos de Envolventes” . . . . . . .s’ . . . . 124 22. 133 o Clase ’CargarProgSlave. . . . . . . . . . . . . . . 124 e 22. . . . . .h’ . .1 Carpeta “Instrumentos Creados” . . . . . . . . . . . . . . . . . . . . . . .5 Integrar todos los programas y aplicaciones en un solo programa . . . . . . . . . . . . . . . . . . . . . . . . 138 Clase ’efectos.c’ . 133 Clase ’CargarProgSlave. . .4. 137 Clase ’dac. . . . . . . . . . . 144 11 . . 125 n 22. . . . . . 124 22.2 Mejora en la velocidad de funcionamiento . c´digos de los DSPic esclavos . . . . . . . . . . . . . . . . . . . . . .1 Mejora en el sistema de generaci´n autom´tica de notas . . . . . . . . 124 22. . . . . . . . . . . . . . . . . . . . . .3 Cambiar los par´metros a editar de un instrumento . . . . . . . . . .c’ . . . . . . . . . . . .s’ . . . . . . . . . . . 125 23 Conclusiones Bibliograf´ ıa Anexos 126 127 131 Anexo A. . . . . . 123 a 21. 122 o a 21. . 136 Clase ’dac. . . . . . . . . 135 Clase ’escribirEnMemoriaConst. . . . . . . . .2. 139 Clase ’efectos. . .2. . . . . 123 22 Explicaci´n del contenido del CD adjunto o 124 22. . . .1 Carpeta “Imitaciones Generadas Mediante Sinuidales Puras” .2 Carpeta “Imitaciones Generadas Mediante Envolvente Global” . . . . .4. . . . . . . . . . . . . . . . .h’ . . . . . . 125 22. . . .1 Carpeta “Imitaciones Generadas con los Distintos M´todos” . . . . . . 124 22. . . . .3. . . . . 122 21. .1 Carpeta “Imitaciones Generadas Con El Programa CopiaSonido” . . . . . . . . . . . . . . . . . . 131 Anexo B. . . 143 Clase ’call2. . . .4 Carpeta “Software Dise˜ado” . . . . . . . . .4 Agregar un conversor de instrumentos VSTi al formato del sintetizador123 21. . . . . . . . . . . . . .1. . . . . . . . . . . . . . . . .c’ . .

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 169 Clase ’I2C. . . . . . . . . . . . . . . 186 o n Instroducci´n’ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 214 Clase ’instrumento. . . . . . . . . . . . . . . . . .h’ . . . . . . . . . . . . . . . . . . .h’ . . . . . . . . . . . . . . . . . . . . . .c’ . . . . . . . . . . . . . . . . . . . . . . . . . . . . c´digos del DSPic master . . . .c’ . . . . . . . . . . c´digos del software para dise˜ar instrumentos . . . . . . . . . . 223 Clase ’nota. . . . . . . . . . . . . . . . . . . . . . . . . . . 153 Clase ’Main.vb’ . . . . . . . . . . . . . . . . . . . .vb’ .h’ . . . . . . . . 174 Clase ’mapearP. . . . . . 215 Clase ’mascara. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .c’ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 154 Anexo C. . . . . . . . .vb’ . . . . . . . 180 Clase ’main. . . . . .c’ . . . . . . . . . 225 12 . . . . . . . . . . . .vb’ . . . . . . . . 152 Clase ’tablas. . . . . . . . . . . . . . . . 175 Clase ’mapearP. . . . . . . . . . . . . . . . . 148 Clase ’iniciarReloj. . . . . . . . . .h’ . . . . . . .c’ . . . . .c’ . . . .h’ . . . . .h’ . . . . . . . 177 Clase ’serie. . . . . . . . 145 Clase ’I2C. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187 Clase ’crearMascara. . . . . 149 Clase ’iniciarReloj. . . . . .h’ . . . . . . . . . . . . . . . . . . . . .c’ . . . . 150 Clase ’manejoPuertos. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176 Clase ’serie. . . . . . . . . .vb’ . . . . 218 Clase ’metodosComunes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 186 o Clase ’crearInstrumento. . . . . . . . . . . . . . . 165 Clase ’adc. . . . . . . . . . . . 181 Anexo D. . . . 151 Clase ’manejoPuertos. . . . . . . . . . . . . . . . . .vb’ . . . . . . . . . . . .Clase ’I2C. . . . . . . . .h’ . . . . . . . .c’ . . . . . . . . . . . . 165 o Clase ’adc. . . . . . . . . . . . . . . . .c’ . . . . . . . . . . . . . . . . . . .vb’ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 202 Clase ’inicio. . 170 Clase ’I2C. . 166 Clase ’cargarPrograma. . . . . 167 Clase ’cargarPrograma. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .c’ . . .h’ . . . . . . . . . . . . . . . . .

. . . . . . . . . . . . . . . . 257 Efecto limitador if . . . . . . . . . . . . . . . . . . 264 13 . . . . . . . . . . . . . . . . . . . 246 o Funci´n ’fourieFacilDetectaPicos’ . . . . . . . . . . . . 244 o Funci´n ’copiaNota’ . . . . . . . . . . . . . . . . . . . 258 Efecto limitador logar´ ıtmico . 242 Anexo E. . . . . . . .vb’ . . . . . . . . . . . . . . . . . 264 o a Clase ’reduceImagenes. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244 o Funci´n ’acortaSonido’ . 233 Clase ’ventanaInicial. . . . . . . . . . . . . . . . . . . . . . 262 o Clase ’main’ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247 o Funci´n ’fouriePartesPicos’ . . . . . . . . . . . . . . 254 Efecto delay . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256 Efecto flanger . . . . . . . . . . . .vb’ . . . . . 259 Efecto vibrato . . . c´digos de scilab . . . . . . . . . . . . 245 o Funci´n ’copiaSonido’ . . . . .vb’ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 262 Anexo G. . . 261 Anexo F. . . 228 Clase ’pideUnDouble. . . . . . . . . . . . . . . . . . . . . . . . . . . . 231 Clase ’transmitir. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248 o Funci´n ’graficaFacil’ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260 Efecto Wah-Wah . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250 o Funci´n ’haceGraficas’ . . . . . . . . . . . . . . .vb’ . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255 Efecto eco . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .Clase ’pideEnteros. . . . . . . c´digos de la prueba previa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .vb’ . . . . . . . . . 251 o Efecto chorus . . . . . . . . . . . . . . . . . . . . . . . . . c´digos del software ”‘reduce Im´genes”’ . . . . . . . . . . .

Para conectar varios instrumentos MIDI a un dispositivo a que interprete las instrucciones hay varias formas. 1.1. El puerto MIDI THROW es un puerto que sirve para conectar varios instrumentos en serie porque genera una salida que es igual a lo que se recibe por el puerto de entrada MIDI IN m´s los mensajes MIDI correspondientes a lo que el usuario a est´ tocando en el instrumento. la intensidad. que notas hay que tocar. si no que contiene una serie de instrucciones para indicarle al reproductor como reproducir el sonido.mp3 o . de esta forma el int´rprete recibe las instrucciones generadas por e e los tres instrumentos. Los instrumentos MIDI por lo general a e disponen de tres puertos MIDI llamados MIDI IN. especialmente en el primer instrumento de la serie (en el ejemplo anterior del ‘A’). indican que sonido hay que utilizar. e b) En serie. el MIDI THROW del B al MIDI IN del C y finalmente del MIDI THROW del C a la entrada del int´rprete.1. Supongamos que se quieren conectar los instrumentos A.1 1 Introducci´n o Conceptos b´sicos a MIDI La sigla MIDI es una abreviatura de Musical Instrument Digital Interface (instrumento musical de interface digital). Para eso hay que conectar el MIDI OUT del A al MIDI IN e del B.wav. El objetivo de los VSTi u 1 Wikipedia en Espa˜ol: MIDI n 14 . B y C a un mismo int´rprete y e por la misma entrada de ´ste.1. es decir se conecta cada instrumento al dispositivo interpretador en una entrada distinta de ´ste. Es un protocolo de comunicaci´n que surgi´ en 1982 como o o un acuerdo entre distintos fabricantes de instrumentos musicales electr´nicos.2 Instrumento MIDI Un instrumento MIDI es un instrumento con la capacidad de generar se˜ales MIDI que n indiquen lo que el usuario est´ tocando en ´l.1 1.1 1. Un archivo o MIDI no contiene datos de audio muestreado como lo hace un archivo . El puerto MIDI OUT es una salida que emite los mensajes MIDI correspondientes a lo que el usuario est´ tocando en ´l. Este m´todo tiene la desventaja de que genera latencia (retardo) e en la salida de audio. Estas instrucciones se llaman mensajes MIDI. 1. etc. se utiliza cuando el dispositivo que interpretar´ los comandos tiene a menos entradas MIDI que la cantidad de instrumentos que se desea que este maneje.3 Instrumentos VSTi Esta tecnolog´ fue desarrollada por Steinberg una compa˜´ alemana dedicada al desarıa nıa rollo de software y equipos relacionados al mundo de la m´sica. El puerto MIDI IN recibe instrucciones MIDI generados por a e otro dispositivo. las m´s conocidas son: a a) En paralelo. MIDI OUT y MIDI THROW.

por ejemplo o un instrumento VSTi que simula una guitarra puede tener los programas “Metallica.mp3.es traducir las se˜ales MIDI a sonidos. .1. cada programa es una modo distinto de funcionamiento del VSTi. etc. a Muchos instrumentos VSTi tienen im´genes asociadas al instrumento que representan. La imagen 1 muestra el diagrama de conexi´n de esta opci´n. Para darle mayor control al usuario sobre la salida de audio.4 Efectos VST Los efectos VST son tecnolog´ muy similares a los instrumentos VSTi. la mayor´ de los instruıa mentos VSTi tienen la posibilidad de que el usuario cambie algunos par´metros de ellos. etc”.wav. un adaptador de MIDI a USB y un PC con entrada USB.5 VST Host Son programas encargados de interpretar los instrumentos VSTi.6 Conexi´n de un dispositivo MIDI a un PC o Para hacer sonar un instrumento MIDI en un PC se precisa: a) Un instrumento con salida MIDI.1. Un instrumento VSTi en el caso de Windows es un n archivo DLL. Los instrumentos VSTi por lo general tambi´n cuentan con programas de reproe ducci´n. Disturbed.1. permitirle al usuario asignar a cada entrada MIDI un instrumento VSTi y modificar los valores de dicho instrumento entre otras cosas. Los archivos VST por lo general son e programados en lenguaje “C” y tambi´n exportados en archivos DLL. Para poder usar un a a instrumento VSTi es necesario una aplicaci´n que soporte esta tecnolog´ esta aplicaci´n o ıa. El instrumento VSTi le indica al VST Host como reproducir las instrucciones MIDI que este recibe. e 1. o o 15 . no s´lo a sonidos generados por instrumentos o VSTi si no que tambi´n a sonidos . Nirvana. 1. se profundizar´ en este tipo de archivos m´s adelante. En este caso se conecta la salida MIDI del instrumento al adaptador y del adaptador al PC. 1. Un instrumento VSTi puede ser desde un archivo que haga sonar un instrumento MIDI como una guitarra profesional hasta uno en el cual le corresponde a cada nota del instrumento MIDI el sonido de un animal. o es llamada “VST Host”. a estas im´genes a la vez contienen dibujos de controles rotatorios y otros tipos de controles a para que el usuario pueda modificar el valor de alguno de los par´metros de los sonidos a generados por el instrumento VSTi. La idea detr´s de esto es de proveerle al usuario la a misma libertad que tendr´ con un instrumento real para ajustar algunos par´metros del ıa a sonido. pero su objetivo ıas es aplicarle efectos a sonidos ya existentes.

se abren los instrumentos VSTi que se deseen asociar a cada entrada MIDI y se los asocia.1. En este caso se conecta directamente el instrumento al PC.7 Reproducci´n de un instrumento MIDI conectado al PC o Se abre el VST Host.45 se deben seguir los siguientes pasos: 1) Abrir el programa. En este caso se conecta directamente el instrumento al PC. 2) Seleccionar las entradas y salidas MIDI. para eso en el men´ “devices” entrar a la u opci´n “MIDI” luego seleccionar la entrada MIDI deseada en la secci´n “MIDI input deo o vices” y la salida deseada en la secci´n “MIDI output devices”. las salidas posibles pueden o 16 .8 Reproducci´n de un instrumento MIDI con el programa VSTHost V o 1. Imagen 1: Imagen de la conexi´n opci´n “a” o o Imagen 2: Foto de los puertos de conexi´n de un piano MIDI o 1.1.45 Para poder escuchar los sonidos generados por instrumento MIDI conectado al PC en el programa VSTHost v 1. 1.b) Un instrumento con salida USB que transmita los datos en formato MIDI y un PC con entrada USB. c) Un instrumento con salida MIDI y un PC con entrada MIDI.

o Un sintetizador MIDI es un dispositivo con entradas MIDI y controles lineales y rotatorios y con una o m´s salidas de audio y MIDI. a a 5) Para cambiar el programa de funcionamiento del instrumento. 4) Para modificar los par´metros del instrumento puede hacer clic el bot´n a o que se encuentra cerca del nombre del instrumento virtual.ser salidas MIDI. 1. a 2 Wikipedia en espa˜ol: Sintetizadores n 17 . usando t´cnicas como s´ e ıntesis aditiva.9 2 Sintetizador MIDI Los sintetizadores son instrumentos musicales electr´nicos dise˜ados para producir sonidos o n generados artificialmente. o 3) Seleccionar el instrumento VSTi que se desea asociar a la entrada MIDI. Su principal funci´n es recibir los a o comandos MIDI y emitir por su salida de audio el sonido generado por las instrucciones MIDI recibidas. de modelado f´ o ısico o modulaci´n de fase. para eso en el men´ “File” seleccionar la opci´n “New plugin” y seleccionar el instrumento u o deseado. salidas de audio para escuchar los sonidos generados con parlantes m´s a potentes. Otra forma a a de modificar los par´metros es hacer clic en el bot´n a o que se encuentra cerca del nombre del instrumento virtual. Los controles sirven para modificar par´metros del sonido generado. etc. substractiva. de modulaci´n de frecuencia. en el men´ “Pluu gin” seleccionar el programa deseado. aparecer´ una imagen con a distintos controles que le permitir´ modificar los par´metros del instrumento. aparecer´ una ventana que permite cambiar los par´metros.1. el mapeador de Microsoft para reproducci´n de MIDI.

terminan e resultando para ciertos usuarios.1. la idea a es hacer un sistema sencillo de manejar para el usuario “que enchufe el instrumento y suene directo”. En el mercado ya existen dispositivos m´s complejos que el de este proyecto. Los dispositivos m´s complejos que existen en el mercado no s´lo que a o son caros. sino que tambi´n dada la gran cantidad de opciones que estos tienen. Tambi´n debe contar con un juego de controles que e modifiquen los par´metros del instrumento VSTi. sobre todo los principiantes y amateurs. El instrumento MIDI le indicar´ cual a nota es la que tiene que reproducir. para que mediante este puerto se le transmitan dichos instrumentos. un problema lograr configurarlos y descargarle desde el PC los instrumentos deseados. El sistema debe tener una interfaz para comunicarse con un PC y la capacidad de manejar instrumentos VSTi. Tambi´n puede modificar los par´metros del instrumento e a mediante los controles. luego el usuario puede conectarlo a su instrumento MIDI y la salida a un amplificador y tocar el instrumento.2 Objetivo del proyecto El objetivo del proyecto es realizar un sistema embebido que tenga la capacidad de generar una salida de audio siguiendo las instrucciones recibidas por el instrumento MIDI que se le conecte (el sistema debe tener una entrada MIDI). a El objetivo es hacer un sistema que se venda con un instrumento VSTi espec´ ıfico instalado. Esquem´ticamente el conexionado del sistema deber´ ser de la siguiente manera: a ıa Imagen 3: Esquema del objetivo del proyecto 18 .

Tampoco desea tener que estar creando controles virtuales para poder modificar par´metros de su instrumento virtual. Si a esto se le suma que muchas veces la gran cantia dad de opciones confunde al usuario inexperto provocando que lo que si quiere configurar no sepa como. se muestra en la imagen 4. Un usuario u principiante o amateur desea hacer sonar el dispositivo sin tener que hacer grandes configuraciones. Simplemente se conecta el instrua mento al sistema.com/product/SM-Pro-Audio-VmachineStand-Alone-VST-Player?sku=241884. se concluye que la V-Machine no es optima para el usuario principiante o ´ amateur que desea “conectar el instrumento y que suene” (Plug and Play). el producto se llama “SMPro Audio V-Machine Standalone VST Player”. Este dispositivo es un dispositivo mucho m´s completo del que se desea realizar a en este proyecto. El dispositivo consta de una entrada MIDI que puede contener informaci´n de varios instrumentos conectados en serie. Este proyecto esta ideado espec´ ıficamente para esos usuarios que quieren “conectar el instrumento y que suene” sin grandes complicaciones.3 1. y que se puedan modificar par´metros sin tener que crear controles virtuales.1.musiciansfriend. Para modificar los par´metros de los distintos instrumentos VSTi y efectos VST ´ a tiene la posibilidad de crear controles rotatorios virtuales. o y permite asociarle a cada instrumento un instrumento VSTi distinto. se conecta tambi´n un parlante y se escuchan las se˜ales generadas e n 19 .3. Tiene la capacidad de cargar varios instrumentos VSTi y efectos VST en su memoria de 1Gb y hacer distintas combinaciones de estos para generar sonidos unicos. Imagen 4: SMPro Audio V-Machine Standalone VST Player Su sitio web es: http://pro-audio.1 Sistemas similares existentes Sistemas embebidos similares Actualmente en el mercado existe un producto similar al que se busca crear en este proyecto. La gran cantidad de opciones de manejo y funciones que este dispositivo contiene lo transforma en un dispositivo ideado para compositores de m´sica y DJ´s. Tambi´n dispone e de una entrada de audio a la cual se le pueden aplicar efectos VST.

o Una de las desventajas de remplazar el sistema que se desea crear con un PC es que al igual que la V-Mahcine. Al ser m´s simple ser´ tambi´n m´s econ´mico lo cual es a a a e a o otra ventaja. Por lo que el precio no ser´ una ventaja frente o a esta otra opci´n. Si u la PC no se usa exclusivamente para tocar el instrumento MIDI tambi´n est´ el problema e a de que en cualquiera de los otros momentos en los que se us´ hayan ingresado virus al PC o o se haya desconfigurado algo que imposibilite el correcto funcionamiento del Host VST. y en el caso de que tal PC no tenga una entrada MIDI. sobre todo en circunstancias como un concierto en las que la mesa donde este el PC pude no ser muy estable. ya vimos que hay adaptadores MIDI-USB muy econ´micos.3.por el instrumento. 1. cuesta alrededor de 600 d´lares en Estados Unidos. si no que hay controles de rotaci´n reales que al girarlos modifican los o par´metros del instrumento. a Si bien se tienen menos funciones que la V-Machine. que es m´s de lo que un m´sico amateur o principiante o a u promedio quiere gastar. esto tiene la ventaja de volver m´s sencillo el funcionamiento. etc. 20 . no es necesario crear a controles virtuales. probablemente la mayor´ de los posibles usuarios de este producto ya tengan acıa ceso a una. es decir que se puede trancar en cualquier momento. Para modificar par´metros del instrumento.2 Generar las funciones de este proyecto con un PC Existen muchos programas para PC que permiten realizar el objetivo de este proyecto y muchas m´s funciones. considerando que la V-Machine no es un dispositivo barato. dichos programas son los Host VST mencionados en la introa ducci´n. o Si bien comprar un PC para remplazar al dispositivo que se busca realizar es muy caro. Otra desventaja es a que algunos m´sicos consideran mal visto llevar PC´s o notebooks a conciertos en vivo. La principal desventaja del PC es que no es tan es estable como un sistema embebido. la PC no es un dispositivo f´cil de manejar.

que puede estar seguido de cierta cantidad de bytes de datos.2 2. El byte MIDI est´ compuesto por diez bits que se env´ a ıan/reciben a una velocidad de 31250 bits/segundo con una tolerancia de +/. MIDI est´ pensado para comunicar un unico controo a ´ lador con varias unidades generadoras de sonido (cada una de las cuales puede tener uno o varios instrumentos sintetizados que deseemos utilizar). Este m´todo es el denominado canal. o Se diferencian por el primer bit: si es un 1.1% seg´n el est´ndar. por norma general. es un byte de estado. Esto con el ´ o fin de que los dispositivos MIDI puedan llevar la cuenta de cuantos bytes se han enviado o recibido.1 Canales MIDI Como se coment´ con anterioridad. los mensajes de estado se dividen en dos grupos: mensajes de canal y mensajes de sistema. se puede enviar un primer mensaje de estado “activar nota”. Dichos a o o comandos constan de tres mensajes. Los ocho bits restantes contienen los mensajes MIDI.1 3 Conceptos avanzados Instrucciones MIDI Como se mencion´ anteriormente las instrucciones MIDI son comandos generados por o los instrumentos MIDI que se encargan de indicar las instrucciones de como generar un sonido en base a lo que el usuario toca en el instrumento. todo por un mismo medio de transmisi´n. y si es un 0. mientras que los mensajes de sistema son procesados por todos los equipos. el resto de bytes son mensajes de sistema. seguido de un byte de datos informado qu´ nota es la que se activa.y de informaci´n -data byte-. Por ejemplo. todos los aparatos conectados a la cadena MIDI reciben todos los o mensajes generados desde el controlador. El protocolo de transmisi´n es el mismo que el del sistema RS-232. El primero es el bit u a de inicio que siempre es 0 y el ultimo el bit de terminaci´n que siempre es 1. ıan o Existen dos tipos de bytes: De estado -status byte. siempre se env´ un byte de ıa estado. 2. Los comandos m´s utilizados son los de activaci´n y desactivaci´n de nota. luego la nota que fue activada/desactivada y finalmente la velocidad con que fue activada/desactivada. el primero es el identificatorio de la funci´n (byte de o estado).1. se re´ a fieren a mensajes de canal. En algunas ocasiones y seg´n el dispositivo MIDI e u que se trate. e A su vez. Es decir. Ello hace necesario un m´todo para diferenciar e cada uno de los instrumentos. es un byte de datos. puede ocurrir que se omita el byte status si es id´ntico al anterior. A continuaci´n se indica en o detalle como son estas instrucciones. Los mensajes de canal son procesados por un dispositivo espec´ ıfico. e 3 Wikipedia en Espa˜ol: MIDI n 21 . Al generar un mensaje MIDI. Las instrucciones MIDI se env´ en serie. cuyos ultimos cuatro bits est´n marcados como “cccc”. La tabla 1 contiene todos los mensajes disponibles: Los primeros bytes.

que puede formar acordes por medio de hacer sonar dos o m´s notas a la vez. ´ Polif´nico: Un instrumento polif´nico puede reproducir varias notas simult´neamente. o cada uno con ciertas caracter´ ısticas. ya que s´lo reproducen o o un unico sonido a la vez. Monof´nico: Un instrumento monof´nico s´lo puede reproducir una nota simult´neamente. o instrumentos). 2. Por ejemplo.2 Modos MIDI Dentro del sistema MIDI.Byte estado 1000cccc 1001cccc 1010cccc 1011cccc 1100cccc 1101cccc 1110cccc 11110000 11110001 11110010 11110011 11110100 11110101 11110110 11110111 11111000 11111001 11111010 11111011 11111100 11111101 11111110 11111111 Descripci´n o Desactivaci´n de nota o Activaci´n de nota o Postpulsaci´n polif´nica o o Cambio de control Cambio de programa Postpulsaci´n monof´nica de canal o o Pitch Mensaje exclusivo del fabricante Mensaje de trama temporal Puntero posici´n de canci´n o o Selecci´n de canci´n o o Indefinido Indefinido Requerimiento de entonaci´n o Fin de mensaje exclusivo Reloj de temporizaci´n o Indefinido Inicio Continuaci´n o Parada Indefinido Espera activa Reseteo del sistema Tabla 1: Tabla de comandos MIDI MIDI puede direccionar hasta 16 canales (tambi´n llamados voces. para reproducir una nueva nota debe primero dejar de sonar la anterior. se decidi´ crear una serie de diferentes modos de funcionamiento. e por ello.1. al instalar el sistema MIDI ser´ necesario asignar un n´mero de canal para cada a u dispositivo. los instrumentos de viento son monof´nicos. a A continuaci´n se muestra la tabla de modos de funcionamiento: o 22 . o o o a Es decir. o o a Un ejemplo es un piano.

1.3 Instrumentos MIDI La tabla 2 muestra los 128 instrumentos de la especificaci´n est´ndar de MIDI. o 2. la informaci´n del canal se puede prescindir.N´mero u 1 2 3 4 Nombre Omni on polif´nico o Omni on monof´nico o Omni off polif´nico o Omni off monof´nico o Descripci´n o Funcionamiento Funcionamiento Funcionamiento Funcionamiento polif´nico sin informaci´n de canal o o monof´nico sin informaci´n de canal o o polif´nico con informaci´n de canal o o monof´nico con informaci´n de canal o o Los mensajes de canal son los que sus bytes de estado en la tabla de funciones MIDI terminan con “cccc”. tambi´n o a e conocidos como GM o “General Midi” 23 . En los casos en los que hay un solo instrumento conectado al sistema.

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 Piano de cola ac´stico u Piano ac´stico brillante u Piano de cola el´ctrico e Piano de cantina Piano Rhodes Piano con chorus Clavicordio Clavinet Celesta Carill´n o Caja de m´sica u Vibr´fono a Marimba Xil´fono o Campanas tubulares Salterio organo Hammond ´ organo percusivo ´ organo de rock ´ organo de iglesia ´ Armonio Acorde´n o Arm´nica o Bandone´n o Guitarra espa˜ola n Guitarra ac´stica u Guitarra el´ctrica (jazz) e Guitarra el´ctrica (limpia) e Guitarra el´ctrica (apagada) e Guitarra saturada (overdrive) Guitarra distorsionada Arm´nicos de guitarra o Bajo ac´stico u Bajo el´ctrico pulsado e Bajo el´ctrico punteado e Bajo sin trastes Bajo golpeado 1 Bajo golpeado 2 Bajo sintetizado 1 Bajo sintetizado 2 Viol´ ın Viola Violoncello 43 Contrabajo 44 Cuerdas con tr´molo e 45 Cuerdas con pizzicato 46 Arpa 47 Timbales 48 Conjunto de cuerda 1 49 Conjunto de cuerda 2 50 Cuerdas sintetizadas 1 51 Cuerdas sintetizadas 2 52 Coro Aahs 53 Voz Oohs 54 Voz sintetizada 55 ´xito de orquesta e 56 Trompeta 57 Tromb´n o 58 Tuba 59 Trompeta con sordina 60 Corno franc´s (trompa) e 61 Secci´n de bronces o 62 Bronces sintetizados 1 63 Bronces sintetizados 2 64 Saxo soprano 65 Saxo alto 66 Saxo tenor 67 Saxo bar´ ıtono 68 Oboe 69 Corno ingl´s e 70 Fagot 71 Clarinete 72 Flaut´ ın 73 Flauta 74 Flauta dulce 75 Flauta de pan 76 Cuello de botella 77 Shakuhachi (flauta japonesa) 78 Silbato 79 Ocarina 80 Melod´ 1 (onda cuadrada) ıa 81 Melod´ 2 (diente de sierra) ıa 82 Melod´ 3 (´rgano de vapor) ıa o 83 Melod´ 4 (siseo organo) ıa ´ 84 Melod´ 5 (charanga) ıa 85 Melod´ 6 (voz) ıa 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 Melod´ 7 (quintas) ıa Melod´ 8 (bajo y melod´ ıa ıas) Fondo 1 (nueva era) Fondo 2 (c´lido) a Fondo 3 (polisintetizador) Fondo 4 (coro) Fondo 5 (de arco) Fondo 6 (met´lico) a Fondo 7 (celestial) Fondo 8 (escobillas) Efecto 1 (lluvia) Efecto 2 (banda sonora) Efecto 3 (cristales) Efecto 4 (atm´sfera) o Efecto 5 (brillo) Efecto 6 (duendes) Efecto 7 (ecos) Efecto 8 (ciencia ficci´n) o Sitar Banjo Shamisen Koto Kalimba Gaita Viol´ celta ın Shanai Campanillas Agog´ o Cajas met´licas a Caja de madera Caja Taiko Timbal mel´dico o Caja sintetizada Platillo invertido Trasteo de guitarra Sonido de respiraci´n o Playa Piada de p´jaro a Timbre de tel´fono e Helic´ptero o Aplauso Disparo de fusil Tabla 2: Instrumentos MIDI 24 .

Dichas clases tienen sus o declaraciones en: AudioEffect. Tambi´n es necesario estar al tanto e de las definiciones de estructura de aeffect.2. en el caso o particular de los VST o VSTi dichos programas son los VST Host. lo que hacen estos plugins es tomar una secci´n de audio (o ino strucci´n MIDI). pero solo los permite exportar en formato DLL.hpp y AudioEffect. 2. Por lo general o o los comandos MIDI o el audio a analizar es dividido en secciones por el anfitri´n que le o encomienda al plugin procesarlo y despu´s toma los resultados generados y los reproduce.2. ıas La idea del proyecto es generar los instrumentos VSTi con el programa “Synth Maker”.cpp.1 Opciones de proceso Tanto los instrumentos VSTi como los efectos VST para procesar audio deben tener un m´todo llamado process() y preferentemente tambi´n uno llamado processReplacing(). les aplica el algoritmo del proceso y coloca e el resultado en un buffer de salida.0. 2. 4 SDK Steinberg 25 .2 Implementaci´n de plugins VST y VSTi o Para implementar plugins VST y VSTi es necesario utilizar las clases base: AudioEffect y AudioEffectX que se encuentran en el VST sdk versi´n 1. es decir que es necesario un programa anfitri´n para poder utilizarlos.3 del SDK en dicha contraparte se le agrega una ‘X’ al final del nombre de la clase. mientras que el segundo m´todo tiene la capacidad e de reescribir los datos que ya se encuentran en el buffer de salida. En Windows los instrumentos VSTi y efectos VST son archivos DLL. No es u a necesario conocer el funcionamiento interno de estos para poder utilizarlos. Cada una de las clases mencionadas anteriormente tiene su contraparte en la versi´n o 2.h. en Mac son archivos Bundle y en Linux y otros sistemas UNIX son librer´ compartidas. El VST Host es el encargado de proveer tanto el buffer de entrada como el de salida. pero el compilado depende del sistema operativo en el cual el VST Host va a ejecutarse. Por lo general. procesarla y mandar el resultado al programa anfitri´n.2 Funcionamiento de los instrumentos VSTi y de los efectos VST 4 Los efectos VST y los instrumentos VSTi no son aplicaciones en si mismos. si no que son plugins. El e e primer m´todo toma los datos de entrada. El c´digo fuente de un instrumento VSTi o de un efecto VST es independiente de o la plataforma de trabajo. dicho programa dispone de una gran cantidad de herramientas para desarrollar instrumentos virtuales. e Desde el punto de vista del VST Host los instrumentos VSTi y los efectos VST son “cajas negras” con un n´mero arbitrario de entradas y par´metros asociados.2.

2 Desventajas del uso de librer´ compartidas DLL ıas 1. n o e o 4. Todos los archivos DLL que se vayan a utilizar deben estar en la carpeta del sistema antes de ejecutar los programas que los usan. En cambio las otras extensiones asociadas a las librer´ de enlace ıas din´mico se cargan porque est´n referenciadas en archivos de inicializaci´n de Windows. 2. a 6. esto reduce el c´digo o y el tama˜o de las aplicaciones. 2. Una funci´n escrita en una archivo DLL esta disponible para cualquier aplicaci´n o o de Windows. en algunos casos tambi´n son guardados en archivos .3. se reduce tambi´n el tiempo de compilaci´n. gran parte de las librer´ de enlace din´mico se guardan en archivos ıas a que tienen extensi´n DLL. o 3. se puede considerar que Windows est´ construido sobre una gran cantidad a de DLL’s. El tiempo de acceso a la DLL por parte de una aplicaci´n es m´s lento que si o a estuvieran las funciones de la DLL en el propio c´digo del programa. definiciones de fuentes. pero distintas funciones se generan inconvenientes para ejecutar dichos programas.1 Ventajas del uso de librer´ DLL ıas 1. por lo que en caso de fallar son o f´cilmente reemplazables. se puede remplazar una DLL o por una mejor y dicho cambio se ver´ reflejado en todos los programas que usan el a mismo archivo DLL sin que sea necesario tener acceso y modificar el c´digo de cada o uno de estos. a a o Estas referencias pueden ser creadas por el propio Windows o por el programa de instalaci´n de alguna aplicaci´n. etc) que pueden ser llamados desde cualquier aplicaci´n de Windows. 26 . Si bien.3 Archivos DLL Los archivos DLL (Dynamic Link Library. Lo que caracteriza a las librer´ de enlace din´mico con extensi´n DLL es que se ıas a o encuentran disponibles para ser cargadas en cualquier momento que el programa se lo solicite a Windows. n 3. 4.3. Como las DLL´s son independientes de la aplicaci´n. En caso de que dos programas utilicen dos DLL con el mismo nombre. Las DLL´s son independientes de la aplicaci´n. o o 2. o De hecho.2. 2. 5. Al reducirse el tama˜o del c´digo. DRV (controlador de dispositivo) y FON (fuente de Windows). Otra consecuencia del segundo punto es el ahorro de espacio en el disco duro. librer´ de enlace din´mico) son archivos que ıa a contienen funciones o recursos (mapas de bits. Si una DLL es mal sustituida todos los programas que la usan se ven afectados. Como varias aplicaciones pueden usar un mismo archivo DLL.exe o e (ejecutables).

o 3. Desventajas de la Llamada Est´tica a un Archivo DLL : a 1. por lo que el uso del archivo DLL o no enlentece la ejecuci´n del programa. 4.5.3. se carga en seguida que se ejecuta la aplicaci´n. o o 5. 2. o Ventajas de la Llamada Est´tica a un Archivo DLL : a 1. El programa incluye el c´digo de cada DLL que utiliza.4 Llamada Est´tica a un Archivo DLL a Este tipo de llamada consiste en cargar el archivo DLL directamente en el momento de compilaci´n del programa. El enlace se produce en tiempo de compilaci´n.3. Como a o consecuencia las funciones de la DLL pueden ser llamadas dentro del c´digo del ejecutable o como cualquier otra funci´n del programa. por lo cual no a existe una forma sencilla de ejecutarlos en otros entornos. Se genera una repetici´n del c´digo de los archivos DLL. 27 . Como consecuencia de los dos puntos anteriores. o 3. Las funciones del archivo DLL son llamadas como cualquier otra funci´n del proo grama. estas fueron declaradas por el programador. Punto de Entrada y Salida del archivo DLL Es la funci´n principal de la DLL. Esto tiene como consecuencia que se incluye el c´digo o o de la librer´ dentro del ejecutable. Las librer´ se cargan autom´ticamente cuando se carga el programa. 2. el tama˜o de los programas aun menta. no ıa ıa hace falta cargarla m´s adelante. Dicha funci´n se llama DllEntryPoint. o Funciones que Contiene la DLL Son las funciones que contiene el archivo DLL. Debe incluirse el c´digo de la DLL en cada ejecutable del programa que la utilice. Como la librer´ forma parte del ejecutable. ıas a 2.3 Estructura de una DLL de 32 bits Un archivo DLL consta b´sicamente de tres partes: a Archivo de Cabecera Contiene todas las declaraciones y/o definiciones que use el archivo DLL. o 2. Los archivos DLL permanecen en memoria durante todo el tiempo que se este ejecutando el programa que los usa. Los archivos DLL est´n hechos para ser ejecutados en Windows. y o es la que se encarga de cargar la DLL (cuando se vaya a usar) y descargarla de la memoria (cuando se deje de usar).

3. luego de utilizarla (en tiempo de ejecuci´n) libere la memoria RAM eliminando el archivo DLL de ´sta.2. el tama˜o de los ejecutables es menor. 6.3. a 28 . 2. No requiere incluir la librer´ DLL en cada ejecutable que la utilice. Realizar el enlace entre un programa y una librer´ DLL en tiempo de ejecuci´n ıa o complica su manejo y aumenta las probabilidades de errores.5 Llamada din´mica a un archivo DLL a Este m´todo consiste en llamar al archivo DLL durante el tiempo de ejecuci´n en el e o momento en que alguna de sus funciones es requerida. El manejo de las funciones de las librer´ DLL es m´s complicado que en el caso ıas a de las llamadas est´ticas. El archivo DLL es cargado en memoria unicamente si el programa lo precisa. El c´digo de las librer´ DLL se puede cargar y descargar de la memoria seg´n si o ıas u este es requerido o no. Se evitan repeticiones del c´digo del archivo DLL. Como consecuencia de los primero dos puntos. Para que este m´todo sea efectivo es ´ e necesario que el programa que requiere el uso de la DLL. Desventajas de la llamada din´mica a un archivo DLL : a 1. La librer´ tiene almacenado su c´digo en un archivo DLL y no en el c´digo del ıa o o programa que la requiere. n 4. ıa 3. Se aumenta la independencia entre el archivo DLL y el programa que lo requiere. La librer´ es cargada en tiempo de ejecuci´n. ıa o 2. lo que enlentece el programa. o e Ventajas de la llamada din´mica a un archivo DLL : a 1. o 5.

La mayor´ de los reproductores que se encuentran con c´digo abierto (open source) ıa o de MIDI utilizan bibliotecas precompiladas de Windows por lo cual no ser´ posible utiıa lizarlos para interpretar instrucciones MIDI. Si bien las ventajas de esta forma son considerables.2 Utilizar un sistema embebido sin sistema operativo La idea de esta posible implementaci´n es hacer el proceso de se˜ales MIDI y de los o n archivos VSTi con sistemas embebidos sin la capacidad de cargar un sistema operativo. clima. son de menor tama˜o que otros sistemas embebidos y est´n dise˜ados para n a n funcionar mucho tiempo sin reiniciarse en condiciones no optimas (de ruido. ´ etc). comenzamos el an´lisis de los posibles sistemas embebidos para crear el sintetizador. la combinaci´n o de comandos e instrucciones MIDI es tan grande que probablemente una biblioteca hecha por nosotros no lograr´ tener un control completo de todas las variables posibles. ’C++’ o similar. ıa 29 .1 Posibles sistemas de implementaci´n o Introducci´n o Una vez definido el objetivo del proyecto y estudiados los conceptos implicados en este. tambi´n hay ciertas desventajas e y obst´culos por sortear. A continuaci´n se ıan o analizan los que consideramos los principales problemas a resolver en caso de optar por esta opci´n. Esta forma de implementaci´n tiene la ventaja de ser econ´mica y de que no se o o necesitar´ recurrir a sistemas hechos por terceros (VST Host. a Buscamos un sistema que sea barato. Dicha biblioteca deber´ incluir solo clases que est´n en el lenguaje de compilaci´n del compilador ıa e o del sistema embebido. En esta secci´n se presentar´n y desarrollar´n los tipos de sistemas embebidos exiso a a tentes que se podr´ utilizar para desarrollar el sistema. etc) para poner en marcha ıa el proyecto. robusto. que pueda interpretar comandos MIDI y que pueda manejar archivos DLL (para poder interpretar instrumentos VSTi). ıan 3. Vemos que puede parecer complicado el desarrollo de una biblioteca capaz de interpretar todos los comandos MIDI. relieve. En caso de trabajar o con sistemas embebidos sin sistema operativos muchas de estas herramientas ya desarrolladas se deber´ re-inventar para poder utilizarlas bajo este entorno.1 Interpretaci´n de los comandos MIDI o Una vez recibidos los comandos MIDI ser´ necesario desarrollar una biblioteca (o enconıa trar alguna hecha) que pueda interpretar las instrucciones MIDI recibidas. o 3.3 3.2. En caso de utilizar un sistema embebido con sistema operativo a se puede utilizar la gran cantidad de c´digos y herramientas que ya existen desarrolladas o para la interpretaci´n de comandos MIDI y de instrumentos VSTi. sistemas embebidos que directamente se programan en ’C’.

En la p´gina de Rabbit compa˜´ que fabrica microcontroladores a nıa embebidos. o 30 . Dado que los archivos DLL son “cajas negras” ser´ necesario encontrar una forma de interpretar los procesos internos ıa que genera Windows para poder usar esas “cajas negras” y poder generar un c´digo capaz o de reproducirlos. Los plug-in en algunos browsers de internet son ejemplos claros de este tipo de archivos. preguntamos al servicio t´cnico si tienen alg´n producto con la capacidad de e u interpretar funciones de un archivo DLL o si tienen conocimiento de alg´n c´digo fuente u o que permita interpretar dichas funciones y la respuesta fue que no.3 Sistemas existentes que interpretan archivos DLL fuera de Windows Se procedi´ a buscar si ya ha habido un caso en el que se haya logrado ejecutar un archivo o DLL cualquiera fuera de la plataforma Windows. buscamos informaci´n en varias de ellas y no ena o contramos en ninguna. 3. En las p´ginas de a los otros fabricantes de sistemas embebidos todas las respuestas nos guiaron a utilizar un sistema embebido con un sistema operativo.2. si vamos a querer utilizar estos mismos archivos en una plataforma sin sistema operativo se necesitar´ generar un programa que logre a interpretarlos.2. la estructura o en la cual las funciones de un archivo DLL son almacenadas y sobre el c´digo assembler o de Windows es muy escasa lo que tambi´n dificulta la tarea de lograr interpretar los e instrumentos VSTi fuera de Windows. Otra de las fuentes de informaci´n en las que buscamos fue en las p´ginas de las o a f´bricas que generan sistemas embebidos.2 Interpretaci´n de Instrumentos VSTi o El objetivo de este proyecto es que el sistema embebido a armar tenga la capacidad de interpretar instrumentos VSTi. Como los DLL fueron pensados para correr unicamente en Windows. Los archivos DLL tambi´n contienen algunas instrucciones sobre el manejo de memoe ria que estos precisan. La documentaci´n sobre el funcionamiento interno de un archivo DLL. por lo cual para poder interpretar los archivos DLL en un sistema embebido sin sistema operativo se deber´ generar un sistema de manejo de memoria que a simule al de Windows. Los archivos DLL tambi´n funcionan como peque˜os programas que necesariamente e n deben ser ejecutados sobre un programa madre.3. en caso de encontrarlo quiz´s se podr´ a ıa realizar lo mismo con los archivos VSTi. muchas de las ´ funciones que estos necesitan para funcionar son exclusivas de Windows. Wine Wine es un programa que permite correr en Linux programas dise˜ados para ser n utilizados s´lo en Windows. raz´n por la cual o si queremos interpretar archivos DLL sin utilizar un sistema operativo se deber´ hallar a cuales son estas funciones espec´ ıficas que nuestro DLL requiere para poder implementarlas. que como se mencion´ en su mayor´ se encuentran en o ıa formato DLL exclusivo de Windows.

(no ser´ necea ıa sario en nuestro caso). KERNEL32. La iniciativa de Wine naci´ hace ya catorce y es un proyecto en o continuo desarrollo. comdlg32. son muy com´nmente usados para poder u cambiar de idioma programas. Tambi´n existen programas como el txtScani y el exeScope que b´sicamente son e a muy parecidos al FlexHex. y o en el resto se observa el c´digo en formato Hexa. Algunos instrumentos VSTi precisan importar m´s librer´ a ıas.dll: Contiene funciones gr´ficas para objetos en 2 dimensiones. En el primero se muestra la posici´n de memoria en la que se esta trabajando.dll: Contiene funciones de audio de bajo nivel. entre ellas: ıas WINMM. A continuaci´n se ver´n las posibles opciones de sistemas operativos.dll: Es el n´cleo m´s importante del kernel de Windows. solo que estos tambi´n tienen la posibilidad de buscar cadenas e de texto y mapas de bits dentro del archivo DLL. GDI32. tambi´n maneja las interrupciones y asigna el tiempo e de ejecuci´n de cada aplicaci´n. y necesitan importar 12 librer´ DLL. Un ejemplo de esto es el FlexHex. La mayor´ de los e ıas ıa instrumentos VSTi utilizan aproximadamente 100 funciones de archivos DLL de Windows. en caso de querer interpretar ıas archivos DLL sin sistema operativo estas tendr´ que ser creadas. 3. Al ser Windows y Linux n sistemas operativos tienen librer´ que son equivalentes. o a 31 . Sirve para gesu a tionar el uso de la memoria. Este programa no nos o es util. solo permite manejar su archivo binario.En el FlexHex se distinguen cuatro paneles.dll: Contiene funciones para la interfaz con el usuario. Ansi y Unicode. (no ser´ necesario a ıa en nuestro caso). Otra funci´n de estos programas mencionados es interpretar la cabecera del archivo o DLL permitiendo conocer los encabezados de las funciones que un archivo DLL contiene y tambi´n cuales son las librer´ que un DLL necesita importar. dado que se busca por ejemplo la cadena de texto “File” y se la remplaza por la cadena “Archivo”. ıan Sistemas que permiten acceso al c´digo binario de un archivo DLL o Existen ciertos programas que permiten abrir este tipo de archivos de forma binaria e incluso alterarlo.3 Utilizar un Sistema Embebido con Sistema Operativo En esta secci´n se va a analizar la opci´n de utilizar como el procesador central para o o la soluci´n del proyecto un sistema embebido con la capacidad de cargar un sistema o operativo.dll: Contiene los mensajes de di´logo y carteles comunes. esto nos da una pauta de lo dif´ que puede ser intentar migrar ıcil programas dise˜ados para Windows a otro sistema operativo. dado que no es posible interpretar funciones (las que est´n incluidas en el archivo ´ a DLL).Este caso tiene en com´n con el nuestro que tambi´n se usa para interpretar archivos u e DLL entre otras cosas. o o USER32.

3 5 Utilizar sistemas operativos en tiempo real Los sistemas operativos en tiempo real. dado que si bien hay varios VST Host ıa gratuitos para Linux. Dentro de Windows tambi´n encontramos VST Host gratuitos y con a˜os de desarrollo.3.2 Sistema Operativo Windows La gran ventaja de utilizar Windows para este proyecto es que los archivos VSTi en formato DLL est´n desarrollados y optimizados para funcionar en este entorno. 3. Desarrollar nosotros un VST Host a parte de tener el problema del tiempo que consuma tambi´n tiene el inconveniente de que seguramente no e podamos generar una versi´n que funcione correcto en todos los casos y menos que este o tan optimizada como los otros Host Vst que tienen a˜os de desarrollo. que est´n dados en formato DLL a librer´ compartidas para que a ıas puedan ser ejecutadas por Linux. de esta forma no ser´ necesario convertir los DLL y ya ıa disponemos de un programa open source para poder modificar. si no que tambi´n pueden garantizar en cuanto tiempo. tambi´n a o e ser´ necesario desarrollar un VST Host nosotros. 5 Wikipedia en espa˜ol: Sistemas operativos de tiempo real n 32 . Como segunda opci´n existe la posibilidad de utilizar el programa Wine para generar o un emulador de Windows. Windows es a u el sistema operativo con mayor compatibilidad con cualquier hardware que precisemos. e n de esta forma podemos basar nuestro software en uno existente y hacerle algunas adaptaciones para acoplarlo a nuestros requisitos. Adem´s del problema de obtener una conversi´n para los archivos DLL.3.1 Sistema Operativo Linux Para utilizar el sistema operativo Linux el principal problema ser´ lograr transformar los ıa instrumentos VSTi. punto que encontramos muy favorable.3. parecer´ ser ideales ıan para el proyecto dado que eligiendo el procesador adecuado y el c´digo adecuado se puede o garantizar que el sonido se va a escuchar bien. o a e Dada las caracter´ ısticas de este tipo de sistema operativo. lo que disminuir´ el o ıa costo del nuestro producto. no es posible garantizar que los comandos MIDI van a ser procesados con una velocidad suficiente como para que el sonido se escuche bien.3. no pudimos encontrar ninguno que sea de c´digo abierto para hacerle o las modificaciones que precisemos. Como ventajas encontramos que Linux es de libre distribuci´n. Como contrapartida la idea de usar un emulador consumir´ muchos recursos del sistema y no funcionar´ tan ıa ıa bien como correr un Windows embebido directamente. Otro problema que podr´ surgir es encontrar drivers ıa de los adaptadores MIDI compatibles con Linux. Esta es una opci´n n o que debemos descartar. Con sistemas operativos que no son en tiempo real (como Windows y Linux). Otra ventaja a es que al ser el sistema operativo m´s utilizado por los editores de m´sica. son sistemas que no solo garantizan que una acci´n pedida se realizar´. 3.

los sistemas operativos ıa en tiempo real. entradas midi. cambian de tarea por interrupciones de reloj y por evento. o a sin paginaci´n. estas sean muy dif´ ıas ıciles de calcular y es dif´ que cumplan los requisitos. y su tasa de interrupci´n del reloj alta pueden o o interferir en la capacidad de procesamiento. etc. no consideramos como opci´n v´lida o a utilizar otro sistema operativo. Raz´n por la cual o si bien es posible dar garant´ sobre los tiempos. Aunque para prop´sito general un procesador moderno suele ser m´s r´pido. o 3. 33 . da una mejor ilusi´n de multitarea.4 Utilizar otros sistemas operativos Se busco tambi´n la posibilidad que existe un sistema operativo o algo similar dedicado e exclusivamente al manejo de instrumentos virtuales y entradas MIDI.3. para o a a programaci´n en tiempo real deben utilizarse procesadores lo m´s predecibles posible. ıcil A diferencia de la mayor´ de los otros sistemas operativos. que cumple con los plazos. Dado que no encontremos ninguna informaci´n de un sistema operativo especial para o manejar instrumentos musicales.Este tipo de sistema operativo no tiene una capacidad de procesamiento alta. es decir. Todos estos factores a˜aden una aleatoriedad que hace que sea dif´ o n ıcil demostrar que el sistema es viable. Este dise˜o de n compartici´n de tiempo gasta m´s tiempo del procesador en cambios de tarea innecesarios. o a Sin embargo. pero no se encontr´ o nada. Su algoritmo de programaci´n especializado. Esto se debe a que ning´n otro sistema operativo tiene u las facilidades que tiene Windows para el tipo de aplicaciones que se desea desarrollar y en caso de renunciar a estas facilidades para utilizar un sistema operativo gratuito utilizaremos Linux.

es decir el retardo entre el tiempo en que la tecla es oprimida y que el sonido se genera. Latencias de hasta 5 ms son consideradas buenas. raz´n por la cual no hay garant´ de o ıas que los retardos que se generan en un PC puedan ser mejorados. o a En caso de optar por esta opci´n deber´ o ıamos.4 4. En Internet hay muchas ıa a compilaciones de Linux para usar en sistemas embebidos. dado que Windows no es gratuito. es muy similar a ejecutar las aplicaciones en un PC. mientras que. Si nos concentr´ramos unicamente a ´ en la confiabilidad del sistema embebido.3 Utilizar un sistema embebido que tenga el sistema operativo Linux Uno de los problemas de la reproducci´n de instrumentos virtuales desde un PC es la o latencia de estos. o Hacer el sintetizador en un sistema operativo con sistema operativo “Windows”. interpretar los comandos de activaci´n y desactivaci´n de nota unicamente. Windows es el sistema ideal para la ejecuci´n de o o un VST Host. En caso de optar por esta opci´n se deber´ renunciar a la posibilidad de reproducir los VSTi. como reflejan los casos mencionados anteriormente. Todas estas capas se van a ver reflejadas en la latencia del 34 .1 An´lisis de las posibles formas de implementaci´n a o Utilizar un sistema embebido sin sistema operativo La idea original de los archivos DLL es que sean simples “cajas negras” hechas para ser interpretadas por Windows. o o 4. En el mercado de sistemas embebidos no pasa lo mismo. mientras que latencias de 20ms o m´s ya son altas. dado que la gran mayor´ est´n desarrollados para ser cargados con Linux. por lo menos en un principio. Linux nos da muchas m´s garant´ pero no en a ıas los puntos que nuestro sistema necesita. Otro problema en la interpretaci´n de n o los instrumentos VSTi es que aunque logremos convertir a otro formato los archivos DLL a´n as´ tendr´ u ı ıamos problemas para poder utilizar todas las otras bibliotecas de Windows que dichos archivos usan. por lo que cualquier software que encontremos o hagamos para interpretarlos probablemente tenga algunos errores por que los archivos DLL no est´n a dise˜ados para ser usados por ese tipo de software. y encima de a e este correr el VST Host. la cantidad de compilaciones es menor. MIDI y reproducci´n de archivos DLL. no consideramos que sea posible hacerlo sin el sistema operativo Windows o su emulador. 4.2 Utilizar un sistema embebido que tenga el sistema operativo Windows Como ya se mencion´ anteriormente. La interpretaci´n de instrumentos VSTi requiere la capacidad de interpretar archivos o DLL que. a En el caso de optar por Linux se deber´ cargarle tambi´n el Wine.

El sistema embebido con capacidad de cargar un sistema operativo ofrece la posibilidad de reproducir archivos DLL. Por a 35 . consideramos que la ejecuci´n del c´digo no ser´ tan eficiente. pero con una latencia a´n mayor que la hay cuando se ejecuta directamente en Windows. esto los convierte en sistemas m´s robustos que tienen menor posibilidad de a sufrir fallos.sistema. Por un lado se encuentra la posibilidad de desarrollar el dispositivo mediante un sistema embebido que soporte el procesamiento de archivos DLL. la implementaci´n mediante microa o controladores significar´ quiz´s la imposibilidad de una reproducci´n total de los archivos ıa a o VSTi y conformarnos con un sonido menos elaborado. o o a a teniendo en cuenta que los VST Host est´n pensados para ser ejecutados en una PC. esto significa una mejor calidad y una gama m´s variada de distintos VSTi. Para saber si el Wine es capaz de ejecutar host de Midi dise˜ados para Windows n y que se puede cargar instrumentos VSTi en formato DLL lo que hicimos fue instalar el Wine en un sistema con Linux y luego cargar en el Wine un host vsti de Windows. a La decisi´n por uno de ellos involucra la resignaci´n parcial de algunos de los objeo o tivos que fueron decididos al comienzo. decidimos no utilizar un sistema embebido con Linux. pr´cticamente no necesitan tiempo para inicializar el programa y son mucho a m´s compactos y baratos. Dado que si bien las soluciones que involucran un sistema operativo parecen m´s a sencillas. Estos son de una arquitectura m´s simple. antes de decidirnos por ella hay que determinar si a el Wine (emulador de Windows para Linux) es capaz de ejecutar correctamente host de midi dise˜ados para ser ejecutados en Windows y tambi´n es necesario idear una soluci´n n e o al problema de la latencia. y este es un punto clave tambi´n si se desea ofrecer un producto serio. ni siquiera de indicios o de que este problema pueda ser resuelto. para esto como se vio previamente se requerir´ de uno a suficientemente potente y complejo para que logre correr sobre el un sistema operativo. resultado de la “traducci´n” de o este tipo de archivo a un nuevo. u 4. quiz´s se logre mediante la instalaci´n de un nuevo hardware a o que elevar´ los costos del producto. El resultado fue positivo en el sentido de que fue posible reproducir sonidos generados por un piano MIDI y cargar instrumentos virtuales VSTi en formato DLL. La mayor e interrogante que encontramos es de si va a ser posible disminuir este tiempo de latencia. que pueda ser procesado por los controladores. Si bien la soluci´n con sistemas con Linux embebido con emulador de Windows o parece la m´s sencilla de implementar. Dado que el problema de la latencia es a´n m´s grave en Wine que directamente u a en Windows y que no disponemos de una soluci´n a ese problema.4 Conclusiones Se ha llegado a uno de los puntos cr´ ıticos del proyecto. como un sistema embebido no tiene las mismas capacidades que un PC. Esta argumento toma m´s valor. perdiendo la ventaja del precio que tiene esta opci´n a o frente a la de utilizar Windows. y suponiendo de que si. por el otro lado se encuentran los microcontroladores sin sistema operativo. no tienen los recursos necesarios para soportar un sistema a operativo.

La diferencia de precio se acent´a m´s teniendo en cuenta que la opci´n de utilizar un sistema embebido u a o con Linux esta descartada. decidimos desarrollar nuestro propio lenguaje de instrumentos virtuales. que si bien un sistema embebido puede tener ventajas contra un PC (ser m´s robusto.estas razones consideramos. Un sistema embebido con sistema operativo no es m´s barato que un PC econ´mico. Por estas razones se decidi´ renunciar a la interpretaci´n de instrumentos VSTi y o o desarrollar nuestro dispositivo sin sistema operativo. junto con un software que permita la conexi´n con el sintetio zador que realicemos y tambi´n la creaci´n de instrumentos. por lo que habr´ que utilizar Windows y pagar la licencia. a o que cumple ampliamente los requisitos de los programas Host de VST. ıa De esta forma queda eliminada tambi´n la opci´n de utilizar un sistema embebido con e o Windows. Una idea es dejar la puerta e o abierta. no consideramos que pueda mejorar el fundamental a problema del retardo. 36 . resistente). para que quiz´s en un futuro si se decide continuar con el proyecto se pueda crear a un software que permite la conversi´n del formato VSTi al formato que nosotros hayamos o creado. Respecto a los instrumentos virtuales.

Como se mencion´ o anteriormente. si no un instrumento en un formato determinado por nosotros. 37 . capaz de comunicarse con el sintetizador y con la capacidad de transmitirle nuevos instrumentos. resignamos la interpretaci´n de instrumentos VSTi. Se plantea como objetivo adicional hacer un software de PC.5 Replanteo del proyecto y de su implementaci´n o Una vez analizadas todas las opciones viables para la resoluci´n del objetivo. decidimos o hacer el sintetizador con sistemas embebidos sin sistema operativo. Dicho instrumento no es un instrumento VSTi. Dicho software tambi´n debe contar con una herramienta de f´cil manejo que permita al usuario generar e a instrumentos. De esta forma. Dicho sintetizador tambi´n debe contar con un juego de potenci´metros que sirvan e o para manejar efectos sonoros a los sonidos generados por el sintetizador. el o proyecto queda fijado como un sintetizador MIDI con la capacidad de interpretaci´n de o comandos MIDI de un unico instrumento y que cada nota tenga un sonido particular ´ determinado por un instrumento virtual.

esto se debe a que cada cuerpo sonoro vibra de una forma distinta.Envolvente Las caracter´ ısticas externas se combinan para formar la envolvente. para poder determinar la forma en la cual nuestro sistema embebido imitar´ instrumentos. Llamaremos envolvente a evoluci´n temporal en amplitud del sonido generado. Lo que tarda en llegar a su m´ximo volumen el sonido luego de haber sido ejecutado.1 Creaci´n de la nota musical o Introducci´n o Una vez que se renunci´ a la interpretaci´n de instrumentos VSTi. 6. es necesario desaro o rollar un nuevo protocolo para la imitaci´n de instrumentos musicales. Es la que permite distinguir entre la misma nota producida por dos instrumentos distintos. En esta secci´n o o buscamos imitar sonidos de distintos instrumentos. La altura y el timbre entrar´n en la primera categor´ y el resto en la segunda. Para simplificar a´n m´s podemos agrupar las cuatro propiedades anteriores en u a grupos de a dos. estos ser´n las caracter´ a ısticas internas y las externas. a ˆ Mantenimiento: Es el tiempo (o porcentaje del tiempo total) en el cual el sonido se mantiene en su m´ximo vol´men.6 6. a ıa Caracter´ ısticas externas . a u 6 Wikipedia en espa˜ol: Sonido n 38 . A lo largo de o u la historia el ser humano ha inventado una serie de reglas para ordenarlo hasta construir un tipo de lenguaje musical. Podemos diferenciar en un sonido cuatro propiedades b´sicas: a ˆ Altura — Frecuencia fundamental de onda ˆ Intensidad — Amplitud de onda ˆ Timbre — Frecuencias arm´nicas de la onda o ˆ Duraci´n — Tiempo de vibraci´n o o El timbre es lo que caracteriza a un instrumento. poder determinar las caracter´ a ısticas fundamentales del sonido de un instrumento y saber los par´metros a considerar en nuesa tro formato de instrumentos virtuales. la voz propia de este.2 6 Componentes de una nota musical El sonido. en combinaci´n con el silencio es la materia prima de la m´sica. Una envolvente por lo o general se descompone en los siguientes cinco par´metros: a ˆ Ataque: Es el tiempo (o porcentaje del tiempo total) de entrada.

la variaci´n de intensidad o o en las notas de un piano tambi´n difiere a las de un banjo e incluso a las notas del mismo e piano. luego de haber rasgueado la cuerda de guitarra esta continuar´ sonando cada vez con una intensidad menor hasta finalmente desaparecer. ˆ Sostenimiento: Luego del ataque y del decaimiento. pero identificar la ıdo frecuencia de la nota que se esta escuchando es algo que incluso a los o´ ıdos entrenados les puede resultar una tarea complicada. La a envolvente no s´lo se diferencia entre familias de instrumentos. a Caracter´ ısticas internas . la nota “La” central del piano posee una frecuencia fundamental de 440 Hz. En los instrumentos de cuerdas u se obtiene un resultado distinto. marcando la intensidad del sonido con la fuerza del soplido. al u detenerse el sonido se apaga s´bitamente por completo. n ˆ Relajaci´n: El tiempo (o porcentaje del tiempo total) que tarda el sonido en perder o toda su amplitud. A continuaci´n o o o se enumeran las formas en las cuales se busc´ imitar sonidos de instrumentos. El intervalo que separa dos sonidos cuyas frecuencias fundamentales tienen una relaci´n de dos a uno se le llama “octava”. Es la frecuencia fundamental la que determina que nota estamos escuchando. tambi´n o e se usa el t´rmino para referirse al rango de frecuencias entre dos notas separadas por una e relaci´n de dos a uno7 . la se˜al se mantiene en un n nivel de sostenimiento. una nota grave tendr´ un envolvente distinta a una aguda. podemos denominar a una nota musical como un sonido cuya frecuencia fundamental es constante. Habiendo definido el sonido. la envolvente es controlada por el m´sico. detectar la a a intensidad del sonido no es algo que a nuestro o´ le cueste hacer. o Fueron tanto las caracter´ ısticas internas como externas las que se intentaron modelar en el entorno del Scilab para luego hallar la manera de trasladar este algoritmo de generaci´n de notas a un c´digo que el microcontrolador pueda entender.Descomposici´n en frecuencias o Las caracter´ ısticas externas son m´s f´ciles e intuitivas de reconocer.ˆ Decaimiento: Es el tiempo (o porcentaje del tiempo total) en que tarda la amplitud en reducirse a la de sostenimiento. el “La” anterior a este su frecuencia vale la mitad. 220 Hz. En el caso de los instrumentos de viento. o 7 Wikipedia: Octava 39 . Una nota musical tocada por cualquier instrumento se compone de varias ondas sinusoidales una de las cuales (la m´s predominante) a tiene la frecuencia fundamental y el resto de las ondas son las frecuencias arm´nicas de o esta. dicho nivel se expresa como porcentaje del m´ximo vol´men a u que adquiere la se˜al. como por ejemplo la trompeta. Para lograr este objetivo se utilizar´ la transformada a de Fourier.

Para comenzar se necesitaba hallar las frecuencias de las ondas que est´bamos escuchando.3 Sinusoidales puras Se tom´ un sonido generado por el rasgueo de una unica cuerda de guitarra y se propuso o ´ analizarlo con el fin de lograr generar uno similar. pero si nos acercamos un poco m´s al eje de las equis ´ a notaremos como nuestra nota de guitarra es bastante m´s compleja. a a o a Se obtuvo la figura de la gr´fica de la imagen 5. En la imagen 6. m´s adelante se explica esta funci´n con m´s detalle. para esto se utiliz´ la funci´n a o o de Scilab “FourieFacilDetectaPicos”. 40 . estando compuesta a por una gama m´s amplia de frecuencias. este est´ indicando el valor de la frecuencia fundamental de la nota que en este caso es de a aproximadamente 110 Hz que corresponde a la nota ’La’ en la escala musical. a Imagen 5: Gr´fica de la transformada de Fourier del sonido de una guitarra a Se observan seis claros picos de los cuales el primero es de mayor magnitud. Esta escala nos hace suponer que nuestro sonido esta compuesto de al parecer de unicamente sinusoidales perfectas. lo que hace esta funci´n es calcular Transformada o R´pida de Fourier (FFT) y graficarla.6. se observa la gr´fica haciendo a a zoom en el eje de las equis.

Otra observaci´n es que contrario a la intuici´n. los arm´nicos de mayor frecuencia o o o y m´s alejados de la frecuencia fundamental no tienen necesariamente menor magnitud a que los arm´nicos m´s cercanos. transformada r´pida de Fourier) se le asigna el n´mero 0. La tabla 3 muestra en su segunda columna las frecuencias en las que se encuentran los “picos” m´s relevantes del sonido a imitar. para el caso de n=10 dicho espectro se muestra en la imagen 7.5.Imagen 6: Gr´fica de la transformada de Fourier del sonido de una guitarra a Aqu´ se observan adem´s de los picos vistos en la previa gr´fica ciertas “irreguları a a idades” en la base de estos. por ejemplo. Como primera prueba se simular´ el sonido mediante la sumatoria de ondas sia nusoidales de las mismas frecuencias que las principales del sonido que se desea imitar y multiplicando por un par´metro cada sinusoidal tal que las frecuencias que son m´s a a influyentes en el sonido original tambi´n lo sean en la imitaci´n. 41 . En la tercer columna muestra la magnitud a de su influencia normalizada. en la gr´fica se observa como. luego se ir´ ´ o a aumentando con el objetivo de hallar cuantos arm´nicos son necesarios para poder reo construir fielmente el sonido original. otra frecuencia tiene la mitad de la altura de la fundamental en su FFT (fast Fourier transform. Estas anomal´ son generadas por el instrumento musical ıas y son otro par´metro que nos permite diferenciar entre cierta nota en una guitarra y la a misma nota en un piano. el sexto pico o a a es de mayor magnitud que el quinto e incluso que el cuarto. por ejemplo. a u El procedimiento de generaci´n del sonido consiste en generar un sonido en Scilab o que sea la suma de ’n’ funciones sinusoidales cada una con una de las ’n’ frecuencias que se desea representar multiplicada por la magnitud que su frecuencia tiene asociada. Para corroborar que nuestro nuevo sonido posee las mismas frecuencias arm´nicas o que el sonido original con sus respectivas magnitudes se calcula el espectro de Fourier de este. es decir que le asigna el valor 1 a la frecuencia fundamental y si. e o Para comenzar se tomaran unicamente los primeros cinco arm´nicos.

Arm´nico o 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Frecuencia 109 218 327 436 545 654 763 872 981 1090 1199 1308 1417 1526 Magnitud (Normalizada) 1 0. como se puede observar en la im´gen 7.0015 0. Tambi´n se prob´ incrementar el n´mero de arm´nicos a incluir en la generaci´n e o u o o del sonido. Para generar las imitaciones se utiliz´ la aplicaci´n de Scilab o o “sinusoidalesPuras”. Esta forma de imitar sonidos no s´lo no genera buenas o imitaciones.020 0.075 0.053 0. se lleg´ a incluir hasta 100 arm´nicos.0006 0.084 0.22 0.010 Tabla 3: Tabla de arm´nicos o Imagen 7: Gr´fica de la transformada de Fourier del sonido generado a Si bien.12 0.0043 0. el sonido que se gener´ no es similar o n o al que se desea imitar. la se˜al generada tiene una descoma n posici´n en frecuencias similar a la se˜al original. si no que tambi´n las se˜ales que genera son se˜ales peri´dicas.011 0.0040 0. y a´n as´ el sonido no lleg´ a ser una o o u ı o buena copia del sonido original. estas se˜ales e n n o n pueden ser en su principio similares a las que se desea imitar pero la periodicidad no les 42 . Algunos resultados se encuentran en el cd adjunto.34 0.

se modelo la envolvente con seis distintas rectas.40 0. El ataque es representado por la recta OA. a Imagen 8: Gr´fica de la amplitud de un sonido de guitarra a Para evitar grandes aproximaciones.21 0. y por ultimo las dos rectas DE y EF representar´n la ´ a relajaci´n. El Decaimiento por la AB.41 0.062 0.63 4. El Sostenimiento por las rectas CD y DE.45 0. n 6.4 Envolvente Global Luego de haber obtenido la composici´n interna de la nota.27 0 Tiempo (s) 0. o Punto A B C D E F Magnitud (normalizada) 1 0.50 0.49 0.9 Tabla 4: Tabla de Puntos 43 .permite ‘apagarse’ como hacen las se˜ales que deseamos imitar. En la imagen 8 se muestra la gr´fica de la amplitud del sonido original junto con a las l´ ıneas que luego se modelar´n para hallar la envolvente. se procedi´ a agregarle una o o envolvente global en la cu´l la variaci´n de intensidad sea para todas las frecuencias la a o misma.

04 ∗ (x − 0. 21)/(0. 63)/(4. 45 − 0.5 6. 40)/(0. pero todav´ no es suficientemente parecido. 51 ∗ (x − 0. para peque˜os pedazos. Recta Ecuaci´n o OA y = x/0. 21) CD y = 0. 63 − 0. 9 − 0. 50)/(0. 41 + 0. 062 AB y = 1 − 0. 08 ∗ (x − 0.Imagen 9: Gr´fica de la envolvente generada a A continuaci´n se hallar´ la ecuaci´n que representa a cada una de las rectas para o a o poder determinar el valor por el cu´l se debe multiplicar a nuestro sonido creado antea riormente que estaba basado unicamente en las frecuencias arm´nicas. M´s adelante se nos mencion´ que este procedimiento se utiliza de forma regular a o para determinar los cambios de frecuencia que tiene una se˜al a lo largo del tiempo y se n 44 . 062)/(0. de esta o n forma se puede observar como es que var´ las magnitudes de las frecuencias a lo largo del ıan tiempo. 6.5. 50 − 0. 49 − 0. 63) Tabla 5: Tabla de Puntos Para generar automaticamente las imitaciones se utiliz´ la aplicaci´n de Scilab “eno o volventeComun”. 40) DE y = 0. 062) BC y = 0. la variaci´n en la amplitud no fue suficiente para o o darle el realismo que se necesita. La nota generada. 27 ∗ (x − 0. Dichas ecuaciones ´ o se encuentran en la tabla 5. 50) EF y = 0. 21 − 0. 27 − 0. El sonido obtenido anteriormente si se asemeja bastante a una cuerda de guitarra. suena de forma mon´tona. Algunas imitaciones realizadas se encuentran en el cd adjunto. a pesar de tener una ıa envolvente.1 Envolvente particular a cada frecuencia Introducci´n o Al obtener este no tan satisfactorio resultado se decidi´ probar realizar la transformada o de Fourier en lugar de para toda la duraci´n de la nota. 18 ∗ (x − 0. 40 − 0.

pero o a luego es sustituida por la fundamental que es la que se mantendr´ con mayor magnitud a a lo largo del tiempo restante. En la imagen11 se a muestra la evoluci´n de la influencia de cada una de las frecuencias a lo largo del tiempo. o ıa Con esta informaci´n podemos concluir que para lograr obtener una nota musical o convincente. En la imagen 10 se observa las gr´ficas a de las transformadas para ’n’=10 del sonido de guitarra que se desea imitar. El significado de la magnitud del eje de las ı ’Y’ no es importante. que presente las mismas caracter´ ısticas que una nota real. Imagen 10: Gr´fica de una transformada de Fourier del sonido de una guitarra. Despu´s hay que generar una envolvente para cada una de las frecuencias m´s ine a fluyentes. Se puede ı observar como la frecuencia del segundo arm´nico la m´s predominante al principio. 45 . la 2 con el segundo y as´ sucesivamente. lo importante es saber que es la misma magnitud para todas las gr´ficas de la imagen. dia vidi´ndolo en 10 partes e 6. e a en este caso son las mencionadas en la tabla 3. en la gr´fica 2 la evoluci´n a o a o de la frecuencia 218Hz. Luego hay que dividir el sonido en ’n’ partes iguales y luego analizar la transformada de Fourier de cada uno de esos ’n’ sonidos. El eje de las ’X’ es el tiempo expresado en segundos.5. e Dividimos el sonido que deseamos imitar en ’n’ partes y luego analizamos la transformada de Fourier en cada una de esas partes.lo denomina la Transformada de Fourier de Tiempo Reducido o STFT por sus siglas en ingl´s “Short Time Fourier Transform”. o En la gr´fica 1 se muestra la evoluci´n de la frecuencia 109 Hz. por lo que si una llega a el valor ’100’ y la otra al ’200’ la segunda a vale el doble en ese instante. La gr´fica a 1 corresponde con el primer intervalo. adem´s de tener a una cantidad significativa de arm´nicos se deber´ generar para cada uno de ellos una o a envolvente particular.2 Explicaci´n del m´todo para obtener la nota o e El primer paso del m´todo es seleccionar las ’m’ frecuencias m´s influyentes en el sonido. y as´ sucesivamente. Dichas envolventes son aproximaciones con rectas de la evoluci´n de la influeno cia de cada una de las frecuencias m´s influyentes a lo largo del tiempo. Con el m´todo anterior no nos era posible representar la e situaci´n en la cual la influencia de cada frecuencia de la nota var´ en el tiempo.

El resultado de este tipo de imitaci´n fue considerando satisfactorio y ser´ ´ste el o ae que va a ser utilizado en nuestro dispositivo. Imagen 11: Gr´fica de las envolventes para las frecuencias m´s influyentes a a 6. y o a luego el procesador se encargar´ de irle solicitando los valores a una memoria externa ıa para luego a trav´s de un conversor digital anal´gico (DAC) lograr obtener la salida de e o audio. mientras que el caso ıa anterior es necesaria una capacidad de procesamiento importante para lograr obtener el resultado de sumar el valor de todos los arm´nicos multiplicados por su envolvente o correspondiente en un per´ ıodo de tiempo menor al de muestreo de la salida. Con este sistema se le exigir´ mucho menos al procesador. a sumar todas las sinusoides y normalizar el sonido resultante. El piano MIDI actuar´ ıa enviando la informaci´n a un procesador de cual nota es la que se est´ solicitando. multiplicarla por la envolvente que le corresponde. Si se utiliza 46 .6 Utilizaci´n de Samples o Como otra opci´n se manejo tambi´n la posibilidad de utilizar una memoria en d´nde se o e o encuentren grabados todos los sonidos de las notas musicales.Finalmente para generar el sonido hay que generar con cada una de las frecuencias m´s influyentes una onda sinusoidal.

Una de las a o razones de esta decisi´n es que el m´todo de multiplicar cada arm´nico por su envolvente o e o permite una mayor flexibilidad al momento de manipular el sonido. u Un objetivo del producto es tambi´n lograr que cada consumidor pueda dise˜ar e n sus propios instrumentos. o 47 . o A pesar de las ventajas que indudablemente tiene este nuevo enfoque.el sistema de los samples la tarea del procesador se limitar´ a solicitar la posici´n de ıa o memoria en la que se encuentra el pr´ximo valor del sample. Este m´todo permitir´ dise˜ar los sonidos de instrumentos que unicamente e ıa n ´ se han escuchado algunas notas e incluso de algunos inexistentes. variando sus arm´nicos y algunas de sus envolventes. n Estos tres son claros ejemplos de sonidos que no podr´n ser sintetizados por nuestro a dispositivo debido a que al realizar el estudio de Fourier se observa que no es posible descomponerlos en algunas pocas frecuencias. ya se mencion´ previamente que estos pueden variar enormemente habiendo algunos o dise˜ados para sonar como tambores. La idea original de reproducir los VSTi permite reproducir casi cualquier sonido. siendo la reproducci´n el resultado o directo de la grabaci´n original. optamos por imitar las notas musicales asign´ndole a cada arm´nico una envolvente. ruidos de animales e incluso voces humanas. Se considera implementar. esto o ser´ imposible en caso de que se utilizar´n los samples. Para confirmar que la metodolog´ mediante la cual se intentar´ recrear los instruıa ıa mentos musicales cubrir´ una mayor´ de estos. esto requiere de avanzada o tecnolog´ para suprimir todo ruido que pueda llegar a aparecer adem´s de micr´fonos de ıa a o alta calidad colocados en habitaciones con buena ac´stica sonora. La personalizaci´n que se le puede realizar a un sample ya o grabado es mucho menor y m´s complicada de realizar que la personalizaci´n que se le a o puede realizar a un sonido obtenido con el sistema de la multiplicaci´n de sinusoidales por o envolventes. para que el sistema de los samples tenga una fidelidad muy alta es necesario realizar una buena grabaci´n de una nota de un instrumento musical real. se procedi´ a seleccionar una variedad de a ıa o instrumentos pertenecientes a las familias de viento y cuerda con el objetivo de investigar su descomposici´n en frecuencias. Esto significa que o una vez que ya se ha cargado el programa con el instrumento virtual.7 Limitaciones Al descartar los samples como m´todo para la recreaci´n de las notas se tom´ una decisi´n e o o o importante que gener´ una p´rdida de funcionalidad con respecto a los objetivos originales o e planteados. o por lo menos dejar la ventana abierta para que en un futuro se pueda implementar. se pueda editar cierta nota espec´ ıfica en el momento. Por otro lado. Este sistema tambi´n o e permite obtener una completa fidelidad de sonido. la opci´n de editar las notas “en vivo”. ıa a 6.

por otro lado en el caso del viol´ se nota claramente y en el del oboe tambi´n ın e pero no de forma tan acentuada que se ha formado una base de frecuencias alrededor de las frecuencias arm´nicas. y ser´ la importancia que tengan estas frecuencias circundantes las que determinar´n lo fiel a a que ser´ la imitaci´n realizada por el sintetizador. a o 48 . en primer lugar que al tener menos arm´nicos y o picos m´s pronunciados los instrumentos de viento son m´s f´ciles de imitar que los de a a a cuerda. Estos sonidos son m´s dif´ o a ıciles de imitar en nuestro sistema.Imagen 12: Descomposici´n en frecuencias de sonidos imposibles de sintetizar o Imagen 13: Descomposici´n en frecuencias de instrumentos de viento y cuerda o En la imagen 13 se observa que.

7 Detecci´n de comandos MIDI o Una vez determinada la forma en la cual los sonidos van a ser reproducidos. el paso siguiente antes de comenzar la selecci´n del microcontrolador a utilizar es investigar como o vamos a poder interpretar las se˜ales MIDI. El circuito utilizado es el indicado en la hoja de datos del MAX232 como circuito recomendado de uso. Ahora sabemos que el unico requisito que debe tener nuestro microcontrolador para ´ poder interpretar comandos MIDI es la capacidad de comunicarse v´ RS232 a una veıa locidad de 31250 bits/seg. para la mayor´ de los microcontroladores ıa es una velocidad accesible. si es necesario un microcontrolador con alguna capacidad especial o si es necesario utilizar alg´n tipo de adaptador u o de circuito adicional. 49 . Como se mencion´ anteriormente. Sabemos que esa velocidad. Por esta raz´n para comunicar un mio o crocontrolador con un instrumento MIDI solo es necesario un MAX232 al igual que para comunicarlo con un PC. Es necesario saber si vamos a poder intern pretar los comandos MIDI con cualquier microcontrolador. el puerto MIDI transmite sus datos en serie a o una velocidad de 31250 bits/seg y su protocolo para la transmisi´n de datos es igual o al protocolo de transmisi´n por el puerto serie. si bien puede ser problema para transmitir datos para algunas computadoras.

decidimos realizar un sistema similar al pedido pero mucho m´s reducido a con el objetivo de encontrar los posibles problemas y facilidades que tiene implementar el sistema requerido de esta forma.hex’ son los que contienen los programas compilados listos para ser transmitidos al Pic. adem´s es f´cil de armar circuitos b´sicos con este y de armarle programadores. 16C71X. 16C8X. dicho circuito se muestra en la imagen 14. junto o con dos arm´nicos en un pic16f628a. 16F6X. Como herramienta de simulaci´n de los c´digos escritos utilizamos el PICSIMULATOR. Para que el Pic pueda conectarse con el PC para poder recibir su programaci´n o utilizamos el circuito JDM programer. Imagen 14: Circuito JDM Para transmitir los archivos ’. 12C67X. 16C62X. Transforma los c´digos o o escritos en lenguaje ’C’ al lenguaje assembler del pic y crea un archivo ’.1 Prueba previa Objetivo de la prueba Para determinar si la implementaci´n del sistema con sistemas embebidos sin sistema opeo rativo es viable. 24CXX. 16F8X con un PC a trav´s del puerto e serie. a a a Los c´digos de programaci´n para el PIC fueron escritos con el programa ’MikroC’. si no que simplemente era realizar unas pruebas preliminares.hex ’ generados al Pic utilizamos el programa ICPROG. 16C55X. o Dado que el objetivo de la prueba no era realizar el sistema final. o o El objetivo de esta prueba fue dise˜ar un sistema con la capacidad de interpretar n comandos MIDI de activaci´n y desactivaci´n de notas. Los archivos ’.hex’. junto con la intensidad con la que o o 50 . o o Este programa permite escribir c´digos en lenguaje ’C’ para el PIC. La prueba consisti´ en implementar un sistema que o interprete comandos MIDI y que pueda reproducir una funci´n sinusoidal principal. 16C71. Sirve para poder comunicar cualquier pic de las l´ ıneas 12C5XX. 16C61.8 8. decidimos trabajar con el pic16f628a por que si bien es un PIC muy limitado es un PIC con el cual tenemos experiencia de trabajo.

Es necesario que la salida actualice su valor cada un tiempo constante. el cual sirve para indicar la magnitud de los arm´nicos de las notas. o El c´digo de esta prueba esta en el anexo F. ıa nota indicar´ el n´mero de nota que fue activada (la frecuencia) y velocidad guardar´ la a u a informaci´n de cual fue la intensidad con la que se presion´. Los valores de los o elementos de dicho array son fijados en el momento de programaci´n. que cuente el tiempo que debe transcurrir entre que el sistema genera una salida y genera la siguiente. los puertos de salida y los timers. previamente o configurado. en la cual configura el puerto serie. 8. la soluci´n fue iniciar un timer. y el valor o de pico del segundo arm´nico como picoPrimerArmonico * velocidadArmonicos[1] / 255. lo que es muy util al momento de e ´ depurar. ya que esto nos permite mandar los comandos que espec´ ıficamente queremos y tambi´n nos permite recibir comandos desde el PIC. o En el c´digo se puede observar como el programa primero ejecuta una configuraci´n o o inicial. decidimos que el sistema reproduzca s´lo una nota a la vez. El programa tambi´n cuenta o o e con un array de variables del tipo short int llamado velocidadArmonicos de dos posiciones.2 Construcci´n del c´digo para la prueba o o El sistema tiene una variable llamada nota y otra llamada velocidad que representar´n los a dos datos que el protocolo MIDI env´ cada vez que detecta que se ha activado una nota. La forma de actualizarse en caso de un cambio de nota es interruptiva. Luego ingresa a un loop que es el encargado de traducir los comandos MIDI a salidas del puerto B. no ser´ correcto actualizar el valor de una salida cuando ıa reci´n es calculado. se calcula la siguiente salida y cuando el timer llega a su valor de cuenta se actualiza la salida.las notas son tocadas. se interpreta y se actualizan los valores de nota y o de velocidad. o 8. 51 . Cada nota ser´ reproducida como una sinuidal de su frecuencia a principal m´s un arm´nico con el doble de esta frecuencia y otro con el triple.3 Origen de los datos Dado que los comandos MIDI tienen una forma de transmisi´n muy similar a la utilizada o por el puerto serie del PC. al tener un PIC tan limitado junto con una frecuencia de funcionamiento tan lenta. para realizar esta prueba enviamos los comandos MIDI desde un PC. Una vez inicializado el timer. se reinicia el timer y se comienza a calcular la salida siguiente. por ejemplo a una frecuencia de 44100 Hz. a o Para hacer m´s sencilla la prueba decidimos que el PIC trabaje con su oscilador a interno de 4Mhz. por que esto provocar´ que la frecuencia de muestreo de la salida e ıa no sea constante. Para resolver ese asunto. El valor de pico o del primer arm´nico se calcula como velocidad * velocidadArmonicos[0] /255. cada vez que se recibe por el puerto serie un comando MIDI se almacena y cuando se recibieron suficientes como para completar una instrucci´n MIDI.

decidimos que la salida de audio tenga 8 bits de resoluci´n. al m´ximo de la salida de audio el valor 255 y 0 volts en n a la se˜al de audio al valor 128 del PIC.3. decidimos asociarle al m´ a e ınimo voltaje de la se˜al de audio el valor 0. lo que necesitamos es una combinaci´n o o entre un conversor y un restador. El voltaje ‘V0’ corresponde al bit menos significativo del puerto B. Un conversor digital a anal´gico simple asocia el valor digital 0 con 0v. como el caso de la transmisi´n de voz. a decidimos utilizar una escala lineal.1 Generaci´n de sonidos o Uno de los objetivos de la prueba fue probar la velocidad con la cual el PIC realiza las cuentas y probar distintas formas de hacerlas. Se precisa un circuito que o o asocie una salida digital de 0 con el valor -9v y el valor de 255 con 9v. En la imagen 15 se muestra el circuito del conversor. o Para distribuir estos 256 posibles valores de salidas entre el voltaje m´ ınimo y m´ximo. 8. el voltaje ‘V1’ al segundo menos significativo y as´ ı sucesivamente. es decir que el voltaje m´ximo es lo m´s parecido posible al valor absoluto del e a a m´ ınimo voltaje. Dado que el PIC seleccionado maneja registros de 8 bits. o Para que la salida sea lo m´s sim´trica posible. 52 .8. el circuito por debajo de esta zona es el que se encarga de que el conversor este combinado con un restador. Otros tipos de escala como la logar´ u ıtmica son recomendados para sistemas en los cuales la mayor´ del tiempo la se˜al toma valores lejanos de los m´ximos ıa n a posibles.4 Conversor digital a anal´gico o El circuito necesario para transformar la se˜al generada por el Pic en una se˜al de audio n n anal´gica no es exactamente un conversor digital a anal´gico. La zona del circuito enmarcada en rojo es un conversor digital a anal´gico o simple. De esta forma el rango de salidas posible es casi n sim´trico. Esto se debe a que facilita la conversi´n de digital o a anal´gico y por que es el sistema utilizado por la mayor´ de los sistemas de audio o ıa orientados a la m´sica.

Este fue uno de los intentos realizados. Aproximamos los resultados de las funciones u seno y coseno como el entero que m´s se parezca a el verdadero valor del seno o el coseno a multiplicado por 127. al PIC le toma demasiado tiempo hacer cuentas con variables del tipo o double dado que estas son muy precisas. 53 . Luego repetir el procedimiento para los arm´nicos y normalizar la salida. mucho m´s de lo necesario teniendo en cuenta a que nuestra salida solo tiene 256 posibles valores. el siguiente paso es calcular como llegar a las salidas deseadas.5 8. Las funciones coseno y seno que tiene implementado el microC tienen una precisi´n o muy grande.Imagen 15: Circuito del conversor digital a anal´gico o 8. esta precisi´n tiene como consecuencia o que el c´lculo de estos n´meros tome m´s tiempo del que tomar´ si lo calcul´ramos con a u a ıa a una precisi´n menor. o Como consecuencia decidimos que el resultado de las funciones trigonom´tricas sea e expresado como short int.1 An´lisis de la prueba a Operaciones trigonom´tricas e Una vez asociados los voltajes de salida del PIC con los voltajes de la salida de audio.5. dado que devuelven un punto flotante. es decir asociar a cada valor de las funciones trigonom´tricas e un n´mero entero entre el -127 y el 127. La soluci´n m´s sencilla es multiplicar la intensidad con la que una nota fue oprimida o a por una variable del tipo double que valga entre -1 y 1 correspondiente al coseno de (2 ∗ π ∗ f ∗ t) . si bien o el intento funcion´. siendo f la frecuencia asociada a la nota pedida.

El gran tiempo tomado se debe en parte a que o o este no es un dise˜o de PIC optimizado para este tipo de operaciones. por esa raz´n los o errores cometidos al aproximar resultados de multiplicaciones y sumas (para no tener que trabajar con variables del tipo double) ser´ acumulativo. esta o ecuaci´n tiene como soluciones en r´gimen cosenos y senos de per´ o e ıodo 4 ∗ φ ∗ T . este es el m´todo que calcula senos o e e y cosenos en menor cantidad de tiempo. La soluci´n que encontramos fue cargar en la memoria de o programaci´n del PIC un array con 256 valores del per´ o ıodo de un coseno. Esta soluci´n al igual que las mencionadas o anteriormente funciona. a En todos los m´todos anteriores no s´lo se gasta tiempo calculando los senos y e o cosenos. siendo T el per´ ıodo de actualizaci´n de los datos en la ecuaci´n en diferencias. Este m´todo requiere el c´lculo de un coseno e a (cos(φ)) que hay que realizarlo de otra forma. etc). El primer valor del array corresponde a 128*coseno(0). sino del entero que mejor aproxime a el verdadero valor a del coseno por 128. se calcula el coseno de una variable t que aumenta a una raz´n que depende de la nota que se desea reproducir.Otra alternativa a las funciones seno y coseno que dispone el MikroC son las funciones sen1000 y cos1000. A continuaci´n se enuncian formas a´n m´s r´pidas. Por esta raz´n. que para el dise˜o final. lo n´meros no u ser´n variables del tipo ‘double’. o 8. Similarmente que con las operaciones trigonom´tricas.5. por lo cual para variarlo debemos hacer una multiplicaci´n. Una desventaja de este m´todo es que e el resultado de y(n) depende de los valores calculados anteriormente. en este caso o el valor pico lo determinamos variando y(0) e y(1) sin necesidad de hacer multiplicaciones extra. Este m´todo tiene la ventaja de que los cosenos no hay que calcularlos e sino que hay que obtenerlos de una tabla y que en vez de realizar multiplicaciones para saber de que valor se busca el coseno. si no que tambi´n se gasta tiempo haciendo multiplicaciones y divisiones para e saber de que valor se precisa el seno y el coseno (por que por lo general se desea saber cos(wt) o cos(wt/Fs). uno de los requisitos n del microcontrolador es tener la capacidad de resolver multiplicaciones y divisiones en menos tiempo. Como realizar divisiones toma m´s tiempo que realizar multiplicaciones y las multia plicaciones m´s r´pidas son las de variables del tipo short int e int.2 Multiplicaciones y divisiones Otra de las operaciones que notamos consum´ gran cantidad de ciclos de reloj son las ıa operaciones de multiplicaci´n y divisi´n. el tercero a 128*coseno(4π/256) y as´ sucesivamente hasta llegar a ı 128*(510π/256). Estas soluciones contemplan el problema del largo tiempo que toman las funciones seno y coseno antes mencionado. Dado que esta operaci´n tiene menos precisi´n es mucho m´s r´pida que calcular o o a a senos o cosenos directamente. de los m´todos mencionados. o u a a La tercer alternativa pensada para poder calcular senos y cosenos r´pidamente fue a utilizar la siguiente ecuaci´n en diferencias: y(n) = 2 ∗ cos(φ) ∗ y(n − 1) − y(n − 2). decidimos transformar a a 54 . La amplitud o o puede ser modificada al variar y(0) e y(1). justamente. La salida de las funciones sen1000 y cos1000 son el n´mero entero m´s parecido a 1000 multiplicado por el seno o coseno u a deseado. En los casos anteriores el valor pico de las funciones seno y coseno esta determinado. Una de las conn clusiones de esta prueba es. para realizar mule tiplicaciones y divisiones en tiempos aceptables es necesario que estas no sean de variables double o long sino de la menor cantidad de bits posibles. el segundo a 128*coseno(2π/256).

para as´ poder trabajar a menos o ı frecuencia realizando la misma cantidad de operaciones por segundo. y las conclusiones de la prueba se pueden obtener sin tener el sonido de la salida refinado al cien por ciento. la m´xima frecuencia con la cual se pueden obtener un valor digital pronto a para ser colocado en el puerto B del PIC es de 1. los sonidos generados tienen mucha menos complejidad que la que esperamos que tenga los sonidos del dispositivo final. el PIC no llegar´ a realizar las cuentas necesarias.5. esto nos permitir´ generar sonidos de ıa hasta 2750 Hz. Dado o o o que esto es solo una prueba inicial no se consider´ necesario dado que de todas formas o se logra escuchar la salida del PIC. en la explicaci´n del teorema de Nyquist-Shannon.5.4 Funcionamiento de la prueba Dado la frecuencia de funcionamiento. Este “truco” es preciso unicamente cuando 256 es m´ltiplo del divisor. 8. Si una variable de dos bytes se la divide por 256. podemos multiplicar a esta variable por 64 y tomar el byte m´s significativo (64 es el resultado de dividir 256 a por cuatro). a Si se quisiera aumentar la frecuencia de salida. En caso de usar microcontroladores similares ser´ necesario una frecuencia de trabajo de 160 Mhz aproximadamente para ıa obtener una frecuencia de salida suficientemente alta como para poder generar salidas en todo el espectro de frecuencias audibles por el ser humano. la raz´n de esto se detalla en la o o o secci´n de fundamentos te´ricos. Es necesario pasar a una gama de microprocesadores que le tome menos ciclos de reloj realizar cada instrucci´n. 8. ´ u 8. nos quedar´ como resultado el byte m´s significativo.todas las divisiones en multiplicaciones de esas variables. y el tiempo que le toma al microcontrolador realizar las operaciones. ıan porque las se˜ales generadas constar´ s´lo de 2 arm´nicos. por lo tanto si a a queremos dividir una variable cuyo valor entra en un byte por cuatro. No existen microcontroladores de la gama del usado que soporten trabajar a 160 Mhz. y aunque existiesen no ser´ suficientes para reproducir el sonido que esperamos. entregando el mismo a valor que en el caso anterior. a´n as´ notamos que al tipo de microcontrolador utilizado le falta capacidad de u ı procesamiento para manejar las salidas deseadas. una de las formas posibles ser´ ıa conectarle al PIC un cristal externo de 20 Mhz.5.5 Conclusiones de la prueba Al ser el sistema de la prueba un sistema muy sencillo.1 Khz. Con esta frecuencia de salida de acuerdo al teorema de Nyquist-Shannon que se ve en el anexo A se podr´n generar sonidos de hasta 550 Hz. Si se fuerza una frecuencia de salida mayor. Como se mencion´ anteriormente el objetivo de esta prueba no es generar o un sistema util sino probar las capacidades que tiene un PIC de generar sonidos.3 Observaci´n o Para el correcto funcionamiento del sistema de prueba se deber´ haberle agregado un ıa filtro anal´gico a la salida del conversor anal´gico digital. Por esto es necesario cambiar n ıan o o la familia del microprocesador. el objetivo idea ser´ ıa 55 . raz´n ´ o por la cual no consideramos necesario conectar el cristal.

luego calcula otra. la mantiene constante por un tiempo. Por o e esta raz´n consideramos que un microcontrolador solo va a poder reproducir una nota o simult´neamente. no con pulsos rectangulares. que se considera una calidad alta en la grabaci´n de sonido. por eso consideramos que es importante trabajar con un microcontrolador con la capacidad de generar salidas como impulsos. Va a ser necesario combinar varios microcontroladores para generar a sonidos polif´nicos. que es un recurso limitado. la complejidad de la generaci´n de los sonidos tambi´n va a ser mayor. la mantiene constante por un tiempo y as´ sucesivamente. o 56 . esto implica registros e o de m´s de 8 bits. ı Como se enuncia en el teorema de Nyquist-Shannon. Si bien se puede generar se˜ales muy similares al impulso con cualquier microcontrolador. o Tambi´n estamos buscando una mayor resoluci´n en el sonido. para poder transformar una se˜al n digital en anal´gica. Si bien para el sistema final se va a disponer de sistemas con capacidad mucho mayor.alcanzar una frecuencia de salida de datos de 44100 Hz. Como se mencion´ anteriormente. n si este no tiene la capacidad de generarlas por hardware es necesario un gasto extra de tiempo de procesamiento. la forma ideal es que la se˜al de salida se trasmita con impulsos o n (deltas de Dyrac). a En nuestra prueba el microcontrolador calcula una salida. otra caracter´ o ıstica fundamental que debe tener el microcontrolador es la capacidad de realizar multiplicaciones y divisiones en menos ciclos de reloj que el usado para la prueba previa.

9 9. En este caso la l´ ınea DSPic tambi´n tiene ventajas dado que el programador e 57 . decidimos seleccionar el DSP a utilizar. Que tenga la capacidad de realizar multiplicaciones en un solo siclo de reloj.2. producida por la compa˜´ Microchip. nıa a continuaci´n se enumeran algunas de las razones por las que tomamos esa decisi´n. Que tenga la capacidad de trabajar con 16 bits. si existe alg´n compilador ‘C’ o similar o si es necesario codificar en u assembler.2 Selecci´n del fabricante del DSP o Existen muchos microcontroladores DSP y muchas marcas. no solo por comparaci´n de las caracter´ o ısticas mencionadas en las hojas de datos si no que tambi´n decidimos ponderar otras caracter´ e ısticas. (e). Estas caracter´ ısticas nos llevaron a elegir la l´ ınea de DSP llamada DSPic. o Cuando se elige un microprocesador tambi´n hay que tener en cuenta el software e para programarlo. (b). tambi´n es e necesario tener un hardware y un software para programarlo. (c). decidimos a utilizarlos. dichos procesadores se llaman DSP (digital signal processor). Que pueda hacer operaciones en pocos ciclos de reloj Encontramos que existen sistemas embebidos dise˜ados para el manejo de sonidos n que cumplen con estos requisitos. Como la gran mayor´ de los DSP tienen las capacidades ıa que consideramos fundamentales que tenga nuestro procesador. En el caso del DSPic. Que tenga puerto serie.1 Productos adicionales Cuando se selecciona y compra un DSP. no solo se compra el procesador. el siguiente paso consiste en elegir el modelo y marca deseado. Que tenga salida anal´gica que genere impulsos. Esto nos fue muy util a la hora de decidirnos por estos DSP. Como estos procesadores cumplen todos los requisitos que establecimos que nuestro sistema debe tener y a su vez est´n optimizados para el manejo de sonidos. ´ dado que nos permiti´ hacer algunas pruebas antes de decidirnos. nuestras prioridades en la b´squeda del sistema embeo u bido son: (a). Los DSP son un tipo de procesador. 9. o (d). en la universidad ORT disponemos de un programador (PICKit 2) que permite programar todos los modelos de DSPic.1 Selecci´n del sistema embebido o Selecci´n de la arquitectura del sistema embebido o Como se mencion´ anteriormente. las empresas tienen microcontroladores muy similares. o o 9. no una marca ni un modelo en particular.

Los circuitos necesarios son b´sicos y se a encuentran en las hojas de datos. u consideramos fundamental utilizar un microcontrolador que disponga de mucha ayuda en internet. dado que por lo menos nos aseguramos de encontrar accesorios de la l´ ınea Pic. Para o esos y otros casos es muy util tener un depurador que permita tener un control de las ´ variables del DSP mientras este ejecuta una aplicaci´n. lo cual no es util si el c´digo o ´ o fue escrito en c´digo ‘C’ y traducido a assembler por un compilador. En Argentina si hay en venta microprocesadores de la gama DSPic. la simulaci´n se ejecuta o indicando en que linea del c´digo assembler se encuentra. Tambi´n consideramos e e que en caso de precisar alg´n tipo de soporte t´cnico para nuestros DSPic vamos a poder u e encontrar gente con m´s experiencia de la que encontrar´ a ıamos con el resto de las marcas. si existe soporte y repuestos para la compa˜´ Microchip en Uruguay.2 Soporte y repuestos en Uruguay Si bien en Uruguay hay muy poco soporte y repuestos de la l´ ınea de DSP. a que el DSP no esta recibiendo bien los datos de entrada o a cualquier otra raz´n. Un requisito para poder utilizar optimamente el servicio en l´ ´ ınea es que el hardware y software para programar el DSP sean del mismo fabricante que el DSP. a 9. Nos parece fundamental que el soporte en l´ ınea de la empresa de microcontroladores sea bueno. que tambi´n sirven para los DSPic (como el Pickit 2).2. 9.’MPLAB’ es de libre distribuci´n y tiene una versi´n que permite programar toda la l´ o o ınea DSPic en lenguaje ‘C’. Esto le da a los DSPic una ventaja nıa frente a los otros DSP. Facilita mucho la tarea de encontrar fallas en un c´digo poder simularlo en la PC con un total control de las variables. Otro aspecto a tener en cuenta de la l´ ınea DSPic es que no precisan complejos circuitos adicionales para comenzar a funcionar.3 Soporte en l´ ınea Dado que es evidente que con cualquier microcontrolador que trabajemos vamos a llegar a etapas en las cuales vamos a tener alg´n problema que nos cueste mucho resolver. Dicha versi´n es de uso gratuito para estudiantes. e Cuando simulamos programas generados en la prueba previa. o Muchas veces en el simulador un c´digo funciona bien pero en la implementaci´n o o real no. de esta forma. al enviarle dudas al servicio en l´ ınea estos est´n familiarizados con el lenguaje a de programaci´n y su hardware. por lo que no ser´n muy complicados de conseguir en caso de necesitar de forma urgente. El PicKit 2 brinda la posibilidad o de depurar toda la l´ ınea de procesadores DSP. El simulador de o MPLAB para DSPic indica que linea del c´digo ‘C’ se esta ejecutando en cada momento. La versi´n gratuita o o del MPLAB tambi´n cuenta con un simulador de DSPic. esto puede deberse a las caracter´ ısticas del DSP que el simulador no simula bien.2. o Otras herramientas b´sicas a la hora de seleccionar un microcontrolador son un a simulador y un depurador (debugger ). Este requisito la l´ o ınea DSPic lo cumple dado que todas 58 .

Estas p´ginas nos fueron tan utiles como a ´ la informaci´n brindada por microchip. En estos ejemplos se muestra el uso de cada una de las herramientas que el DSPic dispone. SOIC o similar. dicho encapo sulado permite colocarlo en un s´calo y luego poder modificar la ubicaci´n del s´calo o o o de forma muy f´cil y sin riesgo para la integridad del microcontrolador. en especial problemas similares a los experimentados o ´ por nosotros y posibles soluciones para estos. o sobre todo en la etapa en la cual desarrollamos el sistema. o nıa Durante el trabajo con la l´ ınea DSPic (tanto en las pruebas previas como luego de decidir que este va a ser nuestro microcontrolador) nos surgieron algunos problemas. La l´ ınea DSPic tiene una enorme cantidad de ayudas y foros dedicados a todas las l´ ıneas de procesadores inclusive los DSP. ´ La pagina web de microchip tambi´n cuenta con una gran cantidad de ejemplos de e c´digos escritos para la l´ o ınea DSPic con el mismo programador que utilizamos nosotros. 9. tanto de programaci´n para hacer m´s eficientes ciertos c´digos como para hacer funcionar o a o ciertas herramientas del microcontrolador. Muchos mia crocontroladores vienen exclusivamente en presentaciones QFN.las herramientas que utilizamos de programaci´n son de la compa˜´ Microchip. dichas presentaciones no est´n dise˜adas para permitir cambiar de posici´n el microcontrolador a n o m´s de una vez. En los foros encontramos informaci´n muy util. ´ o o As´ como es importante tener ayuda desde el servicio t´cnico de microchip. a Utilizar microcontroladores en presentaci´n SPDIP fue una gran ventaja para nosotros. o Los comentarios en internet de la experiencia que tuvo la gente que utiliz´ esta l´ o ınea de DSP son muy alentadores en su mayor´ ıa. La imagen 16 es una foto que ilustra como es el encapsulado SPDIP. tambi´n ı e e es importante que exista ayuda en los foros. Dichas presentaciones son para soldar en una placa con toda ya armado.2. Cada vez que enviamos estas dudas al servicio en l´ ınea de microchip este no solo respondi´ r´pido si no que tambi´n con respuestas o a e concretas y utiles. Estos ejemplos nos fueron muy utiles para la elaboraci´n de nuestro c´digo.4 Presentaci´n o Los DSPic que utilizamos vienen en una versi´n con encapsulado SPDIP. Imagen 16: Foto del encapsulado SPDIP 59 .

5 Experiencia previa El trabajo en el campo de la electr´nica y de los procesadores. Dentro de los que o tienen estas dos caracter´ ısticas mencionadas. los DSPic33f y los DSPic30f. tanto en el trabajo a realizado en esta t´sis como en trabajos anteriores realizados con microcontroladores.2. muestra que no siempre o es f´cil utilizar las funciones de un procesador. pero necesita cierto equipo para funcionar. En nuestro caso. 2. decidimos optar por los que tengan menor cantidad de pines. 4. Las letras XXX representan el tama˜o de la memoria interna del DSPic expresado en Kb. Utilizar por primera vez una funci´n que nunca utilizamos de un sistema o embebido en la mayor´ de los casos consume mucho tiempo. A continuaci´n se enumeran algunas de las caracter´ o ısticas del DSPic33fj128GP802: 1. Los procesadores DSPic tienen dos familias. Lo que no todos tienen es encapsulado SPDIP y una salida anal´gica capaz de generar impulsos. esto u nıa consideramos que nos puede ser de mucha ayuda. trabajar hasta a 40MIPs (millones de instrucciones por segundo) y trabajan con registros de 16 bits. En muchos casos un usuario puede no o notar esto hasta que se encuentra en la situaci´n en la cual pretende utilizar la facilidad. Tambi´n o e tenemos experiencia en el manejo del MPLAB y del PicKit 2 (para programar Pics). si la tenemos en procesadores anteriores de la compa˜´ Microchip.3 Selecci´n del modelo de DSPic o Una vez determinado que el microprocesador a utilizar es de la gama DSPic. Si bien no tenemos experiencia de trabajo con ning´n DSPIC. exe perimentamos que en la mayor´ de los casos utilizar una funci´n de un sistema embebido ıa o no es sencillo. o 60 . el siguiente paso es determinar cual modelo usaremos. dicha gama tiene 28 patas y cumple todos los requisitos que buscamos que tenga el microcontrolador. Maneja registros de 16 bis. De esta forma quedamos con la gama DSPic33fjXXXgp802. como en la soluci´n de problemas a la hora de implementar el hardware. Pueden realizar hasta 40 millones de instrucciones por segundo. pero luego pasamos al dspic33fj128gp802. o la realiza con alguna limitaci´n. Inicialmente n comenzamos con el DSPic33fj64gp802. Ambas familias est´n orientadas al proceso de se˜ales digitales. pero la familia a n DSPic33f es la m´s potente. Multiplicaciones de variables enteras en un solo ciclo de reloj. 3. tanto en la interpretaci´n de la hoja de o datos. dado que no precisamos de una gran cantidad de entradas y salidas.9. Convertidor digital anal´gico (DAC). ıa En otros casos un microprocesador tiene cierta facilidad. decidimos utilizar la gama DSPic33f dado que es la m´s a moderna. a Dentro de la familia DSPIC33f actualmente hay 92 modelos. o Por estas razones consideramos muy importante utilizar un procesador con el cual tengamos experiencia previa de trabajo. 9. Todos estos modelos pueden hacer multiplicaciones en un ciclo de reloj.

10 entradas anal´gicas. 61 . 8. en caso de querer comercializar el sintetizador se implementar´ ıa con el encapsulado QFN dado que es m´s barato y peque˜o. o 6. por 6mm. 7.5. Si bien el encapsulado utilizado para realizar este proyecto fue el SPDIP. con velocidad de hasta 1 Megabit/seg. Interfaz I 2 C. pero todas fueron usadas. 2 UART (Universal Asynchronous Receiver Transmitter).72 al o n por mayor. El reducido tama˜o del a n n encapsulado QFN (6mm. Muchas de estas caracter´ ısticas no fueron consideradas como caracter´ ısticas fundamentales.) hace que el tama˜o no sea un problema pensando n en comercializar el producto. La versi´n QFN viene en tama˜o de 6mm por 6mm por un precio de U$S 3.

´ Imagen 17: Esquema del Dispositivo 62 . Luego se encuentran siete controladores utilizados para manejar los efectos y por ultimo una salida de audio. consta de dos entradas.10 Arquitectura externa del sintetizador En la imagen 17 se muestra un esquema simplificado de la interfaz del dispositivo. una MIDI que ser´ utilizada para conectar el instrumento MIDI y la a otra es la entrada por la cual se conectar´ la computadora para cargarle al sistema el a instrumento virtual que se quiera utilizar.

La explicaci´n de los efectos es a un nivel b´sico. El primer par´metro del efecto seleccionado se modifica mediante la rotaci´n de la a o perilla 2. Los DSPic se alimentan con 3. En caso de que el efecto tenga un segundo par´metro este se modifica mediante a perilla n´mero 3. a o o 63 . El sistema no funciona bien si se le aplica dos veces el mismo efecto a la se˜al de salida. u El manejo del segundo efecto digital es igual al anterior pero manejando las perillas 4. con eso basta para la reproducci´n de instrumentos. para controlar los efectos se utiliza la caja de manejo de efectos. Hay efectos que requieren de un solo par´metro y otros de o a dos. alrededor de la perilla hay un indicador del efecto que le corresponde a cada posici´n. los efectos o o a son explicados m´s a fondo en la explicaci´n del c´digo de funcionamiento de los esclavos. n A continuaci´n se explica en detalle a que efecto digital corresponde cada posici´n o o de las perillas 1 y 4 comenzando de la posici´n m´s a la izquierda y avanzando de a una o a posici´n hacia la derecha. a Imagen 18: Representaci´n de la caja de efectos o Para seleccionar el primer efecto digital a aplicar se coloca la perilla 1 en la posici´n o correspondiente al efecto deseado.11 11. los integrao o dos MAX-232 con 5V y por ultimo el amplificador lo hace con ±9V.5V.5 y 6 en lugar de las 1. y de otras cinco perillas que son para o el ajuste de los par´metros de los efectos. Actualmente es necesario conectar el sintetizador a varias fuentes de tensi´n.2 Utilizaci´n de los efectos digitales o El sintetizador consta con la capacidad de aplicarle a la se˜al de salida hasta dos efectos n digitales. o 11.1 Instrucciones de uso del sintetizador Reproducci´n de instrumentos o El primer paso para el uso consta de la conexi´n del sintetizador a las fuentes de corriente o correspondientes. cada una con una tensi´n distinta. En caso de querer ´ comercializar el producto consideramos fundamental lograr que se pueda conectar a una unica fuente. Consta de dos perillas discretas para la selecci´n de efectos (1 y 4). dicha caja esta esquematizada en la imagen 18 con cada una de sus perillas numeradas. ´ Luego hay que conectar el instrumento por la entrada MIDI y parlantes por la salida de audio.2 y 3 respectivamente.

a El resultado es una variaci´n peri´dica en el volumen. Si el primer n par´metro de este efecto esta al m´ a ınimo. El n n primer par´metro del efecto indica el tiempo de retraso que tiene la se˜al que se le suma a n a la de salida. El efecto eco consta de un segundo par´metro que regula la magnitud con la que la a se˜al retrasada es sumada a la de salida. e a si esta al m´ ınimo la frecuencia de la se˜al sinusoidal es m´ n ınima y si esta al m´ximo es a m´xima.2. Si la se˜al de salida es mayor a a n un valor x hace que sea x.11. a n 11. mientras a a u que si esta al m´ ınimo se aten´a todas. a n Utiliza solo un par´metro que si esta al m´ximo no se aten´a ninguna frecuencia. a Al igual que el efecto eco. este efecto tambi´n hace uso del segundo par´metro. o o 11.2. en los casos intermedios se aten´an solo a partir u u de una frecuencia ‘f’ que depende la posici´n del valor del par´metro. Si este par´metro esta en el m´ a ınimo a la se˜al de salida se le suma la se˜al n n salida y si esta en el m´ximo a la se˜al de salida se le suma la misma se˜al pero retrasada a n n 253 milisegundos. ı 11.4 Efecto Wah-Wah B´sicamente este efecto lo que hace es atenuar las altas frecuencias de la se˜al de salida.3 Efecto tr´molo e Este efecto lo que hace es multiplicar la se˜al de salida por una constante ‘C1’ y sumarle n la salida multiplicada por otra constante ‘C2’ y por una se˜al sinusoidal.2 Efecto eco Este efecto consta en sumarle a la se˜al de salida una se˜al generada anteriormente. El valor x depende del par´metro del efecto. entonces ‘C1’ es 1 y ’C2’ es 0. mientras que si esta al m´ximo ‘C1’ es 0 y ’C2’ es 1.1 No aplicar el efecto Tal cual indica el nombre esta posici´n es para no aplicarle efectos a la salida generada. de ah´ el nombre.2.5 Efecto limitador ’if ’ Este es un limitador que depende de un solo par´metro. o 11. si es menor a −x hace que sea −x y para los casos intermedios mantiene intacta la se˜al. Musicalmente se o a aumenta la resonancia de la nota haci´ndola sonar parecida a la voz humana diciendo la e s´ ılaba wah. Si el segundo par´metro esta en el m´ n a ınimo a la se˜al de salida se le suma la se˜al atrasada multiplicada por cero (es como si no se le n n sumara) y si esta en el m´ximo se le suma la se˜al atrasada multiplicada por 1.2. si esta al m´ n a ınimo 64 .2.

si esta al m´ o ınimo no se genera distorsi´n y si esta al m´ximo o a la distorsi´n ser´ m´xima. o El modo de uso del software del sintetizador esta en la secci´n ’Manual de instrucciones o del programa interfaz de comunicaci´n’.7 Efecto vibrato Este efecto modifica todas las frecuencias de la se˜al de salida. Utiliza un solo par´metro n a que si esta al m´ ınimo el sonido suena m´s grave y si esta al m´ximo el sonido suena m´s a a a agudo. o a a 11. 11. a n 11.3 Utilizaci´n del efecto anal´gico o o El sintetizador tambi´n cuenta con la posibilidad de generar un efecto anal´gico a la salida e o de audio. distorsiona la salida en sus valores extremos. Cuanto m´s cerca este el valor de la salida del valor m´ximo o m´ a a ınimo que puede adquirir m´s distorsionada ser´. Este efecto es explicado m´s a fondo en la secci´n ‘Arquitectura del Sistema’. dicho efecto es una saturaci´n.6 Efecto limitador ’log’ Este es un limitador que simula un amplificador saturado. o 65 . El efecto se maneja mediante la perilla n´mero 7 o u que sirve para aumentar el volumen de la salida generada.4 Cambio y creaci´n de instrumentos o Para conectar el sintetizador al PC simplemente enchufe el cable serie del sintetizador al PC. En algunos PC es necesario reiniciar el sistema para que se pueda realizar la conexi´n. a o 11. Este efecto tiene un par´metro que regula la a a a magnitud de la distorsi´n. esta dise˜ado de tal forma que n al subir demasiado el volumen la se˜al sature al amplificador interno y se genere dicho n efecto.2.2.entonces x vale cero (no se escucha la salida en este caso) y si esta al m´ximo entonces x a es el m´ximo valor que puede adquirir la se˜al de salida (es como no aplicar el efecto).

cuyo funcionamiento fue detallado en el manual de usuario del sintetizador. por lo que de tener una gran cantidad de a 66 . volviendo m´s complejo el uso para el usuario.2. o 12. En esta secci´n se explica el ı o o dise˜o de dicha arquitectura. Hay que dise˜ar una arquitectura que permita que varios DSP puedan n trabajar en conjunto para obtener as´ sonidos polif´nicos. 12.1 MIDI Las conexiones utilizadas para lograr descifrar los comandos MIDI ya fueron mencionados previamente en la secciones de Prueba Previa y detecci´n de comandos MIDI. 12.2.1 An´lisis de la arquitectura externa a El esquema general de la arquitectura externa se observa en la im´gen 17 en la secci´n a o anterior. La primera fue configurada para obtener los comandos MIDI. La selecci´n del o sistema para la elecci´n de efectos y la configuraci´n de sus par´metros permite tener una o o a cantidad significativa de efectos evitando la necesidad de sobrecargar al dispositivo de perillas.2. sin paridad y 1 bit de parada por ser esta la m´s difundida y una que cualquier a PC puede soportar.2 RS-232 La entrada RS-232 permite al dispositivo comunicarse con la computadora a trav´s del e puerto COM.12 Arquitectura del Sistema Dado que cada microcontrolador solo podr´ generar una sola nota a la vez y el objetivo a del proyecto es poder generar sonidos polif´nicos. 8 o o o Data bits. n 12. Cada preset agregado significa un a pin m´s de nuestro microcontrolador ocupado. la segunda para cargarle nuevos instrumentos. una MIDI que se utiliza para la conexi´n con el o instrumento musical y una RS-232 que sirve para conectarse con un PC. es necesario que el sintetizador conste o de varios DSPic. Para la comunicaci´n con el PC se utiliz´ la configuraci´n 9600 de Baud Rate.3 Efectos El manejo de los efectos se realiza mediante la caja de manejo de efectos.2 Entradas El sistema consta de dos entradas. El DSPIC33FJ128GP802 posee la capacidad de manejar dos UART independientes. 12.

o 12. es decir enviar la informaci´n a todos los pics esclavos o enviarla a un unico o ´ pic. Para efectuar la comunicaci´n entre los pics se utiliz´ el protocolo I 2 C. La imagen 19 es un esquema de la arquitectura interna del sintetizador. a los niveles de voltaje que a entienden los dispositivos TTL/CMOS que son 0 y 5V. La entrada MIDI tiene un circuito similar con el mismo objetivo. En ella se observa que ambas entradas est´n conectadas a un DSPic a trav´s de dos integrados a e MAX-232. Imagen 19: Esquema de la Arquitectura Interna 67 . esto se debe o o a que es un protocolo est´ndar dise˜ado para comunicar integrados que se encuentran en a n un mismo circuito impreso. En el caso de la entrada que se conecta al PC el MAX-232 fue utilizado para convertir los niveles de voltaje del RS-232 que son de 3 a 15 volts tanto positivo como negativo (el rango cerca del cero no es un nivel v´lido). los datos neceo sarios para cargar el nuevo instrumento o un cambio en los par´metros de los efectos a llegan unicamente a un DSPic que llamaremos “maestro”. Toda informaci´n proveniente de afuera ya sea un comando MIDI. Dependia endo de que tipo de informaci´n se haya recibido el maestro decidir´ si es necesario hacer o a un broadcast. El maestro tiene 10 dspic que ´ llamaremos “esclavos” entre los cuales deber´ distribuir las acciones a realizar.potenci´metros en nuestro sistema requiere de otro microcontrolador para poder cubrir o la demanda de entradas anal´gicas.3 Arquitectura Interna En esta secci´n se ver´ con mayor detalle c´mo es que se procesa la informaci´n llegada o a o o por la entrada MIDI hasta obtener el resultado final en la salida de audio.

3. Es muy usado en la industria de los microcontroladores para comunicar circuitos integrados que residen en un mismo circuito impreso. e El esclavo direccionado responde enviando un bit de ACK que le indica al maestro que el esclavo reconoce la solicitud y est´ en condiciones de comunicarse. una por la que env´ los datos o ıa (SDA) y la otra carga la se˜al del reloj (SCL).. siendo el esclavo el que fija o esta cantidad de acuerdo a sus caracter´ ısticas. ’1’ lectura y ’0’ escritura. I 2 C utiliza dos l´ ıneas para transmitir la informaci´n. Su velocidad en modo est´ndar es de 100Kbits/s aunque permite velocidades de hasta 3. — ACK — stop — idle — El bus esta libre cuando SDA y SCL est´n en estado l´gico alto.12. el I 2 C es un bus de comunicaci´n n n o en serie y su nombre viene de Inter-Integrated Circuit (Circuitos Inter-Integrados). Dado que no tenemos grandes requisitos en la veolcidad de transmisi´n de datos. sin embargo en el caso de nuestro sistema el pic maestro se mantendr´ fijo y ser´ el unico que comience las transmisiones. a Seguidamente comienza el intercambio de informaci´n entre los dispositivos. El dispositivo maestro inicia la transferencia de datos y genera la se˜al de reloj. a a ´ Una transacci´n en el bus I 2 C tienen el siguiente formato: o — start — A7 A6 . Cada byte le´ ıdo/escrito por el maestro debe ser reconocido por un bit de ACK por el dispositivo maestro/esclavo. o utilizamos como velocidad 100Kbits/s. en el caso de que se comunicaran cirn cuitos que no comparten la misma masa se deber´ agregar un l´ a ınea m´s para usar como a referencia. Todos los bytes deben constar de 8 bits y el n´mero m´ximo de bytes que pueden u a ser enviados en una misma transmisi´n no esta restringido. o La direcci´n enviada es comparada por cada esclavo del bus con su propia direcci´n. caso contrario el esclavo se mantendr´ ocioso hasta que en la pr´xima transmisi´n a o o vuelva a recibir la condici´n de arranque y verifique si el maestro desea comunicarse con o ´l. Despu´s de la stop condition es obligatorio e 8 Wikipedia en Espa˜ol: I 2 C n 68 . El bus del I 2 C es multi-maestro. Luego el maestro empezar´ a leer o escribir bytes de a datos. Los dispositivos conectados al bus I 2 C tiene una direcci´n unica para cada uno y o ´ pueden ser maestros o esclavos.. esto significa que no exige que n el maestro sea siempre el mismo dispositivo. esto alerta a los o o dispositivos esclavos poni´ndolos a la espera de una transmisi´n. El maestro inicia a o la comunicaci´n enviando un patr´n conocido llamado start condition. o o en caso de coincidir el esclavo prestar´ atenci´n a la siguiente informaci´n enviada por el a o o maestro.1 8 I 2C Dise˜ado originalmente por Phillips en el a˜o 1992. Luego el maestro env´ e o ıa un byte que contiene los siete bits que componen la direcci´n del esclavo (A7-A1) y el o octavo bit de menor peso corresponde con la operaci´n deseada..4 a Mbits/s. el mao estro le env´ la direcci´n del registro interno que se desea leer o escribir y el esclavo ıa o responde con otro bit de ACK. Cuando la comunicaci´n finaliza el maestro transmite una stop condition (condici´n o o de detenci´n) para liberar las l´ o ıneas del bus..DATA. A1 — R/W — ACK — .

abilidad de que ocurra una falla con alguno de ellos y tambi´n un costo monetario mayor.3. En el caso de nuestro sistema adem´s del byte indicando la posici´n de memoria a o interna que se desea leer o escribir. para permitir en el caso de que se est´ utilizando un e organo MIDI que cada dedo pueda presionar una nota a la vez. El saturador anal´gico funciona como un amplificador o cuya ganancia es controlada mediante uno de los potenci´metros de la caja de efectos. una vez que ıa o o llega a la ultima direcci´n comienza nuevamente desde la primera. esto sumado a la frecuencia de conversi´n del DAC impide al o DSPic lograr procesar mas de una nota a la vez. ´ Una desventaja que esta arquitectura presenta es la cantidad de microcontroladores que tendr´ nuestro sistema. Existen dos soluciones para este problema. debido a la cantidad de arm´nicos y envolventes o que se deben procesar. Cada vez que el maestro detecta un cambio en una de sus entradas anal´gicas (las que est´n o a conectadas a los potenci´metros que regulan los efectos) env´ a todos los esclavos los o ıa nuevos par´metros para el efecto modificado. o o 12. Esto implica un mayor consumo de energ´ una mayor proba ıa. despu´s pasan por el saturador anal´gico y finalmente son o e o emitidas por la salida de audio.2 Generaci´n del Sonido o Una vez que el DSPic maestro recibe una nota MIDI se la env´ a uno de los esclavos. Para realizar este prototipo se colocaron diez microcontroladores.3.3 Generaci´n de efectos o Cada esclavo esta encargado de aplicarle los efectos a la nota que esta generando. necesaria para liberar el bus. 12. los DSPics son econ´micos y m´s robustos que otros procesadores o a con mayor capacidad que son los que deber´ ıamos utilizar en caso de querer reducir la cantidad de procesadores en el sistema. Dado que la entrada anal´gica del maestro a o tiene una precisi´n de 10 bits y que los par´metros de los efectos son de 7 bits. Luego. Como consecuencia se necesitar´n tantos a esclavos como notas se deseen tocar al mismo tiempo. 12. Esto se debe a que las escrituras y lecturas que se realizan en nuestro sistema son de solamente un byte. ıa cuando recibe la siguiente nota se la env´ al esclavo en la pr´xima direcci´n. por otra parte. el maestro enviar´ o recibir´ un unico byte m´s antes a a ´ a de enviar la stop condition. Cuando un esclavo ´ o recibe la orden de generar una nota transmite la se˜al de audio resultante a trav´s de n e su salida anal´gica. e Pero. las salidas generadas por todos los esclavos son sumadas o mediante el sumador anal´gico.para el bus estar en idle (estado ocioso) durante unos microsegundos. o para ganancias altas satura. pero en ambas se deber´ sacrificar la ıa 69 . si un cambio o a en la posici´n de un potenci´metro no es suficientemente significativo no es transmitido.3.4 La necesidad de tantos microcontroladores Se mencion´ en la secci´n de “Selecci´n del Microcontrolador” la necesidades de tener o o o un alta capacidad de procesamiento.

e Esta forma de presentar la salida. hace que el circuito sumador necesario no sea exactamente un sumador. es decir que sume la diferencia de potencial entre las patas de los DSPic. entonces I8 = I4 + I5 + I6 : 70 . Lo que realizamos fue una combinaci´n de un circuito sumador con un circuito o restador. utilizamos a la nomenclatura V1x y V2x para referirnos a el voltaje respecto a tierra de cada pata de la salida anal´gica del DSPic x.5V. y en el caso de que sea al rev´s se tiene una diferencia de -3.calidad del sonido generado. De esta forma si la pata DAC1RP que es la considerada positiva tiene 3. este circuito fue ilustrado solo para 3 DSPic. e o de esta forma se dispondr´ de mayor tiempo para realizar las debidas operaciones. la salida buscada del circuito ser´ o ıa: (V1n − V2n ) n El circuito del sumador anal´gico se presenta en la im´gen 20. o I8 I4 I5 I6 = = = = VI ⇒ R1 V21 −VI R V22 −VI R V23 −VI R VI = I8 ∗ R1 Como la corriente entre las entradas de un amplificador operacional es cero.3.5V y la otra 0v entonces la diferencia de potencial es 3. dado que un sumador tiene n entradas y una salida que vale la suma de la diferencia de potencial entre cada una de esas entradas y tierra. Por o otro lado tambi´n existe la posibilidad de disminuir la frecuencia de conversi´n del DAC. si llamamos V1x al voltaje respecto a tierra de una de las patas de la salida anal´gica del DSPic ’x’ y V2x a la otra pata.5V hasta 3.5V sin necesidad o de utilizar fuentes negativas. a a o ıa 12. si bien tiene sus ventajas. esta se presenta como la diferencia de potencial entre dos patas DAC1RN y DAC1RP. En primer lugar se podr´ reproducir sonidos m´s simples. o a Para simplificar el an´lisis.5 Circuito del sumador anal´gico o Para lograr que la salida anal´gica del DSPic pueda ir desde -3. El circuito que precisamos es un circuito que sume diferencias de potencial. ıan a con menor cantidad de arm´nicos y en vez de una envolvente por arm´nico agrupar las o o frecuencias arm´nicas de a tres o cuatro para que compartan la misma envolvente. ıa Se consider´ que la calidad y fidelidad del sonido son los elementos b´sicos del o a sistema y el sacrificarlos por obtener quiz´s un producto m´s econ´mico no tendr´ sentido.5V.

3. I1 = I2 = I3 = V11 −VII R V12 −VII R V13 −VII R = = = V11 −VI R V12 −VI R V13 −VI R Como la corriente entre las entradas de un amplificador operacional es cero. entonces VI = VII . entonces I7 = I1 + I2 + I3 : V11 − VI V12 − VI V13 − VI V11 + V12 + V13 3 ∗ VI + + = − R R R R R 71 I7 = .Imagen 20: Circuito sumador    V21 − VI V22 − VI V23 − VI   ∗ R1 VI = I8 ∗ R1 = (I4 + I5 + I6 ) ∗ R1 =  + +  R R R  I4 I5 I6 VI = (V21 + V22 + V23 − 3 ∗ VI ) ∗ R1 R1 ⇒ VI 1 + 3 R R = (V21 + V22 + V23 ) ∗ R1 R Obtenemos as´ la expresi´n n´mero 12.5: ı o u R1 R R1 R VI 1 + 3 = (V4 + V5 + V6 ) ∗ Como el voltaje entre las entradas de un amplificador operacional es cero.

se decidi´ agregarle al circuito una o saturaci´n anal´gica. luego se suman todas las salidas generadas.5. de tal forma si el valor de o la resistencia se acerca al m´ximo el amplificador satura. entonces VI = VII = 0. que no es extremadamente chica. o Al analizar el circuito sumador se considero el amplificador operacional ideal debido a que al amplificador no se le exige mucha potencia. controlada con un potenci´metro. ıa Si el efecto es un efecto lineal. Tambi´n como e la intensidad de salida del DSPic puede alcanzar los 10 mA. dicha constante ser´ asignada de tal forma que la suma de todos los voltajes de salida a R no pueda superara el m´ximo voltaje que el sumador puede entregar.I7 = VOU T = VI − R1 ∗ VI − VOU T VII − VOU T = ⇒ VOU T = VI − R1 ∗ I7 R1 R1 V11 + V12 + V13 3 ∗ VI 3R1 R1 − = VI 1 + − (V11 + V12 + V13 ) ∗ R R R R Remplazando con la expresi´n 12. a Dado que a la salida de este circuito se coloca otro circuito con alta resistencia de entrada (se coloca el saturador anal´gico que se explica a continuaci´n). En la im´gen 21 se muestra el a a circuito del saturador.3. cada DSPic calcula por si mismo la nota que tiene que o generar y le aplica el efecto correspondiente.6 Saturador Anal´gico o Como se explic´ anteriormente. Idealmente habr´ que sumar todos los sonidos de las notas y luego aplicarle los efectos. multiplicado por la constante R1 . 12. ni se precisa que tenga una gran ganancia ni resistencia interna o externa. Como el voltaje entre las entradas de un amplificador operacional es cero. por eso aparte de las saturaciones digitales. es decir la suma de una de las patas de todos los microcontroladores menos la suma de la otra de las patas. no hay problema con que cada DSPic calcule los efectos de su nota y luego se sumen los resultados. como el eco en donde la suma de los ecos de dos sonidos es igual al eco de la suma del sonidos. podemos utilizar R = 1k y no exigir que el amplificador operacional tenga una resistencia de entrada muy grande. llegamos a que: o VOU T = VI 1 + 3R1 R1 R1 −(V11 + V12 + V13 )∗ = ((V21 + V22 + V23 ) − (V11 + V12 + V13 ))∗ R R R La salida del sumador es la buscada. Como conclusi´n. o o o Esta saturaci´n consiste en pasar la se˜al generada por un circuito amplificador cuya o n ganancia depende del valor de resistencia de un potenci´metro.3. 72 . cualquier amplificador operacional o que hay en plaza nos sirve. Pero en el caso de la saturaci´n no ocurre lo o mismo. Se utiliz´ el amplificador 741. no tenemos requio o sitos respecto a la resistencia de salida del amplificador. Como tambi´n los voltajes que e manejamos no son voltajes extremadamente chicos (del orden de los microvoltios) tampoco hay requisitos respecto a la ganancia del amplificador operacional.

3. por lo que tambi´n utilizamos el 741. o Dado que las entradas anal´gica del DSPic detectan voltajes entre 0 y 3. tampoco tenemos requisitos exigentes en los otros aspectos del amplificador operacional. o a 12. exige poca corriente del amplificador. si se acerca el amplificador comenzar´ a distorsionar. Al igual que para el caso del sumador.7 Circuitos de la caja de efectos La caja de efectos consta de cinco potenci´metros. uno de los cuales es destinado a cambiar o la resistencia R2 del saturador anal´gico.Imagen 21: Circuito saturador Como la intensidad que ingresa a un amplificador operacional es cero. V = I2 R1 I1 = I2 = 0 − VOU T V R2 = ⇒ VOU T = −V ∗ R2 R1 R1 R2 VOU T = −V ∗ R1 se cumple mientras que el valor absoluto de VOU T no sea cercano a VM AX . por lo que no tenemos requisitos de potencia a la salida del amplificador operacional. An´logamente e a con el caso anterior se consider´ para este an´lisis un amplificador ideal.cualquier amplificador operacional de plaza nos sirve. a El o´ humano no nota la diferencia de un sonido y el mismo sonido invertido.5V. Dado que el parlante que se utilizar´ para reproducir los sonidos tiene alimentaci´n a o propia. entonces I1 = I2 . por eso la caja de efectos consta de dos cables o de salida que tienen entre si la resistencia de dicho potenci´metro. por ıdo eso no importa que el amplificador sea inversor. la caja o de efectos debe “traducir” la posici´n de las perillas relacionadas con los efectos digitales o 73 .

Para eso consta de cuatro potenci´metros que cada uno tiene o tres patas. otra en el otro y una tercer pata en un punto intermedio de la resistencia que depende de la posici´n de su perilla.a tensiones de ese rango. luego se procedi´ o o igual que para las perillas de variaci´n de par´metros de los efectos. hay un voltaje entre 0 y 3. mientras que para los esclavos se utiliz´ un dise˜o espec´ e o n ıfico PCB Printed Circuit Board (Circuito Impreso). a n ventaja enorme en el caso de que una placa fallase o que se deseen agregar m´s esclavos a al sistema. dicho voltaje es el que se o conecta a la entrada anal´gica del maestro. o a A diferencia de las perillas para modificar los par´metros de los efectos.8 Dise˜ o del PCB y de los circuitos de los DSPic n En la im´gen 23 se muestran los circuitos de los esclavos y en la im´gen 22 se muestra el a a circuito del maestro. o a 12. Para las perillas de selecci´n de efectos se utilizaron llaves rotativas a o multiposici´n (llaves que tienen una cantidad discreta de posiciones. dado que se forma un divisor resistivo. Se conecta uno de los PCB con la salida del circuito maestro y luego se 74 .3. Estos circuitos son los circuitos recomendados en las hojas de datos para las funciones que utilizamos de cada DSPic. La idea detr´s del dise˜o fue permitir que las placas se pudieran interconectar.5V que depende de la posici´n de la perilla. Se conecta a o la primer y segunda pata mencionadas de los potenci´metros 0 y 3. por esa raz´n no se puede implementar exaco o tamente el mismo sistema para las perillas de selecci´n de efectos que el que se utiliza o para sus par´metros. una en un extremo de su resistencia. que cada una cierra o otro circuito) para crear un potenci´metro pero de posiciones discretas. De esta forma se conectan los potenci´metros o o dedicados a la variaci´n de los par´metros de los efectos.5v respectivamente y o de esta forma en la tercer pata mencionada. las perillas a de selecci´n de efectos deben ser discretas. Imagen 22: Circuito del maestro Para el maestro y los circuitos anal´gicos los circuitos fueron soldados en placas o gen´ricas.

Por otro lado se tomo la recomendaci´n de evitar el ruteo o en ´ngulos rectos y se observan unicamente ´ngulos de 45 grados.Imagen 23: Circuito de los esclavos conecta por el otro costado otra placa PCB. Cada PCB tiene lugar para colocar hasta 3 esclavos. Imagen 24: Dise˜o PCB n En la im´gen 24 se observan las previsiones en los extremos para que puedan ser a conectados entre otras placas. que fueron inevitables de suprimir todas debido a que el PCB fue impreso utilizando una unica ´ capa. Por la cantidad de a ´ a conexiones fue inevitable agregar pads para permitir realizar puenteos. La separaci´n entre las pistas es de 16 mil (0. Se intent´ mantener el tama˜o al m´ o n ınimo y evitar las conexiones puenteadas.61 o mm). a esa otra placa PCB se le conecta otra y as´ ı sucesivamente hasta conectar la cantidad deseada. 75 .41 mm) y su grosor es de 24 mil (0.

Como nuestro programa requiere m´s de 32kb de memoria utilizamos a a a a el comando psv const X attribute ((space(psv))) siendo X un tipo de variable v´lido (como int. cada modo con una relaci´n paro o o ticular entre el tama˜o en memoria del c´digo generado y la velocidad de ejecuci´n n o o del c´digo. etc) antes de los nombres de todas las variables que queremos que se localicen en una p´gina que no sea la que se usa por defecto. long int. o ˆ Tiene varios modos de optimizaci´n de c´digos. a ´ ˆ Es compatible con todas las herramientas del MPLAB. o o ˆ Permite intercalar c´digo ‘C’ con assembler. esta versi´n tiene las mismas funciones que la versi´n profesional. el tiempo de ejecuci´n de o o los m´todos es una prioridad. por defecto para optimizar los tiempos de ejecuci´n el compilador no perite utilizar o m´s de una p´gina. decidimos utilizar un modo de compilaci´n que al convertir e o de lenguaje ‘C’ a assembler prioriza el tiempo de ejecuci´n de los m´todos al tama˜o en o e n memoria que ocupa el c´digo. o Dado que para la generaci´n de sonido en tiempo real. o ˆ Permite localizar c´digo y datos en direcciones absolutas. Utilizamos la versi´n gratuita para o estudiantes. de esta forma podemos a utilizar toda la memoria del DSP. pero no o o tiene todas las optimizaciones de c´digos que la versi´n profesional tiene.MPLAB C Compiler for dsPIC DSCs 76 . A continuaci´n o o o se presentan las caracter´ ısticas que nos fueron m´s utiles del compilador. o Los 128 kb de memoria interna del DSP que utilizamos est´n divididos en p´ginas de a a 32kb. 9 Microchip.13 9 Entorno de programaci´n de los DSPic o Para la programaci´n de los DSPic utilizamos el programa MPLAB (de Microchip) con o el compilador de lenguaje ‘C’ que Microchip provee. memoria y conversi´n de a a o datos. o o ˆ Compilador ANSI con las clases est´ndar de matem´tica.2009. lo cual permite realizar simulaciones tanto directamente en el DSPic como por software en el MPLAB viendo como avanza el programa tanto en el c´digo de assembler como en el c´digo ‘C’. ˆ Genera objetos relocalizables para la reutilizaci´n de c´digo.

primero el software chequea si ya se encuentra en el modo de programaci´n. simplemente manda grabar el nuevo valor en la posici´n de memoria correspondiente al o tipo de dato que se esta enviando. ´ste esta encare 2 gado de reenviar a trav´s del bus I C toda informaci´n pertinente y filtrar el resto. si es as´ va agregando los datos a un buffer de cien posiciones. La comunicaci´n entre el maestro y los esclavos se realiza siguiendo el o mismo protocolo de comunicaci´n que se realizar´ entre un DSPic y varias memorias o ıa externas. luego se levantar´ otra bandera para indicar que los a a pr´ximos dos datos a recibir ser´n los par´metros de estos comandos (nota y velocidad). o 14. Una vez que se o ı. entonces cuando se reciba un valor mayor a 127 y menor a 144 se levantar´ una bandera llamada flagNoteOff. los esclavos reconocen que si se les ordena grabar un valor en la posici´n 1 de la memoria significa que este dato representa la o velocidad con la que deber´n reproducir la nueva nota MIDI. e o 14. Cuando el u instrumento MIDI env´ cualquier informaci´n por su salida MIDI-OUT se generar´ una ıe o a interrupci´n en el DSPic maestro. levanta una bandera indicando que ya se obtuvieron los cien valores a enviar. Cuando se ejecuta la interrupci´n por haber recibido un mensaje o nuevo desde el PC. se levanta una bandera o 77 . de o u forma interruptiva. En caso de que no se encuentre en modo de programaci´n.14 Explicaci´n del c´digo del Maestro o o El maestro es la puerta de enlace de los esclavos con el mundo de afuera. Cuando el maestro quiere transmitir cierto tipo de dato.1 Funcionamiento del I 2 C Desde el punto de vista del maestro. los comandos Note-Off son los “1000cccc” y los Noteo On los “1001cccc”. cada esclavo se comporta como una memoria externa de 20 posiciones.2 Interrupci´n MIDI o Los comandos MIDI son manejados con la UART n´mero 1 del maestro. cada una tiene su funci´n espec´ o ıfica. o a a Luego de recibir estos dos par´metros. De las 20 posiciones de memoria accesibles por I 2 C que tiene cada esclavo. En la secci´n de explicaci´n a o o del c´digo del esclavo se detalla que informaci´n almacena cada posici´n de memoria. o o o 14. Por ejemplo. si se recibe un comando de activaci´n de a o Nota se levantar´ la flagNoteOn.3 Interrupci´n PC o La comunicaci´n con un PC es manejada mediante la UART n´mero 2 del DSPIC. encuentra lleno. si el dato recibido coo incide con la condici´n de arranque para comenzar a programar. se levanta una bandera para indicar que ya a se tiene toda la informaci´n que el DSPic necesita para reproducir la nota. Como se vio en la explicaci´n de comandos MIDI en o o la secci´n ‘conceptos avanzados’.

Las entradas anal´gicas del o DSPic tienen una resoluci´n de 10 bits.4. porque los o par´metros de los efectos var´ entre 1 y 128. El n´mero 20 fue elegido o ´ u luego de observar la oscilaci´n del conversor cuando las perillas se manten´ quietas.4 Funcionamiento del Main Al comienzo del main se configuran cuales pines del DSPic actuar´n de forma digital y a cuales de forma anal´gica. el mapeo de sus puertos y las inicializaciones del I 2 C y del conversor anal´gico-digital. esto se debe realizar uno por uno medio ante una estructura del tipo for. Despu´s de enviar una nota al esclavo con la direcci´n ´ o e o de I 2 C m´s alta se vuelve a comenzar con el de direcci´n m´s baja. o Como I 2 C no permite una funci´n de broadcast. si pertenece a uno de los presets se divide por 8. o ıan Si el cambio pertenece a algunas de las perillas discretas se divide el resultado de la conversi´n por 146 para obtener un valor entre cero y siete (son los siete efectos m´s o a la posici´n de descanso). 78 . esta informaci´n se utilizar´ o a cuando se reciba un comando de Note-Off. luego con el de la o direcci´n siguiente (todos los esclavos tiene direcciones consecutivas) y as´ sucesivamente o ı hasta llegar a la ultima direcci´n. la configuraci´n o o de ambas UARTs. o 14.2 Funci´n agregarNota() o El maestro enviar´ los dos par´metros para reproducir la nota (que nota es y con que a a intensidad fue presionada) al pr´ximo esclavo que corresponda. La selecci´n del esclavo o o se realiza en orden a partir del que tiene la direcci´n de menor valor.indicando que se comenzaran a recibir los datos del nuevo instrumento. Para asegurarnos que el cambio que se detect´ haya sido realizado a o por el usuario y no que sea un tema de sensibilidad del conversor an´logico a digital. 14. si fue Note-Off se ejecuta quitarNota(). el maestro entra en un bucle infinito donde se mantiene ocupado verificando si se han realizado cambios en los efectos y si se han levantado las banderas indicando que se ha recibido un comando MIDI o que el usuario comenzar´ a cargar a un nuevo instrumento. a ıan Luego de realizada la divisi´n es necesario informar del cambio a todos los esclavos. 14. Si fue la o bandera de cargar un instrumento se corre la funci´n cargarNuevoPrograma(). se a implemento un mecanismo de seguridad que s´lo considera que ha habido un cambio si la o variaci´n con respecto al ultimo valor guardado es mayor a 20. Si se recibi´ un comando en el caso de que haya sido Note-On o se ejecuta la funci´n agregarNota(). La informaci´n de que a o a o nota se ha enviado a cada esclavo se almacena en un array. se setea la velocidad de trabajo en 40MIPs.4. o Luego de esto.1 Cambios en las perillas Dentro del loop infinito el DSPic ir´ verificando una por una sus seis entradas anal´gicas a o para detectar si ha habido un cambio en cualquiera de ellas. es decir divide el intervalo de voltajes de entrada o v´lido en 1024 valores.

luego de encontrada se le a env´ a ese mismo esclavo la informaci´n de que reproduzca la nota 100 (el sistema trabaja ıa o con instrumentos de hasta 86 notas). Luego de recibir todos los valores que representan al nuevo instrumento.14. el maestro le env´ un dato a la PC para indicarle que puede empezar a enviar los siguientes ıa cien valores. a o o Al comenzar el maestro le notifica a todos los esclavos que se ha comenzado a recibir un nuevo instrumento. lo que estamos haciendo es enviar el valor del int a grabar en una posici´n de memoria pero el I 2 C s´lo permite el env´ de variables del tipo short int o o ıo (un byte). Dentro del while el m´todo se mantiene a la espera de que se levante la bandera que indica que se ha e completado el buffer de cien posiciones del que se hablo en la parte “Interrupci´n PC”. el interpretar´ esto a como que debe conclu´ con la reproducci´n de la nota. Luego de efectuadas las cincuenta rondas necesarias para enviar los cien valores. se procede a enviar los datos a todos los esclavos en rondas de dos bytes. con velocidad (intensidad) cero.4 Funci´n cargarNuevoPrograma() o Aqu´ se detallar´ la l´gica detr´s de la funci´n cargarNuevoPrograma() para un contenido ı a o a o m´s detallado ver la secci´n “Protocolo de Transmisi´n”.3 Funci´n quitarNota() o Se comienza buscando dentro del array mencionado en agregarNota() a que esclavo se le ha enviado la nota recibida como par´metro en el comando Note-Off. e 79 . el maestro le env´ un byte de confirmaci´n a la PC para avisarle que la transmisi´n ha ıa o o finalizado con ´xito. La raz´n de que se env´ de a dos es porque las posiciones de memoria en el o ıan DSPic almacenan 16 bits. ır o 14. Luego se entra en una estructura del tipo while. luego abandona el while para volver al main.4.4. o Una vez completo. la condici´n para o salir del while es que se hayan grabado todos los valores del instrumento.

e 80 . Tambi´n hay un puntero llamado RAMPtr que al e iniciar el programa se lo hace apuntar al primer elemento de RAMBuffer. char value) y I2Cread(char addr. por eso la comunicaci´n I 2 C o o o consideramos que debe ser la primera en ser explicada. Para simular el comportamiento de una memoria utiliza una estructura que se llam´ o flag. e En nuestro caso se distinguen dos funciones en la comunicaci´n del maestro con el o esclavo I2Cwrite(char addr. cuando se termine de enviar la informaci´n se resetear´ el bus y ah´ el o a ı esclavo se dar´ cuenta de que los pr´ximos bytes que se reciban no necesariamente est´n a o a dirigidos a ´l. que es un conjunto de banderas. Los esclavos est´n programados para responder las cadenas I 2 C siguiendo el protoa colo dise˜ado para la comunicaci´n entre un maestro y una memoria externa actuando de n o esclava. Cuando un esclavo detecta que se est´n comunicando con e a ´l. luego vendr´ una cantidad determinada de data que ser´ recibida unicamente por a a ´ el DSPic esclavo.15 15. 15. Cuando ocurre la primera interrupci´n por I 2 C debido a la recepci´n de la direcci´n o o o del DSPic esclavo. tambi´n o e la selecci´n de efectos y la configuraci´n de instrumentos.1. los DSPic esclavos act´an como el protocolo indica que debe actuar una memou ria externa. dado que al ser un protocolo conocido y probado tiene menos probabilidades de tener errores.1 15. el m´todo chequea si se desea escribir o leer de la memoria del DSPic.2 Funcionamiento detallado Esta secci´n explica como hace el sistema para simular ser una memoria externa y que o es lo que hace internamente cuando detecta informaci´n de una nueva nota y cambio de o efectos.1 Explicaci´n del c´digo de los esclavos o o Funcionamiento de la comunicaci´n I 2 C o Funcionamiento general Toda la generaci´n de notas comienza con mensajes recibidos desde el maestro. adem´s de una mayor eficiencia. tambi´n tiene una direcci´n de I 2 C para identificar cuando un e o pedido u orden va dirigido a ´l. char subaddr). o Cada esclavo tiene una variable llamada RAMBuffer que es un vector de 20 posiciones del tipo short int. El I 2 C como se explic´ previamente tiene la capacidad de direccionar sus mensajes o a enviar poniendo como encabezado del mensaje la direcci´n del esclavo al que se desea o hablar. La detecci´n o de mensajes por I 2 C es interruptiva.1. El a protocolo es explicado en la secci´n “Arquitectura Interna del Sistema”. Decidimos utilizar este protocolo. En la tabla 6 se explica para que o se utiliza cada elemento del vector RAMBuffer. si le piden que escriba en cierta posici´n de memoria escribe en esa posici´n del vector e o o RAMBuffer y cuando la instrucci´n es de lectura de cierta direcci´n env´ el valor de la o o ıan posici´n de memoria del vector RAMBuffer requerida. char subaddr.

con lo que se finalizar´ la transmisi´n de una ıa o instrucci´n de reproducci´n de nota. se baja la bandera F lag. esta nos recuerda que el pr´ximo dato a recibir indicar´ cual es la posici´n de memoria en la cual se deber´ o a o a grabar el dato.AddrF lag y se eleva la Flag. se le suma el valor subaddr al valor de RAMPtr o y se procede enviando al maestro el valor *RAMPtr. enseguida despu´s se guarda el dato recibido en la variable e T emp. Por ejemplo a o si la direcci´n de memoria donde se almacenar´n los datos es la 1. de esta forma RAMPtr pasa a valer la posici´n de memoria donde hay que guardar el pr´ximo dato a recibir. luego se vuelve el valor de RAMPtr a la direcci´n de memoria de RAM Buf f er[0].AddrF lag. una vez que llega este char subaddr.DataFlag.Byte estado RAMBuffer [0] RAMBuffer [1] RAMBuffer [2] RAMBuffer [3] RAMBuffer [4] RAMBuffer [5] RAMBuffer [6] RAMBuffer [7] RAMBuffer [8] RAMBuffer [9] RAMBuffer [10] RAMBuffer [11] RAMBuffer [12] RAMBuffer [13] RAMBuffer [14] RAMBuffer [15] RAMBuffer [16] RAMBuffer [17] RAMBuffer [18] RAMBuffer [19] Descripci´n o Nota a reproducir Velocidad de la nota Par´metro 1 del efecto 1 a Par´metro 1 del efecto 2 a Par´metro 2 del efecto 1 a Par´metro 2 del efecto 2 a Primer efecto a realizar Segundo efecto a realizar Previsi´n o Previsi´n o Byte m´s significativo del dato del nuevo instrumento a Byte menos significativo del dato del nuevo instrumento Se guarda el CRC recibido del maestro Se guarda el CRC calculado por el esclavo Previsi´n o Indica inicio recepci´n del nuevo instrumento o Previsi´n o Previsi´n o Previsi´n o Previsi´n o Tabla 6: Distribuci´n de RAMBuffer o Rango de Valores 0 al 85 0 al 127 0 al 127 0 al 127 0 al 127 0 al 127 0 al 7 0 al 7 0 al 255 0 al 255 0 al 255 0 al 255 0 al 255 0 al 255 0 al 255 0 al 1 0 al 255 0 al 255 0 al 255 0 al 255 En caso de que sea escribir se levanta la bandera F lag. significa que el pr´ximo o a o dato a transmitir es la velocidad de una nota. luego realiza RAM P tr = RAM P tr + T emp. Previo a recibir o o el ultimo dato tambi´n se fija dependiendo de cual es la posici´n de memoria donde se ´ e o almacenar´n los datos. por lo que se activar´ la bandera recibiP unV el para o o ıa avisar que cuando se reciba el pr´ximo dato v´ I 2 C hay que activar la bandera bandera o ıa que indica que hay una instrucci´n MIDI pronta para procesar. Cuando se reciba el char o value. cual va a ser la acci´n a hacer luego de almacenarlos. a En el caso de la funci´n I2Cread. este ser´ almacenado en *RAMPtr. o 81 .

1 Generaci´n de sonidos de notas o Explicaci´n general del funcionamiento o Como se mencion´. Estas matrices tienen los datos para generar todas las envolventes y frecuencias de todas las notas. El vector envols es un vector de 15 posiciones que almacena el valor de cada envolvente. A cada envolvente le corresponden 7 incrementos. o entonces es necesario tener una variable que se llama ciclos que es la que indica la cantidad de samples calculados de la nota que se esta reproduciendo. a Una vez detectado que hay que generar cierta nota. Dado que es necesario saber cuantos samples se van calculando de una nota para poder saber si lleg´ el momento de cambiar el coeficiente angular de una envolvente. Como la matriz envolsIniciales es la que tiene los datos de los valores iniciales de cada envolvente. dicho valor es actualizado al generar cada sample. el primero es con el cual se incrementa hasta llegar a la cantidad de ciclos que indica la primera posici´n de la matriz o cambios con respecto a esa envolvente. que tiene los datos de la frecuencia de cada componente de la nota a reproducir. El c´lculo de un sample consiste en aumentar todas las envolventes por el incremento a 82 . en la matriz incrementos todos los datos de la matriz todosLosIncrementos correspondientes a la nota X y en la matriz cambios todos los datos de la matriz todosLosCambios correspondientes a la nota X. luego se le aplicar´ el segundo incremento hasta a llegar a la segunda posici´n de la matriz cambios y as´ sucesivamente. en la matriz aumentosSeno todos los datos de la matriz TodosLosAumentosSeno correspondientes a la nota X.2. antes de comenzar a generar los samples.2 15. La matriz cambios es una matriz de 15 por 7. El vector aumentosSeno es un vector de 15 posiciones.15. La matriz incrementos.todosLosIncrementos y envolsIniciales para obtener los datos para crear las 15 envolventes y se utiliza la matriz todosLosAumentosSeno para obtener las 15 frecuencias a utilizar para generar la nota. el m´todo de generaci´n de notas musicales que se utilizar´ ser´ el de o e o a a una envolvente particular para cada frecuencia. lo primero que hace el programa al detectar que hay que reproducir la nota X es copiar en la matriz envols los datos de la matriz envolsIniciales correspondientes a la nota X. es necesario hacer que el vector envols tome los valores iniciales de las envolventes. Se considerar´n las 15 frecuencias m´s a a influyentes de cada sonido y cada envolvente ser´ aproximada utilizando 7 rectas. se utilizan las matrices todosLosCambios. el s´ptimo elemento de cada fila es un 655350 que e luego se explica porque es necesario. Esta variable se inicia en cero y se incrementa en uno luego de calcular cada sample. en la cual est´n almacenados la a cantidad de samples a la cual se dan cada uno de los 6 cambios de coeficiente angular para cada una de las 15 envolventes. El matriz envolsIniciales tiene los datos de los valores iniciales de cada una de las envolventes de cada nota. es una matriz de 15 por 7 que indica cuanto debe ser el incremento (positivo o negativo) de cada una de las envolventes luego de transcurrido cada ciclo. De esta forma o ı quedan determinadas todas las envolventes.

por esa raz´n en la matriz todosLosCambios se almacenan los n´meros que deber´ estar. El valor de cada envolvente ıa a es guardado como una variable del tipo long int. pero para mejorar la precisi´n en la o o generaci´n de este lo que se hace es calcularlo como un n´mero de 32 bits y luego devolver o u como resultado los 16 bits m´s significativos. aunque el incremento que hay que aplicar a una ena volvente fuera el m´ ınimo no nulo posible (fuera 1). Tambi´n se utiliza un vector llamado indices de 15 posiciones del tipo int que se e inicializa todo con ceros. pero o u ıan divididos entre 10. tener m´s precisi´n en los incrementos porque el total de valores que puede tener la ena o volvente es mucho mayor. en el cada puntero en la posici´n X apunta o a los dos bytes m´s significativos del elemento en la posici´n X del vector envols. se los multiplica por 10. Este vector sirve para indicar hasta cual cambio llego cada componente de cada nota. a u Dado que la cantidad de samples en los cuales se desea generar un cambio en el coeficiente angular de una envolvente puede ser mayor a 65535. Pero para calcular samples se consideran las envolventes solo como variables del tipo unsigned int. Este vector sirve para saber que valor de la tabla seno es el pr´ximo que corresponde utilizar para cada envolvente. El vector punteroM ascaras es un vector de 15 punteros a variables del tipo unsigned int. Pero. es decir que sirve para saber con que incremento hay que aumentar cada envolvente. El vector aumentoSeno es el que o 83 . N el n´mero de sample que se esta generando u y F s la frecuencia de generaci´n de valores a la salida. El vector envols es tambi´n de variables del tipo long int. e a e utiliza una variable llamada salidaLong que es del tipo long int y almacena ah´ el dato. A u 15000 su vez el m´todo utiliza otro vector llamado tiempos que tambi´n es de 15 posiciones que e e se inicializan todas en cero.que corresponda y luego multiplicar cada envolvente por sen( 2∗π∗fs0 ∗N ). Para calcular senos se utiliza una tabla llamada seno que es una tabla de variables del tipo int de 15000 valores. esto se debe a que si e us´ramos variables del tipo int. Luego al pasar los datos de la matriz todosLosCambios a la matriz cambios. Siendo f0 la F frecuencia correspondiente a la envolvente. luego de calcular menos de 70000 samples la envolvente ya superar´ el m´ximo valor posible. para a o todo X entre 0 y 14. el elemento del vector indices correspondiente a esa envolvente aumenta en uno.2 Explicaci´n detallada de las variables o El sonido generado tiene una resoluci´n de 16 bits. Los n´meros que deber´ estar en la u ıan matriz todosLosCambios pueden no entrar en variables del tipo unsigned int. a Las envolventes son consideradas variables del tipo long int al aumentarlas as´ se puede ı. El valor n´mero n de la tabla seno es 511*seno( 2∗n∗π ). la matriz todosLosCambios es una matriz de variables del tipo unsigned int. ı luego presenta como salido los 2 bytes m´s significativos de este n´mero.2. Cuando la cantidad de samples generados es igual a un punto de cambio de una envolvente. o 15. la matriz cambios es una matriz de variables del tipo long int. a El m´todo que se encarga del c´lculo de cada sample es el m´todo calcularSample(). del cual al multiplicar por una sinusoidal para calcular el valor de cada sample se consideran solo los dos bytes m´s significativos. para ahorrar memoria.

o a Lo primero que hace el m´todo es verificar que no se hallan calculado m´s de 200000 e a samples. 15. habr´n transcurrido dos per´ a ıodos del seno. en caso o de que aumente la variable tiempos de a una unidad. esto significa que se obtuvo una se˜al de 2 Hz. Para hallar la cantidad de saltos que se deben realizar para obtener una determinada frecuencia podemos utilizar la ecuaci´n: o fdeseada ∗ 15000 30KHz fdeseada 2 Saltos = Saltos = 15. si es mayor ya no calcula m´s. entonces modifica las variables necesarias para que luego al generar cada sample se sepa que hay que ir disminuyendo la intensidad de la nota hasta que esta se apague. si se quisiera obtener una de 440 Hz se deber´ aumentar la n ıa velocidad 220 veces. esto significa avanzar de a 220 valores. Tambi´n es el encargado de inicializar todas las variables para e que la nota este lista para generarse. el valor con el que o son inicializadas y cuales son esas variables ya fue explicado. para eso verifica que la variable ciclos sea menor a 200000. Si la variable nota no vale 100.4 Funcionamiento del m´todo calcularSample() e Este es el m´todo que calcula los samples de la nota a generar. graba en las variables nota y velocidad la nota que hay que generar y la intensidad con la que debe ser generada respectivamente. Lo primero que hace el m´todo es verificar si la variable nota vale 100. Como se mencion´ nuestra tabla seno posee 15 mil valores.indica de a cuanto tiene que aumentar cada posici´n del vector tiempos luego de calcular o cada sample. si ese es e el caso es porque el comando recibido fue el de noteoff. Calcula 200000 samples e por nota. La frecuencia de conversi´n del DAC esta configurada para trabajar a 30 KHz la o raz´n de esto se explicar´ m´s adelante. A continuaci´n se anuncia el procedimiento del programa en caso de que la a o variable ciclos sea menor a 200000. Luego inicializa todas las variables necesarias para la generaci´n de notas. El primer paso es iniciar la variable salidaLong en cero. Despu´s hace un proceso que e 84 .3 Funcionamiento del m´todo agregarN ota() e Este es el m´todo encargado de la interpretaci´n de los comandos de generaci´n de notas e o o recibidos desde el maestro. lo cual permite una duraci´n del sonido de m´s de 6 segundos. luego de transcurrido 1 segundo que equivalen a 30 mil samples. pero ahora aprovecharemos para ver algunas o a a implicancias de esto.

si pasa hace que la a e envolvente para el pr´ximo sample valga cero. o o 4. pero permiten un mejor e entendimiento de este. envols[i] = envols[i] + incrementos[i][indices[i]]. 5. pero de la forma actual el tiempo o que toma calcular cada sample se reduce en m´s de 100 ciclos de reloj. Las envolventes nunca deber´ ser menores a cero. Se agrega a salidaLong el valor de la envolvente multiplicado por el punto que corresponda de la funci´n sinusoidal. o 2. a continuaci´n se explica el proceso para la envolvente o n´mero i. pero si por alg´n error de ıan u c´lculo pueden ser. tiempos[i] = tiempos[i] + aumentosSeno[i]. o En esta explicaci´n del proceso hay ciertos cambios en el orden de las acciones. Dado que el ahorro a de tiempo en el c´lculo de cada sample es nuestra prioridad. salidaLong = salidaLong + punteroM ascaras[i] ∗ seno[tiempos[i]]. Finalmente. Se aumenta el valor del elemento correspondiente del vector tiempos. se disminuyendo gradual pero ´ r´pidamente el valor de la variable velocidad. la tabla seno no puede llegar a ese valor. o estos cambios de orden no afectan el funcionamiento del m´todo. decidimos repetir c´digo a a o cambio de mejorar el tiempo de procesamiento. 3. por eso el m´todo chequea que esto no pase. Algunas variables auxiliares fueron omitidas para que el m´todo e quede m´s f´cil de entender. el m´todo calcularSample multiplica el valor de salidaLong por la e velocidad con la que la tecla fue oprimida y aumenta la variable ciclos en uno. u 1.es igual para todas las envolventes. Si tiempos[i] es mayor a 15000 (largo de la tabla seno) se le resta 15000.Tambi´n podr´ implemene ıa tarse con una estructura f or para evitar repetir c´digo. Esto se debe a que en cambios[i] est´n todos los puntos de cambio de la nota que a se esta reproduciendo y en cambios[i][indices[i]] esta el pr´ximo punto de cambio. as´ para el pr´ximo sample se utiliza otro valor de ı o la tabla seno. 85 . Esto es por que si por ejemplo tiempos[i] = 16000. a a Este proceso se repite 15 veces. esto es por que en indices[i] se encuentra la cantidad de puntos de cambio de la envolvente que ya fueron superados por la cantidad de samples calculados. una por cada envolvente. Cuando el ultimo comando recibido fue el de noteoff. Tambi´n se actualiza el valor e de la envolvente. o Dado que el ultimo valor de la tabla cambios es mayor a la cantidad de samples que ´ se reproducen por nota (el ultimo valor es 655350) se puede asegurar que la tabla ´ cambios no es desbordada. pero como la funci´n seno es peri´dica entonces el elemento que deber´ estar en la o o ıa posici´n 16000 de la tabla es igual al elemento que esta en la posici´n 1000. de esta forma los sonidos no desarparecen a tan bruscamente. Si la cantidad de ciclos es mayor a cambios[i][indices[i]] se aumenta en uno indices[i]. Se toma como incremento el incremento que esta en la posici´n o indices[i]. 6.

1 Funcionamiento general de los efectos Luego de generar cada sample. todas son enteros. a Cada vez que se modifica RAMBuffer en una de las posiciones de la 2 a la 7. Lo que hace el m´todo es determinar en base al dato que se encuentra en e RAM Buf f er[numEf ec] que efecto hay que aplicar y aplicarlo con los par´metros correa spondientes. se llama al m´todo e void actualizarParametrosEfectos (unsigned short int numEfec). los efectos son controlados por o o una serie de potenci´metros que est´n conectados con el maestro. Ahora o se ver´ la explicaci´n de como llega la informaci´n a los esclavos y de como hacen estos a o o para generar los efectos en base a esta informaci´n. pero cada una con distinto rango de valores v´lidos. El maestro cuando o a detecta un cambio en alguno de los potenci´metros se los transmite a los esclavos. De esta forma logramos que todas las samples se calculen en el tiempo necesario hasta para el peor caso y obtenemos una ecuaci´n muy o simple para calcular los saltos que se deben realizar para obtener las frecuencias deseadas. Despu´s llama dos veces al m´todo aplicarEfectos (unsigned short int numEfec). El par´metro representa la posici´n de memoria en el vector a a o RAMBuffer donde se encuentra el n´mero asociado al efecto a realizar. e e primero con par´metro 6 y luego con par´metro 7. primero con par´metro a 6 y luego con par´metro 7.Dado que calcular cada sample toma aproximadamente 1050 ciclos de reloj aproximadamente. Decidimos hacer que la frecuencia de salida del DSPic sea de 30 KHz. a Cada efecto tiene una o dos variables.5 Funcionamiento de los efectos Como se explic´ en la secci´n Arquitectura del Sistema. Las posiciones de RAMBuffer[] 4 y 5 son s´lo en o caso de que el efecto necesite dos par´metros. por eso la interrupci´n o a o 2 de I C levanta la bandera banderaCambioEf ectos que indica que hay que actualizar los par´metros de los efectos. lo que da 1333 ciclos de reloj por sample. el esclavo llama al m´todo con el siguiente encabezado: e void grabarDato(int dato) pas´ndole como par´metro el ultimo dato generado y al m´todo a a ´ e aumentarP unteroT remolo().5. El programa tiene una variable interna por cada una de las varia ables de cada efecto. Lo primero que u hace el m´todo es detectar cual es el efecto a aplicar para saber que variables es necesario e actualizar y luego actualizarlas en base al valor de la posici´n correspondiente del vector o RAMBuffer. 86 . o 15. Cuando esta activada banderaCambioEf ectos. 15. El par´metro representa la posici´n a a a o de memoria en el vector RAMBuffer donde se encuentra el n´mero asociado al efecto u a realizar. RAM Buf f er[2] y RAM Buf f er[4] para el primer efecto y RAM Buf f er[3] con RAM Buf f er[5] para el segundo. Estos m´todos se explicar´n m´s adelante cuando se exe a a plique los efectos para los cuales sirven. significa que se modific´ alguno de los par´metros de los efectos.

5. entonces indice vale 7600 + punteroGuardar − atrasoEco. La idea del efecto eco es que la salida sea la salida que corresponde m´s una salida a anterior multiplicada por un n´mero menor a 1.5. este valor es llamado valorEco. El primer dato lo guarda en la posici´n 0. entonces indice vale punteroGuardar menos atrasoEco. siendo salidaAUtilizar el valor calculado del sample y el m´todo e eco() es el que calcula la salida anterior que hay que sumarle al sample calculado. Luego de obtener valorEco. lo que hace el m´todo iniciarEf ectos es hacer que pae raDevolver apunte a los dos bytes m´s significativos de valorLargo. se almacena el u resultado en valorLargo y se toma como resultado lo apuntado por paraDevolver. lo cual es x multiplicada por un n´mero menor a 1. del tipo unsigned int o int y luego tomar como o resultado los dos bytes m´s significativos del resultado de la multiplicaci´n.15. En la clase efectos hay una variable llamada valorLargo del tipo long int y un puntero llamado paraDevolver. Si punteroGuardar es mayor o igual a atrasoEco. La ultima posici´n del vector ultimos donde se guardo ´ o un dato se almacena en la variable punteroGuardar. lo que hace el m´todo es multiplicarlo por magnitudEco e y almacenar la salida generada en valorLargo.2 Explicaci´n del m´todo inicarEf ectos o e Este m´todo debe ser llamado una vez antes de comenzar a generar los efectos. De esta forma si a se desea multiplicar x por un n´mero menor a 1 se lo multiplica por z. el segundo en la 1 y as´ sucesivamente. Para eso genera la variable indice que corresponde a la posici´n del vector a o ultimos en la cual se encuentra el sample buscado. lo que hace es grabar los ultimos 7600 samples a ´ ´ calculados en el vector ultimos. luego de o ı grabar en la posici´n 7599 vuelve a grabar en la posici´n 0. Sirve para que el efecto eco o o tenga los datos anteriores almacenados. el multiplicador mencionado vale magnitudEco . De esta forma indice siempre es un n´mero no menor a cero y en ultimos[indice] se encuentra el u sample generado atrasoEco samples antes. Por eso el efecto eco tiene dos par´metros. De esta forma a o z u el resultado termina siendo x ∗ ( 65535 ). e En muchos casos es necesario multiplicar una variable x. del tipo int por valores menores a uno. que es un vector con capacidad para 7600 enteros del tipo int. Finalmente devuelve lo apuntado por el 87 . 65535 Cuando se desea generar el efecto eco se ejecuta el siguiente comando: salidaAU tilizar = salidaAU tilizar + eco(). u a uno llamado atrasoEco que es la cantidad de samples que esta atrasada la se˜al que se le n suma a el sonido generado y otro par´metro llamado magnitudEco que es una variable a del tipo unsigned int. las pruebas que realizamos nos dejaron como experiencia que la forma m´s f´cil de hacer esta multiplicaci´n es guardar en una variable del tipo long int la a a o multiplicaci´n de x por una variable z. 15. si punteroGuardar es menor a atrasoEco.3 Funcionamiento del efecto Eco El m´todo void grabarDato(int dato) graba el dato que se le pasa como par´metro en e a el vector ultimos. Como a este m´todo se lo utiliza pas´ndole como e a par´metro el ultimo sample calculado. Lo primero que hace el m´todo eco es obtener el sample generado atrasoEco same ples atr´s.

o El m´todo que se utiliza para aplicar este efecto es el m´todo: int tremolo(int e e valorActual) que recibe como par´metro el ultimo sample calculado y devuelve ese sample a ´ multiplicado por el valor correspondiente de la m´scara. la salida generada no ser´ el resultado a de aplicar dos veces este efecto. Dado que largo del vector ultimos es de 7600 samples y como Fs es igual a 30 khz. en caso de que punteroTremolo sea mayor o igual a 15000 u (largo de la tabla de seno) hace la operaci´n punteroTremolo=punteroTremolo-15000. El valor que se toma de esta tabla es el valor seno[punteroT remolo].4 Funcionamiento del efecto tr´molo e Lo que hace este efecto es multiplicar el sonido generado por una onda sinusoidal m´s una a constante. Si magnitud a u tr´molo vale 0. La variable punteroTremolo se inicia en cero y luego de calcular cada sample se llama al m´todo e aumentarPunteroTremolo que lo que hace es sumarle a la variable punteroTremolo el n´mero f recuenciaT remolo. a 88 . si vale 1 la frecuencia de la sinusoidal es 2Hz y si vale 9 la frecuencia es 18Hz. En la imagen 25. uno llamado f recuenciaT emolo que es un n´mero entre a u 1 y 9. el m´ximo atraso posible del eco es de 253 ms. no es posible utilizar como n primer y segundo efecto el eco. se puede observar como es la funci´n por a o la que es multiplicada el sonido para varios casos de magnitudT remolo.5. El otro par´metro es llamado magnitudT remolo que es un n´mero entre 0 y 63. Tiene dos par´metros. Imagen 25: Gr´fica de los multiplicadores que se aplican a la se˜al en el efecto tr´molo a n e Los valores para la funci´n seno que se utilizan en la m´scara se obtienen de la o a tabla seno que tambi´n se utiliza para obtener los senos para generar los sonidos de las e notas. entonces la salida se deja tal cual es la entrada. si vale 63 se la multiplica e por una sinusoidal pura y si vale un valor intermedio entre ambos se la multiplica por una sinusoidal m´s una constante. si se intenta hacer.vector paraDevolver. a Como consecuencia de la forma de dise˜o de este efecto. 15.

El primer paso es calcular el valor de la m´scara, lo que hace es calcular el valor a de la m´scara multiplicado por 65535 mediante la siguiente f´rmula: intmultiplicador = a o (seno[punteroT remolo] − 512) ∗ magnitudT remolo + 32256 (la tabla seno tiene un rango del -511 al 511). Luego multiplica valorActual por multiplicador y almacena el resultado en valorLargo, finalmente devuelve el valor apuntado por el vector paraDevolver.

15.5.5

Funcionamiento del efecto wah-wah

Este efecto lo que hace es pasar el sonido generado por un filtro pasabajos de frecuencia de corte variable. Dicha frecuencia de corte es modificada al mover uno de los potenci´metros. o El filtro a utilizar es un filtro pasabajos Butterworth digital de segundo orden. , donde y(n) La funci´n del filtro es la siguiente: o es la salida n´mero n, x(n) es la entrada n´mero n y f0 es la frecuencia de corte dividido u u la frecuencia de salida, es un n´mero que var´ entre 0 y 0,5. En este caso la entrada es u ıa el sonido generado y la salida el sonido filtrado. Para facilitar las cuentas decidimos pasar todos los n´meros a enteros, por lo que en u la expresi´n de y(n) multiplicamos tanto el divisor como el dividendo por 16384=128*128, o por lo que qued´: o √ y(n − 1) ∗ (32768 + (128 ∗ 2) ∗ (128 ∗ f0 )) − 16384 ∗ y(n − 2) + (128 ∗ f0 )2 ∗ x(n) √ y(n) = 16384 + (128 ∗ 2) ∗ (128 ∗ f0 ) + (128 ∗ f0 )2 Dado que es m´s f´cil manejar n´meros enteros que reales, decidimos utilizar como a a u par´metro del m´todo la variable frecCorte que vale 128*f0 , de esta forma frecCorte es a e un par´metro que si vale cero indica que la frecuencia de corte es 0 y si vale 64 indica que a la frecuencia de corte es 0,5. La f´rmula del filtro queda de la siguiente forma: o
√ y(n − 1) ∗ (32768 + (128 ∗ 2) ∗ (frecCorte)) − 16384 ∗ y(n − 2) + (frecCorte)2 ∗ x(n) √ y(n) = 16384 + (128 ∗ 2) ∗ (frecCorte) + (frecCorte)2
√ 2 y(n−1)∗(2+ 2∗f0 )−y(n−2)+f0 ∗x(n) √ y(n)= 2 1+ 2∗f0 +f0

Dado que los posibles valores de frecCorte son 64 (del 0 al 63, si se quiere tomar el valor 64 es lo mismo que no aplicar el filtro), para ahorrar tiempo de procesamiento se agreg´ una tabla llamada fCuadrado que indica para cada frecCorte cuanto vale al o cuadrado. Como el dividendo de la funci´n de y(n) no depende de la entrada ni de las o salidas anteriores, se agreg´ tambi´n una tabla llamada diviWah que indica para cada o e frecCorte cuanto vale el divisor. La variable y(n-1) tambi´n esta multiplicada por una e expresi´n que solo depende de frecCorte, por lo que tambi´n creamos una tabla llamada o e parteMultiplicadores que para cada valor de frecCorte devuelve el valor de dicha expresi´n. o Entonces el filtro queda:
y(n) = y(n − 1) ∗ (parteM ultiplicadores[f recCorte]) − 16384 ∗ y(n − 2) + (f Cuadrado[f recCorte]) ∗ x(n) diviW ah[f recCorte]

89

Para implementar esta cuenta decidimos que primero valorLargo tome el valor del divisor, al dividirlo entre el dividendo notamos que la operaci´n tomaba cerca de 400 o ciclos de reloj, lo cual nos pareci´ incoherente dado que la hoja de datos dice que las o divisiones de este tipo deber´ tomar 17 ciclos m´s lo que tome pasar las variables a los ıan a registros correspondientes. Decidimos crear la funci´n asmFunction que esta dentro de la o clase call2.s para que realice esta divisi´n, de esta forma la divisi´n si tom´ los ciclos eso o o tipulados. La p´gina web de microchip indica que la versi´n gratuita para estudiantes del a o compilador de lenguaje ‘C’ para DSPic no posee todas las optimizaciones implementadas, suponemos que esta fue la causa del problema. Es posible que para cierta combinaci´n de valores, el dividendo de la expresi´n de o o y(n) supere los 32bits (largo de la variable valorLargo), por eso decidimos antes de pasar los valores por el filtro dividirlos todos entre 4 y luego multiplicar el resultado final por 4.

15.5.6

Funcionamiento del efecto limitador if

Este es un efecto de saturaci´n que simplemente pregunta si el sample es mayor a max, o si es devuelve max, si es menor a menos max devuelve menos max y si esta entre max y menos max devuelve el valor del sample.

15.5.7

Funcionamiento del efecto limitador logar´ ıtmico

Este es un efecto de saturaci´n que intenta imitar la saturaci´n de un amplificador. Si o o se dispone de una se˜al x(t) que esta entre -1 y 1, la ecuaci´n de este limitador ser´ n o ıa: 3 y(t) = x(t) − A ∗ (x(t)) , siendo A un par´metro entre 0 y 1/3. Dado que nuestra se˜al de a n sonido esta entre -32768 y 32767, para aplicar el efecto ser´ necesario normalizar la se˜al ıa n X(t)3 X(t) por lo que la ecuaci´n del limitador quedar´ y1 (t) = 32768 − A 327683 , siendo X(t) nuestra o ıa se˜al de sonido. Este limitador esta dise˜ado para entradas y salidas normalizadas a 1, n n como queremos que nuestra salida este normalizada a 32768, entonces hacemos: y2 (t) = 32768 ∗ . Como no queremos manejar fracciones creamos un par´metro llamado limiteLog que a vale 32768*A, de esta forma tenemos que: X(t)3 y3 (t) = X(t) − limiteLog 327683 . La funci´n que aplica el limitador logar´ o ıtmico es la funci´n int limitadorLog(int o valorActual), donde valorActual es el valor del ultimo sample, y devuelve y3 siendo X(t) ´ valorActual.
X(t) Lo primero que hace el m´todo es calcular el valor de limiteLog 327683 , para eso e aplica la siguiente operaci´n: valorLargo=X(t)*X(t), luego hace que valorLargo sea lo o
3

X(t) X(t)3 −A 32768 327683

90

X(t) apuntado por el vector paraDevolver, de esta forma valorLargo pasa a valer 65536 . Despu´s e hace la siguiente operaci´n: valorLargo=valorLargo*X(t) y vuelve a hacer que valorLargo o X(t)3 valga lo apuntado por paraDevolver, de esa forma valorLargo pasa a valer 655362 . La pr´xima operaci´n es: valorLargo=valorLargo*limiteLog, de esa forma lo apuntado por o o 3 paraDevolver vale valorLargo∗X(t) , finalmente devuelve: X(t) menos 8 por lo apuntado por 3 65536 paraDevolver.

2

15.5.8

Explicaci´n del efecto vibrato o

Este efecto lo que hace es modificar las frecuencias de la salida de audio, para eso lo que hace es modificar la frecuencia de generaci´n de datos de la salida anal´gica. o o Este efecto tiene un par´metro llamado ValorVibrato que es un n´mero del 0 al 127 a u que depende de la posici´n del potenci´metro asociado al primer par´metro del efecto. o o a Para lograr modificar la frecuencia del DAC, lo que hace es fijarse si la variable ValorVibrato es mayor a 85, si es aumenta la frecuencia de salida de audio, si es menor a 40 disminuye la frecuencia de salida de audio y si esta entre 40 y 85 la mantiene.

15.6

Explicaci´n de las funciones actualizarParametrosEfectos o y aplicarEfectos

Las dos funciones comienzan fij´ndose en base a la posici´n de RAMBuffer que se le pase a o por par´metro que efecto hay que aplicar. Luego la funci´n aplicarEfectos aplica el efecto a o y la funci´n actualizarParametrosEfectos actualiza los par´metros del efecto. o a Ambas funciones son llamadas primero con par´metro 6 y luego con 7, esto se debe a a que esas son las posiciones de la memoria RAMBuffer donde se almacenan los n´meros u asociados a los efectos a reproducir. La tabla 7 muestra que n´mero tiene asociado cada u efecto. N´mero u 0 1 2 3 4 5 6 Efecto asociado No aplicar efecto Tr´molo e Wah-Wah Limitador if Limitador log Eco Vibrato

Tabla 7: N´mero asociado a cada efecto u

91

15.7

Funcionamiento del m´todo main e

Este es el m´todo principal, es el que se ejecuta al iniciarse cada esclavo. Comienza e iniciando todas las herramientas del pic que van a ser utilizadas e inicializando todas las variables. Tambi´n inicializa el puntero salida que es un puntero a una variable del tipo e int para que apunte a los dos bytes m´s significativos de salidaLong, de esta forma lo a apuntado por salida son los datos que hay que emitir por la salida anal´gica. o Una vez realizadas las inicializaciones, el m´todo ingresa en un bucle infinito el cual e primero calcula la salida mediante el m´todo calcularSample, luego graba el dato para e que pueda ser utilizado por el efecto eco y tambi´n aumenta el puntero para el efecto e tr´molo, despu´s le aplica los efectos a los sonidos generados y espera a que la cola de e e espera de la salida anal´gica (DAC) tenga un lugar libre para insertar el dato que gener´. o o Finalmente se chequea si es necesario actualizar los datos de los par´metros o si hay una a nota nueva para generar, en ambos casos llama al m´todo necesario para hacer la acci´n. e o

92

16
16.1

Documentaci´n del programa interfaz o
Introducci´n al manejo del programa interfaz o

Una vez configurados los pics y todo el hardware es necesario generar un software en PC con la capacidad de comunicarse con nuestro sistema embebido y de transmitir tablas con descripciones del funcionamiento de instrumentos musicales. La idea del software es que maneje el protocolo de comunicaci´n del sintetizador para poder trasmitir instrumeno tos. Debe permitir que el usuario transmita una tabla de datos que gener´ indicando la o descripci´n de un instrumento. o El siguiente objetivo ser´ lograr que el mismo software provea al usuario de una ıa herramienta relativamente sencilla para la generaci´n de instrumentos virtuales. Dicha o herramienta deber´ permitirle al usuario generar cada una de las notas del instrumento, ıa esto significa seleccionar las frecuencias arm´nicas junto con sus envolventes. As´ mismo o ı tambi´n deber´ permitir al usuario escuchar los sonidos generados antes de transmitirlos e ıa al dispositivo.

16.2

Estructura del programa

El programa tiene tres modos b´sicos: manejo de envolventes, transmisi´n de instrumentos a o y el de generaci´n de instrumentos. El modo de manejo de envolventes, es el que permite o dise˜ar envolventes para luego poder aplic´rselas a las frecuencias de una nota. Este n a modo tambi´n permite guardar y abrir las envolventes. El modo trasmisi´n permite e o trasmitirle al dispositivo descripciones de instrumentos previamente generadas ya sea con nuestro programa o con cualquier otro siempre y cuando estas descripciones est´n en el e formato correspondiente, dicho formato se describe m´s adelante. El modo generaci´n a o de instrumentos permite generar instrumentos en un formato que f´cilmente se puede a transmitir al sintetizador. Este modo tambi´n permite guardar los instrumentos, abrirlos e y escuchar los sonidos generados.

16.3
16.3.1

Aspectos t´cnicos del programa e
Lenguaje utilizado

Decidimos realizar este programa con el lenguaje Visual Basic simplemente por que este es el lenguaje que mejor manejamos, es un lenguaje que permite realizar todas las funciones que precisamos para el programa y existe en internet mucha ayuda disponible.

16.3.2

Caracter´ ısticas extras

En la programaci´n del software se le agregaron caracter´ o ısticas a algunas clases que no se usan como por ejemplo una foto asociada a los instrumentos. Dichas caracter´ ısticas

93

fueron agregadas en caso de que en un futuro se le deseen agregar funciones adicionales al software. 94 .

Todos los n´meros deben ser ingresados en el formato en el cual este configurado el PC. copie el archivo “Interfaz de comunicaci´n o con el sintetizador. esto abrir´ una o a ventana llamada “Manejo de envolventes”.3 Crear un instrumento nuevo Para crear un instrumento nuevo.17 Manual de instrucciones del programa interfaz de comunicaci´n o Comenzando con el programa 17. as´ ı a ı como guardar y abrir otras envolventes. a a 17. haga clic en el bot´n “Crear o instrumento”.ico” a la ruta deseada. Este programa se adapta al idioma local donde se ubique el usuario.1 Para ejecutarlo se hace un doble clic sobre el archivo “Interfaz de comunicaci´n con el o sintetizador. El programa comienza mostrando una ventana llamada “Ventana inicial” desde la cual se puede acceder a todas las funciones del programa. Dicha ventana se muestra en la imagen 26. Esta ventana se explicar´ m´s adelante. all´ se podr´n crear envolventes desde cero. en la “Ventana inicial”.2 Ingreso al modo Manejo de Envolventes Para ingresar a este modo haga clic en el bot´n “Manejo de envolventes”.exe” junto con el archivo ”nota musical. u Imagen 26: Screenshot de “Ventana inicial” 17.exe”. al programa le toma aproximadamente un minuto la creaci´n del nuevo o 95 . Si desea copiar el programa.

Dicha ventana se explicar´ m´s adelante. Se puede observar una barra que indica el estado de la creaci´n del instruo mento. luego se abrir´ una ventana que permitir´ seleccionar el instrumento que se a a desea abrir. se abrir´ una ventana con el nombre “Manejo a a del instrumento” que es la que permite trabajar en el instrumento. a a 17.5 Uso de la ventana “Manejo de envolventes” Como se indico anteriormente. La creaci´n puede ocasionar que la ventana no responda durante el proceso. Los instrumentos que se pueden abrir son s´lo aquellos con extensi´n “. o o Una vez seleccionado un instrumento v´lido. abrir y guardar instrumentos. esta es la ventana que sirve para la creaci´n y edici´n de o o envolventes. en la imagen 27 se muestra como se ve inicialmente.instrumento. o Cada instrumento nuevo generado ya contiene todas sus notas y cada nota sus envolventes y frecuencias.inst”. Imagen 27: Screenshot de “Manejo de envolventes” al iniciar la ventana 96 . haga clic en el bot´n “Abrir instrumento” de la ventana o principal.4 Abrir instrumentos Para abrir un instrumento. Una vez creado el instrumento nuevo se abrir´ una ventana con el nombre “Manejo a del instrumento” que es la que permite modificar. 17.

Si desea comenzar a dise˜ar de nuevo la envolvente puede hacer clic en el bot´n n o reiniciar. para eso en el men´ edici´n haga clic en la opci´n “Crear extrapolando otras dos envolu o o ventes por promedio”. En el eje X cada unidad esta expresada en “samples”. etc.5. en el grupo “Valor a modificar” seleccione el n´mero de punto que desea modificar. siendo el 1 el primer punto u luego del valor inicial y el 6 el ultimo punto. entonces el valor inicial de la 97 . o a En la imagen 28 se muestra una toma de pantalla de una envolvente con todos sus puntos definidos. El programa no a permitir´ que a un mismo valor del eje de las X le correspondan dos o mas valores distintos a en el eje de las Y. Si lo desea. Si el valor que se desea ingresar es mayor al m´ximo valor de la gr´fica en el eje Y. y luego haga clic en la gr´fica en el lugar ´ a donde desea reubicar el punto. Por ejemplo si una envolvente a a tiene valor inicial 1 y la otra 2.17. N´tese que si el puntero del mouse se ubica sobre la gr´fica. se abrir´ una ventana que permite seleccionar la ruta donde est´n a a almacenadas las envolventes que desea extrapolar y el valor del “peso” con el que cada una ser´ considerada. Recuerde que cada a envolvente puede tener como m´ximo 6 puntos aparte del valor inicial. y los dos pesos son iguales. primero es a a necesario modificar el m´ximo valor del eje Y en la gr´fica. Observar´ que el proa grama va formando la gr´fica de la envolvente resultante. Como la frecuencia de salida de sonido del sintetizador es de 30 KHz. en la esquina inferior o a derecha de la ventana se indica en que posici´n exacta de la gr´fica se encuentra el puntero. un valor de 30000 en el eje de las X corresponde a 1 segundo. Para modificar alguno de los puntos de una envolvente. cuanto mayor sea el peso de una envolvente respecto a de la otra m´s ser´ considerada al realizar el promedio. Por esa raz´n es que el programa permite generar envolventes que resulten de la extrapolaci´n de o o otras dos. es decir muestras de sonido.5. Si los pesos son iguales se realiza un promedio ponderando igualmente a los valores de una y de otra m´scara. es posible modificar los m´ximos valores de los ejes X e Y. para eso ingrese el nuevo a a m´ximo valor deseado en el cuadro de texto a la derecha de la etiqueta “YM´ximo” y a a luego haga clic en confirmarY. 17.1 Crear una nueva envolvente de forma simple Para crear una envolvente de forma simple primero se debe indicar el valor inicial de la envolvente en el cuadro correspondiente. para que este valor sea aceptado. el valor 15000 a medio segundo. Una de las formas de extrapolar envolventes es promediando dos que ya se tienen. como se menciono a antes.2 Crear envolventes mediante extrapolaci´n de otras envolventes o Muchas veces se desea generar envolventes similares a otras que ya se tienen. Una vez fijado el valor inicial simplemente haga clic en la gr´fica en los siguientes a puntos por donde desee que pase la envolvente que esta creando.

a Para lograr la opci´n deseada en el ejemplo anterior el procedimiento es muy similar o al de crear extrapolando por promedio. se toman un tiempo a a bajo volumen y luego aumentan el volumen. pero en lugar de hacer clic en la opci´n “Crear o extrapolando por promedio”. pero si el peso de la primer m´scara es mayor.5. Hay un ejemplo de dos a m´scaras ponderadas con este tipo de ponderaci´n en el cd adjunto.5. hay que seleccionar la opci´n “Crear extrapolando”. a o Si se dispone de una envolvente que comienza con altos valores al comienzo y al final valores bajos y de otra que comienza con bajos valores y al final toma altos valores. en el medio disminuye y al final vuelve a tomar valores medianos. se muestra una toma de pantalla de la ventana que le permite seleccionar los par´metros de la extrapolaci´n. a o 17.Imagen 28: Screenshot de “Manejo de envolventes. si no m´s bien sonidos que a a tengan cualidades intermedias de entre los dos. a o En la imagen 29 . con una envolvente ya dise˜ada” n envolvente resultante ser´ de 1. entonces a a el valor inicial de la envolvente resultante estar´ entre 1 y 1. la extrapolaci´n por promedio de ambas envolventes generar´ una envolvente que tenga o ıa valores medianos al principio. pero que no sean promedio de las dos m´scaras. Hay o un ejemplo de dos m´scaras poderadas con este tipo de ponderaci´n en el cd adjunto. es decir que no se tomen tanto tiempo como la segunda envolvente para llegar a su m´ximo.3 Herramientas utiles para la creaci´n de envolventes ´ o Cambiar la imagen de fondo del panel 98 .5. Muchas veces se busca generar sonidos intermedios. pero que tampoco comiencen con a su m´ximo. Estas dos m´scaras mencionadas anteriormente corresponden a sonidos que a comienzan altos y se apagan r´pido y a sonidos que comienzan bajos.

una de a las herramientas de Scilab (que se explica m´s adelante) permite generar en base a un a sonido en formato . De esta forma se puede poner la gr´fica que se desea copiar de a fondo y copiarla m´s f´cil.5. 17. Para facilitar a la copia de la gr´fica.Imagen 29: Screenshot de la ventana que permite configurar la extrapolaci´n o Es posible que ya se tenga la gr´fica de la envolvente que se desea generar.masc”. dentro del men´ o u “Archivo” y luego elija la ruta de la envolvente a abrir en la ventana de selecci´n de o 99 . Al hacer clic una de ellas se abre una ventana en la cual se le permite ingresar la constante por la que desea multiplicar el eje.5 Abrir envolventes Para abrir una envolvente simplemente haga clic en la opci´n “Abrir”. puede hacer clic en la opci´n “Cambiar imagen de fondo”. Imagen 30: Screenshot de la ventana para ingresar la escala 17. a o a En caso de que ya se haya guardado alguna vez la envolvente. La imagen 30 es una toma de pantalla de esa ventana. dentro a o del men´ “edici´n”.4 Guardar envolventes Para guardar una envolvente generada haga clic en la opci´n “Guardar Como” en el men´ o u “Archivo”. al hacer clic en la opci´n “Guardar” en el men´ “Archivo” la envolvente se guardar´ en la ultima ruta donde o u a ´ haya sido guardada. La extensi´n de las envolventes ser´ “. luego seleccione la ruta donde desea guardar la envolvente en la ventana que aparecer´ . a a Multiplicar los ejes por constantes Estas herramientas se encuentran en el men´ “edici´n” y sirven para multiplicar u o las coordenadas x e y de todos los puntos de una envolvente por una constante num´rica e mayor a cero.wav gr´ficas con cada una de las envolventes de la nota. esta herramienta permite cambiar el fondo del panel donde se genera u o la envolvente por otro.5.

se abrir´ un dialogo que le permite o a seleccionar un instrumento a enviar.archivo que se abrir´. Para eso haga clic en el e bot´n “chequear puertos”. siendo X el puerto serie solicitado. De la lista de puertos serie disponibles seleccione el puerto serie en el cual esta conectado el sintetizador y luego haga clic en el bot´n “conectar”. esa acci´n abrir´ una ventana llamada “Ventana de transmisi´n”. El instrumento que desee enviar. Si el proceso fue o correctamente realizado. se recomienda cerrar todos los programas que pueden estar interfiriendo y volver a intentar. a Una transmisi´n correcta tarda unos 5 minutos aproximadamente. haya resultado esta correcta o no. esto provoca que se genere la lista de puertos serie que est´n o a disponibles en la PC. o No se deben abrir dos ventanas de transmisi´n simult´neamente. dicho protocolo se explica m´s adelante. si este es el caso se puede observar una etiqueta que dice “esta conectado con el puerto X”. Imagen 31: Screenshot de la ventana de trasmisi´n de instrumentos o El primer paso a realizar dentro de la “Ventana de transmisi´n” es seleccionar el o puerto serie a trav´s del cual esta conectado el sintetizador. debe ser un archivo con la extensi´n “. luego de concluo ida se informa al usuario si ha terminado correctamente o no. o a el programa puede experimentar fallas importantes. Una vez conectado en el puerto serie correspondiente. el cual este organizado seg´n el protocolo de transmisi´n ya o u o establecido. en caso de hacerlo. 100 .6 Manejo del modo transmisi´n de instrumentos o Para ingresar a este modo. No es necesario pero se recomienda reiniciar el PC luego de cada transmisi´n. a 17. para enviar un instrumento haga clic en el bot´n “Mandar un instrumento”.hex”. el programa y el sintetizador ya se encuentran conectados. dentro de la ventana inicial ingrese en la opci´n “Transmitir o Instrumento”. En algunos casos el proceso de conexi´n falla. si los problemas persisten se recomienda reiniciar la PC y volver a intentar. o a o La imagen 31 muestra una toma de pantalla de la ventana de transmisi´n de inso trumentos. o esto se debe probablemente a que hay otro programa utilizando el mismo puerto serie.

“Guardar”. “Exportar Instrumento” y “Salir”. La imagen 32 muestra una toma de pantalla de la ventana de manejo de instrumento. La barra superior u contiene unicamente el men´ “Archivo”. El formato “. es decir 101 .7 Ventana Manejo del instrumento Esta ventana consta de una barra de men´ superior y tres paneles.hex”. Los tres paneles que contiene la ventana “Manejo ´ u del instrumento” son: “Editar cada envolvente”. Opci´n “Abrir” o La opci´n “abrir” sirve para abrir otro instrumento.17. “Edici´n com´n a todas las envolventes” o u y “Probar las notas generadas”. a a Opciones “Guardar” y “Guardar Como” Los instrumentos se pueden guardar tanto en formato “. A continuaci´n se explica cada una o de estas opciones. ”Guardar Como”.7.inst” es el que guarda un instrumento completamente. se le preguntar´ primero si o a confirma que desea abrir otro instrumento en lugar del que esta trabajando y luego se le presentar´ una ventana en la cual podr´ seleccionar el instrumento a abrir.1 Barra superior El men´ “Archivo” consta de las opciones “Abrir”.inst” como en formato “. Imagen 32: Screenshot de la ventana de manejo de instrumento 17. ”Imu portar desde hex”.

este formato es un formato m´s sencillo.hex”. puede llegar a tomar varios a minutos dependiendo del procesador del PC. o 17. si bien se puede guardar con una extensi´n distinta a “. e 102 . Es a o posible que la PC no responda durante el proceso de importaci´n. siendo X el arm´nico que el cuadro representa. para editar una nota. La barra de desplazamiento que se encuentra debajo de dichos cuadros es la que permite trasladarse para que los cuadros representen otro de los quince componentes. En la ventana “manejo de instrumento” se observa un dibujo de las teclas de un piano en la parte superior. La opci´n “guardar como” o es la que se usa para guardar instrumentos en el formato “.hex”.2 Editar cada envolvente Este es el panel que sirve para editar cada nota por separado sin generalizar ni copiar elementos de otra nota.con todos los nombres y valores de cada componente. su manejo es igual al de la funci´n “guardar como”. La opci´n “Guardar” sirve para guardar el instrumento en la ultima ruta donde o ´ halla sido guardado. el n´mero de componente se indica en la parte superior de u cada cuadro.inst”. haga clic sobre la tecla correspondiente a esa nota en dicho dibujo. o Los cuadros tambi´n cambian de color dependiendo de la componente que representan. obs´rvese que el n´mero de nota aparece e u debajo del dibujo del piano. contiene s´lo algunas herramientas o o para que el sintetizador pueda deducir como generar la nota. Notar´ que en la esquina inferior derecha a de la pantalla aparecer´ una barra indicando el progreso del proceso de importaci´n. La apertura de este tipo de archivo no es instant´nea. en caso de que nunca halla sido guardado la opci´n “Guardar” es o equivalente a la opci´n “Guardar Como”. al hacer clic en ella se abrir´ una ventana en la cual se le permite seleccionar la ruta donde se desea guardar el a instrumento. que s´lo a o contiene la informaci´n que el sintetizador necesita. o Opci´n “salir” o La opci´n “salir” es para cerrar la ventana. donde dice “frecuencia NºX”. El formato “. en cada uno de ellos se puede trabajar cada e uno de los 15 componentes de la nota. Como se describi´ anteriormente. junto con un espacio que permite asignarle un nombre a dicha nota. o Opci´n “exportar instrumento” o La opci´n “exportar instrumento”. cada nota tiene quince componentes de frecuencia o cada uno con su respectiva envolvente.hex” no guarda nombres ni imagen es de cada nota. sirve para guardar el instrumento que se esta o realizando en formato “.inst” es recomendable o que se guarde con esta extensi´n. La tecla seleccionada del dibujo del piano pasa a tener un color rojo.7. dicho panel tiene un color de fondo que var´ con la nota que se este ıa tocando y tiene tambi´n tres cuadros iguales. es la que se utiliza para poder abrir archivos o “. Si se desea guardar un instrumento para luego volver a o abrirlo con este software es recomendable guardarlo con las opciones “Guardar Como” y “Guardar”. o Opci´n “Importar desde hex” o La opci´n “importar desde hex”. Una vez elegida la nota seleccione el panel “Editar cada envolvente”.

Si se desea utilizar esta herramienta ingrese el ıa o n´mero de nota que desea tomar como primer referencia en el cuadro de texto que se ubica u 103 . a En este panel se dispone de la posibilidad de asignar todas las envolventes de un cierto rango de notas extrapolando las envolventes de otras notas. Para modificar un multiplicador escriba el valor deseado en el cuadro de texto que se encuentra a la izquierda del bot´n “aplicar multiplicador” en el cuadro correspondiente a la componente o deseada y haga clic en el bot´n “aplicar multiplicador”.Para modificar la frecuencia de una de las componentes cambie el valor del cuadro de texto que se encuentra a la derecha del texto “frecuencia NºX” por el valor deseado y haga clic en el bot´n “aplicar valor” que se encuentra a la derecha del cuadro de texto. Para asignarle a una componente una envolvente que ya haya sido creada y este guardada. Se abrir´ una ventana en la cual podr´ a a seleccionar la envolvente que desea asignarle a la componente. que es un n´mero por el cual va e u a ser multiplicado su eje de las Y. la n´mero 1 es la extrapolaci´n por promedio o u u o ya explicada en la explicaci´n de la ventana “Manejo de envolventes” y la n´mero 2 es la o u otra extrapolaci´n ya explicada en la explicaci´n de la ventana “Manejo de envolventes”. o 17. Para eso en el cuadro de texto que se ubica a la derecha del texto “Generar por extrapolaci´n desde la” ingrese el n´mero de componente que tiene la envolvente que o u desea tomar como primer referencia para la extrapolaci´n y en el cuadro de texto que se o encuentra a la derecha del texto “hasta la” ingrese la componente que tiene la envolvente que desea tomar como segunda referencia para la extrapolaci´n. a a Cada envolvente.7. La funci´n es que se pueda f´cilmente aumentar y o a reducir la influencia de una frecuencia en el resultado final de una nota.3 Edici´n com´ n a todas las envolventes o u Este panel es el que sirve para editar envolventes pero. Para aplicar los cambios haga clic en el bot´n “aplicar a o cambios”. pero s´ todas las componentes intermedias entre ambas. cuanto m´s a ı a cercana este una componente a la componente 2 m´s parecida ser´ a esta y cuanto m´s a a a cercana este a la componente 10. o o Si por ejemplo se toman como referencia las componentes 2 y 10. o haga clic en el bot´n “Editar envolvente” que tambi´n se encuentra en el mismo cuadro que la o e componente que desea modificar. Luego seleccione si la o extrapolaci´n deseada es la n´mero 1 o la 2. Este panel tambi´n cuenta con la posibilidad de generar envolventes para una come ponente en base a la extrapolaci´n de dos envolventes de otras componentes de la misma o nota. dichas envolventes no ser´n modificadas. haga clic en el bot´n “abrir envolvente de archivo” que se encuentra en el o cuadro que representa la envolvente deseada. haga doble clic en la gr´fica a que aparece debajo de la componente cuya envolvente se desea modificar. Se abrir´ una ventana de “manejo de envolventes” en la a cual podr´ modificar la envolvente. tambi´n tiene un multiplicador. El resultado es que para todas las notas del rango a extrapolar la envolvente de cada componente es el resultado de la extrapolaci´n de las envolventes con el mismo n´mero de envolvente pero de las notas o u tomadas como gu´ para la extrapolaci´n. o Para editar la envolvente de una de las componentes. a diferencia del panel anterior. editarlas en base a las envolventes de otra nota y no editando cada par´metro por separado. m´s parecida ser´ a esta otra.

existe tambi´n e la opci´n de generar la lista de frecuencias de un rango de notas por extrapolaci´n o o logar´ ıtmica. A su vez. Al finalizar esta operaci´n aparecer´ un cartel indicando o a el resultado de la operaci´n.a la derecha del texto correspondiente a la extrapolaci´n que desea generar y la segunda o nota que desea tomar como referencia en el cuadro de texto que se ubica a la derecha del texto “hasta la nota” en la misma l´ ınea y luego haga clic en el bot´n “Extrapolar” que se o encuentra en esa l´ ınea. a a Para normalizar un rango de notas. debe seleccionar la carpeta donde desea almacenar los sonidos en el cuadro de texto que se ubica a la derecha del texto “Guardar en la carpeta”. se selecciona ´ el rango de notas que desea normalizar y se hace clic en el bot´n “normalizar”. a o Dado que por lo general dos notas no tienen las mismas frecuencias. Al hacer clic en ese bot´n o o se abre un cuadro que permite indicar donde se desea guardar el archivo “. es decir modificar los multiplicadores de cada una de las envolventes para que el sonido de la nota tenga un volumen optimo. o En la imagen 33. La operaci´n de extrapolaci´n de notas puede tardar o o varios minutos dependiendo de la velocidad del PC que se este usando y de la cantidad de notas que se deseen generar. Tambi´n se puede copiar todas las envolventes de una nota y asign´rselas a las e a componentes de otro rango de notas. e El panel tambi´n dispone de la posibilidad de copiar frecuencias que se utiliza de e forma an´loga a la opci´n de copiar envolventes. no modifica las o o o frecuencias. Las extrapolaciones que se realizan son iguales a las explicadas en la ventana “manejo de envolventes”. puede usar el bot´n explorar que abre una ventana o 104 . Luego para aplicar los cambios haga clic en el bot´n “copiar”. El manejo de dicha opci´n es igual al de la opci´n de extrapolaci´n de o o o envolventes. El bot´n “generar sonido” permite generar el sonido de la nota que se encuentra o indicada en el cuadro de texto a la izquierda de dicho bot´n. o u 17. Para eso seleccione el n´mero de nota del que desea u copiar las envolventes en el cuadro de texto que se ubica a la derecha del texto “copiar las envolventes de la nota” e ingrese los n´meros correspondientes al rango de notas en u el que desea pegar los resultados en los otros dos cuadros de textos que hay en la misma l´ ınea. o Tambi´n se puede generar los sonidos de un rango de notas. se muestra una captura de pantalla de la ventana “Manejo de instrumentos”. el resultado s´lo modifica frecuencias y no envolventes. con el panel “Edici´n com´n a todas las envolventes” abierto. Este proceso puede o tardar varios minutos.7.4 Probar las notas generadas Este panel sirve para normalizar notas. para evitar que su volumen sea muy bajo o tan alto que no se puedan reproducir y tambi´n para probar los sonidos generados por las e notas. Esta extrapolaci´n s´lo genera envolventes. aparecer´ un cartel indicando el resultado de la operaci´n cuando a o ´sta finalice.wav” que contendr´ el sonido que generar´ la nota. para eso seleccione el e rango de notas en los cuadros de texto correspondientes.

Se puede generar un instrumento con el software dise˜ado n y luego transmitirlo.hex” respecto a los “. Las dos opciones que permiten generar sonidos. Los archivos “.8 Formato de los archivos para enviarle al sintetizador Para hacer m´s f´cil la transmisi´n de instrumentos a nuestro sistema embebido. con el panel “Probar notas generadas” seleccionado.Imagen 33: Screenshot de la ventana para la edici´n com´n a todas las envolventes o u que facilita la selecci´n de la carpeta.inst” es que son m´s f´ciles de generar y es posible generarlos a partir de otras formas que con nuestro a a 105 . Existe a o su vez una tercera forma que consiste en conocer el protocolo de comunicaci´n para la o recepci´n de instrumentos del sintetizador y transmitirle por cuenta propia el instrumento. 17. Tambi´n puede modificar la duraci´n de las notas o e o generadas modificando el valor del cuadro que se ubica a la derecha del texto “duraci´n o en milisegundos”. o Como ya se mencion´ anteriormente la ventana de “transmisi´n de instrumentos”. La imagen 34 muestra una captura de imagen de la ventana “Manejo del instrumento”.hex” son archivos con mucha menos informaci´n y que ocupan mucho menos espacio que los o archivos “. esta se a a o puede hacer a varios niveles. La ventaja de los archivos “.inst”. Tambi´n se puede generar de otra forma un instrumento y transe mit´ ırselo al sintetizador mediante la ventana “Transmisi´n de instrumentos”. previo a la generaci´n normalizan o las notas que van a generar.hex” y los transmite al sintetizador. o o recibe instrumentos en formato “.

o Primero se presenta de la primer nota la primer frecuencia dividido dos. El orden es el mismo que para las frecuencias. sin espacios. luego la primer frecuencia de la segunda nota dividido dos y se procede de esa forma hasta llegar a la ultima frecuencia de la ultima nota.hex”.hex” generados se puedan escuchar correctamente en el sintetizador.Imagen 34: Screenshot de la ventana con “Probar notas generadas” seleccionado software.hex” y mediante la ventana “transmisi´n de instrumentos” o transmit´ ırselos al sintetizador. De esta forma cualquier otro programador puede dise˜ar el software que desee n para generar instrumentos “. luego el de la segunda envolvente de la primer nota y as´ sucesivamente hasta completar los valores iniciales de todas las envolventes de la ı 106 . primero el valor inicial de la primer envolvente de la primer nota.hex” Al principio del archivo se presenta la informaci´n sobre todas las frecuencias. o Para que los archivos “. luego la segunda frecuencia dividido dos y luego la tercer frecuencia dividido dos y as´ sucesivamente hasta ı llegar a la ultima frecuencia. En caso de que un n´mero no sea entero es necesario u redondearlo a entero antes de ponerlo en el archivo “.hex” es un archivo de texto compuesto por 20640 n´meros enteros u separados por comas. es decir que el m´ximo valor absoluto que puede alcanzar el sonido de una nota sea uno. El objetivo de esta secci´n es explicar el formato de los archivos “. a Un archivo “. En total ´ ´ son 1290 los valores que debe tener esta parte. es necesario que los sonidos de todas las notas sean normalizados a uno. Luego se presentan los valores iniciales de cada envolvente de cada nota multiplicados por 134217728.

primer nota, luego se procede con la segunda nota, luego con la tercera y as´ sucesivamente ı hasta llegar a la ultima nota. En total son 1290 los valores que debe tener esta parte. ´ Despu´s se presenta los puntos de cambio que son los puntos en los cuales la gr´fica e a de las envolventes tiene un cambio en la pendiente, cada envolvente tiene seis puntos de esos (el cero no cuenta). Los cambios se expresan en segundos multiplicados por 3000, por ejemplo si se desea que un cambio sea a los 2 segundos se utiliza como par´metro el a n´mero 6000. Se presenta primero el primer punto de cambio de la primer envolvente de la u primer frecuencia, luego el segundo punto de cambio de la primer envolvente de la primer frecuencia, luego el tercero y as´ sucesivamente hasta completar la primer envolvente, ı despu´s de los puntos de cambio de cada envolvente se agrega el n´mero 65535, luego se e u procede con la segunda envolvente de la misma forma, luego la tercera y as´ sucesivamente ı hasta terminar la primer nota, despu´s de la primer nota se prosigue con la siguiente de e la misma forma. Es necesario que cada envolvente tenga seis puntos de cambios, si no se desean tantos se pueden poner en puntos cualesquiera y asignar el mismo incremento a la envolvente antes y despu´s del cambio. En total son 9030 los valores que debe tener esta e parte. Finalmente se presentan los incrementos que debe tomar cada envolvente entre dos puntos de cambio. El incremento es el n´mero que se le suma al valor de cada envolvente u luego de calcular cada valor de salida. A cada envolvente se le suman incrementos 30000 veces (el rate de salida del sintetizador) por segundo. Al principio cada envolvente es incrementada con el primer valor de incremento que le corresponde, luego del primer cambio pasa a incrementarse con el segundo hasta el segundo cambio, en ese momento pasa a incrementarse con el tercero y as´ sucesivamente. Cada incremento se presenta ı multiplicado por 134217728. La cantidad de incrementos que cada envolvente posee es siete. Se presentan de la siguiente forma, primero el primer incremento de la primer envolvente de la primer nota, luego el segundo incremento de la primer envolvente de la primer nota y as´ sucesivamente hasta completar los siete incrementos de la primer ı envolvente de la primer nota, despu´s se sigue con la segunda envolvente de la primer e nota y as´ sucesivamente hasta la ultima envolvente de la primer nota, luego se procede ı ´ con la segunda nota de la misma forma y luego la tercer nota y as´ sucesivamente hasta ı llegar a la ultima nota. En total son 9030 los valores que debe tener esta parte. ´

107

18
18.1

Explicaci´n de los c´digos de Scilab o o
Introducci´n a los programas de Scilab o

El objetivo final de la mayor´ de los programas que realizamos en Scilab es dar ayudas ıa al usuario para que este pueda tener una idea de como es la envolvente de cada una de las frecuencias de una nota musical dada. Estos programas deben tener la capacidad de buscar las frecuencias m´s importantes de un sonido y poder graficar su evoluci´n en a o el tiempo con tanta precisi´n como el usuario requiera. De esta forma el usuario puede o basarse en la evoluci´n mostrada por los c´digos de Scilab para generar un sonido tan o o parecido como el quiera a uno que ya dispone. Para todos los casos suponemos que el usuario cuenta con un vector con todos los elementos menores a uno en valor absoluto que representa los valores que toma el sonido que desea imitar.

18.2

Programa “graficaFacil”

En muchos casos es necesario graficar el vector de valores del sonido, pero por lo general este vector tiene m´s de 100000 elementos raz´n por la cual al Scilab le toma demasiado a o tiempo graficarlo y tambi´n toma mucho tiempo el manejo de la gr´fica (cambiar extremos, e a colores, etc). Esta aplicaci´n es util cuando se desea graficar el vector de valores del sonido o ´ para tener noci´n de la potencia de sonido y en que partes el sonido tiene mayor volumen. o Lo que hace esta aplicaci´n es graficar el sonido pedido pero agrupando valores o consecutivos del vector, sum´ndolos en valor absoluto y representando ese conjunto de a puntos unicamente como un s´lo punto que vale la suma de los valores absolutos de ´ o los puntos que representa. Si bien este programa no es util para realizar un an´lisis en ´ a frecuencia del sonido, si sirve para tener una idea de como evoluciona el volumen del sonido a analizar. El encabezado del programa es el siguiente: z=graficaFacil(entrada,cantidad,colorGraf,canal) Donde “entrada” es la ruta donde esta guardado el sonido en formato .wav . “cantidad” es la cantidad de puntos que la gr´fica del sonido va a tener. “color graf” es el a n´mero asociado al color que la gr´fica va a tener y “canal” es el canal que se desea u a graficar, sirve en sonidos est´reo para saber cual de los dos canales se va graficando. “z” e es un vector que contiene los puntos que fueron graficados.

18.3

Programa “acortaSonido”

Esta aplicaci´n sirve para acortar sonidos, es decir hacer que empiecen m´s tarde o tero a minen antes, para poder analizar s´lo la parte deseada del sonido. o Su encabezado es el siguiente: z=acortaSonido(entrada, salida, desde, hasta, canal, sumar). 108

Donde “entrada” es la ruta donde se encuentra el sonido en formato “.wav” y “salida” es la ruta donde se desea almacenar el resultado de acortar el sonido. “desde” es desde que muestra se desea que empiece el sonido resultante, si la muestra es uno empieza del mismo punto que el original, si es Fs empieza un segundo m´s tarde, etc. “hasta” a representa hasta que muestra se desea que abarque el sonido final, por convenci´n si se o ingresa como par´metro “hasta” un n´mero menor a cero, el resultado final ser´ hasta a u a el ultimo valor del sonido de entrada. “canal” indica el canal que desea considerar del ´ sonido, sirve para cuando el sonido es est´reo y s´lo se quiere considerar un canal. En e o caso de que el sonido sea est´reo, si la variable “sumar” es mayor a cero entonces se va a e trabajar con el resultado de la suma de los dos canales del sonido. “z” es un vector con los valores del sonido resultante.

18.4

Programa “fourierFacilDetectaPicos”

La Transformada de Fourier de un vector tiene como resultado otro vector del mismo largo, si se considera un vector que representa un sonido que en la mayor´ de los casos ıa tiene m´s de 50000 valores, la transformada tambi´n tiene ese largo. Graficar vectores a e muy largos es un problema para el Scilab, le toma demasiado tiempo y puede incluso llegar a trancar la computadora. Este programa esta dise˜ado para poder visualizar la n descomposici´n en frecuencias de un sonido sin hacer que el Scilab grafique un vector con o tantos puntos como el sonido original. Lo que hace el programa es calcular la descomposici´n en frecuencias de un sonido o y luego divide en grupos el vector resultado formando los grupos por conjuntos de puntos consecutivos, despu´s hace una gr´fica donde cada grupo es representado por la suma e a del m´dulo de cada uno de sus puntos. Es decir que el resultado final es muy similar a o la descomposici´n en frecuencias del sonido original pero sumando las magnitudes de los o puntos que est´n consecutivos. Es muy util para poder tener noci´n de la potencia que a ´ o tiene un sonido en cada una de sus frecuencias. La funci´n FFT (Fast Fourier Transform) es la Transformada de Fourier en tiempo o discreto del sonido la cual devuelve s´lo un vector de valores, este programa como tiene o acceso a la frecuencia de muestreo del sonido genera un eje X adaptado para que el usuario pueda visualizar cada valor del resultado final relacionado con su valor en Hz. Dado que la grafica de la descomposici´n en frecuencias de un vector real es sim´trica o e respecto al eje de las Y, para reducir la cantidad de puntos a graficar este programa s´lo o grafica uno de los lados, en el resultado final el eje de las X comienza en cero y termina en Fs/2. Este programa tambi´n devuelve un vector con las frecuencias donde m´s se concene a tra la potencia del sonido. El tama˜o de dicho vector puede ser elegido por par´metro. n a Cuando una frecuencia es considerada de las m´s importantes, las frecuencias de los ena tornos ya no son devueltas por el programa, por ejemplo si 440Hz es la frecuencia con mayor potencia del sonido final, esta va a ser devuelta, pero no va a ser devuelta la frecuencia 439Hz aunque probablemente acumule m´s potencia que otras que si son dea vueltas. Esto se debe a que el objetivo no es s´lo devolver las frecuencias m´s influyentes o a si no tambi´n dar una idea de los “sectores” donde se acumula m´s potencia. e a 109

El encabezado del programa es el siguiente: [Picos,largoAudio,Fs] = fourierFacilDetectaPicos(entrada, cantidad, cantidadMuestras, numeroPicos, colorGraf ) Donde “entrada” es la ruta donde se encuentra el sonido a analizar en formato “.wav”. “cantidad” es la cantidad de puntos que se desea que tenga la gr´fica de la a descomposici´n en frecuencias. “cantidadMuestras” es para evitar tomar todos los valores o del sonido a analizar, el programa considera s´lo los primeros “cantidadMuestras” valores o del sonido pedido, si se asigna un n´mero negativo a esta variable, el programa considera u el sonido entero. “numeroPicos” es la cantidad de frecuencias m´s influyentes que se desea a que el programa devuelva. “colorgraf” es el n´mero asociado al color con el que se desea u graficar el resultado final. “Picos” es el vector que contiene las frecuencias m´s influyentes, a “largoAudio” es la cantidad de muestras del sonido original y “Fs” es la frecuencia de muestreo del sonido original.

18.5

Programa “fourierPartes”

El objetivo de este programa es analizar como evolucionan ciertas frecuencias de un sonido en el tiempo. La idea es ver como se van desarrollando en el tiempo las frecuencias m´s importantes de un sonido, es decir las envolventes que tienen las frecuencias m´s a a importantes del sonido. Lo que hace b´sicamente este programa es analizar para un conjunto de frecuencias a que valor tiene cada una de ellas en la descomposici´n de frecuencias de un sonido en o distintos intervalos del tiempo. Para eso el programa divide en varias partes el sonido a analizar y para cada parte analiza la influencia de cada una de las frecuencias a analizar. Finalmente grafica para cada frecuencia su influencia en cada uno de los intervalos del sonido. Es una herramienta muy util para crear las envolventes de los sonidos de los ins´ trumentos. Devuelve por cada frecuencia una ventana con una gr´fica de como evoluciona a su influencia en el sonido a analizar en funci´n del n´mero de muestra (por ejemplo, el o u valor en el eje de las x igual a la frecuencia de muestro corresponde a un tiempo de un segundo). La gr´fica cuyo n´mero de ventana sea menor corresponde a la primer frecuencia a u devuelta por el programa, la gr´fica con el segundo menor n´mero de ventana corresponde a u a la segunda frecuencia devuelta y as´ sucesivamente. Si bien las frecuencias que se pasan ı por par´metros se pasan como un vector de n´meros, el programa analiza no s´lo cada a u o frecuencia, si no que con ella tambi´n su entrono, por ejemplo si se pasa como frecuencia e a analizar 440Hz, la frecuencia 439Hz tambi´n va a ser incluida en el an´lisis como parte e a de la frecuencia 440Hz. El encabezado del programa es el siguiente: coeficientes = fourierPartes(rutaorigen, desde, hasta, largoParticion, frecuencias). Donde “rutaOrigen” es la ruta donde se encuentra el archivo de audio a analizar en formato “.wav”. “desde” es desde que n´mero de muestra del sonido se desea analizar, u si esta variable vale uno se analiza desde el principio del sonido. “hasta” es el ultimo ´ n´mero de muestra a analizar, si se le asigna un valor menor a cero se analiza el sonido u 110

hasta el final. Como se mencion´ antes el sonido se divide en varios intervalos, la variable o “largoParticion” indica el largo de cada uno de estos intervalos. “frecuencias” es un vector con todas las frecuencias a analizar. “coeficientes” es una matriz donde se encuentra la evoluci´n de cada una de las frecuencias pedidas. o

18.6

Programa “copiaNota”

El objetivo de este programa es probar los sonidos a generar, este programa recibe por par´metros elementos como para poder generar las envolventes de una nota y tambi´n a e recibe por par´metros las frecuencias de la nota, en base a eso puede generar el sonido de a la misma forma que el sintetizador lo har´ ıa. El encabezado del programa es el siguiente: [y, mi, incrementos, cambios, evolucion]= copiaNota(rutaDestino, frecuencias, evolucion, cadaCuantosEvol, nota, largo, Fs) Donde “rutaDestino” es la ruta donde se desea almacenar el sonido resultante. “frecuencias” es la lista con las 15 frecuencias m´s influyentes del sonido. “evolucion” es una a matriz que indica como evoluciona cada frecuencia en el tiempo, es la matriz que devuelve el programa “fourierPartes”. “cadaCuantosEvol” es un par´metro que indica de que largo a (expresado en n´mero de muestras) fueron los intervalos en los que fue dividido el sonido u en la aplicaci´n “fouriePartes” para generar la tabla “evolucion”. “nota” indica el n´mero o u de nota que se desea imitar. “largo” es la cantidad de muestras que se desea que tenga el sonido de salida. “Fs” es la frecuencia de muestreo del sonido de salida. “y” es el sonido de salida. “mi” es la lista de los valores iniciales de cada una de las envolventes. “incrementos” es cada uno de los incrementos que tiene cada envolvente. “cambios” son las cantidades de muestras en las que se generan los cambios en las envolventes y “evolucion” es una copia de la matriz “evolucion” que se recibe por par´metros. a

18.7

Programa “copiaSonido”

Una vez que ya se tiene un programa que puede analizar un sonido y establecer cuales son las frecuencias m´s influyentes y tambi´n se tiene un programa que puede en base a una a e lista de frecuencias devolver una matriz que expresa la evoluci´n de cada una de estas o frecuencias en el tiempo, se esta muy cerca de generar en base a un sonido cualquiera par´metros para que el sintetizador pueda copiarlo. Este es el objetivo de esta aplicaci´n, a o generar las tablas para pasarle al sintetizador que permitan imitar un sonido cuya ruta de acceso recibe por par´metro. Este programa tambi´n genera el sonido resultante de a e la imitaci´n del sonido de la ruta de origen. Dado que a este programa se le pasa por o par´metros s´lo un sonido y un instrumento del sintetizador tiene 86 notas, el programa a o recibe por par´metro que nota es la que se le esta pasando y luego para las otras 85 notas a generaliza en base al sonido de la nota generada. Lo que b´sicamente hace este programa es unir los hilos entre las aplicaciones mena cionadas anteriormente, es decir ejecuta una, luego le pasa por par´metros las salidas a de esa a la segunda y luego toma los par´metros de salida de ambas aplicaciones para a 111

cuanto m´s f´cil sea de imitar el sonido que recibe por a a par´metros el programa mejor quedar´ la imitaci´n. “nota” es el a n´mero de nota asociado a la imitaci´n que se va a generar. aqum] = copiaSonido(rutaOrigen.wav” siendo X el par´metro ’nota’. nota). dado que sus ejes coinciden. “cantidadSenos” es otro par´metro del sintetizador que vale 15000. “mascarasIniciales” es el vector con todos los valores iniciales de las envolventes del sonido generado.8 Programa “haceGraficas” Este programa lo que hace es deducir las frecuencias m´s influyentes de un sonido que a recibe por par´metro. para eso es necesario que el sonido a a o a imitar sea lo m´s corto posible y si es un instrumento de cuerda mejor. frecuenciaPic. La ventaja de este programa es que hace todas las gr´ficas colocando el eje de las X y el eje de las Y con un peque˜o sector de los a n valores negativos igual que la ventana “manejo de envolventes”. 18. es necesario que estas est´n cargadas en Scilab para poder utilizarlo. “cambios” es la matriz con los n´meros de muestras en u los cuales las envolventes cambian sus incrementos. si no mostrar que se puede llegar a generar programas que autom´ticamente generen las tablas para que el a sintetizador pueda imitar sonidos. Como este programa utiliza algunas de las aplicaciones mencionadas anteriormente. Las gr´ficas que genera a este programa son ideales para poner como imagen de fondo en dicha ventana. El encabezado del programa es el siguiente: [y. “evolucion” es la tabla de evoluci´n que devuelve la o aplicaci´n “fourierPartes” y “aqum” es una variable auxiliar de control. luego tambi´n se pueden o e importar desde la ventana “Manejo de instrumento”. evolucion. “rua taDestinoTabla” es la ruta donde se desea almacenar la tabla generada para pasarle al sintetizador. Previamente es necesario generar un mapa de bits o foto que s´lo o 112 . Este programa a todav´ no esta muy perfeccionado por lo que las imitaciones en varios casos no son ıa buenas. A su vez guarda la imitaci´n del o sonido generada en el disco duro. rutaDestinoTabla. el principal objetivo de este programa no es imitar sonidos. Si bien la idea es e poder imitar cualquier sonido.wav”. dicho valor es 30000. Estas tablas son archivos con o el formato “. cambios. “frecuenciaPic” es la frecuencia de muestreo del sintetizador.hex”. “Picos” son las 15 frecuencias m´s a influyentes en el sonido original. “incrementos” es la tabla con los incrementos del sonido generado. mascarasIniciales. “y” es el vector con todos u o los valores del sonido generados. Donde “rutaOrigen” es la ruta donde se encuentra el sonido a imitar en formato “. el sonido se guarda con el nombre “nota X. incrementos. en caso de que o la funci´n haya concluido satisfactoriamente (la amplia mayor´ de los casos) la variable o ıa “aqum” debe finalizar con el valor 20640. Picos. rutaDestinoSonido. devolver un vector con esas frecuencias y despu´s graficar la evoluci´n a e o de cada una de esas frecuencias en el tiempo. cantidadSenos.ejecutar una tercera aplicaci´n. “rutaDestinoSonido” es la carpeta donde se desea almacenar el sonido generado. se recomienda guardarlos con esa extensi´n. Tambi´n genera las tablas para poder pasarle mediante o e la ventana “modo transmisi´n” los datos al sintetizador.

estos son los que representan a las ’n’ frecuencias o m´s influyentes del sonido a imitar. col). “largoSalida” es la cantidad de samples que la salida tendr´. Luego. largoSalida.10 Programa “envolventeComun” Este es el programa que se utiliz´ para generar las imitaciones de sonido mediante el o m´todo de la “envolvente global”. puntosFourier. sin m´rgenes. rutaDestino) Donde “entrada” es la ruta donde se encuentra almacenado el sonido a imitar. “rutaDestino” es la ruta donde se desea almacenar la salida generada. N´tese que esta funci´n tiene definidas otras ´ a a o o funciones en el mismo archivo. El programa tambi´n grafica la descomposici´n en frecuencias e o de la imitaci´n generada.9 Programa “sinusoidalesPuras” Este es el programa que se utiliz´ para generar las imitaciones de sonido mediante el o m´todo de las sinusoidales puras. “puntosFourier” es la cantidad de grupos de puntos consecutivos en los que se quiere dividir la transformada de Fourie del sonido a imitar (es lo mismo que “cantidad” en la funci´n “fourieFacilDetectaPicos”). “col” es un n´mero asociado al color que u se desea que tenga la gr´fica y “frecuencias” es el vector con las principales frecuencias del a sonido a analizar. Lo primero que hace el m´todo es imitar el sonido e e deseado con la aplicaci´n “sinuisoidalesPuras”. Donde “ruta” es la ruta de origen del sonido. al igual que la aplicaci´n “fourieFacilDetectaPio cos”. del conjunto de puntos agrupados o o que form´ selecciona los ’n’ mayores. la segunda es la evoluci´n en el tiempo de la primer frecuencia del vector o “frecuencias”. cantidadMejores. agrupa los puntos de la transformada que son consecutivos y los considera como uno s´lo que vale la suma de los m´dulos de estos. la tercer gr´fica es la evoluci´n en el tiempo de la segunda frecuencia del a o vector “frecuencias” y as´ sucesivamente. colorGraf. a 18. “colorGraf” es el n´mero asociado al color con el que o u las gr´ficas van a ser dibujadas. La primer gr´fica que genera este programa es un an´lisis en frecuencia a a del sonido. o El encabezado del programa es el siguiente: frecuencias=haceGraficas(ruta. Finalmente genera la se˜al de salida como la suma a n del valor de cada uno de los ’n’ puntos mencionados multiplicado por una sinuidal de la frecuencia que representan. Luego con la aplicaci´n “graficaFacil” o o obtiene ‘n’ puntos de la envolvente del sonido a imitar. utiliza estos puntos para generar una envolvente tan larga como se desea que sea la imitaci´n generada y finalmente mulo tiplica la imitaci´n por dicha envolvente. ı 18. dichas funciones son s´lo de uso interno. “cantidadMejores” es la cantidad de frecuencias m´s a a influyentes que se van a buscar. El programa comienza calculando la transformada de e Fourier del sonido que se desea imitar y. o El encabezado del programa es el siguiente: sonidoGenerado = sinusoidalesPuras(entrada. La envolvente se forma uniendo con rectas los o 113 .incluya el area de la gr´fica.

Esto se debe a que se representar´ por ejemplo. a 18.11 Observaci´n general o La potencia de una se˜al sinusoidal es proporcional a su amplitud al cuadrado. “rutaDestino” es la ruta donde se desea almacenar la imitaci´n generada. Si bien estos programas se n explicaron como si se sumara amplitudes sumando sus m´dulos. Estas aplicaciones no son explicadas a dado que son herramientas auxiliares que no tiene una finalidad en s´ para el uso del ı sintetizador. otra raz´n es que son aplicaciones sencillas de usar donde los par´metros o a tienen nombres conocidos. “numRectas” es la cantidad o de rectas con las que se desea generar la envolvente. El encabezado del programa es el siguiente: salida=envolventeComun(rutaEntrada. Por esta n raz´n.12 Programas que generan efectos Tambi´n se generaron algunas aplicaciones de Scilab que generan algunos efectos de audio. Este programa tambi´n grafica en la o e ventana n´mero 0 la descomposici´n en frecuencias de la imitaci´n generada antes de ser u o o multiplicada por la envolvente y en la ventana 1 grafica la envolvente a utilizar. largoSalida. 114 . “largoSalida” o es la cantidad de samples que se desea que la imitaci´n tenga. De esta forma. n sinusoidal de amplitud 2A que dos se˜ales sinusoidales de frecuencias similares y amplitud n A cuando la potencia de la se˜al de amplitud 2A es mayor. si en los programas que agrupan frecuencias similares (como el programa “fouriero FacilDetectaPicos”) se agrupan directamente sumando sus m´dulos se estar´ cometiendo o ıa un error.‘n’ puntos obtenidos en la funci´n “graficaFacil”. 18. de la misma forma una se˜al ıa. si un punto tiene mayor altura en la gr´fica que otro significa a que entre las frecuencias que representa hay m´s potencia acumulada. En el cd adjunto hay ejemplos de uso de estos efectos. rutaDestino. lo que realmente hace el o programa es sumar el cuadrado de todos los m´dulos y luego calcular la ra´ cuadrada de o ız la suma. numRectas) Donde “rutaEntrada” es la ruta donde se alamcena el sonido que se desea imitar. e dichas aplicaciones est´n dentro de la carpeta efectos.

para eliminar dicho marco lo que hace el programa es eliminar de los bordes de los mapas de bits la cantidad de bits que corresponde al ancho del marco.19 Herramienta para reducir im´genes a La funci´n de scilab “haceGraficas” genera las gr´ficas con los ejes en la misma posici´n o a o que la ventana “manejo de envolventes”. cada a a o im´gen debe incluir s´lo la gr´fica que le corresponde. se encarga de eliminar el marco de a esas gr´ficas.exe” contenido en el a cd. la aplicaci´n a o creada en visual studio llamada “reduce im´genes”. a Imagen 35: Screenshot de la ventana del programa “Reduce Imagenes” Una vez dentro del programa haga clic en el bot´n “seleccionar im´genes” y seleco a cione todas las im´genes que desea reducir. El scilab tiene una opci´n para a o a o exportar gr´ficas como mapa de bits. pero las exporta con un marco extra. a Para utilizarla haga doble clic en el archivo “reduce im´genes. 115 . Como la posici´n del marco que el Scilab le agrega a las gr´ficas en el momento o a de crearlas es fijo. Luego de terminada la reducci´n aparece un cartel indicando si esta o fue exitosa o no. La im´gen 35 es una captura de pantalla de dicho programa. las im´genes ser´n reducidas y guardadas en a a a la misma carpeta. pero para poder sacar provecho de esa coincidencia de los ejes es necesario crear una im´gen por cada gr´fica que gener´ el programa.

Las posiciones de memoria en los DSPic son de dos bytes pero los datos s´lo pueden o enviarse de a un byte. long int[86][15]. 40 bytes Este es el mismo orden en el cual los archivos ‘. En la secci´n “Formato de los archivos para enviarle al sintetizador” se encuentra el orden m´s o a detallado. Luego se proceder´ a enviar la informaci´n conteniendo los o a o detalles. int[86][15][7] tama˜o 18060 bytes n 5. Debajo se enlistan los pasos: 1. o En caso de que el dispositivo no responda. En el caso de las variables del tipo int hay que enviar primero 116 . Se comenzar´ enviando el byte 0x32 (32 en hexadecimal. esta es a la condici´n de arranque. significa que ha habido un error durante la transmisi´n. Enviar los cien bytes de data y esperar la recepci´n de un 0x26 antes de continuar o enviando mas data.20 Protocolo para Transmitir un Nuevo Instrumento La idea en la generaci´n del software de PC es ofrecer junto al hardware una posibilidad o para que los usuarios puedan sintetizar sus propios instrumentos de una manera amigable. Codificaci´n de los datos o Los datos a enviar deben ser en el siguiente orden: 1. lo mejor en este caso es re-iniciar el sistema quit´ndole la corriente y volver o a a intentar. Pero la idea del proyecto es que cada uno. 2. tama˜o 2580 bytes o n 2. pero como el maestro tiene n integrado un buffer de cien posiciones que s´lo permite transmitir los datos una vez que o se llena se necesitan agregar cuarenta bytes cualesquiera para que los ultimo sesenta sean ´ procesados. M´scaras Iniciales. 50 en decimal). Enviar un 0x32. Luego de que se haya enviado los ultimos cien bytes. tama˜o 5160 bytes a n 3. esperar la respuesta de un 0x15 ´ (21 en decimal) que confirme que el dispositivo ha recibido toda la informaci´n. si as´ lo desea. o Aqu´ se detalla cu´l debe ser el protocolo de transmisi´n de datos en el momento ı a o de cargar un nuevo instrumento. pueda dise˜ar su propio programa ı n para la generaci´n de sonidos. unsigned int[85][15]. Arm´nicos. unsigned int[86][15][7] tama˜o 18060 bytes o n 4. El tama˜o total de un instrumento es de 43860 bytes. 3. Posici´n de Cambios. Incrementos. Relleno.hex’ deben ser generados.

a a Por ejemplo. para enviar el valor 22790307 que en hexadecimal es el 0x15BC0A3 hay que enviar la siguiente trama: 0xC0 0xA3 0x01 0x5B.el byte m´s significativo y luego el menos. 117 . En el caso de las variables del tipo long int a se deber´ enviar primero los 2 bytes menos significativos y luego los m´s significativos.

En el planteo del objetivo del proyecto fue necesario renunciar a n muchas aplicaciones adicionales y accesorios que podr´ tener el sintetizador por el hecho ıa de que es imposible abarcar todas las opciones posibles simult´neamente. 21. o o lee el dato auxiliar de los siguientes DSPic hasta que pueda leer correctamente el dato auxiliar de uno de esos. De esa forma puede hacer cierto control del funcionamiento de un esclavo antes de mandarle una instrucci´n MIDI para reproducir. si bien funciona bien. a la arquitectura del sintetizador permite la realizaci´n de varias de ellas de una forma o relativamente sencilla. o 118 . o Dichos chequeos ser´ muy utiles en casos de fallas en el hardware.3 Detecci´n autom´tica de esclavos que est´n fallando o a a Como se menciona en la secci´n de explicaci´n de los c´digos de los DSPic. no se chequean posibles fallas en una transmisi´n de comandos MIDI. 21.2 Aumento de los controles internos El sintetizador. tiene muy pocos controles internos. los DSPic o o o esclavos funcionan como memorias desde el punto de vista del maestro para el env´ de ıo 2 datos v´ I C. Sin embargo. podr´ guardar en ıa ıa cierta posici´n de memoria cierto dato auxiliar. ni en las comunicaciones por I 2 C. El maestro. que ve a los esclavos como memorias. ıan ´ 21. en caso de querer comercializar el producto es necesario implementar una o soluci´n para que se pueda alimentar con una unica fuente. si la lectura se realiza o o correctamente. Si la lectura falla.21 Posibles mejoras y complementos El mundo de la m´sica y la interpretaci´n de instrumentos permiten realizar una gran u o cantidad de aplicaciones.1 21.1. A continuaci´n se nombran varias de las aplicaciones y accesorios o que se le podr´ agregar al proyecto sin realizar cambios fundamentales en la arquitectura ıan del sistema. Cuando recibe un comando MIDI se o lo transmite al esclavo que corresponde y luego lee el dato auxiliar que guardo en el esclavo que le corresponde recibir la pr´xima instrucci´n MIDI.1 Posibles mejoras en el sintetizador Alimentaci´n con una unica fuente o ´ Actualmente el sintetizador requiere para su correcto funcionamiento de varias fuentes de alimentaci´n. le transmite la pr´xima instrucci´n MIDI a ese DSPic.1.1. Lo ideal ser´ que se pueda o ´ ıa alimentar a trav´s de pilas o una bater´ e ıa. Obviamente no es posible abarcar todas estas aplicaciones en un solo proyecto de un a˜o.

o de implementar esta soluci´n la se˜al pasar´ de digital a anal´gica dos veces (una vez al o n ıa o ser generada por los esclavos y otra despu´s de ser procesados los efectos) por lo que este e error ser´ mayor.21. pero a´n quedan algunas m´s por o u a hacer. si no que cada esclavo genera la salida (anal´gica) de la nota que le corresponde.1. mientras que el o´ humano puede llegar a escuchar ıdo sonidos de hasta 20 Khz. pero se perder´ precisi´n en ıa ıa o el sonido dado que la salida de los Pics tiene una resoluci´n de 16 bits mientras que la o entrada anal´gica tiene una resoluci´n de 10 bits. como el efecto wah-wah y hacer que el sintetizador solo aplique un efecto.1 Khz. Tambi´n se perder´ calidad de sonido o o e ıa en el pasaje de digital a anal´gica debido al error propio del DSPic y el de los sumadores. Como se menciona o en la parte de explicaci´n de los c´digos en muchos casos dos c´digos que cumplen el mismo o o o objetivo y parecen equivalentes. por ejemplo hacer que los esclavos no generen los efectos. Consideramos u u que con la versi´n profesional se podr´ optimizar parte de los c´digos para lograr de esa o ıan o forma llegar a procesar los samples en menos de 903 instrucciones. La forma m´s sencilla de lograr que se calcule en menos de 903 instrucciones cada a sample es reducir la fidelidad del sonido. Ser´ una buena mejorar lograr que ıa el sintetizador llegara a esa frecuencia. De todas formas esta alternativa tiene una gran ventaja que es que el ıa generador de efectos queda independiente del sintetizador.1 khz. por lo que se podr´ conectar ıa no s´lo a este. Otra formar de lograr esto es optimizar los c´digos de los esclavos. El est´ndar que se usa de audio para reproducir sonidos de hasta a 20 Khz es usar una frecuencia de salida de 44. Dado que el sintetizador utiliza los DSPic con mayor velocidad del mercado. o Lograr 44.4 Mejora de la frecuencia de salida La frecuencia de salida del sonido del sintetizador es de 30 Khz. no tiene todas las optimizaciones que la versi´n profesional o dispone. Se u lograron realizar varias optimizaciones en el c´digo. no es posible lograr esa frecuencia de salida utilizando la l´ ınea DSPic sin modificar los c´digos o de la programaci´n del DSPic. La versi´n que utilizamos del programador en lenguaje ‘C’ del MPLAB es la versi´n o o gratuita para estudiantes. si no a cualquier otro dispositivo que el usuario desee que emita una se˜al o n 119 . Actualmente al procesador le lleva aproximadamente 1050 instrucciones de reloj calcular cada sample. pueden tomar un n´mero distinto de ciclos de reloj. Se podr´ hacer que cada nota tenga solo diez ıa arm´nicos. dicha versi´n si bien no tiene limitaciones respecto a la cantidad o de aplicaciones y funciones. un claro ejemplo de esto es explicado al explicar el efecto “Wah-Wah” con el tema de las divisiones de n´meros de 4 bytes dividido n´meros de 2 bytes. luego todas las salidas son sumadas y un o DSPic lee por su entrada anal´gica el valor de dicha suma y le procesa los efectos.1 Khz de frecuencia de salida implica calcular cada sample en hasta 903 instrucciones de reloj. Otra o o ıa alternativa es renunciar a los efectos que mayor cantidad de ciclos toman. De esta o forma se lograr´ tener una frecuencia de salida de 44. Una tercer alternativa consiste en diversificar las tareas que realiza cada esclavo. esta frecuencia permite reproducir sonidos de hasta 15 Khz. dicho n´mero var´ seg´n la nota a reproducir y los u ıa u efectos seleccionados. con eso la generaci´n de los sonidos tomar´ aproximadamente 850 ciclos.

Tambi´n a e se podr´ hacer que se modifique los puntos de cambio para hacer la nota m´s larga o ıa a m´s corta. Para o realizar esta mejora se deber´ hacer que en vez de copiar tal cual son los par´metros de ıa a la nota a reproducir de la memoria de programaci´n a la memoria de trabajo. a 21. u 21. multiplicar los incrementos de alguna de las componentes. n a cuando el esclavo debe reproducir una nota lo que hace es copiar los par´metros de dicha a nota de la memoria de programaci´n a ciertas variables en su memoria de trabajo. Actualmente.1. La forma m´s sencilla de a incorporar la interfaz USB ser´ cambiar el modelo del DSPic maestro por uno que s´ ıa ı tenga esta interfaz.1. se los copie o con modificaciones que dependen de la posici´n de algunos potenci´metros. o o Se podr´ por ejemplo. En nuestro sistema realizar esto toma varios minutos y requiere de una conexi´n o a una PC. para lograr de esa forma hacer que la nota tenga m´s componentes agudos o graves. pero la soluci´n optima es que o o ´ el sintetizador tenga una interfaz de comunicaci´n USB. dicha o interfaz es antigua y no se encuentra en muchas de los nuevos modelos de computadoras.7 Almacenar m´ ltiples instrumentos virtuales en un solo sintetizador u Tanto cuando se utiliza el PC como sintetizador MIDI o el SMPro Audio V-Machine Standalone VST Player.5 Modificaci´n din´mica de los instrumentos o a Una de las mejoras que nos parece m´s util para el sintetizador es de darle la capacidad a ´ de modificar con potenci´metros algunos par´metros del instrumento virtual en cualquier o a momento. al copiar los par´metros de la memoria de programaci´n a ıa. Dado que la memoria de programaci´n de los DSPic que utilizamos para el proyecto o no alcanza para almacenar m´s de un instrumentos y no existen DSPics con grandes a 120 . se podr´ conectar el generador de efectos a la salida o ıa de un reproductor de MP3 para poder aplicarle los efectos a la m´sica que este genera. Una posible soluci´n es utilizar un adaptador USB a serie. pero existen una gran cantidad de microprocesadores de la l´ ınea DSPic y tambi´n de l´ e ıneas anteriores como algunos PICs de la l´ ınea 18F que si disponen dicha interfaz.1. 21.de sonido anal´gica.6 Utilizar interfaz USB La interfaz de comunicaci´n entre el sintetizador y el PC es mediante el puerto serie. a o la memoria de trabajo. cambiar el instrumento virtual que se esta utilizando toma escasos segundos. Por ejemplo. La idea para solucionar esto ser´ poder guardar datos de varios instrumentos ıa en el sintetizador. o El modelo de DSPic seleccionado no tiene interfaz USB. La arquitectura del sintetizador y el formato de los instrumentos virtuales fueron dise˜ado para que este tipo de cambios pueda ser realizado muy f´cilmente.

Dado que el protocolo MIDI provee una forma de identificar instrumentos a trav´s e de los “canales MIDI”. que cada DSPic grabe el sonido que genera tiene sus ventajas.1.8 M´ ltiples instrumentos conectados a un solo sintetizador u Si se logra realizar la mejora de tener varios instrumentos virtuales en un solo sintetizador. una de las limitaciones del proyecto es que no es posible o recrear de forma correcta los sonidos de instrumentos de viento. el sonido generado se puede grabar conect´ndole un dispositivo adecuado en la salida a de audio. En los o instrumentos de viento. dependiente del tiempo que se este soplando. El funcionamiento o ıan del programa de los esclavos ser´ muy similar. para luego poder modificar la forma en la que estos son aplicados.1. De esa forma el sonido generado se puede volver a reproducir. dado que se graba antes de convertirse en un valor anal´gico. 21. se deber´ utilizar memorias externas. Si bien.memorias de programaci´n. 121 .1.10 Opci´n de grabaci´n o o Una herramienta de gran utilidad para el sintetizador ser´ que tenga la posibilidad de ıa grabar los sonidos generados. Tambi´n habr´ que dise˜ar alg´n protocolo para que todos los esclavos puedan e ıa n u acceder sin colisiones a la memoria externa y as´ evitar la necesidad de una memoria ı externa por cada esclavo. una posible mejora ser´ hacer que cada DSPic adem´s de ıa a transmitir por su salida anal´gica cada sample que calcula pueda tambi´n guardarlo en o e una memoria externa. a 21. Para resolver esto se deber´ remover el concepto de envolvente y reproducir el sonido ıa con una intensidad constante que dependa unicamente del valor de intensidad recibido ´ por el comando MIDI. Otra de las ventajas es que puede almacenarse la variable salidaLong o que tiene una precisi´n de 32 bits y una tecera ventaja es que se podr´ implementar un o ıa sistema para que el sonido pueda ser grabado antes de aplicarle los efectos. el sonido de cada nota tiene un largo variable. el paso siguiente ser´ poder conectar varios instrumentos al sintetizador y poder asignarle ıa a cada uno un instrumento virtual. Para realizar esta mejora ser´ necesario aumentar el n´mero de DSPics a utilizar ıa u para poder mejorar la cantidad de notas simult´neas a reproducir. Una de ellas es que el sonido se puede grabar con mayor calidad. no consideramos que sea dif´ lograr interconectar varios instruıcil mentos al sintetizador. 21. Esto se debe a que una vez que se oprimi´ una tecla no dispone de forma de alargar o acortar su sonido.9 Ampliar la cantidad de tipos de instrumentos que se pueden generar Como se mencion´ anteriormente. salvo que los datos se obtendr´ de la ıa ıan memoria externa y ser´ necesario un par´metro adicional que indicara el instrumento ıa a deseado.

las posibles mejoras del software del PC. pueden llegar a ser proyectos enteros. sobre todo teniendo en cuenta la gran cantidad de aplicaciones relacionadas con el procesamiento de sonidos que permiten realizar los procesadores de hoy en d´ ıa. A diferencia de las posibles mejoras del sintetizador.2.2 Mejora en la velocidad de funcionamiento Sabemos que en el programa “Interfaz de comunicaci´n” hay m´todos que si bien funcioo e nan. a n o A continuaci´n se mencionan algunas de estas mejoras.1. Por ende.Una variante de esta mejora propuesta consiste en que el maestro grabe cada funci´n o MIDI que recibe junto con el momento en que fue recibida. Que las imitaciones sean mejores que las de la funci´n “copiaSonido”. mucho m´s amigae ıa a ble y f´cil de usar. M´s que peque˜os agregados en un c´digo.midi’ son archivos que contienen instrucciones MIDI para o reproducir un sonido. 21. o 21. o Este programa tambi´n podr´ brindar una mejor interfaz al usuario. a o 21. la lentitud en la creaci´n e importaci´n de ıan o o 122 . Los esclavos no tienen porque conocer si el sonido que est´n reproduciendo es grabado o esta a siendo generado actualmente. en varios casos no se obtienen buenos resultados.1 Mejora en el sistema de generaci´n autom´tica de notas o a Como se mencion´ anteriormente. Consideramos que m´s que un buen imitador de sonidos es un programa a que demuestra que se puede generar programas que realmente puedan imitar sonidos y transformarlos en notas de instrumentos virtuales. este tiene una gran cantidad de posibles mejoras a aplicarle.2. de esta forma se puede volver a reproducir el sonido generado pero con cualquier instrumento virtual que se desee. en su mayor´ requieren de una reestructuraci´n de la arquitectura b´sica del ıa o a software.2 Posibles mejoras en el software de PC El objetivo central del proyecto no fue el software de interconexi´n entre el PC y el o sintetizador.11 Reproducir archivos . 21.midi Los archivos con extensi´n ’. una posible mejora para el sistema consiste en reproducir estos archivos. A su vez podr´ tambi´n permitir al usuario seleccionar valores de a ıa e par´metros para mejorar la imitaci´n. no son tan eficientes como podr´ serlo. la aplicaci´n de Scilab “copiaSonido” puede transformar o o sonidos en notas de instrumentos virtuales que pueden ser pasadas al sintetizador. Una mejora que consideramos muy util que se le podr´ hacer al proyecto es generar ´ ıa un programa que realmente pueda transformar casi cualquier sonido en una nota de un instrumento virtual. no se le dedic´ el a o tiempo suficiente. Esto se debe a que no es una aplicaci´n o f´cil de realizar y que al no ser una prioridad de nuestro proyecto.

Eso ser´ una gran mejora a nuestro proyecto dado que permitir´ no solo utilizar ıa ıa la gran cantidad de instrumentos VSTi existentes.2. Deducir las envolventes no es algo intuitivo. opciones como a o que el sonido sea m´s agudo. tampoco es una forma c´moda de generar instrumentos. Lo que se propone como mejora es agregarle o al software opciones m´s intuitivas para la generaci´n de instrumentos. La mejora propuesta consiste en unificar todas las herramientas creadas para que puedan ser ejecutadas desde un mismo programa. 123 . 21. Esto se debe a que el software de PC trabaja en Windows que es el entorno natural de los instrumentos VSTi en formato DLL. a a a e agregarle eco.4 Agregar un conversor de instrumentos VSTi al formato del sintetizador La idea original del proyecto era que se le puedan transmitir instrumentos VSTi al sintetizador. Ser´ una mejora muy pr´ctica lograr reducir esos ıa a tiempos. 21.2. Esta mejora la incorporamos dentro de las mejoras de software dado que consideramos m´s sencillo que el software de PC pueda convertir los instrumentos VSTi a el a formato que interpreta el sintetizador a que hacer que el sintetizador interprete directamente los VSTi. Dichas opciones har´ de la creaci´n de instrumentos una tarea ıan o accesible a cualquier usuario. m´s parecido al de una guitarra el´ctrica. mientras que para otras hay que utilizar Scilab.5 Integrar todos los programas y aplicaciones en un solo programa Actualmente para utilizar ciertas herramientas hay que utilizar la interfaz de conecci´n o entre el PC y el sintetizador.2. o m´s prolongado. 21. si no que tambi´n utilizar cualquiera e de los editores de instrumentos VSTi que existen para crear instrumentos.3 Cambiar los par´metros a editar de un instrumento a Actualmente en el software “Interfaz de comunicaci´n”.instrumentos es un ejemplo de esto. etc. la forma de editar instrumentos o implica un manejo de envolventes.

Para generar las imitaciones y grabar los sonidos se utiliz´ el o u o software dise˜ado por nosotros. pero son una buena pauta de que se puede llegar a generar un programa que imite casi cualquier nota musical mediante el m´todo de la envolvente e individual.3.3 Carpeta “Imitaciones Generadas Mediante Envolvente Individual” Esta carpeta contiene algunas de las pruebas de imitaci´n de sonidos generadas mediante o el m´todo de la envolvente particular para cada frecuencia.1. 124 .sce”. estas o imitaciones no son perfectas. Para e o o u generar las imitaciones utilizamos la funci´n de Scilab “envolventeComun”. o En este caso hay sonidos originales con los cuales comparar dado que estos sonidos si se generaron intentando imitar sonidos espec´ ıficos.1 Explicaci´n del contenido del CD adjunto o Carpeta “Imitaciones Generadas con los Distintos M´todos” e Carpeta “Imitaciones Generadas Mediante Sinuidales Puras” Esta carpeta contiene algunas de las pruebas de imitaci´n de sonidos generadas mediante o el m´todo de las sinudoidales puras mencionado en la secci´n “creaci´n de la nota musical”.1 Carpeta “Imitaciones Generadas Con El Programa CopiaSonido” Esta subcarpeta contiene imitaciones generadas mediante el m´todo de la envolvente e individual. n Como se mencion´ anteriormente. o filtrando ciertas frecuencias. Esta ventaja fue utilizada para la generaci´n de los sonidos que se encuentran o en esta carpeta. una de las ventajas de este m´todo para generar o e sonidos contra otros m´todos basados en samples es que permite realizar facilmente una e gran cantidad de modificaciones en el sonido generado (como filtrar o modificar ciertas frecuencias). en esta carpeta no hay ning´n sonido real. o 22. si no que fueron generados mediante modificaciones de otros ya generados.1 22. Como muchos de los sonidos de esta carpeta no fueron generados buscando imitar un sonido de un instrumento en particular. s´lo hay sonidos generdos mediante el m´todo de u o e la envolvente particular de cada frecuencia. 22. o 22. mencionado en la secci´n e o “creaci´n de la m´sical”. e o o Para generar las imitaciones utilizamos la funci´n de Scilab “sinusoidalesPuras. Como se mencion´ anteriormente.2 Carpeta “Imitaciones Generadas Mediante Envolvente Global” Esta carpeta contiene algunas de las pruebas de imitaci´n de sonidos generadas mediante o el m´todo de envolvente global mencionado en la secci´n “creaci´n de la m´sical”. pero generadas automaticamente mediante la funci´n de scilab “CopiaSonido”. muchos sonidos fueron generados en base a extrapolaciones de otros generados anteriormente.22 22.

a a La carpeta ‘ejemplos de extrapolaci´n por promedio’ es similar a la carpeta ‘ejemplos de o extrapolaci´n’ pero tiene un ejemplo de extrapolaci´n por promedio. o o 125 . Tiene en la carpeta ’Instrumentos Creados’ ejemplos de instrumentos o y en la carpeta ’envolventes creadas’ ejemplos de envolventes creadas. La subcarpeta llamada ’ejemplos de extrapolaci´n’ tiene un ejemplo en el cual se extrapola entre o la m´scara ‘1 de 15 (inicial).1 Carpeta “Instrumentos Creados” Esta carpeta tiene varios ejemplos de instrumentos creados junto con la grabaci´n de o algunas de las notas de los instrumentos.2 Carpeta “Ejemplos de Envolventes” Esta carpeta tiene dos subcarpetas.4. ambas con ejemplos de extrapolaciones. Tiene el archivo ejecutable junto con el ´ ıcono en la carpeta “archivo ejecutable”. Estos instrumentos son un claro ejemplo de como los m´todos de extrapolaci´n y copiado pueden ser utiles para generar notas cercanas e o ´ a cierta nota que se tiene generada. pero los sonidos generados para notas lejanas a una disponible no son tan buenos.4 Carpeta “Software Dise˜ ado” n Esta carpeta tiene todo lo referente al software dise˜ado para la comunicaci´n entre el n o PC y el sintetizador. Tiene tambi´n los archivos como para poder modificar el software en la e carpeta “C´digos”. se o generaron en detalle una o dos de sus notas y luego mediante los m´todos de extrapolaci´n e o y copiado se generaron las restantes notas.4. 22. en la carpeta a a estan guardadas todas las m´scaras intermedias y capturas de pantalla de sus gr´ficas. Para la generaci´n de todos los instrumentos. 22.masc’ y la m´scara ‘15 de 15 (final).22.masc’.

si bien es m´s limitado que el formato “. o Se llev´ la experiencia del trabajo de equipo un paso m´s. junto con una buena coordinaci´n de tiempos y esfuerzos o para poder llegar al objetivo. con una arquitectura bien pensada n ´ que permite una gran cantidad de mejoras que de concretarse pueden poner el sintetizador a la par de cualquier otro sistema del mercado. Fue necesario tomar grandes decisiones respecto al proyecto. El nuevo formato de instrumentos virtuales. Se gan´ mucha experiencia en el campo de la ingenier´ sobre todo en el aso ıa. Fue necesario un total o a entendimiento en el equipo. en los obligatorios de programaci´n los alumnos no eligen el lenguaje de proo gramaci´n. dado el tiempo que le toma llegar.vsti”. se logr´ llegar a un o compromiso acorde a las limitaciones del mercado local y al tiempo destinado del proyecto en el cual se replantearon los objetivos y se lograron cumplir. Fue necesario superar las dificultades del escaso mercado local para traer del exterior microcontroladores. en los obligatorios de sistemas embebidos el alumno no puede elegir el sistema o embebido a utilizar. En cualquier otro proyecto de la carrera. decisiones que modificaban totalmente el rumbo del proyecto que hoy viendo en retrospectiva las consideramos acertadas en su mayor´ ıa. un sistema en el cual todas las decisiones las tenemos que tomar por nuestra cuenta. fueron resueltos y en otros casos requirieron de una reestructuraci´n de la arquitectura y hasta de un replanteo del objetivo o del proyecto. en el cual se presentaron varios problemas que. pecto pr´ctico. Traer algo del exterior. Aprendimos a trabajar con procesadores DSP y sobre sistemas operativos a y sus archivos. las decisiones fundamentales no son tomadas por nosotros. Uno de los mayores desaf´ de este proyecto fue enfrentarnos casi ıos que por primera vez a una situaci´n en la cual tenemos que generar un sistema empezando o desde cero. tambi´n creemos que es un formato a e con un buen futuro. por que si bien e no fue posible cumplir con todos los requisitos originales del proyecto. que de desarrollarse m´s puede llegar a ser realmente util. Consideramos que el trabajo fue un ´xito. a ´ 126 . en algunos casos. Consideramos que dise˜amos un dispositivos util. implic´ que o debamos planificar con antelaci´n las compras y prever posibles fallas antes de encargar.23 Conclusiones Consideramos que logramos un proceso de estudio y aprendizaje exitoso.

Digital Signal Processors and Controllers Disponible en internet: http://www.Sistemas embebidos Linux Disponible en internet: http://www.analog.2009.com/node/1000192 [Microchip] microchip.MPLAB C Compiler for dsPIC DSCs Disponible en internet: http://www.GNU/Linux embebido Disponible en internet: http://linuxemb.Bibliograf´ ıa Referencias bibliogr´ficas a [analog devices] analog devices.2009.2009.microchip.com [Microsoft] Microsoft.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=2629&param= en533465 [Microchip]Microchip.net/modules.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1406&dDocName= en535363 [microcontroller] [online] Disponible en internet: http://microcontroller.Windows embedded 127 .html [blogElectronica] blogElectronica.embedded.jsp?nodeId=012795 [linuxemb] linuxemb.2009.com/webapp/sps/site/homepage.16-bitPIC24 MCU and DSPic DSC products [online] Disponible en internet: http://www.microchip.com/ [embedded] [online] Disponible en internet: http://www.com/en/embedded-processing-dsp/processors/index.blogelectronica.electronicosonline.programacionenc.php?name=Forums\&file=printview\&t=748\&start= 0 [electr´nicos online] [online] o Disponible en internet: http://www.2009.2009.2009.com/ [LinuxJournal] LinuxJournal.com [freescale] freescale.wikidot.2009.com/modulos-embebidos-procesadores-digi-connectcore/ [CoolC/C++] CoolC/C++.linuxjournal.DSP Disponible en internet: http://www.programaci´n de archivos dll [online] o Disponible en internet: http://www.A Host For Native Linux VST Plugins ? [online] Disponible en internet: http://www.freescale.2009.

2009.ti.microsoft.com/windowsembedded/en-us/default.com/scripts/slxweb.com/directory/files [redeweb] H´ctor Palacios P´rez.cs.nsf/web/all/01E4BFF8EC93532086256B6000669953 [processlibrary] processlibrary.com/\_txt/articulos/520503.2009.redeweb.umd.2009 [online] Disponible en internet: http://pro-audio.2009.gersic.com/vstsdk/ [texas instruments] texas instruments.VST-plug ins documentation [online] Disponible en internet: http://www.tsp?sectionId=46 [The university of Maryland] Department of Computer Science.DSP Disponible en internet: http://focus.musiciansfriend.com/worldwide/latam.softonic.Windows Embedded: descripci´n general o Disponible en internet: https://partner.microsoft.2009.ni.24/7 support Disponible en internet: http://support.2009.microchip.com/product/SM-Pro-Audio-Vmachine-Stand-Alone-VST-Player? sku=241884 [National instruments] National instruments.com/dsp/docs/dsphome.com/spain/productossoluciones/psembedded [Microsoft] MSDN.edu/class/fall2001/cmsc411/proj01/arm/dsp.2009 [online] Disponible en internet: http://www.Linux en los sistemas embebidos: e e Disponible en internet: http://www.ar [Softonic] Softonic.aspx [Musican´s friend] VMachine.com/ [soporte de microchip] microchip.2009.sistemasembebidos.VSTi [online] Disponible en internet: http://digital.processlibrary.2009.What is Windows Embedded? Disponible en internet: http://msdn.ARMed solutions to the DSP war Disponible en internet: http://www.com.Disponible en internet: http://www.microsoft.descargar ExeScope [online] Disponible en internet: http://exescope.mspx [Microsoft] Microsoft partner network.pdf [Sistemas embebidos] [online] Disponible en internet: www.dll/external?name=webticketcust [Steinberg] gersic.2009.html 128 .com/en-us/windowsembedded/default.2009.

microchip.de/~ygrabit/public_html/vstgui/V2.MIDI [online] Disponible en internet: es.php?idp=1419\&id=13\&texto= C/Visual+C\# http://msdn.htm [Wikipedia] WIKIPEDIA.313/77337-como-veo-las-funciones-de-dll.emcelettronica.org/wiki/Teorema_de_muestreo_de_Nyquist-Shannon [Wikipedia] WIKIPEDIA.ar/foro/ http://www.wikipedia.forosdelweb.com/codigo/enlace.hermannseib.aspx?forumid=152 129 .org/wiki/Sintetizador [Wikipedia] WIKIPEDIA.com http://www.2009.aspx http://www.com/forums/tt.wikipedia.Sintetizador [online] Disponible en internet: http://es.com/forums/programacion.org/wiki/Synthesizer [Wikipedia]Wikipedia.2009.2009.com/english/vsthost.2009.com.wikipedia.2009.VST-plug ins documentation [online] Disponible en internet: http://ygrabit.microsoft.2/doc/ [VSTHost] hermannseib.80).com/es-es/library/31d242h4(VS.VSTHost [online] Disponible en internet: http://www.psicofxp.2009 [online] Disponible en internet: http://dev.2010.wikipedia.VST [online] Disponible en internet: http://en.org/wiki/Virtual\_Studio\_Technology [Your Electronics Open Source] EE Software Development.steinberg.org/wiki/MIDI [Wikipedia] WIKIPEDIA. html http://www.com/ee-software-development Foros de internet que utilizamos http://sistemasembebidos.wikipedia.wikipedia.Teorema de muestreo de Nyquist-Shannon Disponible en internet: http://es.2009.2009.org/wiki/Sistema_operativo_de_tiempo_real [Wikipedia] WIKIPEDIA.[VST-Guy] VST-Guy.lawebdelprogramador.Sistema operativo de tiempo real [online] Disponible en internet: http://es.Synthesizer [online] Disponible en internet: http://en.

mforos.com/f24/bootloader-codigo-fuente-dspic-827/ 130 .http://todopic.forosdeelectronica.com/781922-dspic/ http://www.

e El muestreo digital es una de las partes que intervienen en la digitalizaci´n de las se˜ales. Dicha funci´n o o se define como: lim → h(t) n→+∞ 1 h(t)= n si 0 < t < n . entonces se obtiene la se˜al sinc. generar la funci´n sinc se convierte en un problema n o o dado que un sistema digital no puede generar funciones continuas. la se˜al impulso es m´s f´cil n o n a a de generar para estos sistemas dado que s´lo consiste en generar un valor alto de tensi´n o o por un intervalo de tiempo muy peque˜o. teorema de Nyquist-Shannon Este teorema trata sobre el muestreo digital de se˜ales 10 y la reconstrucci´n de una se˜al n o n a partir de su muestreo. se denomina frecuencia o tasa de muestreo y determina el n´mero u de muestras que se toman en un intervalo de tiempo [Wikipedia] 10 131 . siendo el intervalo entre las muestras o n o constante. Consiste o n en tomar muestras peri´dicas de la amplitud de una se˜al anal´gica. g(t) es la funci´n conocida como sinc.Anexos Anexo A. 0 en otro caso A diferencia de la se˜al sinc que es dif´ de generar para un sistema digital dado que es n ıcil una se˜al anal´gica y que su valor no se mantiene constante. Se puede n demostrar tambi´n que un filtro pasabajos con frecuencia de corte que este entre ’B’ y ’F’ e tambi´n sirve. Dado que el principal uso de este teorema es para generar con o sistemas digitales se˜ales anal´gicas. El teorema tambi´n demuestra que si f(t) es una funci´n con ancho de banda ’B’ y la se˜al e o n es muestreada a una frecuencia Fs > 2 B . siguiendo la f´rmula: o  f (t) =   f n  Fs n=−∞ f (t)muestreada ∞  ∗g t − n   Fs  g(t) = sen(2πF T ) 2πF T Siendo F la frecuencia de muestreo. si se pasa la se˜al impulso por n un filtro pasabajos de frecuencia de corte ’F’. El ritmo de este muestreo. El teorema demuestra que la reconstrucci´n exacta de una se˜al continua es posible si o n esta tiene un ancho de banda ’B’ (no tiene componentes en frecuencias mayores a ’B’) y la frecuencia de muestreo es mayor a 2’B’. entonces f(t) se puede recuperar exactamente a partir de sus muestras. dicha funci´n o o es una funci´n continua. Como la descomposici´n en frecuencias de la n o se˜al impulso es la funci´n h(f)=1 y la descomposici´n en frecuencias de la se˜al sinc es n o o n igual en el intervalo entre -’F’ y ’F’ y en el resto es 0. La soluci´n m´s com´n o a u adoptada es que el sistema digital genere la funci´n conocida como impulso.

con B ≤ F recCorte ≤ Frecuencia de muestreo.Como consecuencia. n 132 . para generar una se˜al anal´gica continua de ancho de banda ’B’ a n o partir de sus muestras (si la frecuencia de muestreo es mayor a 2’B’) hay que reproducir las muestras multiplicadas por la funci´n impulso (reproducirlas con la misma frecuencia o que fueron muestreadas) y luego aplicarle un filtro pasa bajos de frecuencia de corte F recCorte a la se˜al generada.

// Es e l mismo que e l que e s t a d e f i n i d o en main . // Es e l mismo que e l que e s t a d e f i n i d o en main . 0 xE0CA. int direccionL . // Se comienza a e s c r i b i r en l a p o s i c i ´ n de memoria o 0 x8000 d i r e c c i o n H = 0 x0 . d i r e c c i o n L+=0x3FE ) { MemWriteLatch ( 0 x1 . MemCommand(PM ROW ERASE) . 0 x0 . c // Es e l mismo que e l que e s t a e x t e r n u n s i g n e d s h o r t i n t RAMBuffer [ 2 0 ] . d e f i n i d o en main . d i r e c c i o n L . h” extern short int recibiDatoProg . n e c e s a r i o para poder s o b r e e s c r i b i r l a memoria . d i r e c c i o n L <0x5400 . c e x t e r n c h a r recibiCRC . w h i l e ( RAMBuffer [ 1 5 ] > 0 ) { // M i e n t r a s no s e e s c r i b a l a p o s i c i ´ n f i n a l de o memoria s i g o r e c i b i e n d o d a t o s . c e x t e r n s h o r t i n t terminoPrograma . // Es e l mismo que e l que e s t a d e f i n i d o en main . d i r e c c i o n L .c’ #i n c l u d e ” C a r g a r P r o g S l a v e . d i r e c c i o n L <0xE4C8+0x3FE . d i r e c c i o n L = 0 x8000 . // Es e l mismo que e l que e s t a d e f i n i d o en main . MemCommand(PM ROW ERASE) . c e x t e r n i n t datoProgH . 0 x0 . 0 x0 ) . 0 x0 ) . 0 x0 ) . v o i d cargoPrograma ( ) { f o r ( d i r e c c i o n L =0x8000 . d i r e c c i o n L+=0x3FE ) { // Borra l o s d a t o s d e l i n s t r u m e n t o a n t e r i o r . 0 x5400 . e x t e r n c h a r * CRC L . e x t e r n i n t datoProgL . 0 x0 . 0 x0 . // Es e l mismo que e l que e s t a d e f i n i d o en main . c e x t e r n c h a r r e c i b i C R C d a t o . } MemWriteLatch ( 0 x1 . i f ( r e c i b i D a t o P r o g >1){ 133 . MemCommand(PM ROW ERASE) . } MemWriteLatch ( 0 x0 . int direccionH . MemCommand(PM ROW ERASE) . 0 x0 ) . c´digos de los DSPic esclavos o Clase ’CargarProgSlave. // Es e l mismo que e l que e s t a d e f i n i d o en main . MemWriteLatch ( 0 x0 . c char llevoCuenta = 0 .Anexo B. int llevoCuentaTotal = 0. c e x t e r n i n t datoProg . f o r ( d i r e c c i o n L =0x1174 .

l l e v o C u e n t a T o t a l ++. llevoCuentaTotal = 0. } i f ( d i r e c c i o n L==POS INCREMENTOS L+BUFFER INC) { //La t a b l a de i n c r e m e n t o s e s l a u l t i m a en s e r e s c r i t a . d i r e c c i o n H= POS MASK INICIAL H . d i r e c c i o n L . d i r e c c i o n L=POS MASK INICIAL L . } } } slaves/CargarProgSlave. MemWriteLatch ( d i r e c c i o n H . datoProg ) . d i r e c c i o n L = d i r e c c i o n L +2. Luego f i n a l i z a r ´ l a ´ a f u n c i ´ n y s e v o l v e r ´ a l main .r e c i b i D a t o P r o g =0. // Las d i r e c c i o n e s de memoria aumentan de a dos . } i f ( d i r e c c i o n L==POS MASK INICIAL L+BUFFER MASK) { d i r e c c i o n L=POS CAMBIOS L . } i f ( d i r e c c i o n L==POS CAMBIOS L+BUFFER CAMB) { d i r e c c i o n L=POS INCREMENTOS L . llevoCuentaTotal = 0. d i r e c c i o n H=POS CAMBIOS H . o a RAMBuffer [ 1 5 ] = 0 . MemCommand(CONFIG WORD WRITE) . } i f ( d i r e c c i o n L==POS ARMONICOS L+BUFFER ARM) { //Una vez que s e t e r m i n e de e s c r i b i r en l a p o s i c i ´ n de memoria l o s a r m ´ n i c o s s e va a l a de o o las envolventes . d i r e c c i o n H=POS INCREMENTOS H . l l e v o C u e n t a = l l e v o C u e n t a +1. llevoCuentaTotal = 0.c 134 . 0 x0 .

slaves/CargarProgSlave.h 135 .Clase ’CargarProgSlave. h> #d e f i n e #d e f i n e #d e f i n e #d e f i n e #d e f i n e #d e f i n e PM ROW ERASE 0 x4042 PM ROW WRITE 0 x4001 CONFIG WORD WRITE 0 x4003 PM ERASE SECURE SEG 0x404C PM ERASE GRAL SEG 0x404D UNA RONDA 50 #d e f i n e POS ARMONICOS L 0 x8000 #d e f i n e POS ARMONICOS H 0 x0 #d e f i n e BUFFER ARM 0xA14 #d e f i n e POS INCREMENTOS L 0 x1174 #d e f i n e POS INCREMENTOS H 0 x1 #d e f i n e BUFFER INC 0x468C #d e f i n e POS MASK INICIAL L 0x8A14 #d e f i n e POS MASK INICIAL H 0 x0 #d e f i n e BUFFER MASK 0 x1428 #d e f i n e POS CAMBIOS L 0x9E3C #d e f i n e POS CAMBIOS H 0 x0 #d e f i n e BUFFER CAMB 0x468C v o i d cargoPrograma ( ) .h’ #i n c l u d e <p33FJ128GP802 .

W0 mov W0.NVMKEY mov #0xAA.#15 . MemReadLatch : . ********************************************************** . ********************************************************* .W1 = Wn . MemCommand : .NVMCON mov #0x55 .NVMKEY b s e t NVMCON . .s’ . ********************************************************* . no r e t u r n v a l u e s . [W1] return .W0 = TBLPAG .s 136 .W0 t b l r d h [W1] . [W1] t b l w t h W2. g l o b a l MemReadLatch MemReadLatch : mov W0. no r e t u r n v a l u e s . r e t u r n : data i n W1:W0 .W2 = WordHi . Wait f o r w r i t e end bra Loop return slaves/escribirEnMemoriaConst. . Unlock s e q u e n c e mov W0. TBLPAG t b l w t l W3. MemWriteLatch : .W1 = Wn .W0.W3 = WordLo . g l o b a l MemCommand MemCommand : mov W0.TBLPAG t b l r d l [W1] . .#15 nop . Required nop Loop : b t s c NVMCON .W1 return .Clase ’escribirEnMemoriaConst.W0 = NVMCON .W0 = TBLPAG . g l o b a l MemWriteLatch MemWriteLatch : mov W0.

h” // Este m´todo s i r v e para i n i c i a l i z a r e l DAC a 30Khz .SELACLK = 0 . DAC1STATbits . DAC1CONbits . APSTSCLR = 7 .FORM = 1 .c’ #d e f i n e v al orD ac 18 #i n c l u d e <p33FJ128GP802 . ASRCSEL = 0 .RMVOEN = 1 . c a n a l d e r e c h o . ACLKCONbits .ROEN = 1 .AMPON = 1 . DAC1DFLT = 0 x8000 . DAC1CONbits .Clase ’dac. ACLKCONbits .DACEN = 1 . ACLKCONbits .c 137 . DAC1STATbits . h> #i n c l u d e ” dac . DAC1CONbits . } slaves/dac. e void initDac ( void ) { ACLKCONbits .AOSCMD = 0 .DACFDIV = val orD ac . DAC1CONbits .

slaves/dac.h’ void initDac ( void ) .Clase ’dac.h 138 .

Clase ’efectos. //Lo que hace e s h a c e r que e l v e c t o r ’ p a r a D e v o l v e r ’ apunte a l o s dos b y t e s m´s s i g n i f i c a t i v o s de ’ v a l o r L a r g o ’ . extern int l i m i t e I f . } //−−−−−−−−−−−−−−−−−−− E f e c t o s y s u s m´ todos a u x i l i a r e s −−−−−−−−−−−−−−−−−−−− e v o i d grabarDato ( i n t dato ) { // Este m´todo guarda l o s u l t i m o s s a m p l e s e ´ g e n e r a d o s . p a r a D e v o l v e r++. u l t i m o s [ punteroGuardar ]= dato .c’ #d e f i n e v al orD ac 18 #d e f i n e l a r g o T a b l a S e n o s 15000 #d e f i n e maximoEco 7600 #i n c l u d e ” e f e c t o s . extern int frecCorte . int parametrosEfectos [ 6 ] . i n t p u n t e r o A g r e g a r =0. int copiaActual . e x t e r n c o n s t i n t fCuadrado [ 6 4 ] . //−−−−−−−−−−−−−−−−−−−−−−I n i c i a l i z a c i ´ n de l o s e f e c t o s −−−−−−−−−−−−−−−−−−−−−− o v o i d i n i c i a r E f e c t o s ( ) { // Este m´todo i n i c i a l i z a l o s e f e c t o s e // Debe s e r llamado una vez a n t e s de comenzar a u t i l i z a r l o s e f e c t o s . i n t ) . extern i n t atrasoEco . punteroGuardar++. i n t s a l i d a A n t e s =0. extern const long int parteMultiplicadores [ 6 4 ] . extern int frecuenciaTremolo . u n s i g n e d i n t punteroTremolo =0. extern int frecuenciaVibrato . } } 139 . h” #i n c l u d e ” p 3 3 f j 1 2 8 g p 8 0 2 . i n t * paraDevolver . extern int limiteLog . i n t punteroGuardar =0. a p a r a D e v o l v e r=&v a l o r L a r g o . extern int valorVibrato . long int valorLargo . i n t u l t i m o s [ maximoEco ] . s i r v e para e l e f e c t o ’ e c o ’ . e x t e r n i n t asmFunction ( i n t . e x t e r n c o n s t i n t diviWah [ 6 4 ] . h” //−−−−−−−−−−−−−−−−−−−−−−−−D e c l a r a c i ´ n de v a r i a b l e s −−−−−−−−−−−−−−−−−−−−−−−−− o extern const i n t seno [ largoTablaSenos ] . i f ( punteroGuardar==maximoEco ) { punteroGuardar =0. i n t s a l i d a H a c e 2 =0. e x t e r n i n t magnitudTremolo . e x t e r n u n s i g n e d i n t magnitudEco .

// Finalmente .i n t e c o ( ) { // Este e s e l e f e c t o ’ e c o ’ . i n t i n d i c e=punteroGuardar−a t r a s o E c o . i n t valorEco . 0 s i ’ f r e c C o r t e =0’ 140 . ˜ a i n t m u l t i p l i c a d o r =( s e n o [ punteroTremolo ] −512) * magnitudTremolo +32256. u // Devuelve ’ * p a r a D e v o l v e r ’ que son l o s dos b y t e s m´s s i g n i f i c a t i v o s de a v a l o r L a r g o . // M u l t i p l i c a ’ v a l o r E c o ’ por ’ magnitudEco ’ que e s un n´ mero e n t r e 1 y 6 5 5 3 5 . v a l o r L a r g o =(( l o n g i n t ) m u l t i p l i c a d o r ) * ( ( l o n g i n t ) v a l o r A c t u a l ) . } } i n t wahwah ( i n t v a l o r A c t u a l ) { // Este m´todo d e v u e l v e pasa l a s e n a l por un e ˜ f i l t r o p a s a b a j o s con dos p o l o s . LLama ’ v a l o r E c o ’ a o e s e sample . u // S i magnitudTremlo v a l e c e r o . a } v o i d aumentarPunteroTremolo ( ) { // Este m´todo s e e n c a r g a de aumentar e l e v a l o r d e l c u a l s e va a tomar e l s e n o para e l e f e c t o t r´ m o l o . // Valor l a r g o e s un ’ l o n g i n t ’ que v a l e e l p r o d u c t o de ’ m u l t i p l i c a d o r ’ por ’ valorActual ’ r e t u r n * p a r a D e v o l v e r . u // s e n o [ x ] e s un n´ mero e n t r e −512 y 5 1 2 . } i n t t r e m o l o ( i n t v a l o r A c t u a l ) { // Este m´todo l o que hace e s m u l t i p l i c a r una e s e n a l por una onda s i n u i d a l m´s una c o n s t a n t e . dado que ( −512) * 63=32256 . u //De e s t a forma ’ m u l t p l i c a d o r ’ pasa a s e r un n´ mero e n t r e −32256 y 3 2 2 5 6 . } else { v a l o r E c o=u l t i m o s [ i n d i c e+maximoEco ] . i f ( i n d i c e >=0){ v a l o r E c o=u l t i m o s [ i n d i c e ] . e n t o n c e s m u l t i p l i c a d o r e s una c o n s t a n t e . // S i magnitudTremolo v a l e 6 3 . // Retorna un sample a n t e r i o r ( que tan a n t e r i o r depende de ’ a t r a s o E c o ’ ) m u l t i p l i c a d o por un v a l o r menor a uno que depende de magnitud e c o . m u l t i p l i c a d o r v a l e l a s i n u i d a l pura . // Primero d e t e r m i n a c u a l f u e e l sample que s e g e n e r ´ ’ a t r a s o E c o ’ s a m p l e s a t r a s . i f ( punteroTremolo >( l a r g o T a b l a S e n o s −1) ) { // V e r i f i c o que e l v a l o r d e l c u a l voy a tomar e l s e n o no p a s e e l l a r g o de l a t a b l a de s e n o s . a // ’ magnitudTremolo ’ e s un n´ mero e n t r e 1 y 6 3 . punteroTremolo=punteroTremolo−l a r g o T a b l a S e n o s . //La f r e c u e n c i a de c o r t e e s Fs /2 s i ’ f r e c C o r t e =63 ’ . e s d e c i r que e s como d e v o l v e r ’ v a l o r E c o ’ * ’ magnitudEco ’ / 6 5 5 3 5 . // ’ m u l t i p l i c a d o r ’ e s e l v a l o r de l a onda s i n u i d a l m´s l a c o n s t a n t e . e punteroTremolo+=f r e c u e n c i a T r e m o l o . } v a l o r L a r g o =(( l o n g i n t ) magnitudEco ) * ( ( l o n g i n t ) v a l o r E c o ) . s e d e v u e l v e ’ * p a r a D e v o l v e r ’ que son l o s dos b y t e s m´s s i g n i f i c a t i v o s de v a l o r L a r g o . return * paraDevolver .

e // El f i l t r o e s una suma de p r o d u c t o s que l u e g o s e d i v i d e e n t r e un d i v i s o r . v a l o r L a r g o =( * p a r a D e v o l v e r ) . s e r ’ valorLargo ’* valorActual . } return valorActual . a v a l o r L a r g o =( v a l o r L a r g o ) * ( ( l o n g i n t ) v a l o r A c t u a l ) . // ’ ValorLargo ’ Primero toma e l v a l o r de l a suma de l o s productos . i f ( v a l o r A c t u a l <menosLimite ) { r e t u r n menosLimite . // ’ v a l o r L a r g o ’ pasa a 4* s a l i d a A n t e s . a v a l o r L a r g o =(( l o n g i n t ) v a l o r A c t u a l ) * ( ( l o n g i n t ) v a l o r A c t u a l ) . v a l o r L a r g o =( * p a r a D e v o l v e r ) . u //La i d e a e s que e s t e e f e c t o e s como una s a t u r a c i ´ n . } i n t menosLimite=(− l i m i t e I f ) .c o p i a A c t u a l=v a l o r A c t u a l / 4 . } i n t l i m i t a d o r L o g ( i n t v a l o r A c t u a l ) { // Esta f u n c i ´ n d e v u e l v e o v a l o r A c t u a l −l i m i t e L o g * v a l o r A c t u a l ˆ 3 / 3 2 7 6 8 ˆ 3 . // Por t o d a s l a s m u l t i p l i c a c i o n e s y d i v i s i o n e s que s e hacen l o s v a l o r e s i n t e r m e d i o s pueden s e r mayor a l m´ximo v a l o r que e l t i p o de v a r i a b l e que l o c o n t i n e n . r e a l i z a l a d i v i s i ´ n : ’ ValorLargo ’ / ’ diviWah ’ o o return } i n t l i m i t a d o r I f ( i n t v a l o r A c t u a l ) { // Este m´todo e s s o l o un i f . //Dado que e l d i v i s o r no depende de l o s v a l o r e s de y ( n ) . // ’ v a l o r L a r g o ’ e s ’ v a l o r A c t u a l ’ ˆ 2 . m´s s e nota . i f ( v a l o r A c t u a l >l i m i t e I f ) { return l i m i t e I f . cuanto mayor e s e l o v a l o r de ’ v a l o r A c t u a l ’ . tenemos l o s d i v i s o r e s guardados en una t a b l a . ( ( diviWah [ f r e c C o r t e ] ) ) ) . En e s t e momento ’ * p a r a D e v o l v e r ’ v a l e l i m i t e L o g * v a l o r A c t u a l ˆ3/65536ˆ3 141 . // ’ v a l o r L a r g o ’ pasa a s e r s o l o s u s dos b y t e s m´s s i g n i f i c a t i v o s . // l i m i t e L o g e s un n´ mero que v a l e de 0 a 1 2 0 0 0 . // M u l t i p l i c o v a l o r L a r g o por ’ l i m i t e L o g ’ . de e s t a forma e s como s i l o d i v i d i e r a e n t r e 6 5 5 3 6 . //La f u n c i ´ n ’ asmFunction ’ . // Se a c t u a l i z a e l v a l o r de y ( n−2) . s a l i d a H a c e 2=s a l i d a A n t e s . // ’ v a l o r L a r g o ’ pasa a s e r s o l o s u s dos b y t e s m´s s i g n i f i c a t i v o s . a v a l o r L a r g o =( v a l o r L a r g o ) * ( ( l o n g i n t ) ( l i m i t e L o g ) ) . s a l i d a A n t e s=asmFunction ((& v a l o r L a r g o ) . de e s t a forma e s como s i l o d i v i d i e r a e n t r e 6 5 5 3 6 . v a l o r L a r g o =(( l o n g i n t ) s a l i d a A n t e s ) * ( ( l o n g i n t ) ( p a r t e M u l t i p l i c a d o r e s [ f r e c C o r t e ] ) ) −(( l o n g i n t ) s a l i d a H a c e 2 ) * 16384+( fCuadrado [ f r e c C o r t e ] ) * ( ( l o n g i n t ) c o p i a A c t u a l ) . s i e l v a l o r e a b s o l u t o de l a s a l i d a s u p e r a c i e r t o v a l o r pasa a v a l e r e s e v a l o r . a // Por e s o a n t e s de a p l i c a r e l f i l t r o d i v i d i m o s e l n´ mero a f i l t r a r e n t r e 4 u y d e s p u´ s l o m u l t i p l i c a m o s por 4 .

r e t u r n ( v a l o r A c t u a l −8 * ( * p a r a D e v o l v e r ) ) ; // Devuelvo v a l o r A c t u a l −8 * ( * p a r a D e v o l v e r )=v a l o r A c t u a l −l i m i t e L o g * v a l o r A c t u a l ˆ 3 / 3 2 7 6 8 ˆ 3 . } v o i d v i b r a t o ( ) { // Esta f u n c i ´ n l o que hace e s cambiar l a f r e c u e n c i a de o s a l i d a d e l DAC. i f ( v a l o r V i b r a t o >85){ // S i v a l o r V i b r a t o >85 e n t o n c e s l a f r e c u e n c i a de s a l i d a d e l DAC aumenta . DAC1CONbits .DACFDIV=valorDac −1; return ; } i f ( v a l o r V i b r a t o <40){ // S i v a l o r V i b r a t o <40 , e n t o n c e s l a f r e c u e n c i a de s a l i d a d e l DAC aumenta . DAC1CONbits .DACFDIV=val orD ac +1; return ; } DAC1CONbits .DACFDIV=v al orD ac ; }

slaves/efectos.c

142

Clase ’efectos.h’
void i n i c i a r E f e c t o s ( ) ; v o i d grabarDato ( i n t dato ) ; i n t eco ( ) ; v o i d aumentarPunteroTremolo ( ) ; i n t tremolo ( i n t valorActual ) ; i n t wahwah ( i n t v a l o r A c t u a l ) ; int l i m i t a d o r I f ( int valorActual ) ; int limitadorLog ( int valorActual ) ; void vibrato ( ) ;

slaves/efectos.h

143

Clase ’call2.s’
. g l o b a l asmFunction asmFunction : mov w1 , w3 mov [ w0 ] , w4 i n c w0 , w0 i n c w0 , w0 mov [ w0 ] , w5 r e p e a t #17 d i v . s d w4 , w3 ; d i v i d e w5w4/w3 return .end

slaves/call2.s

144

Clase ’I2C.c’
#i n c l u d e ” p 3 3 f j 1 2 8 g p 8 0 2 . h” #i n c l u d e ” I2C . h” //−−−−−−−−−−−−−−−−−−−−−−−−D e c l a r a c i ´ n de v a r i a b l e s o −−−−−−−−−−−−−−−−−−−−−−−−− unsigned short i n t recibiPunVel ; unsigned i n t recibiPunEfecto ; s t r u c t FlagType Flag ; extern short int recibiDatoProg ; e x t e r n i n t datoProgL ; e x t e r n i n t datoProgH ; e x t e r n i n t datoProg ; e x t e r n s h o r t i n t terminoPrograma ; extern char recibiCRC dato ; e x t e r n c h a r recibiCRC ;

//−−−−−−−−−−−−−−−−−−−−−−−M´todo para i n c i a r e l I2C−−−−−−−−−−−−−−−−−−−−−−−− e void i 2 c 1 i n i t ( void ) { TRISB=0XFFFF ; ODCBbits .ODCB5=1; ODCBbits .ODCB6=1; ODCBbits .ODCB8=1; ODCBbits .ODCB9=1; I2C1ADD = d i r e c c i o n ; RAMPtr = &RAMBuffer [ 0 ] ; Flag . AddrFlag = 0 ; Flag . DataFlag = 0 ; I E C 1 b i t s . SI2C1IE = 1 ; } //−−−−−−−−−−−−−−−−−−−−−−Manejo de i n t e r r u p c i ´ n de I2C−−−−−−−−−−−−−−−−−−−−−− o void a t t r i b u t e ( ( i n t e r r u p t , n o a u t o p s v ) ) S I 2 C 1 I n t e r r u p t ( v o i d ) { // Este m´todo hace r e s p o n d e r a l DSPic como una memoria de 20 p o s i c i o n e s . e // Tambi´n s e comporta como una memoria de 20 p o s i c i o n e s , guardando en e ’ RAMBuffer [ 2 0 ] ’ l o s d a t o s que r e c i b e . u n s i g n e d c h a r Temp ; // Se usa para l e c t u r a s temporales futuras .

i f ( ( I2C1STATbits .R W == 0 )&&(I2C1STATbits . D A == 0 ) ) { // Compruebo s i e s t e n hablando con mi d i r e c c i ´ n y s e s o l i c i t o una e s c r i t u r a . o Temp = I2C1RCV ; // Leo e l dato r e c i b i d o . Flag . AddrFlag = 1 ; // Aviso que e l pr´ ximo dato va a s e r l a d i r e c c i ´ n o o d e n t r o de l a memoria . } e l s e i f ( ( I2C1STATbits .R W == 0 )&&(I2C1STATbits . D A == 1 ) ) { // Chequeo a v e r s i no f u e una d i r e c c i ´ n , p e r o e s una orden de e s c r i t u r a . o i f ( Flag . AddrFlag ) { // Chequeo s i e l dato que r e c i b´ ( y t o d a v´a no l e´ ) ı ı ı l a d i r e c c i ´ n d e n t r o de ’ RAMBuffer [ 2 0 ] ’ donde debo e s c r i b i r . o

145

Flag . AddrFlag = 0 ; Flag . DataFlag = 1 ;

// Aviso que e l pr´ ximo byte e s e l de d a t o s . o

Temp=I2C1RCV ; // Leo e l dato que r e c i b´ . ı RAMPtr = RAMPtr + Temp ; //RAMPtr e r a l a d i r e c c i ´ n donde comienza o ’ RAMBuffer ’ , ahora e s l a d i r e c c i ´ n donde debo e s c r i b i r . o i f (Temp==0){ if . // S o l o para que s i temp =0 no p r e g u n t e por l o s o t r o s

} e l s e i f (Temp==1){ // Chequeo s i e s c r i b e n en l a d i r e c c i ´ n o c o r r e s p o n d i e n t e a l a ’ v e l o c i d a d ’ de l a nota a t o c a r , s i e s e e s e l c a s o hay que a v i s a r que cuando r e c i b a l a v e l o c i d a d voy a t e n e r todo para g e n e r a r una nota . r e c i b i P u n V e l =1; } e l s e i f (Temp<8){ // S i Temp e s t a e n t r e 2 y 7 e s por que e l pr´ ximo o dato e s uno de l o s p a r ´ m e t r o s de uno de l o s e f e c t o s . a r e c i b i P u n E f e c t o =1; } i f (Temp==11){ // S i Temp=11 e s por que voy a empezar a r e c i b i r d a t o s para programar un i n s t r u m e n t o . recibiDatoProg = 1; } i f (Temp==12){ // S i Temp=12 e s por que s e t e r m i n o de programar un instrumento . terminoPrograma =1; } i f (Temp==16){ // S i Temp=16 e s por que me van a e n v i a r un CRC. recibiCRC = 1 ; } } e l s e i f ( Flag . DataFlag ) { // Chequeo s i e l dato que r e c i b´ ( y t o d a v´a no ı ı l e´ ) e s un dato para g u a r d a r en l a memoria . ı Temp=I2C1RCV ; // Leo e l dato que r e c i b´ . ı
*RAMPtr = ( u n s i g n e d c h a r )Temp ;

// Guardo e l dato en l a memoria .

i f ( r e c i b i P u n V e l ) { // S i l o que r e c i b´ f u e una v e l o c i d a d , a v i s o que ya ı e s t o y l i s t o para g e n e r a r un s o n i d o . r e c i b i P u n V e l =0; bandera =2; } i f ( r e c i b i P u n E f e c t o ) { // S i l o que r e c i b´ f u e un par´ metro de un ı a e f e c t o , a v i s o que hay que a c t u a l i z a r l o s p a r ´ m e t r o s de l o s a efectos . r e c i b i P u n E f e c t o =0;

146

o Flag . me p r e p a r o para empezar y avis´ .c 147 . } SI2C1IF = 0 . ı o Temp = I2C1RCV . // Espero que t e r m i n e e l e n v´o . // Leo e l dato r e c i b i d o . // Leo e l dato de ’ RAMBuffer ’ y l o e n v´o v´a I2C a l ı ı I2C1CONbits . // Coloco e l v a l o r d e l r e g i s t r o r e c i b i D a t o P r o g en 2 para i n d i c a r l e a l programa que ya puede g r a b a r una p o s i c i ´ n o de memoria . } i f ( recibiCRC==1){ // S i l o que r e c i b´ f u e un CRC. a e r e c i b i D a t o P r o g =2. R e i n i c i o b a n d e r a s . AddrFlag = 0 . // R e i n i c i o e l p u n t e r o a ’ RAMBuffer ’ . } Flag . // El r e s u l t a d o l o almaceno en datoProg que s e r ´ e l que g r a b a r´ en memoria . RAMPtr = &RAMBuffer [ 0 ] .TBF) . // Borro l a bandera de i n t e r r u p c i ´ n d e l I2C . o } slaves/I2C. ı r e c i b i C R C d a t o=Temp . o datoProgH=RAMBuffer [ 1 0 ] * 0 x100 . maestro . DataFlag = 0 . I2C1TRN = *RAMPtr .R W == 1 )&&(I2C1STATbits . } } e l s e i f ( ( I2C1STATbits .banderaCambioEfectos =2. datoProg=datoProgH+datoProgL . // R e i n i c i o e l p u n t e r o a ’ RAMBuffer ’ . SCLREL = 1 . D A == 0 ) ) { // Chequeo s i l o que r e c i b´ f u e una orden de e n v i a r d a t o s y f u e a mi d i r e c c i ´ n . l o almaceno . // l i b e r o l a l i n e a SCL1 w h i l e ( I2C1STATbits . ı RAMPtr = &RAMBuffer [ 0 ] . } i f ( r e c i b i D a t o P r o g ==1){ // S i l o que r e c i b´ f u e l a s e n a l de que hay ı ˜ que empezar a programar un i n s t u m e n t o s . // Fin de l a t r a n s m i c i ´ n . // M u l t i p l i c o e l byte m´s a s i g n i f i c a t i v o d e l i n t por 0 x100 para c o r r e r l o dos p o s i c i o n e s a l a d e r e c h a y l e sumo e l menos s i g n i f i c a t i v o datoProgL=RAMBuffer [ 1 1 ] .

e x t e r n u n s i g n e d s h o r t i n t banderaCambioEfectos . u n s i g n e d c h a r DataFlag : 1 . // P o i n t e r t o RAM memory l o c a t i o n s void i 2 c 1 i n i t ( void ) . e x t e r n u n s i g n e d s h o r t i n t RAMBuffer [ 2 0 ] .Clase ’I2C. void a t t r i b u t e ( ( interrupt . extern int multiplicador . EEPROM f o r Master I2C d e v i c e s t r u c t FlagType { u n s i g n e d c h a r AddrFlag : 1 . e x t e r n s t r u c t FlagType Flag . no auto psv ) ) SI2C1Interrupt ( void ) .h’ #d e f i n e d i r e c c i o n 0 x4e e x t e r n u n s i g n e d s h o r t i n t bandera . }. extern int lim ite . //RAM a r e a which w i l l work a s slaves/I2C. //RAM a r e a which w i l l work a s EEPROM f o r Master I2C d e v i c e e x t e r n u n s i g n e d s h o r t i n t *RAMPtr .h 148 . // e x t e r n u n s i g n e d c h a r RAMBuffer [ 2 5 6 ] . // c o n s t i n t a b o r r a r =3.

PLLPOST = 0 . w h i l e ( OSCCONbits . h” // Este m´todo c o n f i g u r a e l DSPic para que t r a b a j e con su o s c i l a d o r i n t e r n o e a su m´xima v e l o c i d a d .c 149 . PLLPRE = 0 . } slaves/iniciarReloj. CLKDIVbits . OSCTUN = 0 . builtin write OSCCONH ( 0 x01 ) .LOCK != 1 ) { } . a void InitClock ( ) { PLLFBD = 4 1 .COSC != 0 b001 ) . RCONbits . w h i l e ( OSCCONbits .c’ #i n c l u d e <p33FJ128GP802 .SWDTEN = 0 .Clase ’iniciarReloj. h> #i n c l u d e ” i n i c i a r R e l o j . CLKDIVbits . builtin write OSCCONL ( 0 x01 ) .

slaves/iniciarReloj.Clase ’iniciarReloj.h’ void InitClock ( ) .h 150 .

h” v o i d mapearPuertos ( ) { // Este m´todo s e e n c a r g a de mapear l o s p u e r t o s e remapeables . RPINR18bits . builtin write OSCCONL (OSCCON & ˜(1<<6) ) . U1CTSR = 1 . AD1PCFGL=0xFFFF . TRISB=1. // Asigno U1RTS a RP3 . h> #i n c l u d e ” manejoPuertos .U1RXR = 0 . builtin write OSCCONL (OSCCON | (1<<6) ) . RPOR1bits . RPINR18bits . RPOR1bits . // Asigno U1CTS a RP1 . } slaves/manejoPuertos. // Asigno U1RX a RP0 .c’ #i n c l u d e <p33FJ128GP802 . // Bloqueo l o s r e g i s t r o s .Clase ’manejoPuertos.c 151 . RP3R = 4 . RP2R = 3 . // Desbloqueo l o s r e g i s t r o s . // Asigno U1TX a RP2 .

h 152 . slaves/manejoPuertos.Clase ’manejoPuertos.h’ v o i d mapearPuertos ( ) .

psv const unsigned i n t a t t r i b u t e ( ( s p a c e ( psv ) .h 153 . psv const unsigned i n t a t t r i b u t e ( ( s p a c e ( psv ) ) ) todosLosCambios [ 8 6 ] [ 1 5 ] [ 7 ] . o const i n t seno [ 1 5 0 0 0 ] . psv const long int a t t r i b u t e ( ( s p a c e ( psv ) ) ) e n v o l s I n i c i a l e s [ 8 6 ] [ 1 5 ] slaves/encTablas. c o n s t i n t fCuadrado [ 6 4 ] .Clase ’tablas. const long int parteMultiplicadores [ 6 4 ] . psv const int a t t r i b u t e ( ( s p a c e ( psv ) ) ) todosLosIncrementos [ 8 6 ] [ 1 5 ] [ 7 ] . o se decidi´ colocar solo el encabezado de las tablas. psv const unsigned i n t a t t r i b u t e ( ( s p a c e ( psv ) ) ) TodosLosAumentosSeno [ 8 6 ] [ 1 5 ] . a d d r e s s ( 0 xE4C8 ) ) ) espacioLibre [ 5 0 0 ] .h’ Dado que esta clase contiene s´lo tablas y algunas de ellas tienen varios miles de elementos. c o n s t i n t diviWah [ 6 4 ] .

// Esta v a r i a b l e i n d i c a s i s e r e c i b i ´ n una o i n s t r u c c i ´ n MIDI completa y e s n e c e s a r i o i n t e r p r e t a r l a . FOSC(FCKSM CSECMD & OSCIOFNC OFF FWDT(FWDTEN OFF) . //RAMBuffer [ 1 5 ] i n d i c a s i hay que cambiar e l i n s t r u m e n t o . i n t . u //RAMBuffer [ 1 0 ] e s e l byte m´s s i g n i f i c a t i v o d e l i n t de data r e c i b i d o a cuando s e c a r g a e l nuevo i n s t r u m e n t o //RAMBuffer [ 1 1 ] e s e l byte menos s i g n i f i c a t i v o d e l i n t de data r e c i b i d o cuando s e c a r g a e l nuevo i n s t r u m e n t o //RAMBuffer [ 1 2 ] e s donde s e g u a r d a r ´ e l CRC r e c i b i d o por e l maestro . & POSCMD NONE) .c’ #d e f i n e maximoCiclos 200000 #d e f i n e l a r g o T a b l a S e n o s 15000 #d e f i n e s a m p l e s B a j a r 60 #i n c l u d e <p33FJ128GP802 . h” //−−−−−−−−−−−−−−−−−−−−−−−−−−−−−C o n f i g u r a c i ´ n −−−−−−−−−−−−−−−−−−−−−−−−−−−−−− o FOSCSEL(FNOSC FRC) . //−−−Almacenamiento de d a t o s e x t e r n o s para g e n e r a c i ´ n d e l s o n i d o −−− o u n s i g n e d s h o r t i n t RAMBuffer [ 2 0 ] . i n t . h” #i n c l u d e ” manejoPuertos . //RAMBuffer [ 1 ] e s l a i n t e n s i d a d con l a que hay que r e p r o d u c i r l a nota . //RAMBuffer [ 2 ] e s e l p r i m e r par´ mtero d e l p r i m e r e f e c t o que s e l e va a a p l i c a r al sonido . //RAMBuffer [ 0 ] e s l a nota que hay que reproducir . //RAMBuffer [ 4 ] e s e l segundo par´ mtero d e l p r i m e r e f e c t o que s e l e va a a p l i c a r al sonido . o u n s i g n e d s h o r t i n t banderaCambioEfectos . //Cada e f e c t o t i e n e un n´ mero a s o c i a d o . a //RAMBuffer [ 1 3 ] e s donde s e g u a r d a r ´ e l byte r e s u l t a n t e de c a l c u l a r a n u e s t r o CRC. h> #i n c l u d e ” dac . i n t ) . //−−−−−−−−−−−−−−−M´ todos en a s s e m b l e r que s e u t i l i z a r ´ n −−−−−−−−−−−−−−−− e a e x t e r n i n t MemWriteLatch ( i n t .Clase ’Main. //RAMBuffer [ 7 ] e s e l n´ mero d e l segundo e f e c t o que s e va a a p l i c a r . //RAMBuffer [ 5 ] e s e l segundo par´ mtero d e l segundo e f e c t o que s e l e va a a p l i c a r al sonido . h” #i n c l u d e ” t a b l a s . //RAMBuffer [ 3 ] e s e l p r i m e r par´ mtero d e l segundo e f e c t o que s e l e va a a p l i c a r al sonido . RAMBuffer [ 6 ] e s e l n´ mero de e f e c t o u u que s e va a a p l i c a r p r i m e r o . 154 . h” #i n c l u d e ” e f e c t o s . // Esta v a r i a b l e i n d i c a s i s e r e c i b i o n una i n s t r u c c i ´ n de cambio de uno de l o s par´ mtros de l o s ´ o a efectos . h” #i n c l u d e ” I2C . //−−−−−−−−−−−−−−−Banderas para l a g e n e r a c i ´ n de s o n i d o s −−−−−−−−−−−−−−−− o u n s i g n e d s h o r t i n t bandera . e x t e r n i n t MemCommand( i n t ) .

l o s v a l o r e s de l a t a b l a de cambios de e s a nota s e c o p i a n de l a memoria de programaci´ n a e s t e v e c t o r . // Esta v a r i a b l e i n d i c a l a ’ v e l o c i d a d ’ de l a nota que hay que r e p r o d u c i r . 0 . reproducir . 0 . // Es e l p u n t e r o a l ´ r e a de memoria mencionada . 0 . // Guarda e l v a l o r de cada una de l a s m´ scaras . 0 . 0 . 0 . u n s i g n e d s h o r t i n t nota . l a o s a l i d a e s c a l c u l a d a com un ’ l o n g i n t ’ . a i n t i n d i c e s [ ] = { 0 . 0 . u n s i g n e d s h o r t i n t s a m p l e s P a r a B a j a r . // Esta v a r i a b l e i n d i c a l a nota que hay que u n s i g n e d s h o r t i n t estoyEnNoteOff =0. 0 . o u n s i g n e d i n t aumentosSeno [ 1 5 ] . 0 } . 0 . // Este e s e l v e c t o r que i n d i c a en que v a l o r d e l s e n o e s t a cada una de l a s componentes de l a nota . // Cuenta c u a n t o s s a m p l e s p a s a r o n d e s d e l a u l t i m a vez que b a j e l a v e l o c i d a d . e s t a v a r i a b l e i n d i c a l a c a n t i d a d r e c i b i d a de b y t e s de una i n s t r u c c i ´ n MIDI que s e e s t a r e c i b i e n d o . 0 . // Esta v a l e l o apuntado por e l p u n t e r o ’ s a l i d a ’ l o n g i n t c i c l o s =0. //Una vez que s e r e c i b e l a s e n a l de t o c a r c i e r t a ˜ nota . 0 . 0 . e s t a v a r i a b l e e s l a que toma e s e valor . o i n t * punteroMascaras [ 1 5 ] . 0 .u n s i g n e d s h o r t i n t *RAMPtr . l a ’ v e l o c i d a d ’ e s a l i n t e n s i d a d . i n t t i e m p o s [ ] = { 0 . 0 . 0 . i n t * s a l i d a . l o s v a l o r e s de l a t a b l a de aumentosSeno de e s a nota s e c o p i a n de l a memoria de programaci´ n a e s t e v e c t o r . a //−−−−−−−−−−−−−V a r i a b l e s i n t e r n a s de g e n e r a c i ´ n d e l s o n i d o −−−−−−−−−−−−− o long int envols [ 1 5 ] . // s a l i d a L o n g e s e l r e s u l t a d o de l a suma de cada f r e c u e n c i a por su envolvente . l o s v a l o r e s de l a t a b l a de i n c r e m e n t o s de e s a nota s e c o p i a n de l a memoria de programaci´ n a e s t a m a t r i z . // S i e s t o y en ’ n o t e o f f ’ cada ’ s a m p l e s B a j a r ’ s a m p l e s c a l c u l a d o s b a j o en 1 l a v e l o c i d a d . ´ l o n g i n t s a l i d a L o n g . 0 . // Este v e c t o r t i e n e un p u n t e r o a l byte m´s a s i g n i f i c a t i v o de cada uno de l o s e l e m e n t o s d e l v e c t o r ’ e n v o l s ’ u n s i g n e d s h o r t i n t posDato . 0 . 0 } . //Una vez que s e r e c i b e l a s e n a l de t o c a r ˜ c i e r t a nota . 0 . // Este v e c t o r apunta a l o s dos b y t e s m´s s i g n i f i c a t i v o s d e l a n´ mero ’ s a l i d a L o n g ’ . 0 . // Esta v a r i a b l e l l e v a e l c o n t e o de l a c a n t i d a d de m ue s t ra s g e n e r a d a s ya d e l s o n i d o de l a nota que s e e s t a r e p r o d u c i e n d o //−−−−−−−−−−−−−−V a r i a b l e s para l a r e p r o d u c c i ´ n de e f e c t o s −−−−−−−−−−−−−− o 155 . i n t i n c r e m e n t o s [ 1 5 ] [ 7 ] . 0 . //Cada i n s t r u c c i ´ n MIDI e s t a compuesta por o v a r i o s bytes . 0 . // Este v e c t o r i n d i c a en que v a l o r de l a t a b l a de i n c r e m e n t o s de cada e n v o l v e n t e s e e s t a . o l o n g i n t cambios [ 1 5 ] [ 7 ] . // Para m e j o r a r l a p r e s i c i ´ n en l a s c u e n t a s . 0 . //Una vez que s e r e c i b e l a s e n a l de t o c a r ˜ c i e r t a nota . 0 . u int salidaAUtilizar . o u n s i g n e d s h o r t i n t v e l o c i d a d . 0 . 0 . 0 .

// Es una v a r i a b l e a u x i l i a r u t i l i z a d a para s a b e r l a f r e c u e n c i a de c o r t e en e l e f e c t o ’ wah wah ’ . // Es una v a r i a b l e a u x i l i a r u t i l i z a d a para s a b e r donde poner e l l´ m i t e en e l e f e c t o ’ l i m i t e I f ’ . e u n s i g n e d i n t magnitudEco . // Es una v a r i a b l e a u x i l i a r u t i l i z a d a para s a b e r l a magnitud de l a i n f l u e n c i a d e l e f e c t o ’ e c o ’ . // Es una v a r i a b l e a u x i l i a r u t i l i z a d a para s a b e r l a magnitud de i n f l u e n c i a d e l e f e c t o ’ t r´ m o l o ’ . // Es una v a r i a b l e a u x i l i a r u t i l i z a d a para s a b e r l a f r e c u e n c i a en e l e f e c t o ’ t r´ m o l o ’ . c ’ v o i d r eal iza rCR C ( i n t v a l o r ) { CRC += v a l o r . ı i n t l i m i t e L o g . l o n g i n t CRC. i n t datoProgL . char recibiCRC dato = 0 . //−V a r i a b l e s para l a r e p r o g r a m a c i ´ n de l a memoria de programaci´ n−− o o i n t datoProg . c h a r recibiCRC . i n t a t r a s o E c o . e void agregarNota ( ) { unsigned short i n t i . short int recibiDatoProg . ı i n t v a l o r V i b r a t o . // Es una v a r i a b l e a u x i l i a r u t i l i z a d a para s a b e r que f r e c u e n c i a u t i l i z a r en e l e f e c t o ’ v i b r a t o ’ . i n t f r e c C o r t e . i n t magnitudTremolo . e i n t f r e c u e n c i a T r e m o l o . j . l l a m a a e s t e m´todo . i n t datoProgH . } //−−−−−−−−−M´todo para l a i n t e r p r e t a c i ´ n de comandos MIDI−−−−−−−−−− e o //Cuando e l programa d e t e c t a que s e r e c i b i e r o n s u f i c i e n t e s d a t o s por I2C como para poder g e n e r a r una nota . c h a r * CRC L . // Es una v a r i a b l e a u x i l i a r u t i l i z a d a para s a b e r donde poner e l l´ m i t e en e l e f e c t o ’ l i m i t e L o g ’ .i n t l i m i t e I f . s h o r t i n t terminoPrograma . //−−−−−−−−−−−−−−Fin de l a d e c l a r a c i ´ n de v a r i a b l e s g l o b a l e s −−−−−−−−−−−−−− o //−−−−−−−−−−−−−−−−−−−−−M´ todos para l a r e p r o g r a m a c i ´ n de l a memoria de e o programaci´ n ( para cambiar e l i n s t r u m e n t o )−−−−−−−−−−−−−−−−−−−−−− o //La mayor´ de l o s m´ todos para l a reprogramamci´ n s e e n c u e n t r a n en ıa e o ’ Cargar P r o g S l a v e . 156 . char llegoFF . // Es una v a r i a b l e a u x i l i a r u t i l i z a d a para s a b e r e l a t r a s o del e f e c t o ’ eco ’ .

j <7. e s t a t a b l a i n d i c a l a f r e c u e n c i a de l a s componentes de l a nota . i <15. por l o c u a l s e l o a s o c i a a l a v a r i a b l e ’ nota ’ i f ( nota ==100){ estoyEnNoteOff =1. Esta c u e n t a s i r v e para s a b e r cuando l l e g o e l momento de cambiar l o s i n c r e m e n t o s de cada e n v o l v e n t e . // Se c o p i a n en l a m a t r i z ’ cambios ’ l o s e l e m e n t o s de l a m a t r i z ’ todosLosCambios ’ que c o r r e s p o n d e n a l a nota a r e p r o d u c i r . } //−−−−−−−−−−−−M´todo para c a l c u l a r e l v a l o r de l o s samples−−−−−−−−−−−−− e void calcularSample ( ) { 157 . aumentosSeno [ i ]= TodosLosAumentosSeno [ nota ] [ i ] . // Se r e i n i c i a e l v a l o r de l a t a b l a de s e n o s donde comienza cada componente de l a nota . t i e m p o s [ i ] = 0 . s a m p l e s P a r a B a j a r =0. para que t o d a s l a s e n v o l v e n t e s comiencen aumentando por su p r i m e r i n c r e m e n t o . j ++){ cambios [ i ] [ j ] = 1 0 * ( ( l o n g i n t ) todosLosCambios [ nota ] [ i ] [ j ] ) .nota=RAMBuffer [ 0 ] . // Se m u l t i p l i c a por 10 por que para a h o r r a r memoria de programaci´ n l o s o cambios s e guardan d i v i d i o s e n t r e 1 0 . l o s v a l o r e s con l o s c u a l e s comienzan t o d a s l a s m´ scaras a de l a nota a r e p r o d u c i r . } else { estoyEnNoteOff =0. // Se c o p i a n en e l v e c t o r ’ e n v o l s ’ . // Se c o p i a n en e l v e c t o r ’ aumentosSeno ’ t o d o s l o s v a l o r e s de l a t a b l a ’ TodosLosAumentosSeno ’ . // Se c o p i a n en l a m a t r i z ’ i n c r e m e n t o s ’ l o s e l e m e n t o s de l a m a t r i z ’ t o d o s L o s I n c r e m e n t o s ’ que c o r r e s p o n d e n a l a nota a r e p r o d u c i r . // Se r e i n i c i a e l v e c t o r i n d i c e s . por l o c u a l s e l o a s o c i a a l a v a r i a b l e ’ v e l o c i d a d ’ f o r ( i =0. } return . i ++){ e n v o l s [ i ]= e n v o l s I n i c i a l e s [ nota ] [ i ] . i n c r e m e n t o s [ i ] [ j ]= t o d o s L o s I n c r e m e n t o s [ nota ] [ i ] [ j ] . // Se r e i n i c i a l a c u e n t a de l o s c i c l o s . i n d i c e s [ i ] = 0 . f o r ( j =0. // Rumbuffer [ 1 ] guarda l a v e l o c i d a d de nota a r e p r o d u c i r . d i c h a m a t r i z c o n t i e n e l a i n f o r m a c i ´ n para s a b e r cuando cada o e n v o l v e n t e debe v a r i a r su i n c r e m e n t o . // Rumbuffer [ 0 ] guarda e l n´ mero de nota a u r e p r o d u c i r . d i c h a m a t r i z c o n t i e n e l o s i n c r e m e n t o s que s e l e hacen a cada e n v o l v e n t e l u e g o de g e n e r a r cada sample . } } c i c l o s =0. v e l o c i d a d=RAMBuffer [ 1 ] .

158 . o e n v o l s [ 0 ] = e n v o l s [ 0 ] + i n c r e m e n t o s [ 0 ] [ i n d ] . i n d i c e s [0]+=1. // Esta v a r i a b l e s i r v e para almacenar con c u a l de s u s i n c r e m e n t o s e s t a s i e n d o i n c r e m e n t a d a l a componenente que s e e s t a analizando . } //−−−−−−−−−−−−−C ´ l c u l o de l a s o t r a s componentes d e l sample−−−−−−−−−−−−− a // Las r e s t a n t e s componentes d e l sample s e c a l c u l a n de forma an´ loga . envols [0]=0. // ’ * punteroMascaras [ 0 ] ’ e s un p u n t e r o que apunta a l o s 2 b y t e s m´s a s i g n i f i c a t i v o s de l a e n v o l v e n t e que s e l e a p l i c a a l a p r i m e r f r e c u e n c i a . e l v a l o r de una o e n v o l v e n t e e s menor a c e r o . // Se aumenta e l v a l o r d e l c u a l s e va a c a l c u l a r e l s e n o en e l pr´ ximo sample . o //La v a r i a b l e ’ * punteroMascaras [ 0 ] ’ . i n d=i n d i c e s [ 1 ] . donde i e s l a e n v o l v e n t e a a n a l i z a r . } i f ( e n v o l s [ 0 ] < 0 ) { // S i por a l g u n a i m p r e s i c i ´ n en l a t a b l a de o i n c r e m e n t o s o por a l g u n a o t r a i m p r e s i c i ´ n . //−−−−−−−−−−−−−−−−−−−−−−−−C ´ l c u l o de l a p r i m e r componente d e l a sample−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−−− i f ( c i c l o s <maximoCiclos ) { i n d=i n d i c e s [ 0 ] . t i e m p o s [ 0 ] = t i e m p o s [ 0 ] + aumentosSeno [ 0 ] . } i f ( c i c l o s >cambios [ 0 ] [ i n d ] ) { // Se comprueba s i l a c a n t i d a d de s a m p l e s c a l c u d o s s u p e r a l a c a n t i d a d a l a c u a l hay que m o d i f i c a r e l i n c r e m e n t o s de l a e n v o l v e n t e . s e l o toma como c e r o . t i e n e como v a l o r l o s dos b y t e s m´s a s i g n i f i c a t i v o s de l a v a r i a b l e ’ e n v o l s [ 0 ] ’ i f ( t i e m p o s [ 0 ] > ( l a r g o T a b l a S e n o s −1) ) { // S i e l pr´ ximo v a l o r de l a t a b l a o de s e n o s e s mayor a l l a r g o de l a t a b l a s e v u e l v e a comenzar d e s d e e l p r i n c i p i o de l a t a b l a . s a l i d a L o n g =( l o n g i n t ) ( * punteroMascaras [ 0 ] ) * ( l o n g i n t ) ( s e n o [ t i e m p o s [ 0 ] ] ) . Por e j e m p l o s e n o ( 4 1 0 )=s e n o ( 5 0 ) (En g r a d o s ) t i e m p o s [ 0 ] = t i e m p o s [0] − l a r g o T a b l a S e n o s . e s t a a o p e r a c i ´ n s e p o d r´a haber r e a l i z a d o con un ’ f o r ’ .i n t i n d . // Se aumenta e l v a l o r de l a e n v o l v e n t e que s e va a u s a r para m u l t i p l i c a r a l a componente en f r e c u e n c i a para e l pr´ ximo sample . //Dado que e s t a e s l a p r i m e r componente en f r e c u e n c i a que s e e s t a a n a l i z a n d o s a l i d a L o n g comienza v a l i e n d o e l v a l o r c o r r e s p o n d i e n t e a e s t a componente . // S o l o e s una c o p i a de l a v a r i a b l e i n d i c e s [ i ] . p e r o de e s t a forma o ı consume menos c i c l o s de r e l o j . // s a l i d a L o n g va a v a l e r l a suma de cada componenente en f r e c u e n c i a por l a e n v o l v e n t e que l e c o r r e s p o n d e . s i r v e para a h o r r a r c i c l o s de r e l o j . // Se l e a s i g n a a l a v a r i a b l e i n d e l v a l o r d e l p r i m e r indice .

} i f ( c i c l o s >cambios [ 2 ] [ i n d ] ) { i n d i c e s [2]+=1. i f ( t i e m p o s [ 1 ] > ( l a r g o T a b l a S e n o s −1) ) { t i e m p o s [ 1 ] = t i e m p o s [1] − l a r g o T a b l a S e n o s . } i f ( c i c l o s >cambios [ 1 ] [ i n d ] ) { i n d i c e s [1]+=1. t i e m p o s [ 3 ] = t i e m p o s [ 3 ] + aumentosSeno [ 3 ] . t i e m p o s [ 4 ] = t i e m p o s [ 4 ] + aumentosSeno [ 4 ] . s a l i d a L o n g=s a l i d a L o n g +( l o n g i n t ) ( * punteroMascaras [ 5 ] ) * ( l o n g i n t ) ( seno [ tiempos [ 5 ] ] ) . envols [2]= envols [2]+ incrementos [ 2 ] [ ind ] . } i n d=i n d i c e s [ 5 ] . envols [5]= envols [5]+ incrementos [ 5 ] [ ind ] . } i n d=i n d i c e s [ 4 ] . } i f ( c i c l o s >cambios [ 3 ] [ i n d ] ) { i n d i c e s [3]+=1. } i f ( c i c l o s >cambios [ 4 ] [ i n d ] ) { i n d i c e s [4]+=1. t i e m p o s [ 2 ] = t i e m p o s [ 2 ] + aumentosSeno [ 2 ] . envols [4]= envols [4]+ incrementos [ 4 ] [ ind ] . i f ( t i e m p o s [ 2 ] > ( l a r g o T a b l a S e n o s −1) ) { t i e m p o s [ 2 ] = t i e m p o s [2] − l a r g o T a b l a S e n o s . 159 . s a l i d a L o n g=s a l i d a L o n g +( l o n g i n t ) ( * punteroMascaras [ 6 ] ) * ( l o n g i n t ) ( seno [ tiempos [ 6 ] ] ) . t i e m p o s [ 5 ] = t i e m p o s [ 5 ] + aumentosSeno [ 5 ] . envols [3]= envols [3]+ incrementos [ 3 ] [ ind ] . s a l i d a L o n g=s a l i d a L o n g +( l o n g i n t ) ( * punteroMascaras [ 4 ] ) * ( l o n g i n t ) ( seno [ tiempos [ 4 ] ] ) . s a l i d a L o n g=s a l i d a L o n g +( l o n g i n t ) ( * punteroMascaras [ 3 ] ) * ( l o n g i n t ) ( seno [ tiempos [ 3 ] ] ) . t i e m p o s [ 1 ] = t i e m p o s [ 1 ] + aumentosSeno [ 1 ] . } i n d=i n d i c e s [ 6 ] . s a l i d a L o n g=s a l i d a L o n g +( l o n g i n t ) ( * punteroMascaras [ 2 ] ) * ( l o n g i n t ) ( seno [ tiempos [ 2 ] ] ) . i f ( t i e m p o s [ 5 ] > ( l a r g o T a b l a S e n o s −1) ) { t i e m p o s [ 5 ] = t i e m p o s [5] − l a r g o T a b l a S e n o s . } i n d=i n d i c e s [ 3 ] . envols [1]= envols [1]+ incrementos [ 1 ] [ ind ] .s a l i d a L o n g=s a l i d a L o n g +( l o n g i n t ) ( * punteroMascaras [ 1 ] ) * ( l o n g i n t ) ( seno [ tiempos [ 1 ] ] ) . i f ( t i e m p o s [ 3 ] > ( l a r g o T a b l a S e n o s −1) ) { t i e m p o s [ 3 ] = t i e m p o s [3] − l a r g o T a b l a S e n o s . i f ( t i e m p o s [ 4 ] > ( l a r g o T a b l a S e n o s −1) ) { t i e m p o s [ 4 ] = t i e m p o s [4] − l a r g o T a b l a S e n o s . } i f ( c i c l o s >cambios [ 5 ] [ i n d ] ) { i n d i c e s [5]+=1. } i n d=i n d i c e s [ 2 ] .

t i e m p o s [ 1 0 ] = t i e m p o s [ 1 0 ] + aumentosSeno [ 1 0 ] . } i n d=i n d i c e s [ 1 1 ] . } i n d=i n d i c e s [ 7 ] . i f ( t i e m p o s [ 6 ] > ( l a r g o T a b l a S e n o s −1) ) { t i e m p o s [ 6 ] = t i e m p o s [6] − l a r g o T a b l a S e n o s . envols [6]= envols [6]+ incrementos [ 6 ] [ ind ] . } i f ( c i c l o s >cambios [ 8 ] [ i n d ] ) { i n d i c e s [8]+=1. } i f ( c i c l o s >cambios [ 1 0 ] [ i n d ] ) { i n d i c e s [10]+=1. } i f ( c i c l o s >cambios [ 7 ] [ i n d ] ) { i n d i c e s [7]+=1. i f ( t i e m p o s [ 8 ] > ( l a r g o T a b l a S e n o s −1) ) { t i e m p o s [ 8 ] = t i e m p o s [8] − l a r g o T a b l a S e n o s . } i n d=i n d i c e s [ 8 ] . s a l i d a L o n g=s a l i d a L o n g +( l o n g i n t ) ( * punteroMascaras [ 1 1 ] ) * ( l o n g i n t ) ( seno [ tiempos [ 1 1 ] ] ) . i f ( t i e m p o s [ 7 ] > ( l a r g o T a b l a S e n o s −1) ) { t i e m p o s [ 7 ] = t i e m p o s [7] − l a r g o T a b l a S e n o s . t i e m p o s [ 7 ] = t i e m p o s [ 7 ] + aumentosSeno [ 7 ] . s a l i d a L o n g=s a l i d a L o n g +( l o n g i n t ) ( * punteroMascaras [ 1 0 ] ) * ( l o n g i n t ) ( seno [ tiempos [ 1 0 ] ] ) . } i n d=i n d i c e s [ 1 0 ] . envols [7]= envols [7]+ incrementos [ 7 ] [ ind ] .t i e m p o s [ 6 ] = t i e m p o s [ 6 ] + aumentosSeno [ 6 ] . t i e m p o s [ 9 ] = t i e m p o s [ 9 ] + aumentosSeno [ 9 ] . i f ( t i e m p o s [ 9 ] > ( l a r g o T a b l a S e n o s −1) ) { t i e m p o s [ 9 ] = t i e m p o s [9] − l a r g o T a b l a S e n o s . s a l i d a L o n g=s a l i d a L o n g +( l o n g i n t ) ( * punteroMascaras [ 8 ] ) * ( l o n g i n t ) ( seno [ tiempos [ 8 ] ] ) . i f ( t i e m p o s [ 1 0 ] > ( l a r g o T a b l a S e n o s −1) ) { t i e m p o s [ 1 0 ] = t i e m p o s [10] − l a r g o T a b l a S e n o s . envols [9]= envols [9]+ incrementos [ 9 ] [ ind ] . s a l i d a L o n g=s a l i d a L o n g +( l o n g i n t ) ( * punteroMascaras [ 7 ] ) * ( l o n g i n t ) ( seno [ tiempos [ 7 ] ] ) . envols [8]= envols [8]+ incrementos [ 8 ] [ ind ] . i f ( t i e m p o s [ 1 1 ] > ( l a r g o T a b l a S e n o s −1) ) { 160 . } i f ( c i c l o s >cambios [ 6 ] [ i n d ] ) { i n d i c e s [6]+=1. } i n d=i n d i c e s [ 9 ] . s a l i d a L o n g=s a l i d a L o n g +( l o n g i n t ) ( * punteroMascaras [ 9 ] ) * ( l o n g i n t ) ( seno [ tiempos [ 9 ] ] ) . envols [10]= envols [10]+ incrementos [ 1 0 ] [ ind ] . t i e m p o s [ 8 ] = t i e m p o s [ 8 ] + aumentosSeno [ 8 ] . envols [11]= envols [11]+ incrementos [ 1 1 ] [ ind ] . t i e m p o s [ 1 1 ] = t i e m p o s [ 1 1 ] + aumentosSeno [ 1 1 ] . } i f ( c i c l o s >cambios [ 9 ] [ i n d ] ) { i n d i c e s [9]+=1.

v e l o c i d a d −−. envols [12]= envols [12]+ incrementos [ 1 2 ] [ ind ] . } //−−−−−−−−−−−−−Fin d e l c a l c u l o de l a s componentes r e s t a n t e s −−−−−−−−−−−− s a l i d a L o n g=s a l i d a L o n g * v e l o c i d a d . l a 161 . } i f ( c i c l o s >cambios [ 1 4 ] [ i n d ] ) { i n d i c e s [14]+=1. i f ( t i e m p o s [ 1 4 ] > ( l a r g o T a b l a S e n o s −1) ) { t i e m p o s [ 1 4 ] = t i e m p o s [14] − l a r g o T a b l a S e n o s . i f ( s a m p l e s P a r a B a j a r==s a m p l e s B a j a r ) { b a j a r l a i n t e n s i d a d de l a nota . } i n d=i n d i c e s [ 1 2 ] . } i f ( c i c l o s >cambios [ 1 1 ] [ i n d ] ) { i n d i c e s [11]+=1. i f ( v e l o c i d a d >0){ bajo . hay que gradualmente // V e r i f i c o que c o r r e s p o n d e // S i t o d a v´a l a v e l o c i d a d no l l e g ´ a l m´ ı o ınimo . } i n d=i n d i c e s [ 1 3 ] . } i f ( c i c l o s >cambios [ 1 3 ] [ i n d ] ) { i n d i c e s [13]+=1. } i f ( c i c l o s >cambios [ 1 2 ] [ i n d ] ) { i n d i c e s [12]+=1. s a l i d a L o n g=s a l i d a L o n g +( l o n g i n t ) ( * punteroMascaras [ 1 2 ] ) * ( l o n g i n t ) ( seno [ tiempos [ 1 2 ] ] ) . i f ( estoyEnNoteOff ) { // S i e s t o y en n o t e o f f v a j a r l a i n t e n s i d a d de l a nota . // El sample r e s u l t a n t e s e l o m u l t i p l i c a por l a i n t e n s i d a d con l a que l a hay que r e p r o d u c i r l a nota . envols [14]= envols [14]+ incrementos [ 1 4 ] [ ind ] . envols [13]= envols [13]+ incrementos [ 1 3 ] [ ind ] . c i c l o s ++. i f ( t i e m p o s [ 1 2 ] > ( l a r g o T a b l a S e n o s −1) ) { t i e m p o s [ 1 2 ] = t i e m p o s [12] − l a r g o T a b l a S e n o s . t i e m p o s [ 1 4 ] = t i e m p o s [ 1 4 ] + aumentosSeno [ 1 4 ] . i f ( t i e m p o s [ 1 3 ] > ( l a r g o T a b l a S e n o s −1) ) { t i e m p o s [ 1 3 ] = t i e m p o s [13] − l a r g o T a b l a S e n o s . // Se a c t u a l i z a l a c a n t i d a d de s a m p l e s g e n e r a d o s . s a l i d a L o n g=s a l i d a L o n g +( l o n g i n t ) ( * punteroMascaras [ 1 3 ] ) * ( l o n g i n t ) ( seno [ tiempos [ 1 3 ] ] ) . t i e m p o s [ 1 2 ] = t i e m p o s [ 1 2 ] + aumentosSeno [ 1 2 ] . s a l i d a L o n g=s a l i d a L o n g +( l o n g i n t ) ( * punteroMascaras [ 1 4 ] ) * ( l o n g i n t ) ( seno [ tiempos [ 1 4 ] ] ) . t i e m p o s [ 1 3 ] = t i e m p o s [ 1 3 ] + aumentosSeno [ 1 3 ] . s a m p l e s P a r a B a j a r++. } i n d=i n d i c e s [ 1 4 ] .t i e m p o s [ 1 1 ] = t i e m p o s [11] − l a r g o T a b l a S e n o s .

return . } i f ( i n d i c e E f e c t o ==2){ f r e c C o r t e=RAMBuffer [ numEfec − 4 ] / 2 . i f ( i n d i c e E f e c t o >2){ i f ( i n d i c e E f e c t o ==3){ l i m i t e I f =256 * RAMBuffer [ numEfec − 4 ] . } e l s e { // S i ya l a b a j e a l m´ ınimo . a estoyEnNoteOff =0. a // Es llamado l u e g o de g e n e r a r cada sample . //Hay que l l a m a r l o una vez con e l par´ metro 6 para a c t u a l i z a r l o s a p a r ´ m e t r o s d e l p r i m e r e f e c t o y o t r a con e l par´ metro 7 para a c t u a l i z a r a a l o s p a r ´ m e t r o s d e l segundo . a t r a s o E c o =50* RAMBuffer [ numEfec − 2 ] . return . } v o i d a p l i c a r E f e c t o s ( u n s i g n e d s h o r t i n t numEfec ) { // Este e s e l programa e n c a r g a d o de a p l i c a r l e e l e f e c t o s e l e c c i o n a d o a e l s o n i d o . // D e t e c t a e l e f e c t o que e s t a a c t i v a d o y a s i g n a a e l e f e c t o s e l e c c i o n a d o s u s p ar ´ m e t r o s . 162 .s a m p l e s P a r a B a j a r =0. return . //Hay que l l a m a r l o una vez con e l par´ metro 6 para a p l i c a r e l p r i m e r a e f e c t o y o t r a con e l par´ metro 7 para a p l i c a r e l segundo . return . f r e c u e n c i a T r e m o l o=1+RAMBuffer [ numEfec − 2 ] / 1 6 . a // Es llamado cada vez que e l programa d e t e c t a un cambio en l o s p a r ´ m e t r o s a de l o s e f e c t o s . } v a l o r V i b r a t o=RAMBuffer [ numEfec − 4 ] . no e s t o y m´s en n o t e o f f . } i f ( i n d i c e E f e c t o ==4){ l i m i t e L o g =100 * RAMBuffer [ numEfec − 4 ] . } i f ( i n d i c e E f e c t o ==5){ magnitudEco =512 * RAMBuffer [ numEfec − 4 ] . a i n t i n d i c e E f e c t o=RAMBuffer [ numEfec ] . return . return . } } } } } //−−−−−−−−−−−−−M´ todos para l a g e n e r a c i ´ n de l o s e f e c t o s −−−−−−−−−−−−−− e o v o i d a c t u a l i z a r P a r a m e t r o s E f e c t o s ( u n s i g n e d s h o r t i n t numEfec ) { // Este m´todo s e e n c a r g a de que l o s p a r ´ m e t r o s para l a g e n e r a c i ´ n de e f e c t o s e a o esten actualizados . } magnitudTremolo=RAMBuffer [ numEfec − 4 ] / 2 .

i f ( i n d i c e E f e c t o >2){ i f ( i n d i c e E f e c t o ==3){ s a l i d a A U t i l i z a r=l i m i t a d o r I f ( s a l i d a A U t i l i z a r ) . } i f ( indiceEfecto ){ s a l i d a A U t i l i z a r=t r e m o l o ( s a l i d a A U t i l i z a r ) . return . } //−−−−−I n i c i a l i z a c i ´ n de u t i l i d e a d e s d e l DSPIC−−−−−− o mapearPuertos ( ) . return . o // I n i c i a l i z a c i ´ n de l a i n t e r f a z I2C . o 163 . i n t i n d i c e E f e c t o=RAMBuffer [ numEfec ] . } i f ( i n d i c e E f e c t o ==2){ s a l i d a A U t i l i z a r=wahwah ( s a l i d a A U t i l i z a r ) . return . return . } i f ( i n d i c e E f e c t o ==4){ s a l i d a A U t i l i z a r=l i m i t a d o r L o g ( s a l i d a A U t i l i z a r ) . f o r ( i =0. } //−−−−−−−−−−−−−−−−−−−−−−−−M´todo P r i n c i p a l ( Main )−−−−−−−−−−−−−−−−−−−−−−−− e i n t main ( v o i d ) { //−−−−−−−−−−−−−−−D e c l a r a c i ´ n e i n i c i a l i z a c i ´ n de v a r i a b l e s −−−−−−−−−−−−−−− o o unsigned short i n t i . s a l i d a=s a l i d a +1. i <15. i2c1 init () . o // I n i c i a l i z a c i ´ n d e l d i g i t a l t o a n a l a o g c o n v e r t e r . return . // E s t a s dos l i n e a s hacen que cada v e c t o r de punteroMascaras apunte a l o s 2 b y t e s m´s s i g n i f i c a t i v o s de su c o r r e s o n d i e n t e en e l v e c t o r ’ e n v o l s ’ a punteroMascaras [ i ]++. // E s t a s dos l i n e a s hacen que e l v e c t o r ’ s a l i d a ’ apunte a l o s 2 b y t e s m´s s i g n i f i c a t i v o s de ’ s a l i d a L o n g ’ a c i c l o s =0.// Primero d e t e c t a e l e f e c t o que hay que r e a l i z a r y l u e g o l l a m a a l m´todo e que l o r e a l i z a . posDato =0. // I n i c i a l i z a c i ´ n de l o s p u e r t o s . } return . i ++){ punteroMascaras [ i ]=& e n v o l s [ i ] . RAMBuffer [ 2 ] = 2 . return . s a l i d a=&s a l i d a L o n g . } vibrato () . } i f ( i n d i c e E f e c t o ==5){ s a l i d a A U t i l i z a r=s a l i d a A U t i l i z a r+e c o ( ) . initDac () .

actualizarParametrosEfectos (7) . bandera =0.c 164 . u grabarDato ( s a l i d a A U t i l i z a r ) . // Grabo e l dato en l a memoria de l o s u l t i m o s s a m p l e s c a l c u l a d o s . } DAC1RDAT = s a l i d a A U t i l i z a r . S i r v e para e l e f e c t o e c o . } i f ( banderaCambioEfectos >1){ // S i ’ banderaCambioEfectos ’ e s mayor a 1 e s por que s e cambi´ a l g u n o de l o s p a r ´ m e t r o s de l o s o a e f e c t o s y hay que a c t u a l i z a r l o s . // Este aumento de volumen e s t a p u e s t o aca tambi´ n pensando en un f u t u r o e para poder cambiar e l n´ mero 6 por una v a r i a b l e de una p e r i l l a . ´ aumentarPunteroTremolo ( ) . banderaCambioEfectos =0. } i f ( RAMBuffer [ 1 5 ] > 0 ) { cargoPrograma ( ) . // C a l c u l o e l v a l o r d e l pr´ ximo sample o s a l i d a A U t i l i z a r =( * s a l i d a ) . // A p l i c o l o s e f e c t o s . w h i l e ( DAC1STATbits . actualizarParametrosEfectos (6) . //Aumento e l p u n t e r o a u x i l i a r que s e usa para e l e f e c t o de t r´ m o l o .i n i c i a r E f e c t o s ( ) . aplicarEfectos (7) . o //−−−−−−−−−−−−−−−−−−−−−−−−−Bucle p r i n c i p a l −−−−−−−−−−−−−−−−−−−−−−−−− while (1) { c a l c u l a r S a m p l e ( ) .RFULL==1){ // Espero a que e l DAC t e r m i n e de p r o c e s a r e l sample que e s t a p r o c e s a n d o a s i s e l i b e r a un l u g a r en su c o l a de d a t o s . e aplicarEfectos (6) . //Aumento e l volumen . // Asigno a l a v a r i a b l e s a l i d a A U t i l i z a r l a s a l i d a que voy a u t i l i z a r s a l i d a A U t i l i z a r=s a l i d a A U t i l i z a r * 6 . posDato =0. o agregarNota ( ) . // Pongo en l a c o l a de d a t o s d e l DAC e l ultimo valor calculado . ´ i f ( bandera >1){ // S i ’ bandera ’ e s mayor a 1 e s por que s e r e c i b i ´ o una i n s t r u c c i ´ n m u s i c a l . } } } slaves/main. // I n i c i a l i z a c i ´ n de l o s e f e c t o s .

Anexo C. AD1CHS0bits . AD1CON3bits . CHPS = 0 . } −−−−−−−−−−−−− master/adc.VCFG = 0 .ADON = 1 . h> #i n c l u d e ” adc . h” //−−−−−−−−−−−−−C o n f i g u r a c i ´ n d e l c o n v e r s o r a n a l ´ g i c o d i g i t a l o o // Este m´todo c o n f i g u r a e l ADC.c 165 .DMABL = 0 b10 . SSRC = 0 b111 . AD1CON1bits . AD1CON3bits .ADCS = 4 0 . AD1CON1bits . AD1CON2bits .ASAM = 0 . AD1CON4bits . c´digos del DSPic master o Clase ’adc.SAMP = 0 .c’ #i n c l u d e <p33FJ128GP802 . e v o i d initADC ( v o i d ) { AD1CON1bits . AD1CON2bits .SAMC = 7 . AD1CON1bits . CH0SA = 1 1 .

Clase ’adc. master/adc.h 166 .h’ v o i d initADC ( v o i d ) .

b u f f e r D a t a [ auxc +1]) . o b u f f e r L i s t o =0. f o r ( p i c = d i r e c c i o n D e s d e .Clase ’cargarPrograma. p i c <( d i r e c c i o n D e s d e+numeroPics ) . retardo (5000) . 1 0 . // Los b y t e s s e e n v´a n en r o n d a s de a ı dos . 1 5 . } w h i l e ( p r o g r a m a c i o n A c t i v a==1){ RCON = 0 x0 . llevoCuenta = 0. a //En l a v e r s i ´ n f i n a l no e s t a implementado . I2Cwrite (2* pic . CRC +=v a l o r . h” #i n c l u d e <p33FJ128GP802 . // LLeva l a c u e n t a de l a c a n t i d a d t o t a l de b y t e s e n v i a d o s . 1 1 . s h o r t i n t auxc .c’ #i n c l u d e ” CargarPrograma . // a e n v i a r l a i n f o r m a c i ´ n a l o s p i c s . f o r ( auxc =0. //−−−−−−−−−−−−−−−−−−−−Fin de d e c l a r a c i ´ n de v a r i a b l e s −−−−−−−−−−−−−−−−−−−−− o v o i d realizoCRC ( s h o r t i n t v a l o r ) { // Simple a l g o r i t m o para c h e q u e a r e l CRC. h> //−−−−−−−−−−−−−−−−−−−−−−−−D e c l a r a c i ´ n de v a r i a b l e s −−−−−−−−−−−−−−−−−−−−−−− o e x t e r n s h o r t i n t dato2 . 167 . p e r o l o c o n s i d e r a m o s u t i l o ´ para una f u t u r a mejora d e l programa . } v o i d cargarNuevoPrograma ( ) { //Una vez que s e e n t r a a l m´todo para c a r g a r e un nuevo i n s t r u m e n t o no s e s a l e h a s t a c o m p l e t a r l a t r a n s m i s i ´ n de d a t o s . e r r o r += I 2 C p o l l ( 2 * p i c ) . i f ( b u f f e r L i s t o ==1){ //Cuando s e r e c i b e n 100 v a l o r e s s e l e v a n t a l a s e n a l de b u f f e r L i s t o y s e p r o c e d e ˜ CRC = 0 . error = 0. I 2 C w r i t e ( 2 * p i c . e r r o r += I 2 C p o l l ( 2 * p i c ) . para que e l i n t r e c i b i d o ya pueden s e r g r a b a d o s en l a memoria d e l p i c e s c l a v o . retardo (5000) . suma t o d o s l o s v a l o r e s y l u e g o s e comparar´ e l byte menos s i g n i f i c a t i v o . p i c++){ // Les a v i s o a t o d o s l o s p i c s que voy a comenzar a e n v i a r e l nuevo instrumento . h” #i n c l u d e ” I2C . auxc <(UNA RONDA* 2 ) . o u n s i g n e d i n t l l e v o C u e n t a T o t a l = 0 . I 2 C w r i t e ( 2 * p i c . short int pic . auxc=auxc +2){ // Recorro l o s c i e n v a l o r e s que r e c i b´ ı for ( pic = direccionDesde . 1 ) . b u f f e r D a t a [ auxc ] ) . p i c <( d i r e c c i o n D e s d e+numeroPics ) . retardo (5000) . p i c++){ l o s p i c s que hay en e l d i s p o s i t i v o // Se l o s e n v´o a t o d o s ı e r r o r += I 2 C p o l l ( 2 * p i c ) .

} } l l e v o C u e n t a T o t a l+= UNA RONDA * 2 . } } } master/cargarPrograma.c 168 . e U2TXREG = 0 x15 . // Le i n d i c o a l a PC que s i g a enviando datos . d a t o s e n v i´ . p r o g r a m a c i o n A c t i v a =0.retardo (40000) . } i f ( l l e v o C u e n t a T o t a l >=43860){ // Luego de e n v i a r t o d o s l o s datos . l l e v o C u e n t a ++. l l e v o C u e n t a =0. e // L l e v o l a c u e n t a t o t a l de c u a n t o s dato2 = 0 . l e a v i s o a l a PC que t e r m i n´ de c a r g a r e l i n s t r u m e n t o . // b a j o l a bandera de p r o g r a m a c i ´ n A c t i v a y v u e l v o a l o main d e l programa . U2TXREG = S e g u i r E n v i a n d o .

i n t b u f f e r D a t a [ 2 * UNA RONDA+ 1 0 ] . s h o r t i n t * CRC L . v o i d realizoCRC ( s h o r t i n t v a l o r ) . b u f f e r L i s t o . c h a r bandera2 . int llevoCuenta . s h o r t i n t CRC L recibido .h’ #d e f i n e #d e f i n e #d e f i n e #d e f i n e #d e f i n e #d e f i n e #d e f i n e #d e f i n e #d e f i n e #d e f i n e extern extern extern extern extern extern extern extern extern SeguirEnviando 0 x26 EMPEZAR PROGRAMAR 0 x32 DETENER ENVIO 0 x18 ERROR CON PIC 0xFF GRABACION EXITOSA 0xF0 FINALIZO TRANSMICION 0xF2 UNA RONDA 50 VALOR FINAL 0 x30 numeroPics 3 d i r e c c i o n D e s d e 0 x4e s h o r t i n t dato2 . master/cargarPrograma. programacionActiva . v o i d cargarNuevoPrograma ( ) . char j .Clase ’cargarPrograma.h 169 . unsigned short i n t e r r o r . p o s B u f f e r . l o n g i n t CRC.

I2CEN = 1 . I2C1CONbits . ODCBbits . I2C1CONbits . x++.ODCB8=1. I2C1BRG = 9 5 . } return . w h i l e ( I2C1CONbits . ODCBbits . } v o i d i 2 c r e s t a r t ( v o i d ) { // E s t a s f u n c i o n e s s e usan para r e i n i c i a r c o n e c c i o n e s de I2C . I2CEN = 0 .ODCB6=1. i <c i c l o s .c’ #i n c l u d e <p33FJ128GP802 . DISSLW = 1 . temp = I2CRCV . retardo (398) . i n t j =0. ODCBbits . } v o i d i 2 c s t a r t ( v o i d ) { // Esta f u n c i ´ n i n i c i a una c o m u n i c a c i ´ n v i a I2C . } v o i d i n i c i a r I 2 C ( ) { // Este m´todo c o n f i g u r a l o s r e g i s t r o s n e c e s a r i o s d e l e DSPic para poder u t i l i z a r e l I2C . } } retardo (78) . s e usa para e l a e s p e r a e n t r e t r a n s m i c i o n e s por I2C . i n t s e g u i r =1. i f ( x > 20) { s e g u i r =0. MI2C1IF = 0 . h” v o i d r e t a r d o ( i n t c i c l o s ) { // Este m´todo s o l o hace un r e t a r d o . 170 .Clase ’I2C. i n t i =0. f o r ( i =0. i ++){ Nop ( ) . ODCBbits . I2C1CONbits . SEN = 1 . I2C1CONbits . i n t j =1. i n t temp .ACKDT = 0 . j =0. reset i2c bus () . o o int x = 0.ODCB9=1.ODCB5=1. I F S 1 b i t s . h> #i n c l u d e ” I2C . SEN&&s e g u i r ) { retardo (38) . I2C1CONbits . return .

// El p r o t o c o l o de c o m u n i c a c i ´ n con memorias v´a I2C i m p l i c a i n s t r u c c i o n e s o ı de m´s de un byte por vez . } c h a r s e n d i 2 c b y t e ( i n t data ) { // Esta f u n c i ´ n e s para mandar un byte por o I2C . x ++.int x = 0.PEN = 1 .ACKSTAT == 1 ) { reset i2c bus () . } retardo (78) . retardo (398) . i <500.TBF) { } I F S 1 b i t s . x++. } f o r ( i =0. return (0) . I2C1CONbits . MI2C1IF = 0 .RSEN = 1 . } 171 . w h i l e ( I2C1STATbits . i <10. i ++){ i f ( I2C1STATbits . w h i l e ( I2C1CONbits .BCL = 0 .RCEN = 0 . } i f ( i == 5 0 0 ) { return (1) . w h i l e ( I2C1CONbits . } I2C1CONbits .IWCOL = 0 .PEN) { retardo (38) . } retardo (78) . I2C1STATbits . I F S 1 b i t s . I2C1STATbits . a // Por e s o e s t a no e s l a f u n c i ´ n que vamos a u t i l i z a r para mandar d a t o s v´a o ı I2C . i f ( x > 2 0 ) break . j =1. f o r ( i =0. I2C1CONbits . return (1) . retardo (38) . I2CTRN = data .RSEN) { retardo (38) . int i .TRSTAT) break . i ++){ i f ( ! I2C1STATbits . i f ( x > 20) break . } retardo (38) . } void r e s e t i 2 c b u s ( void ) { int x = 0. MI2C1IF = 0 .

172 . r e t u r n data . c h a r v a l u e ) { // Esta f u n c i ´ n graba o una p o s i c i ´ n de una memoria v´a I2C . I2C1CONbits . retardo (398) . i f ( i > 2 0 0 0 ) break . retardo (398) . p e r o s i g u e n d o e l p r o t o c o l o . reset i2c bus () . i2c start () .RCEN = 1 . s e n d i 2 c b y t e ( addr ) . // Devuelve 0 s i no hay un e r r o r . r e t u r n data . o //Lo que hace e s u t i l i z a r l a s f u n c i o n e s a n t e r i o r e s de e s c r i t u r a y l e c t u r a de bytes . c h a r subaddr ) { // Esta f u n c i ´ n l e e una p o s i c i ´ n de o o una memoria v´a I2C . // Esta e s l a f u n c i ´ n que s e u t i l i z a para l e e r b y t e s o int i = 0. } //−−−−−−−−−−−−−−F u n c i o n e s de I2C que s e llaman d e s d e a f u e r a −−−−−−−−−−−−−− v o i d I 2 C w r i t e ( c h a r addr . retardo (398) . // Devuelve 0 s i no hay un e r r o r . p e r o s i g u e n d o e l p r o t o c o l o . s e n d i 2 c b y t e ( subaddr ) . I2C1CONbits . } data = I2CRCV . return . I2C1CONbits . w h i l e ( ! I2C1STATbits .RBF) { i ++. i f ( i > 2 0 0 0 ) break .ACKEN = 1 . retardo (398) . } data = I2CRCV . } c h a r I2Cread ( c h a r addr . c h a r data = 0 . ı // Esta e s l a f u n c i ´ n que u t i l i z a m o s para l e e r de l o s e s c l a v o s . c h a r subaddr . } c h a r i 2 c r e a d a c k ( v o i d ) { // Esta f u n c i ´ n l e e d a t o s y g e n e r a l o s o ’ a c k n o w l e d g e s ’ que e l p r o t o c o l o de c o m u n i c a c i ´ n i n d i c a .RCEN = 1 .char i 2 c r e a d ( void ) { por I2C . send i2c byte ( value ) . o int i = 0. o ı // Esta e s l a f u n c i ´ n que u t i l i z a m o s para comunicarnos con l o s e s c l a v o s . o //Lo que hace e s u t i l i z a r l a s f u n c i o n e s a n t e r i o r e s de e s c r i t u r a y l e c t u r a de bytes . c h a r data = 0 . w h i l e ( ! I2C1STATbits . retardo (398) .RBF) { i ++.

i2c restart () . retardo (398) . r e t u r n temp . temp = s e n d i 2 c b y t e ( addr ) .c h a r temp . temp = i 2 c r e a d ( ) . reset i2c bus () .c 173 . i2c start () . s e n d i 2 c b y t e ( subaddr ) . s e n d i 2 c b y t e ( addr | 0 x01 ) . // Devulve 0 s i e s t a c o n e c t a d o . } master/I2C. u n s i g n e d c h a r temp = 0 . } u n s i g n e d c h a r I 2 C p o l l ( c h a r addr ) { // Esta e s l a f u n c i ´ n que s e usa para o saber s i c i e r t o e s c l a v o esta conectado . reset i2c bus () . r e t u r n temp . s e n d i 2 c b y t e ( addr ) . i2c start () .

void i 2 c r e s t a r t ( void ) .Clase ’I2C. char i 2 c r e a d a c k ( void ) . c h a r I2Cread ( c h a r addr . u n s i g n e d c h a r I 2 C p o l l ( c h a r addr ) . c h a r s e n d i 2 c b y t e ( i n t data ) . v o i d I 2 C w r i t e ( c h a r addr . master/I2C. void r e s e t i 2 c b u s ( void ) .h’ void i n i c i a r I 2 C ( ) .h 174 . char i 2 c r e a d ( void ) . c h a r subaddr . void retardo ( i n t c i c l o s ) . void i 2 c s t a r t ( void ) . c h a r subaddr ) . c h a r v a l u e ) .

TRISB12=1. TRISBbits . TRISB6 = 1 . RPINR19bits . RPOR1bits . TRISAbits .U2RXR = 6 . TRISAbits .U1RXR = 0 .c’ #i n c l u d e <p33FJ128GP802 . RPINR18bits .c 175 . TRISB15=1. TRISBbits . TRISBbits . RP3R = 4 . TRISB14=1.Clase ’mapearP. TRISBbits . TRISA1=1. builtin write OSCCONL (OSCCON & ˜(1<<6) ) . RP2R = 3 . TRISB=1. RPINR18bits . RPOR3bits . U1CTSR = 1 . RPOR1bits . h” //−−−−−−−−−−−−−−−−−−−−−−−−C o n f i g u r a c i ´ n de p u e r t o s −−−−−−−−−−−−−−−−−−−−−−−− o v o i d mapearPuertos ( ) { // Este m´todo a s i g n a l o s p u e r t o s s e r i e en l o s e puertos remapeables . RP7R = 5 . TRISB13=1. h> #i n c l u d e ”mapearP . TRISBbits . TRISA0=1. } master/mapearP. builtin write OSCCONL (OSCCON | (1<<6) ) .

h 176 .Clase ’mapearP. master/mapearP.h’ v o i d mapearPuertos ( ) .

} // El p u e r t o s e r i e 2 e s e l que s e comunica con e l s o f t w a r e de PC. h> #i n c l u d e ” s e r i e . IPC2 =4096.c’ #i n c l u d e <p33FJ128GP802 . //−−−−−−−−−−−−−−−−−−−C o n f i g u r a c i ´ n de l o s p u e r t o s s e r i e −−−−−−−−−−−−−−−−−−−− o // El p u e r t o s e r i e 1 e s e l que r e c i b e l o s comandos MIDI . U1BRG = 3 1 6 . } //−−−−−−−−−−−−−−C o n f i g u r a c i ´ n de i n t e r r u p c i o n e s de r e c e p c i ´ n −−−−−−−−−−−−−− o o void attribute ( ( i n t e r r u p t . extern short int p o s B u f f e r . b u f f e r L i s t o . I E C 1 b i t s . I E C 0 b i t s . U2TXIE = 0 . U1RXIE = 1 . h” //−−−−−−−−−−−−−−−−D e c l a r a c i ´ n de v a r i a b l e s y d e f i n i c i o n e s −−−−−−−−−−−−−−−− o #d e f i n e UNA RONDA 50 #d e f i n e EMPEZAR PROGRAMAR 0 x32 u n s i g n e d s h o r t i n t dato . U1TXIF = 0 . v o i d InitUART1 ( ) { // Este m´todo c o n f i g u r a e l p u e r t a s e r i e 1 para 31250 8 e N 1 . posDato . f l a g N o t e O f f . i n t e r r u p t i v o en l a r e c e p c i ´ n . programacionActiva . U1MODEbits . I F S 1 b i t s . o 177 . extern int bufferData [ ] . U1STAbits . e x t e r n u n s i g n e d s h o r t i n t bandera . dato2 . U2MODEbits .UTXEN = 1 .UARTEN = 1 . U1STA=0. U2TXIF = 0 . I F S 0 b i t s . f u n c i o n A c t u a l . U2BRG = 2 5 6 . U2RXIF = 0 . I E C 1 b i t s . I E C 0 b i t s . U2STAbits . U1RXIF = 0 . IPC3=0. U2STA=0. IPC7 =1024. o U1MODE=8.UARTEN = 1 . U1TXIE = 0 . v o i d InitUART2 ( ) { // Este m´todo c o n f i g u r a e l p u e r t a s e r i e 2 para 9600 8 e N 1 . n o a u t o p s v ) ) U1RXInterrupt ( v o i d ) { // I n t e r r u p c i ´ n a l r e c i b i r d a t o s por e l p u e r t o s e r i e 1 . extern unsigned i n t datosFuncion [ ] . // =0000000000001000. o U2MODE=0.UTXEN = 1 .Clase ’serie. // =00010000000000 I F S 1 b i t s . e x t e r n s h o r t i n t flagNoteOn . U2RXIE = 1 . i n t e r r u p t i v o en l a r e c e p c i ´ n . I F S 0 b i t s .

// S i ya r e c i b´ una ronda de datos . // A c t u a l i z o l a p o s i c i ´ n de memoria que c o r r e s p o n d e . } I F S 0 b i t s . o // R e c i b´ l a s e n a l de ’ n o t e o f f ’ ? ı ˜ i f ( p r o g r a m a c i o n A c t i v a==1){ instrumento . r e i n i c i o l a c u e n t a ı y a v i s o que ya r e c i b´ una ronda de d a t o s . // Guardo e l dato r e c i b i d o en l a v a r i a b l e ’ dato ’ U1TXREG=dato . p o s B u f f e r =0. } i f ( posDato >1){ // S i posDato e s mayor a 1 . posDato =0. // Chequeo s i ya e s t o y programando un // Bajo l a bandera de i n t e r r u p c i ´ n . p o s B u f f e r ++. posDato++. o dato2 = U2RXREG. guardo en l a p o s i c i ´ n de memoria que c o r r e s p o n d e e l o dato . // Almaceno e l dato en l a p o s i c i ´ n de o memoria c o r r e s p o n d i e n t e . e s por que ya r e c i b´ t o d o s ı l o s d a t o s n e c e s a r i o s para i n t e r p r e t a r e l comando MIDI . // Guardo e l dato r e c i b i d o en l a v a r i a b l e ’ dato ’ . // S i ya e s t o y programando un i n s t r u m e n t o . i f ( dato >127 && dato <=143){ posDato =0. ı b u f f e r L i s t o =1. } } 178 . posDato =0.dato=U1RXREG. } else { d a t o s F u n c i o n [ posDato ]= dato . //Hago un eco . b u f f e r D a t a [ p o s B u f f e r ] = dato2 . s i r v e s o l o para c o n t r o l a r e l programa . } void attribute ( ( i n t e r r u p t . o i f ( p o s B u f f e r >=(2*UNA RONDA) ) { // chequeo s i ya r e c i b´ ’UNA RONDA ’ de ı d a t o s ( cada dato ocupa 2 b y t e s ) . bandera =10. } e l s e i f ( dato >=144){ // S i dato e s mayor a 144 e s por que r e c i b´ l a s e n a l ı ˜ de ’ n o t e on ’ . U1RXIF = 0 . flagNoteOn =1. n o a u t o p s v ) ) U2RXInterrupt ( v o i d ) { // I n t e r r u p c i ´ n a l r e c i b i r d a t o s por e l p u e r t o s e r i e 2 . f l a g N o t e O f f =1.

} } I F S 1 b i t s . U2TXIF = 0 . no auto psv ) ) I F S 0 b i t s . ı i n t r c o n a u x = RCON. } i f ( dato==0x10 ) { // Chequeo s i a n t e s de s i n e s t a r en p r o g r a m a c i o n A c t i v a me e n v´a n un 0 x10 . } U1TXInterrupt ( v o i d ) { // Bajo l a bandera de i n t e r r u p c i ´ n . // Aviso que e n t r o en e s t a d o de programaci´ n . o p o s B u f f e r =0. void attribute (( interrupt . o U2TXInterrupt ( v o i d ) { master/serie. // R e i n i c i o l a e s c r i t u r a d e l b u f f e r . p e r o por l a s dudas en c a s o de que s e a c t i v e n . e n v´o v a l o r e s de c o n t r o l ı U2TXREG = r c o n a u x . a l PC. bajamos l a bandera . // S i e s t e e s e l caso . U2RXIF = 0 . U2TXREG = ( r c o n a u x /0 x100 ) .else { i f ( dato2== EMPEZAR PROGRAMAR) { // Chequeo s i r e c i b´ l a s e n a l de empezar ı ˜ a programar . no auto psv ) ) I F S 1 b i t s . p r o g r a m a c i o n A c t i v a =1.c 179 . U1TXIF = 0 . } //−−−−−−−−−−−−−−−−−−−−−−I n t e r r u p c i o n e s de t r a n s m i c i ´ n −−−−−−−−−−−−−−−−−−−−−− o // E s t a s i n t e r r u p c i o n e s e s t a n supuestamente d e s a c t i v a d a s . } void attribute (( interrupt .

Clase ’serie.h’
v o i d InitUART1 ( ) ; v o i d InitUART2 ( ) ; void attribute void attribute void attribute void attribute

(( interrupt (( interrupt (( interrupt (( interrupt

, , , ,

no no no no

auto auto auto auto

psv ) ) psv ) ) psv ) ) psv ) )

U1RXInterrupt ( v o i d ) ; U2RXInterrupt ( v o i d ) ; U1TXInterrupt ( v o i d ) ; U2TXInterrupt ( v o i d ) ;

master/serie.h

180

Clase ’main.c’
#i n c l u d e <p33FJ128GP802 . h> #i n c l u d e ” I2C . h” #i n c l u d e ” s e r i e . h” #i n c l u d e ” CargarPrograma . h” #i n c l u d e ” adc . h” #i n c l u d e ”mapearP . h” #d e f i n e n u m P e r i l l a s 6 //−−−−−−−−−−−−−−−−−−−−−−−−−−−−−C o n f i g u r a c i ´ n −−−−−−−−−−−−−−−−−−−−−−−−−−−−−− o FOSCSEL(FNOSC FRC) ; FOSC(FCKSM CSECMD & OSCIOFNC OFF & POSCMD NONE) ; FWDT(FWDTEN OFF) ; //−−−−−−−−−−−−−−−−−−−−−−− D e c l a r a c i ´ n de v a r i a b l e s −−−−−−−−−−−−−−−−−−−−−−−− o u n s i g n e d s h o r t i n t r e c i b i , posDato , v e l o c i d a d , nota , f u n c i o n A c t u a l , bandera ; unsigned short i n t destino ; unsigned i n t datosFuncion [ 2 ] ; int adc buffer [ numPerillas ] ; unsigned short i n t a d c i ; unsigned i n t adc valor ; unsigned short i n t * adc valor2 ; unsigned i n t adc bandera ; unsigned i n t adc dato ; i n t a d c v a l o r I n t = 0 x1234 ; unsigned short i n t t a b l a P e r i l l a s [ ] = { 5 , 7 , 6 , 3 , 4 , 2 } ; i n t b u f f e r D a t a [ 2 * UNA RONDA+ 1 0 ] ; s h o r t i n t programacionActiva , p o s B u f f e r , b u f f e r L i s t o , dato2 ; u n s i g n e d s h o r t i n t e r r o r =0; l o n g i n t CRC; s h o r t i n t * CRC L ; s h o r t i n t CRC L recibido ; c h a r bandera2 =0; char j , k , encontreNota ; int llevoCuenta = 0; u n s i g n e d s h o r t i n t e r r o r 2 =0; s h o r t i n t flagNoteOn , f l a g N o t e O f f ; u n s i g n e d s h o r t i n t notasGuardadas [ numeroPics ] ; //−−−−−−−−−−−−−−−−−−−−−−−−C o n f i g u r a c i ´ n d e l r e l o j −−−−−−−−−−−−−−−−−−−−−−−−−− o v o i d I n i t C l o c k ( ) { // Este m´todo hace que e l DSPic f u n c i o n e con e l e c r i s t a l i n t e r n o a 40 Mips . PLLFBD = 4 1 ; CLKDIVbits . PLLPOST = 0 ; CLKDIVbits . PLLPRE = 0 ; OSCTUN = 0 ; RCONbits .SWDTEN = 0 ; builtin write OSCCONH ( 0 x01 ) ; builtin write OSCCONL ( 0 x01 ) ; w h i l e ( OSCCONbits .COSC != 0 b001 ) ; w h i l e ( OSCCONbits .LOCK != 1 ) { } ; } //−−−−−−−−−−−−−−−−−−−I n t e r p r e t a c i ´ n de comandos MIDI−−−−−−−−−−−−−−−−−−−− o v o i d a g r e g a r N o t a ( ) { // Este m´todo i n t e r p r e t a l o s comandos MIDI . e

181

// Es llamado cuando e l programa d e t e c t a que s e completo una i n s t r u c c i ´ n o MIDI . nota=d a t o s F u n c i o n [ 0 ] ; e r r o r 2=e r r o r 2+I 2 C p o l l ( 2 * d e s t i n o ) ; // Env´ por I2C a q u i e n c o r r e s p o n d e ıo l a nota . I 2 C w r i t e ( 2 * d e s t i n o , 0 , nota ) ; v e l o c i d a d=d a t o s F u n c i o n [ 1 ] ; I2Cwrite (2* destino , 1 , velocidad ) ; la velocidad .

// Env´ por I2C a q u i e n c o r r e s p o n d e ıo

e r r o r 2=e r r o r 2+I 2 C p o l l ( 2 * d e s t i n o ) ; notasGuardadas [ d e s t i n o −d i r e c c i o n D e s d e ]= nota ; d e s t i n o ++; // F i j o e l d e s t i n o para e l pr´ ximo e n v´o . o ı i f ( d e s t i n o >=d i r e c c i o n D e s d e+numeroPics ) { d e s t i n o=d i r e c c i o n D e s d e ; } i f ( e r r o r 2 >0){ U1TXREG = 5 ; // S i hubo un e r r o r a v i s o por p u e r t o s e r i e . error2 = 0; } return ; } void quitarNota ( ) { nota = 1 0 0 ; //La c a n t i d a d de n o t a s que e l s i s t e m a puede r e p r o d u c i r e s de 8 6 , s i s e pasa un 1 0 0 , l o s e s c l a v o s saben que deben apagar su nota actual . encontreNota = 0 ; k=0; while ( ! encontreNota ) { i f ( notasGuardadas [ k]== nota ) { d e s t i n o = d i r e c c i o n D e s d e+k ; notasGuardadas [ k ] = 1 0 0 ; // Para que l a pr´ xima vez que h a l l a que o apagar l a nota ’ nota ’ no l e e n v´e a l mismo e s c l a v o l a s e n a l . ı ˜ e r r o r 2=e r r o r 2+I 2 C p o l l ( 2 * d e s t i n o ) ; I 2 C w r i t e ( 2 * d e s t i n o , 0 , nota ) ; I 2 C w r i t e ( 2 * d e s t i n o , 1 , 0 ) ; // Env´ por I2C a q u i e n c o r r e s p o n d e l a ıo velocidad . e r r o r 2=e r r o r 2+I 2 C p o l l ( 2 * d e s t i n o ) ; encontreNota = 1 ; } k++; i f ( k==numeroPics ) { encontreNota = 1 ; } } } //−−−−−−−−−−−−−−−−−−−−−−−−−−−−M´todo p r i n c i p a l −−−−−−−−−−−−−−−−−−−−−−−−−−−− e i n t main ( v o i d ) { //−−−−−−− C o n f i g u r a c i ´ n de e l e m e n t o s y d e c l a r a c i ´ n de v a r i a b l e s −−−−−−−− o o

182

unsigned i n t r r ; i n t aux ; char e r r o r 3 = 0 ; unsigned short i n t i , j ; adc i = 0; AD1PCFGL = 0xE1FC ; // =1110000111111100 InitClock () ; mapearPuertos ( ) ; InitUART1 ( ) ; InitUART2 ( ) ; posDato =0; v e l o c i d a d =0; nota =0; d e s t i n o=d i r e c c i o n D e s d e ; initADC ( ) ; iniciarI2C () ; i = 1; adc valor = 0; adc dato = 0; a d c v a l o r 2 = &a d c v a l o r ; adc buffer [ 0 ] = 0; adc buffer [ 1 ] = 0; p o s B u f f e r =0; //−−−−−−−−−−−−−−−−−−−−−−−−−−−−−Bucle p r i n c i p a l −−−−−−−−−−−−−−−−−−−−−−−−−−−− while (1) { f o r ( r r =1; r r <10000; r r ++){ // Espera para que l o s c o n v e r s o r e s a n a l ´ g i c o o d i g i t a l esten l i s t o s . aux=r r ; } i f ( a d c i ==0){ // Chequeo c u a l e n t r a d a a n a l ´ g i c o t o c a a n a l i z a r y l a o analizo . AD1CHS0bits . CH0SA = 1 2 ; } i f ( a d c i ==1){ AD1CHS0bits . CH0SA = 1 1 ; } i f ( a d c i ==2){ AD1CHS0bits . CH0SA = 1 0 ; } i f ( a d c i ==3){ AD1CHS0bits . CH0SA = 9 ; } i f ( a d c i ==4){ AD1CHS0bits . CH0SA = 1 ; } i f ( a d c i ==5){ AD1CHS0bits . CH0SA = 0 ; } AD1CON1bits .SAMP = 1 ; w h i l e ( ! AD1CON1bits .DONE) ; // A n ´ l i s i s de l a e n t r a d a a n a l ´ g i c a a o correspondiente . // Espero h a s t a que s e h a l l a l e´ d o l a e n t r a d a c o r r e s p o n d i e n t e . ı aux=ADC1BUF0 ; // Guardo e l dato l e´ d o . ı

183

i f ( ( ( aux−a d c b u f f e r [ a d c i ] ) >20) | | ( ( a d c b u f f e r [ a d c i ]−aux ) >20) ) { // Chequeo s i e l v a l o r de l a e n t r a d a a n a l ´ g i c a e s s i g n i f i c a t i v a m e n t e o d i s t i n t o a l u l t i m o que e n v i e . ´ a d c b u f f e r [ a d c i ]= aux ; // S i e s s i g n i f i c a t i v a m e n t e d i s t i n t o , l o voy a e n v i a r . Primero a c t u a l i z o e l v a l o r que t e n g o guardado . e r r o r 3 =0; // Esta v a r i a b l e va a d e t e c t a r s i s e g e n e r a un e r r o r en l a t r a n s m i c i ´ n d e l I2C . o i f ( a d c i ==1|| a d c i ==2){ // S i e l dato que l e´ c o r r e s p o n d e a una ı p e r i l l a c o r r e s p o n d i e n t e a l a s e l e c c i ´ n de e f e c t o , t e n g o que o mandar un n´ mero d e l 0 a l 7 . u j=aux / 1 4 6 ; i f ( j >1){ j=j −1; } } e l s e { // S i e s una p e r i l l a a s o c i a d a a un e f e c t o , t e n g o que mandar un n´ mero d e l 1 a l 1 2 8 . u j=aux / 8 ; } U1TXREG = j ;

// Env´ por p u e r t o s e r i e e l cambio para c o n t r o l . ıo

U1TXREG = a d c i ; f o r ( i=d i r e c c i o n D e s d e ; i <( d i r e c c i o n D e s d e+numeroPics ) ; i ++){ a t o d o s l o s e s c l a v o s d e l cambio .

// Le a v i s o

e r r o r 3=e r r o r 3+I 2 C p o l l ( 2 * i ) ; I2Cwrite (2* i , t a b l a P e r i l l a s [ a d c i ] , j ) ; e r r o r 3=e r r o r 3+I 2 C p o l l ( 2 * i ) ; i f ( e r r o r 3 >0){ U1TXREG=0x34 ; // S i hubo un e r r o r en l a t r a n s m i c i ´ n por I2C a v i s o o por p u e r t o s e r i e . e r r o r 3 =0; } r e t a r d o ( 1 0 0 0 0 ) ; //Hago una e s p e r a e n t r e t r a s n m i c i ´ n y t r a n s m i c i ´ n o o para que s e l i b e r e e l p u e r t o . } } a d c i ++;

// A c t u a l i z o l a e n t r a d a a n a l ´ g i c a a c h e q u e a r . o

i f ( a d c i > n u m P e r i l l a s −1){ adc i = 0; } i f ( bandera >0){ // S i s e complet´ l a r e c e p c i ´ n de una i n s t r u c c i ´ n MIDI , o o o la analizo . i f ( flagNoteOn==1){ agregarNota ( ) ; flagNoteOn =0; } i f ( f l a g N o t e O f f ==1){ quitarNota () ;

184

} i f ( ( programacionActiva >0) ) { // S i hay que r e p r o g r a m a r e l i n s t r u m e n t o . posDato =0. comienzo a r e p r o g r a m a r l o . cargarNuevoPrograma ( ) . U2TXREG = 0 x18 . } } } master/main.c 185 .f l a g N o t e O f f =0. } bandera =0.

Decidimos no agregar las clases visuales (clases encargadas del dise˜o de n las ventanas) debido a que estas son clases generadas autom´ticamente por Visual Studio a que contienen s´lo informaci´n sobre el aspecto de la ventana (tama˜o y posici´n de cada o o n o uno de los objetos). El sistema para la creaci´n de este c´digo fue el de lograr un programa que haga ciertas funo o ciones probarlo y si se llega correctamente al objetivo y hay tiempo. Se lleg´ a un punto en el cual debimos optar e n o por reestructurar el programa para que quede con una programaci´n prolija. Mientras que agregarle al proe a grama m´s facilidades permite un mejor uso de todas las caracter´ a ısticas del sintetizador. Decidimos a seguirle agregando aplicaciones al programa por que dado que no es una prioridad del proyecto consideramos que no es necesario que este est´ extremadamente prolijo y con e m´todos extremadamente eficientes y f´ciles de entender. c´digos del software para dise˜ ar instrumentos o n Introducci´n o A continuaci´n se presentan los c´digos de las clases del programa creado para dise˜ar o o n instrumentos. Este fue un programa generado en las ultimas etapas del proyecto. la o o estructura no est´ perfectamente dise˜ada. ampliar el programa para agregarle funciones y as´ sucesivamente para transformar el programa b´sico con el ı a que se comenz´ en el actual.Anexo D. comenz´ siendo un ´ o peque˜o programa que s´lo realizaba algunas acciones b´sicas y termin´ siendo lo que es n o a o actualmente. 186 . siguiendo o est´ndares y bien comentada o seguirle agregando aplicaciones al programa. La forma de desarrollo del programa se debi´ a que al no ser un objetivo o prioritario del proyecto no se lo pudo planificar estructuralmente desde el principio. o Esta forma de creaci´n del programa fue la que llev´ a que si bien el programa funcione.

m i I n s t r u m e n t o End Get S e t ( ByVal v a l u e As i n s t r u m e n t o ) Me . 9 . 6 . nombre LImportando . Text = ” E d i t a r cada e n v o l v e n t e ” TabPage2 .vb’ Imports System . j . True ) Next Next rearmarPaneles () TabPage1 . i . Text = ”La o c t a v a s e l e c c i o n a d a e s l a n´ mero 1 ” u L ab el 5 . 8 . V i s i b l e = F a l s e 187 . Text = ” Probar l a s n o t a s g e n e r a d a s ” L ab el 2 . F o r m a t t e r s .Clase ’crearInstrumento. 1 0 . n o t a s ( 0 ) . Text = ” E d i c i ´ n com´ n a t o d a s l a s e n v o l v e n t e s ” o u TabPage3 . Text = ”La nota s e l e c c i o n a d a e s l a n´ mero 1 ” u TNombre . 11} Dim p r i m e r E n v o l v e n t e As I n t e g e r = 1 Dim l i s t a H i j o s As L i s t ( Of c r e a r M a s c a r a ) Dim ultimaRuta As S t r i n g = ” ” Dim yaGuardo As Boolean = F a l s e P r i v a t e m i I n s t r u m e n t o As i n s t r u m e n t o #End Region #Region ” p r o p i e d a d e s ” P u b l i c P r o p e r t y miInstrumento ( ) As i n s t r u m e n t o Get Return Me . Binary Public Class crearInstrumento #Region ” v a r i a b l e s ” Dim t e c l a A c t u a l As I n t e g e r = 0 Dim esDeArriba As Boolean = F a l s e Dim l i s t a X A r r i b a As L i s t ( Of I n t e g e r ) Dim esLaPrimerVez As Boolean = True Dim t e c l a A c t u a l A r r i b a As I n t e g e r = −1 Dim numeroNota As I n t e g e r = 1 Dim l i s t a N o t a s A b a j o ( ) As I n t e g e r = { 1 . Text = miInstrumento . S e r i a l i z a t i o n . m i I n s t r u m e n t o = v a l u e End S e t End P r o p e r t y #End Region #Region ” c o n s t r u c t o r e s ” P u b l i c Sub New ( ) InitializeComponent () miInstrumento = New i n s t r u m e n t o ( ) Dim i As I n t e g e r Dim vent As c r e a r M a s c a r a Dim j As I n t e g e r For j = 0 To 85 For i = 0 To 14 vent = New c r e a r M a s c a r a (Me. 4 . 3 . 12} Dim l i s t a N o t a s A r r i b a ( ) As I n t e g e r = { 2 . True . 7 . 5 . IO Imports System . Runtime .

i c o ” Dim i c o n o As New I c o n ( r u t a I c o n o ) Me . Text = ” E d i t a r cada e n v o l v e n t e ” TabPage2 . BackColor = C o l o r . V i s i b l e = F a l s e ProgressBar1 . BackColor = C o l o r . GetDirectoryName ( A p p l i c a t i o n . f o t o I ma g e nF r ec u en c ia 3 . n o t a s ( 0 ) . n o t a s ( numeroNota − 1) . V i s i b l e = False Try Dim r u t a I c o n o As S t r i n g = Path . Text = miInstrumento .ProgressBar1 . ByVal r u t a As S t r i n g . GetDirectoryName ( A p p l i c a t i o n . f o t o P a n e l F r e c u e n c i a 1 . i c o ” Dim i c o n o As New I c o n ( r u t a I c o n o ) Me . BackColor = C o l o r . f o t o I ma g e nF r ec u en c ia 2 . 50 . FromArgb ( 8 0 . l i s t a M a s c a r a s ( primerEnvolvente + 1) . FromArgb ( 5 0 + ( p r i m e r E n v o l v e n t e + 1) * 6 . Text = ” Probar l a s n o t a s g e n e r a d a s ” LImportando . BackColor = C o l o r . 103 − numeroNota / 2 . I c o n = i c o n o Catch ex As E x c e p t i o n End Try yaGuardo = yaG ultimaRuta = r u t a Timer1 . 50) Panel1 . 50) P a n e l F r e c u e n c i a 3 . l i s t a M a s c a r a s ( primerEnvolvente − 1) . S t a r t ( ) End Sub P u b l i c Sub New( ByVal i n s As i n s t r u m e n t o . Image = miInstrumento . Image = miInstrumento . n o t a s ( numeroNota − 188 . Text = ”La nota s e l e c c i o n a d a e s l a n´ mero 1 ” u TNombre . ExecutablePath ) + ”\ nota musical . Text = ” E d i c i ´ n com´ n a t o d a s l a s e n v o l v e n t e s ” o u TabPage3 . FromArgb ( 5 0 + ( primerEnvolvente ) * 6 . l i s t a M a s c a r a s ( primerEnvolvente ) . n o t a s ( numeroNota − 1) . 50 . Text = miInstrumento . 60 + numeroNota / 2 ) TFrecuencia1 . ExecutablePath ) + ”\ nota musical . I c o n = i c o n o Catch ex As E x c e p t i o n End Try Timer1 . 50 . 50) P a n e l F r e c u e n c i a 2 . FromArgb ( 5 0 + ( p r i m e r E n v o l v e n t e − 1) * 6 . ByVal yaG As Boolean ) InitializeComponent () miInstrumento = i n s TabPage1 . Image = miInstrumento . n o t a s ( numeroNota − 1) . S t a r t ( ) End Sub #End Region #Region ” m´ todos ” e P u b l i c Sub r e a r m a r P a n e l e s ( ) I ma g e nF r ec u en c ia 1 . V i s i b l e = False L ab el 2 . Text = ”La o c t a v a s e l e c c i o n a d a e s l a n´ mero 1 ” u L ab el 5 . nombre Try Dim r u t a I c o n o As S t r i n g = Path .

C r e a t e ) Dim b f As New BinaryFormatter b f . l i s t a C o e f i c i e n t e s ( primerEnvolvente + 1) TNombre . T o S t r i n g ( ”F2” ) T m u l t i p l i c a d o r F r e c u e n c i a 1 . i n s t ) | * . numeroMascara ) vent . n o t a s ( numeroNota − 1 ) . l i s t a C o e f i c i e n t e s ( primerEnvolvente − 1) T m u l t i p l i c a d o r F r e c u e n c i a 2 . i n s t ” vent . Text = miInstrumento . Text = miInstrumento . n o t a s ( numeroNota − 1) . No Then seguir = False End I f End I f I f s e g u i r Then guardarComo ( vent . F i l t e r = ” i n s t r u m e n t o s ( * . Text = miInstrumento . Text = miInstrumento . numeroNota − 1 . C h e c k F i l e E x i s t s Then Dim c a r t e l As MsgBoxResult = MsgBox ( ” Desea s o b r e e s c r i b i r e l a r c h i v o s e l e c c i o n a d o ” . miInstrumento ) f s . MsgBoxStyle . l i s t a F r e c u e n c i a s ( p r i m e r E n v o l v e n t e − 1 ) . T o S t r i n g ( ”F2” ) TFrecuencia3 . Text = miInstrumento . FileMode . C r i t i c a l ) a Me .1 ) . ShowDialog ( ) Dim s e g u i r As Boolean = True I f vent . l i s t a F r e c u e n c i a s ( p r i m e r E n v o l v e n t e + 1 ) . i n s t ” vent . n o t a s ( numeroNota − 1) . FileName ) End I f End Sub P r i v a t e Sub importarMascara ( ByVal d e s f a s a j e As I n t e g e r ) 189 . YesNo ) I f c a r t e l = MsgBoxResult . MsgBoxStyle . Enabled = True End Try End Sub P r i v a t e Sub guardarComo ( ByVal r u t a D e s t i n o As S t r i n g ) Try Dim f s As New F i l e S t r e a m ( r u t a D e s t i n o . Close () yaGuardo = True ultimaRuta = r u t a D e s t i n o Catch ex As E x c e p t i o n MsgBox ( ” i m p o s i b l e g u a r d a r ” ) End Try End Sub P r i v a t e Sub guardarAntesRuta ( ) Dim vent As New S a v e F i l e D i a l o g vent . AddExtension = True vent . D e f a u l t E x t ( ) = ” . Text = miInstrumento . n o t a s ( numeroNota − 1) . l i s t a F r e c u e n c i a s ( p r i m e r E n v o l v e n t e ) . ShowDialog ( ) Catch ex As E x c e p t i o n MsgBox ( ” E r r o r a l a b r i r l a m´ scara ” . n o t a s ( numeroNota − 1 ) . n o t a s ( numeroNota − 1 ) . S e r i a l i z e ( f s . T o S t r i n g ( ”F2” ) TFrecuencia2 . nombre End Sub P r i v a t e Sub e d i t a r M a s c a r a ( ByVal numeroMascara As I n t e g e r ) Dim vent As c r e a r M a s c a r a Try vent = New c r e a r M a s c a r a (Me. l i s t a C o e f i c i e n t e s ( primerEnvolvente ) T m u l t i p l i c a d o r F r e c u e n c i a 3 .

150) Panel2 . 1 . ShowDialog ( ) Try Dim f s As New F i l e S t r e a m ( vent . I n v a l i d a t e ( r e c t ) t e c l a A c t u a l = Fix ( ( ( ( M o u s e P o s i t i o n − Me . T o S t r i n g 190 . l i s t a M a s c a r a s ( p r i m e r E n v o l v e n t e + d e s f a s a j e ) = mas rearmarPaneles () Catch ex As E x c e p t i o n MsgBox ( ”No s e pudo a b r i r e l a r c h i v o e s p e c i f i c a d o ” ) End Try End Sub #End Region #Region ” r e a c c i o n e s ” P r i v a t e Sub P a n e l 2 C l i c k ( ByVal s e n d e r As Object . L o c a t i o n ) . 1 5 0 ) Panel2 .X Dim p o s i c i o n Y As I n t e g e r = ( M o u s e P o s i t i o n − Me . FileMode . Close () miInstrumento . Text = ”La nota s e l e c c i o n a d a e s l a n´ mero ” + u numeroNota . 5 0 . L o c a t i o n ) . FileName .Dim vent As New O p e n F i l e D i a l o g vent . T o S t r i n g I f p o s i c i o n Y > 48 And p o s i c i o n Y < 137 Then Dim i As I n t e g e r For i = 0 To l i s t a X A r r i b a . Open ) Dim b f As New BinaryFormatter Dim mas As mascara = CType ( b f . C l i c k esDeArriba = F a l s e Dim p o s i c i o n X As I n t e g e r = ( M o u s e P o s i t i o n − Me .Y I f p o s i c i o n X > 6 And p o s i c i o n X < 1025 And p o s i c i o n Y > 49 And p o s i c i o n Y < 199 Then Dim numOctava As I n t e g e r = Fix ( 1 + ( ( p o s i c i o n X ) − 6 ) / 1 4 0 ) L ab el 2 . I n v a l i d a t e ( r e c t ) I f esDeArriba Then numeroNota = ( numOctava − 1 ) * 12 + l i s t a N o t a s A r r i b a ( t e c l a A c t u a l A r r i b a − ( numOctava − 1 ) * 5) Else numeroNota = ( numOctava − 1 ) * 12 + l i s t a N o t a s A b a j o ( t e c l a A c t u a l − ( numOctava − 1 ) * 7 ) End I f I f numeroNota = 87 Then numeroNota = 86 End I f L ab el 5 . EventArgs ) Handles Panel2 .X) − 6 ) / 2 0 ) r e c t = New R e c t a n g l e ( 6 + 20 * t e c l a A c t u a l − 1 4 . D e s e r i a l i z e ( f s ) . Text = ”La o c t a v a s e l e c c i o n a d a e s l a n´ mero ” + u numOctava . Count − 1 I f ( p o s i c i o n X − 6 ) >= l i s t a X A r r i b a ( i ) And ( p o s i c i o n X − 6 ) <= ( l i s t a X A r r i b a ( i ) + 1 4 ) Then esDeArriba = True teclaActualArriba = i End I f Next End I f Dim r e c t As New R e c t a n g l e ( 6 + 20 * t e c l a A c t u a l − 1 4 . mascara ) f s . 1 . 5 0 . ByVal e As System . L o c a t i o n ) . n o t a s ( numeroNota − 1 ) .

posX . ByVal e As System . Windows . 2 . Black . Red . posX + 2 . 8 8 ) posX = posX + 20 numTecla = numTecla + 1 Next posX = posX + 20 For j = 0 To 2 I f t e c l a A c t u a l A r r i b a = numTecla And esDeArriba Then g r a f i c o . Add( posX ) End I f g r a f i c o . 2 . 9 0 ) End I f I f esLaPrimerVez Then l i s t a X A r r i b a . posX . 9 0 ) Else g r a f i c o . 2 . posX . Forms . 2 . Black . 2 0 . 1 4 . Add( posX ) End I f g r a f i c o . 2 . F i l l R e c t a n g l e ( Brushes . 1 4 .End I f rearmarPaneles () End Sub P r i v a t e Sub P a n e l 2 P a i n t ( ByVal s e n d e r As Object . 1 2 . P ai nt I f esLaPrimerVez Then l i s t a X A r r i b a = New L i s t ( Of I n t e g e r ) End I f Dim g r a f i c o As G r ap hi cs = e . DrawRectangle ( punta . 1 5 0 ) posX = posX + 20 Next posX = 15 Dim numTecla As I n t e g e r = 0 For i = 0 To 6 For j = 0 To 1 I f t e c l a A c t u a l A r r i b a = numTecla And esDeArriba Then g r a f i c o . 2 . 9 0 ) Else g r a f i c o . Red . posX . posX . 1 4 . PaintEventArgs ) Handles Panel2 . F i l l R e c t a n g l e ( Brushes . G ra ph i cs Dim punta As New Pen ( C o l o r . 4 ) Dim posX As I n t e g e r = 2 Dim j As I n t e g e r Dim i As I n t e g e r For i = 0 To 50 I f t e c l a A c t u a l = i And esDeArriba = F a l s e Then g r a f i c o . 1 5 0 ) End I f g r a f i c o . posX . DrawRectangle ( punta . F i l l R e c t a n g l e ( Brushes . 1 5 0 ) Else g r a f i c o . posX . 2 0 . 2 . Red . 1 4 . DrawRectangle ( punta . F i l l R e c t a n g l e ( Brushes . F i l l R e c t a n g l e ( Brushes . 1 2 . 2 . 2 . F i l l R e c t a n g l e ( Brushes . Black . LightGray . 9 0 ) End I f I f esLaPrimerVez Then l i s t a X A r r i b a . 2 0 . posX + 2 . 8 8 ) posX = posX + 20 numTecla = numTecla + 1 Next posX = posX + 20 Next esLaPrimerVez = F a l s e End Sub 191 .

T o S t r i n g + ” =” E F r e c u e n c i a 3 . Object . C l i c k importarMascara ( −1) rearmarPaneles () End Sub P r i v a t e Sub I m a g e n F r e c u e n c i a 1 D o u b l e C l i c k ( ByVal s e n d e r As Object . EventArgs ) Handles Im a ge n F re c ue n c ia 3 . ByVal e As System . ByVal e As System . ByVal e As System . C l i c k editarMascara ( primerEnvolvente + 1) End Sub P r i v a t e Sub I m a g e n F r e c u e n c i a 2 D o u b l e C l i c k ( ByVal s e n d e r As Object . C l i c k editarMascara ( primerEnvolvente − 1) End Sub P r i v a t e Sub B E d i t a r M a s c a r a 2 C l i c k ( ByVal s e n d e r As Object . D i s p o s e d For Each vent As c r e a r M a s c a r a In l i s t a H i j o s vent . ByVal e As System . ByVal e As System . EventArgs ) Handles Im a ge n F re c ue n c ia 2 . D o u b l e C l i c k editarMascara ( primerEnvolvente + 1) End Sub 192 . EventArgs ) Handles BEditarMascara2 . EventArgs ) Handles BEditarMascara3 . ByVal e As System . D o u b l e C l i c k editarMascara ( primerEnvolvente − 1) End Sub P r i v a t e Sub c r e a r I n s t r u m e n t o D i s p o s e d ( ByVal s e n d e r As Object . EventArgs ) Handles BDeArchivo1 . Text = ” f r e c u e n c i a Nº ” + ( p r i m e r E n v o l v e n t e + 2 ) . ByVal e As System . ValueChanged p r i m e r E n v o l v e n t e = 1 + Fix ( H S c r o l l B a r 1 . T o S t r i n g + ” =” rearmarPaneles () End Sub P r i v a t e Sub BDeArchivo1 Click ( ByVal s e n d e r As System . EventArgs ) Handles Me . T o S t r i n g + ” =” E F r e c u e n c i a 2 . ByVal e As System . ByVal e As System . Text = ” f r e c u e n c i a Nº ” + p r i m e r E n v o l v e n t e . D i s p o s e ( ) Next End Sub P r i v a t e Sub B E d i t a r M a s c a r a 1 C l i c k ( ByVal s e n d e r As Object . Text = ” f r e c u e n c i a Nº ” + ( p r i m e r E n v o l v e n t e + 1 ) . EventArgs ) Handles Im a ge n F re c ue n c ia 1 .P r i v a t e Sub HScrollBar1 ValueChanged ( ByVal s e n d e r As Object . C l i c k editarMascara ( primerEnvolvente ) End Sub P r i v a t e Sub B E d i t a r M a s c a r a 3 C l i c k ( ByVal s e n d e r As Object . Value / 7 ) I f p r i m e r E n v o l v e n t e > 13 Then p r i m e r E n v o l v e n t e = 13 End I f E F r e c u e n c i a 1 . EventArgs ) Handles H S c r o l l B a r 1 . EventArgs ) Handles BEditarMascara1 . D o u b l e C l i c k editarMascara ( primerEnvolvente ) End Sub P r i v a t e Sub I m a g e n F r e c u e n c i a 3 D o u b l e C l i c k ( ByVal s e n d e r As Object .

o a MsgBoxStyle . Value − 1 ) Dim mulHasta As Double = miInstrumento . n o t a s ( numeroNota − 1 ) . Object . C l i c k Try Dim f r e c As Double = ( TFrecuencia2 . C l i c k Try Dim f r e c As Double = ( TFrecuencia3 . Value − 1 ) Dim mulDesde As Double = miInstrumento . n o t a s ( numeroNota − 1 ) . ByVal e As System . l i s t a C o e f i c i e n t e s ( NDesdeInter . l i s t a C o e f i c i e n t e s ( NHastaInter . l i s t a F r e c u e n c i a s ( primerEnvolvente ) = f r e c Catch ex As E x c e p t i o n MsgBox ( ”No i n s e r t ´ una f r e c u e n c i a v ´ l i d a ” . u MsgBoxStyle . Text ) miInstrumento . ByVal e As System . Value − NDesdeInter . Value − 1 ) Dim masHasta As mascara = miInstrumento . ByVal e As System . n o t a s ( numeroNota − 1) . n o t a s ( numeroNota − 1 ) . C r i t i c a l ) Else Dim i As I n t e g e r Dim mas As mascara Dim masDesde As mascara = miInstrumento . Value − 2 193 . EventArgs ) Handles BFrecuencia1 . . n o t a s ( numeroNota − 1) . Object . EventArgs ) Handles BFrecuencia3 . Value < 2 Then MsgBox ( ” v e r i f i q u e que l o s n´ meros e s t e n b i e n . Value To NHastaInter . l i s t a M a s c a r a s ( NHastaInter . l i s t a M a s c a r a s ( NDesdeInter . Text ) miInstrumento . C r i t i c a l ) End Try End Sub P r i v a t e Sub B I n t e r p o l a r C l i c k ( ByVal s e n d e r As System . Value − NDesdeInter . EventArgs ) Handles B I n t e r p o l a r . C r i t i c a l ) End Try End Sub P r i v a t e Sub B F r e c u e n c i a 2 C l i c k ( ByVal s e n d e r As System . C l i c k Try Dim f r e c As Double = CDbl ( TFrecuencia1 . C r i t i c a l ) End Try End Sub P r i v a t e Sub B F r e c u e n c i a 3 C l i c k ( ByVal s e n d e r As System . n o t a s ( numeroNota − 1) . ByVal e As System . n o t a s ( numeroNota − 1 ) . l i s t a F r e c u e n c i a s ( primerEnvolvente + 1) = f r e c Catch ex As E x c e p t i o n MsgBox ( ”No i n s e r t ´ una f r e c u e n c i a v ´ l i d a ” .P r i v a t e Sub B F r e c u e n c i a 1 C l i c k ( ByVal s e n d e r As System . ” . Value − 1 Dim vent As c r e a r M a s c a r a I f N I n t e r . o a MsgBoxStyle . Object . l i s t a F r e c u e n c i a s ( primerEnvolvente − 1) = f r e c Catch ex As E x c e p t i o n MsgBox ( ”No i n s e r t ´ una f r e c u e n c i a v ´ l i d a ” . . Object . Text ) miInstrumento . C l i c k I f NHastaInter . Value − 1 ) Dim pon1 As I n t e g e r = 1 Dim pon2 As I n t e g e r = NHastaInter . o a MsgBoxStyle . EventArgs ) Handles BFrecuencia2 . Value = 1 Then For i = NDesdeInter .

l i s t a M a s c a r a s ( i ) = mas vent = New c r e a r M a s c a r a (Me. Object . mulHasta * pon1 . C h e c k F i l e E x i s t s Then Dim c a r t e l As MsgBoxResult = MsgBox ( ” Desea s o b r e e s c r i b i r e l a r c h i v o s e l e c c i o n a d o ” . mulHasta * pon1 . ByVal e As System . l i s t a M a s c a r a s ( i ) = mas vent = New c r e a r M a s c a r a (Me. Object . True . C l i c k importarMascara ( 0 ) rearmarPaneles () End Sub P r i v a t e Sub BDeArchivo3 Click ( ByVal s e n d e r As System . masHasta . ” s i n ” ) pon1 = pon1 + 1 pon2 = pon2 − 1 miInstrumento . True ) Next End I f rearmarPaneles () End I f End Sub P r i v a t e Sub BDeArchivo2 Click ( ByVal s e n d e r As System . EventArgs ) Handles GuardarComoToolStripMenuItem . numeroNota − 1 . ByVal e As System . C l i c k Dim vent As New S a v e F i l e D i a l o g vent . Value To NHastaInter . F i l t e r = ” a r c h i v o s de s o n i d o ( * . ByVal e As System . MsgBoxStyle . i . masHasta . No Then seguir = False End I f 194 . EventArgs ) Handles BGenerar . mulDesde * pon2 . n o t a s ( numeroNota − 1 ) . ShowDialog ( ) Dim s e g u i r As Boolean = True I f vent . Object . AddExtension = True vent . ” s i n ” . numeroNota − 1 . F a l s e ) pon1 = pon1 + 1 pon2 = pon2 − 1 miInstrumento . True ) Next Else For i = NDesdeInter . wav” vent . Object . C l i c k guardarAntesRuta ( ) End Sub P r i v a t e Sub B G e n e r a r C l i c k ( ByVal s e n d e r As System . EventArgs ) Handles BDeArchivo2 . C l i c k importarMascara ( 1 ) rearmarPaneles () End Sub P r i v a t e Sub GuardarComoToolStripMenuItem Click ( ByVal s e n d e r As System . ByVal e As System . D e f a u l t E x t ( ) = ” . mulDesde * pon2 . i . YesNo ) I f c a r t e l = MsgBoxResult . wav ) | * . n o t a s ( numeroNota − 1 ) . wav” vent .mas = New mascara ( masDesde . EventArgs ) Handles BDeArchivo3 . True . Value − 2 mas = New mascara ( masDesde .

. miInstrumento . FileName ) Then MsgBox ( ” E r r o r a l g r a b a r e l a r c h i v o de s o n i d o . Length > 0 Then Try Dim t e x t o As S t r i n g = Me . 1) 195 . v e r i f i q u e que . grabarWav ( l i s t a V a l o r e s . ShowDialog ( ) I f vent . EventArgs ) Handles ImportarDesdeHexToolStripMenuItem . 30000) I f Not metodosComunes . Value = ( j * 100 / 8 5 ) Next rearmarPaneles () Catch ex As E x c e p t i o n Me . C r i t i c a l ) End I f End I f rearmarPaneles () End Sub P r i v a t e Sub ImportarDesdeHexToolStripMenuItem Click ( ByVal s e n d e r As System . 1 5 0 0 0 . F i l t e r = ” a s s e m b l e r ( * . ByVal e As System . miInstrumento . . V i s i b l e = False End I f End Sub P r i v a t e Sub E x p o r t a r I n s t r u m e n t o T o o l S t r i p M e n u I t e m C l i c k ( ByVal s e n d e r As System . Object . Length > 0 Then Try LImportando . True .End I f I f s e g u i r Then Dim l i s t a V a l o r e s As L i s t ( Of I n t e g e r ) = Me . MsgBoxStyle . True ) Next P r o g r e s s B a r 1 . generarSonido (60000 . F i l t e r = ” a s s e m b l e r ( * . C l i c k Dim vent As New O p e n F i l e D i a l o g vent . C l i c k Dim vent As New S a v e F i l e D i a l o g vent . AddExtension = True vent . FileNames . EventArgs ) Handles ExportarInstrumentoToolStripMenuItem . V i s i b l e = True P r o g r e s s B a r 1 . Value − 1) . FileNames . FileName . ” . e x p o r t a r ( 1 5 0 0 0 . hex ” vent . MsgBoxStyle . Object . n o t a s ( NNotaAGenerar . i . hex ) | * . j . 3 0 0 0 0 ) Me . ByVal e As System . V i s i b l e = True Dim i n s t r As New i n s t r u m e n t o ( vent . V i s i b l e = F a l s e ProgressBar1 . ShowDialog ( ) I f vent . C r i t i c a l ) End Try LImportando . Enabled = True MsgBox ( ” I m p o s i b l e i m p o r t a r d e l a r c h i v o s e l e c c i o n a d o ” . vent . 30000 . hex ” vent . miInstrumento = i n s t r Dim i As I n t e g e r Dim ventAux As c r e a r M a s c a r a Dim j As I n t e g e r For j = 0 To 85 For i = 0 To 14 ventAux = New c r e a r M a s c a r a (Me. AddExtension = True vent . hex ) | * .

C l i c k Dim vent As New F o l d e r B r o w s e r D i a l o g vent . . n o t a s ( numeroNota − 1 ) . g e n e r a r S o n i d o ( ND * 3 0 . Object . ” . 3 0 0 0 0 ) . Object . Value miInstrumento . Value < 0 Then MsgBox ( ” E l e j i s t e mal l o s n´ meros . ByVal e As System . . ” ) End Try End I f End Sub P r i v a t e Sub B E x p l o r a r C l i c k ( ByVal s e n d e r As System . WriteAllText ( vent . False ) Catch ex As E x c e p t i o n MsgBox ( ”no s e pudo e x p o r t a r . C r i t i c a l ) u End Try 196 . ByVal e As System . TRuta . F i l e S y s t e m . t e x t o . Value − NGenerarDesde . Text ) miInstrumento . . g e n e r a r S o n i d o ( 6 0 0 0 0 . Click Try Dim num As Double = CDbl ( T m u l t i p l i c a d o r F r e c u e n c i a 1 . Text + ”\ nota ” + ( i + 1 ) . . Value − 1 To NGenerarHasta . S e l e c t e d P a t h End Sub P r i v a t e Sub B N o r m a l i z a r C l i c k ( ByVal s e n d e r As System . wav” ) End I f Next End I f rearmarPaneles () End Sub P r i v a t e Sub B A p l i c a r M u l t i p l i c a d o r 1 C l i c k ( ByVal s e n d e r As System . . EventArgs ) Handles BGenerarVarios . l i s t a C o e f i c i e n t e s ( p r i m e r E n v o l v e n t e − 1 ) = num Catch ex As E x c e p t i o n MsgBox ( ”Debe i n s e r t a r un n´ mero” . ByVal e As System . EventArgs ) Handles BExplorar . n o t a s ( i − 1 ) . MsgBoxStyle . Value < 0 Then MsgBox ( ” E l e j i s t e mal l o s n´ meros . Object . C l i c k I f NGenerarHasta . EventArgs ) Handles BNormalizar . MsgBoxStyle . . T o S t r i n g + ” .My. C r i t i c a l ) u Else Dim s a l i o B i e n As Boolean = True Dim i As I n t e g e r For i = NGenerarDesde . ” . n o t a s ( i ) . . C l i c k I f NNormalizarHasta . FileName . Value − NNormalizarDesde . Text = vent . MsgBoxStyle . . Object . Computer . C r i t i c a l ) u Else Dim i As I n t e g e r For i = NNormalizarDesde . Value − 1 I f s a l i o B i e n Then s a l i o B i e n = s a l i o B i e n And metodosComunes . ByVal e As System . ShowDialog ( ) TRuta . EventArgs ) Handles BAplicarMultiplicador1 . 3 0 0 0 0 ) Next End I f rearmarPaneles () End Sub P r i v a t e Sub B G e n e r a r V a r i o s C l i c k ( ByVal s e n d e r As System . grabarWav ( miInstrumento . Value To NGenerarHasta .

True ) End I f Next 197 . n o t a s ( NNotaHasta1 . n o t a s ( NNotaDesde1 . n o t a s ( numeroNota − 1 ) .End Sub P r i v a t e Sub B A p l i c a r M u l t i p l i c a d o r 2 C l i c k ( ByVal s e n d e r As System . C r i t i c a l ) u End Try End Sub P r i v a t e Sub B A p l i c a r M u l t i p l i c a d o r 3 C l i c k ( ByVal s e n d e r As System . MsgBoxStyle . Value − NNotaDesde1 . Object . MsgBoxStyle . Value − 2 Dim masDesde As mascara Dim masHasta As mascara Dim mulDesde As Double Dim mulHasta As Double For j = 0 To 14 masDesde = miInstrumento . EventArgs ) Handles BAplicarMultiplicador2 . Click Try Dim num As Double = CDbl ( T m u l t i p l i c a d o r F r e c u e n c i a 2 . Click Try Dim num As Double = CDbl ( T m u l t i p l i c a d o r F r e c u e n c i a 3 . l i s t a M a s c a r a s ( j ) = mas vent = New c r e a r M a s c a r a (Me. Object . Value − 1) . l i s t a M a s c a r a s ( j ) masHasta = miInstrumento . ByVal e As System . ” . l i s t a C o e f i c i e n t e s ( p r i m e r E n v o l v e n t e ) = num Catch ex As E x c e p t i o n MsgBox ( ”Debe i n s e r t a r un n´ mero” . Value − 1 Dim vent As c r e a r M a s c a r a For i = NNotaDesde1 . mulDesde * pon2 . n o t a s ( NNotaHasta1 . l i s t a C o e f i c i e n t e s ( j ) mulHasta = miInstrumento . Value To NNotaHasta1 . Value − NNotaDesde1 . l i s t a M a s c a r a s ( j ) mulDesde = miInstrumento . C l i c k I f NNotaHasta1 . Text ) miInstrumento . True . C r i t i c a l ) Else Dim i As I n t e g e r Dim j As I n t e g e r Dim pon1 As I n t e g e r = 1 Dim pon2 As I n t e g e r = NNotaHasta1 . n o t a s ( numeroNota − 1 ) . ByVal e As System . n o t a s ( i ) . ByVal e As System . n o t a s ( NNotaDesde1 . i . Value < 2 Then MsgBox ( ” Los v a l o r e s i n g r e s a d o s no son c o r r e c t o s . Value − 1) . Text ) miInstrumento . EventArgs ) Handles BAplicarMultiplicador3 . l i s t a C o e f i c i e n t e s ( j ) I f mulDesde * pon2 > 0 And mulHasta * pon1 > 0 Then Dim mas As New mascara ( masDesde . l i s t a C o e f i c i e n t e s ( p r i m e r E n v o l v e n t e + 1 ) = num Catch ex As E x c e p t i o n MsgBox ( ”Debe i n s e r t a r un n´ mero” . C r i t i c a l ) u End Try End Sub P r i v a t e Sub B E x t r a p o l a r N o t a 1 C l i c k ( ByVal s e n d e r As System . Object . ” s i n ” ) miInstrumento . j . mulHasta * pon1 . Value − 1) . Value − 1) . MsgBoxStyle . masHasta . EventArgs ) Handles BExtrapolarNota1 .

nombre = TNombre . Object . MsgBoxStyle . True ) End I f Next pon1 = pon1 + 1 pon2 = pon2 − 1 Next MsgBox ( ” Se e x t r a p o l o b i e n ” . Value − NNotaDesde1 . Value − 1) . n o t a s ( i ) . masHasta . Text Catch ex As E x c e p t i o n MsgBox ( ” E r r o r a l a s i g n a r e l nombre” . Value − 1) . Value − 1) . Value − 1) . j . mulHasta * pon1 . C r i t i c a l ) End Try End Sub P r i v a t e Sub A b r i r T o o l S t r i p M e n u I t e m C l i c k ( ByVal s e n d e r As System . C l i c k Try miInstrumento . ” s i n ” . EventArgs ) Handles BExtrapolarNota2 . Value < 2 Then MsgBox ( ” Los v a l o r e s i n g r e s a d o s no son c o r r e c t o s ” . EventArgs ) Handles BCambiarNombre . Value − 2 Dim masDesde As mascara Dim masHasta As mascara Dim mulDesde As Double Dim mulHasta As Double For j = 0 To 14 masDesde = miInstrumento . l i s t a C o e f i c i e n t e s ( j ) mulHasta = miInstrumento . Value To NNotaHasta2 . n o t a s ( NNotaDesde2 . Value − NNotaDesde2 . C r i t i c a l ) Else Dim i As I n t e g e r Dim j As I n t e g e r Dim pon1 As I n t e g e r = 1 Dim pon2 As I n t e g e r = NNotaHasta2 . ByVal e As System . MsgBoxStyle . mulDesde * pon2 . Object . I n f o r m a t i o n ) End I f End Sub P r i v a t e Sub B E x t r a p o l a r N o t a 2 C l i c k ( ByVal s e n d e r As System . ByVal e As System . n o t a s ( NNotaHasta2 . True . C l i c k 198 . l i s t a C o e f i c i e n t e s ( j ) I f mulDesde * pon2 > 0 And mulHasta * pon1 > 0 Then Dim mas As New mascara ( masDesde . EventArgs ) Handles AbrirToolStripMenuItem . F a l s e ) miInstrumento . n o t a s ( NNotaHasta2 . MsgBoxStyle . MsgBoxStyle .pon1 = pon1 + 1 pon2 = pon2 − 1 Next MsgBox ( ” Se e x t r a p o l o b i e n ” . n o t a s ( numeroNota − 1 ) . C l i c k I f NNotaHasta1 . Object . l i s t a M a s c a r a s ( j ) mulDesde = miInstrumento . i . l i s t a M a s c a r a s ( j ) masHasta = miInstrumento . ByVal e As System . Value − 1 Dim vent As c r e a r M a s c a r a For i = NNotaDesde2 . l i s t a M a s c a r a s ( j ) = mas vent = New c r e a r M a s c a r a (Me. I n f o r m a t i o n ) End I f End Sub P r i v a t e Sub BCambiarNombre Click ( ByVal s e n d e r As System . n o t a s ( NNotaDesde2 .

Object . C r i t i c a l ) u Else Dim masAux As mascara Dim notaACopiar As nota = miInstrumento . MsgBoxStyle . C l i c k I f yaGuardo Then guardarComo ( ultimaRuta ) Else guardarAntesRuta ( ) End I f End Sub P r i v a t e Sub Timer1 Tick ( ByVal s e n d e r As Object . C r i t i c a l ) End Try End I f End Sub P r i v a t e Sub S a l i r T o o l S t r i p M e n u I t e m C l i c k ( ByVal s e n d e r As System . n o t a s ( NACopiarEnv . Object . Tick Timer1 . EventArgs ) Handles Timer1 . i n s t ) | * . Stop ( ) numeroNota = 1 primerEnvolvente = 1 rearmarPaneles () End Sub P r i v a t e Sub B C o p i a r C l i c k ( ByVal s e n d e r As System . Click Me . YesNo ) I f r e s p u e s t a = MsgBoxResult . EventArgs ) Handles GuardarToolStripMenuItem . Close () miInstrumento = i n s yaGuardo = True ultimaRuta = r u t a Catch ex As E x c e p t i o n MsgBox ( ” I m p o s i b l e a b r i r e l a r c h i v o s e l e c c i o n a d o ” . Yes Then Dim vent As New O p e n F i l e D i a l o g vent . C l i c k I f NCopiarDesdeEnv . i n s t r u m e n t o ) f s . Value > NCopiarHastaEnv . FileMode . MsgBoxStyle . ByVal e As System . AddExtension = True vent .Dim r e s p u e s t a As MsgBoxResult = MsgBox ( ” Desea d e j a r e l i n s t r u m e n t o a c t u a l y a b r i r o t r o ? ” . MsgBoxStyle . F i l t e r = ” i n s t r u m e n t o s ( * . EventArgs ) Handles SalirToolStripMenuItem . ShowDialog ( ) Try Dim i n s As i n s t r u m e n t o Dim r u t a As S t r i n g = vent . Value Then MsgBox ( ” El n´ mero de nota d e s d e e l c u a l c o p i a r no puede s e r u mayor a l n´ mero h a s t a e l c u a l c o p i a r ” . ByVal e As System . EventArgs ) Handles BCopiarEnv . FileName Dim f s As New F i l e S t r e a m ( ruta . Open ) Dim b f As New BinaryFormatter i n s = CType ( b f . ByVal e As System . D i s p o s e ( ) End Sub P r i v a t e Sub GuardarToolStripMenuItem Click ( ByVal s e n d e r As Object . Value − 1 ) Dim vent As c r e a r M a s c a r a Dim i As I n t e g e r 199 . i n s t ” vent . D e s e r i a l i z e ( f s ) . ByVal e As System .

C r i t i c a l ) u Else Dim FrecAux As Double Dim notaACopiar As nota = miInstrumento . Value − 1 ) Dim i As I n t e g e r Dim j As I n t e g e r For i = 0 To 14 FrecAux = notaACopiar . Value To NExtraFrecHasta . Value − 1 ) Dim notaAux As nota Dim m u l t i p l i c a d o r As Double Dim d i f e r e n c i a As I n t e g e r = NExtraFrecHasta . j − 1 . EventArgs ) Handles B E x t r a p o l a r F r e c . Value > NExtraFrecHasta . o MsgBoxStyle . Value − 2 notaAux = miInstrumento . n o t a s ( j − 1 ) . n o t a s ( NExtraFrecHasta . l i s t a M a s c a r a s ( i ) = New mascara ( masAux ) vent = New c r e a r M a s c a r a (Me. C r i t i c a l ) Else Dim i As I n t e g e r Dim j As I n t e g e r Dim notaDesde As nota = miInstrumento . Object . True ) Next Next End I f MsgBox ( ” El p r o c e s o de c o p i a d o f i n a l i z ´ s a t i s f a c t o r i a m e n t e ” .Dim j As I n t e g e r For i = 0 To 14 masAux = notaACopiar . l i s t a M a s c a r a s ( i ) For j = NCopiarDesdeEnv . i . Value > NCopiarHastaFrec . ByVal e As System . l i s t a F r e c u e n c i a s ( i ) = FrecAux Next Next End I f MsgBox ( ” El p r o c e s o de c o p i a d o f i n a l i z ´ s a t i s f a c t o r i a m e n t e ” . ByVal e As System . e l v a l o r d e s d e o a debe s e r menor a e l v a l o r h a s t a menos 2 ” . l i s t a F r e c u e n c i a s ( i ) For j = NCopiarDesdeFrec . Value To NCopiarHastaEnv . C l i c k I f NExtraFrecDesde . n o t a s ( i ) For j = 0 To 14 200 . Value − NExtraFrecDesde . n o t a s ( j − 1 ) . MsgBoxStyle . I n f o r m a t i o n ) rearmarPaneles () End Sub P r i v a t e Sub B E x t r a p o l a r F r e c C l i c k ( ByVal s e n d e r As System . o MsgBoxStyle . True . Value To NCopiarHastaFrec . Value − 1 ) Dim notaHasta As nota = miInstrumento . Value − 2 Then MsgBox ( ” El rango de e x t r a p o l a c i ´ n no e s v ´ l i d o . EventArgs ) Handles BCopiarFrec . Object . Value miInstrumento . Value Then MsgBox ( ” El n´ mero de nota d e s d e e l c u a l c o p i a r no puede s e r u mayor a l n´ mero h a s t a e l c u a l c o p i a r ” . n o t a s ( NACopiarFrec . C l i c k I f NCopiarDesdeFrec . n o t a s ( NExtraFrecDesde . I n f o r m a t i o n ) End Sub P r i v a t e Sub B C o p i a r F r e c C l i c k ( ByVal s e n d e r As System . MsgBoxStyle . Value miInstrumento . Value For i = NExtraFrecDesde .

o o MsgBoxStyle . Value ) / d i f e r e n c i a ) notaAux .multiplicador = Math . ( 1 + i − NExtraFrecDesde . I n f o r m a t i o n ) End Sub #End Region End C l a s s programaVisual/apli/WindowsApplication1/crearInstrumento. Pow ( ( notaHasta . l i s t a F r e c u e n c i a s ( j ) ) . l i s t a F r e c u e n c i a s ( j ) = notaDesde .vb 201 . l i s t a F r e c u e n c i a s ( j ) / notaDesde . l i s t a F r e c u e n c i a s ( j ) * m u l t i p l i c a d o r Next Next End I f MsgBox ( ” F i n a l i z ´ s a t i s f a c t o r i a m e n t e l a e x t r a p o l a c i ´ n ” .

S e r i a l i z a t i o n . IO Imports System . p i n t a r P a n e l ( ) End Sub P u b l i c Sub aumentarValoresY ( ByVal c o n s t a n t e As Double ) Dim i As I n t e g e r For i = 0 To 6 I f l i s t a P u n t o s Y ( i ) > 0 Then listaPuntosY ( i ) = listaPuntosY ( i ) * constante End I f Next Me . I n v a l i d a t e ( ) 202 . F o r m a t t e r s . p i n t a r P a n e l ( ) End Sub P r i v a t e Sub p i n t a r P a n e l ( ) u l t i m o B i e n = True Panel1 . Binary Public Class crearMascara #Region ” v a r i a b l e s ” P r i v a t e l i s t a P u n t o s X ( 6 ) As I n t e g e r P r i v a t e l i s t a P u n t o s Y ( 6 ) As Double P r i v a t e XMax As I n t e g e r P r i v a t e YMax As Double P r i v a t e x E l e g i d o As I n t e g e r = 0 P r i v a t e v e c e s As I n t e g e r = 0 P r i v a t e u l t i m o B i e n As Boolean = True P r i v a t e hayQueAumetarPunto As Boolean = F a l s e P r i v a t e r u t a A c t u a l As S t r i n g P r i v a t e y a E l i g i o R u t a As Boolean P r i v a t e nombre As S t r i n g P r i v a t e miVentanaPadre As c r e a r I n s t r u m e n t o P r i v a t e numeroNota As I n t e g e r P r i v a t e numeroMascara As I n t e g e r Dim hayQueGuardarImagen As Boolean = F a l s e Dim a n c h o P a n e l O r i g i n a l As I n t e g e r Dim l a r g o P a n e l O r i g i n a l As I n t e g e r Dim hayQueDevolverMascara As Boolean = F a l s e Dim tengoPadre As Boolean = F a l s e Dim l i s t a P a r a B o r r a r As L i s t ( Of Double ) Dim yaGuardo As Boolean = F a l s e Dim ultimaRuta As S t r i n g = ” ” #End Region #Region ” m´ todos ” e P u b l i c Sub aumentarValoresX ( ByVal c o n s t a n t e As Double ) Dim i As I n t e g e r For i = 0 To 6 I f l i s t a P u n t o s X ( i ) > 0 Then listaPuntosX ( i ) = listaPuntosX ( i ) * constante End I f Next Me .Clase ’crearMascara. Runtime .vb’ Imports System .

cambios . masc” a vent . mascara ) f s . S e r i a l i z e ( f s . MsgBoxStyle . Close () yaGuardo = True ultimaRuta = r u t a D e s t i n o Catch ex As E x c e p t i o n MsgBox ( ” i m p o s i b l e g u a r d a r ” ) End Try End Sub P r i v a t e Sub guardarAntesRuta ( ) Dim vent As New S a v e F i l e D i a l o g vent . masc” vent . C h e c k F i l e E x i s t s Then Dim c a r t e l As MsgBoxResult = MsgBox ( ” Desea s o b r e e s c r i b i r e l a r c h i v o s e l e c c i o n a d o ” . C r e a t e ) Dim b f As New BinaryFormatter b f . ShowDialog ( ) Dim s e g u i r As Boolean = True I f vent . Close () armarTablas ( mas ) Return mas Catch ex As E x c e p t i o n MsgBox ( ” E r r o r a l a b r i r l a e n v o l v e n t e ” . D e f a u l t E x t ( ) = ” . FileMode . FileName ) End I f End Sub P u b l i c Function a b r i r M a s c a r a ( ByVal unaRuta As S t r i n g ) As mascara Dim mas As New mascara Try Dim f s As New F i l e S t r e a m ( unaRuta . C r i t i c a l ) End Try Return Nothing End Function P r i v a t e Sub armarTablas ( ByVal mas As mascara ) listaPuntosX (0) = 0 l i s t a P u n t o s Y ( 0 ) = mas . D e s e r i a l i z e ( f s ) . YesNo ) I f c a r t e l = MsgBoxResult . AddExtension = True vent . F i l t e r = ” m´ scaras ( * . mas ) f s . MsgBoxStyle . masc ) | * .End Sub P r i v a t e Sub guardarComo ( ByVal r u t a D e s t i n o As S t r i n g ) Try Dim mas As mascara = c r e a r M a s c a r a ( ) Dim f s As New F i l e S t r e a m ( r u t a D e s t i n o . cambios ( i ) = 65535 Then listaPuntosX ( i + 1) = listaPuntosX ( i ) 203 . Open ) Dim b f As New BinaryFormatter mas = CType ( b f . No Then seguir = False End I f End I f I f s e g u i r Then guardarComo ( vent . v a l o r I n i c i a l Dim i As I n t e g e r Dim ymax As Double = 0 For i = 0 To mas . FileMode . Count − 2 I f mas .

Me . EventArgs ) Handles B Apl ic ar . Panel1 . V i s i b l e = True L ab e l1 2 . V i s i b l e = F a l s e L ab e l1 2 . 0 . l i s t a P u n t o s Y . l i s t a P u n t o s X . Width . YesNo ) 204 . mapaBits ) Return mas End Function P u b l i c Sub a p l i c a r C a m b i o s ( ByVal a c t u a l i z o P a d r e As Boolean ) Me . Panel1 . Width = 264 Panel1 . i n c r e m e n t o s ( i ) * ( listaPuntosX ( i + 1) − listaPuntosX ( i ) ) End I f Next For Each num As Double In l i s t a P u n t o s Y I f num > ymax Then ymax = num End I f Next Me . Width = a n c h o P a n e l O r i g i n a l pintarPanel () L ab e l1 1 . MsgBoxStyle . V i s i b l e = True Dim mas As New mascara (Me . l i s t a M a s c a r a s ( numeroMascara ) = crearMascara ( ) I f a c t u a l i z o P a d r e Then Me . Height ) ) Panel1 . r e a r m a r P a n e l e s ( ) End I f End Sub #End Region #Region ” r e a c c i o n e s ” P r i v a t e Sub B A p l i c a r C l i c k ( ByVal s e n d e r As Object . New R e c t a n g l e ( 0 . cambios . Height = 154 L ab e l1 1 . miVentanaPadre . miInstrumento . V i s i b l e = F a l s e pintarPanel () Dim mapaBits As Bitmap = New Bitmap ( Panel1 . ByVal e As System . n o t a s ( numeroNota ) . Me . ByVal e As System . YMax = ymax pintarPanel () End Sub P r i v a t e Function c r e a r M a s c a r a ( ) As mascara hayQueGuardarImagen = F a l s e Panel1 . Height ) Panel1 . TNombre . cambios ( mas . Count − 2 ) Me . cambios ( i ) l i s t a P u n t o s Y ( i + 1 ) = l i s t a P u n t o s Y ( i ) + mas . DrawToBitmap ( mapaBits . XMax = 10 * mas . Text . Height = l a r g o P a n e l O r i g i n a l Panel1 . miVentanaPadre . EventArgs ) Handles AbrirToolStripMenuItem . C l i c k Dim r e s p u e s t a As MsgBoxResult = MsgBox ( ” Desea d e j a r l a m´ scara a a c t u a l y a b r i r o t r a ? ” .listaPuntosY ( i + 1) = listaPuntosY ( i ) Else l i s t a P u n t o s X ( i + 1 ) = 10 * mas . C l i c k a p l i c a r C a m b i o s ( True ) End Sub P r i v a t e Sub A b r i r T o o l S t r i p M e n u I t e m C l i c k ( ByVal s e n d e r As Object . Width . Panel1 .

Y − Panel1 . Add( l i s t a P u n t o s X ( i ) ) 205 . Height / 20 − Me . AddExtension = True vent . L o c a t i o n . PaintEventArgs ) Handles Panel1 . Length > 0 Then a b r i r M a s c a r a ( vent . Windows . ByVal e As System . Width ) ) . Forms . ” + ( ( 0 . masc” vent . 9 5 − ( ( M o u s e P o s i t i o n .X − 4 − Panel1 . Add( La b el 8 ) Dim l i s t a E t i q u e t a s Y As L i s t ( Of L ab e l ) = New L i s t ( Of L ab el ) l i s t a E t i q u e t a s Y . Text = ( ( 2 0 * ( ( M o u s e P o s i t i o n . Height / 2 0 ) ) * YMax) . MouseEventArgs ) Handles Panel1 . L o c a t i o n . Object . C l i c k guardarAntesRuta ( ) End Sub P r i v a t e Sub Panel1 MouseMove ( ByVal s e n d e r As Object . P ai nt Dim g r a f i c o As G r ap hi cs = e . ShowDialog ( ) I f vent . T o S t r i n g ( ”F0” ) + ” . Add( La b el 1 2 ) Dim i As I n t e g e r For i = 0 To 6 I f l i s t a P u n t o s Y ( i ) <> −1 And l i s t a P u n t o s Y ( i ) < 0 Then listaPuntosY ( i ) = 0 End I f Next For i = 0 To 6 I f l i s t a P u n t o s X ( i ) > −1 Then l i s t a X A P i n t a r .Y − 23 − Panel1 .I f r e s p u e s t a = MsgBoxResult . C r i t i c a l ) a End Try End I f End Sub P r i v a t e Sub GuardarComoToolStripMenuItem Click ( ByVal s e n d e r As System . EventArgs ) Handles GuardarComoToolStripMenuItem . Object . Add( La b el 6 ) l i s t a E t i q u e t a s X . Windows . L o c a t i o n . F i l t e r = ” i n s t r u m e n t o s ( * .X) * XMax) ) / ( 1 9 * Panel1 . MsgBoxStyle . Add( La b el 1 0 ) l i s t a E t i q u e t a s Y . Add( La b el 9 ) l i s t a E t i q u e t a s Y . L o c a t i o n . Add( La b el 5 ) l i s t a E t i q u e t a s X . G ra ph i cs Dim p1 As P oi nt Dim p2 As P oi nt Dim punta As Pen Dim l i s t a X A P i n t a r As L i s t ( Of Double ) = New L i s t ( Of Double ) Dim l i s t a Y A p i n t a r As L i s t ( Of Double ) = New L i s t ( Of Double ) Dim l i s t a E t i q u e t a s X As L i s t ( Of L ab e l ) = New L i s t ( Of L ab el ) l i s t a E t i q u e t a s X . FileNames . masc ) | * . Add( La b el 7 ) l i s t a E t i q u e t a s X .X − Panel1 . Add( La b el 1 1 ) l i s t a E t i q u e t a s Y .Y) ) / ( 1 9 * Panel1 . Width / 20 − Me . ByVal e As System . Forms . FileName ) End I f Catch ex As E x c e p t i o n MsgBox ( ” e r r o r a l a b r i r l a m´ scara ” . Yes Then Try Dim vent As New O p e n F i l e D i a l o g ( ) vent . MouseMove L ab el 1 . T o S t r i n g ( ”F2” ) End Sub P r i v a t e Sub P a n e l 1 P a i n t ( ByVal s e n d e r As System . ByVal e As System .

Height ) g r a f i c o . Width / 20 + 19 * i * Panel1 . Height / 2 0 ) p2 = New P o in t ( Panel1 . Height − Panel1 . Width / 20 yNuevoPunto1 = Panel1 . p1 . Height − ( l i s t a Y A p i n t a r ( i ) * Panel1 . Height / 2 0 ) g r a f i c o . Height / 20 − 3 ) g r a f i c o . yNuevoPunto1 ) p2 = New P o in t ( xNuevoPunto2 . Height / 2 0 ) yNuevoPunto2 = Panel1 . DrawLine ( punta . Height / 1 0 0 ) p2 = New P oi nt ( Panel1 . 1 ) p1 = New P o in t ( Panel1 . 0 ) p2 = New P o in t ( Panel1 . Height − ( l i s t a Y A p i n t a r ( i + 1 ) * Panel1 . Height − Panel1 . Width / 20 − 3 . p2 ) For i = 1 To 4 p1 = New P oi nt ( Panel1 . Panel1 . p2 ) l i s t a E t i q u e t a s X ( i − 1 ) . Width * 19 / (XMax * 2 0 ) + Panel1 . Height − Panel1 . Width / 1 0 0 . Count − 2 xNuevoPunto1 = l i s t a X A P i n t a r ( i ) * Panel1 . Panel1 . yNuevoPunto2 ) g r a f i c o . Text = ( CDbl (XMax * i / 5 ) ) . Add( l i s t a P u n t o s Y ( i ) ) End I f Next punta = New Pen ( C o l o r . Height / 20 + 3 ) p2 = New P oi nt ( Panel1 . 19 * Panel1 . Text = ( CDbl (YMax * i / 5 ) ) . Panel1 . DrawLine ( punta . Width * 19 / (XMax * 2 0 ) + Panel1 . Width / 20 + 19 * i * Panel1 . T o S t r i n g ( ”F0” ) l i s t a E t i q u e t a s Y ( i − 1 ) . Width / 2 0 . Height / 2 0 ) Try p1 = New P o in t ( xNuevoPunto1 . Width / 20 xNuevoPunto2 = l i s t a X A P i n t a r ( i + 1 ) * Panel1 . p2 ) p1 = New P o in t ( 0 . p1 . 19 * Panel1 . DrawLine ( punta . Width . Width / 20 + 3 .l i s t a Y A p i n t a r . Panel1 . p2 ) p1 = New P oi nt ( Panel1 . Height − Panel1 . Height / 20 − 19 * i * Panel1 . Height / 1 0 0 ) g r a f i c o . Height * 19 / (YMax * 2 0 ) + Panel1 . Black . DrawLine ( punta . Height * 19 / (YMax * 2 0 ) + Panel1 . Red . S e l e c t ( ) 206 . p1 . Width / 2 0 . p1 . p1 . Height / 20 − 19 * i * Panel1 . p2 ) Catch ex As E x c e p t i o n End Try Next veces = veces + 1 I f u l t i m o B i e n And hayQueAumetarPunto Then hayQueAumetarPunto = F a l s e xElegido = xElegido + 1 I f x E l e g i d o > 6 Then xElegido = 6 End I f I f x E l e g i d o = 1 Then RadioButton1 . DrawLine ( punta . Panel1 . Width / 1 0 0 . 3 ) Dim xNuevoPunto1 As Double Dim yNuevoPunto1 As Double Dim xNuevoPunto2 As Double Dim yNuevoPunto2 As Double For i = 0 To l i s t a X A P i n t a r . T o S t r i n g ( ”F2” ) Next punta = New Pen ( C o l o r .

C l i c k Dim p o s i c i o n X As I n t e g e r = ( ( 2 0 * ( ( M o u s e P o s i t i o n . C l i c k xElegido = 5 End Sub P r i v a t e Sub R a d i o B u t t o n 6 C l i c k ( ByVal s e n d e r As Object . C l i c k xElegido = 1 End Sub P r i v a t e Sub R a d i o B u t t o n 2 C l i c k ( ByVal s e n d e r As Object . Width ) ) Dim o t r a C o n d i c i o n As Boolean = x E l e g i d o > 5 I f Not o t r a C o n d i c i o n Then o t r a C o n d i c i o n = p o s i c i o n X < l i s t a P u n t o s X ( x E l e g i d o + 1 ) Or l i s t a P u n t o s X ( x E l e g i d o + 1 ) = −1 207 . S e l e c t ( ) End I f I f x E l e g i d o = 6 Then RadioButton6 . ByVal e As System .End I f I f x E l e g i d o = 2 Then RadioButton2 . C l i c k xElegido = 3 End Sub P r i v a t e Sub R a d i o B u t t o n 4 C l i c k ( ByVal s e n d e r As Object . ByVal e As System . EventArgs ) Handles RadioButton1 . EventArgs ) Handles RadioButton6 . EventArgs ) Handles RadioButton5 . EventArgs ) Handles RadioButton3 . S e l e c t ( ) End I f I f x E l e g i d o = 3 Then RadioButton3 . S e l e c t ( ) End I f End I f End Sub P r i v a t e Sub R a d i o B u t t o n 1 C l i c k ( ByVal s e n d e r As Object . C l i c k xElegido = 6 End Sub P r i v a t e Sub P a n e l 1 C l i c k ( ByVal s e n d e r As Object .X − Panel1 . ByVal e As System . S e l e c t ( ) End I f I f x E l e g i d o = 4 Then RadioButton4 . L o c a t i o n . S e l e c t ( ) End I f I f x E l e g i d o = 5 Then RadioButton5 .X − 4 − Panel1 . ByVal e As System . C l i c k xElegido = 4 End Sub P r i v a t e Sub R a d i o B u t t o n 5 C l i c k ( ByVal s e n d e r As Object . EventArgs ) Handles RadioButton4 . EventArgs ) Handles RadioButton2 . EventArgs ) Handles Panel1 . C l i c k xElegido = 2 End Sub P r i v a t e Sub R a d i o B u t t o n 3 C l i c k ( ByVal s e n d e r As Object . Width / 20 − Me .X) * XMax) ) / ( 1 9 * Panel1 . ByVal e As System . L o c a t i o n . ByVal e As System . ByVal e As System .

L o c a t i o n . Height / 2 0 ) ) * YMax) .Y − 2 3 ) .Y − 23 − Panel1 . Height / 20 − Me . EventArgs ) Handles BXM. ByVal e As System . ByVal e As System .Y − Panel1 . Text = ( p o s i c i o n X ) . T o S t r i n g ( ”F2” ) hayQueAumetarPunto = True pintarPanel () Else MsgBox ( ” El punto e l e g i d o no f u e c o r r e c t o . ” + ( M o u s e P o s i t i o n . T o S t r i n g + ” .Y − Me . 9 5 − ( ( M o u s e P o s i t i o n . EventArgs ) Handles BVI . C l i c k Dim i As I n t e g e r For i = 0 To 6 l i s t a P u n t o s X ( i ) = −1 l i s t a P u n t o s Y ( i ) = −1 pintarPanel () Next End Sub P r i v a t e Sub BXM Click ( ByVal s e n d e r As Object . L o c a t i o n . I n v a l i d a t e ( ) ultimoBien = False End I f End Sub P r i v a t e Sub BVI Click ( ByVal s e n d e r As Object .Y − Panel1 .End I f I f ( p o s i c i o n X > Panel1 . Width / 20 listaPuntosY (0) = v a l o r I n i c i a l xElegido = 0 hayQueAumetarPunto = True pintarPanel () End I f Catch ex As E x c e p t i o n End Try End Sub P r i v a t e Sub B R e i n i c i a r C l i c k ( ByVal s e n d e r As Object . L o c a t i o n . T o S t r i n g listaPuntosX ( xElegido ) = posicionX l i s t a P u n t o s Y ( x E l e g i d o ) = ( ( 0 .Y) ) / ( 1 9 * Panel1 . C l i c k Dim xM As I n t e g e r Try xM = CInt (TXM. Text ) I f ( v a l o r I n i c i a l < 0 ) Or ( v a l o r I n i c i a l > YMax) Then MsgBox ( ” El v a l o r i n i c i a l debe e s t a r e n t r e 0 y ” + YMax . Text ) I f xM <= 0 Then MsgBox ( ” El x m´ximo debe s e r un e n t e r o mayor a c e r o ” ) a Else 208 . ByVal e As System . C l i c k Try Dim v a l o r I n i c i a l As Double = CDbl ( TextBox1 . EventArgs ) Handles B R e i n i c i a r . Width / 2 0 ) And ( p o s i c i o n X > l i s t a P u n t o s X ( x E l e g i d o − 1 ) ) And ( ( l i s t a P u n t o s X ( x E l e g i d o − 1 ) ) >= 0 ) And o t r a C o n d i c i o n Then L ab el 1 . T o S t r i n g ) Else l i s t a P u n t o s X ( 0 ) = Panel1 . L o c a t i o n . v e r i f i q u e que su coordenada en x s e a mayor a l a d e l punto a n t e r i o r y menor a la del siguiente ”) Panel1 .

numeroUno . v a l o r I n i c i a l ) MsgBox ( mas2 . C l i c k Dim yM As Double Try yM = CDbl (TYM. EventArgs ) Handles Me . numeroDos . Enabled = True End I f End Sub P r i v a t e Sub C r e a r I n t e r p o l a n d o O t r a s D o s M ´ s c a r a s T o o l S t r i p M e n u I t e m C l i c k ( ByVal a s e n d e r As System . Object . EventArgs ) Handles Me . Enabled = True End I f End Sub P r i v a t e Sub c r e a r M a s c a r a D i s p o s e d ( ByVal s e n d e r As Object . ByVal e As System . r e s p u e s t a = True Then Dim mas1 As mascara Dim mas2 As mascara Dim m a s c a r a F i n a l As mascara Try mas1 = a b r i r M a s c a r a ( pideN . mas2 . ByVal e As System . ShowDialog ( ) I f pideN . r u t a 1 ) mas2 = a b r i r M a s c a r a ( pideN . pideN . miVentanaPadre . ByVal e As System . v a l o r I n i c i a l ) m a s c a r a F i n a l = New mascara ( mas1 . D e a c t i v a t e I f tengoPadre Then Me . Text ) I f yM <= 0 Then MsgBox ( ” El y m´ximo debe s e r mayor a c e r o ” ) a Else YMax = yM pintarPanel () End I f Catch ex As E x c e p t i o n End Try End Sub P r i v a t e Sub c r e a r M a s c a r a D e a c t i v a t e ( ByVal s e n d e r As Object . pideN . D i s p o s e d I f tengoPadre Then Me . ByVal e As System . Click a Dim pideN As New p i d e E n t e r o s (Me) pideN . ” s i n ” ) armarTablas ( m a s c a r a F i n a l ) Catch ex As E x c e p t i o n MsgBox ( ”ERROR AL INTERPOLAR” ) 209 . miVentanaPadre . r u t a 2 ) MsgBox ( mas1 .XMax = xM pintarPanel () End I f Catch ex As E x c e p t i o n End Try End Sub P r i v a t e Sub BYM Click ( ByVal s e n d e r As Object . EventArgs ) Handles BYM. EventArgs ) Handles CrearInterpolandoOtrasDosM´scarasToolStripMenuItem .

BMP. ByVal e As System . Length > 0 Then Try Panel1 .End Try End I f End Sub P r i v a t e Sub CrearExtrapolandoOtrasDosM´ scarasV2ToolStripMenuItem Click ( ByVal a s e n d e r As System . Object . EventArgs ) Handles 210 . FromFile ( vent . pideN . pideN . ShowDialog ( ) I f pideN . True ) vent .* ” vent . r u t a 2 ) m a s c a r a F i n a l = New mascara ( mas1 . Object . ByVal e As System . numeroUno . GIF | A l l f i l e s a (*. ” s i n ” . * . C l i c k a Dim pideN As New p i d e E n t e r o s (Me) pideN . EventArgs ) Handles MultiplicarElEjeXPorUnaConstanteToolStripMenuItem . BackgroundImage = Image .*) |*. GIF ) | * . r e s p u e s t a = True Then Dim mas1 As mascara Dim mas2 As mascara Dim m a s c a r a F i n a l As mascara Try mas1 = a b r i r M a s c a r a ( pideN . F a l s e ) armarTablas ( m a s c a r a F i n a l ) Catch ex As E x c e p t i o n MsgBox ( ”ERROR AL INTERPOLAR” ) End Try End I f End Sub P r i v a t e Sub CambiarIm´ genDeFondoToolStripMenuItem Click ( ByVal s e n d e r a As System . T i t l e = ” S e l e c c i o n e l a im´ gen que d e s e a poner de fondo en e l a panel ” vent . Object . mas2 . BackgroundImageLayout = ImageLayout .BMP. C l i c k a Dim vent As New O p e n F i l e D i a l o g vent . EventArgs ) Handles CambiarIm´ genDeFondoToolStripMenuItem . S t r e t c h Catch ex As E x c e p t i o n End Try End I f End Sub P r i v a t e Sub M u l t i p l i c a r E l E j e X P o r U n a C o n s t a n t e T o o l S t r i p M e n u I t e m C l i c k ( ByVal s e n d e r As System . * . F i l t e r = ” a r c h i v o s de im´ genes ( * . JPG . EventArgs ) Handles CrearExtrapolandoOtrasDosM´ scarasV2ToolStripMenuItem . M u l t i s e l e c t = True vent . C l i c k Dim vent As New pideUnDouble (Me. ByVal e As System . ShowDialog ( ) I f vent . JPG . * . * . Object . FileNames . FileName ) Panel1 . ShowDialog ( ) End Sub P r i v a t e Sub M u l t i p l i c a r E l E j e Y P o r U n a C o n s t a n t e T o o l S t r i p M e n u I t e m C l i c k ( ByVal s e n d e r As System . ByVal e As System . r u t a 1 ) mas2 = a b r i r M a s c a r a ( pideN . numeroDos .

ByVal tablaY ( ) As I n t e g e r . Height BA pl ica r . C l i c k I f yaGuardo Then guardarComo ( ultimaRuta ) Else guardarAntesRuta ( ) End I f End Sub #End Region #Region ” c o n s t r u c t o r e s ” P u b l i c Sub New ( ) InitializeComponent () Dim i As I n t e g e r For i = 0 To 6 l i s t a P u n t o s X ( i ) = −1 l i s t a P u n t o s Y ( i ) = −1 Next Me . YMax = 1 Me . C l i c k Dim vent As New pideUnDouble (Me. XMax = l i s t a P u n t o s X ( 6 ) Me . V i s i b l e = F a l s e Try Dim r u t a I c o n o As S t r i n g = Path . r u t a A c t u a l = ” ” Me . GetDirectoryName ( A p p l i c a t i o n . y a E l i g i o R u t a = F a l s e Me . F a l s e ) vent . i c o ” Dim i c o n o As New I c o n ( r u t a I c o n o ) Me . nombre = ” ” a n c h o P a n e l O r i g i n a l = Panel1 . Width l a r g o P a n e l O r i g i n a l = Panel1 . ByVal nom As S t r i n g ) InitializeComponent () Dim i As I n t e g e r Dim maximoY As Double = 0 For i = 0 To 6 l i s t a P u n t o s X ( i ) = tablaX ( i ) l i s t a P u n t o s Y ( i ) = tablaY ( i ) I f tablaY ( i ) > maximoY Then maximoY = tablaY ( i ) End I f Next Me .MultiplicarElEjeYPorUnaConstanteToolStripMenuItem . YMax = maximoY 211 . Object . ShowDialog ( ) End Sub P r i v a t e Sub GuardarToolStripMenuItem Click ( ByVal s e n d e r As System . ByVal r u t a As S t r i n g . XMax = 60000 Me . ExecutablePath ) + ”\ nota musical . I c o n = i c o n o Catch ex As E x c e p t i o n End Try End Sub P u b l i c Sub New( ByVal tablaX ( ) As I n t e g e r . ByVal e As System . EventArgs ) Handles GuardarToolStripMenuItem .

miVentanaPadre = vent Me . miInstrumento . r u t a A c t u a l = ” ” Me .Me . nombre = ” ” a n c h o P a n e l O r i g i n a l = Panel1 . I c o n = i c o n o Catch ex As E x c e p t i o n End Try End Sub P u b l i c Sub New( ByVal vent As c r e a r I n s t r u m e n t o . miVentanaPadre . ByVal numeroNo As I n t e g e r . GetDirectoryName ( A p p l i c a t i o n . n o t a s ( numeroNo ) . TNombre . r u t a A c t u a l = r u t a Me . Enabled = F a l s e numeroNota = numeroNo numeroMascara = numeroMas 212 . nombre = nom Me . Width l a r g o P a n e l O r i g i n a l = Panel1 . ByVal c i e r r o E n s e g u i d a As Boolean . r u t a A c t u a l = ” ” Me . y a E l i g i o R u t a = True yaGuardo = True ultimaRuta = r u t a Me . Enabled = F a l s e numeroNota = numeroNo numeroMascara = numeroMas armarTablas (Me . miInstrumento . Text = nom a n c h o P a n e l O r i g i n a l = Panel1 . y a E l i g i o R u t a = F a l s e Me . Width l a r g o P a n e l O r i g i n a l = Panel1 . nombre = ” ” a n c h o P a n e l O r i g i n a l = Panel1 . l i s t a M a s c a r a s ( numero listaParaBorrar = Me . Height BA pl ica r . ExecutablePath ) + ”\ nota musical . ByVal numeroMas As I n t e g e r ) InitializeComponent () Me . miVentanaPadre . ExecutablePath ) + ”\ nota musical . n o t a s ( numeroNo ) . I c o n = i c o n o Catch ex As E x c e p t i o n End Try End Sub P u b l i c Sub New( ByVal vent As c r e a r I n s t r u m e n t o . miVentanaPadre . miVentanaPadre . ByVal numeroMas As I n t e g e r . Height Me . y a E l i g i o R u t a = F a l s e Me . Height Me . i c o ” Dim i c o n o As New I c o n ( r u t a I c o n o ) Me . V i s i b l e = F a l s e Try Dim r u t a I c o n o As S t r i n g = Path . ByVal t e n g o As Boolean ) InitializeComponent () Me . Width l a r g o P a n e l O r i g i n a l = Panel1 . GetDirectoryName ( A p p l i c a t i o n . l i s t a M a s c a r a s ( numeroMas ) . i n c r tengoPadre = True Try Dim r u t a I c o n o As S t r i n g = Path . miVentanaPadre = vent Me . ByVal numeroNo As I n t e g e r . i c o ” Dim i c o n o As New I c o n ( r u t a I c o n o ) Me .

l i s t a M a s c a r a s ( numero tengoPadre = t e n g o aplicarCambios ( False ) Me . miVentanaPadre .vb 213 . D i s p o s e ( ) End Sub #End Region End C l a s s programaVisual/apli/WindowsApplication1/crearMascara. n o t a s ( numeroNo ) .armarTablas (Me . miInstrumento .

vb’ Module i n i c i o P u b l i c Sub main ( ) ’Dim vent As v e n t a n a P r i n c i p a l = New v e n t a n a P r i n c i p a l Dim vent As v e n t a n a I n i c i a l = New v e n t a n a I n i c i a l vent .Clase ’inicio. ShowDialog ( ) End Sub End Module programaVisual/apli/WindowsApplication1/inicio.vb 214 .

Computer . Log ( 2 ) * i / 1 2 ) n o t a s .Clase ’instrumento. nombre End Get S e t ( ByVal v a l u e As S t r i n g ) Me . n o t a s End Get S e t ( ByVal v a l u e As L i s t ( Of nota ) ) Me . f o t o End Get S e t ( ByVal v a l u e As Image ) Me . ” f o t o As Image n o t a s As L i s t ( Of nota ) nombre As S t r i n g 215 . nombre = v a l u e End S e t End P r o p e r t y #End Region #Region ” c o n s t r u c t o r e s ” P u b l i c Sub New ( ) Me . ReadAllText ( r u t a ) Dim s e p a r a d o r As Char = ” . nombre = ” S i n nombre a s i g n a d o ” End Sub P u b l i c Sub New( ByVal r u t a As S t r i n g . n o t a s = v a l u e End S e t End P r o p e r t y P u b l i c P r o p e r t y nombre ( ) As S t r i n g Get Return Me .vb’ < S e r i a l i z a b l e ( )> P u b l i c C l a s s i n s t r u m e n t o #Region ” a t r i b u t o s ” Private Private Private #End Region #Region ” p r o p i e d a d e s ” P u b l i c P r o p e r t y f o t o ( ) As Image Get Return Me . f o t o = v a l u e End S e t End P r o p e r t y P u b l i c P r o p e r t y n o t a s ( ) As L i s t ( Of nota ) Get Return Me . F i l e S y s t e m . f o t o = c r e a r I m a g e n V a c i a ( ) n o t a s = New L i s t ( Of nota ) Dim i As I n t e g e r For i = 0 To 85 Dim f r e As Double = 27 * Math . ByVal l a r g o T a b l a S e n o s As I n t e g e r . ByVal FsPic As I n t e g e r ) n o t a s = New L i s t ( Of nota ) Dim t e x t o T o t a l As S t r i n g = My. Add(New nota ( f r e ) ) Next Me . Exp ( Math .

frec (2) ) ) Next End Sub #End Region #Region ” m´ todos ” e P r i v a t e Function c r e a r I m a g e n V a c i a ( ) As Image Dim pan As New Panel pan . listaIncrementos . f o t o = c r e a r I m a g e n V a c i a ( ) Me . ByVal volumen As I n t e g e r ) As S t r i n g Dim p a r a D e v o l v e r As S t r i n g = ” ” Dim i As I n t e g e r Dim j As I n t e g e r Dim k As I n t e g e r 216 . n o t a s . DrawToBitmap ( paraDevolver . 1 ) ) Return p a r a D e v o l v e r End Function P u b l i c Function e x p o r t a r ( ByVal l a r g o T a b l a S e n o s As I n t e g e r . 0 . ToString . Add(New mascara ( ” s i n nombre” . New R e c t a n g l e ( 0 . nombre = ” S i n nombre a s i g n a d o ” Dim l i s t a M a s c a r a s As New L i s t ( Of mascara ) Dim l i s t a C a m b i o s As L i s t ( Of I n t e g e r ) Dim l i s t a I n c r e m e n t o s As L i s t ( Of Double ) Dim f r e c As L i s t ( Of Double ) Dim l i s t a V a l o r e s I n i c i a l e s ( 1 4 ) As Double Dim v a l o r I n i c i a l As Double Dim l i s t a C o e f i c i e n t e s As New L i s t ( Of Double ) For i = 0 To 14 l i s t a C o e f i c i e n t e s . s e p a r a d o r ) Dim i As I n t e g e r Dim j As I n t e g e r Dim k As I n t e g e r Me . l ist aC oef ici en tes . ByVal FsPic As I n t e g e r . L i g h t Y e l l o w Dim p a r a D e v o l v e r As New Bitmap ( 1 . Add ( ( CDbl ( s e p a r a d o ( 1 0 5 * i + 7 * j + k + 11610) ) / 65536) ) Next l i s t a M a s c a r a s . BackColor = C o l o r .Dim s e p a r a d o ( ) As S t r i n g = S p l i t ( t e x t o T o t a l . listaMascaras . Add( CInt ( CDbl ( s e p a r a d o ( 1 0 5 * i + 7 * j + k + 2580) ) ) ) l i s t a I n c r e m e n t o s . Add ( ( FsPic * ( CDbl ( s e p a r a d o ( 1 5 * i + j ) ) ) / ( largoTablaSenos ) ) ) l i s t a V a l o r e s I n i c i a l e s ( j ) = CInt ( CDbl ( s e p a r a d o ( 1 5 * i + j + 1290) ) / 65536) v a l o r I n i c i a l = CDbl ( ( s e p a r a d o ( 1 5 * i + j + 1 2 9 0 ) ) / 6 5 5 3 6 ) l i s t a C a m b i o s = New L i s t ( Of I n t e g e r ) l i s t a I n c r e m e n t o s = New L i s t ( Of Double ) For k = 0 To 6 l i s t a C a m b i o s . 1 . v a l o r I n i c i a l ) ) Next Me . 1 ) pan . f r e c . Add ( 1 ) Next For i = 0 To 85 f r e c = New L i s t ( Of Double ) For j = 0 To 14 f r e c . listaCambios . Add(New nota ( ” s i n nombre ” + i .

i n c r e m e n t o s ( k ) * volumen * Me . n o t a s ( i ) . n o t a s ( i ) . T o S t r i n g + ” . n o t a s ( i ) . ” Next Next Next For i = 0 To 85 For j = 0 To 14 For k = 0 To 6 aux = CInt ( 1 3 4 2 1 7 7 2 8 * Me . n o t a s ( i ) . cambios ( k ) ) p a r a D e v o l v e r = p a r a D e v o l v e r + aux . ” Next Next For i = 0 To 85 For j = 0 To 14 aux = CInt ( 1 3 4 2 1 7 7 2 8 * volumen * Me . l i s t a C o e f i c i e n t e s ( j ) ) I f i = 85 And j = 14 And k = 6 Then p a r a D e v o l v e r = p a r a D e v o l v e r + aux .vb 217 . v a l o r I n i c i a l * Me . ” Next Next For i = 0 To 85 For j = 0 To 14 For k = 0 To 6 aux = CInt (Me . T o S t r i n g + ” . T o S t r i n g + ” . l i s t a M a s c a r a s ( j ) . l i s t a F r e c u e n c i a s ( j ) * l a r g o T a b l a S e n o s / FsPic ) p a r a D e v o l v e r = p a r a D e v o l v e r + aux . T o S t r i n g + ” . l i s t a C o e f i c i e n t e s ( j ) ) p a r a D e v o l v e r = p a r a D e v o l v e r + aux . T o S t r i n g Else p a r a D e v o l v e r = p a r a D e v o l v e r + aux . n o t a s ( i ) . l i s t a M a s c a r a s ( j ) . n o t a s ( i ) . ” End I f Next Next Next Return p a r a D e v o l v e r End Function #End Region End C l a s s programaVisual/apli/WindowsApplication1/instrumento.Dim aux As I n t 6 4 For i = 0 To 85 For j = 0 To 14 aux = CInt (Me . l i s t a M a s c a r a s ( j ) .

i n c r e m e n t o s = v a l u e End S e t End P r o p e r t y P u b l i c P r o p e r t y cambios ( ) As L i s t ( Of I n t e g e r ) Get Return Me . c a m b i o s = v a l u e End S e t End P r o p e r t y P u b l i c P r o p e r t y v a l o r I n i c i a l ( ) As Double Get Return Me . i n c r e m e n t o s End Get S e t ( ByVal v a l u e As L i s t ( Of Double ) ) Me . nombre End Get S e t ( ByVal v a l u e As S t r i n g ) Me .vb’ < S e r i a l i z a b l e ( )> P u b l i c C l a s s mascara #Region ” a t r i b u t o s ” Private Private Private Private Private #End Region #Region ” p r o p i e d a d e s ” P u b l i c P r o p e r t y i n c r e m e n t o s ( ) As L i s t ( Of Double ) Get Return Me .Clase ’mascara. v a l o r I n i c i a l End Get S e t ( ByVal v a l u e As Double ) Me . nombre = v a l u e End S e t End P r o p e r t y P u b l i c P r o p e r t y f o t o ( ) As Image Get Return Me . v a l o r I n i c i a l = v a l u e End S e t End P r o p e r t y P u b l i c P r o p e r t y nombre ( ) As S t r i n g Get Return Me . f o t o End Get S e t ( ByVal v a l u e As Image ) Me . f o t o = v a l u e i n c r e m e n t o s As L i s t ( Of Double ) c a m b i o s As L i s t ( Of I n t e g e r ) v a l o r I n i c i a l As Double nombre As S t r i n g f o t o As Image 218 . c a m b i o s End Get S e t ( ByVal v a l u e As L i s t ( Of I n t e g e r ) ) Me .

Add( 5 0 0 * i + 5 0 0 ) i n c r e m e n t o s . Add( ( − 0 . Add ( 6 5 5 3 5 ) i n c r e m e n t o s . Add ( ( i − 6 ) / 1 4 5 0 0 0 ) Else cambios . Count − 1 Me . i n c r e m e n t o s = New L i s t ( Of Double ) Me . nombre = nom Me . cambios . i n c r e m e n t o s = New L i s t ( Of Double ) Me . v a l o r I n i c i a l Me . i n c r e m e n t o s . 2 ) / ( 6 5 5 3 5 0 − 10 * cambios ( 5 ) ) ) End I f Next End Sub P u b l i c Sub New( ByVal mas As mascara ) Dim i As I n t e g e r Me .End S e t End P r o p e r t y #End Region #Region ” c o n s t r u c t o r e s ” P u b l i c Sub New( ByVal nom As S t r i n g ) Me . Count − 1 Me . Add ( ( i − 6 ) / 1 2 0 0 0 0 ) Else cambios . v a l o r I n i c i a l = 1 Me . cambios = New L i s t ( Of I n t e g e r ) Me . nombre = mas . Add( mas . f o t o = c r e a r I m a g e n V a c i a ( ) Dim i As I n t e g e r For i = 0 To 6 I f i <= 5 Then cambios . Add( 5 0 0 * i + 5 0 0 ) i n c r e m e n t o s . i n c r e m e n t o s . f o t o = c r e a r I m a g e n V a c i a ( ) End Sub P u b l i c Sub New ( ) Me . Add( ( − 0 . f o t o = c r e a r I m a g e n V a c i a ( ) Dim i As I n t e g e r For i = 0 To 6 I f i <= 5 Then cambios . cambios = New L i s t ( Of I n t e g e r ) For i = 0 To mas . cambios = New L i s t ( Of I n t e g e r ) Me . nombre Me . v a l o r I n i c i a l = 1 Me . v a l o r I n i c i a l = mas . i n c r e m e n t o s ( i ) ) Next For i = 0 To mas . nombre = ” S i n nombre a s i g n a d o ” Me . cambios . cambios ( i ) ) Next Me . Add( mas . 1 3 ) / ( 6 5 5 3 5 0 − 10 * cambios ( 5 ) ) ) End I f Next End Sub 219 . Add ( 6 5 5 3 5 ) i n c r e m e n t o s . i n c r e m e n t o s = New L i s t ( Of Double ) Me .

v a l o r I n i c i a l puntosY2 ( 0 ) = mas2 . Remove ( 0 ) End Sub P u b l i c Sub New( ByVal mas1 As mascara . nombre = nom Me . v a l o r I n i c i a l = v i Me . ByVal f o t As Image ) Me . i n c r e m e n t o s ( 0 ) 220 . Count − 2 ) ) ) Me . f o t o = c r e a r I m a g e n V a c i a ( ) Dim i As I n t e g e r Dim puntosY1 ( 7 ) As Double Dim puntosY2 ( 7 ) As Double puntosY1 ( 0 ) = mas1 . cambios = New L i s t ( Of I n t e g e r ) Me . v a l o r I n i c i a l = l i s t a Y ( 0 ) cambios = New L i s t ( Of I n t e g e r ) Dim i As I n t e g e r cambios . Add ( 0 ) For i = 1 To l i s t a X . cambios ( 0 ) * mas1 . c o p i a L i s t a E n t e r o s ( l i s t a C a m b i o s ) Me . ByVal pon2 As Double . v a l o r I n i c i a l puntosY1 ( 1 ) = mas1 . Add ( 6 5 5 3 5 ) i n c r e m e n t o s = New L i s t ( Of Double ) For i = 1 To cambios .P u b l i c Sub New( ByVal nom As S t r i n g . Length − 1 ) ) / ( 6 5 5 3 5 0 − 10 * cambios ( cambios . Add ( 6 5 5 3 5 ) Else cambios . ByVal mas2 As mascara . c o p i a L i s t a D o u b l e ( l i s t a I n c r e m e n t o s ) Me . ByVal v i As Integer ) Me . ByVal l i s t a Y ( ) As Double . ByVal nom As S t r i n g ) Me . Length − 1 I f l i s t a X ( i ) = −1 Then cambios . cambios ( 0 ) * mas2 . i n c r e m e n t o s ( 0 ) puntosY2 ( 1 ) = mas2 . Add( CInt ( l i s t a X ( i ) / 1 0 ) ) End I f Next cambios . i n c r e m e n t o s = metodosComunes . v a l o r I n i c i a l + 10 * mas1 . nombre = nom Me . cambios = metodosComunes . Add ( ( 0 − l i s t a Y ( l i s t a Y . ByVal nom As S t r i n g . v a l o r I n i c i a l + 10 * mas2 . nombre = nom Me . f o t o = f o t cambios . Add ( 0 ) End Try Next i n c r e m e n t o s . Add ( ( l i s t a Y ( i ) − l i s t a Y ( i − 1 ) ) / ( 1 0 * ( cambios ( i ) − cambios ( i − 1 ) ) ) ) Catch ex As E x c e p t i o n i n c r e m e n t o s . ByVal l i s t a I n c r e m e n t o s As L i s t ( Of Double ) . Count − 2 I f l i s t a Y ( i ) = −1 Then l i s t a Y ( i ) = l i s t a Y ( i − 1) End I f Try i n c r e m e n t o s . i n c r e m e n t o s = New L i s t ( Of Double ) Me . ByVal l i s t a C a m b i o s As L i s t ( Of I n t e g e r ) . f o t o = c r e a r I m a g e n V a c i a ( ) End Sub P u b l i c Sub New( ByVal l i s t a X ( ) As I n t e g e r . ByVal pon1 As Double .

Count − 2 While listaCambiosAux1 ( i n d i c e 1 ) < Me . Add(Me . cambios ( i ) ) E l s e I f mas2 . Add ( 0 ) listaCambiosAux2 . cambios ( i + 1 ) − listaCambiosAux1 ( i n d i c e 1 ) ) ) + pon2 * ( puntosY2 ( i n d i c e 2 ) + mas2 . i n c r e m e n t o s ( i + 1 ) + 1) + 1 ) + ( 1 0 * ( mas2 . Add( mas1 . cambios ( i * mas1 . cambios . cambios . Add ( ( pon1 * ( puntosY1 ( i n d i c e 1 ) + mas1 . Add( mas2 . Add ( ( aux ( i + 1 ) − aux ( i ) ) / ( 1 0 * (Me . Count − 2 I f mas1 . cambios ( i + 1 ) − listaCambiosAux2 ( i n d i c e 2 ) ) ) ) / ( pon1 + pon2 ) ) Me . cambios . cambios ( i ) ) ) Catch ex As E x c e p t i o n puntosY1 ( i + 2 ) = puntosY1 ( i End Try Try puntosY2 ( i + 2 ) = puntosY2 ( i + 1 ) − mas2 . i n c r e m e n t o s ( i n d i c e 2 ) * 10 * (Me . cambios ( i ) = 65535 Then Me . v a l o r I n i c i a l = ( pon1 * puntosY1 ( 0 ) + pon2 * puntosY2 ( 0 ) ) / ( pon1 + pon2 ) Me . cambios ( i ) = 65535 Then Me . cambios ( i ) ) Else Me . cambios ( i + 1 ) indice1 = indice1 + 1 End While While listaCambiosAux2 ( i n d i c e 2 ) < Me . i n c r e m e n t o s ( i + 1 ) + 1) Next Me . cambios ( i ) ) / ( pon1 + pon2 ) ) End I f Try puntosY1 ( i + 2 ) = puntosY1 ( i + 1 ) − mas1 . cambios . Add ( 1 ) For i = 0 To mas1 . cambios ( i + 1 ) − Me . i n c r e m e n t o s . cambios . cambios . cambios ( i ) ) listaCambiosAux2 . cambios ( i ) ) ) ) Next 221 . Add( mas2 . i n c r e m e n t o s ( i n d i c e 1 ) * 10 * (Me . v a l o r I n i c i a l ) For i = 0 To Me .Dim i n d i c e 1 As I n t e g e r = 0 Dim i n d i c e 2 As I n t e g e r = 0 Dim aux As New L i s t ( Of Double ) Me . Add ( 0 ) For i = 0 To mas1 . cambios . Add( mas1 . cambios . cambios ( i * mas2 . Add ( 6 5 5 3 5 ) Dim listaCambiosAux1 As New L i s t ( Of I n t e g e r ) Dim listaCambiosAux2 As New L i s t ( Of I n t e g e r ) listaCambiosAux1 . cambios ( i + 1 ) indice2 = indice2 + 1 End While indice2 = indice2 − 1 indice1 = indice1 − 1 aux . cambios ( i ) ) ) Catch ex As E x c e p t i o n puntosY2 ( i + 2 ) = puntosY2 ( i End Try + 1 ) + ( 1 0 * ( mas1 . Count − 1 listaCambiosAux1 . Add ( ( pon1 * mas1 . cambios ( i ) ) Next indice1 = 0 indice2 = 0 aux . cambios ( i ) + pon2 * mas2 .

Remove ( 1 ) Dim p a r a B o r r a r As I n t e g e r = 2 I f pon1 = 1 Then paraBorrar = 3 End I f End Sub P u b l i c Sub New( ByVal mas1 As mascara . f o t o = c r e a r I m a g e n V a c i a ( ) Me . Add ( 0 ) l i s t a C a m b i o s 2 . Add ( 0 ) Me . nombre = nom Me . Add( mas1 .vb 222 . cambios . v a l o r I n i c i a l ) / ( pon1 + pon2 ) Dim l i s t a C a m b i o s 1 As New L i s t ( Of I n t e g e r ) Dim l i s t a C a m b i o s 2 As New L i s t ( Of I n t e g e r ) Dim aux1 As Double Dim aux2 As Double l i s t a C a m b i o s 1 . Count − 2 aux1 = ( l i s t a C a m b i o s 1 ( i + 1 ) − l i s t a C a m b i o s 1 ( i ) ) * mas1 . cambios . cambios = New L i s t ( Of I n t e g e r ) Me . cambios . i n c r e m e n t o s ( i ) aux2 = ( l i s t a C a m b i o s 2 ( i + 1 ) − l i s t a C a m b i o s 2 ( i ) ) * mas2 . ByVal mas2 As mascara .Me . cambios ( i ) ) Me . v a l o r I n i c i a l = ( pon1 * mas1 . ByVal pon1 As Double . cambios . i n c r e m e n t o s . i n c r e m e n t o s ( i ) Me . 1 ) Return p a r a D e v o l v e r End Function #End Region End C l a s s programaVisual/apli/WindowsApplication1/mascara. Remove ( 0 ) End Sub #End Region #Region ” m´ todos ” e P r i v a t e Function c r e a r I m a g e n V a c i a ( ) As Image Dim p a r a D e v o l v e r As New Bitmap ( 1 . cambios ( i ) ) / ( pon1 + pon2 ) ) Next For i = 0 To l i s t a C a m b i o s 1 . Add ( ( pon1 * mas1 . ByVal nom As S t r i n g . Count − 1 l i s t a C a m b i o s 1 . i n c r e m e n t o s = New L i s t ( Of Double ) Me . ByVal noPromedio As Boolean ) Me . v a l o r I n i c i a l + pon2 * mas2 . Add ( 0 ) Dim i As I n t e g e r For i = 0 To mas1 . Add( mas2 . cambios ( i ) ) l i s t a C a m b i o s 2 . Add ( ( pon1 * aux1 + pon2 * aux2 ) / ( ( pon1 + pon2 ) * ( l i s t a C a m b i o s 1 ( i + 1 ) + l i s t a C a m b i o s 2 ( i + 1 ) − listaCambios1 ( i ) − listaCambios2 ( i ) ) ) ) Next Me . ByVal pon2 As Double . cambios ( i ) + pon2 * mas2 . cambios .

Write ( System . True ) For i = 0 To v a l o r e s . 0 . GetBytes ( v a l o r e s ( i ) ) . IO . 0 . MemoryStream ( l i s t a B y t e s . B i t C o n v e r t e r . Write ( enc . GetBytes ( tamanio ) . 0 . Length ) Dim ms2 As New System .vb’ P u b l i c C l a s s metodosComunes P u b l i c Shared Function grabarWav ( ByVal v a l o r e s As L i s t ( Of I n t e g e r ) . Add(num) Next Return p a r a D e v o l v e r End Function P u b l i c Shared Function c o p i a L i s t a M a s c a r a s ( ByVal l i s t a As L i s t ( Of mascara ) ) As L i s t ( Of mascara ) Dim p a r a D e v o l v e r As New L i s t ( Of mascara ) For Each mas As mascara In l i s t a p a r a D e v o l v e r . Write ( l i s t a B y t e s . Write ( System . Add( mas ) 223 . 4 ) ms . 2 ) ms . B i t C o n v e r t e r . GetBytes ( 1 ) . B i t C o n v e r t e r . B i t C o n v e r t e r . Count − 1 ms2 . 0 . Write ( System . Write ( System . ByVal r u t a As S t r i n g ) As Boolean Try Dim h e a d e r ( 4 3 ) As Byte Dim ms As New System . B i t C o n v e r t e r . GetBytes ( 1 ) . 4 ) ms . l i s t a B y t e s . B i t C o n v e r t e r . Close () Return True Catch ex As E x c e p t i o n Return F a l s e End Try End Function P u b l i c Shared Function c o p i a L i s t a D o u b l e ( ByVal l i s t a As L i s t ( Of Double ) ) As L i s t ( Of Double ) Dim p a r a D e v o l v e r As New L i s t ( Of Double ) For Each num As Double In l i s t a p a r a D e v o l v e r . GetBytes ( ”WAVE” ) . GetBytes ( 2 ) . 0 . UTF8Encoding Dim i As I n t e g e r Dim tamanio As I n t e g e r = v a l o r e s . 4 ) Dim o F i l e S t r e a m As System . Write ( System . Write ( System . 4 ) ms . MemoryStream ( header . Write ( System . 4 ) ms . Write ( header . 0 . F i l e S t r e a m ( ruta . IO . B i t C o n v e r t e r . GetBytes ( tamanio ) . 2 ) ms . 0 . 0 . B i t C o n v e r t e r . 0 . 2 ) ms . Write ( enc . 0 . 4 ) ms . 4 4 . F i l e S t r e a m o F i l e S t r e a m = New System . GetBytes ( 3 0 0 0 0 ) . Write ( System . 0 . GetBytes ( tamanio + 3 6 ) . 2 ) ms .Clase ’metodosComunes. Length ) oFileStream . GetBytes ( 1 6 ) . GetBytes ( ” fmt ” ) . Write ( System . 0 . 4 ) ms . 2 ) Next o F i l e S t r e a m . GetBytes ( ” data ” ) . 0 . B i t C o n v e r t e r . 0 . 4 ) ms . System . C r e a t e ) o F i l e S t r e a m . Count ) As Byte ms . Text . True ) Dim enc As New System . 0 . tamanio . 0 . IO . Write ( System . FileMode . Count * 2 Dim l i s t a B y t e s ( 2 * v a l o r e s . Write ( enc . B i t C o n v e r t e r . 0 . GetBytes ( ”RIFF” ) . IO . 4 ) ms . IO . Write ( enc . GetBytes ( 1 6 ) . 0 . h e a d e r .

vb 224 .Next Return p a r a D e v o l v e r End Function P u b l i c Shared Function c o p i a L i s t a E n t e r o s ( ByVal l i s t a As L i s t ( Of I n t e g e r ) ) As L i s t ( Of I n t e g e r ) Dim p a r a D e v o l v e r As New L i s t ( Of I n t e g e r ) For Each num As I n t e g e r In l i s t a p a r a D e v o l v e r . Add(num) Next Return p a r a D e v o l v e r End Function End C l a s s programaVisual/apli/WindowsApplication1/metodosComunes.

l i s t a M a s c a r a s End Get S e t ( ByVal v a l u e As L i s t ( Of mascara ) ) Me .vb’ < S e r i a l i z a b l e ( )> P u b l i c C l a s s nota #Region ” a t r i b u t o s ” Private Private Private Private Private #End Region #Region ” m o d i f i c a d o r e s ” P u b l i c P r o p e r t y l i s t a C o e f i c i e n t e s ( ) As L i s t ( Of Double ) Get Return Me . l i s t a C o e f i c i e n t e s = v a l u e End S e t End P r o p e r t y P u b l i c P r o p e r t y nombre ( ) As S t r i n g Get Return Me . l i s t a F r e c u e n c i a s End Get S e t ( ByVal v a l u e As L i s t ( Of Double ) ) Me . nombre = v a l u e End S e t End P r o p e r t y P u b l i c P r o p e r t y l i s t a F r e c u e n c i a s ( ) As L i s t ( Of Double ) Get Return Me . l i s t a F r e c u e n c i a s = v a l u e End S e t End P r o p e r t y P u b l i c P r o p e r t y l i s t a M a s c a r a s ( ) As L i s t ( Of mascara ) Get Return Me . nombre End Get S e t ( ByVal v a l u e As S t r i n g ) Me . f r e c u e n c i a P r i n c i p a l = v a l u e nombre As S t r i n g l i s t a F r e c u e n c i a s As L i s t ( Of Double ) l i s t a M a s c a r a s As L i s t ( Of mascara ) f r e c u e n c i a P r i n c i p a l As Double l i s t a C o e f i c i e n t e s As L i s t ( Of Double ) 225 . f r e c u e n c i a P r i n c i p a l End Get S e t ( ByVal v a l u e As Double ) Me . l i s t a M a s c a r a s = v a l u e End S e t End P r o p e r t y P u b l i c P r o p e r t y f r e c u e n c i a P r i n c i p a l ( ) As Double Get Return Me . l i s t a C o e f i c i e n t e s End Get S e t ( ByVal v a l u e As L i s t ( Of Double ) ) Me .Clase ’nota.

c o p i a L i s t a D o u b l e ( l i s t a C o e f ) End Sub P u b l i c Sub New ( ) Me . ByVal FsPic As I n t e g e r ) As L i s t ( Of I n t e g e r ) Dim l i s t a V a l o r e s As New L i s t ( Of Double ) Dim p a r a D e v o l v e r As New L i s t ( Of I n t e g e r ) Dim i n d i c e As I n t e g e r = 0 226 .End S e t End P r o p e r t y #End Region #Region ” c o n s t r u c t o r e s ” P u b l i c Sub New( ByVal nom As S t r i n g . Add ( 1 4 5 0 0 ) Else l i s t a F r e c u e n c i a s . ByVal l i s t a C o e f As L i s t ( Of Double ) . c o p i a L i s t a M a s c a r a s ( l i s t a M a s c ) Me . l i s t a F r e c u e n c i a s = metodosComunes . l i s t a M a s c a r a s = metodosComunes . nombre = ” S i n nombre a s i g n a d o ” l i s t a F r e c u e n c i a s = New L i s t ( Of Double ) l i s t a M a s c a r a s = New L i s t ( Of mascara ) l i s t a C o e f i c i e n t e s = New L i s t ( Of Double ) Dim i As I n t e g e r For i = 0 To 14 I f f r e c P r i n * ( i + 1 ) / 3 > 14500 Then l i s t a F r e c u e n c i a s . Add(New mascara ( ) ) Me . l i s t a C o e f i c i e n t e s . f r e c u e n c i a P r i n c i p a l = f r e c P r i n Me . Add ( 1 ) Next Me . nombre = nom Me . Add( f r e c P r i n * ( i + 1 ) / 3 ) End I f l i s t a M a s c a r a s . l i s t a C o e f i c i e n t e s = metodosComunes . Add( 1 4 7 * ( i + 1 ) ) l i s t a M a s c a r a s . ByVal f r e c P r i n As Double ) Me . f r e c u e n c i a P r i n c i p a l = f r e c P r i n End Sub #End Region #Region ” m´ todos ” e P u b l i c Function g e n e r a r S o n i d o ( ByVal c a n t i d a d M u e s t r a s As I n t e g e r . Add ( 1 ) Next Me . l i s t a C o e f i c i e n t e s . Add(New mascara ( ) ) Me . ByVal l i s t a F r e c As L i s t ( Of Double ) . ByVal l i s t a M a s c As L i s t ( Of mascara ) . c o p i a L i s t a D o u b l e ( l i s t a F r e c ) Me . f r e c u e n c i a P r i n c i p a l = 440 End Sub P u b l i c Sub New( ByVal f r e c P r i n As Double ) Me . nombre = ” S i n nombre a s i g n a d o ” Dim i As I n t e g e r l i s t a F r e c u e n c i a s = New L i s t ( Of Double ) l i s t a M a s c a r a s = New L i s t ( Of mascara ) l i s t a C o e f i c i e n t e s = New L i s t ( Of Double ) For i = 0 To 14 l i s t a F r e c u e n c i a s .

Abs ( v a l o r A c t u a l ) > d i v i s o r Then d i v i s o r = Math . l i s t a M a s c a r a s ( i ) . 0 . 0 . l i s t a C o e f i c i e n t e s ( i ) / d i v i s o r Next For i = 0 To c a n t i d a d M u e s t r a s − 1 p a r a D e v o l v e r . cambios ( l i s t a S e c t o r e s ( i ) ) Then listaSectores ( i ) = listaSectores ( i ) + 1 End I f Next l i s t a V a l o r e s . 0 . Add( v a l o r A c t u a l ) I f Math . PI * l i s t a F r e c u e n c i a s ( i ) * i n d i c e / FsPic ) I f i n d i c e > 10 * Me . i n c r e m e n t o s ( l i s t a S e c t o r e s ( i ) ) valorActual = valorActual + l i s t a C o e f i c i e n t e s ( i ) * v a l o r e s M a s c a r a s ( i ) * Math . 0 . 0} Dim v a l o r e s M a s c a r a s ( 1 4 ) As Double Dim i As I n t e g e r For i = 0 To 14 valoresMascaras ( i ) = listaMascaras ( i ) . 0 .Dim l i s t a S e c t o r e s ( ) As I n t e g e r = { 0 . l i s t a M a s c a r a s ( i ) . S i n ( 2 * Math . v a l o r I n i c i a l Next Dim v a l o r A c t u a l As Double Dim d i v i s o r As Double = 0 For i n d i c e = 0 To c a n t i d a d M u e s t r a s − 1 valorActual = 0 For i = 0 To 14 valoresMascaras ( i ) = valoresMascaras ( i ) + Me . Add( CInt ( 3 2 0 0 0 * ( l i s t a V a l o r e s ( i ) / d i v i s o r ) ) ) Next Return p a r a D e v o l v e r End Function #End Region End C l a s s programaVisual/apli/WindowsApplication1/nota. 0 . l i s t a C o e f i c i e n t e s ( i ) = Me . 0 . Abs ( v a l o r A c t u a l ) End I f Next For i = 0 To 14 Me . 0 . 0 .vb 227 . 0 . 0 . 0 . 0 .

numeroDos v e n t P a d r e As c r e a r M a s c a r a numeroUno As I n t e g e r numeroDos As I n t e g e r r u t a 1 As S t r i n g r u t a 2 As S t r i n g r e s p u e s t a As Boolean 228 . IO Imports System .vb’ Imports System . r u t a 1 = v a l u e End S e t End P r o p e r t y P u b l i c P r o p e r t y r u t a 2 ( ) As S t r i n g Get Return Me . S e r i a l i z a t i o n . r u t a 2 = v a l u e End S e t End P r o p e r t y P u b l i c P r o p e r t y numeroDos ( ) As I n t e g e r Get Return Me . numeroUno = v a l u e End S e t End P r o p e r t y P u b l i c P r o p e r t y r u t a 1 ( ) As S t r i n g Get Return Me . r u t a 2 End Get S e t ( ByVal v a l u e As S t r i n g ) Me . F o r m a t t e r s . Runtime . Binary Public Class pideEnteros #Region ” a t r i b u t o s ” Private Private Private Private Private Private #End Region #Region ” p r o p i e d a d e s ” P u b l i c P r o p e r t y ventPadre ( ) As c r e a r M a s c a r a Get Return Me .Clase ’pideEnteros. r u t a 1 End Get S e t ( ByVal v a l u e As S t r i n g ) Me . numeroUno End Get S e t ( ByVal v a l u e As I n t e g e r ) Me . v e n t P a d r e = v a l u e End S e t End P r o p e r t y P u b l i c P r o p e r t y numeroUno ( ) As I n t e g e r Get Return Me . v e n t P a d r e End Get S e t ( ByVal v a l u e As c r e a r M a s c a r a ) Me .

Value Me . Enabled = F a l s e Me . ByVal e As System . v e n t P a d r e = ventana Me . ExecutablePath ) + ”\ nota musical . EventArgs ) Handles BCancelar . D i s p o s e d Me . r e s p u e s t a = v a l u e End S e t End P r o p e r t y #End Region #Region ” c o n s t r u c t o r ” P u b l i c Sub New( ByVal ventana As c r e a r M a s c a r a ) InitializeComponent () Me . Text Me . ByVal e As System . numeroUno = NPeso1 . D i s p o s e ( ) End Sub P r i v a t e Sub p i d e E n t e r o s D i s p o s e d ( ByVal s e n d e r As Object . C l i c k Dispose () End Sub 229 . C l i c k Me .End Get S e t ( ByVal v a l u e As I n t e g e r ) Me . numeroDos = NPeso2 . ventPadre . EventArgs ) Handles Me . Text Me . Enabled = True End Sub P r i v a t e Sub B C a n c e l a r C l i c k ( ByVal s e n d e r As Object . Value Me . r e s p u e s t a = True Me . ventPadre . I c o n = i c o n o Catch ex As E x c e p t i o n End Try End Sub #End Region #Region ” r e a c c i o n e s ” P r i v a t e Sub B A c e p t a r C l i c k ( ByVal s e n d e r As Object . numeroDos = v a l u e End S e t End P r o p e r t y P u b l i c P r o p e r t y r e s p u e s t a ( ) As Boolean Get Return Me . r u t a 2 = TRuta2 . EventArgs ) Handles BAceptar . i c o ” Dim i c o n o As New I c o n ( r u t a I c o n o ) Me . r u t a 1 = TRuta1 . r e s p u e s t a = F a l s e Try Dim r u t a I c o n o As S t r i n g = Path . GetDirectoryName ( A p p l i c a t i o n . r e s p u e s t a End Get S e t ( ByVal v a l u e As Boolean ) Me . ByVal e As System .

Enabled = True End Sub #End Region End C l a s s programaVisual/apli/WindowsApplication1/pideEnteros. TRuta1 . FormClosedEventArgs ) Handles Me . TRuta2 . ByVal e As System . T i t l e = ” s e l e c c i o n e l a segunda e n v o l v e n t e d e s d e l a c u a l quiere extrapolar ” vent . masc ) | * . C l i c k Dim vent As New O p e n F i l e D i a l o g vent . FileName End I f End Sub P r i v a t e Sub BExaminar2 Click ( ByVal s e n d e r As System . masc ) | * . Object . ByVal e As System . Text = vent . ShowDialog ( ) I f vent . EventArgs ) Handles BExaminar1 . FileName <> Nothing Then Me . AddExtension = True vent . Forms . FileName <> Nothing Then Me .P r i v a t e Sub BExaminar1 Click ( ByVal s e n d e r As System . ShowDialog ( ) I f vent . Windows . masc” vent . T i t l e = ” s e l e c c i o n e l a p r i m e r e n v o l v e n t e d e s d e l a c u a l q u i e r e extrapolar ” vent . F i l t e r = ” i n s t r u m e n t o s ( * . EventArgs ) Handles BExaminar2 . F i l t e r = ” i n s t r u m e n t o s ( * . Object . ByVal e As System . FormClosed Me . ventPadre .vb 230 . masc” vent . C l i c k Dim vent As New O p e n F i l e D i a l o g vent . Text = vent . FileName End I f End Sub P r i v a t e Sub p i d e E n t e r o s F o r m C l o s e d ( ByVal s e n d e r As Object .

aumentarValoresY (num) End I f Me .Clase ’pideUnDouble. i c o ” Dim i c o n o As New I c o n ( r u t a I c o n o ) Me . ByVal e As System . MsgBoxStyle . GetDirectoryName ( A p p l i c a t i o n . Text ) I f esX Then Me . i c o ” Dim i c o n o As New I c o n ( r u t a I c o n o ) Me . ByVal esEjeX As Boolean ) InitializeComponent () ventanaPadre = vent esX = esEjeX Try Dim r u t a I c o n o As S t r i n g = Path .vb’ Imports System . IO Imports System . I c o n = i c o n o Catch ex As E x c e p t i o n End Try End Sub #End Region #Region ” r e a c c i o n e s ” P r i v a t e Sub B A c e p t a r C l i c k ( ByVal s e n d e r As System . ventanaPadre . ExecutablePath ) + ”\ nota musical . F o r m a t t e r s . Object . D i s p o s e ( ) Catch ex As E x c e p t i o n MsgBox ( ” El v a l o r i n s e r t a d o no e s v ´ l i d o . GetDirectoryName ( A p p l i c a t i o n . ExecutablePath ) + ”\ nota musical . C l i c k Try Dim num As Double = CDbl ( TValor . C r i t i c a l ) u 231 . Runtime . aumentarValoresX (num) Else Me . EventArgs ) Handles BAceptar . ventanaPadre . S e r i a l i z a t i o n . Binary P u b l i c C l a s s pideUnDouble #Region ” v a r i a b l e s ” P r i v a t e ventanaPadre As c r e a r M a s c a r a P r i v a t e esX As Boolean #End Region #Region ” c o n s t r u c t o r e s ” P u b l i c Sub New( ByVal vent As crearMascara . I c o n = i c o n o Catch ex As E x c e p t i o n End Try End Sub P u b l i c Sub New ( ) InitializeComponent () Try Dim r u t a I c o n o As S t r i n g = Path . v e r i f i q u e que s e a un a n´ mero mayor a c e r o ” .

ByVal e As System .End Try End Sub P r i v a t e Sub B C a n c e l a r C l i c k ( ByVal s e n d e r As System . Forms . Enabled = True End Sub #End Region End C l a s s programaVisual/apli/WindowsApplication1/pideUnDouble. EventArgs ) Handles BCancelar . ventanaPadre . FormClosedEventArgs ) Handles Me . Object . Windows . D i s p o s e ( ) End Sub P r i v a t e Sub pideUnDouble FormClosed ( ByVal s e n d e r As Object . ByVal e As System . C l i c k Me . FormClosed Me .vb 232 .

Exclamation ) Else Try 233 . Close () readThread . S e r i a l i z a t i o n . ExecutablePath ) + ”\ nota musical . Binary Public Class transmitir #Region ” v a r i a b l e s ” Dim Dim Dim Dim Dim Dim Dim Dim Dim Dim Dim Dim s e r i a l P o r t As S e r i a l P o r t nombrePuerto As S t r i n g textoAEnviar As S t r i n g r e c i b i E c o As Boolean = F a l s e ultimoMandado As Byte readThread As Thread mandarThread As Thread e s t o y C o n e c t a d o As Boolean = F a l s e b y t e R e c i b i d o As Byte aqum As I n t e g e r = 0 huboError As Boolean = F a l s e cantidadDeDatosEnviados As I n t e g e r = 0 #End Region #Region ” c o n s t r u c t o r ” P u b l i c Sub New ( ) InitializeComponent () ListBox1 . EventArgs ) Handles BConectar . GetDirectoryName ( A p p l i c a t i o n . C l i c k I f e s t o y C o n e c t a d o Then estoyConectado = False s e r i a l P o r t . F o r m a t t e r s . Items . I c o n = i c o n o Catch ex As E x c e p t i o n End Try End Sub #End Region #Region ” r e a c c i o n e s ” P r i v a t e Sub B C o n e c t a r C l i c k ( ByVal s e n d e r As Object . J o i n ( ) End I f I f ListBox1 . MsgBoxStyle . IO . Threading Imports System . Runtime . S e l e c t e d I t e m = Nothing Or ListBox1 . IO Imports System . i c o ” Dim i c o n o As New I c o n ( r u t a I c o n o ) Me . ByVal e As System . P o r t s Imports System .vb’ Imports System Imports System . S e l e c t e d I n d e x = 0 Then MsgBox ( ”Debe s e l e c c i o n a r un p u e r t o s e r i e ” .Clase ’transmitir. Add( ”Debe c h e q u e a r l o s p u e r t o s ” ) Try Dim r u t a I c o n o As S t r i n g = Path .

DataBits = 8 s e r i a l P o r t . None s e r i a l P o r t . S e l e c t e d I t e m . o MsgBoxStyle . F i l e S y s t e m . S t a r t ( ) mandarThread = New Thread ( AddressOf mandar ) mandarThread . J o i n ( ) mandarThread . C r i t i c a l ) End Try End Sub 234 . FileName ) Dim s e p a r a d o r As Char = ” . EventArgs ) Handles BArchivoNumeros . ReadTimeout = 500 s e r i a l P o r t . s e p a r a d o r ) Dim c u e n t a As I n t e g e r = TestArray . ByVal e As System . Close () readThread . PortName = nombrePuerto s e r i a l P o r t . hex ) | * . Text = ”Ha e l e g i d o e l p u e r t o s e r i e : ” + nombrePuerto s e r i a l P o r t = New S e r i a l P o r t ( ) ’ C o n f i g u r a c i ´ n d e l p u e r t o o serie s e r i a l P o r t . D i s p o s e d Try estoyConectado = False s e r i a l P o r t . J o i n ( ) Catch ex As E x c e p t i o n End Try End Sub P r i v a t e Sub BArchivoNumeros Click ( ByVal s e n d e r As Object . Length > 0 Then textoAEnviar = My.nombrePuerto = ListBox1 . FileNames . ShowDialog ( ) I f e l e g i r A r c h i v o . BaudRate = 9600 s e r i a l P o r t . P a r i t y = P a r i t y . ByVal e As System . Length Timer1 . StopBits = 1 s e r i a l P o r t . Computer . T o S t r i n g L ab el 1 . Enabled = True Catch ex As E x c e p t i o n MsgBox ( ” E r r o r de c o n e c c i ´ n con e l p u e r t o s e l e c c i o n a d o ” . EventArgs ) Handles Me . hex ” e l e g i r A r c h i v o . F i l t e r = ” i n s t r u m e n t o s en hex ( * . C r i t i c a l ) End Try End I f End Sub P r i v a t e Sub v e n t a n a P r i n c i p a l D i s p o s e d ( ByVal s e n d e r As Object . C l i c k Try Dim e l e g i r A r c h i v o As New O p e n F i l e D i a l o g e l e g i r A r c h i v o . None s e r i a l P o r t . WriteTimeout = 500 s e r i a l P o r t . AddExtension = True e l e g i r A r c h i v o . S t a r t ( ) End I f Catch ex As E x c e p t i o n MsgBox ( ” E r r o r a l e n v i a r i n s t r u m e n t o ” . MsgBoxStyle . Handshake = Handshake . Open ( ) readThread = New Thread ( AddressOf r e a d ) readThread . ” Dim TestArray ( ) As S t r i n g = S p l i t ( textoAEnviar . ReadAllText ( e l e g i r A r c h i v o . S t a r t ( ) e s t o y C o n e c t a d o = True BArchivoNumeros .

Text = ”Ha s i d o r e c i b´ d o un ” + ı b y t e R e c i b i d o . Second + 2 I f segundoHasta > 59 Then segundoHasta = segundoHasta − 60 End I f Dim l i s t a As Byte ( ) = {50} s e r i a l P o r t . ReadByte ( ) r e c i b i E c o = True aqum = aqum + 1 L ab el 5 . V i s i b l e = True L ab el 5 . T o S t r i n g + ” b y t e s r e c i b i d o s ” Catch ex As E x c e p t i o n End Try End While End Sub P r i v a t e Sub mandar ( ) I f e s t o y C o n e c t a d o Then Dim s e p a r a d o r As Char = ” . ” Dim TestArray ( ) As S t r i n g = S p l i t ( textoAEnviar . 1 ) recibiEco = False While ( segundoHasta <> Now . Second ) And ( Not r e c i b i E c o ) End While I f segundoHasta <= Now .P r i v a t e Sub r e a d ( ) While ( e s t o y C o n e c t a d o ) Try b y t e R e c i b i d o = s e r i a l P o r t . 0 . Second Then huboError = True MsgBox ( ”No r e c i b´ c o n f i r m a c i ´ n de comienzo de ı o programamci´ n ” ) o E l s e I f b y t e R e c i b i d o <> 24 Then MsgBox ( ” R e c i b´ e c o p e r o no e r a e l e s p e r a d o ” ) ı End I f segundoHasta = Now . Write ( l i s t a . Second ) End While I f Not huboError Then For i = 0 To 1289 I f Not huboError Then Try linea = 0 aEnviar = CDbl ( TestArray ( i ) ) 235 . T o S t r i n g + ” . a c t u a l m e n t e van ” + aqum . Second + 5 I f segundoHasta > 59 Then segundoHasta = segundoHasta − 60 End I f While ( segundoHasta <> Now . s e p a r a d o r ) Dim i As I n t e g e r Dim largoTrama As I n t e g e r = 100 Dim byteAEnviar1 As Byte Dim byteAEnviar2 As Byte Dim byteAEnviar3 As Byte Dim byteAEnviar4 As Byte Dim l i n e a As I n t e g e r = 0 Dim datosMandados As I n t e g e r = 0 Dim aEnviar As Long Dim r e c i b i 2 6 As Boolean = F a l s e Dim segundoHasta As I n t e g e r = Now .

1 ) linea = linea + 1 datosMandados = datosMandados + 1 linea = linea + 1 I f datosMandados = largoTrama Then segundoHasta = Now .linea = linea + 1 I f aEnviar < 0 Then aEnviar = aEnviar + 65536 End I f linea = linea + 1 byteAEnviar2 = CByte ( Fix ( ( aEnviar ) / 2 5 6 ) ) linea = linea + 1 byteAEnviar1 = CByte ( ( aEnviar − 256 * CDbl ( byteAEnviar2 ) ) ) linea = linea + 1 l i s t a ( 0 ) = byteAEnviar2 linea = linea + 1 s e r i a l P o r t . Second ) And ( Not r e c i b i E c o ) End While I f r e c i b i E c o Then I f b y t e R e c i b i d o <> 38 Then MsgBox ( ” R e c i b´ e c o p e r o no e r a e l ı esperado ” ) huboError = True End I f Else huboError = True MsgBox ( ”No r e c i b´ c o n f i r m a c i ´ n de ı o comienzo de que r e c i b i ´ e l s e t de o 100 datos . aqum v a l e ” + aqum . Write ( l i s t a . T o S t r i n g + ” e l n´ mero a i n t e r p r e t a r u v a l e ” + TestArray ( i ) + ” l i n e a v a l e ” + l i n e a . T o S t r i n g ) End I f End I f Catch ex As E x c e p t i o n MsgBox ( ” E r r o r a l e n v i a r l a trama . aqum v a l e ” + aqum . Write ( l i s t a . 0 . 0 . Second + 10 I f segundoHasta > 59 Then segundoHasta = segundoHasta − 60 End I f datosMandados = 0 While ( segundoHasta <> Now . 1 ) linea = linea + 1 datosMandados = datosMandados + 1 cantidadDeDatosEnviados = cantidadDeDatosEnviados + 1 cantidadDeDatosEnviados = cantidadDeDatosEnviados + 1 linea = linea + 1 l i s t a ( 0 ) = byteAEnviar1 recibiEco = False linea = linea + 1 s e r i a l P o r t . ToString ) huboError = True End Try 236 .

Second ) And ( Not r e c i b i E c o ) End While I f r e c i b i E c o Then I f b y t e R e c i b i d o <> 38 Then MsgBox ( ” R e c i b´ e c o p e r o no e r a e l ı esperado ” ) huboError = True End I f Else huboError = True MsgBox ( ”No r e c i b´ c o n f i r m a c i ´ n de ı o comienzo de que r e c i b i ´ e l s e t de o 100 datos . 0 . 1 ) cantidadDeDatosEnviados = cantidadDeDatosEnviados + 1 l i s t a ( 0 ) = byteAEnviar1 cantidadDeDatosEnviados = cantidadDeDatosEnviados + 1 s e r i a l P o r t .End I f Next End I f I f Not huboError Then For i = 1290 To 2579 I f Not huboError Then Try aEnviar = CDbl ( TestArray ( i ) ) byteAEnviar4 = CByte ( Fix ( ( aEnviar ) / 1 6 7 7 7 2 1 6 ) ) byteAEnviar3 = CByte ( Fix ( ( ( aEnviar − 16777216 * CDbl ( byteAEnviar4 ) ) ) / 6 5 5 3 6 ) ) byteAEnviar2 = CByte ( Fix ( ( aEnviar − 16777216 * CDbl ( byteAEnviar4 ) − 65536 * CDbl ( byteAEnviar3 ) ) / 2 5 6 ) ) byteAEnviar1 = CByte ( Fix ( aEnviar − 16777216 * CDbl ( byteAEnviar4 ) − 65536 * CDbl ( byteAEnviar3 ) − 256 * CDbl ( byteAEnviar2 ) ) ) l i s t a ( 0 ) = byteAEnviar2 s e r i a l P o r t . 1 ) recibiEco = False datosMandados = datosMandados + 2 I f datosMandados = largoTrama Then segundoHasta = Now . T o S t r i n g ) End I f End I f l i s t a ( 0 ) = byteAEnviar4 s e r i a l P o r t . 0 . 1 ) cantidadDeDatosEnviados = cantidadDeDatosEnviados + 1 237 . aqum v a l e ” + aqum . Write ( l i s t a . Second + 10 I f segundoHasta > 59 Then segundoHasta = segundoHasta − 60 End I f datosMandados = 0 While ( segundoHasta <> Now . Write ( l i s t a . 0 . Write ( l i s t a .

0 . 0 . 1 ) datosMandados = datosMandados + 1 cantidadDeDatosEnviados = 238 . 1 ) cantidadDeDatosEnviados = cantidadDeDatosEnviados + 1 recibiEco = False datosMandados = datosMandados + 2 I f datosMandados = largoTrama Then segundoHasta = Now . T o S t r i n g + ” e s t o y en l a segunda tabla ”) huboError = True End Try End I f Next End I f I f Not huboError Then For i = 2580 To 20639 I f Not huboError Then Try aEnviar = CDbl ( TestArray ( i ) ) I f aEnviar < 0 Then aEnviar = aEnviar + 65536 End I f byteAEnviar2 = CByte ( Fix ( ( aEnviar ) / 2 5 6 ) ) byteAEnviar1 = CByte ( ( aEnviar − 256 * CDbl ( byteAEnviar2 ) ) ) l i s t a ( 0 ) = byteAEnviar2 s e r i a l P o r t . Second ) And ( Not r e c i b i E c o ) End While I f r e c i b i E c o Then I f b y t e R e c i b i d o <> 38 Then MsgBox ( ” R e c i b´ e c o p e r o no e r a e l ı esperado ” ) huboError = True End I f Else huboError = True MsgBox ( ”No r e c i b´ c o n f i r m a c i ´ n de ı o comienzo de que r e c i b i ´ e l s e t de o 100 datos . T o S t r i n g + ” e l n´ mero a i n t e r p r e t a r u v a l e ” + TestArray ( i ) + ” l i n e a v a l e ” + l i n e a .l i s t a ( 0 ) = byteAEnviar3 s e r i a l P o r t . T o S t r i n g ) End I f End I f Catch ex As E x c e p t i o n MsgBox ( ” E r r o r a l e n v i a r l a trama . aqum v a l e ” + aqum . Write ( l i s t a . Write ( l i s t a . Second + 10 I f segundoHasta > 59 Then segundoHasta = segundoHasta − 60 End I f datosMandados = 0 While ( segundoHasta <> Now . aqum v a l e ” + aqum .

0 . Write ( l i s t a . 1 ) recibiEco = False datosMandados = datosMandados + 1 I f datosMandados = largoTrama Then segundoHasta = Now . Write ( l i s t a . aqum v a l e ” + aqum . T o S t r i n g + ” e l n´ mero a i n t e r p r e t a r u v a l e ” + TestArray ( i ) + ” l i n e a v a l e ” + l i n e a . 0 . Second ) And ( Not r e c i b i E c o ) End While I f r e c i b i E c o Then recibiEco = False 239 . 1 ) cantidadDeDatosEnviados = cantidadDeDatosEnviados + 1 End While segundoHasta = Now .cantidadDeDatosEnviados + 2 l i s t a ( 0 ) = byteAEnviar1 s e r i a l P o r t . aqum v a l e ” + aqum . Second + 10 I f segundoHasta > 59 Then segundoHasta = segundoHasta − 60 End I f While ( segundoHasta <> Now . Second ) And ( Not r e c i b i E c o ) End While I f r e c i b i E c o Then I f b y t e R e c i b i d o <> 38 Then MsgBox ( ” R e c i b´ e c o p e r o no e r a e l ı esperado ” ) huboError = True End I f Else huboError = True MsgBox ( ”No r e c i b´ c o n f i r m a c i ´ n de ı o comienzo de que r e c i b i ´ e l s e t de o 100 datos . T o S t r i n g ) End I f End I f Catch ex As E x c e p t i o n MsgBox ( ” E r r o r a l e n v i a r l a trama . T o S t r i n g + ” e s t o y en l a t e r c e r a tabla ”) huboError = True End Try End I f Next End I f While datosMandados < largoTrama And datosMandados > 0 datosMandados = datosMandados + 1 l i s t a (0) = 1 recibiEco = False s e r i a l P o r t . Second + 10 I f segundoHasta > 59 Then segundoHasta = segundoHasta − 60 End I f datosMandados = 0 While ( segundoHasta <> Now .

J o i n ( ) End Sub P r i v a t e Sub Timer1 Tick ( ByVal s e n d e r As Object . GetPortNames ( ) ListBox1 . C l e a r ( ) I f S e r i a l P o r t . Items . Items . EventArgs ) Handles BCheq .I f b y t e R e c i b i d o <> 38 Then MsgBox ( ” R e c i b´ e c o p e r o no e r a e l e s p e r a d o ” ) ı huboError = True End I f Else huboError = True MsgBox ( ”No r e c i b´ c o n f i r m a c i ´ n de comienzo de que r e c i b i ´ ı o o e l s e t de 100 datos . Add( ” L i s t a de p u e r t o s d i s p o n i b l e s : ” ) For Each s In S e r i a l P o r t . V i s i b l e = True L ab el 4 . EventArgs ) Handles Timer1 . ByVal e As System . Object . Second ) And ( Not r e c i b i E c o ) End While I f r e c i b i E c o Then I f b y t e R e c i b i d o <> 21 Then MsgBox ( ” R e c i b´ un dato p e r o no e r a l a c o n f i r m a c i ´ n de ı o f i n a l i a c i ´ n de l a programaci´ n ” ) o o huboError = True End I f Else huboError = True MsgBox ( ”No r e c i b´ c o n f i r m a c i ´ n de f i n a l i z a c i ´ n d e l ı o o p r o c e s o . T o S t r i n g ) End I f I f huboError Then MsgBox ( ” El p r o c e s o s a l i ´ mal” ) o Else MsgBox ( ” F e l i c i t a c i o n e s . C l i c k Dim s As S t r i n g ListBox1 . Add( s ) Next s BConectar . Length > 0 Then ListBox1 . aqum v a l e ” + aqum . Add( ”No hay p u e r t o s s e r i e d i s p o n i b l e s ” ) End I f End Sub 240 . Tick L ab el 4 . Items . GetPortNames . Second + 10 I f segundoHasta > 59 Then segundoHasta = segundoHasta − 60 End I f While ( segundoHasta <> Now . Text = ” Hasta ahora han s i d o e n v i a d o s ” + cantidadDeDatosEnviados . Items . Enabled = True Else ListBox1 . ByVal e As System . aqum v a l e ” + aqum . T o S t r i n g + ” d a t o s ” End Sub P r i v a t e Sub BCheq Click ( ByVal s e n d e r As System . T o S t r i n g ) End I f segundoHasta = Now . e l p i c e s t a b i e n grabado ” ) End I f End I f mandarThread .

vb 241 .#End Region End C l a s s programaVisual/apli/WindowsApplication1/transmitir.

Runtime . Object . ShowDialog ( ) End Sub P r i v a t e Sub B C r e a r I n s t r u m e n t o C l i c k ( ByVal s e n d e r As System . Enabled = True vent . ByVal e As System .vb’ Imports System . i . ByVal e As System . C r i t i c a l ) End Try End I f End Sub P r i v a t e Sub BMandarArchivo Click ( ByVal s e n d e r As System . ShowDialog ( ) I f vent . Close () Dim vent2 As New c r e a r I n s t r u m e n t o ( i n s . C l i c k Dim i n s As i n s t r u m e n t o = New i n s t r u m e n t o Dim i As I n t e g e r Dim ventAux As c r e a r M a s c a r a Dim j As I n t e g e r Dim vent As New c r e a r I n s t r u m e n t o ( i n s . i n s t ) | * . ShowDialog ( ) 242 . Binary Public Class ventanaInicial #Region ” r e a c c i o n e s ” P r i v a t e Sub BCre arMa scar a Cli ck ( ByVal s e n d e r As System .Clase ’ventanaInicial. Object . ShowDialog ( ) Catch ex As E x c e p t i o n MsgBox ( ” I m p o s i b l e a b r i r e l a r c h i v o s e l e c c i o n a d o ” . FileName Dim f s As New F i l e S t r e a m ( ruta . ByVal e As System . ruta . F a l s e ) Next P r o g r e s s B a r 1 . FileMode . C l i c k Dim vent As New O p e n F i l e D i a l o g vent . F o r m a t t e r s . j . EventArgs ) Handles BCrearMascara . EventArgs ) Handles BMandarArchivo . D e s e r i a l i z e ( f s ) . True ) vent2 . F a l s e ) For j = 0 To 85 For i = 0 To 14 ventAux = New c r e a r M a s c a r a ( vent . Object . Object . AddExtension = True vent . S e r i a l i z a t i o n . EventArgs ) Handles BCrearInstrumento . C l i c k Dim vent As New c r e a r M a s c a r a vent . Length > 0 Then Try Dim i n s As i n s t r u m e n t o Dim r u t a As S t r i n g = vent . Value = ( j * 100 / 8 5 ) Next vent . i n s t r u m e n t o ) f s . i n s t ” vent . C l i c k Dim vent As New t r a n s m i t i r vent . ShowDialog ( ) End Sub P r i v a t e Sub B A b r i r I n s t r u m e n t o C l i c k ( ByVal s e n d e r As System . IO Imports System . Open ) Dim b f As New BinaryFormatter i n s = CType ( b f . MsgBoxStyle . EventArgs ) Handles BAbrirInstrumento . ByVal e As System . FileNames . ” ” . True . F i l t e r = ” i n s t r u m e n t o s ( * .

GetDirectoryName ( A p p l i c a t i o n . I c o n = i c o n o Catch ex As E x c e p t i o n End Try End Sub #End Region End C l a s s programaVisual/apli/WindowsApplication1/ventanaInicial.End Sub #End Region #Region ” c o n s t r u c t o r e s ” P u b l i c Sub New ( ) InitializeComponent () Try Dim r u t a I c o n o As S t r i n g = Path . i c o ” Dim i c o n o As New I c o n ( r u t a I c o n o ) Me . ExecutablePath ) + ”\ nota musical .vb 243 .

wavwrite ( z . end z=z /max( abs ( z ) ) . z=z e r o s ( 1 . Fs . hasta . endfunction scilab/acortaSonido.sci 244 . : ) . l a r g o ) . : ) . : )+y ( 2 . sumar ) [ y . c´digos de scilab o Funci´n ’acortaSonido’ o f u n c t i o n z= a c o r t a S o n i d o ( entrada .Anexo E. b i t s ]= wavread ( e n t r a d a ) . desde . c a n a l . Fs . end i f ( hasta <0) h a s t a=l e n g t h ( y ) end l a r g o=hasta−d e s d e . s a l i d a ) . end i f sumar>0 y=y ( 1 . f o r i=d e s d e +1: d e s d e+l a r g o z ( i −d e s d e )=y ( i ) . i f sumar<=0 y=y ( c a n a l . s a l i d a .

1 ) ) .sci 245 . 2 ) f o r j =1:tam ( 1 . i n d i c e s ( j ) ) . i ) ) / cadaCuantosEvol end end f o r i =1: l e n g t h ( y ) f o r j =1: l e n g t h ( f r e c u e n c i a s ) y ( i )=y ( i )+v a l o r e s ( j ) * s i n ( 2 * %pi * f r e c u e n c i a s ( j ) * i / Fs ) . tam=s i z e ( e v o l u c i o n ) . end i f ( i n d i c e s ( j ) <5) i f ( i==cambios ( j . v a l o r e s ( j )=v a l o r e s ( j )+i n c r e m e n t o s ( j . ˆ ( ( nota −49) / 1 2 ) . y=y/max( abs ( y ) ) r u t a D e s t i n o=r u t a D e s t i n o+” \ nota ”+s t r i n g ( nota )+” . end end v a l o r e s=z e r o s ( 1 . cambios=z e r o s ( tam ( 1 . 1 ) cambios ( i . j ) =( e v o l u c i o n ( j +1. 2 ) . endfunction scilab/copiaNota. tam ( 1 . f r e c u e n c i a s . i n d i c e s ( j ) ) ) i n d i c e s ( j )=i n d i c e s ( j ) +1. tam ( 1 . tam ( 1 . mi=z e r o s ( 1 . f o r i =1: l e n g t h ( f r e c u e n c i a s ) v a l o r e s ( i )=e v o l u c i o n ( 1 . i f ( v a l o r e s ( j ) <0) v a l o r e s ( j ) =0. wav” . nota . 1 )=tam ( 1 . l a r g o ) i n d i c e s=o n e s ( 1 . i n c r e m e n t o s =2048 * i n c r e m e n t o s /maximoy . y=z e r o s ( 1 . 2 ) . l e n g t h ( f r e c u e n c i a s ) ) . 1 5 ) . cambios . j )=cadaCuantosEvol * j . l e n g t h ( f r e c u e n c i a s ) ) . i n c r e m e n t o s . 1 )−1 i n c r e m e n t o s ( i .Funci´n ’copiaNota’ o f u n c t i o n [ y . 1 ) −1. l a r g o . 2 ) f o r j =1:tam ( 1 . i ) . i )−e v o l u c i o n ( j . i ) . mi ( i )=e v o l u c i o n ( 1 . r u t a D e s t i n o ) mi=2048 * mi/maximoy . 1 ) −1) f o r i =1:tam ( 1 . e v o l u c i o n ]= copiaNota ( r u t a D e s t i n o . cadaCuantosEvol . Fs ) f r e c u e n c i a s=f r e c u e n c i a s * 2 . e v o l u c i o n . Fs . mi . f o r i =1:tam ( 1 . wavwrite ( y . end i n c r e m e n t o s=z e r o s ( tam ( 1 . end end end end maximoy=max( abs ( y ) ) .

end end f o r i =1:86 tam=s i z e ( cambios ) . f o r j =1:tam ( 1 . Fs ) . s t r i n g ( round ( f r e c u e n c i a s ( j ) * c a n t i d a d S e n o s / f r e c u e n c i a P i c ) )+” . f r e c u e n c i a P i c . endfunction scilab/copiaSonido.1 . aqum=aqum+1. l a r g o A u d i o / 8 . f o r i =1:86 f r e c u e n c i a s=P i c o s * 2 . ” ) . c a n t i d a d S e n o s . e r r ]=mopen ( r u t a D e s t i n o T a b l a . end m f p r i n t f ( fd . ’w ’ ) . end end end mclose ( fd ) . aqum=aqum+1. nota . k ) * Fs / ( f r e c u e n c i a P i c ) ) ) ) .sci 246 . [ fd . 1 5 . i n c r e m e n t o s . cambios . s t r i n g ( round ( 6 5 5 3 6 * m a s c a r a s I n i c i a l e s ( j ) ) )+” . 2 ) i f i ==86 & j==tam ( 1 . e v o l u c i o n . rutaDestinoTabla . cambios . s t r i n g ( 6 5 5 3 5 )+” . [ y . c o e f i c i e n t e s=F o u r i e r P a r t e s ( r u t a O r i g e n . 1 ) f o r k=1:tam ( 1 . c o e f i c i e n t e s . P i c o s ) . 1 ) f o r k=1:tam ( 1 . s t r i n g ( round ( cambios ( j . aqum=aqum+1. P i c o s . l a r g o A u d i o / 8 . − 1 . else m f p r i n t f ( fd . ” ) . s t r i n g ( round ( 6 5 5 3 6 * i n c r e m e n t o s ( j . i n c r e m e n t o s . −1 . m a s c a r a s I n i c i a l e s . P i c o s . e v o l u c i o n ]= copiaNota ( r u t a D e s t i n o S o n i d o . 2 ) m f p r i n t f ( fd . f o r j =1:tam ( 1 . end end f o r i =1:86 tam=s i z e ( i n c r e m e n t o s ) . rutaDestinoSonido . s t r i n g ( round ( 6 5 5 3 6 * i n c r e m e n t o s ( j . l arg oAud io . m a s c a r a s I n i c i a l e s . Fs]= F o u r i e r F a c i l ( r u t a O r i g e n . ˆ ( ( ( i −nota ) / 1 2 ) ) f o r j =1: l e n g t h ( f r e c u e n c i a s ) t e x t o=m f p r i n t f ( fd . aqum]= copiaSonido ( rutaOrigen . 1 ) . end aqum=aqum+1. 5 0 0 0 . l arg oAud io . 2 )−2 m f p r i n t f ( fd . nota ) [ P i c o s . ” ) . end end f o r i =1:86 f o r j =1: l e n g t h ( m a s c a r a s I n i c i a l e s ) m f p r i n t f ( fd . ” ) aqum=aqum+1. 1 ) & k==tam ( 1 . aqum=0. k ) * f r e c u e n c i a P i c / ( 1 0 * Fs ) ) )+” . ” ) .Funci´n ’copiaSonido’ o f u n c t i o n [ y . k ) * Fs / ( f r e c u e n c i a P i c ) ) )+” .

k )>valorMaximo valorMaximo=z ( 1 . z=z e r o s ( 1 . end endfunction scilab/fourieFacilDetectaPicos. c a n t i d a d M u e s t r a s . end y=y ( 1 . f o r k=1: l e n g t h ( z ( 1 . b i t s ]= wavread ( e n t r a d a ) . c a n t i d a d . k ) . f o r i =1: numeroPicos valorMaximo =0. ( z ( 1 . kMaximo=0. : ) ) plot2d ( j . i ) ) .Funci´n ’fourieFacilDetectaPicos’ o f u n c t i o n [ P i c o s . Fs . : ) ) / cantidad .1+ round ( 2 * i * ( c a n t i d a d −1)/ l e n g t h ( f o u ) ) )= abs ( z (1 . end i f c a n t i d a d M u e s t r a s <0 [ y . end j =0: c a n t i d a d −1 j=j * Fs / ( 2 * c a n t i d a d ) maximo=max( z ( 1 . i )=s q r t ( z ( 1 . numeroPicos . : ) ) i f z ( 1 . la rgoA udi o . c a n t i d a d ) f o u= f f t ( y ) f o r i =1: l e n g t h ( f o u ) /2 z (1 . Fs . colorGraf ) P i c o s=z e r o s ( 1 . end end f o r k=−5:5 i f kMaximo+k>0 z ( 1 . kMaximo=k . c a n t i d a d M u e s t r a s ) . Fs]= F o u r i e r F a c i l ( entrada . b i t s ]= wavread ( entrada . c o l o r G r a f ) i f cantidadMuestras > 0 [ y . end end P i c o s ( i )=j ( kMaximo ) .1+ round ( 2 * i * ( c a n t i d a d −1)/ l e n g t h ( f o u ) ) ) )+abs ( f o u ( i ) ) ˆ2 end f o r i =1: l e n g t h ( z ) z ( 1 . numeroPicos ) .sci 247 . : ) . l a r g o A u d i o=l e n g t h ( y ) . kMaximo+k ) =−1.

length ( frecuencias ) ) .m) ) . f o r j =1: l a r g o P a r t i c i o n i f j+i <l e n g t h ( s o n i d o ) y ( j )=s o n i d o ( i+j ) . y=y ( 1 .m)+ abs ( f o u ( p o s i c i o n e s F r e c u e n c i a s (m)+k ) ) ˆ2 end end end c o e f i c i e n t e s ( aqum . j=j * Fs / ( l e n g t h ( f o u ) ) . Fs . b i t s ]= wavread ( r u t a o r i g e n . h a s t a +1) .m)=s q r t ( c o e f i c i e n t e s ( aqum . p o s i c i o n e s F r e c u e n c i a s=z e r o s ( 1 .m)=c o e f i c i e n t e s ( aqum . c o e f i c i e n t e s=z e r o s ( round ( ( hasta −d e s d e ) / l a r g o P a r t i c i o n ) +1. f o r k=−3:3 i f ( p o s i c i o n e s F r e c u e n c i a s (m)+k>0) i f ( p o s i c i o n e s F r e c u e n c i a s (m)+k<=l e n g t h ( f o u ) ) c o e f i c i e n t e s ( aqum . end end f o u= f f t ( y ) j =0: l e n g t h ( f o u ) −1. hasta . aqum=1. end [ y . s o n i d o=z e r o s ( 1 . f o r m=1: l e n g t h ( f r e c u e n c i a s ) f o r n=1: l e n g t h ( f o u )−1 i f j ( n )< =f r e c u e n c i a s (m) i f j ( n+1)>f r e c u e n c i a s (m) p o s i c i o n e s F r e c u e n c i a s (m)=n . hasta−d e s d e ) . end f o r i =1: l a r g o P a r t i c i o n : l e n g t h ( s o n i d o ) y=z e r o s ( 1 . y=y ( 1 . l a r g o P a r t i c i o n . end end end end f o r m=1: l e n g t h ( f r e c u e n c i a s ) c o e f i c i e n t e s ( aqum . e j e =0: l e n g t h ( c o e f i c i e n t e s ) / l e n g t h ( f r e c u e n c i a s ) −1. end aqum=aqum+1. aqum=1. 248 . : ) . b i t s ]= wavread ( r u t a o r i g e n ) . Fs . desde . l a r g o P a r t i c i o n ) .Funci´n ’fouriePartesPicos’ o f u n c t i o n c o e f i c i e n t e s= F o u r i e r P a r t e s ( r u t a o r i g e n . f r e c u e n c i a s ) [ y . : ) . f o r i =1: hasta−d e s d e s o n i d o ( i )=y ( i+d e s d e ) . i f hasta <0 h a s t a=l e n g t h ( y ) −2. end s a l i d a =0. l e n g t h ( f r e c u e n c i a s ) ) .m) =0.

e j e=e j e * l a r g o P a r t i c i o n . i +1) . 1 . i f i +( j −1) * d i v i s i o n e s <=l e n g t h ( f r e c u e n c i a s ) p l o t 2 d ( e j e .sci 249 . end end end endfunction scilab/fouriePartesPicos. d i v i s i o n e s=round ( l e n g t h ( f r e c u e n c i a s ) / 4 ) f o r j =1: d i v i s i o n e s x s e t ( ’ window ’ . i +( j −1) * d i v i s i o n e s ) ) . c o e f i c i e n t e s ( : . j +1) f o r i =1:4 s u b p l o t ( 5 .

b i t s ]= wavread ( e n t r a d a ) . z=z e r o s ( 1 . f o r i =1: l e n g t h ( y ) z (1 . y=y ( c a n a l . c a n t i d a d ) f o u=y .sci 250 .1+ round ( i * ( c a n t i d a d −1)/ l e n g t h ( y ) ) )+abs ( f o u ( i ) ) end j =0: c a n t i d a d −1 j=j * l e n g t h ( y ) / ( c a n t i d a d * Fs ) maximo=max( z ( 1 . c o l o r G r a f . : ) ) /maximo . c a n a l ) [ y . : ) ) p l o t 2 d ( j . Fs . c a n t i d a d .Funci´n ’graficaFacil’ o f u n c t i o n z= g r a f i c a F a c i l ( entrada . : ) . ( z ( 1 . c o l o r G r a f ) endfunction scilab/graficaFacil.1+ round ( i * ( c a n t i d a d −1)/ l e n g t h ( y ) ) )= z (1 .

s o n i d o=z e r o s ( 1 . l a r g o P a r t i c i o n ) . c o e f i c i e n t e s=z e r o s ( round ( ( hasta −d e s d e ) / l a r g o P a r t i c i o n ) +1.Funci´n ’haceGraficas’ o f u n c t i o n f r e c u e n c i a s= h a c e G r a f i c a s ( ruta .m)=s q r t ( c o e f i c i e n t e s ( aqum . Fs . 5 0 0 . c o l ) [ f r e c u e n c i a s . : ) . Fs .m)=c o e f i c i e n t e s ( aqum . end end f o u= f f t ( y ) j =0: l e n g t h ( f o u ) −1. f o r j =1: l a r g o P a r t i c i o n i f j+i <l e n g t h ( s o n i d o ) y ( j )=s o n i d o ( i+j ) . end f o r i =1: l a r g o P a r t i c i o n : l e n g t h ( s o n i d o ) y=z e r o s ( 1 . Fs]= F o u r i e r F a c i l ( ruta .m)+ abs ( f o u ( p o s i c i o n e s F r e c u e n c i a s (m)+k ) ) ˆ2 end end end c o e f i c i e n t e s ( aqum . b i t s ]= wavread ( r u t a o r i g e n ) . y=y ( 1 . − 1 . 1 5 . 1 0 0 0 0 . c o l ) c o e f i c i e n t e s=F o u r i e r P a r t e s ( ruta . y=y ( 1 . 1 . p o s i c i o n e s F r e c u e n c i a s=z e r o s ( 1 . f o r i =1: hasta−d e s d e s o n i d o ( i )=y ( i+d e s d e ) . h a s t a +1) . : ) . f r e c u e n c i a s ) endfunction f u n c t i o n c o e f i c i e n t e s= F o u r i e r P a r t e s ( r u t a o r i g e n .m) ) end 251 . − 1 . j=j * Fs / ( l e n g t h ( f o u ) ) . end [ y . aqum=1. i f hasta <0 h a s t a=l e n g t h ( y ) −2. end end end end f o r m=1: l e n g t h ( f r e c u e n c i a s ) c o e f i c i e n t e s ( aqum . l arg oAu dio .m) =0. hasta . length ( frecuencias ) ) . f o r k=−1:1 i f ( p o s i c i o n e s F r e c u e n c i a s (m)+k>0) i f ( p o s i c i o n e s F r e c u e n c i a s (m)+k<=l e n g t h ( f o u ) ) c o e f i c i e n t e s ( aqum . desde . l e n g t h ( f r e c u e n c i a s ) ) . f o r m=1: l e n g t h ( f r e c u e n c i a s ) f o r n=1: l e n g t h ( f o u )−1 i f j ( n )< =f r e c u e n c i a s (m) i f j ( n+1)>f r e c u e n c i a s (m) p o s i c i o n e s F r e c u e n c i a s (m)=n . f r e c u e n c i a s ) [ y . b i t s ]= wavread ( r u t a o r i g e n . l a r g o P a r t i c i o n . hasta−d e s d e ) .

e j e=e j e * l a r g o P a r t i c i o n / Fs . j +1) i f j<=l e n g t h ( f r e c u e n c i a s ) p l o t 2 d ( e j e .max( e j e ) . 0 ) plot2d ( j . 9 5 . f o r k=1: l e n g t h ( z ( 1 . z=z e r o s ( 1 . k )>valorMaximo valorMaximo=z ( 1 . end s a l i d a =0.aqum=aqum+1. end end f o r k=−25:25 i f kMaximo+k>0 z ( 1 . numeroPicos . end end endfunction f u n c t i o n [ P i c o s . colorGraf ) P i c o s=z e r o s ( 1 . end y=y ( 1 . i ) ) end j =0: c a n t i d a d −1 j=j * Fs / ( 2 * c a n t i d a d ) maximo=max( z ( 1 . c a n t i d a d ) f o u= f f t ( y ) f o r i =1: l e n g t h ( f o u ) /2 z (1 . − 0 . c a n t i d a d M u e s t r a s ) . i )=s q r t ( z ( 1 . e j e =0: l e n g t h ( c o e f i c i e n t e s ) / l e n g t h ( f r e c u e n c i a s ) −1. c o e f i c i e n t e s ( : . f o r i =1: numeroPicos valorMaximo =0.1+ round ( 2 * i * ( c a n t i d a d −1)/ l e n g t h ( f o u ) ) ) )+abs ( f o u ( i ) ) ˆ2 end f o r i =1: l e n g t h ( z ) z ( 1 . j ) ) / 0 . aqum=1.1+ round ( 2 * i * ( c a n t i d a d −1)/ l e n g t h ( f o u ) ) )= abs ( z (1 .05 * max( e j e ) / 0 . c o l . l a r g o A u d i o=l e n g t h ( y ) . end i f c a n t i d a d M u e s t r a s <0 [ y . ( z ( 1 .max( c o e f i c i e n t e s ( : . j ) ) ] ) . d i v i s i o n e s =15 i =1 f o r j =1: d i v i s i o n e s x s e t ( ’ window ’ . r e c t= [ −0. b i t s ]= wavread ( entrada . c a n t i d a d M u e s t r a s . kMaximo=k . Fs . : ) ) x s e t ( ’ window ’ . c o l o r G r a f ) i f cantidadMuestras > 0 [ y . kMaximo=0. j ) . : ) ) / cantidad . kMaximo+k ) =−1. : ) . numeroPicos ) . 0 5 * max( c o e f i c i e n t e s ( : . c a n t i d a d . la rgoA udi o . Fs . k ) . 252 . Fs]= F o u r i e r F a c i l ( entrada . 9 5 . : ) ) i f z ( 1 . b i t s ]= wavread ( e n t r a d a ) .

end end P i c o s ( i )=j ( kMaximo ) .sci 253 . end endfunction scilab/haceGraficas.

y=y . b i t s ]= wavread ( ru taE ntra da ) t =1: l e n g t h ( y ) . Fs . magnitud ) [ y .sci 254 . * (1+ magnitud * c o s ( 2 * %pi * f r e c u e n c i a * t / Fs ) ) y=y/max( abs ( y ) ) wavwrite ( y . f r e c u e n c i a . Fs .Efecto chorus f u n c t i o n E f e c t o C h o r u s ( rutaEntrada . r u t a S a l i d a . r u t a S a l i d a ) endfunction scilab/efectosScilab/efectoChorus.

sci 255 . Fs . r u t a S a l i d a .Efecto delay f u n c t i o n E f e c t o D e l a y ( rutaEntrada . b i t s ]= wavread ( ru taE ntra da ) c a n t i d a d=round ( Fs * d e l a y ) +1. Fs . del ay . magnitudes ) [ y . f o r j =1: l e n g t h ( magnitudes ) f o r i=j * c a n t i d a d +1: l e n g t h ( y ) y ( i )=y ( i )+magnitudes ( j ) * y ( i −j * c a n t i d a d ) end end y=y/max( abs ( y ) ) wavwrite ( y . r u t a S a l i d a ) endfunction scilab/efectosScilab/efectoDelay.

r u t a S a l i d a ) endfunction scilab/efectosScilab/efectoEco.sci 256 . magnitud ) [ y . Fs . r u t a S a l i d a . dela y . b i t s ]= wavread ( ru taE ntra da ) c a n t i d a d=round ( Fs * d e l a y ) +1. f o r i=c a n t i d a d +1: l e n g t h ( y ) y ( i )=y ( i )+magnitud * y ( i −c a n t i d a d ) end y=y/max( abs ( y ) ) wavwrite ( y .Efecto eco f u n c t i o n E f e c t o E c o ( rutaEntrada . Fs .

r e t r a s o . z e r o s ( 1 . i f ( u ( i ) <1) u ( i ) =1. Fs . f o r i =1: l e n g t h ( t ) u ( i )=u ( i )−round ( maxRetraso * (1+ c o s ( 2 * %pi * f r e c u e n c i a * t ( i ) / Fs ) ) / 2 ) . f r e c u e n c i a . r u t a S a l i d a . p rof und ida d . r u t a S a l i d a ) endfunction scilab/efectosScilab/efectoFlanger. a g r e g a r ) [ y .Efecto flanger function u=E f e c t o F l a n g e r ( rutaEntrada .sci 257 . wavwrite ( y . end y=y/max( abs ( y ) ) . b i t s ]= wavread ( ru taE ntra da ) y=[y ( 1 . end end f o r i =1: l e n g t h ( y ) y ( i )=y ( i )+p r o f u n d i d a d * y ( u ( i ) ) . Fs . a g r e g a r ) ] maxRetraso=Fs * r e t r a s o . : ) . t =1: l e n g t h ( y ) . u=t .

sci 258 . l i m i t e ) [ x . Fs . end i f x ( i )<−l i m i t e x ( i )=−l i m i t e . b i t s ]= wavread ( ru taE ntra da ) . r u t a S a l i d a ) . Fs . end end wavwrite ( x . r u t a S a l i d a . x=x/max( abs ( x ) ) f o r i =1: l e n g t h ( x ) i f x ( i )>l i m i t e x ( i )=l i m i t e . endfunction scilab/efectosScilab/efectoLimitador.Efecto limitador if f u n c t i o n l i m i t a d o r ( rutaEntrada .

r u t a S a l i d a . b i t s ]= wavread ( ru taE ntra da ) . wavwrite ( x . c o e f i c i e n t e ) [ x .Efecto limitador logar´ ıtmico f u n c t i o n l i m i t a d o r F u n c i o n ( rutaEntrada . endfunction scilab/efectosScilab/efectoLimitadorLog. Fs . Fs . x=x−(x . x=x/max( abs ( x ) ) . r u t a S a l i d a ) .sci 259 . ˆ 3 ) * c o e f i c i e n t e .

y=y . r u t a S a l i d a . b i t s ]= wavread ( ru taE ntra da ) t =1: l e n g t h ( y ) . Fs .Efecto vibrato f u n c t i o n E f e c t o V i b r a t o ( rutaEntrada . Fs . r u t a S a l i d a ) endfunction scilab/efectosScilab/efectoVibrato. * (1+ magnitud * c o s ( 2 * %pi * f r e c u e n c i a * t / Fs ) ) y=y/max( abs ( y ) ) wavwrite ( y . magnitud ) [ y . f r e c u e n c i a .sci 260 .

5 + 0 . end y=y/max( abs ( y ) ) . v a r i a c i o n .sci 261 . endfunction scilab/efectosScilab/efectoWahWah. f o r i =3: l e n g t h ( y ) . maximo ) [ x . t =1: l e n g t h ( x ) . minimo . f o r i =1: l e n g t h ( y ) p o t e n c i a=p o t e n c i a+y ( i ) ˆ 2 . wavwrite ( y . r u t a S a l i d a . r u t a S a l i d a ) . l e n g t h ( x ) ) . y=z e r o s ( 1 . 5 * c o s ( 2 * %pi * v a r i a c i o n * t / Fs ) ) . b i t s ]= wavread ( ru taE ntra da ) . y ( i ) =(y ( i −1) * (2+ s q r t ( 2 ) * f r e c u e n c i a C o r t e ( i ) )−y ( i −2)+ ( f r e c u e n c i a C o r t e ( i ) ˆ 2 ) * x ( i ) ) /(1+ s q r t ( 2 ) * f r e c u e n c i a C o r t e ( i )+ f r e c u e n c i a C o r t e ( i ) ˆ2) end p o t e n c i a =0. Fs . f r e c u e n c i a C o r t e =2* %pi * f r e c u e n c i a C o r t e . Fs . f r e c u e n c i a C o r t e=minimo+(maximo−minimo ) * ( 0 .Efecto Wah-Wah f u n c t i o n p o t e n c i a=WahWah( rutaEntrada .

posDato =0. unsigned short i n t v e l o c i d a d e s [ armonicos ] . unsigned short i n t tiempos [ armonicos ] . OPTION REG=0. u n s i g n e d s h o r t i n t nota . PORTB=0. void agregarNota ( ) { i f ( f u n c i o n A c t u a l >143) { i f ( d a t o s F u n c i o n [1]==0) { datosFuncion [0]= datosFuncion [ 1 ] . unsigned i n t t o t a l I n t . nota =0. GIE=1. f o r ( i =0. aux++. f o r ( i =1. c´digos de la prueba previa o Clase ’main’ #d e f i n e c u e n t a 132 #d e f i n e a r m o n i c o s 3 c o n s t s h o r t i n t s e n [ ] // Esta t a b l a no f u e impresa . PIE1 . } nota=d a t o s F u n c i o n [ 0 ] . v e l o c i d a d e s [0]= datosFuncion [ 1 ] . t o t a l I n t =1234. s h o r t i n t bandera . i <a r m o n i c o s . i ++){ 262 . INTCON. INTCON. RCIE=1. SPBRG=25. } v o i d main ( ) { short int total . PORTB=0. dado que s o l o e s una t a b l a de 128 n´ meros ( ya f u e e x p l i c a d a ) . aux=(& t o t a l I n t ) . TMR0=c u e n t a . i ++){ t o t a l I n t=v e l o c i d a d e s [ i −1] * c o e f A r m o n i c o s [ i − 1 ] . } nota =0. F5=0. TXSTA=36. v e l o c i d a d e s [ i ]= * aux . TRISB=128. PEIE=1. INTCON. coefArmonicos [1]=127. RCSTA=144. unsigned short i n t tot . coefArmonicos [0]=127. unsigned short i n t coefArmonicos [ armonicos ] .Anexo F. unsigned short i n t datosFuncion [ 2 ] . unsigned short i n t funcionActual . s h o r t i n t * aux . s h o r t i n t posDato . u short int i . } return . i <a r m o n i c o s .

t o t a l I n t=t o t a l I n t+v e l o c i d a d e s [ 2 ] * s e n [ t i e m p o s [ 2 ] ] . } } } void i n t e r r u p t ( ) { i f ( PIR1 . t o t a l I n t =32768. TXIF==0){} TXREG=*aux . PORTB++. t o t a l I n t=t o t a l I n t+v e l o c i d a d e s [ 1 ] * s e n [ t i e m p o s [ 1 ] ] . } while (1) { i f (INTCON. PORTA=*aux .c 263 . } i f ( bandera==2){ agregarNota ( ) . TMR0=c u e n t a .velocidades [ i ]=0. } i f ( ( posDato==2) | | ( f u n c i o n A c t u a l <144 && posDato==1)) { bandera =2. RCIF==1){ u n s i g n e d s h o r t i n t d a t o s R e c i b i d o s=RCREG. t o t a l I n t=t o t a l I n t+v e l o c i d a d e s [ 0 ] * s e n [ t i e m p o s [ 0 ] ] . posDato =0. F2=0. t i e m p o s [ 0 ] = t i e m p o s [ 0 ] + nota . bandera =0. F2==1){ INTCON. RBIF=0. w h i l e ( PIR1 . } } INTCON. t i e m p o s [ 2 ] = t i e m p o s [ 2 ] + 3 * nota . i f ( d a t o s R e c i b i d o s >126) { f u n c i o n A c t u a l=d a t o s R e c i b i d o s . posDato++. } progPruePrevia/main. t i e m p o s [ 1 ] = t i e m p o s [ 1 ] + 2 * nota . } else { d a t o s F u n c i o n [ posDato ]= d a t o s R e c i b i d o s .

Width ) Dim h a s t a J As I n t e g e r = CInt ( 0 . Height ) Dim f o t o 2 As New Bitmap ( h a s t a I − d e s d e I . 1 2 5 * f o t o . j − desdeJ . ” r e d u c i d o . ” . Height ) Dim h a s t a I As I n t e g e r = CInt ( 0 . h a s t a J − desdeJ ) Dim i As I n t e g e r Dim j As I n t e g e r For i = d e s d e I To h a s t a I − 1 For j = desdeJ To h a s t a J − 1 f o t o 2 . Object . S e t P i x e l ( i − d e s d e I . GetPixel ( i . bmp” a b r i r . I n f o r m a t i o n ) Catch ex As E x c e p t i o n MsgBox ( ” E r r o r en l a r e d u c c i \ ’ on” . c´digos del software ”‘reduce Im´genes”’ o a Clase ’reduceImagenes. C r i t i c a l ) End Try End Sub End C l a s s reduceImagenes/apli/WindowsApplication1/reduceImagenes. ByVal e As System . ” ) f o t o 2 .vb’ Public Class reduceImagenes P r i v a t e Sub B R e d u c i r C l i c k ( ByVal s e n d e r As System . R ep l ac e ( ” . F i l t e r = ”mapas de b i t s ( * . AddExtension = True a b r i r . FileNames . FileNames ( k ) r u t a = r u t a . f o t o . 8 8 * f o t o . EventArgs ) Handles BReducir . Width ) Dim desdeJ As I n t e g e r = CInt ( 0 . M u l t i s e l e c t = True a b r i r .vb 264 . 8 8 * f o t o . Length − 1 Dim f o t o As Bitmap = New Bitmap ( a b r i r . C l i c k Try Dim k As I n t e g e r Dim a b r i r As New O p e n F i l e D i a l o g a b r i r . j ) ) Next Next Dim r u t a As S t r i n g = a b r i r . MsgBoxStyle . 1 2 5 * f o t o . Save ( r u t a ) Next MsgBox ( ”La r e d u c c i \ ’ on f i n a l i z \ ’ o s a t i s f a c t o r i a m e n t e ” . FileNames ( k ) ) Dim d e s d e I As I n t e g e r = CInt ( 0 . bmp) | * . ShowDialog ( ) For k = 0 To a b r i r . MsgBoxStyle .Anexo G.

Sign up to vote on this title
UsefulNot useful