diff --git a/HISTORY.md b/HISTORY.md
index 59fb22ac..bdf8fb5c 100755
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -53,6 +53,7 @@
* ported multiline library to new (custom input slot) format
* new "text costumes" library for generating costumes from letters or words of text
* took out "b block" costume from catalog
+* added microphone "resolution" concept governing "bins" (buffer / bin sizes)
### 2019-03-10
* Objects, Blocks, Threads: added microphone note and pitch detection
diff --git a/snap.html b/snap.html
index f528fe5f..0981b360 100755
--- a/snap.html
+++ b/snap.html
@@ -6,9 +6,9 @@
-
-
-
+
+
+
diff --git a/src/blocks.js b/src/blocks.js
index 9f122ff6..9b525a3f 100644
--- a/src/blocks.js
+++ b/src/blocks.js
@@ -148,7 +148,7 @@ CustomCommandBlockMorph, SymbolMorph, ToggleButtonMorph, DialMorph*/
// Global stuff ////////////////////////////////////////////////////////
-modules.blocks = '2019-March-10';
+modules.blocks = '2019-March-11';
var SyntaxElementMorph;
var BlockMorph;
@@ -992,7 +992,9 @@ SyntaxElementMorph.prototype.labelPart = function (spec) {
'note' : ['note'],
'pitch' : ['pitch'],
'signals' : ['signals'],
- 'frequencies' : ['frequencies']
+ 'frequencies' : ['frequencies'],
+ '~' : null,
+ 'bins' : ['bins']
},
true // read-only
);
diff --git a/src/objects.js b/src/objects.js
index 48bfa500..e8081b76 100644
--- a/src/objects.js
+++ b/src/objects.js
@@ -84,7 +84,7 @@ BlockEditorMorph, BlockDialogMorph, PrototypeHatBlockMorph, localize,
TableMorph, TableFrameMorph, normalizeCanvas, BooleanSlotMorph, HandleMorph,
AlignmentMorph, Process, XML_Element, VectorPaintEditorMorph*/
-modules.objects = '2019-March-10';
+modules.objects = '2019-March-11';
var SpriteMorph;
var StageMorph;
@@ -8871,8 +8871,7 @@ function Microphone() {
this.analyser = null;
// parameters:
- this.signalBufferSize = 512; // should probably be 1024 by default
- this.fftSize = 1024; // should probably be 2048 by default
+ this.resolution = 2;
this.MIN_SAMPLES = 0; // will be initialized when AudioContext is created.
this.GOOD_ENOUGH_CORRELATION = 0.9;
@@ -8904,6 +8903,27 @@ Microphone.prototype.isOn = function () {
return false;
};
+// Microphone shared properties
+
+Microphone.prototype.binSizes = [256, 512, 1024, 2048, 4096];
+
+// Microphone resolution
+
+Microphone.prototype.binSize = function () {
+ return this.binSizes[this.resolution - 1];
+};
+
+Microphone.prototype.setResolution = function (num) {
+ if (contains([1, 2, 3, 4], num)) {
+ if (this.isReady) {
+ this.stop();
+ this.resolution = num;
+ }
+ }
+};
+
+// Microphone ops
+
Microphone.prototype.start = function () {
var AudioContext = window.AudioContext || window.webkitAudioContext,
myself = this;
@@ -8964,7 +8984,7 @@ Microphone.prototype.setupNodes = function (stream) {
Microphone.prototype.createAnalyser = function () {
var freqBufLength;
this.analyser = this.audioContext.createAnalyser();
- this.analyser.fftSize = this.fftSize;
+ this.analyser.fftSize = this.binSizes[this.resolution];
freqBufLength = this.analyser.frequencyBinCount;
this.freqBuffer = new Uint8Array(freqBufLength);
this.pitchBuffer = new Float32Array(freqBufLength);
@@ -8973,7 +8993,7 @@ Microphone.prototype.createAnalyser = function () {
Microphone.prototype.createProcessor = function () {
var myself = this;
this.processor = this.audioContext.createScriptProcessor(
- this.signalBufferSize
+ this.binSizes[this.resolution - 1]
);
this.processor.onaudioprocess = function (event) {
diff --git a/src/threads.js b/src/threads.js
index f381c5b1..4e6fd682 100644
--- a/src/threads.js
+++ b/src/threads.js
@@ -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-March-10';
+modules.threads = '2019-March-11';
var ThreadManager;
var Process;
@@ -2252,9 +2252,13 @@ Process.prototype.doStopAllSounds = function () {
// Process audio input (interpolated)
Process.prototype.reportAudio = function (choice) {
- var stage = this.blockReceiver().parentThatIsA(StageMorph);
+ var stage = this.blockReceiver().parentThatIsA(StageMorph),
+ selection = this.inputOption(choice);
+ if (selection === 'bins') {
+ return stage.microphone.binSize();
+ }
if (stage.microphone.isOn()) {
- switch (this.inputOption(choice)) {
+ switch (selection) {
case 'volume':
return stage.microphone.volume;
case 'pitch':