New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add Functions to Voice. #32
Comments
|
I'm thinking that this is a good idea, but perhaps a bit over-complicated, for what we need. Let's talk about requirements, and then we can talk about what it would take to establish those requirements. So the main requirement is that we want to be able to tag voices with character names, so that we can toggle voices on and off by character. I think you're on the right track with adding a tag parameter to voice, but for backwards compatibility's sake, it has to be a keyword argument that defaults to None. So the voice function should probably have the signature: The voice statement should also take an optional voice tag. I think we should make it a name, rather than a string, so that the user can write:
I think characters should take a voice tag, but in a somewhat different way. Basically, if a character has a voice tag, the value of that tag should be stored in a variable that the voice_interact function can access. So the code: should be equivalent to Finally, I'd suggest that instead of voice_dir, we have config.voice_filename_format, which would be formatted with {filename} and {tag}. (There should be a 'default' tag, probably.) This would let us write: Which would then let us have:
play the file named voice/eileen/0001.ogg . What do you think of this variant? |
|
Alright I see the logic in that. I really like your idea about the config.voice_filename_format idea. It would also be a great Idea to add these filename_formats options in other places like images, music and sounds as well. Now With the file format, would you would want the default be "voice/{tag}/{filename}.ogg" or keep the default at the game base with the option of them setting it themselves in the config.rpy? I'm asking this cause someone is going to wonder why their mp3 file won't work with this filename format. I would make the default at the game base with the option of the developer changing this config function personally. Now, back to the voice tagging system, I see how you going about this. So with voice_tag in the Character() funtion, Renpy would add the voice_tag in the voice_list variable in the first init run (which would become a persistent variable so less loading time). Then a user could toggle off that character in the Preference Screen which would cause the tag_name be set to false. When RenPy come to a voice() function it would read the dialog() name thats under it and compare it to the list of name_tags that it got from the Character() function. If that tag_name is set to false it would send the signal to the voice_interact function and skip it. Correct? Another option for the voice_list variable, would you want it to add voices as the game goes, or just add it on the first init and keep the voice_list variable persistent. Later on after getting this part working I want make it so that it would mask the voice name till a user would trip flag and the name would reveal itself later in the game, but that it in the future idea after we get the base function put in. Edit: With the last Idea, that should be a screen option not a renpy system option. |
|
The default voice_filename_format has to be {filename}, for backwards compatibility. I don't see voice_list the way you see it, as something that needs to be updated. Instead, what we'll have is persistent._voice_mute, which should be a dict mapping a voice tag to a "mute" state. If the voice tag is not present, or maps to False, the voice is played - otherwise, it's muted. Finally, we should have a pair of actions that update persistent._voice_mute. SetVoiceMute(voice_tag, mute) allows us to set the voice mute of a channel, while ToggleVoiceMute(voice_tag, invert_select=False) allows us to create a button that toggles mute. (ToggleVoiceMute should be selected when the channel is muted - but invert_select should invert it.) |
|
Alright, I'm getting what you meaning slowly. So in other words when a user uses The filename is the path of the file, but can be change with the Which by default is set to "{filename}" but can be change to "voice/{tag}/{filename}.ogg" if the user wishes to. If the tag is not set to "None" it would be the tag that the user desires like or like in the voice statement which would use a name instead of a string Now if the "tag" is set to "None", it will used the "voice_tag" from the Character() function Which comes to a question...how would renpy know to uses the 'eileen' voice tag if the say statement is below that has the character's voice_tag? Would it read the next line in the background? Then if the Character() has a voice_tag, renpy use it to play the voice file? Now moving right along assuming renpy knows what it doing, to toggle individual character's voice on and off. On the preference screen when a user selects a voice button it would activate the action Which then would add the voice_tag to the persistent._voice_mute as a dict. If renpy reads the voice() function and activate voice_interact(), voice_interact would see that the voice_tag 'eileen' is in a muted state it will basically skip it. Now if the user click the button again to unmute it, it would activate the Thus remove the voice_tag from the persistent._voice_mute dict and once again when renpy voice() activate voice_interact and voice_interacts see that the voice_tag map to false, it would play the voice file in the 'voice' channel. Please correct if I'm wrong. Once we agree on a certain method to accomplish this, I'll create a roadmap txt file stating what I am doing and follow that roadmap till the voice_enhancement project is finish. I'm a bit new to python so I may ask for help along the way, but I want to learn more about python and this is a way to do it. By just doing it. ^^ Btw sorry for the weird interaction with git's comment system. When previewing I pressed the spacebar a few times and it posted all four of them. And then again when in the comment preveiw i pressed tab then space which cause it to close the issue and post the comment. Gotta love user Error.....^^' |
|
Basically correct. (I suggest we use voice_tag to refer to voice tags exclusively.) "how would renpy know to uses the 'eileen' voice tag if the say statement is below that has the character's voice_tag?" take a look at common/00voice.rpy to see how it works. Basically, all voice() does is to store information in the _voice object. The voice_interact function - which is called automatically at the start of each interaction - takes care of playing the voice. I think you're confusing how to use SetVoiceMute and ToggleVoiceMute. Basically, we'd like to support code like: |
|
I get it now. Since voice_interact is called upon each interaction, then when it comes across a say statement, it would read the Character()'s name and then pull up the voice_tag from it and if the voice_tag is not in the persistent._voice_mute, Renpy will play the voice file that is according to the voice() function. If that is the logic, let me know cause I want to get this README stating what I'm doing, done. Plus I'll be adding the comments to 'common/00voice.rpy' so that I would know where to add the lines needed. I'm learning so I need to have a roadmap to work with. |
|
Btw how would I add the voice_tag to the Charater() function? I know it's in renpy/character.py but I don't see a way to do so. |
|
I think it's probably best if I add it for you. The Character code is opaque, to say the least. But if you can handle the 00voice.rpy portion of this, we can meet in the middle. |
|
Okay, so do you want me to add you as a collaborator to my branch then? |
|
Sure, add me as a collaborator. |
|
I've added a voice_tag parameter to Character, and a corresponding config.voice_tag_callback config variable, and checked the result into your branch. So you should be good to go. The way you're initializing the voice mute dict seems wrong. First of all, it should be persistent._voice_mute - the leading underscore makes it a Ren'Py-internal name. Secondly, you only want to initialize it if it's None - your current code does so unconditionally. Also - why don't we make it a set? That seems to match what we're doing with it better than a dict. So the final initialization should look like: |
|
Okay, after reading what set() dose in python docs, and testing and playing around with in python, I think it's a good idea. I'll go ahead and add that Idea into the voice_enhancement branch. Btw while working on finishing 00voice.rpy, and add the two actions in 00screen.rpy, could you put a post on the forum asking for voice samples? I want to add the changes to the RenPy' tutorial to showcase voice so they know it's there and show examples on how to implement it. I'll leave it up to you as to what they say. |
|
I took your branch, merged it, cleaned it up, and added the remaining features. It'll be released with 6.15. |
odysseywestra commentedSep 9, 2012
Alright I've come up with an Idea on how to add functions to voice, like switching on and off individual characters and having the developer set a default voice directory for their game. I like some feed back before I continue this...
NEW VOICE PARAMETERS
Usuage: voice(tag_name, file, **kwargs)
This extra contains the new implementation of voice support. It can
be toggle on and off as a whole, but now has support to toggle off
and on for individual characters in the Preference Screen. Plus
once you set the config.voice_dir you can place the voice files in
another folder without haveing to type or retype the path/to/file
every time you want voice in the game.
To use it, place a voice tag_name sndfile line before
each line of dialogue. Please note that the tag_name is an
optional argument, but in order to switch off an on voice for
individual characters a character name must be place there.
Normally, a voice is cancelled at the start of the next interaction.
If you want a voice to span interactions, call the
voice_sustains
Now to in order to toggle on and off the voice for each individual
character, you to set the has_voice in the Character() to
true cause by default has_voice is set to false.
When has_voice is set to true the Character() name variable
will be added to the _voice.list variable as a string with a
list of other Character() that has the has_voice set to
true.
Now to make sure that renpy will not re-add these characters to the
_voice.list variable it will be set as a persistent variable and
will be automatically loaded next time the game is started again.
On the Preference Screen developer would set an
action button(s) that would utilize the _voice.list variable
of characters. When you click on the characters name it will darken
indicating the character's voice is off or normal color indicating
the character's voice is on.
Alright to utilize the voice toggle in the game script, the
developer needs to place the character's name or substitute name from
in the define argument in to the tag_name from voice.
Now and example with the substitute name from define argument.
Now the one last new thing about voice is that if you set the
config.voice_dir in the config.rpy to the directory of the
voice files. Once that is set, you wouldn't have to type or retype
the path/to/file every time you want voice in the game.
Please not that config.voice_dir default path will be the game
base which is when it is set to "None"
The text was updated successfully, but these errors were encountered: