Looking for a solution for audio playback

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
ReAnimator
Regular
Posts: 67
Joined: Mon Dec 16, 2013 1:00 pm
Contact:

Looking for a solution for audio playback

#1 Post by ReAnimator »

Hello,
I am experiencing technical problem on sound.
Say, I have this monster. It's growling (loop footage). Then I want him to speak.
Once it finished his sentence, I want its growling back without getting back to the beginning.
Like this. "Grrrr 'Ha-ha-ha' rrrrr --- Grrrrrrrrr"
I have no idea how to do this. Can anyone give me a light?

User avatar
PyTom
Ren'Py Creator
Posts: 16096
Joined: Mon Feb 02, 2004 10:58 am
Completed: Moonlight Walks
Projects: Ren'Py
IRC Nick: renpytom
Github: renpytom
itch: renpytom
Location: Kings Park, NY
Contact:

Re: Looking for a solution for audio playback

#2 Post by PyTom »

You could do something like:

Code: Select all

play sound "growl.ogg" loop
"..."

$ renpy.music.set_volume(0.0, .25, channel='sound')
voice "hahaha.ogg"
monster "Ha-ha-ha"

$ renpy.music.set_volume(1.0, .25, channel='sound')
"..."
http://www.renpy.org/doc/html/audio.htm ... set_volume
Supporting creators since 2004
(When was the last time you backed up your game?)
"Do good work." - Virgil Ivan "Gus" Grissom
Software > Drama • https://www.patreon.com/renpytom

ReAnimator
Regular
Posts: 67
Joined: Mon Dec 16, 2013 1:00 pm
Contact:

Re: Looking for a solution for audio playback

#3 Post by ReAnimator »

Ahh! Volume! I've never thought about that. Big thanks, Pytom.
Another question.
Is it possible to get back to growling right after the sentence is finished without touching anything?
I mean, in this case it won't come back until you click the button, right?

ReAnimator
Regular
Posts: 67
Joined: Mon Dec 16, 2013 1:00 pm
Contact:

Re: Looking for a solution for audio playback

#4 Post by ReAnimator »

Hi,
I'm still looking for a solution for this.
Currently I have to manually mute the voice effect every time he speaks.
I don't think this is an efficient way to do this.
Is there any ways to 'keep watching if the character speaks, if not, the voice effect appears' which I think a lot better.

User avatar
SinnyROM
Regular
Posts: 166
Joined: Mon Jul 08, 2013 12:25 am
Projects: Blue Birth
Organization: Cosmic Static Games
Contact:

Re: Looking for a solution for audio playback

#5 Post by SinnyROM »

Maybe you can use the character callback property for this? http://www.renpy.org/doc/html/character_callbacks.html
This example can be modified to mute/unmute in addition to playing a sound: http://lemmasoft.renai.us/forums/viewto ... 263#p73263

ReAnimator
Regular
Posts: 67
Joined: Mon Dec 16, 2013 1:00 pm
Contact:

Re: Looking for a solution for audio playback

#6 Post by ReAnimator »

Hey, SinnyROM! Thanks for your help!
It works great. Much much better than manually placing codes.
It's perfect if the voice effect continues after the dialogue without clicking though.
I also wonder

init python:
def callback(event, **kwargs):

what's this **kwargs thingy???

SundownKid
Lemma-Class Veteran
Posts: 2299
Joined: Mon Feb 06, 2012 9:50 pm
Completed: Icebound, Selenon Rising Ep. 1-2
Projects: Selenon Rising Ep. 3-4
Organization: Fastermind Games
Deviantart: sundownkid
Location: NYC
Contact:

Re: Looking for a solution for audio playback

#7 Post by SundownKid »

ReAnimator wrote:Hey, SinnyROM! Thanks for your help!
It works great. Much much better than manually placing codes.
It's perfect if the voice effect continues after the dialogue without clicking though.
I also wonder

init python:
def callback(event, **kwargs):

what's this **kwargs thingy???
"args" means arguments. It means whatever additional arguments you want to add there.

ReAnimator
Regular
Posts: 67
Joined: Mon Dec 16, 2013 1:00 pm
Contact:

Re: Looking for a solution for audio playback

#8 Post by ReAnimator »

Hey, SundownKid!
I am pretty much novice so I don't understand what that means but if I take this out from code Ren'py returns error. So this additional arguments must be necessary for some reason? Why's the name **kwargs?? I can change it to **abc and it still works. What's the point of having this in the code?

User avatar
SinnyROM
Regular
Posts: 166
Joined: Mon Jul 08, 2013 12:25 am
Projects: Blue Birth
Organization: Cosmic Static Games
Contact:

Re: Looking for a solution for audio playback

#9 Post by SinnyROM »

SundownKid mentioned args is arguments; the kw is for keywords. So **kwargs takes in a certain type of argument with keys, i.e. a dictionary. The name is a convention, so as long as you keep ** in the parameters it'll be fine. Here's a page with an explanation and some examples: http://markmiyashita.com/blog/python-args-and-kwargs/

I'm not sure why it wouldn't work without **kwargs - maybe the callback function requires it somehow. I don't see it but someone else with a clearer mind might!

User avatar
trooper6
Lemma-Class Veteran
Posts: 3712
Joined: Sat Jul 09, 2011 10:33 pm
Projects: A Close Shave
Location: Medford, MA
Contact:

Re: Looking for a solution for audio playback

#10 Post by trooper6 »

**kwargs must be in the code.

What it means is that you can add in additional keyword arguments to your callback, if you like. But if you don't need additional information passed to your callback, you can ignore it--but don't delete it.

How would you use a keyword arg? Well there are many ways depending on your imagination. But here is one example.

Let's say you want clicks to play when your characters are speaking using slow text...but not when they are not speaking. You could make a callback like so:

Code: Select all

init -1 python:
    renpy.music.register_channel("Chan1", mixer= "sfx", loop=True)
            
    def clicks(event, **kwargs):
        if event == "show" or event == "begin":
            renpy.music.play("click.wav", channel="Chan1")     
        if event == "slow_done" or event == "end":
            renpy.music.stop(channel="Chan1")
And then you give your callback to a character and you are good to go:

Code: Select all

define e = Character('Eileen', color="#c8ffc8", what_slow_cps=20, what_slow_abortable=False, callback=clicks)
What if you have two characters and you want a different click sound to happen for each one? You could make two different callbacks:

Code: Select all

init -1 python:
    renpy.music.register_channel("Chan1", mixer= "sfx", loop=True)
            
    def clicks1(event, **kwargs):
        if event == "show" or event == "begin":
            renpy.music.play("high_click.wav", channel="Chan1")     
        if event == "slow_done" or event == "end":
            renpy.music.stop(channel="Chan1")

    def clicks2(event, **kwargs):
        if event == "show" or event == "begin":
            renpy.music.play("low_click.wav", channel="Chan1")     
        if event == "slow_done" or event == "end":
            renpy.music.stop(channel="Chan1")
And then define your two characters:

Code: Select all

define e = Character('Eileen', color="#c8ffc8", what_slow_cps=20, what_slow_abortable=False, callback=clicks1)
define f = Character('Faye', color="#c8ffc8", what_slow_cps=20, what_slow_abortable=False, callback=clicks2)
That would work...but you are repeating code, and whenever you start repeating code there is probably a more efficient way to do what you want to do. What happens if instead of just two different clicks...you had 10? Then you'd have to make ten different callbacks? Nope, you can just have one callback and use a keyword arg. That would look like this (we are going to add a keyword argument called "char" that tells us which character is speaking and then we will decide which click sound to play based on that):

Code: Select all

init -1 python:
    renpy.music.register_channel("Chan1", mixer= "sfx", loop=True)
            
    def clicks(event, char=1, **kwargs):
        if event == "show" or event == "begin":
            if char == 1:
                renpy.music.play("high_click.wav", channel="Chan1")
            if char == 2:  
                renpy.music.play("low_click.wav", channel="Chan1")
            if char == 3:
                renpy.music.play("med_click.wav", channel="Chan1")
        if event == "slow_done" or event == "end":
            renpy.music.stop(channel="Chan1")
Then you make your characters, and include a callback keyword...which in this case looks like 'cb_char':

Code: Select all

define e = Character('Eileen', color="#c8ffc8", what_slow_cps=20, what_slow_abortable=False, callback=clicks, cb_char=1)
define f = Character('Faye', color="#c8ffc8", what_slow_cps=20, what_slow_abortable=False, callback=clicks, cb_char=2)
define r = Character('Roger', color="#c8ffc8", what_slow_cps=20, what_slow_abortable=False, callback=clicks, cb_char=3)
A Close Shave:
*Last Thing Done (Aug 17): Finished coding emotions and camera for 4/10 main labels.
*Currently Doing: Coding of emotions and camera for the labels--On 5/10
*First Next thing to do: Code in all CG and special animation stuff
*Next Next thing to do: Set up film animation
*Other Thing to Do: Do SFX and Score (maybe think about eye blinks?)
Check out My Clock Cookbook Recipe: http://lemmasoft.renai.us/forums/viewto ... 51&t=21978

ReAnimator
Regular
Posts: 67
Joined: Mon Dec 16, 2013 1:00 pm
Contact:

Re: Looking for a solution for audio playback

#11 Post by ReAnimator »

Thanks, SinnyROM and trooper6!
Your explanation is very helpful but clearly beyond my knowledge.
I can somehow understand what you wrote but it's impossible to get on my own.
I'll leave that **kwarg.
Thank you, both. I really appreciate!

Code: Select all

init -1 python:
    renpy.music.register_channel("Chan1", mixer= "sfx", loop=True)
           
    def clicks(event, char=1, **kwargs):
        if event == "show" or event == "begin":
            if char == 1:
                renpy.music.play("high_click.wav", channel="Chan1")
            if char == 2: 
                renpy.music.play("low_click.wav", channel="Chan1")
            if char == 3:
                renpy.music.play("med_click.wav", channel="Chan1")
        if event == "slow_done" or event == "end":
            renpy.music.stop(channel="Chan1")
In the last example, I have to replace char to cb_char, no?

User avatar
trooper6
Lemma-Class Veteran
Posts: 3712
Joined: Sat Jul 09, 2011 10:33 pm
Projects: A Close Shave
Location: Medford, MA
Contact:

Re: Looking for a solution for audio playback

#12 Post by trooper6 »

ReAnimator wrote:
In the last example, I have to replace char to cb_char, no?
Nope.

When you make your callback you just give that callback a name...like "char."

so:

Code: Select all

def clicks(event, char=1, **kwargs):
But when you are making a character...

Code: Select all

define e = Character('Eileen', color="#c8ffc8", what_slow_cps=20, what_slow_abortable=False, callback=clicks, cb_char=1)
What you have here is the character Eileen. And you have defined here with a bunch of keyword arguments that belong to her: color, what_slow_cps, what_slow_abortable, callback.
If you put char=1 in her definition, renpy would think that char is a keyword argument that belongs to eileen. But it is a keyword argument that belongs to the callback. The way you let the program know it is the callback's keyword and not Eileen's keyword is by adding the prefix "cb_" to the keyword. In this case you end up with, cb_char.
A Close Shave:
*Last Thing Done (Aug 17): Finished coding emotions and camera for 4/10 main labels.
*Currently Doing: Coding of emotions and camera for the labels--On 5/10
*First Next thing to do: Code in all CG and special animation stuff
*Next Next thing to do: Set up film animation
*Other Thing to Do: Do SFX and Score (maybe think about eye blinks?)
Check out My Clock Cookbook Recipe: http://lemmasoft.renai.us/forums/viewto ... 51&t=21978

ReAnimator
Regular
Posts: 67
Joined: Mon Dec 16, 2013 1:00 pm
Contact:

Re: Looking for a solution for audio playback

#13 Post by ReAnimator »

trooper6 wrote: The way you let the program know it is the callback's keyword and not Eileen's keyword is by adding the prefix "cb_" to the keyword. In this case you end up with, cb_char.
Thanks again but... how does the one know this?? Like adding prefix "cb_"... It must be strictly "cb_", right? Oh my... I'm getting nervous... I will never get this right...

User avatar
trooper6
Lemma-Class Veteran
Posts: 3712
Joined: Sat Jul 09, 2011 10:33 pm
Projects: A Close Shave
Location: Medford, MA
Contact:

Re: Looking for a solution for audio playback

#14 Post by trooper6 »

ReAnimator wrote:
trooper6 wrote: The way you let the program know it is the callback's keyword and not Eileen's keyword is by adding the prefix "cb_" to the keyword. In this case you end up with, cb_char.
Thanks again but... how does the one know this?? Like adding prefix "cb_"... It must be strictly "cb_", right? Oh my... I'm getting nervous... I will never get this right...
Most things are well documented. The cb_ prefix thing is not well documented. It showed up in a changelog post for 6.2.0: http://lemmasoft.renai.us/forums/viewto ... 873#p27873

But I just found out about it by not getting it to work and asking on the forums and getting someone to explain it to me. As far as I know, however, callback is the only one that takes a prefix for its keyword args in the character definition. So...you know that one and that should be it.
A Close Shave:
*Last Thing Done (Aug 17): Finished coding emotions and camera for 4/10 main labels.
*Currently Doing: Coding of emotions and camera for the labels--On 5/10
*First Next thing to do: Code in all CG and special animation stuff
*Next Next thing to do: Set up film animation
*Other Thing to Do: Do SFX and Score (maybe think about eye blinks?)
Check out My Clock Cookbook Recipe: http://lemmasoft.renai.us/forums/viewto ... 51&t=21978

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot]