Bennu Game Development

Foros en Español => Proyectos => Topic started by: Drumpi on February 12, 2010, 06:17:19 PM

Title: PiEfSi de speech recognition
Post by: Drumpi on February 12, 2010, 06:17:19 PM
O lo que es lo mismo, unas gotas de lo que es mi proyecto de fin de carrera sobre reconocimiento de palabras.

De momento, hago este hilo porque veo que el mejor método que tengo ahora para estudiar las propiedades del sonido es la de usar bennu para abrir un WAV y ver la forma de onda y su FFT, por lo que es probable que consiga un prg para hacer dicha transformada básica en el tema de sonido (y parece ser que imagen).
Como es algo estandar, no creo que influya en temas de derechos y demás.

La idea es poder VER cómo varían las frecuencias de una voz a otra, a distintos tonos e incluso diciendo palabras simples, y a lo mejor necesito que me echeis una mano.
De momento dejo el hilo abierto, hoy he empezado a ver mi voz con otro programa, pero espero poder hacer lo propio con un código bennu, y visto lo visto apenas usa unas pocas frecuencias.

En el momento que vea que la cosa funciona en Bennu, pasaré a trasladarlo a la beagle y aqui ya no tendré más que mostrar, hasta que termine y me ponga a hacer el módulo.

Ya iré comentando cosas e iré pidiendo ayuda ;). Splinter, espero que hayas hecho tus deberes con los float :D :D :D :D :D
Title: Re: PiEfSi de speech recognition
Post by: Windgate on February 12, 2010, 08:30:57 PM
¿Ya hay alguna forma de conocer la forma de onda de un .wav con Bennu?
Title: Re: PiEfSi de speech recognition
Post by: SplinterGU on February 12, 2010, 10:27:30 PM
no realmente desde bennu, pero creo que la idea no es analizar un wav, sino capturar uno...

con respecto a analizar la onda de un sonido se podria indagar en los filtros de SDL_mixer... que sirven en base a un wav cargado en memoria hacerle post-processing...
Title: Re: PiEfSi de speech recognition
Post by: Rein (K´)ah Al-Ghul on February 12, 2010, 10:50:03 PM
Para visualizar la voz, planeas usar algo similar a un ecualizador y/o un espectrografo??
si recuerdo bien, la voz humana va desde 80 Hz hasta los 1100 Hz...
supongo que las demas frecuencias se dan por descartadas :P
Title: Re: PiEfSi de speech recognition
Post by: Drumpi on February 13, 2010, 01:45:46 AM
La idea es coger un archivo en formato wav, que va sin compresión, y leer todos los datos para obtener una forma de onda, es decir, la amplitud de la señal en cada momento discreto del tiempo, y con eso crear una imagen, pixel por pixel, de la señal.
Después mostrar esa información por la pantalla y crear un algoritmo de FFT para obtener la descomposición en frecuencias en cada posición del tiempo, y verlo.

Obviamente, fread y put_pixel serán mis herramientas básicas ;D

De esta forma, conseguir ver en qué frecuencias se descompone la voz y cómo varía. Ver qué frecuencias son las de cada persona, cuales representan el tono y así descartarlas para obtener la de la letra o sílaba, si es posible.
La idea es obtener las frecuencias que representan los fonemas, descartando tono y características propias de las personas, si es posible (algo tiene que haber o las personas no seríamos capaces de entendernos unas con otras).

Quizás con eso pueda elaborar un diccionario reducido para el proyecto y no tenga que recurrir a otras bases de datos.
De frecuencias no descarto nada, pues quiero intentar un estudio desde lo más básico. He leido bastante del tema y todo se centra en un diccionario con distintas voces (creo, porque no recuerdo la cifra exacta, que un diccionario completo consta de más de 104000 minutos de audio) y quien sabe, a lo mejor encuentro un método sencillo ^^U
Title: Re: PiEfSi de speech recognition
Post by: grisendo on February 13, 2010, 01:06:48 PM
Mola tío :D

Yo no sé mucho de sonido, soy más bien de imágenes pero hay muchas cosas en común
en las cuales igual te puedo dar algún tipo de ayuda... Aunque me imagino que te habrás
mirado mil cosas y sabrás de todo más que yo jeje.

Así a ojo, y utilizado terminología poco seria, creo que el timbre viene dado por los "adornos"
de la onda (si es más triangulada, cuadrada o sinusoidal), la amplitud de onda el volumen y
el tono viene dado por la frecuencia de la onda...

Pero vamos, posiblemente necesites utilizar entrenadores/clasificadores como redes neuronales,
máquinas vector soporte, etc... de eso sé algo más.

Si puedes poner por aquí alguna bibliografía básica sobre el tema estaría muy bien :)
Y si cuando termines el PFC me pasas la memoria para que aprenda sobre el tema, ya ni te cuento :P
Title: Re: PiEfSi de speech recognition
Post by: l1nk3rn3l on February 13, 2010, 05:27:19 PM
http://www.codeproject.com/KB/audio-video/tambiSR.aspx

http://sourceforge.net/projects/tpapro/

;D


Title: Re: PiEfSi de speech recognition
Post by: l1nk3rn3l on February 13, 2010, 05:28:06 PM
http://www.google.com/Top/Computers/Speech_Technology/

AUNQUE pensandolo bien lo que propones para bennu es
muy bueno , ya tenemos deteccion de movimientos con camara
ahora solo falta ordenes de voz en ingles o castellano,
para mover unidades ...

o hacer alguna otra cosa posible con la voz como insultar al oponente..   ;D
Title: Re: PiEfSi de speech recognition
Post by: grisendo on February 13, 2010, 06:01:33 PM
Quizá esto te sirva... o no  ::)

He hecho este PRG donde la función loadRawWav(fichero) lee un archivo .WAV sin compresión (PCM, de 8 o 16 bits, mono o estéreo) y lo almacena en los vectores globales raw_left y raw_right, cuyo tamaño final se almacena en la global raw_max_length. Si es mono, ambos vectores tienen los mismos valores.

pintaOnda() te muestra la onda en pantalla de cada canal (una parte de ella, para moverse hay que usar las teclas IZQUIERDA y DERECHA)
el canal izquierdo es el de arriba y el canal derecho es el de abajo.

Solo he comprobado que funciona con el "chord.wav" de windows xp (c:\windows\media\chord.wav) y comparando con un editor de audio
parece que las ondas coinciden... No me he molestado en comparar más archivos :)

A partir de esos vectores con los valores de la onda, puedes calcular la DFT, FFT, DCT...

Aunque para hacer todo esto... es más fácil con Matlab! Sobretodo porque o usas todo sonidos sin compresión o tienes que implementar
la codificación para cada tipo de archivo de audio que vayas a utilizar... Y porque tiene miles de funciones (FFT y tal) ya implementadas!!

Pero bueno, ahí te lo dejo ;)

[code language="bennu"]PROGRAM test;

CONST
    WIDTH = 800;
    HEIGHT = 600;

    Y_LEFT_CENTER = 200;
    Y_RIGHT_CENTER = 400;
    MAX_HEIGHT = 100;
    X_STEP = 20;

END

GLOBAL
    int *raw_left;
    int *raw_right;
    unsigned int raw_max_length;

    unsigned int fileSize;
    unsigned int channels;
    unsigned int sampleRate;
    unsigned int bitsPerSample;
    unsigned int dataSize;

    int cargado;

    unsigned int max_value;
END

BEGIN
    set_fps(25, 0);
    set_mode(WIDTH, HEIGHT, 32, MODE_WINDOW);
    cargado = 0;
    loadRawWav("chord.wav");
    pintaOnda();
    LOOP
        FRAME;
    END
END

PROCESS pintaOnda()
PRIVATE
    int x_i, x_e;
    int x_len;
    int i;
    int fondo;
BEGIN
    x_len = WIDTH;
    x_i = 0;
    drawing_color(rgb(255, 0, 0));
    fondo = map_new(HEIGHT, WIDTH, 32);
    LOOP
        x_e = x_i + x_len;
        FOR(i=x_i; i<x_e; i++)
            IF((i>=0)AND(i<raw_max_length))
                map_put_pixel(0, fondo, (i-x_i), Y_LEFT_CENTER+raw_left*MAX_HEIGHT/max_value, rgb(255, 0, 0));
                map_put_pixel(0, fondo, (i-x_i), Y_LEFT_CENTER, rgb(0, 255, 0));
                map_put_pixel(0, fondo, (i-x_i), Y_RIGHT_CENTER+raw_right*MAX_HEIGHT/max_value, rgb(255, 0, 0));
                map_put_pixel(0, fondo, (i-x_i), Y_RIGHT_CENTER, rgb(0, 255, 0));
            END
        END
        IF(key(_right))
            map_clear(0, fondo, rgb(0,0,0));
            x_i += X_STEP;
        END
        IF(key(_left))
            map_clear(0, fondo, rgb(0,0,0));
            x_i -= X_STEP;
        END
        IF(key(_esc))
            BREAK;
        END
        put_screen(0, fondo);
        FRAME;
    END
ONEXIT
    let_me_alone();
END

FUNCTION loadRawWav(string fichero)
PRIVATE
    int i;
    int handle;

    int value;

    unsigned byte oneByte;
    unsigned short twoBytes;
    unsigned int fourBytes;

    signed short twoBytesSigned;

    int channel;
BEGIN

    // Formato WAV PCM explicado en https://ccrma.stanford.edu/courses/422/projects/WaveFormat/

    handle = fopen(fichero, O_READ);

    fread(handle, fourBytes); // Leo ChunkID: "RIFF"
    fread(handle, fourBytes); // Leo ChunkSize: Tamanyo del fichero - 8
    fileSize = fourBytes + 8;

    fread(handle, fourBytes); // Leo Format: "WAVE"
    fread(handle, fourBytes); // Leo Subchunk1ID: "fmt "
    fread(handle, fourBytes); // Leo Subchunk1Size: 16
    fread(handle, twoBytes); // Leo AudioFormat: 1
    fread(handle, twoBytes); // Leo NumChannels: 2
    channels = twoBytes;

    fread(handle, fourBytes); // Leo SampleRate
    sampleRate = fourBytes;

    fread(handle, fourBytes); // Leo ByteRate
    fread(handle, twoBytes); // Leo BlockAlign
    fread(handle, twoBytes); // Leo BitsPerSample
    bitsPerSample = twoBytes;

    fread(handle, fourBytes); // Leo Subchunk2ID: "data"
    fread(handle, fourBytes); // Leo Subchunk2Size: Tamanyo de los datos
    dataSize = fourBytes / channels;

    IF(bitsPerSample==8)
        max_value = 255;
    ELSE
        max_value = 32767;
    END

    channel = 0;
    raw_max_length = 0;

    raw_left = mem_alloc(dataSize*sizeof(int));
    raw_right = mem_alloc(dataSize*sizeof(int));

    FOR(i=0; i<dataSize; i++)
        IF(!feof(handle))
            IF(bitsPerSample == 8)
                fread(handle, oneByte);
                value = oneByte;
            ELSIF(bitsPerSample == 16)
                fread(handle, twoBytesSigned);
                value = twoBytesSigned;
            END
            IF(channels == 1)
                raw_left[raw_max_length] = value;
                raw_right[raw_max_length] = value;
                raw_max_length++;
            ELSE
                IF(channel == 0)
                    raw_left[raw_max_length] = value;
                    channel = 1;
                ELSE
                    raw_right[raw_max_length] = value;
                    raw_max_length++;
                    channel = 0;
                END
            END
        ELSE
            RETURN(0);
        END
    END
    fclose(handle);
    RETURN(1);
END[/code]
Title: Re: PiEfSi de speech recognition
Post by: Drumpi on February 14, 2010, 12:11:00 AM
Juer, que no me deja responder:

Muchas gracias por los enlaces, L1nk3rn3l, les echaré un vistacillo, pero no creo que me valgan, pues son programas enfocados al inglés, y su fonética no tiene nada que ver con la que quiero desarrollar, en español. Además, usan el API de Windows, lo que me deja el código cerrado, que es lo que quiero ver.
Title: Re: PiEfSi de speech recognition
Post by: Drumpi on February 14, 2010, 12:12:41 AM
Y a ti también, Grisendo. Me he estado leyendo el PFC que nos pasastes y es muy completo, además, se entiende de miedo y me está ayudando mucho a buscar cosas. Pena que la base de datos, Aurora2, es en inglés, me habría ahorrado mucho trabajo (y diversión ;D). He estado buscando otras bases de datos en español, pero sólo encuentro sudamericanas, y además con muy pocas palabras.
Title: Re: PiEfSi de speech recognition
Post by: Drumpi on February 14, 2010, 12:13:00 AM
Quiero intentar evitar la fase de "entrenamiento", más que nada porque dudo que me de tiempo a aprender redes neuronales, teniendo que re-aprender C, y a manejar la beagleboard. Yo soy un teleco, no informático: mi carrera consiste en tomar una señal y procesarla, no que el ordenador haga virguerías ^^U
Como mucho, que la fase de entrenamiento se dedique a extraer las características sonoras de la persona para eliminarlas de la señal.
Title: Re: PiEfSi de speech recognition
Post by: Drumpi on February 14, 2010, 12:13:17 AM
Y gracias por el código, pero precisamente hoy ya he estado trabajando en ello. Precisamente venía a pedir ayuda porque tenía problemas con las signed short, ya que estoy acostumbrado a usar sólo byte, word e int, pero ya he mirado tu código y ya dispongo de lectura para SIGNED WORD.
Ya he conseguido dibujar mi primera onda: ahora debo ajustarla a la pantalla (no me ha dejado crear un mapa de 29321x65536) y empezar a transformarla en frecuencias (posiblemente la deje "bonita" metiéndole el fichero a examinar por parámetros y permitiendo cargar más de una señal, porque luego tendré que comparar).

Aun no se si dividir la señal en tramas, como en el proyecto, o hacer la conversión de forma contínua (o semi-continua, si añado sólo medio buffer de datos nuevos puedo ahorrar la mitad de cálculos).
Title: Re: PiEfSi de speech recognition
Post by: Drumpi on February 14, 2010, 12:14:01 AM
Y perdón por tantos mensajes, pero llevo cuatro horas intentando responder y no me dejaba escribir un mensaje más largo :S
Title: Re: PiEfSi de speech recognition
Post by: grisendo on February 14, 2010, 12:58:47 AM
Justamente iba a postear ahora una segunda versión más maja que la anterior :P
con líneas en vez de puntos y la posibilidad de hacer zoom y moverse con las flechas...
gracias a la cual he descubierto que o no sé hacer funcionar drawing_stipple()
o funciona mal (lo he intentado usar para pintar el eje con línea discontinua pero
no pinta nada el jodío).

Alguien sabe si hay alguna forma de emitir "pitiditos" de una determinada
amplitud? Para reproducir un sonido muestra a muestra a partir de un vector
(sí, a veces se me va la pinza y me gusta trabajar a bajísimo nivel :P)

Pongo aquí el código de dibujar, por si acaso le sirve a alguien:

[code language="bennu"]PROGRAM test2;

CONST
    WIDTH = 1280;
    HEIGHT = 1024;

    Y_LEFT_CENTER = 200;
    Y_RIGHT_CENTER = 800;
    MAX_HEIGHT = 300;
    X_STEP = 20;

END

GLOBAL
    int *raw_left;
    int *raw_right;
    unsigned int raw_max_length;

    unsigned int fileSize;
    unsigned int channels;
    unsigned int sampleRate;
    unsigned int bitsPerSample;
    unsigned int dataSize;

    int cargado;

    unsigned int max_value;
END

BEGIN
    set_fps(25, 0);
    set_mode(WIDTH, HEIGHT, 32, MODE_WINDOW);
    cargado = 0;
    loadRawWav("chord.wav");
    pintaOnda();
    LOOP
        FRAME;
    END
END

PROCESS pintaOnda()
PRIVATE
    int x_i, x_e;
    int x_len;
    int i, j;
    int fondo;
    int color, negro, linea;
    int zoom;
    int valleft[WIDTH];
    int valright[WIDTH];
    int minj, maxj;
BEGIN
    zoom = 1;
    x_i = 0;
    color = rgb(255, 0, 0);
    negro = rgb(0, 0, 0);
    linea = rgb(255, 255, 255);
    fondo = map_new(WIDTH, HEIGHT, 32);
    drawing_map(0, fondo);
    LOOP
        drawing_color(negro);
        draw_box(0, 0, WIDTH-1, HEIGHT-1);
        x_len = WIDTH*zoom;
        x_e = x_i + x_len;
        minj = WIDTH;
        maxj = 0;
        FOR(i=x_i, j=0; i<x_e; i+=zoom, j++)
            IF((i>=0)AND(i<raw_max_length))
                IF(j<minj)
                    minj=j;
                END
                valleft[j]=Y_LEFT_CENTER-raw_left*MAX_HEIGHT/max_value;
                valright[j]=Y_RIGHT_CENTER-raw_right*MAX_HEIGHT/max_value;
                maxj=j;
            END
        END
        drawing_color(color);
        FOR(j=minj; j<maxj-1; j++)
            draw_line(j, valleft[j], j+1, valleft[j+1]);
            draw_line(j, valright[j], j+1, valright[j+1]);
        END
        drawing_color(linea);
        IF(minj<=maxj)
            draw_line(minj, Y_LEFT_CENTER, maxj, Y_LEFT_CENTER);
            draw_line(minj, Y_RIGHT_CENTER, maxj, Y_RIGHT_CENTER);
        END
        IF(key(_right))
            IF(x_e<raw_max_length+X_STEP*ZOOM)
                x_i += X_STEP*zoom;
            END
        ELSIF(key(_left))
            IF(x_i>-X_STEP*ZOOM)
                x_i -= X_STEP*zoom;
            END
        ELSIF(key(_down))
            IF(zoom<25)
                zoom++;
            END
        ELSIF(key(_up))
            IF(zoom>1)
                zoom--;
            END
        ELSIF(key(_esc))
            BREAK;
        END
        put_screen(0, fondo);
        FRAME;
    END
ONEXIT
    let_me_alone();
END

FUNCTION loadRawWav(string fichero)
PRIVATE
    int i;
    int handle;

    int value;

    unsigned byte oneByte;
    unsigned short twoBytes;
    unsigned int fourBytes;

    signed short twoBytesSigned;

    int channel;
BEGIN

    // Formato WAV PCM explicado en https://ccrma.stanford.edu/courses/422/projects/WaveFormat/

    handle = fopen(fichero, O_READ);

    fread(handle, fourBytes); // Leo ChunkID: "RIFF"
    fread(handle, fourBytes); // Leo ChunkSize: Tamanyo del fichero - 8
    fileSize = fourBytes + 8;

    fread(handle, fourBytes); // Leo Format: "WAVE"
    fread(handle, fourBytes); // Leo Subchunk1ID: "fmt "
    fread(handle, fourBytes); // Leo Subchunk1Size: 16
    fread(handle, twoBytes); // Leo AudioFormat: 1
    fread(handle, twoBytes); // Leo NumChannels: 2
    channels = twoBytes;

    fread(handle, fourBytes); // Leo SampleRate
    sampleRate = fourBytes;

    fread(handle, fourBytes); // Leo ByteRate
    fread(handle, twoBytes); // Leo BlockAlign
    fread(handle, twoBytes); // Leo BitsPerSample
    bitsPerSample = twoBytes;

    fread(handle, fourBytes); // Leo Subchunk2ID: "data"
    fread(handle, fourBytes); // Leo Subchunk2Size: Tamanyo de los datos
    dataSize = fourBytes / channels;

    IF(bitsPerSample==8)
        max_value = 255;
    ELSE
        max_value = 32767;
    END

    channel = 0;
    raw_max_length = 0;

    raw_left = mem_alloc(dataSize*sizeof(int));
    raw_right = mem_alloc(dataSize*sizeof(int));

    FOR(i=0; i<dataSize; i++)
        IF(!feof(handle))
            IF(bitsPerSample == 8)
                fread(handle, oneByte);
                value = oneByte;
            ELSIF(bitsPerSample == 16)
                fread(handle, twoBytesSigned);
                value = twoBytesSigned;
            END
            IF(channels == 1)
                raw_left[raw_max_length] = value;
                raw_right[raw_max_length] = value;
                raw_max_length++;
            ELSE
                IF(channel == 0)
                    raw_left[raw_max_length] = value;
                    channel = 1;
                ELSE
                    raw_right[raw_max_length] = value;
                    raw_max_length++;
                    channel = 0;
                END
            END
        ELSE
            RETURN(0);
        END
    END
    fclose(handle);
    RETURN(1);
END[/code]
Title: Re: PiEfSi de speech recognition
Post by: Rein (K´)ah Al-Ghul on February 14, 2010, 01:04:33 AM
(http://upload.wikimedia.org/wikipedia/commons/f/f1/Voice_waveform_and_spectrum.png)

drumpi, es algo asi lo que busncas verdad??
la vista de la derecha deberia ser en 3D, siendo la profundidad cada instante de tiempo...
Title: Re: PiEfSi de speech recognition
Post by: Drumpi on February 14, 2010, 02:34:17 PM
Grisendo: gracias, pero prefiero hacérmelo yo mismo, si me lo haces tu ¿qué hago yo? ;D
No, es broma, le echaré un vistazo, a ver si surgen ideas, pero de momento ya tengo una idea bastante clara de lo que quiero hacer.

Rein (K')ah Al-Ghul: (te voy a tener que buscar un mote, porque vaya apodo) Sí, más o menos es eso lo que ando buscando hacer, y que la segunda imagen varíe dinámicamente para ver los cambios, y luego poder hacer gráficas de las frecuencias que yo quiera en el tiempo. Veo que está hecho en Matlab, quizás debería plantearme seriamente usarlo, pero no se cómo pasar la señal del micro al programa, o cómo cargar los datos de un wav en un vector.
Title: Re: PiEfSi de speech recognition
Post by: Drumpi on February 14, 2010, 02:37:10 PM
Aun así, ese espectro de la señal es bastante complejo, demasiado para lo que debo determinar, porque fijaos en la siguiente onda:

(http://forum.bennugd.org/index.php?action=dlattach;topic=1178.0;attach=856)

Ese soy yo diciendo "oooooo" (de "hola"). No creo que eso se descomponga en más de 20 senos sumados, y eso es lo que voy buscando, la frecuencia de esos senos para hacer el estudio.
Title: Re: PiEfSi de speech recognition
Post by: grisendo on February 15, 2010, 12:16:42 PM
Lo siento! Entendí que no sabías por donde cogerlo y me pasé de ayudarte :P

Esa es toda la onda que se produce al decir la letra "O"?
Me imagino que no, porque veo la barra horizontal de la aplicación movida... Pero si fuese esa, veo que se repite por todas partes!!!
A ver si puedes adjuntar el WAV :)

Yo con lo que sé de imágenes, lo que intentaría sería primero eliminar el ruido, luego normalizar los valores de amplitud de todas las ondas con las que trabajes (comprimirlas o estirarlas a lo alto para que todos sus valores estén entre -1 y 1, o los que quieras) para hacerla invariante ante volumen, igualar el tono de todas ellas (comprimirlas o estirarlas a lo largo para que la longitud de onda sea la misma en todas) y... si no quieres utilizar clasificadores y cosas así, ahí me quedo xDD. Aunque he de decirte que existen programas como Weka que llevan hechos miles de clasificadores y te evitan programarlos por ti mismo: http://www.cs.waikato.ac.nz/ml/weka/ (http://www.cs.waikato.ac.nz/ml/weka/)

Por cierto, he visto tu post de "dirty rects", veo que utilizas puntos... si vas a ver las ondas así siempre, vale, pero si quieres meterle "zoom", con los puntos cuando lo alejes no verás más que  nubes de puntos sin sentido, es mejor utilizar rectas como en mi segundo ejemplo ;)
Title: Re: PiEfSi de speech recognition
Post by: Drumpi on February 15, 2010, 06:07:48 PM
Bueno, no es exactamente "ooooo", es parte de "hoooooooollllllaaaaaaaa..." ;D De todas formas te lo adjunto para que lo mires. Mientras se mantiene el tono y la amplitud, la señal es periódica perfecta y muy simple.
El problema viene a que la voz no es perfecta, nadie es capaz de mantener los músculos de la garganta inmóviles (aunque sea por el pulso) y la señal sufre de imperfecciones. Puedo tratarlo como "ruido" y filtrarlo, pero ya es mucho trabajo, confío en que eso sólo leve a pequeñísimas variaciones de frecuencia y amplitud.

Lo cierto es que me da igual la amplitud y los cambios de frecuencia, quiero hacer un análisis visual para ver los cámbios de frecuencias con los tonos.

Lo de los puntos, bueno, es sólo para ver lo que puedo hacer y no, ya lo "dejaré bonito" más tarde ;D

(Se va la luz)

Voy a hacer la FFT típica a ver qué sale con una señal "perfecta" (el sonido de una flauta que usé para el FrikiMusic, obtenida con un tracker), si no, empezaré a hacer números hasta que salga lo estudiado en clase (deltas aisladas).
Title: Re: PiEfSi de speech recognition
Post by: Drumpi on February 17, 2010, 08:01:38 PM
Bien, empiezan los problemas... pero por desgracia son del código, no de lo principal.
Estoy aun liado con el IDE, con la carga de ficheros, y como soy tan así, he creado una lista enlazada para guardar los datos, en lugar de un vector definido (según mi cabeza, controlar cuales casillas están libres y cuales no es mucho más complicado que la susodicha lista).

Bien, pues os comento. Bennu me da un error rarísimo:
bgdi seasee.dcb
Assertion failed: code < string_allocated && code >= 0, file strings.c, line 264

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

Como es lógico, me fallan los punteros.

He aislado el fallo hasta la función NUEVO_WAV del fichero MANAGE_FILE.INC (el código completo os lo pongo después para descargar)

[code language="bennu"]function nuevo_wav (string nw_dir)
private
    fichero_abierto pointer nw_ptr;
begin
    say("Abriendo wav");
    if (file_exists(nw_dir))
        nw_ptr=anadir_wav_lista();
        say("añadir wav lista: sucessful");
        say("dato: "+itoa(nw_ptr.id_wav));
       
        cargar_wav(nw_dir,nw_ptr.id_wav);
        say("cargar wav: sucessful");
        graph=new_map(1000,400,16);
        set_center(file,graph,0,0);
        draw_wav(nw_ptr.id_wav,file,graph,0,500);
        say("crear gráfica: sucessful");
        nw_ptr.id_onda=add_grafica(file,graph,0,0,0);
        graph=0;
        say("añadir gráfica a la lista: sucessful");
    end
end[/code]

El problema me lo da al usar la función CARGAR_WAV (RW_FILE.INC), función que iba perfectamente cuando le pasaba una variable directamente (id_wav es de un tipo definido por mi, y se ha añadido en una variable de otro tipo, FICHERO_ABIERTO, como el puntero auxiliar).

[code language="bennu"]type fichero_abierto
    info_wav id_wav;
   
    int id_onda;
    int onda_ini;
    int onda_max_amplitud;
   
    int id_espectro;
    int espectro_ini;
    int espectro_max;
   
    fichero_abierto pointer ptr_sig;
end[/code]

anadir_wav_lista (manage_file.inc) devuelve un puntero:

[code language="bennu"]function anadir_wav_lista ()
private
    fichero_abierto pointer awl_ptr;
begin
    (...)
    return (awl_ptr);
end[/code]

Por todo esto, sé que debería funcionar, pero no se que falla: he probado poniendo:

cargar_wav(nw_dir,&nw_ptr.id_wav);
cargar_wav(nw_dir,&(nw_ptr.id_wav));
cargar_wav(nw_dir,*nw_ptr.id_wav);

Pero nada (en el tercer caso hasta me da error de que se esperaba un puntero).

Si quereis ver el código completo, está AQUI (http://drumpi.se32.com/cosas/test.rar), incluyendo hasta los archivos de sonido. Espero que me podais echar una mano, porque ya estoy de punteros hasta el gorro ^^U

Gracias.
Title: Re: PiEfSi de speech recognition
Post by: SplinterGU on February 17, 2010, 09:10:37 PM
estas concatenando datos a una string no inicializada...

    //***********************************
    for (cont=0;cont<4;cont++)
        fread(wav_file,datob);
        cw_wav.riff+=chr(datob);
    end
    say("Cabecera RIFF: "+cw_wav.riff);

debe ser

    cw_wav.riff = "";

    //***********************************
    for (cont=0;cont<4;cont++)
        fread(wav_file,datob);
        cw_wav.riff+=chr(datob);
    end
    say("Cabecera RIFF: "+cw_wav.riff);
Title: Re: PiEfSi de speech recognition
Post by: Drumpi on February 18, 2010, 01:18:54 PM
Juer, pues sí, era eso, vaya tontería ¿no? eso pasa por acostumbrarnos a no inicializar las variables.
Lo que no entiendo es por qué antes funcionaba ¿tiene algo que ver que ahora los datos se obtengan mediante reserva de memoria en tiempo de ejecución?

Muchas gracias, Splinter, con el dolor de cabeza que me ha supuesto, te mereces un Karma.
Title: Re: PiEfSi de speech recognition
Post by: SplinterGU on February 18, 2010, 04:38:18 PM
Ahhh... ya veo, no es un dato creado por Bennu, sino que lo creas vos allocando memoria... claro, si alocas memoria para crear una estructura y dentro de esa estructura hay miembros strings, debes inicializar todas las strings.
Title: Re: PiEfSi de speech recognition
Post by: Windgate on February 18, 2010, 08:12:04 PM
A mí me gustaría poder usar en un juego controles por voz:

QUIETO, CORRE, SALTA

¿Hay algo ya palpable en este módulo para usarlo?

Y me gustaría asociar esos controles con el módulo de reconocimiento facial de grisendo, me excitaría mucho, uuUuUUUUuUUuuuUHHHhHHHHhhh...

Sería en 3D
Title: Re: PiEfSi de speech recognition
Post by: SplinterGU on February 18, 2010, 10:50:51 PM
hay un juego que lo hace, esos de estrategia, no recuerdo el nombre...
Title: Re: PiEfSi de speech recognition
Post by: gecko on February 19, 2010, 03:05:10 AM
si, es de la saga de los de Tom Clancy.

el Tom Clancy's End War, y la verdad que esta muy bueno, te crea un ambiente y una sensacion de realismo, o nose, una sensacion de que "la maquina esta jugando con vos" que es rara de sentir...
Title: Re: PiEfSi de speech recognition
Post by: SplinterGU on February 19, 2010, 05:25:42 AM
no sabia de ese juego... el que yo me referia es uno que se ve desde arriba... world of the warcraft, puede ser?
Title: Re: PiEfSi de speech recognition
Post by: Windgate on February 19, 2010, 07:29:01 AM
Al WoW le he metido varias horas de vida y que yo sepa no tiene de eso... Aunque tampoco me he puesto a mirar las opciones de accesibilidad...
Title: Re: PiEfSi de speech recognition
Post by: SplinterGU on February 19, 2010, 03:23:34 PM
me habre confundido...
Title: Re: PiEfSi de speech recognition
Post by: Drumpi on February 19, 2010, 05:09:43 PM
Del proyecto, palpable, lo único que hay es lo que habeis visto en la descarga... bueno, hay bastante más: se pueden mover las gráficas, desplazarnos a lo largo de la misma...
Si en septiembre/octubre/medio noviembre estuve repasando apuntes, leyendo acerca de la Beagle, instalando SO... y luego medio noviembre con el motor de scroll tileado y Venturer para GP2X, y para rematar, el Doggy!!! :P

Pero vamos, que para Junio espero que esté, por la cuenta que me trae (la fecha tope es septiembre). Lo que veo más complicado es conseguir la base de datos de palabras, pues la que viene en la memoria de Grisendo es en inglés, y estoy buscando una en español, y sólo encuentro algunas sin terminar.
Voy a ver si puedo generar alguna con cosas básicas (números y direcciones), y si se puede ampliar, mejor, pero yo no contaría con nada espectacular :S
Que el programa que estoy haciendo es para eso, para ver hasta qué punto puedo reconocer letras o sílabas, o tengo que tirar de librería que contenga palabras, y si dependerá mucho o poco de la persona que hable, cómo le afectaría el ruido... que no las tengo todas conmigo. Que no soy programador, que soy teleco, que lo mío es el HW ;D
Title: Re: PiEfSi de speech recognition
Post by: Drumpi on February 21, 2010, 06:24:36 PM
Bueno, me acabo de quedar pillado:
He estado mirando el código de la FFT (sí, voy lento, pero es lo más que me dejan en casa, entre una cosa y otra), y no entiendo lo que quiere decir lo siguiente (lo marco en negrita)

/**********************************************************/
/* fft.c                                                  */
/* (c) Douglas L. Jones                                   */
/* University of Illinois at Urbana-Champaign             */
/* January 19, 1992                                       */
/*                                                        */
/*   fft: in-place radix-2 DIT DFT of a complex input     */
/*                                                        */
/*   input:                                               */
/* n: length of FFT: must be a power of two               */
/* [b]m: n = 2**m[/b]                                            */
/*   input/output                                         */
/* x: double array of length n with real part of data     */
/* y: double array of length n with imag part of data     */
/*                                                        */
/*   Permission to copy and use this program is granted   */
/*   under a Creative Commons "Attribution" license       */
/*   http://creativecommons.org/licenses/by/1.0/          */
/**********************************************************/


Creo entender que significa que asignemos a n el valor de 2^m (dos elevado a m) ¿no?
Title: Re: PiEfSi de speech recognition
Post by: DCelso on February 21, 2010, 07:52:22 PM
no, y para marcar en negrita dentro de un "quote" o "code" tienes que usar código html osea <b> y </n> :D.

Si te digo que * , además de ser un operador binario de multiplicacion es un operador unario para extraer el valor de un puntero ¿te aclaro la respuesta?

Si fuese código c sería 2 por el valor que hay en la direccion a la que apunta m.
Pero como está en un comentario pues puede que sea una representación de elevado a como tu comentas. Tendrías que asegurarte viendo el código fuente que vendrá más abajo.

Title: Re: PiEfSi de speech recognition
Post by: SplinterGU on February 21, 2010, 08:10:43 PM
je, en este caso significa potencia... recuerden que en el viejo Spectrum o ZX-8*, ** significa potencia... y en el texto de arriba dice claro, "n debe ser una potencia de 2"...

cuando se quieren expresar en formulas matematicas dentro en textos electronicos las potencias, se suele usar "**".

viene de muchos años atras, ya me siento un viejo... :(
Title: Re: PiEfSi de speech recognition
Post by: Drumpi on February 22, 2010, 03:28:47 AM
Yo me imaginaba eso, es que no hay más info en el código ya que m es un valor de entrada a la función.
Lo estuve buscando por internet, pero lo más que encontré era que el operador ** no se puede sobrecargar, o definir, o algo así.

No te sientas viejo, Splinter, acabas de demostrar ser el más sabio del lugar :)
Title: Re: PiEfSi de speech recognition
Post by: Drumpi on February 22, 2010, 03:32:27 AM
Por cierto, he terminado las funciones que generan los gráficos de la FFT... pero no funciona bien, mañana toca debug a lo salvaje.
Es que por más que busco, no encuentro el significado de los valores de salida. Se que sale un vector de valores complejos, cuyos módulos son lo que ando buscando (la amplitud de cada frecuencia), pero eso no me indica la frecuencia a la que representa.
Title: Re: PiEfSi de speech recognition
Post by: SplinterGU on February 22, 2010, 02:15:12 PM
http://www.carlospes.com/sintaxis_ansi_c/operadores_aritmeticos.php

http://exa.unne.edu.ar/depar/areas/ingenieria/computacion/Tema%204.pdf (pagina 24)

mira en este articulo la nota del comando pow

http://www.freenetpages.co.uk/hp/alan.gauld/spanish/tutfunc.htm

Title: Re: PiEfSi de speech recognition
Post by: grisendo on February 22, 2010, 03:11:04 PM
Se supone que tienes que hacer añadir ceros para hacer que el tamaño del vector entrada sea potencia de 2, y entonces hacer la FFT...

En las imágenes, el resultado es una matriz compleja cuadrada, donde las frecuencias altas estaban en el centro? esquinas?... creo que esquinas. De los valores complejos había que trabajar con su módulo (que era con lo que yo he trabajado únicamente) y con su fase.

Me imagino que en las ondas de sonido (unidimensionales), los valores de las frecuencias altas estarán en los lados de la onda compleja resultado, y los de las bajas en el centro... Entonces poniendo por ejemplo los valores centrales a cero estarías haciendo un filtro de paso alto, poniendo los valores laterales a cero, un filtro de paso bajo, etc...
Title: Re: PiEfSi de speech recognition
Post by: Drumpi on February 22, 2010, 05:33:35 PM
No, si por la cantidad de valores no es, eso lo tengo controlado :D
Ya descubrí el problema, y es que al hacer los cálculos del módulo se me producía un overflow de datos y me daban números negativos que Bennu interpretaba como le daba la gana. He cambiado el tipo de datos de los arrays por floats y problema solucionado (aunque no me hace gracia trabajar con este tipo de datos).

El caso es que he obtenido una gráfica, creo entender que las frecuencias crecen de izquierda a derecha, porque he obtenido unos valores delta que muestran la clásica gráfica de una señal y sus diversos armónicos. Pero no termino de entenderla...
-La gráfica es casi idéntica, independientemente de la señal que pongo y de la posición inicial de análisis (aunque aun tengo que comprobar una cosa, porque hago un escalado en función del valor más grande, por lo que no veo los cambios globales).
-Veo las delta, pero no sé qué frecuencias representan. Según la cantidad de datos que analizo obtengo más o menos armónicos, pero no se el valor en la coordenada X.

En fin, ahora es cuando me toca emplear mi intuición y mis conocimientos de señales, pero entender esos valores de X sería una gran ayuda.
Title: Re: PiEfSi de speech recognition
Post by: grisendo on February 22, 2010, 08:30:46 PM
No sé con qué sonidos estás probando, pero si estás analizando siempre tu voz, lo más seguro que utilices el mismo tono. Intenta generar con algún aparato/aplicación señales sinusoidales de diferentes tonos (diferentes frecuencias) y ver qué resultados te salen en la transformada... o cantar xDD Creo que sonidos más graves tienen los mayores valores a la izquierda... ¿o la del sonido es simétrica como la de las imágenes?

Según tengo entendido, la FFT es periódica. No sé qué algoritmo utilizas exactamente para calcularla, pero creo que el resultado está normalizado. El hecho de que haya más valores intermedios (en el eje x) es porque se están utilizando más valores de cuantización, no sé si me explico... la onda completa de un sonido sería un periodo, si dura 1 segundo (T=1) esa onda es muy sencilla y puede expresarse en fourier con pocas frecuencias, si dura 100 años (T=100 años) esa onda es muy compleja (o puede serlo) y se necesita más precisión para representarla con fourier (mayor muestreo frecuencial).

Y luego para entender exactamente los valores X e Y hace falta ir un poquillo colocao, porque son todo exponenciales de complejos :D

No te fíes mucho de lo que te diga yo jeje, pero prueba cosas así para ver cómo funciona...
Si hay alguien que sepa más y ve que estoy metiendo la pata, que avise, porque estoy hablando de carrerilla xD
Title: Re: PiEfSi de speech recognition
Post by: Drumpi on February 23, 2010, 01:47:03 AM
Hombre, no soy tonto: uso sonidos generados por mi editor de IT, concretamente el sonido de una ocarina, y el de una flauta. Uno de ellos representa una sinusoide, el otro son dos sinusoides sumadas ;D

Por lo que dices, me suena más a que la FFT podría ser la transformada de Fourier de una señal discreta, lo cual simplificaría las cosas y significa que la coordenada X indica un valor entre 0 y 2pi (tendría que repasar los apuntes para ver su significado real).

Pero bueno, mañana voy a coger y me voy a generar un wav A MANO de una sinusoide perfecta, a ver si me salta una única delta, como debería ser. Si no, tendré que crear un programa para generar señales a partir de su FFT :S

Bueno, para el que quiera echarle un vistazo, aquí teneis esto:
http://drumpi.se32.com/cosas/test.rar
No es gran cosa: desde el prg principal se carga un wav y se le calcula la FFT. Podeis cargar los wavs que querais y calcularle su FFT, yo prefiero hacerlo con el comando RUN desde la ventana de debug (debeis tener en primer plano el gráfico DEL WAV si quereis calcularle la FFT).
Dentro del programa, podeis usar el botón izquierdo del ratón para desplazar las ventanas y traerlas al frente, el botón central os permite desplazaros a lo ancho del wav, y cada segundo recalcula la FFT correspondiente a partir de la posición actual. Calcula la FFT para 1024 puntos.

El código es un poco "extraño", he intentado modularizarlo lo máximo posible (se resume en manejar una estructura que contiene dos tipos definidos por mi, una con los datos del wav y otro con los de la FFT... y aparte una lista de procesos que maneja, cada uno, una gráfica, que puede ser de un WAV o una FFT). Si alguien ve un error, espero que me lo comente, el código de la FFT prácticamente lo he copiado linea por linea y aun no me he puesto a hacer cálculos "a mano" (lo que sería una locura, la verdad).

En fin, espero que los que hayan entendido algo de lo que he dicho le vean algo más de sentido que yo.
PD: incluyo los wav con los que estoy probando.
Title: Re: PiEfSi de speech recognition
Post by: Drumpi on February 25, 2010, 01:58:47 AM
Juer, me tiene frito.
No se por qué pero no me cuadran los resultados.

Finalmente sí, he mirado por internet y lo que se obtiene parece ser que es la transformada de Fourier para una señal discreta, por lo que los valores corresponden a un ciclo entre 0 y 2pi (pues después se repiten)... pero eso no me dice los valores de frecuencia, sigo buscando... y no quiero tener que instalar Matlab.

De todas formas, para probar he cogido y me he creado mi propio wav (sí, he hecho un sonido desde cero, a mano). Con una señal a cero me devuelve lo esperado, todo a cero. Si tiene un valor constante, me devuelve lo de siempre: una delta con sus armónicos... menos uno. Con una señal sinusoidal me devuelve lo de siempre, y con una suma de sinusoides (dos notas) igual, no hay cambios. No se si es que lo que vi en internet, de que se cuela un fenómeno ondulatorio de baja frecuencia sin saber por qué es lo que me está fastidiando o que no hago bien la transformada, no lo se.

Ahora investigo si puedo obtener los valores de frecuencia o si voy a tener que usar Matlab para hacer el análisis (aunque de todas formas, voy a tener que implementarlo luego todo en C, por lo que me da lo mismo) :S
Title: Re: PiEfSi de speech recognition
Post by: Drumpi on February 28, 2010, 05:10:08 PM
Bueno, he dado un pasito más:
He hallado un error en el código y lo he arreglado. Lo he subido a
http://drumpi.se32.com/cosas/prueba.rar
Con todo listo para funcionar.

La señal ya sale algo más normal, parece ser que sale una señal sinc, que se debe a tomar un número finito de valores... creo.
Lo que no entiendo es que, calculando la FFT, a pesar de que MACHACO los valores, aunque la señal se halle en el mismo punto, la FFT cambia y crece sin parar. Creía que era algo del funcionamiento del seno y del coseno (por eso de que devuelven números enteros en milésimas) pero entonces las gráficas devuelven cosas más raras aún :S

A ver si encontrais vosotros algún error, porque creo que es cosa del código, no de la teoría.
Title: Re: PiEfSi de speech recognition
Post by: Windgate on March 01, 2010, 12:03:28 PM
Ojo, ojo, seno y coseno en Bennu devuelven float, entre -1.0 y 1.0 pero float, ¿No tendrás algún fallo ahí, no?

Por mi experiencia seno y coseno son suficientemente precisos... Aunque nunca me he puesto a dibujar gráficas, vaya.
Title: Re: PiEfSi de speech recognition
Post by: Drumpi on March 01, 2010, 07:24:01 PM
No esaba seguro y contemplé las dos posibilidades, aun así, lo repasaré, porque creo que hay algo que no anda muy fino en las conversiones FLOAT<->INT, o los INT no son tan precisos como requiere el programa, no lo se seguro, ya informaré sobre ello.
De todas formas, el código está ahi, por si alguien se anima a revisarlo ;D
Title: Re: PiEfSi de speech recognition
Post by: Drumpi on March 08, 2010, 11:59:18 AM
Bueno, finalmente le pude corregir algunos fallos y mantener estables los datos obtenidos, aun así falla.
Pero eso poco importa porque ahora me acaban de cambiar completamente el proyecto: mi objetivo ahora es hacer un manual de iniciación al desarrollo para el OAMP y la BeagleBoard, tanto de su CPU como de su DSP, por lo que parece ser que lo de reconocimiento de voz se pospone.
Me han dado la posibilidad de que, si me funcionan los ejemplos básicos, le pueda dedicar algo de tiempo a hacer algo sencillo al respecto, así que...

Lo bueno es que si me funciona bien la cosa, lo mismo puedo hacer yo mismo el port de Bennu a pandora :D :D :D
Title: Re: PiEfSi de speech recognition
Post by: Drumpi on March 22, 2010, 02:14:01 AM
Atención: post de desahogo.

Me **** en la madre que ***** al ******* que...
Bueno, os pongo en antecedentes: el proyecto de fin de carrera ha cambiado, ya no va de reconocimiento de voz, ahora es un manual de desarrollo en BeagleBoard. Pues bien, uno de los primeros puntos es el de compilar un Linux, la distribución Angstrom para ser más precisos, usando OpenEmbedded. Vale, llevo media semana peleándome para instalarlo y tenerlo lo tengo.
Así que paso a hacer una prueba: compilar nano (y todas sus dependencias, incluido el core)...

5 horas.
5 horas de descargas, configuración y compilación, y más de 6GB ocupados, la mitad del espacio sobrante de la partición de Ubuntu.

Bueno, pues pienso yo que casi todo estaba ya hecho, terminar de compilar la distribución no podía llevar tanto...

Y UNA M*****!!!!!!!!!!!!!!!!!!!!!!!
Otras 5 horas, realizando más de 3000 tareas, y venga a descargar, y venga a configurar, y venga a compilar... ¡que me ha dado tiempo a aburrirme del Smash Bross Melee, del Sonic Unleashed y del Sonic Heroes!
Y cuando vuelvo después de cenar... error.

¡¡¡¡ERROR!!!!
¡¡¡NO HAY SUFICIENTE ESPACIO EN DISCO!!!
QUE SE HA TRAGADO 12GB Y NO HA HECHO NI LA MITAD

¿Y ahora que? no puedo usar la partición de Linux, y las otras están bastante llenas (por bastante quiero decir que las tengo al 98%).
¡¡¡GANAS DE MATAR A MÁXIMO NIVEL!!!

Total, mañana, más calmado, le mandaré un correo a mi director de proyecto, a ver qué me dice, pero me veo los tres próximos días vaciando el disco duro  >:(