Azpazeta 2.0 Juno. Disponible a partir de hoy.

Hoy es un día muy feliz para mí, primero porque es mi cumpleaños y segundo porque sale oficialmente la nueva versión de Azpazeta, la 2.0 JUNO. Vamos a repasar las novedades que trae y lo probaremos.

Diseñado desde cero

Este es el titular para Azpazeta 2.0 Juno que al contrario de lo que el número de versión sugiere es un juego completamente nuevo. Se ha diseñado teniendo en cuenta modularidad y que sea una plataforma para añadir rápidamente nuevas características; en este aspecto Azpazeta original fallaba bastante con un código relativamente desordenado. Otra característica importante es el rendimiento de Azpazeta que ha mejorado de una manera vertiginosa. Antes con la implementación de gráficos original, el muñeco se movía lento. Ahora y gracias a su renderizado por hardware OpenGL y GLSL es mucho más rápido. No tenemos tests pero la diferencia es abismal. Otra novedad importante es el sistema de mapas y scripts que unidos sirven para crear aventuras increíbles en el universo Azpazeta. Relacionado con lo anterior tenemos la tienda online de mapas, un servicio online gratuito que provee de mapas para descargar desde Azpazeta. Otro detalle importante es el formato de partidas que sufre un resiseño (no muy grande) para ofrecer mejores características. Quizá un detalle que pase desapercibido al principio es la ventana de opciones que incluye muchas opciones (algunas sin uso actual) que siempre se agradece. Un detalla también importante internamente pero difícil de ver es la división del juego en Cliente-Servidor lo que proveerá una jugabilidad más amplia en el futuro, aunque según se está viendo, puede ser causa de problemas al intentar jugar a Azpazeta, sobre todo en plataformas Windows.

Y lo que llegará…

Azpazeta 2.0 viene sin mapas, os recomiendo pasaros por Azpazeta Market para descargaros unos cuantos, si tienes una idea para hacer un mapa, coméntanosla, nosotros te asesoraremos de como hacerlo mejor y como subirlo a Azpazeta Market gratuitamente. Si quieres ayudar en la plataforma, también eres bien recibido, hay muchas tareas que implementar. Por último comentar que ya se han definido las novedades que traerá Azpazeta 2.1 LINK, entre ellas: mayor estabilidad, sonido y audio, implementación de policía y tiendas y pequeños mini-concursos. A esto se sumarán seguramente más novedades pequeñas igualmente agradecidas.

A disfrutar

Bueno y llegado el momento, los links de descarga. Azpazeta lo podreis encontrar en muchas webs, pero yo os recomiendo ir a la que hemos creado para el lanzamiento.

loading...

PortAudio + libsndfile. Reproducir Ogg Vorbis, FLAC y WAV en C++

Escribo este post ya que cuando quise buscar información sobre el tema no encontré nada en castellano y en inglés poca información. Así pues escribo el que yo considero el mejor método para reproducir audio Ogg Vorbis, FLAC y WAV en C++.
Lo primero es descargar e instalar las librerías, ambas son multiplataforma. En Windows irás a la página oficial y seguirás las instrucciones:

A su vez si tenemos que compilar libsndfile también necesitaremos libogg y libvorbis para activar la reproducción de Ogg Vorbis o las librerías de FLAC para activar FLAC en la librería. El soporte para WAV es nativo y no hace falta nada.
En Linux podemos ahorrarnos tiempo instalando los paquetes binarios. En Debian/Ubuntu:

sudo apt-get install portaudio19-dev libsndfile1-dev

Ahora creamos un fichero de C. Atención, aunque C++ sea compatible con el código de C, este código de C tiene problemas en compiladores de C++. Así pues el código de aquí abajo da error con g++ pero funciona correctamente y sin advertencias en gcc. Si quieres insertarlo en un programa de C++, sigue creando este fichero como fichero de C y en el header encapsula la función definida en un “extern C”:

extern "C" {   
	miFuncionAudio();
}

Ahora en el ejemplo voy a usar una función main para no liarnos y usar solo C, pero eso serán los pasos a seguir si tienes C++.  Creamos el fichero con extensión .c y escribimos la función main(). Ahora abriremos el archivo de audio con la librería encargada de decodificar el audio, libsndfile. Después inicializamos PortAudio y obtenemos el dispositivo de audio por defecto (en el caso de mi Ubuntu, es ALSA). Configuramos el dispositivo con los datos que tenemos del fichero. Abrimos un stream de PortAudio que leerá el archivo. Esta función necesita dos funciones de callbak que se crean más arriba. La principal tiene como objetivo leer el fichero más y la otra hacer algo cuando termine el fichero (se puede dejar vacía). En la de leer el fichero tenemos que tener en cuenta si el equipo es Mono o Estéreo. Yo no he llegado a saber como detectarlo, así que hago la multiplicación por 2 para el estéreo. Luego en el flujo principal iniciamos el stream, sonará, esperamos 10 segundos, paramos y cerramos el stream. Finalmente cerramos el fichero de audio y deshabilitamos PortAudio. Fácil y sencillo. Ahora el código:

#include "portaudio.h"
#include "sndfile.h"

SF_INFO sfinfo;
PaStreamParameters out_param;
PaStream * stream;
PaError err;
SNDFILE * file;
static int
output_cb(const void * input, void * output, unsigned long frames_per_buffer,
        const PaStreamCallbackTimeInfo *time_info, PaStreamCallbackFlags flags, void * data)
{
	SNDFILE * filex = data;
	/* Here you need to multiply per 2 for stereo and per 1 for mono*/
	sf_read_short(filex, output, frames_per_buffer*2);
	return paContinue;
}
static void
end_cb(void * data)
{
	 Pa_StopStream(stream);
	 Pa_CloseStream(stream);
	 sf_close(file);
	 Pa_Terminate();
}  
#define error_check(err) \     do {\         if (err) { \             fprintf(stderr, "line %d ", __LINE__); \             fprintf(stderr, "error number: %d\n", err); \             fprintf(stderr, "\n\t%s\n\n", Pa_GetErrorText(err)); \             return err; \         } \     } while (0)  
int main(int argc, char ** argv)
{
	 file = sf_open(argv[1], SFM_READ, &sfinfo);
	 printf("%d frames %d samplerate %d channels\n", (int)sfinfo.frames,
	 sfinfo.samplerate, sfinfo.channels);
	 /* init portaudio */
	 err = Pa_Initialize();
	 error_check(err);
	 /* we are using the default device */
	 out_param.device = Pa_GetDefaultOutputDevice();
	 if (out_param.device == paNoDevice)
	 {
		fprintf(stderr, "Haven't found an audio device!\n");
		return -1;
	 }
	 /* stero or mono */
	 out_param.channelCount = sfinfo.channels;
	 out_param.sampleFormat = paInt16;
	 out_param.suggestedLatency = Pa_GetDeviceInfo(out_param.device)->defaultLowOutputLatency;
	 out_param.hostApiSpecificStreamInfo = NULL;
	 err = Pa_OpenStream(&stream, NULL, &out_param, sfinfo.samplerate,
	 paFramesPerBufferUnspecified, paClipOff,output_cb, file);
	 error_check(err);
	 err = Pa_SetStreamFinishedCallback(stream, &end_cb);
	 error_check(err);
	 err = Pa_StartStream(stream);
	 error_check(err);
	 printf("Play for 10 seconds.\n");
	 Pa_Sleep(10000);
	 err = Pa_StopStream(stream);
	 error_check(err);
	 err = Pa_CloseStream(stream);
	 error_check(err);
	 sf_close(file);
	 Pa_Terminate();
	 return 0;
}

Y para terminar un diagrama de salidas de audio nativas soportadas por PortAudio: