Skip to content

Latest commit

 

History

35 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PAV - P5: síntesis musical polifónica

Obtenga su copia del repositorio de la práctica accediendo a Práctica 5 y pulsando sobre el botón Fork situado en la esquina superior derecha. A continuación, siga las instrucciones de la Práctica 3 para crear una rama con el apellido de los integrantes del grupo de prácticas, dar de alta al resto de integrantes como colaboradores del proyecto y crear la copias locales del repositorio.

Como entrega deberá realizar un pull request con el contenido de su copia del repositorio. Recuerde que los ficheros entregados deberán estar en condiciones de ser ejecutados con sólo ejecutar:

  make release

A modo de memoria de la práctica, complete, en este mismo documento y usando el formato markdown, los ejercicios indicados.

Ejercicios.

Envolvente ADSR.

Tomando como modelo un instrumento sencillo (puede usar el InstrumentDumb), genere cuatro instrumentos que permitan visualizar el funcionamiento de la curva ADSR.

  • Un instrumento con una envolvente ADSR genérica, para el que se aprecie con claridad cada uno de sus parámetros: ataque (A), caída (D), mantenimiento (S) y liberación (R).

Para los siguientes parametros obtenemos, mediante el instrumento SENO que desarrollamos:

A D S R
value 0.1 0.1 0.3 0.1

======= 0.1 0.1 0.3 0.1

  • Un instrumento percusivo, como una guitarra o un piano, en el que el sonido tenga un ataque rápido, no haya mantenimiemto y el sonido se apague lentamente.
    • Para un instrumento de este tipo, tenemos dos situaciones posibles:
      • El intérprete mantiene la nota pulsada hasta su completa extinción.

* El intérprete da por finalizada la nota antes de su completa extinción, iniciándose una disminución rápida del sonido hasta su finalización.

- Debera representar en esta memoria **ambos** posibles finales de la nota. * Un instrumento *plano*, como los de cuerdas frotadas (violines y semejantes) o algunos de viento. En ellos, el ataque es relativamente rápido hasta alcanzar el nivel de mantenimiento (sin sobrecarga), y la liberación también es bastante rápida.

Para los cuatro casos, deberá incluir una gráfica en la que se visualice claramente la curva ADSR. Deberá añadir la información necesaria para su correcta interpretación, aunque esa información puede reducirse a colocar etiquetas y títulos adecuados en la propia gráfica (se valorará positivamente esta alternativa).

Instrumentos Dumb y Seno.

Implemente el instrumento Seno tomando como modelo el InstrumentDumb. La señal deberá formarse mediante búsqueda de los valores en una tabla.

  • Incluya, a continuación, el código del fichero seno.cpp con los métodos de la clase Seno.
#include <iostream>
#include <math.h>
#include "seno.h"
#include "keyvalue.h"
#include <stdlib.h>

using namespace upc;
using namespace std;

Instrumentseno::Instrumentseno(const std::string &param) 
  : adsr(SamplingRate, param) {
  bActive = false;
  x.resize(BSIZE);

  /*
    You can use the class keyvalue to parse "param" and configure your instrument.
    Take a Look at keyvalue.h    
  */
  KeyValue kv(param);
  int N;

  if (!kv.to_int("N",N))
    N = 40; //default value

  //Create a tbl with one period of a sinusoidal wave
  tbl.resize(N);
  float phase = 0, step = 2 * M_PI /(float) N;
  index = 0;

  for (int i=0; i < N ; ++i) {
    tbl[i] = sin(phase);

    phase += step;
  }

}


void Instrumentseno::command(long cmd, long note, long vel) {

f0 = 440*pow(2,(note - 69.)/12);

  if (cmd == 9) {		//'Key' pressed: attack begins
    bActive = true;
    adsr.start();
    index = 0;
	phas = 0;
//	increment = 10*(f0/(SamplingRate/tbl.size()));
//	increment = 2 * M_PI * (f0/SamplingRate);
	increment = ((f0 / SamplingRate) * tbl.size());
//	increment = SamplingRate / (f0) ;
	fprintf(stdout,"increment-->%d\n",increment);
	fprintf(stdout,"tblsize-->%d\n",tbl.size());
	A = vel / 127.;
	phas = 0;
  }
  else if (cmd == 8) {	//'Key' released: sustain ends, release begins
    adsr.stop();
  }
  else if (cmd == 0) {	//Sound extinguished without waiting for release to end
    adsr.end();
  }
}


const vector<float> & Instrumentseno::synthesize() {
  if (not adsr.active()) {
    x.assign(x.size(), 0);
    bActive = false;
    return x;
  }
  else if (not bActive)
    return x;
  for (unsigned int i=0; i<x.size(); ++i) {


//      x[i] = A * sin(phas);
=======
// 	x[i] = A * sin(phas);

	phas = phas + increment;

//	x[i] = A * tbl[round(phas)];


//Amb interpolació
x[i] =tbl[floor(phas)]+(phas-floor(phas))*(tbl[floor(phas+1)]-tbl[floor(phas)])/(floor(phas+1)-floor(phas));


	 while(phas >= tbl.size()) phas = phas - tbl.size();

  }
  adsr(x); //apply envelope to x and update internal status of ADSR

  return x;
}
  • Explique qué método se ha seguido para asignar un valor a la señal a partir de los contenidos en la tabla, e incluya una gráfica en la que se vean claramente (use pelotitas en lugar de líneas) los valores de la tabla y los de la señal generada.

    • -Tal y como indica el enunciado podemos obtener la frecuencia fundamental a partir de la expresión:f0 = 440*pow(2,(note - 69.)/12) Por otro lado, la tabla que generamos a partir del seno de una fase determinada se puede recorrer a diferente velocidad. Esto permite modificar la frecuencia del seno y obtener así la fase deseada en función de la frecuencia fundamental. La expresión que cumple con esta explicación es (f0 / SamplingRate) * tbl.size()

      De aquí obtenemos el resultado gráfico donde observamos el mostreado (con interpolación) y lo obtenido de 
      recorrer la tabla del seno.
      <img src="img/Figure_1.png" width="640" align="center">
    

======= D'aqui obtenim el resultat gràfic on observem el mostrejat (amb interpolació) obtingut de la senyal x sobre el recorregut de la taula tbl

  • Si ha implementado la síntesis por tabla almacenada en fichero externo, incluya a continuación el código del método command(). *Problemas para la lectura del fichero wav.

Efectos sonoros.

  • Incluya dos gráficas en las que se vean, claramente, el efecto del trémolo y el vibrato sobre una señal sinusoidal. Deberá explicar detalladamente cómo se manifiestan los parámetros del efecto (frecuencia e índice de modulación) en la señal generada (se valorará que la explicación esté contenida en las propias gráficas, sin necesidad de literatura).

DO RE sin effects


DO RE con efecto de tremolo


DO RE con efecto de vibrato


*En todos los 3 casos observamos una primera nota sin alteración a causa de los efectos seguida de una segunda nota (RE) que si
se ve afectada por estos. En el primer caso (*TREMOLO*) vemos fàcilmente, de manera independiente al ataque o caída,
una variación considerable de la amplitud de la senyal.

*En el caso del *vibrato* (3a imagen) podemos apreciar igualmente la variación, estiramiento y contracción, de la frecuencia.
A diferencia de la representación sin efectos, esto produce subidas y bajadas de tono alrededor de la nota en cuestión.
  • Si ha generado algún efecto por su cuenta, explique en qué consiste, cómo lo ha implementado y qué resultado ha producido. Incluya, en el directorio work/ejemplos, los ficheros necesarios para apreciar el efecto, e indique, a continuación, la orden necesaria para generar los ficheros de audio usando el programa synth.

Síntesis FM.

Construya un instrumento basado en síntesis FM, siguiendo las explicaciones contenidas en el enunciado y el artículo de John M. Chowning. El instrumento usará como parámetros básicos los números N1 y N2, y el índice de modulación I, que deberá venir expresado en semitonos.

  • Use el instrumento para generar un vibrato de parámetros razonables e incluya una gráfica en la que se vea, claramente, la correspondencia entre los valores N1, N2 e I con la señal obtenida.

  • Use el instrumento para generar un sonido tipo clarinete y otro tipo campana. Tome los parámetros del sonido (N1, N2 e I) y de la envolvente ADSR del citado artículo. Con estos sonidos, genere sendas escalas diatónicas (fichero doremi.sco) y ponga el resultado en los ficheros work/doremi/clarinete.wav y work/doremi/campana.work.

    • También puede colgar en el directorio work/doremi otras escalas usando sonidos interesantes. Por ejemplo, violines, pianos, percusiones, espadas láser de la Guerra de las Galaxias, etc.

Orquestación usando el programa synth.

Use el programa synth para generar canciones a partir de su partitura MIDI. Como mínimo, deberá incluir la orquestación de la canción You've got a friend in me (fichero ToyStory_A_Friend_in_me.sco) del genial Randy Newman.

  • En este (lamentable) arreglo, la pista 1 corresponde al instrumento solista (puede ser un piano, flautas, violines, etc.), y la 2 al bajo (bajo eléctrico, contrabajo, tuba, etc.).
  • Coloque el resultado, junto con los ficheros necesarios para generarlo, en el directorio work/music.
  • Indique, a continuación, la orden necesaria para generar la señal (suponiendo que todos los archivos necesarios están en direcotorio indicado).
synth dumb.orc ../samples/ToyStory_A_Friend_in_me.sco ToyStory_A_Friend_in_me.wav
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~.sh

<p> O como dice el enunciado, señalando el directorio correspondiente en cada fichero de input o output</p>

También puede orquestar otros temas más complejos, como la banda sonora de *Hawaii5-0* o el villacinco de John
Lennon *Happy Xmas (War Is Over)* (fichero `The_Christmas_Song_Lennon.sco`), o cualquier otra canción de su agrado
o composición. Se valorará la riqueza instrumental, su modelado y el resultado final.
- Coloque los ficheros generados, junto a sus ficheros `score`, `instruments` y `efffects`, en el directorio
  `work/music`.
- Indique, a continuación, la orden necesaria para generar cada una de las señales usando los distintos ficheros.

About

PAV - P5: síntesis musical polifónica

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages