pxt-core 7.5.14 → 7.5.15
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/pxt.js +95 -26
- package/built/pxtblockly.js +22 -4
- package/built/pxtblocks.d.ts +2 -0
- package/built/pxtblocks.js +22 -4
- package/built/pxtsim.d.ts +1 -0
- package/built/pxtsim.js +95 -26
- package/built/target.js +1 -1
- package/built/web/main.js +1 -1
- package/built/web/pxtapp.js +1 -1
- package/built/web/pxtblockly.js +1 -1
- package/built/web/pxtblocks.js +1 -1
- package/built/web/pxtembed.js +1 -1
- package/built/web/pxtsim.js +1 -1
- package/built/web/react-common-authcode.css +6 -0
- package/built/web/react-common-skillmap.css +1 -1
- package/built/web/rtlreact-common-skillmap.css +1 -1
- package/built/web/rtlsemantic.css +1 -1
- package/built/web/semantic.css +1 -1
- package/package.json +1 -1
- package/react-common/components/controls/DraggableGraph.tsx +8 -4
- package/react-common/styles/controls/Dropdown.less +5 -0
- package/react-common/styles/controls/RadioButtonGroup.less +7 -0
- package/theme/soundeffecteditor.less +21 -5
package/built/pxt.js
CHANGED
|
@@ -153626,9 +153626,19 @@ var pxsim;
|
|
|
153626
153626
|
let _mute = false; //mute audio
|
|
153627
153627
|
// for playing WAV
|
|
153628
153628
|
let audio;
|
|
153629
|
+
const channels = [];
|
|
153630
|
+
// All other nodes get connected to this node which is connected to the actual
|
|
153631
|
+
// destination. Used for muting
|
|
153632
|
+
let destination;
|
|
153629
153633
|
function context() {
|
|
153630
|
-
if (!_context)
|
|
153634
|
+
if (!_context) {
|
|
153631
153635
|
_context = freshContext();
|
|
153636
|
+
if (_context) {
|
|
153637
|
+
destination = _context.createGain();
|
|
153638
|
+
destination.connect(_context.destination);
|
|
153639
|
+
destination.gain.setValueAtTime(1, 0);
|
|
153640
|
+
}
|
|
153641
|
+
}
|
|
153632
153642
|
return _context;
|
|
153633
153643
|
}
|
|
153634
153644
|
function freshContext() {
|
|
@@ -153645,8 +153655,13 @@ var pxsim;
|
|
|
153645
153655
|
}
|
|
153646
153656
|
function mute(mute) {
|
|
153647
153657
|
_mute = mute;
|
|
153648
|
-
stopAll();
|
|
153649
153658
|
const ctx = context();
|
|
153659
|
+
if (mute) {
|
|
153660
|
+
destination.gain.setTargetAtTime(0, ctx.currentTime, 0.015);
|
|
153661
|
+
}
|
|
153662
|
+
else {
|
|
153663
|
+
destination.gain.setTargetAtTime(1, ctx.currentTime, 0.015);
|
|
153664
|
+
}
|
|
153650
153665
|
if (!mute && ctx && ctx.state === "suspended")
|
|
153651
153666
|
ctx.resume();
|
|
153652
153667
|
}
|
|
@@ -153840,9 +153855,8 @@ var pxsim;
|
|
|
153840
153855
|
node.playbackRate.value = hz / (context().sampleRate / 1024);
|
|
153841
153856
|
return node;
|
|
153842
153857
|
}
|
|
153843
|
-
const channels = [];
|
|
153844
153858
|
class Channel {
|
|
153845
|
-
|
|
153859
|
+
disconnectNodes() {
|
|
153846
153860
|
if (this.gain)
|
|
153847
153861
|
disconnectVca(this.gain, this.generator);
|
|
153848
153862
|
else if (this.generator) {
|
|
@@ -153856,7 +153870,7 @@ var pxsim;
|
|
|
153856
153870
|
const idx = channels.indexOf(this);
|
|
153857
153871
|
if (idx >= 0)
|
|
153858
153872
|
channels.splice(idx, 1);
|
|
153859
|
-
this.
|
|
153873
|
+
this.disconnectNodes();
|
|
153860
153874
|
}
|
|
153861
153875
|
}
|
|
153862
153876
|
let instrStopId = 1;
|
|
@@ -153890,7 +153904,7 @@ var pxsim;
|
|
|
153890
153904
|
/** Square waves are perceved as much louder than other sounds, so scale it down a bit to make it less jarring **/
|
|
153891
153905
|
const scaleVol = (n, isSqWave) => (n / 1024) / 4 * (isSqWave ? .5 : 1);
|
|
153892
153906
|
const finish = () => {
|
|
153893
|
-
ch.
|
|
153907
|
+
ch.disconnectNodes();
|
|
153894
153908
|
timeOff = 0;
|
|
153895
153909
|
currWave = -1;
|
|
153896
153910
|
currFreq = -1;
|
|
@@ -153918,7 +153932,7 @@ var pxsim;
|
|
|
153918
153932
|
return loopAsync();
|
|
153919
153933
|
});
|
|
153920
153934
|
}
|
|
153921
|
-
ch.generator =
|
|
153935
|
+
ch.generator = getGenerator(soundWaveIdx, freq);
|
|
153922
153936
|
if (!ch.generator)
|
|
153923
153937
|
return pxsim.U.delay(duration);
|
|
153924
153938
|
currWave = soundWaveIdx;
|
|
@@ -153940,7 +153954,7 @@ var pxsim;
|
|
|
153940
153954
|
}
|
|
153941
153955
|
}
|
|
153942
153956
|
ch.generator.connect(ch.gain);
|
|
153943
|
-
ch.gain.connect(
|
|
153957
|
+
ch.gain.connect(destination);
|
|
153944
153958
|
ch.generator.start();
|
|
153945
153959
|
}
|
|
153946
153960
|
idx += 12;
|
|
@@ -153973,7 +153987,7 @@ var pxsim;
|
|
|
153973
153987
|
_vca.gain.value = 0;
|
|
153974
153988
|
_vco.type = 'triangle';
|
|
153975
153989
|
_vco.connect(_vca);
|
|
153976
|
-
_vca.connect(
|
|
153990
|
+
_vca.connect(destination);
|
|
153977
153991
|
_vco.start(0);
|
|
153978
153992
|
}
|
|
153979
153993
|
setCurrentToneGain(gain);
|
|
@@ -153989,7 +154003,7 @@ var pxsim;
|
|
|
153989
154003
|
AudioContextManager.tone = tone;
|
|
153990
154004
|
function setCurrentToneGain(gain) {
|
|
153991
154005
|
if (_vca === null || _vca === void 0 ? void 0 : _vca.gain) {
|
|
153992
|
-
_vca.gain.setTargetAtTime(
|
|
154006
|
+
_vca.gain.setTargetAtTime(gain, _context.currentTime, 0.015);
|
|
153993
154007
|
}
|
|
153994
154008
|
}
|
|
153995
154009
|
AudioContextManager.setCurrentToneGain = setCurrentToneGain;
|
|
@@ -154026,13 +154040,30 @@ var pxsim;
|
|
|
154026
154040
|
let nodes = [];
|
|
154027
154041
|
let nextTime = context().currentTime;
|
|
154028
154042
|
let allScheduled = false;
|
|
154043
|
+
const channel = new Channel();
|
|
154044
|
+
channel.gain = context().createGain();
|
|
154045
|
+
channel.gain.gain.value = 0;
|
|
154046
|
+
channel.gain.gain.setValueAtTime(volume, context().currentTime);
|
|
154047
|
+
channel.gain.connect(destination);
|
|
154048
|
+
if (channels.length > 5)
|
|
154049
|
+
channels[0].remove();
|
|
154050
|
+
channels.push(channel);
|
|
154051
|
+
const checkCancel = () => {
|
|
154052
|
+
if (isCancelled && isCancelled() || !channel.gain) {
|
|
154053
|
+
if (resolve)
|
|
154054
|
+
resolve();
|
|
154055
|
+
resolve = undefined;
|
|
154056
|
+
channel.remove();
|
|
154057
|
+
return true;
|
|
154058
|
+
}
|
|
154059
|
+
return false;
|
|
154060
|
+
};
|
|
154029
154061
|
// Every time we pull a buffer, schedule a node in the future to play it.
|
|
154030
154062
|
// Scheduling the nodes ahead of time sounds much smoother than trying to
|
|
154031
154063
|
// do it when the previous node completes (which sounds SUPER choppy in
|
|
154032
154064
|
// FireFox).
|
|
154033
154065
|
function playNext() {
|
|
154034
|
-
|
|
154035
|
-
while (!allScheduled && nodes.length < MAX_SCHEDULED_BUFFER_NODES && !cancelled) {
|
|
154066
|
+
while (!allScheduled && nodes.length < MAX_SCHEDULED_BUFFER_NODES && !checkCancel()) {
|
|
154036
154067
|
const data = pull();
|
|
154037
154068
|
if (!data || !data.length) {
|
|
154038
154069
|
allScheduled = true;
|
|
@@ -154048,6 +154079,8 @@ var pxsim;
|
|
|
154048
154079
|
}
|
|
154049
154080
|
}
|
|
154050
154081
|
function play(data) {
|
|
154082
|
+
if (checkCancel())
|
|
154083
|
+
return;
|
|
154051
154084
|
const buff = context().createBuffer(1, data.length, sampleRate);
|
|
154052
154085
|
if (buff.copyToChannel) {
|
|
154053
154086
|
buff.copyToChannel(data, 0);
|
|
@@ -154070,15 +154103,6 @@ var pxsim;
|
|
|
154070
154103
|
newNode.start(nextTime);
|
|
154071
154104
|
nextTime += buff.duration;
|
|
154072
154105
|
}
|
|
154073
|
-
const channel = new Channel();
|
|
154074
|
-
channel.gain = context().createGain();
|
|
154075
|
-
channel.gain.gain.value = 0;
|
|
154076
|
-
if (!_mute)
|
|
154077
|
-
channel.gain.gain.setValueAtTime(volume, context().currentTime);
|
|
154078
|
-
channel.gain.connect(context().destination);
|
|
154079
|
-
if (channels.length > 5)
|
|
154080
|
-
channels[0].remove();
|
|
154081
|
-
channels.push(channel);
|
|
154082
154106
|
playNext();
|
|
154083
154107
|
});
|
|
154084
154108
|
}
|
|
@@ -155103,18 +155127,62 @@ var pxsim;
|
|
|
155103
155127
|
result = "0" + result;
|
|
155104
155128
|
return result;
|
|
155105
155129
|
}
|
|
155106
|
-
let
|
|
155130
|
+
let playing = false;
|
|
155131
|
+
let soundQueue;
|
|
155132
|
+
let cancellationToken = {
|
|
155133
|
+
cancelled: false
|
|
155134
|
+
};
|
|
155107
155135
|
function __playSoundExpression(notes, waitTillDone) {
|
|
155136
|
+
if (!soundQueue)
|
|
155137
|
+
soundQueue = [];
|
|
155108
155138
|
const cb = pxsim.getResume();
|
|
155109
|
-
|
|
155110
|
-
|
|
155111
|
-
|
|
155139
|
+
const soundPromise = new Promise((resolve, reject) => {
|
|
155140
|
+
soundQueue.push({
|
|
155141
|
+
notes,
|
|
155142
|
+
onFinished: resolve,
|
|
155143
|
+
onCancelled: reject
|
|
155144
|
+
});
|
|
155145
|
+
});
|
|
155146
|
+
if (!playing) {
|
|
155147
|
+
playNextSoundAsync();
|
|
155148
|
+
}
|
|
155112
155149
|
if (!waitTillDone)
|
|
155113
155150
|
cb();
|
|
155114
155151
|
else
|
|
155115
|
-
soundPromise
|
|
155152
|
+
soundPromise.then(cb);
|
|
155116
155153
|
}
|
|
155117
155154
|
music.__playSoundExpression = __playSoundExpression;
|
|
155155
|
+
async function playNextSoundAsync() {
|
|
155156
|
+
if (soundQueue.length) {
|
|
155157
|
+
playing = true;
|
|
155158
|
+
const sound = soundQueue.shift();
|
|
155159
|
+
let currentToken = cancellationToken;
|
|
155160
|
+
try {
|
|
155161
|
+
await playSoundExpressionAsync(sound.notes, () => currentToken.cancelled);
|
|
155162
|
+
if (currentToken.cancelled) {
|
|
155163
|
+
sound.onCancelled();
|
|
155164
|
+
}
|
|
155165
|
+
else {
|
|
155166
|
+
sound.onFinished();
|
|
155167
|
+
}
|
|
155168
|
+
}
|
|
155169
|
+
catch (_a) {
|
|
155170
|
+
sound.onCancelled();
|
|
155171
|
+
}
|
|
155172
|
+
playNextSoundAsync();
|
|
155173
|
+
}
|
|
155174
|
+
else {
|
|
155175
|
+
playing = false;
|
|
155176
|
+
}
|
|
155177
|
+
}
|
|
155178
|
+
function clearSoundQueue() {
|
|
155179
|
+
soundQueue = [];
|
|
155180
|
+
cancellationToken.cancelled = true;
|
|
155181
|
+
cancellationToken = {
|
|
155182
|
+
cancelled: false
|
|
155183
|
+
};
|
|
155184
|
+
}
|
|
155185
|
+
music.clearSoundQueue = clearSoundQueue;
|
|
155118
155186
|
function playSoundExpressionAsync(notes, isCancelled, onPull) {
|
|
155119
155187
|
const synth = new music.SoundEmojiSynthesizer(0);
|
|
155120
155188
|
const soundEffects = parseSoundEffects(notes);
|
|
@@ -155146,6 +155214,7 @@ var pxsim;
|
|
|
155146
155214
|
}
|
|
155147
155215
|
music.playSoundExpressionAsync = playSoundExpressionAsync;
|
|
155148
155216
|
function __stopSoundExpressions() {
|
|
155217
|
+
clearSoundQueue();
|
|
155149
155218
|
pxsim.AudioContextManager.stopAll();
|
|
155150
155219
|
}
|
|
155151
155220
|
music.__stopSoundExpressions = __stopSoundExpressions;
|
package/built/pxtblockly.js
CHANGED
|
@@ -7828,6 +7828,7 @@ var pxt;
|
|
|
7828
7828
|
return;
|
|
7829
7829
|
}
|
|
7830
7830
|
}
|
|
7831
|
+
const hasInput = (name) => { var _a; return (_a = block.inputList) === null || _a === void 0 ? void 0 : _a.some(i => i.name === name); };
|
|
7831
7832
|
inputs.forEach(inputParts => {
|
|
7832
7833
|
const fields = [];
|
|
7833
7834
|
let inputName;
|
|
@@ -7976,12 +7977,19 @@ var pxt;
|
|
|
7976
7977
|
});
|
|
7977
7978
|
let input;
|
|
7978
7979
|
if (inputName) {
|
|
7980
|
+
// Don't add duplicate inputs
|
|
7981
|
+
if (hasInput(inputName))
|
|
7982
|
+
return;
|
|
7979
7983
|
input = block.appendValueInput(inputName);
|
|
7980
7984
|
input.setAlign(Blockly.ALIGN_LEFT);
|
|
7981
7985
|
}
|
|
7982
7986
|
else if (expanded) {
|
|
7983
7987
|
const prefix = hasParameter ? blocks_4.optionalInputWithFieldPrefix : blocks_4.optionalDummyInputPrefix;
|
|
7984
|
-
|
|
7988
|
+
inputName = prefix + (anonIndex++);
|
|
7989
|
+
// Don't add duplicate inputs
|
|
7990
|
+
if (hasInput(inputName))
|
|
7991
|
+
return;
|
|
7992
|
+
input = block.appendDummyInput(inputName);
|
|
7985
7993
|
}
|
|
7986
7994
|
else {
|
|
7987
7995
|
input = block.appendDummyInput();
|
|
@@ -15149,6 +15157,7 @@ var pxtblockly;
|
|
|
15149
15157
|
class FieldSoundEffect extends pxtblockly.FieldBase {
|
|
15150
15158
|
constructor() {
|
|
15151
15159
|
super(...arguments);
|
|
15160
|
+
this.registeredChangeListener = false;
|
|
15152
15161
|
this.onWorkspaceChange = (ev) => {
|
|
15153
15162
|
if (ev.type !== Blockly.Events.CHANGE)
|
|
15154
15163
|
return;
|
|
@@ -15178,10 +15187,19 @@ var pxtblockly;
|
|
|
15178
15187
|
if (!this.options.effectFieldName)
|
|
15179
15188
|
this.options.effectFieldName = "effect";
|
|
15180
15189
|
this.redrawPreview();
|
|
15181
|
-
this.sourceBlock_.workspace
|
|
15190
|
+
if (this.sourceBlock_.workspace) {
|
|
15191
|
+
this.workspace = this.sourceBlock_.workspace;
|
|
15192
|
+
if (!this.sourceBlock_.isShadow() && !this.sourceBlock_.isInsertionMarker()) {
|
|
15193
|
+
this.registeredChangeListener = true;
|
|
15194
|
+
this.workspace.addChangeListener(this.onWorkspaceChange);
|
|
15195
|
+
}
|
|
15196
|
+
}
|
|
15182
15197
|
}
|
|
15183
15198
|
onDispose() {
|
|
15184
|
-
this.
|
|
15199
|
+
if (this.workspace && this.registeredChangeListener) {
|
|
15200
|
+
this.workspace.removeChangeListener(this.onWorkspaceChange);
|
|
15201
|
+
this.registeredChangeListener = false;
|
|
15202
|
+
}
|
|
15185
15203
|
}
|
|
15186
15204
|
onValueChanged(newValue) {
|
|
15187
15205
|
return newValue;
|
|
@@ -15347,7 +15365,7 @@ var pxtblockly;
|
|
|
15347
15365
|
render_() {
|
|
15348
15366
|
super.render_();
|
|
15349
15367
|
this.size_.height = TOTAL_HEIGHT + Y_PADDING * 2;
|
|
15350
|
-
this.size_.width = TOTAL_WIDTH;
|
|
15368
|
+
this.size_.width = TOTAL_WIDTH + X_PADDING;
|
|
15351
15369
|
}
|
|
15352
15370
|
updateSiblingBlocks(sound) {
|
|
15353
15371
|
this.setNumberInputValue(this.options.durationInputName, sound.duration);
|
package/built/pxtblocks.d.ts
CHANGED
|
@@ -1145,6 +1145,8 @@ declare namespace pxtblockly {
|
|
|
1145
1145
|
class FieldSoundEffect extends FieldBase<FieldSoundEffectParams> {
|
|
1146
1146
|
protected mostRecentValue: pxt.assets.Sound;
|
|
1147
1147
|
protected drawnSound: pxt.assets.Sound;
|
|
1148
|
+
protected workspace: Blockly.Workspace;
|
|
1149
|
+
protected registeredChangeListener: boolean;
|
|
1148
1150
|
protected onInit(): void;
|
|
1149
1151
|
protected onDispose(): void;
|
|
1150
1152
|
protected onValueChanged(newValue: string): string;
|
package/built/pxtblocks.js
CHANGED
|
@@ -4266,6 +4266,7 @@ var pxt;
|
|
|
4266
4266
|
return;
|
|
4267
4267
|
}
|
|
4268
4268
|
}
|
|
4269
|
+
const hasInput = (name) => { var _a; return (_a = block.inputList) === null || _a === void 0 ? void 0 : _a.some(i => i.name === name); };
|
|
4269
4270
|
inputs.forEach(inputParts => {
|
|
4270
4271
|
const fields = [];
|
|
4271
4272
|
let inputName;
|
|
@@ -4414,12 +4415,19 @@ var pxt;
|
|
|
4414
4415
|
});
|
|
4415
4416
|
let input;
|
|
4416
4417
|
if (inputName) {
|
|
4418
|
+
// Don't add duplicate inputs
|
|
4419
|
+
if (hasInput(inputName))
|
|
4420
|
+
return;
|
|
4417
4421
|
input = block.appendValueInput(inputName);
|
|
4418
4422
|
input.setAlign(Blockly.ALIGN_LEFT);
|
|
4419
4423
|
}
|
|
4420
4424
|
else if (expanded) {
|
|
4421
4425
|
const prefix = hasParameter ? blocks_4.optionalInputWithFieldPrefix : blocks_4.optionalDummyInputPrefix;
|
|
4422
|
-
|
|
4426
|
+
inputName = prefix + (anonIndex++);
|
|
4427
|
+
// Don't add duplicate inputs
|
|
4428
|
+
if (hasInput(inputName))
|
|
4429
|
+
return;
|
|
4430
|
+
input = block.appendDummyInput(inputName);
|
|
4423
4431
|
}
|
|
4424
4432
|
else {
|
|
4425
4433
|
input = block.appendDummyInput();
|
|
@@ -11587,6 +11595,7 @@ var pxtblockly;
|
|
|
11587
11595
|
class FieldSoundEffect extends pxtblockly.FieldBase {
|
|
11588
11596
|
constructor() {
|
|
11589
11597
|
super(...arguments);
|
|
11598
|
+
this.registeredChangeListener = false;
|
|
11590
11599
|
this.onWorkspaceChange = (ev) => {
|
|
11591
11600
|
if (ev.type !== Blockly.Events.CHANGE)
|
|
11592
11601
|
return;
|
|
@@ -11616,10 +11625,19 @@ var pxtblockly;
|
|
|
11616
11625
|
if (!this.options.effectFieldName)
|
|
11617
11626
|
this.options.effectFieldName = "effect";
|
|
11618
11627
|
this.redrawPreview();
|
|
11619
|
-
this.sourceBlock_.workspace
|
|
11628
|
+
if (this.sourceBlock_.workspace) {
|
|
11629
|
+
this.workspace = this.sourceBlock_.workspace;
|
|
11630
|
+
if (!this.sourceBlock_.isShadow() && !this.sourceBlock_.isInsertionMarker()) {
|
|
11631
|
+
this.registeredChangeListener = true;
|
|
11632
|
+
this.workspace.addChangeListener(this.onWorkspaceChange);
|
|
11633
|
+
}
|
|
11634
|
+
}
|
|
11620
11635
|
}
|
|
11621
11636
|
onDispose() {
|
|
11622
|
-
this.
|
|
11637
|
+
if (this.workspace && this.registeredChangeListener) {
|
|
11638
|
+
this.workspace.removeChangeListener(this.onWorkspaceChange);
|
|
11639
|
+
this.registeredChangeListener = false;
|
|
11640
|
+
}
|
|
11623
11641
|
}
|
|
11624
11642
|
onValueChanged(newValue) {
|
|
11625
11643
|
return newValue;
|
|
@@ -11785,7 +11803,7 @@ var pxtblockly;
|
|
|
11785
11803
|
render_() {
|
|
11786
11804
|
super.render_();
|
|
11787
11805
|
this.size_.height = TOTAL_HEIGHT + Y_PADDING * 2;
|
|
11788
|
-
this.size_.width = TOTAL_WIDTH;
|
|
11806
|
+
this.size_.width = TOTAL_WIDTH + X_PADDING;
|
|
11789
11807
|
}
|
|
11790
11808
|
updateSiblingBlocks(sound) {
|
|
11791
11809
|
this.setNumberInputValue(this.options.durationInputName, sound.duration);
|
package/built/pxtsim.d.ts
CHANGED
|
@@ -1728,6 +1728,7 @@ declare namespace pxsim.codal.music {
|
|
|
1728
1728
|
protected getValue(offset: number, length: number): number;
|
|
1729
1729
|
}
|
|
1730
1730
|
function __playSoundExpression(notes: string, waitTillDone: boolean): void;
|
|
1731
|
+
function clearSoundQueue(): void;
|
|
1731
1732
|
function playSoundExpressionAsync(notes: string, isCancelled?: () => boolean, onPull?: (freq: number, volume: number) => void): Promise<void>;
|
|
1732
1733
|
function __stopSoundExpressions(): void;
|
|
1733
1734
|
interface TonePrint {
|
package/built/pxtsim.js
CHANGED
|
@@ -6973,9 +6973,19 @@ var pxsim;
|
|
|
6973
6973
|
let _mute = false; //mute audio
|
|
6974
6974
|
// for playing WAV
|
|
6975
6975
|
let audio;
|
|
6976
|
+
const channels = [];
|
|
6977
|
+
// All other nodes get connected to this node which is connected to the actual
|
|
6978
|
+
// destination. Used for muting
|
|
6979
|
+
let destination;
|
|
6976
6980
|
function context() {
|
|
6977
|
-
if (!_context)
|
|
6981
|
+
if (!_context) {
|
|
6978
6982
|
_context = freshContext();
|
|
6983
|
+
if (_context) {
|
|
6984
|
+
destination = _context.createGain();
|
|
6985
|
+
destination.connect(_context.destination);
|
|
6986
|
+
destination.gain.setValueAtTime(1, 0);
|
|
6987
|
+
}
|
|
6988
|
+
}
|
|
6979
6989
|
return _context;
|
|
6980
6990
|
}
|
|
6981
6991
|
function freshContext() {
|
|
@@ -6992,8 +7002,13 @@ var pxsim;
|
|
|
6992
7002
|
}
|
|
6993
7003
|
function mute(mute) {
|
|
6994
7004
|
_mute = mute;
|
|
6995
|
-
stopAll();
|
|
6996
7005
|
const ctx = context();
|
|
7006
|
+
if (mute) {
|
|
7007
|
+
destination.gain.setTargetAtTime(0, ctx.currentTime, 0.015);
|
|
7008
|
+
}
|
|
7009
|
+
else {
|
|
7010
|
+
destination.gain.setTargetAtTime(1, ctx.currentTime, 0.015);
|
|
7011
|
+
}
|
|
6997
7012
|
if (!mute && ctx && ctx.state === "suspended")
|
|
6998
7013
|
ctx.resume();
|
|
6999
7014
|
}
|
|
@@ -7187,9 +7202,8 @@ var pxsim;
|
|
|
7187
7202
|
node.playbackRate.value = hz / (context().sampleRate / 1024);
|
|
7188
7203
|
return node;
|
|
7189
7204
|
}
|
|
7190
|
-
const channels = [];
|
|
7191
7205
|
class Channel {
|
|
7192
|
-
|
|
7206
|
+
disconnectNodes() {
|
|
7193
7207
|
if (this.gain)
|
|
7194
7208
|
disconnectVca(this.gain, this.generator);
|
|
7195
7209
|
else if (this.generator) {
|
|
@@ -7203,7 +7217,7 @@ var pxsim;
|
|
|
7203
7217
|
const idx = channels.indexOf(this);
|
|
7204
7218
|
if (idx >= 0)
|
|
7205
7219
|
channels.splice(idx, 1);
|
|
7206
|
-
this.
|
|
7220
|
+
this.disconnectNodes();
|
|
7207
7221
|
}
|
|
7208
7222
|
}
|
|
7209
7223
|
let instrStopId = 1;
|
|
@@ -7237,7 +7251,7 @@ var pxsim;
|
|
|
7237
7251
|
/** Square waves are perceved as much louder than other sounds, so scale it down a bit to make it less jarring **/
|
|
7238
7252
|
const scaleVol = (n, isSqWave) => (n / 1024) / 4 * (isSqWave ? .5 : 1);
|
|
7239
7253
|
const finish = () => {
|
|
7240
|
-
ch.
|
|
7254
|
+
ch.disconnectNodes();
|
|
7241
7255
|
timeOff = 0;
|
|
7242
7256
|
currWave = -1;
|
|
7243
7257
|
currFreq = -1;
|
|
@@ -7265,7 +7279,7 @@ var pxsim;
|
|
|
7265
7279
|
return loopAsync();
|
|
7266
7280
|
});
|
|
7267
7281
|
}
|
|
7268
|
-
ch.generator =
|
|
7282
|
+
ch.generator = getGenerator(soundWaveIdx, freq);
|
|
7269
7283
|
if (!ch.generator)
|
|
7270
7284
|
return pxsim.U.delay(duration);
|
|
7271
7285
|
currWave = soundWaveIdx;
|
|
@@ -7287,7 +7301,7 @@ var pxsim;
|
|
|
7287
7301
|
}
|
|
7288
7302
|
}
|
|
7289
7303
|
ch.generator.connect(ch.gain);
|
|
7290
|
-
ch.gain.connect(
|
|
7304
|
+
ch.gain.connect(destination);
|
|
7291
7305
|
ch.generator.start();
|
|
7292
7306
|
}
|
|
7293
7307
|
idx += 12;
|
|
@@ -7320,7 +7334,7 @@ var pxsim;
|
|
|
7320
7334
|
_vca.gain.value = 0;
|
|
7321
7335
|
_vco.type = 'triangle';
|
|
7322
7336
|
_vco.connect(_vca);
|
|
7323
|
-
_vca.connect(
|
|
7337
|
+
_vca.connect(destination);
|
|
7324
7338
|
_vco.start(0);
|
|
7325
7339
|
}
|
|
7326
7340
|
setCurrentToneGain(gain);
|
|
@@ -7336,7 +7350,7 @@ var pxsim;
|
|
|
7336
7350
|
AudioContextManager.tone = tone;
|
|
7337
7351
|
function setCurrentToneGain(gain) {
|
|
7338
7352
|
if (_vca === null || _vca === void 0 ? void 0 : _vca.gain) {
|
|
7339
|
-
_vca.gain.setTargetAtTime(
|
|
7353
|
+
_vca.gain.setTargetAtTime(gain, _context.currentTime, 0.015);
|
|
7340
7354
|
}
|
|
7341
7355
|
}
|
|
7342
7356
|
AudioContextManager.setCurrentToneGain = setCurrentToneGain;
|
|
@@ -7373,13 +7387,30 @@ var pxsim;
|
|
|
7373
7387
|
let nodes = [];
|
|
7374
7388
|
let nextTime = context().currentTime;
|
|
7375
7389
|
let allScheduled = false;
|
|
7390
|
+
const channel = new Channel();
|
|
7391
|
+
channel.gain = context().createGain();
|
|
7392
|
+
channel.gain.gain.value = 0;
|
|
7393
|
+
channel.gain.gain.setValueAtTime(volume, context().currentTime);
|
|
7394
|
+
channel.gain.connect(destination);
|
|
7395
|
+
if (channels.length > 5)
|
|
7396
|
+
channels[0].remove();
|
|
7397
|
+
channels.push(channel);
|
|
7398
|
+
const checkCancel = () => {
|
|
7399
|
+
if (isCancelled && isCancelled() || !channel.gain) {
|
|
7400
|
+
if (resolve)
|
|
7401
|
+
resolve();
|
|
7402
|
+
resolve = undefined;
|
|
7403
|
+
channel.remove();
|
|
7404
|
+
return true;
|
|
7405
|
+
}
|
|
7406
|
+
return false;
|
|
7407
|
+
};
|
|
7376
7408
|
// Every time we pull a buffer, schedule a node in the future to play it.
|
|
7377
7409
|
// Scheduling the nodes ahead of time sounds much smoother than trying to
|
|
7378
7410
|
// do it when the previous node completes (which sounds SUPER choppy in
|
|
7379
7411
|
// FireFox).
|
|
7380
7412
|
function playNext() {
|
|
7381
|
-
|
|
7382
|
-
while (!allScheduled && nodes.length < MAX_SCHEDULED_BUFFER_NODES && !cancelled) {
|
|
7413
|
+
while (!allScheduled && nodes.length < MAX_SCHEDULED_BUFFER_NODES && !checkCancel()) {
|
|
7383
7414
|
const data = pull();
|
|
7384
7415
|
if (!data || !data.length) {
|
|
7385
7416
|
allScheduled = true;
|
|
@@ -7395,6 +7426,8 @@ var pxsim;
|
|
|
7395
7426
|
}
|
|
7396
7427
|
}
|
|
7397
7428
|
function play(data) {
|
|
7429
|
+
if (checkCancel())
|
|
7430
|
+
return;
|
|
7398
7431
|
const buff = context().createBuffer(1, data.length, sampleRate);
|
|
7399
7432
|
if (buff.copyToChannel) {
|
|
7400
7433
|
buff.copyToChannel(data, 0);
|
|
@@ -7417,15 +7450,6 @@ var pxsim;
|
|
|
7417
7450
|
newNode.start(nextTime);
|
|
7418
7451
|
nextTime += buff.duration;
|
|
7419
7452
|
}
|
|
7420
|
-
const channel = new Channel();
|
|
7421
|
-
channel.gain = context().createGain();
|
|
7422
|
-
channel.gain.gain.value = 0;
|
|
7423
|
-
if (!_mute)
|
|
7424
|
-
channel.gain.gain.setValueAtTime(volume, context().currentTime);
|
|
7425
|
-
channel.gain.connect(context().destination);
|
|
7426
|
-
if (channels.length > 5)
|
|
7427
|
-
channels[0].remove();
|
|
7428
|
-
channels.push(channel);
|
|
7429
7453
|
playNext();
|
|
7430
7454
|
});
|
|
7431
7455
|
}
|
|
@@ -8450,18 +8474,62 @@ var pxsim;
|
|
|
8450
8474
|
result = "0" + result;
|
|
8451
8475
|
return result;
|
|
8452
8476
|
}
|
|
8453
|
-
let
|
|
8477
|
+
let playing = false;
|
|
8478
|
+
let soundQueue;
|
|
8479
|
+
let cancellationToken = {
|
|
8480
|
+
cancelled: false
|
|
8481
|
+
};
|
|
8454
8482
|
function __playSoundExpression(notes, waitTillDone) {
|
|
8483
|
+
if (!soundQueue)
|
|
8484
|
+
soundQueue = [];
|
|
8455
8485
|
const cb = pxsim.getResume();
|
|
8456
|
-
|
|
8457
|
-
|
|
8458
|
-
|
|
8486
|
+
const soundPromise = new Promise((resolve, reject) => {
|
|
8487
|
+
soundQueue.push({
|
|
8488
|
+
notes,
|
|
8489
|
+
onFinished: resolve,
|
|
8490
|
+
onCancelled: reject
|
|
8491
|
+
});
|
|
8492
|
+
});
|
|
8493
|
+
if (!playing) {
|
|
8494
|
+
playNextSoundAsync();
|
|
8495
|
+
}
|
|
8459
8496
|
if (!waitTillDone)
|
|
8460
8497
|
cb();
|
|
8461
8498
|
else
|
|
8462
|
-
soundPromise
|
|
8499
|
+
soundPromise.then(cb);
|
|
8463
8500
|
}
|
|
8464
8501
|
music.__playSoundExpression = __playSoundExpression;
|
|
8502
|
+
async function playNextSoundAsync() {
|
|
8503
|
+
if (soundQueue.length) {
|
|
8504
|
+
playing = true;
|
|
8505
|
+
const sound = soundQueue.shift();
|
|
8506
|
+
let currentToken = cancellationToken;
|
|
8507
|
+
try {
|
|
8508
|
+
await playSoundExpressionAsync(sound.notes, () => currentToken.cancelled);
|
|
8509
|
+
if (currentToken.cancelled) {
|
|
8510
|
+
sound.onCancelled();
|
|
8511
|
+
}
|
|
8512
|
+
else {
|
|
8513
|
+
sound.onFinished();
|
|
8514
|
+
}
|
|
8515
|
+
}
|
|
8516
|
+
catch (_a) {
|
|
8517
|
+
sound.onCancelled();
|
|
8518
|
+
}
|
|
8519
|
+
playNextSoundAsync();
|
|
8520
|
+
}
|
|
8521
|
+
else {
|
|
8522
|
+
playing = false;
|
|
8523
|
+
}
|
|
8524
|
+
}
|
|
8525
|
+
function clearSoundQueue() {
|
|
8526
|
+
soundQueue = [];
|
|
8527
|
+
cancellationToken.cancelled = true;
|
|
8528
|
+
cancellationToken = {
|
|
8529
|
+
cancelled: false
|
|
8530
|
+
};
|
|
8531
|
+
}
|
|
8532
|
+
music.clearSoundQueue = clearSoundQueue;
|
|
8465
8533
|
function playSoundExpressionAsync(notes, isCancelled, onPull) {
|
|
8466
8534
|
const synth = new music.SoundEmojiSynthesizer(0);
|
|
8467
8535
|
const soundEffects = parseSoundEffects(notes);
|
|
@@ -8493,6 +8561,7 @@ var pxsim;
|
|
|
8493
8561
|
}
|
|
8494
8562
|
music.playSoundExpressionAsync = playSoundExpressionAsync;
|
|
8495
8563
|
function __stopSoundExpressions() {
|
|
8564
|
+
clearSoundQueue();
|
|
8496
8565
|
pxsim.AudioContextManager.stopAll();
|
|
8497
8566
|
}
|
|
8498
8567
|
music.__stopSoundExpressions = __stopSoundExpressions;
|