Closed pixelzoom closed 2 years ago
Required for Fourier, see https://github.com/phetsims/fourier-making-waves/issues/56.
@jbphet FYI, until the Slider sound API is available, I've implemented crude non-pedagogical sounds for amplitude sliders in Fourier. See AudibleSlider.js. It uses the same sounds as WaveInterferenceSlider, at the request of Fourier design team.
See https://github.com/phetsims/wave-interference/issues/523 for some question about WaveInterferenceSlider.js that might inform the Slider sound API.
A lot of sliders end up having a pedagogical need, but for the ones that don't I feel that the Waves Intro slider UI sound would work well as a default.
https://phet.colorado.edu/sims/html/waves-intro/latest/waves-intro_en.html
... I feel that the Waves Intro slider UI sound would work well as a default. ...
Indeed. From https://github.com/phetsims/fourier-making-waves/issues/54#issuecomment-820753954:
Amplitude sliders would probably not have a "harmonic" sound, probably just click, click, click (like Waves Intro).
And the current implementation of fourier-making-waves/AudibleSlider.js uses the same sounds and behavior as WaveInterferenceSlider.js (but is not a copy-paste of its implementation).
@Ashton-Morris and I discussed this in the 4/27/2021 sound design meeting, here are our initial thoughts:
Don't forget to consider the Slider track. Clicking on the track moves immediately to that value. Does that need a sound? How does that work with discrete vs continuous?
@Ashton-Morris - Can you comment on @pixelzoom's question just above? I don't think we have considered this much in previous designs. In Waves Intro there doesn't appear to be a sound at all. In Molarity, it makes a single sound for the new position, which seems quite nice. In Gravity Force Lab it activates the continuous sound for a short time (and I know this isn't coming directly from the slider, but the effect is what we're looking at).
I noticed the lack of a sound for the slider track when I was implementing sound for Fourier's amplitude sliders, and patterning it on the sliders in Waves Intro / Wave Interference - which as you noted, do not support sound for the track. It wasn't clear to me how I'd even implement sound for the default slider track on the client side. Fourier has a custom slider track, so I can do anything I want there, but that doesn't address the general issue for Slider.
For discrete sliders, at the very least I would expect to hear a click as the thumb moves to its new location.
For continuous sliders, I'm not sure.
For clicking on the track I feel that a single "middle slider sound" like the ones on the waves intro slider would be sufficient.
For continuous sounds I am not sure. My instinct is that if we had a short sample of the continuous slider sound play after clicking it would sound out of place.
Raising the priority of this issue to medium. Fourier is supposed to be feature-complete by 6/30/2021. That will likely slip a few weeks, but I would expect Fourier to be ready for dev testing in mid to late July. This issue definitely blocks dev testing.
This API will also need to be accessible via NumberControl, which has Slider as a subcomponent.
Fourier feature-complete milestone has been revised to 8/24/21. It will then go immediately into QA, for 9/30/21 publication.
What little support there is for sound in Slider doesn't seem to play nice with custom tracks. For example, see https://github.com/phetsims/fourier-making-waves/issues/179. This is probably because Slider passes options to DefaultSliderTrack, but doesn't do anything for a custom track. So... Please keep in mind that Slider needs to support custom tracks - and thumbs! And if I pass a custom thumb or track to Slider, I shouldn't have to assume responsibility for sound.
Another thing to consider, which came up in https://github.com/phetsims/fourier-making-waves/issues/197... When using keyboard navigation, sounds need to play when using Page Up/Down to go to max/min.
UI sounds will be added for Geometric Optics, see https://github.com/phetsims/geometric-optics/issues/236. That sim has 3 sliders (NumberControl) which are central to it's UI. They will not have sound until this issue is addressed.
UI sound has been added to the requirements for the first version of Geometric Optics, see https://github.com/phetsims/geometric-optics/issues/236. Some of its most important controls are sliders.
There has also been discussion about making UI sound a standard part of sim implementation. I guess that's possible without Slider sound. But it's not going to be an optimal UX, depending on how important the sliders are in the sim. And it's going to be expensive (implementation + QA) to go back and add Slider sound to sims later.
Should the priority of this issue be raised, given the interest in UI sounds?
Slider sound support came up at 11/11/21 dev meeting. @jbphet mentioned that he was adding sound to sliders in greenhouse-effect, and that may move this common-code issue forward. Let me know if you'd like me to review anything.
It will be important to make sure that adding generalized sound doesn't mess up sound in any existing simulations, or turn on something that we don't want turned on. To that end, I'm going to try to make some lists of sims and common-code components that will need to be checked as part of this effort.
I made a list of all sims with sound currently turned out by searching for supportsSound: true
in package.json
files, then searched for all sims that import any variants of Slider
directly, and then cross referenced the two using the command grep -Fxf temp.txt temp2.txt
. This provides a list of sims whose slider behavior will need to be regression tested after implementing generalized support for sound in the sliders. Note that this is not an exhaustive list of every sim that will need regression testing, since sims could have included a slider via a common-code component.
Here is a list of the components in scenery-phet that import a slider. These will also need to be tested once generalized sound has been added:
@jbphet added sound support in the above commits. @arouinfar and I have been reviewing its usage in Geometric Optics, see https://github.com/phetsims/geometric-optics/issues/259, and it's looking (and sounding!) good.
But there are some general questions that seem to belong in this issue:
Now that all sliders have sound, are we reviewing their behavior in all sims? For example, fourier-making-waves now has several Sliders that didn't previously have sound, and the sounds currently have no relation to the other behavior (e.g. delta
) of those Sliders. Should we create a "blocks-publication" issue to review the sims listed in https://github.com/phetsims/sun/issues/697#issuecomment-1049200997?
There's currently no sound with keyboard navigation. Is that something you haven't gotten to yet? Will the implementation for alt input make use of options keyboardStep
, shiftKeyboardStep
, pageKeyboardStep
? Will soundGeneratorOptions
apply to both mouse/touch and keyboard input?
About the name of ValueChangeSoundGeneratorOption.numberOfMiddleThresholds
... Is it "middle" because it's for all values except min/max? If so, you might want to clarify in the doc.
Here's some boilerplate that I see duplicated in all of the NumberControl instances of Geometric Optics. Presumably this will also need to be done for other NumberControl instances.
const numberControlDefaults: OptionizeDefaults<{}, NumberControlOptions> = merge( {}, GOConstants.NUMBER_CONTROL_OPTIONS, {
delta: GOConstants.DIAMETER_SPINNER_STEP,
sliderOptions: {
soundGeneratorOptions: {
numberOfMiddleThresholds: diameterProperty.range!.getLength() / GOConstants.DIAMETER_SLIDER_STEP - 1
}
What I see here is that numberOfMiddleThresholds
is typically a function of options.delta
and numberProperty.range
. So how about adding this default to NumberControl?
options.sliderOptions.soundGeneratorOptions.numberOfMiddleThresholds:
numberProperty.range!.getLength() / options.delta - 1
A default like this might result in fewer sims that don't need adjusting. The sims that I've looked at so far definitely need adjusting.
I've added the blocks-publication label. Now that Sliders have sound, the sims that I've spot-checked definitely need to be reviewed (and probably adjusted) before publishing. That likely includes sims in the 4/1/2022 batch for https://github.com/orgs/phetsims/projects/44.
In https://github.com/phetsims/fourier-making-waves/issues/56, I enabled Slider sound for the amplitude sliders in Fourier's Discrete screen. After setting numberOfMiddleThresholds
to match the slider interval (0.05), these sliders sound a bit like an angry bumble bee -- too much sound. So that raises a couple of design questions:
The soundGenerator
option is strange.
I expected to turn off sound by doing:
soundGenerator: null
But here's a usage in fourier-making-waves AmplitudeSlider.js
soundGenerator: ValueChangeSoundGenerator.NO_SOUND
In ValueChangeSoundGenerator.ts:
// This is used to generate sounds as the slider is moved by the user. If set to null, the default sound generator
// will be created. Set to ValueChangeSoundGenerator.NO_SOUND to disable sound generation for this slider.
soundGenerator?: ValueChangeSoundGenerator | null;
Getting a non-null default when you set an option to null
is very odd and non-intiuitive.
What I expected is:
null
, I get no sound.If it makes your implementation cleaner to use ValueChangeSoundGenerator.NO_SOUND
internally when soundGenerator: null
, that's fine.
@jbphet and I paired on this for awhile today. In the above commits, we addressed the soundGenerator
option comments that I had made in https://github.com/phetsims/sun/issues/697#issuecomment-1061074504. The new behavior is summarized in the documentation, and is the same for Slider and SliderTrack:
// This is used to generate sounds as the slider is moved by the user. If not provided, the default sound generator
// will be created. If set to null, the slider will generate no sound.
soundGenerator?: ValueChangeSoundGenerator | null;
// Options for the default sound generator. These should only be provided when using the default.
soundGeneratorOptions?: ValueChangeSoundGeneratorOptions
In recent review discussions with various designers and developers, we decided to:
NumberControl
, we should use the inputs to derive the number of middle threshold sounds so that the client doesn't have to do it, since this will be the most typical caseOnce this is done, we will review at a design meeting. @arouinfar will line up the meeting and will work with @kathy-phet to determine who should be there.
@arouinfar and @pixelzoom - In regard to item 5 above, I tried something fairly simple for the sound generator to moderate the number of "middle" sounds that are played. The change basically just prevents the sound from being played again if it was played within the last X seconds, and I'm using 0.033 seconds as the default value. I feel like this works surprisingly well. Can you please check it out in Geometric Optics and Fourier and let me know what you think? I have some other ideas, but it would be quite nice if we can make it work with something this simple.
For reference, I added some code to see how many plays of the middle sound where played versus skipped when moving the sliders quickly in these two sims, and in Geo Opts it played a little less than half the number of tick sounds on a very fast drag, and in Fourier is played around 1/3 of them.
@pixelzoom - In addition to the question above, could you also please review the commit for using the information available in NumberControl to set the sound generator thresholds? It seems to work well in Geometric Optics (thanks for the suggestion), but I'd like you to take a look since I don't know NumberControl
that well.
@jbphet CT is complaining about the sound generator thresholds, failing in several sims. For example:
fourier-making-waves : interactive-description-fuzz : unbuilt
https://bayes.colorado.edu/continuous-testing/ct-snapshots/1646964676568/fourier-making-waves/fourier-making-waves_en.html?continuousTest=%7B%22test%22%3A%5B%22fourier-making-waves%22%2C%22interactive-description-fuzz%22%2C%22unbuilt%22%5D%2C%22snapshotName%22%3A%22snapshot-1646964676568%22%2C%22timestamp%22%3A1646968422080%7D&brand=phet&ea&fuzz&supportsInteractiveDescription=true&memoryLimit=1000
Query: brand=phet&ea&fuzz&supportsInteractiveDescription=true&memoryLimit=1000
Uncaught Error: Assertion failed: not enough unique thresholds were produced - is the constraint function too constraining?
Error: Assertion failed: not enough unique thresholds were produced - is the constraint function too constraining?
at window.assertions.assertFunction (https://bayes.colorado.edu/continuous-testing/ct-snapshots/1646964676568/assert/js/assert.js:25:13)
at new ValueChangeSoundGenerator (https://bayes.colorado.edu/continuous-testing/ct-snapshots/1646964676568/chipper/dist/js/tambo/js/sound-generators/ValueChangeSoundGenerator.js:84:15)
at new Slider (https://bayes.colorado.edu/continuous-testing/ct-snapshots/1646964676568/chipper/dist/js/sun/js/Slider.js:107:32)
at new HSlider (https://bayes.colorado.edu/continuous-testing/ct-snapshots/1646964676568/chipper/dist/js/sun/js/HSlider.js:18:5)
at new NumberControl (https://bayes.colorado.edu/continuous-testing/ct-snapshots/1646964676568/chipper/dist/js/scenery-phet/js/NumberControl.js:221:19)
at new WavePacketNumberControl (https://bayes.colorado.edu/continuous-testing/ct-snapshots/1646964676568/chipper/dist/js/fourier-making-waves/js/wavepacket/view/WavePacketNumberControl.js:35:5)
at new ConjugateStandardDeviationControl (https://bayes.colorado.edu/continuous-testing/ct-snapshots/1646964676568/chipper/dist/js/fourier-making-waves/js/wavepacket/view/ConjugateStandardDeviationControl.js:67:5)
at new WavePacketWidthSubpanel (https://bayes.colorado.edu/continuous-testing/ct-snapshots/1646964676568/chipper/dist/js/fourier-making-waves/js/wavepacket/view/WavePacketControlPanel.js:271:47)
at new WavePacketControlPanel (https://bayes.colorado.edu/continuous-testing/ct-snapshots/1646964676568/chipper/dist/js/fourier-making-waves/js/wavepacket/view/WavePacketControlPanel.js:67:5)
at new WavePacketScreenView (https://bayes.colorado.edu/continuous-testing/ct-snapshots/1646964676568/chipper/dist/js/fourier-making-waves/js/wavepacket/view/WavePacketScreenView.js:154:26)
id: Bayes Chrome
Snapshot from 3/10/2022, 7:11:16 PM
The CT issue is related to constraining values, reaching & crossing thresholds, and floating point inaccuracies as related to NumberControl
. This may take me a while to get dialed in, so I've commented out the assertion for now.
@jbphet the slider sounds great! I tested in geometric-optics, fourier-making-waves, and waves-intro in master. I really like the directionality and min/max behavior. The threshold of 0.033 seconds seems reasonable to me. I still hear individual clicks when holding down an arrow key or moving the mouse slowly, but the angry bumblebee is nowhere to be found when rapidly dragging the thumb around.
The CT issue described above was due to something I hadn't anticipated. Because NumberControl
uses a delta value option to specify valid values, it is possible to create a situation where the positions where sounds should be played are not spaced evenly over the length of the slider. I thought about changing the sound generator to have the same API, i.e. use a delta value instead of a number of thresholds, but that felt unnatural and potentially error prone to me. In the end, I decided to allow either the number of thresholds or a delta value to be used to specify where along the slider's range the sounds should be played.. The NumberControl
is using the delta option for its sound generator options, all other places currently in the code base are specifying the number of thresholds.
I added an instance of NumberControl
to tambo that exhibits this asymmetry as a test case. It has some odd behavior that is unrelated to sound generation, so I'll follow up on that. The main point is that there is a demo and test case for the asymmetric case that can be easily run.
As part of the effort to get this working correctly in all the test cases, I had to expand the use of thresholding in ValueChangeSoundGenerator
. I'll revisit this in the future, since I got it working but probably should think it through a bit more.
Sliders sound great in Fourier and Geometric Optics -- no more angry bees.
https://github.com/phetsims/scenery-phet/commit/396ea26e30510c0f655c8fd9ba905cfd5739c1b8 looks good. But Slider has option constrainValue
(singular), and you've added soundGeneratorOptions.constrainValues
(plural). That's going to result in programming errors. Any reason why they can't have the same name?
Related to soundGeneratorOptions.constrainValues
.... SoundGeneratorOptions has no such option. It took me some poking around to determine that soundGeneratorOptions
is actually of type ValueChangeSoundGeneratorOptions | null
. The names of nested options should generally match the fully name of the type that their associated type. So please rename soundGeneratorOptions
to valueSoundGeneratorOptions
-- in Slider.ts, NumberControl.ts, and elsewhere if relevant.
Both of @pixelzoom's suggestions in the comment above sounded good to me, so I've implemented them.
The behavior of this feature as it currently stands was reviewed in a design meeting yesterday, 3/17/2022. For the most part, the design team was good with it. There were two questions that came up, and it was recommended that I discuss these with @terracoda. They are:
I'll set up a discussion and note the outcome.
@terracoda and I just met over Zoom, and her opinion is that it is not necessary to have unique sounds for the arrow versus shift-arrow keys, nor does there need to be a difference for discrete versus continuous movement. We both felt like if there were cases where the amount of motion mattered, we'd use the pitch-mapping capability to vary the sound that was produced.
She did suggest that I run it by @emily-phet, so I'll do that in the next sound design meeting, which will be Tuesday 3/22/2022.
This is now in a state where I believe it's ready for code review. @pixelzoom said he'd do it (thanks!), so I'll add the appropriate label and assign to him.
My general approach for this was to create a sound generator that had methods that could be used to evaluate changes to a value and decide which if any sounds to play, then pass this sound generator into Slider, and have slider hook it up in the appropriate places so that sounds are produced on user-initiated changes to the value. The sound generator does not monitor an axon Property
, because it's often difficult to discern when changes to the property value were triggered by some direct user action (such as moving the slider) versus some indirect user action (such as pressing the reset button). So, with that for background, the review should probably focus on:
ValueChangeSoundGenerator.ts
, which is new and was created as a part of this effortSlider.ts
, mostly in the options and drag handlerSliderSoundTestNode.ts
, and it would be good to look at the demo too and see if it seems like it covers most of the important basesI reviewed everything that @jbphet mentioned in https://github.com/phetsims/sun/issues/697#issuecomment-1072811918, and took a peek at NumberControl.ts too. Useful (and fun) tests in SliderSoundTestNode.ts. Everything looks really nice, very clean, excellent documentation. Thanks for doing this.
Closing!
In one of the comments above, I said:
[@terracoda] did suggest that I run it by @emily-phet, so I'll do that in the next sound design meeting[.]
I wanted to close the loop on this, so we discussed it in today's sound design meeting, and @emily-phet is fine with all the movement sounds being the same with no special sounds for arrow keys or discrete versus continuous.
Reopening. A question arose in my mind about whether the sounds produced by a slider would stop being produced if the output level for the "user-interface" category was set to zero. My hope was that it would, but I couldn't recall specifically implementing code to do so. I tested it, and it worked, but when I dug into it, I realized that it wasn't working for the right reasons. It works because ValueChangeSoundGenerator
is using SoundClipPlayer
instances for its sounds, and the instances that it is using are all individually set up to be in the "user-interface" category. However, ValueChangeSoundGenerator
extends SoundGenerator
, so in principle, it should be added to the soundManager
and connected to the audio path, but it's not. This seems messed up.
So, at this juncture, this feature works correctly, but will likely be confusing to future users of ValueChangeSoundGenerator
and even more confusing to anyone who needs to maintain it. I should either make it explicit that ValueChangedSoundGenerator
is not a sound generator itself, and is instead a container for a bunch of SoundClipPlayer
instances (and should change its name), or I should make it into a real sound generator. My inclination is for the latter, but I'd like to think on it for a bit. Using SoundClipPlayer
instances reduces the memory resources that are used and keeps everything at consistent output levels, but I don't think the resource difference is very large versus using plain SoundClip
s, and it would be easier for people to follow if separate sound clips were used. Plus, it would be easier to set different output levels for different instances of ValueChangedSoundGenerator
, which may well be something that we want to do, and wouldn't work at all with the current implementation.
I've addressed the concern that I raised in the previous comment by changing ValueChangedSoundGenerator
to ValueChangedSoundPlayer
and make it not be a sound generator. I opted for this approach because if it was a sound generator, the client would have to pass in sound generators with connect
methods, and not hook them up to anything, and wouldn't be able to use the shared sound players. This seemed worse.
I think this is done (again), closing.
From https://github.com/phetsims/fourier-making-waves/issues/54#issuecomment-825159430: