Conversión de archivos de audio en linux

February 24th, 2010 by ilikeblues

La herramienta SoX, multiplataforma, permite realizar varias operaciones muy interesantes sobre ficheros de audio:

  • Obtener información:
     $ sox fichero.wav
  • Reproducir audio:
    $ play fichero.wav
  • Grabar archivo:
    $ rec -r 8000 -c 1 fichero.wav

    → graba con un muestreo de 8 kbps y a un canal (la extensión determina el formato).

  • Convertir:
    $ sox fichero.wav fichero.ogg

    → convierte el fichero del formato “wav” a “ogg”

  • Acelerar:
    $ sox fichero.wav acelerado.wav speed 2.0
  • Recortar:
    $ sox fichero.wav recortado.wav trim 60 10

    → devuelve los 10 segundos posteriores al primer minuto.

  • Escuchar podcast:
    $ play http://dondesea.com/ficheros/audio/podcast.mp3

La instalación de Ubuntu es muy sencilla:

$ sudo apt-get install sox libsox-fmt-all

Para otras plataformas: http://sox.sourceforge.net

La reproducción, grabado y/o conversión desde/hacia mp3 requiere de la librería lame.

Via | http://bitelia.com


Subversion: ignorar ficheros

February 10th, 2010 by ilikeblues

Para forzar a SVN a que ignore ciertos ficheros, como pueden ser los resultados de la compilación (objetos .o) es necesario establecer la propiedad “svn:ignore” en todas las carpetas donde queremos ignorarlos.

Para un proyecto con múltiples carpetas que contienen este tipo de ficheros lo más sencillo es:

$ svn propset svn:ignore -F $HOME/ignore_file . -R

donde -R indica que se haga de manera recursiva desde “.” (el directorio actual) y -F indica que se tomen las reglas de exclusión del fichero inficado.

El contenido del fichero ignore_file podría ser, por ejemplo:

*.o
*.so
*.exe

Con esto quedaráin excluidos los ficheros objeto, las librerías compartidas y los ejecutables (suponiendo que todos tengan nombres acabados en .exe).


Google Wave Invitations

January 19th, 2010 by ilikeblues

Tengo 7 invitaciones para Google Wave. Las primeros en solicitarlas a través de comentarios en este post, recibirán una.

Para ello es necesario que indiquen correctamente la dirección de email al escribir el comentario (no es necesario publicarlo en el texto).

Cerraré los comentarios cuando ya no queden invitaciones.


I ‘ve got 7 new invitations to Google Wave. Please, leave a comment on this post in order to get one.

Do not forget to fulfill the email field in the comment form.

Comments on the post will be closed where there are no invitations left to be sent.


VT6656 Driver para Ubuntu Karmic Koala

November 6th, 2009 by ilikeblues

Tal como sugieren en el thread del bug correspondiente, VT6656 wireless chipset is unsupported, la solución para conseguir que funcione la tarjeta (o adaptador USB) wifi con chipset VT6656 es compilar la versión “staging” del driver, incluído en la versión del kernel 2.6.32-rc6.

En mi último viaje a Japón compré un Kohjinsha SC3 que monta este chipset. Así que he generado un pequeño paquete que permite compilar e instalar el driver en Ubuntu 9.10 (Karmic Koala).

Podéis descargar los fuentes aquí:

driver_staging_vt6656.tgz

Al descomprimirlo generará una carpeta llamada “driver”. Basta con hacer (dentro de la carpeta generada):

$ sudo make install

para que se añada el driver al arranque de Ubuntu. Si ejecutamos:

$ modprobe vntwusb

el driver se cargará y podremos conectar a la red usando nuestra tarjeta wifi con chipset VT6656.

Por último decir que, tal como indican en el thread relacionado con el bug, sólo funciona la encriptación WPA2. No funcionan ni WPA ni la mixta (WPA+WPA2).

Que lo disfrutéis.


Javascript: comprobar si es el navegador de iPhone

October 20th, 2009 by ilikeblues

El siguiente código Javascript comprueba si el navegador actual es el de iPhone:

function iPhoneCheck() {
    var agent = navigator.userAgent.toLowerCase();
    var iphone = (agent.indexOf('iphone')!=-1);
    if (iphone) {
        return true;
    } else {
        return false;
    }
}

Vía: http://blog.unijimpe.net/detectar-browser-iphone/


Conexión a Base de Datos Safari-JavaScript

October 19th, 2009 by ilikeblues

Para realizar la conexión a una base de datos  mediante Javascript, podemos utilizar el siguiente código:

try {
   if (!window.openDatabase) {
      alert('not supported');
   } else {
      var shortName = 'mydatabase';
      var version = '1.0';
      var displayName = 'My Important Database';
      var maxSize = 65536; // in bytes
      var mydb = openDatabase(shortName, version, displayName, maxSize);

      // You should have a database instance in mydb.
   }
} catch(e) {
   // Error handling code goes here.
   if (e == 2) {
      // Version number mismatch.
      alert("Invalid database version.");
   } else {
      alert("Unknown error "+e+".");
   }
   return;
}

alert("Database is: "+mydb);

Con esto, sin más que implementar las transacciones necesarias, podemos hacer persistente la información cargada durante la sesión para su uso posterior.

Estas bases de datos se pueden utilizar para la implementación de aplicaciones Offline mediante Safari.

Para eliminar estas bases de datos creadas por aplicaciones web, basta con ir a la sección “Safari” de los ajustes del iPhone.

Vía: Safari Client-Side Storage and Offline Applications Programming Guide


iPhone SDK: Registrar una clase como observador de un evento

July 6th, 2009 by ilikeblues
[[NSNotificationCenter defaultCenter]
      addObserver:self
      selector:@selector(onDataChangeEvent:)
      name:@"dataChangeEvent"
      object:nil];

La clase que contiene este código:

  1. Recibirá notificaciones de disparo del evento “dataChangeEvent”.
  2. Debe implementar el método “onDataChagneEvent”.

Cuando algún otro objeto dispare el evento, las instancias de esta clase recibirán la notificación y ejecutarán el método especificado.


AspectJ aplicado sobre una librería jar

May 12th, 2009 by ilikeblues

El problema inicial es el siguiente: tenemos una aplicación java bajo prueba, formada por un conjunto de ficheros “jar”, de cuyo código conocemos algunos (o todos los) interfaces públicos.

A efectos prácticos, supongamos un único fichero jar llamado “underTest.jar” (los resultados son extensibles) y la clase que contiene el método “main” es “MainClass”, dentro del paquete “mainpack”:

public class MainClass {
public MainClass() {
}

/**
* @param args
*/
public static void main(String[] args) {
System.out.println("Ejecutando el main...");
}

}

Así, el comando para ejecutar la aplicación sería:

java -classpath underTest.jar mainpack.MainClass

El resultado de la ejecución sería:

Ejecutando el main...

En este caso, podemos utilizar AspectJ para insertar puntos de ruptura, logear información de ejecución, de performance, etc.

Vamos con la prueba de concepto.

En primer lugar, vamos a crear una librería (jar) con los “aspectos” a utilizar. En este caso, algo muy simple: una clase que traza la entrada y la salida del método “main” de nuestra aplicación.

El código sería:

public aspect ProfilingAspect {

pointcut mainMethod() : execution(static * *.main(..));

before() : mainMethod()
{
System.out.println("Entrando al main...");
}

after() : mainMethod()
{
System.out.println("Saliendo del main...");
}

}

Podemos usar eclipse para crear un proyecto de tipo AspectJ, compilarlo y generar un fichero jar con soporte para AspectJ (echar un vistazo a las Cheat Sheets de eclipse con el plugin AJDT).

Supongamos que el fichero jar creado con el “aspecto” anterior es mainAspect.jar.

El siguiente paso sería modificar el comando utilizado para ejecutar la aplicación:

java
-classpath $ASPECTJ_HOME/aspectjweaver.jar:$ASPECTJ_HOME/aspectjrt.jar:.
-Djava.system.class.loader=org.aspectj.weaver.loadtime.WeavingURLClassLoader
-Daj.class.path=mainAspect.jar:underTest.jar
-Daj.aspect.path=mainAspect.jar
mainpack.MainClass

Donde $ASPECTJ_HOME apunta al directorio de instalación de las librerías de AspectJ (aspectjweaver.jar y aspectjrt.jar) en la máquina. Con esto el resultado de la ejecución sería:

Entrando al main...
Ejecutando el main...
Saliendo del main...

Usar un pool de threads para atender peticiones a un socket servidor

May 8th, 2009 by ilikeblues

Un pequeño ejemplo de cómo construir un pool de threads para atender las peticiones de conexión que se realicen a un socket servidor:

class NetworkService {
    private final ServerSocket serverSocket;
    private final ExecutorService pool;

    public NetworkService(int port, int poolSize) throws IOException {
      serverSocket = new ServerSocket(port);
      pool = Executors.newFixedThreadPool(poolSize);
    }

    public void serve() {
      try {
        for (;;) {
          pool.execute(new Handler(serverSocket.accept()));
        }
      } catch (IOException ex) {
        pool.shutdown();
      }
    }
  }

  class Handler implements Runnable {
    private final Socket socket;
    Handler(Socket socket) { this.socket = socket; }
    public void run() {
      // read and service request
    }
 }

C++: excepción en construtor o destructor

January 14th, 2009 by ilikeblues

Cuando un constructor de clase lanza una excepción, los destructores para todos los objetos locales (objetos que forman parte de la clase que se está construyendo) son llamados. Si uno de los destructores llamados lanza una excepción, el método terminate será ejecutado.

En general, no se debería lanzar una excepción durante la ejecución de un constructor sin hacer un catch de la misma y llevar a acabo una “limpieza” de los recursos utilizados por la clase. Una solución sencilla podría ser utilizar el constructor por defecto para crear los miembros “seguros” de la clase y después llamar a un método de inicialización para los “no seguros”, incluyendo el exception handling en éste.

Veamos un ejemplo sencillo. Supongamos que tenemos el siguiente código:

class Employee {
   ...
   Image * m_pImage;
   AudioClip * m_pAudio;
};

Employee(..., string image, string audio) : ..., m_pImage(NULL), m_pAudio(NULL)
{
   ...
   m_pImage = new Image(image);
   m_pAudio = new AudioClip(audio); // throw point
}

Si el código “new AudioClip(audio)” lanza una excepción, el flujo de control sale del constructor y se produce un memory leak. El destructor sólo sería llamado si el objeto hubiera sido completamente construido, pero no ha sido así.

Entonces, la manera correcta de implementar ese constructor sería:

Employee(..., string image, string audio) : ..., m_pImage(NULL), m_pAudio(NULL)
{
   ...
   try {
      m_pImage = new Image(image);
      m_pAudio = new AudioClip(audio);
   }
   catch(...)
   {
      delete m_pImage;
      delete m_pAudio;
      throw;
   }
}

De manera que, si se levanta una excepción, los recursos reservados son liberados y se vuelve a despachar la excepción para que notificar al objeto que intentaba construir esta clase.

Esta solución es buena, funciona bien, excepto en el caso de que tengamos punteros constantes como miembros de la clase:

class Employee {
   ...
   Image * const m_pImage;
   AudioClip * const m_pAudio;
};

Estos miembros deben ser incializados por el incializador de miembros propio de la clase, donde no podemos poner bloques try… catch.

En este caso, podríamos utilizar la clase auto_ptr<> (o similar) como wrapper para los punteros, de manera que se conviertan en objetos locales a nuestra clase:

class Employee {
   ...
   auto_ptr<image> m_pImage;
   auto_ptr<audioClip> m_pAudio;
};

Como ya se ha dicho, si ocurre una excepción durante la ejecución del constructor, se ejecutan los destructores de todos los miembros locales a la clase. Es decir, se llamaría al destructor de auto_ptr<>, el cual libera, de la manera adecuada, todos los recursos reservados.

[Fuente: http://progtutorials.tripod.com]