CAAD
http://foro.caad.es/

[SGW+DMX] Fade-outs en tiempo real
http://foro.caad.es/viewtopic.php?f=12&t=3514
Página 1 de 1

Autor:  Makinaimo [ 08 Ene 2010 16:04 ]
Asunto:  [SGW+DMX] Fade-outs en tiempo real

Hola. Estoy usando la librería SGW+DMX (un grandísimo trabajo, Eliuk), y gracias a lo sencillas de usar que son las librerías y la formidable documentación que incluyen, no he tenido ningún problema para usarlas. Hasta ahora.
Intento lanzar un fade-out en tiempo real para poner fin a la reproducción de audio de fondo, pero no consigo hacer lanzar el efecto y me tengo que conformar con lanzar fade-outs simples (en los que el efecto es mucho menos chulo). No se si es por algo que yo haya hecho mal en el código, o porque el intérprete no es capaz de gestionar los fade-out. ¿Alguien podría aclararme algo?

Un saludo.

Código:
    #Ifdef TARGET_GLULX;
    Damusix.AsignarCanal( MUS_theme, 0, -1, -1 );
    Damusix.FadeOut( MUS_theme, 3500, 0 );
    !Damusix.SimpleFadeOut( MUS_theme, 3500, 0 ); ! El fade-out simple si funciona bien
    !Damusix.PararTodo(); ! Necesario al usar el fade-out simple
    #Endif;


Inform 6.31 [lib. 6/11]
Git, versión 1.2.4 / VM 3.1.1 / Núm. serie de librería 040227
Librería Española INFSP 0.9 [901.21], basada en InformATE!
Lib. sgw+dmx.h v.2.3 (2009/02/27)
Lib. damusix.h v.3 (2009/01/03)
Lib. dainunek.h v.3 (2009/01/03)

Autor:  jarel [ 08 Ene 2010 17:19 ]
Asunto:  Re: [SGW+DMX] Fade-outs en tiempo real

Creo que debido a los conflictos que el tiempo real podía ocasionar con otras librerías o funciones de autor, Eliuk dejó esa parte un poco a cuenta del programador.

En cualquier caso te pego un código para funcionar sobre DAMUSIX.
Provee una función llamada Emusica(), cuyo uso es el siguiente:
Emusica (cancion1); -> comprueba si está sonando alguna canción por el canal 0, de ser así hace un fade out, y acto seguido lanza la nueva canción "cancion1". Si no estaba sonando nada, lanza directamente la "cancion1".
Emusica (); -> hace un fade out en la canción que esté sonando por el canal 0, y apaga. Si no está sonando nada, pues no hace nada.

* Las canciones son lanzadas en modo "loop".
* Emusica() sólo funciona cuando la canción sobre la que se pretende hacer un fade ha sido lanzada previamente también a través de emusica(cancion), o a través de la función musica(cancion,volumen). Para canciones sin "loop" habría que añadir una función que compruebe la finalización del sonido del canal.
* La función glk($00D6, 100); regula la frecuencia con la que glulx consulta a la función HandleGlkEvent, y por tanto la velocidad del Fade out. Puedes variar el parámetro "100" para conseguir distintas velocidades, aunque mejor que modifiques los decrementos de bajandovolumen.
Por otro lado, funciones como esperartecla(); echan al traste esa frecuencia, ya que se valen de ella para generar las pausas. Si usas un esperartecla() asegúrate de colocar justo detrás un "glk($00D6, 100);" para restituir el "metrónomo". En cualquier caso, los esperartecla congelarán el proceso del fade out ahí donde le pillen hasta que pulses la tecla.

Código:
global cancionquesuena=0;
global cancionquesonara=0;
global volumenmus = 100; !volumen al 100%
global bajandovolumen =0; !para bajar el volumen gradualmente, se activa en glkevents

! FUNCION PARA LA FRECUENCIA: glk($00D6, 100);!glk_request_timer_events(100); !DELAY
!EVENTOS DE TIEMPO
[HandleGlkEvent ev contexto;
   contexto = 0; ! Esta linea solo está a para evitar un warning
   contador_eventos_tiempo++;
   if(contador_eventos_tiempo>200)contador_eventos_tiempo=0;
   switch (ev-->0) {
!evtype_SoundNotify:
evType_Timer:

!bajado gradual de volúmen
if(bajandovolumen>0){!zzz
             bajandovolumen=bajandovolumen-3; Damusix.Volumen(cancionquesuena,bajandovolumen);
            !print bajandovolumen, ", ";
            if(bajandovolumen<5){!uuu
                        bajandovolumen=0; Damusix.Parar(cancionquesuena);
                        if(cancionquesonara>0)musica(cancionquesonara, -1);else cancionquesuena=0;
                        }!uuu
          }!zzz
evtype_Redraw, evtype_Arrange:
   !RepintaGraficos();
}
];

[emusica quecancion;
if(cancionquesuena==0 && quecancion~=0){musica(quecancion, volumenmus);rtrue;}
cancionquesonara=quecancion;
if(bajandovolumen==0)bajandovolumen=95;
rtrue;
];
[musica queesonido quevolumen;
Damusix.AsignarCanal(queesonido,0,quevolumen,-1);
Damusix.Tocar(queesonido);
cancionquesuena=queesonido;
bajandovolumen=0;
cancionquesonara=0;
rtrue;
];

Autor:  Eliuk Blau [ 08 Ene 2010 18:52 ]
Asunto:  Re: [SGW+DMX] Fade-outs en tiempo real

Makinaimo escribió:
Código:
    #Ifdef TARGET_GLULX;
    Damusix.AsignarCanal( MUS_theme, 0, -1, -1 );
    Damusix.FadeOut( MUS_theme, 3500, 0 );
    #Endif;


El código es correcto, sí. Hay dos cosas que debes tener en cuenta:

1) Asignar Canal con -1 de volumen, hace que le ponga Volumen Global, que quizá en ese momento puede ser menor al 100% [quizás cero]. Debes tener cuidado con eso y tener en cuenta siempre cualquier cambio anterior que hayas hecho en el volumen global.

2) Después del AsignarCanal() y antes de FadeOut() no hay ninguna sentencia Tocar(). Damusix siempre detiene la reproducción de cualquier sonido en el canal que se está asignando con AsignarCanal(), así que, en tu caso, MUS_theme se asigna al canal cero, y el canal cero ahora está detenido y luego hace el Fade con un canal detenido. Evidentemente, no va a funcionar. :) El sonido debe estar en reproducción siempre previamente para que el Fade tenga efecto. Quedaría así:


Código:
#Ifdef TARGET_GLULX;
Damusix.AsignarCanal( MUS_theme, 0, -1, -1 );
Damusix.Tocar( MUS_theme );
Damusix.FadeOut( MUS_theme, 3500, 0 );
#Endif;


En realidad, Damusix gestiona todo lo necesario con los FadeIn y FadeOut. Pero tal como apunta Jarel, lo que dejo en manos del programador son casos más complejos, como CrossFades (no es tu caso). En Damusix estos se pueden realizar, pero con manejos especiales por parte del programador, no vienen integrados en la librería. Por ejemplo, yo hago CrossFades en un proyecto que no publico aún, pero para ello hago uso de una librería externa de manejo del tiempo real que escribí específicamente para estos fines. Lo que Damusix hace actualmente es todo lo que se podía hacer sin comenzar a causar inestabilidades en el código del programador habitual. 8)

Saludos! :)

Autor:  Makinaimo [ 08 Ene 2010 19:16 ]
Asunto:  Re: [SGW+DMX] Fade-outs en tiempo real

Vaya, si :) , se me olvidó poner la instrucción Damusix.Toca( MUS_theme); en el post, pero si que la tengo en el código de la aventura. El caso es que tengo esa MUS_theme sonando en el canal 0 con repeticiones infinitas, sin manipular el volumen (ni el global ni el del canal) en ningún momento, y cuando la ejecución de la aventura llega al fade-out no me reproduce el efecto, la música sigue sonando ininterrumpidamente. Ahora mismo estoy usando los fade simple, que si que me funcionan bien, pero el efecto queda mucho mejor con el fade-out en tiempo real. (Los uso en la versión GLULX de Homo Homini Orcus)

Gracias a los dos por las respuestas tan rápidas.

Autor:  Eliuk Blau [ 08 Ene 2010 19:39 ]
Asunto:  Re: [SGW+DMX] Fade-outs en tiempo real

Manda código fuente para darle una revisada. :) A mi email.
(código completo, plis, con multimedia y todo, para poder compilar)

Autor:  Eliuk Blau [ 14 Ene 2010 02:32 ]
Asunto:  Re: [SGW+DMX] Fade-outs en tiempo real

Ya está. Makinaimo, aquí tienes la corrección de tu problema con los Fades.

Era nada más ni nada menos que un Bug trivial, por desconocimiento. ¿Te acuerdas que una vez te comenté en el código de Dagoon que tú ocupabas tus propias funciones de Pausa y Espera tecla, en lugar de la rutina wait() proporcionada por SGW+DMX?

Bueno, pues ahí el problema. Resulta que, como lo menciono en una parte del manual de Damusix, algunas rutinas usan el timer para sus propios fines. Usualmente las rutinas genéricas de Pausa() se escriben de tal manera. Y tu problema concreto era que justo después de los Fades de tiempo real llamabas a tu rutina de pausa... que reprograma el timer y luego lo detenía, matando con ese acto cualquier posibilidad que el Fade se realizara correctamente.

Lo que hice fue cambiar todos los Pause() y PressAnyKey() de tu código, por la rutina wait() proporcionada por SGW+DMX. Esa rutina es simplemente un wrapper para las funciones de pausa que ya vienen de fábrica en la Lib. 6/11 (para qué repetir código que ya funciona bien). Y lo único que hace es determinar si Damusix tiene un Fade activo en ese momento. Si es tal la situación, fuerza la NO-UTILIZACION de una pausa temporizada... para no matar el efecto de Damusix. :) [lo logra haciendo uso de la rutina Damusix.EnFade(), que se menciona en la Doc de Damusix y que ayuda mucho en los casos en los que necesites trabajar con el Timer, y no quieras cargarte los efectos de FadeOut en tiempo real de Damusix]. (De hecho, te aconsejo que mires el código fuente de wait() para que te hagas una idea de cómo está implementada. :D )

Así que ahora están funcionando los Fades de tiempo real perfectamente. Puedes mirarlo en el código en las lineas que me comentaste por mail.

Acá está tu código corregido y compilado. Cuando lo bajes me avisas por acá mismo para borrar el archivo. :mrgreen:

http://dl.dropbox.com/u/2223571/HHOrcus_src_corregido.rar

Saludos! :)

Autor:  jarel [ 14 Ene 2010 10:41 ]
Asunto:  Re: [SGW+DMX] Fade-outs en tiempo real

Eliuk Blau escribió:
Ya está. Makinaimo, aquí tienes la corrección de tu problema con los Fades.

Era nada más ni nada menos que un Bug trivial, por desconocimiento. ¿Te acuerdas que una vez te comenté en el código de Dagoon que tú ocupabas tus propias funciones de Pausa y Espera tecla, en lugar de la rutina wait() proporcionada por SGW+DMX?

Bueno, pues ahí el problema. Resulta que, como lo menciono en una parte del manual de Damusix, algunas rutinas usan el timer para sus propios fines. Usualmente las rutinas genéricas de Pausa() se escriben de tal manera. Y tu problema concreto era que justo después de los Fades de tiempo real llamabas a tu rutina de pausa... que reprograma el timer y luego lo detenía, matando con ese acto cualquier posibilidad que el Fade se realizara correctamente.

Y eso que ya le advertí sobre ello en la primera respuesta... ¬¬

Autor:  Makinaimo [ 15 Ene 2010 11:20 ]
Asunto:  Re: [SGW+DMX] Fade-outs en tiempo real

Vaya, qué cabezón soy... ni siquiera había pensado en que mis rutinas podían hacer uso del timer. Prometo escucharte (leerte) más atentamente la próxima vez, Jarel.
Eliuk, muchísimas gracias por hacer de profe y corregirme el trabajo. Ya puedes borrar el archivo cuando quieras.

Creo que esperaré a que termine la comp para añadir las correcciones y repasar los textos, en una nueva revisión de la aventura.
Un saludo.

Autor:  Eliuk Blau [ 15 Ene 2010 18:03 ]
Asunto:  Re: [SGW+DMX] Fade-outs en tiempo real

Encantado, man. :mrgreen:

Buena suerte en la comp.! :)

Página 1 de 1 Todos los horarios son UTC + 1 hora
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/