phetsims / center-and-variability

"Center and Variability" is an educational simulation in HTML5, by PhET Interactive Simulations.
GNU General Public License v3.0
1 stars 2 forks source link

Play mean or median sound on soccer ball landing/movement (if corresponding play area checkbox is checked) #300

Closed samreid closed 1 year ago

samreid commented 1 year ago

EM: Idea - when the median checkbox is checked, the median sound plays only rather than the position of the ball

Concerns: The sound the ball lands on the number line is no longer connected to the balls Future screens might be confusing Will it be confusing with the connection between the number line position of the balls and the checkboxes being checked

SR: mocked it up and it sounds nice, there’s a question about whether the mean/median is conflated if both checkboxes are checked or on future screens

Ideas If median checkbox is checked, the median position sound plays If mean checkbox is checked, the mean position sound plays If both or neither is checked, we hear the sounds of the balls landing in their positions on the number line On Variability screen, could play the sound of the size of the spread measure when checkbox is selected in the accordion box

MB: How could we indicate this to the user? EM: Think of these holistically and not given a particular indicator, so it might be ok. Sound users are used to exploring. People tend to attend to where their focus is in the sim (e.g., visually). If someone checks the box, their focus is there, and if not, they’ll proceed with exploration. Could be an interview question where the user is expressing confusion with the sounds changing with the checkboxes being toggled on/off.

samreid commented 1 year ago

Patch from investigation:

```diff Subject: [PATCH] Update kicker 1-4 distributions, see https://github.com/phetsims/center-and-variability/issues/246 --- Index: js/soccer-common/model/NumberTone.ts IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/js/soccer-common/model/NumberTone.ts b/js/soccer-common/model/NumberTone.ts --- a/js/soccer-common/model/NumberTone.ts (revision 1abe9e6ce8f110b1d383dcab4d9eb9fb05c03a33) +++ b/js/soccer-common/model/NumberTone.ts (date 1687373158709) @@ -12,6 +12,7 @@ import soccerCommon from '../soccerCommon.js'; import phetAudioContext from '../../../../tambo/js/phetAudioContext.js'; import Utils from '../../../../dot/js/Utils.js'; +import CAVConstants from '../../common/CAVConstants.js'; // This is the dominant frequency of numberTone2_mp3. If the audio file is changed, this will need to be updated. const E3 = 164.81; // Hz @@ -58,41 +59,41 @@ export const toStepDiscrete = ( value: number ): number => { assert && assert( value >= 1 && value <= 18, `value ${value} is out of range` ); const step = value === 1 ? 0 : // C - value === 1.5 ? 1 : // C# - value === 2 ? 2 : // D - value === 2.5 ? 3 : // D# - value === 3 ? 4 : // E - value === 3.5 ? 4.5 : // FAKE - value === 4 ? 5 : // F - value === 4.5 ? 6 : // F# - value === 5 ? 7 : // G - value === 5.5 ? 8 : // G# - value === 6 ? 9 : // A - value === 6.5 ? 10 : // A# - value === 7 ? 11 : // B - value === 7.5 ? 11.5 : // FAKE - value === 8 ? 12 : // C - value === 8.5 ? 13 : // C# - value === 9 ? 14 : // D - value === 9.5 ? 15 : // D# - value === 10 ? 16 : // E - value === 10.5 ? 16.5 : // FAKE - value === 11 ? 17 : // F - value === 11.5 ? 18 : // F# - value === 12 ? 19 : // G - value === 12.5 ? 20 : // G# - value === 13 ? 21 : // A - value === 13.5 ? 22 : // A# - value === 14 ? 23 : // B - value === 14.5 ? 23.5 : // B - value === 15 ? 24 : // C - value === 15.5 ? 25 : // C# - value === 16 ? 26 : // D - value === 16.5 ? 27 : // D# - value === 17 ? 28 : // E - value === 17.5 ? 28.5 : // E - value === 18 ? 29 : // F - -1; + value === 1.5 ? 1 : // C# + value === 2 ? 2 : // D + value === 2.5 ? 3 : // D# + value === 3 ? 4 : // E + value === 3.5 ? 4.5 : // FAKE + value === 4 ? 5 : // F + value === 4.5 ? 6 : // F# + value === 5 ? 7 : // G + value === 5.5 ? 8 : // G# + value === 6 ? 9 : // A + value === 6.5 ? 10 : // A# + value === 7 ? 11 : // B + value === 7.5 ? 11.5 : // FAKE + value === 8 ? 12 : // C + value === 8.5 ? 13 : // C# + value === 9 ? 14 : // D + value === 9.5 ? 15 : // D# + value === 10 ? 16 : // E + value === 10.5 ? 16.5 : // FAKE + value === 11 ? 17 : // F + value === 11.5 ? 18 : // F# + value === 12 ? 19 : // G + value === 12.5 ? 20 : // G# + value === 13 ? 21 : // A + value === 13.5 ? 22 : // A# + value === 14 ? 23 : // B + value === 14.5 ? 23.5 : // B + value === 15 ? 24 : // C + value === 15.5 ? 25 : // C# + value === 16 ? 26 : // D + value === 16.5 ? 27 : // D# + value === 17 ? 28 : // E + value === 17.5 ? 28.5 : // E + value === 18 ? 29 : // F + -1; assert && assert( step >= 0, 'step must be greater than or equal to 0' ); return step; }; @@ -129,6 +130,17 @@ public static playMedian( value: number ): void { const playbackSpeed = toPlaybackRate( value ); + // set the frequency of the band pass filter to be equal to the frequency of the adjusted sound + const frequency = E3 * playbackSpeed; + medianFilter.frequency.setTargetAtTime( frequency, phetAudioContext.currentTime, 0 ); + + medianSoundClip.setPlaybackRate( playbackSpeed ); + medianSoundClip.play(); + } + + public static playMedianGlobal(): void { + const playbackSpeed = toPlaybackRate( window.sceneModel.meanValueProperty.value! ); + // set the frequency of the band pass filter to be equal to the frequency of the adjusted sound const frequency = E3 * playbackSpeed; medianFilter.frequency.setTargetAtTime( frequency, phetAudioContext.currentTime, 0 ); Index: js/median/view/CardNode.ts IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/js/median/view/CardNode.ts b/js/median/view/CardNode.ts --- a/js/median/view/CardNode.ts (revision 1abe9e6ce8f110b1d383dcab4d9eb9fb05c03a33) +++ b/js/median/view/CardNode.ts (date 1687373043714) @@ -168,7 +168,7 @@ // Moving to the right, go up in pitch by 4 semitones randomSound.setPlaybackRate( destination.x < this.positionProperty.value.x ? 1 : Math.pow( 2, 4 / 12 ) ); - randomSound.play(); + // randomSound.play(); } this.animation.start(); Index: js/soccer-common/model/SoccerBall.ts IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/js/soccer-common/model/SoccerBall.ts b/js/soccer-common/model/SoccerBall.ts --- a/js/soccer-common/model/SoccerBall.ts (revision 1abe9e6ce8f110b1d383dcab4d9eb9fb05c03a33) +++ b/js/soccer-common/model/SoccerBall.ts (date 1687372732316) @@ -128,7 +128,7 @@ if ( landed ) { this.soccerBallLandedEmitter.emit( this ); - NumberTone.play( x ); + NumberTone.playMedianGlobal(); } } } Index: js/soccer-common/model/SoccerSceneModel.ts IDEA additional info: Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP <+>UTF-8 =================================================================== diff --git a/js/soccer-common/model/SoccerSceneModel.ts b/js/soccer-common/model/SoccerSceneModel.ts --- a/js/soccer-common/model/SoccerSceneModel.ts (revision 1abe9e6ce8f110b1d383dcab4d9eb9fb05c03a33) +++ b/js/soccer-common/model/SoccerSceneModel.ts (date 1687372818410) @@ -116,6 +116,8 @@ providedOptions: SoccerSceneModelOptions ) { + + // TODO: should we move styles like this into studio? See https://github.com/phetsims/center-and-variability/issues/117 const pre = '
';
     const code = '';
@@ -132,6 +134,8 @@

     super( options );

+    window.sceneModel = this;
+
     const updateDataMeasures = () => this.updateDataMeasures();

     this.maxKicksLimit = Math.max( ...maxKicksChoices );
Index: js/median/view/CardNodeContainer.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/median/view/CardNodeContainer.ts b/js/median/view/CardNodeContainer.ts
--- a/js/median/view/CardNodeContainer.ts   (revision 1abe9e6ce8f110b1d383dcab4d9eb9fb05c03a33)
+++ b/js/median/view/CardNodeContainer.ts   (date 1687372986518)
@@ -455,7 +455,7 @@

           // Moving to the right, go up in pitch by 4 semitones
           randomSound.setPlaybackRate( dragCell < originalCell ? 1 : Math.pow( 2, 4 / 12 ) );
-          randomSound.play();
+          // randomSound.play();
         }
       }
     };
Index: js/soccer-common/view/SoccerBallNode.ts
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/js/soccer-common/view/SoccerBallNode.ts b/js/soccer-common/view/SoccerBallNode.ts
--- a/js/soccer-common/view/SoccerBallNode.ts   (revision 1abe9e6ce8f110b1d383dcab4d9eb9fb05c03a33)
+++ b/js/soccer-common/view/SoccerBallNode.ts   (date 1687372732313)
@@ -123,7 +123,7 @@
     // When the user drags a soccer ball, play audio corresponding to its new position.
     soccerBall.valueProperty.link( value => {
       if ( value !== null && ( isDragging || isSliderDragging ) ) {
-        NumberTone.play( value );
+        NumberTone.playMedianGlobal(  );
       }
     } );            
samreid commented 1 year ago

Implemented and would be good to get design review from @catherinecarter. If it needs changes, please reassign to me. If it seems good please reassign to @matthew-blackman and @marlitas for code review.

catherinecarter commented 1 year ago

Working as intended. Will look for confusion in interviews about whether this interaction makes sense.

catherinecarter commented 1 year ago

Reopening for code review.

marlitas commented 1 year ago

Code changes look good an it sounds great. Love the change! Closing.