Algoritmos y Programacion I (75.02) - web.fi.uba.arweb.fi.uba.ar/~fferrari/tps/[75.02 - Algoritmos y...

60
Universidad de Buenos Aires Facultad De Ingenier ´ ıa no 2012 - 1 er Cuatrimestre Algoritmos y Programaci ´ on I (75.02) TRABAJO PR ´ ACTICO N 3 TEMA: Sintetizador de m´ usica FECHA: 30 de agosto de 2012 INTEGRANTES: Ferrari Bihurriet, Francisco - #92275 <franferra 09 [email protected]> Arias, Francisco Nicolas - #93459 <[email protected]> 75.02 - Algoritmos y Programaci´ on I Ing. Mart´ ın Cardozo

Transcript of Algoritmos y Programacion I (75.02) - web.fi.uba.arweb.fi.uba.ar/~fferrari/tps/[75.02 - Algoritmos y...

Universidad de Buenos AiresFacultad De Ingenierıa

Ano 2012 - 1er Cuatrimestre

Algoritmos y Programacion I (75.02)

TRABAJO PRACTICO Nº 3TEMA: Sintetizador de musicaFECHA: 30 de agosto de 2012

INTEGRANTES:Ferrari Bihurriet, Francisco - #92275

<franferra 09 [email protected]>

Arias, Francisco Nicolas - #93459<[email protected]>

75.02 - Algoritmos y Programacion I Ing. Martın Cardozo

INDICE

Indice

1. Enunciado 3

2. Estructura Funcional 11

3. Consideraciones y Estrategias 123.1. Validacion de datos y lectura de archivos de entrada . . . . . . . . . . . . . 123.2. Sıntesis del sonido . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123.3. Escritura en del archivo de salida en formato WAV . . . . . . . . . . . . . 12

4. Resultados de ejecucion 134.1. En condiciones inesperadas de entrada . . . . . . . . . . . . . . . . . . . . 134.2. En condiciones normales de entrada . . . . . . . . . . . . . . . . . . . . . . 15

5. Problemas encontrados en el desarrollo 175.1. Optimizacion del tiempo de sıntesis . . . . . . . . . . . . . . . . . . . . . . 175.2. Funciones de modulacion incorrectas . . . . . . . . . . . . . . . . . . . . . 18

6. Conclusiones 18

7. Bibliografıa consultada 18

8. Codigos fuente 198.1. ADT musical score . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19

8.1.1. ADT musical score.h . . . . . . . . . . . . . . . . . . . . . . . . . . 198.1.2. ADT musical score PRIVATE.h . . . . . . . . . . . . . . . . . . . . 208.1.3. ADT musical score.c . . . . . . . . . . . . . . . . . . . . . . . . . . 22

8.2. ADT synthesizer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278.2.1. modulationlib.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278.2.2. modulationlib.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 288.2.3. ADT synthesizer.h . . . . . . . . . . . . . . . . . . . . . . . . . . . 318.2.4. ADT synthesizer PRIVATE.h . . . . . . . . . . . . . . . . . . . . . 328.2.5. ADT synthesizer.c . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

8.3. ADT wav file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408.3.1. ADT wav file.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 408.3.2. ADT wav file PRIVATE.h . . . . . . . . . . . . . . . . . . . . . . . 408.3.3. ADT wav file.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42

8.4. main modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448.4.1. addsynthlib.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 448.4.2. addsynthlib.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 458.4.3. common.h . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 488.4.4. main.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

8.5. langs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 558.5.1. msgs dictionary es.c . . . . . . . . . . . . . . . . . . . . . . . . . . 558.5.2. msgs dictionary en.c . . . . . . . . . . . . . . . . . . . . . . . . . . 56

1

INDICE

8.6. Makefile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 578.6.1. Makefile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 578.6.2. lang . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

2

1 Enunciado

1. Enunciado

Trabajo Practico N◦3 - Sintetizador de musica

1. Objetivo del TP

El objetivo del presente trabajo consiste en la realizacion de un aplicativo en modoconsola, escrito en ANSI-C89, que secuencie archivos WAVE en base a la especificacionde un sintetizador y una partitura musical.

2. Alcance del TP

Mediante el presente TP se busca que el Estudiante adquiera y aplique conocimientossobre los siguientes temas:

Argumentos en Lınea de Ordenes (CLA).

Makefile y proyectos modularizados.

TDAs.

Memoria dinamica.

Archivos de texto y binarios.

Formato WAVE (audio).

Punteros a Funciones.

3. Introduccion

3.1. El sonido

La percepcion que sentimos como sonido se debe a la vibracion de ondas en el aireque es sensada por nuestros oidos. En los sonidos podemos distinguir una intensidad, porla cual hay sonidos mas fuertes que otros; un tono, por el cual hay sonidos mas agudosy sonidos mas graves; y un timbre, por el cual no todas las cosas que tienen el mismotono suenan igual.

Supongamos una onda de 110Hz que oscila durante un cuarto de segundo (Fig. 1).Esta onda es sencilla de concebir matematicamente, pero es imposible de obtener pormedios fısicos.

Una onda fısica no podrıa comenzar a oscilar instantaneamente, ni tampoco podrıaatenuarse inmediatamente. Si oyeramos una onda de esas caracterısticas, percibirıamosun chasquido al comienzo y al final de la misma1. Una onda producida por un elementofısico tendra un incremento paulatino hasta su maximo producido por el ataque y suentrada en resonancia, ira apaciguandose por disipacion de energıa durante el sostenido,

1Le dejamos hacer al Analisis de Fourier las cuentas pertinentes.

1

3

1 Enunciado

Algoritmos y Programacion I (75.02) – Trabajo Practico N◦3 – 1er Cuatr. 2012

-1

-0.5

0

0.5

1

-0.05 0 0.05 0.1 0.15 0.2 0.25 0.3

Figura 1: Onda sinusoidal de 110Hz de duracion 0,25s.

-1

-0.5

0

0.5

1

-0.05 0 0.05 0.1 0.15 0.2 0.25 0.3

Figura 2: 0 < t < 0,05: Ataque. 0,05 < t < 0,25: Sostenido. t > 0,25: Decaimiento.

y luego tardara unos instantes en volverse a poner en reposo durante el decaimiento (Fig.2).

Hasta ahora tenemos una onda pura y, como ya deberıa ser predecible, tampoco lasondas puras son lo que abunda en la naturaleza2. La mayor parte de los dispositivos,ademas de vibrar con la frecuencia fundamental que percibimos como tono vibran enmultiplos de la misma, llamados armonicos o en frecuencias parasitas. Ni siquiera instru-mentos como un diapason son capaces de entregar un sonido puro. Las ondas generadaspor un instrumento oscilaran a una frecuencia dada por su tono, y generaran resonanciasen diferentes armonicos con menor amplitud (Fig. 3).

Juntando el tono, dado por la frecuencia fundamental; la intensidad, modulada porel ataque-sostenido-decaimiento y el timbre, dado por la adicion de armonicos; una ondade 110Hz producida por un instrumento real, tendrıa un aspecto similar al de la Figura4.

2¡Por suerte!, un aburrido ejemplo cotidiano de sonido puro son los pulsos del telefono.

-1

-0.5

0

0.5

1

0 0.001 0.002 0.003 0.004 0.005 0.006 0.007 0.008 0.009

Figura 3: Sıntesis aditiva de una onda (rojo) en base a una frecuencia fundamental de110Hz (verde) y 7 armonicos (azules). Este timbre podrıa imitar el de una flauta.

2

4

1 Enunciado

Algoritmos y Programacion I (75.02) – Trabajo Practico N◦3 – 1er Cuatr. 2012

-1

-0.5

0

0.5

1

-0.05 0 0.05 0.1 0.15 0.2 0.25 0.3

Figura 4: Onda de 110Hz sintetizada en tono, intensidad y timbre.

Nota Cifrado americano Octava Frecuencia (Hz)La A 4 220,000La] A] – B[ 4 233,082Si B 4 246,942Do C 4 261,626Do] C] – D[ 4 277,183Re D 4 293,665Re] D] – E[ 4 311,127Mi E 4 329,629Fa F 4 349,228Fa] F] – G[ 4 369,994Sol G 4 391,995Sol] G] – A[ 4 415,305La A 5 440,000

Tabla 1: Frecuencias para la cuarta octava (afinacion 440).

3.2. La escala musical

La musica se genera en base a sonidos. Ahora bien, para que la misma suene agradableal oido, se construyen escalas que fijan que tonos estan permitidos. Todas las escalasse construyen en base a particiones de la octava, y luego se replican en las octavassubsiguientes3. Se considera que hay una octava entre dos notas donde una duplica lafrecuencia de la otra.

Las escalas occidentales son dodecafonicas, se construyen en base a 12 particionesequidistantes de una octava4. Ademas, se fija que la nota La de la quinta octava oscilaa 440Hz5. Las notas de la escala son Do, Do] (o Re[6), Re, Re] (o Mi[), Mi, Fa, Fa](o Sol[), Sol, Sol] (o La[), La, La] (o Si[) y Si, en ese orden.

Por razones de simplificar la notacion, introduciremos el cifrado americano. En elmismo a cada nota se le asigna una letra entre la A y la G, comenzando por la nota Lay continuando cıclicamente a la octava siguiente.

Sabiendo que hay 12 notas, equidistantes exponencialmente7, que el La de la quintase fija en 440Hz, que las octavas avanzan duplicando, y el nombre de las notas, podemosreconstruir la frecuencia para cualquier nota dada. La Tabla 1 muestra un ejemplo deello.

3Para esto y lo demas que desarrollemos en el capıtulo, le pasamos a Pitagoras el fardo de dar lasexplicaciones.

4Mas o menos, y si bien esto no es valido para la teorıa estricta o para algunos instrumentos, sı lo espara la mayorıa.

5Si el comite ISO lo dice, no vamos a contradecirlo.6Otra vez, sin ponerse exquisitos ni dar vueltas innecesarias con comas y otras yerbas.7Es decir, si una nota tiene frecuencia f , la nota siguiente tendra frecuencia f · 12

√2.

3

5

1 Enunciado

Algoritmos y Programacion I (75.02) – Trabajo Practico N◦3 – 1er Cuatr. 2012

char[4] ChunkId Vale "RIFF"

uint32 ChunkSize 36 + 2nchar[4] Format Vale "WAVE"

char[4] Subchunk1ID Vale "fmt "

uint32 Subchukn1Size Vale 16

uint16 AudioFormat Vale 1

uint16 NumChannels Vale 1

uint32 SampleRate 8000, 44100, etc.uint32 ByteRate 2× SampleRateuint16 BlockAlign Vale 16

uint16 BitsPerSample Vale 16

char[4] SubChunk2ID Vale "data"

uint32 SubChunk2Size 2n

int16[n] Data Secuencia de n muestras

Figura 5: Contenido binario de un archivo WAVE PCM monoaural de 16bits.

3.3. El formato WAVE

El formato WAVE forma parte de la especificacion RIFF de Microsoft. El mismopermite almacenar en modo raw sin compresion muestras de audio.

Un archivo WAVE es un archivo binario compuesto por un preambulo, y dos chunks.El primero de ellos es de tamano fijo, y contiene la informacion acerca de las caracterısti-cas del track ; mientras que el segundo contiene las muestras de audio que componen almismo.

Para este trabajo se utilizara la compresion PCM (esto es, sin compresion), 16 bitsde resolucion y formato monoaural. El contenido binario de un archivo WAVE de estascaracterısticas es el de la Tabla 5.

Tanto los numeros de 16 bits como de 32 en el formato WAVE, se almacenan enel archivo en formato little endian. Las muestras se almacenan como enteros de 16 bitsen complemento a 2, puede asumirse que es el mismo formato que utiliza C. No puedeasumirse bajo ningun punto de vista el endianness de la plataforma.

4. Desarrollo del TP

El trabajo practico consistira en un ejecutable en modo consola que pueda realizarla sıntesis sobre un archivo WAVE en base a la configuracion de un sintetizador y unasecuencia de notas.

La sintaxis de ejecucion sera:

$ ./sintetizador [-f <frecuencia>] -p <partitura.txt> -s <sintetizador.txt> -o <audio.wav>

> sintetizador [-f <frecuencia>] -p <partitura.txt> -s <sintetizador.txt> -o <audio.wav>

La especificacion de los parametros se encuentra en la Tabla 2.

4.1. Archivo de partitura

El archivo de partitura, sera un archivo ASCII donde cada lınea representara unanota a ser ejecutada.

Cada lınea contendra un tiempo de inicio de la ejecucion de la nota, la nota a in-terpretar y la duracion. Todos los tiempos se especificaran en segundos. Las notas se

4

6

1 Enunciado

Algoritmos y Programacion I (75.02) – Trabajo Practico N◦3 – 1er Cuatr. 2012

Parametro Valores-p Nombre del archivo de entrada que describe la partitura.-s Nombre del archivo de entrada que describe el sintetizador.-o Nombre del archivo de salida WAVE.-f Frecuencia de muestreo. Una de: 8000, 9600, 11025, 12000,

16000, 22050, 24000, 32000, 44100, 48000, 88200, 96000.(optativo)

Tabla 2: Parametros de CLA.

especificaran en cifrado americano, utilizando el sufijo “s” para notas sostenidas (]) y“b” para notas bemoles ([) y su octava correspondiente.

Por ejemplo:

0 A4 .5

.5 Bb4 .5

1 B4 .5

1.5 C4 .5

2 Cs4 .5

2.5 D4 .5

Describe una secuencia de semitonos de medio segundo de duracion, desde el La hastael Re de la cuarta octava. La duracion de la ejecucion del fragmento sera de 3 segundos.

En el archivo se desconoce la cantidad de notas a ejecutar, y no es requisito que elmismo venga ordenado cronologicamente (tampoco hace falta).

4.2. Archivo de sintetizador

El archivo de sintetizador, sera un archivo ASCII con informacion sobre los armoni-cos, y las envolventes para modular la amplitud.

El archivo de sintetizador estara dividido en cuatro partes:

Armonicos, donde se especificara el numero de armonicos y luego pares de multiplo eintensidad.

Ataque, donde se especificara el tipo de ataque y luego los parametros.

Sostenido, donde se especificara el tipo de sostenido y luego los parametros.

Decaimiento, donde se especificara el tipo de decaimiento y luego los parametros.

Los moduladores de amplitud seran alguno de los de la Tabla 3.Por ejemplo, un archivo de sintetizador podrıa tener este contenido:

8

1 0.577501

2 0.577501

3 0.063525

4 0.127050

5 0.103950

6 0.011550

7 0.011550

8 0.011550

TRI 0.05 0.03 1.3

CONSTANT

INVLINEAR .02

5

7

1 Enunciado

Algoritmos y Programacion I (75.02) – Trabajo Practico N◦3 – 1er Cuatr. 2012

Nombre Ecuacion Parametros Uso enCONSTANT f(t) = 1 – SLINEAR f(t) = t

t0t0 A

INVLINEAR f(t) = max{

1− tt0

; 0}

t0 S, D

SIN f(t) = 1 + a sen(ft) a, f S

EXP f(t) = e5(t−t0)

t0 t0 A

INVEXP f(t) = e−5tt0 t0 S, D

QUARTCOS f(t) = cos(πt2t0

)t0 S, D

QUARTSIN f(t) = sen(πt2t0

)t0 A

HALFCOS f(t) =1+cos

(πtt0

)2 t0 S, D

HALFSIN f(t) =1+sen

(π(tt0− 1

2

))2 t0 A

LOG f(t) = log10

(9tt0

+ 1)

t0 A

INVLOG f(t) =

{log10

(−9tt0

+10)

t<t0,

0 t≥t0.t0 S, D

TRI f(t) =

{ ta1t1

t<t1,

t−t1t1−t0 + a1 t>t1.

t0, t1, a1 A

PULSES f(t′) = mın{| 1−a1t1

(t′ − t0 + t1)|+ a1; 1},t′= t

t0−b tt0 c t0, t1, a1 S

Tabla 3: Moduladores de amplitud. Para su uso en A: Ataque, S: Sostenido, D: Decai-miento.

En el se define la progresion de 8 armonicos en octavas8, un ataque TRI de duracion0,05s, un sostenido CONSTANT y un decaimiento INVLINEAR de duracion 0,02s.

4.3. Sıntesis

La sıntesis del sonido se realizara para cada nota por separado, realizando una adicionsobre el audio de las demas notas.

Dada una nota que comienza en el instante t0, de frecuencia f y duracion d, con unsintetizador con una serie de n armonicos donde estan definidos sus multiplos Mi y susintensidades Ii, ademas de sus funciones de ataque fa, sostenimiento fs y decaimientofd, se procede como sigue.

El timbre del instrumento se obtiene de computar la siguiente expresion:

y(t) =n∑

i=1

Ii sen (2πfMi(t− t0))

Esto nos da una senal infinita, la misma sera ajustada segun la modulacion de amplitud.La modulacion de amplitud se compone por la concatenacion de ataque, sostenido y

decaimiento. Antes de explicar como se combinan, vale observar que todas las funcionespara ser usadas como ataque, recorren un camino de 0 a 1 en un tiempo t0, todaslas funciones de decaimiento recorren el camino inverso en un tiempo t0, y todas lasfunciones de sostenido comienzan en 1 y son siempre positivas. Esto es importante paracomprender como se las empalma.

Una nota no puede durar nunca menos que el tiempo de ataque ta, una vez finali-zada la nota, se ejecuta el decaimiento, de tiempo td. Luego, la funcion de modulacion

8Estos armonicos, casualmente, son los mismos de la Figura 3.

6

8

1 Enunciado

Algoritmos y Programacion I (75.02) – Trabajo Practico N◦3 – 1er Cuatr. 2012

estara dada por:

m(t) =

fa(t− t0) t0 < t < t0 + tafs(t− (t0 + ta)) t0 + ta < t < t0 + dfs(t0 + d)fd(t− (t0 + d)) t0 + d < t < t0 + d+ td0 Para otro t

Observar que la misma es una funcion continua.Finalmente, la amplitud de la nota estara dada por:

a(t) = Ay(t)m(t)

Esta funcion sera distinta de cero como mucho en el intervalo t0 < t < t0 + d + td. Laconstante A debe ser elegida convenientemente para darle el volumen a nuestro instru-mento; al elegirla notar que un valor pequeno va a hacer que al truncar sobre 16bits sepierdan muchos valores intermedios, y notar que un valor muy grande puede hacer quela adicion de varias notas genere un desbordamiento, lo cual en el audio se va a traduciren una saturacion del sonido.

El unico paso que resta para llevar estas notas a un archivo WAVE es muestrear estasondas segun la frecuencia dada. Dicha discretizacion debe hacerse en tantas muestras porsegundo como las indicadas en la frecuencia de muestreo fm, con t variando en intervalosde 1/fm.

5. Restricciones

La realizacion de los programas pedidos esta sujeta a las siguientes restricciones:

Deben utilizarse TDAs tanto en los contenedores como en las entidades que ası lorequieran.

Debe recurrirse al uso de punteros a funciones a fin de parametrizar la eleccion delos moduladores.

Hay ciertas cuestiones que no han sido especificadas intencionalmente en este Re-querimiento, para darle al Desarrollador la libertad de elegir implementacionesque, segun su criterio, resulten mas convenientes en determinadas situaciones. Porlo tanto, se debe explicitar cada una de las decisiones adoptadas, y el o los funda-mentos considerados para las mismas.

6. Entrega del Trabajo Practico

Debera presentarse la correspondiente Documentacion de desarrollo del TP impre-sa y encarpetada, siguiendo la numeracion siguiente, incluyendo:

1. Caratula del TP. Incluir una direccion de correo electronico de contacto.

2. Enunciado del TP.

3. Estructura logica simplificada de los programas desarrollados (diagramas deflujo).

4. Estructura funcional de los programas desarrollados (Arbol de Funciones).

5. Explicacion de cada una de las alternativas consideradas y las estrategiasadoptadas.

7

9

1 Enunciado

Algoritmos y Programacion I (75.02) – Trabajo Practico N◦3 – 1er Cuatr. 2012

6. Resultados de la ejecucion (corridas) de los programas, captura de las panta-llas, bajo condiciones normales e inesperadas de entrada.

7. Resena sobre los problemas encontrados en el desarrollo de los programas ylas soluciones implementadas para subsanarlos.

8. Conclusiones.

NOTA: El Informe debera ser redactado en correcto idioma castellano, con tipo-grafıa Times New Roman, Arial, o Verdana, de tamano 11 para los parrafos, y 13o 14 para los tıtulos.

Debera entregarse una impresion de los codigos fuentes (implementacion y hea-ders) de los programas desarrollados. NO entregar archivos de codigos objeto y/oejecutables.

NOTA: Los codigos fuentes deberan ser impresos con tipografıa Monospace.

Debera entregarse el archivo Makefile del proyecto para el compilador C GCC-DJGPP.

Deberan entregarse por correo electronico a la casilla [email protected],todos los archivos fuentes y scripts necesarios para compilar el trabajo practico,ademas del informe en formato electronico. Dicho correo debera contener en sucuerpo el nombre, apellido y padron de los integrantes del grupo.

De no hacerse la entrega digital en tiempo y forma, el TP no sera corregido.

SI NO SE PRESENTA CADA UNO DE ESTOS ITEMS, SERA RECHAZADO EL TP

7. Bibliografıa

Debe incluirse la referencia a toda bibliografıa consultada para la realizacion delpresente TP: libros, artıculos, URLs, etc., citando:

Denominacion completa del material (Tıtulo, Autores, Edicion, Volumen, etc.).

Codigo ISBN del libro (opcional: codigo interbibliotecario).

URL del sitio consultado.

8

10

2 Estructura Funcional

2. Estructura Funcional

/* addsynthlib: 3 */evenlope()

/* ADT_musical_score: 1 */ADT_musical_score_new()

/* ADT_synthesizer: 1 */ADT_synthesizer_new()

/* ADT_wav_file: 1 */ADT_wav_file_create_from_vector()

/* addsynthlib: 1 */tabsin_create_table()

/* addsynthlib: 2 */tabsin_destroy_table()

/* ADT_musical_score: 2 */ADT_musical_score_destroy()

/* ADT_musical_score: 3 */ADT_musical_score_get_quantity_notes()

/* ADT_musical_score: 5 */ADT_musical_score_get_duration_at()

/* ADT_musical_score: 6 */ADT_musical_score_get_start_time_at()

/* ADT_synthesizer: 2 */ADT_synthesizer_destroy()

/* ADT_synthesizer: 5 */ADT_synthesizer_get_modulation_at()

/* ADT_wav_file: 2 */ADT_wav_file_destroy()

/* addsynthlib: 4 */synthesize()

/* ADT_musical_score: 8 */ADT_musical_score_get_frequency_at()

/* ADT_synthesizer: 3 */ADT_synthesizer_get_quantity_harmonics()

/* ADT_synthesizer: 4 */ADT_synthesizer_get_harmonic_at()

/* ADT_synthesizer: 5 */ADT_synthesizer_get_modulation_at()

/* ADT_musical_score: 3 */ADT_musical_score_get_quantity_notes()

/* ADT_musical_score: 6 */ADT_musical_score_get_start_time_at()

/* ADT_musical_score: 5 */ADT_musical_score_get_duration_at()

/* ADT_musical_score: 9 */ADT_musical_score_set_from_file()

/* ADT_musical_score: 2 */ADT_musical_score_destroy()

/* ADT_synthesizer: 6 */ADT_synthesizer_set_from_file()

/* ADT_synthesizer: 2 */ADT_synthesizer_destroy()

/* ADT_wav_file: 3 */ADT_wav_file_write()

/* ADT_wav_file: <interna> */_write_little_endian()

/* modulationlib */modulation_invlinear()

/* modulationlib */modulation_linear()

/* modulationlib */modulation_constant()

/* modulationlib */modulation_sin()

/* modulationlib */modulation_exp()

/* modulationlib */modulation_invexp()

/* modulationlib */modulation_quartcos()

/* modulationlib */modulation_quartsin()

/* modulationlib */modulation_halfcos()

/* modulationlib */modulation_halfsin()

/* modulationlib */modulation_log()

/* modulationlib */modulation_invlog()

/* modulationlib */modulation_tri()

/* modulationlib */modulation_pulses()

/* ADT_synthesizer: 5 */ADT_synthesizer_get_modulation_at()

/* ADT_musical_score: 5 */ADT_musical_score_get_duration_at()

main()

progress_msg()

status_msg()

show_usage()

validate_arguments()

11

3 Consideraciones y Estrategias

3. Consideraciones y Estrategias

Durante el desarrollo se opto por una eficiente modulacion mediante el uso de Tipos deDato Abstracto. Esto permitio una simplificacion del codigo del modulo principal (main),como tambien la posibilidad de aislar los modulos entre sı, facilitando la division de tareasentre los desarrolladores.

Para facilitar esta division de tareas y abordar el desarrollo, se tomo la estrategiade diseno Top-down, por lo que el problema principal se redujo en tres grandes bloquesdescriptos a continuacion.

3.1. Validacion de datos y lectura de archivos de entrada

Para la lectura de los archivos de entrada se disenaron dos TDAs especıficos, unodestinado al archivo de partitura y otro al de sintetizador. De esta manera, el bloqueprincipal nunca interactua directamente con los datos de entrada (de estos archivos, sı lohace con los argumentos en la lınea de ordenes).

Como consecuencia, el modulo principal dispone de la informacion previamente vali-dada, a traves de la claridad de las interfaces (getters y setters) de los TDAs.

3.2. Sıntesis del sonido

Para generar el audio se utilizo una biblioteca de sıntesis aditiva, con rutinas quepermiten sintetizar la partitura de manera completa, haciendo uso de los Tipos de Datodescriptos anteriormente.

Aquı fue necesario desarrollar una funcion que controle la envolvente de la senal, paraluego ser invocada por otra que realice la sıntesis final, haciendo una correcta adicion dearmonicos en cada nota de la partitura.

Ademas, en esta biblioteca se incluyen rutinas para hacer un “cacheo” de la funcionseno de la biblioteca math, con el fin de aumentar la eficiencia de la sıntesis. (Esto sera ex-plicado en detalle en la seccion 5.1).

3.3. Escritura en del archivo de salida en formato WAV

En cuanto al archivo de salida, de formato WAV monofonico, se diseno un tercer TDApara su manejo. Este permite la posibilidad de crear una instancia a partir de un vector demuestras en formato double, encargandose de la normalizacion del audio, para su correctarepresentacion en 16 bits.

En este TDA se incluyen ademas rutinas para la correcta escritura del archivo, cuyosenteros tienen formato little endian. Para esto se utiliza una funcion interna que es capaz deescribir en 16 o 32 bits, little endian, independientemente del endianness de la plataforma.

Ası es posible olvidarse del problema del formato de salida y manejar la sıntesis enun vector de double, asegurandose que la amplitud ‘nunca’ superara el rango maximo derepresentacion del tipo. Luego el audio sera normalizado, aprovechando todo este rango,sin problemas de saturacion u overflow.

12

4 Resultados de ejecucion

Para futuras utilizaciones en otros proyectos, se listo un conjunto de primitivas real-mente necesarias y utiles, que quedaron sin implementar, por lo que este TDA es el masincompleto de los tres.

4. Resultados de ejecucion

4.1. En condiciones inesperadas de entrada

Errores en los CLAs:

Archivos de entrada inexistentes:

13

4.1 En condiciones inesperadas de entrada

Archivos de entrada corruptos:

1. Incongruente cantidad de armonicos con los especificados luego en el archivode sintetizador:

2. Funciones de modulacion inexistentes o faltantes en el archivo de sintetizador:

14

4.2 En condiciones normales de entrada

3. Notas musicales inexistentes en el archivo de partitura (se consideraran comoC1, do de la primera octava):

4.2. En condiciones normales de entrada

Cancion realizada para la prueba (disponible en el directorio ‘test’ de la entregadigital):

15

4.2 En condiciones normales de entrada

Diferentes tipos de modulacion sobre una misma nota musical:

LINEAR 0.5; CONSTANT; HALFCOS 0.5

EXP 0.5; SIN 0.5 2; INVLOG 0.5

QUARTSIN 0.5; PULSES 1 0.25 0.5; INVLINEAR 0.5

HALFSIN 0.5; INVLINEAR 5; INVEXP 0.5

LOG 0.5; INVEXP 5; QUARTCOS 0.5

TRI 0.5 0.25 2; QUARTCOS 5; HALFCOS 0.5

16

5 Problemas encontrados en el desarrollo

5. Problemas encontrados en el desarrollo

5.1. Optimizacion del tiempo de sıntesis

Durante el desarrollo, una vez terminado el Tipo de Dato Abstracto Archivo WAV(mono), se continuo con algunas pequenas pruebas de sıntesis simple, sin consideracionde la envolvente ni de los armonicos, y generando archivos un tanto extensos.Ası fue que se observo un elevado tiempo de sıntesis, teniendo en cuenta que finalmente,por cada nota serıa necesario generar varias ondas como componentes armonicas de lasıntesis aditiva.Se saco la conclusion de que este elevado tiempo se debıa a una agresiva utilizacion de lafuncion sin() de la biblioteca math (funcion que a su vez realiza varias iteraciones ensu interior).

Fue entonces que surgio la estrategia de crear una tabla (cache) con los valores delseno a utilizar. Se decidio ajustar la ‘resolucion de tabulado’ en funcion de la frecuencia demuestreo, generando los valores correspondientes a una longitud de onda completa parauna onda de 1 Hz de frecuencia. El acceso a la tabla se hace mediante una aritmeticacıclica, que permite calcular el ındice a utilizar a partir de la variable independiente (eneste caso, el tiempo).

Esta tabla es inicializada una sola vez al comienzo de la ejecucion y es utilizada entodo el proceso, luego de la sıntesis la misma es destruida.

Junto con la idea de la tabulacion del seno (y ya teniendo en cuenta la adicion dearmonicos), surgio a posteriori la ocurrencia de hacer una tabulacion de la forma de on-da completa, realizando la sıntesis aditiva por unica vez y para todas las notas. Estosignificarıa un ahorro muy considerable en los tiempos de sıntesis. Pero se encontro unproblema, si los multiplos de la frecuencia fundamental (armonicos) fueran enteros estoserıa totalmente posible. Lamentablemente no es ası, una de las caracterısticas del sinteti-zador debe ser la de generar batidos por medio de multiplos fraccionarios, cosa que jamassucedera en el dominio de una sola longitud de onda de la fundamental.

En consecuencia se adopto la solucion intermedia, con el tabulado del seno y la sıntesisaditiva a traves de varios usos de la misma tabla. Otra posible solucion hubiera sidocalcular el tiempo de los batidos, muestrear en la tabla una onda de 1 Hz durante todoese tiempo, y finalmente reajustar el calculo del ındice de acceso.

A modo de resena se adjuntan los tiempos sobre pruebas de sıntesis realizadas paraun mismo archivo (igual duracion):

Uso exclusivo de la biblioteca math: 117 segundos

Utilizacion de la tabla para evitar la invocacion de sin(): 66 segundos

Utilizacion de la tabla para almacenar la forma de onda: 10 segundos

Puede observarse que a pesar de la inminente eficiencia de la ultima implementacion,la finalmente elegida implica un ahorro de mas del 40 % en el tiempo de sıntesis.

17

5.2 Funciones de modulacion incorrectas

5.2. Funciones de modulacion incorrectas

Se encontraron errores en las funciones de modulacion TRI y PULSES. A continuacionse presentan las versiones de estas funciones corregidas.

Funcion TRI: f(t) =

{ ta1t1

t ≤ t1a1−1t1−t0 (t− t0) + 1 t > t1

Funcion PULSES: f(t′) = mın{|1−a1

t1(2t′ − 1)t0|+ a1; 1

}, t′ = t

t0− b t

t0c

6. Conclusiones

El programa cuenta con soporte de multiples idiomas que se definen en tiempo decompilacion, mediante el uso de un archivo auxiliar incluido en el archivo Makefile. Eluso de make permite realizar proyectos muy profesionales y automatizados, aumentandoademas las cualidades de facilidad de uso y verificabilidad, ya que la compilacion se realizamediante un simple comando en el terminal, y los modulos sin modificaciones no soncompilados innecesariamente.

El uso de los TDAs en este trabajo ha sido fundamental, las posibilidades de reutili-zacion de los mismos en otras aplicaciones, la simplificacion de codigo, como tambien lasposibles futuras modificaciones a este programa lo hacen una herramienta fundamentalen la buena programacion en lenguaje C.

Cualidades de modularizacion, mantenibilidad, evolucionabilidad, y comprensibilidadse incrementan notablemente mediante la utilizacion de esta tecnica, que es lo mas cercanoa la Programacion Orientada a Objetos (OOP) que se puede lograr en el lenguaje C.

7. Bibliografıa consultada

The Not So Short Introduction to LATEX 2ε (Tobias Oetiker).URL: http://tobi.oetiker.ch/lshort/lshort.pdf

The Listings Package (Carsten Heinz - Brooks Moses).URL: ftp://ftp.tex.ac.uk/tex-archive/macros/latex/contrib/listings/listings.pdf

Fundamentals of Software Engineering (Ghezzi-Jazayeri-Mandrioli).ISBN-13: 978-0133056990

18

8 Codigos fuente

8. Codigos fuente

8.1. ADT musical score

8.1.1. ADT musical score.h

1 /* *****************************************************************************

2

3 Algoritmos y Programaci on I - 75.02/95.11 - Curso Ing. Mart ın Cardozo

4 TP N o 3 - 1er Cuatrimestre 2012

5

6 Alumnos: ARIAS , Francisco - FERRARI BIHURRIET , Francisco

7 Archivo: ADT_musical_score.h

8 Descrip: Encabezado pu blico para el TDA partitura musical.

9 Obs:

10

11 ***************************************************************************** */

12

13

14 #include "../ main_modules/common.h"

15

16 #if ndef ADT_MUSICAL_SCORE_H

17 #define ADT_MUSICAL_SCORE_H

18

19 typedef struct tnote tnote;

20

21 typedef struct ADT_musical_score_t ADT_musical_score_t;

22

23 typedef enum{

24

25 C=0,

26 Cs=1,

27 D=2,

28 Ds=3,

29 E=4,

30 F=5,

31 Fs=6,

32 G=7,

33 Gs=8,

34 A=9,

35 As=10,

36 B=11

37

38 }tone_t;

39

40 /* ******************************** Primitives ******************************** */

41

42

43 /* 1) Creador de partitura */

44 status_t ADT_musical_score_new(ADT_musical_score_t **);

45

46 /* 2) Destructor de partitura */

47 void ADT_musical_score_destroy(ADT_musical_score_t **);

48

19

8.1 ADT musical score

49 /* 3) Obtener la cantidad de notas. Precondicion: no debe recibir NULL */

50 size_t ADT_musical_score_get_quantity_notes(const ADT_musical_score_t* );

51

52 /* 4) Obtener la n-sima nota. En caso de fallar devuelve NULL.

53 PRECONDICION: SE DEBE TENER ACCESO AL ARCHIVO

54 ADT_musical_score_PRIVATE.h */

55 tnote* ADT_musical_score_get_note_at(const ADT_musical_score_t*, size_t);

56

57 /* 5) Obtener la duracion de la n-sima nota. Precondiciones:

58 I) No debe recibir puntero NULL

59 II) La posicion debe ser menor que la cant de notas */

60 double ADT_musical_score_get_duration_at(const ADT_musical_score_t*, size_t);

61

62 /* 6) Obtener el tiempo de inicio de la n-sima nota. Precondiciones:

63 I) No debe recibir puntero NULL

64 II) La posicion debe ser menor que la cant de notas */

65 double ADT_musical_score_get_start_time_at(const ADT_musical_score_t*, size_t);

66

67 /* 7) Obtener el tono de la n-sima nota. Precondiciones:

68 I) No debe recibir puntero NULL

69 II) La posicion debe ser menor que la cant de notas */

70 tone_t ADT_musical_score_get_tone_at(const ADT_musical_score_t*, size_t);

71

72 /* 8) Obneter la fracuencia de la n-sina nota

73 I) No debe recibir puntero NULL

74 II) La posicion debe ser menor que la cant de notas */

75 double ADT_musical_score_get_frequency_at(const ADT_musical_score_t*, size_t);

76

77 /* 9) Leer notas desde archivo */

78 status_t ADT_musical_score_set_from_file(ADT_musical_score_t **, string);

79

80 /* 10) Imprimir partitura */

81 status_t ADT_musical_score_print(const ADT_musical_score_t *);

82

83 /* 11) Escribir la nota n-esima (TODO)

84 status_t ADT_musical_score_set_element_at(ADT_musical_score_t*, void*, long );

85 */

86

87 /* ----------------------------------------------------------------------------*/

88

89

90 #endif /* ADT_MUSICAL_SCORE_H */

8.1.2. ADT musical score PRIVATE.h

1 /* *****************************************************************************

2

3 Algoritmos y Programaci on I - 75.02/95.11 - Curso Ing. Mart ın Cardozo

4 TP N o 3 - 1er Cuatrimestre 2012

5

6 Alumnos: ARIAS , Francisco - FERRARI BIHURRIET , Francisco

7 Archivo: ADT_musical_score_PRIVATE.h

8 Descrip: Encabezado privado para el TDA partitura musical.

9 Obs: Para una correcta utilizaci on del TDA no debe conocerse el

10 funcionamiento interno , el cu al queda expuesto aqu ı.

11

12 ***************************************************************************** */

13

14

15 #include "ADT_musical_score.h"

20

8.1 ADT musical score

16

17 #if ndef ADT_MUSICAL_SCORE_PRIVATE_H

18 #define ADT_MUSICAL_SCORE_PRIVATE_H

19

20 #define N 0 /* 0 or 1 */

21 #define SCALE_FACTOR 1.05946309435929526 /* (pow (2 ,1.0/ QUANTITY_TONES)) */

22 #define SIZE_AUX_VEC 30

23 #define STRING_SPACE " " /* separador de parametros en partitura */

24 #define QUANTITY_TONES 12 /* cantidad de tonos en una octava musical */

25 #define C1_FREQUENCY 16.3515978312874147

26 #define BEMOL_SYMBOL 'b'

27 #define SHARP_SYMBOL 's'

28 #define EMPTY_LINE "\n"

29

30 const string string_tones[QUANTITY_TONES ]=

31 {

32

33 "C",

34 "Cs", /*Db*/

35 "D",

36 "Ds", /*Eb*/

37 "E",

38 "F",

39 "Fs", /*Gb*/

40 "G",

41 "Gs", /*Ab*/

42 "A",

43 "As", /*Bb*/

44 "B"

45

46 };

47

48 /* --------------------------------------------------------------------- */

49

50 /* ...................... Manejo de memoria dinamica ...................... */

51

52 #define INIT_CHOP 10 /* memoria inicial */

53 #define CHOP_SIZE 10 /* incremento de memoria */

54

55 /* ........................................................................ */

56

57 /* ....................... Estructura del ADT partitura ................... */

58

59 struct tnote

60 {

61

62 double start_time;

63 double duration;

64 tone_t tone;

65 uchar octave;

66

67 };

68

69 struct ADT_musical_score_t

70 {

71

72 tnote **notes;

73 size_t quantity_notes;

74 size_t alloc_size;

21

8.1 ADT musical score

75

76 };

77

78 /* ........................................................................ */

79

80 #endif /* ADT_MUSICAL_SCORE_PRIVATE_H */

8.1.3. ADT musical score.c

1 /* *****************************************************************************

2

3 Algoritmos y Programaci on I - 75.02/95.11 - Curso Ing. Mart ın Cardozo

4 TP N o 3 - 1er Cuatrimestre 2012

5

6 Alumnos: ARIAS , Francisco - FERRARI BIHURRIET , Francisco

7 Archivo: ADT_musical_score.c

8 Descrip: Implementaci on del TDA partitura musical.

9 Obs: Compilacion en modo prueba:

10 gcc ADT_musical_score.c -o musical_score

11 -ansi -pedantic -Wall -lm -DTEST

12

13 ***************************************************************************** */

14

15

16 #include <stdio.h>

17 #include <stdlib.h>

18 #include <string.h>

19 #include <math.h>

20 #include "ADT_musical_score_PRIVATE.h"

21

22 /* |/////////////////////////////////| 1) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

23 /* |//////////////////////////| Creador de partitura |\\\\\\\\\\\\\\\\\\\\\\\\\| */

24 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

25

26

27 status_t ADT_musical_score_new(ADT_musical_score_t ** musical_score){

28

29 size_t i, j;

30

31 if( musical_score == NULL) return ERROR_NULL_POINTER;

32

33 if( ((* musical_score) = (ADT_musical_score_t *)

34 malloc(sizeof(ADT_musical_score_t))) == NULL )

35 return ERROR_NO_MEMORY;

36

37 if( ((* musical_score)->notes = (tnote **)

38 malloc(INIT_CHOP*sizeof(tnote*))) == NULL ){

39 free( *musical_score );

40 *musical_score = NULL;

41 return ERROR_NO_MEMORY;

42 }

43

44 for(i=0; i<INIT_CHOP; i++){

45

46 if( ((* musical_score)->notes[i] = (tnote *)

47 malloc(sizeof(tnote))) == NULL ){

48 for(j=0; j<i; j++)

49 free ((* musical_score)->notes[j]);

50 free ((* musical_score)->notes);

51 free(* musical_score);

22

8.1 ADT musical score

52 *musical_score=NULL;

53 return ERROR_NO_MEMORY;

54 }

55

56 }

57

58 (* musical_score)->quantity_notes = 0;

59 (* musical_score)->alloc_size = INIT_CHOP;

60

61 return OK;

62

63 }

64

65 /* |/////////////////////////////////| 2) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

66 /* |////////////////////////| Destructor de partitura |\\\\\\\\\\\\\\\\\\\\\\\\| */

67 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

68

69 void ADT_musical_score_destroy(ADT_musical_score_t ** musical_score){

70

71 size_t i, aux_alloc_size;

72

73 aux_alloc_size = (* musical_score)->alloc_size;

74

75 for(i=0;i<aux_alloc_size;i++)

76 free (((* musical_score)->notes[i]));

77 free ((* musical_score)->notes);

78 free(* musical_score);

79 *musical_score = NULL;

80

81 }

82

83 /* |/////////////////////////////////| 3) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

84 /* |///////////////////////| Obtener la cantidad de notas |\\\\\\\\\\\\\\\\\\\| */

85 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

86

87 size_t ADT_musical_score_get_quantity_notes(const ADT_musical_score_t*

88 musical_score){

89

90 return musical_score ->quantity_notes;

91 }

92

93 /* |/////////////////////////////////| 4) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

94 /* |///////////////////////| Obtener la n-sima nota |\\\\\\\\\\\\\\\\\\\\\\\\\| */

95 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

96

97 tnote* ADT_musical_score_get_note_at(const ADT_musical_score_t* musical_score ,

98 size_t position){

99

100 if( musical_score == NULL || (musical_score ->quantity_notes) < position )

101 return NULL;

102

103 return musical_score ->notes[position -N];

104 }

105

106 /* |/////////////////////////////////| 5) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

107 /* |//////////////////| Obtener la duracion de la n-sima nota |\\\\\\\\\\\\\\\| */

108 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

109

110 double ADT_musical_score_get_duration_at(const ADT_musical_score_t*

23

8.1 ADT musical score

111 musical_score , size_t position){

112

113 return (musical_score ->notes[position -N])->duration;

114 }

115

116 /* |/////////////////////////////////| 6) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

117 /* |////////////| Obtener el tiempo de inicio de la n-sima nota |\\\\\\\\\\\\\| */

118 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

119

120 double ADT_musical_score_get_start_time_at(const ADT_musical_score_t*

121 musical_score , size_t position){

122

123 return (musical_score ->notes[position -N])->start_time;

124 }

125

126 /* |/////////////////////////////////| 7) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

127 /* |//////////////////| Obtener el tono de la n-sima nota |\\\\\\\\\\\\\\\\\\\| */

128 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

129

130 tone_t ADT_musical_score_get_tone_at(const ADT_musical_score_t* musical_score ,

131 size_t position){

132

133 return (musical_score ->notes[position -N])->tone;

134 }

135

136 /* |/////////////////////////////////| 8) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

137 /* |//////////////| Obneter la fracuencia de la n-sina nota |\\\\\\\\\\\\\\\\\| */

138 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

139

140 double ADT_musical_score_get_frequency_at(const ADT_musical_score_t*

141 musical_score , size_t position){

142

143 return C1_FREQUENCY*pow(2,(( musical_score ->notes[position -N]->octave) -1))*

144 pow(SCALE_FACTOR , (musical_score ->notes[position -N]->tone));

145

146 }

147

148 /* |/////////////////////////////////| 9) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

149 /* |//////////////////////| Leer notas desde archivo |\\\\\\\\\\\\\\\\\\\\\\\\| */

150 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

151

152 status_t ADT_musical_score_set_from_file(ADT_musical_score_t ** musical_score ,

153 string file_name_musical_score){

154

155 FILE* file_musical_score;

156 size_t i;

157 size_t aux_alloc_size = INIT_CHOP;

158 size_t aux_quantity_notes = 0;

159 tnote ** aux_notes;

160 char aux_vec[SIZE_AUX_VEC ];

161 string aux_string;

162

163

164 if( musical_score == NULL || file_name_musical_score == NULL )

165 return ERROR_NULL_POINTER;

166

167 if( (file_musical_score = fopen( file_name_musical_score , "r" )) == NULL ){

168 ADT_musical_score_destroy(musical_score);

169 return ERROR_MUSICAL_SCORE;

24

8.1 ADT musical score

170 }

171

172 while( fgets(aux_vec , SIZE_AUX_VEC , file_musical_score) != NULL ){

173

174 if( !strcmp(aux_vec ,EMPTY_LINE) ){

175 ADT_musical_score_destroy(musical_score);

176 return ERROR_MUSICAL_SCORE;

177

178 }

179

180

181 if( aux_quantity_notes == aux_alloc_size ){

182 if( (aux_notes = (tnote **) realloc ((* musical_score)->notes ,

183 sizeof(tnote *)*( aux_alloc_size+CHOP_SIZE))) == NULL ){

184 ADT_musical_score_destroy(musical_score);

185 return ERROR_NO_MEMORY;

186 }

187

188 (* musical_score)->notes = aux_notes;

189

190 for(i=aux_alloc_size; i<( aux_alloc_size+CHOP_SIZE); i++){

191 if( ((* musical_score)->notes[i] =

192 malloc(sizeof(tnote))) == NULL ){

193 (* musical_score)->alloc_size = (aux_alloc_size+i);

194 ADT_musical_score_destroy(musical_score);

195 return ERROR_NO_MEMORY;

196

197 }

198

199 }

200

201 aux_alloc_size += CHOP_SIZE;

202 }

203

204 aux_string = strtok(aux_vec , STRING_SPACE);

205 (* musical_score)->notes[aux_quantity_notes]->start_time =

206 strtod(aux_string , NULL);

207

208 aux_string = strtok(NULL , STRING_SPACE);

209

210

211 for(i=0; i<QUANTITY_TONES; i++){

212

213 if( !strncmp(aux_string , string_tones[i],1) ){

214 if( aux_string [1] == BEMOL_SYMBOL ){

215 (* musical_score)->notes[aux_quantity_notes]->tone =

216 (tone_t)(i-1);

217 (* musical_score)->notes[aux_quantity_notes]->octave =

218 (uchar) strtoul(aux_string +2,NULL ,0);

219 break;

220 }

221

222 if( aux_string [1] == SHARP_SYMBOL ){

223 (* musical_score)->notes[aux_quantity_notes]->tone =

224 (tone_t)(i+1);

225 (* musical_score)->notes[aux_quantity_notes]->octave =

226 (uchar) strtoul(aux_string +2,NULL ,0);

227 break;

228 }

25

8.1 ADT musical score

229

230 (* musical_score)->notes[aux_quantity_notes]->tone = (tone_t)i;

231 (* musical_score)->notes[aux_quantity_notes]->octave =

232 (uchar) strtoul(aux_string +1,NULL ,0);

233 break;

234

235

236 }

237

238 }

239

240 aux_string = strtok(NULL , STRING_SPACE);

241 (* musical_score)->notes[aux_quantity_notes]->duration =

242 strtod(aux_string , NULL);

243

244 aux_quantity_notes ++;

245

246 }

247

248 (* musical_score)->quantity_notes = aux_quantity_notes;

249 (* musical_score)->alloc_size = aux_alloc_size;

250

251 fclose(file_musical_score);

252

253 return OK;

254

255 }

256

257 /* |//////////////////////////////| 10) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

258 /* |//////////////////////////| Imprimir partitura |\\\\\\\\\\\\\\\\\\\\\\\\\\| */

259 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

260

261

262 status_t ADT_musical_score_print(const ADT_musical_score_t* musical_score){

263

264 size_t i, quantity_notes;

265

266 if( musical_score == NULL ) return ERROR_NULL_POINTER;

267

268 quantity_notes = ADT_musical_score_get_quantity_notes(musical_score);

269

270 for(i=0; i<quantity_notes; i++)

271

272 printf( " %f %s %u %f frequency --> %f\n",

273 ADT_musical_score_get_start_time_at(musical_score , i),

274 string_tones[musical_score ->notes[i]->tone],

275 (uint)musical_score ->notes[i]->octave ,

276 ADT_musical_score_get_duration_at(musical_score , i),

277 ADT_musical_score_get_frequency_at(musical_score , i));

278

279 return OK;

280 }

281

282

283

284

285 /* |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| */

286 /* |||||||||||||||||||||||||||||| MAIN de prueba |||||||||||||||||||||||||||||| */

287 /* |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| */

26

8.2 ADT synthesizer

288

289 #if def TEST

290

291 int main(void){

292

293 ADT_musical_score_t *musical_score;

294

295 /* Creacion (1) */

296 if( (ADT_musical_score_new (& musical_score)) != OK ){

297 fprintf(stderr , "Error en la creacion de la partitura\n");

298 return EXIT_FAILURE;

299 }

300

301 /* Llenado (9) */

302 if( (ADT_musical_score_set_from_file (& musical_score , "TEST_PARTITURA.txt"))

303 != OK){

304 fprintf(stderr , "Error en el seteo de los elementos\n");

305 return EXIT_FAILURE;

306 }

307

308 /* Impresion (10) */

309

310 if( (ADT_musical_score_print(musical_score)) != OK){

311 fprintf(stderr , "Error en la impresion de prueba\n");

312 return EXIT_FAILURE;

313 }

314

315 /* Destruccion (2) */

316

317 ADT_musical_score_destroy (& musical_score);

318

319 return EXIT_SUCCESS;

320

321 }

322

323 #endif

8.2. ADT synthesizer

8.2.1. modulationlib.h

1 /* *****************************************************************************

2

3 Algoritmos y Programaci on I - 75.02/95.11 - Curso Ing. Mart ın Cardozo

4 TP N o 3 - 1er Cuatrimestre 2012

5

6 Alumnos: ARIAS , Francisco - FERRARI BIHURRIET , Francisco

7 Archivo: modulationlib.h

8 Descrip: Encabezado de la biblioteca modulationlib.

9 Obs: Precondiciones:

10 1) El puntero recibido no debe ser NULL.

11 2) El primer elemento del vector (t0) debe ser distinto de cero.

12

13 ***************************************************************************** */

14

15

16 #if ndef MODULATIONLIB_H

17 #define MODULATIONLIB_H

18

19 #define PI 3.14159265358979323846

27

8.2 ADT synthesizer

20

21 /* Posici on de los par a metros en el vector */

22 #define param_T0 0

23 #define param_T1 1

24 #define param_A1 2

25 #define param_A 0

26 #define param_F 1

27

28

29 /* *********************** PROTOTYPES *************************************** */

30

31 double modulation_constant(const double[], double);

32 double modulation_linear(const double[], double);

33 double modulation_invlinear(const double[], double);

34 double modulation_sin(const double[], double);

35 double modulation_exp(const double[], double);

36 double modulation_invexp(const double[], double);

37 double modulation_quartcos(const double[], double);

38 double modulation_quartsin(const double[], double);

39 double modulation_halfcos(const double[], double);

40 double modulation_halfsin(const double[], double);

41 double modulation_log(const double[], double);

42 double modulation_invlog(const double[], double);

43 double modulation_tri(const double[], double);

44 double modulation_pulses(const double[], double);

45

46 /* -------------------------------------------------------------------------- */

47

48 #endif /* MODULATIONLIB_H */

8.2.2. modulationlib.c

1 /* *****************************************************************************

2

3 Algoritmos y Programaci on I - 75.02/95.11 - Curso Ing. Mart ın Cardozo

4 TP N o 3 - 1er Cuatrimestre 2012

5

6 Alumnos: ARIAS , Francisco - FERRARI BIHURRIET , Francisco

7 Archivo: modulationlib.c

8 Descrip: Biblioteca de moduladores de la amplitud en la se~nal de audio.

9 Obs:

10

11 ***************************************************************************** */

12

13

14 #include <math.h>

15 #include <stdio.h>

16 #include <stdlib.h>

17 #include "modulationlib.h"

18

19

20 /* Macro de funci on: mınimo entre dos valores */

21 #define MINIMUM(a,b) ((a)<(b)?(a):(b))

22 /* ------------------------------------------ */

23

24 /*

25 Par a metros en el vector , estas macros son poco expl ı citas y cortas ,

26 para acortar las fo rmulas en las funciones , por eso se declaran

27 dentro de 'modulationlib.c', para que sean internas y no entren en

28 en conflicto con otras definiciones.

28

8.2 ADT synthesizer

29 */

30 #define T0 parameters[param_T0]

31 #define T1 parameters[param_T1]

32 #define A1 parameters[param_A1]

33 #define A parameters[param_A]

34 #define F parameters[param_F]

35

36 /* -------------------------------------------------------------- */

37 /* CONSTANT */

38 /* -------------------------------------------------------------- */

39 double modulation_constant(const double parameters [], double t)

40 {

41 return 1;

42 }

43

44 /* -------------------------------------------------------------- */

45 /* LINEAR */

46 /* -------------------------------------------------------------- */

47 double modulation_linear(const double parameters [], double t)

48 {

49 return t/T0;

50 }

51

52 /* -------------------------------------------------------------- */

53 /* INVLINEAR */

54 /* -------------------------------------------------------------- */

55 double modulation_invlinear(const double parameters [], double t)

56 {

57 if( T0 <t ) return 0; /* 0 > 1 - t/T0 */

58 return 1 - t/T0;

59 }

60

61 /* -------------------------------------------------------------- */

62 /* SIN */

63 /* -------------------------------------------------------------- */

64 double modulation_sin(const double parameters [], double t)

65 {

66 return 1 + A*sin (2*PI*F*t);

67 }

68

69 /* -------------------------------------------------------------- */

70 /* EXP */

71 /* -------------------------------------------------------------- */

72 double modulation_exp(const double parameters [], double t)

73 {

74 return exp ((-5*(T0 -t))/T0);

75 }

76

77 /* -------------------------------------------------------------- */

78 /* INVEXP */

79 /* -------------------------------------------------------------- */

80 double modulation_invexp(const double parameters [], double t)

81 {

82 return exp((-5*t)/T0);

83 }

84

85 /* -------------------------------------------------------------- */

86 /* QUARTCOS */

87 /* -------------------------------------------------------------- */

29

8.2 ADT synthesizer

88 double modulation_quartcos(const double parameters [], double t)

89 {

90 return cos((PI*t)/(2*T0));

91 }

92

93 /* -------------------------------------------------------------- */

94 /* QUARTSIN */

95 /* -------------------------------------------------------------- */

96 double modulation_quartsin(const double parameters [], double t)

97 {

98 return sin((PI*t)/(2*T0));

99 }

100

101 /* -------------------------------------------------------------- */

102 /* HALFCOS */

103 /* -------------------------------------------------------------- */

104 double modulation_halfcos(const double parameters [], double t)

105 {

106 return (1+ cos((PI*t)/T0))/2;

107 }

108

109 /* -------------------------------------------------------------- */

110 /* HALFSIN */

111 /* -------------------------------------------------------------- */

112 double modulation_halfsin(const double parameters [], double t)

113 {

114 return (1+ sin(PI*((t-T0)/T0 +0.5)))/2;

115 }

116

117 /* -------------------------------------------------------------- */

118 /* LOG */

119 /* -------------------------------------------------------------- */

120 double modulation_log(const double parameters [], double t)

121 {

122 return log10 ((9*t)/T0 + 1);

123 }

124

125 /* -------------------------------------------------------------- */

126 /* INVLOG */

127 /* -------------------------------------------------------------- */

128 double modulation_invlog(const double parameters [], double t)

129 {

130 if( t<T0 ) return log10 ((-9*t)/T0 + 10);

131 return 0;

132 }

133

134 /* -------------------------------------------------------------- */

135 /* TRI */

136 /* -------------------------------------------------------------- */

137 double modulation_tri(const double parameters [], double t)

138 {

139 if( t<=T1 ) return (t*A1)/T1;

140 return (t-T0)*(A1 -1)/(T1 -T0) + 1;

141 }

142

143 /* -------------------------------------------------------------- */

144 /* PULSES */

145 /* -------------------------------------------------------------- */

146 double modulation_pulses(const double parameters [], double t)

30

8.2 ADT synthesizer

147 {

148 double aux;

149

150 t = t/T0 - floor(t/T0); /* t' */

151 aux = fabs( ((1-A1)/T1) * (2*t-1) * T0 ) + A1;

152 return MINIMUM(aux ,1);

153 }

8.2.3. ADT synthesizer.h

1 /* *****************************************************************************

2

3 Algoritmos y Programaci on I - 75.02/95.11 - Curso Ing. Mart ın Cardozo

4 TP N o 3 - 1er Cuatrimestre 2012

5

6 Alumnos: ARIAS , Francisco - FERRARI BIHURRIET , Francisco

7 Archivo: ADT_synthesizer.h

8 Descrip: Encabezado pu blico para el TDA sintetizador.

9 Obs:

10

11 ***************************************************************************** */

12

13

14 #include "ADT_synthesizer_PRIVATE.h"

15 #include "../ main_modules/common.h"

16 #include "modulationlib.h"

17

18 #if ndef ADT_SYNTHESIZER_H

19 #define ADT_SYNTHESIZER_H

20

21 static const modulation_t modulation_functions[QUANTITY_MODULATORS] = {

22

23 modulation_constant ,

24 modulation_linear ,

25 modulation_invlinear ,

26 modulation_sin ,

27 modulation_exp ,

28 modulation_invexp ,

29 modulation_quartcos ,

30 modulation_quartsin ,

31 modulation_halfcos ,

32 modulation_halfsin ,

33 modulation_log ,

34 modulation_invlog ,

35 modulation_tri ,

36 modulation_pulses

37

38 };

39

40 static const string string_modulators[QUANTITY_MODULATORS] = {

41

42 "CONSTANT",

43 "LINEAR",

44 "INVLINEAR",

45 "SIN",

46 "EXP",

47 "INVEXP",

48 "QUARTCOS",

49 "QUARTSIN",

50 "HALFCOS",

31

8.2 ADT synthesizer

51 "HALFSIN",

52 "LOG",

53 "INVLOG",

54 "TRI",

55 "PULSES"

56

57 };

58

59

60

61 typedef enum {ATTACK=0, SUSTAINED=1, RELEASE =2} type_modulation_t;

62

63 typedef struct ADT_synthesizer_t ADT_synthesizer_t;

64 typedef struct tharmonic tharmonic;

65 typedef struct tmodulation tmodulation;

66

67

68 /* ******************************** primitives ******************************** */

69

70

71 /* 1) Creador de sintetizador */

72 status_t ADT_synthesizer_new(ADT_synthesizer_t **);

73

74 /* 2) Destructor de sintetizador */

75 void ADT_synthesizer_destroy(ADT_synthesizer_t **);

76

77 /* 3) Obtener la cantidad de armonicos. Precondicion: no debe recibir puntero

78 NULL */

79 size_t ADT_synthesizer_get_quantity_harmonics(const ADT_synthesizer_t *);

80

81 /* 4) Obtener el n-sima armonico. La funcion devuelve por el penultimo

82 argumento los pares de multiplo y por el ultimo arguemento

83 la intesidad */

84 status_t ADT_synthesizer_get_harmonic_at(const ADT_synthesizer_t*, size_t ,

85 double*, double *);

86

87 /* 5) Obtener la modulacion. El segundo argumento funciona como una bandera

88 indicadora de la modulacion deseada (ATTACK , SUSTAINED o RELEASE).

89 la funcion devuelve por interfaz la modularizacion deseada y los

90 parametros relacionados con dicha modulacion */

91 status_t ADT_synthesizer_get_modulation_at(const ADT_synthesizer_t*,

92 type_modulation_t , double**,

93 modulation_t *);

94

95 /* 6) Escribir desde archivo */

96 status_t ADT_synthesizer_set_from_file(ADT_synthesizer_t **, string);

97

98 /* 7) Imprimir copia del archivo sitetizador */

99 status_t ADT_synthesizer_print(const ADT_synthesizer_t *);

100

101 /* ----------------------------------------------------------------------------*/

102

103

104 #endif /* ADT_SYNTHESIZER_H */

8.2.4. ADT synthesizer PRIVATE.h

1 /* *****************************************************************************

2

3 Algoritmos y Programaci on I - 75.02/95.11 - Curso Ing. Mart ın Cardozo

32

8.2 ADT synthesizer

4 TP N o 3 - 1er Cuatrimestre 2012

5

6 Alumnos: ARIAS , Francisco - FERRARI BIHURRIET , Francisco

7 Archivo: ADT_synthesizer_PRIVATE.h

8 Descrip: Encabezado privado para el TDA sintetizador.

9 Obs: Para una correcta utilizaci on del TDA no debe conocerse el

10 funcionamiento interno , el cu al queda expuesto aqu ı.

11

12 ***************************************************************************** */

13

14

15 #include "modulationlib.h"

16

17 #if ndef ADT_SYNTHESIZER_PRIVATE_H

18 #define ADT_SYNTHESIZER_PRIVATE_H

19

20

21

22 /* *************** Declaration of a function pointer types ******************** */

23

24 typedef double (* modulation_t)(const double[], double);

25

26 /* ----------------------------------------------------------------------------*/

27

28 #define N 0

29 #define QUANTITY_PARAMETERS 3

30 #define SIZE_AUX_VEC 30

31 #define STRING_SPACE " "

32 #define QUANTITY_MODULATORS 14

33 #define PHASE_MODULATION_AMOUNT 3

34 #define FILE_NAME_TEST "TEST_SINTETIZADOR.txt"

35

36 /* ....................... Estructura del ADT sintetizador ................... */

37

38 struct tharmonic{

39

40 double multiples_pairs;

41 double intensity;

42

43 };

44

45 struct tmodulation{

46

47 modulation_t modulation;

48 double parameters[QUANTITY_PARAMETERS ];

49

50 };

51

52 struct ADT_synthesizer_t{

53

54 unsigned char quantity_harmonic;

55 struct tharmonic ** harmonics;

56 struct tmodulation ** modulators; /* 0: Attack - 1: Sustained - 2: Release */

57

58 };

59

60 /* --------------------------------------------------------------------- */

61

62 #endif /* ADT_SYNTHESIZER_PRIVATE_H */

33

8.2 ADT synthesizer

8.2.5. ADT synthesizer.c

1 /* *****************************************************************************

2

3 Algoritmos y Programaci on I - 75.02/95.11 - Curso Ing. Mart ın Cardozo

4 TP N o 3 - 1er Cuatrimestre 2012

5

6 Alumnos: ARIAS , Francisco - FERRARI BIHURRIET , Francisco

7 Archivo: ADT_synthesizer.c

8 Descrip: Implementaci on del TDA sintetizador.

9 Obs: Compilacion en modo prueba:

10 gcc ADT_synthesizer.c modulationlib.c -o synthesizer

11 -ansi -pedantic -Wall -lm -DTEST

12

13 ***************************************************************************** */

14

15

16 #include <stdio.h>

17 #include <stdlib.h>

18 #include <string.h>

19 #include <math.h>

20 #include <ctype.h>

21 #include "../ main_modules/common.h"

22 #include "ADT_synthesizer_PRIVATE.h"

23 #include "ADT_synthesizer.h"

24 #include "modulationlib.h"

25

26

27 /* |/////////////////////////////////| 1) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

28 /* |//////////////////////////| Creador de sintetizador |\\\\\\\\\\\\\\\\\\\\\| */

29 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

30

31

32 status_t ADT_synthesizer_new(ADT_synthesizer_t ** synthesizer){

33

34 size_t i, j;

35

36 if( synthesizer == NULL ) return ERROR_NULL_POINTER;

37

38 if( ((* synthesizer) = (ADT_synthesizer_t *)

39 malloc(sizeof(ADT_synthesizer_t))) == NULL )

40 return ERROR_NO_MEMORY;

41

42 if( ((* synthesizer)->modulators = (tmodulation **)

43 malloc( PHASE_MODULATION_AMOUNT*sizeof(tmodulation *) )) == NULL ){

44 free(* synthesizer);

45 *synthesizer = NULL;

46 return ERROR_NO_MEMORY;

47 }

48

49 for(i=0; i<PHASE_MODULATION_AMOUNT; i++){

50 if( ((* synthesizer)->modulators[i] = (tmodulation *)

51 malloc(sizeof(tmodulation))) == NULL ){

52 for(j=0; j<i; j++)

53 free ((* synthesizer)->modulators[j]);

54 free ((* synthesizer)->modulators);

55 free(* synthesizer);

56 *synthesizer = NULL;

57 return ERROR_NO_MEMORY;

34

8.2 ADT synthesizer

58 }

59 }

60

61 (* synthesizer)->quantity_harmonic = 0;

62 (* synthesizer)->harmonics = NULL;

63

64 for(j=0; j<PHASE_MODULATION_AMOUNT; j++){

65 (* synthesizer)->modulators[j]->modulation = NULL;

66 for(i=0; i<QUANTITY_PARAMETERS; i++)

67 (* synthesizer)->modulators[j]->parameters[i] = 0;

68 }

69

70 return OK;

71

72 }

73

74

75 /* |/////////////////////////////////| 2) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

76 /* |//////////////////////| Destructor de sintetizador |\\\\\\\\\\\\\\\\\\\\\\| */

77 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

78

79

80 void ADT_synthesizer_destroy(ADT_synthesizer_t ** synthesizer){

81

82 size_t i, aux_quantity_harmonic;

83

84 aux_quantity_harmonic = (* synthesizer)->quantity_harmonic;

85

86 for(i=0; i<aux_quantity_harmonic; i++)

87 free ((* synthesizer)->harmonics[i]);

88 free ((* synthesizer)->harmonics);

89 for(i=0; i<PHASE_MODULATION_AMOUNT; i++)

90 free ((* synthesizer)->modulators[i]);

91 free ((* synthesizer)->modulators);

92 free(* synthesizer);

93 *synthesizer = NULL;

94

95 }

96

97 /* |/////////////////////////////////| 3) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

98 /* |//////////////////| Obtener la cantidad de armonicos |\\\\\\\\\\\\\\\\\\\\| */

99 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

100

101 size_t ADT_synthesizer_get_quantity_harmonics(const ADT_synthesizer_t*

102 synthesizer){

103

104 return synthesizer ->quantity_harmonic;

105 }

106

107 /* |/////////////////////////////////| 4) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

108 /* |///////////////////////| Obtener el n-sima armonico |\\\\\\\\\\\\\\\\\\\\\| */

109 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

110

111 status_t ADT_synthesizer_get_harmonic_at(const ADT_synthesizer_t* synthesizer ,

112 size_t position , double* multiples_pairs , double* intensity){

113

114 if( synthesizer == NULL || synthesizer ->quantity_harmonic < position )

115 return ERROR_NULL_POINTER;

116

35

8.2 ADT synthesizer

117 *multiples_pairs = (synthesizer ->harmonics[position -N]->multiples_pairs);

118 *intensity = (synthesizer ->harmonics[position -N]->intensity);

119

120 return OK;

121 }

122

123 /* |/////////////////////////////////| 5) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

124 /* |////////////////////////| Obtener la modulacion. |\\\\\\\\\\\\\\\\\\\\\\\| */

125 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

126

127 status_t ADT_synthesizer_get_modulation_at(const ADT_synthesizer_t* synthesizer ,

128 type_modulation_t modulation , double ** parameters , modulation_t* modulator){

129

130 size_t i;

131

132 if( synthesizer == NULL ) return ERROR_NULL_POINTER;

133

134 for(i=0; i<PHASE_MODULATION_AMOUNT; i++){

135 if( modulation == i){

136 if( modulator == NULL){

137 *parameters = (synthesizer ->modulators[i]->parameters);

138 return OK;

139 }

140 *parameters = (synthesizer ->modulators[i]->parameters);

141 *modulator = (synthesizer ->modulators[i]->modulation);

142 }

143 }

144

145 return OK;

146 }

147

148 /* |/////////////////////////////////| 6) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

149 /* |///////////////////////| Escribir desde archivo |\\\\\\\\\\\\\\\\\\\\\\\\\| */

150 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

151

152 status_t ADT_synthesizer_set_from_file(ADT_synthesizer_t ** synthesizer ,

153 string file_name_synthesizer){

154

155 size_t i,j,L, aux_quantity_harmonic;

156 FILE* file_synthesizer;

157 char aux_vec[SIZE_AUX_VEC ];

158 string aux_string;

159

160 if( synthesizer == NULL || file_name_synthesizer == NULL )

161 return ERROR_NULL_POINTER;

162

163 if( (file_synthesizer = fopen(file_name_synthesizer , "r")) == NULL){

164 ADT_synthesizer_destroy(synthesizer);

165 return ERROR_SYNTHESIZER;

166 }

167

168 if( fgets(aux_vec , SIZE_AUX_VEC , file_synthesizer) == NULL )

169 return ERROR_SYNTHESIZER;

170

171 if( (aux_quantity_harmonic = strtoul(aux_vec , NULL , 0)) == 0)

172 return ERROR_SYNTHESIZER;

173

174 if( ((* synthesizer)->harmonics = (tharmonic **)

175 malloc(aux_quantity_harmonic*sizeof(tharmonic *))) == NULL ){

36

8.2 ADT synthesizer

176 ADT_synthesizer_destroy(synthesizer);

177 return ERROR_NO_MEMORY;

178 }

179

180 for(i=0; i<aux_quantity_harmonic; i++){

181 if( ((* synthesizer)->harmonics[i] = (tharmonic *)

182 malloc(sizeof(tharmonic))) == NULL ){

183 (* synthesizer)->quantity_harmonic = i;

184 ADT_synthesizer_destroy(synthesizer);

185 return ERROR_NO_MEMORY;

186 }

187

188 }

189

190 for(i=0; i<aux_quantity_harmonic; i++){

191

192 if( fgets(aux_vec , SIZE_AUX_VEC , file_synthesizer) == NULL )

193 return ERROR_SYNTHESIZER;

194

195 aux_string = strtok(aux_vec , STRING_SPACE );

196

197 (* synthesizer)->harmonics[i]->multiples_pairs =

198 strtod(aux_string , NULL);

199 aux_string = strtok(NULL , STRING_SPACE );

200 (* synthesizer)->harmonics[i]->intensity = strtod(aux_string , NULL);

201

202 }

203

204

205 for(j=0; j<PHASE_MODULATION_AMOUNT; j++){

206

207 if( fgets(aux_vec , SIZE_AUX_VEC , file_synthesizer) == NULL ||

208 !strcmp(aux_vec , "\n") )

209 return ERROR_SYNTHESIZER;

210

211 aux_string = strtok(aux_vec , STRING_SPACE);

212

213 if( isdigit(aux_vec [0]))

214 return ERROR_SYNTHESIZER;

215

216 /* Caso especial: CONSTANT , no tiene par a metros */

217 L = strlen(aux_vec) -2;

218 if( aux_vec[L+1] == '\n' && L == strlen(string_modulators [0]) &&

219 !strncmp(aux_vec , string_modulators [0], L) ){

220 (* synthesizer)->modulators[j]->modulation = modulation_functions [0];

221 continue;

222 }

223 /* -------------------------------------------- */

224

225 for(i=0; i<QUANTITY_MODULATORS; i++){

226

227 if( !strcmp(aux_string , string_modulators[i]) ){

228 (* synthesizer)->modulators[j]->modulation =

229 modulation_functions[i];

230 break;

231 }

232

233 }

234

37

8.2 ADT synthesizer

235 for(i=0; i<QUANTITY_PARAMETERS &&

236 (aux_string = strtok(NULL , STRING_SPACE)) != NULL; i++)

237 ((* synthesizer)->modulators[j]->parameters[i]) =

238 strtod(aux_string , NULL);

239

240 }

241

242 /* Validaci on */

243 for(j=0; j<PHASE_MODULATION_AMOUNT; j++){

244 if ( (* synthesizer)->modulators[j]->modulation == NULL )

245 return ERROR_SYNTHESIZER;

246 }

247

248

249 (* synthesizer)->quantity_harmonic = aux_quantity_harmonic;

250 fclose(file_synthesizer);

251

252 return OK;

253 }

254

255 /* ||||||||||||||||||||||||||||||||| 7) ||||||||||||||||||||||||||||||||||| */

256 /* |||||||||||||||||| Imprimir copia del archivo sintetizador ||||||||||||||||| */

257 /* |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| */

258

259 status_t ADT_synthesizer_print(const ADT_synthesizer_t* synthesizer){

260

261 size_t i, j, quantity_harmonics;

262 double multiples_pairs , intensity;

263 modulation_t modulation = NULL;

264 double* parameters = NULL;

265 double t;

266

267 if( synthesizer == NULL) return ERROR_NULL_POINTER;

268

269 if( (quantity_harmonics =

270 ADT_synthesizer_get_quantity_harmonics(synthesizer)) == 0)

271 return ERROR_SYNTHESIZER;

272

273 printf(" %lu\n", (ulong) quantity_harmonics);

274

275 for(i=0; i<quantity_harmonics ; i++){

276 if( ADT_synthesizer_get_harmonic_at(synthesizer , i,

277 &multiples_pairs , &intensity) != OK)

278 return ERROR_SYNTHESIZER;

279 printf(" %f %f\n", multiples_pairs , intensity);

280 }

281

282 for(i=0; i<PHASE_MODULATION_AMOUNT; i++){

283 for(j=0; j<QUANTITY_MODULATORS; j++){

284 if( synthesizer ->modulators[i]->modulation ==

285 modulation_functions[j] )

286 printf(" %s ", string_modulators[j]);

287 }

288 for(j=0; j<QUANTITY_PARAMETERS; j++)

289 printf(" %f ", synthesizer ->modulators[i]->parameters[j]);

290 printf("\n");

291 }

292

293 printf("\n %s\n\n", "Prueba de funciones de modulacion:");

38

8.2 ADT synthesizer

294 printf(" %s\n\n", "Ingrese el instante a evaluar: [segundos] ");

295

296 if( scanf(" %lf", &t) != 1 )

297 return ERROR_SYNTHESIZER;

298

299 ADT_synthesizer_get_modulation_at(synthesizer , ATTACK ,

300 &parameters , &modulation);

301 printf("Funcion de ataque evaluada en t = %f s --> %f\n",

302 t, modulation(parameters , t));

303

304 ADT_synthesizer_get_modulation_at(synthesizer , SUSTAINED ,

305 &parameters , &modulation);

306 printf("Funcion de duracion evaluada en t = %f s --> %f\n", t,

307 modulation(parameters , t));

308

309 ADT_synthesizer_get_modulation_at(synthesizer , RELEASE ,

310 &parameters , &modulation);

311 printf("Funcion de decaimiento evaluada en t = %f s --> %f\n", t,

312 modulation(parameters , t));

313

314 return OK;

315 }

316

317 /* |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| */

318 /* |||||||||||||||||||||||||||||| MAIN de prueba |||||||||||||||||||||||||||||| */

319 /* |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| */

320

321 #ifdef TEST

322

323

324 /* MAIN */

325 int main(void){

326

327 ADT_synthesizer_t *synthesizer;

328

329 /* Creacion (1) */

330 if( (ADT_synthesizer_new (& synthesizer)) != OK ){

331 fprintf(stderr , "Error en la creacion del sintetizador\n");

332 return EXIT_FAILURE;

333 }

334

335 /* Llenado (6) */

336 if( (ADT_synthesizer_set_from_file (& synthesizer , FILE_NAME_TEST )) != OK){

337 fprintf(stderr , "Error en el seteo de los elementos\n");

338 return EXIT_FAILURE;

339 }

340

341 /* Impresion (8) */

342

343 if( (ADT_synthesizer_print(synthesizer)) != OK){

344 fprintf(stderr , "Error en la impresion de prueba\n");

345 return EXIT_FAILURE;

346 }

347

348 /* Destruccion (2) */

349

350 ADT_synthesizer_destroy (& synthesizer);

351

352 return EXIT_SUCCESS;

39

8.3 ADT wav file

353

354 }

355

356 #endif

8.3. ADT wav file

8.3.1. ADT wav file.h

1 /* *****************************************************************************

2

3 Algoritmos y Programaci on I - 75.02/95.11 - Curso Ing. Mart ın Cardozo

4 TP N o 3 - 1er Cuatrimestre 2012

5

6 Alumnos: ARIAS , Francisco - FERRARI BIHURRIET , Francisco

7 Archivo: ADT_wav_file.h

8 Descrip: Encabezado pu blico para el TDA archivo WAV.

9 Obs:

10

11 ***************************************************************************** */

12

13

14 #include "../ main_modules/common.h"

15

16 #if ndef ADT_WAV_FILE_H

17 #define ADT_WAV_FILE_H

18

19 typedef struct __wav_file * ADT_wav_file_t; /* En el encabezado privado ... */

20

21

22 /* |///////////////////////////////////// \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

23 /* |||||||||||||||||||||||||||||||| Prototipos |||||||||||||||||||||||||||||||| */

24 /* |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ////////////////////////////////////| */

25

26 /* 1) Funci on para crear un archivo mono de 16bit a partir de un 'double[]' */

27 status_t ADT_wav_file_create_from_vector(uint , uint , double [],

28 ADT_wav_file_t *);

29

30 /* 2) Funci on para destruir un archivo WAV */

31 status_t ADT_wav_file_destroy(ADT_wav_file_t *);

32

33 /* 3) Funci on para escribir en un stream (abierto en modo "wb") */

34 status_t ADT_wav_file_write(ADT_wav_file_t , FILE *);

35

36 /*

37 TODO:

38 * ADT_wav_file_create_from_stream.

39 * ADT_wav_file_create_empty.

40 * ADT_wav_file_get_sample.

41 * ADT_wav_file_set_sample.

42 * ADT_wav_file_change_sample_rate.

43 */

44

45

46 #endif /* ADT_WAV_FILE_H */

8.3.2. ADT wav file PRIVATE.h

1 /* *****************************************************************************

2

40

8.3 ADT wav file

3 Algoritmos y Programaci on I - 75.02/95.11 - Curso Ing. Mart ın Cardozo

4 TP N o 3 - 1er Cuatrimestre 2012

5

6 Alumnos: ARIAS , Francisco - FERRARI BIHURRIET , Francisco

7 Archivo: ADT_wav_file_PRIVATE.h

8 Descrip: Encabezado privado para el TDA archivo WAV.

9 Obs: Para una correcta utilizaci on del TDA no debe conocerse el

10 funcionamiento interno , el cu al queda expuesto aqu ı.

11

12 ***************************************************************************** */

13

14

15 #include <limits.h>

16 #include "../ main_modules/common.h"

17 #include "ADT_wav_file.h"

18

19 #if ndef ADT_WAV_FILE_PRIVATE_H

20 #define ADT_WAV_FILE_PRIVATE_H

21

22 /* ------------------------- Definiciones varias ------------------------ */

23 #define WAV_ID_SIZES 4 /* Tama~no en Bytes de los IDs. */

24 #define WAV_CHUNK_ID "RIFF" /* Identificador del Chunk principal. */

25 #define WAV_FORMAT "WAVE" /* Identificador del formato WAVE. */

26 #define WAV_SUBCHUNK1_ID "fmt " /* Identificador del 1er SubChunk. */

27 #define WAV_SUBCHUNK2_ID "data" /* Identificador del 2do SubChunk. */

28 /* ··································· */

29 #define WAV_CHUNK_FIX_PART_SIZE 36 /* Tama~no de la parte fija del Chunk. */

30 #define WAV_SUBCHUNK1_SIZE 16 /* Tama~no del 1er SubChunk. */

31 #define WAV_AUDIO_FORMAT 1 /* Tipo de compresi on de audio (PCM). */

32 #define WAV_MONO_CHANNELS 1 /* Canales en MONO: solo uno. */

33 #define WAV_BITS_SAMPLE 16 /* Tama~no de las muestras (en bits). */

34 #define WAV_BYTES_SAMPLE (WAV_BITS_SAMPLE/CHAR_BIT) /* (en bytes). */

35 /* ··································· */

36 #define MAX_INT16 (pow (2,16) /2) /* (maximo de un 'int16 '). */

37 #define WAV_MAX_SAMPLE_VALUE (MAX_INT16 -2) /* (maximo valor absoluto). */

38 #define WAV_MAX_N_SAMPLES (44100*2*3600) /* (max: 2 h a 44,1 KHz). */

39 #define WAV_MAX_SAMPLE_RATE 192000 /* (max frec. de muestreo). */

40 /* ---------------------------------------------------------------------- */

41

42 /* ------------------------ Enumerativo de tipos ------------------------ */

43 typedef enum {TYPE_INT16 =2, TYPE_INT32 =4} type_t; /* No cambiar valores! */

44 /* ---------------------------------------------------------------------- */

45

46 /* --------------------- Estructura del ADT_wav_file -------------------- */

47 struct __wav_file

48 {

49 /* Chunk */

50 char ChunkID[WAV_ID_SIZES ];

51 uint ChunkSize;

52 char Format[WAV_ID_SIZES ];

53 /* SubChunk1 */

54 char SubChunk1ID[WAV_ID_SIZES ];

55 uint SubChunk1Size;

56 uint AudioFormat;

57 uint NumChannels;

58 uint SampleRate;

59 uint ByteRate;

60 uint BlockAlign;

61 uint BitsPerSample;

41

8.3 ADT wav file

62 /* SubChunk2 */

63 char SubChunk2ID[WAV_ID_SIZES ];

64 uint SubChunk2Size;

65 short *Data;

66 };

67 /* ---------------------------------------------------------------------- */

68

69 /* ------------------ Prototipos de funciones internas ------------------ */

70 void _write_little_endian(uint , type_t , FILE *);

71 /* ---------------------------------------------------------------------- */

72

73 #endif /* ADT_WAV_FILE_PRIVATE_H */

8.3.3. ADT wav file.c

1 /* *****************************************************************************

2

3 Algoritmos y Programaci on I - 75.02/95.11 - Curso Ing. Mart ın Cardozo

4 TP N o 3 - 1er Cuatrimestre 2012

5

6 Alumnos: ARIAS , Francisco - FERRARI BIHURRIET , Francisco

7 Archivo: ADT_wav_file.c

8 Descrip: Implementaci on del TDA archivo WAV.

9 Obs:

10

11 ***************************************************************************** */

12

13

14 #include <stdio.h>

15 #include <string.h>

16 #include <stdlib.h>

17 #include <math.h>

18 #include "ADT_wav_file_PRIVATE.h"

19

20

21

22 /* |/////////////////////////////////| 1) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

23 /* |////////////////////////////////| Creador |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

24 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

25 status_t ADT_wav_file_create_from_vector(uint n_samples , uint sample_rate ,

26 double vector[],

27 ADT_wav_file_t *wav_file)

28 {

29 size_t i;

30 double scale; /* Factor de escala */

31

32 /* Validaciones de entrada */

33 if(wav_file ==NULL || vector ==NULL) return ERROR_NULL_POINTER;

34 if(! n_samples) return ERROR_INVALID_INFO;

35 if(n_samples > WAV_MAX_N_SAMPLES) return ERROR_TOO_LONG_FILE;

36 if(sample_rate > WAV_MAX_SAMPLE_RATE) return ERROR_INVALID_INFO;

37

38 /* Pedido de memoria y validaci on */

39 *wav_file = (ADT_wav_file_t)malloc(sizeof(struct __wav_file));

40 if(* wav_file ==NULL) return ERROR_NO_MEMORY;

41

42 /* ---------------- Volcado de datos en Chunk ---------------- */

43 memcpy ((* wav_file)->ChunkID , WAV_CHUNK_ID , WAV_ID_SIZES);

44 (* wav_file)->ChunkSize = WAV_CHUNK_FIX_PART_SIZE +

45 WAV_BYTES_SAMPLE*n_samples;

42

8.3 ADT wav file

46 memcpy ((* wav_file)->Format , WAV_FORMAT , WAV_ID_SIZES);

47

48 /* -------------- Volcado de datos en SubChunk1 -------------- */

49 memcpy ((* wav_file)->SubChunk1ID , WAV_SUBCHUNK1_ID , WAV_ID_SIZES);

50 (* wav_file)->SubChunk1Size = WAV_SUBCHUNK1_SIZE;

51 (* wav_file)->AudioFormat = WAV_AUDIO_FORMAT;

52 (* wav_file)->NumChannels = WAV_MONO_CHANNELS;

53 (* wav_file)->SampleRate = sample_rate;

54 (* wav_file)->ByteRate = WAV_BYTES_SAMPLE*sample_rate;

55 (* wav_file)->BlockAlign = WAV_BITS_SAMPLE;

56 (* wav_file)->BitsPerSample = WAV_BITS_SAMPLE;

57

58 /* -------------- Volcado de datos en SubChunk2 -------------- */

59 memcpy ((* wav_file)->SubChunk2ID , WAV_SUBCHUNK2_ID , WAV_ID_SIZES);

60 (* wav_file)->SubChunk2Size = WAV_BYTES_SAMPLE*n_samples;

61

62 /* Pedido de memoria para las muestras y validaci on */

63 (* wav_file)->Data = (short *) malloc(n_samples*sizeof(short));

64 if((* wav_file)->Data==NULL)

65 {

66 free(* wav_file);

67 return ERROR_NO_MEMORY;

68 }

69 /* Bu squeda de maximo absoluto para evitar overflow */

70 scale = 0;

71 for(i=0; i<n_samples; i++)

72 {

73 if(fabs(vector[i])>scale)

74 scale = fabs(vector[i]);

75 }

76 /* Ca lculo del factor de escala */

77 scale = WAV_MAX_SAMPLE_VALUE/scale;

78 /* Guardado de las muestras utilizando el factor de escala */

79 for(i=0; i<n_samples; i++)

80 ((* wav_file)->Data)[i] = scale*vector[i];

81

82

83 return OK;

84 }

85

86

87

88 /* |/////////////////////////////////| 2) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

89 /* |//////////////////////////////| Destructor |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

90 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

91 status_t ADT_wav_file_destroy(ADT_wav_file_t *wav_file)

92 {

93 if(wav_file ==NULL || *wav_file ==NULL) return ERROR_NULL_POINTER;

94

95 free ((* wav_file)->Data);

96 free(* wav_file);

97 *wav_file = NULL;

98 return OK;

99 }

100

101

102

103 /* |/////////////////////////////////| 3) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

104 /* |//////////////////////////| Escritor en archivo |\\\\\\\\\\\\\\\\\\\\\\\\\| */

43

8.4 main modules

105 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

106 status_t ADT_wav_file_write(ADT_wav_file_t wav_file , FILE *stream)

107 {

108 size_t i;

109 uint n_samples;

110

111 if(stream ==NULL || wav_file ==NULL) return ERROR_NULL_POINTER;

112

113 /* --------------- Escritura de datos en Chunk --------------- */

114 fwrite (&( wav_file ->ChunkID), 1, WAV_ID_SIZES , stream);

115 _write_little_endian(wav_file ->ChunkSize , TYPE_INT32 , stream);

116 fwrite (&( wav_file ->Format), 1, WAV_ID_SIZES , stream);

117

118 /* ------- Escritura de datos en SubChunk1 ------- */

119 fwrite (&( wav_file ->SubChunk1ID), 1, WAV_ID_SIZES , stream);

120 _write_little_endian(wav_file ->SubChunk1Size , TYPE_INT32 , stream);

121 _write_little_endian(wav_file ->AudioFormat , TYPE_INT16 , stream);

122 _write_little_endian(wav_file ->NumChannels , TYPE_INT16 , stream);

123 _write_little_endian(wav_file ->SampleRate , TYPE_INT32 , stream);

124 _write_little_endian(wav_file ->ByteRate , TYPE_INT32 , stream);

125 _write_little_endian(wav_file ->BlockAlign , TYPE_INT16 , stream);

126 _write_little_endian(wav_file ->BitsPerSample , TYPE_INT16 , stream);

127

128 /* ------- Escritura de datos en SubChunk2 ------- */

129 fwrite (&( wav_file ->SubChunk2ID), 1, WAV_ID_SIZES , stream);

130 _write_little_endian(wav_file ->SubChunk2Size , TYPE_INT32 , stream);

131

132 n_samples = (wav_file ->SubChunk2Size)/WAV_BYTES_SAMPLE;

133 for(i=0; i<n_samples; i++)

134 _write_little_endian ((wav_file ->Data)[i], TYPE_INT16 , stream);

135

136 return OK;

137 }

138

139

140

141 /* |/////////////////////////////////| *) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

142 /* |//////////////////////////| Funciones internas |\\\\\\\\\\\\\\\\\\\\\\\\\\| */

143 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

144 void _write_little_endian(uint value , type_t type , FILE *stream)

145 {

146 uchar convert[TYPE_INT32], i;

147

148 /* En 'type_t ' cada tipo tiene asignada la cantidad de bytes! */

149 for(i=0; i<type; i++)

150 convert[i]=( value&(UCHAR_MAX <<i*CHAR_BIT))>>i*CHAR_BIT;

151

152 fwrite (&convert , 1, type , stream);

153 }

8.4. main modules

8.4.1. addsynthlib.h

1 /* *****************************************************************************

2

3 Algoritmos y Programaci on I - 75.02/95.11 - Curso Ing. Mart ın Cardozo

4 TP N o 3 - 1er Cuatrimestre 2012

5

6 Alumnos: ARIAS , Francisco - FERRARI BIHURRIET , Francisco

44

8.4 main modules

7 Archivo: addsynthlib.h

8 Descrip: Encabezado de la biblioteca de sı ntesis aditiva.

9 Obs:

10

11 ***************************************************************************** */

12

13

14 #if ndef ADDSYNTHLIB_H

15 #define ADDSYNTHLIB_H

16

17 #include <stdio.h>

18 #include "../ ADT_synthesizer/ADT_synthesizer.h"

19 #include "../ ADT_musical_score/ADT_musical_score.h"

20

21 #define TWOPI 2*3.14159265358979323846

22

23 typedef struct

24 {

25 double *values;

26 size_t sample_rate;

27 } tabsin_t;

28

29

30 /* |///////////////////////////////////// \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

31 /* |||||||||||||||||||||||||||||||| Prototipos |||||||||||||||||||||||||||||||| */

32 /* |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ ////////////////////////////////////| */

33

34 /* 1) Funci on para crear la tabla con el seno precalculado */

35 tabsin_t * tabsin_create_table(size_t);

36

37 /* 2) Funci on para destruir la tabla */

38 void tabsin_destroy_table(tabsin_t **);

39

40 /* 3) Funci on para obtener la envolvente en funci on del tiempo */

41 double evenlope(const ADT_synthesizer_t *, const ADT_musical_score_t *,

42 double , size_t);

43

44 /* 4) Funci on para sintetizar una partitura completa */

45 void synthesize(const ADT_musical_score_t *, const ADT_synthesizer_t *,

46 tabsin_t *, double []);

47

48

49 #endif /* ADDSYNTHLIB_H */

8.4.2. addsynthlib.c

1 /* *****************************************************************************

2

3 Algoritmos y Programaci on I - 75.02/95.11 - Curso Ing. Mart ın Cardozo

4 TP N o 3 - 1er Cuatrimestre 2012

5

6 Alumnos: ARIAS , Francisco - FERRARI BIHURRIET , Francisco

7 Archivo: addsynthlib.c

8 Descrip: Biblioteca de sı ntesis aditiva.

9 Obs: Contiene rutinas que utilizan la funci on seno tabulada seg un la

10 frecuancia de muestreo , para optimizar la velocidad de sı ntesis.

11

12 ***************************************************************************** */

13

14

45

8.4 main modules

15 #include <stdio.h>

16 #include <stdlib.h>

17 #include <math.h>

18 #include "addsynthlib.h"

19 #include "common.h"

20

21

22 /* |/////////////////////////////////| 1) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

23 /* |/////////| Funci on para crear la tabla con el seno precalculado |\\\\\\\\\| */

24 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

25 tabsin_t * tabsin_create_table(size_t sample_rate)

26 {

27 tabsin_t *ptable;

28 size_t i;

29 double aux;

30

31 /* Memoria para la estructura */

32 ptable = (tabsin_t *) malloc(sizeof(tabsin_t));

33 if(ptable == NULL) return NULL;

34

35 /* Memoria para la tabla */

36 ptable ->values = (double *) malloc(sample_rate*sizeof(double));

37 if(ptable ->values == NULL)

38 {

39 free(ptable);

40 return NULL;

41 }

42

43 ptable ->sample_rate = sample_rate;

44

45 aux = TWOPI / (sample_rate -1);

46

47 /* Cargado de la tabla */

48 for(i=0; i < sample_rate; i++)

49 (ptable ->values)[i] = sin(i*aux);

50

51 return ptable;

52 }

53

54

55

56 /* |/////////////////////////////////| 2) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

57 /* |////////////////////| Funci on para destruir la tabla |\\\\\\\\\\\\\\\\\\\\| */

58 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

59 void tabsin_destroy_table(tabsin_t ** table)

60 {

61 if(table == NULL || *table == NULL) return;

62

63 free ((* table)->values);

64 free(* table);

65 *table = NULL;

66 }

67

68

69

70 /* |/////////////////////////////////| 3) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

71 /* |///////| Funci on para obtener la envolvente en funci on del tiempo |\\\\\\\| */

72 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

73 #define ATTACK_TIME parameters_attack[param_T0]

46

8.4 main modules

74 #define RELEASE_TIME parameters_release[param_T0]

75

76 double evenlope(const ADT_synthesizer_t *synthesizer ,

77 const ADT_musical_score_t *musical_score ,

78 double t, size_t note)

79 {

80 modulation_t modulation_attack;

81 modulation_t modulation_sustained;

82 modulation_t modulation_release;

83 double *parameters_attack;

84 double *parameters_sustained;

85 double *parameters_release;

86 double duration;

87

88 if( synthesizer == NULL || musical_score == NULL )

89 return 0;

90 if( (ADT_synthesizer_get_modulation_at(synthesizer , ATTACK ,

91 &parameters_attack , &modulation_attack)) != OK )

92 return 0;

93 if( (ADT_synthesizer_get_modulation_at(synthesizer , SUSTAINED ,

94 &parameters_sustained , &modulation_sustained)) != OK )

95 return 0;

96 if( (ADT_synthesizer_get_modulation_at(synthesizer , RELEASE ,

97 &parameters_release , &modulation_release)) != OK )

98 return 0;

99

100

101 duration = ADT_musical_score_get_duration_at(musical_score , note);

102

103 if( t < ATTACK_TIME )

104 return modulation_attack(parameters_attack , t);

105

106 if( t >= ATTACK_TIME && t < duration )

107 return modulation_sustained(parameters_sustained , t-ATTACK_TIME);

108

109 if( t >= duration && t < duration+RELEASE_TIME )

110 return modulation_sustained(parameters_sustained , duration -ATTACK_TIME)

111 * modulation_release(parameters_release , t-duration);

112

113 return 0;

114 }

115

116

117

118 /* |/////////////////////////////////| 4) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

119 /* |////////////| Funci on para sintetizar una partitura completa |\\\\\\\\\\\\| */

120 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

121 /*

122 Precondici on: El vector de doubles alcanza , es decir que ya fue pedida

123 la memoria para toda la canci on.

124 */

125 void synthesize(const ADT_musical_score_t *musical_score ,

126 const ADT_synthesizer_t *synth ,

127 tabsin_t *table , double samples_vec [])

128 {

129 size_t i, harmonic , n_harmonics , note , n_notes;

130 double T; /* Per ıodo en muestras */

131 uint init_sample , n_samples;

132 double harmonic_multiple , harmonic_intensity;

47

8.4 main modules

133 double *release_time;

134

135 if(musical_score == NULL || synth == NULL ||

136 table == NULL || samples_vec == NULL) return;

137

138 /* Se obtiene el release_time */

139 ADT_synthesizer_get_modulation_at(synth , RELEASE , &release_time , NULL);

140 /* Se obtiene el numero de arm o nicos */

141 n_harmonics = ADT_synthesizer_get_quantity_harmonics(synth);

142 /* Se obtiene la cantidad de notas */

143 n_notes = ADT_musical_score_get_quantity_notes(musical_score);

144

145 /*-- Para cada nota --*/

146 for(note =0; note < n_notes; note ++)

147 {

148 /* Se obtiene la muestra inicial */

149 init_sample = ADT_musical_score_get_start_time_at(musical_score , note)

150 * table ->sample_rate;

151 /* Se obtiene la cantidad de muestras */

152 n_samples = ( ADT_musical_score_get_duration_at(musical_score , note)

153 + *release_time) * table ->sample_rate;

154

155 /*-- Sı ntesis: Para cada arm onico --*/

156 for(harmonic =0; harmonic <n_harmonics; harmonic ++)

157 {

158 /* Se obtiene el mu ltiplo y la intensidad */

159 ADT_synthesizer_get_harmonic_at(synth , harmonic , &harmonic_multiple ,

160 &harmonic_intensity);

161 /* Asignaci on del per ıodo en muestras */

162 T = table ->sample_rate /

163 ( ADT_musical_score_get_frequency_at(musical_score , note)

164 * harmonic_multiple );

165

166 /*-- Para cada muestra --*/

167 for(i=0; i < n_samples; i++)

168 {

169 samples_vec[i+init_sample] += harmonic_intensity

170 * (table ->values) /* Uso del seno tabulado: */

171 [ (size_t)( (i/T - floor(i/T)) * table ->sample_rate ) ]

172 * evenlope(synth , musical_score ,

173 i/( double)table ->sample_rate , note);

174 }

175 }

176 }

177 }

8.4.3. common.h

1 /* *****************************************************************************

2

3 Algoritmos y Programaci on I - 75.02/95.11 - Curso Ing. Mart ın Cardozo

4 TP N o 3 - 1er Cuatrimestre 2012

5

6 Alumnos: ARIAS , Francisco - FERRARI BIHURRIET , Francisco

7 Archivo: common.h

8 Descrip: Encabezado de definiciones comunes a todos los mo dulos.

9 Obs:

10

11 ***************************************************************************** */

12

48

8.4 main modules

13

14 #if ndef COMMON_H

15 #define COMMON_H

16

17

18 /* ----------------------- Abreviaturas de tipos ----------------------- */

19 typedef unsigned char uchar;

20 typedef unsigned short ushort;

21 typedef unsigned int uint;

22 typedef unsigned long ulong;

23 typedef char * string;

24 /* --------------------------------------------------------------------- */

25

26

27 /* ----------------------- Enumerativo de estado ----------------------- */

28 typedef enum

29 {

30 OK = 0, /* Ning un error ha ocurrido. */

31 ERROR_BAD_ARGUMENTS = 1, /* Error de argumentos incorrectos. */

32 ERROR_BAD_SAMPLE_RATE = 2, /* Error de frecuencia de muestreo. */

33 ERROR_MUSICAL_SCORE = 3, /* Error en el archivo de partitura. */

34 ERROR_SYNTHESIZER = 4, /* Error en el archivo de sintetizador. */

35 ERROR_NULL_POINTER = 5, /* Error de puntero nulo. */

36 ERROR_INVALID_INFO = 6, /* Error de informaci on inv alida. */

37 ERROR_NO_MEMORY = 7, /* Error de falta de memoria. */

38 ERROR_TOO_LONG_FILE = 8, /* Error de archivo demasiado largo. */

39 ERROR_WAV_FILE = 9 /* Error en el archivo WAV. */

40 } status_t;

41 /* ··································· */

42 extern const string status_msgs []; /* Mensajes en archivo externo. */

43 /* --------------------------------------------------------------------- */

44

45

46 /* ---------------------- Enumerativo de progreso ---------------------- */

47 typedef enum

48 {

49 PROGRESS_PREVIOUS_TASKS = 0, /* Tareas previas. */

50 PROGRESS_MUSIC_SYNTHESIS = 1, /* Sı ntesis de la musica. */

51 PROGRESS_OUT_FILE_CREATION = 2, /* Creaci on del archivo de salida. */

52 PROGRESS_DUMP_OF_DATA = 3, /* Volcado de datos. */

53 PROGRESS_FILE_CREATED = 4 /* Archivo creado. */

54 } progress_t;

55 /* ··································· */

56 extern const string progress_msgs []; /* Mensajes en archivo externo. */

57 /* --------------------------------------------------------------------- */

58

59

60 /* -------------------------- Mensajes de uso -------------------------- */

61 #define USAGE_USAGE 0 /* Uso. */

62 #define USAGE_SAMPLE_RATE 1 /* Frecuencia de muestreo. */

63 #define USAGE_FILE_MUSICAL_SCORE 2 /* Archivo de partitura musical. */

64 #define USAGE_FILE_SYNTHESIZER 3 /* Archivo de sintetizador. */

65 #define USAGE_FILE_WAVE 4 /* Archivo de audio (WAV). */

66 /* ··································· */

67 extern const string usage_msgs []; /* Mensajes en archivo externo. */

68 /* --------------------------------------------------------------------- */

69

70

71 /* ----------------------- Validate arguments -------------------------- */

49

8.4 main modules

72 #define ARGUMENT_SAMPLE_RATE "-f"

73 #define ARGUMENT_FILE_MUSICAL_SCORE "-p"

74 #define ARGUMENT_FILE_SYNTHESIZER "-s"

75 #define ARGUMENT_FILE_WAVE "-o"

76 #define DEFAULT_SAMPLE_RATE 44100 /*Hz*/

77 #define MAX_SAMPLE_RATE 96000 /*Hz*/

78 /* --------------------------------------------------------------------- */

79

80 #endif /* COMMON_H */

8.4.4. main.c

1 /* *****************************************************************************

2

3 Algoritmos y Programaci on I - 75.02/95.11 - Curso Ing. Mart ın Cardozo

4 TP N o 3 - 1er Cuatrimestre 2012

5

6 Alumnos: ARIAS , Francisco - FERRARI BIHURRIET , Francisco

7 Archivo: main.c

8 Descrip: Modulo principal de la aplicaci on.

9 Obs:

10

11 ***************************************************************************** */

12

13

14 #include <stdio.h>

15 #include <stdlib.h>

16 #include <string.h>

17 #include "../ ADT_musical_score/ADT_musical_score.h"

18 #include "../ ADT_synthesizer/ADT_synthesizer.h"

19 #include "../ ADT_wav_file/ADT_wav_file.h"

20 #include "addsynthlib.h"

21

22 typedef struct

23 {

24 string musical_score;

25 string synthesizer;

26 string wave;

27 } tfiles_names;

28

29

30 /* ******************************* PROTOTYPES ********************************* */

31

32 /* 1) validacion de argumentos */

33 status_t validate_arguments(int , string [], tfiles_names*, size_t *);

34

35 /* 2) Impresores de errores y estados */

36 void progress_msg(progress_t);

37 void status_msg(status_t);

38 void show_usage(void);

39

40 /* ----------------------------------------------------------------------------*/

41

42 string program_name;

43

44 /* ******************************* FUNCTION MAIN ****************************** */

45

46 int main(int argc , string argv []){

47

48 /*****--------------------------- variables ------------------------------*****/

50

8.4 main modules

49

50 status_t st;

51 size_t sample_rate , note , quantity_notes;

52 tfiles_names files_names;

53 ADT_musical_score_t *musical_score;

54 ADT_synthesizer_t *synthesizer;

55 ADT_wav_file_t wav_file;

56 uint n_samples;

57 double *samples_vec;

58 double *release;

59 double time_length , aux;

60 FILE *out_file;

61 tabsin_t *table;

62

63 /*****--------------------------------------------------------------------*****/

64

65 /* Validacion de argumentos */

66 program_name = *argv;

67 st = validate_arguments(argc , argv , &files_names , &sample_rate);

68 if(st != OK)

69 {

70 status_msg(st);

71 show_usage ();

72 return st;

73 }

74

75

76 progress_msg(PROGRESS_PREVIOUS_TASKS);

77

78 /* Creacion de los TDA partitura y sintetizador */

79 if( (st = ADT_musical_score_new (& musical_score)) != OK )

80 {

81 status_msg(st);

82 return st;

83 }

84

85 if( (st = ADT_synthesizer_new (& synthesizer)) != OK )

86 {

87 ADT_musical_score_destroy (& musical_score);

88 status_msg(st);

89 return st;

90 }

91

92 /* Cargar el contenido de los archivos en los TDA */

93 if( (st = ADT_musical_score_set_from_file (& musical_score ,

94 files_names.musical_score)) != OK )

95 {

96 ADT_synthesizer_destroy (& synthesizer);

97 status_msg(st);

98 return st;

99 }

100

101 if( (st = ADT_synthesizer_set_from_file (& synthesizer ,

102 files_names.synthesizer)) != OK )

103 {

104 ADT_musical_score_destroy (& musical_score);

105 status_msg(st);

106 return st;

107 }

51

8.4 main modules

108

109 /* |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| */

110 /* |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| */

111

112 /* Otenci on del tiempo de duraci on de la canci on */

113 time_length = 0;

114 quantity_notes = ADT_musical_score_get_quantity_notes(musical_score);

115 for(note = 0; note < quantity_notes; note ++)

116 {

117 aux = ADT_musical_score_get_start_time_at(musical_score , note) +

118 ADT_musical_score_get_duration_at(musical_score , note);

119 if(aux > time_length)

120 time_length = aux;

121 }

122 /* Suma del release time */

123 ADT_synthesizer_get_modulation_at(synthesizer , RELEASE , &release , NULL);

124 time_length += (* release);

125

126 /* Otenci on de la cantidad de muestras total */

127 n_samples = time_length*sample_rate + 1;

128

129 /* Pedido para las muestras inicializadas en 0 */

130 samples_vec = (double *) calloc(n_samples , sizeof(double));

131 if(samples_vec == NULL)

132 {

133 ADT_musical_score_destroy (& musical_score);

134 ADT_synthesizer_destroy (& synthesizer);

135 status_msg(ERROR_NO_MEMORY);

136 return ERROR_NO_MEMORY;

137 }

138

139 /* Creado de la tabla del seno precalculado */

140 table = tabsin_create_table(sample_rate);

141 if(table == NULL)

142 {

143 free(samples_vec);

144 ADT_musical_score_destroy (& musical_score);

145 ADT_synthesizer_destroy (& synthesizer);

146 status_msg(ERROR_NO_MEMORY);

147 return ERROR_NO_MEMORY;

148 }

149

150 /* Sintetizado de la partitura */

151 progress_msg(PROGRESS_MUSIC_SYNTHESIS);

152 synthesize(musical_score , synthesizer , table , samples_vec);

153

154 /* Liberaci on de lo que ya no se utilizar a: tabla de senos y TDAs */

155 tabsin_destroy_table (& table);

156 ADT_musical_score_destroy (& musical_score);

157 ADT_synthesizer_destroy (& synthesizer);

158

159 /* Creaci on del TDA Archivo WAV */

160 progress_msg(PROGRESS_OUT_FILE_CREATION);

161 st = ADT_wav_file_create_from_vector(n_samples , sample_rate ,

162 samples_vec , &wav_file);

163

164 /* Liberaci on de las muestras en double */

165 free(samples_vec);

166 if(st != OK)

52

8.4 main modules

167 {

168 status_msg(st);

169 return st;

170 }

171

172 /* Apertura del archivo de salida */

173 out_file = fopen(files_names.wave , "wb");

174 if(out_file == NULL)

175 {

176 ADT_wav_file_destroy (& wav_file);

177 status_msg(ERROR_WAV_FILE);

178 return ERROR_WAV_FILE;

179 }

180

181 /* Escritura del archivo de salida */

182 progress_msg(PROGRESS_DUMP_OF_DATA);

183 st = ADT_wav_file_write(wav_file , out_file);

184

185 /* Cierre del archivo de salida */

186 fclose(out_file);

187 if(st != OK)

188 {

189 ADT_wav_file_destroy (& wav_file);

190 status_msg(st);

191 return st;

192 }

193

194 /* Destrucci on del TDA Archivo WAV */

195 st = ADT_wav_file_destroy (& wav_file);

196

197 fputc('\n', stderr);

198 status_msg(st);

199 fprintf(stderr , " %s: ' %s '.\n\n", progress_msgs[PROGRESS_FILE_CREATED],

200 files_names.wave);

201 return st;

202 }

203

204 /* ----------------------------------------------------------------------------*/

205

206

207 /* |/////////////////////////////////| 1) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

208 /* |//////////////////////| Validacion de argumentos |\\\\\\\\\\\\\\\\\\\\\\\\| */

209 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

210

211 /* Macro de fuci on: es impar? */

212 #define ISODD(n) ((n) %2)

213 /* -------------------------- */

214

215 status_t validate_arguments(int argc , string argv[], tfiles_names *files_names ,

216 size_t *sample_rate)

217 {

218 size_t i;

219

220 /* Los argumentos estan dados de a pares , sumando el

221 nombre del programa , lo correcto es un numero impar. */

222 if(! ISODD(argc))

223 return ERROR_BAD_ARGUMENTS;

224

225 *sample_rate = 0;

53

8.4 main modules

226 files_names ->musical_score = NULL;

227 files_names ->synthesizer = NULL;

228 files_names ->wave = NULL;

229

230 /* Bu squeda de argumentos */

231 for(i = 1; i < argc; i += 2)

232 {

233 if( !strcmp(argv[i], ARGUMENT_FILE_MUSICAL_SCORE) )

234 files_names ->musical_score = argv[i+1];

235

236 if( !strcmp(argv[i], ARGUMENT_FILE_SYNTHESIZER) )

237 files_names ->synthesizer = argv[i+1];

238

239 if( !strcmp(argv[i], ARGUMENT_FILE_WAVE) )

240 files_names ->wave = argv[i+1];

241

242 if( !strcmp(argv[i], ARGUMENT_SAMPLE_RATE) )

243 *sample_rate = strtoul(argv[i+1],NULL ,10);

244 }

245

246 /* Si los par a metros obligatorios no fueron ingresados */

247 if( files_names ->musical_score == NULL ||

248 files_names ->synthesizer == NULL ||

249 files_names ->wave == NULL )

250 return ERROR_BAD_ARGUMENTS;

251

252 /* Si el par a metro opcional no fue ingresado */

253 if(!(* sample_rate))

254 *sample_rate = DEFAULT_SAMPLE_RATE;

255

256 /* Validaci on de maxima frecuencia de muestreo */

257 if( *sample_rate > MAX_SAMPLE_RATE )

258 return ERROR_BAD_SAMPLE_RATE;

259

260 return OK;

261 }

262

263

264 /* |/////////////////////////////////| 2) |\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

265 /* |////////////////////| Impresores de errores y estados |\\\\\\\\\\\\\\\\\\\| */

266 /* |/////////////////////////////////////|\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\| */

267

268 void progress_msg(progress_t pg)

269 {

270 fprintf(stderr , "\n %s... ", progress_msgs[pg]);

271 }

272

273 /* -------------------------------------------------------------------------- */

274

275 void status_msg(status_t st)

276 {

277 fprintf(stderr , " %s\n", status_msgs[st]);

278 }

279

280 /* -------------------------------------------------------------------------- */

281

282 void show_usage(void)

283 {

284 fprintf(stderr , "\n %s: %s [ %s < %s>] %s < %s> %s < %s> %s < %s>\n\n",

54

8.5 langs

285 usage_msgs[USAGE_USAGE], program_name ,

286 ARGUMENT_SAMPLE_RATE , usage_msgs[USAGE_SAMPLE_RATE],

287 ARGUMENT_FILE_MUSICAL_SCORE , usage_msgs[USAGE_FILE_MUSICAL_SCORE],

288 ARGUMENT_FILE_SYNTHESIZER , usage_msgs[USAGE_FILE_SYNTHESIZER],

289 ARGUMENT_FILE_WAVE , usage_msgs[USAGE_FILE_WAVE ]);

290 }

8.5. langs

8.5.1. msgs dictionary es.c

1 /* *****************************************************************************

2

3 Algoritmos y Programaci on I - 75.02/95.11 - Curso Ing. Mart ın Cardozo

4 TP N o 3 - 1er Cuatrimestre 2012

5

6 Alumnos: ARIAS , Francisco - FERRARI BIHURRIET , Francisco

7 Archivo: msgs_dictionary_es.c

8 Descrip: Diccionario de mensajes al usuario en idioma castellano.

9 Obs:

10

11 ***************************************************************************** */

12

13

14 #include <stdio.h>

15 #include "../ main_modules/common.h"

16

17 /* ------------------------- Mensajes de estado ------------------------- */

18 const string status_msgs []=

19 {

20 "Ok.",

21 "Error! Codigo 1: Argumentos incorrectos.",

22 "Error! Codigo 2: Frecuencia de muestreo incorrecta.",

23 "Error! Codigo 3: En el archivo de partitura.",

24 "Error! Codigo 4: En el archivo de sintetizador.",

25 "Error! Codigo 5: Se recibio un puntero nulo!",

26 "Error! Codigo 6: Informacion invalida!",

27 "Error! Codigo 7: Memoria insuficiente!",

28 "Error! Codigo 8: Archivo demasiado largo!",

29 "Error! Codigo 9: No se pudo abrir el archivo WAV! Esta en uso?"

30 };

31 /* ---------------------------------------------------------------------- */

32

33 /* ------------------------ Mensajes de progreso ------------------------ */

34 const string progress_msgs []=

35 {

36 "Realizando tareas previas",

37 "Sintetizando la musica",

38 "Creando el archivo de salida",

39 "Volcando los datos en el archivo",

40 "Archivo escrito"

41 };

42 /* ---------------------------------------------------------------------- */

43

44 /* --------------------------- Mensajes de uso -------------------------- */

45 const string usage_msgs []=

46 {

47 "Uso",

48 "frecuencia",

49 "partitura.txt",

55

8.5 langs

50 "sintetizador.txt",

51 "audio.wav"

52 };

53 /* ---------------------------------------------------------------------- */

8.5.2. msgs dictionary en.c

1 /* *****************************************************************************

2

3 Algoritmos y Programaci on I - 75.02/95.11 - Curso Ing. Mart ın Cardozo

4 TP N o 3 - 1er Cuatrimestre 2012

5

6 Alumnos: ARIAS , Francisco - FERRARI BIHURRIET , Francisco

7 Archivo: msgs_dictionary_en.c

8 Descrip: Diccionario de mensajes al usuario en idioma ingl es.

9 Obs:

10

11 ***************************************************************************** */

12

13

14 #include <stdio.h>

15 #include "../ main_modules/common.h"

16

17 /* ------------------------- Mensajes de estado ------------------------- */

18 const string status_msgs []=

19 {

20 "Ok.",

21 "Error! Code 1: Incorrect arguments.",

22 "Error! Code 2: Incorrect sample rate.",

23 "Error! Code 3: In the musical score file.",

24 "Error! Code 4: In the synthesizer file.",

25 "Error! Code 5: A null pointer was received!",

26 "Error! Code 6: Invalid information!",

27 "Error! Code 7: Insufficient memory!",

28 "Error! Code 8: Too long file!",

29 "Error! Code 9: Could not open the WAV file! In use?"

30 };

31 /* ---------------------------------------------------------------------- */

32

33 /* ------------------------ Mensajes de progreso ------------------------ */

34 const string progress_msgs []=

35 {

36 "Performing previous work",

37 "Synthesizing the music",

38 "Creating the output file",

39 "Flushing the data in the file",

40 "File written"

41 };

42 /* ---------------------------------------------------------------------- */

43

44 /* --------------------------- Mensajes de uso -------------------------- */

45 const string usage_msgs []=

46 {

47 "Usage",

48 "sample_rate",

49 "musical_score.txt",

50 "synthesizer.txt",

51 "audio.wav"

52 };

53 /* ---------------------------------------------------------------------- */

56

8.6 Makefile

8.6. Makefile

8.6.1. Makefile

1 #*******************************************************************************

2

3 # Algoritmos y Programaci on I - 75.02/95.11 - Curso Ing. Mart ın Cardozo

4 # TP N o 3 - 1er Cuatrimestre 2012

5 #

6 # Alumnos: ARIAS , Francisco - FERRARI BIHURRIET , Francisco

7 # Archivo: Makefile

8 # Descrip: Makefile para la construcci on de la aplicaci on completa.

9 # Obs: Admite la compilaci on para distintos idiomas. Los mismos son

10 # configurables en el archivo lang.

11

12 #*******************************************************************************

13

14 # //////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ #

15 # |||||||||||||||||||||||||||||| Configuraciones ||||||||||||||||||||||||||||| #

16 # \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\////////////////////////////////////// #

17

18 # Compilador:

19 CC = gcc

20 # Flags para linkeo:

21 LFLAGS = -ansi -pedantic -Wall

22 # Flags para compilacion:

23 CFLAGS = -ansi -pedantic -Wall -O3 -c

24 # Nombre de salida del proyecto:

25 OUT = synthesizer

26 # Directorio de instalacion:

27 INSTALL_PATH = /usr/bin

28 # Idioma por defecto:

29 LANG = en

30 # Archivo de idioma:

31 include lang

32

33

34

35 # //////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ #

36 # ||||||||||||||||||||||||| Objetivos y dependencias ||||||||||||||||||||||||| #

37 # \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\////////////////////////////////////// #

38

39 # -------------------------- Codigos objeto -------------------------- #

40 OBJETS = ADT_musical_score.o \

41 ADT_synthesizer.o \

42 modulationlib.o \

43 ADT_wav_file.o \

44 addsynthlib.o \

45 main.o \

46 msgs_dictionary.o

47

48

49 # ---------------------- Reglas de construccion ---------------------- #

50 $(OUT): $(OBJETS)

51 $(CC) $(LFLAGS) $(OBJETS) -o "$(OUT)" -lm

52

53 ADT_musical_score.o: ADT_musical_score/ADT_musical_score.c \

54 ADT_musical_score/ADT_musical_score_PRIVATE.h \

55 ADT_musical_score/ADT_musical_score.h \

57

8.6 Makefile

56 main_modules/common.h

57 $(CC) $(CFLAGS) "$<" -o "$@"

58

59 ADT_synthesizer.o: ADT_synthesizer/ADT_synthesizer.c \

60 ADT_synthesizer/ADT_synthesizer_PRIVATE.h \

61 ADT_synthesizer/ADT_synthesizer.h \

62 ADT_synthesizer/modulationlib.h \

63 main_modules/common.h

64 $(CC) $(CFLAGS) "$<" -o "$@"

65

66 modulationlib.o: ADT_synthesizer/modulationlib.c \

67 ADT_synthesizer/modulationlib.h

68 $(CC) $(CFLAGS) "$<" -o "$@"

69

70 ADT_wav_file.o: ADT_wav_file/ADT_wav_file.c \

71 ADT_wav_file/ADT_wav_file_PRIVATE.h \

72 ADT_wav_file/ADT_wav_file.h \

73 main_modules/common.h

74 $(CC) $(CFLAGS) "$<" -o "$@"

75

76 addsynthlib.o: main_modules/addsynthlib.c \

77 main_modules/addsynthlib.h \

78 ADT_musical_score/ADT_musical_score.h \

79 ADT_synthesizer/ADT_synthesizer.h \

80 ADT_synthesizer/modulationlib.h \

81 main_modules/common.h

82 $(CC) $(CFLAGS) "$<" -o "$@"

83

84 main.o: main_modules/main.c \

85 ADT_musical_score/ADT_musical_score.h \

86 ADT_synthesizer/ADT_synthesizer.h \

87 ADT_synthesizer/modulationlib.h \

88 ADT_wav_file/ADT_wav_file.h \

89 main_modules/addsynthlib.h \

90 main_modules/common.h

91 $(CC) $(CFLAGS) "$<" -o "$@"

92

93 msgs_dictionary.o: langs/msgs_dictionary_$(LANG).c \

94 lang \

95 main_modules/common.h

96 $(CC) $(CFLAGS) "$<" -o "$@"

97

98

99

100 # //////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ #

101 # ||||||||||||||||||||||||||||| Utilidades extras |||||||||||||||||||||||||||| #

102 # \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\////////////////////////////////////// #

103

104 # ---------------------- Limpiar co digos objeto ---------------------- #

105 objclean:

106 rm -f *.o

107

108 # -------------------------- Limpiar (todo) -------------------------- #

109 clean: objclean

110 rm -f "$(OUT)"

111

112 # ------------- Construir y eliminar archivos temporales ------------- #

113 deltemps: $(OUT) objclean

114

58

8.6 Makefile

115 # ------------------------------ Instalar ---------------------------- #

116 install: $(OUT)

117 @ cp "$(OUT)" "$(INSTALL_PATH)"

118 @ echo "'$(OUT)' --> Installed in: $(INSTALL_PATH)"

119

120

121 # --------------------- Todo (instalar y limpiar) -------------------- #

122 all: install clean

123

124

125 # ---------------------------- Desinstalar --------------------------- #

126 remove:

127 rm -f "$(INSTALL_PATH)/$(OUT)"

128

129

130 # ------------------ Purgar (desinstalar y limpiar) ------------------ #

131 purge: remove clean

8.6.2. lang

1 #*******************************************************************************

2

3 # Algoritmos y Programaci on I - 75.02/95.11 - Curso Ing. Mart ın Cardozo

4 # TP N o 3 - 1er Cuatrimestre 2012

5 #

6 # Alumnos: ARIAS , Francisco - FERRARI BIHURRIET , Francisco

7 # Archivo: lang

8 # Descrip: Selector del idioma a utilizar en la compilaci on con 'make '.

9 # Obs: Si se dejan todas las opciones comentadas el programa asumir a el

10 # idioma por defecto.

11

12 #*******************************************************************************

13

14

15 # Para idioma castellano , descomente la siguiente linea:

16 LANG = es

17

18 # For english language , uncomment the following line:

19 # LANG = en

59