pxt-core 8.4.2 → 8.4.3
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/backendutils.js +1 -0
- package/built/cli.js +83 -75
- package/built/pxt.js +1264 -176
- package/built/pxtblockly.js +323 -40
- package/built/pxtblocks.d.ts +30 -7
- package/built/pxtblocks.js +324 -41
- package/built/pxtlib.d.ts +91 -5
- package/built/pxtlib.js +1173 -98
- package/built/pxtsim.js +8 -3
- package/built/server.js +4 -0
- package/built/target.js +1 -1
- package/built/web/main.js +1 -1
- package/built/web/multiplayer/css/main.2dd69ed8.css +4 -0
- package/built/web/multiplayer/js/main.f3b8f930.js +2 -0
- package/built/web/pxtapp.js +1 -1
- package/built/web/pxtasseteditor.js +1 -1
- package/built/web/pxtblockly.js +1 -1
- package/built/web/pxtblocks.js +1 -1
- package/built/web/pxtembed.js +2 -2
- package/built/web/pxtlib.js +1 -1
- package/built/web/pxtsim.js +1 -1
- package/built/web/pxtworker.js +2 -2
- package/built/web/react-common-authcode.css +4 -6993
- package/built/web/react-common-multiplayer.css +13 -0
- package/built/web/react-common-skillmap.css +1 -1
- package/built/web/rtlreact-common-authcode.css +13 -0
- package/built/web/rtlreact-common-multiplayer.css +13 -0
- package/built/web/rtlreact-common-skillmap.css +1 -1
- package/built/web/rtlsemantic.css +1 -1
- package/built/web/semantic.css +1 -1
- package/built/web/skillmap/js/main.a6cf40e1.chunk.js +1 -0
- package/common-docs/identity/sign-in.md +17 -3
- package/common-docs/static/music-editor/apple.png +0 -0
- package/common-docs/static/music-editor/burger.png +0 -0
- package/common-docs/static/music-editor/cake.png +0 -0
- package/common-docs/static/music-editor/car.png +0 -0
- package/common-docs/static/music-editor/cat.png +0 -0
- package/common-docs/static/music-editor/cherry.png +0 -0
- package/common-docs/static/music-editor/clam.png +0 -0
- package/common-docs/static/music-editor/computer.png +0 -0
- package/common-docs/static/music-editor/crab.png +0 -0
- package/common-docs/static/music-editor/dog.png +0 -0
- package/common-docs/static/music-editor/duck.png +0 -0
- package/common-docs/static/music-editor/egg.png +0 -0
- package/common-docs/static/music-editor/explosion.png +0 -0
- package/common-docs/static/music-editor/fish.png +0 -0
- package/common-docs/static/music-editor/ice-cream.png +0 -0
- package/common-docs/static/music-editor/lemon.png +0 -0
- package/common-docs/static/music-editor/metronomeWorker.js +35 -0
- package/common-docs/static/music-editor/snake.png +0 -0
- package/common-docs/static/music-editor/star.png +0 -0
- package/common-docs/static/music-editor/strawberry.png +0 -0
- package/common-docs/static/music-editor/taco.png +0 -0
- package/common-docs/static/music-editor/treble-clef.svg +1 -0
- package/package.json +4 -2
- package/react-common/components/controls/Input.tsx +7 -3
- package/react-common/styles/controls/Button.less +9 -0
- package/react-common/styles/react-common-authcode-core.less +1 -1
- package/react-common/styles/react-common-authcode.less +1 -1
- package/react-common/styles/react-common-multiplayer-core.less +10 -0
- package/react-common/styles/react-common-multiplayer.less +12 -0
- package/theme/highcontrast.less +6 -0
- package/theme/music-editor/EditControls.less +22 -0
- package/theme/music-editor/MusicEditor.less +25 -0
- package/theme/music-editor/Note.less +16 -0
- package/theme/music-editor/NoteGroup.less +7 -0
- package/theme/music-editor/PlaybackControls.less +55 -0
- package/theme/music-editor/ScrollableWorkspace.less +3 -0
- package/theme/music-editor/Staff.less +31 -0
- package/theme/music-editor/Track.less +0 -0
- package/theme/music-editor/TrackSelector.less +48 -0
- package/theme/music-editor/Workspace.less +3 -0
- package/theme/pxt.less +1 -0
- package/theme/tutorial-sidebar.less +3 -0
- package/webapp/public/multiplayer.html +1 -0
- package/webapp/public/skillmap.html +1 -1
- package/built/web/skillmap/js/main.6eec9e0f.chunk.js +0 -1
package/built/pxtlib.js
CHANGED
|
@@ -216,6 +216,9 @@ var pxt;
|
|
|
216
216
|
this.setUserProfileAsync(this.state$.profile);
|
|
217
217
|
this.setUserPreferencesAsync(this.state$.preferences);
|
|
218
218
|
}
|
|
219
|
+
async authTokenAsync() {
|
|
220
|
+
return await pxt.storage.shared.getAsync(AUTH_CONTAINER, CSRF_TOKEN_KEY);
|
|
221
|
+
}
|
|
219
222
|
/**
|
|
220
223
|
* Starts the process of authenticating the user against the given identity
|
|
221
224
|
* provider. Upon success the backend will write an http-only session cookie
|
|
@@ -700,6 +703,11 @@ var pxt;
|
|
|
700
703
|
return (_d = (_b = (_a = user === null || user === void 0 ? void 0 : user.idp) === null || _a === void 0 ? void 0 : _a.displayName) !== null && _b !== void 0 ? _b : (_c = user === null || user === void 0 ? void 0 : user.idp) === null || _c === void 0 ? void 0 : _c.username) !== null && _d !== void 0 ? _d : EMPTY_USERNAME;
|
|
701
704
|
}
|
|
702
705
|
auth.userName = userName;
|
|
706
|
+
function firstName(user) {
|
|
707
|
+
const userName = pxt.auth.userName(user);
|
|
708
|
+
return (userName === null || userName === void 0 ? void 0 : userName.split(" ").shift()) || userName;
|
|
709
|
+
}
|
|
710
|
+
auth.firstName = firstName;
|
|
703
711
|
function userInitials(user) {
|
|
704
712
|
const username = pxt.auth.userName(user);
|
|
705
713
|
return ts.pxtc.Util.initials(username);
|
|
@@ -8742,6 +8750,7 @@ var pxt;
|
|
|
8742
8750
|
const url = new URL(`https://${endpointName}.streaming.media.azure.net/${videoID}/manifest(format=mpd-time-csf).mpd`);
|
|
8743
8751
|
if (startTime) {
|
|
8744
8752
|
url.hash = `t=${startTime}`;
|
|
8753
|
+
url.searchParams.append("startTime", startTime);
|
|
8745
8754
|
}
|
|
8746
8755
|
if (endTime) {
|
|
8747
8756
|
url.searchParams.append("endTime", endTime);
|
|
@@ -12633,6 +12642,8 @@ var pxt;
|
|
|
12633
12642
|
sprite_1.IMAGE_PREFIX = "image";
|
|
12634
12643
|
sprite_1.ANIMATION_NAMESPACE = "myAnimations";
|
|
12635
12644
|
sprite_1.ANIMATION_PREFIX = "anim";
|
|
12645
|
+
sprite_1.SONG_NAMESPACE = "mySongs";
|
|
12646
|
+
sprite_1.SONG_PREFIX = "song";
|
|
12636
12647
|
/**
|
|
12637
12648
|
* 16-color sprite
|
|
12638
12649
|
*/
|
|
@@ -13688,6 +13699,1044 @@ var pxt;
|
|
|
13688
13699
|
})(shared = storage.shared || (storage.shared = {}));
|
|
13689
13700
|
})(storage = pxt.storage || (pxt.storage = {}));
|
|
13690
13701
|
})(pxt || (pxt = {}));
|
|
13702
|
+
var pxt;
|
|
13703
|
+
(function (pxt) {
|
|
13704
|
+
var assets;
|
|
13705
|
+
(function (assets) {
|
|
13706
|
+
var music;
|
|
13707
|
+
(function (music) {
|
|
13708
|
+
const BUFFER_SIZE = 12;
|
|
13709
|
+
function renderInstrument(instrument, noteFrequency, gateLength, volume) {
|
|
13710
|
+
var _a, _b, _c, _d, _e;
|
|
13711
|
+
const totalDuration = gateLength + instrument.ampEnvelope.release;
|
|
13712
|
+
const ampLFOInterval = ((_a = instrument.ampLFO) === null || _a === void 0 ? void 0 : _a.amplitude) ? Math.max(500 / instrument.ampLFO.frequency, 50) : 50;
|
|
13713
|
+
const pitchLFOInterval = ((_b = instrument.pitchLFO) === null || _b === void 0 ? void 0 : _b.amplitude) ? Math.max(500 / instrument.pitchLFO.frequency, 50) : 50;
|
|
13714
|
+
let timePoints = [0];
|
|
13715
|
+
let nextAETime = instrument.ampEnvelope.attack;
|
|
13716
|
+
let nextPETime = ((_c = instrument.pitchEnvelope) === null || _c === void 0 ? void 0 : _c.amplitude) ? instrument.pitchEnvelope.attack : totalDuration;
|
|
13717
|
+
let nextPLTime = ((_d = instrument.pitchLFO) === null || _d === void 0 ? void 0 : _d.amplitude) ? pitchLFOInterval : totalDuration;
|
|
13718
|
+
let nextALTime = ((_e = instrument.ampLFO) === null || _e === void 0 ? void 0 : _e.amplitude) ? ampLFOInterval : totalDuration;
|
|
13719
|
+
let time = 0;
|
|
13720
|
+
while (time < totalDuration) {
|
|
13721
|
+
if (nextAETime <= nextPETime && nextAETime <= nextPLTime && nextAETime <= nextALTime) {
|
|
13722
|
+
time = nextAETime;
|
|
13723
|
+
timePoints.push(nextAETime);
|
|
13724
|
+
if (time < instrument.ampEnvelope.attack + instrument.ampEnvelope.decay && instrument.ampEnvelope.attack + instrument.ampEnvelope.decay < gateLength) {
|
|
13725
|
+
nextAETime = instrument.ampEnvelope.attack + instrument.ampEnvelope.decay;
|
|
13726
|
+
}
|
|
13727
|
+
else if (time < gateLength) {
|
|
13728
|
+
nextAETime = gateLength;
|
|
13729
|
+
}
|
|
13730
|
+
else {
|
|
13731
|
+
nextAETime = totalDuration;
|
|
13732
|
+
}
|
|
13733
|
+
}
|
|
13734
|
+
else if (nextPETime <= nextPLTime && nextPETime <= nextALTime && nextPETime < totalDuration) {
|
|
13735
|
+
time = nextPETime;
|
|
13736
|
+
timePoints.push(nextPETime);
|
|
13737
|
+
if (time < instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay && instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay < gateLength) {
|
|
13738
|
+
nextPETime = instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay;
|
|
13739
|
+
}
|
|
13740
|
+
else if (time < gateLength) {
|
|
13741
|
+
nextPETime = gateLength;
|
|
13742
|
+
}
|
|
13743
|
+
else if (time < gateLength + instrument.pitchEnvelope.release) {
|
|
13744
|
+
nextPETime = Math.min(totalDuration, gateLength + instrument.pitchEnvelope.release);
|
|
13745
|
+
}
|
|
13746
|
+
else {
|
|
13747
|
+
nextPETime = totalDuration;
|
|
13748
|
+
}
|
|
13749
|
+
}
|
|
13750
|
+
else if (nextPLTime <= nextALTime && nextPLTime < totalDuration) {
|
|
13751
|
+
time = nextPLTime;
|
|
13752
|
+
timePoints.push(nextPLTime);
|
|
13753
|
+
nextPLTime += pitchLFOInterval;
|
|
13754
|
+
}
|
|
13755
|
+
else if (nextALTime < totalDuration) {
|
|
13756
|
+
time = nextALTime;
|
|
13757
|
+
timePoints.push(nextALTime);
|
|
13758
|
+
nextALTime += ampLFOInterval;
|
|
13759
|
+
}
|
|
13760
|
+
if (time >= totalDuration) {
|
|
13761
|
+
break;
|
|
13762
|
+
}
|
|
13763
|
+
if (nextAETime <= time) {
|
|
13764
|
+
if (time < instrument.ampEnvelope.attack + instrument.ampEnvelope.decay && instrument.ampEnvelope.attack + instrument.ampEnvelope.decay < gateLength) {
|
|
13765
|
+
nextAETime = instrument.ampEnvelope.attack + instrument.ampEnvelope.decay;
|
|
13766
|
+
}
|
|
13767
|
+
else if (time < gateLength) {
|
|
13768
|
+
nextAETime = gateLength;
|
|
13769
|
+
}
|
|
13770
|
+
else {
|
|
13771
|
+
nextAETime = totalDuration;
|
|
13772
|
+
}
|
|
13773
|
+
}
|
|
13774
|
+
if (nextPETime <= time) {
|
|
13775
|
+
if (time < instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay && instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay < gateLength) {
|
|
13776
|
+
nextPETime = instrument.pitchEnvelope.attack + instrument.pitchEnvelope.decay;
|
|
13777
|
+
}
|
|
13778
|
+
else if (time < gateLength) {
|
|
13779
|
+
nextPETime = gateLength;
|
|
13780
|
+
}
|
|
13781
|
+
else if (time < gateLength + instrument.pitchEnvelope.release) {
|
|
13782
|
+
nextPETime = Math.min(totalDuration, gateLength + instrument.pitchEnvelope.release);
|
|
13783
|
+
}
|
|
13784
|
+
else {
|
|
13785
|
+
nextPETime = totalDuration;
|
|
13786
|
+
}
|
|
13787
|
+
}
|
|
13788
|
+
while (nextALTime <= time) {
|
|
13789
|
+
nextALTime += ampLFOInterval;
|
|
13790
|
+
}
|
|
13791
|
+
while (nextPLTime <= time) {
|
|
13792
|
+
nextPLTime += pitchLFOInterval;
|
|
13793
|
+
}
|
|
13794
|
+
}
|
|
13795
|
+
let prevAmp = instrumentVolumeAtTime(instrument, gateLength, 0, volume) | 0;
|
|
13796
|
+
let prevPitch = instrumentPitchAtTime(instrument, noteFrequency, gateLength, 0) | 0;
|
|
13797
|
+
let prevTime = 0;
|
|
13798
|
+
let nextAmp;
|
|
13799
|
+
let nextPitch;
|
|
13800
|
+
const out = new Uint8Array(BUFFER_SIZE * (timePoints.length + 1));
|
|
13801
|
+
for (let i = 1; i < timePoints.length; i++) {
|
|
13802
|
+
if (timePoints[i] - prevTime < 5) {
|
|
13803
|
+
prevTime = timePoints[i];
|
|
13804
|
+
continue;
|
|
13805
|
+
}
|
|
13806
|
+
nextAmp = instrumentVolumeAtTime(instrument, gateLength, timePoints[i], volume) | 0;
|
|
13807
|
+
nextPitch = instrumentPitchAtTime(instrument, noteFrequency, gateLength, timePoints[i]) | 0;
|
|
13808
|
+
addNote(out, (i - 1) * 12, (timePoints[i] - prevTime) | 0, prevAmp, nextAmp, instrument.waveform, prevPitch, nextPitch);
|
|
13809
|
+
prevAmp = nextAmp;
|
|
13810
|
+
prevPitch = nextPitch;
|
|
13811
|
+
prevTime = timePoints[i];
|
|
13812
|
+
}
|
|
13813
|
+
addNote(out, timePoints.length * 12, 10, prevAmp, 0, instrument.waveform, prevPitch, prevPitch);
|
|
13814
|
+
return out;
|
|
13815
|
+
}
|
|
13816
|
+
music.renderInstrument = renderInstrument;
|
|
13817
|
+
function renderDrumInstrument(sound, volume) {
|
|
13818
|
+
let prevAmp = sound.startVolume;
|
|
13819
|
+
let prevFreq = sound.startFrequency;
|
|
13820
|
+
const scaleVolume = (value) => (value / 1024) * volume;
|
|
13821
|
+
let out = new Uint8Array((sound.steps.length + 1) * BUFFER_SIZE);
|
|
13822
|
+
for (let i = 0; i < sound.steps.length; i++) {
|
|
13823
|
+
addNote(out, i * BUFFER_SIZE, sound.steps[i].duration, scaleVolume(prevAmp), scaleVolume(sound.steps[i].volume), sound.steps[i].waveform, prevFreq, sound.steps[i].frequency);
|
|
13824
|
+
prevAmp = sound.steps[i].volume;
|
|
13825
|
+
prevFreq = sound.steps[i].frequency;
|
|
13826
|
+
}
|
|
13827
|
+
addNote(out, sound.steps.length * BUFFER_SIZE, 10, scaleVolume(prevAmp), 0, sound.steps[sound.steps.length - 1].waveform, prevFreq, prevFreq);
|
|
13828
|
+
return out;
|
|
13829
|
+
}
|
|
13830
|
+
music.renderDrumInstrument = renderDrumInstrument;
|
|
13831
|
+
function instrumentPitchAtTime(instrument, noteFrequency, gateLength, time) {
|
|
13832
|
+
var _a, _b;
|
|
13833
|
+
let mod = 0;
|
|
13834
|
+
if ((_a = instrument.pitchEnvelope) === null || _a === void 0 ? void 0 : _a.amplitude) {
|
|
13835
|
+
mod += envelopeValueAtTime(instrument.pitchEnvelope, time, gateLength);
|
|
13836
|
+
}
|
|
13837
|
+
if ((_b = instrument.pitchLFO) === null || _b === void 0 ? void 0 : _b.amplitude) {
|
|
13838
|
+
mod += lfoValueAtTime(instrument.pitchLFO, time);
|
|
13839
|
+
}
|
|
13840
|
+
return Math.max(noteFrequency + mod, 0);
|
|
13841
|
+
}
|
|
13842
|
+
function instrumentVolumeAtTime(instrument, gateLength, time, maxVolume) {
|
|
13843
|
+
var _a;
|
|
13844
|
+
let mod = 0;
|
|
13845
|
+
if (instrument.ampEnvelope.amplitude) {
|
|
13846
|
+
mod += envelopeValueAtTime(instrument.ampEnvelope, time, gateLength);
|
|
13847
|
+
}
|
|
13848
|
+
if ((_a = instrument.ampLFO) === null || _a === void 0 ? void 0 : _a.amplitude) {
|
|
13849
|
+
mod += lfoValueAtTime(instrument.ampLFO, time);
|
|
13850
|
+
}
|
|
13851
|
+
return ((Math.max(Math.min(mod, instrument.ampEnvelope.amplitude), 0) / 1024) * maxVolume) | 0;
|
|
13852
|
+
}
|
|
13853
|
+
function envelopeValueAtTime(envelope, time, gateLength) {
|
|
13854
|
+
const adjustedSustain = (envelope.sustain / 1024) * envelope.amplitude;
|
|
13855
|
+
if (time > gateLength) {
|
|
13856
|
+
if (time - gateLength > envelope.release)
|
|
13857
|
+
return 0;
|
|
13858
|
+
else if (time < envelope.attack) {
|
|
13859
|
+
const height = (envelope.amplitude / envelope.attack) * gateLength;
|
|
13860
|
+
return height - ((height / envelope.release) * (time - gateLength));
|
|
13861
|
+
}
|
|
13862
|
+
else if (time < envelope.attack + envelope.decay) {
|
|
13863
|
+
const height2 = envelope.amplitude - ((envelope.amplitude - adjustedSustain) / envelope.decay) * (gateLength - envelope.attack);
|
|
13864
|
+
return height2 - ((height2 / envelope.release) * (time - gateLength));
|
|
13865
|
+
}
|
|
13866
|
+
else {
|
|
13867
|
+
return adjustedSustain - (adjustedSustain / envelope.release) * (time - gateLength);
|
|
13868
|
+
}
|
|
13869
|
+
}
|
|
13870
|
+
else if (time < envelope.attack) {
|
|
13871
|
+
return (envelope.amplitude / envelope.attack) * time;
|
|
13872
|
+
}
|
|
13873
|
+
else if (time < envelope.attack + envelope.decay) {
|
|
13874
|
+
return envelope.amplitude - ((envelope.amplitude - adjustedSustain) / envelope.decay) * (time - envelope.attack);
|
|
13875
|
+
}
|
|
13876
|
+
else {
|
|
13877
|
+
return adjustedSustain;
|
|
13878
|
+
}
|
|
13879
|
+
}
|
|
13880
|
+
function lfoValueAtTime(lfo, time) {
|
|
13881
|
+
return Math.cos(((time / 1000) * lfo.frequency) * 2 * Math.PI) * lfo.amplitude;
|
|
13882
|
+
}
|
|
13883
|
+
function set16BitNumber(buf, offset, value) {
|
|
13884
|
+
const temp = new Uint8Array(2);
|
|
13885
|
+
new Uint16Array(temp.buffer)[0] = value | 0;
|
|
13886
|
+
buf[offset] = temp[0];
|
|
13887
|
+
buf[offset + 1] = temp[1];
|
|
13888
|
+
}
|
|
13889
|
+
function get16BitNumber(buf, offset) {
|
|
13890
|
+
const temp = new Uint8Array(2);
|
|
13891
|
+
temp[0] = buf[offset];
|
|
13892
|
+
temp[1] = buf[offset + 1];
|
|
13893
|
+
return new Uint16Array(temp.buffer)[0];
|
|
13894
|
+
}
|
|
13895
|
+
function addNote(sndInstr, sndInstrPtr, ms, beg, end, soundWave, hz, endHz) {
|
|
13896
|
+
if (ms > 0) {
|
|
13897
|
+
sndInstr[sndInstrPtr] = soundWave;
|
|
13898
|
+
sndInstr[sndInstrPtr + 1] = 0;
|
|
13899
|
+
set16BitNumber(sndInstr, sndInstrPtr + 2, hz);
|
|
13900
|
+
set16BitNumber(sndInstr, sndInstrPtr + 4, ms);
|
|
13901
|
+
set16BitNumber(sndInstr, sndInstrPtr + 6, (beg * 255) >> 6);
|
|
13902
|
+
set16BitNumber(sndInstr, sndInstrPtr + 8, (end * 255) >> 6);
|
|
13903
|
+
set16BitNumber(sndInstr, sndInstrPtr + 10, endHz);
|
|
13904
|
+
sndInstrPtr += BUFFER_SIZE;
|
|
13905
|
+
}
|
|
13906
|
+
sndInstr[sndInstrPtr] = 0;
|
|
13907
|
+
return sndInstrPtr;
|
|
13908
|
+
}
|
|
13909
|
+
function encodeSongToHex(song) {
|
|
13910
|
+
const encoded = encodeSong(song);
|
|
13911
|
+
return pxt.U.toHex(encoded);
|
|
13912
|
+
}
|
|
13913
|
+
music.encodeSongToHex = encodeSongToHex;
|
|
13914
|
+
function decodeSongFromHex(hex) {
|
|
13915
|
+
const bytes = pxt.U.fromHex(hex);
|
|
13916
|
+
return decodeSong(bytes);
|
|
13917
|
+
}
|
|
13918
|
+
music.decodeSongFromHex = decodeSongFromHex;
|
|
13919
|
+
/**
|
|
13920
|
+
* Byte encoding format for songs
|
|
13921
|
+
* FIXME: should this all be word aligned?
|
|
13922
|
+
*
|
|
13923
|
+
* song(7 + length of all tracks bytes)
|
|
13924
|
+
* 0 version
|
|
13925
|
+
* 1 beats per minute
|
|
13926
|
+
* 3 beats per measure
|
|
13927
|
+
* 4 ticks per beat
|
|
13928
|
+
* 5 measures
|
|
13929
|
+
* 6 number of tracks
|
|
13930
|
+
* ...tracks
|
|
13931
|
+
*
|
|
13932
|
+
* track(6 + instrument length + note length bytes)
|
|
13933
|
+
* 0 id
|
|
13934
|
+
* 1 flags
|
|
13935
|
+
* 2 instruments byte length
|
|
13936
|
+
* 4...instrument
|
|
13937
|
+
* notes byte length
|
|
13938
|
+
* ...note events
|
|
13939
|
+
*
|
|
13940
|
+
* instrument(27 bytes)
|
|
13941
|
+
* 0 waveform
|
|
13942
|
+
* 1 amp attack
|
|
13943
|
+
* 3 amp decay
|
|
13944
|
+
* 5 amp sustain
|
|
13945
|
+
* 7 amp release
|
|
13946
|
+
* 9 amp amp
|
|
13947
|
+
* 11 pitch attack
|
|
13948
|
+
* 13 pitch decay
|
|
13949
|
+
* 15 pitch sustain
|
|
13950
|
+
* 17 pitch release
|
|
13951
|
+
* 19 pitch amp
|
|
13952
|
+
* 21 amp lfo freq
|
|
13953
|
+
* 22 amp lfo amp
|
|
13954
|
+
* 24 pitch lfo freq
|
|
13955
|
+
* 25 pitch lfo amp
|
|
13956
|
+
*
|
|
13957
|
+
* drum(5 + 7 * steps bytes)
|
|
13958
|
+
* 0 steps
|
|
13959
|
+
* 1 start freq
|
|
13960
|
+
* 3 start amp
|
|
13961
|
+
* 5...steps
|
|
13962
|
+
*
|
|
13963
|
+
* drum step(7 bytes)
|
|
13964
|
+
* 0 waveform
|
|
13965
|
+
* 1 freq
|
|
13966
|
+
* 3 volume
|
|
13967
|
+
* 5 duration
|
|
13968
|
+
*
|
|
13969
|
+
* note event(5 + 1 * polyphony bytes)
|
|
13970
|
+
* 0 start tick
|
|
13971
|
+
* 2 end tick
|
|
13972
|
+
* 4 polyphony
|
|
13973
|
+
* 5...notes(1 byte each)
|
|
13974
|
+
*
|
|
13975
|
+
*/
|
|
13976
|
+
function encodeSong(song) {
|
|
13977
|
+
const encodedTracks = song.tracks
|
|
13978
|
+
.filter((track) => track.notes.length > 0)
|
|
13979
|
+
.map(encodeTrack);
|
|
13980
|
+
const trackLength = encodedTracks.reduce((d, c) => c.length + d, 0);
|
|
13981
|
+
const out = new Uint8Array(7 + trackLength);
|
|
13982
|
+
out[0] = 0; // encoding version
|
|
13983
|
+
set16BitNumber(out, 1, song.beatsPerMinute);
|
|
13984
|
+
out[3] = song.beatsPerMeasure;
|
|
13985
|
+
out[4] = song.ticksPerBeat;
|
|
13986
|
+
out[5] = song.measures;
|
|
13987
|
+
out[6] = encodedTracks.length;
|
|
13988
|
+
let current = 7;
|
|
13989
|
+
for (const track of encodedTracks) {
|
|
13990
|
+
out.set(track, current);
|
|
13991
|
+
current += track.length;
|
|
13992
|
+
}
|
|
13993
|
+
return out;
|
|
13994
|
+
}
|
|
13995
|
+
function decodeSong(buf) {
|
|
13996
|
+
const res = {
|
|
13997
|
+
beatsPerMinute: get16BitNumber(buf, 1),
|
|
13998
|
+
beatsPerMeasure: buf[3],
|
|
13999
|
+
ticksPerBeat: buf[4],
|
|
14000
|
+
measures: buf[5],
|
|
14001
|
+
tracks: []
|
|
14002
|
+
};
|
|
14003
|
+
let current = 7;
|
|
14004
|
+
while (current < buf.length) {
|
|
14005
|
+
const [track, pointer] = decodeTrack(buf, current);
|
|
14006
|
+
current = pointer;
|
|
14007
|
+
res.tracks.push(track);
|
|
14008
|
+
}
|
|
14009
|
+
return res;
|
|
14010
|
+
}
|
|
14011
|
+
function encodeInstrument(instrument) {
|
|
14012
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
14013
|
+
const out = new Uint8Array(28);
|
|
14014
|
+
out[0] = instrument.waveform;
|
|
14015
|
+
set16BitNumber(out, 1, instrument.ampEnvelope.attack);
|
|
14016
|
+
set16BitNumber(out, 3, instrument.ampEnvelope.decay);
|
|
14017
|
+
set16BitNumber(out, 5, instrument.ampEnvelope.sustain);
|
|
14018
|
+
set16BitNumber(out, 7, instrument.ampEnvelope.release);
|
|
14019
|
+
set16BitNumber(out, 9, instrument.ampEnvelope.amplitude);
|
|
14020
|
+
set16BitNumber(out, 11, ((_a = instrument.pitchEnvelope) === null || _a === void 0 ? void 0 : _a.attack) || 0);
|
|
14021
|
+
set16BitNumber(out, 13, ((_b = instrument.pitchEnvelope) === null || _b === void 0 ? void 0 : _b.decay) || 0);
|
|
14022
|
+
set16BitNumber(out, 15, ((_c = instrument.pitchEnvelope) === null || _c === void 0 ? void 0 : _c.sustain) || 0);
|
|
14023
|
+
set16BitNumber(out, 17, ((_d = instrument.pitchEnvelope) === null || _d === void 0 ? void 0 : _d.release) || 0);
|
|
14024
|
+
set16BitNumber(out, 19, ((_e = instrument.pitchEnvelope) === null || _e === void 0 ? void 0 : _e.amplitude) || 0);
|
|
14025
|
+
out[21] = ((_f = instrument.ampLFO) === null || _f === void 0 ? void 0 : _f.frequency) || 0;
|
|
14026
|
+
set16BitNumber(out, 22, ((_g = instrument.ampLFO) === null || _g === void 0 ? void 0 : _g.amplitude) || 0);
|
|
14027
|
+
out[24] = ((_h = instrument.pitchLFO) === null || _h === void 0 ? void 0 : _h.frequency) || 0;
|
|
14028
|
+
set16BitNumber(out, 25, ((_j = instrument.pitchLFO) === null || _j === void 0 ? void 0 : _j.amplitude) || 0);
|
|
14029
|
+
return out;
|
|
14030
|
+
}
|
|
14031
|
+
function decodeInstrument(buf, offset) {
|
|
14032
|
+
return {
|
|
14033
|
+
waveform: buf[offset],
|
|
14034
|
+
ampEnvelope: {
|
|
14035
|
+
attack: get16BitNumber(buf, offset + 1),
|
|
14036
|
+
decay: get16BitNumber(buf, offset + 3),
|
|
14037
|
+
sustain: get16BitNumber(buf, offset + 5),
|
|
14038
|
+
release: get16BitNumber(buf, offset + 7),
|
|
14039
|
+
amplitude: get16BitNumber(buf, offset + 9),
|
|
14040
|
+
},
|
|
14041
|
+
pitchEnvelope: {
|
|
14042
|
+
attack: get16BitNumber(buf, offset + 11),
|
|
14043
|
+
decay: get16BitNumber(buf, offset + 13),
|
|
14044
|
+
sustain: get16BitNumber(buf, offset + 15),
|
|
14045
|
+
release: get16BitNumber(buf, offset + 17),
|
|
14046
|
+
amplitude: get16BitNumber(buf, offset + 19),
|
|
14047
|
+
},
|
|
14048
|
+
ampLFO: {
|
|
14049
|
+
frequency: buf[offset + 21],
|
|
14050
|
+
amplitude: get16BitNumber(buf, 22)
|
|
14051
|
+
},
|
|
14052
|
+
pitchLFO: {
|
|
14053
|
+
frequency: buf[offset + 24],
|
|
14054
|
+
amplitude: get16BitNumber(buf, 25)
|
|
14055
|
+
}
|
|
14056
|
+
};
|
|
14057
|
+
}
|
|
14058
|
+
function decodeTrack(buf, offset) {
|
|
14059
|
+
if (buf[offset + 1]) {
|
|
14060
|
+
return decodeDrumTrack(buf, offset);
|
|
14061
|
+
}
|
|
14062
|
+
return decodeMelodicTrack(buf, offset);
|
|
14063
|
+
}
|
|
14064
|
+
function encodeDrumInstrument(drum) {
|
|
14065
|
+
const out = new Uint8Array(5 + 7 * drum.steps.length);
|
|
14066
|
+
out[0] = drum.steps.length;
|
|
14067
|
+
set16BitNumber(out, 1, drum.startFrequency);
|
|
14068
|
+
set16BitNumber(out, 3, drum.startVolume);
|
|
14069
|
+
for (let i = 0; i < drum.steps.length; i++) {
|
|
14070
|
+
const start = 5 + i * 7;
|
|
14071
|
+
out[start] = drum.steps[i].waveform;
|
|
14072
|
+
set16BitNumber(out, start + 1, drum.steps[i].frequency);
|
|
14073
|
+
set16BitNumber(out, start + 3, drum.steps[i].volume);
|
|
14074
|
+
set16BitNumber(out, start + 5, drum.steps[i].duration);
|
|
14075
|
+
}
|
|
14076
|
+
return out;
|
|
14077
|
+
}
|
|
14078
|
+
function decodeDrumInstrument(buf, offset) {
|
|
14079
|
+
const res = {
|
|
14080
|
+
startFrequency: get16BitNumber(buf, offset + 1),
|
|
14081
|
+
startVolume: get16BitNumber(buf, offset + 3),
|
|
14082
|
+
steps: []
|
|
14083
|
+
};
|
|
14084
|
+
for (let i = 0; i < buf[offset]; i++) {
|
|
14085
|
+
const start = offset + 5 + i * 7;
|
|
14086
|
+
res.steps.push({
|
|
14087
|
+
waveform: buf[start],
|
|
14088
|
+
frequency: get16BitNumber(buf, start + 1),
|
|
14089
|
+
volume: get16BitNumber(buf, start + 3),
|
|
14090
|
+
duration: get16BitNumber(buf, start + 5)
|
|
14091
|
+
});
|
|
14092
|
+
}
|
|
14093
|
+
return res;
|
|
14094
|
+
}
|
|
14095
|
+
function encodeNoteEvent(event) {
|
|
14096
|
+
const out = new Uint8Array(5 + event.notes.length);
|
|
14097
|
+
set16BitNumber(out, 0, event.startTick);
|
|
14098
|
+
set16BitNumber(out, 2, event.endTick);
|
|
14099
|
+
out[4] = event.notes.length;
|
|
14100
|
+
for (let i = 0; i < event.notes.length; i++) {
|
|
14101
|
+
out[5 + i] = event.notes[i];
|
|
14102
|
+
}
|
|
14103
|
+
return out;
|
|
14104
|
+
}
|
|
14105
|
+
function decodeNoteEvent(buf, offset) {
|
|
14106
|
+
const res = {
|
|
14107
|
+
startTick: get16BitNumber(buf, offset),
|
|
14108
|
+
endTick: get16BitNumber(buf, offset + 2),
|
|
14109
|
+
notes: []
|
|
14110
|
+
};
|
|
14111
|
+
for (let i = 0; i < buf[offset + 4]; i++) {
|
|
14112
|
+
res.notes.push(buf[offset + 5 + i]);
|
|
14113
|
+
}
|
|
14114
|
+
return res;
|
|
14115
|
+
}
|
|
14116
|
+
function encodeTrack(track) {
|
|
14117
|
+
if (track.drums)
|
|
14118
|
+
return encodeDrumTrack(track);
|
|
14119
|
+
return encodeMelodicTrack(track);
|
|
14120
|
+
}
|
|
14121
|
+
function encodeMelodicTrack(track) {
|
|
14122
|
+
const encodedInstrument = encodeInstrument(track.instrument);
|
|
14123
|
+
const encodedNotes = track.notes.map(encodeNoteEvent);
|
|
14124
|
+
const noteLength = encodedNotes.reduce((d, c) => c.length + d, 0);
|
|
14125
|
+
const out = new Uint8Array(6 + encodedInstrument.length + noteLength);
|
|
14126
|
+
out[0] = track.id;
|
|
14127
|
+
out[1] = 0;
|
|
14128
|
+
set16BitNumber(out, 2, encodedInstrument.length);
|
|
14129
|
+
let current = 4;
|
|
14130
|
+
out.set(encodedInstrument, current);
|
|
14131
|
+
current += encodedInstrument.length;
|
|
14132
|
+
set16BitNumber(out, current, noteLength);
|
|
14133
|
+
current += 2;
|
|
14134
|
+
for (const note of encodedNotes) {
|
|
14135
|
+
out.set(note, current);
|
|
14136
|
+
current += note.length;
|
|
14137
|
+
}
|
|
14138
|
+
return out;
|
|
14139
|
+
}
|
|
14140
|
+
function decodeMelodicTrack(buf, offset) {
|
|
14141
|
+
const res = {
|
|
14142
|
+
id: buf[offset],
|
|
14143
|
+
instrument: decodeInstrument(buf, offset + 4),
|
|
14144
|
+
notes: []
|
|
14145
|
+
};
|
|
14146
|
+
const noteStart = offset + 4 + get16BitNumber(buf, offset + 2);
|
|
14147
|
+
const noteLength = get16BitNumber(buf, noteStart);
|
|
14148
|
+
let currentOffset = noteStart + 2;
|
|
14149
|
+
while (currentOffset < noteStart + 2 + noteLength) {
|
|
14150
|
+
res.notes.push(decodeNoteEvent(buf, currentOffset));
|
|
14151
|
+
currentOffset += 5 + res.notes[res.notes.length - 1].notes.length;
|
|
14152
|
+
}
|
|
14153
|
+
return [res, currentOffset];
|
|
14154
|
+
}
|
|
14155
|
+
function encodeDrumTrack(track) {
|
|
14156
|
+
const encodedDrums = track.drums.map(encodeDrumInstrument);
|
|
14157
|
+
const drumLength = encodedDrums.reduce((d, c) => c.length + d, 0);
|
|
14158
|
+
const encodedNotes = track.notes.map(encodeNoteEvent);
|
|
14159
|
+
const noteLength = encodedNotes.reduce((d, c) => c.length + d, 0);
|
|
14160
|
+
const out = new Uint8Array(6 + drumLength + noteLength);
|
|
14161
|
+
out[0] = track.id;
|
|
14162
|
+
out[1] = 1;
|
|
14163
|
+
set16BitNumber(out, 2, drumLength);
|
|
14164
|
+
let current = 4;
|
|
14165
|
+
for (const drum of encodedDrums) {
|
|
14166
|
+
out.set(drum, current);
|
|
14167
|
+
current += drum.length;
|
|
14168
|
+
}
|
|
14169
|
+
set16BitNumber(out, current, noteLength);
|
|
14170
|
+
current += 2;
|
|
14171
|
+
for (const note of encodedNotes) {
|
|
14172
|
+
out.set(note, current);
|
|
14173
|
+
current += note.length;
|
|
14174
|
+
}
|
|
14175
|
+
return out;
|
|
14176
|
+
}
|
|
14177
|
+
function decodeDrumTrack(buf, offset) {
|
|
14178
|
+
const res = {
|
|
14179
|
+
id: buf[offset],
|
|
14180
|
+
instrument: { ampEnvelope: { attack: 0, decay: 0, sustain: 0, release: 0, amplitude: 0 }, waveform: 0 },
|
|
14181
|
+
notes: [],
|
|
14182
|
+
drums: []
|
|
14183
|
+
};
|
|
14184
|
+
const drumByteLength = get16BitNumber(buf, offset + 2);
|
|
14185
|
+
let currentOffset = offset + 4;
|
|
14186
|
+
while (currentOffset < offset + 4 + drumByteLength) {
|
|
14187
|
+
res.drums.push(decodeDrumInstrument(buf, currentOffset));
|
|
14188
|
+
currentOffset += 5 + 7 * res.drums[res.drums.length - 1].steps.length;
|
|
14189
|
+
}
|
|
14190
|
+
const noteLength = get16BitNumber(buf, currentOffset);
|
|
14191
|
+
currentOffset += 2;
|
|
14192
|
+
while (currentOffset < offset + 4 + drumByteLength + noteLength) {
|
|
14193
|
+
res.notes.push(decodeNoteEvent(buf, currentOffset));
|
|
14194
|
+
currentOffset += 5 + res.notes[res.notes.length - 1].notes.length;
|
|
14195
|
+
}
|
|
14196
|
+
return [res, currentOffset];
|
|
14197
|
+
}
|
|
14198
|
+
function cloneSong(song) {
|
|
14199
|
+
return Object.assign(Object.assign({}, song), { tracks: song.tracks.map(track => (Object.assign(Object.assign({}, track), { instrument: track.instrument && Object.assign(Object.assign({}, track.instrument), { ampEnvelope: Object.assign({}, track.instrument.ampEnvelope), pitchEnvelope: track.instrument.pitchEnvelope && Object.assign({}, track.instrument.pitchEnvelope), ampLFO: track.instrument.ampLFO && Object.assign({}, track.instrument.ampLFO), pitchLFO: track.instrument.pitchLFO && Object.assign({}, track.instrument.pitchLFO) }), drums: track.drums && track.drums.map(drum => (Object.assign(Object.assign({}, drum), { steps: drum.steps.map(step => (Object.assign({}, step))) }))), notes: track.notes.map(noteEvent => (Object.assign(Object.assign({}, noteEvent), { notes: noteEvent.notes.slice() }))) }))) });
|
|
14200
|
+
}
|
|
14201
|
+
music.cloneSong = cloneSong;
|
|
14202
|
+
function songEquals(a, b) {
|
|
14203
|
+
return naiveEqualCheck(a, b);
|
|
14204
|
+
}
|
|
14205
|
+
music.songEquals = songEquals;
|
|
14206
|
+
function naiveEqualCheck(a, b) {
|
|
14207
|
+
if (typeof a !== typeof b)
|
|
14208
|
+
return false;
|
|
14209
|
+
else if (typeof a !== "object")
|
|
14210
|
+
return a === b;
|
|
14211
|
+
else if (Array.isArray(a)) {
|
|
14212
|
+
if (a.length !== b.length)
|
|
14213
|
+
return false;
|
|
14214
|
+
for (let i = 0; i < a.length; i++) {
|
|
14215
|
+
if (!naiveEqualCheck(a[i], b[i]))
|
|
14216
|
+
return false;
|
|
14217
|
+
}
|
|
14218
|
+
return true;
|
|
14219
|
+
}
|
|
14220
|
+
const aKeys = Object.keys(a);
|
|
14221
|
+
const bKeys = Object.keys(b);
|
|
14222
|
+
if (aKeys.length !== bKeys.length)
|
|
14223
|
+
return false;
|
|
14224
|
+
for (const key of aKeys) {
|
|
14225
|
+
if (bKeys.indexOf(key) === -1)
|
|
14226
|
+
return false;
|
|
14227
|
+
if (!naiveEqualCheck(a[key], b[key]))
|
|
14228
|
+
return false;
|
|
14229
|
+
}
|
|
14230
|
+
return true;
|
|
14231
|
+
}
|
|
14232
|
+
function inflateSong(song) {
|
|
14233
|
+
const base = getEmptySong(1);
|
|
14234
|
+
song.tracks = base.tracks.map((track, index) => {
|
|
14235
|
+
const existing = song.tracks.find(t => t.id === index);
|
|
14236
|
+
if (existing)
|
|
14237
|
+
track.notes = existing.notes;
|
|
14238
|
+
return track;
|
|
14239
|
+
});
|
|
14240
|
+
}
|
|
14241
|
+
music.inflateSong = inflateSong;
|
|
14242
|
+
function getEmptySong(measures) {
|
|
14243
|
+
return {
|
|
14244
|
+
ticksPerBeat: 8,
|
|
14245
|
+
beatsPerMeasure: 4,
|
|
14246
|
+
beatsPerMinute: 120,
|
|
14247
|
+
measures,
|
|
14248
|
+
tracks: [
|
|
14249
|
+
{
|
|
14250
|
+
id: 0,
|
|
14251
|
+
name: lf("Duck"),
|
|
14252
|
+
notes: [],
|
|
14253
|
+
iconURI: "/static/music-editor/duck.png",
|
|
14254
|
+
instrument: {
|
|
14255
|
+
waveform: 15,
|
|
14256
|
+
octave: 4,
|
|
14257
|
+
ampEnvelope: {
|
|
14258
|
+
attack: 5,
|
|
14259
|
+
decay: 530,
|
|
14260
|
+
sustain: 705,
|
|
14261
|
+
release: 450,
|
|
14262
|
+
amplitude: 1024
|
|
14263
|
+
},
|
|
14264
|
+
pitchEnvelope: {
|
|
14265
|
+
attack: 5,
|
|
14266
|
+
decay: 40,
|
|
14267
|
+
sustain: 0,
|
|
14268
|
+
release: 100,
|
|
14269
|
+
amplitude: 40
|
|
14270
|
+
},
|
|
14271
|
+
ampLFO: {
|
|
14272
|
+
frequency: 3,
|
|
14273
|
+
amplitude: 20
|
|
14274
|
+
},
|
|
14275
|
+
pitchLFO: {
|
|
14276
|
+
frequency: 6,
|
|
14277
|
+
amplitude: 2
|
|
14278
|
+
}
|
|
14279
|
+
}
|
|
14280
|
+
},
|
|
14281
|
+
{
|
|
14282
|
+
id: 1,
|
|
14283
|
+
name: lf("Cat"),
|
|
14284
|
+
notes: [],
|
|
14285
|
+
iconURI: "/static/music-editor/cat.png",
|
|
14286
|
+
instrument: {
|
|
14287
|
+
waveform: 12,
|
|
14288
|
+
octave: 5,
|
|
14289
|
+
ampEnvelope: {
|
|
14290
|
+
attack: 150,
|
|
14291
|
+
decay: 100,
|
|
14292
|
+
sustain: 365,
|
|
14293
|
+
release: 400,
|
|
14294
|
+
amplitude: 1024
|
|
14295
|
+
},
|
|
14296
|
+
pitchEnvelope: {
|
|
14297
|
+
attack: 120,
|
|
14298
|
+
decay: 300,
|
|
14299
|
+
sustain: 0,
|
|
14300
|
+
release: 100,
|
|
14301
|
+
amplitude: 50
|
|
14302
|
+
},
|
|
14303
|
+
pitchLFO: {
|
|
14304
|
+
frequency: 10,
|
|
14305
|
+
amplitude: 6
|
|
14306
|
+
}
|
|
14307
|
+
}
|
|
14308
|
+
},
|
|
14309
|
+
{
|
|
14310
|
+
id: 2,
|
|
14311
|
+
name: lf("Dog"),
|
|
14312
|
+
notes: [],
|
|
14313
|
+
iconURI: "/static/music-editor/dog.png",
|
|
14314
|
+
instrument: {
|
|
14315
|
+
waveform: 1,
|
|
14316
|
+
octave: 4,
|
|
14317
|
+
ampEnvelope: {
|
|
14318
|
+
attack: 10,
|
|
14319
|
+
decay: 100,
|
|
14320
|
+
sustain: 500,
|
|
14321
|
+
release: 100,
|
|
14322
|
+
amplitude: 1024
|
|
14323
|
+
},
|
|
14324
|
+
pitchLFO: {
|
|
14325
|
+
frequency: 5,
|
|
14326
|
+
amplitude: 0
|
|
14327
|
+
}
|
|
14328
|
+
}
|
|
14329
|
+
},
|
|
14330
|
+
{
|
|
14331
|
+
id: 3,
|
|
14332
|
+
name: lf("Fish"),
|
|
14333
|
+
notes: [],
|
|
14334
|
+
iconURI: "/static/music-editor/fish.png",
|
|
14335
|
+
instrument: {
|
|
14336
|
+
waveform: 1,
|
|
14337
|
+
octave: 3,
|
|
14338
|
+
ampEnvelope: {
|
|
14339
|
+
attack: 220,
|
|
14340
|
+
decay: 105,
|
|
14341
|
+
sustain: 1024,
|
|
14342
|
+
release: 350,
|
|
14343
|
+
amplitude: 1024
|
|
14344
|
+
},
|
|
14345
|
+
ampLFO: {
|
|
14346
|
+
frequency: 5,
|
|
14347
|
+
amplitude: 100
|
|
14348
|
+
},
|
|
14349
|
+
pitchLFO: {
|
|
14350
|
+
frequency: 1,
|
|
14351
|
+
amplitude: 4
|
|
14352
|
+
}
|
|
14353
|
+
}
|
|
14354
|
+
},
|
|
14355
|
+
{
|
|
14356
|
+
id: 4,
|
|
14357
|
+
name: lf("Car"),
|
|
14358
|
+
notes: [],
|
|
14359
|
+
iconURI: "/static/music-editor/car.png",
|
|
14360
|
+
instrument: {
|
|
14361
|
+
waveform: 16,
|
|
14362
|
+
octave: 4,
|
|
14363
|
+
ampEnvelope: {
|
|
14364
|
+
attack: 5,
|
|
14365
|
+
decay: 100,
|
|
14366
|
+
sustain: 1024,
|
|
14367
|
+
release: 30,
|
|
14368
|
+
amplitude: 1024
|
|
14369
|
+
},
|
|
14370
|
+
pitchLFO: {
|
|
14371
|
+
frequency: 10,
|
|
14372
|
+
amplitude: 4
|
|
14373
|
+
}
|
|
14374
|
+
}
|
|
14375
|
+
},
|
|
14376
|
+
{
|
|
14377
|
+
id: 5,
|
|
14378
|
+
name: lf("Computer"),
|
|
14379
|
+
notes: [],
|
|
14380
|
+
iconURI: "/static/music-editor/computer.png",
|
|
14381
|
+
instrument: {
|
|
14382
|
+
waveform: 15,
|
|
14383
|
+
octave: 1,
|
|
14384
|
+
ampEnvelope: {
|
|
14385
|
+
attack: 10,
|
|
14386
|
+
decay: 100,
|
|
14387
|
+
sustain: 500,
|
|
14388
|
+
release: 10,
|
|
14389
|
+
amplitude: 1024
|
|
14390
|
+
}
|
|
14391
|
+
}
|
|
14392
|
+
},
|
|
14393
|
+
{
|
|
14394
|
+
id: 6,
|
|
14395
|
+
name: lf("Burger"),
|
|
14396
|
+
notes: [],
|
|
14397
|
+
iconURI: "/static/music-editor/burger.png",
|
|
14398
|
+
instrument: {
|
|
14399
|
+
waveform: 1,
|
|
14400
|
+
octave: 1,
|
|
14401
|
+
ampEnvelope: {
|
|
14402
|
+
attack: 10,
|
|
14403
|
+
decay: 100,
|
|
14404
|
+
sustain: 500,
|
|
14405
|
+
release: 100,
|
|
14406
|
+
amplitude: 1024
|
|
14407
|
+
}
|
|
14408
|
+
}
|
|
14409
|
+
},
|
|
14410
|
+
{
|
|
14411
|
+
id: 7,
|
|
14412
|
+
name: lf("Cherry"),
|
|
14413
|
+
notes: [],
|
|
14414
|
+
iconURI: "/static/music-editor/cherry.png",
|
|
14415
|
+
instrument: {
|
|
14416
|
+
waveform: 2,
|
|
14417
|
+
octave: 3,
|
|
14418
|
+
ampEnvelope: {
|
|
14419
|
+
attack: 10,
|
|
14420
|
+
decay: 100,
|
|
14421
|
+
sustain: 500,
|
|
14422
|
+
release: 100,
|
|
14423
|
+
amplitude: 1024
|
|
14424
|
+
}
|
|
14425
|
+
}
|
|
14426
|
+
},
|
|
14427
|
+
{
|
|
14428
|
+
id: 8,
|
|
14429
|
+
name: lf("Lemon"),
|
|
14430
|
+
notes: [],
|
|
14431
|
+
iconURI: "/static/music-editor/lemon.png",
|
|
14432
|
+
instrument: {
|
|
14433
|
+
waveform: 15,
|
|
14434
|
+
octave: 2,
|
|
14435
|
+
ampEnvelope: {
|
|
14436
|
+
attack: 10,
|
|
14437
|
+
decay: 100,
|
|
14438
|
+
sustain: 500,
|
|
14439
|
+
release: 10,
|
|
14440
|
+
amplitude: 1024
|
|
14441
|
+
}
|
|
14442
|
+
}
|
|
14443
|
+
},
|
|
14444
|
+
{
|
|
14445
|
+
id: 9,
|
|
14446
|
+
name: lf("Explosion"),
|
|
14447
|
+
notes: [],
|
|
14448
|
+
iconURI: "/static/music-editor/explosion.png",
|
|
14449
|
+
instrument: {
|
|
14450
|
+
waveform: 11,
|
|
14451
|
+
octave: 4,
|
|
14452
|
+
ampEnvelope: {
|
|
14453
|
+
attack: 10,
|
|
14454
|
+
decay: 100,
|
|
14455
|
+
sustain: 500,
|
|
14456
|
+
release: 100,
|
|
14457
|
+
amplitude: 1024
|
|
14458
|
+
}
|
|
14459
|
+
},
|
|
14460
|
+
drums: [
|
|
14461
|
+
{
|
|
14462
|
+
startFrequency: 100,
|
|
14463
|
+
startVolume: 1024,
|
|
14464
|
+
steps: [
|
|
14465
|
+
{
|
|
14466
|
+
waveform: 3,
|
|
14467
|
+
frequency: 120,
|
|
14468
|
+
duration: 10,
|
|
14469
|
+
volume: 1024
|
|
14470
|
+
},
|
|
14471
|
+
{
|
|
14472
|
+
waveform: 3,
|
|
14473
|
+
frequency: 1,
|
|
14474
|
+
duration: 100,
|
|
14475
|
+
volume: 0
|
|
14476
|
+
}
|
|
14477
|
+
]
|
|
14478
|
+
},
|
|
14479
|
+
{
|
|
14480
|
+
startFrequency: 1,
|
|
14481
|
+
startVolume: 1024,
|
|
14482
|
+
steps: [
|
|
14483
|
+
{
|
|
14484
|
+
waveform: 5,
|
|
14485
|
+
frequency: 1,
|
|
14486
|
+
duration: 20,
|
|
14487
|
+
volume: 0
|
|
14488
|
+
}
|
|
14489
|
+
]
|
|
14490
|
+
},
|
|
14491
|
+
{
|
|
14492
|
+
startFrequency: 1,
|
|
14493
|
+
startVolume: 1024,
|
|
14494
|
+
steps: [
|
|
14495
|
+
{
|
|
14496
|
+
waveform: 5,
|
|
14497
|
+
frequency: 1,
|
|
14498
|
+
duration: 20,
|
|
14499
|
+
volume: 480
|
|
14500
|
+
},
|
|
14501
|
+
{
|
|
14502
|
+
waveform: 5,
|
|
14503
|
+
frequency: 1,
|
|
14504
|
+
duration: 20,
|
|
14505
|
+
volume: 260
|
|
14506
|
+
},
|
|
14507
|
+
{
|
|
14508
|
+
waveform: 5,
|
|
14509
|
+
frequency: 1,
|
|
14510
|
+
duration: 20,
|
|
14511
|
+
volume: 200
|
|
14512
|
+
},
|
|
14513
|
+
{
|
|
14514
|
+
waveform: 5,
|
|
14515
|
+
frequency: 1,
|
|
14516
|
+
duration: 200,
|
|
14517
|
+
volume: 0
|
|
14518
|
+
},
|
|
14519
|
+
]
|
|
14520
|
+
},
|
|
14521
|
+
{
|
|
14522
|
+
startFrequency: 175,
|
|
14523
|
+
startVolume: 1024,
|
|
14524
|
+
steps: [
|
|
14525
|
+
{
|
|
14526
|
+
waveform: 1,
|
|
14527
|
+
frequency: 200,
|
|
14528
|
+
duration: 10,
|
|
14529
|
+
volume: 1024
|
|
14530
|
+
},
|
|
14531
|
+
{
|
|
14532
|
+
waveform: 1,
|
|
14533
|
+
frequency: 150,
|
|
14534
|
+
duration: 20,
|
|
14535
|
+
volume: 1024
|
|
14536
|
+
},
|
|
14537
|
+
{
|
|
14538
|
+
waveform: 5,
|
|
14539
|
+
frequency: 1,
|
|
14540
|
+
duration: 20,
|
|
14541
|
+
volume: 100
|
|
14542
|
+
},
|
|
14543
|
+
{
|
|
14544
|
+
waveform: 5,
|
|
14545
|
+
frequency: 1,
|
|
14546
|
+
duration: 300,
|
|
14547
|
+
volume: 0
|
|
14548
|
+
},
|
|
14549
|
+
]
|
|
14550
|
+
},
|
|
14551
|
+
{
|
|
14552
|
+
startFrequency: 100,
|
|
14553
|
+
startVolume: 1024,
|
|
14554
|
+
steps: [
|
|
14555
|
+
{
|
|
14556
|
+
waveform: 3,
|
|
14557
|
+
frequency: 120,
|
|
14558
|
+
duration: 10,
|
|
14559
|
+
volume: 1024
|
|
14560
|
+
},
|
|
14561
|
+
{
|
|
14562
|
+
waveform: 1,
|
|
14563
|
+
frequency: 120,
|
|
14564
|
+
duration: 100,
|
|
14565
|
+
volume: 0
|
|
14566
|
+
}
|
|
14567
|
+
]
|
|
14568
|
+
},
|
|
14569
|
+
{
|
|
14570
|
+
startFrequency: 1,
|
|
14571
|
+
startVolume: 1024,
|
|
14572
|
+
steps: [
|
|
14573
|
+
{
|
|
14574
|
+
waveform: 5,
|
|
14575
|
+
frequency: 1,
|
|
14576
|
+
duration: 20,
|
|
14577
|
+
volume: 0
|
|
14578
|
+
}
|
|
14579
|
+
]
|
|
14580
|
+
},
|
|
14581
|
+
{
|
|
14582
|
+
startFrequency: 1,
|
|
14583
|
+
startVolume: 1024,
|
|
14584
|
+
steps: [
|
|
14585
|
+
{
|
|
14586
|
+
waveform: 5,
|
|
14587
|
+
frequency: 1,
|
|
14588
|
+
duration: 20,
|
|
14589
|
+
volume: 480
|
|
14590
|
+
},
|
|
14591
|
+
{
|
|
14592
|
+
waveform: 5,
|
|
14593
|
+
frequency: 1,
|
|
14594
|
+
duration: 20,
|
|
14595
|
+
volume: 260
|
|
14596
|
+
},
|
|
14597
|
+
{
|
|
14598
|
+
waveform: 5,
|
|
14599
|
+
frequency: 1,
|
|
14600
|
+
duration: 20,
|
|
14601
|
+
volume: 200
|
|
14602
|
+
},
|
|
14603
|
+
{
|
|
14604
|
+
waveform: 5,
|
|
14605
|
+
frequency: 1,
|
|
14606
|
+
duration: 200,
|
|
14607
|
+
volume: 0
|
|
14608
|
+
},
|
|
14609
|
+
]
|
|
14610
|
+
},
|
|
14611
|
+
{
|
|
14612
|
+
startFrequency: 175,
|
|
14613
|
+
startVolume: 1024,
|
|
14614
|
+
steps: [
|
|
14615
|
+
{
|
|
14616
|
+
waveform: 1,
|
|
14617
|
+
frequency: 200,
|
|
14618
|
+
duration: 10,
|
|
14619
|
+
volume: 1024
|
|
14620
|
+
},
|
|
14621
|
+
{
|
|
14622
|
+
waveform: 1,
|
|
14623
|
+
frequency: 150,
|
|
14624
|
+
duration: 20,
|
|
14625
|
+
volume: 1024
|
|
14626
|
+
},
|
|
14627
|
+
{
|
|
14628
|
+
waveform: 5,
|
|
14629
|
+
frequency: 1,
|
|
14630
|
+
duration: 20,
|
|
14631
|
+
volume: 100
|
|
14632
|
+
},
|
|
14633
|
+
{
|
|
14634
|
+
waveform: 5,
|
|
14635
|
+
frequency: 1,
|
|
14636
|
+
duration: 300,
|
|
14637
|
+
volume: 0
|
|
14638
|
+
},
|
|
14639
|
+
]
|
|
14640
|
+
},
|
|
14641
|
+
{
|
|
14642
|
+
startFrequency: 100,
|
|
14643
|
+
startVolume: 1024,
|
|
14644
|
+
steps: [
|
|
14645
|
+
{
|
|
14646
|
+
waveform: 3,
|
|
14647
|
+
frequency: 120,
|
|
14648
|
+
duration: 10,
|
|
14649
|
+
volume: 1024
|
|
14650
|
+
},
|
|
14651
|
+
{
|
|
14652
|
+
waveform: 1,
|
|
14653
|
+
frequency: 120,
|
|
14654
|
+
duration: 100,
|
|
14655
|
+
volume: 0
|
|
14656
|
+
}
|
|
14657
|
+
]
|
|
14658
|
+
},
|
|
14659
|
+
{
|
|
14660
|
+
startFrequency: 1,
|
|
14661
|
+
startVolume: 1024,
|
|
14662
|
+
steps: [
|
|
14663
|
+
{
|
|
14664
|
+
waveform: 5,
|
|
14665
|
+
frequency: 1,
|
|
14666
|
+
duration: 20,
|
|
14667
|
+
volume: 0
|
|
14668
|
+
}
|
|
14669
|
+
]
|
|
14670
|
+
},
|
|
14671
|
+
{
|
|
14672
|
+
startFrequency: 1,
|
|
14673
|
+
startVolume: 1024,
|
|
14674
|
+
steps: [
|
|
14675
|
+
{
|
|
14676
|
+
waveform: 5,
|
|
14677
|
+
frequency: 1,
|
|
14678
|
+
duration: 20,
|
|
14679
|
+
volume: 480
|
|
14680
|
+
},
|
|
14681
|
+
{
|
|
14682
|
+
waveform: 5,
|
|
14683
|
+
frequency: 1,
|
|
14684
|
+
duration: 20,
|
|
14685
|
+
volume: 260
|
|
14686
|
+
},
|
|
14687
|
+
{
|
|
14688
|
+
waveform: 5,
|
|
14689
|
+
frequency: 1,
|
|
14690
|
+
duration: 20,
|
|
14691
|
+
volume: 200
|
|
14692
|
+
},
|
|
14693
|
+
{
|
|
14694
|
+
waveform: 5,
|
|
14695
|
+
frequency: 1,
|
|
14696
|
+
duration: 200,
|
|
14697
|
+
volume: 0
|
|
14698
|
+
},
|
|
14699
|
+
]
|
|
14700
|
+
},
|
|
14701
|
+
{
|
|
14702
|
+
startFrequency: 175,
|
|
14703
|
+
startVolume: 1024,
|
|
14704
|
+
steps: [
|
|
14705
|
+
{
|
|
14706
|
+
waveform: 1,
|
|
14707
|
+
frequency: 200,
|
|
14708
|
+
duration: 10,
|
|
14709
|
+
volume: 1024
|
|
14710
|
+
},
|
|
14711
|
+
{
|
|
14712
|
+
waveform: 1,
|
|
14713
|
+
frequency: 150,
|
|
14714
|
+
duration: 20,
|
|
14715
|
+
volume: 1024
|
|
14716
|
+
},
|
|
14717
|
+
{
|
|
14718
|
+
waveform: 5,
|
|
14719
|
+
frequency: 1,
|
|
14720
|
+
duration: 20,
|
|
14721
|
+
volume: 100
|
|
14722
|
+
},
|
|
14723
|
+
{
|
|
14724
|
+
waveform: 5,
|
|
14725
|
+
frequency: 1,
|
|
14726
|
+
duration: 300,
|
|
14727
|
+
volume: 0
|
|
14728
|
+
},
|
|
14729
|
+
]
|
|
14730
|
+
}
|
|
14731
|
+
]
|
|
14732
|
+
}
|
|
14733
|
+
]
|
|
14734
|
+
};
|
|
14735
|
+
}
|
|
14736
|
+
music.getEmptySong = getEmptySong;
|
|
14737
|
+
})(music = assets.music || (assets.music = {}));
|
|
14738
|
+
})(assets = pxt.assets || (pxt.assets = {}));
|
|
14739
|
+
})(pxt || (pxt = {}));
|
|
13691
14740
|
/// <reference path="../localtypings/pxtpackage.d.ts"/>
|
|
13692
14741
|
/// <reference path="../localtypings/pxtparts.d.ts"/>
|
|
13693
14742
|
/// <reference path="../localtypings/pxtarget.d.ts"/>
|
|
@@ -17752,6 +18801,7 @@ var pxt;
|
|
|
17752
18801
|
pxt.IMAGE_MIME_TYPE = "image/x-mkcd-f4";
|
|
17753
18802
|
pxt.TILEMAP_MIME_TYPE = "application/mkcd-tilemap";
|
|
17754
18803
|
pxt.ANIMATION_MIME_TYPE = "application/mkcd-animation";
|
|
18804
|
+
pxt.SONG_MIME_TYPE = "application/mkcd-song";
|
|
17755
18805
|
class AssetCollection {
|
|
17756
18806
|
constructor() {
|
|
17757
18807
|
this.assets = [];
|
|
@@ -17938,21 +18988,24 @@ var pxt;
|
|
|
17938
18988
|
tilemaps: new AssetCollection(),
|
|
17939
18989
|
tiles: new AssetCollection(),
|
|
17940
18990
|
animations: new AssetCollection(),
|
|
17941
|
-
images: new AssetCollection()
|
|
18991
|
+
images: new AssetCollection(),
|
|
18992
|
+
songs: new AssetCollection(),
|
|
17942
18993
|
};
|
|
17943
18994
|
this.state = {
|
|
17944
18995
|
revision: this.nextID++,
|
|
17945
18996
|
tilemaps: new AssetCollection(),
|
|
17946
18997
|
tiles: new AssetCollection(),
|
|
17947
18998
|
animations: new AssetCollection(),
|
|
17948
|
-
images: new AssetCollection()
|
|
18999
|
+
images: new AssetCollection(),
|
|
19000
|
+
songs: new AssetCollection(),
|
|
17949
19001
|
};
|
|
17950
19002
|
this.gallery = {
|
|
17951
19003
|
revision: 0,
|
|
17952
19004
|
tilemaps: new AssetCollection(),
|
|
17953
19005
|
tiles: new AssetCollection(),
|
|
17954
19006
|
animations: new AssetCollection(),
|
|
17955
|
-
images: new AssetCollection()
|
|
19007
|
+
images: new AssetCollection(),
|
|
19008
|
+
songs: new AssetCollection(),
|
|
17956
19009
|
};
|
|
17957
19010
|
this.undoStack = [];
|
|
17958
19011
|
this.redoStack = [];
|
|
@@ -18054,6 +19107,19 @@ var pxt;
|
|
|
18054
19107
|
};
|
|
18055
19108
|
return this.state.images.add(newImage);
|
|
18056
19109
|
}
|
|
19110
|
+
createNewSong(data, displayName) {
|
|
19111
|
+
this.onChange();
|
|
19112
|
+
const newSong = {
|
|
19113
|
+
internalID: this.getNewInternalId(),
|
|
19114
|
+
id: this.generateNewID("song" /* AssetType.Song */),
|
|
19115
|
+
type: "song" /* AssetType.Song */,
|
|
19116
|
+
song: pxt.assets.music.cloneSong(data),
|
|
19117
|
+
meta: {
|
|
19118
|
+
displayName
|
|
19119
|
+
},
|
|
19120
|
+
};
|
|
19121
|
+
return this.state.songs.add(newSong);
|
|
19122
|
+
}
|
|
18057
19123
|
updateTile(tile) {
|
|
18058
19124
|
this.onChange();
|
|
18059
19125
|
const existing = this.resolveProjectTileByInternalID(tile.internalID);
|
|
@@ -18090,6 +19156,7 @@ var pxt;
|
|
|
18090
19156
|
const blob = {};
|
|
18091
19157
|
this.state.images.serializeToJRes(blob);
|
|
18092
19158
|
this.state.animations.serializeToJRes(blob);
|
|
19159
|
+
this.state.songs.serializeToJRes(blob);
|
|
18093
19160
|
blob["*"] = {
|
|
18094
19161
|
"mimeType": "image/x-mkcd-f4",
|
|
18095
19162
|
"dataEncoding": "base64",
|
|
@@ -18171,6 +19238,7 @@ var pxt;
|
|
|
18171
19238
|
tilemaps: this.state.tilemaps.clone(),
|
|
18172
19239
|
animations: this.state.animations.clone(),
|
|
18173
19240
|
tiles: this.state.tiles.clone(),
|
|
19241
|
+
songs: this.state.songs.clone(),
|
|
18174
19242
|
};
|
|
18175
19243
|
}
|
|
18176
19244
|
undo() {
|
|
@@ -18183,6 +19251,7 @@ var pxt;
|
|
|
18183
19251
|
this.state.images.applyDiff(undo.images, true);
|
|
18184
19252
|
this.state.tilemaps.applyDiff(undo.tilemaps, true);
|
|
18185
19253
|
this.state.animations.applyDiff(undo.animations, true);
|
|
19254
|
+
this.state.songs.applyDiff(undo.songs, true);
|
|
18186
19255
|
this.state.revision = undo.beforeRevision;
|
|
18187
19256
|
this.redoStack.push(undo);
|
|
18188
19257
|
this.committedState = this.cloneState();
|
|
@@ -18196,6 +19265,7 @@ var pxt;
|
|
|
18196
19265
|
this.state.images.applyDiff(redo.images);
|
|
18197
19266
|
this.state.tilemaps.applyDiff(redo.tilemaps);
|
|
18198
19267
|
this.state.animations.applyDiff(redo.animations);
|
|
19268
|
+
this.state.songs.applyDiff(redo.songs);
|
|
18199
19269
|
this.state.revision = redo.afterRevision;
|
|
18200
19270
|
this.undoStack.push(redo);
|
|
18201
19271
|
this.committedState = this.cloneState();
|
|
@@ -18212,7 +19282,8 @@ var pxt;
|
|
|
18212
19282
|
tiles: this.state.tiles.diff(this.committedState.tiles),
|
|
18213
19283
|
images: this.state.images.diff(this.committedState.images),
|
|
18214
19284
|
tilemaps: this.state.tilemaps.diff(this.committedState.tilemaps),
|
|
18215
|
-
animations: this.state.animations.diff(this.committedState.animations)
|
|
19285
|
+
animations: this.state.animations.diff(this.committedState.animations),
|
|
19286
|
+
songs: this.state.songs.diff(this.committedState.songs)
|
|
18216
19287
|
});
|
|
18217
19288
|
this.committedState = this.cloneState();
|
|
18218
19289
|
this.cleanupTemporaryAssets();
|
|
@@ -18242,16 +19313,8 @@ var pxt;
|
|
|
18242
19313
|
}
|
|
18243
19314
|
isNameTaken(assetType, name) {
|
|
18244
19315
|
const isTaken = (id) => {
|
|
18245
|
-
|
|
18246
|
-
|
|
18247
|
-
return this.state.images.isIDTaken(id) || this.gallery.images.isIDTaken(id);
|
|
18248
|
-
case "tile" /* AssetType.Tile */:
|
|
18249
|
-
return this.state.tiles.isIDTaken(id) || this.gallery.tiles.isIDTaken(id);
|
|
18250
|
-
case "tilemap" /* AssetType.Tilemap */:
|
|
18251
|
-
return this.state.tilemaps.isIDTaken(id) || this.gallery.tilemaps.isIDTaken(id);
|
|
18252
|
-
case "animation" /* AssetType.Animation */:
|
|
18253
|
-
return this.state.animations.isIDTaken(id) || this.gallery.animations.isIDTaken(id);
|
|
18254
|
-
}
|
|
19316
|
+
return getAssetCollection(this.state, assetType).isIDTaken(id) ||
|
|
19317
|
+
getAssetCollection(this.gallery, assetType).isIDTaken(id);
|
|
18255
19318
|
};
|
|
18256
19319
|
const shortId = getShortIDCore(assetType, name);
|
|
18257
19320
|
const checkShortId = shortId && shortId !== name;
|
|
@@ -18277,6 +19340,10 @@ var pxt;
|
|
|
18277
19340
|
* assets.animation`shortId`
|
|
18278
19341
|
* assets.animation`displayName`
|
|
18279
19342
|
*
|
|
19343
|
+
* SONGS:
|
|
19344
|
+
* assets.song`shortId`
|
|
19345
|
+
* assets.song`displayName`
|
|
19346
|
+
*
|
|
18280
19347
|
* TILEMAPS:
|
|
18281
19348
|
* tilemap`shortId`
|
|
18282
19349
|
*
|
|
@@ -18315,6 +19382,11 @@ var pxt;
|
|
|
18315
19382
|
if (displayName)
|
|
18316
19383
|
assetTsRefs += `|assets.animation\`${displayName}\``;
|
|
18317
19384
|
break;
|
|
19385
|
+
case "song" /* pxt.AssetType.Song */:
|
|
19386
|
+
assetTsRefs = `assets.song\`${shortId}\``;
|
|
19387
|
+
if (displayName)
|
|
19388
|
+
assetTsRefs += `|assets.song\`${displayName}\``;
|
|
19389
|
+
break;
|
|
18318
19390
|
default:
|
|
18319
19391
|
assetTsRefs = `assets.image\`${shortId}\``;
|
|
18320
19392
|
if (displayName)
|
|
@@ -18337,6 +19409,11 @@ var pxt;
|
|
|
18337
19409
|
if (displayName)
|
|
18338
19410
|
assetPyRefs += `|assets.animation\("""${displayName}"""\)`;
|
|
18339
19411
|
break;
|
|
19412
|
+
case "song" /* pxt.AssetType.Song */:
|
|
19413
|
+
assetPyRefs = `assets.song\("""${shortId}"""\)`;
|
|
19414
|
+
if (displayName)
|
|
19415
|
+
assetPyRefs += `|assets.song\("""${displayName}"""\)`;
|
|
19416
|
+
break;
|
|
18340
19417
|
default:
|
|
18341
19418
|
assetPyRefs = `assets.image\("""${shortId}"""\)`;
|
|
18342
19419
|
if (displayName)
|
|
@@ -18362,65 +19439,29 @@ var pxt;
|
|
|
18362
19439
|
return false;
|
|
18363
19440
|
}
|
|
18364
19441
|
lookupAsset(assetType, name) {
|
|
18365
|
-
|
|
18366
|
-
|
|
18367
|
-
return this.state.images.getByID(name) || this.gallery.images.getByID(name);
|
|
18368
|
-
case "tile" /* AssetType.Tile */:
|
|
18369
|
-
return this.state.tiles.getByID(name) || this.gallery.tiles.getByID(name);
|
|
18370
|
-
case "tilemap" /* AssetType.Tilemap */:
|
|
18371
|
-
return this.state.tilemaps.getByID(name) || this.gallery.tilemaps.getByID(name);
|
|
18372
|
-
case "animation" /* AssetType.Animation */:
|
|
18373
|
-
return this.state.animations.getByID(name) || this.gallery.animations.getByID(name);
|
|
18374
|
-
}
|
|
19442
|
+
return getAssetCollection(this.state, assetType).getByID(name) ||
|
|
19443
|
+
getAssetCollection(this.gallery, assetType).getByID(name);
|
|
18375
19444
|
}
|
|
18376
19445
|
lookupAssetByName(assetType, name) {
|
|
18377
|
-
|
|
18378
|
-
case "image" /* AssetType.Image */:
|
|
18379
|
-
return this.state.images.getByDisplayName(name);
|
|
18380
|
-
case "tile" /* AssetType.Tile */:
|
|
18381
|
-
return this.state.tiles.getByDisplayName(name);
|
|
18382
|
-
case "tilemap" /* AssetType.Tilemap */:
|
|
18383
|
-
return this.state.tilemaps.getByDisplayName(name);
|
|
18384
|
-
case "animation" /* AssetType.Animation */:
|
|
18385
|
-
return this.state.animations.getByDisplayName(name);
|
|
18386
|
-
}
|
|
19446
|
+
return getAssetCollection(this.state, assetType).getByDisplayName(name);
|
|
18387
19447
|
}
|
|
18388
19448
|
getAssets(type) {
|
|
18389
|
-
|
|
18390
|
-
case "image" /* AssetType.Image */: return this.state.images.getSnapshot();
|
|
18391
|
-
case "tile" /* AssetType.Tile */: return this.state.tiles.getSnapshot();
|
|
18392
|
-
case "tilemap" /* AssetType.Tilemap */: return this.state.tilemaps.getSnapshot();
|
|
18393
|
-
case "animation" /* AssetType.Animation */: return this.state.animations.getSnapshot();
|
|
18394
|
-
}
|
|
19449
|
+
return getAssetCollection(this.state, type).getSnapshot();
|
|
18395
19450
|
}
|
|
18396
19451
|
getGalleryAssets(type) {
|
|
18397
|
-
|
|
18398
|
-
case "image" /* AssetType.Image */: return this.gallery.images.getSnapshot();
|
|
18399
|
-
case "tile" /* AssetType.Tile */: return this.gallery.tiles.getSnapshot();
|
|
18400
|
-
case "tilemap" /* AssetType.Tilemap */: return this.gallery.tilemaps.getSnapshot();
|
|
18401
|
-
case "animation" /* AssetType.Animation */: return this.gallery.animations.getSnapshot();
|
|
18402
|
-
}
|
|
19452
|
+
return getAssetCollection(this.gallery, type).getSnapshot();
|
|
18403
19453
|
}
|
|
18404
19454
|
lookupBlockAsset(type, blockID) {
|
|
18405
19455
|
let filter = (a) => { var _a, _b; return ((_b = (_a = a.meta) === null || _a === void 0 ? void 0 : _a.blockIDs) === null || _b === void 0 ? void 0 : _b.indexOf(blockID)) !== -1; };
|
|
18406
|
-
|
|
18407
|
-
case "image" /* AssetType.Image */: return this.state.images.getSnapshot(filter)[0];
|
|
18408
|
-
case "tile" /* AssetType.Tile */: return this.state.tiles.getSnapshot(filter)[0];
|
|
18409
|
-
case "tilemap" /* AssetType.Tilemap */: return this.state.tilemaps.getSnapshot(filter)[0];
|
|
18410
|
-
case "animation" /* AssetType.Animation */: return this.state.animations.getSnapshot(filter)[0];
|
|
18411
|
-
}
|
|
19456
|
+
return getAssetCollection(this.state, type).getSnapshot(filter)[0];
|
|
18412
19457
|
}
|
|
18413
19458
|
updateAsset(asset) {
|
|
18414
19459
|
this.onChange();
|
|
18415
19460
|
switch (asset.type) {
|
|
18416
|
-
case "image" /* AssetType.Image */:
|
|
18417
|
-
return this.state.images.update(asset.id, asset);
|
|
18418
19461
|
case "tile" /* AssetType.Tile */:
|
|
18419
19462
|
return this.updateTile(asset);
|
|
18420
|
-
|
|
18421
|
-
return this.state.
|
|
18422
|
-
case "animation" /* AssetType.Animation */:
|
|
18423
|
-
return this.state.animations.update(asset.id, asset);
|
|
19463
|
+
default:
|
|
19464
|
+
return getAssetCollection(this.state, asset.type).update(asset.id, asset);
|
|
18424
19465
|
}
|
|
18425
19466
|
}
|
|
18426
19467
|
duplicateAsset(asset, displayName) {
|
|
@@ -18442,53 +19483,22 @@ var pxt;
|
|
|
18442
19483
|
break;
|
|
18443
19484
|
case "animation" /* AssetType.Animation */:
|
|
18444
19485
|
newAsset = this.createNewAnimationFromData(clone.frames, clone.interval, name);
|
|
19486
|
+
break;
|
|
19487
|
+
case "song" /* AssetType.Song */:
|
|
19488
|
+
newAsset = this.createNewSong(asset.song, name);
|
|
19489
|
+
break;
|
|
18445
19490
|
}
|
|
18446
19491
|
return newAsset;
|
|
18447
19492
|
}
|
|
18448
19493
|
removeAsset(asset) {
|
|
18449
19494
|
this.onChange();
|
|
18450
|
-
|
|
18451
|
-
case "image" /* AssetType.Image */:
|
|
18452
|
-
return this.state.images.removeByID(asset.id);
|
|
18453
|
-
case "tile" /* AssetType.Tile */:
|
|
18454
|
-
return this.state.tiles.removeByID(asset.id);
|
|
18455
|
-
case "tilemap" /* AssetType.Tilemap */:
|
|
18456
|
-
return this.state.tilemaps.removeByID(asset.id);
|
|
18457
|
-
case "animation" /* AssetType.Animation */:
|
|
18458
|
-
return this.state.animations.removeByID(asset.id);
|
|
18459
|
-
}
|
|
19495
|
+
getAssetCollection(this.state, asset.type).removeByID(asset.id);
|
|
18460
19496
|
}
|
|
18461
19497
|
addChangeListener(asset, listener) {
|
|
18462
|
-
|
|
18463
|
-
case "image" /* AssetType.Image */:
|
|
18464
|
-
this.state.images.addListener(asset.internalID, listener);
|
|
18465
|
-
break;
|
|
18466
|
-
case "tile" /* AssetType.Tile */:
|
|
18467
|
-
this.state.tiles.addListener(asset.internalID, listener);
|
|
18468
|
-
break;
|
|
18469
|
-
case "tilemap" /* AssetType.Tilemap */:
|
|
18470
|
-
this.state.tilemaps.addListener(asset.internalID, listener);
|
|
18471
|
-
break;
|
|
18472
|
-
case "animation" /* AssetType.Animation */:
|
|
18473
|
-
this.state.animations.addListener(asset.internalID, listener);
|
|
18474
|
-
break;
|
|
18475
|
-
}
|
|
19498
|
+
getAssetCollection(this.state, asset.type).addListener(asset.internalID, listener);
|
|
18476
19499
|
}
|
|
18477
19500
|
removeChangeListener(type, listener) {
|
|
18478
|
-
|
|
18479
|
-
case "image" /* AssetType.Image */:
|
|
18480
|
-
this.state.images.removeListener(listener);
|
|
18481
|
-
break;
|
|
18482
|
-
case "tile" /* AssetType.Tile */:
|
|
18483
|
-
this.state.tiles.removeListener(listener);
|
|
18484
|
-
break;
|
|
18485
|
-
case "tilemap" /* AssetType.Tilemap */:
|
|
18486
|
-
this.state.tilemaps.removeListener(listener);
|
|
18487
|
-
break;
|
|
18488
|
-
case "animation" /* AssetType.Animation */:
|
|
18489
|
-
this.state.animations.removeListener(listener);
|
|
18490
|
-
break;
|
|
18491
|
-
}
|
|
19501
|
+
getAssetCollection(this.state, type).removeListener(listener);
|
|
18492
19502
|
}
|
|
18493
19503
|
loadPackage(pack) {
|
|
18494
19504
|
const allPackages = pack.sortedDeps();
|
|
@@ -18513,7 +19523,7 @@ var pxt;
|
|
|
18513
19523
|
this.gallery.images.add(image);
|
|
18514
19524
|
}
|
|
18515
19525
|
}
|
|
18516
|
-
else {
|
|
19526
|
+
else if (image.type === "animation" /* AssetType.Animation */) {
|
|
18517
19527
|
if (isProject) {
|
|
18518
19528
|
this.state.animations.add(image);
|
|
18519
19529
|
}
|
|
@@ -18521,6 +19531,14 @@ var pxt;
|
|
|
18521
19531
|
this.gallery.animations.add(image);
|
|
18522
19532
|
}
|
|
18523
19533
|
}
|
|
19534
|
+
else {
|
|
19535
|
+
if (isProject) {
|
|
19536
|
+
this.state.songs.add(image);
|
|
19537
|
+
}
|
|
19538
|
+
else {
|
|
19539
|
+
this.gallery.songs.add(image);
|
|
19540
|
+
}
|
|
19541
|
+
}
|
|
18524
19542
|
}
|
|
18525
19543
|
}
|
|
18526
19544
|
for (const tm of getTilemaps(pack.parseJRes())) {
|
|
@@ -18597,6 +19615,9 @@ var pxt;
|
|
|
18597
19615
|
this.state.animations.add(animation);
|
|
18598
19616
|
}
|
|
18599
19617
|
}
|
|
19618
|
+
else if (entry.mimeType === pxt.SONG_MIME_TYPE) {
|
|
19619
|
+
this.state.songs.add(this.generateSong(entry));
|
|
19620
|
+
}
|
|
18600
19621
|
}
|
|
18601
19622
|
for (const animation of toInflate) {
|
|
18602
19623
|
this.state.animations.add(this.inflateAnimation(animation, this.state.images.getSnapshot()));
|
|
@@ -18607,6 +19628,7 @@ var pxt;
|
|
|
18607
19628
|
cleanupCollection(this.state.tiles);
|
|
18608
19629
|
cleanupCollection(this.state.tilemaps);
|
|
18609
19630
|
cleanupCollection(this.state.animations);
|
|
19631
|
+
cleanupCollection(this.state.songs);
|
|
18610
19632
|
function cleanupCollection(collection) {
|
|
18611
19633
|
const inactiveAssets = collection.getSnapshot(asset => { var _a; return !asset.meta.displayName && ((_a = asset.meta.blockIDs) === null || _a === void 0 ? void 0 : _a.some(id => activeBlockIDs.indexOf(id) === -1)); });
|
|
18612
19634
|
const toRemove = [];
|
|
@@ -18636,6 +19658,17 @@ var pxt;
|
|
|
18636
19658
|
bitmap: pxt.sprite.getBitmapFromJResURL(`data:${pxt.IMAGE_MIME_TYPE};base64,${entry.data}`).data()
|
|
18637
19659
|
};
|
|
18638
19660
|
}
|
|
19661
|
+
generateSong(entry) {
|
|
19662
|
+
return {
|
|
19663
|
+
internalID: this.getNewInternalId(),
|
|
19664
|
+
type: "song" /* AssetType.Song */,
|
|
19665
|
+
id: entry.id,
|
|
19666
|
+
meta: {
|
|
19667
|
+
displayName: entry.displayName
|
|
19668
|
+
},
|
|
19669
|
+
song: pxt.assets.music.decodeSongFromHex(entry.data)
|
|
19670
|
+
};
|
|
19671
|
+
}
|
|
18639
19672
|
generateAnimation(entry) {
|
|
18640
19673
|
if (entry.dataEncoding === "json") {
|
|
18641
19674
|
let data;
|
|
@@ -18689,6 +19722,8 @@ var pxt;
|
|
|
18689
19722
|
return this.generateNewIDInternal("tile" /* AssetType.Tile */, pxt.sprite.TILE_PREFIX, pxt.sprite.TILE_NAMESPACE);
|
|
18690
19723
|
case "tilemap" /* AssetType.Tilemap */:
|
|
18691
19724
|
return this.generateNewIDInternal("tilemap" /* AssetType.Tilemap */, lf("level"));
|
|
19725
|
+
case "song" /* AssetType.Song */:
|
|
19726
|
+
return this.generateNewIDInternal("song" /* AssetType.Song */, pxt.sprite.SONG_PREFIX, pxt.sprite.SONG_NAMESPACE);
|
|
18692
19727
|
}
|
|
18693
19728
|
}
|
|
18694
19729
|
generateNewIDInternal(type, varPrefix, namespaceString) {
|
|
@@ -18726,6 +19761,9 @@ var pxt;
|
|
|
18726
19761
|
assets.push(animation);
|
|
18727
19762
|
}
|
|
18728
19763
|
}
|
|
19764
|
+
else if (entry.mimeType === pxt.SONG_MIME_TYPE) {
|
|
19765
|
+
assets.push(this.generateSong(entry));
|
|
19766
|
+
}
|
|
18729
19767
|
}
|
|
18730
19768
|
for (const animation of toInflate) {
|
|
18731
19769
|
assets.push(this.inflateAnimation(animation, assets));
|
|
@@ -18786,6 +19824,7 @@ var pxt;
|
|
|
18786
19824
|
let out = "";
|
|
18787
19825
|
const imageEntries = [];
|
|
18788
19826
|
const animationEntries = [];
|
|
19827
|
+
const songEntries = [];
|
|
18789
19828
|
for (const key of entries) {
|
|
18790
19829
|
if (key === "*")
|
|
18791
19830
|
continue;
|
|
@@ -18812,10 +19851,17 @@ var pxt;
|
|
|
18812
19851
|
expression: `[${animation.frames.map(f => pxt.sprite.bitmapToImageLiteral(pxt.sprite.Bitmap.fromData(f), "typescript")).join(", ")}]`
|
|
18813
19852
|
});
|
|
18814
19853
|
}
|
|
19854
|
+
else if (entry.mimeType === pxt.SONG_MIME_TYPE) {
|
|
19855
|
+
songEntries.push({
|
|
19856
|
+
keys: [getShortIDCore("song" /* AssetType.Song */, key, true), entry.displayName],
|
|
19857
|
+
expression: `hex\`${entry.data}\``
|
|
19858
|
+
});
|
|
19859
|
+
}
|
|
18815
19860
|
}
|
|
18816
19861
|
const warning = lf("Auto-generated code. Do not edit.");
|
|
18817
19862
|
out += emitFactoryHelper("image", imageEntries);
|
|
18818
19863
|
out += emitFactoryHelper("animation", animationEntries);
|
|
19864
|
+
out += emitFactoryHelper("song", songEntries);
|
|
18819
19865
|
return `// ${warning}\nnamespace ${pxt.sprite.IMAGES_NAMESPACE} {\n${out}\n}\n// ${warning}\n`;
|
|
18820
19866
|
}
|
|
18821
19867
|
pxt.emitProjectImages = emitProjectImages;
|
|
@@ -18859,6 +19905,8 @@ var pxt;
|
|
|
18859
19905
|
return Object.assign(Object.assign({}, asset), { frames: asset.frames.map(frame => cloneBitmap(frame)) });
|
|
18860
19906
|
case "tilemap" /* AssetType.Tilemap */:
|
|
18861
19907
|
return Object.assign(Object.assign({}, asset), { data: asset.data.cloneData() });
|
|
19908
|
+
case "song" /* AssetType.Song */:
|
|
19909
|
+
return Object.assign(Object.assign({}, asset), { song: pxt.assets.music.cloneSong(asset.song) });
|
|
18862
19910
|
}
|
|
18863
19911
|
}
|
|
18864
19912
|
pxt.cloneAsset = cloneAsset;
|
|
@@ -18892,6 +19940,13 @@ var pxt;
|
|
|
18892
19940
|
case "animation" /* AssetType.Animation */:
|
|
18893
19941
|
allJRes[id] = serializeAnimation(asset);
|
|
18894
19942
|
break;
|
|
19943
|
+
case "song" /* AssetType.Song */:
|
|
19944
|
+
allJRes[id] = {
|
|
19945
|
+
data: pxt.assets.music.encodeSongToHex(asset.song),
|
|
19946
|
+
mimeType: pxt.SONG_MIME_TYPE,
|
|
19947
|
+
displayName: asset.meta.displayName
|
|
19948
|
+
};
|
|
19949
|
+
break;
|
|
18895
19950
|
}
|
|
18896
19951
|
}
|
|
18897
19952
|
function assetEquals(a, b) {
|
|
@@ -18911,6 +19966,8 @@ var pxt;
|
|
|
18911
19966
|
return a.interval === bAnimation.interval && pxt.U.arrayEquals(a.frames, bAnimation.frames, pxt.sprite.bitmapEquals);
|
|
18912
19967
|
case "tilemap" /* AssetType.Tilemap */:
|
|
18913
19968
|
return a.data.equals(b.data);
|
|
19969
|
+
case "song" /* AssetType.Song */:
|
|
19970
|
+
return pxt.assets.music.songEquals(a.song, b.song);
|
|
18914
19971
|
}
|
|
18915
19972
|
}
|
|
18916
19973
|
pxt.assetEquals = assetEquals;
|
|
@@ -18950,11 +20007,13 @@ var pxt;
|
|
|
18950
20007
|
return `assets.animation${leftTick}${shortId}${rightTick}`;
|
|
18951
20008
|
case "tilemap" /* AssetType.Tilemap */:
|
|
18952
20009
|
return `tilemap${leftTick}${shortId}${rightTick}`;
|
|
20010
|
+
case "song" /* AssetType.Song */:
|
|
20011
|
+
return `assets.song${leftTick}${shortId}${rightTick}`;
|
|
18953
20012
|
}
|
|
18954
20013
|
}
|
|
18955
20014
|
pxt.getTSReferenceForAsset = getTSReferenceForAsset;
|
|
18956
20015
|
function parseAssetTSReference(ts) {
|
|
18957
|
-
const match = /^\s*(?:(?:assets\s*\.\s*(image|tile|animation|tilemap))|(tilemap))\s*(?:`|\(""")([^`"]+)(?:`|"""\))\s*$/m.exec(ts);
|
|
20016
|
+
const match = /^\s*(?:(?:assets\s*\.\s*(image|tile|animation|tilemap|song))|(tilemap))\s*(?:`|\(""")([^`"]+)(?:`|"""\))\s*$/m.exec(ts);
|
|
18958
20017
|
if (match) {
|
|
18959
20018
|
const type = match[1] || match[2];
|
|
18960
20019
|
const name = match[3].trim();
|
|
@@ -18978,6 +20037,8 @@ var pxt;
|
|
|
18978
20037
|
return project.lookupAssetByName("tilemap" /* AssetType.Tilemap */, name) || project.lookupAsset("tilemap" /* AssetType.Tilemap */, name);
|
|
18979
20038
|
case "animation":
|
|
18980
20039
|
return project.lookupAssetByName("animation" /* AssetType.Animation */, name);
|
|
20040
|
+
case "song":
|
|
20041
|
+
return project.lookupAssetByName("song" /* AssetType.Song */, name);
|
|
18981
20042
|
}
|
|
18982
20043
|
}
|
|
18983
20044
|
return undefined;
|
|
@@ -18993,6 +20054,8 @@ var pxt;
|
|
|
18993
20054
|
return lf("level");
|
|
18994
20055
|
case "animation" /* pxt.AssetType.Animation */:
|
|
18995
20056
|
return lf("myAnim");
|
|
20057
|
+
case "song" /* pxt.AssetType.Song */:
|
|
20058
|
+
return lf("mySong");
|
|
18996
20059
|
default:
|
|
18997
20060
|
return lf("asset");
|
|
18998
20061
|
}
|
|
@@ -19017,6 +20080,9 @@ var pxt;
|
|
|
19017
20080
|
case "animation" /* AssetType.Animation */:
|
|
19018
20081
|
prefix = pxt.sprite.ANIMATION_NAMESPACE + ".";
|
|
19019
20082
|
break;
|
|
20083
|
+
case "song" /* AssetType.Song */:
|
|
20084
|
+
prefix = pxt.sprite.SONG_NAMESPACE + ".";
|
|
20085
|
+
break;
|
|
19020
20086
|
}
|
|
19021
20087
|
if (prefix) {
|
|
19022
20088
|
if (id.startsWith(prefix)) {
|
|
@@ -19101,6 +20167,15 @@ var pxt;
|
|
|
19101
20167
|
function read16Bit(buf, offset) {
|
|
19102
20168
|
return buf[offset] | (buf[offset + 1] << 8);
|
|
19103
20169
|
}
|
|
20170
|
+
function getAssetCollection(snapshot, type) {
|
|
20171
|
+
switch (type) {
|
|
20172
|
+
case "animation" /* AssetType.Animation */: return snapshot.animations;
|
|
20173
|
+
case "image" /* AssetType.Image */: return snapshot.images;
|
|
20174
|
+
case "tile" /* AssetType.Tile */: return snapshot.tiles;
|
|
20175
|
+
case "tilemap" /* AssetType.Tilemap */: return snapshot.tilemaps;
|
|
20176
|
+
case "song" /* AssetType.Song */: return snapshot.songs;
|
|
20177
|
+
}
|
|
20178
|
+
}
|
|
19104
20179
|
})(pxt || (pxt = {}));
|
|
19105
20180
|
var pxt;
|
|
19106
20181
|
(function (pxt) {
|