Page 1 of 1

Pick Random Music Loop each time [Urgent]

Posted: Thu Nov 05, 2015 6:03 pm
by csky
Hi there, I have an urgent problem I've been trying to solve and I can't seem to figure it out.
I need this solved in about a few hours from now, but even if this thread is not replied by then it will still be useful.

Pretty much what I've got going is two music channels. The 'music' channel is playing a rhythmic beat that continuously plays and won't need to be touched. (This is working fine so it's not a problem)

On the other hand I have another channel "Chan1" needing to pick one of three loops randomly and play it, then pick another loop randomly and play it, and loop that forever ect.

I've been reading the documentation and past renpy questions about similar things, and I managed to find this code here that I tried.

Code: Select all

$ randomswamp = renpy.random.choice( ("music/swamp silence.ogg", "music/swamp pan1.ogg", "music/swamp pan2") )
$ renpy.music.play (randomswamp, channel="Chan1", if_changed=True, loop=True, fadein=0, tight=True)
The problem is, it selects one of the three tracks randomly and then ONLY loops that one track forever. It doesn't go back and re-pick another one randomly when it loops, which is what I want it to do.
To summarize, I want it so it picks a new random track every loop.

I know that with images you can define animation loops and use the 'repeat' command, but I can't figure out how to do this with music. My ability with code is very simple, and nothing in the renpy documentation music page seems to cover what I want to do.

Re: Pick Random Music Loop each time [Urgent]

Posted: Thu Nov 05, 2015 7:20 pm
by Zetsubou
What you want is renpy.music.set_queue_empty_callback
http://www.renpy.org/doc/html/audio.htm ... y_callback

Re: Pick Random Music Loop each time [Urgent]

Posted: Thu Nov 05, 2015 7:36 pm
by csky
Zetsubou wrote:What you want is renpy.music.set_queue_empty_callback
http://www.renpy.org/doc/html/audio.htm ... y_callback
Okay, that's a start, I suppose. I had a look, but I have no idea what to do with it. It sounds complex and I have no clue how it works or where to start.
It doesn't have any examples so I'm still clueless.

Re: Pick Random Music Loop each time [Urgent]

Posted: Thu Nov 05, 2015 7:42 pm
by Zetsubou
The idea is that set_queue_empty_callback will call a function whenever the queue for that channel is empty.
So using your code:

Code: Select all

init python:
    def queueChanCallback():
        randomswamp = renpy.random.choice( ("music/swamp silence.ogg", "music/swamp pan1.ogg", "music/swamp pan2") )
        renpy.music.play (randomswamp, channel="Chan1", if_changed=True, loop=False, fadein=0, tight=True)
    renpy.music.set_queue_empty_callback(queueChanCallback, channel='Chan1')

#... other code ...

label start:
    #game stuff...
    $ queueChanCallback()
Once queueChanCallback is called in the start label, it runs your code once.
Then, when the queue finishes, the callback says to run the function again, and thus runs the random choice method again.

^All untested. I've never used this function before. I'm just going by the docs. You may need to use queue instead of play.

Re: Pick Random Music Loop each time [Urgent]

Posted: Thu Nov 05, 2015 8:02 pm
by csky
Thanks man, I managed to get it working now, I did have to swap for queue instead of play.

Re: Pick Random Music Loop each time [Urgent]

Posted: Thu Nov 05, 2015 8:11 pm
by csky
Oh actually, I take that back. The loop is working fine, but it won't stop when I use stop Chan1 or renpy.music.stop(

Re: Pick Random Music Loop each time [Urgent]

Posted: Thu Nov 05, 2015 8:20 pm
by Zetsubou
Hm, you could probably get away with using a variable to check if it should loop.

Code: Select all

init python:
    continueLooping = True

    def queueChanCallback():
        if continueLooping:
            randomswamp = renpy.random.choice( ("music/swamp silence.ogg", "music/swamp pan1.ogg", "music/swamp pan2") )
            renpy.music.queue (randomswamp, channel="Chan1", if_changed=True, loop=False, fadein=0, tight=True)
    renpy.music.set_queue_empty_callback(queueChanCallback, channel='Chan1')

#... other code ...

label start:
    #start music
    $ queueChanCallback()
    
    #Now lets stop the music
    $ continueLooping = False
    stop music

    #start music again
    $ continueLooping = True
    $ queueChanCallback()
Once again, untested ;)

Re: Pick Random Music Loop each time [Urgent]

Posted: Thu Nov 05, 2015 8:58 pm
by csky
Thanks. I'll try again later. For now I did a temporary fix where I just made a second call queue and had all the files as 'silence' to replace the other one.

But I'll try figure out the proper way in the long term.

Re: Pick Random Music Loop each time [Urgent]

Posted: Tue Sep 27, 2016 6:02 pm
by crimsonnight
Zetsubou wrote:Hm, you could probably get away with using a variable to check if it should loop.

Code: Select all

init python:
    continueLooping = True

    def queueChanCallback():
        if continueLooping:
            randomswamp = renpy.random.choice( ("music/swamp silence.ogg", "music/swamp pan1.ogg", "music/swamp pan2") )
            renpy.music.queue (randomswamp, channel="Chan1", if_changed=True, loop=False, fadein=0, tight=True)
    renpy.music.set_queue_empty_callback(queueChanCallback, channel='Chan1')

#... other code ...

label start:
    #start music
    $ queueChanCallback()
    
    #Now lets stop the music
    $ continueLooping = False
    stop music

    #start music again
    $ continueLooping = True
    $ queueChanCallback()
Once again, untested ;)
Thanks for the code. How can I play a track before executing it though? At the moment, the tracks play wherever I write the init code, making the 'play' command redundant.

PS 'stop music' doesn't work for me, but stopping the created channel does.

This is the code that works for me (tracks play on the title screen):

Code: Select all

init python:
    continueLooping = True

    def titlemusic():
        if continueLooping:
            randomswamp = renpy.random.choice( ("music/2.ogg", "music/3.ogg", "music/4.ogg", "music/5.ogg") )
            renpy.music.queue (randomswamp, channel="titletrack", loop=False, fadein=0, tight=True)
    renpy.music.set_queue_empty_callback(titlemusic, channel='titletrack')

# The game starts here.

label start:

    #Now lets stop the music
    $ continueLooping = False
    stop titletrack
   
and I want to play 'music/1.ogg' before the others start looping.