pxt-common-packages 10.1.7 → 10.1.10

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 (40) hide show
  1. package/built/common-sim.js +3 -3
  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 +8032 -7916
  6. package/libs/controller---none/built/debug/binary.js +8011 -7895
  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 +7924 -7808
  11. package/libs/game/camera.ts +3 -4
  12. package/libs/game/physics.ts +30 -0
  13. package/libs/game/sprite.ts +0 -22
  14. package/libs/game---light/compat.ts +10 -0
  15. package/libs/game---light/pxt.json +1 -3
  16. package/libs/lcd/built/debug/binary.js +8 -8
  17. package/libs/light-spectrum-sensor/built/debug/binary.js +8 -8
  18. package/libs/lora/built/debug/binary.js +8 -8
  19. package/libs/matrix-keypad/built/debug/binary.js +8 -8
  20. package/libs/mixer/melody.ts +2 -2
  21. package/libs/mixer/pxt.json +1 -0
  22. package/libs/mixer/sim/music.ts +1 -1
  23. package/libs/mixer/soundEffect.ts +380 -0
  24. package/libs/mqtt/built/debug/binary.js +176 -176
  25. package/libs/net/built/debug/binary.js +176 -176
  26. package/libs/net-game/built/debug/binary.js +9712 -9596
  27. package/libs/palette/built/debug/binary.js +7923 -7807
  28. package/libs/pixel/built/debug/binary.js +8 -8
  29. package/libs/power/built/debug/binary.js +8 -8
  30. package/libs/proximity/built/debug/binary.js +8 -8
  31. package/libs/radio/built/debug/binary.js +8 -8
  32. package/libs/radio-broadcast/built/debug/binary.js +8 -8
  33. package/libs/rotary-encoder/built/debug/binary.js +8 -8
  34. package/libs/screen/built/debug/binary.js +50 -50
  35. package/libs/screen/sim/image.ts +2 -2
  36. package/libs/screen---st7735/screen.cpp +7 -0
  37. package/libs/servo/built/debug/binary.js +8 -8
  38. package/libs/sprite-scaling/built/debug/binary.js +7923 -7807
  39. package/libs/storyboard/built/debug/binary.js +7923 -7807
  40. package/package.json +2 -2
@@ -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
+ }