Skip to content

Commit

Permalink
Add arpeggio example for midi in
Browse files Browse the repository at this point in the history
  • Loading branch information
amiika committed Oct 6, 2023
2 parents 52872ba + be85953 commit 15e47ec
Show file tree
Hide file tree
Showing 8 changed files with 733 additions and 20 deletions.
36 changes: 36 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,42 @@ <h1 class="mt-12 font-semibold rounded bg-gray-800 justify-center text-center te
</div>
</div>
</div>

<!-- Midi settings -->
<div id="midi-settings-container" class="bg-gray-200 rounded-lg flex flex-row mr-4 ml-4">
<div class="flex flex-row">
<div class="flex items-center mb-4 ml-6">
<label for="default-checkbox" class="ml-2 text-sm font-medium text-dark">MIDI Clock:&nbsp;</label>
<select id="midi-clock-input" class="w-32 h-8 text-sm font-medium text-black bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2">
<option value="-1">Internal</option>
</select>
</div>
<div class="flex items-center mb-4 ml-6">
<label for="default-checkbox" class="ml-2 text-sm font-medium text-dark">Clock PPQN:&nbsp;</label>
<select id="midi-clock-ppqn-input" class="w-32 h-8 text-sm font-medium text-black bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2">
<option value="24">24</option>
<option value="48">48</option>
</select>
</div>
<div class="flex items-center mb-4 ml-20">
<input id="send-midi-clock" type="checkbox" value="" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
<label for="default-checkbox" class="ml-2 text-sm font-medium text-dark">Send MIDI Clock</label>
</div>
</div>
<div class="flex flex-row">
<div class="flex items-center mb-4 ml-6">
<label for="default-checkbox" class="ml-2 text-sm font-medium text-dark">MIDI input:&nbsp;</label>
<select id="default-midi-input" class="w-32 h-8 text-sm font-medium text-black bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2">
<option value="-1">None</option>
</select>
</div>
<div class="flex items-center mb-4 ml-20">
<input id="midi-channels-scripts" type="checkbox" value="" class="w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600">
<label for="default-checkbox" class="ml-2 text-sm font-medium text-dark">Route channels to scripts</label>
</div>
</div>
</div>

<div class="flex space-x-6 border-t border-gray-200 rounded-b dark:border-gray-600 mx-4 border-spacing-y-4">
<button id="close-settings-button" data-modal-hide="defaultModal" type="button" class="hover:bg-gray-700 bg-gray-800 mt-4 mb-4 text-white focus:ring-4 font-medium rounded-lg text-sm px-5 py-2.5 text-center">OK</button>
</div>
Expand Down
130 changes: 126 additions & 4 deletions src/API.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { seededRandom } from "zifferjs";
import { MidiConnection } from "./IO/MidiConnection";
import { MidiCCEvent, MidiConnection, MidiNoteEvent } from "./IO/MidiConnection";
import { tryEvaluate, evaluateOnce } from "./Evaluator";
import { DrunkWalk } from "./Utils/Drunk";
import { Editor } from "./main";
Expand Down Expand Up @@ -57,11 +57,12 @@ export class UserAPI {
public patternCache = new LRUCache({ max: 1000, ttl: 1000 * 60 * 5 });
private errorTimeoutID: number = 0;
private printTimeoutID: number = 0;

MidiConnection: MidiConnection = new MidiConnection();
public MidiConnection: MidiConnection;
load: samples;

constructor(public app: Editor) {}
constructor(public app: Editor) {
this.MidiConnection = new MidiConnection(this, app.settings);
}

_loadUniverseFromInterface = (universe: string) => {
this.app.loadUniverse(universe as string);
Expand Down Expand Up @@ -447,6 +448,127 @@ export class UserAPI {
this.MidiConnection.panic();
};

public active_note_events = (channel?: number): MidiNoteEvent[]|undefined => {
/**
* @returns A list of currently active MIDI notes
*/
let events;
if(channel) {
events = this.MidiConnection.activeNotesFromChannel(channel);
} else {
events = this.MidiConnection.activeNotes;
}
if(events.length>0) return events
else return undefined;
}

public transmission(): boolean {
/**
* Returns true if there are active notes
*/
return this.MidiConnection.activeNotes.length > 0;
}

public active_notes = (channel?: number): number[]|undefined => {
/**
* @returns A list of currently active MIDI notes
*/
const notes = this.active_note_events(channel);
if(notes && notes.length > 0) return notes.map((e) => e.note);
else return undefined;
}

public kill_active_notes = (): void => {
/**
* Clears all active notes
*/
this.MidiConnection.activeNotes = [];
}

public sticky_notes = (channel?: number): number[]|undefined => {
/**
*
* @param channel
* @returns
*/
let notes;
if(channel) notes = this.MidiConnection.stickyNotesFromChannel(channel);
else notes = this.MidiConnection.stickyNotes;
if(notes.length > 0) return notes.map((e) => e.note);
else return undefined;
}

public kill_sticky_notes = (): void => {
/**
* Clears all sticky notes
*/
this.MidiConnection.stickyNotes = [];
}

public buffer = (channel?: number): boolean => {
/**
* Return true if there is last note event
*/
if(channel) return this.MidiConnection.findNoteFromBufferInChannel(channel) !== undefined;
else return this.MidiConnection.noteInputBuffer.length > 0;
}

public buffer_event = (channel?: number): MidiNoteEvent|undefined => {
/**
* @returns Returns latest unlistened note event
*/
if(channel) return this.MidiConnection.findNoteFromBufferInChannel(channel);
else return this.MidiConnection.noteInputBuffer.shift();
}

public buffer_note = (channel?: number): number|undefined => {
/**
* @returns Returns latest received note
*/
const note = this.buffer_event(channel);
return note ? note.note : undefined;
}

public last_note_event = (channel?: number): MidiNoteEvent|undefined => {
/**
* @returns Returns last received note
*/
if(channel) return this.MidiConnection.lastNoteInChannel[channel];
else return this.MidiConnection.lastNote;
}

public last_note = (channel?: number): number|undefined => {
/**
* @returns Returns last received note
*/
const note = this.last_note_event(channel);
return note ? note.note : undefined;
}

public last_cc = (control: number, channel?: number): number|undefined => {
/**
* @returns Returns last received cc
*/
if(channel) return this.MidiConnection.lastCCInChannel[channel][control];
else return this.MidiConnection.lastCC[control];
}

public has_cc = (channel?: number): boolean => {
/**
* Return true if there is last cc event
*/
if(channel) return this.MidiConnection.findCCFromBufferInChannel(channel) !== undefined;
else return this.MidiConnection.ccInputBuffer.length > 0;
}

public buffer_cc = (channel?: number): MidiCCEvent|undefined => {
/**
* @returns Returns latest unlistened cc event
*/
if(channel) return this.MidiConnection.findCCFromBufferInChannel(channel);
else return this.MidiConnection.ccInputBuffer.shift();
}

// =============================================================
// Ziffers related functions
// =============================================================
Expand Down
36 changes: 35 additions & 1 deletion src/AppSettings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,11 @@ export interface Settings {
* @param line_numbers - Whether or not to show line numbers
* @param time_position - Whether or not to show time position
* @param tips - Whether or not to show tips
* @param send_clock - Whether or not to send midi clock
* @param midi_channels_scripts - Whether midi input channels fires scripts
* @param midi_clock_input - The name of the midi clock input
* @param midi_clock_ppqn - The pulses per quarter note for midi clock
* @param default_midi_input - The default midi input for incoming messages
*/
vimMode: boolean;
theme: string;
Expand All @@ -55,6 +60,11 @@ export interface Settings {
time_position: boolean;
load_demo_songs: boolean;
tips: boolean;
send_clock: boolean;
midi_channels_scripts: boolean;
midi_clock_input: string|undefined;
midi_clock_ppqn: number;
default_midi_input: string|undefined;
}

export const template_universe = {
Expand Down Expand Up @@ -111,7 +121,11 @@ export class AppSettings {
* @param line_numbers - Whether or not to show line numbers
* @param time_position - Whether or not to show time position
* @param tips - Whether or not to show tips
* @param send_clock - Whether or not to send midi clock
* @param midi_channels_scripts - Whether midi input channels fires scripts
* @param midi_clock_input - The name of the midi clock input
* @param midi_clock_ppqn - The pulses per quarter note for midi clock
* @param default_midi_input - The default midi input for incoming messages
*/

public vimMode: boolean = false;
Expand All @@ -123,6 +137,11 @@ export class AppSettings {
public line_numbers: boolean = true;
public time_position: boolean = true;
public tips: boolean = true;
public send_clock: boolean = false;
public midi_channels_scripts: boolean = true;
public midi_clock_input: string|undefined = undefined;
public default_midi_input: string|undefined = undefined;
public midi_clock_ppqn: number = 24;
public load_demo_songs: boolean = true;

constructor() {
Expand All @@ -141,6 +160,11 @@ export class AppSettings {
this.line_numbers = settingsFromStorage.line_numbers;
this.time_position = settingsFromStorage.time_position;
this.tips = settingsFromStorage.tips;
this.send_clock = settingsFromStorage.send_clock;
this.midi_channels_scripts = settingsFromStorage.midi_channels_scripts;
this.midi_clock_input = settingsFromStorage.midi_clock_input;
this.midi_clock_ppqn = settingsFromStorage.midi_clock_ppqn || 24;
this.default_midi_input = settingsFromStorage.default_midi_input;
this.load_demo_songs = settingsFromStorage.load_demo_songs;
} else {
this.universes = template_universes;
Expand All @@ -165,6 +189,11 @@ export class AppSettings {
line_numbers: this.line_numbers,
time_position: this.time_position,
tips: this.tips,
send_clock: this.send_clock,
midi_channels_scripts: this.midi_channels_scripts,
midi_clock_input: this.midi_clock_input,
midi_clock_ppqn: this.midi_clock_ppqn,
default_midi_input: this.default_midi_input,
load_demo_songs: this.load_demo_songs,
};
}
Expand All @@ -187,6 +216,11 @@ export class AppSettings {
this.line_numbers = settings.line_numbers;
this.time_position = settings.time_position;
this.tips = settings.tips;
this.send_clock = settings.send_clock;
this.midi_channels_scripts = settings.midi_channels_scripts;
this.midi_clock_input = settings.midi_clock_input;
this.midi_clock_ppqn = settings.midi_clock_ppqn;
this.default_midi_input = settings.default_midi_input;
this.load_demo_songs = settings.load_demo_songs;
localStorage.setItem("topos", JSON.stringify(this.data));
}
Expand Down
Loading

0 comments on commit 15e47ec

Please sign in to comment.