kopia lustrzana https://github.com/backface/turtlestitch
new "play frequency" commands in the Sounds category
rodzic
9d2628274f
commit
0da085bc59
|
@ -16,6 +16,7 @@
|
|||
* selectors for changing and querying "draggable" and "rotation style" settings
|
||||
* new sound + music "volume" feature + blocks
|
||||
* new sound + music stereo "panning" feature + blocks
|
||||
* new "play frequency" commands in the Sounds category
|
||||
* added "neg" selector to monadic function reporter in "Operators" category
|
||||
* added "log2" selector to monadic function reporter in "Operators" category
|
||||
* added "^" reporter (power of) in the Operators category
|
||||
|
@ -23,7 +24,6 @@
|
|||
* special context-aware drop-downs for custom blocks
|
||||
* new "stick to" submenu in the sprite context menu where applicable
|
||||
* multi-line and monospaced "code" input slots for custom blocks
|
||||
* new "play frequency" commands in the AudioComp libary's Sound category
|
||||
* new "string" library, thanks, Brian
|
||||
* new "text costumes" library for generating costumes from letters or words of text
|
||||
* enhanced support for embedding Snap in other website, thanks, Bernat!
|
||||
|
@ -56,9 +56,12 @@
|
|||
* German
|
||||
* French
|
||||
|
||||
### 2019-04-04
|
||||
* Objects, Threads: new "play frequency" commands in the Sounds category
|
||||
|
||||
### 2019-04-03
|
||||
* Objects: Threads: Safari compatibility tweaks (only use StereoPanner if available)
|
||||
* Objects. Store: new feature: volume blocks
|
||||
* Objects, Threads: Safari compatibility tweaks (only use StereoPanner if available)
|
||||
* Objects, Store: new feature: volume blocks
|
||||
* Objects: added relabelling information for the new volume blocks
|
||||
* Objects, Store: new feature: audio stereo-panning blocks
|
||||
* Objects: added relabelling information for the new stereo-panning blocks
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
<script type="text/javascript" src="src/morphic.js?version=2019-02-07"></script>
|
||||
<script type="text/javascript" src="src/widgets.js?version=2018-10-02"></script>
|
||||
<script type="text/javascript" src="src/blocks.js?version=2019-04-02"></script>
|
||||
<script type="text/javascript" src="src/threads.js?version=2019-04-03"></script>
|
||||
<script type="text/javascript" src="src/objects.js?version=2019-04-03"></script>
|
||||
<script type="text/javascript" src="src/threads.js?version=2019-04-04"></script>
|
||||
<script type="text/javascript" src="src/objects.js?version=2019-04-04"></script>
|
||||
<script type="text/javascript" src="src/gui.js?version=2019-03-25"></script>
|
||||
<script type="text/javascript" src="src/paint.js?version=2019-02-22"></script>
|
||||
<script type="text/javascript" src="src/lists.js?version=2019-02-07"></script>
|
||||
|
|
110
src/objects.js
110
src/objects.js
|
@ -84,7 +84,7 @@ BlockEditorMorph, BlockDialogMorph, PrototypeHatBlockMorph, localize,
|
|||
TableMorph, TableFrameMorph, normalizeCanvas, BooleanSlotMorph, HandleMorph,
|
||||
AlignmentMorph, Process, XML_Element, VectorPaintEditorMorph*/
|
||||
|
||||
modules.objects = '2019-April-03';
|
||||
modules.objects = '2019-April-04';
|
||||
|
||||
var SpriteMorph;
|
||||
var StageMorph;
|
||||
|
@ -513,6 +513,17 @@ SpriteMorph.prototype.initBlocks = function () {
|
|||
category: 'sound',
|
||||
spec: 'pan left/right'
|
||||
},
|
||||
playFreq: {
|
||||
type: 'command',
|
||||
category: 'sound',
|
||||
spec: 'play frequency %n hz',
|
||||
defaults: [440]
|
||||
},
|
||||
stopFreq: {
|
||||
type: 'command',
|
||||
category: 'sound',
|
||||
spec: 'stop frequency'
|
||||
},
|
||||
|
||||
// Sound - Debugging primitives for development mode
|
||||
reportSounds: {
|
||||
|
@ -1471,6 +1482,9 @@ SpriteMorph.prototype.init = function (globals) {
|
|||
this.pan = 0;
|
||||
this.pannerNode = null; // must be lazily initialized in Chrome, sigh...
|
||||
|
||||
// frequency player, experimental
|
||||
this.freqPlayer = null; // Note, to be lazily initialized
|
||||
|
||||
// pen hsv color support
|
||||
this.cachedHSV = [0, 0, 0]; // not serialized
|
||||
|
||||
|
@ -1534,6 +1548,7 @@ SpriteMorph.prototype.fullCopy = function (forClone) {
|
|||
c.color = this.color.copy();
|
||||
c.gainNode = null;
|
||||
c.pannerNode = null;
|
||||
c.freqPlayer = null;
|
||||
c.blocksCache = {};
|
||||
c.paletteCache = {};
|
||||
c.cachedHSV = c.color.hsv();
|
||||
|
@ -2030,6 +2045,9 @@ SpriteMorph.prototype.blockTemplates = function (category) {
|
|||
blocks.push(block('setPan'));
|
||||
blocks.push(watcherToggle('getPan'));
|
||||
blocks.push(block('getPan'));
|
||||
blocks.push('-');
|
||||
blocks.push(block('playFreq'));
|
||||
blocks.push(block('stopFreq'));
|
||||
|
||||
// for debugging: ///////////////
|
||||
|
||||
|
@ -3384,6 +3402,57 @@ SpriteMorph.prototype.getPannerNode = function () {
|
|||
return this.pannerNode;
|
||||
};
|
||||
|
||||
// SpriteMorph frequency player
|
||||
|
||||
SpriteMorph.prototype.playFreq = function (hz) {
|
||||
// start playing the given frequency until stopped
|
||||
var note,
|
||||
ctx = this.audioContext(),
|
||||
gain = this.getGainNode(),
|
||||
pan = this.getPannerNode(),
|
||||
stage = this.parentThatIsA(StageMorph);
|
||||
if (!this.freqPlayer) {
|
||||
this.freqPlayer = new Note();
|
||||
}
|
||||
note = this.freqPlayer;
|
||||
if (note.oscillator) {
|
||||
note.oscillator.frequency.value = hz;
|
||||
} else {
|
||||
note.oscillator = ctx.createOscillator();
|
||||
if (!note.oscillator.start) {
|
||||
note.oscillator.start = note.oscillator.noteOn;
|
||||
}
|
||||
if (!note.oscillator.stop) {
|
||||
note.oscillator.stop = note.oscillator.noteOff;
|
||||
}
|
||||
note.setInstrument(this.instrument);
|
||||
note.oscillator.frequency.value = hz;
|
||||
this.setVolume(this.volume);
|
||||
note.oscillator.connect(gain);
|
||||
if (pan) {
|
||||
gain.connect(pan);
|
||||
pan.connect(ctx.destination);
|
||||
this.setPan(this.pan);
|
||||
} else {
|
||||
gain.connect(ctx.destination);
|
||||
}
|
||||
note.ended = false;
|
||||
if (stage) {
|
||||
stage.activeSounds.push(note);
|
||||
stage.activeSounds = stage.activeSounds.filter(function (snd) {
|
||||
return !snd.ended && !snd.terminated;
|
||||
});
|
||||
}
|
||||
note.oscillator.start(0);
|
||||
}
|
||||
};
|
||||
|
||||
SpriteMorph.prototype.stopFreq = function () {
|
||||
if (this.freqPlayer) {
|
||||
this.freqPlayer.stop();
|
||||
}
|
||||
};
|
||||
|
||||
// SpriteMorph user menu
|
||||
|
||||
SpriteMorph.prototype.userMenu = function () {
|
||||
|
@ -6568,6 +6637,9 @@ StageMorph.prototype.init = function (globals) {
|
|||
this.pan = 0;
|
||||
this.pannerNode = null; // must be lazily initialized in Chrome, sigh...
|
||||
|
||||
// frequency player, experimental
|
||||
this.freqPlayer = null; // Note, to be lazily initialized
|
||||
|
||||
this.watcherUpdateFrequency = 2;
|
||||
this.lastWatcherUpdate = Date.now();
|
||||
|
||||
|
@ -7400,6 +7472,9 @@ StageMorph.prototype.blockTemplates = function (category) {
|
|||
blocks.push(block('setPan'));
|
||||
blocks.push(watcherToggle('getPan'));
|
||||
blocks.push(block('getPan'));
|
||||
blocks.push('-');
|
||||
blocks.push(block('playFreq'));
|
||||
blocks.push(block('stopFreq'));
|
||||
|
||||
// for debugging: ///////////////
|
||||
|
||||
|
@ -8038,6 +8113,14 @@ StageMorph.prototype.getPan
|
|||
StageMorph.prototype.getPannerNode
|
||||
= SpriteMorph.prototype.getPannerNode;
|
||||
|
||||
// StageMorph frequency player
|
||||
|
||||
StageMorph.prototype.playFreq
|
||||
= SpriteMorph.prototype.playFreq;
|
||||
|
||||
StageMorph.prototype.stopFreq
|
||||
= SpriteMorph.prototype.stopFreq;
|
||||
|
||||
// StageMorph non-variable watchers
|
||||
|
||||
StageMorph.prototype.toggleWatcher
|
||||
|
@ -9037,6 +9120,7 @@ function Note(pitch) {
|
|||
this.frequency = null; // alternative for playing a non-note frequency
|
||||
this.setupContext();
|
||||
this.oscillator = null;
|
||||
this.ended = false; // for active sounds management
|
||||
}
|
||||
|
||||
// Note shared properties
|
||||
|
@ -9085,12 +9169,7 @@ Note.prototype.play = function (type, gainNode, pannerNode) {
|
|||
if (!this.oscillator.stop) {
|
||||
this.oscillator.stop = this.oscillator.noteOff;
|
||||
}
|
||||
this.oscillator.type = [
|
||||
'sine',
|
||||
'square',
|
||||
'sawtooth',
|
||||
'triangle'
|
||||
][(type || 1) - 1];
|
||||
this.setInstrument(type);
|
||||
this.oscillator.frequency.value = isNil(this.frequency) ?
|
||||
Math.pow(2, (this.pitch - 69) / 12) * 440 : this.frequency;
|
||||
this.oscillator.connect(gainNode);
|
||||
|
@ -9100,14 +9179,31 @@ Note.prototype.play = function (type, gainNode, pannerNode) {
|
|||
} else {
|
||||
gainNode.connect(this.audioContext.destination);
|
||||
}
|
||||
this.ended = false;
|
||||
this.oscillator.start(0);
|
||||
};
|
||||
|
||||
Note.prototype.setInstrument = function (type) {
|
||||
// private - make sure the oscillator node has been initialized before
|
||||
this.oscillator.type = [
|
||||
'sine',
|
||||
'square',
|
||||
'sawtooth',
|
||||
'triangle'
|
||||
][(type || 1) - 1];
|
||||
};
|
||||
|
||||
Note.prototype.stop = function () {
|
||||
if (this.oscillator) {
|
||||
this.oscillator.stop(0);
|
||||
this.oscillator = null;
|
||||
}
|
||||
this.ended = true;
|
||||
};
|
||||
|
||||
Note.prototype.pause = function () {
|
||||
// emulate a sound for active sounds mngmt
|
||||
this.stop();
|
||||
};
|
||||
|
||||
// Microphone /////////////////////////////////////////////////////////
|
||||
|
|
|
@ -62,7 +62,7 @@ StageMorph, SpriteMorph, StagePrompterMorph, Note, modules, isString, copy,
|
|||
isNil, WatcherMorph, List, ListWatcherMorph, alert, console, TableMorph, Color,
|
||||
TableFrameMorph, ColorSlotMorph, isSnapObject, Map*/
|
||||
|
||||
modules.threads = '2019-April-03';
|
||||
modules.threads = '2019-April-04';
|
||||
|
||||
var ThreadManager;
|
||||
var Process;
|
||||
|
@ -4147,6 +4147,9 @@ Process.prototype.doPlayFrequencyForSecs = function (hz, secs) {
|
|||
Process.prototype.doSetInstrument = function (num) {
|
||||
this.instrument = +num;
|
||||
this.receiver.instrument = +num;
|
||||
if (this.receiver.freqPlayer) {
|
||||
this.receiver.freqPlayer.setInstrument(+num);
|
||||
}
|
||||
};
|
||||
|
||||
// Process constant input options
|
||||
|
|
Ładowanie…
Reference in New Issue