Bueno, como todavia no puedo mirar en el cvs escribo unas cosillas
para el fichero SoundServer.cpp.
En el constructor la parte de
#ifdef _WIN32
alutInit(0,NULL);
alGetError();
...
Seria mejor poner
Device = alcOpenDevice((ALubyte*)"DirectSound3D");
//No creo que una tarjeta actual de sonido no soporte Dsound.
Efectivamente, veo que los ogg los cargais enteros en memoria,(un
poco bestia). asi qeu bueno, la solución es algo complicada, ya
que
hay que hacer una serie de funciones que usaremos como callbacks,
y unas cosillas mas, luego tendremos que iniciar cargar, y luego
para actuliazar los bufferes tendriamos que ponerlo dentro de un
bucle(bucle principal), o en todo caso crear una hebra o algo por el
estilo, que se encargue de actualizar los bufferes.
Aqui pongo el codigo que he hecho(teneis mi permiso pa usarlo):
Para el fichero en memoria creo una structura llamada MYFILE
/*
Esta estructura es utilizada para la carga de musica comprimida.
Esta estructura almacena la longitud total del fichero comprimido
así
como su posición actual.
*/
struct MFILE
{
long m_longitudtotal;
//Longitud total de la muestra
long m_posactual;
//La posicion actual en la que se encuentra reproduciendo
char *m_datos;
//Puntero que contiene los datos
bool abre(const std::string nombre);
bool destruye();
~MFILE();
};
/********************************************************************
****/
/*
MFILE */
/********************************************************************
****/
/*
Abre el fichero y lo carga en memoria
*/
bool MFILE::abre(const std::string nombre)
{
FILE *fi = fopen(nombre.c_str(),"rb");
if(fi==NULL)
{
printf("ERROR, no existe el fichero\n");
return false;
}
fseek(fi,0,SEEK_END);
m_longitudtotal = ftell(fi);
rewind(fi);
m_datos = (char*)_aligned_malloc(sizeof(char)
*m_longitudtotal,16);
if(!m_datos)
return false;
fread(m_datos,sizeof(char),m_longitudtotal,fi);
fclose(fi);
m_posactual = 0;
return true;
}
/*
Destruye el fichero si contiene informacion la elimina
*/
bool MFILE::destruye()
{
if(m_datos!=NULL)
_aligned_free(m_datos);
m_longitudtotal = 0;
m_posactual = 0;
return true;
}
/*
Destructor de la clase;
*/
MFILE::~MFILE()
{
if(m_datos!=NULL)
_aligned_free(m_datos);
}
(quitad los _aligned_malloc y free por lo que useis(new o malloc, da
igual).
A continuacion pongo las callbacks necesarias
/********************************************************************
****/
/* CALLBACKS PARA
OGG */
/********************************************************************
****/
/*
Funcion de posicionamiento:
Abstrae el posicionamiento de la funcion fseek.
Se realiza desde la memoria, esta es lineal y ademas
alineada.
*/
int funcion_seek(void *mfile,ogg_int64_t offset,int whence)
{
switch(whence)
{
case 0://SET
((MFILE*)mfile)->m_posactual = (long)offset;
break;
case 1://CUR
if(offset+((MFILE*)mfile)->m_posactual<=((MFILE*)
mfile)->m_longitudtotal)
((MFILE*)mfile)->m_posactual = ((MFILE*)
mfile)->m_posactual + (long)offset;
else
((MFILE*)mfile)->m_posactual = ((MFILE*)
mfile)->m_longitudtotal;
break;
case 2://END
((MFILE*)mfile)->m_posactual = ((MFILE*)mfile)-
>m_longitudtotal+(long)offset;
break;
default:
return -1;
}
return 0;
}
/*
Funcion de posicion:
Indica cual es la posicion actual en el vector.
Abstrae el funcionamiento de ftell();
*/
long funcion_tell(void *mfile)
{
return ((MFILE*)mfile)->m_posactual;
}
/*
Funcion de cierre:
Como no queremos tener que recargar el contenido en
memoria, para
el cierre lo que hacemos es posicionar la posicion
actual en 0
así las funciones de lectura simplemnte no sabran
que se ha cerrado
ni nada por el estilo.
Para la eliminacion del contenido de mfile habria
que llamar a destruye
*/
int funcion_close(void *mfile)
{
((MFILE*)mfile)->m_posactual=0;
return 1;
}
/*
Funcion de lectura:
Tiene comprobaciones de que no se ha llegado al
final del array,
o si por algún caso se ha producido un error y hemos
sobrepasado
el limite.
Sino realiza en memcpu del buffer en buf simulando
la lectura desde
el disco solo que es desde memoria
*/
size_t funcion_lectura(void *buf,size_t size,size_t nmeb,void *mfile)
{
if(((MFILE*)mfile)->m_posactual == ((MFILE*)mfile)-
>m_longitudtotal)
{
return 0;
}
if(((MFILE*)mfile)->m_posactual > ((MFILE*)mfile)-
>m_longitudtotal)
{
return -1;
}
long disponible = ((MFILE*)mfile)->m_longitudtotal -
((MFILE*)mfile)->m_posactual;
long pedido = (long)(nmeb*size);
long datos_a_leer = disponible>pedido?pedido:disponible;
memcpy(buf,&(((MFILE*)mfile)->m_datos[((MFILE*)mfile)-
>m_posactual]),datos_a_leer*sizeof(char));
((MFILE*)mfile)->m_posactual+=datos_a_leer;
return datos_a_leer;
}
Para mi reproductor tengo una clase ogg(si no creais que pq haya
dicho de usar asm, no uso c++, de hecho la libreria matematica esa
usa una interfaz de c++)
la clase es largo y complicado para ponerlo aqui, asi que pongo lo
que hace.
tengo un miembro de la clase que se llama
m_call, que es del tipo ov_callback
asi abro el fichero con MFILE, y despues hago:
m_call.close_func = funcion_close;
m_call.read_func = funcion_lectura;
m_call.seek_func = funcion_seek;
m_call.tell_func = funcion_tell;
para abrir el fichero ogg usamos
ov_open_callbacks(m_mfichero,&m_ogg,NULL,0,m_call);
donde m_mfichero es del tipo MFILE.
La diferencia es la siguiente:
fichero ogg de 4 megas
metodo: todo el fichero en memoria,
memoria 30 megas
cpu 2%
metodo: leer del disco duro lo necesario
memoria 0 megas
cpu 99%
metodo: leer con callback
memoria 2 megas
cpu 6%
La diferencia a mi me parece aceptable.