jueves, septiembre 10, 2009

Como hacer musica en GNU Octave o Música en GNU Octave o bien migrando "Musica en Matlab" a Octave

En la una de las entradas anteriores se describe un programa para hacer música en Matlab, programa que fue probado en Windows.
La idea es si existe un computador con alguna distribución de GNU/Linux, y en vez de Matlab ocupamos el siempre útil y nunca bien ponderado GNU Octave para ejecutar este programa.
Muchos comandos de Matlab se ejecutan de igual manera en GNU Octave.
Excepto por algunos comandos importantes :

menu('title','opc 1','opc 2')

Este comando no está en GNU Octave, por lo menos en la instalación del paquete Octave-forge, así que el menú con botones de Matlab, pasa a ser un sencillo menú por consola.
Otro comando que existe para Matlab y funciona en Octave es :

sound(y,fm)

las primeras veces que ejecuté el programa arrojaba un error así:

octave:2 Fs=44100;
octave:3 t=0:1/Fs:1;
octave:4  y=sin(2*pi*440*t);
octave:5  sound(y,Fs)
sh: ofsndplay: command not found
warning: warn_fortran_indexing is no longer a built-in variable; please read the NEWS file or type `news' for details
warning: warn_fortran_indexing is no longer a built-in variable; please read the NEWS file or type `news' for details
warning: broken pipe -- some output may be lost

La solución es simplemente un
clear all
antes de ejecutar el comando. Existe un error al hacer esto cuando un instala el Octave-forge, pero la solución es borrar unos paquetes que por lo menos en este caso no son prioridad, en detalle está acá.

El funcionamiento muestra el detalle de lo reproducido:


octave:7 clear all
octave:8  Fs=44100;
octave:9  t=0:1/Fs:1;
octave:10  y=sin(2*pi*440*t);
octave:11  sound(y,Fs)
warning: warn_fortran_indexing is no longer a built-in variable; please read the NEWS file or type `news' for details
warning: warn_fortran_indexing is no longer a built-in variable; please read the NEWS file or type `news' for details
play au: header size 24 is too small

-: (au)

Encoding: Signed PCM
Channels: 1 @ 16-bit
Samplerate: 44100Hz
Replaygain: off
Duration: unknown

In:0.00% 00:00:01.00 [00:00:00.00] Out:44.1k [      |      ] Hd:0.0 Clip:0
Done.



Al intentar correr el programa en Fedora 12 obtenía el siguiente error:

octave:1> Fs=44100;t=0:1/Fs:1;y=sin(2*pi*440*t);sound(y)
error: sound.m: No command line utility found for sound playing
error: called from:
error:   /usr/share/octave/packages/audio-1.1.4/sound.m at line 108, column 5


La solución para esto, que dan en los foros de ubuntu es en resumen la siguiente:

Tener instalado alsa-utils o pulseaudio-utils.
Luego dice poner en ~/.octaverc
global sound_play_utility = 'aplay';

o bien
global sound_play_utility = 'paplay';


o bien ponerlo directamente en Octave.

Vemos que funciona:

octave:2>  Fs=44100;t=0:1/Fs:1;y=sin(2*pi*440*t);sound(y,Fs)
Playing Sparc Audio 'stdin' : Signed 16 bit Big Endian, Rate 44100 Hz,Mono


Otro comando que se ejecuta de manera parecida en Octave es:


wavwrite( 'nombre',y, Fs, nbits)

la diferencia es importante es que la señal guardada en un vector y, debe ser ingresada necesariamente como un vector columna. En este caso y es un vector fila, cual debe ser ingresado traspuesto:


octave:13> wavwrite( 'Roco_audio.wav',y', Fs, 16)

Con esas consideraciones, el programa esta listo para ejecutarse.
Básicamente, los cambios que hay que hacerle al código Matlab para ejecutarse en Octave son relativamente menores.
El programa fue probado en GNU Octave, version 3.0.3 sobre Mandriva Linux Free 2009 Spring.
También fue probado en

El programa

El menú del programa se ve así, obviamente las tildes son omitidas para evitar errores de codificación de caracteres :
   MENU     
-----------------------
Seleccione Opcion

1) Ingresar notas 1ra voz
2) Ingresar notas 2da voz
3) Ingresar notas 3ra voz
4) Ingresar Percusion
5) Sonido
6) Guardar Cancion
7) Duracion de la negra [s]
8) Salir
-----------------------


La idea es la misma que en acá, salvo que en Octave.
Acá el programa y las funciones

y un ejemplo que no incluye el uso de la percusión :

Lambada GNU Octave

La Badinerie de J.S. Bach BWV 1067


Chao

Francisco Roco