pxt-common-packages 10.1.7 → 10.1.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (33) hide show
  1. package/built/common-sim.js +1 -1
  2. package/libs/azureiot/built/debug/binary.js +461 -461
  3. package/libs/color/built/debug/binary.js +8 -8
  4. package/libs/color-sensor/built/debug/binary.js +8 -8
  5. package/libs/controller/built/debug/binary.js +6906 -6906
  6. package/libs/controller---none/built/debug/binary.js +6886 -6886
  7. package/libs/datalogger/built/debug/binary.js +63 -63
  8. package/libs/edge-connector/built/debug/binary.js +8 -8
  9. package/libs/esp32/built/debug/binary.js +462 -462
  10. package/libs/game/built/debug/binary.js +6825 -6825
  11. package/libs/lcd/built/debug/binary.js +8 -8
  12. package/libs/light-spectrum-sensor/built/debug/binary.js +8 -8
  13. package/libs/lora/built/debug/binary.js +8 -8
  14. package/libs/matrix-keypad/built/debug/binary.js +8 -8
  15. package/libs/mixer/melody.ts +2 -2
  16. package/libs/mixer/pxt.json +1 -0
  17. package/libs/mixer/sim/music.ts +1 -1
  18. package/libs/mixer/soundEffect.ts +380 -0
  19. package/libs/mqtt/built/debug/binary.js +176 -176
  20. package/libs/net/built/debug/binary.js +176 -176
  21. package/libs/net-game/built/debug/binary.js +8414 -8414
  22. package/libs/palette/built/debug/binary.js +6824 -6824
  23. package/libs/pixel/built/debug/binary.js +8 -8
  24. package/libs/power/built/debug/binary.js +8 -8
  25. package/libs/proximity/built/debug/binary.js +8 -8
  26. package/libs/radio/built/debug/binary.js +8 -8
  27. package/libs/radio-broadcast/built/debug/binary.js +8 -8
  28. package/libs/rotary-encoder/built/debug/binary.js +8 -8
  29. package/libs/screen/built/debug/binary.js +50 -50
  30. package/libs/servo/built/debug/binary.js +8 -8
  31. package/libs/sprite-scaling/built/debug/binary.js +6824 -6824
  32. package/libs/storyboard/built/debug/binary.js +6824 -6824
  33. package/package.json +2 -2
@@ -56,7 +56,7 @@ const pxsim_pxtrt = pxsim.pxtrt;
56
56
  const pxsim_numops = pxsim.numops;
57
57
 
58
58
 
59
- function _main___P48221(s) {
59
+ function _main___P48261(s) {
60
60
  let r0 = s.r0, step = s.pc;
61
61
  s.pc = -1;
62
62
 
@@ -66,19 +66,19 @@ if (yieldSteps-- < 0 && maybeYield(s, step, r0) || runtime !== pxsim.runtime) re
66
66
  switch (step) {
67
67
  case 0:
68
68
 
69
- globals._intervals___48464 = (undefined);
70
- globals._pollEventQueue___48477 = (undefined);
69
+ globals._intervals___48504 = (undefined);
70
+ globals._pollEventQueue___48517 = (undefined);
71
71
  r0 = undefined;
72
72
  return leave(s, r0)
73
73
  default: oops()
74
74
  } } }
75
- _main___P48221.info = {"start":0,"length":0,"line":0,"column":0,"endLine":0,"endColumn":0,"fileName":"characterlcd.ts","functionName":"<main>","argumentNames":[]}
76
- _main___P48221.continuations = [ ]
75
+ _main___P48261.info = {"start":0,"length":0,"line":0,"column":0,"endLine":0,"endColumn":0,"fileName":"characterlcd.ts","functionName":"<main>","argumentNames":[]}
76
+ _main___P48261.continuations = [ ]
77
77
 
78
- function _main___P48221_mk(s) {
78
+ function _main___P48261_mk(s) {
79
79
  checkStack(s.depth);
80
80
  return {
81
- parent: s, fn: _main___P48221, depth: s.depth + 1,
81
+ parent: s, fn: _main___P48261, depth: s.depth + 1,
82
82
  pc: 0, retval: undefined, r0: undefined, overwrittenPC: false, lambdaArgs: null,
83
83
  } }
84
84
 
@@ -88,5 +88,5 @@ function _main___P48221_mk(s) {
88
88
 
89
89
  const breakpoints = setupDebugger(1, [])
90
90
 
91
- return _main___P48221
91
+ return _main___P48261
92
92
  })
@@ -56,7 +56,7 @@ const pxsim_pxtrt = pxsim.pxtrt;
56
56
  const pxsim_numops = pxsim.numops;
57
57
 
58
58
 
59
- function _main___P96995(s) {
59
+ function _main___P97115(s) {
60
60
  let r0 = s.r0, step = s.pc;
61
61
  s.pc = -1;
62
62
 
@@ -66,19 +66,19 @@ if (yieldSteps-- < 0 && maybeYield(s, step, r0) || runtime !== pxsim.runtime) re
66
66
  switch (step) {
67
67
  case 0:
68
68
 
69
- globals._intervals___97238 = (undefined);
70
- globals._pollEventQueue___97251 = (undefined);
69
+ globals._intervals___97358 = (undefined);
70
+ globals._pollEventQueue___97371 = (undefined);
71
71
  r0 = undefined;
72
72
  return leave(s, r0)
73
73
  default: oops()
74
74
  } } }
75
- _main___P96995.info = {"start":0,"length":0,"line":0,"column":0,"endLine":0,"endColumn":0,"fileName":"tsl2591.ts","functionName":"<main>","argumentNames":[]}
76
- _main___P96995.continuations = [ ]
75
+ _main___P97115.info = {"start":0,"length":0,"line":0,"column":0,"endLine":0,"endColumn":0,"fileName":"tsl2591.ts","functionName":"<main>","argumentNames":[]}
76
+ _main___P97115.continuations = [ ]
77
77
 
78
- function _main___P96995_mk(s) {
78
+ function _main___P97115_mk(s) {
79
79
  checkStack(s.depth);
80
80
  return {
81
- parent: s, fn: _main___P96995, depth: s.depth + 1,
81
+ parent: s, fn: _main___P97115, depth: s.depth + 1,
82
82
  pc: 0, retval: undefined, r0: undefined, overwrittenPC: false, lambdaArgs: null,
83
83
  } }
84
84
 
@@ -88,5 +88,5 @@ function _main___P96995_mk(s) {
88
88
 
89
89
  const breakpoints = setupDebugger(1, [])
90
90
 
91
- return _main___P96995
91
+ return _main___P97115
92
92
  })
@@ -56,7 +56,7 @@ const pxsim_pxtrt = pxsim.pxtrt;
56
56
  const pxsim_numops = pxsim.numops;
57
57
 
58
58
 
59
- function _main___P59523(s) {
59
+ function _main___P59563(s) {
60
60
  let r0 = s.r0, step = s.pc;
61
61
  s.pc = -1;
62
62
 
@@ -66,19 +66,19 @@ if (yieldSteps-- < 0 && maybeYield(s, step, r0) || runtime !== pxsim.runtime) re
66
66
  switch (step) {
67
67
  case 0:
68
68
 
69
- globals._intervals___59766 = (undefined);
70
- globals._pollEventQueue___59779 = (undefined);
69
+ globals._intervals___59806 = (undefined);
70
+ globals._pollEventQueue___59819 = (undefined);
71
71
  r0 = undefined;
72
72
  return leave(s, r0)
73
73
  default: oops()
74
74
  } } }
75
- _main___P59523.info = {"start":0,"length":0,"line":0,"column":0,"endLine":0,"endColumn":0,"fileName":"lora.ts","functionName":"<main>","argumentNames":[]}
76
- _main___P59523.continuations = [ ]
75
+ _main___P59563.info = {"start":0,"length":0,"line":0,"column":0,"endLine":0,"endColumn":0,"fileName":"lora.ts","functionName":"<main>","argumentNames":[]}
76
+ _main___P59563.continuations = [ ]
77
77
 
78
- function _main___P59523_mk(s) {
78
+ function _main___P59563_mk(s) {
79
79
  checkStack(s.depth);
80
80
  return {
81
- parent: s, fn: _main___P59523, depth: s.depth + 1,
81
+ parent: s, fn: _main___P59563, depth: s.depth + 1,
82
82
  pc: 0, retval: undefined, r0: undefined, overwrittenPC: false, lambdaArgs: null,
83
83
  } }
84
84
 
@@ -88,5 +88,5 @@ function _main___P59523_mk(s) {
88
88
 
89
89
  const breakpoints = setupDebugger(1, [])
90
90
 
91
- return _main___P59523
91
+ return _main___P59563
92
92
  })
@@ -56,7 +56,7 @@ const pxsim_pxtrt = pxsim.pxtrt;
56
56
  const pxsim_numops = pxsim.numops;
57
57
 
58
58
 
59
- function _main___P188067(s) {
59
+ function _main___P188347(s) {
60
60
  let r0 = s.r0, step = s.pc;
61
61
  s.pc = -1;
62
62
 
@@ -66,19 +66,19 @@ if (yieldSteps-- < 0 && maybeYield(s, step, r0) || runtime !== pxsim.runtime) re
66
66
  switch (step) {
67
67
  case 0:
68
68
 
69
- globals._intervals___188310 = (undefined);
70
- globals._pollEventQueue___188323 = (undefined);
69
+ globals._intervals___188590 = (undefined);
70
+ globals._pollEventQueue___188603 = (undefined);
71
71
  r0 = undefined;
72
72
  return leave(s, r0)
73
73
  default: oops()
74
74
  } } }
75
- _main___P188067.info = {"start":0,"length":0,"line":0,"column":0,"endLine":0,"endColumn":0,"fileName":"keypad.ts","functionName":"<main>","argumentNames":[]}
76
- _main___P188067.continuations = [ ]
75
+ _main___P188347.info = {"start":0,"length":0,"line":0,"column":0,"endLine":0,"endColumn":0,"fileName":"keypad.ts","functionName":"<main>","argumentNames":[]}
76
+ _main___P188347.continuations = [ ]
77
77
 
78
- function _main___P188067_mk(s) {
78
+ function _main___P188347_mk(s) {
79
79
  checkStack(s.depth);
80
80
  return {
81
- parent: s, fn: _main___P188067, depth: s.depth + 1,
81
+ parent: s, fn: _main___P188347, depth: s.depth + 1,
82
82
  pc: 0, retval: undefined, r0: undefined, overwrittenPC: false, lambdaArgs: null,
83
83
  } }
84
84
 
@@ -88,5 +88,5 @@ function _main___P188067_mk(s) {
88
88
 
89
89
  const breakpoints = setupDebugger(1, [])
90
90
 
91
- return _main___P188067
91
+ return _main___P188347
92
92
  })
@@ -112,7 +112,7 @@ namespace music {
112
112
 
113
113
  /**
114
114
  * Play a melody from the melody editor.
115
- * @param melody - string of up to eight notes [C D E F G A B C5] or rests [-] separated by spaces,
115
+ * @param melody - string of up to eight notes [C D E F G A B C5] or rests [-] separated by spaces,
116
116
  * which will be played one at a time, ex: "E D G F B A C5 B "
117
117
  * @param tempo - number in beats per minute (bpm), dictating how long each note will play for
118
118
  */
@@ -176,7 +176,7 @@ namespace music {
176
176
  */
177
177
  //% help=music/stop-all-sounds
178
178
  //% blockId=music_stop_all_sounds block="stop all sounds"
179
- //% weight=10
179
+ //% weight=45
180
180
  //% group="Sounds"
181
181
  export function stopAllSounds() {
182
182
  Melody.stopAll();
@@ -13,6 +13,7 @@
13
13
  "ns.ts",
14
14
  "targetoverrides.ts",
15
15
  "music.ts",
16
+ "soundEffect.ts",
16
17
  "pxtparts.json",
17
18
  "headphone.svg"
18
19
  ],
@@ -1,6 +1,6 @@
1
1
  namespace pxsim.music {
2
2
  export function playInstructions(b: RefBuffer) {
3
- return AudioContextManager.playInstructionsAsync(b)
3
+ return AudioContextManager.playInstructionsAsync(b.data)
4
4
  }
5
5
 
6
6
  export function queuePlayInstructions(when: number, b: RefBuffer) {
@@ -0,0 +1,380 @@
1
+ enum WaveShape {
2
+ //% block="sine"
3
+ Sine = 0,
4
+ //% block="sawtooth"
5
+ Sawtooth = 1,
6
+ //% block="triangle"
7
+ Triangle = 2,
8
+ //% block="square"
9
+ Square = 3,
10
+ //% block="noise"
11
+ Noise = 4
12
+ }
13
+
14
+ enum InterpolationCurve {
15
+ //% block="linear"
16
+ Linear,
17
+ //% block="curve"
18
+ Curve,
19
+ //% block="logarithmic"
20
+ Logarithmic
21
+ }
22
+
23
+ enum SoundExpressionEffect {
24
+ //% block="none"
25
+ None = 0,
26
+ //% block="vibrato"
27
+ Vibrato = 1,
28
+ //% block="tremolo"
29
+ Tremolo = 2,
30
+ //% block="warble"
31
+ Warble = 3
32
+ }
33
+
34
+ enum SoundExpressionPlayMode {
35
+ //% block="until done"
36
+ UntilDone,
37
+ //% block="in background"
38
+ InBackground
39
+ }
40
+
41
+ namespace music {
42
+ export class SoundEffect {
43
+ waveShape: WaveShape;
44
+ startFrequency: number;
45
+ endFrequency: number;
46
+ startVolume: number;
47
+ endVolume: number;
48
+ duration: number;
49
+ effect: SoundExpressionEffect;
50
+ interpolation: InterpolationCurve;
51
+
52
+ constructor() {
53
+ this.waveShape = WaveShape.Sine;
54
+ this.startFrequency = 5000;
55
+ this.endFrequency = 1;
56
+ this.startVolume = 255;
57
+ this.endVolume = 0;
58
+ this.duration = 1000;
59
+ this.effect = SoundExpressionEffect.None;
60
+ this.interpolation = InterpolationCurve.Linear;
61
+ }
62
+
63
+ toBuffer(volume?: number) {
64
+ if (volume === undefined) volume = music.volume();
65
+
66
+ return soundToInstructionBuffer(
67
+ this.waveShape,
68
+ this.startFrequency,
69
+ this.endFrequency,
70
+ this.startVolume,
71
+ this.endVolume,
72
+ this.duration,
73
+ this.effect,
74
+ this.interpolation,
75
+ 20,
76
+ 1,
77
+ volume
78
+ );
79
+ }
80
+ }
81
+
82
+
83
+ /**
84
+ * Play a SoundEffect.
85
+ * @param sound the SoundEffect to play
86
+ * @param mode the play mode, play until done or in the background
87
+ */
88
+ //% blockId=soundExpression_playSoundEffect
89
+ //% block="play sound $sound $mode"
90
+ //% sound.shadow=soundExpression_createSoundEffect
91
+ //% weight=30
92
+ //% help=music/play-sound-effect
93
+ //% blockGap=8
94
+ //% group="Sounds"
95
+ export function playSoundEffect(sound: SoundEffect, mode: SoundExpressionPlayMode) {
96
+ const toPlay = sound.toBuffer(music.volume());
97
+
98
+ queuePlayInstructions(0, toPlay);
99
+ if (mode === SoundExpressionPlayMode.UntilDone) {
100
+ pause(sound.duration);
101
+ }
102
+ }
103
+
104
+ /**
105
+ * Create a sound expression from a set of sound effect parameters.
106
+ * @param waveShape waveform of the sound effect
107
+ * @param startFrequency starting frequency for the sound effect waveform
108
+ * @param endFrequency ending frequency for the sound effect waveform
109
+ * @param startVolume starting volume of the sound, or starting amplitude
110
+ * @param endVolume ending volume of the sound, or ending amplitude
111
+ * @param duration the amount of time in milliseconds (ms) that sound will play for
112
+ * @param effect the effect to apply to the waveform or volume
113
+ * @param interpolation interpolation method for frequency scaling
114
+ */
115
+ //% blockId=soundExpression_createSoundEffect
116
+ //% help=music/create-sound-effect
117
+ //% block="$waveShape|| start frequency $startFrequency end frequency $endFrequency duration $duration start volume $startVolume end volume $endVolume effect $effect interpolation $interpolation"
118
+ //% waveShape.defl=WaveShape.Sine
119
+ //% waveShape.fieldEditor=soundeffect
120
+ //% waveShape.fieldOptions.useMixerSynthesizer=true
121
+ //% startFrequency.defl=5000
122
+ //% startFrequency.min=0
123
+ //% startFrequency.max=5000
124
+ //% endFrequency.defl=0
125
+ //% endFrequency.min=0
126
+ //% endFrequency.max=5000
127
+ //% startVolume.defl=255
128
+ //% startVolume.min=0
129
+ //% startVolume.max=255
130
+ //% endVolume.defl=0
131
+ //% endVolume.min=0
132
+ //% endVolume.max=255
133
+ //% duration.defl=500
134
+ //% duration.min=1
135
+ //% duration.max=9999
136
+ //% effect.defl=SoundExpressionEffect.None
137
+ //% interpolation.defl=InterpolationCurve.Linear
138
+ //% compileHiddenArguments=true
139
+ //% inlineInputMode="variable"
140
+ //% inlineInputModeLimit=3
141
+ //% expandableArgumentBreaks="3,5"
142
+ //% weight=20
143
+ //% group="Sounds"
144
+ export function createSoundEffect(waveShape: WaveShape, startFrequency: number, endFrequency: number, startVolume: number, endVolume: number, duration: number, effect: SoundExpressionEffect, interpolation: InterpolationCurve): SoundEffect {
145
+ const result = new SoundEffect();
146
+
147
+ result.waveShape = waveShape;
148
+ result.startFrequency = startFrequency;
149
+ result.endFrequency = endFrequency;
150
+ result.startVolume = startVolume;
151
+ result.endVolume = endVolume;
152
+ result.duration = duration;
153
+ result.effect = effect;
154
+ result.interpolation = interpolation;
155
+
156
+ return result;
157
+ }
158
+
159
+ interface Step {
160
+ frequency: number;
161
+ volume: number;
162
+ }
163
+
164
+ export function soundToInstructionBuffer(waveShape: WaveShape, startFrequency: number, endFrequency: number, startVolume: number, endVolume: number, duration: number, effect: SoundExpressionEffect, interpolation: InterpolationCurve, fxSteps: number, fxRange: number, globalVolume: number) {
165
+ const steps: Step[] = [];
166
+
167
+ // Optimize the simple case
168
+ if (interpolation === InterpolationCurve.Linear && effect === SoundExpressionEffect.None) {
169
+ steps.push({
170
+ frequency: startFrequency,
171
+ volume: (startVolume / 255) * globalVolume,
172
+ })
173
+ steps.push({
174
+ frequency: endFrequency,
175
+ volume: (endVolume / 255) * globalVolume,
176
+ })
177
+ }
178
+ else {
179
+
180
+ fxSteps = Math.min(fxSteps, Math.floor(duration / 5))
181
+
182
+ const getVolumeAt = (t: number) => ((startVolume + t * (endVolume - startVolume) / duration) / 255) * globalVolume;
183
+ let getFrequencyAt: (t: number) => number;
184
+
185
+ switch (interpolation) {
186
+ case InterpolationCurve.Linear:
187
+ getFrequencyAt = t => startFrequency + t * (endFrequency - startFrequency) / duration;
188
+ break;
189
+ case InterpolationCurve.Curve:
190
+ getFrequencyAt = t => startFrequency + (endFrequency - startFrequency) * Math.sin(t / duration * (Math.PI / 2));
191
+ break;
192
+ case InterpolationCurve.Logarithmic:
193
+ getFrequencyAt = t => startFrequency + (Math.log(1 + 9 * (t / duration)) / Math.log(10)) * (endFrequency - startFrequency)
194
+ break;
195
+ }
196
+
197
+ const timeSlice = duration / fxSteps;
198
+
199
+ for (let i = 0; i < fxSteps; i++) {
200
+ const newStep = {
201
+ frequency: getFrequencyAt(i * timeSlice),
202
+ volume: getVolumeAt(i * timeSlice)
203
+ };
204
+
205
+ if (effect === SoundExpressionEffect.Tremolo) {
206
+ if (i % 2 === 0) {
207
+ newStep.volume = Math.max(newStep.volume - fxRange * 500, 0)
208
+ }
209
+ else {
210
+ newStep.volume = Math.min(newStep.volume + fxRange * 500, 1023)
211
+ }
212
+ }
213
+ else if (effect === SoundExpressionEffect.Vibrato) {
214
+ if (i % 2 === 0) {
215
+ newStep.frequency = Math.max(newStep.frequency - fxRange * 100, 0)
216
+ }
217
+ else {
218
+ newStep.frequency = newStep.frequency + fxRange * 100
219
+ }
220
+ }
221
+ else if (effect === SoundExpressionEffect.Warble) {
222
+ if (i % 2 === 0) {
223
+ newStep.frequency = Math.max(newStep.frequency - fxRange * 1000, 0)
224
+ }
225
+ else {
226
+ newStep.frequency = newStep.frequency + fxRange * 1000
227
+ }
228
+ }
229
+
230
+ steps.push(newStep)
231
+ }
232
+ }
233
+
234
+ const out = control.createBuffer(12 * (steps.length - 1));
235
+ const stepDuration = Math.floor(duration / (steps.length - 1))
236
+
237
+ for (let i = 0; i < steps.length - 1; i++) {
238
+ const offset = i * 12;
239
+ out.setNumber(NumberFormat.UInt8LE, offset, waveToValue(waveShape));
240
+ out.setNumber(NumberFormat.UInt16LE, offset + 2, steps[i].frequency);
241
+ out.setNumber(NumberFormat.UInt16LE, offset + 4, stepDuration);
242
+ out.setNumber(NumberFormat.UInt16LE, offset + 6, steps[i].volume);
243
+ out.setNumber(NumberFormat.UInt16LE, offset + 8, steps[i + 1].volume);
244
+ out.setNumber(NumberFormat.UInt16LE, offset + 10, steps[i + 1].frequency);
245
+ }
246
+
247
+ return out;
248
+ }
249
+
250
+ function waveToValue(wave: WaveShape) {
251
+ switch (wave) {
252
+ case WaveShape.Square: return 15;
253
+ case WaveShape.Sine: return 3;
254
+ case WaveShape.Triangle: return 1;
255
+ case WaveShape.Noise: return 18;
256
+ case WaveShape.Sawtooth: return 2;
257
+ }
258
+ }
259
+
260
+
261
+ /**
262
+ * Generate a random similar sound effect to the given one.
263
+ *
264
+ * @param sound the sound effect
265
+ */
266
+ //% blockId=soundExpression_generateSimilarSound
267
+ //% block="randomize $sound"
268
+ //% sound.shadow=soundExpression_createSoundEffect
269
+ //% weight=0 help=music/generate-similar-sound
270
+ //% blockGap=8
271
+ //% group="Sounds"
272
+ export function randomizeSound(sound: SoundEffect) {
273
+ const res = new SoundEffect();
274
+ res.waveShape = sound.waveShape;
275
+ res.startFrequency = sound.startFrequency;
276
+ res.endFrequency = sound.endFrequency;
277
+ res.startVolume = sound.startVolume;
278
+ res.endVolume = sound.endVolume;
279
+ res.duration = sound.duration;
280
+ res.effect = sound.effect;
281
+ res.interpolation = randomInterpolation();
282
+
283
+ res.duration = Math.clamp(
284
+ Math.min(100, res.duration),
285
+ Math.max(2000, res.duration),
286
+ res.duration + (Math.random() - 0.5) * res.duration,
287
+ );
288
+
289
+ if (res.waveShape === WaveShape.Noise) {
290
+ // The primary waveforms don't produce sounds that are similar to noise,
291
+ // but adding an effect sorta does
292
+ if (Math.percentChance(20)) {
293
+ res.waveShape = randomWave();
294
+ res.effect = randomEffect();
295
+ }
296
+ }
297
+ else {
298
+ res.waveShape = randomWave();
299
+
300
+ // Adding an effect can drastically alter the sound, so keep it
301
+ // at a low percent chance unless there already is one
302
+ if (res.effect !== SoundExpressionEffect.None || Math.percentChance(10)) {
303
+ res.effect = randomEffect();
304
+ }
305
+ }
306
+
307
+ // Instead of randomly changing the frequency, change the slope and choose
308
+ // a new start frequency. This keeps a similar profile to the sound
309
+ const oldFrequencyDifference = res.endFrequency - res.startFrequency;
310
+ let newFrequencyDifference = oldFrequencyDifference + (oldFrequencyDifference * 2) * (Math.random() - 0.5);
311
+
312
+ if (Math.sign(oldFrequencyDifference) !== Math.sign(newFrequencyDifference)) {
313
+ newFrequencyDifference *= -1;
314
+ }
315
+
316
+ newFrequencyDifference = Math.clamp(-5000, 5000, newFrequencyDifference);
317
+
318
+ res.startFrequency = Math.clamp(
319
+ Math.max(-newFrequencyDifference, 1),
320
+ Math.clamp(1, 5000, 5000 - newFrequencyDifference),
321
+ Math.random() * 5000,
322
+ );
323
+
324
+ res.endFrequency = Math.clamp(1, 5000, res.startFrequency + newFrequencyDifference);
325
+
326
+ // Same strategy for volume
327
+ const oldVolumeDifference = res.endVolume - res.startVolume;
328
+ let newVolumeDifference = oldVolumeDifference + oldVolumeDifference * (Math.random() - 0.5);
329
+
330
+ newVolumeDifference = Math.clamp(-255, 255, newVolumeDifference);
331
+
332
+ if (Math.sign(oldVolumeDifference) !== Math.sign(newVolumeDifference)) {
333
+ newVolumeDifference *= -1;
334
+ }
335
+
336
+ res.startVolume = Math.clamp(
337
+ Math.max(-newVolumeDifference, 0),
338
+ Math.clamp(0, 255, 255 - newVolumeDifference),
339
+ Math.random() * 255,
340
+ );
341
+
342
+ res.endVolume = Math.clamp(0, 255, res.startVolume + newVolumeDifference);
343
+
344
+ return res;
345
+ }
346
+
347
+ function randomWave() {
348
+ switch (Math.randomRange(0, 3)) {
349
+ case 1: return WaveShape.Sawtooth;
350
+ case 2: return WaveShape.Square;
351
+ case 3: return WaveShape.Triangle;
352
+ case 0:
353
+ default:
354
+ return WaveShape.Sine;
355
+ }
356
+ }
357
+
358
+ function randomEffect() {
359
+ switch (Math.randomRange(0, 2)) {
360
+ case 1: return SoundExpressionEffect.Warble;
361
+ case 2: return SoundExpressionEffect.Tremolo;
362
+ case 0:
363
+ default:
364
+ return SoundExpressionEffect.Vibrato;
365
+ }
366
+ }
367
+
368
+ function randomInterpolation() {
369
+ switch (Math.randomRange(0, 2)) {
370
+ case 1: return InterpolationCurve.Linear;
371
+ case 2: return InterpolationCurve.Curve;
372
+ case 0:
373
+ default:
374
+ return InterpolationCurve.Logarithmic;
375
+ }
376
+ }
377
+
378
+ //% shim=music::queuePlayInstructions
379
+ function queuePlayInstructions(timeDelta: number, buf: Buffer) { }
380
+ }