mod_gme: Modulo para reproducir archivos de música de consola

Started by warrior_rockk, September 09, 2015, 01:13:29 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

warrior_rockk

Estos días he estado trasteando, por curiosidad , como hacer módulos en Bennu y, aprovechando que encontré en internet una librería en C de emulación de sintetizadores de consolas, me he animado con este módulo que reproduce formatos de música de diversas consolas. En concreto:



AY        ZX Spectrum/Amstrad CPC
GBS       Nintendo Game Boy
GYM       Sega Genesis/Mega Drive
HES       NEC TurboGrafx-16/PC Engine
KSS       MSX Home Computer/other Z80 systems (doesn't support FM sound)
NSF/NSFE  Nintendo NES/Famicom (with VRC 6, Namco 106, and FME-7 sound)
SAP       Atari systems using POKEY sound chip
SPC       Super Nintendo/Super Famicom
VGM/VGZ   Sega Master System/Mark III, Sega Genesis/Mega Drive,BBC Micro


Su uso es muy simple, con load_song(string filename), cargamos en memoria la canción que queramos (autodetecta el tipo de sistema) y con play_song() lo reproducimos.
Existen diversas funciones para cambiar el tempo, silenciar canales independientes, obtener información de la canción, hacer fade, etc...
Esta es la lista de funciones hasta ahora:



//cargar un archivo de musica

int gme_load_song(string filename)


//reproducir musica cargada
int gme_play_song()


//detener musica
int gme_stop_song()


//pausar musica
int gme_pause_song()


//reanudar musica
int gme_resume_song()


//obtener numero de voces / canales
int gme_voice_count()


//mutear voz / canal
int gme_mute_voice(int voice)


//desmutear voz / canal
int gme_unmute_voice(int voice)


//setear tempo (1.0 = tiempo normal)
int gme_set_tempo(float tempo)


//devuelve true si la canción ha terminado
int gme_song_ended()


//devuelve información de la pista. Existen varias constantes tales como GME_GAME_INFO o GME_SONG_INFO.. en el ejemplo están todos)
string gme_get_song_info(int info_type)


//devuelve (en milisegundos) la duración de la canción
double gme_get_song_length()


//devuelve (en milisegundos) la duración del intro de la canción (-1 si no tuviera)
double gme_get_intro_length()


//devuelve (en milisegundos) la duración del loop de la canción (-1 si no tuviera)
double gme_get_loop_length()


//devuelve los milisegundos de reproducción actual
double gme_get_song_pos()


//hace un fade off de la musica a la duracion de milisegundos que se le pase)
int gme_fade_off(double duration_ms)


//devuelve true si está haciendo fade off
int gme_is_fading()




Adjunto la extensión y ejemplo de uso donde se puede ver fácilmente las diversas opciones que tiene.




Cosas pendientes por hacer:
===================
-descomprimir automáticamente archivos vgm comprimidos
-función para cambiar el volumen de la canción
-integrarlo en SDL_mixer para mejor convivencia con Bennu
-documentar todas funciones
-...


Saludos!




JaViS

Working on Anarkade. A couch multiplayer 2D shooter.

FreeYourMind

excelente aporte. cual es el nombre de la libreria original ?

warrior_rockk


La momia que fuma

Uoooooo!! Esto lo propuse yo hace tiempo (Concretamente, soporte spc solamente) con nulo éxito.


Me quito el sombrero, acabas de desbloquear una libreria de música GIGANTESCA para nuestros proyectos :D  (Siempre que no sean comerciales, obviamente ;D )


Y aún encima tirando de archivos de música ridículamente pequeños...(Alguna vez tuve que pasar a ogg alguna musiquilla de 16 bits y algo se me moría en el alma al comparar tamaño con el formato original xD)


Bravo!!

warrior_rockk

A mi me pasaba lo mismo. Para mis proyectos retro utilizo música chiptune y me daba mucha rabia tener que pasarlo a formatos "superiores" con el consiguiente aumento de tamaño. Pero sobretodo me daba rabia no poder utilizar las posibilidades de tener control sobre la música, por ejemplo, poder acelerar el tempo cuando se te va a acabar el tiempo de juego, mutear el canal de percusión para dar ambiente a que te metes en una cueva, poder reproducir intro al comenzar el nivel y luego hacer loop sin repetir el intro... se me abre un mundo de posibilidades!

La momia que fuma

Lo de ajustar el tempo va un poco loco todavía, no? O solo me pasa a mí?


A poco que toco en el programa de ejemplo para aumentar tempo...solo tiene dos velocidades, normal o a toda leche xD


O sea, le doy a subir tempo y se pone a toda leche. Le doy a bajar para dejarlo como estaba, y no me hace caso, tampoco puedo hacerlo más rápido aún si sigo dandole a subir, se queda atascado en esa velocidad hasta que cargo otra (o la misma) canción. Como mucho reacciona quedandose pillado en un mismo punto si hago al tempo bajar de 0...


(Incluso si partiendo de la musica en estado normal, le doy a bajar tempo, se pone a toda leche igual xD)

warrior_rockk

Acabo de probar lo del tempo y me sucede exactamente lo mismo. Tengo algún fallo con esa función. Voy a revisarlo y lo corrijo.

warrior_rockk

Vale ya está. Un pequeño error tratando los float. No había probado esta función porque la hice en el curro y no puedo poner sonido allí jeje. Aquí está el módulo corregido. Tener en cuenta que en el código de ejemplo no se comprueba si se hace KEY_DOWN o KEY_UP con lo que hay rebote en las acciones.

La momia que fuma

Quote from: warrior_rockk on September 13, 2015, 06:33:03 PMTener en cuenta que en el código de ejemplo no se comprueba si se hace KEY_DOWN o KEY_UP con lo que hay rebote en las acciones.


Jeje, me había dado cuenta y se lo puse yo  :P  (Además de mostrar el valor de tempo)


Se me olvidó decírtelo antes, la musica de msx (al menos el archivo incluído en el ejemplo) no va...


Imagino que soporta (o soportará), ya que se visualiza en el programa ejemplo, loops de los que no saltan al principio de todo, no? (Lo malo es que ninguna de las canciones ejemplo parecen estar preparadas para ello, y a bote pronto no se me ocurre ninguna de ese tipo para hacer la prueba yo xD)


Ahora el tempo funciona de lujo, mola un puñao  ;D

warrior_rockk

Miraré el ejemplo de MSX a ver si es problema del ejemplo que he buscado. A ver si muestro también algún ejemplo del tema de los loops con alguna muestra que tenga intro y loop.

Yawin

Sé que en sí este tema no va sobre esto. Pero ya que estáis posteando algunos que sabéis: ¿sería posible un tutorial sencillito de cómo hacer nuestras propias librerías?
Sigue el desarrollo de mi motor RPG: https://www.youtube.com/watch?v=TbsDq3RHU7g

process main()
       begin
           loop
               pedo();
               frame;
            end
       end

warrior_rockk

Yo utilicé como información el ejemplo de sumarLib de los ejemplos DLL del BennuPack y la información sobre DLLs de la wiki (aunque aun se refiera a Fenix) y en el mismo día ya estaba desarrollando mi librería.
Lo mejor es que le eches un vistazo y hagas pruebas y postees dudas concretas que podamos ayudar. Aunque no estaría mal un tutorial con todo explicado y resumido. A ver se saca tiempo y se puede escribir....

FreeYourMind

pero si tutoriales ya se han hecho hace tiempo, prg hizo alguno sino recuerdo mal, fué de donde miré como hacer modulos

warrior_rockk

Nunca había revisado el completísimo manual de Bennu de Osk, pero hay un capítulo referente a desarrollo de módulos que es bastante detallado
http://www.bennugd.org/downloads/ManualBennuGD_Osk.pdf