75.02 - Algoritmos y Programación I

Anuncio
Universidad de Buenos Aires
Facultad De Ingenierı́a
Año 2012 - 1er Cuatrimestre
Algoritmos y Programación I (75.02)
TRABAJO PRÁCTICO Nº 3
TEMA: Sintetizador de música
FECHA: 30 de agosto de 2012
INTEGRANTES:
Ferrari Bihurriet, Francisco
- #92275
<franferra 09 90@hotmail.com>
Arias, Francisco Nicolas
- #93459
<ariasfrancisco91@yahoo.com>
75.02 - Algoritmos y Programación I
Ing. Martı́n Cardozo
ÍNDICE
Índice
1. Enunciado
3
2. Estructura Funcional
11
3. Consideraciones y Estrategias
12
3.1. Validación de datos y lectura de archivos de entrada . . . . . . . . . . . . . 12
3.2. Sı́ntesis del sonido . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12
3.3. Escritura en del archivo de salida en formato WAV . . . . . . . . . . . . . 12
4. Resultados de ejecución
13
4.1. En condiciones inesperadas de entrada . . . . . . . . . . . . . . . . . . . . 13
4.2. En condiciones normales de entrada . . . . . . . . . . . . . . . . . . . . . . 15
5. Problemas encontrados en el desarrollo
17
5.1. Optimización del tiempo de sı́ntesis . . . . . . . . . . . . . . . . . . . . . . 17
5.2. Funciones de modulación incorrectas . . . . . . . . . . . . . . . . . . . . . 18
6. Conclusiones
18
7. Bibliografı́a consultada
18
8. Códigos fuente
8.1. ADT musical score . . . . . . . . . . .
8.1.1. ADT musical score.h . . . . . .
8.1.2. ADT musical score PRIVATE.h
8.1.3. ADT musical score.c . . . . . .
8.2. ADT synthesizer . . . . . . . . . . . .
8.2.1. modulationlib.h . . . . . . . . .
8.2.2. modulationlib.c . . . . . . . . .
8.2.3. ADT synthesizer.h . . . . . . .
8.2.4. ADT synthesizer PRIVATE.h .
8.2.5. ADT synthesizer.c . . . . . . .
8.3. ADT wav file . . . . . . . . . . . . . .
8.3.1. ADT wav file.h . . . . . . . . .
8.3.2. ADT wav file PRIVATE.h . . .
8.3.3. ADT wav file.c . . . . . . . . .
8.4. main modules . . . . . . . . . . . . . .
8.4.1. addsynthlib.h . . . . . . . . . .
8.4.2. addsynthlib.c . . . . . . . . . .
8.4.3. common.h . . . . . . . . . . . .
8.4.4. main.c . . . . . . . . . . . . . .
8.5. langs . . . . . . . . . . . . . . . . . . .
8.5.1. msgs dictionary es.c . . . . . .
8.5.2. msgs dictionary en.c . . . . . .
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
19
19
19
20
22
27
27
28
31
32
34
40
40
40
42
44
44
45
48
50
55
55
56
1
ÍNDICE
8.6. Makefile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
8.6.1. Makefile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
8.6.2. lang . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59
2
1 Enunciado
1.
Enunciado
Trabajo Práctico N◦3 - Sintetizador de música
1.
Objetivo del TP
El objetivo del presente trabajo consiste en la realización de un aplicativo en modo
consola, escrito en ANSI-C89, que secuencie archivos WAVE en base a la especificación
de un sintetizador y una partitura musical.
2.
Alcance del TP
Mediante el presente TP se busca que el Estudiante adquiera y aplique conocimientos
sobre los siguientes temas:
Argumentos en Lı́nea de Ordenes (CLA).
Makefile y proyectos modularizados.
TDAs.
Memoria dinámica.
Archivos de texto y binarios.
Formato WAVE (audio).
Punteros a Funciones.
3.
Introducción
3.1.
El sonido
La percepción que sentimos como sonido se debe a la vibración de ondas en el aire
que es sensada por nuestros oidos. En los sonidos podemos distinguir una intensidad, por
la cual hay sonidos más fuertes que otros; un tono, por el cual hay sonidos más agudos
y sonidos más graves; y un timbre, por el cual no todas las cosas que tienen el mismo
tono suenan igual.
Supongamos una onda de 110Hz que oscila durante un cuarto de segundo (Fig. 1).
Esta onda es sencilla de concebir matemáticamente, pero es imposible de obtener por
medios fı́sicos.
Una onda fı́sica no podrı́a comenzar a oscilar instantáneamente, ni tampoco podrı́a
atenuarse inmediatamente. Si oyéramos una onda de esas caracterı́sticas, percibirı́amos
un chasquido al comienzo y al final de la misma1 . Una onda producida por un elemento
fı́sico tendrá un incremento paulatino hasta su máximo producido por el ataque y su
entrada en resonancia, irá apaciguándose por disipación de energı́a durante el sostenido,
1
Le dejamos hacer al Análisis de Fourier las cuentas pertinentes.
1
3
1 Enunciado
Algoritmos y Programación I (75.02) – Trabajo Práctico 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
0.25
0.3
Figura 1: Onda sinusoidal de 110Hz de duración 0,25s.
1
0.5
0
-0.5
-1
-0.05
0
0.05
0.1
0.15
0.2
Figura 2: 0 < t < 0,05: Ataque. 0,05 < t < 0,25: Sostenido. t > 0,25: Decaimiento.
y luego tardará 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 las
ondas puras son lo que abunda en la naturaleza2 . La mayor parte de los dispositivos,
además de vibrar con la frecuencia fundamental que percibimos como tono vibran en
múltiplos de la misma, llamados armónicos o en frecuencias parásitas. Ni siquiera instrumentos como un diapasón son capaces de entregar un sonido puro. Las ondas generadas
por un instrumento oscilarán a una frecuencia dada por su tono, y generarán resonancias
en diferentes armónicos con menor amplitud (Fig. 3).
Juntando el tono, dado por la frecuencia fundamental; la intensidad, modulada por
el ataque-sostenido-decaimiento y el timbre, dado por la adición de armónicos; una onda
de 110Hz producida por un instrumento real, tendrı́a un aspecto similar al de la Figura
4.
2
¡Por suerte!, un aburrido ejemplo cotidiano de sonido puro son los pulsos del teléfono.
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 de
110Hz (verde) y 7 armónicos (azules). Este timbre podrı́a imitar el de una flauta.
2
4
1 Enunciado
Algoritmos y Programación I (75.02) – Trabajo Práctico 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
La
La]
Si
Do
Do]
Re
Re]
Mi
Fa
Fa]
Sol
Sol]
La
Cifrado americano
A
A] – B[
B
C
C] – D[
D
D] – E[
E
F
F] – G[
G
G] – A[
A
Octava
4
4
4
4
4
4
4
4
4
4
4
4
5
Frecuencia (Hz)
220,000
233,082
246,942
261,626
277,183
293,665
311,127
329,629
349,228
369,994
391,995
415,305
440,000
Tabla 1: Frecuencias para la cuarta octava (afinación 440).
3.2.
La escala musical
La música se genera en base a sonidos. Ahora bien, para que la misma suene agradable
al oido, se construyen escalas que fijan qué tonos están permitidos. Todas las escalas
se construyen en base a particiones de la octava, y luego se replican en las octavas
subsiguientes3 . Se considera que hay una octava entre dos notas donde una duplica la
frecuencia de la otra.
Las escalas occidentales son dodecafónicas, se construyen en base a 12 particiones
equidistantes de una octava4 . Además, se fija que la nota La de la quinta octava oscila
a 440Hz5 . Las notas de la escala son Do, Do] (ó Re[6 ), Re, Re] (ó Mi[), Mi, Fa, Fa]
(ó Sol[), Sol, Sol] (ó La[), La, La] (ó Si[) y Si, en ese orden.
Por razones de simplificar la notación, introduciremos el cifrado americano. En el
mismo a cada nota se le asigna una letra entre la A y la G, comenzando por la nota La
y continuando cı́clicamente a la octava siguiente.
Sabiendo que hay 12 notas, equidistantes exponencialmente7 , que el La de la quinta
se fija en 440Hz, que las octavas avanzan duplicando, y el nombre de las notas, podemos
reconstruir la frecuencia para cualquier nota dada. La Tabla 1 muestra un ejemplo de
ello.
3
Para esto y lo demás que desarrollemos en el capı́tulo, le pasamos a Pitágoras el fardo de dar las
explicaciones.
4
Más o menos, y si bien esto no es válido para la teorı́a estricta o para algunos instrumentos, sı́ lo es
para la mayorı́a.
5
Si el comité ISO lo dice, no vamos a contradecirlo.
6
Otra vez, sin ponerse exquisitos ni dar vueltas innecesarias con comas y otras yerbas.
√
7
Es decir, si una nota tiene frecuencia f , la nota siguiente tendrá frecuencia f · 12 2.
3
5
1 Enunciado
Algoritmos y Programación I (75.02) – Trabajo Práctico N◦ 3 – 1er Cuatr. 2012
char[4]
uint32
char[4]
char[4]
uint32
uint16
uint16
uint32
uint32
uint16
uint16
char[4]
uint32
ChunkId
ChunkSize
Format
Subchunk1ID
Subchukn1Size
AudioFormat
NumChannels
SampleRate
ByteRate
BlockAlign
BitsPerSample
SubChunk2ID
SubChunk2Size
int16[n]
Data
Vale "RIFF"
36 + 2n
Vale "WAVE"
Vale "fmt "
Vale 16
Vale 1
Vale 1
8000, 44100, etc.
2 × SampleRate
Vale 16
Vale 16
Vale "data"
2n
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 especificación RIFF de Microsoft. El mismo
permite almacenar en modo raw sin compresión muestras de audio.
Un archivo WAVE es un archivo binario compuesto por un preámbulo, y dos chunks.
El primero de ellos es de tamaño fijo, y contiene la información acerca de las caracterı́sticas del track ; mientras que el segundo contiene las muestras de audio que componen al
mismo.
Para este trabajo se utilizará la compresión PCM (esto es, sin compresión), 16 bits
de resolución y formato monoaural. El contenido binario de un archivo WAVE de estas
caracterı́sticas es el de la Tabla 5.
Tanto los números de 16 bits como de 32 en el formato WAVE, se almacenan en
el archivo en formato little endian. Las muestras se almacenan como enteros de 16 bits
en complemento a 2, puede asumirse que es el mismo formato que utiliza C. No puede
asumirse bajo ningún punto de vista el endianness de la plataforma.
4.
Desarrollo del TP
El trabajo práctico consistirá en un ejecutable en modo consola que pueda realizar
la sı́ntesis sobre un archivo WAVE en base a la configuración de un sintetizador y una
secuencia de notas.
La sintáxis de ejecución será:
$ ./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 especificación de los parámetros se encuentra en la Tabla 2.
4.1.
Archivo de partitura
El archivo de partitura, será un archivo ASCII donde cada lı́nea representará una
nota a ser ejecutada.
Cada lı́nea contendrá un tiempo de inicio de la ejecución de la nota, la nota a interpretar y la duración. Todos los tiempos se especificarán en segundos. Las notas se
4
6
1 Enunciado
Algoritmos y Programación I (75.02) – Trabajo Práctico N◦ 3 – 1er Cuatr. 2012
Parámetro
-p
-s
-o
-f
Valores
Nombre del archivo de entrada que describe la partitura.
Nombre del archivo de entrada que describe el sintetizador.
Nombre del archivo de salida WAVE.
Frecuencia de muestreo. Una de: 8000, 9600, 11025, 12000,
16000, 22050, 24000, 32000, 44100, 48000, 88200, 96000.
(optativo)
Tabla 2: Parámetros de CLA.
especificarán 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 duración, desde el La hasta
el Re de la cuarta octava. La duración de la ejecución del fragmento será de 3 segundos.
En el archivo se desconoce la cantidad de notas a ejecutar, y no es requisito que el
mismo venga ordenado cronológicamente (tampoco hace falta).
4.2.
Archivo de sintetizador
El archivo de sintetizador, será un archivo ASCII con información sobre los armónicos, y las envolventes para modular la amplitud.
El archivo de sintetizador estará dividido en cuatro partes:
Armónicos, donde se especificará el número de armónicos y luego pares de múltiplo e
intensidad.
Ataque, donde se especificará el tipo de ataque y luego los parámetros.
Sostenido, donde se especificará el tipo de sostenido y luego los parámetros.
Decaimiento, donde se especificará el tipo de decaimiento y luego los parámetros.
Los moduladores de amplitud serán 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 Programación I (75.02) – Trabajo Práctico N◦ 3 – 1er Cuatr. 2012
Nombre
CONSTANT
LINEAR
Ecuación
f (t) = 1
t
f (t) =
n t0
o
f (t) = máx 1 − tt0 ; 0
f (t) = 1 + a sen(f t)
INVLINEAR
SIN
f (t) = e
EXP
−5t
INVEXP
QUARTCOS
QUARTSIN
HALFCOS
HALFSIN
LOG
INVLOG
TRI
PULSES
5(t−t0 )
t0
f (t) = et0 πt
f (t) = cos 2t
0
πt
f (t) = sen 2t
0 1+cos πt
t0
f (t) =
2
1+sen π tt − 12
0
f (t) =
2
f (t) = log10 9t
t0 + 1
−9t
log10 t +10
t<t0 ,
0
f (t) =
0
t≥t0 .
ta1
t<t1 ,
t1
f (t) =
t−t1
t1 −t0 + a1 t>t1 . o
n
0
1
0
t
t
f (t0 ) = mı́n | 1−a
t1 (t − t0 + t1 )| + a1 ; 1 ,t = t0 −b t0 c
Parámetros
–
t0
Uso en
S
A
t0
a, f
S, D
S
t0
A
t0
S, D
t0
S, D
t0
A
t0
S, D
t0
A
t0
A
t0
S, D
t0 , t1 , a1
A
t0 , t1 , a1
S
Tabla 3: Moduladores de amplitud. Para su uso en A: Ataque, S: Sostenido, D: Decaimiento.
En él se define la progresión de 8 armónicos en octavas8 , un ataque TRI de duración
0,05s, un sostenido CONSTANT y un decaimiento INVLINEAR de duración 0,02s.
4.3.
Sı́ntesis
La sı́ntesis del sonido se realizará para cada nota por separado, realizando una adición
sobre el audio de las demás notas.
Dada una nota que comienza en el instante t0 , de frecuencia f y duración d, con un
sintetizador con una serie de n armónicos donde están definidos sus múltiplos Mi y sus
intensidades Ii , además de sus funciones de ataque fa , sostenimiento fs y decaimiento
fd , se procede como sigue.
El timbre del instrumento se obtiene de computar la siguiente expresión:
y(t) =
n
X
i=1
Ii sen (2πf Mi (t − t0 ))
Esto nos da una señal infinita, la misma será ajustada según la modulación de amplitud.
La modulación de amplitud se compone por la concatenación de ataque, sostenido y
decaimiento. Antes de explicar cómo se combinan, vale observar que todas las funciones
para ser usadas como ataque, recorren un camino de 0 a 1 en un tiempo t0 , todas
las funciones de decaimiento recorren el camino inverso en un tiempo t0 , y todas las
funciones de sostenido comienzan en 1 y son siempre positivas. Esto es importante para
comprender cómo se las empalma.
Una nota no puede durar nunca menos que el tiempo de ataque ta , una vez finalizada la nota, se ejecuta el decaimiento, de tiempo td . Luego, la función de modulación
8
Estos armónicos, casualmente, son los mismos de la Figura 3.
6
8
1 Enunciado
Algoritmos y Programación I (75.02) – Trabajo Práctico N◦ 3 – 1er Cuatr. 2012
estará dada por:


fa (t − t0 )
t0 < t < t0 + ta


 f (t − (t + t ))
t0 + ta < t < t 0 + d
s
0
a
m(t) =
 fs (t0 + d)fd (t − (t0 + d)) t0 + d < t < t0 + d + td



0
Para otro t
Observar que la misma es una función continua.
Finalmente, la amplitud de la nota estará dada por:
a(t) = Ay(t)m(t)
Esta función será distinta de cero como mucho en el intervalo t0 < t < t0 + d + td . La
constante A debe ser elegida convenientemente para darle el volumen a nuestro instrumento; al elegirla notar que un valor pequeño va a hacer que al truncar sobre 16bits se
pierdan muchos valores intermedios, y notar que un valor muy grande puede hacer que
la adición de varias notas genere un desbordamiento, lo cual en el audio se va a traducir
en una saturación del sonido.
El único paso que resta para llevar estas notas a un archivo WAVE es muestrear estas
ondas según la frecuencia dada. Dicha discretización debe hacerse en tantas muestras por
segundo como las indicadas en la frecuencia de muestreo fm , con t variando en intervalos
de 1/fm .
5.
Restricciones
La realización de los programas pedidos está sujeta a las siguientes restricciones:
Deben utilizarse TDAs tanto en los contenedores como en las entidades que ası́ lo
requieran.
Debe recurrirse al uso de punteros a funciones a fin de parametrizar la elección de
los moduladores.
Hay ciertas cuestiones que no han sido especificadas intencionalmente en este Requerimiento, para darle al Desarrollador la libertad de elegir implementaciones
que, según su criterio, resulten más convenientes en determinadas situaciones. Por
lo tanto, se debe explicitar cada una de las decisiones adoptadas, y el o los fundamentos considerados para las mismas.
6.
Entrega del Trabajo Práctico
Deberá presentarse la correspondiente Documentación de desarrollo del TP impresa y encarpetada, siguiendo la numeración siguiente, incluyendo:
1. Carátula del TP. Incluir una dirección de correo electrónico de contacto.
2. Enunciado del TP.
3. Estructura lógica simplificada de los programas desarrollados (diagramas de
flujo).
4. Estructura funcional de los programas desarrollados (Árbol de Funciones).
5. Explicación de cada una de las alternativas consideradas y las estrategias
adoptadas.
7
9
1 Enunciado
Algoritmos y Programación I (75.02) – Trabajo Práctico N◦ 3 – 1er Cuatr. 2012
6. Resultados de la ejecución (corridas) de los programas, captura de las pantallas, bajo condiciones normales e inesperadas de entrada.
7. Reseña sobre los problemas encontrados en el desarrollo de los programas y
las soluciones implementadas para subsanarlos.
8. Conclusiones.
NOTA: El Informe deberá ser redactado en correcto idioma castellano, con tipografı́a Times New Roman, Arial, o Verdana, de tamaño 11 para los párrafos, y 13
ó 14 para los tı́tulos.
Deberá entregarse una impresión de los códigos fuentes (implementación y headers) de los programas desarrollados. NO entregar archivos de códigos objeto y/o
ejecutables.
NOTA: Los códigos fuentes deberán ser impresos con tipografı́a Monospace.
Deberá entregarse el archivo Makefile del proyecto para el compilador C GCCDJGPP.
Deberán entregarse por correo electrónico a la casilla algo7502entregas@gmail.com,
todos los archivos fuentes y scripts necesarios para compilar el trabajo práctico,
además del informe en formato electrónico. Dicho correo deberá contener en su
cuerpo el nombre, apellido y padrón de los integrantes del grupo.
De no hacerse la entrega digital en tiempo y forma, el TP no será corregido.
SI NO SE PRESENTA CADA UNO DE ESTOS ITEMS, SERÁ RECHAZADO EL TP
7.
Bibliografı́a
Debe incluirse la referencia a toda bibliografı́a consultada para la realización del
presente TP: libros, artı́culos, URLs, etc., citando:
Denominación completa del material (Tı́tulo, Autores, Edición, Volumen, etc.).
Código ISBN del libro (opcional: código interbibliotecario).
URL del sitio consultado.
8
10
2 Estructura Funcional
2.
Estructura Funcional
main()
validate_arguments()
status_msg()
show_usage()
progress_msg()
/* ADT_musical_score: 1 */
ADT_musical_score_new()
/* ADT_synthesizer: 1 */
ADT_synthesizer_new()
/* ADT_musical_score: 9 */
ADT_musical_score_set_from_file()
/* ADT_synthesizer: 6 */
ADT_synthesizer_set_from_file()
/* 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_synthesizer: 5 */
ADT_synthesizer_get_modulation_at()
/* addsynthlib: 1 */
tabsin_create_table()
/* addsynthlib: 4 */
synthesize()
/* ADT_musical_score: 2 */
ADT_musical_score_destroy()
/* ADT_synthesizer: 2 */
ADT_synthesizer_destroy()
/* ADT_synthesizer: 5 */
ADT_synthesizer_get_modulation_at()
/* ADT_synthesizer: 3 */
ADT_synthesizer_get_quantity_harmonics()
/* 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_synthesizer: 4 */
ADT_synthesizer_get_harmonic_at()
/* ADT_musical_score: 8 */
ADT_musical_score_get_frequency_at()
/* addsynthlib: 3 */
evenlope()
/* ADT_synthesizer: 5 */
ADT_synthesizer_get_modulation_at()
/* addsynthlib: 2 */
tabsin_destroy_table()
/* ADT_musical_score: 5 */
ADT_musical_score_get_duration_at()
/* ADT_musical_score: 2 */
ADT_musical_score_destroy()
/* ADT_synthesizer: 2 */
ADT_synthesizer_destroy()
/* ADT_wav_file: 1 */
ADT_wav_file_create_from_vector()
/* ADT_wav_file: 3 */
ADT_wav_file_write()
/* ADT_wav_file: 2 */
ADT_wav_file_destroy()
/* ADT_wav_file: <interna> */
_write_little_endian()
/* modulationlib */
modulation_constant()
/* modulationlib */
modulation_quartsin()
/* modulationlib */
modulation_linear()
/* modulationlib */
modulation_halfcos()
/* modulationlib */
modulation_invlinear()
/* modulationlib */
modulation_halfsin()
/* modulationlib */
modulation_sin()
/* modulationlib */
modulation_log()
/* modulationlib */
modulation_exp()
/* modulationlib */
modulation_invlog()
/* modulationlib */
modulation_invexp()
/* modulationlib */
modulation_tri()
/* modulationlib */
modulation_quartcos()
/* modulationlib */
modulation_pulses()
11
3 Consideraciones y Estrategias
3.
Consideraciones y Estrategias
Durante el desarrollo se optó por una eficiente modulación mediante el uso de Tipos de
Dato Abstracto. Esto permitió una simplificación del código del módulo principal (main),
como también la posibilidad de aislar los módulos entre sı́, facilitando la división de tareas
entre los desarrolladores.
Para facilitar esta división de tareas y abordar el desarrollo, se tomó la estrategia
de diseño Top-down, por lo que el problema principal se redujo en tres grandes bloques
descriptos a continuación.
3.1.
Validación de datos y lectura de archivos de entrada
Para la lectura de los archivos de entrada se diseñaron dos TDAs especı́ficos, uno
destinado al archivo de partitura y otro al de sintetizador. De esta manera, el bloque
principal nunca interactúa directamente con los datos de entrada (de estos archivos, sı́ lo
hace con los argumentos en la lı́nea de órdenes).
Como consecuencia, el módulo principal dispone de la información previamente validada, a través de la claridad de las interfaces (getters y setters) de los TDAs.
3.2.
Sı́ntesis del sonido
Para generar el audio se utilizó una biblioteca de sı́ntesis aditiva, con rutinas que
permiten sintetizar la partitura de manera completa, haciendo uso de los Tipos de Dato
descriptos anteriormente.
Aquı́ fue necesario desarrollar una función que controle la envolvente de la señal, para
luego ser invocada por otra que realice la sı́ntesis final, haciendo una correcta adición de
armónicos en cada nota de la partitura.
Además, en esta biblioteca se incluyen rutinas para hacer un “cacheo” de la función
seno de la biblioteca math, con el fin de aumentar la eficiencia de la sı́ntesis. (Esto será explicado en detalle en la sección 5.1).
3.3.
Escritura en del archivo de salida en formato WAV
En cuanto al archivo de salida, de formato WAV monofónico, se diseñó un tercer TDA
para su manejo. Éste permite la posibilidad de crear una instancia a partir de un vector de
muestras en formato double, encargándose de la normalización del audio, para su correcta
representación en 16 bits.
En este TDA se incluyen además rutinas para la correcta escritura del archivo, cuyos
enteros tienen formato little endian. Para esto se utiliza una función interna que es capaz de
escribir 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 en
un vector de double, asegurándose que la amplitud ‘nunca’ superará el rango máximo de
representación del tipo. Luego el audio será normalizado, aprovechando todo este rango,
sin problemas de saturación u overflow.
12
4 Resultados de ejecución
Para futuras utilizaciones en otros proyectos, se listó un conjunto de primitivas realmente necesarias y útiles, que quedaron sin implementar, por lo que este TDA es el más
incompleto de los tres.
4.
4.1.
Resultados de ejecución
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 armónicos con los especificados luego en el archivo
de sintetizador:
2. Funciones de modulación 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 considerarán como
C1, do de la primera octava):
4.2.
En condiciones normales de entrada
Canción realizada para la prueba (disponible en el directorio ‘test’ de la entrega
digital):
15
4.2 En condiciones normales de entrada
Diferentes tipos de modulación 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.
5.1.
Problemas encontrados en el desarrollo
Optimización del tiempo de sı́ntesis
Durante el desarrollo, una vez terminado el Tipo de Dato Abstracto Archivo WAV
(mono), se continuó con algunas pequeñas pruebas de sı́ntesis simple, sin consideración
de la envolvente ni de los armónicos, y generando archivos un tanto extensos.
Ası́ fue que se observó un elevado tiempo de sı́ntesis, teniendo en cuenta que finalmente,
por cada nota serı́a necesario generar varias ondas como componentes armónicas de la
sı́ntesis aditiva.
Se sacó la conclusión de que este elevado tiempo se debı́a a una agresiva utilización de la
función sin() de la biblioteca math (función que a su vez realiza varias iteraciones en
su interior).
Fue entonces que surgió la estrategia de crear una tabla (cache) con los valores del
seno a utilizar. Se decidió ajustar la ‘resolución de tabulado’ en función de la frecuencia de
muestreo, generando los valores correspondientes a una longitud de onda completa para
una onda de 1 Hz de frecuencia. El acceso a la tabla se hace mediante una aritmética
cı́clica, que permite calcular el ı́ndice a utilizar a partir de la variable independiente (en
este caso, el tiempo).
Esta tabla es inicializada una sola vez al comienzo de la ejecución y es utilizada en
todo el proceso, luego de la sı́ntesis la misma es destruida.
Junto con la idea de la tabulación del seno (y ya teniendo en cuenta la adición de
armónicos), surgió a posteriori la ocurrencia de hacer una tabulación de la forma de onda completa, realizando la sı́ntesis aditiva por única vez y para todas las notas. Esto
significarı́a un ahorro muy considerable en los tiempos de sı́ntesis. Pero se encontró un
problema, si los múltiplos de la frecuencia fundamental (armónicos) fueran enteros esto
serı́a totalmente posible. Lamentablemente no es ası́, una de las caracterı́sticas del sintetizador debe ser la de generar batidos por medio de múltiplos fraccionarios, cosa que jamás
sucederá en el dominio de una sola longitud de onda de la fundamental.
En consecuencia se adoptó la solución intermedia, con el tabulado del seno y la sı́ntesis
aditiva a través de varios usos de la misma tabla. Otra posible solución hubiera sido
calcular el tiempo de los batidos, muestrear en la tabla una onda de 1 Hz durante todo
ese tiempo, y finalmente reajustar el cálculo del ı́ndice de acceso.
A modo de reseña se adjuntan los tiempos sobre pruebas de sı́ntesis realizadas para
un mismo archivo (igual duración):
Uso exclusivo de la biblioteca math: 117 segundos
Utilización de la tabla para evitar la invocación de sin(): 66 segundos
Utilización de la tabla para almacenar la forma de onda: 10 segundos
Puede observarse que a pesar de la inminente eficiencia de la última implementación,
la finalmente elegida implica un ahorro de más del 40 % en el tiempo de sı́ntesis.
17
5.2 Funciones de modulación incorrectas
5.2.
Funciones de modulación incorrectas
Se encontraron errores en las funciones de modulación TRI y PULSES. A continuación
se presentan las versiones de estas funciones corregidas.
Función TRI: f (t) =
ta1
t1
a1 −1
(t
t1 −t0
t ≤ t1
− t0 ) + 1 t > t1
n
o
0
1
Función PULSES: f (t0 ) = mı́n | 1−a
(2t
−
1)t
|
+
a
;
1
, t0 =
0
1
t1
6.
t
t0
− b tt0 c
Conclusiones
El programa cuenta con soporte de múltiples idiomas que se definen en tiempo de
compilación, mediante el uso de un archivo auxiliar incluido en el archivo Makefile. El
uso de make permite realizar proyectos muy profesionales y automatizados, aumentando
además las cualidades de facilidad de uso y verificabilidad, ya que la compilación se realiza
mediante un simple comando en el terminal, y los módulos sin modificaciones no son
compilados innecesariamente.
El uso de los TDAs en este trabajo ha sido fundamental, las posibilidades de reutilización de los mismos en otras aplicaciones, la simplificación de código, como también las
posibles futuras modificaciones a este programa lo hacen una herramienta fundamental
en la buena programación en lenguaje C.
Cualidades de modularización, mantenibilidad, evolucionabilidad, y comprensibilidad
se incrementan notablemente mediante la utilización de esta técnica, que es lo más cercano
a la Programación 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 Códigos fuente
8.
Códigos fuente
8.1.
ADT musical score
8.1.1.
ADT musical score.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Algoritmos y Programaci ó n I - 75.02/95.11 - Curso Ing . Mart ı́ n Cardozo
TP N o 3 - 1 er Cuatrimestre 2012
Alumnos : ARIAS , Francisco - FERRARI BIHURRIET , Francisco
Archivo : AD T_mus ical_s core . h
Descrip : Encabezado p ú blico para el TDA partitura musical .
Obs :
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include " ../ main_modules / common . h "
16
17
18
19
20
#if ndef A D T_ M U SI C A L_ S C OR E _ H
#define A DT _ M US I C AL _ S CO R E _H
21
22
23
24
25
26
typedef struct A DT _ m us i c al _ s co r e _t A DT _ m us i c al _ s c or e _ t ;
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
typedef struct tnote tnote ;
typedef enum {
C =0 ,
Cs =1 ,
D =2 ,
Ds =3 ,
E =4 ,
F =5 ,
Fs =6 ,
G =7 ,
Gs =8 ,
A =9 ,
As =10 ,
B =11
} tone_t ;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Primitives * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 1) Creador de partitura */
status_t A D T _ m u s i c a l _ s c o r e _ n e w ( A D T _m u s ic a l _s c o re _ t **) ;
/* 2) Destructor de partitura */
void A D T _ m u s i c a l _ s c o r e _ d e s t r o y ( A DT _ m us i c al _ s co r e _t **) ;
19
8.1 ADT musical score
49
50
51
52
53
/* 3) Obtener la cantidad de notas . Precondicion : no debe recibir NULL */
size_t A D T _ m u s i c a l _ s c o r e _ g e t _ q u a n t i t y _ n o t e s ( const A DT _ m us i c al _ s co r e _t * ) ;
4) Obtener la n - sima nota . En caso de fallar devuelve NULL .
PRECONDICION : SE DEBE TENER ACCESO AL ARCHIVO
54
A D T _ m u s i c a l _ s c o r e _ P R I V A T E . h */
55 tnote * A D T _ m u s i c a l _ s c o r e _ g e t _ n o t e _ a t ( const A D T _m u s ic a l _s c o re _ t * , size_t ) ;
56
57
58
59
/*
5) Obtener la duracion de la n - sima nota . Precondiciones :
I ) No debe recibir puntero NULL
II ) La posicion debe ser menor que la cant de notas */
60 double A D T _ m u s i c a l _ s c o r e _ g e t _ d u r a t i o n _ a t ( const A DT _ m us i c al _ s co r e _t * , size_t ) ;
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
/*
/*
6) Obtener el tiempo de inicio de la n - sima nota . Precondiciones :
I ) No debe recibir puntero NULL
II ) La posicion debe ser menor que la cant de notas */
double A D T _ m u s i c a l _ s c o r e _ g e t _ s t a r t _ t i m e _ a t ( const A DT _ m us i c al _ s co r e _t * , size_t ) ;
/*
7) Obtener el tono de la n - sima nota . Precondiciones :
I ) No debe recibir puntero NULL
II ) La posicion debe ser menor que la cant de notas */
tone_t A D T _ m u s i c a l _ s c o r e _ g e t _ t o n e _ a t ( const A DT _ m us i c al _ s co r e _t * , size_t ) ;
/*
8) Obneter la fracuencia de la n - sina nota
I ) No debe recibir puntero NULL
II ) La posicion debe ser menor que la cant de notas */
double A D T _ m u s i c a l _ s c o r e _ g e t _ f r e q u e n c y _ a t ( const A DT _ m us i c al _ s co r e _t * , size_t ) ;
77
78
79
80
81
82
/* 9) Leer notas desde archivo */
status_t A D T _ m u s i c a l _ s c o r e _ s e t _ f r o m _ f i l e ( A D T _m u s ic a l _s c o re _ t ** , string ) ;
83
84
85
86
87
88
/* 11) Escribir la nota n - esima ( TODO )
status_t A D T _ m u s i c a l _ s c o r e _ s e t _ e l e m e n t _ a t ( A D T _m u s ic a l _s c o re _ t * , void * , long ) ;
*/
89
90
/* 10) Imprimir partitura */
status_t A D T _ m u s i c a l _ s c o r e _ p r i n t ( const A D T _m u s ic a l _s c o re _ t *) ;
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#endif /* A DT _ M US I C AL _ S CO R E _H */
8.1.2.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
ADT musical score PRIVATE.h
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Algoritmos y Programaci ó n I - 75.02/95.11 - Curso Ing . Mart ı́ n Cardozo
TP N o 3 - 1 er Cuatrimestre 2012
Alumnos :
Archivo :
Descrip :
Obs :
ARIAS , Francisco - FERRARI BIHURRIET , Francisco
ADT_musical_score_PRIVATE .h
Encabezado privado para el TDA partitura musical .
Para una correcta utilizaci ó n del TDA no debe conocerse el
funcionamiento interno , el cu á l queda expuesto aqu ı́ .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include " ADT_ musica l_scor e . h "
20
8.1 ADT musical score
16
17
18
19
20
#if ndef A D T _ M U S I C A L _ S C O R E _ P R I V A T E _ H
#define A D T _ M U S I C A L _ S C O R E _ P R I V A T E _ H
#define
#define
#define
#define
#define
#define
#define
27 #define
28 #define
21
22
23
24
25
26
29
30
31
32
const string string_tones [ QUANTITY_TONES ]=
{
"C",
" Cs " ,
"D",
" Ds " ,
"E",
"F",
" Fs " ,
"G",
" Gs " ,
"A",
" As " ,
"B"
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
73
74
/* Db */
/* Eb */
/* Gb */
/* Ab */
/* Bb */
};
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* . . . . . . . . . . . . . . . . . . . . . . Manejo de memoria dinamica . . . . . . . . . . . . . . . . . . . . . . */
#define INIT_CHOP 10
#define CHOP_SIZE 10
/* memoria inicial */
/* incremento de memoria */
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
/* . . . . . . . . . . . . . . . . . . . . . . . Estructura del ADT partitura . .. . . .. . . .. . . .. . . .. */
struct tnote
{
61
62
63
64
65
66
67
68
69
70
71
72
N 0 /* 0 or 1 */
SCALE_FACTOR 1 .0 5 9 46 3 0 94 3 5 92 9 5 26 /* ( pow (2 ,1.0/ QUANTITY_TONES ) ) */
SIZE_AUX_VEC 30
STRING_SPACE " " /* separador de parametros en partitura
*/
QUANTITY_TONES 12 /* cantidad de tonos en una octava musical */
C1_FREQUENCY 1 6. 3 5 15 9 7 83 1 2 87 4 1 47
BEMOL_SYMBOL ' b '
SHARP_SYMBOL ' s '
EMPTY_LINE " \ n "
double
double
tone_t
uchar
start_time ;
duration ;
tone ;
octave ;
};
struct A DT _ m us i c al _ s co r e _t
{
tnote ** notes ;
size_t quantity_notes ;
size_t alloc_size ;
21
8.1 ADT musical score
75
76
77
78
79
80
};
/* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */
#endif /* A D T _ M U S I C A L _ S C O R E _ P R I V A T E _ H */
8.1.3.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ADT musical score.c
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Algoritmos y Programaci ó n I - 75.02/95.11 - Curso Ing . Mart ı́ n Cardozo
TP N o 3 - 1 er Cuatrimestre 2012
Alumnos :
Archivo :
Descrip :
Obs :
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include
#include
#include
#include
20 #include
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
ARIAS , Francisco - FERRARI BIHURRIET , Francisco
AD T_mus ical_s core . c
Implementaci ó n del TDA partitura musical .
Compilacion en modo prueba :
gcc A DT_mus ical_s core . c -o musical_score
- ansi - pedantic - Wall - lm - DTEST
< stdio .h >
< stdlib .h >
< string .h >
< math .h >
" ADT_musical_score_PRIVATE .h"
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
1) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / | Creador de partitura | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
status_t A D T _ m u s i c a l _ s c o r e _ n e w ( A D T _m u s ic a l _s c o re _ t ** musical_score ) {
size_t i , j ;
if ( musical_score == NULL ) return ERR OR _N UL L_ PO IN TE R ;
if ( ((* musical_score ) = ( A DT _ m us i c al _ s co r e _t *)
malloc ( sizeof ( A DT _ m us i c al _ s co r e _t ) ) ) == NULL )
return ERROR_NO_MEMORY ;
if ( ((* musical_score ) -> notes = ( tnote **)
malloc ( INIT_CHOP * sizeof ( tnote *) ) ) == NULL ) {
free ( * musical_score ) ;
* musical_score = NULL ;
return ERROR_NO_MEMORY ;
}
for ( i =0; i < INIT_CHOP ; i ++) {
if ( ((* musical_score ) -> notes [ i ] = ( tnote *)
malloc ( sizeof ( tnote ) ) ) == NULL ) {
for ( j =0; j < i ; j ++)
free ((* musical_score ) -> notes [ j ]) ;
free ((* musical_score ) -> notes ) ;
free (* musical_score ) ;
22
8.1 ADT musical score
* musical_score = NULL ;
return ERROR_NO_MEMORY ;
52
53
54
55
56
}
}
57
58
59
60
61
62
(* musical_score ) -> quantity_notes = 0;
(* musical_score ) -> alloc_size = INIT_CHOP ;
return OK ;
63
64
65
66
67
68
}
69
70
71
72
73
void A D T _ m u s i c a l _ s c o r e _ d e s t r o y ( A DT _ m us i c al _ s co r e _t ** musical_score ) {
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
2) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / / | Destructor de partitura | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
size_t i , aux_alloc_size ;
aux_alloc_size = (* musical_score ) -> alloc_size ;
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
for ( i =0; i < aux_alloc_size ; i ++)
free (((* musical_score ) -> notes [ i ]) ) ;
free ((* musical_score ) -> notes ) ;
free (* musical_score ) ;
* musical_score = NULL ;
}
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
3) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / | Obtener la cantidad de notas | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \\ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
size_t A D T _ m u s i c a l _ s c o r e _ g e t _ q u a n t i t y _ n o t e s ( const A DT _ m us i c al _ s co r e _t *
musical_score ) {
return musical_score - > quantity_notes ;
}
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
4) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / | Obtener la n - sima nota | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
tnote * A D T _ m u s i c a l _ s c o r e _ g e t _ n o t e _ a t ( const A D T _m u s ic a l _s c o re _ t * musical_score ,
size_t position ) {
if ( musical_score == NULL || ( musical_score - > quantity_notes ) < position )
return NULL ;
return musical_score - > notes [ position - N ];
}
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
5) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / | Obtener la duracion de la n - sima nota |\ \\\\\\ \\\\\\ \\| */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
double A D T _ m u s i c a l _ s c o r e _ g e t _ d u r a t i o n _ a t ( const A DT _ m us i c al _ s co r e _t *
23
8.1 ADT musical score
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
musical_score , size_t position ) {
return ( musical_score - > notes [ position - N ]) -> duration ;
}
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
6) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* |////////////| Obtener el tiempo de inicio de la n - sima nota |\\\\\\\\\\\\\| */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
double A D T _ m u s i c a l _ s c o r e _ g e t _ s t a r t _ t i m e _ a t ( const A DT _ m us i c al _ s co r e _t *
musical_score , size_t position ) {
return ( musical_score - > notes [ position - N ]) -> start_time ;
}
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
7) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / | Obtener el tono de la n - sima nota | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
128 /* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
tone_t A D T _ m u s i c a l _ s c o r e _ g e t _ t o n e _ a t ( const A DT _ m us i c al _ s co r e _t * musical_score ,
size_t position ) {
return ( musical_score - > notes [ position - N ]) -> tone ;
}
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
8) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* |//////////////| Obneter la fracuencia de la n - sina nota | \\ \ \ \\ \ \ \\ \ \ \\ \ \ \| */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
double A D T _ m u s i c a l _ s c o r e _ g e t _ f r e q u e n c y _ a t ( const A DT _ m us i c al _ s co r e _t *
musical_score , size_t position ) {
return C1_FREQUENCY * pow (2 ,(( musical_score - > notes [ position - N ] - > octave ) -1) ) *
pow ( SCALE_FACTOR , ( musical_score - > notes [ position - N ] - > tone ) ) ;
}
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
9) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / | Leer notas desde archivo | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
status_t A D T _ m u s i c a l _ s c o r e _ s e t _ f r o m _ f i l e ( A D T _m u s ic a l _ sc o r e_ t ** musical_score ,
string f i l e _ n a m e _ m u s i c a l _ s c o r e ) {
FILE * f il e_ mu si ca l_ sc or e ;
size_t i ;
size_t aux_alloc_size = INIT_CHOP ;
size_t aux _q ua nt it y_ no te s = 0;
tnote ** aux_notes ;
char aux_vec [ SIZE_AUX_VEC ];
string aux_string ;
if ( musical_score == NULL || f i l e _ n a m e _ m u s i c a l _ s c o r e == NULL )
return E RR OR _N UL L_ PO IN TE R ;
if ( ( f il e_ mu si ca l_ sc or e = fopen ( file_name_musical_score , " r " ) ) == NULL ) {
A D T _ m u s i c a l _ s c o r e _ d e s t r o y ( musical_score ) ;
return E RR O R _M U S IC A L _S C O RE ;
24
8.1 ADT musical score
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
}
while ( fgets ( aux_vec , SIZE_AUX_VEC , fi le _m us ic al _s co re ) != NULL ) {
if ( ! strcmp ( aux_vec , EMPTY_LINE ) ) {
A D T _ m u s i c a l _ s c o r e _ d e s t r o y ( musical_score ) ;
return E RR O R _M U S IC A L _S C O RE ;
}
if ( a ux _q ua nt it y_ no te s == aux_alloc_size ) {
if ( ( aux_notes = ( tnote **) realloc ((* musical_score ) -> notes ,
sizeof ( tnote *) *( aux_alloc_size + CHOP_SIZE ) ) ) == NULL ) {
A D T _ m u s i c a l _ s c o r e _ d e s t r o y ( musical_score ) ;
return ERROR_NO_MEMORY ;
}
187
188
189
190
191
(* musical_score ) -> notes = aux_notes ;
for ( i = aux_alloc_size ; i <( aux_alloc_size + CHOP_SIZE ) ; i ++) {
if ( ((* musical_score ) -> notes [ i ] =
malloc ( sizeof ( tnote ) ) ) == NULL ) {
(* musical_score ) -> alloc_size = ( aux_alloc_size + i ) ;
A D T _ m u s i c a l _ s c o r e _ d e s t r o y ( musical_score ) ;
return ERROR_NO_MEMORY ;
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
}
}
aux_alloc_size += CHOP_SIZE ;
}
aux_string = strtok ( aux_vec , STRING_SPACE ) ;
(* musical_score ) -> notes [ aux _q ua nt it y_ no te s ] - > start_time =
strtod ( aux_string , NULL ) ;
aux_string = strtok ( NULL , STRING_SPACE ) ;
for ( i =0; i < QUANTITY_TONES ; i ++) {
if ( ! strncmp ( aux_string , string_tones [ i ] ,1) ) {
if ( aux_string [1] == BEMOL_SYMBOL ) {
(* musical_score ) -> notes [ au x_q ua nt it y_ no te s ] - > tone =
( tone_t ) (i -1) ;
(* musical_score ) -> notes [ au x_q ua nt it y_ no te s ] - > octave =
( uchar ) strtoul ( aux_string +2 , NULL ,0) ;
break ;
}
if ( aux_string [1] == SHARP_SYMBOL ) {
(* musical_score ) -> notes [ au x_q ua nt it y_ no te s ] - > tone =
( tone_t ) ( i +1) ;
(* musical_score ) -> notes [ au x_q ua nt it y_ no te s ] - > octave =
( uchar ) strtoul ( aux_string +2 , NULL ,0) ;
break ;
}
25
8.1 ADT musical score
229
230
231
232
233
(* musical_score ) -> notes [ a ux _q ua nt it y_ no te s ] - > tone = ( tone_t ) i ;
(* musical_score ) -> notes [ a ux _q ua nt it y_ no te s ] - > octave =
( uchar ) strtoul ( aux_string +1 , NULL ,0) ;
break ;
234
235
236
237
238
239
}
}
aux_string = strtok ( NULL , STRING_SPACE ) ;
(* musical_score ) -> notes [ aux _q ua nt it y_ no te s ] - > duration =
strtod ( aux_string , NULL ) ;
240
241
242
243
244
245
au x_ qu an ti ty _n ot es ++;
}
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
(* musical_score ) -> quantity_notes = aux _q ua nt it y_ no te s ;
(* musical_score ) -> alloc_size = aux_alloc_size ;
fclose ( fil e_ mu si ca l_ sc or e ) ;
return OK ;
}
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
10) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / | Imprimir partitura | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
status_t A D T _ m u s i c a l _ s c o r e _ p r i n t ( const A D T _m u s ic a l _s c o r e_ t * musical_score ) {
263
264
265
266
267
268
size_t i , quantity_notes ;
if ( musical_score == NULL ) return ERR OR _N UL L_ PO IN TE R ;
quantity_notes = A D T _ m u s i c a l _ s c o r e _ g e t _ q u a n t i t y _ n o t e s ( musical_score ) ;
269
270
271
272
273
for ( i =0; i < quantity_notes ; i ++)
printf ( " %f %s %u %f frequency --> %f \ n " ,
A D T _ m u s i c a l _ s c o r e _ g e t _ s t a r t _ t i m e _ a t ( musical_score , i ) ,
string_tones [ musical_score - > notes [ i ] - > tone ] ,
( uint ) musical_score - > notes [ i ] - > octave ,
A D T _ m u s i c a l _ s c o r e _ g e t _ d u r a t i o n _ a t ( musical_score , i ) ,
A D T _ m u s i c a l _ s c o r e _ g e t _ f r e q u e n c y _ a t ( musical_score , i ) ) ;
274
275
276
277
278
279
280
281
282
283
284
285
286
287
return OK ;
}
/* | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | */
/* | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | MAIN de prueba | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | */
/* | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | */
26
8.2 ADT synthesizer
288
289
290
291
292
293
294
295
296
297
298
#if def TEST
int main ( void ) {
ADT _ m us i c a l_ s c or e _ t * musical_score ;
/* Creacion (1) */
if ( ( A D T _ m u s i c a l _ s c o r e _ n e w (& musical_score ) ) != OK ) {
fprintf ( stderr , " Error en la creacion de la partitura \ n " ) ;
return EXIT_FAILURE ;
}
299
300
301
302
303
304
/* Llenado (9) */
if ( ( A D T _ m u s i c a l _ s c o r e _ s e t _ f r o m _ f i l e (& musical_score , " TEST_PARTITURA . txt " ) )
!= OK ) {
fprintf ( stderr , " Error en el seteo de los elementos \ n " ) ;
return EXIT_FAILURE ;
}
305
306
307
308
309
/* Impresion (10) */
if ( ( A D T _ m u s i c a l _ s c o r e _ p r i n t ( musical_score ) ) != OK ) {
fprintf ( stderr , " Error en la impresion de prueba \ n " ) ;
return EXIT_FAILURE ;
}
310
311
312
313
314
315
/* Destruccion (2) */
316
317
318
319
320
321
}
322
323
#endif
A D T _ m u s i c a l _ s c o r e _ d e s t r o y (& musical_score ) ;
return EXIT_SUCCESS ;
ADT synthesizer
8.2.
8.2.1.
1
2
3
4
5
6
7
8
9
10
11
12
modulationlib.h
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Algoritmos y Programaci ó n I - 75.02/95.11 - Curso Ing . Mart ı́ n Cardozo
TP N o 3 - 1 er Cuatrimestre 2012
Alumnos :
Archivo :
Descrip :
Obs :
1)
2)
ARIAS , Francisco - FERRARI BIHURRIET , Francisco
modulationlib . h
Encabezado de la biblioteca modulationlib .
Precondiciones :
El puntero recibido no debe ser NULL .
El primer elemento del vector ( t0 ) debe ser distinto de cero .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14
15
16
17
#if ndef MODULATIONLIB_H
#define MODULATIONLIB_H
18
19
#define PI 3 . 1 4 1 5 9 2 6 5 3 5 8 9 7 9 3 2 3 8 4 6
27
8.2 ADT synthesizer
20
21
22
23
24
/* Posici ó n de los par á metros en el vector */
#define param_T0 0
#define param_T1 1
#define param_A1 2
25 #define param_A
0
26 #define param_F
1
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
/* * * * * * * * * * * * * * * * * * * * * * * * PROTOTYPES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
double
double
double
double
double
double
double
double
double
double
double
double
double
double
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#endif /* MODULATIONLIB_H */
8.2.2.
1
2
15
16
17
18
19
20
21
22
23
24
25
26
27
28
modulationlib.c
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Algoritmos y Programaci ó n I - 75.02/95.11 - Curso Ing . Mart ı́ n Cardozo
TP N o 3 - 1 er Cuatrimestre 2012
3
4
5
6
7
8
9
10
11
12
13
14
mo d u la t i on _ c o ns t a nt ( const double [] , double ) ;
mod ulatio n_line ar ( const double [] , double ) ;
m o d u l a t i o n _ i n v l i n e a r ( const double [] , double ) ;
modulation_sin ( const double [] , double ) ;
modulation_exp ( const double [] , double ) ;
mod ulatio n_inve xp ( const double [] , double ) ;
mo d u la t i on _ q u ar t c os ( const double [] , double ) ;
mo d u la t i on _ q u ar t s in ( const double [] , double ) ;
m od ul at io n_ ha lf co s ( const double [] , double ) ;
m od ul at io n_ ha lf si n ( const double [] , double ) ;
modulation_log ( const double [] , double ) ;
mod ulatio n_invl og ( const double [] , double ) ;
modulation_tri ( const double [] , double ) ;
mod ulatio n_puls es ( const double [] , double ) ;
Alumnos : ARIAS , Francisco - FERRARI BIHURRIET , Francisco
Archivo : modulationlib . c
Descrip : Biblioteca de moduladores de la amplitud en la se ~
n al de audio .
Obs :
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include
#include
#include
#include
< math .h >
< stdio .h >
< stdlib .h >
" modulationlib . h "
/* Macro de funci ó n : m ı́ nimo entre dos valores */
#define MINIMUM (a , b ) (( a ) <( b ) ?( a ) :( b ) )
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
Par á metros en el vector , estas macros son poco expl ı́ citas y cortas ,
para acortar las f ó rmulas en las funciones , por eso se declaran
dentro de ' modulationlib . c ' , para que sean internas y no entren en
en conflicto con otras definiciones .
28
8.2 ADT synthesizer
*/
#define
#define
#define
#define
34 #define
29
30
31
32
33
T0
T1
A1
A
F
parameters [ param_T0 ]
parameters [ param_T1 ]
parameters [ param_A1 ]
parameters [ param_A ]
parameters [ param_F ]
35
36
37
38
39
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
CONSTANT
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
double mo d u la t i on _ c on s t a nt ( const double parameters [] , double t )
40 {
41
return 1;
42 }
43
44
45
46
47
48
49
50
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
LINEAR
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
double mo dulati on_lin ear ( const double parameters [] , double t )
{
return t / T0 ;
}
51
52
53
54
55
56
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
INVLINEAR
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
double m o d u l a t i o n _ i n v l i n e a r ( const double parameters [] , double t )
{
57
if ( T0 < t ) return 0; /* 0 > 1 - t / T0 */
58
return 1 - t / T0 ;
59 }
60
61
62
63
64
65
66
67
68
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
SIN
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
double modulation_sin ( const double parameters [] , double t )
{
return 1 + A * sin (2* PI * F * t ) ;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
EXP
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
double modulation_exp ( const double parameters [] , double t )
{
74
return exp (( -5*( T0 - t ) ) / T0 ) ;
75 }
69
70
71
72
73
76
77
78
79
80
81
82
83
84
85
86
87
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
INVEXP
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
double mo dulati on_inv exp ( const double parameters [] , double t )
{
return exp (( -5* t ) / T0 ) ;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
QUARTCOS
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
29
8.2 ADT synthesizer
88
89
90
91
92
double mo d u la t i o n_ q u ar t c os ( const double parameters [] , double t )
{
return cos (( PI * t ) /(2* T0 ) ) ;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
QUARTSIN
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
double mo d u la t i on _ q u ar t s in ( const double parameters [] , double t )
{
return sin (( PI * t ) /(2* T0 ) ) ;
99 }
93
94
95
96
97
98
100
101
102
103
104
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
HALFCOS
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
double m od ul at io n_ ha lf co s ( const double parameters [] , double t )
105 {
106
return (1+ cos (( PI * t ) / T0 ) ) /2;
107 }
108
109
110
111
112
113
114
115
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
HALFSIN
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
double m od ul at io n_ ha lf si n ( const double parameters [] , double t )
{
return (1+ sin ( PI *(( t - T0 ) / T0 +0.5) ) ) /2;
}
116
117
118
119
120
121
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
LOG
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
double modulation_log ( const double parameters [] , double t )
{
122
return log10 ((9* t ) / T0 + 1) ;
123 }
124
125
126
127
128
129
130
131
132
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
INVLOG
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
double mod ulatio n_invl og ( const double parameters [] , double t )
{
if ( t < T0 ) return log10 (( -9* t ) / T0 + 10) ;
return 0;
}
133
134
135
136
137
138
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/*
TRI
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
double modulation_tri ( const double parameters [] , double t )
{
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 mod ulatio n_puls es ( const double parameters [] , double t )
30
8.2 ADT synthesizer
147
148
149
150
151
152
153
{
double aux ;
t = t / T0 - floor ( t / T0 ) ; /* t ' */
aux = fabs ( ((1 - A1 ) / T1 ) * (2* t -1) * T0 ) + A1 ;
return MINIMUM ( aux ,1) ;
}
8.2.3.
1
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Algoritmos y Programaci ó n I - 75.02/95.11 - Curso Ing . Mart ı́ n Cardozo
TP N o 3 - 1 er Cuatrimestre 2012
Alumnos : ARIAS , Francisco - FERRARI BIHURRIET , Francisco
Archivo : ADT_synthesizer . h
Descrip : Encabezado p ú blico para el TDA sintetizador .
Obs :
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include " A D T _ s y n t h e s i z e r _ P R I V A T E . h "
#include " ../ main_modules / common . h "
#include " modulationlib . h "
#if ndef A DT_SYN THESI ZER_H
#define A DT_SYN THESIZ ER_H
static const modulation_t m o d u l a t i o n _ f u n c t i o n s [ Q UA N T IT Y _ MO D U LA T O RS ] = {
modulation_constant ,
modulation_linear ,
modulation_invlinear ,
modulation_sin ,
modulation_exp ,
modulation_invexp ,
modulation_quartcos ,
modulation_quartsin ,
modulation_halfcos ,
modulation_halfsin ,
modulation_log ,
modulation_invlog ,
modulation_tri ,
modu lation _pulse s
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
ADT synthesizer.h
};
static const string st ring_m odulat ors [ Q UA N T IT Y _ MO D U LA T O RS ] = {
" CONSTANT " ,
" LINEAR " ,
" INVLINEAR " ,
" SIN " ,
" EXP " ,
" INVEXP " ,
" QUARTCOS " ,
" QUARTSIN " ,
" HALFCOS " ,
31
8.2 ADT synthesizer
" HALFSIN " ,
" LOG " ,
" INVLOG " ,
" TRI " ,
" PULSES "
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
};
typedef enum { ATTACK =0 , SUSTAINED =1 , RELEASE =2} t ype_mo dulati on_t ;
typedef struct A DT_syn thesiz er_t A DT_syn thesiz er_t ;
typedef struct tharmonic tharmonic ;
typedef struct tmodulation tmodulation ;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * primitives * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 1) Creador de sintetizador */
status_t A D T _s y n th e s iz e r _n e w ( ADT_ synthe sizer_ t **) ;
/* 2) Destructor de sintetizador */
void A D T _ s y n t h e s i z e r _ d e s t r o y ( AD T_synt hesize r_t **) ;
3) Obtener la cantidad de armonicos . Precondicion : no debe recibir puntero
NULL */
79 size_t A D T _ s y n t h e s i z e r _ g e t _ q u a n t i t y _ h a r m o n i c s ( const AD T_syn thesiz er_t *) ;
80
81
82
83
84
/*
4) Obtener el n - sima armonico . La funcion devuelve por el penultimo
argumento los pares de multiplo y por el ultimo arguemento
la intesidad */
status_t A D T _ s y n t h e s i z e r _ g e t _ h a r m o n i c _ a t ( const ADT_ synthe sizer_ t * , size_t ,
85
double * , double *) ;
86
87
88
89
90
/*
5) Obtener la modulacion . El segundo argumento funciona como una bandera
indicadora de la modulacion deseada ( ATTACK , SUSTAINED o RELEASE ) .
la funcion devuelve por interfaz la modularizacion deseada y los
parametros relacionados con dicha modulacion */
91 status_t A D T _ s y n t h e s i z e r _ g e t _ m o d u l a t i o n _ a t ( const ADT_ synthe sizer_ t * ,
92
type_modulation_t , double ** ,
93
modulation_t *) ;
94
95
/*
/* 6) Escribir desde archivo */
status_t A D T _ s y n t h e s i z e r _ s e t _ f r o m _ f i l e ( ADT_ synthe sizer_ t ** , string ) ;
96
97
98
99
100
101
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
102
103
104
#endif /* AD T_SYNT HESIZE R_H */
/* 7) Imprimir copia del archivo sitetizador */
status_t A D T _ s y n t h e s i z e r _ p r i n t ( const ADT_ synthe sizer_ t *) ;
8.2.4.
1
2
3
ADT synthesizer PRIVATE.h
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Algoritmos y Programaci ó n I - 75.02/95.11 - Curso Ing . Mart ı́ n Cardozo
32
8.2 ADT synthesizer
TP N o 3 - 1 er Cuatrimestre 2012
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
Alumnos :
Archivo :
Descrip :
Obs :
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include " modulationlib . h "
#if ndef A D T _ S Y N T H E S I Z E R _ P R I V A T E _ H
#define A D T _ S Y N T H E S I Z E R _ P R I V A T E _ H
/* *************** Declaration of a function pointer types * * * * * * * * * * * * * * * * * * * * */
typedef double (* modulation_t ) ( const double [] , double ) ;
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#define
#define
#define
#define
32 #define
33 #define
34 #define
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
ARIAS , Francisco - FERRARI BIHURRIET , Francisco
ADT_synthesizer_PRIVATE .h
Encabezado privado para el TDA sintetizador .
Para una correcta utilizaci ó n del TDA no debe conocerse el
funcionamiento interno , el cu á l queda expuesto aqu ı́ .
N 0
Q UA N T IT Y _ PA R A ME T E RS 3
SIZE_AUX_VEC 30
STRING_SPACE " "
Q UA N T IT Y _ MO D U LA T O RS 14
PHASE_MODULATION_AMOUNT 3
FILE_NAME_TEST " T EST_SI NTETIZ ADOR . txt "
/* . . . . . . . . . . . . . . . . . . . . . . . Estructura del ADT sintetizador . .. . . .. . . .. . . .. .. .. */
struct tharmonic {
double multiples_pairs ;
double intensity ;
};
struct tmodulation {
modulation_t modulation ;
double parameters [ Q UA N T IT Y _ PA R A ME T E RS ];
};
struct AD T_synt hesize r_t {
unsigned char quan tity_h armoni c ;
struct tharmonic
** harmonics ;
struct tmodulation ** modulators ; /* 0: Attack - 1: Sustained - 2: Release */
};
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#endif /* A D T _ S Y N T H E S I Z E R _ P R I V A T E _ H */
33
8.2 ADT synthesizer
8.2.5.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
ADT synthesizer.c
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Algoritmos y Programaci ó n I - 75.02/95.11 - Curso Ing . Mart ı́ n Cardozo
TP N o 3 - 1 er Cuatrimestre 2012
Alumnos :
Archivo :
Descrip :
Obs :
ARIAS , Francisco - FERRARI BIHURRIET , Francisco
ADT_synthesizer . c
Implementaci ó n del TDA sintetizador .
Compilacion en modo prueba :
gcc ADT_synthesizer . c modulationlib . c -o synthesizer
- ansi - pedantic - Wall - lm - DTEST
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include
#include
#include
#include
#include
#include
#include
#include
#include
< stdio .h >
< stdlib .h >
< string .h >
< math .h >
< ctype .h >
" ../ main_modules / common . h "
" ADT_synthesizer_PRIVATE .h"
" ADT_synthesizer . h "
" modulationlib . h "
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
1) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / | Creador de sintetizador | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
status_t A D T _s y n th e s iz e r _n e w ( ADT_ synthe sizer_ t ** synthesizer ) {
size_t i , j ;
36
37
38
39
40
41
if ( synthesizer == NULL ) return ERR OR _N UL L_ PO IN TE R ;
42
43
44
45
46
47
if ( ((* synthesizer ) -> modulators = ( tmodulation **)
malloc ( P H A S E _ M O D U L A T I O N _ A M O U N T * sizeof ( tmodulation *) ) ) == NULL ) {
free (* synthesizer ) ;
* synthesizer = NULL ;
return ERROR_NO_MEMORY ;
}
48
49
50
51
52
53
54
55
56
57
if ( ((* synthesizer ) = ( AD T_synt hesize r_t *)
malloc ( sizeof ( AD T_synt hesize r_t ) ) ) == NULL )
return ERROR_NO_MEMORY ;
for ( i =0; i < P H A S E _ M O D U L A T I O N _ A M O U N T ; i ++) {
if ( ((* synthesizer ) -> modulators [ i ] = ( tmodulation *)
malloc ( sizeof ( tmodulation ) ) ) == NULL ) {
for ( j =0; j < i ; j ++)
free ((* synthesizer ) -> modulators [ j ]) ;
free ((* synthesizer ) -> modulators ) ;
free (* synthesizer ) ;
* synthesizer = NULL ;
return ERROR_NO_MEMORY ;
34
8.2 ADT synthesizer
}
58
59
60
61
62
}
(* synthesizer ) -> qu antity _harmo nic = 0;
(* synthesizer ) -> harmonics = NULL ;
63
64
65
66
67
68
69
70
71
72
73
74
for ( j =0; j < P H A S E _ M O D U L A T I O N _ A M O U N T ; j ++) {
(* synthesizer ) -> modulators [ j ] - > modulation = NULL ;
for ( i =0; i < Q U AN T I TY _ P AR A M ET E R S ; i ++)
(* synthesizer ) -> modulators [ j ] - > parameters [ i ] = 0;
}
return OK ;
}
75
76
77
78
79
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
2) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / | Destructor de sintetizador | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
80
81
82
83
84
85
void A D T _ s y n t h e s i z e r _ d e s t r o y ( AD T_synt hesize r_t ** synthesizer ) {
size_t i , a u x _ q u a n t i t y _ h a r m o n i c ;
a u x _ q u a n t i t y _ h a r m o n i c = (* synthesizer ) -> qua ntity_ harmon ic ;
for ( i =0; i < a u x _ q u a n t i t y _ h a r m o n i c ; i ++)
free ((* synthesizer ) -> harmonics [ i ]) ;
free ((* synthesizer ) -> harmonics ) ;
for ( i =0; i < P H A S E _ M O D U L A T I O N _ A M O U N T ; i ++)
free ((* synthesizer ) -> modulators [ i ]) ;
free ((* synthesizer ) -> modulators ) ;
free (* synthesizer ) ;
* synthesizer = NULL ;
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
}
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
3) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / | Obtener la cantidad de armonicos | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
size_t A D T _ s y n t h e s i z e r _ g e t _ q u a n t i t y _ h a r m o n i c s ( const AD T_synt hesiz er_t *
synthesizer ) {
return synthesizer - > qu antity _harmo nic ;
}
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
4) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / | Obtener el n - sima armonico | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
109 /* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
110
111
112
113
114
115
116
status_t A D T _ s y n t h e s i z e r _ g e t _ h a r m o n i c _ a t ( const ADT_ synthe sizer_ t * synthesizer ,
size_t position , double * multiples_pairs , double * intensity ) {
if ( synthesizer == NULL || synthesizer - > qu antity _harmo nic < position )
return E RR OR _N UL L_ PO IN TE R ;
35
8.2 ADT synthesizer
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
* multiples_pairs = ( synthesizer - > harmonics [ position - N ] - > multiples_pairs ) ;
* intensity = ( synthesizer - > harmonics [ position - N ] - > intensity ) ;
return OK ;
}
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
5) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / / | Obtener la modulacion . | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
status_t A D T _ s y n t h e s i z e r _ g e t _ m o d u l a t i o n _ a t ( const ADT_ synthe sizer_ t * synthesizer ,
type _modul ation_ t modulation , double ** parameters , modulation_t * modulator ) {
size_t i ;
if ( synthesizer == NULL ) return ERR OR _N UL L_ PO IN TE R ;
for ( i =0; i < P H A S E _ M O D U L A T I O N _ A M O U N T ; i ++) {
if ( modulation == i ) {
if ( modulator == NULL ) {
* parameters = ( synthesizer - > modulators [ i ] - > parameters ) ;
return OK ;
}
* parameters = ( synthesizer - > modulators [ i ] - > parameters ) ;
* modulator = ( synthesizer - > modulators [ i ] - > modulation ) ;
}
}
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
return OK ;
}
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
6) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / | Escribir desde archivo | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
status_t A D T _ s y n t h e s i z e r _ s e t _ f r o m _ f i l e ( ADT_ synthe sizer_ t ** synthesizer ,
string f i l e _ n a m e _ s y n t h e s i z e r ) {
size_t i ,j ,L , a u x _ q u a n t i t y _ h a r m o n i c ;
FILE * file_synthesizer ;
char aux_vec [ SIZE_AUX_VEC ];
string aux_string ;
if ( synthesizer == NULL || f i l e _ n a m e _ s y n t h e s i z e r == NULL )
return E RR OR _N UL L_ PO IN TE R ;
if ( ( file_synthesizer = fopen ( file_name_synthesizer , " r " ) ) == NULL ) {
A D T _ s y n t h e s i z e r _ d e s t r o y ( synthesizer ) ;
return ER ROR_SY NTHESI ZER ;
}
168
169
170
171
172
173
if ( fgets ( aux_vec , SIZE_AUX_VEC , file_synthesizer ) == NULL )
return ER ROR_SY NTHESI ZER ;
174
175
if ( ((* synthesizer ) -> harmonics = ( tharmonic **)
malloc ( a u x _ q u a n t i t y _ h a r m o n i c * sizeof ( tharmonic *) ) ) == NULL ) {
if ( ( a u x _ q u a n t i t y _ h a r m o n i c = strtoul ( aux_vec , NULL , 0) ) == 0)
return ER ROR_SY NTHESI ZER ;
36
8.2 ADT synthesizer
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
A D T _ s y n t h e s i z e r _ d e s t r o y ( synthesizer ) ;
return ERROR_NO_MEMORY ;
}
for ( i =0; i < a u x _ q u a n t i t y _ h a r m o n i c ; i ++) {
if ( ((* synthesizer ) -> harmonics [ i ] = ( tharmonic *)
malloc ( sizeof ( tharmonic ) ) ) == NULL ) {
(* synthesizer ) -> qu antity _harmo nic = i ;
A D T _ s y n t h e s i z e r _ d e s t r o y ( synthesizer ) ;
return ERROR_NO_MEMORY ;
}
}
for ( i =0; i < a u x _ q u a n t i t y _ h a r m o n i c ; i ++) {
if ( fgets ( aux_vec , SIZE_AUX_VEC , file_synthesizer ) == NULL )
return ER ROR_SY NTHESI ZER ;
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
aux_string = strtok ( aux_vec , STRING_SPACE ) ;
(* synthesizer ) -> harmonics [ i ] - > multiples_pairs =
strtod ( aux_string , NULL ) ;
aux_string = strtok ( NULL , STRING_SPACE ) ;
(* synthesizer ) -> harmonics [ i ] - > intensity = strtod ( aux_string , NULL ) ;
}
for ( j =0; j < P H A S E _ M O D U L A T I O N _ A M O U N T ; j ++) {
if ( fgets ( aux_vec , SIZE_AUX_VEC , file_synthesizer ) == NULL ||
! strcmp ( aux_vec , " \ n " ) )
return ER ROR_SY NTHESI ZER ;
aux_string = strtok ( aux_vec , STRING_SPACE ) ;
if ( isdigit ( aux_vec [0]) )
return ER ROR_SY NTHESI ZER ;
/* Caso especial : CONSTANT , no tiene par á metros */
L = strlen ( aux_vec ) -2;
if ( aux_vec [ L +1] == ' \ n ' && L == strlen ( st ring_m odulat ors [0]) &&
! strncmp ( aux_vec , strin g_modu lators [0] , L ) ) {
(* synthesizer ) -> modulators [ j ] - > modulation = m o d u l a t i o n _ f u n c t i on s [0];
continue ;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
for ( i =0; i < Q U AN T I TY _ M OD U L AT O R S ; i ++) {
if ( ! strcmp ( aux_string , st ring_m odulat ors [ i ]) ) {
(* synthesizer ) -> modulators [ j ] - > modulation =
m o d u l a t i o n _ f u n c t i o n s [ i ];
break ;
}
227
228
229
230
231
232
233
234
}
37
8.2 ADT synthesizer
for ( i =0; i < Q U AN T I TY _ P AR A M ET E R S &&
( aux_string = strtok ( NULL , STRING_SPACE ) ) != NULL ; i ++)
((* synthesizer ) -> modulators [ j ] - > parameters [ i ]) =
strtod ( aux_string , NULL ) ;
235
236
237
238
239
}
240
241
242
243
244
245
/* Validaci ó n */
for ( j =0; j < P H A S E _ M O D U L A T I O N _ A M O U N T ; j ++) {
if ( (* synthesizer ) -> modulators [ j ] - > modulation == NULL )
return ER ROR_SY NTHESI ZER ;
}
246
247
248
249
250
251
252
253
254
255
256
(* synthesizer ) -> qu antity _harmo nic = a u x _ q u a n t i t y _ h a r m o n i c ;
fclose ( file_synthesizer ) ;
return OK ;
}
/* | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
7)
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | */
/* ||| || || || || || || || | Imprimir copia del archivo sintetizador || ||||| |||||||||| */
257 /* | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | */
258
259
260
261
262
263
264
265
266
267
268
status_t A D T _ s y n t h e s i z e r _ p r i n t ( const ADT_ synthe sizer_ t * synthesizer ) {
size_t i , j , qua nt it y_ ha rm on ic s ;
double multiples_pairs , intensity ;
modulation_t modulation = NULL ;
double * parameters = NULL ;
double t ;
if ( synthesizer == NULL ) return ERR OR _N UL L_ PO IN TE R ;
269
270
271
272
273
274
if ( ( q ua nt it y_ ha rm on ic s =
A D T _ s y n t h e s i z e r _ g e t _ q u a n t i t y _ h a r m o n i c s ( synthesizer ) ) == 0)
return ER ROR_SY NTHESI ZER ;
275
276
277
278
279
for ( i =0; i < qu an ti ty _h arm on ic s ; i ++) {
if ( A D T _ s y n t h e s i z e r _ g e t _ h a r m o n i c _ a t ( synthesizer , i ,
& multiples_pairs , & intensity ) != OK )
return ERR OR_SY NTHESI ZER ;
printf ( " %f %f \ n " , multiples_pairs , intensity ) ;
}
280
281
282
283
284
285
printf ( " %lu \ n " , ( ulong ) qu ant it y_ ha rm on ic s ) ;
286
287
288
289
290
291
for ( i =0; i < P H A S E _ M O D U L A T I O N _ A M O U N T ; i ++) {
for ( j =0; j < Q U AN T I TY _ M OD U L AT O R S ; j ++) {
if ( synthesizer - > modulators [ i ] - > modulation ==
modulation_functions [j] )
printf ( " %s " , st ring_m odulat ors [ j ]) ;
}
for ( j =0; j < Q U AN T I TY _ P AR A M ET E R S ; j ++)
printf ( " %f " , synthesizer - > modulators [ i ] - > parameters [ j ]) ;
printf ( " \ n " ) ;
}
292
293
printf ( " \ n %s \ n \ n " , " Prueba de funciones de modulacion : " ) ;
38
8.2 ADT synthesizer
printf ( " %s \ n \ n " , " Ingrese el instante a evaluar : [ segundos ] " ) ;
294
295
296
297
298
if ( scanf ( " %lf " , & t ) != 1 )
return ER ROR_SY NTHESI ZER ;
A D T _ s y n t h e s i z e r _ g e t _ m o d u l a t i o n _ a t ( synthesizer , ATTACK ,
& parameters , & modulation ) ;
printf ( " Funcion de ataque evaluada en t = %f s --> %f \ n " ,
t , modulation ( parameters , t ) ) ;
299
300
301
302
303
304
A D T _ s y n t h e s i z e r _ g e t _ m o d u l a t i o n _ a t ( synthesizer , SUSTAINED ,
& parameters , & modulation ) ;
printf ( " Funcion de duracion evaluada en t = %f s --> %f \ n " , t ,
modulation ( parameters , t ) ) ;
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
A D T _ s y n t h e s i z e r _ g e t _ m o d u l a t i o n _ a t ( synthesizer , RELEASE ,
& parameters , & modulation ) ;
printf ( " Funcion de decaimiento evaluada en t = %f s --> %f \ n " , t ,
modulation ( parameters , t ) ) ;
return OK ;
}
/* | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | */
/* | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | MAIN de prueba | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | */
/* | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | */
#if def TEST
/* MAIN */
int main ( void ) {
ADT_ synth esizer _t * synthesizer ;
/* Creacion (1) */
if ( ( A DT _ s yn t h es i z er _ n ew (& synthesizer ) ) != OK ) {
fprintf ( stderr , " Error en la creacion del sintetizador \ n " ) ;
return EXIT_FAILURE ;
}
/* Llenado (6) */
if ( ( A D T _ s y n t h e s i z e r _ s e t _ f r o m _ f i l e (& synthesizer , FILE_NAME_TEST ) ) != OK ) {
fprintf ( stderr , " Error en el seteo de los elementos \ n " ) ;
return EXIT_FAILURE ;
}
/* Impresion (8) */
if ( ( A D T _ s y n t h e s i z e r _ p r i n t ( synthesizer ) ) != OK ) {
fprintf ( stderr , " Error en la impresion de prueba \ n " ) ;
return EXIT_FAILURE ;
}
/* Destruccion (2) */
A D T _ s y n t h e s i z e r _ d e s t r o y (& synthesizer ) ;
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
4
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Algoritmos y Programaci ó n I - 75.02/95.11 - Curso Ing . Mart ı́ n Cardozo
TP N o 3 - 1 er Cuatrimestre 2012
5
6
7
8
9
10
11
12
13
14
15
Alumnos : ARIAS , Francisco - FERRARI BIHURRIET , Francisco
Archivo : ADT_wav_file . h
Descrip : Encabezado p ú blico para el TDA archivo WAV .
Obs :
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include " ../ main_modules / common . h "
16
17
18
19
20
21
#if ndef ADT_WAV_FILE_H
#define ADT_WAV_FILE_H
22
23
24
25
26
27
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Prototipos | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | */
/* | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | */
typedef struct __wav_file * ADT_wav_file_t ;
/* En el encabezado privado ... */
/* 1) Funci ó n para crear un archivo mono de 16 bit a partir de un ' double [] ' */
status_t A D T _ w a v _ f i l e _ c r e a t e _ f r o m _ v e c t o r ( uint , uint , double [] ,
28
ADT_wav_file_t *) ;
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
/* 2) Funci ó n para destruir un archivo WAV */
status_t A D T _ w a v _ f i l e _ d e s t r o y ( ADT_wav_file_t *) ;
/* 3) Funci ó n para escribir en un stream ( abierto en modo " wb ") */
status_t A DT _w av_ fi le _w ri te ( ADT_wav_file_t , FILE *) ;
/*
TODO :
*
*
*
*
*
*/
#endif /* ADT_WAV_FILE_H */
8.3.2.
1
ADT_wav_file_create_from_stream .
ADT_wav_file_create_empty .
ADT_wav_file_get_sample .
ADT_wav_file_set_sample .
ADT_wav_file_change_sample_rate .
ADT wav file PRIVATE.h
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2
40
8.3 ADT wav file
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
Algoritmos y Programaci ó n I - 75.02/95.11 - Curso Ing . Mart ı́ n Cardozo
TP N o 3 - 1 er Cuatrimestre 2012
Alumnos :
Archivo :
Descrip :
Obs :
ARIAS , Francisco - FERRARI BIHURRIET , Francisco
ADT_wav_file_PRIVATE .h
Encabezado privado para el TDA archivo WAV .
Para una correcta utilizaci ó n del TDA no debe conocerse el
funcionamiento interno , el cu á l queda expuesto aqu ı́ .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include < limits .h >
#include " ../ main_modules / common . h "
#include " ADT_wav_file . h "
#if ndef A D T _ W A V _ F I L E _ P R I V A T E _ H
#define A D T _ W A V _ F I L E _ P R I V A T E _ H
/* - - - - - - - - - - - - - - - - - - - - - - - - - Definiciones varias - - - - - - - - - - - - - - - - - - - - - - - #define WAV_ID_SIZES
4
/* Tama ~
n o en Bytes de los IDs .
#define WAV_CHUNK_ID
" RIFF "
/* Identificador del Chunk principal .
#define WAV_FORMAT
" WAVE "
/* Identificador del formato WAVE .
#define WAV_SUBCHUNK1_ID " fmt "
/* Identificador del 1 er SubChunk .
#define WAV_SUBCHUNK2_ID " data "
/* Identificador del 2 do SubChunk .
/* ···································
*/
#define W A V _ C H U N K _ F I X _ P A R T _ S I Z E 36 /* Tama ~
n o de la parte fija del Chunk .
#define WA V_ SUB CH UN K1 _S IZ E
16 /* Tama ~
n o del 1 er SubChunk .
#define WAV_AUDIO_FORMAT
1 /* Tipo de compresi ó n de audio ( PCM ) .
#define WA V_MON O_CHAN NELS
1 /* Canales en MONO : solo uno .
#define WAV_BITS_SAMPLE
16 /* Tama ~
n o de las muestras ( en bits ) .
#define WAV_BYTES_SAMPLE
( WAV_BITS_SAMPLE / CHAR_BIT ) /* ( en bytes ) .
/* ···································
*/
#define MAX_INT16
( pow (2 ,16) /2) /* ( m á ximo de un ' int16 ' ) .
#define W A V _ M A X _ S A M P L E _ V A L U E
( MAX_INT16 -2) /* ( m á ximo valor absoluto ) .
#define WA V_MAX_ N_SAM PLES
(44100*2*3600) /* ( m á x : 2 h a 44 ,1 KHz ) .
#define W AV _ M AX _ S AM P L E_ R A TE
192000
/* ( m á x frec . de muestreo ) .
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - Enumerativo de tipos - - - - - - - - - - - - - - - - - - - - - - - - */
typedef enum { TYPE_INT16 =2 , TYPE_INT32 =4} type_t ; /* No cambiar valores ! */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* - - - - - - - - - - - - - - - - - - - - - Estructura del ADT_wav_file - - - - - - - - - - - - - - - - - - - - */
struct __wav_file
{
/* Chunk */
char ChunkID [ WAV_ID_SIZES ];
uint ChunkSize ;
char Format [ WAV_ID_SIZES ];
/* SubChunk1 */
char SubChunk1ID [ WAV_ID_SIZES ];
uint SubChunk1Size ;
uint AudioFormat ;
uint NumChannels ;
uint SampleRate ;
uint ByteRate ;
uint BlockAlign ;
uint BitsPerSample ;
41
8.3 ADT wav file
62
63
64
65
66
67
68
69
70
71
72
73
/* SubChunk2 */
char SubChunk2ID [ WAV_ID_SIZES ];
uint SubChunk2Size ;
short * Data ;
};
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* - - - - - - - - - - - - - - - - - - Prototipos de funciones internas - - - - - - - - - - - - - - - - - - */
void _ w r i t e _ l i t t l e _ e n d i a n ( uint , type_t , FILE *) ;
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
#endif /* A D T _ W A V _ F I L E _ P R I V A T E _ H */
8.3.3.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
ADT wav file.c
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Algoritmos y Programaci ó n I - 75.02/95.11 - Curso Ing . Mart ı́ n Cardozo
TP N o 3 - 1 er Cuatrimestre 2012
Alumnos : ARIAS , Francisco - FERRARI BIHURRIET , Francisco
Archivo : ADT_wav_file . c
Descrip : Implementaci ó n del TDA archivo WAV .
Obs :
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include
#include
#include
#include
#include
< stdio .h >
< string .h >
< stdlib .h >
< math .h >
" ADT_wav_file_PRIVATE .h"
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
1) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | Creador | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
status_t A D T _ w a v _ f i l e _ c r e a t e _ f r o m _ v e c t o r ( uint n_samples , uint sample_rate ,
double vector [] ,
ADT_wav_file_t * wav_file )
{
size_t i ;
double scale ; /* Factor de escala */
32
33
34
35
36
37
/* Validaciones de entrada */
if ( wav_file == NULL || vector == NULL )
if (! n_samples )
if ( n_samples > WA V_MAX_ N_SAMP LES )
if ( sample_rate > W AV _ M AX _ S AM P L E_ R A TE )
38
39
40
41
42
/* Pedido de memoria y validaci ó n */
* wav_file = ( ADT_wav_file_t ) malloc ( sizeof ( struct __wav_file ) ) ;
if (* wav_file == NULL ) return ERROR_NO_MEMORY ;
43
44
45
return
return
return
return
ERR OR _N UL L_ PO IN TE R ;
ERR OR _I NV AL ID _I NF O ;
E RR O R _T O O _L O N G_ F I LE ;
ER ROR _I NV AL ID _I NF O ;
/* - - - - - - - - - - - - - - - - Volcado de datos en Chunk - - - - - - - - - - - - - - - - */
memcpy ((* wav_file ) -> ChunkID , WAV_CHUNK_ID , WAV_ID_SIZES ) ;
(* wav_file ) -> ChunkSize = W A V _ C H U N K _ F I X _ P A R T _ S I Z E +
WAV_BYTES_SAMPLE * n_samples ;
42
8.3 ADT wav file
memcpy ((* wav_file ) -> Format , WAV_FORMAT , WAV_ID_SIZES ) ;
46
47
48
49
50
/* - - - - - - - - - - - - - - Volcado de datos en SubChunk1 - - - - - - - - - - - - - - */
memcpy ((* wav_file ) -> SubChunk1ID , WAV_SUBCHUNK1_ID , WAV_ID_SIZES ) ;
(* wav_file ) -> SubChunk1Size = WAV _S UB CH UN K1 _S IZ E ;
(* wav_file ) -> AudioFormat
= WAV_AUDIO_FORMAT ;
(* wav_file ) -> NumChannels
= WA V_MONO _CHANN ELS ;
(* wav_file ) -> SampleRate
= sample_rate ;
(* wav_file ) -> ByteRate
= WAV_BYTES_SAMPLE * sample_rate ;
(* wav_file ) -> BlockAlign
= WAV_BITS_SAMPLE ;
(* wav_file ) -> BitsPerSample = WAV_BITS_SAMPLE ;
51
52
53
54
55
56
57
58
59
60
61
62
/* - - - - - - - - - - - - - - Volcado de datos en SubChunk2 - - - - - - - - - - - - - - */
memcpy ((* wav_file ) -> SubChunk2ID , WAV_SUBCHUNK2_ID , WAV_ID_SIZES ) ;
(* wav_file ) -> SubChunk2Size = WAV_BYTES_SAMPLE * n_samples ;
/* Pedido de memoria para las muestras y validaci ó n */
(* wav_file ) -> Data = ( short *) malloc ( n_samples * sizeof ( short ) ) ;
if ((* wav_file ) -> Data == NULL )
{
free (* wav_file ) ;
return ERROR_NO_MEMORY ;
}
/* B ú squeda de m á ximo absoluto para evitar overflow */
scale = 0;
for ( i =0; i < n_samples ; i ++)
{
if ( fabs ( vector [ i ]) > scale )
scale = fabs ( vector [ i ]) ;
}
/* C á lculo del factor de escala */
scale = W A V _ M A X _ S A M P L E _ V A L U E / scale ;
/* Guardado de las muestras utilizando el factor de escala */
for ( i =0; i < n_samples ; i ++)
((* wav_file ) -> Data ) [ i ] = scale * vector [ i ];
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
return OK ;
}
86
87
88
89
90
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
2) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | Destructor | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
91 status_t A D T _ w a v _ f i l e _ d e s t r o y ( ADT_wav_file_t * wav_file )
92 {
93
if ( wav_file == NULL || * wav_file == NULL ) return ERR OR _N UL L_ PO IN TE R ;
94
95
96
97
98
99
100
101
102
103
104
free ((* wav_file ) -> Data ) ;
free (* wav_file ) ;
* wav_file = NULL ;
return OK ;
}
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
3) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / | Escritor en archivo | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
43
8.4 main modules
105
106
107
108
109
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
status_t A DT _w av_ fi le _w ri te ( ADT_wav_file_t wav_file , FILE * stream )
{
size_t i ;
uint n_samples ;
110
111
112
113
114
115
if ( stream == NULL || wav_file == NULL ) return ERR OR _N UL L_ PO IN TE R ;
/* - - - - - - - - - - - - - - - Escritura de datos en Chunk - - - - - - - - - - - - - - - */
fwrite (&( wav_file - > ChunkID ) , 1 , WAV_ID_SIZES , stream ) ;
_ w r i t e _ l i t t l e _ e n d i a n ( wav_file - > ChunkSize , TYPE_INT32 , stream ) ;
fwrite (&( wav_file - > Format ) , 1 , WAV_ID_SIZES , stream ) ;
116
117
118
119
120
121
/*
------- Escritura de datos en SubChunk1 ------*/
fwrite (&( wav_file - > SubChunk1ID ) , 1 , WAV_ID_SIZES , stream ) ;
_ w r i t e _ l i t t l e _ e n d i a n ( wav_file - > SubChunk1Size , TYPE_INT32 , stream ) ;
_ w r i t e _ l i t t l e _ e n d i a n ( wav_file - > AudioFormat ,
TYPE_INT16 , stream ) ;
_ w r i t e _ l i t t l e _ e n d i a n ( wav_file - > NumChannels ,
TYPE_INT16 , stream ) ;
_ w r i t e _ l i t t l e _ e n d i a n ( wav_file - > SampleRate ,
TYPE_INT32 , stream ) ;
_ w r i t e _ l i t t l e _ e n d i a n ( wav_file - > ByteRate ,
TYPE_INT32 , stream ) ;
_ w r i t e _ l i t t l e _ e n d i a n ( wav_file - > BlockAlign ,
TYPE_INT16 , stream ) ;
_ w r i t e _ l i t t l e _ e n d i a n ( wav_file - > BitsPerSample , TYPE_INT16 , stream ) ;
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
------- Escritura de datos en SubChunk2 ------*/
fwrite (&( wav_file - > SubChunk2ID ) , 1 , WAV_ID_SIZES , stream ) ;
_ w r i t e _ l i t t l e _ e n d i a n ( wav_file - > SubChunk2Size , TYPE_INT32 , stream ) ;
n_samples = ( wav_file - > SubChunk2Size ) / WAV_BYTES_SAMPLE ;
for ( i =0; i < n_samples ; i ++)
_ w r i t e _ l i t t l e _ e n d i a n (( wav_file - > Data ) [ i ] , TYPE_INT16 , stream ) ;
return OK ;
}
139
140
141
142
143
144
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
*) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / | Funciones internas | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
void _ w r i t e _ l i t t l e _ e n d i a n ( uint value , type_t type , FILE * stream )
145 {
146
uchar convert [ TYPE_INT32 ] , i ;
147
148
149
150
151
152
153
/* En ' type_t ' cada tipo tiene asignada la cantidad de bytes ! */
for ( i =0; i < type ; i ++)
convert [ i ]=( value &( UCHAR_MAX < < i * CHAR_BIT ) ) >>i * CHAR_BIT ;
fwrite (& convert , 1 , type , stream ) ;
}
main modules
8.4.
8.4.1.
1
2
3
4
5
6
addsynthlib.h
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Algoritmos y Programaci ó n I - 75.02/95.11 - Curso Ing . Mart ı́ n Cardozo
TP N o 3 - 1 er Cuatrimestre 2012
Alumnos : ARIAS , Francisco - FERRARI BIHURRIET , Francisco
44
8.4 main modules
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
Archivo : addsynthlib . h
Descrip : Encabezado de la biblioteca de s ı́ ntesis aditiva .
Obs :
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#if ndef ADDSYNTHLIB_H
#define ADDSYNTHLIB_H
#include < stdio .h >
#include " ../ ADT_synthesizer / ADT_synthesizer . h "
#include " ../ ADT_ musica l_scor e / ADT_ musica l_scor e . h "
#define TWOPI 2 * 3 . 1 4 1 5 9 2 6 5 3 5 8 9 7 9 3 2 3 8 4 6
typedef struct
{
double * values ;
size_t sample_rate ;
} tabsin_t ;
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Prototipos | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | */
/* | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | */
/* 1) Funci ó n para crear la tabla con el seno precalculado */
tabsin_t * t a b si n _ cr e a te _ t ab l e ( size_t ) ;
/* 2) Funci ó n para destruir la tabla */
void t a b s i n _ d e s t r o y _ t a b l e ( tabsin_t **) ;
/* 3) Funci ó n para obtener la envolvente en funci ó n del tiempo */
double evenlope ( const AD T_synt hesize r_t * , const A DT _ m us i c al _ s co r e _t * ,
double , size_t ) ;
/* 4) Funci ó n para sintetizar una partitura completa */
void synthesize ( const A DT _ m us i c al _ s co r e _t * , const AD T_synt hesize r_t * ,
tabsin_t * , double []) ;
#endif /* ADDSYNTHLIB_H */
8.4.2.
1
2
3
4
5
6
7
8
9
10
11
12
addsynthlib.c
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Algoritmos y Programaci ó n I - 75.02/95.11 - Curso Ing . Mart ı́ n Cardozo
TP N o 3 - 1 er Cuatrimestre 2012
Alumnos :
Archivo :
Descrip :
Obs :
ARIAS , Francisco - FERRARI BIHURRIET , Francisco
addsynthlib . c
Biblioteca de s ı́ ntesis aditiva .
Contiene rutinas que utilizan la funci ó n seno tabulada seg ú n la
frecuancia de muestreo , para optimizar la velocidad de s ı́ ntesis .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13
14
45
8.4 main modules
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include
#include
#include
#include
#include
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
1) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* |/////////| Funci ó n para crear la tabla con el seno precalculado |\\\\\\\\\| */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
tabsin_t * t a b si n _ cr e a te _ t ab l e ( size_t sample_rate )
{
tabsin_t * ptable ;
size_t i ;
double aux ;
/* Memoria para la estructura */
ptable = ( tabsin_t *) malloc ( sizeof ( tabsin_t ) ) ;
if ( ptable == NULL ) return NULL ;
32
33
34
35
36
/* Memoria para la tabla */
ptable - > values = ( double *) malloc ( sample_rate * sizeof ( double ) ) ;
if ( ptable - > values == NULL )
{
free ( ptable ) ;
return NULL ;
}
37
38
39
40
41
42
ptable - > sample_rate = sample_rate ;
43
44
45
46
47
48
49
50
51
52
53
54
< stdio .h >
< stdlib .h >
< math .h >
" addsynthlib . h "
" common . h "
aux = TWOPI / ( sample_rate -1) ;
/* Cargado de la tabla */
for ( i =0; i < sample_rate ; i ++)
( ptable - > values ) [ i ] = sin ( i * aux ) ;
return ptable ;
}
55
56
57
58
59
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
2) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / | Funci ó n para destruir la tabla | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \\ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
void t a b s i n _ d e s t r o y _ t a b l e ( tabsin_t ** table )
60 {
61
if ( table == NULL || * table == NULL ) return ;
62
63
64
65
66
67
68
69
70
71
free ((* table ) -> values ) ;
free (* table ) ;
* table = NULL ;
}
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
3) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* |///////| Funci ó n para obtener la envolvente en funci ó n del tiempo |\\\\\\\| */
72 /* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
73 #define ATTACK_TIME
p aramet ers_at tack [ param_T0 ]
46
8.4 main modules
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#define RELEASE_TIME pa ra me ter s_ re le as e [ param_T0 ]
double evenlope ( const AD T_synt hesize r_t * synthesizer ,
const A D T _m u s ic a l _s c o re _ t * musical_score ,
double t , size_t note )
{
modulation_t mo dulati on_at tack ;
modulation_t m o d u l a t i o n _ s u s t a i n e d ;
modulation_t mo du lat io n_ re le as e ;
double * pa ramete rs_att ack ;
double * p a r a m e t e r s _ s u s t a i n e d ;
double * par am et er s_ re le as e ;
double duration ;
if ( synthesizer == NULL || musical_score == NULL )
return 0;
if ( ( A D T _ s y n t h e s i z e r _ g e t _ m o d u l a t i o n _ a t ( synthesizer , ATTACK ,
& parameters_attack , & modul ation_ attack ) ) != OK )
return 0;
if ( ( A D T _ s y n t h e s i z e r _ g e t _ m o d u l a t i o n _ a t ( synthesizer , SUSTAINED ,
& parameters_sustained , & m o d u l a t i o n _ s u s t a i n e d ) ) != OK )
return 0;
if ( ( A D T _ s y n t h e s i z e r _ g e t _ m o d u l a t i o n _ a t ( synthesizer , RELEASE ,
& parameters_release , & mo du la ti on _r el ea se ) ) != OK )
return 0;
91
92
93
94
95
96
97
98
99
100
101
duration = A D T _ m u s i c a l _ s c o r e _ g e t _ d u r a t i o n _ a t ( musical_score , note ) ;
102
103
104
105
106
107
if ( t < ATTACK_TIME )
return mo dulati on_att ack ( parameters_attack , t ) ;
if ( t >= ATTACK_TIME && t < duration )
return m o d u l a t i o n _ s u s t a i n e d ( parameters_sustained , t - ATTACK_TIME ) ;
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
if ( t >= duration && t < duration + RELEASE_TIME )
return m o d u l a t i o n _ s u s t a i n e d ( parameters_sustained , duration - ATTACK_TIME )
* mo du la ti on _r el ea se ( parameters_release , t - duration ) ;
return 0;
}
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
4) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* |////////////| Funci ó n para sintetizar una partitura completa |\\\\\\\\\\\\| */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/*
Precondici ó n : El vector de doubles alcanza , es decir que ya fue pedida
la memoria para toda la canci ó n .
*/
void synthesize ( const A DT _ m us i c al _ s co r e _t * musical_score ,
const ADT_s ynthes izer_t * synth ,
tabsin_t * table , double samples_vec [])
{
size_t i , harmonic , n_harmonics , note , n_notes ;
double T ; /* Per ı́ odo en muestras */
uint
init_sample , n_samples ;
double harmonic_multiple , ha rmo ni c_ in te ns it y ;
47
8.4 main modules
double * release_time ;
133
134
135
136
137
if ( musical_score == NULL || synth == NULL ||
table == NULL || samples_vec == NULL ) return ;
/* Se obtiene el release_time */
A D T _ s y n t h e s i z e r _ g e t _ m o d u l a t i o n _ a t ( synth , RELEASE , & release_time , NULL ) ;
/* Se obtiene el n ú mero de arm ó nicos */
n_harmonics = A D T _ s y n t h e s i z e r _ g e t _ q u a n t i t y _ h a r m o n i c s ( synth ) ;
/* Se obtiene la cantidad de notas */
n_notes = A D T _ m u s i c a l _ s c o r e _ g e t _ q u a n t i t y _ n o t e s ( musical_score ) ;
138
139
140
141
142
143
144
145
146
147
148
149
/* -- Para cada nota -- */
for ( note =0; note < n_notes ; note ++)
{
/* Se obtiene la muestra inicial */
init_sample = A D T _ m u s i c a l _ s c o r e _ g e t _ s t a r t _ t i m e _ a t ( musical_score , note )
* table - > sample_rate ;
/* Se obtiene la cantidad de muestras */
n_samples = ( A D T _ m u s i c a l _ s c o r e _ g e t _ d u r a t i o n _ a t ( musical_score , note )
+ * release_time ) * table - > sample_rate ;
150
151
152
153
154
/* -- S ı́ ntesis : Para cada arm ó nico -- */
for ( harmonic =0; harmonic < n_harmonics ; harmonic ++)
{
/* Se obtiene el m ú ltiplo y la intensidad */
A D T _ s y n t h e s i z e r _ g e t _ h a r m o n i c _ a t ( synth , harmonic , & harmonic_multiple ,
& ha rm on ic _i nt en si ty ) ;
/* Asignaci ó n del per ı́ odo en muestras */
T = table - > sample_rate /
( A D T _ m u s i c a l _ s c o r e _ g e t _ f r e q u e n c y _ a t ( musical_score , note )
* harmo nic_mu ltiple ) ;
155
156
157
158
159
160
161
162
163
164
165
166
/* -- Para cada muestra -- */
for ( i =0; i < n_samples ; i ++)
{
samples_vec [ i + init_sample ] += h ar mo ni c_ in ten si ty
* ( table - > values ) /* Uso del seno tabulado : */
[ ( size_t ) ( ( i / T - floor ( i / T ) ) * table - > sample_rate ) ]
* evenlope ( synth , musical_score ,
i /( double ) table - > sample_rate , note ) ;
}
167
168
169
170
171
172
173
174
175
176
177
}
}
}
8.4.3.
1
2
3
4
5
6
7
8
9
10
11
12
common.h
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Algoritmos y Programaci ó n I - 75.02/95.11 - Curso Ing . Mart ı́ n Cardozo
TP N o 3 - 1 er Cuatrimestre 2012
Alumnos : ARIAS , Francisco - FERRARI BIHURRIET , Francisco
Archivo : common . h
Descrip : Encabezado de definiciones comunes a todos los m ó dulos .
Obs :
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
48
8.4 main modules
13
14
15
16
17
#if ndef COMMON_H
#define COMMON_H
/* - - - - - - - - - - - - - - - - - - - - - - - Abreviaturas de tipos - - - - - - - - - - - - - - - - - - - - - - - */
typedef unsigned char uchar ;
typedef unsigned short ushort ;
typedef unsigned int
uint ;
typedef unsigned long ulong ;
typedef char *
string ;
24 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
18
19
20
21
22
23
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/* - - - - - - - - - - - - - - - - - - - - - - - Enumerativo de estado - - - - - - - - - - - - - - - - - - - - - - - */
typedef enum
{
OK = 0 ,
/* Ning ú n error ha ocurrido .
*/
E R RO R _ BA D _ AR G U ME N T S = 1 ,
/* Error de argumentos incorrectos .
*/
E R R O R _ B A D _ S A M P L E _ R A T E = 2 , /* Error de frecuencia de muestreo .
*/
E R RO R _ MU S I CA L _ SC O R E = 3 ,
/* Error en el archivo de partitura .
*/
ERRO R_SYNT HESIZE R = 4 ,
/* Error en el archivo de sintetizador . */
ER RO R_ NU LL _P OI NT ER = 5 ,
/* Error de puntero nulo .
*/
ER RO R_ IN VA LI D_ IN FO = 6 ,
/* Error de informaci ó n inv á lida .
*/
ERROR_NO_MEMORY = 7 ,
/* Error de falta de memoria .
*/
E R RO R _ TO O _ LO N G _F I L E = 8 ,
/* Error de archivo demasiado largo .
*/
ERROR_WAV_FILE = 9
/* Error en el archivo WAV .
*/
} status_t ;
/* ···································
*/
extern const string status_msgs []; /* Mensajes en archivo externo .
*/
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* - - - - - - - - - - - - - - - - - - - - - - Enumerativo de progreso - - - - - - - - - - - - - - - - - - - - - - */
typedef enum
{
PROGRESS_PREVIOUS_TASKS = 0,
/* Tareas previas .
*/
PROGRESS_MUSIC_SYNTHESIS = 1,
/* S ı́ ntesis de la m ú sica .
*/
P R O G R E S S _ O U T _ F I L E _ C R E A T I O N = 2 , /* Creaci ó n del archivo de salida . */
PROGRESS_DUMP_OF_DATA = 3,
/* Volcado de datos .
*/
PROGRESS_FILE_CREATED = 4
/* Archivo creado .
*/
} progress_t ;
/* ···································
*/
extern const string progress_msgs []; /* Mensajes en archivo externo . */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - Mensajes de uso - - - - - - - - - - - - - - - - - - - - - - - - - - */
#define USAGE_USAGE
0 /* Uso .
*/
#define US AGE_SA MPLE_ RATE
1 /* Frecuencia de muestreo .
*/
#define U S A G E _ F I L E _ M U S I C A L _ S C O R E 2 /* Archivo de partitura musical .
*/
#define U S A G E _ F I L E _ S Y N T H E S I Z E R
3 /* Archivo de sintetizador .
*/
#define USAGE_FILE_WAVE
4 /* Archivo de audio ( WAV ) .
*/
/* ···································
*/
extern const string usage_msgs []; /* Mensajes en archivo externo . */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* - - - - - - - - - - - - - - - - - - - - - - - Validate arguments - - - - - - - - - - - - - - - - - - - - - - - - - - */
49
8.4 main modules
#define A R G U M E N T _ S A M P L E _ R A T E
" -f "
#define A R G U M E N T _ F I L E _ M U S I C A L _ S C O R E " -p "
#define A R G U M E N T _ F I L E _ S Y N T H E S I Z E R
" -s "
#define AR GU ME NT_ FI LE _W AV E
" -o "
#define D EF A U LT _ S AM P L E_ R A TE
44100 /* Hz */
77 #define MAX_SAMPLE_RATE
96000 /* Hz */
78 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
72
73
74
75
76
79
80
#endif /* COMMON_H */
8.4.4.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
main.c
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Algoritmos y Programaci ó n I - 75.02/95.11 - Curso Ing . Mart ı́ n Cardozo
TP N o 3 - 1 er Cuatrimestre 2012
Alumnos : ARIAS , Francisco - FERRARI BIHURRIET , Francisco
Archivo : main . c
Descrip : M ó dulo principal de la aplicaci ó n .
Obs :
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include
#include
#include
#include
18 #include
19 #include
20 #include
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
< stdio .h >
< stdlib .h >
< string .h >
" ../ ADT_ musica l_scor e / ADT_ musica l_scor e . h "
" ../ ADT_synthesizer / ADT_synthesizer . h "
" ../ ADT_wav_file / ADT_wav_file . h "
" addsynthlib . h "
typedef struct
{
string musical_score ;
string synthesizer ;
string wave ;
} tfiles_names ;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * PROTOTYPES * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
/* 1) validacion de argumentos */
status_t v al id ate _a rg um en ts ( int , string [] , tfiles_names * , size_t *) ;
/* 2) Impresores de errores y estados */
void progress_msg ( progress_t ) ;
void status_msg ( status_t ) ;
void show_usage ( void ) ;
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
string program_name ;
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * FUNCTION MAIN * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int main ( int argc , string argv []) {
/* **** - - - - - - - - - - - - - - - - - - - - - - - - - - - variables - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -**** */
50
8.4 main modules
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
status_t st ;
size_t sample_rate , note , quantity_notes ;
tfiles_names files_names ;
A DT _ m us i c al _ s co r e _t * musical_score ;
ADT_ synthe sizer _t * synthesizer ;
ADT_wav_file_t wav_file ;
uint n_samples ;
double * samples_vec ;
double * release ;
double time_length , aux ;
FILE * out_file ;
tabsin_t * table ;
/* **** - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -**** */
/* Validacion de argumentos */
program_name = * argv ;
st = v al id at e_ ar gu me nt s ( argc , argv , & files_names , & sample_rate ) ;
if ( st != OK )
{
status_msg ( st ) ;
show_usage () ;
return st ;
}
progress_msg ( P R O G R E S S _ P R E V I O U S _ T A S K S ) ;
/* Creacion de los TDA partitura y sintetizador */
if ( ( st = A D T _ m u s i c a l _ s c o r e _ n e w (& musical_score ) ) != OK )
{
status_msg ( st ) ;
return st ;
}
if ( ( st = A DT _ s yn t h es i z er _ n ew (& synthesizer ) ) != OK )
{
A D T _ m u s i c a l _ s c o r e _ d e s t r o y (& musical_score ) ;
status_msg ( st ) ;
return st ;
}
/* Cargar el contenido de los archivos en los TDA */
if ( ( st = A D T _ m u s i c a l _ s c o r e _ s e t _ f r o m _ f i l e (& musical_score ,
files_names . musical_score ) ) != OK )
{
A D T _ s y n t h e s i z e r _ d e s t r o y (& synthesizer ) ;
status_msg ( st ) ;
return st ;
}
if ( ( st = A D T _ s y n t h e s i z e r _ s e t _ f r o m _ f i l e (& synthesizer ,
files_names . synthesizer ) ) != OK )
{
A D T _ m u s i c a l _ s c o r e _ d e s t r o y (& musical_score ) ;
status_msg ( st ) ;
return st ;
}
51
8.4 main modules
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
/* | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | */
/* | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | */
/* Otenci ó n del tiempo de duraci ó n de la canci ó n */
time_length = 0;
quantity_notes = A D T _ m u s i c a l _ s c o r e _ g e t _ q u a n t i t y _ n o t e s ( musical_score ) ;
for ( note = 0; note < quantity_notes ; note ++)
{
aux = A D T _ m u s i c a l _ s c o r e _ g e t _ s t a r t _ t i m e _ a t ( musical_score , note ) +
A D T _ m u s i c a l _ s c o r e _ g e t _ d u r a t i o n _ a t ( musical_score , note ) ;
if ( aux > time_length )
time_length = aux ;
}
/* Suma del release time */
A D T _ s y n t h e s i z e r _ g e t _ m o d u l a t i o n _ a t ( synthesizer , RELEASE , & release , NULL ) ;
time_length += (* release ) ;
/* Otenci ó n de la cantidad de muestras total */
n_samples = time_length * sample_rate + 1;
/* Pedido para las muestras inicializadas en 0 */
samples_vec = ( double *) calloc ( n_samples , sizeof ( double ) ) ;
if ( samples_vec == NULL )
{
A D T _ m u s i c a l _ s c o r e _ d e s t r o y (& musical_score ) ;
A D T _ s y n t h e s i z e r _ d e s t r o y (& synthesizer ) ;
status_msg ( ERROR_NO_MEMORY ) ;
return ERROR_NO_MEMORY ;
}
/* Creado de la tabla del seno precalculado */
table = t a b si n _ cr e a te _ t ab l e ( sample_rate ) ;
if ( table == NULL )
{
free ( samples_vec ) ;
A D T _ m u s i c a l _ s c o r e _ d e s t r o y (& musical_score ) ;
A D T _ s y n t h e s i z e r _ d e s t r o y (& synthesizer ) ;
status_msg ( ERROR_NO_MEMORY ) ;
return ERROR_NO_MEMORY ;
}
/* Sintetizado de la partitura */
progress_msg ( P R O G R E S S _ M U S I C _ S Y N T H E S I S ) ;
synthesize ( musical_score , synthesizer , table , samples_vec ) ;
/* Liberaci ó n de lo que ya no se utilizar á : tabla de senos y TDAs */
t a b s i n _ d e s t r o y _ t a b l e (& table ) ;
A D T _ m u s i c a l _ s c o r e _ d e s t r o y (& musical_score ) ;
A D T _ s y n t h e s i z e r _ d e s t r o y (& synthesizer ) ;
/* Creaci ó n del TDA Archivo WAV */
progress_msg ( P R O G R E S S _ O U T _ F I L E _ C R E A T I O N ) ;
st = A D T _ w a v _ f i l e _ c r e a t e _ f r o m _ v e c t o r ( n_samples , sample_rate ,
samples_vec , & wav_file ) ;
/* Liberaci ó n de las muestras en double */
free ( samples_vec ) ;
if ( st != OK )
52
8.4 main modules
167
168
169
170
171
{
172
173
174
175
176
177
/* Apertura del archivo de salida */
out_file = fopen ( files_names . wave , " wb " ) ;
if ( out_file == NULL )
{
A D T _ w a v _ f i l e _ d e s t r o y (& wav_file ) ;
status_msg ( ERROR_WAV_FILE ) ;
return ERROR_WAV_FILE ;
}
status_msg ( st ) ;
return st ;
}
178
179
180
181
182
183
/* Escritura del archivo de salida */
progress_msg ( P R O G R E S S _ D U M P _ O F _ D A T A ) ;
st = A DT _w av _f il e_ wr it e ( wav_file , out_file ) ;
184
185
186
187
188
/* Cierre del archivo de salida */
fclose ( out_file ) ;
if ( st != OK )
{
A D T _ w a v _ f i l e _ d e s t r o y (& wav_file ) ;
status_msg ( st ) ;
return st ;
}
189
190
191
192
193
194
/* Destrucci ó n del TDA Archivo WAV */
st = A D T _ w a v _ f i l e _ d e s t r o y (& wav_file ) ;
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
fputc ( ' \ n ' , stderr ) ;
status_msg ( st ) ;
fprintf ( stderr , " %s : ' %s ' .\ n \ n " , progress_msgs [ P R O G R E S S _ F I L E _ C R E A T E D ] ,
files_names . wave ) ;
return st ;
}
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
1) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / | Validacion de argumentos | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* Macro de fuci ó n : es impar ? */
#define ISODD ( n ) (( n ) %2)
/* - - - - - - - - - - - - - - - - - - - - - - - - - - */
status_t v al id ate _a rg um en ts ( int argc , string argv [] , tfiles_names * files_names ,
size_t * sample_rate )
{
218
size_t i ;
219
220
221
222
223
/* Los argumentos estan dados de a pares , sumando el
nombre del programa , lo correcto es un n ú mero impar . */
if (! ISODD ( argc ) )
return E RR O R _B A D _A R G UM E N TS ;
224
225
* sample_rate = 0;
53
8.4 main modules
files_names - > musical_score = NULL ;
files_names - > synthesizer = NULL ;
files_names - > wave = NULL ;
226
227
228
229
230
/* B ú squeda de argumentos */
for ( i = 1; i < argc ; i += 2)
{
if ( ! strcmp ( argv [ i ] , A R G U M E N T _ F I L E _ M U S I C A L _ S C O R E ) )
files_names - > musical_score = argv [ i +1];
231
232
233
234
235
236
if ( ! strcmp ( argv [ i ] , A R G U M E N T _ F I L E _ S Y N T H E S I Z E R ) )
files_names - > synthesizer = argv [ i +1];
237
238
239
240
241
242
if ( ! strcmp ( argv [ i ] , ARG UM EN T_ FI LE _W AV E ) )
files_names - > wave = argv [ i +1];
if ( ! strcmp ( argv [ i ] , A R G U M E N T _ S A M P L E _ R A T E ) )
* sample_rate = strtoul ( argv [ i +1] , NULL ,10) ;
243
244
245
246
247
}
/* Si los par á metros obligatorios no fueron ingresados */
if ( files_names - > musical_score == NULL ||
files_names - > synthesizer == NULL ||
files_names - > wave == NULL )
return E RR O R _B A D _A R G UM E N TS ;
248
249
250
251
252
253
/* Si el par á metro opcional no fue ingresado */
if (!(* sample_rate ) )
* sample_rate = D E FA U L T _S A M PL E _ RA T E ;
254
255
256
257
258
259
260
261
262
263
264
265
/* Validaci ó n de m á xima frecuencia de muestreo */
if ( * sample_rate > MAX_SAMPLE_RATE )
return E R R O R _ B A D _ S A M P L E _ R A T E ;
return OK ;
}
/* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / |
2) | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
/* | / / / / / / / / / / / / / / / / / / / / | Impresores de errores y estados | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \\ \ \ | */
266 /* | / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / | \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ | */
267
268
269
270
void progress_msg ( progress_t pg )
{
fprintf ( stderr , " \ n %s ... " , progress_msgs [ pg ]) ;
271 }
272
273
274
275
276
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
void status_msg ( status_t st )
{
277
fprintf ( stderr , " %s \ n " , status_msgs [ st ]) ;
278 }
279
280
281
282
283
284
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
void show_usage ( void )
{
fprintf ( stderr , " \ n %s : %s [ %s < %s >] %s < %s > %s < %s > %s < %s >\ n \ n " ,
54
8.5 langs
usage_msgs [ USAGE_USAGE ] ,
ARGUMENT_SAMPLE_RATE ,
ARGUMENT_FILE_MUSICAL_SCORE ,
ARGUMENT_FILE_SYNTHESIZER ,
ARGUMENT_FILE_WAVE ,
285
286
287
288
289
290
}
8.5.
langs
8.5.1.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
program_name ,
usage_msgs [ USAGE _SAMPL E_RAT E ] ,
usage_msgs [ U S A G E _ F I L E _ M U S I C A L _ S C O R E ] ,
usage_msgs [ U S A G E _ F I L E _ S Y N T H E S I Z E R ] ,
usage_msgs [ USAGE_FILE_WAVE ]) ;
msgs dictionary es.c
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Algoritmos y Programaci ó n I - 75.02/95.11 - Curso Ing . Mart ı́ n Cardozo
TP N o 3 - 1 er Cuatrimestre 2012
Alumnos : ARIAS , Francisco - FERRARI BIHURRIET , Francisco
Archivo : ms gs _di ct io na ry _e s . c
Descrip : Diccionario de mensajes al usuario en idioma castellano .
Obs :
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include < stdio .h >
#include " ../ main_modules / common . h "
/* - - - - - - - - - - - - - - - - - - - - - - - - - Mensajes de estado - - - - - - - - - - - - - - - - - - - - - - - - - */
const string status_msgs []=
{
" Ok . " ,
" Error ! Codigo 1: Argumentos incorrectos . " ,
" Error ! Codigo 2: Frecuencia de muestreo incorrecta . " ,
" Error ! Codigo 3: En el archivo de partitura . " ,
" Error ! Codigo 4: En el archivo de sintetizador . " ,
" Error ! Codigo 5: Se recibio un puntero nulo ! " ,
" Error ! Codigo 6: Informacion invalida ! " ,
" Error ! Codigo 7: Memoria insuficiente ! " ,
" Error ! Codigo 8: Archivo demasiado largo ! " ,
" Error ! Codigo 9: No se pudo abrir el archivo WAV ! Esta en uso ? "
};
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* - - - - - - - - - - - - - - - - - - - - - - - - Mensajes de progreso - - - - - - - - - - - - - - - - - - - - - - - - */
const string progress_msgs []=
{
" Realizando tareas previas " ,
" Sintetizando la musica " ,
" Creando el archivo de salida " ,
" Volcando los datos en el archivo " ,
" Archivo escrito "
};
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - Mensajes de uso - - - - - - - - - - - - - - - - - - - - - - - - - - */
const string usage_msgs []=
{
47
" Uso " ,
48
" frecuencia " ,
49
" partitura . txt " ,
55
8.5 langs
50
51
52
53
" sintetizador . txt " ,
" audio . wav "
};
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
8.5.2.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
msgs dictionary en.c
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Algoritmos y Programaci ó n I - 75.02/95.11 - Curso Ing . Mart ı́ n Cardozo
TP N o 3 - 1 er Cuatrimestre 2012
Alumnos : ARIAS , Francisco - FERRARI BIHURRIET , Francisco
Archivo : ms gs _di ct io na ry _e n . c
Descrip : Diccionario de mensajes al usuario en idioma ingl é s .
Obs :
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include < stdio .h >
#include " ../ main_modules / common . h "
/* - - - - - - - - - - - - - - - - - - - - - - - - - Mensajes de estado - - - - - - - - - - - - - - - - - - - - - - - - - */
const string status_msgs []=
{
" Ok . " ,
" Error ! Code 1: Incorrect arguments . " ,
" Error ! Code 2: Incorrect sample rate . " ,
" Error ! Code 3: In the musical score file . " ,
" Error ! Code 4: In the synthesizer file . " ,
" Error ! Code 5: A null pointer was received ! " ,
" Error ! Code 6: Invalid information ! " ,
" Error ! Code 7: Insufficient memory ! " ,
" Error ! Code 8: Too long file ! " ,
" Error ! Code 9: Could not open the WAV file ! In use ? "
};
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
/* - - - - - - - - - - - - - - - - - - - - - - - - Mensajes de progreso - - - - - - - - - - - - - - - - - - - - - - - - */
const string progress_msgs []=
{
" Performing previous work " ,
" Synthesizing the music " ,
" Creating the output file " ,
" Flushing the data in the file " ,
40
" File written "
41 };
42 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
34
35
36
37
38
39
43
44
/* - - - - - - - - - - - - - - - - - - - - - - - - - - - Mensajes de uso - - - - - - - - - - - - - - - - - - - - - - - - - - */
const string usage_msgs []=
{
" Usage " ,
" sample_rate " ,
" musical_score . txt " ,
" synthesizer . txt " ,
51
" audio . wav "
52 };
53 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
45
46
47
48
49
50
56
8.6 Makefile
8.6.
Makefile
8.6.1.
Makefile
1
2
3
4
5
6
7
# *******************************************************************************
#
#
#
#
#
8 #
9 #
10 #
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
Algoritmos y Programaci ó n I - 75.02/95.11 - Curso Ing . Mart ı́ n Cardozo
TP N o 3 - 1 er Cuatrimestre 2012
Alumnos :
Archivo :
Descrip :
Obs :
ARIAS , Francisco - FERRARI BIHURRIET , Francisco
Makefile
Makefile para la construcci ó n de la aplicaci ó n completa .
Admite la compilaci ó n para distintos idiomas . Los mismos son
configurables en el archivo lang .
# *******************************************************************************
# //////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ #
# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Configuraciones | | | | | | | | | | | | | | | | | | | | | | | | | | | | | #
# \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\////////////////////////////////////// #
# Compilador :
CC = gcc
# Flags para linkeo :
LFLAGS = - ansi - pedantic - Wall
# Flags para compilacion :
CFLAGS = - ansi - pedantic - Wall - O3 -c
# Nombre de salida del proyecto :
OUT = synthesizer
# Directorio de instalacion :
INSTALL_PATH = / usr / bin
# Idioma por defecto :
LANG = en
# Archivo de idioma :
include lang
# //////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ #
# | | | | | | | | | | | | | | | | | | | | | | | | | Objetivos y dependencias | | | | | | | | | | | | | | | | | | | | | | | | | #
37 # \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / / #
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# - - - - - - - - - - - - - - - - - - - - - - - - - - Codigos objeto - - - - - - - - - - - - - - - - - - - - - - - - - - #
OBJETS = ADT _music al_sco re . o \
ADT_synthesizer . o
\
modulationlib . o
\
ADT_wav_file . o
\
addsynthlib . o
\
main . o
\
msgs_dictionary . o
# - - - - - - - - - - - - - - - - - - - - - - Reglas de construccion - - - - - - - - - - - - - - - - - - - - - - #
$ ( OUT ) : $ ( OBJETS )
$ ( CC ) $ ( LFLAGS ) $ ( OBJETS ) -o " $ ( OUT ) " - lm
ADT_ musica l_sco re . o : ADT _music al_sco re / ADT _music al_sco re . c
\
ADT _music al_sco re / A D T _ m u s i c a l _ s c o r e _ P R I V A T E . h \
ADT _music al_sco re / ADT _music al_sco re . h
\
57
8.6 Makefile
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
main_modules / common . h
$ ( CC ) $ ( CFLAGS ) " $ < " -o " $ @ "
ADT_synthesizer . o :
ADT_synthesizer / ADT_synthesizer . c
ADT_synthesizer / A D T _ s y n t h e s i z e r _ P R I V A T E . h
ADT_synthesizer / ADT_synthesizer . h
ADT_synthesizer / modulationlib . h
main_modules / common . h
$ ( CC ) $ ( CFLAGS ) " $ < " -o " $ @ "
\
\
\
\
modulationlib . o :
\
ADT_wav_file . o :
\
\
\
addsynthlib . o :
\
\
\
\
\
main . o :
main_modules / main . c
ADT _music al_sco re / ADT _music al_sco re . h
ADT_synthesizer / ADT_synthesizer . h
ADT_synthesizer / modulationlib . h
ADT_wav_file / ADT_wav_file . h
main_modules / addsynthlib . h
main_modules / common . h
$ ( CC ) $ ( CFLAGS ) " $ < " -o " $ @ "
\
\
\
\
\
\
langs / msgs_ dictio nary_ $ ( LANG ) . c
lang
main_modules / common . h
$ ( CC ) $ ( CFLAGS ) " $ < " -o " $ @ "
\
\
ADT_synthesizer / modulationlib . c
ADT_synthesizer / modulationlib . h
$ ( CC ) $ ( CFLAGS ) " $ < " -o " $ @ "
ADT_wav_file / ADT_wav_file . c
ADT_wav_file / A D T _ w a v _ f i l e _ P R I V A T E . h
ADT_wav_file / ADT_wav_file . h
main_modules / common . h
$ ( CC ) $ ( CFLAGS ) " $ < " -o " $ @ "
main_modules / addsynthlib . c
main_modules / addsynthlib . h
ADT _music al_sco re / ADT _music al_sco re . h
ADT_synthesizer / ADT_synthesizer . h
ADT_synthesizer / modulationlib . h
main_modules / common . h
$ ( CC ) $ ( CFLAGS ) " $ < " -o " $ @ "
msgs_dictionary . o :
# //////////////////////////////////////\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\ #
# | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Utilidades extras | | | | | | | | | | | | | | | | | | | | | | | | | | | | #
# \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\////////////////////////////////////// #
# - - - - - - - - - - - - - - - - - - - - - - Limpiar c ó digos objeto - - - - - - - - - - - - - - - - - - - - - - #
objclean :
rm -f *. o
# - - - - - - - - - - - - - - - - - - - - - - - - - - Limpiar ( todo ) - - - - - - - - - - - - - - - - - - - - - - - - - - #
clean : objclean
rm -f " $ ( OUT ) "
# - - - - - - - - - - - - - Construir y eliminar archivos temporales - - - - - - - - - - - - - #
deltemps : $ ( OUT ) objclean
58
8.6 Makefile
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Instalar - - - - - - - - - - - - - - - - - - - - - - - - - - - - #
install : $ ( OUT )
@ cp " $ ( OUT ) " " $ ( INSTALL_PATH ) "
@ echo " '$ ( OUT ) ' --> Installed in : $ ( INSTALL_PATH ) "
# - - - - - - - - - - - - - - - - - - - - - Todo ( instalar y limpiar ) - - - - - - - - - - - - - - - - - - - - #
all : install clean
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - Desinstalar - - - - - - - - - - - - - - - - - - - - - - - - - - - #
remove :
rm -f " $ ( INSTALL_PATH ) / $ ( OUT ) "
# - - - - - - - - - - - - - - - - - - Purgar ( desinstalar y limpiar ) - - - - - - - - - - - - - - - - - - #
purge : remove clean
8.6.2.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
lang
# *******************************************************************************
#
#
#
#
#
#
#
#
Algoritmos y Programaci ó n I - 75.02/95.11 - Curso Ing . Mart ı́ n Cardozo
TP N o 3 - 1 er Cuatrimestre 2012
Alumnos :
Archivo :
Descrip :
Obs :
ARIAS , Francisco - FERRARI BIHURRIET , Francisco
lang
Selector del idioma a utilizar en la compilaci ó n con ' make ' .
Si se dejan todas las opciones comentadas el programa asumir á el
idioma por defecto .
# *******************************************************************************
# Para idioma castellano , descomente la siguiente linea :
LANG = es
# For english language , uncomment the following line :
# LANG = en
59
Descargar