mirror of
https://github.com/eliasstepanik/strudel-docker.git
synced 2026-01-11 05:38:34 +00:00
- add defaultmidimap function
- add midisounds function - add midiport control
This commit is contained in:
parent
d86df33b8c
commit
c810a02a79
@ -1515,6 +1515,7 @@ export const { hbrick } = registerControl('hbrick');
|
||||
export const { lbrick } = registerControl('lbrick');
|
||||
export const { midichan } = registerControl('midichan');
|
||||
export const { midimap } = registerControl('midimap');
|
||||
export const { midiport } = registerControl('midiport');
|
||||
export const { control } = registerControl('control');
|
||||
export const { ccn } = registerControl('ccn');
|
||||
export const { ccv } = registerControl('ccv');
|
||||
|
||||
@ -90,7 +90,7 @@ if (typeof window !== 'undefined') {
|
||||
}
|
||||
|
||||
// registry for midi mappings, converting control names to cc messages
|
||||
export const midiMappings = new Map();
|
||||
export const midicontrolMap = new Map();
|
||||
|
||||
// takes midimap and converts each control key to the main control name
|
||||
function unifyMapping(mapping) {
|
||||
@ -103,10 +103,6 @@ function unifyMapping(mapping) {
|
||||
}),
|
||||
);
|
||||
}
|
||||
// adds a midimap to the registry
|
||||
export function addMidimap(name, mapping) {
|
||||
midiMappings.set(name, unifyMapping(mapping));
|
||||
}
|
||||
|
||||
function githubPath(base, subpath = '') {
|
||||
if (!base.startsWith('github:')) {
|
||||
@ -121,6 +117,11 @@ function githubPath(base, subpath = '') {
|
||||
return `https://raw.githubusercontent.com/${path}/${subpath}`;
|
||||
}
|
||||
|
||||
// configures the default midimap, which is used when no "midimap" port is set
|
||||
export function defaultmidimap(mapping) {
|
||||
midicontrolMap.set('default', unifyMapping(mapping));
|
||||
}
|
||||
|
||||
let loadCache = {};
|
||||
// adds multiple midimaps to the registry
|
||||
export async function midimaps(map) {
|
||||
@ -134,10 +135,34 @@ export async function midimaps(map) {
|
||||
map = await loadCache[map];
|
||||
}
|
||||
if (typeof map === 'object') {
|
||||
Object.entries(map).forEach(([name, mapping]) => addMidimap(name, mapping));
|
||||
Object.entries(map).forEach(([name, mapping]) => midicontrolMap.set(name, unifyMapping(mapping)));
|
||||
}
|
||||
}
|
||||
|
||||
// registry for midi sounds, converting sound names to controls
|
||||
export const midisoundMap = new Map();
|
||||
// adds multiple midimaps to the registry
|
||||
export async function midisounds(map) {
|
||||
if (typeof map === 'object') {
|
||||
Object.entries(map).forEach(([name, mapping]) => midisoundMap.set(name, mapping));
|
||||
}
|
||||
}
|
||||
|
||||
function applyMidisounds(hapValue) {
|
||||
const { s } = hapValue;
|
||||
if (!midisoundMap.has(s)) {
|
||||
return;
|
||||
}
|
||||
let controls = midisoundMap.get(hapValue.s);
|
||||
if (Array.isArray(controls)) {
|
||||
controls = controls[hapValue.n || 0];
|
||||
}
|
||||
if (typeof controls === 'string') {
|
||||
controls = { note: controls };
|
||||
}
|
||||
Object.assign(hapValue, controls);
|
||||
}
|
||||
|
||||
// normalizes the given value from the given range and exponent
|
||||
function normalize(value = 0, min = 0, max = 1, exp = 1) {
|
||||
if (min === max) {
|
||||
@ -197,20 +222,39 @@ Pattern.prototype.midi = function (output) {
|
||||
console.log('not enabled');
|
||||
return;
|
||||
}
|
||||
const device = getDevice(output, WebMidi.outputs);
|
||||
hap.ensureObjectValue();
|
||||
//magic number to get audio engine to line up, can probably be calculated somehow
|
||||
const latencyMs = 34;
|
||||
// passing a string with a +num into the webmidi api adds an offset to the current time https://webmidijs.org/api/classes/Output
|
||||
const timeOffsetString = `+${getEventOffsetMs(targetTime, currentTime) + latencyMs}`;
|
||||
// convert s to midisounds preset (if set)
|
||||
applyMidisounds(hap.value);
|
||||
|
||||
// destructure value
|
||||
let { note, nrpnn, nrpv, ccn, ccv, midichan = 1, midicmd, gain = 1, velocity = 0.9, midimap } = hap.value;
|
||||
let {
|
||||
note,
|
||||
ccn,
|
||||
ccv,
|
||||
midichan = 1,
|
||||
midicmd,
|
||||
gain = 1,
|
||||
velocity = 0.9,
|
||||
midimap = 'default',
|
||||
midiport = output,
|
||||
} = hap.value;
|
||||
|
||||
const device = getDevice(midiport, WebMidi.outputs);
|
||||
if (!device) {
|
||||
logger(
|
||||
`[midi] midiport "${midiport}" not found! available: ${WebMidi.outputs.map((output) => `'${output.name}'`).join(', ')}`,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
velocity = gain * velocity;
|
||||
|
||||
// if midimap is set, send a cc messages from defined controls
|
||||
if (!!midimap && midiMappings.has(midimap)) {
|
||||
const ccs = mapCC(midiMappings.get(midimap), hap.value);
|
||||
if (midicontrolMap.has(midimap)) {
|
||||
const ccs = mapCC(midicontrolMap.get(midimap), hap.value);
|
||||
ccs.forEach(({ ccn, ccv }) => sendCC(ccn, ccv, device, midichan, timeOffsetString));
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user