[JUEGO] Guitarfun 3.5 USB para Wii

Thyl-Thalion escribió:Probado con Pendrive USB Kingston de 256MB. Funciona. Probaré hoy con más cosas (PSP, HDD, otros pendrive). Molto bene !!!!

Recuerda que solo funciona con el sistema de archivos FAT/FAT32
No funcionará no con ntfs ni extf2 ni nada de mac solo fat
Hola, Hemes.
Yo uso un viejo joystick de mi Atari, con un adaptador que compré en un chino, pero el juego no me reconoce el segundo jugador. ¿podrías arreglarlo? porfa, que si no, voy a tener que pasar de jugar...
[carcajad]

Ahora en serio: estoy alucinado con el juego!!! Es genial y te agradezco enormemente que hayas dedicado tanto tiempo para regalar horas de diversión a la gente.
Muchas gracias por todo (y también a la gente que por su cuenta intenta ayudar mejorando el juego). Espero que este esfuerzo se traduzca en algún tipo de recompensa en breve.
esta va mucho mejor pero tarda mucho al cargar las canciones
Erep escribió:esta va mucho mejor pero tarda mucho al cargar las canciones

Es que el usb va a un tope de 700kb/s, mientras que la sd va a unos 5700kb/s y hermes no va leyendo poco a poco, sino que carga toda la canción de golpe en memoria. Para que fuera casi inmediato habría que crear un thread que fuera leyendo en 2º plano y rellenando el buffer.
Lo que no se es si esto haría que se sobrecargase el sistema y desincronizaría las canciones.
Para una canción tiene que cargar unos 10Mb por lo que son unos 15 segundos de carga en usb, mientras que con la sd serían unos 2 segundos. Sería una posible mejora, pero eso se lo dejo a otro ;) a no ser que haya mucha gente interesada en mejorar el arranque de las canciones.
Yo la verdad es que he jugado un par de veces, pero soy tan malo que no he seguido probándolo, ademas que no noto la desincronización que dicen algunos respecto a las notas, se ve que tengo mal oido y pulso de vista.
Lo de la desincronización suele pasar en niveles alto que es cuando hay muchas notas y se puede dar aquel problema que se estuvo debatiendo un tiempo, si dices que eres muy malo no se si estaras jugando ya con los 5 colores, pero si juegas en facil o medio, para que se desincronice es porque la canción está fatal hecha (que las hay, pero no tiene que ver con la aplicacion).
Buenas :)

rodries siento no haber podido responderte antes, pero ayer estuve ocupado haciendo otra cosa y no podía probar la libreria y hoy he tenido un grave problema que no sabía si era debido a libfat o aun nivel mas bajo (driver usb) o era algo de mi programa y al final ha resultado ser, que sin darme cuenta había metido demasiada carga en el mezclador de audio que utiliza la interrupción de sonido.

El caso es que era muy raro. en cierto juego petaba cuando se cerraba/abria de nuevo un fichero y de una forma un tanto aleatoria: podía darse en el primer caso o despues de 20 intentos, según le diera.

Es algo que siempre me ha preocupado en sndlib, que el mezclado se produjera en la misma interrupción, pero que no tiene porque pasar nada sialvo que hagas algo similar a lo que mio (que era un mezclado externo a la librería y algo excesivo)

Por otro lado, ya no me da problema con los saves, pero si que parece que el dispositivo USB le cuesta algo pillarlo (uso una deteccion que busca si existe el directorio conveniente primero en el dispositivo USB y si no está en la SD). Sobre todo le cuesta cuando accede por primera vez, pero se resuleve repartiendo usleeps por doquier XD

Sobre guitarfun el programa necesita cachear en memoria las tres pistas Ogg (como maximo). En el programa original, en PS2, una pista la leia directamente del dispositivo y el resto desde memoria, para acortar la espera, pero decidí cachear las 3 porque por alguna razón, al reproducir el Ogg metía un pequeño parón leyendo de dispositivo a veces (no se si ahora se producirá o no, parece que no, pero he estado centrado en otras cosas y no me he dado cuenta)

El caso es que se deben cachear las pistas porque acceder a tres dispositivos a la vez, es demasiado lento. Quizá se podría hacer un hilo que fuera cargando poco a poco el fichero mientras se reproduce, pero sería algo complejo y añadiría un plus de proceso que a lo mejor, lo acabas pagando.

El problema es la velocidad de los dispositivos: en PC es una espera corta, con la SD es media y por lo que decís, por USB es demasiado lenta. Hay canciones que pueden transferir unos 25 MB entre los 3 Oggs.

Subo el enlace de rodries a la cabecera (por cierto, no he podido probarlo... ni siquiera tengo canciones en la SD ahora mismo [+risas] )
Hermes escribió:Buenas :)

rodries siento no haber podido responderte antes, pero ayer estuve ocupado haciendo otra cosa y no podía probar la libreria y hoy he tenido un grave problema que no sabía si era debido a libfat o aun nivel mas bajo (driver usb) o era algo de mi programa y al final ha resultado ser, que sin darme cuenta había metido demasiada carga en el mezclador de audio que utiliza la interrupción de sonido.

El caso es que era muy raro. en cierto juego petaba cuando se cerraba/abria de nuevo un fichero y de una forma un tanto aleatoria: podía darse en el primer caso o despues de 20 intentos, según le diera.

Es algo que siempre me ha preocupado en sndlib, que el mezclado se produjera en la misma interrupción, pero que no tiene porque pasar nada sialvo que hagas algo similar a lo que mio (que era un mezclado externo a la librería y algo excesivo)

Por otro lado, ya no me da problema con los saves, pero si que parece que el dispositivo USB le cuesta algo pillarlo (uso una deteccion que busca si existe el directorio conveniente primero en el dispositivo USB y si no está en la SD). Sobre todo le cuesta cuando accede por primera vez, pero se resuleve repartiendo usleeps por doquier XD

A mi también me ha ocurrido cosas similares, de hecho en una de las modificaciones del usbstorage.c en la carpeta ogc_io de la libfat en la linea 104 hay un comentario que he puesto:
usleep(50); // I don't know why I have to wait but it's needed
prueba a subir el usleep a 100 o 200 a ver si se te soluciona. Ese parche es para poder montar y desmontar el usb sin que se quede bloqueado el dispositivo.

Hermes escribió:Sobre guitarfun el programa necesita cachear en memoria las tres pistas Ogg (como maximo). En el programa original, en PS2, una pista la leia directamente del dispositivo y el resto desde memoria, para acortar la espera, pero decidí cachear las 3 porque por alguna razón, al reproducir el Ogg metía un pequeño parón leyendo de dispositivo a veces (no se si ahora se producirá o no, parece que no, pero he estado centrado en otras cosas y no me he dado cuenta)

El caso es que se deben cachear las pistas porque acceder a tres dispositivos a la vez, es demasiado lento. Quizá se podría hacer un hilo que fuera cargando poco a poco el fichero mientras se reproduce, pero sería algo complejo y añadiría un plus de proceso que a lo mejor, lo acabas pagando.

El problema es la velocidad de los dispositivos: en PC es una espera corta, con la SD es media y por lo que decís, por USB es demasiado lenta. Hay canciones que pueden transferir unos 25 MB entre los 3 Oggs.

Pienso que podría intentar a ver como queda con un hilo con baja prioridad en 2º plano que vaya rellenando la memoria mientras se reproduce, no debería afectar al rendimiento ya que la lectura consume poca cpu
Lo que no pillo es lo de las 3 pistas, en las dos canciones que me he bajado solo hay 2 ogg guitar.ogg y song.ogg, aunque desconozco el formato FOF y puede que haya canciones con 3 ogg.
Si me lio te mandaré un privado para que me expliques el hilo de reproducción, es que tu código cuesta un egg seguirlo, está poco estructurado y funciones muy largas con muchos ifdef y if XD, aunque no es complicado de entender, solo que me pierdo muchas veces siguiendo la traza.
La verdad es que disfruto mas trajinando el código de tu juego que jugando XD

Edit:
Ya veo en el código que puede existir rhythm.ogg, ¿me puedas dar por privado un enlace a una canción que tenga 3 ogg?
rodries escribió:A mi también me ha ocurrido cosas similares, de hecho en una de las modificaciones del usbstorage.c en la carpeta ogc_io de la libfat en la linea 104 hay un comentario que he puesto:
usleep(50); // I don't know why I have to wait but it's needed
prueba a subir el usleep a 100 o 200 a ver si se te soluciona. Ese parche es para poder montar y desmontar el usb sin que se quede bloqueado el dispositivo.


Si, eso lo vi ayer.

Hay una cosa que me mosquea del uso USB y es que hace llamadas asíncronas a IOS, pero no parece tomarse muchas molestias
en comprobar si al entrar a ciertas funciones, puede haber una de estas llamadas en proceso: podría explicar por que se necesitan esos delays. Meter un delay está indicando que hay un proceso que trabaja en paralelo al que hay que esperar y solo se me ocurre que venga de ahí.


rodries escribió:Pienso que podría intentar a ver como queda con un hilo con baja prioridad en 2º plano que vaya rellenando la memoria mientras se reproduce, no debería afectar al rendimiento ya que la lectura consume poca cpu
Lo que no pillo es lo de las 3 pistas, en las dos canciones que me he bajado solo hay 2 ogg guitar.ogg y song.ogg, aunque desconozco el formato FOF y puede que haya canciones con 3 ogg.
Si me lio te mandaré un privado para que me expliques el hilo de reproducción, es que tu código cuesta un egg seguirlo, está poco estructurado y funciones muy largas con muchos ifdef y if XD, aunque no es complicado de entender, solo que me pierdo muchas veces siguiendo la traza.
La verdad es que disfruto mas trajinando el código de tu juego que jugando XD

Edit:
Ya veo en el código que puede existir rhythm.ogg, ¿me puedas dar por privado un enlace a una canción que tenga 3 ogg?


Si metes un hilo de "baja prioridad", tienes que tener en cuenta, sobre todo la prioridad de thread_ogg, puesto que en las canciones asume el rol de hilo permanente y las lecturas al realizarse desde memoria, interrumpen poco y encima tener en cuenta
que la lectura de ogg necesita datos del principio y del final del fichero por lo menos, antes de poder echar a andar.

Ademas ten en cuenta que podría afectar al Online... y por supuesto: trata de respetar el código de PC (el programa tiene mucho código y se vuelve mas lioso por éste hecho) y tambien recuerda que no debería estar trabajando durante la reproduccion de la lista de canciones (ahi se tira de dos oggs desde dispositivo ya que tiene poca carga de trabajo)

En PC no puedes fijar la prioridad tan a dedo como en la consola, por lo que no te aconsejo cachear ahí los ficheros, aparte de que no merece la pena en mi opinión.

Sobre las canciones de tres pistas, debes buscar packs de canciones de los Guitar Hero a partir del 2 que es el primero en dar la posibilidad de tocar el bajo (no confundir con "tocarse los bajos" [carcajad] ). Hacer canciones de estas, es algo que solo está al alcance de los profesionales y no te extrañes no haberlas visto antes: a mi me pasó en PS2 que monté el juego para usar solo dos pistas y cuando me encontré con una tercera pista se me quedó cara de gilipollas, porque si ya le costaba al bicho mover dos pistas, imaginate 3 [+risas] (al final, no solo pudo con las tres, si no que pudo con dos jugadores, despues de algunos arreglos ;))

Saludos.
Hermes escribió:Si, eso lo vi ayer.

Hay una cosa que me mosquea del uso USB y es que hace llamadas asíncronas a IOS, pero no parece tomarse muchas molestias
en comprobar si al entrar a ciertas funciones, puede haber una de estas llamadas en proceso: podría explicar por que se necesitan esos delays. Meter un delay está indicando que hay un proceso que trabaja en paralelo al que hay que esperar y solo se me ocurre que venga de ahí.

usa LWP_CondTimedWait para dar error si se produce un timeout, puede que se le haya olvidado usarlo en algun sitio que utilize una llamada asincrona y no controle el timeout, la verdad es que es algo lioso el código.

Hermes escribió:Si metes un hilo de "baja prioridad", tienes que tener en cuenta, sobre todo la prioridad de thread_ogg, puesto que en las canciones asume el rol de hilo permanente y las lecturas al realizarse desde memoria, interrumpen poco y encima tener en cuenta
que la lectura de ogg necesita datos del principio y del final del fichero por lo menos, antes de poder echar a andar.

Ademas ten en cuenta que podría afectar al Online... y por supuesto: trata de respetar el código de PC (el programa tiene mucho código y se vuelve mas lioso por éste hecho) y tambien recuerda que no debería estar trabajando durante la reproduccion de la lista de canciones (ahi se tira de dos oggs desde dispositivo ya que tiene poca carga de trabajo)

En PC no puedes fijar la prioridad tan a dedo como en la consola, por lo que no te aconsejo cachear ahí los ficheros, aparte de que no merece la pena en mi opinión.

Ok, ya veremos a ver si se complica o no, si se me lia lo dejaré estar.
Una duda que tengo en thread_ogg es porque despues de cargar el track1 en memoria haces close y le asignas el valor 0x666 y ese es el valor que luego le pasas a ov_open.
y lo mismo con los otros 2 tracks restantes.

Edit:
ya me he dado cuenta de lo que has hecho en f_read, joe podias haber puesto un comentario :)
Hermes escribió:Sobre las canciones de tres pistas, debes buscar packs de canciones de los Guitar Hero a partir del 2 que es el primero en dar la posibilidad de tocar el bajo (no confundir con "tocarse los bajos" [carcajad] ). Hacer canciones de estas, es algo que solo está al alcance de los profesionales y no te extrañes no haberlas visto antes: a mi me pasó en PS2 que monté el juego para usar solo dos pistas y cuando me encontré con una tercera pista se me quedó cara de gilipollas, porque si ya le costaba al bicho mover dos pistas, imaginate 3 [+risas] (al final, no solo pudo con las tres, si no que pudo con dos jugadores, despues de algunos arreglos ;))

Saludos.

Pienso que una mejora es que si son solo 2 ogg el tercer ogg no deberias de volver a leerlo ya que podrías reutilizar guitar.ogg, digamos que file[1]=file[2] mas o menos. Así se acortaría 1/3 la carga de las canciones que usen 2 ogg. ¿Ves alguna pega en esto?
rodries escribió:
usa LWP_CondTimedWait para dar error si se produce un timeout, puede que se le haya olvidado usarlo en algun sitio que utilize una llamada asincrona y no controle el timeout, la verdad es que es algo lioso el código.


Pues esa es otra cosa que puede no estar bien, porque puede producirse un timeout antes de lo que debería.

rodries escribió:
Ok, ya veremos a ver si se complica o no, si se me lia lo dejaré estar.
Una duda que tengo en thread_ogg es porque despues de cargar el track1 en memoria haces close y le asignas el valor 0x666 y ese es el valor que luego le pasas a ov_open.
y lo mismo con los otros 2 tracks restantes.

Edit:
ya me he dado cuenta de lo que has hecho en f_read, joe podias haber puesto un comentario :)


¿No es mas divertido ir a ciegas? [+risas]

Si, esa es la forma que tengo de cachear los ogg: de hecho la tremor utiliza fopen, etc, por defecto, pero permite digamos, definir tus propias funciones: yo usaba open, read, etc, porque es lo que tenía disponible en PS2 de forma estable, mediante mi librería (total, si es lo mismo)



rodries escribió:Pienso que una mejora es que si son solo 2 ogg el tercer ogg no deberias de volver a leerlo ya que podrías reutilizar guitar.ogg, digamos que file[1]=file[2] mas o menos. Así se acortaría 1/3 la carga de las canciones que usen 2 ogg. ¿Ves alguna pega en esto?


El tercer ogg no se procesa si no existe: directamente, no se lee (mira el código de control de fd3) y lo unico que hace, es pasar samples suficientes al mezclador.

Lo unico que no tengo en cuenta es si solo hay un ogg, que en ese caso, si pasa eso que dices (se leeria dos veces el mismo fichero)

Por cierto, se me ha olvidado decirte que lo mismo que hace que no me liste el USB a mi, sobre todo en el primer acceso desde el arranque, hace que tu deteccion "mounted()" falle y en realidad, no estes usando cache alguna!!!

Yo uso algo asi:

fatInit(8, false);

    fatSetDefaultInterface(PI_INTERNAL_SD);
    usleep(1000*1000);
   have_device=0;
   {

    char fat[7] = "fat0:/";
   
   fat[3] = 48+PI_INTERNAL_SD;
   
   dir = diropen(fat);
    if (dir) {dirclose(dir); have_device|=1;fatEnableReadAhead(PI_INTERNAL_SD, 6, 64);}
   usleep(200*1000);

   fat[3] = 48+PI_USBSTORAGE;
   
   dir = diropen(fat);
    if (dir) {dirclose(dir);  have_device|=2;fatEnableReadAhead(PI_USBSTORAGE, 6, 64);}
   usleep(200*1000);

    }


Quizá sea algo exagerado con los tiempos, pero prefiero ser holgado que quedarme corto.

En PS2, yo tenía preparado el device USB de tal forma, que si abria el dispositivo con un open, me devolvia un error caracteristico si no había nada conectado y otro error si no estaba preparado (no se si aquí hay algo similar). De forma esa forma sabía si no habia dispositivo USB y si lo había, solo tenia que hacer un bucle de espera por un determinado tiempo que se cortaba en cuanto me devolviera un OK (es decir, se adaptaba a los tiempos de cada dispositivo que suele ser difente, obviamente)

Aqui como no hay nada de eso, pues lo mejor es meter una buena pausa al principio
Hermes escribió:Por cierto, se me ha olvidado decirte que lo mismo que hace que no me liste el USB a mi, sobre todo en el primer acceso desde el arranque, hace que tu deteccion "mounted()" falle y en realidad, no estes usando cache alguna!!!

Yo uso algo asi:

fatInit(8, false);

    fatSetDefaultInterface(PI_INTERNAL_SD);
    usleep(1000*1000);
   have_device=0;
   {

    char fat[7] = "fat0:/";
   
   fat[3] = 48+PI_INTERNAL_SD;
   
   dir = diropen(fat);
    if (dir) {dirclose(dir); have_device|=1;fatEnableReadAhead(PI_INTERNAL_SD, 6, 64);}
   usleep(200*1000);

   fat[3] = 48+PI_USBSTORAGE;
   
   dir = diropen(fat);
    if (dir) {dirclose(dir);  have_device|=2;fatEnableReadAhead(PI_USBSTORAGE, 6, 64);}
   usleep(200*1000);

    }


Quizá sea algo exagerado con los tiempos, pero prefiero ser holgado que quedarme corto.

En PS2, yo tenía preparado el device USB de tal forma, que si abria el dispositivo con un open, me devolvia un error caracteristico si no había nada conectado y otro error si no estaba preparado (no se si aquí hay algo similar). De forma esa forma sabía si no habia dispositivo USB y si lo había, solo tenia que hacer un bucle de espera por un determinado tiempo que se cortaba en cuanto me devolviera un OK (es decir, se adaptaba a los tiempos de cada dispositivo que suele ser difente, obviamente)

Aqui como no hay nada de eso, pues lo mejor es meter una buena pausa al principio

Yo cambiaría 48+ por '0'+ es mas intuitivo a la hora de entenderlo, no tiene nadie porque saber que el código ascii del 0 es 48. Como te gusta fastidiar a los que luego trajinan con tus fuentes XD

Esto si que me pilla fuera de juego, no entiendo porque poniendo un usleep donde lo has puesto ya funciona sin pegas.
A mi nunca me ha fallado el montar el usb a la primera, no se porque te pasa a tí, ademas de que me has dejao flipao que por poner un usleep en ese punto se arregle todo, ya que en ese punto la unidad debería estar ya funcionando.
Haz una prueba, quita tus usleep y pon uno en la funcion __usbstorage_IsInserted que está en el usbstorage.c de ogc_io de la libfat en el punto que te voy a decir:
Al final de la funcion cambia:
if(__mounted == 1)
return true;
return false;
Por:
if(__mounted == 1)
{
usleep(100);
return true;
}
return false;

y dime si ahora ya no falla.
Si no falla es por que cuando se abre el usb esta ocupado durante un momento y se ve que se realiza un acceso a el cuando aun no está listo.
Ya me contaras.
Pues macho, que cosa mas rara ¿Te acuerdas que tenia problemas y tenía que meter delays, etc? Pues ahora no me da fallo alguno, incluso cuando le quito el delay ese que metes tu. He pasado de que en cada arranque sin los delays me fallaba, a que ahora no me falla nunca: ni en la primera carga, ni cargando varias veces desde WIFI, ni cambiando de puerto, etc

No se que coño he tocado, que se ha arreglado solo XD.

De todas formas, he retirado un poco la inicializacion de fat, para ganar la ventaja de la pantalla de presentacion de mi programa
y un detalle que se me ha ocurrido, es flushear el buffer que devuelve USB_GetDeviceList() por si esa es la explicación de que tengas que meter el udelay:

DCFlushRange(buffer, DEVLIST_MAXSIZE << 3);

No se si sirve para algo o no, pero lo pongo por si las moscas. A lo mejor el problema es que liberas esa memoria, sin haberse volcado los datos de la cache y se asigna en otra parte y por eso te peta. Desde luego es un efecto raro.

Lo que está claro es que si el udelay ese es necesario y es porque algo escribe en esa memoria, el udelay está en mal sitio, pues deberia estar antes de la lectura del buffer para asegurarse de que lo que sea ha terminado o si es un problema de escritura de cache, pues flusheando se arregla [+risas]

Si tienes alguna aplicacion donde puedas forzar el fallo del udelay quitalo y si prueba con el flush a ver que tal.
Pues la verdad es que no tengo ni idea de porque puede ser el fallo, pero me alegro mucho que te funcione la libfat sin problemas y como dicen en mi tierra si funciona no lo toques :)
El usleep que puse era porque al hacer fatunmont y famount para ver si se ha cambiado de llave usb no me detectaba el dispositvo y eso que al no cambiarla no intento ni siquiera inicializarla ya que el pid y el vid coinciden. Si quitas el usleep de la linea 104 y haces fatunmont y famount la llave dejar de funcionar casi siempre pero no me preguntes el porque.

En el gitarfun lo que he hecho es que el f_seek devuelva -1 por lo que no es seekeable y ya no va al final de la cancion a sacar informacion, el unico efecto negativo es que ov_time_seek ya no funciona pero solo lo usas para adelantar 30 segs el inicio de la cancion cuando estás en la lista, como ventaja es que inmediatamente se pone a reproducir en la lista. También he mejorado la carga al hacer que el tercer track sea igual al segundo sino existe rhythm.ogg por lo que en la mayoria de las canciones se acelera la carga 1/3 y ademas al no tener seek la apertura que antes tardaba 1,5 segundos te la ahorras y como son 2 tracks se ha ganado 3 segundos de carga adicionales. Como te comento el único efecto negativo es no poder reproducir a partir del segundo 30 en la lista de canciones.
A lo mejor mañana me pongo a hecharle un vistazo al thread de carga en 2ºplano
Ya veré de que humor me levanto.
Tios !! Gracias !!
Disfruto casi más leyendo estos posts que jugando.
Sois unos craks!!!
[tadoramo] [tadoramo]
o.O Jope, si que avanza este homebrew, XD Dentro de poco sera el mismo que la PS2 O Wii XD, ojala consiga acerlo identico, seria un crack!! weno ya lo es XD
XD...Buen homebrew...Ya os veo a todos viciaos XD XD XD XD XD
rodries escribió:Pues la verdad es que no tengo ni idea de porque puede ser el fallo, pero me alegro mucho que te funcione la libfat sin problemas y como dicen en mi tierra si funciona no lo toques :)
El usleep que puse era porque al hacer fatunmont y famount para ver si se ha cambiado de llave usb no me detectaba el dispositvo y eso que al no cambiarla no intento ni siquiera inicializarla ya que el pid y el vid coinciden. Si quitas el usleep de la linea 104 y haces fatunmont y famount la llave dejar de funcionar casi siempre pero no me preguntes el porque.

En el gitarfun lo que he hecho es que el f_seek devuelva -1 por lo que no es seekeable y ya no va al final de la cancion a sacar informacion, el unico efecto negativo es que ov_time_seek ya no funciona pero solo lo usas para adelantar 30 segs el inicio de la cancion cuando estás en la lista, como ventaja es que inmediatamente se pone a reproducir en la lista. También he mejorado la carga al hacer que el tercer track sea igual al segundo sino existe rhythm.ogg por lo que en la mayoria de las canciones se acelera la carga 1/3 y ademas al no tener seek la apertura que antes tardaba 1,5 segundos te la ahorras y como son 2 tracks se ha ganado 3 segundos de carga adicionales. Como te comento el único efecto negativo es no poder reproducir a partir del segundo 30 en la lista de canciones.
A lo mejor mañana me pongo a hecharle un vistazo al thread de carga en 2ºplano
Ya veré de que humor me levanto.



Humm, no me gusta que hayas quitado lo del adelanto de 30 segundos, porque sirven de referencia y eso debe quedar asi.

Por tanto, mi sugerencia es que actives un flag para tratar de forma diferente (como yo lo hago) la reproduccion desde el menu y la de la musica en el juego.

Yo no he probado tu version, pero si el dispositivo USB es tan lento que supone un inconveniente (lo de adelantar 30 segundos) en la seleccion de canciones, es mejor que lo dejes: la idea del programa es que sea lo suficientemenete agil y si va a perder su agilidad y practicidad pues para eso, nos quedamos como estamos.

También he mejorado la carga al hacer que el tercer track sea igual al segundo sino existe rhythm.ogg por lo que en la mayoria de las canciones se acelera la carga 1/3 y ademas al no tener seek la apertura que antes tardaba 1,5 segundos te la ahorras


Esto ya te he dicho que no es asi: el programa SOLO reproduce 2 pistas si la tercera no existe, por lo que has hecho... nada XD.

Veamos, esta es la apertura del 3 Ogg:
if(midi_ritmo) sprintf(pathname,"%sguitar.ogg",list_songs[tema].path);
         else sprintf(pathname,"%srhythm.ogg",list_songs[tema].path);


En el codigo anterior podemos ver que si está activada la variable midi_ritmo se toma como nombre "guitar.ogg". Esto es asi porque significa que estamos tocando el bajo y por tanto, la primera pista es el bajo y aqui será la guitarra. Pero claro, para que esa condicion se de, la cancion tiene que tener una pista de ritmo y además, ser seleccionado el bajo como instrumento a tocar. Es decir, en condiciones normales, midi_ritmo vale 0.

Y si no se cumple la condicion, entonces la tercera pista es el ritmo, pero tal y como se ve en esta seccion:

my_eof3=0;

      fd3=open(pathname,O_RDONLY | O_BINARY, S_IREAD);
      
      if(fd3>=0)
         {

         file[1].size=lseek(fd3,0,2);
         lseek(fd3,0,0);
         file[1].pos=0;
         file[1].mem=malloc(file[1].size);
         if(!file[1].mem)
            {
            close(fd3);
            fd3=-1;
            if(debug_mode) s_debug("Track #3: malloc fail");
            }
         else
            {
            delay_online=1;
            n=read(fd3,file[1].mem,file[1].size);
            delay_online=0;
            close(fd3);
            fd3=0x667;
            if(n<file[1].size)
               {
               f_close(&fd3);
               fd3=-1;
               if(debug_mode) s_debug("Track #3: truncated file");
               }
            }
         }


Si no se abre el fichero, aqui no se usa nombre alternativo, como si sucede en el caso de fd y fd2, donde si no existe guitar.ogg, se toma song.ogg o viceversa (pero eso solo pasa en el caso de que solo haya 1 ogg)

En la continuacion del codigo se puede ver que si fd3<0, no se abre el ogg de ritmo y ese guitar.ogg no es posible tomarlo a menos que exista un rhythm.ogg y ademas, esté seleccionado el bajo como instrumento. Además, se ve claramente que está separado porque aqui no se toma como un error el que fd3 sea menor que 0 ya que el resto del programa está preparado para ello.

Asi que no se que estás haciendo ahí, pero no tendrias que tocar nada XD

Por cierto, con respecto a la librería, ayer tuve un fallo desde arranque, que no me tomó el dispositivo quiza influenciado por que
pongo un .mod a reproducir y ese hilo tiene una prioridad de 80. Una cosa que no recordé ayer, es que fije la prioridad del main a 40 (la misma que asigno a guitarfun). No se si tendra algo que ver o no, pero como bien dices, si algo parece funcionar bien, no lo toques.
Hermes escribió:Si no se abre el fichero, aqui no se usa nombre alternativo, como si sucede en el caso de fd y fd2, donde si no existe guitar.ogg, se toma song.ogg o viceversa (pero eso solo pasa en el caso de que solo haya 1 ogg)

En la continuacion del codigo se puede ver que si fd3<0, no se abre el ogg de ritmo y ese guitar.ogg no es posible tomarlo a menos que exista un rhythm.ogg y ademas, esté seleccionado el bajo como instrumento. Además, se ve claramente que está separado porque aqui no se toma como un error el que fd3 sea menor que 0 ya que el resto del programa está preparado para ello.

Asi que no se que estás haciendo ahí, pero no tendrias que tocar nada

Sí me di cuenta. Realmente la aceleración la tengo en que casi siempre song.ogg y guitar.ogg es el mismo fichero y en tal caso lo que hago es que se lea una vez para los 2, por lo que ahora tarda la mitad en cargar.
Respecto a lo de los 30 segundos, miraré si estoy en lista o en loading y en tal caso haré que sea seekable o no y así funcionará bien (pero lento) en lista y la carga algo mas rápida.
Un truco que puedo hacer para lo de los 30 seg es un bucle que lea los ov
for(i=0;i<2000;i++)
{
   ov_read(&vf,(void *) pcmout,MAX_PCMOUT,&current_section);
   ov_read(&vf2,(void *) pcmout,MAX_PCMOUT,&current_section2);
}

pero no me gusta, es lento aunque algo menos, así que lo haré seekable y que espere 1,5 seg el arranque de la música en la lista, por track, lo que en total son 3 segundos.
¿Tienes alguna variable gobal para saber si estás en la lista o en loading?
basicamente prondré en el f_seek if(loading) return -1;
En cuanto revise el código te lo subo para que le heches un vistazo y colgaré una versión compilada.
rodries escribió:¿Tienes alguna variable gobal para saber si estás en la lista o en loading?
basicamente prondré en el f_seek if(loading) return -1;
En cuanto revise el código te lo subo para que le heches un vistazo y colgaré una versión compilada.


No, no uso ninguna variable global porque usos metodos distintos. los ogg de la lista se reproducen en la misma funcion, mientras que los ogg del juego se reproducen en un hilo aparte.

Y sobre lo de echar un vistazo, bastante jaleo tengo yo ahora como para mirarlo (por no tener, no tnego ni las canciones en la SD)

Por cierto, me estoy fijando en un problema poco conveniente en libfat. Por razones curiosas, necesito conocer el espacio libre en el dispositivo y en el caso de la SD, me lo devuelve de forma casi inmediata, mientras que por USB tarda un huevo, como 8 segundos.

Rastreando la función veo que se lee un solo sector si no está dentro de la cache y eso está mal: en la cache solo deberian entrar CLUSTERS y no sectores sueltos (asi no me extraña que vaya tan lento, si la FAT necesita acceder a todo el cluster y aqui se lee sector a sector...)
Hermes escribió:No, no uso ninguna variable global porque usos metodos distintos. los ogg de la lista se reproducen en la misma funcion, mientras que los ogg del juego se reproducen en un hilo aparte.

Y sobre lo de echar un vistazo, bastante jaleo tengo yo ahora como para mirarlo (por no tener, no tnego ni las canciones en la SD)

Ok, no problem, subiré una versión compilada para que la gente lo pruebe y comente si va bien.

Hermes escribió:Por cierto, me estoy fijando en un problema poco conveniente en libfat. Por razones curiosas, necesito conocer el espacio libre en el dispositivo y en el caso de la SD, me lo devuelve de forma casi inmediata, mientras que por USB tarda un huevo, como 8 segundos.

Rastreando la función veo que se lee un solo sector si no está dentro de la cache y eso está mal: en la cache solo deberian entrar CLUSTERS y no sectores sueltos (asi no me extraña que vaya tan lento, si la FAT necesita acceder a todo el cluster y aqui se lee sector a sector...)

Realmente no tienes ganancia con eso, ya que un cluster son 2 sectores, y si usas la readaheadcache tendras PageSize sectores contiguos leidos de golpe.
No recuerdo en que sitio lee el espacio disponible pero si me dices por donde anda le hecho un vistazo, a ver si me imagino como mejorar la velocidad.
Por ejemplo antes cuando habrias un fichero siempre iba hasta el final del fichero y usaba _FAT_fat_lastCluster que es lentisimo porque va saltando de cluster en cluster y cuando habrías un fichero grande tardaba un huevo, puede ser algo similar.
rodries escribió:Realmente no tienes ganancia con eso, ya que un cluster son 2 sectores, y si usas la readaheadcache tendras PageSize sectores contiguos leidos de golpe.
No recuerdo en que sitio lee el espacio disponible pero si me dices por donde anda le hecho un vistazo, a ver si me imagino como mejorar la velocidad.
Por ejemplo antes cuando habrias un fichero siempre iba hasta el final del fichero y usaba _FAT_fat_lastCluster que es lentisimo porque va saltando de cluster en cluster y cuando habrías un fichero grande tardaba un huevo, puede ser algo similar.



Ahi te has equivocado, compañero: el tamaño del cluster es variable y lo minimo que he visto, es utilizar 4 (en un dispositivo USB de 256MB). Pero ahora mismo acabo de probar una modificacion que asigna la cache en grupos de 8 sectores (con las pertinentes correcciones claro) y la cosa se ha acelerado por 4 (mi pendrive usar 4096 bytes por cluster, luego 512x8=4096)

Lo que si es verdad es que no deberias tratar de leer mas de un cluster desde un dispositivo USB, porque es muy probable que no lo soporte, pero que sepas que es típico tener 32KB o 64KB en un disco duro como cluster (depende del tamaño del HDD, por ejemplo, mi unidad de D: es FAT32 y usa 32KB por cluster)

Si no lees por clusters, estás desperdiciando velocidad, sobre todo en este caso, que tiene que mirar las tablas de la FAT (cada entrada ocupa el tamaño de un cluster, por lo que si lo lees de una tacada, ganas mucha velocidad y encima evitas tener que
gestionar demasiadas entradas en la cache, que tanto bucle for tampoco es bueno)

En fin, que voy a seguir toqueteando y cuando tenga el codigo adaptable, te paso mis cambios ;)

Ahora algo que tardaba unos 8 segundos en hacerse, tarda solo 2 (para mirar el numero de asignaciones libres, tiene que hacer una buena lectura)
Hermes escribió:Ahi te has equivocado, compañero: el tamaño del cluster es variable y lo minimo que he visto, es utilizar 4 (en un dispositivo USB de 256MB). Pero ahora mismo acabo de probar una modificacion que asigna la cache en grupos de 8 sectores (con las pertinentes correcciones claro) y la cosa se ha acelerado por 4 (mi pendrive usar 4096 bytes por cluster, luego 512x8=4096)

Lo que si es verdad es que no deberias tratar de leer mas de un cluster desde un dispositivo USB, porque es muy probable que no lo soporte, pero que sepas que es típico tener 32KB o 64KB en un disco duro como cluster (depende del tamaño del HDD, por ejemplo, mi unidad de D: es FAT32 y usa 32KB por cluster)

Si no lees por clusters, estás desperdiciando velocidad, sobre todo en este caso, que tiene que mirar las tablas de la FAT (cada entrada ocupa el tamaño de un cluster, por lo que si lo lees de una tacada, ganas mucha velocidad y encima evitas tener que
gestionar demasiadas entradas en la cache, que tanto bucle for tampoco es bueno)

En fin, que voy a seguir toqueteando y cuando tenga el codigo adaptable, te paso mis cambios ;)

Ahora algo que tardaba unos 8 segundos en hacerse, tarda solo 2 (para mirar el numero de asignaciones libres, tiene que hacer una buena lectura)

No te lo discuto pero las 3 usb que he probado tienes dos sectores por cluster, y están formateadas con windows. En el chkdsk puedo leer 1024 bytes en cada unidad de asignación, pero la verdad es que el tamaño del cluster puede variar sin problemas, va en función del tamaño total del dispositivo.
En el usb el buffer máximo de trabajo son 4kb, pero cuando haces una lectura de 4kb manda 3 comandos scsi, el primero le dice que va a leer el segundo lee los 4kb y el tercero lee el posible resto del buffer y cierra lectura. Si le dices que lea 32kb (que serían 64 PageSize en readaheadcache) ejecuta 10 comandos , 1 apertura lectura, 8 lecturas de 4kb y 1 cierre lectura, por eso se acelera mucho la lectura si le dices que lea mas sectores de la cuenta. Antes para leer 32kb ejecutaba 34 comandos, en caso de tener el cluster a 1kb.
Me encanta que arregles la cache de la libfat de esta forma no hará falta readaheadcache en cuanto tengas los cambios hechos pásamelos a ver si mejora la velocidad respecto readaheadcache, aunque básicamente haces algo parecido, lees mas datos en una pasada.
Supongo que la mejora puede que se note en la escritura. Estoy deseando ver que cambios has hecho XD

Aprovecho para subir el guitarfun optimizado para el arranque de canciones.
Si se lee de usb no se adelanta la canción 30seg. ya que tarda 3,5 seg en realizar la operacion, pero si se hace desde sd lo hace sin problema.
Ahora arranca mas rápidamente tanto desde usb, como de sd, pero no siempre, dependiendo de la canción. En usb suele tardar la mitad menos 3seg que antes.
Binario:
http://rapidshare.com/files/148330819/Guitarfun.zip.html

Fuentes:
http://rapidshare.com/files/148331393/guitarfun_src.zip.html
rodries escribió:
Hermes escribió:Ahi te has equivocado, compañero: el tamaño del cluster es variable y lo minimo que he visto, es utilizar 4 (en un dispositivo USB de 256MB). Pero ahora mismo acabo de probar una modificacion que asigna la cache en grupos de 8 sectores (con las pertinentes correcciones claro) y la cosa se ha acelerado por 4 (mi pendrive usar 4096 bytes por cluster, luego 512x8=4096)

Lo que si es verdad es que no deberias tratar de leer mas de un cluster desde un dispositivo USB, porque es muy probable que no lo soporte, pero que sepas que es típico tener 32KB o 64KB en un disco duro como cluster (depende del tamaño del HDD, por ejemplo, mi unidad de D: es FAT32 y usa 32KB por cluster)

Si no lees por clusters, estás desperdiciando velocidad, sobre todo en este caso, que tiene que mirar las tablas de la FAT (cada entrada ocupa el tamaño de un cluster, por lo que si lo lees de una tacada, ganas mucha velocidad y encima evitas tener que
gestionar demasiadas entradas en la cache, que tanto bucle for tampoco es bueno)

En fin, que voy a seguir toqueteando y cuando tenga el codigo adaptable, te paso mis cambios ;)

Ahora algo que tardaba unos 8 segundos en hacerse, tarda solo 2 (para mirar el numero de asignaciones libres, tiene que hacer una buena lectura)

No te lo discuto pero las 3 usb que he probado tienes dos sectores por cluster, y están formateadas con windows. En el chkdsk puedo leer 1024 bytes en cada unidad de asignación, pero la verdad es que el tamaño del cluster puede variar sin problemas, va en función del tamaño total del dispositivo.
En el usb el buffer máximo de trabajo son 4kb, pero cuando haces una lectura de 4kb manda 3 comandos scsi, el primero le dice que va a leer el segundo lee los 4kb y el tercero lee el posible resto del buffer y cierra lectura. Si le dices que lea 32kb (que serían 64 PageSize en readaheadcache) ejecuta 10 comandos , 1 apertura lectura, 8 lecturas de 4kb y 1 cierre lectura, por eso se acelera mucho la lectura si le dices que lea mas sectores de la cuenta. Antes para leer 32kb ejecutaba 34 comandos, en caso de tener el cluster a 1kb.
Me encanta que arregles la cache de la libfat de esta forma no hará falta readaheadcache en cuanto tengas los cambios hechos pásamelos a ver si mejora la velocidad respecto readaheadcache, aunque básicamente haces algo parecido, lees mas datos en una pasada.
Supongo que la mejora puede que se note en la escritura. Estoy deseando ver que cambios has hecho XD



Por cierto hay un detalle que resulta gracioso: ahora me estoy ocupando de lo que tu has hecho y tu de lo mio XD

Por cierto, he visto que usas FAT_racache_readSectors para leer y que usa su propia cache particular, pero aqui hay dos errores:

1) En _FAT_write_r no te has ocupado de escribir los datos en la cache de racache, por lo que si un dato se escribe y luego tratas de leerlo, no se habra refrescado (dependiendo de lo que pase en el punto 2) )

2) Para leer sectores parciales, utilizas _FAT_cache_readPartialSector en _FAT_read_r y eso es un error fatal por que tira de una cache distinta!!! [+risas] . Asi que te podrias encontrar con que algo que está en racache, pasa a leerse, de nuevo en cache, por lo que aparte de la perdida de tiempo, jodes la cache de la que tiras al leer las entradas FAT.

Lo que voy a hacer para solucionar esto, es usar dos caches separadas: una para lectura y escritura, y la otra que se ocupe de tratar con las tablas y santas pascuas.

Al usar clusters existe un problemilla a tener en cuenta: cuando le especificas el numero de paginas, lo haces pensando en sectores, por lo que lo suyo sería adaptar el numero de paginas pensando en el numero de sectores por cluster, pero teniendo en cuenta el tamaño que le estamos pidiendo.

Vamos que no es lo mismo pedir que cachee 256 entradas de sectores que 256 entradas de cluster, por lo que en mi caso 256 paginas deberian traducirse a 32 de forma interna y eso me haria ganar velocidad en las gestiones, leyendo la misma cantidad de datos.


En fin, voy a seguir con ello ;)
Hermes escribió:Por cierto, he visto que usas FAT_racache_readSectors para leer y que usa su propia cache particular, pero aqui hay dos errores:

1) En _FAT_write_r no te has ocupado de escribir los datos en la cache de racache, por lo que si un dato se escribe y luego tratas de leerlo, no se habra refrescado (dependiendo de lo que pase en el punto 2) )

racache solo se usa en la lectura de archivos y cuando escribes en cualquier fichero se invalida toda la cache, lo puedes ver en fatfile.c en la funcion write al final. Empezé actualizando la racache pero no veia ganancia casi ninguna y aumentaba la complejidad. Tenia que pasar la racache por todos sitios y todas las funciones, cosa que hice pero al final la ganancia era casi nula y lo quite para no enredar el codigo original.
Hermes escribió:2) Para leer sectores parciales, utilizas _FAT_cache_readPartialSector en _FAT_read_r y eso es un error fatal por que tira de una cache distinta!!! [+risas] . Asi que te podrias encontrar con que algo que está en racache, pasa a leerse, de nuevo en cache, por lo que aparte de la perdida de tiempo, jodes la cache de la que tiras al leer las entradas FAT.

Como te comento anteriormente las entradas FAT no se cachean con racache, solo el acceso a archivos, por lo que no hay errores, de hecho el error que encontrastes al principio era por eso mismo, ya que empezé a cachearlo todo, hasta las entradas FAT, pero al final no había ganancia en la lectura de archivos, aunque sí en la manipulación de archivos como apertura y lectura de directorios


Hermes escribió:Lo que voy a hacer para solucionar esto, es usar dos caches separadas: una para lectura y escritura, y la otra que se ocupe de tratar con las tablas y santas pascuas.

Al usar clusters existe un problemilla a tener en cuenta: cuando le especificas el numero de paginas, lo haces pensando en sectores, por lo que lo suyo sería adaptar el numero de paginas pensando en el numero de sectores por cluster, pero teniendo en cuenta el tamaño que le estamos pidiendo.

Vamos que no es lo mismo pedir que cachee 256 entradas de sectores que 256 entradas de cluster, por lo que en mi caso 256 paginas deberian traducirse a 32 de forma interna y eso me haria ganar velocidad en las gestiones, leyendo la misma cantidad de datos.


En fin, voy a seguir con ello ;)

Simplemente para hacer pruebas aumenta el PageSize y veras como apenas hay ganancia, pero te comes mas ram, ademas creo recordar que tenía problemas cuando aumentaba mucho la caché y pasaba de 4Mb, no o recuerdo bien, aunque puede que con la libogc del git no te de problemas.
Piensa que racache(64,128) son 4Mb de caché, hay que buscar un equilibrio entre velocidad y consumo de ram, para leer mucos ficheros pequeños sueltos es mejor aumentar numpages y reducir pagesize y si vas a leer poca cantidad de ficheros pero grandes al reves.

Tengo ganas de ver tus cambios. Sobre todo medir la mejora. :)
Ya se que racache solo cachea los datos de los archivos, pero al principio, hay una lectura parcial para los datos que no estan alineados, que tira desde la otra cache y luego al final, hay otra lectura desalineada

Vamos que esto es asi:

cache-> lectura desalineada con el sector al comienzo
racache-> lecturas alineadas con el sector
cache-> lectura desalineada con el sector final

Todo depende de lo que leas, pero se puede armar ahi una buena. Y en los Writes he visto que invalidas racache, pero cache no la actualizas (sobre todo cuando hace la escritura directa por bloques XD)

De todas formas, deja que lo mire con calma a ver que es lo que se consigue. Lo que está claro es que por cachear ficheros no vas a ganar velocidad de transferencia, salvo que haya lecturas recurrentes sobre la misma zona.
Hermes escribió:Ya se que racache solo cachea los datos de los archivos, pero al principio, hay una lectura parcial para los datos que no estan alineados, que tira desde la otra cache y luego al final, hay otra lectura desalineada

Vamos que esto es asi:

cache-> lectura desalineada con el sector al comienzo
racache-> lecturas alineadas con el sector
cache-> lectura desalineada con el sector final

Todo depende de lo que leas, pero se puede armar ahi una buena. Y en los Writes he visto que invalidas racache, pero cache no la actualizas (sobre todo cuando hace la escritura directa por bloques XD)

De todas formas, deja que lo mire con calma a ver que es lo que se consigue. Lo que está claro es que por cachear ficheros no vas a ganar velocidad de transferencia, salvo que haya lecturas recurrentes sobre la misma zona.

De usar cache a no usarla pasa de 250kb/s a 760kb/s ya que normalmente los archivos estan en zonas contiguas. Cuando active la cache para leerlo todo no se noto mejoría por lo que lo quité para simplificar, la verdad es qu no estudié mucho la cache ya que no me gusó como la hizo chism que es el autor y le expliqué que debería hacer lecturas porbloques mayores n vez de por sector y dijo qu le hecharía un vistzo por lo que no seguí co el tema. La mayoria de los parches son de sven y no mio, no quiero que la gente se piense que le estoy quitando credito, yo ayudé a sven a averiguar el porque inicialmente el driver usb no pasaba de 60kb y a arreglar un par de fallos de libfat.
rodries escribió:De usar cache a no usarla pasa de 250kb/s a 760kb/s ya que normalmente los archivos estan en zonas contiguas. Cuando active la cache para leerlo todo no se noto mejoría por lo que lo quité para simplificar, la verdad es qu no estudié mucho la cache ya que no me gusó como la hizo chism que es el autor y le expliqué que debería hacer lecturas porbloques mayores n vez de por sector y dijo qu le hecharía un vistzo por lo que no seguí co el tema. La mayoria de los parches son de sven y no mio, no quiero que la gente se piense que le estoy quitando credito, yo ayudé a sven a averiguar el porque inicialmente el driver usb no pasaba de 60kb y a arreglar un par de fallos de libfat.


La verdad es que la librería es rara de cojones XD.

Yo estoy implementado dos lineas de caches (de momento tengo la escritura deshabilitada, por si meto un gazapo) y la idea es que la escritura tambien tire de ahi, incluso en los bloques desalineados para cubrir todos los posibles fallos que pueda haber.

El cachear muchos sectores, no sirve para nada salvo que los vuelvas a releer: por eso es mas importante cachear las tablas que los propios datos.

No es cuestion de poner 4MB de cache para datos, si luego resulta que le asignas a la cache de las tablas, solo 8 entradas de 512 bytes!

Asi en cuanto leas dos clusters, te has cepillado la cache y te va a estar penalizando.

EDIT:

Un fallo muy curioso en la cache, algo tremendo [+risas]

Resulta que si se llena, mira a ver cual es la entrada que tiene menos uso y la sustituye... pero si la sustituye, la que tiene menos uso es la nueva!: la proxima vez que necesite alojar un cluster (sector antiguamente), que va a ser presumiblemente pronto, se va a cepillar la entrada mas nueva qu eno por nueva, deja de ser util [+risas]
Hermes escribió:
rodries escribió:De usar cache a no usarla pasa de 250kb/s a 760kb/s ya que normalmente los archivos estan en zonas contiguas. Cuando active la cache para leerlo todo no se noto mejoría por lo que lo quité para simplificar, la verdad es qu no estudié mucho la cache ya que no me gusó como la hizo chism que es el autor y le expliqué que debería hacer lecturas porbloques mayores n vez de por sector y dijo qu le hecharía un vistzo por lo que no seguí co el tema. La mayoria de los parches son de sven y no mio, no quiero que la gente se piense que le estoy quitando credito, yo ayudé a sven a averiguar el porque inicialmente el driver usb no pasaba de 60kb y a arreglar un par de fallos de libfat.


La verdad es que la librería es rara de cojones XD.

Yo estoy implementado dos lineas de caches (de momento tengo la escritura deshabilitada, por si meto un gazapo) y la idea es que la escritura tambien tire de ahi, incluso en los bloques desalineados para cubrir todos los posibles fallos que pueda haber.

El cachear muchos sectores, no sirve para nada salvo que los vuelvas a releer: por eso es mas importante cachear las tablas que los propios datos.

No es cuestion de poner 4MB de cache para datos, si luego resulta que le asignas a la cache de las tablas, solo 8 entradas de 512 bytes!

Asi en cuanto leas dos clusters, te has cepillado la cache y te va a estar penalizando.

EDIT:

Un fallo muy curioso en la cache, algo tremendo [+risas]

Resulta que si se llena, mira a ver cual es la entrada que tiene menos uso y la sustituye... pero si la sustituye, la que tiene menos uso es la nueva!: la proxima vez que necesite alojar un cluster (sector antiguamente), que va a ser presumiblemente pronto, se va a cepillar la entrada mas nueva qu eno por nueva, deja de ser util [+risas]


Por eso cambie el contador por gettick para que te de la mas vieja en racache, en racache tamien estaba por numero de usos y la cambié por antiguedad.
Yo intenté hacer que en 2º plano continuese leyendo mientras que se le pedía o no paginas haciendo una lectura de los siguientes sectores ya que lo normal es leer los siguientes sectores a no ser que el archivo esté fragmentado, pero tuve problemas raros de sincronización y tuve que quitarla. De todas formas aumentaba la velocidad solo un 2% así que la quité.
Normalmente uno lee ficheros por lo que la mejora está en hacer lecturas anticipadas de los ultimos sectores solicitados, no creo que te aumente el rendimiento por cachear las tablas ya que apenas se hacen acceso a ellas, solo para abrir un fichero y ya está en modo lectura.
¿ Has conseguido mejorar la velocidad algo respecto a racache actual ?
rodries escribió:
Por eso cambie el contador por gettick para que te de la mas vieja en racache, en racache tamien estaba por numero de usos y la cambié por antiguedad.
Yo intenté hacer que en 2º plano continuese leyendo mientras que se le pedía o no paginas haciendo una lectura de los siguientes sectores ya que lo normal es leer los siguientes sectores a no ser que el archivo esté fragmentado, pero tuve problemas raros de sincronización y tuve que quitarla. De todas formas aumentaba la velocidad solo un 2% así que la quité.
Normalmente uno lee ficheros por lo que la mejora está en hacer lecturas anticipadas de los ultimos sectores solicitados, no creo que te aumente el rendimiento por cachear las tablas ya que apenas se hacen acceso a ellas, solo para abrir un fichero y ya está en modo lectura.
¿ Has conseguido mejorar la velocidad algo respecto a racache actual ?


Si, yo estoy usando un contador global que tiene el mismo uso y asi evitamos incompatibilidades con otros sistemas.

Sobre ganar velocidad o no, no se hasta que punto he ganado pues salvo lo de pillar el tamaño del disco, que es algo muy visible (y ahi he ganado como un 400% XD) , no puedo hacer medidas desde el emulador que sean significativas (con guitarfun si se notaria, pero eso ya se verñá con mas calma).

De momento estoy monitorizando la cache de las tablas, para ver que valor es optimo para la cache .

En el Dracula X, que es un CD cuyas pistas estan fraccionadas en ficheros, parece que se mantiene en 7 cambios, de momento, lo cual no está mal, porque por defecto, nosotros ponemos 8 en fatInit (la diferencia es que antes eran 8 sectores, es decir un cluster de mi pendrive y ahora serian 8 clusters, segun ese dato).

Luego... yo creo que estamos ganando velocidad de cajon, porque ahora la cache es mas amplia y funciona mejor XD

Por cierto, ¿sabes si el memcpy de Devkitpro esta optimizado?

Lo digo porque podriamos ganar velocidad si asignaramos memoria a la cache con memalign(8, ...) si es asi

Edit 2:

Al final he asignado memoria alineada a 32 bytes y he tocado el usbstorage para evitar el memcpy en la lectura de sectores, si está alineado a 32 bytes y parece que va bien ¿puede haber algun problema si no se usa dev->buffer?
Hermes escribió:Si, yo estoy usando un contador global que tiene el mismo uso y asi evitamos incompatibilidades con otros sistemas.

Sobre ganar velocidad o no, no se hasta que punto he ganado pues salvo lo de pillar el tamaño del disco, que es algo muy visible (y ahi he ganado como un 400% XD) , no puedo hacer medidas desde el emulador que sean significativas (con guitarfun si se notaria, pero eso ya se verñá con mas calma).

Me refiero a hacer un simple test de velocidad de lectura de un archivo grande.
#define FREAD_BUFFER_SIZE 4096
#define ticks_to_msecs(ticks)      ((u32)((u64)(ticks)/(u64)(TB_TIMER_CLOCK)))

void SpeedTest(char *fichero)
{
   FILE *f;
   char buf[FREAD_BUFFER_SIZE];
   u32 bytes_read;
   u32 total;
   double secs;
   u32 t1;
   
   f=fopen(fichero,"rb");
   if(f==NULL)
   {
      printf("No existe archivo: %s\n",fichero);
      return;
   }

   total=0;
   t1=gettick();
   while(1)
   {
      bytes_read = fread(buf, sizeof(char), FREAD_BUFFER_SIZE, f);
        total+=bytes_read;
      if (bytes_read < FREAD_BUFFER_SIZE)
      {
         s32 result = -!feof(f);
         if (result < 0)
         {
            printf("DEBUG: fread error: [%i] %s\n", ferror(f), strerror(ferror(f)));
         }
         break;
      }
      secs=ticks_to_msecs(gettick()-t1)/1000.0;
      printf ("\x1b[%d;%dH", 5, 1 );
      printf("read: %f kb sg: %f  kb/s: %f \n",total/1024.0,secs,(total/1024.0)/secs);
      
      WPAD_ScanPads();      
      if ( WPAD_ButtonsDown(0) & WPAD_BUTTON_1 ) //si se apreta el boton 1 se para el test
      {
         return;
      }
    }
   fclose(f);
}


Con esta función puedes ver la velocidad de lectura de un archivo, no se tendré algun fallo de compilación no he podido probarlo y lo he sacado de un trozo de código antiguo.
Veo que realmente lo que estás optimizando es el acceso al archivo, no creo que se mejore la velocidad respecto a racache en el caso de una lectura secuencial de un archivo. Aunque a la hora de hacer seek puede que mejore bastante, de hecho en cuanto lo tengas mas o menos funcional pásemelo a ver si hay mejoraría en el tema de abrir las canciones en el guitarfun
Hermes escribió:De momento estoy monitorizando la cache de las tablas, para ver que valor es optimo para la cache .

En el Dracula X, que es un CD cuyas pistas estan fraccionadas en ficheros, parece que se mantiene en 7 cambios, de momento, lo cual no está mal, porque por defecto, nosotros ponemos 8 en fatInit (la diferencia es que antes eran 8 sectores, es decir un cluster de mi pendrive y ahora serian 8 clusters, segun ese dato).

Luego... yo creo que estamos ganando velocidad de cajon, porque ahora la cache es mas amplia y funciona mejor XD

Por cierto, ¿sabes si el memcpy de Devkitpro esta optimizado?

Lo digo porque podriamos ganar velocidad si asignaramos memoria a la cache con memalign(8, ...) si es asi

Edit 2:

Al final he asignado memoria alineada a 32 bytes y he tocado el usbstorage para evitar el memcpy en la lectura de sectores, si está alineado a 32 bytes y parece que va bien ¿puede haber algun problema si no se usa dev->buffer?

No se si memcpy está optimizado, pero me supongo que sí.
Respecto a lo que de no usar dev->buffer supongo que te refieres a cambiar:
__USB_BlkMsgTimeout(dev, dev->ep_in, thisLen, dev->buffer);
por:
__USB_BlkMsgTimeout(dev, dev->ep_in, thisLen, buffer);
y quitar la linea:
memcpy(buffer, dev->buffer, retval);

Estoy practicamente seguro de que no pasa nada y te ahorras un memcpy por ciclo pero no creo que se gane mucho piensa que hacer 8 memcpy de 4kb para leer 32kb no debería gastar casi nada de cpu, aunque vete a saber, es cuestion de probar. No creo que pase nada ya que cuando acaba de leer llama a __read_csw que lo primero que hace es memset(dev->buffer, 0, CSW_SIZE); por lo tanto el buffer no se utiliza para nada en la lectura.

Bueno haz un cutre programa con la función que te he pasado y haz un par de test de velocidad a ver si se nota la diferencia. Y en cuanto me pases lo que tienes hecho probaré el tema de seek a ver como pirula.
Yo pienso que lo ideal sería eliminar racache y mejorar cache para que haga lo mismo que racache y cuando mande a realizar una lectura de un cluster que lea un mínimo de clusters en función del tamaño de los mismos, por ejemplo si el cluster es de 1kb que lea 64clusters y si es de tamaño 32kb que lea 2 clusters, es decir que lea siempre de una tacada 64kb. Eso para la lectura porque para la escritura es algo mas complejo, ya que debería averiguar que cluster está libre para escribir/sobreescribir y ver cuantos cluster consecutivos hay libres y cuando se llene la caché con la cantidad de datos para escribir en el número de cluster elegidos hacerlo de una pasada o cuando pase un cierto tiempo por seguridad, además de que habría que sincronizar ambas caches lectura/escritura.
Bueno, he hecho una prueba tirando de una ROM, usando 8 clusters de cache para tablas y 2 para ficheros (mas no tiene sentido y no gana velocidad, tratandose de un fichero que se lee y no necesita volver atras)

He optimizado el acceso a las entradas del cluster, memorizando la entrada de cache donde se aloja y recuperandola despues: el truco es que al pedir la pagina de la cache, se usa preferentemente esta y si no esta, pues entonces hace el bucle.

En USB, tanto fragmentando la lectura en grupos de 256 bytes, como si lo leo de una tacada, la transferencia es de unos 584 KBytes/sec, para un fichero de unos 2,6MBytes

En SD, la misma lectura es de 6666 Kbytes/sec.

Lo cual deja claro que el principal problema del USB, es que tiene el driver en el PPC y que hay que mejorar el driver en todo lo posible, evitando cosas inutiles como memcpy que se pueden evitar usando memoria alineada, por ejemplo.

En usbstorage veo que se le asigna 4096 como tamaño maximo de lectura. Por lo general, un dispositivo USB debe estar preparado para poder leer de una tacada el tamaño de un cluster y como en mi caso coincide con ese tamaño, no se debe variar.

No se debe variar porque el dispositivo puede no soportar un tamaño mayor (como yo comprobé cuando trabaje en esto en PS2), pero seguramente si se ajustara ese tamaño al del cluster, ganara velocidad en los discos duros.

Leer de fondo varios clusters de forma consecutiva no tiene mucho sentido cuando realmente, estamos leyendo varios clusters de una sola tacada mediante la lectura normal (por eso en el test que hago, da lo mismo 2 que 64 clusters de cache en esa zona): lo que hay que mejorar es el acceso al dispositivo.

En un programa hacer lecturas en paralelo tiene sentido para evitar bloquear un proceso y solo es eficaz si es capaz de entregar los datos a tiempo de que los use el proceso: se piden unos datos adelantados y cuando el proceso los requieres, deben estar ahi.

Pero aqui el proceso está esperando esos datos de forma inmediata, por lo que si implementaramos un modo especial de lectura multiple (que se puede hacer) podemos ganar algo de tiempo desde el punto de vista de acelerar libfat, pero no en el proceso de lectura del dispositivo

La prueba es que la SD va como un tiro y usa las mismas funciones de libfat que el USB: mas de 10 veces de diferencia de velocidad, deja claro que el problema es la implementacion del driver USB en el PPC y que hay que trabajar por ahi (si se puede)

Mis cambios por el momento, aportan otras cosas, pero si no se mejora eso...
un usb 1.1 no da mas de si.
Hermes escribió:Bueno, he hecho una prueba tirando de una ROM, usando 8 clusters de cache para tablas y 2 para ficheros (mas no tiene sentido y no gana velocidad, tratandose de un fichero que se lee y no necesita volver atras)

He optimizado el acceso a las entradas del cluster, memorizando la entrada de cache donde se aloja y recuperandola despues: el truco es que al pedir la pagina de la cache, se usa preferentemente esta y si no esta, pues entonces hace el bucle.

Me gustaría que me pasases lo que tengas si es operativo para hecharle un vistazo.

Hermes escribió:En USB, tanto fragmentando la lectura en grupos de 256 bytes, como si lo leo de una tacada, la transferencia es de unos 584 KBytes/sec, para un fichero de unos 2,6MBytes

En SD, la misma lectura es de 6666 Kbytes/sec.

Lo cual deja claro que el principal problema del USB, es que tiene el driver en el PPC y que hay que mejorar el driver en todo lo posible, evitando cosas inutiles como memcpy que se pueden evitar usando memoria alineada, por ejemplo.

No me cuadra tu velocidad. Usando racache se alcanzan unos 760kb/s a no ser que el archivo esté muy fragmentado y sin racache va a 250kb/s. ¿Esos 584kb/s te los da usando racache? ¿o usando tus modificaciones sobre la cache sin usar racache?
Hermes escribió:En usbstorage veo que se le asigna 4096 como tamaño maximo de lectura. Por lo general, un dispositivo USB debe estar preparado para poder leer de una tacada el tamaño de un cluster y como en mi caso coincide con ese tamaño, no se debe variar.

Aunque aumentes a 7kb que es lo que hice inicialmente no ganas nada ya que __USB_BlkMsgTimeout solo devuelve como máximo 4096 me di cuenta poniendo un printf en retval.
Y a partir de casi 8kb se cuelga el dispositivo.
Hermes escribió:No se debe variar porque el dispositivo puede no soportar un tamaño mayor (como yo comprobé cuando trabaje en esto en PS2), pero seguramente si se ajustara ese tamaño al del cluster, ganara velocidad en los discos duros.

Leer de fondo varios clusters de forma consecutiva no tiene mucho sentido cuando realmente, estamos leyendo varios clusters de una sola tacada mediante la lectura normal (por eso en el test que hago, da lo mismo 2 que 64 clusters de cache en esa zona): lo que hay que mejorar es el acceso al dispositivo.

En un programa hacer lecturas en paralelo tiene sentido para evitar bloquear un proceso y solo es eficaz si es capaz de entregar los datos a tiempo de que los use el proceso: se piden unos datos adelantados y cuando el proceso los requieres, deben estar ahi.

Pero aqui el proceso está esperando esos datos de forma inmediata, por lo que si implementaramos un modo especial de lectura multiple (que se puede hacer) podemos ganar algo de tiempo desde el punto de vista de acelerar libfat, pero no en el proceso de lectura del dispositivo

La prueba es que la SD va como un tiro y usa las mismas funciones de libfat que el USB: mas de 10 veces de diferencia de velocidad, deja claro que el problema es la implementacion del driver USB en el PPC y que hay que trabajar por ahi (si se puede)

Mis cambios por el momento, aportan otras cosas, pero si no se mejora eso...

Eso ya hay que dejarlo para los máquinas y yo no llego a tanto y no tengo tanto tiempo para empezar con desemsamblar el ios, tocar un driver ya son palabras mayores.
Abría que implementar ehci desde cero en el driver usb ya que no hay nada hecho y puede que incluso el usb2 de la wii estuviese capado por hard, vete a saber. O ninty saca el driver o me parece que nos vamos a quedar con lo que hay, ya se le han preguntado a los que mas saben si tienen pensado intentar sacarle velocidad al usb y a ninguno le apetece enredar con eso, además de que dicen que el driver usb no está muy bien hecho y es problemático, algo de la memoria pero no recuerdo.
Para medir la velocidad pura sin pasar por libfat y ver la velocidad máxima que alcanza el driver actual se podría llamar a USBStorage_Read pidióndole un monton de sectores a ver cuanto tarda, y de esta forma saber la pérdida de rendimiento de la libfat.
Ahora mismo durante unos dias no voy a disponer de mi wii, así que no se cuando podré hacer el test, a ver si te animas a hacerlo, porque serviría de referencia a ver si ya se ha alcanzado un rendimiento optimo con libfat y no merecería la pena seguir trabajando en ella.
Ya nos contarás tu averiguaciones.

Edit:
Se supone que usb 1.1 debería llegar a 1.5 MB/s y actualmente va a la mitad, puede que sea que libfat está mal hecha o que esté capado en ios o que esté mal hecho el driver de sven, por eso te digo de hacer la prueba del USBStorage_Read

Edit2:
Leyendo las especificaciones he encontrado esto:
The USB 1.1 bus speed is 12 Mb/sec, which is 1.5 MB/second (Mb = bits, MB = Bytes), but no one device ever exceeds half of that, so the USB 1.1 advantage is not speed (and implementations do vary).

Ademas la wii dicen que es usb 2.0 pero no he leido si es full-speed o high-speed por que si es full-speed da la misma velocidad que usb1.1 y sería imposible hacer nada para acelerar el usb, ni haciendo un driver ehci.

Por lo que ahora mismo tenemos la maxima velocidad que puede dar usb 1.1, así que no creo que consigas mejorar mas la libfat en cuanto a lectura, pero tus cambios de los accesos a la tabla fat son muy interesantes a ver si se mejora el seek y la lectura de directorios grandes.
rodries Un poquito de tranquilidad, please XD : tu me has pedido un test de velocidad y eso es lo que ha dado, por el momento.

Como te he dicho, estoy tocando otras cosas y tu cache racache no existe [+risas] : en realidad tira de una cache identica a la otra y sinceramente, esa cache no es tan determinante, sobre todo cuando haces lecturas en bloques.

Ademas, mi cache está alineando los clusters con el disco duro y no con la particion, por lo que es muy facil que al leer requiera dos lecturas para completar un cluster.

Lo mejor es que ahora mismo, mi trabajo no lo tengas en cuenta, que no contamines tu codigo con lo que yo esté ideando y dejarme hacer (que por tocar, estoy tocando hasta cosas que no me parecen optimas en usb.c)

Cuando sea el momento oportuno, no te preocupes que lo tendras para hacer tus test, pero ahora no es el momento oportuno porque estoy haciendo probaturas y mirando que es lo que puedo tocar y como lo puedo tocar, mas que interesado en ver unos resultados inmediatos de velocidad en la lectura de ficheros (para mi es mas importante que leer bloques pequeños no este penalizando mas que leer bloques grandes, que la cache cubra bien los datos, para evitar fallos raros y que se trabaje sobre clusters y no sobre sectores)
Es que soy un impaciente XD

Cambiando de tercio, creo que debes actualizar el post inicial con el ultimo binario, porque sino la gente no se va a dar cuenta y no lo van a probar a ver si se nota la optimizacion de carga y funciona bien. A mi me tarda unos 4 o 5 segundos en cargar una canción con usb por lo que creo que no merece hacer la carga en un thread en 2º plano. A ver si la gente lo prueba y opina como va.

PD: Espero que me mantengas informado de tus averiguaciones, son muy interesantes.
rodries escribió:Es que soy un impaciente XD


Pues he vuelto todo atras, he vuelto a meter tu libfat, la he probado y he visto que iba a unos 730 KB. He apañado lo de la cache de las tablas (leyendo solo sectores) y ha subido algo la velocidad (aunque pillar el tamaño del disco duro, tarda un huevo, 6 segundos de reloj, frente a los 2 de antes)

Entonces me he dicho ¿cuantos sectores lee este tio a la vez, para que su sistema sea tan rapido? Y ahi me he quedado sorprendido ¿solo 2? ¿pero como coño puede ser que lea solo dos sectores, si tiene ahi una funcion racache que deberia leer todo el cluster de una tacada? Pues porque no llega a llamarla nunca XD. Nunca le llegas a pedir mas de dos sectores, porque atencion: a la funcion read, lo maximo que le llega, son 1024 bytes a leer (aunque le este pidiendo un bloque de 2,6 MB) [+risas]

La madre que me pario: asi no me extraña que esto rinda tan poco [+risas]
Hermes escribió:
rodries escribió:Es que soy un impaciente XD


Pues he vuelto todo atras, he vuelto a meter tu libfat, la he probado y he visto que iba a unos 730 KB. He apañado lo de la cache de las tablas (leyendo solo sectores) y ha subido algo la velocidad (aunque pillar el tamaño del disco duro, tarda un huevo, 6 segundos de reloj, frente a los 2 de antes)

Entonces me he dicho ¿cuantos sectores lee este tio a la vez, para que su sistema sea tan rapido? Y ahi me he quedado sorprendido ¿solo 2? ¿pero como coño puede ser que lea solo dos sectores, si tiene ahi una funcion racache que deberia leer todo el cluster de una tacada? Pues porque no llega a llamarla nunca XD. Nunca le llegas a pedir mas de dos sectores, porque atencion: a la funcion read, lo maximo que le llega, son 1024 bytes a leer (aunque le este pidiendo un bloque de 2,6 MB) [+risas]

La madre que me pario: asi no me extraña que esto rinda tan poco [+risas]

Correcto, ¿recuerdas la primera versión que te daba problemas y tenía muchos warnings? [buuuaaaa] Pues en esa versión todo tiraba de racache, incluso el acceso a tablas y cuando se escribía solo se invalidaba la página afectada por la escritura, pero se ve que hice algo mal y heché para atrás todos los cambios, para dar estabilidad. Pienso que lo ideal sería partir de esa versión y reparar lo que hice mal, pero voy a estar fuera de circulación durante una semana. Ahora que entiendes como va libfat (que es mas rara que un perro verde :) ) puede que veas donde me equivoqué [ayay] .
Yo había pensado usar 2 caches, una para archivos y otra para las tablas, de esta forma los accesos estarían siempre cacheados y deberían ser muy rápidos, pero ultimamente el curro no me deja hecharle tiempo. Ya me contarás.
Saludos.
rodries escribió:
Correcto, ¿recuerdas la primera versión que te daba problemas y tenía muchos warnings? [buuuaaaa] Pues en esa versión todo tiraba de racache, incluso el acceso a tablas y cuando se escribía solo se invalidaba la página afectada por la escritura, pero se ve que hice algo mal y heché para atrás todos los cambios, para dar estabilidad. Pienso que lo ideal sería partir de esa versión y reparar lo que hice mal, pero voy a estar fuera de circulación durante una semana. Ahora que entiendes como va libfat (que es mas rara que un perro verde :) ) puede que veas donde me equivoqué [ayay] .
Yo había pensado usar 2 caches, una para archivos y otra para las tablas, de esta forma los accesos estarían siempre cacheados y deberían ser muy rápidos, pero ultimamente el curro no me deja hecharle tiempo. Ya me contarás.
Saludos.


El problema es que tu implementacion es demasiado manual y tiene algunos fallos, por ejemplo, con fatEnableReadAhead(PI_USBSTORAGE, 6, 64); se me queda flipada mi SD, si la utilizo mediante un lector SD externo que tengo y tengo que aumentar el tamaño de 64 a 128, mientras que de la forma que lo estoy haciendo yo, va como un tiro (la SD utiliza clusters de 32KB)

De tu forma, si lees un fichero desde el principio y en "cachos" de 1024, no te penaliza la lectura, pero como desalinees la lectura, empezaras a a leer un sector que entra en "cache", para luego leer el resto desde "racache"... penalizando, no solo en esta lectura, si no que puede "robarte" una entrada de la FAT que estas usando.

Pero lo peor viene en la escritura: si vale, tu invalidas racache, pero es que para escribir, primero hay que leer. Es decir, si tu escribes en fichero que tiene datos en un cluster, si usas _FAT_disc_writeSectors, te los cepillas [snif] : solo se hace bien si da la casualidad de que se llama a _FAT_cache_writePartialSector porque en ese caso, si el sector no está en cache primero se lee y luego se escriben los datos (con un memcpy, por lo que deja la escritura real para cuando se libere el sector o se cierre el fichero). Evidentemente, si estas escribiendo un fichero nuevo, no notaras el problema, pero vamos que si tratas de escribir un dato si que se borre el resto del sector (cluster en mi caso), asi no vas bien.

Lo que yo tengo implementado hasta el momento, es una modificacion de la cache normal pero mucho mas optima (aunque de momento, solo tengo conectadas las funciones de lectura y nada de escritura) y ya va a la muy buena velocidad (760 KBytes/seg), pero ademas, nos va a resolver esos problemas que estamos teniendo.

1) Las entradas de la cache ya no almacenan sectores si no clusters

2) Todas las funciones se han adaptado para que en vez de pasar el sector, pasen de forma separada el sector de inicio del cluster (o el inicio de la tabla de clusters, que es igual) y luego se le pasa el offset al sector, propiamente dicho. Esto que parece enredoso lo hago para poder establecer el sector de inicio real del cluster, que es el que se debe almacenar como indice en la cache (vamos que los sectores esten alineados con la base de los clusters)

3) Para que la lectura sea optima, se deben leer sectores consecutivos: con unos 64 la cosa va bien, como tu mismo has visto, pero se tienen que hacer en una sola lectura. Con eso vamos a ganar velocidad siempre y cuando los datos esten situados consecutivos, pero si por alguna razon, no hay 64 sectores seguidos con datos, nos está penalizando (esto tengo una idea para tratar de resolverlo mas adelante)

Por ello la nueva cache tiene la posibilidad de agrupar entradas y eso se hace de forma automatica calculando el numero de sectores que le pasas en fatEnableReadAhead, como pageSize dividido entre el numero de sectores por clustes e implementando la logica necesaria.

Para leer de la FAT solo se utiliza una "pagina" de tamaño 1 (es decir, todas las entradas de la cache se utilizan individualmente), pero por ejemplo si el dispositivo usa 8 sectores por cluster al ser PageSize 64 quedaria como 64/8=8 y las entradas de la cache se agruparian de 8 en 8.

Para que entiendas el sistema, a la hora de comprobar la "antiguedad" o si es CACHE_FREE para asignar, se mirarian los indices 0, 8, 16, etc, pero a la hora de mirar si un cluster está presente, se miran de uno en uno. Por tanto para refrescar se tratan los 8 como grupo (en este caso), pero al mismo tiempo, permite un trato individualizado

De esta forma, se puede llegar a leer 64 sectores de una tacada, controlando que no haya inconsistencias en la cache (clusteres repetidos por solapamiento, cosa que se produce porque leas por ejemplo, un cluster anterior a lo que tienes en cache), controlar la escritura de forma adecuada, actualizando cluster a cluster, etc. Luego, a la hora de actualizar, se leerian en este caso, los 8 clusters, ajustando las entradas de forma adecuada.

Si encima lo apoyaramos con una buena lectura de los indices de cluster, de forma que pudieramos ver si podemos leer 64 sectores (como 8 clusters en este caso) de forma seguida o leer menos, no desperdiciariamos velocidad de lectura por culpa de las fragmentaciones. Esta es la idea que tengo para mas adelante, cuando todo esté trabajando correctamente y en su sitio, que al leer las entradas del cluster, se compruebe hasta que punto se puede leer (porque si el fichero está fragmentado, leer sectores de forma inutl, no favorece la velocidad, evidentemente)

En tu cache no se pueden hacer estas cosas porque el tamaño de pagina es fijo y hasta ahi es mas o menos como lo mio, pero no puedes invalidar partes de lo que tienes en cache o marcar solo una parte como escritura, controlar el solapamiento de clusters, etc, y por eso es por lo que no te funciona bien cuando tratas de aplicarlo a cosas tan delicadas como leer/escribir las entradas de las tablas.

Con el sistema que estoy utilizando, se puede desperdiciar algo de memoria, pero merece la pena incluso aunque no ganaramos velocidad punta, ya que es mas importante asegurarse de que todo funciona como debe, evitar cosas raras y que el sistema pierda lo menos posible de velocidad cuando las cosas no le sean tan favorables.

En cuanto tenga todo rulando y un poco limpio, lo colgaré por aqui y le daré un descanso, antes de ponerme con la optimizacion para los ficheros fragmentados (que eso va a tener tela XD )
:O Estas hecho una máquina. [plas]
Pensaba que no existía nada para el tema de los archivos fragmentdos, a no ser que leas primero como está repartido el fichero para preveer que no se lean sectores innecesarios, pero en este caso pienso que vale mas la salsa que el pollo, ya que o está muy fragmentado y los clusteres son pequeños o no creo que ganes apenas velocidad. Y si están muy fragmentados que usen el defrag XD

Bueno, me has puesto los dientes largos ya tengo ganas de que rule esos fuentes. [babas]
Muy bien explicado Hermes [beer]
rodries escribió::O Estas hecho una máquina. [plas]
Pensaba que no existía nada para el tema de los archivos fragmentdos, a no ser que leas primero como está repartido el fichero para preveer que no se lean sectores innecesarios, pero en este caso pienso que vale mas la salsa que el pollo, ya que o está muy fragmentado y los clusteres son pequeños o no creo que ganes apenas velocidad. Y si están muy fragmentados que usen el defrag XD

Bueno, me has puesto los dientes largos ya tengo ganas de que rule esos fuentes. [babas]


Pues ahora mismo lo estoy probando bien: velocidades de lectura de 762KB/s con solo dos "paginas" de 32 KB para racache (eso es lo que se pone por defecto, si no llamas a la funcion fatEnableReadAhead). habria que probar con lecturas escrituras raras, para ver si aparecen problemas de algun tipo, pero habiendo creado directorios, ficheros y habiendo borrado fichero, desde dentro del emulador, parece que Scandisk no protesta ;)

fatInit(8, false); establece 8 clusters para acceso a las tablas lo cual quiere decir que la cosa varía entre 32KB (4 sectores por cluster) y 64KB (un disco duro puede usar 128 sectores por cluster, asi que en este caso limito a un maximo de 8 sectores que es un margen suficientemente bueno y ayuda a ahorrar memoria sobre todo en otras maquinas como NDS o GBA)

Para las lecturas, por defecto, el fatinit establece 2 paginas de 64 sectores (64KB), y con fatEnableReadAhead(6,64), estarias gastando 192KB igual que antes, solo que aqui el 64 no lo deberias bajar pues si el dispositivo usa clusters de 32 KB como mi SD resulta conveniente y ya hemos visto que es la mejor medida y es un tamaño en mi opinión muy optimo para hacer lecturas fraccionadas. Aunque no utilice una medida de cluster, la cache puede funcionar indistintamente del tamaño ;)

Por cierto, todo lo que tenias de racache, lo he tirado a la basura finalmente: espero que no me odies por ello [+risas]

Estoy probando a leer desalineando datos e incluso volviendo para atras y parece que no se descoloca nada y va follao (735 KB/s) tsolo con 2 "paginas" de 64 sectores (en realidad no deberia llamarle paginas, porque es una simple agrupacion de clusters)

Mañana si todo va bien, te subo los fuentes para que lo mires (aunque no se si me está ayudando una modificacion que hice en usb.c )

Por cierto, la SD no se lee como USB 1.1: el contador me da 6.264 MBytes por segundo!! (y se nota un huevo que carga antes) y estoy utilizando aritmetica de 64 bits por si al multiplicar por mil (para obtener "decimales" dividiendo entre ms), asi que es obvio que el driver SD usa especificacion USB 2.0 (1.1 está limitado a un tope de 12Mbits por segundo).

O sea que el dispositivo USB puede que no de su maximo rendimiento por cuestiones de interface, pero la SD está muy claro que usa especificacion 2.0 (pero no da el tope de velocidad seguramente, porque el ARM no puede transmitir mas rapido lo que le llega y ocuparse de otras cosas)

Saludos
Funciona si conecto por usb la guitarra del GH3 de xbox360? si no funciona crees que lo puedas hacer?
offspringboy escribió:Funciona si conecto por usb la guitarra del GH3 de xbox360? si no funciona crees que lo puedas hacer?


Ya lo han preguntado varias veces en el hilo. La respuesta de hermes es no. Le haria falta la guitarra y creo que no esta por la labor de comprar una.
offspringboy escribió:Funciona si conecto por usb la guitarra del GH3 de xbox360? si no funciona crees que lo puedas hacer?


Aparte de que no tiene la guitarra, el problema fundamental es que tendría que hacer un driver USB específico y eso no es "moco de pavo", así que olvidate.
Como bien te dice Vrsquid está muchas veces en este hilo explicado pero ya está tan largo que entiendo que de pereza leerlo todo.
Saludos.
Estupendo Hermes
Cuando lo vallas a subir no se te olvide subir el usb.c y el usbsorage.c y si es posible pon comentarios de los cambios y el porque, luego si eso lo pasamos a ingles para ver si lo suben al cvs o al git. Espero que hayas puesto algún comentario en los cambios y sobre todo el porque del cambio, ya que es mucho más fácil para que luego la gente (osea yo) lo lea y pueda intentar mejorarlo, es que después de ver tu guitarfun y lo que he sufrido para ver como pirula no me fio de ti XD
Yo intenté hacer que cuando pedias información, y se quedaba cacheada, mientras tanto continuase leyendo el siguiente bloque (PageSize) y así mientras se continuaba sirviendo datos de la cache podía seguir leyendo ya que en el 90% de los casos te van a pedir el siguiente sector, eso me dio una ganancia de un 8% mas o menos, pero no se que leches pasa con los threads que ocurrían cosas que no debían pasar o se me escapaba algún detalle o algo pasa con ellos, porque me entraba en el hilo cuando tenía puesta una variable global que deberí impedir que entrase. Puede que se pueda optimizar adelantando la lectura del siguiente bloque de datos utilizando un hilo en 2º plano de baja prioridad que vaya leyendo mientras se esté tirando de la caché, el problema es que a veces el hilo principal debía esperar a que terminara la lectura, pero normalmente los sectores que se pedían estaban en el bloque recien leido, por lo que no había penalización, de esta forma el usb no paraba ni un segundo.

Cuando vayas a subir tu libfat abre un nuevo hilo para no seguir contaminado el Guitarfun.
Lo tengo todo preparado en un paquete, pero no esperes comentarios extensos en el codigo (bastante he comentado aquí), aunque eso si, tengo hechas anotaciones en algunos puntos. Mañana lo subire y creare un hilo que hoy no tengo ganas de liarme con post kilometricos ni nada por el estilo (si tengo que explicar, lo explico ahí, pero el codigo fuente no es el lugar para expresar ideas y si alguien no lo entiende, pues que se busque la vida: yo trato de escribir código para que funcione, no para que alguien se 'ilustre' [poraki] XD :p )
Disculpen mi ignorancia con esta aplicacion pero se me esta presentando el siguiente problema con el GuitarFun 3.0. Lo instalé y coloque un par de canciones en formato "Frets on Fire" en la carpeta "songs" en la raiz tanto de la memoria SD como en la USB. El problema es que cuando intento iniciar single player o multiplayer me dice reading from usb y se sale... que podré estar haciendo mal???
Eso ya se ha explicado por lo menos unas cienes de veces.
A ver:sigue estos pasos y verás que fácil:

Thyl-Thalion escribió:a) Descarga el .rar
b) Descomprimelo
c) copia toda la carpeta guitarfun a la raiz de la SD
d) crea los directorios apps\guitarfun\
e) copia el "guitarfun.dol" a este último directorio. Renombralo a "boot.dol"

Te tiene que quedar así:
________________________
Aplicación para el HBC:
G:\apps\guitarfun\boot.dol
_________________________
Directorio para el juego:
G:\guitarfun\songs
G:\guitarfun\bitmaps
G:\guitarfun\guitarfun.dat
G:\guitarfun\songs_score.dat
__________________________

Si quieres icon.png y meta.xml para el HBC, descargate del hilo de cangrejo y comepiedras, que creo que ya lo traen.

a ver si así te va.....

EDITO: el hilo del que hablaba es este
http://www.elotrolado.net/hilo_homebrew-channel-packs-elf-icono-meta_1029712


Esto ya llora ríos de tinta. Por qué será que nadie se lee el pdf de Hermes ?? [chulito]
PiratePila está baneado por "crearse clones para trollear"
A ver si lo puedo probar esta tarde...

¿Sabéis si con adaptadores PS/2 a USB funcionan los teclados normales?

Nunca he jugado a este juego pero los Guitar Hero me gustan, así que lo tendré que probar.
PiratePila escribió:A ver si lo puedo probar esta tarde...

¿Sabéis si con adaptadores PS/2 a USB funcionan los teclados normales?

Nunca he jugado a este juego pero los Guitar Hero me gustan, así que lo tendré que probar.

Son solo para ratones.
695 respuestas
18, 9, 10, 11, 1214