martes, 17 de marzo de 2015

Almacenando datos en un folio: audio en un codigo de barras 2D

Hace ya tiempo surgio la moda de los BIDIs o codigos QR, unos codigos de barras 2D que podias escanear con la camara del movil y acceder a contenido multimedia.
Estos BIDIs, no obstante, tienen una capacidad muy limitada, y en la inmensa mayoria de los casos contienen enlaces a paginas web, aunque tambien son capaces de almacenar numeros de telefono, pass de wifi, o texto, como en el ejemplo que pongo a continuación.
  Hay muchas paginas para crear estos BIDIs o codigos QR, yo he usado http://www.codigos-qr.com/ 
La cuestion es que yo me propuse algo mas grande, almacenar en un simple codigo de barras en papel algo mas que un texto o un enlace.
Para ello hice uso de la impresora y el escaner.
Lo primero que pensé era en almacenar una imagen jpg, pero vi que era un ejemplo bastante aburrido, ya que aunque se pueda representar una imagen en color de poca resolucion en un barcode B/N, cualquiera puede imprimir una imagen en una hoja.

Luego pense en un ROM o .exe, pero suponiendo las limitaciones de espacio de un barcode descarté la idea.

Finalmente me acordé de el codec OPUS que os comenté en una entrada anterior, el cual puede comprimir el sonido mas incluso que MP3 y permite mas flexibilidad en cuanto a bitrates que OGG. Asi que hice calculos, y podriamos decir que hice tres intentos:

1.
Usando una resolucion de cuadrado de 2x2 (Respecto a la resolucion de mi impresora) conseguí hacer un barcode de hasta 352x500, o lo que es lo mismo, 176.000 bits que son unas 21,4 KB.
Aprovechando este tamaño, codifiqué en OPUS un fragmento de una cancion a 16 kbps, una calidad de sonido aceptable para el caso. Asi pude codificar 15 segundos de música en el barcode.
Cuando lo escanee y vi el resultado... ¡fracaso! aunque la impresión se hizo bien y la canción esta correctamente en la hoja, a la hora de escanear, el ruido de la imagen escaneada alteró gran cantidad de bits, haciendo que ni la cabecera del fichero quedase correctamente, por lo que no conseguí ningún resultado.

2.
Esta vez, asumiendo que iba a usar el escaner, aumenté el tamaño de pixel del barcode a 4x4 un tamaño de pixel ridiculamente grande, asi, aun sin utilizar el folio del todo (No necesito gastar demasiada tinta en una "demo") hice un barcode de 160x244, o sea 39.040 b
its que son unas 4,75 KB.
Para este ejemplo, codifico solo 4 segundos de audio a 12 kbps, una calidad ligeramente inferior.
imprimo, escaneo y... ¡casi! La cabecera del fichero es correcta, VLC me detecta el archivo, pero lamentablemente al haber algunos bits corruptos, el formato OPUS no reproduce los fragmentos de archivo que no cumplen su correspondiente checksum, en este caso hay 3 fragmentos (que se pueden distinguir a simple vista en la imagen) y ninguno cumple el checksum. Me pareció increible que hubisen fallos incluso con este tamaño de pixel.
Tras comparar el archivo escaneado y el original, vi que solo habian 3 bits corruptos, los cuales (que casualidad) estaban cada uno en un fragmento distinto. Estos fallos solo corresponden: 3/39040*100= 0,008% y arruinan los resultados.

3.
Simplemente, como habia tenido mala suerte, volví a escanear este segundo folio... 3 veces. Tras escanear y abrir el archivo por 3ª vez... Consigo oir la música! Conseguí reproducir 2 segundos de música almacenados en el barcode del folio. ¿Por que solo 2? Porque como dije, habia 3 fragmentos de sonido. El fragmento del final tenia un bit corrupto y no se reproducia, pero al estar la cabecera y los dos primeros fragmentos correctos, se reproducian estos y en total 2 segundos de audio de los 4 iniciales.
Aunque iba a finalizar aquí, se me ocurrió combinar los 3 primeros escaneos fallidos que hice (Sin contar este ultimo) a ver que pasaba. Los escaneos los tenia en escala de grises en GIMP, asi que los combiné en 3 capas superpuestas (cada uno con una transparencia de 33%) para pasarlos entonces a monocromo y probar con los resultados. Finalmente conseguí oir el audio original completo: Combinando los 3 escaneos conseguí recuperar el  archivo desde la hoja sin fallos.

Anexo: ¿Como imprimir los archivos?
Para imprimir los archivos en un folio cree un archivo BMP monocromo con la resolucion requerida y lo dejé en blanco.
Con un editor hexadecimal remplacé el contenido de este BMP en blanco con los datos del archivo de sonido. Ahora solo hay que abrir el BMP e imprimirlo.

¿Como escanear los archivos?
Tras escanear la hoja en formato BMP (Para evitar las perdidas de JPG), abro el archivo con Gimp y extiendo el barcode a las 4 esquinas del area de dibujo.
Cambio la resolución de la imagen escaneada a la resolucion del barcode y guardo en monocromo.
Ahora con un editor hexadecimal extraigo el archivo desde el BMP obtenido.

Conclusiones:
Es interesante saber que es posible almacenar un archivo de audio de esta manera, no obstante, el ruido a la hora de escanear hace que se aun metodo bastante poco recomendado XD
Cuando escaneas un BIDI ademas de que es mas pequeño y hay menos probabilidades de fallo, se esta comprobando su checksum en cada fps de la camara, es por eso por lo que a veces hay que tenerlo con la camara un tiempo, pero siempre acierta.
En este caso, al ser los barcodes de un tamaño enorme, a pesar de que un escaner tiene una calidad mucho mayor que una camara para este objetivo, al obtener una unica imagen, las probabilidades de que hayan fallos son altas.

No hay comentarios:

Publicar un comentario