jump to navigation

FreeTTS, convertir textos a voz… agosto 21, 2007

Posted by superpiwi in Eclipse, Java, Programacion.
47 comments

Hoy algo divertido, vamos a convertir un texto en voz. Para ello hacemos uso del siguiente API: FreeTTS

Descargate el paquete desde su sitio web y lo descomprimes, Tienes que añadir a tu CLASSPATH los siguientes ficheros:

cmu_time_awb.jar, cmu_us_kal.jar, cmudict04.jar, cmulex.jar, cmutimelex.jar, en_us.jar, freets.jar, jsapi.jar

Aqui te dejo un ejemplo sencillito. He escrito una clase SimpleTTS. Con un constructor donde le pasas la voz que quieres usar («En el ejemplo Kevin16) y 2 metodos: speak (que te reproduce por el altavoz el texto especificado) y toFile (que te graba un fichero de audio).

Ejemplo:

SimpleTTS voz = new SimpleTTS(”kevin16″);
voz.speak(”Hello World!”);
voz.close();


/**
*
* FreeTTS
* requiere en el CLASSPATH: cmu_time_awb.jar, cmu_us_kal.jar, cmudict04.jar, cmulex.jar, cmutimelex.jar,
* en_us.jar, freets.jar, jsapi.jar
*
* @author jose
* @version 0.0.0.1
* @since JDK 1.5 / Eclipse Callisto
*/
import com.sun.speech.freetts.audio.AudioPlayer;
//import com.sun.speech.freetts.audio.JavaClipAudioPlayer;
//import com.sun.speech.freetts.audio.MultiFileAudioPlayer;
import com.sun.speech.freetts.audio.NullAudioPlayer;
//import com.sun.speech.freetts.audio.RawFileAudioPlayer;
import com.sun.speech.freetts.audio.SingleFileAudioPlayer;
//import java.io.*;
//import java.net.URL;
//import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioSystem;
import com.sun.speech.freetts.Voice;
import com.sun.speech.freetts.VoiceManager;
//import com.sun.speech.freetts.audio.JavaClipAudioPlayer;
public class SimpleTTS
{
Voice voice=null;
public SimpleTTS(String voiceName) throws Exception
{
VoiceManager voiceManager = VoiceManager.getInstance();
this.voice = voiceManager.getVoice(voiceName);
if (this.voice == null)
{
System.out.println("La lista de voces disponibles es:");
listAllVoices();
throw new Exception("No se encuentra la voz llamada: "+voiceName+". Por favor selecciona una voz diferente.");
}
this.voice.allocate();
}
//----
public void speak(String text) throws Exception
{
this.voice.speak(text);
}
//----
public void toFile(String filename,String text) throws Exception
{
javax.sound.sampled.AudioFileFormat.Type type = getAudioType(filename);
AudioPlayer audioPlayer = null;
if(audioPlayer == null)
audioPlayer = new NullAudioPlayer();
audioPlayer = new SingleFileAudioPlayer(getBasename(filename), type);
System.out.println("audioPlayer "+audioPlayer);
this.voice.setAudioPlayer(audioPlayer);
this.voice.speak(text);
audioPlayer.close();
}
//----
public void close() throws Exception
{
this.voice.deallocate();
}
//----
public static void listAllVoices()
{
System.out.println();
System.out.println("All voices available:");
VoiceManager voiceManager = VoiceManager.getInstance();
System.out.println("voiceManager:"+voiceManager);
Voice[] voices = voiceManager.getVoices();
for (int i = 0; i < voices.length; i++) {
System.out.println(" " + voices[i].getName()
+ " (" + voices[i].getDomain() + " domain)");
}
}
//----
public static javax.sound.sampled.AudioFileFormat.Type getAudioType(String file)
{
javax.sound.sampled.AudioFileFormat.Type types[] = AudioSystem.getAudioFileTypes();
String extension = getExtension(file);
for(int i = 0; i < types.length; i++)
if(types[i].getExtension().equals(extension))
return types[i];
return null;
}
//----
public static String getExtension(String path)
{
int index = path.lastIndexOf(".");
if(index == -1)
return null;
else
return path.substring(index + 1);
}
//----
public static String getBasename(String path)
{
int index = path.lastIndexOf(".");
if(index == -1)
return path;
else
return path.substring(0, index);
}
//----
static public void main(String[] args) throws Exception
{
try
{
// Instanciamos para usar la voz "kevin16"
SimpleTTS voz = new SimpleTTS("kevin16");
// Reproduce por el altavoz
//while (true)
//{
voz.speak("auan babuluba balan bambu");
voz.speak("Hello World!");
//}
voz.speak("Text to Speech demo");
// Graba un fichero de audio con el contenido en el directorio
voz.toFile("ttsdemo.wav", "Ubuntu Life is the best site of Linux");
// Podriamos reproducir este fichero desde consola: $ mplayer ttsdemo.wav
// Cerramos
voz.close();
}
catch(Exception e)
{
e.printStackTrace();
}
}
//----
}
//end of class SimpleTTS

JSQL2iBatis: Generador de codigo de Acceso a Bases de Datos agosto 19, 2007

Posted by superpiwi in Eclipse, Java, Oracle, Programacion.
10 comments

jsql2ibatis.gif

Este es un post tecnico (para desarrolladores de Java). Si no eres desarrollador o simplemente no te interesa, no lo leas, en esta web tambien encontraras muchas mas cosas.

Hace unas 2 o 3 semanas que termine JSQL2iBatis, pero hasta ahora no he tenido tiempo para contar de que iba esto.

JSQ2iBatis es un generador de codigo para hacer mas facil el acceso a cualquier tipo de base de datos a la que puedas conectar mediante JDBC. Esta inspirado en SQL2iBatis, y es similar a Abator, pero quitando la complejidad de este ultimo pues es mas simple. No es perfecto, tiene “algunos” fallos pero a mi me viene bien, me esta ahorrando mucho “tiempo” de codificacion. Imaginate que tienes que mapear 28 tablas, antes tardaba 1 semana, ahora tengo el codigo en 1 dia.

Yo empece escribiendo JSQL2iBatis como una “tool” que me ayudara para otro proyecto mayor: Alexandria. Es un proyecto que empezare en breve y toda la capa de acceso a base de datos la codificara ayudandome de esta tool.

He liberado el codigo como licencia GNU, podeis usarla libremente, y mejorarlo (esto ultimo es lo que espero mas, pues he escrito el codigo en poco tiempo y se que tiene muchas chapuzas, pero al menos funciona que es lo que me interesaba).

Pero bueno, vayamos “a lo que interesa”, veamos como se usa.

La idea es simple, es tomar un fichero con las sentencias CREATE TABLE de la base de datos y a partir de ese fichero generar las clases JAVA y ficheros XML de SQL Mappings para mapear esas tablas. Veamoslo mejor con un ejemplo.

Primeramente vamos a crear una tabla USUARIOS en MYSQL.

root@soledad:/opt/lampp/bin# ./mysql -u root mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.0.37 Source distribution
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> show tables
-> ;
+---------------------------+
| Tables_in_mysql |
+---------------------------+
| columns_priv |
| db |
| func |
| help_category |
| help_keyword |
| help_relation |
| help_topic |
| host |
| proc |
| procs_priv |
| tables_priv |
| time_zone |
| time_zone_leap_second |
| time_zone_name |
| time_zone_transition |
| time_zone_transition_type |
| user |
+---------------------------+
17 rows in set (0,00 sec)

Creamos una base de datos:

mysql> CREATE DATABASE TEST;
Query OK, 1 row affected (0,12 sec)
mysql> exit
Bye

Nos conectamos a la base de datos recien creada y creamos una tabla usuarios:

root@soledad:/opt/lampp/bin# ./mysql -u root TEST;
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3
Server version: 5.0.37 Source distribution
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> show tables;
Empty set (0,00 sec)
mysql> CREATE TABLE USUARIOS (LOGIN VARCHAR(50),PASS VARCHAR(50),IMAGEN BLOB,PERFIL VARCHAR(1),PRIMARY KEY(LOGIN));
Query OK, 0 rows affected (0,01 sec)
mysql> SELECT * FROM USUARIOS;
Empty set (0,00 sec)

gedit01.jpg

Bien, tenemos la tabla creada en MySQL, y un fichero llamado “TABLE.sql” con las sentencias CREATE TABLE de esta tabla. He de advertir que no soporto tipos compuestos, del estilo NUMBER(10), cuando definas el fichero de DDL con las sentencias CREATE TABLE, unicamente has de indicar el tipo de la columna (VARCHAR,BLOB,NUMBER,etc..) pero no la precision.

Vamos a generar el codigo JAVA y los XML correspondientes. Para ello en el directorio raiz de JSQL2iBatis existe un script “execute.sh” que hemos de ejecutar con la siguiente sintaxis:

./execute.sh <nombre_package> <directorio_destino> <fichero_sql>

donde:

nombre_package: es el package de las clases Java que se generaran. (nota: he detectado un pequeño fallo que hace que no se generen 2 clases java auxiliares, para evitarlo debes emplear como nombre del package “com.sqlmap”, de esa manera esas clases se generaran, despues ya puedes cambiar el nombre del package al que quieras).

directorio_destino: es el directorio donde se genera el codigo de las clases java y el xml.

fichero_sql: es el fichero de DDL con las sentencias CREATE TABLE que queremos mapear.

Por ejemplo ejecutamos:

./execute.sh com.sqlmap /home/jose/Desktop/source TABLE.sql

generacodigo.jpg

Se generaran en la carpeta /home/jose/Desktop/source las clases correspondientes.

Que son: Usuarios.java, Usuarios.xml, SQLMapping.xml, MyProperties.properties,y 2 clases de apoyo para iBatis llamadas SQLMap y SQLMapPool.

Ya solo nos queda añadir el driver de Acceso a MySQL. Y cambiar el properties para que apunte a nuestra base de datos de MySQL:

# Propiedades para MySQL (Descomenta si usas esta bdatos en lugar de ORACLE)
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/TEST
username=root
password=
activeConnections=010
idleConnections=5
maxWait=120000

properties.jpg

Tal vez tengas que editar el XML Usuarios.xml para ajustar el nombre de la tabla. MySQL es sensible a mayusculas y minusculas, no es lo mismo la tabla USUARIOS que la tabla Usuarios. En Oracle no es necesario hacer nada mas.

Pues bien, si has llegado a este punto. Se han generado de manera automatica todo lo necesario para acceder a la tabla Usuarios mediante iBatis. Veamos un ejemplo de codigo:
Podriamos acceder a la tabla de la siguiente manera:

//Para probar el funcionamiento de la clase
public static void main(String args[])
{
try
{
System.out.println("[iniciado]");
Usuarios test = new Usuarios();
test.setLogin("jose");
test.setPass("jose");
test.setImagen("OK".getBytes());
test.setPerfil("user");
test.insert();
System.out.println("[Finalizado]");
}
catch(Exception e)
{
e.printStackTrace();}
}
//----

ejemplo-de-uso-de-jsql2ibatis.png

Y el resultado:

root@soledad:/opt/lampp/bin# ./mysql -u root TEST
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 6
Server version: 5.0.37 Source distribution
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> select * from USUARIOS;
+-------+------+--------+--------+
| LOGIN | PASS | IMAGEN | PERFIL |
+-------+------+--------+--------+
| jose | jose | OK | u |
+-------+------+--------+--------+
1 row in set (0,00 sec)

consulta1.jpg

YATA!!! que sencillo no?, no has tenido que escribir la clase Java de acceso a la tabla Usuarios y ya tienes una clase que te permite hacer INSERT, UPDATE, DELETES y mas operaciones. Incluso soporta insercion y recuperacion de BLOBS y todo…

Que guay!!!, y si no te gusta o quieres cambiar la SQL, solo tienes que editar el fichero Usuarios.xml.

Simple y Sencillo.

Pues ahora en vez de una tabla, escribe un fichero TABLE.sql con 28 tablas. A que mola!!! se acabo el escribir una por una el codigo de acceso Java a cada una de esas tablas.

Se que no es perfecto, pero esta basado en plantillas VELOCITY asi que facilmente cambiando las plantillas puedes generar tu propio codigo.

Espero que sea de utilidad. Puedes encontrar mas detalles en el fichero README que incluyo con la distribucion.

Referencias: iBatis Framework