pxt-microbit 4.1.18 → 4.1.21
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.
- package/built/sim.d.ts +0 -115
- package/built/sim.js +46 -683
- package/built/target.js +796 -29
- package/built/target.json +796 -29
- package/built/targetlight.json +5 -5
- package/built/web/react-common-authcode.css +30 -2
- package/built/web/react-common-skillmap.css +1 -1
- package/built/web/rtlreact-common-skillmap.css +1 -1
- package/built/web/rtlsemantic.css +2 -2
- package/built/web/semantic.css +2 -2
- package/package.json +2 -2
package/built/sim.js
CHANGED
|
@@ -2361,699 +2361,62 @@ var pxsim;
|
|
|
2361
2361
|
serial.setBaudRate = setBaudRate;
|
|
2362
2362
|
})(serial = pxsim.serial || (pxsim.serial = {}));
|
|
2363
2363
|
})(pxsim || (pxsim = {}));
|
|
2364
|
-
/**
|
|
2365
|
-
* Adapted from lancaster-university/codal-microbit-v2
|
|
2366
|
-
* https://github.com/lancaster-university/codal-microbit-v2/blob/master/source/SoundEmojiSynthesizer.cpp
|
|
2367
|
-
*/
|
|
2368
2364
|
var pxsim;
|
|
2369
2365
|
(function (pxsim) {
|
|
2370
2366
|
var music;
|
|
2371
2367
|
(function (music) {
|
|
2372
|
-
// https://github.com/lancaster-university/codal-microbit-v2/blob/master/inc/SoundEmojiSynthesizer.h#L30
|
|
2373
|
-
music.EMOJI_SYNTHESIZER_SAMPLE_RATE = 44100;
|
|
2374
|
-
music.EMOJI_SYNTHESIZER_TONE_WIDTH_F = 1024;
|
|
2375
|
-
music.EMOJI_SYNTHESIZER_TONE_WIDTH = 1024;
|
|
2376
|
-
music.EMOJI_SYNTHESIZER_BUFFER_SIZE = 512;
|
|
2377
|
-
music.EMOJI_SYNTHESIZER_TONE_EFFECT_PARAMETERS = 2;
|
|
2378
|
-
music.EMOJI_SYNTHESIZER_TONE_EFFECTS = 3;
|
|
2379
|
-
music.EMOJI_SYNTHESIZER_STATUS_ACTIVE = 0x1;
|
|
2380
|
-
music.EMOJI_SYNTHESIZER_STATUS_OUTPUT_SILENCE_AS_EMPTY = 0x2;
|
|
2381
|
-
music.EMOJI_SYNTHESIZER_STATUS_STOPPING = 0x4;
|
|
2382
|
-
class SoundEmojiSynthesizer {
|
|
2383
|
-
constructor(id, sampleRate = music.EMOJI_SYNTHESIZER_SAMPLE_RATE) {
|
|
2384
|
-
this.samplesPerStep = [];
|
|
2385
|
-
this.status = 0;
|
|
2386
|
-
this.effectPointer = 0;
|
|
2387
|
-
this.position = 0;
|
|
2388
|
-
this.bufferSize = music.EMOJI_SYNTHESIZER_BUFFER_SIZE;
|
|
2389
|
-
this.sampleRate = sampleRate;
|
|
2390
|
-
this.samplesToWrite = 0;
|
|
2391
|
-
this.samplesWritten = 0;
|
|
2392
|
-
this.sampleRange = 1023;
|
|
2393
|
-
this.orMask = 0;
|
|
2394
|
-
this.effectPointer = -1;
|
|
2395
|
-
this.volume = 1;
|
|
2396
|
-
}
|
|
2397
|
-
get effect() {
|
|
2398
|
-
return this.effectBuffer[this.effectPointer];
|
|
2399
|
-
}
|
|
2400
|
-
play(sound) {
|
|
2401
|
-
this.effectBuffer = sound;
|
|
2402
|
-
this.effectPointer = -1;
|
|
2403
|
-
this.nextSoundEffect();
|
|
2404
|
-
}
|
|
2405
|
-
nextSoundEffect() {
|
|
2406
|
-
const hadEffect = this.effect != null;
|
|
2407
|
-
if (this.status & music.EMOJI_SYNTHESIZER_STATUS_STOPPING) {
|
|
2408
|
-
this.effectPointer = null;
|
|
2409
|
-
this.effectBuffer = [];
|
|
2410
|
-
}
|
|
2411
|
-
// If a sequence of SoundEffects are being played, attempt to move on to the next.
|
|
2412
|
-
// If not, select the first in the buffer.
|
|
2413
|
-
if (this.effect)
|
|
2414
|
-
this.effectPointer++;
|
|
2415
|
-
else
|
|
2416
|
-
this.effectPointer = 0;
|
|
2417
|
-
// Validate that we have a valid sound effect. If not, record that we have nothing to play.
|
|
2418
|
-
if (this.effectPointer >= this.effectBuffer.length) {
|
|
2419
|
-
// if we have an effect with a negative duration, reset the buffer (unless there is an update pending)
|
|
2420
|
-
this.effectPointer = 0;
|
|
2421
|
-
if (this.effect.duration >= 0) {
|
|
2422
|
-
this.effectPointer = -1;
|
|
2423
|
-
this.effectBuffer = [];
|
|
2424
|
-
this.samplesWritten = 0;
|
|
2425
|
-
this.samplesToWrite = 0;
|
|
2426
|
-
this.position = 0;
|
|
2427
|
-
return hadEffect;
|
|
2428
|
-
}
|
|
2429
|
-
}
|
|
2430
|
-
// We have a valid buffer. Set up our synthesizer to the requested parameters.
|
|
2431
|
-
this.samplesToWrite = this.determineSampleCount(this.effect.duration);
|
|
2432
|
-
this.frequency = this.effect.frequency;
|
|
2433
|
-
this.volume = this.effect.volume;
|
|
2434
|
-
this.samplesWritten = 0;
|
|
2435
|
-
// validate and initialise per effect rendering state.
|
|
2436
|
-
for (let i = 0; i < music.EMOJI_SYNTHESIZER_TONE_EFFECTS; i++) {
|
|
2437
|
-
this.effect.effects[i].step = 0;
|
|
2438
|
-
this.effect.effects[i].steps = Math.max(this.effect.effects[i].steps, 1);
|
|
2439
|
-
this.samplesPerStep[i] = Math.floor(this.samplesToWrite / this.effect.effects[i].steps);
|
|
2440
|
-
}
|
|
2441
|
-
return false;
|
|
2442
|
-
}
|
|
2443
|
-
pull() {
|
|
2444
|
-
let done = false;
|
|
2445
|
-
let sample;
|
|
2446
|
-
let bufferEnd;
|
|
2447
|
-
while (!done) {
|
|
2448
|
-
if (this.samplesWritten == this.samplesToWrite || this.status & music.EMOJI_SYNTHESIZER_STATUS_STOPPING) {
|
|
2449
|
-
let renderComplete = this.nextSoundEffect();
|
|
2450
|
-
// If we have just completed active playout of an effect, and there are no more effects scheduled,
|
|
2451
|
-
// unblock any fibers that may be waiting to play a sound effect.
|
|
2452
|
-
if (this.samplesToWrite == 0 || this.status & music.EMOJI_SYNTHESIZER_STATUS_STOPPING) {
|
|
2453
|
-
done = true;
|
|
2454
|
-
if (renderComplete || this.status & music.EMOJI_SYNTHESIZER_STATUS_STOPPING) {
|
|
2455
|
-
this.status &= ~music.EMOJI_SYNTHESIZER_STATUS_STOPPING;
|
|
2456
|
-
// Event(id, DEVICE_SOUND_EMOJI_SYNTHESIZER_EVT_DONE);
|
|
2457
|
-
// lock.notify();
|
|
2458
|
-
}
|
|
2459
|
-
}
|
|
2460
|
-
}
|
|
2461
|
-
// If we have something to do, ensure our buffers are created.
|
|
2462
|
-
// We defer creation to avoid unnecessary heap allocation when generating silence.
|
|
2463
|
-
if (((this.samplesWritten < this.samplesToWrite) || !(this.status & music.EMOJI_SYNTHESIZER_STATUS_OUTPUT_SILENCE_AS_EMPTY)) && sample == null) {
|
|
2464
|
-
this.buffer = new Array(this.bufferSize);
|
|
2465
|
-
sample = 0;
|
|
2466
|
-
bufferEnd = this.buffer.length;
|
|
2467
|
-
}
|
|
2468
|
-
// Generate some samples with the current this.effect parameters.
|
|
2469
|
-
while (this.samplesWritten < this.samplesToWrite) {
|
|
2470
|
-
let skip = ((music.EMOJI_SYNTHESIZER_TONE_WIDTH_F * this.frequency) / this.sampleRate);
|
|
2471
|
-
let gain = (this.sampleRange * this.volume) / 1024;
|
|
2472
|
-
let offset = 512 - (512 * gain);
|
|
2473
|
-
let effectStepEnd = [];
|
|
2474
|
-
for (let i = 0; i < music.EMOJI_SYNTHESIZER_TONE_EFFECTS; i++) {
|
|
2475
|
-
effectStepEnd[i] = (this.samplesPerStep[i] * (this.effect.effects[i].step));
|
|
2476
|
-
if (this.effect.effects[i].step == this.effect.effects[i].steps - 1)
|
|
2477
|
-
effectStepEnd[i] = this.samplesToWrite;
|
|
2478
|
-
}
|
|
2479
|
-
let stepEndPosition = effectStepEnd[0];
|
|
2480
|
-
for (let i = 1; i < music.EMOJI_SYNTHESIZER_TONE_EFFECTS; i++)
|
|
2481
|
-
stepEndPosition = Math.min(stepEndPosition, effectStepEnd[i]);
|
|
2482
|
-
// Write samples until the end of the next this.effect-step
|
|
2483
|
-
while (this.samplesWritten < stepEndPosition) {
|
|
2484
|
-
// Stop processing when we've filled the requested this.buffer
|
|
2485
|
-
if (sample == bufferEnd) {
|
|
2486
|
-
// downStream.pullRequest();
|
|
2487
|
-
return this.buffer;
|
|
2488
|
-
}
|
|
2489
|
-
// Synthesize a sample
|
|
2490
|
-
let s = this.effect.tone.tonePrint(this.effect.tone.parameter, this.position);
|
|
2491
|
-
// Apply volume scaling and OR mask (if specified).
|
|
2492
|
-
this.buffer[sample] = (((s * gain) + offset)); // | this.orMask;
|
|
2493
|
-
// Move on our pointers.
|
|
2494
|
-
sample++;
|
|
2495
|
-
this.samplesWritten++;
|
|
2496
|
-
this.position += skip;
|
|
2497
|
-
// Keep our toneprint pointer in range
|
|
2498
|
-
while (this.position > music.EMOJI_SYNTHESIZER_TONE_WIDTH_F)
|
|
2499
|
-
this.position -= music.EMOJI_SYNTHESIZER_TONE_WIDTH_F;
|
|
2500
|
-
}
|
|
2501
|
-
// Invoke the this.effect function for any effects that are due.
|
|
2502
|
-
for (let i = 0; i < music.EMOJI_SYNTHESIZER_TONE_EFFECTS; i++) {
|
|
2503
|
-
if (this.samplesWritten == effectStepEnd[i]) {
|
|
2504
|
-
if (this.effect.effects[i].step < this.effect.effects[i].steps) {
|
|
2505
|
-
if (this.effect.effects[i].effect)
|
|
2506
|
-
this.effect.effects[i].effect(this, this.effect.effects[i]);
|
|
2507
|
-
this.effect.effects[i].step++;
|
|
2508
|
-
}
|
|
2509
|
-
}
|
|
2510
|
-
}
|
|
2511
|
-
}
|
|
2512
|
-
}
|
|
2513
|
-
// if we have no data to send, return an empty this.buffer (if requested)
|
|
2514
|
-
if (sample == null) {
|
|
2515
|
-
this.buffer = [];
|
|
2516
|
-
}
|
|
2517
|
-
else {
|
|
2518
|
-
// Pad the output this.buffer with silence if necessary.
|
|
2519
|
-
const silence = (this.sampleRange * 0.5); // | this.orMask;
|
|
2520
|
-
while (sample < bufferEnd) {
|
|
2521
|
-
this.buffer[sample] = silence;
|
|
2522
|
-
sample++;
|
|
2523
|
-
}
|
|
2524
|
-
}
|
|
2525
|
-
// Issue a Pull Request so that we are always receiver driven, and we're done.
|
|
2526
|
-
// downStream.pullRequest();
|
|
2527
|
-
return this.buffer;
|
|
2528
|
-
}
|
|
2529
|
-
determineSampleCount(playoutTime) {
|
|
2530
|
-
if (playoutTime < 0)
|
|
2531
|
-
playoutTime = -playoutTime;
|
|
2532
|
-
const seconds = playoutTime / 1000;
|
|
2533
|
-
return Math.floor(this.sampleRate * seconds);
|
|
2534
|
-
}
|
|
2535
|
-
totalDuration() {
|
|
2536
|
-
let duration = 0;
|
|
2537
|
-
for (const effect of this.effectBuffer)
|
|
2538
|
-
duration += effect.duration;
|
|
2539
|
-
return duration;
|
|
2540
|
-
}
|
|
2541
|
-
}
|
|
2542
|
-
music.SoundEmojiSynthesizer = SoundEmojiSynthesizer;
|
|
2543
|
-
})(music = pxsim.music || (pxsim.music = {}));
|
|
2544
|
-
})(pxsim || (pxsim = {}));
|
|
2545
|
-
/**
|
|
2546
|
-
* Adapted from lancaster-university/codal-microbit-v2
|
|
2547
|
-
* https://github.com/lancaster-university/codal-microbit-v2/blob/master/source/SoundExpressions.cpp#L286
|
|
2548
|
-
*/
|
|
2549
|
-
var pxsim;
|
|
2550
|
-
(function (pxsim) {
|
|
2551
|
-
var music;
|
|
2552
|
-
(function (music) {
|
|
2553
|
-
var builtin;
|
|
2554
|
-
(function (builtin) {
|
|
2555
|
-
const giggle = "giggle";
|
|
2556
|
-
const giggleData = "010230988019008440044008881023001601003300240000000000000000000000000000,110232570087411440044008880352005901003300010000000000000000010000000000,310232729021105440288908880091006300000000240700020000000000003000000000,310232729010205440288908880091006300000000240700020000000000003000000000,310232729011405440288908880091006300000000240700020000000000003000000000";
|
|
2557
|
-
const happy = "happy";
|
|
2558
|
-
const happyData = "010231992066911440044008880262002800001800020500000000000000010000000000,002322129029508440240408880000000400022400110000000000000000007500000000,000002129029509440240408880145000400022400110000000000000000007500000000";
|
|
2559
|
-
const hello = "hello";
|
|
2560
|
-
const helloData = "310230673019702440118708881023012800000000240000000000000000000000000000,300001064001602440098108880000012800000100040000000000000000000000000000,310231064029302440098108881023012800000100040000000000000000000000000000";
|
|
2561
|
-
const mysterious = "mysterious";
|
|
2562
|
-
const mysteriousData = "400002390033100440240408880477000400022400110400000000000000008000000000,405512845385000440044008880000012803010500160000000000000000085000500015";
|
|
2563
|
-
const sad = "sad";
|
|
2564
|
-
const sadData = "310232226070801440162408881023012800000100240000000000000000000000000000,310231623093602440093908880000012800000100240000000000000000000000000000";
|
|
2565
|
-
const slide = "slide";
|
|
2566
|
-
const slideData = "105202325022302440240408881023012801020000110400000000000000010000000000,010232520091002440044008881023012801022400110400000000000000010000000000";
|
|
2567
|
-
const soaring = "soaring";
|
|
2568
|
-
const soaringData = "210234009530905440599908881023002202000400020250000000000000020000000000,402233727273014440044008880000003101024400030000000000000000000000000000";
|
|
2569
|
-
const spring = "spring";
|
|
2570
|
-
const springData = "306590037116312440058708880807003400000000240000000000000000050000000000,010230037116313440058708881023003100000000240000000000000000050000000000";
|
|
2571
|
-
const twinkle = "twinkle";
|
|
2572
|
-
const twinkleData = "010180007672209440075608880855012800000000240000000000000000000000000000";
|
|
2573
|
-
const yawn = "yawn";
|
|
2574
|
-
const yawnData = "200002281133202440150008881023012801024100240400030000000000010000000000,005312520091002440044008880636012801022400110300000000000000010000000000,008220784019008440044008880681001600005500240000000000000000005000000000,004790784019008440044008880298001600000000240000000000000000005000000000,003210784019008440044008880108001600003300080000000000000000005000000000";
|
|
2575
|
-
function lookupBuiltIn(sound) {
|
|
2576
|
-
if (sound == giggle)
|
|
2577
|
-
return giggleData;
|
|
2578
|
-
if (sound == happy)
|
|
2579
|
-
return happyData;
|
|
2580
|
-
if (sound == hello)
|
|
2581
|
-
return helloData;
|
|
2582
|
-
if (sound == mysterious)
|
|
2583
|
-
return mysteriousData;
|
|
2584
|
-
if (sound == sad)
|
|
2585
|
-
return sadData;
|
|
2586
|
-
if (sound == slide)
|
|
2587
|
-
return slideData;
|
|
2588
|
-
if (sound == soaring)
|
|
2589
|
-
return soaringData;
|
|
2590
|
-
if (sound == spring)
|
|
2591
|
-
return springData;
|
|
2592
|
-
if (sound == twinkle)
|
|
2593
|
-
return twinkleData;
|
|
2594
|
-
if (sound == yawn)
|
|
2595
|
-
return yawnData;
|
|
2596
|
-
return sound;
|
|
2597
|
-
}
|
|
2598
|
-
builtin.lookupBuiltIn = lookupBuiltIn;
|
|
2599
|
-
})(builtin = music.builtin || (music.builtin = {}));
|
|
2600
|
-
})(music = pxsim.music || (pxsim.music = {}));
|
|
2601
|
-
})(pxsim || (pxsim = {}));
|
|
2602
|
-
/**
|
|
2603
|
-
* Adapted from lancaster-university/codal-core
|
|
2604
|
-
* https://github.com/lancaster-university/codal-core/blob/master/source/streams/Synthesizer.cpp#L54
|
|
2605
|
-
*/
|
|
2606
|
-
var pxsim;
|
|
2607
|
-
(function (pxsim) {
|
|
2608
|
-
var music;
|
|
2609
|
-
(function (music) {
|
|
2610
|
-
var Synthesizer;
|
|
2611
|
-
(function (Synthesizer) {
|
|
2612
|
-
const sineTone = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 11, 12, 13, 13, 14, 15, 16, 16, 17, 18, 19, 20, 21, 22, 22, 23, 24, 25, 26, 27, 28, 29, 30, 32, 33, 34, 35, 36, 37, 38, 40, 41, 42, 43, 45, 46, 47, 49, 50, 51, 53, 54, 56, 57, 58, 60, 61, 63, 64, 66, 68, 69, 71, 72, 74, 76, 77, 79, 81, 82, 84, 86, 87, 89, 91, 93, 95, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 141, 143, 145, 147, 149, 152, 154, 156, 158, 161, 163, 165, 167, 170, 172, 175, 177, 179, 182, 184, 187, 189, 191, 194, 196, 199, 201, 204, 206, 209, 211, 214, 216, 219, 222, 224, 227, 229, 232, 235, 237, 240, 243, 245, 248, 251, 253, 256, 259, 262, 264, 267, 270, 273, 275, 278, 281, 284, 287, 289, 292, 295, 298, 301, 304, 307, 309, 312, 315, 318, 321, 324, 327, 330, 333, 336, 339, 342, 345, 348, 351, 354, 357, 360, 363, 366, 369, 372, 375, 378, 381, 384, 387, 390, 393, 396, 399, 402, 405, 408, 411, 414, 417, 420, 424, 427, 430, 433, 436, 439, 442, 445, 448, 452, 455, 458, 461, 464, 467, 470, 473, 477, 480, 483, 486, 489, 492, 495, 498, 502, 505, 508, 511, 514, 517, 520, 524, 527, 530, 533, 536, 539, 542, 545, 549, 552, 555, 558, 561, 564, 567, 570, 574, 577, 580, 583, 586, 589, 592, 595, 598, 602, 605, 608, 611, 614, 617, 620, 623, 626, 629, 632, 635, 638, 641, 644, 647, 650, 653, 656, 659, 662, 665, 668, 671, 674, 677, 680, 683, 686, 689, 692, 695, 698, 701, 704, 707, 710, 713, 715, 718, 721, 724, 727, 730, 733, 735, 738, 741, 744, 747, 749, 752, 755, 758, 760, 763, 766, 769, 771, 774, 777, 779, 782, 785, 787, 790, 793, 795, 798, 800, 803, 806, 808, 811, 813, 816, 818, 821, 823, 826, 828, 831, 833, 835, 838, 840, 843, 845, 847, 850, 852, 855, 857, 859, 861, 864, 866, 868, 870, 873, 875, 877, 879, 881, 884, 886, 888, 890, 892, 894, 896, 898, 900, 902, 904, 906, 908, 910, 912, 914, 916, 918, 920, 922, 924, 926, 927, 929, 931, 933, 935, 936, 938, 940, 941, 943, 945, 946, 948, 950, 951, 953, 954, 956, 958, 959, 961, 962, 964, 965, 966, 968, 969, 971, 972, 973, 975, 976, 977, 979, 980, 981, 982, 984, 985, 986, 987, 988, 989, 990, 992, 993, 994, 995, 996, 997, 998, 999, 1000, 1000, 1001, 1002, 1003, 1004, 1005, 1006, 1006, 1007, 1008, 1009, 1009, 1010, 1011, 1011, 1012, 1013, 1013, 1014, 1014, 1015, 1015, 1016, 1016, 1017, 1017, 1018, 1018, 1019, 1019, 1019, 1020, 1020, 1020, 1021, 1021, 1021, 1021, 1022, 1022, 1022, 1022, 1022, 1022, 1022, 1022, 1022, 1022, 1023, 1022];
|
|
2613
|
-
const TONE_WIDTH = 1024;
|
|
2614
|
-
function SineTone(arg, position) {
|
|
2615
|
-
position |= 0;
|
|
2616
|
-
let off = TONE_WIDTH - position;
|
|
2617
|
-
if (off < TONE_WIDTH / 2)
|
|
2618
|
-
position = off;
|
|
2619
|
-
return sineTone[position];
|
|
2620
|
-
}
|
|
2621
|
-
Synthesizer.SineTone = SineTone;
|
|
2622
|
-
function SawtoothTone(arg, position) {
|
|
2623
|
-
return position;
|
|
2624
|
-
}
|
|
2625
|
-
Synthesizer.SawtoothTone = SawtoothTone;
|
|
2626
|
-
function TriangleTone(arg, position) {
|
|
2627
|
-
return position < 512 ? position * 2 : (1023 - position) * 2;
|
|
2628
|
-
}
|
|
2629
|
-
Synthesizer.TriangleTone = TriangleTone;
|
|
2630
|
-
function NoiseTone(arg, position) {
|
|
2631
|
-
// deterministic, semi-random noise
|
|
2632
|
-
let mult = arg[0];
|
|
2633
|
-
if (mult == 0)
|
|
2634
|
-
mult = 7919;
|
|
2635
|
-
return (position * mult) & 1023;
|
|
2636
|
-
}
|
|
2637
|
-
Synthesizer.NoiseTone = NoiseTone;
|
|
2638
|
-
function SquareWaveTone(arg, position) {
|
|
2639
|
-
return position < 512 ? 1023 : 0;
|
|
2640
|
-
}
|
|
2641
|
-
Synthesizer.SquareWaveTone = SquareWaveTone;
|
|
2642
|
-
})(Synthesizer = music.Synthesizer || (music.Synthesizer = {}));
|
|
2643
|
-
})(music = pxsim.music || (pxsim.music = {}));
|
|
2644
|
-
})(pxsim || (pxsim = {}));
|
|
2645
|
-
/**
|
|
2646
|
-
* Adapted from lancaster-university/codal-microbit-v2
|
|
2647
|
-
* https://github.com/lancaster-university/codal-microbit-v2/blob/master/source/SoundSynthesizerEffects.cpp
|
|
2648
|
-
*/
|
|
2649
|
-
var pxsim;
|
|
2650
|
-
(function (pxsim) {
|
|
2651
|
-
var music;
|
|
2652
|
-
(function (music) {
|
|
2653
|
-
var SoundSynthesizerEffects;
|
|
2654
|
-
(function (SoundSynthesizerEffects) {
|
|
2655
|
-
/*
|
|
2656
|
-
* Definitions of standard progressions.
|
|
2657
|
-
*/
|
|
2658
|
-
/**
|
|
2659
|
-
* Root Frequency Interpolation Effect Functions
|
|
2660
|
-
*/
|
|
2661
|
-
function noInterpolation(synth, context) {
|
|
2662
|
-
}
|
|
2663
|
-
SoundSynthesizerEffects.noInterpolation = noInterpolation;
|
|
2664
|
-
// Linear interpolate function.
|
|
2665
|
-
// parameter[0]: end frequency
|
|
2666
|
-
function linearInterpolation(synth, context) {
|
|
2667
|
-
let interval = (context.parameter[0] - synth.effect.frequency) / context.steps;
|
|
2668
|
-
synth.frequency = synth.effect.frequency + interval * context.step;
|
|
2669
|
-
}
|
|
2670
|
-
SoundSynthesizerEffects.linearInterpolation = linearInterpolation;
|
|
2671
|
-
// Linear interpolate function.
|
|
2672
|
-
// parameter[0]: end frequency
|
|
2673
|
-
function logarithmicInterpolation(synth, context) {
|
|
2674
|
-
synth.frequency = synth.effect.frequency + (Math.log10(context.step) * (context.parameter[0] - synth.effect.frequency) / 1.95);
|
|
2675
|
-
}
|
|
2676
|
-
SoundSynthesizerEffects.logarithmicInterpolation = logarithmicInterpolation;
|
|
2677
|
-
// Curve interpolate function
|
|
2678
|
-
// parameter[0]: end frequency
|
|
2679
|
-
function curveInterpolation(synth, context) {
|
|
2680
|
-
synth.frequency = (Math.sin(context.step * 3.12159 / 180.0) * (context.parameter[0] - synth.effect.frequency) + synth.effect.frequency);
|
|
2681
|
-
}
|
|
2682
|
-
SoundSynthesizerEffects.curveInterpolation = curveInterpolation;
|
|
2683
|
-
// Cosine interpolate function
|
|
2684
|
-
// parameter[0]: end frequency
|
|
2685
|
-
function slowVibratoInterpolation(synth, context) {
|
|
2686
|
-
synth.frequency = Math.sin(context.step / 10) * context.parameter[0] + synth.effect.frequency;
|
|
2687
|
-
}
|
|
2688
|
-
SoundSynthesizerEffects.slowVibratoInterpolation = slowVibratoInterpolation;
|
|
2689
|
-
//warble function
|
|
2690
|
-
// parameter[0]: end frequency
|
|
2691
|
-
function warbleInterpolation(synth, context) {
|
|
2692
|
-
synth.frequency = (Math.sin(context.step) * (context.parameter[0] - synth.effect.frequency) + synth.effect.frequency);
|
|
2693
|
-
}
|
|
2694
|
-
SoundSynthesizerEffects.warbleInterpolation = warbleInterpolation;
|
|
2695
|
-
// Vibrato function
|
|
2696
|
-
// parameter[0]: end frequency
|
|
2697
|
-
function vibratoInterpolation(synth, context) {
|
|
2698
|
-
synth.frequency = synth.effect.frequency + Math.sin(context.step) * context.parameter[0];
|
|
2699
|
-
}
|
|
2700
|
-
SoundSynthesizerEffects.vibratoInterpolation = vibratoInterpolation;
|
|
2701
|
-
// Exponential rising function
|
|
2702
|
-
// parameter[0]: end frequency
|
|
2703
|
-
function exponentialRisingInterpolation(synth, context) {
|
|
2704
|
-
synth.frequency = synth.effect.frequency + Math.sin(0.01745329 * context.step) * context.parameter[0];
|
|
2705
|
-
}
|
|
2706
|
-
SoundSynthesizerEffects.exponentialRisingInterpolation = exponentialRisingInterpolation;
|
|
2707
|
-
// Exponential falling function
|
|
2708
|
-
function exponentialFallingInterpolation(synth, context) {
|
|
2709
|
-
synth.frequency = synth.effect.frequency + Math.cos(0.01745329 * context.step) * context.parameter[0];
|
|
2710
|
-
}
|
|
2711
|
-
SoundSynthesizerEffects.exponentialFallingInterpolation = exponentialFallingInterpolation;
|
|
2712
|
-
// Argeppio functions
|
|
2713
|
-
function appregrioAscending(synth, context) {
|
|
2714
|
-
synth.frequency = music.MusicalProgressions.calculateFrequencyFromProgression(synth.effect.frequency, context.parameter_p[0], context.step);
|
|
2715
|
-
}
|
|
2716
|
-
SoundSynthesizerEffects.appregrioAscending = appregrioAscending;
|
|
2717
|
-
function appregrioDescending(synth, context) {
|
|
2718
|
-
synth.frequency = music.MusicalProgressions.calculateFrequencyFromProgression(synth.effect.frequency, context.parameter_p[0], context.steps - context.step - 1);
|
|
2719
|
-
}
|
|
2720
|
-
SoundSynthesizerEffects.appregrioDescending = appregrioDescending;
|
|
2721
|
-
/**
|
|
2722
|
-
* Frequency Delta effects
|
|
2723
|
-
*/
|
|
2724
|
-
// Frequency vibrato function
|
|
2725
|
-
// parameter[0]: vibrato frequency multiplier
|
|
2726
|
-
function frequencyVibratoEffect(synth, context) {
|
|
2727
|
-
if (context.step == 0)
|
|
2728
|
-
return;
|
|
2729
|
-
if (context.step % 2 == 0)
|
|
2730
|
-
synth.frequency /= context.parameter[0];
|
|
2731
|
-
else
|
|
2732
|
-
synth.frequency *= context.parameter[0];
|
|
2733
|
-
}
|
|
2734
|
-
SoundSynthesizerEffects.frequencyVibratoEffect = frequencyVibratoEffect;
|
|
2735
|
-
// Volume vibrato function
|
|
2736
|
-
// parameter[0]: vibrato volume multiplier
|
|
2737
|
-
function volumeVibratoEffect(synth, context) {
|
|
2738
|
-
if (context.step == 0)
|
|
2739
|
-
return;
|
|
2740
|
-
if (context.step % 2 == 0)
|
|
2741
|
-
synth.volume /= context.parameter[0];
|
|
2742
|
-
else
|
|
2743
|
-
synth.volume *= context.parameter[0];
|
|
2744
|
-
}
|
|
2745
|
-
SoundSynthesizerEffects.volumeVibratoEffect = volumeVibratoEffect;
|
|
2746
|
-
/**
|
|
2747
|
-
* Volume Delta effects
|
|
2748
|
-
*/
|
|
2749
|
-
/** Simple ADSR enveleope effect.
|
|
2750
|
-
* parameter[0]: Centre volume
|
|
2751
|
-
* parameter[1]: End volume
|
|
2752
|
-
* effect.volume: start volume
|
|
2753
|
-
*/
|
|
2754
|
-
function adsrVolumeEffect(synth, context) {
|
|
2755
|
-
let halfSteps = context.steps * 0.5;
|
|
2756
|
-
if (context.step <= halfSteps) {
|
|
2757
|
-
let delta = (context.parameter[0] - synth.effect.volume) / halfSteps;
|
|
2758
|
-
synth.volume = synth.effect.volume + context.step * delta;
|
|
2759
|
-
}
|
|
2760
|
-
else {
|
|
2761
|
-
let delta = (context.parameter[1] - context.parameter[0]) / halfSteps;
|
|
2762
|
-
synth.volume = context.parameter[0] + (context.step - halfSteps) * delta;
|
|
2763
|
-
}
|
|
2764
|
-
}
|
|
2765
|
-
SoundSynthesizerEffects.adsrVolumeEffect = adsrVolumeEffect;
|
|
2766
|
-
/**
|
|
2767
|
-
* Simple volume ramp effect
|
|
2768
|
-
* parameter[0]: End volume
|
|
2769
|
-
* effect.volume: start volume
|
|
2770
|
-
*/
|
|
2771
|
-
function volumeRampEffect(synth, context) {
|
|
2772
|
-
let delta = (context.parameter[0] - synth.effect.volume) / context.steps;
|
|
2773
|
-
synth.volume = synth.effect.volume + context.step * delta;
|
|
2774
|
-
}
|
|
2775
|
-
SoundSynthesizerEffects.volumeRampEffect = volumeRampEffect;
|
|
2776
|
-
})(SoundSynthesizerEffects = music.SoundSynthesizerEffects || (music.SoundSynthesizerEffects = {}));
|
|
2777
|
-
})(music = pxsim.music || (pxsim.music = {}));
|
|
2778
|
-
})(pxsim || (pxsim = {}));
|
|
2779
|
-
var pxsim;
|
|
2780
|
-
(function (pxsim) {
|
|
2781
|
-
var music;
|
|
2782
|
-
(function (music) {
|
|
2783
|
-
let synth;
|
|
2784
|
-
let soundPromise;
|
|
2785
2368
|
//%
|
|
2786
2369
|
function __playSoundExpression(notes, waitTillDone) {
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
// v2 only...
|
|
2790
|
-
b.ensureHardwareVersion(2);
|
|
2791
|
-
if (!synth)
|
|
2792
|
-
synth = new music.SoundEmojiSynthesizer(0);
|
|
2793
|
-
if (!soundPromise)
|
|
2794
|
-
soundPromise = Promise.resolve();
|
|
2795
|
-
soundPromise = soundPromise.then(() => {
|
|
2796
|
-
notes = music.builtin.lookupBuiltIn(notes);
|
|
2797
|
-
const soundEffects = parseSoundEffects(notes);
|
|
2798
|
-
synth.play(soundEffects);
|
|
2799
|
-
let cancelled = false;
|
|
2800
|
-
return Promise.race([
|
|
2801
|
-
delayAsync(synth.totalDuration())
|
|
2802
|
-
.then(() => {
|
|
2803
|
-
// If safari didn't allow the sound to play for some reason,
|
|
2804
|
-
// it will get delayed until the user does something that
|
|
2805
|
-
// unmutes it. make sure we cancel it so that it doesn't
|
|
2806
|
-
// play long after it was supposed to
|
|
2807
|
-
cancelled = true;
|
|
2808
|
-
}),
|
|
2809
|
-
pxsim.AudioContextManager.playPCMBufferStreamAsync(() => {
|
|
2810
|
-
if (!synth.effect)
|
|
2811
|
-
return undefined;
|
|
2812
|
-
const buff = synth.pull();
|
|
2813
|
-
const arr = new Float32Array(buff.length);
|
|
2814
|
-
for (let i = 0; i < buff.length; i++) {
|
|
2815
|
-
// Buffer is (0, 1023) we need to map it to (-1, 1)
|
|
2816
|
-
arr[i] = ((buff[i] - 512) / 512);
|
|
2817
|
-
}
|
|
2818
|
-
return arr;
|
|
2819
|
-
}, synth.sampleRate, 0.03, () => cancelled)
|
|
2820
|
-
]);
|
|
2821
|
-
});
|
|
2822
|
-
if (!waitTillDone)
|
|
2823
|
-
cb();
|
|
2824
|
-
else
|
|
2825
|
-
soundPromise = soundPromise.then(cb);
|
|
2370
|
+
notes = lookupBuiltIn(notes);
|
|
2371
|
+
pxsim.codal.music.__playSoundExpression(notes, waitTillDone);
|
|
2826
2372
|
}
|
|
2827
2373
|
music.__playSoundExpression = __playSoundExpression;
|
|
2828
2374
|
function __stopSoundExpressions() {
|
|
2829
2375
|
pxsim.AudioContextManager.stopAll();
|
|
2830
2376
|
}
|
|
2831
2377
|
music.__stopSoundExpressions = __stopSoundExpressions;
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
let shape = parseInt(soundChars.substr(13, 2));
|
|
2875
|
-
// [15] XXX unused/bug. This was startFrequency but we use frequency above.
|
|
2876
|
-
// [18] 0000-9999 end frequency
|
|
2877
|
-
let endFrequency = parseInt(soundChars.substr(18, 4));
|
|
2878
|
-
// [22] XXXX unused. This was start volume but we use volume above.
|
|
2879
|
-
// [26] 0000-1023 end volume
|
|
2880
|
-
let endVolume = parseInt(soundChars.substr(26, 4));
|
|
2881
|
-
// [30] 0000-9999 steps
|
|
2882
|
-
let steps = parseInt(soundChars.substr(30, 4));
|
|
2883
|
-
// [34] 00-03 fx choice
|
|
2884
|
-
let fxChoice = parseInt(soundChars.substr(34, 2));
|
|
2885
|
-
// [36] 0000-9999 fxParam
|
|
2886
|
-
let fxParam = parseInt(soundChars.substr(36, 4));
|
|
2887
|
-
// [40] 0000-9999 fxnSteps
|
|
2888
|
-
let fxnSteps = parseInt(soundChars.substr(40, 4));
|
|
2889
|
-
// Details that encoded randomness to be applied when frame is used:
|
|
2890
|
-
// Can the randomness cause any parameters to go out of range?
|
|
2891
|
-
// [44] 0000-9999 frequency random
|
|
2892
|
-
frequency = applyRandom(frequency, parseInt(soundChars.substr(44, 4)));
|
|
2893
|
-
// [48] 0000-9999 end frequency random
|
|
2894
|
-
endFrequency = applyRandom(endFrequency, parseInt(soundChars.substr(48, 4)));
|
|
2895
|
-
// [52] 0000-9999 volume random
|
|
2896
|
-
effectVolume = applyRandom(effectVolume, parseInt(soundChars.substr(52, 4)));
|
|
2897
|
-
// [56] 0000-9999 end volume random
|
|
2898
|
-
endVolume = applyRandom(endVolume, parseInt(soundChars.substr(56, 4)));
|
|
2899
|
-
// [60] 0000-9999 duration random
|
|
2900
|
-
duration = applyRandom(duration, parseInt(soundChars.substr(60, 4)));
|
|
2901
|
-
// [64] 0000-9999 fxParamRandom
|
|
2902
|
-
fxParam = applyRandom(fxParam, parseInt(soundChars.substr(64, 4)));
|
|
2903
|
-
// [68] 0000-9999 fxnStepsRandom
|
|
2904
|
-
fxnSteps = applyRandom(fxnSteps, parseInt(soundChars.substr(68, 4)));
|
|
2905
|
-
if (frequency == -1 || endFrequency == -1 || effectVolume == -1 || endVolume == -1 || duration == -1 || fxParam == -1 || fxnSteps == -1) {
|
|
2906
|
-
return false;
|
|
2907
|
-
}
|
|
2908
|
-
let volumeScaleFactor = 1;
|
|
2909
|
-
switch (wave) {
|
|
2910
|
-
case 0:
|
|
2911
|
-
fx.tone.tonePrint = music.Synthesizer.SineTone;
|
|
2912
|
-
break;
|
|
2913
|
-
case 1:
|
|
2914
|
-
fx.tone.tonePrint = music.Synthesizer.SawtoothTone;
|
|
2915
|
-
break;
|
|
2916
|
-
case 2:
|
|
2917
|
-
fx.tone.tonePrint = music.Synthesizer.TriangleTone;
|
|
2918
|
-
break;
|
|
2919
|
-
case 3:
|
|
2920
|
-
fx.tone.tonePrint = music.Synthesizer.SquareWaveTone;
|
|
2921
|
-
break;
|
|
2922
|
-
case 4:
|
|
2923
|
-
fx.tone.tonePrint = music.Synthesizer.NoiseTone;
|
|
2924
|
-
break;
|
|
2925
|
-
}
|
|
2926
|
-
fx.frequency = frequency;
|
|
2927
|
-
fx.duration = duration;
|
|
2928
|
-
fx.effects[0].steps = steps;
|
|
2929
|
-
switch (shape) {
|
|
2930
|
-
case 0:
|
|
2931
|
-
fx.effects[0].effect = music.SoundSynthesizerEffects.noInterpolation;
|
|
2932
|
-
break;
|
|
2933
|
-
case 1:
|
|
2934
|
-
fx.effects[0].effect = music.SoundSynthesizerEffects.linearInterpolation;
|
|
2935
|
-
fx.effects[0].parameter[0] = endFrequency;
|
|
2936
|
-
break;
|
|
2937
|
-
case 2:
|
|
2938
|
-
fx.effects[0].effect = music.SoundSynthesizerEffects.curveInterpolation;
|
|
2939
|
-
fx.effects[0].parameter[0] = endFrequency;
|
|
2940
|
-
break;
|
|
2941
|
-
case 5:
|
|
2942
|
-
fx.effects[0].effect = music.SoundSynthesizerEffects.exponentialRisingInterpolation;
|
|
2943
|
-
fx.effects[0].parameter[0] = endFrequency;
|
|
2944
|
-
break;
|
|
2945
|
-
case 6:
|
|
2946
|
-
fx.effects[0].effect = music.SoundSynthesizerEffects.exponentialFallingInterpolation;
|
|
2947
|
-
fx.effects[0].parameter[0] = endFrequency;
|
|
2948
|
-
break;
|
|
2949
|
-
case 8: // various ascending scales - see next switch
|
|
2950
|
-
case 10:
|
|
2951
|
-
case 12:
|
|
2952
|
-
case 14:
|
|
2953
|
-
case 16:
|
|
2954
|
-
fx.effects[0].effect = music.SoundSynthesizerEffects.appregrioAscending;
|
|
2955
|
-
break;
|
|
2956
|
-
case 9: // various descending scales - see next switch
|
|
2957
|
-
case 11:
|
|
2958
|
-
case 13:
|
|
2959
|
-
case 15:
|
|
2960
|
-
case 17:
|
|
2961
|
-
fx.effects[0].effect = music.SoundSynthesizerEffects.appregrioDescending;
|
|
2962
|
-
break;
|
|
2963
|
-
case 18:
|
|
2964
|
-
fx.effects[0].effect = music.SoundSynthesizerEffects.logarithmicInterpolation;
|
|
2965
|
-
break;
|
|
2966
|
-
}
|
|
2967
|
-
// Scale
|
|
2968
|
-
switch (shape) {
|
|
2969
|
-
case 8:
|
|
2970
|
-
case 9:
|
|
2971
|
-
fx.effects[0].parameter_p[0] = music.MusicalProgressions.majorScale;
|
|
2972
|
-
break;
|
|
2973
|
-
case 10:
|
|
2974
|
-
case 11:
|
|
2975
|
-
fx.effects[0].parameter_p[0] = music.MusicalProgressions.minorScale;
|
|
2976
|
-
break;
|
|
2977
|
-
case 12:
|
|
2978
|
-
case 13:
|
|
2979
|
-
fx.effects[0].parameter_p[0] = music.MusicalProgressions.diminished;
|
|
2980
|
-
break;
|
|
2981
|
-
case 14:
|
|
2982
|
-
case 15:
|
|
2983
|
-
fx.effects[0].parameter_p[0] = music.MusicalProgressions.chromatic;
|
|
2984
|
-
break;
|
|
2985
|
-
case 16:
|
|
2986
|
-
case 17:
|
|
2987
|
-
fx.effects[0].parameter_p[0] = music.MusicalProgressions.wholeTone;
|
|
2988
|
-
break;
|
|
2989
|
-
}
|
|
2990
|
-
// Volume envelope
|
|
2991
|
-
let effectVolumeFloat = CLAMP(0, effectVolume, 1023) / 1023.0;
|
|
2992
|
-
let endVolumeFloat = CLAMP(0, endVolume, 1023) / 1023.0;
|
|
2993
|
-
fx.volume = volumeScaleFactor * effectVolumeFloat;
|
|
2994
|
-
fx.effects[1].effect = music.SoundSynthesizerEffects.volumeRampEffect;
|
|
2995
|
-
fx.effects[1].steps = 36;
|
|
2996
|
-
fx.effects[1].parameter[0] = volumeScaleFactor * endVolumeFloat;
|
|
2997
|
-
// Vibrato effect
|
|
2998
|
-
// Steps need to be spread across duration evenly.
|
|
2999
|
-
let normalizedFxnSteps = (fx.duration / 10000) * fxnSteps;
|
|
3000
|
-
switch (fxChoice) {
|
|
3001
|
-
case 1:
|
|
3002
|
-
fx.effects[2].steps = normalizedFxnSteps;
|
|
3003
|
-
fx.effects[2].effect = music.SoundSynthesizerEffects.frequencyVibratoEffect;
|
|
3004
|
-
fx.effects[2].parameter[0] = fxParam;
|
|
3005
|
-
break;
|
|
3006
|
-
case 2:
|
|
3007
|
-
fx.effects[2].steps = normalizedFxnSteps;
|
|
3008
|
-
fx.effects[2].effect = music.SoundSynthesizerEffects.volumeVibratoEffect;
|
|
3009
|
-
fx.effects[2].parameter[0] = fxParam;
|
|
3010
|
-
break;
|
|
3011
|
-
case 3:
|
|
3012
|
-
fx.effects[2].steps = normalizedFxnSteps;
|
|
3013
|
-
fx.effects[2].effect = music.SoundSynthesizerEffects.warbleInterpolation;
|
|
3014
|
-
fx.effects[2].parameter[0] = fxParam;
|
|
3015
|
-
break;
|
|
3016
|
-
}
|
|
3017
|
-
return true;
|
|
3018
|
-
}
|
|
3019
|
-
music.parseSoundExpression = parseSoundExpression;
|
|
3020
|
-
function random(max) {
|
|
3021
|
-
return Math.floor(Math.random() * max);
|
|
3022
|
-
}
|
|
3023
|
-
function CLAMP(min, value, max) {
|
|
3024
|
-
return Math.min(max, Math.max(min, value));
|
|
3025
|
-
}
|
|
3026
|
-
function applyRandom(value, rand) {
|
|
3027
|
-
if (value < 0 || rand < 0) {
|
|
3028
|
-
return -1;
|
|
3029
|
-
}
|
|
3030
|
-
const delta = random(rand * 2 + 1) - rand;
|
|
3031
|
-
return Math.abs(value + delta);
|
|
3032
|
-
}
|
|
3033
|
-
function blankSoundEffect() {
|
|
3034
|
-
const res = {
|
|
3035
|
-
frequency: 0,
|
|
3036
|
-
volume: 1,
|
|
3037
|
-
duration: 0,
|
|
3038
|
-
tone: {
|
|
3039
|
-
tonePrint: undefined,
|
|
3040
|
-
parameter: [0]
|
|
3041
|
-
},
|
|
3042
|
-
effects: []
|
|
3043
|
-
};
|
|
3044
|
-
for (let i = 0; i < music.EMOJI_SYNTHESIZER_TONE_EFFECTS; i++) {
|
|
3045
|
-
res.effects.push({
|
|
3046
|
-
effect: undefined,
|
|
3047
|
-
step: 0,
|
|
3048
|
-
steps: 0,
|
|
3049
|
-
parameter: [],
|
|
3050
|
-
parameter_p: []
|
|
3051
|
-
});
|
|
3052
|
-
}
|
|
3053
|
-
return res;
|
|
3054
|
-
}
|
|
3055
|
-
function delayAsync(millis) {
|
|
3056
|
-
return new Promise(resolve => setTimeout(resolve, millis));
|
|
2378
|
+
const giggle = "giggle";
|
|
2379
|
+
const giggleData = "010230988019008440044008881023001601003300240000000000000000000000000000,110232570087411440044008880352005901003300010000000000000000010000000000,310232729021105440288908880091006300000000240700020000000000003000000000,310232729010205440288908880091006300000000240700020000000000003000000000,310232729011405440288908880091006300000000240700020000000000003000000000";
|
|
2380
|
+
const happy = "happy";
|
|
2381
|
+
const happyData = "010231992066911440044008880262002800001800020500000000000000010000000000,002322129029508440240408880000000400022400110000000000000000007500000000,000002129029509440240408880145000400022400110000000000000000007500000000";
|
|
2382
|
+
const hello = "hello";
|
|
2383
|
+
const helloData = "310230673019702440118708881023012800000000240000000000000000000000000000,300001064001602440098108880000012800000100040000000000000000000000000000,310231064029302440098108881023012800000100040000000000000000000000000000";
|
|
2384
|
+
const mysterious = "mysterious";
|
|
2385
|
+
const mysteriousData = "400002390033100440240408880477000400022400110400000000000000008000000000,405512845385000440044008880000012803010500160000000000000000085000500015";
|
|
2386
|
+
const sad = "sad";
|
|
2387
|
+
const sadData = "310232226070801440162408881023012800000100240000000000000000000000000000,310231623093602440093908880000012800000100240000000000000000000000000000";
|
|
2388
|
+
const slide = "slide";
|
|
2389
|
+
const slideData = "105202325022302440240408881023012801020000110400000000000000010000000000,010232520091002440044008881023012801022400110400000000000000010000000000";
|
|
2390
|
+
const soaring = "soaring";
|
|
2391
|
+
const soaringData = "210234009530905440599908881023002202000400020250000000000000020000000000,402233727273014440044008880000003101024400030000000000000000000000000000";
|
|
2392
|
+
const spring = "spring";
|
|
2393
|
+
const springData = "306590037116312440058708880807003400000000240000000000000000050000000000,010230037116313440058708881023003100000000240000000000000000050000000000";
|
|
2394
|
+
const twinkle = "twinkle";
|
|
2395
|
+
const twinkleData = "010180007672209440075608880855012800000000240000000000000000000000000000";
|
|
2396
|
+
const yawn = "yawn";
|
|
2397
|
+
const yawnData = "200002281133202440150008881023012801024100240400030000000000010000000000,005312520091002440044008880636012801022400110300000000000000010000000000,008220784019008440044008880681001600005500240000000000000000005000000000,004790784019008440044008880298001600000000240000000000000000005000000000,003210784019008440044008880108001600003300080000000000000000005000000000";
|
|
2398
|
+
function lookupBuiltIn(sound) {
|
|
2399
|
+
if (sound == giggle)
|
|
2400
|
+
return giggleData;
|
|
2401
|
+
if (sound == happy)
|
|
2402
|
+
return happyData;
|
|
2403
|
+
if (sound == hello)
|
|
2404
|
+
return helloData;
|
|
2405
|
+
if (sound == mysterious)
|
|
2406
|
+
return mysteriousData;
|
|
2407
|
+
if (sound == sad)
|
|
2408
|
+
return sadData;
|
|
2409
|
+
if (sound == slide)
|
|
2410
|
+
return slideData;
|
|
2411
|
+
if (sound == soaring)
|
|
2412
|
+
return soaringData;
|
|
2413
|
+
if (sound == spring)
|
|
2414
|
+
return springData;
|
|
2415
|
+
if (sound == twinkle)
|
|
2416
|
+
return twinkleData;
|
|
2417
|
+
if (sound == yawn)
|
|
2418
|
+
return yawnData;
|
|
2419
|
+
return sound;
|
|
3057
2420
|
}
|
|
3058
2421
|
})(music = pxsim.music || (pxsim.music = {}));
|
|
3059
2422
|
})(pxsim || (pxsim = {}));
|
|
@@ -3817,7 +3180,7 @@ path.sim-board {
|
|
|
3817
3180
|
let pt = this.element.createSVGPoint();
|
|
3818
3181
|
pxsim.svg.buttonEvents(this.head, (ev) => {
|
|
3819
3182
|
let cur = pxsim.svg.cursorPoint(pt, this.element, ev);
|
|
3820
|
-
state.compassState.heading =
|
|
3183
|
+
state.compassState.heading = Math.floor(Math.atan2(cur.y - yc, cur.x - xc) * 180 / Math.PI) + 90;
|
|
3821
3184
|
if (state.compassState.heading < 0)
|
|
3822
3185
|
state.compassState.heading += 360;
|
|
3823
3186
|
this.updateHeading();
|
|
@@ -3826,7 +3189,7 @@ path.sim-board {
|
|
|
3826
3189
|
}
|
|
3827
3190
|
let txt = state.compassState.heading.toString() + "°";
|
|
3828
3191
|
if (txt != this.headText.textContent) {
|
|
3829
|
-
pxsim.svg.rotateElement(this.head, xc, yc,
|
|
3192
|
+
pxsim.svg.rotateElement(this.head, xc, yc, state.compassState.heading - 180);
|
|
3830
3193
|
this.headText.textContent = txt;
|
|
3831
3194
|
if (this.props.runtime)
|
|
3832
3195
|
this.props.runtime.environmentGlobals[pxsim.localization.lf("heading")] = state.compassState.heading;
|