Skip to content

Commit

Permalink
v6 - scale aware
Browse files Browse the repository at this point in the history
  • Loading branch information
zsteinkamp committed Dec 18, 2024
1 parent 6b51e08 commit 11b3dbe
Show file tree
Hide file tree
Showing 7 changed files with 166 additions and 8 deletions.
Binary file modified Project/fractalNoteEcho.amxd
Binary file not shown.
81 changes: 76 additions & 5 deletions Project/fractalNoteEcho.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
return to.concat(ar || Array.prototype.slice.call(from));
};
autowatch = 1;
inlets = 12;
inlets = 13;
outlets = 5;
// inlets
var INLET_NOTE = 0;
Expand All @@ -23,6 +23,7 @@ var INLET_BASE3 = 8;
var INLET_BASE4 = 9;
var INLET_DUR_BASE = 10;
var INLET_DUR_DECAY = 11;
var INLET_SCALE_AWARE = 12;
// outlets
var OUTLET_NOTE = 0;
var OUTLET_VELOCITY = 1;
Expand All @@ -41,6 +42,7 @@ setinletassist(INLET_BASE3, 'Tap 3');
setinletassist(INLET_BASE4, 'Tap 4');
setinletassist(INLET_DUR_BASE, 'Duration Base (float)');
setinletassist(INLET_DUR_DECAY, 'Duration Decay (float)');
setinletassist(INLET_SCALE_AWARE, 'Scale Aware (1|0)');
// outlets
setoutletassist(OUTLET_NOTE, 'Note Number (int)');
setoutletassist(OUTLET_VELOCITY, 'Note Velocity (int)');
Expand Down Expand Up @@ -137,11 +139,67 @@ var options = [
0,
0,
100,
0.5, // INLET_DUR_DECAY
0.5,
1, // INLET_SCALE_AWARE
];
// initialize
//setupRepeats();
var scaleMeta = {
notes: [],
watchers: {
root: null,
int: null,
mode: null
}
};
function init() {
if (!scaleMeta.watchers.root) {
scaleMeta.watchers.root = new LiveAPI(updateScales, 'live_set');
scaleMeta.watchers.root.property = 'root_note';
scaleMeta.watchers.int = new LiveAPI(updateScales, 'live_set');
scaleMeta.watchers.int.property = 'scale_intervals';
scaleMeta.watchers.mode = new LiveAPI(updateScales, 'live_set');
scaleMeta.watchers.mode.property = 'scale_mode';
}
}
function updateScales() {
if (!scaleMeta.watchers.root) {
//log('early')
return;
}
var api = new LiveAPI(function () { }, 'live_set');
var root = api.get('root_note');
var intervals = api.get('scale_intervals');
scaleMeta.notes = [];
var root_note = root - 12;
var note = root_note;
while (note <= 127) {
for (var _i = 0, intervals_1 = intervals; _i < intervals_1.length; _i++) {
var interval = intervals_1[_i];
note = root_note + interval;
if (note >= 0 && note <= 127) {
scaleMeta.notes.push(note);
}
}
root_note += 12;
note = root_note;
}
//log(
// 'ROOT=' +
// root +
// ' INT=' +
// intervals +
// ' MODE=' +
// state.scale_mode +
// ' NAME=' +
// state.scale_name +
// ' AWARE=' +
// state.scale_aware +
// ' NOTES=' +
// state.scale_notes
}
function setupRepeats() {
if (options[INLET_SCALE_AWARE]) {
updateScales();
}
// set up base pattern
pattern = [{ origTap: 0, ms: 0 }];
options[INLET_BASE1] &&
Expand Down Expand Up @@ -213,7 +271,20 @@ function iterRepeats(togo, offsetMs, parentIdx) {
// utility to return a function that will be used to create a note-playing task
function makeTask(r, n, v) {
return function () {
n = Math.floor(n + r.note_incr);
if (options[INLET_SCALE_AWARE]) {
// get base note, look up
var baseIdx = scaleMeta.notes.indexOf(n);
var newIdx = baseIdx + r.note_incr;
n = scaleMeta.notes[newIdx];
//log('NOTE: ' + n + ' base:' + baseIdx + ' new:' + newIdx)
if (!n) {
// invalid note
return;
}
}
else {
n = Math.floor(n + r.note_incr);
}
v = Math.floor(v * r.velocity_coeff);
//utils.log({
// n: n,
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,11 @@ This allows for easy creation of very complex patterns that, due to their nature

## Installation / Setup

If you just want to download and install the device, then go to the [frozen/](https://github.com/zsteinkamp/m4l-js-fractalNoteEcho/tree/main/frozen) directory and download the newest version there.
If you just want to download and install the device, then go to the [releases/](https://github.com/zsteinkamp/m4l-FractalNoteEcho/releases) page and download the newest version there.

### Changelog

- [v6](https://github.com/zsteinkamp/m4l-js-fractalNoteEcho/releases/download/v6/FractalNoteEcho-v6.amxd) - 2024-12-18 - Adds scale awareness.
- [v5](https://github.com/zsteinkamp/m4l-js-fractalNoteEcho/releases/download/v5/FractalNoteEcho-v5.amxd) - 2024-10-29 - Add non-blocking telemetry ping on load. Does not send any identifying information, only the plugin name, the local computer name, type of computer, and CPU type. I just want to see which plugins are used the most.
- [4](https://github.com/zsteinkamp/m4l-js-fractalNoteEcho/releases/download/v4/FractalNoteEcho-4.amxd) - 2023-07-28 - Rewrite in Typescript, add flashing bubbles.
- [3](https://github.com/zsteinkamp/m4l-js-fractalNoteEcho/raw/main/frozen/FractalNoteEcho-3.amxd) - 2023-07-09 - Add tempo-synced time mode option.
Expand Down
Binary file added frozen/FractalNoteEcho-v6.amxd
Binary file not shown.
Binary file modified images/screenshot.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/screenshot.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
90 changes: 88 additions & 2 deletions src/fractalNoteEcho.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
autowatch = 1
inlets = 12
inlets = 13
outlets = 5

// inlets
Expand All @@ -15,6 +15,7 @@ const INLET_BASE3 = 8
const INLET_BASE4 = 9
const INLET_DUR_BASE = 10
const INLET_DUR_DECAY = 11
const INLET_SCALE_AWARE = 12

// outlets
const OUTLET_NOTE = 0
Expand All @@ -35,6 +36,7 @@ setinletassist(INLET_BASE3, 'Tap 3')
setinletassist(INLET_BASE4, 'Tap 4')
setinletassist(INLET_DUR_BASE, 'Duration Base (float)')
setinletassist(INLET_DUR_DECAY, 'Duration Decay (float)')
setinletassist(INLET_SCALE_AWARE, 'Scale Aware (1|0)')

// outlets
setoutletassist(OUTLET_NOTE, 'Note Number (int)')
Expand Down Expand Up @@ -139,12 +141,83 @@ const options = [
0, // INLET_BASE4
100, // INLET_DUR_BASE
0.5, // INLET_DUR_DECAY
1, // INLET_SCALE_AWARE
]

// initialize
//setupRepeats();
type ScaleType = {
notes: number[]
watchers: {
root: LiveAPI
int: LiveAPI
mode: LiveAPI
}
}
const scaleMeta: ScaleType = {
notes: [],
watchers: {
root: null,
int: null,
mode: null,
},
}

function init() {
if (!scaleMeta.watchers.root) {
scaleMeta.watchers.root = new LiveAPI(updateScales, 'live_set')
scaleMeta.watchers.root.property = 'root_note'

scaleMeta.watchers.int = new LiveAPI(updateScales, 'live_set')
scaleMeta.watchers.int.property = 'scale_intervals'

scaleMeta.watchers.mode = new LiveAPI(updateScales, 'live_set')
scaleMeta.watchers.mode.property = 'scale_mode'
}
}

function updateScales() {
if (!scaleMeta.watchers.root) {
//log('early')
return
}
const api = new LiveAPI(() => {}, 'live_set')
const root = api.get('root_note')
const intervals = api.get('scale_intervals')
scaleMeta.notes = []

let root_note = root - 12
let note = root_note

while (note <= 127) {
for (const interval of intervals) {
note = root_note + interval
if (note >= 0 && note <= 127) {
scaleMeta.notes.push(note)
}
}
root_note += 12
note = root_note
}
//log(
// 'ROOT=' +
// root +
// ' INT=' +
// intervals +
// ' MODE=' +
// state.scale_mode +
// ' NAME=' +
// state.scale_name +
// ' AWARE=' +
// state.scale_aware +
// ' NOTES=' +
// state.scale_notes
}

function setupRepeats() {
if (options[INLET_SCALE_AWARE]) {
updateScales()
}
// set up base pattern
pattern = [{ origTap: 0, ms: 0 }]
options[INLET_BASE1] &&
Expand Down Expand Up @@ -230,7 +303,20 @@ function iterRepeats(togo: number, offsetMs: number, parentIdx: number) {
// utility to return a function that will be used to create a note-playing task
function makeTask(r: NoteMeta, n: number, v: number) {
return function () {
n = Math.floor(n + r.note_incr)
if (options[INLET_SCALE_AWARE]) {
// get base note, look up
const baseIdx = scaleMeta.notes.indexOf(n)
const newIdx = baseIdx + r.note_incr
n = scaleMeta.notes[newIdx]
//log('NOTE: ' + n + ' base:' + baseIdx + ' new:' + newIdx)
if (!n) {
// invalid note
return
}
} else {
n = Math.floor(n + r.note_incr)
}

v = Math.floor(v * r.velocity_coeff)

//utils.log({
Expand Down

0 comments on commit 11b3dbe

Please sign in to comment.