Board index FlightGear Development Aircraft

Switch click

Questions and discussion about creating aircraft. Flight dynamics, 3d models, cockpits, systems, animation, textures.

Switch click

Postby jam007 » Wed May 17, 2017 6:03 pm

If you have a number of switches, approx. 10, and you want a click sound as they are switched (both on and off). How do you do it in a smart way?
Bind Nasal script in each knob animation. The script sets a common click property and reset it a short time after. :?:
jam007
 
Posts: 579
Joined: Sun Dec 16, 2012 11:04 am
Location: Uppsala, Sweden
Callsign: LOOP
Version: 2020.4.0
OS: Ubuntu 22.04

Re: Switch click

Postby wlbragg » Wed May 17, 2017 6:17 pm

The script sets a common click property and reset it a short time after.

Yes, that is how we do it in the c172p and the shuttle. There is now also the ability to define the exact position of the sound dynamically (available after the next release).

Note: in this example there is also a default position set if no overriding position is passed.

model.xml
Code: Select all
<action>
            <binding>
                <command>nasal</command>
                <script>
                            SpaceShuttle.click("avionics", -11.50485, -1.16882, -0.52177);
                </script>
            </binding>
        </action>


nasal helper
Code: Select all
# Positional Click Sound Helper
##########################################

var click = func (name, xpos=-12.21132, ypos=-0.03679, zpos=-0.83401, timeout=0.1, delay=0.) {

   var sound_prop = "/sim/model/shuttle/sound/click-" ~ name;

   setprop("/sim/model/shuttle/sound/click-pos-x", xpos);
   setprop("/sim/model/shuttle/sound/click-pos-y", ypos);
   setprop("/sim/model/shuttle/sound/click-pos-z", zpos);

    settimer(func {
        # Play the sound
        setprop(sound_prop, 1);

        # Reset the property after "timeout" so that the sound can be played again.
        settimer(func {
            setprop(sound_prop, 0);
        }, timeout);
    }, delay);
};


sound.xml
Code: Select all
    <!-- Switch click sound -->
    <switch>
        <name>click-avionics-switch</name>
        <mode>once</mode>
        <path>Sounds/click3.wav</path>
        <condition>
            <property>/sim/model/shuttle/sound/click-avionics</property>
        </condition>
        <position>
            <x><property>/sim/model/shuttle/sound/click-pos-x</property></x>
            <y><property>/sim/model/shuttle/sound/click-pos-y</property></y>
            <z><property>/sim/model/shuttle/sound/click-pos-z</property></z>
        </position>
        <reference-dist>.02</reference-dist>
        <max-dist>5.0</max-dist>
    </switch>
Kansas and Ohio/Midwest scenery development.
KEQA, 3AU, KRCP Airport Layout
Intel i7/GeForce RTX 2070/Max-Q
User avatar
wlbragg
 
Posts: 7586
Joined: Sun Aug 26, 2012 12:31 am
Location: Kansas (Tornado Alley), USA
Callsign: WC2020
Version: next
OS: Win10/Linux/RTX 2070

Re: Switch click

Postby jam007 » Wed May 17, 2017 6:29 pm

:)

Thanks!
jam007
 
Posts: 579
Joined: Sun Dec 16, 2012 11:04 am
Location: Uppsala, Sweden
Callsign: LOOP
Version: 2020.4.0
OS: Ubuntu 22.04

Re: Switch click

Postby sanhozay » Wed May 17, 2017 6:44 pm

I agree that the better way is to have a dedicated property, rather than detect changes to a whole bunch of properties in -sound.xml. See the -sound.xml file in the Cessna337 for that solution.

As a slight variation on wilbragg's idea, you can also use fgcommands to wrap the existing property-toggle, property-assign, etc.

Code: Select all
var click = func
{
    setprop("sim/sound/click", 1);
    var t = maketimer(0.1, func {
        setprop("sim/sound/click", 0);
    });
    t.singleShot = 1;
    t.start();
}

var switch = func(command, node)
{
    var property = node.getNode("property").getValue();
    var oldValue = getprop(property);
    fgcommand(command, node);
    if (oldValue != getprop(property))
        click();
}

addcommand("switch-adjust", func(node) {switch("property-adjust", node);});
addcommand("switch-assign", func(node) {switch("property-assign", node);});
addcommand("switch-toggle", func(node) {switch("property-toggle", node);});

Note that maketimer is preferred to settimer these days.

The switch-toggle, switch-assign can then be used in bindings in the model:

Code: Select all
<binding>
  <command>switch-toggle</command>
  <property>controls/switches/battery-master</property>
</binding>

This doesn't have the flexibility of moving the sound in 3D space that wilbragg's solution has, but it is easily reused in checklists, tutorials, etc.
sanhozay
 
Posts: 1207
Joined: Thu Dec 26, 2013 12:57 pm
Location: EGNM
Callsign: G-SHOZ
Version: Git
OS: Ubuntu 16.04

Re: Switch click

Postby wlbragg » Wed May 17, 2017 7:10 pm

I like @sanhozay approach better where only one sound position is acceptable. And I agree we should use maketimer instead of settimer.
Kansas and Ohio/Midwest scenery development.
KEQA, 3AU, KRCP Airport Layout
Intel i7/GeForce RTX 2070/Max-Q
User avatar
wlbragg
 
Posts: 7586
Joined: Sun Aug 26, 2012 12:31 am
Location: Kansas (Tornado Alley), USA
Callsign: WC2020
Version: next
OS: Win10/Linux/RTX 2070

Re: Switch click

Postby jam007 » Wed May 17, 2017 8:39 pm

Have to read more about addcommand!

Noticed that maketimer is the preferred way. So I have just tested this:
Code: Select all
# Triggers switch sound
# name is sound-large or sound-small
# that riggers different sounds.
 var sound_helper = func(name) {
   var sp = "/instrumentation/switches/"~name;
   setprop(sp,1);
   var timer = maketimer(0.1, func(){
     setprop(sp,0); });
   timer.singleShot = 1;
   timer.start();
 }

Very similar to @sanhozay's code. And it works :)

Really, You should add these kinds of useful tricks to the wiki...
jam007
 
Posts: 579
Joined: Sun Dec 16, 2012 11:04 am
Location: Uppsala, Sweden
Callsign: LOOP
Version: 2020.4.0
OS: Ubuntu 22.04

Re: Switch click

Postby Thorsten » Thu May 18, 2017 6:36 am

No, you should add it to the wiki :mrgreen:
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: Switch click

Postby jam007 » Thu May 18, 2017 9:08 am

Thorsten wrote in Thu May 18, 2017 6:36 am:No, you should add it to the wiki :mrgreen:

No problem. Have contributed before.
But that wlbragg and sanhozay and probably others have reinvented the wheel in different ways before me is ineffective. Documenting ideas helps us all to improve these ideas and avoids much unnecessary redundant work. It is also much easier to read the wiki to find good solutions than to understand complicated aircraft like the Cessna, Shuttle or Viggen.

Further. An improvement to he knob/slider animation would be to have a sound trigger property that can be set in <action>, <increase> etc. when manipulated. This would keep all common manipulating animation in one place (well two as the sound.xml has to do the actual sound).
jam007
 
Posts: 579
Joined: Sun Dec 16, 2012 11:04 am
Location: Uppsala, Sweden
Callsign: LOOP
Version: 2020.4.0
OS: Ubuntu 22.04

Re: Switch click

Postby jam007 » Thu May 18, 2017 4:35 pm

Some more thoughts.

Using the system described above combined with parametric switches make it easy to implement sounds for a large number of switches when switched by knob or pick animation. The sound binding is in the common model used for all switches of that type. It calls the sound helper function with a type of sound property that triggers the sound. No need to edit a large number of xml-files.
Drawback: Can not create sound if switches are switched by other means like a keyboard short cut or a nasal function (eg. autostart). Those types of events have to be implemented separately.

I am using the above approach as I already had implemented parametric switches.

An other way to handle a large number of switches could be to:
1) Move the properties that records switch state to a separate xml-file.
2) Make a nasal script that reads the xml-file and sets a listener for each property at program start. The listeners calls the sound helper script.
3) Make the sound helper script that triggers the sound as above. You can have different sound depending on the properties that the listener returns and also handle other event trigged by the switching in this script.
The above is triggered by anything changing the switch state property.
Drawbacks?
jam007
 
Posts: 579
Joined: Sun Dec 16, 2012 11:04 am
Location: Uppsala, Sweden
Callsign: LOOP
Version: 2020.4.0
OS: Ubuntu 22.04

Re: Switch click

Postby sanhozay » Thu May 18, 2017 5:01 pm

jam007 wrote in Thu May 18, 2017 4:35 pm:Drawback: Can not create sound if switches are switched by other means like a keyboard short cut or a nasal function (eg. autostart).

I don't understand what you mean here. The model binding, the binding in a keyboard shortcut or a line in a Nasal script can all call the same click function. An fgcommand can make that neater but is not strictly necessary. The important thing, from a maintenance point of view, is not to have multi-line Nasal snippets copied and pasted between the model, checklists, keyboard shortcuts, etc. Anything that needs more than a line should be in a .nas file somewhere, either as a function or fgcommand.

Another way to handle a large number of switches could be to:
1) Move the properties that records switch state to a separate xml-file.
2) Make a nasal script that reads the xml-file and sets a listener for each property at program start. The listeners calls the sound helper script.
3) Make the sound helper script that triggers the sound as above. You can have different sound depending on the properties that the listener returns and also handle other event trigged by the switching in this script.

What you describe is very similar to the mechanism already provided by the *-sound.xml file. It defines of a series of listeners that trigger sounds when properties change but it does it without resorting to Nasal scripting.
sanhozay
 
Posts: 1207
Joined: Thu Dec 26, 2013 12:57 pm
Location: EGNM
Callsign: G-SHOZ
Version: Git
OS: Ubuntu 16.04

Re: Switch click

Postby Thorsten » Thu May 18, 2017 6:03 pm

But that wlbragg and sanhozay and probably others have reinvented the wheel in different ways before me is ineffective. Documenting ideas helps us all to improve these ideas and avoids much unnecessary redundant work


It's less than ten lines of code, hardly a reason to sweat over re-inventing it.

There's hundreds of solutions of similar size and scope encoded in the Shuttle - if I really document all of them, not only don't I get anything else done, but also you'll be drowning in hundreds of code snippets, trying to look for the one you actually need.

Documentation is pretty useless if it's not organized so that you actually find what you're looking for, and that means evaluating relevance. You have to count time looking through documentation to find what you need against time used to come up with a simple code snippet to solve your problem.
Thorsten
 
Posts: 12490
Joined: Mon Nov 02, 2009 9:33 am

Re: Switch click

Postby jam007 » Thu May 18, 2017 7:25 pm

sanhozay wrote in Thu May 18, 2017 5:01 pm:I don't understand what you mean here. The model binding, the binding in a keyboard shortcut or a line in a Nasal script can all call the same click function.

What I mean is that if a switch can be switched by hand, by shortcut and by script. The call to the click function has to be added in three places rather than to one.

What you describe is very similar to the mechanism already provided by the *-sound.xml file. It defines of a series of listeners that trigger sounds when properties change but it does it without resorting to Nasal scripting.

Isn't the problem that your code and other above solves the triggering for change both switching on and off when mode in-transit doesn't work? If sound.xml had a play on-change mode for booleans the timer etc. wouldn’t be necessary. Or am I missing something?
jam007
 
Posts: 579
Joined: Sun Dec 16, 2012 11:04 am
Location: Uppsala, Sweden
Callsign: LOOP
Version: 2020.4.0
OS: Ubuntu 22.04

Re: Switch click

Postby wlbragg » Thu May 18, 2017 8:41 pm

The call to the click function has to be added in three places rather than to one.

An other way to handle a large number of switches could be to:
[snip]
The above is triggered by anything changing the switch state property.

I think you end up in the same place here because you still have to have something call the switch state property.

Isn't the problem that your code and other above solves the triggering for change both switching on and off when mode in-transit doesn't work?

While that is true, I think it was more to allow for an easy way to redirect to different sounds by passing a name. I extended that to also allow for dynamic sound positioning by passing coordinates.
Kansas and Ohio/Midwest scenery development.
KEQA, 3AU, KRCP Airport Layout
Intel i7/GeForce RTX 2070/Max-Q
User avatar
wlbragg
 
Posts: 7586
Joined: Sun Aug 26, 2012 12:31 am
Location: Kansas (Tornado Alley), USA
Callsign: WC2020
Version: next
OS: Win10/Linux/RTX 2070

Re: Switch click

Postby sanhozay » Thu May 18, 2017 8:46 pm

jam007 wrote in Thu May 18, 2017 7:25 pm:The call to the click function has to be added in three places rather than to one.

OK, I understand. Yes, you are right, which is why it should always be a trivial call and not a chunk of Nasal script. The "switch-command" fgcommand saves having to have two bindings in each place - one for the action and one for the click but it doesn't have the flexibility of wilbragg's approach for 3D sounds.

Using *-sound.xml for each property centralizes things by triggering sounds from implicit property listeners, but it's less easy to work with and becomes very verbose.

the timer etc. wouldn’t be necessary. Or am I missing something?

I don't think the timer is strictly necessary. I think you could trigger the click sound from the click property going true->false or false->true in *-sound.xml. I think you would need two blocks of XML rather than one, whereas the timer replaces one of those.
sanhozay
 
Posts: 1207
Joined: Thu Dec 26, 2013 12:57 pm
Location: EGNM
Callsign: G-SHOZ
Version: Git
OS: Ubuntu 16.04

Re: Switch click

Postby jam007 » Thu May 18, 2017 9:02 pm

wlbragg wrote in Thu May 18, 2017 8:41 pm:I think you end up in the same place here because you still have to have something call the switch state property.

Yes but the sound handling is in one place. Should lower the risk of inconsistencies during development/maintenance. Eg. if you add another working switch to the aircraft. You add that property in the right branch of the switch property tree and you have your sound however the switch is manipulated no more manual work needed.

While that is true, I think it was more to allow for an easy way to redirect to different sounds by passing a name. I extended that to also allow for dynamic sound positioning by passing coordinates.

If there was an on-change mode in fx sound-xml most basic switch sound handling could be done with a <or> condition listing the switch position properties. Only for the kind of advanced things you do there would be need for Nasal scripts. Sadly there aren’t so therefore my nasal listener idea.
jam007
 
Posts: 579
Joined: Sun Dec 16, 2012 11:04 am
Location: Uppsala, Sweden
Callsign: LOOP
Version: 2020.4.0
OS: Ubuntu 22.04

Next

Return to Aircraft

Who is online

Users browsing this forum: No registered users and 13 guests