sábado, 20 de junio de 2009

Sueñan los ordenadores con pianos eléctricos?

Seguimos con "La Semana Monotemática de la Generación de Ruido por Ordenador" xD, y es que me he dado cuenta de que, aunque la mejor forma de utilizar este programa es acompañándolo con música "de verdad", se pueden obtener resultados curiosos uniendo tan solo varias de las melodías monofónicas generadas automáticamente en un archivo polifónico y estéreo que las combine.

El script que ahora os dejo es una variación del que puse ayer, pero incluyéndolo y superándolo. Con el parámetro "m=1", es básicamente el mismo programa, pero con "m>1" genera "m" melodías polifónicas y la combina en un archivo estéreo como el que sigue (hecho con 6 melodías, si no recuerdo mal):



Otra mejora es la cuantización, y la ampliación de la escala a dos octavas, como os comentaba en la entrada anterior. También se han suprimido las tediosas salidas innecesarias que daba antes (interminables vectores que aparecían sin ser para nada necesario para el funcionamiento del script), lo que ha repercutido no sólo en una mejor presencia, sino en un muy significativo aumento de la velocidad. Se han añadido mensajes de errores e información, y ahora aparece un tercer argumento de entrada para controlar la velocidad. Por defecto (en caso de no introducirlo al ejecutar el programa) este tercer argumento vale 60, que es el valor de metrónomo asociado a que una negra dure un segundo (60 golpes por minuto).

Se ha intentado "afinar" mejor las notas. En vez de introducir las frecuencias "a pelo" y sin decimales, se ha utilizado la expresión matemática (y espero que más precisa) siguiente (vista en La Tecla de Escape):


Aquí os dejo el código:


function [Y]=musicgen(n,m,Time)
%
% Script creado por Astaroth (O.R.G.) para generar melodías polifónicas
%a través de números aleatorios (método de MonteCarlo).
%
% Dados "n" (el número de notas que contendrá cada melodía monofónica), y
%"m" (el número de melodías que conformarán la melodía polofónica), este
%script elegirá en cada momento qué nota desea tocar (de la escala a la
%que he confinado este programa), y durante cuánto tiempo la mantendrá,
%estando este restringido a múltiplos enteros de 1/8 del tiempo que dura
%una negra (= 1 segundo, si no se modifica el tercer argumento de entrada,
%por defecto 60).
%
% Si m=1 (melodía monofónica), la salida será un archivo ".wav" mono. En
%caso de ser m>1, entonces la salida será un archivo *.wav estéreo,
%grabándose una vez en cada canal (izquierdo/derecho) cada melodía monofónica
%generada.
%
% Para más información, visitar:
%
% http://astarothsworld.blogspot.com/2009/06/oh-no-pronto-las-maquinas-dominaran-el.html#arriba
%
if nargin<2> disp(' ')
disp('Tienes que introducir como argumentos de entrada, al menos, el número de notas que quieras')
disp('que tenga cada melodía y el número de melodías que quieras que haya. Opcionalmente, puedes')
disp('especificar el valor de la negra dado por el metrónomo (por ejemplo: 60 => 1 negra dura 1 segundo).')
disp(' ')
    else if (nargin==2)|(nargin==3)
        if nargin==2
          disp(' ')
          disp('**********************************************************************************')
          disp('Al no introducir el tercer argumento de entrada suponemos que 1 negra = 1 segundo.')
          disp('**********************************************************************************')
          disp(' ')
          Time=60;

        end
        Pentatonica=[-2,1,3,5,8,10,13,15,17,20,22];
        Y=0;
        k=0;
        for i=1:m
          y=0;
          T0=0;
          o=8000;
          for i=1:n
            nota=Pentatonica(round(rand*10)+1);
            freq=440*(2).^[((nota-10)./12)];
            ale=60/Time*(round(rand*7+1))/8;
            tm=round(o*ale);
            t=linspace(0,1,tm);
            Ond=sin(2*pi*freq*ale*(t+T0));
            T0=tm;
            y=[y,Ond];

          end
          if Y==0
            Y=zeros(2,max(size(y)));

          end
          MY=size(Y);
          MY=MY(2);
          my=size(y);
          my=my(2);
          if MY
            Y(:,MY+1:my)=0;

          else if MY>my
            y(my+1:MY)=0;

          end

        end
        if (-1)^k==1
          fila=1;

        else
          fila=2;

        end
        Y(fila,:)=1/2*(Y(fila,:)+y);
        k=k+1;

      end
      if m==1
        wavwrite(Y(1,:),'AudioTotal.wav');

      else
        wavwrite(Y','AudioTotal.wav');

      end
      disp(' ')
      disp('****************************************')
      disp('Ya tienes tu archivo de audio creado ;)!')
      disp('****************************************')
      disp(' ')

    end

end



Podéis descargároslo de aquí, y ya lo tenéis "todo en uno".


Actualización:

Vamos a jugar un poco con el programilla anterior, y vamos a sustituir la escala pentatónica anterior de 11 tonos por una escala árabe de igual longitud (para que el progrma no se líe, si no habría que cambiar alguna cosilla más), es decir:

Donde pone: [-2,1,3,5,8,10,13,15,17,20,22];
Ponemos: [-2,-1,2,3,5,6,9,10,11,14,15];


Y esto es lo que ha compuesto mi ordenador :p!



Os suena árabe? Un poquillo sí, no? Podéis poner la escala que queráis, y probar ;)!


(Re)Actualización:

Tirando un poco del hilo con lo de las escalas, los que os bajéis el script a partir de ahora encontraréis que he metido unas cuantas escalas (o conjunto de notas permitidas) de muestra, para que podáis elegir en qué escala queréis que el ordenador "componga". El código es muy fácilmente editable, de manera que podéis añadir una línea extra con el conjunto de notas que vosotros mismos elijáis y el ordenador se limitará a esas notas.


% Escalas:
%
% Ahora se pueden modificar las escalas. Simplemente añade la tuya:
%
% Escala=[números asociados a los tonos]
%
% Y comenta las que no utilices poniéndo el sómbolo "%" delante. No
%importa cuántos tonos tenga la escala, el programa se encarga de
%redimensionar los índices que haga falta automáticamente.
%
Escala=[-2,1,3,5,8,10,13,15,17,20,22]; % Pentatonica de Lam
%Escala=[-7,-4,-2,0,3,5,8,10,12,15,17]; % Pentatonica de Mim
%Escala=[-2,-1,2,3,5,6,9,10,11,14,15]; % Árabe
%Escala=[1,4,5,7,8,10,11,13]; % Húngara Mayor
%Escala=[1,3,4,7,8,9,11,13]; % Gitana Húngara
%Escala=[1,2,5,7,9,11,12,13]; % Enigmática
%Escala=[1,2,5,6,8,9,11,13]; % Española
%Escala=[1,3,5,6,8,9,11,13]; % Hindú
%Escala=[1,3,6,8,11,13]; % Egipcia
%Escala=[1,2,6,8,9,13]; % Japonesa
%Escala=[-2,1,5,10,13,17,22]; % Acorde de Lam
%Escala=[1,5,8,13,17,20,25]; % Acorde de DoM



Como véis, todas las líneas menos una están "comentadas" (es decir, tienen el símbolo "%" delante, lo que significa que esas líneas no se ejecutarán). Cuando queráis utilizar una escala, deberéis quitarle el símbolo "%" de delante, y ponérselo a todas las demás. Como digo en el extracto del código que os he pegado arriba, ya no importa (en esta nueva versión del script) qué longitud tenga la escala. Tanto si definís la escala como una sola nota, o un millón de ellas (si tenéis paciencia para escribirlas xD), las reconocerá sin problemas.

Os dejo aquí una muestra sonora generada por el script en la que se ilustra la utilización de varias escalas. Notaréis que, aunque parecidos, cada fragmento tiene matices propios.



CompartirGrupo

2 comentarios:

  1. otra vez problemas en el blog. intenté descargarla y no funciona. lo intentaré mañana :))

    ResponderEliminar
  2. hey Astaroth!
    ya actualicé eh, es que sabes, ando con poco tiempo y cada vez tardo más, pero aquí sigo ;)

    "compuesto por: Astaroth y su ordenador" jaja, muy bueno.
    estaré atenta a todos estos experimentos ;)

    ya veo que proteges tu espada a toda costa, mmmm, buen guerrero! se nota que sé elegir bien a mis aliados.
    (creo que tendré que pasar al plan "b" porque el "a" no me funciona jajaja.)

    ResponderEliminar

Querido astarothista!,

Si te ha gustado la entrada y quieres dejar constancia de ello, tienes alguna sugerencia para completarla o corregirla, quieres mostrar tu opinión respecto a algo de lo que se haya hablado en esta entrada (con respeto) o simplemente quieres dejarme un mensaje a mi o a la comunidad, no dudes en comentar ;)!

Recuerda que también estamos en Facebook y en Google+.