163
Escuela Politécnica Superior de Linares UNIVERSIDAD DE JAÉN Escuela Politécnica Superior de Linares Trabajo Fin de Grado APLICACIÓN DE KARAOKE PARA TABLETA Alumno: Pérez Marín, Pedro José Tutor: Vera Candeas, Pedro Depto.: Ingeniería Telecomunicaciones Septiembre, 2014

Trabajo Fin de Gradotauja.ujaen.es/bitstream/10953.1/2160/1/TFG-Perex-Martin-Pedro-J.pdf · ANEXO I. MANUAL DE USUARIO ... operativo android trabajando junto con el juego de ordenador

Embed Size (px)

Citation preview

Escuela

Polit

écnic

a S

uperior

de L

inare

s

UNIVERSIDAD DE JAÉN Escuela Politécnica Superior de Linares

Trabajo Fin de Grado

Trabajo Fin de Grado

APLICACIÓN DE KARAOKE

PARA TABLETA

Alumno: Pérez Marín, Pedro José

Tutor: Vera Candeas, Pedro Depto.: Ingeniería Telecomunicaciones

Septiembre, 2014

1

ÍNDICE DE CONTENIDOS

1. RESUMEN………………………………………………………………………………………….4

2. INTRODUCCIÓN…………………………………………………………………............………4

2.1. INTRODUCCIÓN AL MUNDO DE LAS TABLETAS…………………………..……4

2.1.1. ¿Qué es una tableta?....................................................................................4

2.1.2. Historia………………………………………………………………………….…..5

2.1.3. Utilidades…………………………………………………………………….……...7

2.1.4. Ventajas y desventajas…………………………………………………………...7

2.1.5. Evolución del mercado de las tabletas…………………………………………8

2.2. ESTUDIO PREVIO Y MATERIAL UTILIZADO……………..……………………….9

2.2.1. Búsqueda de información e investigación……………………………………...9

2.2.2. Herramientas utilizadas en la creación del trabajo…………………………….9

2.2.3 Creación de la aplicación………………………………………………………...10

3. OBJETIVOS………………………………………………………………………………………10

4. MATERIALES Y MÉTODOS…………………………………………………………………...11

4.1. ESTADO DEL ARTE ………………………………………………………………....12

4.1.1. El karaoke y su evolución……………………………………………………….12

4.1.2. Formatos del karaoke ………………………………………………………….13

4.1.3. Técnicas de estimación del pitch ……………………………………..............14

4.1.3.1. YIN……………………………………………………………………………15

4.1.3.2. DDF Decimated difference function for F0 estimation.………………..19

4.2. PROGRAMA DESARROLLADO……………………………………………………22

4.2.1. Contenedor ZIP………………………………………………………………….23

4.2.1.1. Archivo de texto……………………………………………………………24

2

4.2.1.2. Archivo de audio……………………………………………………………29

4.2.1.3. Archivo de video……………………………………………………………29

4.2.1.4. Archivo de imagen………………………………………………………...29

4.3. VISTAS DE LA APLICACIÓN Y DIAGRAMAS DE FLUJO……………………….29

4.3.1. Pantallas del karaoke……………………………………………………………30

4.3.1.1. Pantalla principal…………………………………………………………...30

4.3.1.2. Pantalla explorador de archivos…………………………………………..33

4.3.1.3. Pantalla de ajustes…………………………………………………………39

4.3.1.4. Pantalla de información de canción……………………………………..40

4.3.1.5. Pantalla de juego…………………………………………………………..40

4.3.2. Salir…………………………………………………………………………………45

5. RESULTADOS Y DISCUSIÓN…………………………………………………………………46

5.1. TRABAJO FINAL OBTENIDO……………………………………………………….46

5.2. PROBLEMAS ENCONTRADOS…………………………………………………….47

5.3. LÍNEAS DE FUTURO…………………………………………………………………48

6. CONCLUSIONES………………………………………………………………………………..48

6.1. CONCLUSIONES OBTENIDAS……………………………………………………..48

7. PLIEGO DE CONDICIONES…………………………………………………………………...49

7.1. Requisitos de la aplicación…………………………………………………………..49

7.2. Características del dispositivo de desarrollo……………………………………….49

8. ANEXOS…………………………………………………………………………………………..52

8.1. ANEXO I. MANUAL DE USUARIO………………………………………………….52

8.1.1. Instrucciones para jugar…………………………………………………………52

8.1.2. Cambios en la tableta……………………………………………………………57

3

8.2. ANEXO II. DOCUMENTACIÓN TÉCNICA………………………………………....58

8.3. ANEXO III. ÍNDICE DE FIGURAS………………………………………………….159

9. REFERENCIAS BIBLIOGRÁFICAS…………………………………………………………161

4

1. RESUMEN

El presente trabajo fin de grado consiste en un karaoke para tabletas con sistema

operativo android trabajando junto con el juego de ordenador UltraStar del cual se

descargarán los diferentes archivos (audio, video, imagen y txt) para que el usuario final

pueda disfrutar cantando las canciones de su grupo o artista favorito.

La aplicación presenta un sistema de puntuación con tres niveles de dificultad (baja,

media, alta) basándose en la comparación de las frecuencias cantadas por el cantante y las

frecuencias cantadas por el jugador obtenidas por medio del algoritmo de estimación de la

frecuencia fundamental de la voz cantada, el cual será explicado más adelante.

También, dependiendo de la configuración del idioma de la tableta, la aplicación

aparecerá en Inglés o en Español.

A lo largo de esta memoria se verá un poco de historia tanto del karaoke como de las

tabletas, estudios previos realizados, el desarrollo en sí de toda la aplicación con sus

problemas y soluciones, un pliego de condiciones, un presupuesto y finalmente las clases y

métodos implementados para alcanzar el objetivo de este trabajo.

2. INTRODUCCIÓN

2.1. INTRODUCCIÓN AL MUNDO DE LAS TABLETAS

2.1.1. ¿Qué es una tableta?

Una tableta, también llamada tablet (del inglés: tablet computer), es una

computadora portátil de mayor tamaño que un teléfono inteligente o una PDA, integrada en

una pantalla táctil con la que se interactúa con los dedos sin la necesidad de un teclado

físico o ratón, viéndose estos sustituidos por un teclado virtual.

Este término puede aplicarse a una gran variedad de formatos que difieren en el

tamaño o en la posición de la pantalla con respecto a un teclado. El formato estándar se

llama pizarra, habitualmente de 7 a 12 pulgadas, y carece de teclado integrado aunque

puede conectarse a uno inalámbrico por ejemplo por bluetooth o mediante un cable USB.

Las minitabletas son similares pero de menor tamaño, frecuentemente de de 7 a 8

pulgadas. Otro formato es el portátil convertible, que dispone de un teclado físico que gira

sobre una bisagra o se desliza debajo de la pantalla, pudiéndose manejar como un portátil

clásico.

En este caso, el proyecto ha sido realizado con una Samsung Tab3 de 7” de pantalla.

5

2.1.2. Historia

El primer ejemplo del concepto de tableta fue desarrollado por Alan Kay creando

Dynabook en 1972 (figura 1), sin embargo los monitores delgados y pantallas táctiles no

existían en su época.

Figura 1. Primer concepto de tableta. “Dynabook”

En 1978 Apple Computer presenta un video conceptual acerca del Knowledge

Navigator, una tableta futurista que respondía ante comandos de voz.

En 2001, Nokia desarrolló un prototipo de tablet, el nokia 510 webtablet (figura 2), de

casi 2 kilos de peso y una pantalla táctil de 10 pulgadas.

Figura 2. Nokia 510 webtablet

6

Sin embargo los primeros dispositivos en el mercado comercial aparecieron al

principio del siglo XXI. Microsoft lanzó el Microsoft Tablet PC (figura 3),aunque no alcanzó el

éxito esperado por parte de la compañía.

Figura 3. Microsoft Tablet PC

Finalmente en 2010 Apple presenta el iPad (figura 4) basado en su exitoso iPhone,

alcanzando el éxito comercial.

Figura 4. IPad

7

2.1.3. Utilidades

La evolución cada vez más rápida de las tabletas nos permite realizar multitud de

actividades en nuestra vida cotidiana. Algunas de ellas son:

Lectura de libros electrónicos.

Navegación web.

Llamadas telefónicas, si son 3G, sustituyendo de este modo al teléfono móvil.

GPS.

Reproducción de música.

Visualización de videos y películas, cargadas desde la memoria interna o

externa.

Cámara fotográfica y de video HD.

Videoconferencia.

2.1.4. Ventajas y desventajas

Las tabletas se han convertido en el principal competidor de los ordenadores

portátiles y de sobre mesa. Las ventajas y desventajas de estas dependen en gran medida

de opiniones subjetivas. Lo que atrae a un usuario puede ser exactamente lo que

decepcione a otro. A continuación se cita una serie de ventajas y desventajas entre las

tabletas y los ordenadores portátiles.

Ventajas.

Su facilidad de uso en entornos donde resulta complicado un teclado y un

ratón, como en la cama, de pie o el manejo con una sola mano.

Su peso ligero. Los modelos de menor potencia pueden funcionar de manera

similar a los dispositivos de lectura tales como el Kindle de Amazon.

El entorno táctil hace que en ciertos contextos, como en la manipulación de

imágenes y sonido, el trabajo sea más fácil que con un teclado y un ratón.

Facilita y agiliza la posibilidad de agregar signos matemáticos, diagramas y

símbolos.

Permite la interacción con diferentes teclados sin importar su ubicación.

Para algunos usuarios resulta más interactivo usar el dedo o un lápiz y pulsar

sobre la pantalla en lugar de utilizar ratón.

La duración de la batería es mucho mayor que la de una computadora portátil.

8

Desventajas.

Precio superior debido a la complejidad de la pantalla. Una tableta será más

cara que un portátil con características de hardware similares.

Velocidad de interacción: la escritura a mano sobre la pantalla o escribir en un

teclado virtual puede ser significativamente más lento que la velocidad de

escritura en un teclado convencional.

Comodidad (ergonomía): una tableta no ofrece espacio para el descanso de

la muñeca. Además el usuario tendrá que mover su brazo constantemente

mientras escribe.

Menor capacidad de video: la mayoría de las tabletas están equipadas con

procesadores gráficos incorporados en lugar de tarjetas de video. Aunque se

está comenzando a fabricar como la HP TouchSmart tm2t.

Riesgos en la pantalla ya que se manipulan más que la de los portátiles

convencionales.

2.1.5. Evolución del mercado de las tabletas

Desde que Apple lanzara su exitosa tableta iPad en 2010, todos los fabricantes de

equipos electrónicos han aparecido en la producción de tabletas como Google, Samsung,

Sony, Toshiba, Hacer…etc, lo cual ha generado que el mercado se vea inundado de una

inmensa cantidad de tabletas de diferentes tamaños, aplicaciones, precios y sistemas

operativos.

El crecimiento de ventas de tabletas frente a ordenadores portátiles en los años

2011-2012 fue brutal, vendiéndose aproximadamente 143 millones de tabletas. Este

crecimiento se debió a la comodidad del dispositivo y al tamaño de su pantalla entre 7” y

10”. Según IDC (International Data Corporation), en 2015 se distribuirán 293.5 millones de

portátiles y 300.7 millones de tabletas, será el primer año en que los tablets superen a los

ordenadores portátiles. Además el pronóstico indica en 2018 una distribución de 291.7

millones de portátiles y 383.3 millones de tabletas. Esta diferencia seguirá creciendo salvo

que el mercado de los ordenadores portátiles resurja debido a algún producto o avance

determinado producido en el sector.

En el segundo cuatrimestre de 2014 se distribuyeron 49.3 millones de tabletas a nivel

global, un 11% más que en el mismo periodo del año pasado. Aunque esta cifra es

aparentemente buena, lo cierto es que el crecimiento secuencial es negativo y el mercado

de las tabletas declinó en un 1.5% con respecto al primer trimestre de 2014. La razón es

clara según los responsables del estudio: el cada vez mayor tamaño de los smartphones

9

con pantallas de 5.5” o más está causando que mucha gente se piense la compra de

tabletas, ya que las amplias pantallas de esos dispositivos son a menudo adecuadas para

tareas que en su día parecían reservadas a tabletas. En la figura 5 se observa una evolución

del mercado desde el 2012 hasta el 2018.

Figura 5. Estudio del IDC en ventas de tabletas y portátiles.

2.2. ESTUDIO PREVIO Y MATERIAL UTILIZADO

2.2.1. Búsqueda de información e investigación

Se ha llevado a cabo una profunda búsqueda al comienzo del proyecto en libros de

programación en Java y de programación en android tanto en la biblioteca digital de la

universidad de Jaén como en diferentes direcciones web para poder desarrollar dicha

aplicación. Búsqueda de distintos documentos donde se explica detalladamente los

algoritmos de estimación de la frecuencia fundamental aparte de la aportada por la Escuela

Politécnica Superior de Linares. Además se ha indagado en funciones ya implementadas

que realizasen un trabajo igual o similar al deseado para la plataforma android y para otras

distintas.

2.2.2. Herramientas utilizadas en la creación del trabajo.

Para la realización tanto del escrito de este proyecto como para el desarrollo de la

aplicación ha sido utilizado un ordenador con sistema operativo Windows 7. La aplicación

finalmente ha sido instalada en una tableta Samsung Tab con versión de Android 4.1.2

El desarrollo de la aplicación se ha realizado con la ayuda del entorno de desarrollo

Eclipse junto con el plugin propio de la Android SDK, todo código de libre distribución y

totalmente gratuito.

10

Este documento ha sido desarrollado mediante el editor de textos Microsoft Office

Word.

Para la realización de pruebas de la aplicación se ha utilizado el propio emulador que

ofrece el plugin SDK de android denominado AVD (Android Virtual Devices).

Los montajes fotográficos y la manipulación de imágenes han sido realizados con el

editor de imágenes PhotoScape.

Para la conversión de los formatos de audio ha sido utilizado el software Audacity,

mientras que para la conversión de videos se ha decidido utilizar el software Free Video

Converter.

2.2.3 Creación de la aplicación

Para la creación de la aplicación se ha realizado una serie de pasos los cuales son

citados a continuación:

Creación del algoritmo de la función diferencia encargada de estimar la

frecuencia fundamental de la voz del cantante haciendo uso del software de

distribución y uso gratuito Matlab R2013a.

Desarrollo de cada una de las actividades que componen la aplicación.

Diseño de cada una de las vistas que aparecen en la aplicación con sus

correspondientes mensajes contextuales.

Unificación de los distintos módulos que compone la aplicación,

sincronización de las hebras y depuración.

Realización de pruebas con distintos contenedores para observar por qué

camino guiar la aplicación.

3. OBJETIVOS

El objetivo de este proyecto es familiarizarse con el lenguaje de programación y

sistema operativo Android para el desarrollo de un karaoke para tabletas de dicha

plataforma e implementación del algoritmo de estimación de la frecuencia fundamental de la

voz para implementar un sistema de puntuación que indique al final de la partida qué

cantidad de puntos ha obtenido el jugador. Para conseguir lo citado se tiene que:

Conocer los fundamentos teóricos del proyecto.

Conocer la arquitectura del dispositivo en el que se pretende implementar.

Configurar el entorno de programación, así como las herramientas

proporcionadas por la plataforma.

11

Utilizar un algoritmo de estimación de pitch de bajo consumo.

Comprender las clases implementadas por Paco Moreno en su proyecto.

“Paco Moreno.Implementación de una aplicación de karaoke para telefonía

móvil”.

Desarrollar pequeñas aplicaciones hasta que poco a poco obtengamos el

objetivo marcado.

Investigar el tratamiento y uso de flujos de uso multimedia por parte del

sistema operativo.

Programar cada uno de los módulos que compone el proyecto.

Juntar todos los módulos individuales para conseguir el correcto

funcionamiento del programa y conseguir una estética adecuada de cara al

jugador.

Cabe destacar algunas peculiaridades que presenta la aplicación aparte de su

correcto funcionamiento.

Uso de un descompresor de archivos ZIP, para que el tratamiento de los

archivos por parte del usuario sea lo más simple posible ya que solo tendrá

que copiar un único archivo en el dispositivo donde aparecerá canción, video,

foto y texto comprimidos.

Implementación de un registro de caché para ahorrar tiempo en la

descompresión de los archivos que ya han sido descomprimidos con

anterioridad.

Adaptabilidad de la aplicación a pantallas de distintos tamaños.

La aplicación presenta compatibilidad en tabletas android con versiones

comprendidas entes la 2.2. y la 4.4.

4. MATERIALES Y MÉTODOS

En este apartado se hace un breve repaso a la historia y evolución del karaoke con el

paso del tiempo, cómo se encuentra el mundo de los formatos del karaoke, así como las

técnicas más relevantes investigadas en el ámbito de la estimación del pitch o frecuencia

fundamental de la voz cantada. Además, se explica todo el desarrollo de la aplicación

mostrando las correspondientes vistas y diagramas de flujo.

12

4.1. ESTADO DEL ARTE

En este apartado, los formatos del karaoke se corresponden con los presentes en el

proyecto de Paco Moreno.” Paco Moreno. Implementación de una aplicación de karaoke

para telefonía móvil. 14-16”.

4.1.1. El karaoke y su evolución.

El término karaoke proviene del Japonés “kara”, o vacío, y “okesutora”, que significa

orquesta, por lo que la palabra literalmente quiere decir “orquesta vacía”.

La primera máquina de karaoke la introdujo el cantante Daisuke Inoue, pero el éxito

fue un poco por casualidad ya que la gente asistente a sus conciertos insistía en poder

cantar junto a él, gracias al experimento interactivo tan novedoso. Cuando el cantante vió el

gran potencial del invento, lo patentó en un primer modelo consistente en una máquina a la

que había que echar una moneda para que funcionase. Y las prestaba en régimen de

alquiler a diversos establecimientos de ocio, como un servicio más. Las primeras máquinas

utilizaban cintas magnéticas en las que se grababa un video con la letra sobre impresionada

con una pista de audio que podía contener o no la voz original del cantante. Más adelante

se fueron introduciendo el uso de CDs, laserdisc y, ya por útlimo el DVD.

En el siglo XIX, en Francia surgió un entretenimiento parecido llamado goguette. Esta

modalidad de karaoke consistía en, utilizando la melodía original de una canción que era

interpretada en directo, los asistentes de las cantinas y sala de variedades modificaban la

letra para así realizar composiciones humorísticas o críticas políticas. Esta modalidad

entrañaba una mayor riqueza literaria y artística.

Respecto a los espacios que ocupa el karaoke, también ha ido evolucionando.

Inicialmente se conciben en espacios de ocio abiertos al público, expuesto a ser escuchado

por el resto de asistentes. Suelen contar con un amplio repertorio lo que facilita canciones

para los distintos gustos de las personas que acuden. Además disponen de equipos de

karaoke profesionales y grandes pantallas donde poder seguir las letras, y poder cantar con

un sonido profesional. Dicha actividad ha sido adoptada por bares y restaurantes que lo

utilizan en ocasiones especiales.

A partir de los años 90, comienza el declive del karaoke sobreviviendo a través de

sus más fieles seguidores cantando en público y la aparición de diversos programas de

televisión de ámbito principalmente regional. En paralelo con el crecimiento de las

videoconsolas para toda la familia aparece un concepto más casero del karaoke, el Sing

Star de Play Station. Se consideró el renacer del karaoke.

13

En el país nipón, el karaoke nunca ha perdido interés, sino que se ha reinventado

día a día. Coexiste junto con los cómics manga y la cultura audiovisual, como un elemento

de socialización indiscutible entre los adolescentes.

4.1.2. Formatos del karaoke

En el mercado actual hay muchos tipos de karaokes, los cuales funcionan con

infinidad de formatos. A continuación se va a enumerar los tipos de karaoke más comunes,

explicando brevemente su funcionamiento.

Karaoke – CD: Funcionan con un CD de audio convencional que contiene las

pistas de audio sin voz previamente tratadas en un estudio. No ofrecen la

posibilidad de mostrar la letra por pantalla.

Karaoke – CD + G: Este es el formato de karaoke sin ordenador más

utilizado actualmente. Los archivos se encuentran en un medio que es un Cd

de audio convencional con comandos gráficos insertados en una zona sin

uso. Estos comandos gráficos son interpretados por el reproductor y son los

que permiten la sincronización entre la canción y la letra, e incluso logos e

imágenes.

Karaoke – CD + G - M: Derivado del CD + G, con el apellido Multiplex. En

vez de contener una única pista de audio, contiene dos, una con la voz

original y otra sin ella. Permite aprender la entonación original.

Karaoke – Super CD + G: Formato propietario de CAVS que permite

mediante técnicas de compresión almacenar cerca de 1000 pistas en un

único disco.

Karaoke – VideoCD: También conocido como VCD o Digital Video Disc. Es

la forma de karaoke más popular en Japón. Un VCD es un CD-ROM que

contiene un video codificado en MPEG y que contiene una pista de audio

tratada sin música y una letra sincronizada en un estudio cuando se realizó la

pista de audio.

Karaoke – MIDI: Este formato estándar es utilizado por muchos instrumentos

musicales y dispositivos. Los ficheros midi contienen la información

relacionada con la partitura y el instrumenta que la toca, así como contienen

eventos de texto que son los que sincronizan la música con la letra.

Karaoke – MP3 + G: Este formato es propietario y se basa en la utilización

del karaoke – CDG con pistas MP3.

14

Karaoke – WMA + G: Es el método alternativo creado por TriceraSoft al MP3

+ G. Igual que este pero con la codificación de la pista de audio realizada

mediante el códec WMA.

Karaoke – MP3 + G Zipped: Es una extensión del formato MP3 + G pero

comprimida mediante el algoritmo zip. Antes de su uso el reproductor o la

aplicación debe descomprimir los archivos.

Karaoke – KMF con MP3 + G: Extensión del formato MP3 + G que incorpora

gracias a la asociación de los archivos de tipo KMF algunas características

de seguridad interesantes, así como información gráfica relacionada con la

pista.

Karaoke – KMF con WMA + G: Es el método alternativo creado por

TriceraSoft al KMF con MP3 + G. Igual que este pero con la codificación de la

pista de audio realizada mediante el códec WMA.

Karaoke – DVD: Formato similar al VCD pero que proporciona mayor

capacidad y calidad.

Karaoke - DVD + G: Igual que el caso del formato CD + G, pero utilizando un

soporte físico de un DVD.

Karaoke – NEO + G: Formato propietario de RSQ que permite almacenar 75

canciones en un solo disco. Este formato proporciona la misma calidad que el

CD + G pero con algunas opciones adicionales.

Para cada uno de estos formatos, es necesario que la aplicación o reproductor sea

capaz de capturar el sonido emitido por el usuario final para, mediante el algoritmo y

métodos necesarios que veremos a continuación, el programa sea capaz de asignar una

puntuación en función de la frecuencia cantada. Muchas aplicaciones utilizan estos

métodos como es el caso del video juego SingStar de PlayStation 3 el cual utiliza el

algoritmo ADRess.

4.1.3. Técnicas de estimación del pitch.

La estimación de la frecuencia fundamental ha sido uno de los estudios más

importantes desde que se comenzó el análisis de las señales de voz. En este proyecto se

pretende realizar la estimación del pitch en el dominio del tiempo, aunque también se puede

realizar en el dominio de la frecuencia con métodos muy fiables y efectivos.

A continuación se explicará de manera breve el método YIN, desarrollado por Hideki

Kawahara, investigador de la universidad de Wakayama. Por último se explicará

15

resumidamente el método desarrollado por personal perteneciente a la Escuela Politécnica

Superior de Linares, el DDF.

4.1.3.1 YIN

Este método se basa en una serie de pasos que se analizarán posteriormente. El

método comienza con el cálculo de la función autocorrelación, los siguientes pasos de dicho

método surgirán para solucionar los problemas que presenta esta función y obtener

resultados más precisos.

A. Primer paso: Método de la autocorrelación.

La autocorrelación de una señal discreta la podemos definir como:

𝑟𝑡 𝜏 = 𝑥𝑗 · 𝑥𝑗+𝜏

𝑡+𝑊

𝑗=𝑡+1

(1)

donde 𝑟𝑡(𝜏) es la función de autocorrelación en un intervalo (𝜏) en un tiempo t y con un

tamaño de integración de ventana W. En procesado de señales es común utilizar una

expresión derivada de la anterior:

𝑟𝑡′ 𝜏 = 𝑥𝑗 · 𝑥𝑗+𝜏

𝑡+𝑊−𝜏

𝑗=𝑡+1

(2)

En esta expresión el tamaño de la ventana se reduce conforme van aumentando los

valores de 𝜏, con un resultado que se refleja en el decremento de la envolvente como

función de los intervalos. En la figura 6 se observa este efecto.

16

Figura 6. Ejemplo de la forma de onda de la voz hablada. Autocorrelación de acuerdo a la primera

ecuación. Autocorrelación de acuerdo a la segunda ecuación.

En respuesta a una señal periódica, la función de autocorrelación muestra picos en

los múltiplos del periodo fundamental de dicha señal. El método de estimación de pitch

mediante la autocorrelación escoge el pico de mayor altura para un intervalo no cero

mediante una búsqueda en un rango de intervalos. Si el umbral inferior está muy cercano a

cero, el algoritmo puede llegar a escoger el pico del valor cero, lo cual supondría un error.

De la misma manera, si el umbral superior es demasiado grande, puede llegar a elegirse un

pico situado en un múltiplo de la frecuencia fundamental, lo cual también sería un error. Si

se atiende el resultado obtenido mediante la segunda expresión de la autocorrelación, el

error por escoger un pico en un valor múltiplo del periodo no se podría dar, ya que al ir

decrementándose el valor de la envolvente, no va a haber ningún pico de mayor tamaño que

el del verdadero periodo de la señal. Sin embargo, el error de escoger el pico cercano a cero

no se soluciona tan fácilmente.

B. Segundo paso: La función diferencia.

Suponiendo que se trabaja con una señal 𝑥𝑡 que es una señal periódica de periodo

T, por definición invariante para un desplazamiento temporal de T:

17

𝑥𝑡 − 𝑥𝑡+𝑇 = 0 𝑝𝑎𝑟𝑎 𝑡𝑜𝑑𝑜 𝑡 (3)

Lo mismo se cumple después de elevar al cuadrado dicha expresión y promediarla a

lo largo de una ventana:

𝑥𝑗 − 𝑥𝑗+𝑇 2

= 0

𝑡+𝑊

𝑗=𝑡+1

(4)

Si esta suma se expresa como una función diferencia, y sus términos se expresan en

relación con la función de autocorrelación, se obtiene la siguiente expresión:

𝑑𝑡 𝜏 = 𝑟𝑡 0 + 𝑟𝑡+𝜏 0 − 2𝑟𝑡 𝜏 (5)

Los dos primeros términos están relacionados con la energía. La función diferencia

variaría de forma contraria a la función de autocorrelación, por lo que buscando los mínimos

de la función diferencia se podrá identificar el periodo fundamental de la señal. Si se

analizan los mínimos de la señal diferencia y se comparan con los máximos de la función de

autocorrelación, no siempre coinciden, aunque el error que se comete utilizando la función

diferencia es mucho menor que el que se comete utilizando la función autocorrelación.

C. Tercer paso. Función diferencia normalizada de media acumulativa

En la figura 7 se puede apreciar como la función diferencia toma el valor cero en el

intervalo cero y valores muy cercanos a cero, pero no cero absoluto, en el periodo. Esto es

debido a las imperfecciones en cuanto a periodicidad que presenta la función. A no ser que

se proponga un umbral inferior a la hora de determinar el nulo que se desea tomar, el

método siempre elegiría el mínimo en el intervalo cero.

18

Figura 7. Representación de la función diferencia y de la función diferencia normalizada de media

acumulativa

El problema de fijar un umbral es el que se produce si por cualquier causa la

frecuencia del primer formante presenta resonancia, lo cual llevaría a la función diferencia a

marcar en dicho formante una caída más profunda que para el caso de la frecuencia

fundamental.

La solución propuesta es reemplazar la función diferencia por una función diferencia

normalizada de media acumulativa.

𝑑𝑡′ 𝜏 =

1, 𝑠𝑖 𝜏 = 0𝑑𝑡(𝜏)

1𝜏 · 𝑑𝑡(𝑗)𝜏

𝑗=1

, 𝑒𝑛 𝑜𝑡𝑟𝑜 𝑐𝑎𝑠𝑜 (6)

Esta nueva función se obtiene de dividir cada valor anterior por una media ponderada

de un intervalo reducido. La principal diferencia es que comienza en 1, por lo que no se tiene

el problema de la elección del mínimo en T=0.

19

D. Cuarto paso. Umbrales absolutos.

Una situación muy probable que se puede presentar es que la caída a una frecuencia

múltiplo de la frecuencia fundamental sea más profunda que la caída del periodo. Si la caída

de orden superior está incluida dentro del rango de inspección el algoritmo va a tomar una

decisión errónea, lo cual se conoce como un error de octava.

La solución que este método propone es fijar un umbral absoluto y escoger el valor

mínimo de T que proporciona un valor 𝑑′ menor que el umbral fijado. Si ningún valor

satisface la condición, se toma el mínimo global.

E. Quinto paso. Interpolación parabólica.

Todos los pasos anteriores funcionan si la estimación del periodo era un múltiplo del

periodo de muestreo. Si esto no es así, la estimación puede llegar a ser incorrecta hasta un

valor la mitad del periodo de muestreo. Una solución para este problema es la interpolación

parabólica. Cada mínimo local de la función diferencia normalizada junto con sus vecinos

conforman una parábola, y la ordenada del mínimo interpolado se usa en el proceso de

selección de la caída. La abscisa del mínimo seleccionado sirve para estimar el periodo. La

interpolación de la función diferencia o de la función diferencia normalizada es

computacionalmente mucho más económica que sobre muestrear la señal.

F. Sexto paso. Estimación del mejor local.

A pesar de todo lo aplicado anteriormente, puede darse el caso en el que la

estimación no se estable o que fluctúe alrededor del periodo fundamental. Para asegurarse

de que el valor escogido es el mejor posible, este algoritmo propone un último paso, que se

encarga de realizar una optimización global mediante técnicas de programación difusa con

los valores pertenecientes a distintos intervalos cercanos al valor estimado en los pasos

anteriores.

4.1.3.2. DDF. Decimated difference function for F0 estimation.

A continuación se presenta un método perteneciente a todo un sistema, que ha sido

desarrollado en la Escuela Politécnica Superior de Linares. El sistema está enfocado a su

utilización en sistemas de procesado de señal de bajo consumo, como pueden ser sistemas

digitales para ayudas auditivas, por lo que las prestaciones computacionales quedan

bastante limitadas. La figura 8 representa el diagrama de bloques perteneciente al sistema

completo.

20

Figura 8. Diagrama de bloques del método expuesto para determinar si hay voz o no.

La finalidad de este método es la estimación de la frecuencia fundamental para decir

si el fragmento que se está analizando pertenece a un audio con voz o sin voz. Este parte

de la ecuación diferencia que hemos comentado anteriormente en el método YIN, pero en

una búsqueda por reducir la complejidad al máximo, se introduce un factor de diezmado. El

resultado es la siguiente ecuación.

𝑑𝑑𝑓 𝑛, 𝜏 = 𝑥 𝑛 + 𝑑 𝑊, 𝜏 𝑙 − 𝑥 𝑛 + 𝑑 𝑊, 𝜏 𝑙 + 𝜏 2

(7)

𝑆−1

𝑙=0

Donde S es el tamaño de la ventana y 𝑑(𝑊, 𝜏) el factor de diezmado puediéndose expresar:

𝑑 𝑊, 𝜏 = 𝑊 − 𝜏 − 𝑙

𝑆 − 𝑙 (8)

21

Como se puede observar, el factor de diezmado no permite seleccionar muestras

fuera del intervalo de audio actual.

La función DDF requiere de S restas, S multiplicaciones y S-1 sumas por cada valor

de salida, por lo que la necesidad de computación es directamente dependiente del valor de

S, por lo que una elección adecuada de este valor puede dar una relación capacidad de

cómputo y precisión bastante buena. La figura 9 representa un ejemplo de cómo se computa

la DDF para un valor de 𝜏 dado. Las muestras en negro son las que se tendrán en cuanta

para la computación.

Figura 9. Ejemplo de computación de una señal diezmada y de dicha señal retardada.

Este método también propone una modificación de la función diferencia normalizada

con media acumulativa defendida también en el método YIN. Dicha función, cumulative

mean normalized decimated differential function, se expresa así:

𝑐𝑚𝑑𝑑𝑓 𝑛, 𝜏 =𝜏 · 𝑑𝑑𝑓 𝑛, 𝜏

𝑑𝑑𝑓 𝑛, 𝑗 𝜏𝑗=1

(9)

La complejidad de esta función solo aumenta en una mutiplicación, una suma y una

división para cada valor de salida, por lo que se quedaría en S restas, S+1 multiplicaciones,

S sumas y una división para cada valor de salida. A pesar de esto, la complejidad de dicha

función para cualquier instante de tiempo y con cualquier valor de retardo es muy costosa

22

computacionalmente teniendo en cuenta los sistemas para los que se ha pensado este

método. Por este motivo los autores proponen una serie de valores para los cuales los

resultados y la complejidad satisfacen las necesidades.

Una vez que se conoce la 𝑐𝑚𝑑𝑑𝑓(𝑛, 𝜏) la estimación de la frecuencia fundamental se

calcula atendiendo a los siguientes pasos:

Para todos los posibles valores de 𝜏 se calcula el valor mínimo de la función

𝑐𝑚𝑑𝑑𝑓(𝑛0 , 𝜏).

Este valor mínimo se compara con un umbral para poder así discriminar entre

un fragmento con voz y sin ella.

Para aquellos fragmentos considerados con contenido vocal, la frecuencia

fundamental se calcula como la inversa del periodo para el cual la función

diezmada diferencial de media acumulativa presenta un valor mínimo.

4.2. PROGRAMA DESARROLLADO

El programa llevado a cabo en este proyecto es un karaoke para tabletas android el

cual ha sido llamado “KaraoKe”, el cual hace uso del algoritmo de estimación de la

frecuencia fundamental de la voz cantada desarrollado por parte de integrantes de la

Escuela Politécnica Superior de Linares.

El código de este proyecto se ha guiado a través de las clases y métodos

implementados o utilizados por Paco Moreno en su proyecto, “Paco Moreno.Implementación

de una aplicación de karaoke para telefonía móvil”. También se han tomado algunas figuras

y diagramas de flujo de dicho proyecto, las cuales aparecen indicadas tanto en el índice de

figuras como antes de ser mostrados a lo largo de la memoria. Se ha implementado el

algoritmo de estimación de la frecuencia fundamental de la voz cantada desarrollado por

parte de integrantes de la Escuela Politécnica Superior de Linares.

En el presente proyecto se ha realizado:

Modificación del código del explorador de archivos con referencias como las

que aparecen en la bibliografía en los puntos 9 y 11.

El modo de acceso a cada una de las funciones que presentan los botones de

la vista principal.

Se ha modificado el sistema de puntuación disminuyendo la dificultad de los

tres niveles, los cuales son explicados en la página 44 con su correspondiente

diagrama de flujo.

Diseño y desarrollo de cada una de las vistas de la aplicación.

23

Desarrollo del código que permite a la aplicación mostrar todo su texto ya

sean botones, ajutes, cuadro de diálogo..,etc en inglés siempre que la

configuración de la tableta en el apartado de idioma marque esta opción.

Modificación del código de lectura de datos del archivo txt y grabación para

adaptarlo a las nuevas vistas desarrolladas y al código que permite la

traducción de la aplicación al inglés.

Esta aplicación trabaja con contenedores ZIP donde se almacenarán los distintos

archivos, previamente descargados del juego de ordenador UltraStar, pertenecientes al

tema de un artista o grupo deseado. Estos son:

Archivo de texto: En él aparece toda la información acerca de la canción así

como la sincronización y la letra.

Archivo de audio: Se trata de la pista musical que se ha elegido.

Archivo de video: Presenta el videoclip de la canción elegida.

Archivo de imagen: Aparece una imagen del artista o la carátula del disco.

A continuación se explican las características que presenta el contenedor ZIP y una

descripción más detallada de cada uno de los archivos que contiene.

4.2.1. Contenedor ZIP

Anteriormente se ha definido los distintos formatos de karaoke que podemos

encontrar. En este caso, la elección se ha decantado por manejar contenedores en formato

ZIP. Se ha elegido este tipo de formato aparte de la popularidad de dicho formato de

compresión por la facilidad que ofrece el manejo de este tipo de archivos de cara al usuario

final.

Para que la aplicación funcione correctamente, todos los archivos se deben

encontrar en la misma ruta y tener cada uno de ellos las extensiones adecuadas. El usuario

se encarga de comprimir dichos archivos y de pegarlos en una zona, como puede ser una

carpeta específica para las canciones del karaoke, de la memoria del dispositivo utilizado sin

preocuparse por renombrar carpetas ni nada por el estilo. Cuando el usuario a través del

explorador de archivo seleccione el contenedor deseado, este descomprimirá su contenido

en una carpeta adecuada.

Como bien indica el proyecto realizado por Paco Moreno (antiguo estudiante de la

EPSL cuyo proyecto fue un karaoke para Smartphones android), el software de biblioteca

implementado por android presenta un problema en el terminal. Y es que el sistema detecta

todos los archivos multimedia presentes en el dispositivo, creando las listas de reproducción

24

tanto de audio como de video. Por lo tanto, los archivos multimedia utilizados por el karaoke

no son siempre los que el usuario desea escuchar y por tanto, se debía evitar que la

aplicación encargada de recopilar los archivos multimedia del dispositivo no listase los

utilizados por la aplicación. Para ello, lo que se hace es crear un archivo oculto para el

usuario del dispositivo y que le indica al sistema operativo que no busque contenido

multimedia en dicha carpeta. Este archivo es el nombrado como .nomedia.

4.2.1.1. Archivo de texto

Los archivos de texto son creados por usuarios del programa de karaoke de

ordenador UltraStar, por lo que se debe de seguir el protocolo definido por esta plataforma y

que a continación se explica.

Ejemplo de la información que aporta un archivo de texto y el formato que siguen las

notas de sincronización:

#TITLE:Olvídame y pega la vuelta #ARTIST:Pimpinela #LANGUAGE:Español #EDITION:SingStar Cla ES #GENRE:Pop #YEAR:1984 #CREATOR:Manolo #MP3:Pimpinela - Olvídame y pega la vuelta.mp3 #COVER:Pimpinela - Olvídame y pega la vuelta [CO].jpg #BACKGROUND:Pimpinela - Olvídame y pega la vuelta [BG].jpg #VIDEO:Pimpinela - Olvídame y pega la vuelta.avi #VIDEOGAP:0 #BPM:154,4 #GAP:8257,77 #START:0 #END:283000 : 0 1 34 Ha : 2 1 34 ce : 4 1 34 dos : 6 3 34 a : 10 1 32 ños * 12 1 30 y un * 14 3 30 dí * 18 1 30 a - 19 F 20 1 30 Que F 22 3 30 vi F 26 2 29 vo F 28 2 27 sin F: 30 4 29 él

25

E

#TITLE

Etiqueta de carácter obligatorio. Es el título de la canción. Hay canciones que se

las conoce por un título distinto al que le puso su creador originalmente, así que en estas

ocasiones se podría poner entre paréntesis y a continuación el nombre conocido.

#ARTIST

Etiqueta de carácter obligatorio. Es el artista que interpreta la canción. En

ocasiones se desconoce el autor y se utilizan otros nombres como por ejemplo en el caso

de las películas o series el nombre de estas.

#LANGUAGE

Etiqueta de carácter opcional. El idioma principal de la canción. Es

tremendamente útil y recomendable usarla para poder clasificar las canciones.

Normalmente se utiliza el nombre del idioma en inglés: French, German, etc.

#EDITION

Etiqueta de carácter opcional. Es la edición a la que pertenece la canción. Es lo

que se utiliza para clasificar las canciones que han sido convertidas desde los Singstar.

Erróneamente es la etiqueta que más se utiliza para clasificar las canciones, por ejemplo

poniendo el idioma aquí en lugar de en LANGUAGE. También puede contener

información sobre las distintas agrupaciones de canciones del Ultrastar.

#GENRE

Etiqueta de carácter opcional. El género de la canción (Pop, Rock, etc). Podría ser

de gran utilidad para clasificar canciones si se utilizase siempre de forma adecuada.

#YEAR

Etiqueta de carácter opcional. Año en el que salió la canción al mercado, bien en

un single o en un disco.

#CREATOR

Etiqueta de carácter opcional. Nombre o apodo del creador de la canción. A

algunos creadores de canciones les gusta firmar su obra utilizando esta etiqueta.

#MP3

26

Etiqueta de carácter obligatorio. Nombre del archivo de audio que contiene la

canción. Normalmente se le suele nombrar poniendo lo mismo que en las etiquetas de

#ARTIST y #TITLE. Ejemplo: Olvídame y pega la vuelta – Pimpinela.mp3

#COVER

Etiqueta de carácter opcional. Carátula del disco o single en el que salio por

primera vez la canción. Se admiten más formatos además del jpg. Se suele seguir la

misma regla que para nombrar el archivo de audio, aunque en el caso de que haya otra

imagen de fondo para la canción se añade un espacio y [CO] al final para distinguirlas.

Ejemplo si no hay imagen de fondo: Olvídame y pega la vuelta - Pimpinela.jpg. Ejemplo si

hay imagen de fondo: Olvídame y pega la vuelta – Pimpinela[CO].jpg

#BACKGROUND

Etiqueta de carácter opcional. Es la imagen que sale de fondo mientras se canta

la canción si se especifica a través de los ajustes que no se quiere visualizar el video

como fondo.

#VIDEO

Etiqueta de carácter opcional. Es el video que se mostrara de fondo mientras se

canta la canción. En ocasiones se le añade al final del nombre el videogap que tiene la

canción.

#VIDEOGAP

Etiqueta de carácter opcional. Es el número de segundos que va a empezar el

video antes o después de que comience la canción. Se utiliza para sincronizar los

movimientos de la boca al cantar del video con lo que suena en la canción. Si se quiere

que el video empiece en el segundo 5 se pondrá este valor, si se quiere que empiece 2

segundos más tarde (mientras se queda la pantalla en negro) se pone el valor en

negativo: -2. Ejemplo para que el video empiece nada más comenzar la canción pero

desde el segundo 3: #VIDEOGAP:3. Ejemplo para que el video tarde en aparecer 7

segundos en pantalla y comience por el principio: #VIDEOGAP:-7. Se pueden utilizar

valores decimales para una mayor precisión, por ejemplo: 2,3 o -5,8.

En la utilización de valores decimales se debe de utilizar como separador el punto

“.” en vez de utilizar la coma “,” como ocurre en el caso de los archivos originales de

Ultrastar.

#BPM

27

Etiqueta de carácter obligatorio. Son los golpes por minuto (Beats Per Minute en

inglés) de la canción, es decir la velocidad de la canción. A mayor valor mayor velocidad

y consecuentemente a menor valor menor velocidad. Se calcula con ciertos programas

directamente del archivo de audio. Hay reglas no escritas que dicen que hay que duplicar

el valor que se obtenga. En la realidad ese valor sea como sea (doblándolo o

triplicándolo) debería ser superior a 150 y menor a 400. Fuera de esos límites no es

aconsejable hacer una canción.

#GAP

Etiqueta de carácter obligatorio. Es la pausa en milisegundos desde que comienza

a sonar la canción hasta que se comienza a cantar, comienza la letra. Ajustar bien este

valor es vital para hacer bien una canción. Normalmente se calcula a ojo y luego se va

ajustando según quede mejor o peor.

#START

Etiqueta de carácter opcional. Es el numero de segundos en el que va a empezar

la canción. Sirve por ejemplo para si el archivo de audio tiene 3 segundos de silencio

podamos ponerle #START:3 y que así empiece directamente con la música.

#END

Etiqueta de carácter opcional. Es el número de milisegundos en el que va a

terminar la canción. Se utiliza para terminar una canción justo a la vez que el video o para

acortarla si hay mucho tiempo en silencio hasta que se acaba.

#RELATIVE

Etiqueta de carácter opcional. Si está establecido a "YES" indica que en cada

línea que se escriba las notas comienzan desde la posición cero (como si siempre fuera

la primera línea de la canción) y no desde la posición que le debería corresponder si se

cuenta desde el inicio de la canción.

Hasta aquí todo lo referente a las etiquetas. Ahora se va a realizar una explicación

de cómo se deben expresar las notas y la letra para que la aplicación sea capaz de

establecer la correcta sincronización entre ellas.

Cosas que pueden aparecer en la primera columna:

28

A continuación se va a explicar el significado de los valores que aparecen junto a

estos símbolos. Para explicar esto, se va a utilizar una nota de ejemplo.

: 0 1 34 HA

El primer símbolo (:), nos indica que es una nota que debe de ser tratada y

puntuada de forma normal.

El número siguiente (0), indica el instante temporal en el que comienza a

ejecutarse la nota. Este valor está definido en tiempo de negra, es decir, en un minueto

hay tantos tiempos de negra como el valor del BPM multiplicado por cuatro, ya que en un

compás entran cuatro negras.

El siguiente valor (1), nos indica la nota en la escala MIDI a la que se debe cantar.

Como se puede apreciar, no hay información de la escala, por lo que solo se contemplan

12 notas MIDI.

El tercer valor (34), indica la duración de la nota en las mismas unidades que la

posición temporal.

Por último, la cadena de texto que le sigue (HA), indica la sílaba o sílabas que se

corresponden con dicha nota.

29

4.2.1.2. Archivo de audio

El archivo o pista de audio siempre debe de presentar el mismo nombre que el

que aparece en el archivo de texto citado anteriormente, sino, la aplicación nos dará

error.

La aplicación admite diferentes formatos de audio como WMA, AAC y FLAC

siendo el más común y usado el MP3.

En el caso de utilizar una codificación MP3 se debe de tener en cuenta que la

frecuencia de muestreo debe de ser igual o menor a 48.000Hz, pudiendo tomar valores

inferiores en los pasos siguientes: 44.100Hz, 22.050Hz, 16.000Hz y 8.000Hz. El bitrate

no tiene ninguna limitación por parte del sistema operativo y los elementos encargados

de la reproducción, pero se ha observado que los archivos codificados con bitrares

superiores a 720Kbps ocasionan errores en la reproducción.

4.2.1.3. Archivo de imagen

La imagen debe de presentar un formato que sea compatible con el sistema

operativo android. Este soporta los siguientes formatos: JPEG, BMP, PNG y GIF.

4.2.1.4. Archivo de video

Al igual que el archivo de audio y la imagen, el nombre de este archivo se debe

de corresponder con el indicado en la información del archivo de texto para evitar

posibles errores.

El formato de este archivo debe de ser MP4 o 3GP ya que las clases y métodos

implementados no reconocen otros distintos a estos. Se ha utilizado el codificador H.264

ya que el tamaño de este archivo no puede ser demasiado voluminoso y con este se

obtiene una calidad bastante aceptable. Además, este se tiene adaptar a la pantalla del

dispositivo, en este caso una Samsung Tab 3 cuya resolución es 1024x600.

4.3. VISTAS DE LA APLICACIÓN Y DIAGRAMAS DE FLUJO

Una vez conocido el formato que presenta la aplicación y los distintos archivos

que maneja para su correcta ejecución, se presentan las vistas que el usuario final

observará desde que inicia el karaoke hasta que finaliza la partida.

También aparecen los diagramas de flujo representando la lógica de cada una de

las actividades que conforman la aplicación.

30

4.3.1. Pantallas del karaoke

4.3.1.1. Pantalla principal

Al iniciar la aplicación, el usuario se encuentra con la pantalla mostrada en la

figura 10 donde aparece el menú principal del juego. Presenta un fondo colorido de libre

uso donde se han colocado diferentes destellos blancos, burbujas variadas y un rótulo

con el nombre del karaoke “KaraoKe” a través de un software de montaje fotográfico

Figura 10. Pantalla principal de la aplicación. Izquierda (español) y derecha (inglés).

En el centro de la pantalla se aprecia una serie de botones que permiten navegar

por las opciones que esta presenta.

Comenzando desde arriba hacia abajo se observa el primer botón “Elegir

canción”. Este permite iniciar el explorador de archivos, el cual será comentado más

adelante, para navegar y seleccionar el contenedor zip deseado y comenzar el juego,

conteniendo todos los archivos comentados anteriormente. Dicho explorador es una de

las actividades independientes, la cual podría ser ejecutada como tal.

31

Más abajo se encuentra el botón de “Jugar”. Este permite el comienzo del juego

una vez haya sido seleccionado un contenedor válido. Ejecuta la interfaz gráfica donde

de forma sincronizada aparecerá el video del archivo seleccionado junto con el audio

correspondiente. Se trata de una compleja actividad que será comentada más adelante.

Cabe destacar también que si no se ha seleccionado ningún archivo, la aplicación lanzará

un cuadro de diálogo indicando que se seleccione un archivo para cantar como se

observa en la figura 11.

Figura 11. Cuadro de diálogo indicando la selección de un archivo. Izq (español) y der (inglés).

A continuación se observa el botón de “Ajustes”. Este dirige a una nueva pantalla

donde aparecen todos los ajustes que se le pueden aplicar al karaoke. En este caso, no

se trata de una nueva actividad, si no de una pantalla perteneciente a la aplicación

principal, por lo que se modificará la vista del menú.

Más abajo de los ajustes aparece el botón de “Info. Canción”. Este muestra la

información que aparece en el archivo .txt del contenedor zip seleccionado a través de

32

una lista desplazable. Al igual que ocurre con el botón de ajustes, este nos dirige a una

nueva pantalla distinta a la vista del menú principal. También muestra el cuadro de

diálogo de seleccione un archivo para cantar si no se ha seleccionado ningún contenedor

con anterioridad.

Por último, aparece el botón de “Salir”. Permite al usuario abandonar la aplicación,

matando todos los procesos, liberando los recursos y restaurando el estado de la tableta.

La figura 12 muestra este cuadro de diálogo.

Figura 12. Cuadro de diálogo para abandonar la aplicación. Izq (español) y derecha (inglés).

Como se observa en la figura 12, al pulsar este botón se lanzará un nuevo cuadro

de diálogo donde se pedirá previa confirmación para abandonar la aplicación, de este modo,

finalizarán las tareas anteriormente citadas.

La figura 13 representa el diagrama de flujo simplificado de la pantalla principal, el

cual presenta una lógica similar a la de Paco Moreno “Figura 10”:

33

Figura 13. Diagrama de flujo de la pantalla principal. Proyecto de Paco Moreno “Figura 10”.

4.3.1.2. Pantalla del explorador de archivos

El explorador de archivos es el encargado de recorrer la estructura de directorios

del dispositivo para seleccionar un contenedor válido deseado. Como se comentó

anteriormente, este conforma una aplicación por sí solo, de modo que puede ser ejecutado

independientemente de cualquier otra. Cuando si pinche sobre el botón de “Elegir cancion”

aparecerán las siguientes vistas. Primero se selecciona el directorio storage

(almacenamiento), a continuación se pincha en extSdCard (memoria externa de tarjeta SD)

y finalmente se accede al directorio de CancionesK donde aparecerán los contenedores zip

para que una vez seleccionado el deseado, comience el juego.

34

1º Selección del directorio “storage” (figura14):

Figura 14. Navegación por el explorador de archivos. Selección de storage.

2º Selección del directorio “extSdCard” (figura 15):

Figura 15. Navegación por el explorador de archivos. Selección de extSdCard. Izq (español) y der (inglés).

35

3º Selección de la carpeta “CancionesK” (figura 16):

Figura 16. Navegación por el explorador de archivos. Selección del directorio CancionesK.

Finalmente seleccionamos el contenedor deseado (figura 17):

Figura 17. Navegación por el explorador de archivos. Selección de un contenedor.

El explorador de archivos es una aplicación independiente porque es una parte muy

importante y compleja del programa ya que se encarga de ir recorriendo el árbol de

directorios de la tableta y una vez que el usuario ha elegido un contenedor, este comprobará

si es válido o no. Si el explorador lo toma como válido, este lanzará un diálogo como

veremos a continuación con dos opciones, la de escuchar el archivo de audio almacenado

36

en dicho contenedor y seleccionarlo cuando se detenga su reproducción y la de elegir el

contenedor directamente. En ambos casos se procede a la descompresión de los archivos.

Cuando se decide escuchar, es el propio explorador el que reproduce la pista

musical hasta que el usuario decide detenerla para seleccionarla o seleccionar otro

contenedor. Si se decide seleccionar el contenedor sin previa reproducción, se procederá a

descomprimir los archivos contenidos por este, se leerá el archivo de texto y se

configurarán todas las variables necesarias para que la aplicación principal conozca toda la

información del tema seleccionado.

A continuación se muestra en la figura 18 el cuadro de diálgo que permite reproducir

la pista o seleccionar directamente el contenedor deseado, en la figura 19 la descompresión

del contenedor, en la figura 20 la que permite detener la reproducción y la figura 21 cuando

se ha elegido un contenedor no válido.

Figura 18. Reproducir o elegir contenedor. Izquierda (español) y derecha (inglés).

37

Figura 19. Descomprimiendo contenedor zip. Izq (español) y der (inglés).

Figura 20. Reproducción de la pista de audio. Izq (español) y der (inglés).

38

Figura 21. Archivo seleccionado no válido. Izq (español) y der (inglés).

La figura 22 representa el diagrama de flujo simplificado de la aplicación. Ha sido

utilizado el diagrama de Paco Moreno “Figura 19”:

Figura 22. Diagrama de la aplicación del explorador de archivos. Proyecto de Paco Moreno “Figura 19”.

39

4.3.1.3. Pantalla de ajustes

En el tercer botón de nuestro menú principal aparecen los ajustes. Este abre una

nueva pantalla en la que aparecen las diferentes opciones a ajustar. Lo primero que se

muestra es la dificultad pudiéndose elegir entre tres niveles: baja, media y alta.

En otras configuraciones aparece la opción de poder reproducir el video que aparece

en el contenedor seleccionado, elimandolo de fondo cuando no es marcada dicha opción.

Otra opción que es muy importante es la de guardado en caché. Esto permite o no,

que la aplicación pueda almacenar en la memoria externa del dispositivo los archivos

descomprimidos durante su ejecución, los cuales no serán reconocidos como archivos

multimedia por parte del dispositivo ya que se ha tenido en cuenta. Además, elimina el

tiempo de descompresión al elegir un contenedor que haya descomprimido anteriormente, lo

que supone un importante ahorro de espera.

El inconveniente que presenta el guardado en caché es la falta de espacio en

tabletas con bajo nivel de memoria disponible. Aunque estos dispositivos están siendo

creados cada vez con mayores capacidades, la aplicación se ha diseñado para que siempre

quede un 10% total de memoria disponible, de modo que si se supera este porcentaje, los

archivos serán borrados cuando termine la aplicación. A continuación se muestra en la

figura 23, la vista lanzada al pulsar sobre el botón de ajustes

Figura 23. Pantalla de ajustes. Izq (español) y der (inglés).

40

4.3.1.4. Pantalla de información de canción

Como ocurre en el caso de los ajustes, cuando se pulsa el botón de información

se muestra una nueva pantalla sin la necesidad de ejecutar una nueva actividad.

Esta nueva vista va a estar formada por una serie de parámetros que

representan la información contenida por las cabeceras del archivo de texto almacenado en

el contenedor zip seleccionado. Si se pulsa sobre este botón sin la selección previa de un

contenedor válido, se lanzará el cuadro de diálogo comentado anteriormente indicando que

se debe de seleccionar un archivo. Si el contenedor si ha sido elegido anteriormente, esta

nueva pantalla muestra la figura 24.

Figura 24. Pantalla de información de canción. Izq (español) y der (inglés).

4.3.1.5. Pantalla de juego

Cuando se pulsa el botón de jugar, se pondrá en marcha una actividad que será la

encargada de activar el motor del karaoke, siempre y cuando haya sido seleccionado un

contenedor ZIP válido con anterioridad. Si no es así, la aplicación lanzará el cuadro de

dialogo comentado anteriormente indicando que se elija un archivo para cantar.

41

Si ha sido seleccionado el archivo, comienza a ejecutarse una compleja aplicación

que también podría ser ejecutada por sí sola como en el caso del explorador. Dicha

aplicación se encarga de la sincronización perfecta de cuatro hebras que son:

Hebra de la interfaz gráfica.

Hebra encargada de capturar la información a través del micrófono para su

posterior cálculo de F0.

Hebra encargada de comparar entre lo cantado y la partitura y definir lo que

se debe dibujar por pantalla.

Hebra encargada de la reproducción del video de fondo en una vista

transparente.

Cuando se pulsa el botón de jugar, la primera vista que aparece es la siguiente la

cual indica que se toque la pantalla para que comience la partida. El jugador comenzará el

juego en breves tras pulsar la pantalla. La figura 25 representa esta pantalla.

Figura 25. Pantalla comienzo de juego. Arriba (español) y abajo (inglés).

42

Tras pulsar la pantalla, el videoclip del contenedor seleccionado comenzará a

reproducirse, al igual que el archivo de audio siempre y cuando se haya consumido en

tiempo de VIDEOGAP (tiempo que transcurre desde el comienzo del videoclip hasta el

comienzo del audio). La vista que aparece es la siguiente en la cual se indica al jugador que

se prepare. La figura 26 muestra la pantalla que aparece hasta que da comienzo la letra de

la canción.

Figura 26. Pantalla hasta que se comienza a cantar. Arriba (español) y abajo (inglés).

Una vez que se comienza a cantar, la nueva vista que aparece es la del karaoke

completo donde se puede visualizar el videoclip de fondo, el marcador donde se indica la

puntuación que va obteniendo el jugador a lo largo de la partida, el tiempo total y el

transcurrido de la canción, la letra de la canción, doce líneas que conforma el pentagrama

43

MIDI, las notas que deben de ser cantadas en color verde y las notas cantadas por el

jugador en color rosa. La figura 27 representa la pantalla de juego.

Figura 27. Pantalla de juego cantando.

La figura 28 hace una representación temporal de la sincronización de las cuatro

hebras utilizadas. Diagrama perteneciente al proyecto de Paco Moreno “Figura 27”.

Figura 28. Sincronización temporal de las hebras principales. Proyecto de Paco Moreno “Figura 27”.

A continuación se justifica la información que se intercambia en las diferentes hebras

representadas en la figura 28.

Cuando el botón de jugar es pulsado, se lanza la hebra de la interfaz de

usuario en la que aparece el mensaje de “La partida comenzará cuando

44

pulses la pantalla (figura 28)”, tras pulsarla, dicha interfaz se actualiza

mostrando el mensaje de “Prepárate (figura 29)” lanzando una segunda hebra

encargada de la reproducción del video.

Si el video presenta un valor positivo de VIDEOGAP, la reproducción de la

música comenzará cuando este haya sido consumido, en caso contrario, la

música iniciará su reproducción a la misma vez que el video de forma

sincronizada.

El archivo de audio suele presentar unos segundos de GAP (tiempo

transcurrido desde que comienza la canción hasta que el artista empieza a

cantar), cuando este ha sido consumido, el usuario comienza a cantar, de

modo que la aplicación lanza la hebra de grabación de voz y cálculo de la F0.

Cada vez que el cálculo ha sido realizado, se comparan estas frecuencias en

escala MIDI con las que presenta el archivo de texto de la canción y en

función de la dificultad que se haya seleccionado, se asigna una puntuación u

otra. Finalmente se actualiza la interfaz de usuario donde se modificará la

puntación y letra de texto en caso de que comience una nueva línea.

Este ciclo de capturar información y obtener F0, calcular puntuación y

actualizar interfaz de usuario y el dibujado de la pantalla se va repitiendo

hasta que tanto el video como la pista de audio finalizan.

Todas las clases, métodos y variables utilizados para el correcto funcionamiento de

estas cuatro hebras aparecen definidas en el Anexo II donde aparece toda la documentación

técnica de la aplicación.

Una vez que la partida haya finalizado, se muestra un nuevo mensaje en la pantalla

diciendo: “Buena partida!! Pulsa atrás para continuar”. Tras pulsar el botón de retroceso del

dispositivo, se vuelve a mostrar la pantalla del menú principal, y la aplicación estará lista

para elegir otro archivo diferente y jugar una partida de nuevo.

45

La vista que se obtiene es la que aparece en la figura 29.

Figura 29. Pantalla de finalización de la partida. Arriba (español) y abajo (inglés).

4.3.2. Salir

Se ha comentado al inicio del punto 4.3.1.1. Pantalla principal que cuando se pulsa

el botón de salir, se muestra un cuadro de diálogo pidiendo confirmación para abandonar la

aplicación o para continuar en ella.

46

Si la opción deseada es la de abandonar la aplicación, se comprueba la variable

encargada de determinar si está activo o no el guardado en caché, si está habilitado se

comprueba el espacio libre en el dispositivo y entonces se determina el borrado o no de la

carpeta que contiene los archivos en función de los parámetros medidos.

A continuación se muestra en la figura 30, el diagrama de flujo que representa la

rutina llevada a cabo al recibir el evento de salir. Diagrama equivalente al que aparece en el

proyecto de Paco Moreno “Figura31”.

Figura 30. Diagrama de flujo del evento salir. Proyecto de Paco Moreno “Figura 31”.

5. RESULTADOS Y DISCUSIÓN

5.1. TRABAJO FINAL OBTENIDO

El trabajo final obtenido ha sido una aplicación de karaoke llamada “KaraoKe” para

tabletas con sistema operativo android.

Con esta aplicación se puede disfrutar de unas divertidas partidas de karaoke

sintiéndose un cantante profesional imitando a grupos o artistas favoritos. También se puede

47

ajustar la dificultad del juego para aquellos que no andan muy afinados en las primeras

partidas.

5.2. PROBLEMAS ENCONTRADOS

En la realización del proyecto han aparecido una serie de problemas los cuales son

citados a continuación.

Un problema importante , el cual no ha sido corregido aún en las nuevas versiones

de android, es la gestión de la rotación de la interfaz de usuario ya que debido a sensores

como el acelerómetro, la tableta cambia la vista según la posición. Aunque se puede

seleccionar en el menú de android la opción de no rotación de pantalla, no se quiere dejar

esta tarea para que la tenga en cuenta el usuario final. Se trata de un problema bastante

importante ya que, cuando ocurre un cambio en la configuración de la tableta (en este caso

la orientación), android construye y reconstruye todas las actividades que se estén

ejecutando o aquellas que se encontraban pausadas con el fin de prepararlas para el

momento en el que el usuario interactúe nuevamente con ellas. De modo que si la partida

está en juego, reproduciéndose el video y audio correspondiente y dibujando en la interfaz

de usuario los distintos elementos como marcador, letra, pentagrama…etc y se detecta un

cambio de orientación en el dispositivo, la partida se reiniciará comenzando de nuevo y

restableciendo toda variable. Para solucionar este problema, como en la mayoría de las

aplicaciones de esta plataforma, se he decidido fijar la pantalla de juego en modo horizontal

de manera permanente, de esta forma, aunque se detecte un cambio en la orientación de la

tableta, la aplicación no sufrirá una reiniciación.

También se ha decidido fijar la pantalla del menú principal en vertical, no por ningún

motivo importante, simplemente por la comodidad de no estar cambiando la orientación

continuamente ya que se trata de un dispositivo de considerable tamaño.

Un problema no resuelto aún es tener que modificar las sílabas acentuadas de las

palabras pertenecientes a una canción que aparecen en el archivo txt almacenado en el

contenedor ZIP, ya que el sistema no las reconoce y lo que hace es colocar una

interrogación en ellas.

Otro problema es la limitación de espacio de memoria disponible para una aplicación

en ejecución. Android limita este espacio de memoria, de modo que la RAM siempre tiende

a llenarse hasta dejar un pequeño margen de maniobra, cuyo objetivo es la eficiencia del

dispositivo. Las tabletas android cada vez presentan mayor memoria interna y RAM, por lo

que el problema pierde algo de importancia. De todos modos, el sistema operativo no debe

de trabajar con variables de gran tamaño ni retener instancias de archivos de gran tamaño

48

durante un largo periodo de tiempo. Es por esto por lo que se decide utilizar el codificador de

video H.264 aconsejando no obtener archivos de video de gran tamaño asegurando una

máxima capacidad de los contenedores ZIP para un adecuado funcionamiento.

5.3. LÍNEAS DE FUTURO

El trabajo fin de grado desarrollado se puede complementar con diferentes ideas

surgidas durante la implementación de la aplicación de karaoke por parte de Paco Moreno

para smartphones android, y en el desarrollo de esta para tabletas android. A continuación

se citan algunas de estas interesantes ideas la cuales pueden ser aprovechadas para

futuros trabajos fin de grado.

Corregir el problema de lectura de palabras acentuadas por parte del sistema.

Utilización de otro formato de karaoke que lo haga más eficiente.

Mejorar los formatos soportados tanto de audio como de video.

Mejorar las capacidades de configuración de la aplicación.

Posibilidad de registro de usuario con nombre y contraseña donde aparezca el

record de puntuación o las puntuaciones obtenidas en partidas anteriores.

Uso de micrófono externo USB .

Posibilidad de partida dual entre dos usuarios.

Creación de un acceso directo en la aplicación para la descarga de los contenedores

deseados a través de un servidor alojado en una nube.

Modificar la aplicación para adaptarla a redes sociales como pueden ser Facebook y

Twitter.

6. CONCLUCIONES

6.1. CONCLUSIONES OBTENIDAS

Realizando una valoración de la aplicación, se llega a la conclusión de que el trabajo

de fin de grado realizado, basado en una aplicación de karaoke para tabletas que soportan

la plataforma android, ha sido un gran acierto. Esto se debe a que a pesar de los distintos

sistemas operativos presentes en el mercado como son Microsoft, BlackBerry o IOS, android

acapara el 85% de cuota de mercado en teléfonos inteligentes y tabletas. Un dato de record

que se traduce en una gran oportunidad para desarrolladores android ya que se genera una

gran demanda de todo tipo de aplicaciones para usuarios con diferentes tendencias y sobre

todo en la difusión de la aplicación llevada a cabo.

La posibilidad de poder presentar la aplicación en inglés cuando el idioma de la

tableta se configure de este modo, es muy beneficioso, ya que cuando la aplicación esté

49

disponible en el Play Store, podrá ser bajada por personas con dicha habla, de modo que el

número de descargar aumentaría considerablemente.

También, una gran ventaja que presenta el trabajo realizado es la compatibilidad con

la plataforma libre de Ultrastar, ya que no es necesario realizar una base de datos donde se

almacenen los distintos archivos a utilizar y lo más complejo, la realización del archivo de

texto donde se indica toda la información del tema seleccionado junto con la letra de la

canción, tipo de notas, nota en la escala MIDI y duración de la misma.

Además la aplicación implementa el algoritmo desarrollado por investigadores de la

Escuela Politécnica Superior de Linares, que permite la estimar la frecuencia fundamental

de la voz cantada mediante técnicas de bajo consumo energético, dotando a dicha

aplicación de una mayor eficiencia.

7. PLIEGO DE CONDICIONES

7.1. REQUISITOS DE LA APLICACIÓN

El trabajo de fin de grado desarrollado, una aplicación de karaoke llamada KaraoKe,

necesita de una tableta que soporte la plataforma android la cual debe de presentar una

versión de dicho sistema operativo comprendido entre la 2.2 (froyo) y la 4.4(KitKat) para su

correcto funcionamiento.

Otro requisito muy importante es la existencia de una tarjeta de memoria externa sd

con suficiente espacio de memoria libre, aproximadamente superior a los 200MB para

almacenar y descomprimir los contenedores ZIP. El tamaño disponible no debe de ser

inferior a este ya que los videos que va a utilizar la aplicación van a presentar un tamaño

considerable para que a la hora de jugar, el usuario pueda disfrutar de una reproducción

más que decente, teniendo siempre en cuenta que los contenedores de gran tamaño

pueden provocar la saturación de la aplicación.

Como se ha nombrado anteriormente, la aplicación ha sido probada a lo largo de

todo el proceso en una Samsung Tab 3, con una velocidad de CPU de 1,2Ghz, por lo que

para tabletas con mayor procesador no debe existir ningún problema. No se ha podido

probar para tabletas con inferior CPU por falta de disposición de estas pero si ha sido

instalada en un dispositivo móvil que trabaja a 800Mhz y ha respondido correctamente.

7.2. CARACTERÍSTICAS DEL DISPOSITIVO DE DESARROLLO

50

A continuación se muestran las características aportadas por el fabricante del

dispositivo utilizado para la realización de todo el banco de pruebas durante el desarrollo de

la aplicación. Se ha trabajado con una tableta Samsung Tab 3.

51

52

8. ANEXOS

8.1. ANEXO I. INSTRUCCIONES PARA JUGAR

En este primer anexo se va a explicar los pasos a seguir para que el usuario final

pueda disfrutar de la aplicación desarrollada.

8.1.1. Instrucciones para jugar

El objetivo del manual es hacer que la primera experiencia que tenga el usuario

con la aplicación sea lo más sencilla y agradable posible. Para ello se comenta cada una de

las acciones que se deben de ir haciendo y la configuración a realizar a través de imágenes

hasta que la partida finalice.

Primero. Configurar el programa.

Cuando se arranca el programa, lo primero que se debe de hacer es dirigirse a la

opción de ajustes donde se va a realizar una serie de configuraciones (figura 31).

Figura 31. Botón ajustes seleccionado.

53

Dentro de esta opción, el usuario primeramente puede elegir entre tres niveles de

dificultad, baja, media y alta.

Se puede ajustar el volumen de comienzo de la partida.

Se puede elegir entre la opción de reproducir video de fondo o no. Si no es

reproducido, la letra de la canción, pentagrama, marcador y temporizador serán mostrados

sobre un fondo negro.

También se recomienda mantener la opción de guardado en caché seleccionada ya

que va a permitir al usuario un importante ahorro de tiempo en posteriores elecciones de

contenedores que hayan sido elegidos y descomprimidos con anterioridad.

Segundo. Elegir canción.

Una vez que se haya configurado el dispositivo, se pasa a la selección de la canción

deseada, como muestra la figura 32. Para ello pinchamos en elegir canción.

Figura 32. Botón de elegir canción seleccionado.

54

Tras pinchar, el explorador de archivos se pone en marcha permitiendo al usuario

navegar por el árbol de directorios hasta llegar a la carpeta CancionesK en este caso, y

seleccionar el archivo deseado. Una vez elegido el contenedor, aparecerá la opción de

reproducir su archivo de audio o elegirlo directamente sin previa reproducción. La figura 32

muestra dos vistas del explorador de archivos.

Si se quiere retroceder porque se haya elegido una carpeta errónea, se debe pinchar

el volver y no en retroceder ya que entonces da por finalizada la búsqueda y abre de nuevo

el menú principal.

Figura 32. Explorador de archivos.

Tercero. Información canción.

Cuando la canción haya sido elegida, el usuario puede pinchar en el botón de Info.

canción antes de iniciar la partida, para observar toda la información del tema seleccionado

donde se puede encontrar el nombre del tema, artista, cover… etc. La figura 33 muestra el

botón de Info. Canción pulsado y la figura 34 la información de la canción elegida.

55

Figura 33. Selección Info. Canción. Figura 34. Información de la canción elegida.

Cuarto. Jugar.

Por último, cuando ya esté todo configurado y la canción elegida, puede comenzar la

partida. Para ello se pulsa el botón de jugar (figura 35) y el usuario solo tiene que hacer caso

de los mensajes que van apareciendo en pantalla y a cantar como muestran las figuras 36,

37, 38 y 39.

Figura 35. Selección Jugar.

56

Figura 36. Pantalla comienzo de juego.

Figura 37. Pantalla hasta que se comienza a cantar.

Figura 38. Pantalla de juego.

57

Figura 39. Pantalla fin de juego.

8.1.2. Cambios en la tableta

Cuando iniciamos la aplicación se realizarán una serie de cambios en el dispositivo

los cuales serán fijos o no en función de si la opción de guardado en caché está

seleccionada. Cuando descomprimimos un contenedor ZIP por primera vez, se crea un

nuevo directorio con nombre “cancionesTemp” en la memoria externa del dispositivo donde

aparecen los diferentes archivos que este contenía. Se le ha asignado este nombre porque

dicha carpeta puede ser borrada (siempre de forma manual y con la opción de guardado en

caché deshabilitada) cuando el usuario lo crea conveniente, por lo que tiene una duración

temporal. También encontramos dentro de esta carpeta el archivo “.nomedia”, el cual indica

al sistema operativo que tanto los archivos de música descomprimidos como los de audio no

sean alistados en las lista de reproducción de la tableta, de modo que estos archivos solo

aparecerán en la aplicación y no en la biblioteca del dispositivo.

58

8.2. ANEXO II. DOCUMENTACIÓN TÉCNICA

A continuación se presenta la documentación técnica que ha sido desarrollada a lo

largo de este trabajo fin de grado. Esta incluye las siete clases creadas con cada uno de sus

métodos y variables principales para el correcto funcionamiento de la aplicación. Además,

se hace una justificación de la sincronización de las hebras utilizadas a la hora de cantar en

la clase “MotorApp” y se muestra un diagrama de flujo del proceso desde que se captura el

audio hasta que se obtiene el valor de la nota para ser representada en la escala MIDI.

Dejar claro que las clases en las que se ha guiado este proyecto modificándolas para

el diseño llevado acabo pertenecen al proyecto final de carrera de Paco Moreno, citado

anteriormente y en la bibliografía. Estas son:

AndroidExplorer

DroidKaraoke

EstimadorF0

JuegoMotor

JuegoView

TraducirArchivo

VideoView

All Classes

CalculoF0

DescripcionProgramaK

ExploradorArchivos

LecturaDeTxt

MotorApp

VideoView

VistaJuego

Package com.example.ejemplooooooo

Class Summary

Class Description

CalculoF0 Clase encargada de implementar unas serie de métodos para calcular la frecuencia

fundamental de la voz del usuario, captada a través del micrófono.

DescripcionProgramaK Clase encargada de implementar los métodos necesarios para la representación

general del programa, correspondiéndose con el menú principal de la aplicación.

59

ExploradorArchivos Clase encargada de generar el explorador de archivos para la búsqueda y selección

de estos.

LecturaDeTxt Clase encargada de traducir el archivo de texto almacenada en el contenedor de

cada canción para leer toda su información.

MotorApp Clase encargada de implentar toda la parte del juego de la aplicación.

VideoView Clase encargada de alojar el video de la canción elegida para jugar.

VistaJuego Clase encargada de representar en la interfaz de usuario todo lo que comprende la

pantalla de juego del karaoke.

60

CLASES

com.example.ejemplooooooo

Class CalculoF0

java.lang.Object

com.example.ejemplooooooo.CalculoF0

public class CalculoF0

extends java.lang.Object

Clase encargada de implementar unas serie de métodos para calcular la frecuencia

fundamental de la voz del usuario, captada a través del micrófono.

Constructor Summary

Constructors

Constructor and Description

CalculoF0()

Method Summary

All Methods

Modifier and Type Method and Description

double[] func_diff(double[] x, int fs, int S)

Método encargado de calcular la frecuencia fundamental de la voz

cantada.

61

Methods inherited from class java.lang.Object

equals, getClass, hashCode, notify, notifyAll, toString, wait, wait,

wait.

Constructor Detail

CalculoF0

public CalculoF0()

Method Detail

func_diff

public double[] func_diff(double[] x,

int fs,

int S)

Método encargado de calcular la frecuencia fundamental de la voz cantada.

Parameters:

x - Señal recogida por el micrófono.

fs - Frecuencia de muestreo de la grabación.

S - Número de sumas que realiza la función diferencia.

Returns:

Vector con las frecuencias que el algoritmo calcula en cada

ventana.

62

com.example.ejemplooooooo

Class DescripcionProgramaK

java.lang.Object

Activity

com.example.ejemplooooooo.DescripcionProgramaK

public class DescripcionProgramaK

extends Activity

Clase encargada de implementar los métodos necesarios para la representación general del programa, correspondiéndose con el menú principal de la aplicación.

Field Summary

Fields

Modifier and Type Field and Description

static

java.lang.String

CONFIGURACION

Constante que permite guardar en caché la configuración realizada

en el juego

static int DIF_ALTA

Constante encargada de determinar la dificultad de la partida.

static int DIF_BAJA

Constante encargada de determinar la dificultad de la partida.

static int DIF_MEDIA

Constante encargada de determinar la dificultad de la partida.

63

Constructor Summary

Constructors

Constructor and Description

DescripcionProgramaK()

Method Summary

All Methods

Modifier and Type Method and Description

void ajustes(View v)

Método llamado cuando se pulsa un elemento activo de la vista.

void ErrorExtensionArchivo()

Método encargado de lanzar un cuadro de diálogo indicando que el

archivo seleccionado presenta una extensión no válida.

boolean getPlaying()

Método llamado para modificar el valor de la variable que define el estado

de la aplicación.

void infoCancion(View v)

Método llamado cuando se pulsa un elemento activo de la vista.

void informacionCancion()

Método llamado para mostrár la información de la canción seleccionada.

void jugarApp(View v)

Método llamado cuando se pulsa un elemento activo de la vista.

void onAjustes()

Método llamado para generar la vista de la pantalla de ajustes al pulsar

dicho botón

64

void onBackPressed()

Método llamado al pulsar el botón de retroceso.

void onClick(DialogInterface dialog, int which)

void onCreate(Bundle savedInstanceState)

Método llamado cuando la actividad se crea por primerz vez.

void onRestoreInstanceState(Bundle savedInstanceState)

Método llamado para recuperar las instancias almacenadas con

anterioridad.

void onSaveInstanceState(Bundle savedInstanceState)

Método llamado cuando se desea almacenar diferentes instancias del

programa.

void salida(View v)

Método llamado cuando se pulsa un elemento activo de la vista.

void salir()

Método llamado cuando se decide finalizar la aplicación.

void seleccion(View v)

Método llamado cuando se pulsa un elemento activo de la vista.

void seleccionarArchivo()

void setPlaying(boolean valor)

Método llamado para modificar el valor de la variable que define el estado

de la aplicación.

void surfaceChanged(SurfaceHolder holder, int format,

int width, int height)

Método llamado después de cualquier cambio estructural en la superficie.

void surfaceCreated(SurfaceHolder holder)

Método llamado después de crear la primera superficie.

65

void surfaceDestroyed(SurfaceHolder holder)

Método llamado antes de la destrucción de la superficie.

Methods inherited from class java.lang.Object

equals, getClass, hashCode, notify, notifyAll, toString, wait, wait,

wait.

Field Detail

DIF_BAJA

public static final int DIF_BAJA

Constante encargada de determinar la dificultad de la partida.

See Also:

Constant Field Values

DIF_MEDIA

public static final int DIF_MEDIA

Constante encargada de determinar la dificultad de la partida.

See Also:

Constant Field Values

DIF_ALTA

public static final int DIF_ALTA

Constante encargada de determinar la dificultad de la partida.

See Also:

Constant Field Values

66

CONFIGURACION

public static final java.lang.String CONFIGURACION

Constante que permite guardar en caché la configuración realizada en el juego

See Also:

Constant Field Values

Method Detail

onCreate

public void onCreate(Bundle savedInstanceState)

Método llamado cuando la actividad se crea por primerz vez.

onBackPressed

public void onBackPressed()

Método llamado al pulsar el botón de retroceso.

onAjustes

public void onAjustes()

Método llamado para generar la vista de la pantalla de ajustes al pulsar dicho botón.

ajustes

public void ajustes(View v)

Método llamado cuando se pulsa un elemento activo de la vista. En este caso el botón de

Ajustes.

salida

public void salida(View v)

Método llamado cuando se pulsa un elemento activo de la vista. En este caso el botón de Salir.

67

infoCancion

public void infoCancion(View v)

Método llamado cuando se pulsa un elemento activo de la vista. En este caso el botón de Info.

canción.

Selección

public void seleccion(View v)

Método llamado cuando se pulsa un elemento activo de la vista. En este caso el botón de Elegir

canción.

jugarApp

public void jugarApp(View v)

Método llamado cuando se pulsa un elemento activo de la vista. En este caso el botón de Jugar.

onSaveInstanceState

public void onSaveInstanceState(Bundle savedInstanceState)

Método llamado cuando se desea almacenar diferentes instancias del programa.

onRestoreInstanceState

public void onRestoreInstanceState(Bundle savedInstanceState)

Método llamado para recuperar las instancias almacenadas con anterioridad.

setPlaying

public void setPlaying(boolean valor)

Método llamado para modificar el valor de la variable que define el estado de la aplicación.

getPlaying

68

public boolean getPlaying()

Método llamado para modificar el valor de la variable que define el estado de la aplicación.

salir

public void salir()

Método llamado cuando se decide finalizar la aplicación.

informacionCancion

public void informacionCancion()

Método llamado para mostrar la información de la canción seleccionada.

ErrorExtensionArchivo

public void ErrorExtensionArchivo()

Método encargado de lanzar un cuadro de diálogo indicando que el archivo seleccionado

presenta una extensión no válida.

seleccionarArchivo

public void seleccionarArchivo()

Método que nos informa de que el archivo seleccionado no es correcto o no ha sido

seleccionado.

surfaceCreated

public void surfaceCreated(SurfaceHolder holder)

Método llamado después de crear la primera superficie.

surfaceChanged

public void surfaceChanged(SurfaceHolder holder,

int format,

int width,

int height)

Método llamado después de cualquier cambio estructural en la superficie.

69

surfaceDestroyed

public void surfaceDestroyed(SurfaceHolder holder)

Método llamado antes de la destrucción de la superficie.

onClick

public void onClick(DialogInterface dialog,

int which)

70

com.example.ejemplooooooo

Class ExploradorArchivos

java.lang.Object

ListActivity

com.example.ejemplooooooo.ExploradorArchivos

public class ExploradorArchivos

extends ListActivity

Clase encargada de generar el explorador de archivos para la búsqueda y selección de estos.

Field Summary

Fields

Modifier and Type Field and Description

static

java.lang.String

CACHE

Constante para conocer cual es la cache de la informacion.

java.lang.String mp3Seleccionado

Constante para conocer la ruta del archivo seleccionado.

java.lang.String zipElegido

Constante para conocer la ruta del contenedor zip seleccionado.

71

Constructor Summary

Constructors

Constructor and Description

ExploradorArchivos()

Method Summary

All Methods

Modifier and Type Method and Description

void cuaDiaArchivoCorrecto(java.io.File file)

Método encargado de lanzar un cuadro de diálogo cuando se selecciona un

archivo correcto.

void cuaDiaArchivoIncorrecto(java.lang.String msg)

Método encargado de lanzar un cuadro de diálogo cuando se selecciona un

archivo correct

java.lang.String descomprimirZIP(java.io.File file)

Método encargado de descomprimir todos los archivos pertenecientes al

contenedor seleccionado.

void dialogoDescomprimiendo()

Método encargado de mostrar el cuadro de diálogo de descomprimir.

double espacioLibreSD()

Método encargado de comprabar el espacio libre disponible en la

memoria externa SD.

void nuevaEntradaCache(java.lang.String nombre)

Método que permite almacenar en caché una nueva entrada para la

descompresión de un contenedor.

72

void onBackPressed()

Método llamado cuando se pulsa el botón de retroceso.

void onCreate(Bundle savedInstanceState)

Método llamado cuando la actividad se crea por primerz vez.

void posibilidadSD()

Método encargado de comprobar que la memoria está presente y

correctamente disponible.

void setMP3(java.lang.String path)

Método llamado para configurar la variable MP3Seleccionado.

void terminarDialogoDescomprimiendo()

Método encargado de eliminar el cuadro de diálogo de descomprimiendo.

boolean validezZIP(java.lang.String nombre)

Método encargado de comprobar la validez del contenedor ZIP

seleccionado.

Methods inherited from class java.lang.Object

equals, getClass, hashCode, notify, notifyAll, toString, wait, wait,

wait.

Field Detail

CACHE

public static final java.lang.String CACHE

Constante para conocer cual es la cache de la informacion.

See Also:

Constant Field Values

mp3Seleccionado

public java.lang.String mp3Seleccionado

Constante para conocer la ruta del archivo seleccionado.

73

zipElegido

public java.lang.String zipElegido

Constante para conocer la ruta del contenedor zip seleccionado.

Constructor Detail

ExploradorArchivos

public ExploradorArchivos()

Method Detail

onCreate

public void onCreate(Bundle savedInstanceState)

Método llamado cuando la actividad se crea por primerz vez.

descomprimirZIP

public java.lang.String descomprimirZIP(java.io.File file)

throws java.io.IOException

Método encargado de descomprimir todos los archivos pertenecientes al contenedor

seleccionado.

Parameters:

file - Ruta del archivo seleccionado para descomprimir.

Throws:

java.io.IOException

espacioLibreSD

public double espacioLibreSD()

Método encargado de comprabar el espacio libre disponible en la memoria externa SD.

Returns:

Devuelve el espacio disponible en megabits.

74

posibilidadSD

public void posibilidadSD()

Método encargado de comprobar que la memoria está presente y correctamente disponible.

onBackPressed

public void onBackPressed()

Método llamado cuando se pulsa el botón de retroceso.

cuaDiaArchivoCorrecto

public void cuaDiaArchivoCorrecto(java.io.File file)

Método encargado de lanzar un cuadro de diálogo cuando se selecciona un archivo correcto.

Parameters:

file - Objeto seleccionado.

setMP3

public void setMP3(java.lang.String path)

Método llamado para configurar la variable MP3Seleccionado.

Parameters:

path - Dirección del archivo que contiene la canción

seleccionada.

cuaDiaArchivoIncorrecto

public void cuaDiaArchivoIncorrecto(java.lang.String msg)

Método encargado de lanzar un cuadro de diálogo cuando se selecciona un archivo correct

Parameters:

msg - Mensaje que aparece en el título del cuadro de diálogo.

dialogoDescomprimiendo

public void dialogoDescomprimiendo()

Método encargado de mostrar el cuadro de diálogo de descomprimir.

75

terminarDialogoDescomprimiendo

public void terminarDialogoDescomprimiendo()

Método encargado de eliminar el cuadro de diálogo de descomprimiendo.

validezZIP

public boolean validezZIP(java.lang.String nombre)

Método encargado de comprobar la validez del contenedor ZIP seleccionado.

Parameters:

nombre - Dirección del contenedor ZIP a comprobar.

nuevaEntradaCache

public void nuevaEntradaCache(java.lang.String nombre)

Método que permite almacenar en caché una nueva entrada para la descompresión de un

contenedor.

Parameters:

nombre – Ruta del contenedor que se desea almacenar en caché.

76

com.example.ejemplooooooo

Class LecturaDeTxt

java.lang.Object

com.example.ejemplooooooo.LecturaDeTxt

public class LecturaDeTxt

extends java.lang.Object

Clase encargada de traducir el archivo de texto almacenada en el contenedor de cada canción para leer toda su información.

Field Summary

Fields

Modifier and Type Field and Description

static int ARTIST

Constante para el artista de la canción.

static int BACKGROUND

Constante para el nombre de la imagen de fondo de la canción si no se

reproduce el video.

static int BPM

Constante para el número de beats por minuto de la canción.

static int COVER

Constante para el nombre de la imagen de la carátula del disco.

static int CREATOR

77

Constante para el creador del contenedor de la canción.

static int DORADA

Constante para nota dorada.

static int DOSPUNTOS

Constante para nota de estilo normal.

static int EDITION

Constante para la edición de la canción.

static int END

Constante para el valor a partir del cual se comienza a reproducir la

pista de audio.

static int GAP

Constante para el número de milisegundos que transcurren desde el

inicio de la pista de audio hasta que se debe capturar informacion del

micrófono.

static int GENRE

Constante para el género musical de la canción.

java.lang.String[] info

Cadena de caracteres que contiene la información del archivo de

texto.

static int LANGUAGE

Constante para el idioma de la canción.

java.lang.String[] letra

Cadena de caracteres que contiene la letra de la canción para

representar por pantalla, que presenta el archivo de texto.

static int LIBRE

Constante para nota de estilo libre.

static int MP3

78

Constante para el nombre de la pista de audio de la canción.

int[][] notas

Matriz entera que contiene las notas del archivo de texto.

int numNotas

Número de notas que se muestran por pantalla.

static int RELATIVE

Constante para el valor que especifica un tratamiento especial a las

notas.

static int SALTOLINEA

Constante para indicador de salto de linea.

static int START

Constante para el número de segundos que se encuentra desfasado el

videoclip con la pista de audio.

static int TITLE

Constante para el título de la canción.

static int VIDEO

Constante para el nombre del videoclip de la canción.

static int VIDEOGAP

Constante para el número de segundos que se encuentra desfasado el

video de la pista de audio.

static int YEAR

Constante para el año de la canción.

79

Constructor Summary

Constructors

Constructor and Description

LecturaDeTxt()

Method Summary

All Methods

Modifier and Type Method and Description

int colocarDatos(java.lang.String a)

Método encargado de localizar las notas del archivo de texto y

almacenarlas en la posición correspondiente dentro de la matriz notas.

java.lang.String colocarInformacion(java.lang.String ruta)

Método encargado de obtener la información que presenta el documento

de texto y colocarla en su posición correspondiente dentro del vector de

información.

java.lang.String traducirTxt(java.lang.String archivo)

Método encargado de leer el archivo txt entero para pasarlo a String y así

poder trabajar con él para obtener toda la información.

Methods inherited from class java.lang.Object

equals, getClass, hashCode, notify, notifyAll, toString, wait, wait,

wait.

80

Field Detail

TITLE

public static final int TITLE

Constante para el título de la canción.

See Also:

Constant Field Values

ARTIST

public static final int ARTIST

Constante para el artista de la canción.

See Also:

Constant Field Values

LANGUAGE

public static final int LANGUAGE

Constante para el idioma de la canción.

See Also:

Constant Field Values

EDITION

public static final int EDITION

Constante para la edición de la canción.

See Also:

Constant Field Values

GENRE

public static final int GENRE

Constante para el género musical de la canción.

See Also:

Constant Field Values

YEAR

public static final int YEAR

81

Constante para el año de la canción.

See Also:

Constant Field Values

CREATOR

public static final int CREATOR

Constante para el creador del contenedor de la canción.

See Also:

Constant Field Values

MP3

public static final int MP3

Constante para el nombre de la pista de audio de la canción.

See Also:

Constant Field Values

COVER

public static final int COVER

Constante para el nombre de la imagen de la carátula del disco.

See Also:

Constant Field Values

BACKGROUND

public static final int BACKGROUND

Constante para el nombre de la imagen de fondo de la canción si no se reproduce el video.

See Also:

Constant Field Values

82

VIDEO

public static final int VIDEO

Constante para el nombre del videoclip de la canción.

See Also:

Constant Field Values

VIDEOGAP

public static final int VIDEOGAP

Constante para el número de segundos que se encuentra desfasado el video de la pista de

audio.

See Also:

Constant Field Values

BPM

public static final int BPM

Constante para el número de beats por minuto de la canción.

See Also:

Constant Field Values

GAP

public static final int GAP

Constante para el número de milisegundos que transcurren desde el inicio de la pista de audio

hasta que se debe capturar informacion del micrófono.

See Also:

Constant Field Values

START

public static final int START

Constante para el número de segundos que se encuentra desfasado el videoclip con la pista de

audio.

See Also:

83

Constant Field Values

END

public static final int END

Constante para el valor a partir del cual se comienza a reproducir la pista de audio.

See Also:

Constant Field Values

RELATIVE

public static final int RELATIVE

Constante para el valor que especifica un tratamiento especial a las notas.

See Also:

Constant Field Values

DOSPUNTOS

public static final int DOSPUNTOS

Constante para nota de estilo normal.

See Also:

Constant Field Values

LIBRE

public static final int LIBRE

Constante para nota de estilo libre.

See Also:

Constant Field Values

DORADA

public static final int DORADA

Constante para nota dorada.

See Also:

Constant Field Values

84

SALTOLINEA

public static final int SALTOLINEA

Constante para indicador de salto de linea.

See Also:

Constant Field Values

info

public java.lang.String[] info

Cadena de caracteres que contiene la información del archivo de texto.

notas

public int[][] notas

Matriz entera que contiene las notas del archivo de texto.

numNotas

public int numNotas

Número de notas que se muestran por pantalla.

letra

public java.lang.String[] letra

Cadena de caracteres que contiene la letra de la canción para representar por pantalla, que

presenta el archivo de texto.

Constructor Detail

LecturaDeTxt

public LecturaDeTxt()

85

Method Detail

colocarInformacion

public java.lang.String colocarInformacion(java.lang.String ruta)

Método encargado de obtener la información que presenta el documento de texto y colocarla

en su posición correspondiente dentro del vector de información.

colocarDatos

public int colocarDatos(java.lang.String a)

Método encargado de localizar las notas del archivo de texto y almacenarlas en la posición

correspondiente dentro de la matriz notas.

traducirTxt

public java.lang.String traducirTxt(java.lang.String archivo)

Método encargado de leer el archivo txt entero para pasarlo a String y así poder trabajar con él

para obtener toda la información.

86

com.example.ejemplooooooo

Class MotorApp

java.lang.Object

Activity

com.example.ejemplooooooo.MotorApp

public class MotorApp

extends Activity

Clase encargada de implementar toda la parte del juego de la aplicación.

Field Summary

Fields

Modifier and Type Field and Description

static

java.lang.String

buena

Variable encargada de almacenar un string de espera, el

cual permite su traducción al inglés: Buena partida

static

java.lang.String

cuando

Variable encargada de almacenar un string de espera, el

cual permite su traducción al inglés: cuando pulses la

pantalla

static

java.lang.String

laPartida

Variable encargada de almacenar un string de espera, el

cual permite su traducción al inglés: La partida comenzará

87

static

java.lang.String

preparate

Variable encargada de almacenar un string de espera, el

cual permite su traducción al inglés: Prepárate

static

java.lang.String

pulsaAtras

Variable encargada de almacenar un string de espera, el

cual permite su traducción al inglés: Pulsa atrás para

continuar.

Constructor Summary

Constructors

Constructor and Description

MotorApp()

Method Summary

All Methods

Modifier and Type Method and Description

void actualizarF0()

Método encargado de llamar a la hebra de la interfaz gráfica para que

represente en esta las notas de la canción, las notas cantadas por el

usuario, temporizador y marcador en función de la dificultad elegida.

void actualizarMicro()

Método encargado de lanzar las hebras de capturar información y

calcular la F0.

void calcularF0()

88

Método encargado de crear una hebra para calcular la frecuencia a partir

de la información que ha sido capturada por parte del micrófono, de

manera no bloqueante.

void calcularPuntuacionDificil(int[] frecuencias,

int indice)

Método encargado de realizar el calculo de la puntuación para el nivel

fácil.

void calcularPuntuacionFacil(int[] frecuencias, int indice)

Método encargado de realizar el calculo de la puntuación para el nivel

fácil.

void calcularPuntuacionMedia(int[] frecuencias, int indice)

Método encargado de realizar el calculo de la puntuación para el nivel

fácil.

int calcularTamañoBuffer(int BPM)

Método encargado de calcular el tamaño del buffer de la información

recogida por el micrófono.

java.lang.String colocarLetra(int ind)

Método encargado de concatenar las sílabas correspondientes a una línea

en función del índice que indica el comienzo de una nueva línea.

int[] conseguirF0()

Método encargado de realizar el calculo de la F0 de la información

captada por parte del micrófono.

void detectarSaltosLinea()

Método encargado de ir detentando los saltos de línea que aparecen en el

archivo de texto del contenedor elegido.

89

int[] filtroMediana()

Método encargado de realizar un filro de mediana a las frecuencias

obtenidas.

int freq2MIDI(double freq)

Método encargado de calcular el equivalente MIDI de cada frecuencia

estimada mediante la función diferencia implementada.

double[] getMicro()

Método encargado de recoger la información procedente del micrófono y

formatearla para que sea almacenada en el vector.

void grabarMicrofono()

Método encargado de crear una hebra para grabar la información

captada por el micrófono de manera no bloqueante.

void onBackPressed()

Método llamado cuando se pulsa el botón de retroceso, finalizando la

reproducción de audio, video, grabación y encendido permanente de la

pantalla.

void onCreate(Bundle savedInstanceState)

Método llamado cuando la actividad se crea por primerz vez.

boolean onTouch(View v, MotionEvent event)

Método llamado cuando un evento táctil aparece en esta vista.

void rellenarLineaNotas()

Método encargado de rellenar una matriz con las notas teniendo en

cuenta su posición, duración, valor midi y cuando el tramtamienta de

esta sea un salto de línea.

Methods inherited from class java.lang.Object

90

equals, getClass, hashCode, notify, notifyAll, toString, wait, wait,

wait

Constructor Detail

MotorApp

public MotorApp()

Method Detail

onCreate

public void onCreate(Bundle savedInstanceState)

Método llamado cuando la actividad se crea por primerz vez.

onTouch

public boolean onTouch(View v,

MotionEvent event)

Método llamado cuando un evento táctil aparece en esta vista. Se utiliza para dar comienzo al

juego.

onBackPressed

public void onBackPressed()

Método llamado cuando se pulsa el botón de retroceso, finalizando la reproducción de audio,

video, grabación y encendido permanente de la pantalla.

calcularTamañoBuffer

public int calcularTamañoBuffer(int BPM)

Método encargado de calcular el tamaño del buffer de la información recogida por el

micrófono.

Parameters:

BPM - Número de bits por minuto de la canción elegida.

91

Returns:

Tamaño del buffer en función del número de notas, frecuencia de

muestreo, número de canales, tamaño de cada muestra (16 bits) y

BPM.

grabarMicrofono

public void grabarMicrofono()

Método encargado de crear una hebra para grabar la información captada por el micrófono de

manera no bloqueante.

calcularF0

public void calcularF0()

Método encargado de crear una hebra para calcular la frecuencia a partir de la información

que ha sido capturada por parte del micrófono, de manera no bloqueante.

actualizarMicro

public void actualizarMicro()

Método encargado de lanzar las hebras de capturar información y calcular la F0.

actualizarF0

public void actualizarF0()

Método encargado de llamar a la hebra de la interfaz gráfica para que represente en esta las

notas de la canción, las notas cantadas por el usuario, temporizador y marcador en función de

la dificultad elegida.

getMicro

public double[] getMicro()

Método encargado de recoger la información procedente del micrófono y formatearla para que

sea almacenada en el vector.

Returns:

Vector con la información normalizada.

92

freq2MIDI

public int freq2MIDI(double freq)

Método encargado de calcular el equivalente MIDI de cada frecuencia estimada mediante la

función diferencia implementada.

Parameters:

freq - Frecuencia estimada por parte de la función diferencia.

Returns:

El valor MIDI de la freq estimada.

conseguirF0

public int[] conseguirF0()

Método encargado de realizar el calculo de la F0 de la información captada por parte del

micrófono.

Returns:

Vector con las frecuencias calculadas en MIDI.

filtroMediana

public int[] filtroMediana()

Método encargado de realizar un filro de mediana a las frecuencias obtenidas. Permite corregir

errores en la estimación del pitch debido a la aparición de cambios bruscos en este,

quedándose con el valor que queda en el medio.

Returns:

Vector con las frecuencias calculadas filtradas.

detectarSaltosLinea

public void detectarSaltosLinea()

Método encargado de ir detentando los saltos de línea que aparecen en el archivo de texto del

contenedor elegido.

93

colocarLetra

public java.lang.String colocarLetra(int ind)

Método encargado de concatenar las sílabas correspondientes a una línea en función del índice

que indica el comienzo de una nueva línea.

Parameters:

ind - Índice que indica el comienzo de una nueva línea.

Returns:

Línea indicada por el índice con todas sus sílabas concatenadas.

rellenarLineaNotas

public void rellenarLineaNotas()

Método encargado de rellenar una matriz con las notas teniendo en cuenta su posición,

duración, valor midi y cuando el tramtamienta de esta sea un salto de línea.

calcularPuntuacionDificil

public void calcularPuntuacionDificil(int[] frecuencias,

int indice)

Método encargado de realizar el calculo de la puntuación para el nivel fácil.

Parameters:

frecuencias - Vector con las frecuencias fundamentales

calculadas en escala MIDI.

indice - Indica las notas del archivo de texto que se toman para

realizar la comparación.

calcularPuntuacionMedia

public void calcularPuntuacionMedia(int[] frecuencias,

int indice)

Método encargado de realizar el calculo de la puntuación para el nivel fácil.

Parameters:

frecuencias - Vector con las frecuencias fundamentales

calculadas en escala MIDI.

94

indice - Indica las notas del archivo de texto que se toman para

realizar la comparación.

calcularPuntuacionFacil

public void calcularPuntuacionFacil(int[] frecuencias,

int indice)

Método encargado de realizar el calculo de la puntuación para el nivel fácil.

Parameters:

frecuencias - Vector con las frecuencias fundamentales

calculadas en escala MIDI.

indice - Indica las notas del archivo de texto que se toman para

realizar la comparación.

A continuación se explica la sincronización de lós métodos que son puestos en

marcha a la hora de cantar, ya que es una parte compleja e importante de la aplicación.

Cuando el tiempo de GAP ha sido consumido (tiempo transcurrido desde el

comienzo de la canción hasta que empieza la letra de la canción), comienza a ejecutarse

el método citado anteriormente “grabarMicrófono”, dentro del cual, se encuentra el

método “getMicro”, encargado de capturar y normalizar los datos de audio

almacenándolos en un array double. Además se activa un ejecutable que se encarga de

ejcutar los métodos de “grabarMicro” y “calcularF0” mientras la letra de la canción no

finalice.

Una vez que el buffer ha sido completado, se le pasa al método “calcularF0”,

dentro del cual, se encuentra el método “conseguirF0” lanzando la clase “CalculoF0” para

obtener las frecuncias fundamentales de la voz del usuario a través del algoritmo que

implementa la función diferencia.

Un tema muy importante en este apartado es la perfecta sincronización entre los

distintos métodos utilizados para captar los datos de audio y calcular la frecuencia

fundamental, ya que varios procesos intentan acceder a los mismos recursos. Por ello, se

requiere una sincronización que permita a un solo proceso acceder a estos recursos en

un instante determinado. Visto de otro modo, con los métodos correctamente

95

sincronizados, no se va a realizar el cálculo de la frecuencia fundamental de la voz hasta

que el micrófonono no haya finalizado el llenado del buffer. Del mismo modo, no se

comienza a grabar de nuevo hasta que no se hayan obtenido las frecuencias

fundamentales.

Por último, cuando se obtiene el vector con las frecuencias fundamentales en

hercios, se obtiene el equivalente MIDI de cada una de ellas y se le aplica un filtro de

mediana para suavizar la señal estimada y así evitar posibles errores. Este proceso se

repite hasta que la letra de la canción finaliza como se ha comentado anteriormente.

La figura 40 representa este proceso.

Figura 40. Diagrama de flujo del proceso de captura del audio hasta la obtención de la nota MIDI.

96

com.example.ejemplooooooo

Class VideoView

java.lang.Object

SurfaceView

com.example.ejemplooooooo.VideoView

public class VideoView

extends SurfaceView

Clase encargada de alojar el video de la canción elegida para jugar. Extiende de la clasesurfaceView la cual proporciona una superficie de dibujo dentro de una jerarquía de vistas.

Nested Class Summary

Nested Classes

Modifier and Type Class and Description

class VideoView.HebraVideo

Clase encargada de generar una hebra para la reproducción del video.

Field Summary

Fields

Modifier and Type Field and Description

java.lang.String videoPath

97

Constructor Summary

Constructors

Constructor and Description

VideoView(Context context, AttributeSet attrs)

Constructor de la clase VideoView.

Method Summary

All Methods

Modifier and Type Method and Description

VideoView.HebraVideo getThread()

Método que devuelve la instancia creada por la clase VideoView.

void iniciarHebra()

Método encargado de iniciar la instancia de de la hebra del video.

void stopThread()

Método que finaliza la instancia de la hebra del video.

void surfaceChanged(SurfaceHolder holder, int format,

int width, int height)

Método llamado después de cualquier cambio estructural en la

superficie.

void surfaceCreated(SurfaceHolder holder)

Método llamado después de crear la primera superficie.

void surfaceDestroyed(SurfaceHolder holder)

Método llamado antes de la destrucción de la superficie.

98

Methods inherited from class java.lang.Object

equals, getClass, hashCode, notify, notifyAll, toString, wait, wait,

wait.

Field Detail

videoPath

public java.lang.String videoPath

Constructor Detail

VideoView

public VideoView(Context context,

AttributeSet attrs)

Constructor de la clase VideoView.

Parameters:

context - Contexto desde el que ha sido creada la vista.

attrs - Atributos que se pasan a la vista.

Method Detail

getThread

public VideoView.HebraVideo getThread()

Método que devuelve la instancia creada por la clase VideoView.

Returns:

Objeto de la clase HebraVideo.

stopThread

public void stopThread()

Método que finaliza la instancia de la hebra del video.

99

iniciarHebra

public void iniciarHebra()

Método encargado de iniciar la instancia de de la hebra del video.

surfaceChanged

public void surfaceChanged(SurfaceHolder holder,

int format,

int width,

int height)

Método llamado después de cualquier cambio estructural en la superficie.

surfaceCreated

public void surfaceCreated(SurfaceHolder holder)

Método llamado después de crear la primera superficie.

surfaceDestroyed

public void surfaceDestroyed(SurfaceHolder holder)

Método llamado antes de la destrucción de la superficie. Bloquea el proceso terminando su

ejecución.

100

com.example.ejemplooooooo

Class VideoView.HebraVideo

java.lang.Object

java.lang.Thread

com.example.ejemplooooooo.VideoView.HebraVideo

All Implemented Interfaces:

java.lang.Runnable

Enclosing class:

VideoView

public class VideoView.HebraVideo

extends java.lang.Thread

Clase encargada de generar una hebra para la reproducción del video.

Nested Class Summary

Nested classes/interfaces inherited from class java.lang.Thread

java.lang.Thread.State, java.lang.Thread.UncaughtExceptionHandler

Field Summary

Fields

Modifier and Type Field and Description

java.lang.String videoPath

Fields inherited from class java.lang.Thread

101

MAX_PRIORITY, MIN_PRIORITY, NORM_PRIORITY

Constructor Summary

Constructors

Constructor and Description

HebraVideo(SurfaceHolder surfaceHolder, Context context)

Method Summary

All Methods

Modifier and Type Method and Description

void doStart()

Método llamado al crearse la hebra.

void kill()

Método que se ejecuta cuando la hebra finaliza, deteniendo y liberando

el archivo de video.

void run()

Método que se ejecuta cuando la hebra es lanzada.

Methods inherited from class java.lang.Thread

activeCount, checkAccess, countStackFrames, currentThread, destroy,

dumpStack, enumerate, getAllStackTraces, getContextClassLoader,

getDefaultUncaughtExceptionHandler, getId, getName, getPriority,

getStackTrace, getState, getThreadGroup, getUncaughtExceptionHandler,

holdsLock, interrupt, interrupted, isAlive, isDaemon, isInterrupted,

join, join, join, resume, setContextClassLoader, setDaemon,

setDefaultUncaughtExceptionHandler, setName, setPriority,

102

setUncaughtExceptionHandler, sleep, sleep, start, stop, stop,

suspend, toString, yield

Methods inherited from class java.lang.Object

equals, getClass, hashCode, notify, notifyAll, wait, wait, wait

Field Detail

videoPath

public java.lang.String videoPath

Constructor Detail

HebraVideo

public HebraVideo(SurfaceHolder surfaceHolder,

Context context)

Method Detail

doStart

public void doStart()

Método llamado al crearse la hebra.

run

public void run()

Método que se ejecuta cuando la hebra es lanzada.

Specified by:

run in interface java.lang.Runnable

Overrides:

run in class java.lang.Thread

103

kill

public void kill()

Método que se ejecuta cuando la hebra finaliza, deteniendo y liberando el archivo de video.

104

com.example.ejemplooooooo

Class VistaJuego

java.lang.Object

View

com.example.ejemplooooooo.VistaJuego

public class VistaJuego

extends View

Clase encargada de representar en la interfaz de usuario todo lo que comprende la pantalla de juego del karaoke.

Field Summary

Fields

Modifier and Type Field and Description

static int CANTANDO_STD

Constante para indicar que el estado de la partida está en juego.

static int ESPERA_STD

Constante para indicar que el estado de la partida de juego está en

espera.

int estado

Variable que guarda el estado en el que se encuentra la partida de juego.

static int FINAL_STD

Constante para indicar que la partida ha finalizado.

105

static int GAP_STD

Constante para indicar que el estado de la partida se encuentra en la

consumición del tiempo de la canción hasta que el artista comienza a

cantar.

Constructor Summary

Constructors

Constructor and Description

VistaJuego(Context context)

Constructor de la clase VistaJuego.

VistaJuego(Context context, AttributeSet attrs)

Constructor de la clase VistaJuego con el conjunto de atributos que se le pasan a la instancia.

Method Summary

All Methods

Modifier and Type Method and Description

void actualizarLetra(java.lang.String s)

Método encargado de actualizar la letra por pantalla de la canción

conforme vaya transcurriendo.

void actualizarMarcador(long p)

Método encargado de actualizar la puntuación del marcador presente en

la pantalla.

void actualizarT(int actual, int total)

Método encargado de mostrar la duración total del archivo de audio e ir

106

actualizando el tiempo que transcurre desde el inicio hasta el final de la

pista.

void ajustarPosicionNotasArtista(int[][] notas, int inicio,

int fin)

Método encargado de calcular la posición de las notas originales en

función de la linea cantada, pentagrama y pantalla.

void ajustarPosicionNotasUsuario(int valor,

int notasPorPantalla, boolean nuevaPantalla)

Método encargado de calcular la posición de las notas originales cantadas

por el usuario, en función del valor MIDI, número de notas, pentagrama

y pantalla.

void ajustarPuntosPentagrama()

Método encargado de calcular la posición de las líneas del pentagrama.

int[] calcularCoordenadas(java.lang.String s,

boolean primera)

Método encargado de calcular las coordenadas para colocar el texto que

se dirige al usuario, de manera que este quede centrado en la pantalla del

dispositivo.

void modificarEstado(int estado)

Método encargado de modificar el estado de la aplicación.

void modificarPosicionLetra()

Método encargado de modificar el valor de la posición de la letra la cual

queda centrada en función del tamaño de esta, el ancho de la pantalla y el

númmero de letras de cada línea.

void modificarPosicionMarcador()

Método encardado de modificar el valor de la posición del marcador.

void modificarPosicionTemporizador()

Método encargado de modificar el valor de la posición del temporizador.

Methods inherited from class java.lang.Object

107

equals, getClass, hashCode, notify, notifyAll, toString, wait, wait,

wait

Field Detail

ESPERA_STD

public static final int ESPERA_STD

Constante para indicar que el estado de la partida de juego está en espera.

See Also:

Constant Field Values

GAP_STD

public static final int GAP_STD

Constante para indicar que el estado de la partida se encuentra en la consumición del tiempo

de la canción hasta que el artista comienza a cantar.

See Also:

Constant Field Values

CANTANDO_STD

public static final int CANTANDO_STD

Constante para indicar que el estado de la partida está en juego.

See Also:

Constant Field Values

FINAL_STD

public static final int FINAL_STD

Constante para indicar que la partida ha finalizado.

See Also:

108

Constant Field Values

estado

public int estado

Variable que guarda el estado en el que se encuentra la partida de juego.

Constructor Detail

VistaJuego

public VistaJuego(Context context)

Constructor de la clase VistaJuego.

Parameters:

context - Contexto desde el que ha sido creada la vista.

VistaJuego

public VistaJuego(Context context,

AttributeSet attrs)

Constructor de la clase VistaJuego con el conjunto de atributos que se le pasan a la instancia.

Parameters:

context - Contexto desde el que ha sido creada la vista.

attrs - Atributos que se pasan a la vista

Method Detail

actualizarLetra

public void actualizarLetra(java.lang.String s)

Método encargado de actualizar la letra por pantalla de la canción conforme vaya

transcurriendo.

Parameters:

s - Casena de caracteres con la letra de la nueva línea.

109

modificarEstado

public void modificarEstado(int estado)

Método encargado de modificar el estado de la aplicación.

Parameters:

estado - Variable indicando el nuevo estado.

actualizarMarcador

public void actualizarMarcador(long p)

Método encargado de actualizar la puntuación del marcador presente en la pantalla.

Parameters:

p - Valor de la nueva puntuación.

actualizarT

public void actualizarT(int actual,

int total)

Método encargado de mostrar la duración total del archivo de audio e ir actualizando el tiempo

que transcurre desde el inicio hasta el final de la pista.

Parameters:

actual - Variable de tiempo con el valor de la canción actual.

total - Variable de tiempo con el valor de la canción total.

modificarPosicionLetra

public void modificarPosicionLetra()

Método encargado de modificar el valor de la posición de la letra la cual queda centrada en

función del tamaño de esta, el ancho de la pantalla y el númmero de letras de cada línea.

110

modificarPosicionMarcador

public void modificarPosicionMarcador()

Método encardado de modificar el valor de la posición del marcador.

modificarPosicionTemporizador

public void modificarPosicionTemporizador()

Método encargado de modificar el valor de la posición del temporizador.

ajustarPuntosPentagrama

public void ajustarPuntosPentagrama()

Método encargado de calcular la posición de las líneas del pentagrama.

ajustarPosicionNotasUsuario

public void ajustarPosicionNotasUsuario(int valor,

int notasPorPantalla,

boolean nuevaPantalla)

Método encargado de calcular la posición de las notas originales cantadas por el usuario, en

función del valor MIDI, número de notas, pentagrama y pantalla.

Parameters:

valor - Valor MIDI de la nota cantada por el usuario.

notasPorPantalla - Notas mostradas por pantalla.

nuevaPantalla - Variable boolena que indica si se actualiza la

pantalla.

ajustarPosicionNotasArtista

public void ajustarPosicionNotasArtista(int[][] notas,

int inicio,

int fin)

Método encargado de calcular la posición de las notas originales en función de la linea

cantada, pentagrama y pantalla.

111

Parameters:

notas - Matriz con las notas del tema elegido.

inicio - Variable indicando el inicio de línea.

fin - Variable indicando el final de línea.

calcularCoordenadas

public int[] calcularCoordenadas(java.lang.String s,

boolean primera)

Método encargado de calcular las coordenadas para colocar el texto que se dirige al usuario, de

manera que este quede centrado en la pantalla del dispositivo.

Parameters:

s - Cadena de caracteres a representar.

primera - Variable booleana indicando si la cadena de texto va

en la primera línea o en la segunda.

Returns:

Coordenadas con la posición de la cadena de texto.

A continuación se explica el método de puntuación utilizado en función del nivel de

dificultad elegido.

El sistema de puntuación se basa en la comparación de los equivalentes MIDI de las

frecuencias fundamentales obtenidas y los valores de las notas MIDI que aparecen en el

archivo de texto de la canción elegida. Para convertir un valor de frecuencia en Hz a un

número MIDI se utiliza la siguiente ecuación.

𝑀𝐼𝐷𝐼 = 69 + 12𝑙𝑜𝑔 𝑓𝑟𝑒𝑐

440 / log 2 (10)

donde MIDI es el número MIDI, frec es la frecuenica y el logaritmo es en base 10.

112

Una vez que los valores MIDI han sido obtenidos con la fórmula x, la puntuación en

función del nivel de dificultad se realizará de la siguiente manera:

o Dificultad baja: La puntuación sube al marcador cuando el valor MIDI del usuario

coincide con el valor MIDI del txt, cuando el valor MIDI del usuario esté un semitono

por arriba o por abajo del valor MIDI del txt, cuando el valor MIDI del usuario esté dos

semitonos por arriba o por abajo del valor MIDI del txt o cuando el valor MIDI del

usuario esté tres semitonos por arriba o por abajo del valor MIDI del txt. En estos tres

casos el usuario será puntuado sumando una cantidad de puntos en función de cada

canción.

o Dificultad media: La puntuación sube al marcador cuando el valor MIDI del usuario

coincide con el valor MIDI del txt, cuando el valor MIDI del usuario esté un semitono

por arriba o por abajo del valor MIDI del txt o cuando el valor MIDI del usuario esté

dos semitonos por arriba o por abajo del valor MIDI del txt. En este caso aumenta la

dificultad ya que el usuario no será puntuado cuando su valor MIDI esté tres

semitonos por arriba o por abajo o en cualquier otro caso que no sea el descrito

anteriormente.

o Dificultad alta: El usuario solo será puntuado cuando su valor MIDI coincida con el

valor MIDI del txt o cuando el valor MIDI del usuario este un semitono por arriba o

por abajo del valor MIDI del txt, en cualquier otro caso no subirá puntuación alguna al

marcador.

La figura 40 muestra el diagrama de flujo del proceso llevado a cabo.

113

Figura 41. Diagrama de flujo del sistema de puntuación.

114

USE

Uses of Package

com.example.ejemplooooooo

Classes in com.example.ejemplooooooo used by com.example.ejemplooooooo

Class and Description

VideoView.HebraVideo

Clase encargada de generar una hebra para la reproducción del video.

115

TREE

Hierarchy For Package com.example.ejemplooooooo

Class Hierarchy

o java.lang.Object

o Activity

o com.example.ejemplooooooo.MotorApp

o Activity

o com.example.ejemplooooooo.DescripcionProgramaK

o com.example.ejemplooooooo.CalculoF0

o com.example.ejemplooooooo.LecturaDeTxt

o ListActivity

o com.example.ejemplooooooo.ExploradorArchivos

o SurfaceView

o com.example.ejemplooooooo.VideoView

o java.lang.Thread (implements java.lang.Runnable)

o com.example.ejemplooooooo.VideoView.HebraVideo

o View

o com.example.ejemplooooooo.VistaJuego

116

DEPRECATED

Deprecated API

Contents

117

HELP

How This API Document Is Organized

This API (Application Programming Interface) document has pages corresponding to the items

in the navigation bar, described as follows.

Package

Each package has a page that contains a list of its classes and interfaces, with a summary for each. This page can contain six categories:

Interfaces (italic) Classes Enums Exceptions Errors Annotation Types

Class/Interface

Each class, interface, nested class and nested interface has its own separate page. Each of these pages has three sections consisting of a class/interface description, summary tables, and detailed member descriptions:

Class inheritance diagram Direct Subclasses All Known Subinterfaces All Known Implementing Classes Class/interface declaration Class/interface description Nested Class Summary Field Summary Constructor Summary Method Summary Field Detail Constructor Detail Method Detail

Each summary entry contains the first sentence from the detailed description for that item. The summary entries are alphabetical, while the detailed descriptions are in the order they appear in the source code. This preserves the logical groupings established by the programmer.

Annotation Type

Each annotation type has its own separate page with the following sections:

Annotation Type declaration Annotation Type description

118

Required Element Summary Optional Element Summary Element Detail

Enum

Each enum has its own separate page with the following sections:

Enum declaration Enum description Enum Constant Summary Enum Constant Detail

Use

Each documented package, class and interface has its own Use page. This page describes what packages, classes, methods, constructors and fields use any part of the given class or package. Given a class or interface A, its Use page includes subclasses of A, fields declared as A, methods that return A, and methods and constructors with parameters of type A. You can access this page by first going to the package, class or interface, then clicking on the "Use" link in the navigation bar.

Tree (Class Hierarchy)

There is a Class Hierarchy page for all packages, plus a hierarchy for each package. Each hierarchy page contains a list of classes and a list of interfaces. The classes are organized by

inheritance structure starting with java.lang.Object. The interfaces do not inherit

from java.lang.Object.

When viewing the Overview page, clicking on "Tree" displays the hierarchy for all packages.

When viewing a particular package, class or interface page, clicking "Tree" displays the hierarchy for only that package.

Deprecated API

The Deprecated API page lists all of the API that have been deprecated. A deprecated API is not recommended for use, generally due to improvements, and a replacement API is usually given. Deprecated APIs may be removed in future implementations.

Index

The Index contains an alphabetic list of all classes, interfaces, constructors, methods, and fields.

Prev/Next

These links take you to the next or previous class, interface, package, or related page.

Frames/No Frames

These links show and hide the HTML frames. All pages are available with or without frames.

All Classes

119

The All Classes link shows all classes and interfaces except non-static nested types.

Serialized Form

Each serializable or externalizable class has a description of its serialization fields and methods. This information is of interest to re-implementors, not to developers using the API. While there is no link in the navigation bar, you can get to this information by going to any serialized class and clicking "Serialized Form" in the "See also" section of the class description.

Constant Field Values

The Constant Field Values page lists the static final fields and their values.

This help file applies to API documentation generated using the standard doclet.

120

USE

Uses of Class com.example.ejemplooooooo.CalculoF0

No usage of com.example.ejemplooooooo.CalculoF0

121

Uses of Class com.example.ejemplooooooo.DescripcionProgramaK

No usage of com.example.ejemplooooooo.DescripcionProgramaK

122

Uses of Class com.example.ejemplooooooo.ExploradorArchivos

No usage of com.example.ejemplooooooo.ExploradorArchivos

123

Uses of Class com.example.ejemplooooooo.LecturaDeTxt

No usage of com.example.ejemplooooooo.LecturaDeTxt

124

Uses of Class com.example.ejemplooooooo.MotorApp

No usage of com.example.ejemplooooooo.MotorApp

125

Uses of Class com.example.ejemplooooooo.VideoView

No usage of com.example.ejemplooooooo.VideoView

126

Uses of Class com.example.ejemplooooooo.VistaJuego

No usage of com.example.ejemplooooooo.VistaJuego

127

INDEX

A

actualizarF0() - Method in class com.example.ejemplooooooo.MotorApp

Método encargado de llamar a la hebra de la interfaz gráfica para que represente en

esta las notas de la canción, las notas cantadas por el usuario, temporizador y

marcador en función de la dificultad elegida.

actualizarLetra(String) - Method in class com.example.ejemplooooooo.VistaJuego

Método encargado de actualizar la letra por pantalla de la canción conforme vaya

transcurriendo.

actualizarMarcador(long) - Method in class com.example.ejemplooooooo.VistaJuego

Método encargado de actualizar la puntuación del marcador presente en la pantalla.

actualizarMicro() - Method in class com.example.ejemplooooooo.MotorApp

Método encargado de lanzar las hebras de capturar información y calcular la F0.

actualizarT(int, int) - Method in class com.example.ejemplooooooo.VistaJuego

Método encargado de mostrar la duración total del archivo de audio e ir actualizando

el tiempo que transcurre desde el inicio hasta el final de la pista.

ajustarPosicionNotasArtista(int[][], int, int) - Method in class

com.example.ejemplooooooo.VistaJuego

Método encargado de calcular la posición de las notas originales en función de la linea

cantada, pentagrama y pantalla.

ajustarPosicionNotasUsuario(int, int, boolean) - Method in class

com.example.ejemplooooooo.VistaJuego

Método encargado de calcular la posición de las notas originales cantadas por el

usuario, en función del valor MIDI, número de notas, pentagrama y pantalla.

ajustarPuntosPentagrama() - Method in class com.example.ejemplooooooo.VistaJuego

Método encargado de calcular la posición de las líneas del pentagrama.

ajustes(View) - Method in class com.example.ejemplooooooo.DescripcionProgramaK

Método llamado cuando se pulsa un elemento activo de la vista.

ARTIST - Static variable in class com.example.ejemplooooooo.LecturaDeTxt

Constante para el artista de la canción.

128

129

B

BACKGROUND - Static variable in class com.example.ejemplooooooo.LecturaDeTxt

Constante para el nombre de la imagen de fondo de la canción si no se reproduce el

video.

BPM - Static variable in class com.example.ejemplooooooo.LecturaDeTxt

Constante para el número de beats por minuto de la canción.

buena - Static variable in class com.example.ejemplooooooo.MotorApp

Variable encargada de almacenar un string de espera, el cual permite su

traducción al inglés: Buena partida

130

C

CACHE - Static variable in class com.example.ejemplooooooo.ExploradorArchivos

Constante para conocer cual es la cache de la informacion.

calcularCoordenadas(String, boolean) - Method in class

com.example.ejemplooooooo.VistaJuego

Método encargado de calcular las coordenadas para colocar el texto que se dirige al

usuario, de manera que este quede centrado en la pantalla del dispositivo.

calcularF0() - Method in class com.example.ejemplooooooo.MotorApp

Método encargado de crear una hebra para calcular la frecuencia a partir de la

información que ha sido capturada por parte del micrófono, de manera no bloqueante.

calcularTamañoBuffer(int) - Method in class com.example.ejemplooooooo.MotorApp

Método encargado de calcular el tamaño del buffer de la información recogida por el

micrófono.

CalculoF0 - Class in com.example.ejemplooooooo

Clase encargada de implementar unas serie de métodos para calcular la frecuencia

fundamental de la voz del usuario, captada a través del micrófono.

CalculoF0() - Constructor for class com.example.ejemplooooooo.CalculoF0

CANTANDO_STD - Static variable in class com.example.ejemplooooooo.VistaJuego

Constante para indicar que el estado de la partida está en juego.

colocarDatos(String) - Method in class com.example.ejemplooooooo.LecturaDeTxt

Método encargado de localizar las notas del archivo de texto y almacenarlas en la

posición correspondiente dentro de la matriz notas.

colocarInformacion(String) - Method in class com.example.ejemplooooooo.LecturaDeTxt

Método encargado de obtener la información que presenta el documento de texto y

colocarla en su posición correspondiente dentro del vector de información.

colocarLetra(int) - Method in class com.example.ejemplooooooo.MotorApp

Método encargado de concatenar las sílabas correspondientes a una línea en función

del índice que indica el comienzo de una nueva línea.

131

com.example.ejemplooooooo - package com.example.ejemplooooooo

CONFIGURACION - Static variable in class

com.example.ejemplooooooo.DescripcionProgramaK

Constante que permite guardar en caché la configuración realizada en el juego

conseguirF0() - Method in class com.example.ejemplooooooo.MotorApp

Método encargado de realizar el calculo de la F0 de la información captada por parte

del micrófono.

COVER - Static variable in class com.example.ejemplooooooo.LecturaDeTxt

Constante para el nombre de la imagen de la carátula del disco.

CREATOR - Static variable in class com.example.ejemplooooooo.LecturaDeTxt

Constante para el creador del contenedor de la canción.

cuaDiaArchivoCorrecto(File) - Method in class

com.example.ejemplooooooo.ExploradorArchivos

Método encargado de lanzar un cuadro de diálogo cuando se selecciona un archivo

correcto.

cuaDiaArchivoIncorrecto(String) - Method in class

com.example.ejemplooooooo.ExploradorArchivos

Método encargado de lanzar un cuadro de diálogo cuando se selecciona un archivo

correct

cuando - Static variable in class com.example.ejemplooooooo.MotorApp

Variable encargada de almacenar un string de espera, el cual permite su

traducción al inglés: cuando pulses la pantalla

132

D

descomprimirZIP(File) - Method in class com.example.ejemplooooooo.ExploradorArchivos

Método encargado de descomprimir todos los archivos pertenecientes al contenedor

seleccionado.

DescripcionProgramaK - Class in com.example.ejemplooooooo

Clase encargada de implementar los métodos necesarios para la representación general

del programa, correspondiéndose con el menú principal de la aplicación.

DescripcionProgramaK() - Constructor for class

com.example.ejemplooooooo.DescripcionProgramaK

detectarSaltosLinea() - Method in class com.example.ejemplooooooo.MotorApp

Método encargado de ir detentando los saltos de línea que aparecen en el archivo de

texto del contenedor elegido.

dialogoDescomprimiendo() - Method in class

com.example.ejemplooooooo.ExploradorArchivos

Método encargado de mostrar el cuadro de diálogo de descomprimir.

DIF_ALTA - Static variable in class com.example.ejemplooooooo.DescripcionProgramaK

Constante encargada de determinar la dificultad de la partida.

DIF_BAJA - Static variable in class com.example.ejemplooooooo.DescripcionProgramaK

Constante encargada de determinar la dificultad de la partida.

DIF_MEDIA - Static variable in class com.example.ejemplooooooo.DescripcionProgramaK

Constante encargada de determinar la dificultad de la partida.

DORADA - Static variable in class com.example.ejemplooooooo.LecturaDeTxt

Constante para nota dorada.

133

DOSPUNTOS - Static variable in class com.example.ejemplooooooo.LecturaDeTxt

Constante para nota de estilo normal.

doStart() - Method in class com.example.ejemplooooooo.VideoView.HebraVideo

Método llamado al crearse la hebra.

134

E

EDITION - Static variable in class com.example.ejemplooooooo.LecturaDeTxt

Constante para la edición de la canción.

END - Static variable in class com.example.ejemplooooooo.LecturaDeTxt

Constante para el valor a partir del cual se comienza a reproducir la pista de audio.

ErrorExtensionArchivo() - Method in class

com.example.ejemplooooooo.DescripcionProgramaK

Método encargado de lanzar un cuadro de diálogo indicando que el archivo

seleccionado presenta una extensión no válida.

espacioLibreSD() - Method in class com.example.ejemplooooooo.ExploradorArchivos

Método encargado de comprabar el espacio libre disponible en la memoria externa SD.

ESPERA_STD - Static variable in class com.example.ejemplooooooo.VistaJuego

Constante para indicar que el estado de la partida de juego está en espera.

establecerPuntuacionDificil(int[], int) - Method in class

com.example.ejemplooooooo.MotorApp

establecerPuntuacionFacil(int[], int) - Method in class

com.example.ejemplooooooo.MotorApp

establecerPuntuacionMedia(int[], int) - Method in class

com.example.ejemplooooooo.MotorApp

estado - Variable in class com.example.ejemplooooooo.VistaJuego

Variable que guarda el estado en el que se encuentra la partida de juego.

ExploradorArchivos - Class in com.example.ejemplooooooo

135

Clase encargada de generar el explorador de archivos para la búsqueda y selección de

estos.

ExploradorArchivos() - Constructor for class

com.example.ejemplooooooo.ExploradorArchivos

136

F

filtroMediana() - Method in class com.example.ejemplooooooo.MotorApp

Método encargado de realizar un filro de mediana a las frecuencias obtenidas.

FINAL_STD - Static variable in class com.example.ejemplooooooo.VistaJuego

Constante para indicar que la partida ha finalizado.

freq2MIDI(double) - Method in class com.example.ejemplooooooo.MotorApp

Método encargado de calcular el equivalente MIDI de cada frecuencia estimada

mediante la función diferencia implementada.

func_diff(double[], int, int) - Method in class com.example.ejemplooooooo.CalculoF0

Método encargado de calcular la frecuencia fundamental de la voz cantada.

137

G

GAP - Static variable in class com.example.ejemplooooooo.LecturaDeTxt

Constante para el número de milisegundos que transcurren desde el inicio de la pista

de audio hasta que se debe capturar informacion del micrófono.

GAP_STD - Static variable in class com.example.ejemplooooooo.VistaJuego

Constante para indicar que el estado de la partida se encuentra en la consumición del

tiempo de la canción hasta que el artista comienza a cantar.

GENRE - Static variable in class com.example.ejemplooooooo.LecturaDeTxt

Constante para el género musical de la canción.

getMicro() - Method in class com.example.ejemplooooooo.MotorApp

Método encargado de recoger la información procedente del micrófono y formatearla

para que sea almacenada en el vector.

getPlaying() - Method in class com.example.ejemplooooooo.DescripcionProgramaK

Método llamado para modificar el valor de la variable que define el estado de la

aplicación.

getThread() - Method in class com.example.ejemplooooooo.VideoView

Método que devuelve la instancia creada por la clase VideoView.

grabarMicrofono() - Method in class com.example.ejemplooooooo.MotorApp

Método encargado de crear una hebra para grabar la información captada por el

micrófono de manera no bloqueante.

138

H

HebraVideo(SurfaceHolder, Context) - Constructor for class

com.example.ejemplooooooo.VideoView.HebraVideo

139

I

info - Variable in class com.example.ejemplooooooo.LecturaDeTxt

Cadena de caracteres que contiene la información del archivo de texto.

infoCancion(View) - Method in class com.example.ejemplooooooo.DescripcionProgramaK

Método llamado cuando se pulsa un elemento activo de la vista.

informacionCancion() - Method in class

com.example.ejemplooooooo.DescripcionProgramaK

Método llamado para mostrár la información de la canción seleccionada.

iniciarHebra() - Method in class com.example.ejemplooooooo.VideoView

Método encargado de iniciar la instancia de de la hebra del video.

140

J

jugarApp(View) - Method in class com.example.ejemplooooooo.DescripcionProgramaK

Método llamado cuando se pulsa un elemento activo de la vista.

141

K

kill() - Method in class com.example.ejemplooooooo.VideoView.HebraVideo

Método que se ejecuta cuando la hebra finaliza, deteniendo y liberando el archivo de

video.

142

L

LANGUAGE - Static variable in class com.example.ejemplooooooo.LecturaDeTxt

Constante para el idioma de la canción.

laPartida - Static variable in class com.example.ejemplooooooo.MotorApp

Variable encargada de almacenar un string de espera, el cual permite su

traducción al inglés: La partida comenzará

LecturaDeTxt - Class in com.example.ejemplooooooo

Clase encargada de traducir el archivo de texto almacenada en el contenedor de cada

canción para leer toda su información.

LecturaDeTxt() - Constructor for class com.example.ejemplooooooo.LecturaDeTxt

letra - Variable in class com.example.ejemplooooooo.LecturaDeTxt

Cadena de caracteres que contiene la letra de la canción para representar por pantalla,

que presenta el archivo de texto.

LIBRE - Static variable in class com.example.ejemplooooooo.LecturaDeTxt

Constante para nota de estilo libre.

143

M

modificarEstado(int) - Method in class com.example.ejemplooooooo.VistaJuego

Método encargado de modificar el estado de la aplicación.

modificarPosicionLetra() - Method in class com.example.ejemplooooooo.VistaJuego

Método encargado de modificar el valor de la posición de la letra la cual queda

centrada en función del tamaño de esta, el ancho de la pantalla y el númmero de letras

de cada línea.

modificarPosicionMarcador() - Method in class com.example.ejemplooooooo.VistaJuego

Método encardado de modificar el valor de la posición del marcador.

modificarPosicionTemporizador() - Method in class

com.example.ejemplooooooo.VistaJuego

Método encargado de modificar el valor de la posición del temporizador.

MotorApp - Class in com.example.ejemplooooooo

Clase encargada de implentar toda la parte del juego de la aplicación.

MotorApp() - Constructor for class com.example.ejemplooooooo.MotorApp

MP3 - Static variable in class com.example.ejemplooooooo.LecturaDeTxt

Constante para el nombre de la pista de audio de la canción.

mp3Seleccionado - Variable in class com.example.ejemplooooooo.ExploradorArchivos

Constante para conocer la ruta del archivo seleccionado.

144

N

notas - Variable in class com.example.ejemplooooooo.LecturaDeTxt

Matriz entera que contiene las notas del archivo de texto.

nuevaEntradaCache(String) - Method in class

com.example.ejemplooooooo.ExploradorArchivos

Método que permite almacenar en caché una nueva entrada para la descompresión de

un contenedor.

numNotas - Variable in class com.example.ejemplooooooo.LecturaDeTxt

Número de notas que se muestran por pantalla.

145

O

onAjustes() - Method in class com.example.ejemplooooooo.DescripcionProgramaK

Método llamado para generar la vista de la pantalla de ajustes al pulsar dicho botón

onBackPressed() - Method in class com.example.ejemplooooooo.DescripcionProgramaK

Método llamado al pulsar el botón de retroceso.

onBackPressed() - Method in class com.example.ejemplooooooo.ExploradorArchivos

Método llamado cuando se pulsa el botón de retroceso.

onBackPressed() - Method in class com.example.ejemplooooooo.MotorApp

Método llamado cuando se pulsa el botón de retroceso, finalizando la reproducción de

audio, video, grabación y encendido permanente de la pantalla.

onClick(DialogInterface, int) - Method in class

com.example.ejemplooooooo.DescripcionProgramaK

onCreate(Bundle) - Method in class com.example.ejemplooooooo.DescripcionProgramaK

Método llamado cuando la actividad se crea por primerz vez.

onCreate(Bundle) - Method in class com.example.ejemplooooooo.ExploradorArchivos

Método llamado cuando la actividad se crea por primerz vez.

onCreate(Bundle) - Method in class com.example.ejemplooooooo.MotorApp

Método llamado cuando la actividad se crea por primerz vez.

onRestoreInstanceState(Bundle) - Method in class

com.example.ejemplooooooo.DescripcionProgramaK

Método llamado para recuperar las instancias almacenadas con anterioridad.

onSaveInstanceState(Bundle) - Method in class

com.example.ejemplooooooo.DescripcionProgramaK

Método llamado cuando se desea almacenar diferentes instancias del programa.

146

onTouch(View, MotionEvent) - Method in class com.example.ejemplooooooo.MotorApp

Método llamado cuando un evento táctil aparece en esta vista.

147

P

posibilidadSD() - Method in class com.example.ejemplooooooo.ExploradorArchivos

Método encargado de comprobar que la memoria está presente y correctamente

disponible.

preparate - Static variable in class com.example.ejemplooooooo.MotorApp

Variable encargada de almacenar un string de espera, el cual permite su

traducción al inglés: Prepárate

pulsaAtras - Static variable in class com.example.ejemplooooooo.MotorApp

Variable encargada de almacenar un string de espera, el cual permite su

traducción al inglés: Pulsa atrás para continuar.

148

R

RELATIVE - Static variable in class com.example.ejemplooooooo.LecturaDeTxt

Constante para el valor que especifica un tratamiento especial a las notas.

rellenarLineaNotas() - Method in class com.example.ejemplooooooo.MotorApp

Método encargado de rellenar una matriz con las notas teniendo en cuenta su posición,

duración, valor midi y cuando el tramtamienta de esta sea un salto de línea.

run() - Method in class com.example.ejemplooooooo.VideoView.HebraVideo

Método que se ejecuta cuando la hebra es lanzada.

149

S

salida(View) - Method in class com.example.ejemplooooooo.DescripcionProgramaK

Método llamado cuando se pulsa un elemento activo de la vista.

salir() - Method in class com.example.ejemplooooooo.DescripcionProgramaK

Método llamado cuando se decide finalizar la aplicación.

SALTOLINEA - Static variable in class com.example.ejemplooooooo.LecturaDeTxt

Constante para indicador de salto de linea.

seleccion(View) - Method in class com.example.ejemplooooooo.DescripcionProgramaK

Método llamado cuando se pulsa un elemento activo de la vista.

seleccionarArchivo() - Method in class com.example.ejemplooooooo.DescripcionProgramaK

setMP3(String) - Method in class com.example.ejemplooooooo.ExploradorArchivos

Método llamado para configurar la variable MP3Seleccionado.

setPlaying(boolean) - Method in class com.example.ejemplooooooo.DescripcionProgramaK

Método llamado para modificar el valor de la variable que define el estado de la

aplicación.

START - Static variable in class com.example.ejemplooooooo.LecturaDeTxt

Constante para el número de segundos que se encuentra desfasado el videoclip con la

pista de audio.

stopThread() - Method in class com.example.ejemplooooooo.VideoView

Método que finaliza la instancia de la hebra del video.

surfaceChanged(SurfaceHolder, int, int, int) - Method in class

com.example.ejemplooooooo.DescripcionProgramaK

Método llamado después de cualquier cambio estructural en la superficie.

150

surfaceChanged(SurfaceHolder, int, int, int) - Method in class

com.example.ejemplooooooo.VideoView

Método llamado después de cualquier cambio estructural en la superficie.

surfaceCreated(SurfaceHolder) - Method in class

com.example.ejemplooooooo.DescripcionProgramaK

Método llamado después de crear la primera superficie.

surfaceCreated(SurfaceHolder) - Method in class com.example.ejemplooooooo.VideoView

Método llamado después de crear la primera superficie.

surfaceDestroyed(SurfaceHolder) - Method in class

com.example.ejemplooooooo.DescripcionProgramaK

Método llamado antes de la destrucción de la superficie.

surfaceDestroyed(SurfaceHolder) - Method in class

com.example.ejemplooooooo.VideoView

Método llamado antes de la destrucción de la superficie.

151

T

terminarDialogoDescomprimiendo() - Method in class

com.example.ejemplooooooo.ExploradorArchivos

Método encargado de eliminar el cuadro de diálogo de descomprimiendo.

TITLE - Static variable in class com.example.ejemplooooooo.LecturaDeTxt

Constante para el título de la canción.

traducirTxt(String) - Method in class com.example.ejemplooooooo.LecturaDeTxt

Método encargado de leer el archivo txt entero para pasarlo a String y así poder

trabajar con él para obtener toda la información.

152

V

validezZIP(String) - Method in class com.example.ejemplooooooo.ExploradorArchivos

Método encargado de comprobar la validez del contenedor ZIP seleccionado.

VIDEO - Static variable in class com.example.ejemplooooooo.LecturaDeTxt

Constante para el nombre del videoclip de la canción.

VIDEOGAP - Static variable in class com.example.ejemplooooooo.LecturaDeTxt

Constante para el número de segundos que se encuentra desfasado el video de la pista

de audio.

videoPath - Variable in class com.example.ejemplooooooo.VideoView.HebraVideo

videoPath - Variable in class com.example.ejemplooooooo.VideoView

VideoView - Class in com.example.ejemplooooooo

Clase encargada de alojar el video de la canción elegida para jugar.

VideoView(Context, AttributeSet) - Constructor for class

com.example.ejemplooooooo.VideoView

Constructor de la clase VideoView.

VideoView.HebraVideo - Class in com.example.ejemplooooooo

Clase encargada de generar una hebra para la reproducción del video.

VistaJuego - Class in com.example.ejemplooooooo

Clase encargada de representar en la interfaz de usuario todo lo que comprende la

pantalla de juego del karaoke.

VistaJuego(Context) - Constructor for class com.example.ejemplooooooo.VistaJuego

Constructor de la clase VistaJuego.

153

VistaJuego(Context, AttributeSet) - Constructor for class

com.example.ejemplooooooo.VistaJuego

Constructor de la clase VistaJuego con el conjunto de atributos que se le pasan a la

instancia.

154

Y

YEAR - Static variable in class com.example.ejemplooooooo.LecturaDeTxt

Constante para el año de la canción.

155

Z

zipElegido - Variable in class com.example.ejemplooooooo.ExploradorArchivos

Constante para conocer la ruta del contenedor zip seleccionado.

156

CONSTANTES Y VALORES UTILIZADOS

Constant Field Values

Contents

com.example.*

com.example.*

com.example.ejemplooooooo.DescripcionProgramaK

Modifier and Type Constant Field Value

public static final java.lang.String CONFIGURACION "AjuestesPartidaKaraoke"

public static final int DIF_ALTA 2

public static final int DIF_BAJA 0

public static final int DIF_MEDIA 1

com.example.ejemplooooooo.ExploradorArchivos

Modifier and Type Constant

Field

Value

public static final java.lang.String CACHE "AjuestesPartidaKaraoke"

157

com.example.ejemplooooooo.LecturaDeTxt

Modifier and Type Constant

Field

Value

public static final int ARTIST 1

public static final int BACKGROUND 9

public static final int BPM 12

public static final int COVER 8

public static final int CREATOR 6

public static final int DORADA 2

public static final int DOSPUNTOS 0

public static final int EDITION 3

public static final int END 15

public static final int GAP 13

public static final int GENRE 4

public static final int LANGUAGE 2

public static final int LIBRE 1

public static final int MP3 7

public static final int RELATIVE 16

public static final int SALTOLINEA 3

public static final int START 14

public static final int TITLE 0

158

public static final int VIDEO 10

public static final int VIDEOGAP 11

public static final int YEAR 5

com.example.ejemplooooooo.VistaJuego

Modifier and Type Constant Field Value

public static final int CANTANDO_STD 2

public static final int ESPERA_STD 0

public static final int FINAL_STD 3

public static final int GAP_STD 1

159

8.3. ANEXO III. ÍNDICE DE FIGURAS

Figura 1. Primer concepto de tableta. “Dynabook”………………………………..…5

Figura 2. Nokia 510 webtablet…………..……………………………………………...5

Figura 3. Microsoft Tablet PC…………………………………………………………..6

Figura 4. IPad………………………………………………………………………..…..6

Figura 5. Estudio del IDC en ventas de tabletas y portátiles………………………..9

Figura 6. Ejemplo de la forma de onda de la voz hablada. Autocorrelación de

acuerdo a la primera ecuación. Autocorrelación de acuerdo a la segunda

ecuación………………………………………………………………………………….16

Figura 7. Representación de la función diferencia y de la función diferencia

normalizada de media acumulativa…………………………………………………...18

Figura 8. Diagrama de bloques del método expuesto para determinar si hay voz o

no………………………………………………………………………………………….20

Figura 9. Ejemplo de computación de una señal diezmada y de dicha señal

retardada…………………………………………………………………………………21

Figura 10. Pantalla principal de la aplicación. Izquierda (español) y derecha

(inglés).…………………………………………………………………………………...30

Figura 11. Cuadro de diálogo indicando la selección de un archivo. Izquierda

(español) y derecha (inglés).…………………………………………………………...31

Figura 12. Cuadro de diálogo para abandonar la aplicación. Izquierda (español) y

derecha (inglés).…………………………………………………………………………32

Figura 13. Diagrama de flujo de la pantalla principal. Proyecto Paco Moreno “Figura

10”………………………………………………………………………………………….33

Figura 14. Navegación por el explorador de archivos. Selección de storage……34

Figura 15. Navegación por el explorador de archivos. Selección de extSdCard.

Izquierda (español) y derecha (inglés).……………………………………………….34

Figura 16. Navegación por el explorador de archivos. Selección del directorio

CancionesK………………………………………………………………………………35

Figura 17. Navegación por el explorador de archivos. Selección de un

contenedor……………………………………………………………………………….35

Figura 18. Reproducir o elegir contenedor. Izquierda (español) y derecha

(inglés)……………………………………………………………………………………36

Figura 19. Descomprimiendo contenedor zip. Izquierda (español) y derecha

(inglés)…………………………………………..........................................................37

160

Figura 20. Reproducción de la pista de audio. Izquierda (español) y derecha

(inglés)……………………………………………………………………………………37

Figura 21. Archivo seleccionado no válido. Izquierda (español) y derecha

(inglés)……………………………………………………………………………………38

Figura 22. Diagrama de la aplicación del explorador de archivos. Proyecto de

Paco Moreno “Figura 19”…………………………………………………………........38

Figura 23. Pantalla de ajustes. Izquierda (español) y derecha

(inglés)…………………………………………..........................................................39

Figura 24. Pantalla de información de canción. Izquierda (español) y derecha

(inglés)…………………………………………..........................................................40

Figura 25. Pantalla comienzo de juego. Arriba (español) y abajo

(inglés).…………………………………………………………………………………..41

Figura 26. Pantalla hasta que se comienza a cantar. Arriba (español) y abajo

(inglés).…………………………………………………………………………………..42

Figura 27. Pantalla de juego cantando……………………………………………….43

Figura 28. Sincronización temporal de las hebras principales. Proyecto Paco

Moreno “Figura 27”……………………………………………………………………..43

Figura 29. Pantalla de finalización de la partida. Arriba (español) y abajo

(inglés).……………………………………….............................................................45

Figura 30. Diagrama de flujo del evento salir. Proyecto Paco Moreno

“Figura 31”……………………………………………………………………………….46

Figura 31. Botón ajustes seleccionado…………………………………………….…52

Figura 32. Botón de elegir canción seleccionado………………………………..…..53

Figura 33. Selección Info. Canción……………………………………………………55

Figura 34. Información de la canción elegida………………………………….……..55

Figura 35. Selección Jugar……………………………………………………………..55

Figura 36. Pantalla comienzo de juego……………………………………………….56

Figura 37. Pantalla hasta que se comienza a cantar………………………………..56

Figura 38. Pantalla de juego……………………………………………………………56

Figura 39. Pantalla fin de juego………………………………………………………..57

Figura 40. Diagrama de flujo del proceso de captura del audio hasta la obtención de

la nota MIDI……………………………………………………………………………….94

Figura 41. Diagrama de flujo del sistema de puntuación…………………………..112

161

9. REFERENCIAS BIBLIOGRÁFICAS

1.) Donn Felker. Android Application Development . EEUU: Dummies,2010.

2.) En Android, 2014: http://www.android.com/

3.) En Android Developers, 2014: http://developer.android.com/index.html/

4.) En Android Ya, 2014: http://www.javaya.com.ar/androidya/

5.) En Curso de programación android, 2014: http://www.sgoliver.net/blog/?page_id=3011

6.) En Formatos para karaoke: http://www.karaokeplus.com.mx/c/wiki/formatos-para-

karaoke.php

7.) En Historia del karaoke, 2014: http://karaokehome.mx.tripod.com/karaokehome/id9.html

8.) En Oracle España, 2014: http://www.oracle.com/es/index.html

9.) En programando o intentándolo, 2014:

http://programandoointentandolo.com/2014/06/como-hacer-un-explorador-de-archivos-en-

android.htmlhttp://programandoointentandolo.com/2014/06/como-hacer-un-explorador-de-

archivos-en-android.html

10.) En Samsung España, 2014: http://www.samsung.com/es/home

11.) En sgoliver, 2014: http://www.sgoliver.net/blog/?p=2035

10.) En Wikipedia, 2014: http://es.wikipedia.org/wiki/Tableta_(computadora)

11.) En Wikipedia, 2014: http://es.wikipedia.org/wiki/Karaoke

12.) En http://codigoprogramacion.com/cursos/java/110-manipulacion-de-archivoslectura-de-

un-archivo-de-texto-en-java.html

13.) Francisco Javier Salcedo Campos. Modelos ocultos de Markov: Del reconocimiento de

voz a la música. España: Lulu, 2009.

14.) Francisco Moreno. Aplicación de karaoke para telefonía móvil android. Proyecto final de

carrera. Universidad de Jaén (EPSL).

15.) James C. Sheusi. Programming business applications for the android tablet. Boston:

Course Technology PTR, 2013.

162

16.) Javier García de Galón, et al. Aprenda Java como si estuviera en primero. San

Sebastián: Tecnum, 2000.

17.) Jesús Sánchez Allende, et al. Programación en Java. Madrid: S.A. MCGRAW-HILL /

INTERAMERICANA DE ESPAÑA , 2009.

18.) Jesús Sánchez Allende, Gabriel Huecas Fernández-Toribio, Baltasar Fernández

Manjón, Pilar Moreno Díaz, Antonio José Reinoso Peinado, Ricardo Sosa Sánchez-Cortés.

Programación en Java 2. Madrid: S.A. MCGRAW-HILL / INTERAMERICANA DE ESPAÑA ,

2005.

19.) Joseph Annuzzi, Lauren Darcey, Shane Conder. Introduction to Android Application

Development: Android Essentials.Developer’s library, 2013.

20.) Marcos Faundez Zanuy. Tratamiento digital de voz e imagen y aplicación a la

multimedia. España: Marcombo, 2000.

21.) Mark L. Murphy. The busy Coder´s Guide to Advanced Android Development. EEUU:

Commosware, 2008.

22.) Pablo Cabañas-Molero, Damián Martínez-Molero, Pedro Vera-Candeas, Nicolas Ruiz-

Reyes, Francisco José Rodríguez-Serrano. Low-complexity F0-based speech/nonspeech

discrimination approach for digital hearing aids. Multimedia tools and Aplications, 2010, 297-

301.

23.) Salvador Gomez Oliver. Manual Programación Android.

Shawn Van Every. Pro Android Media. Apress, 2010.