Skip to content

Commit

Permalink
Making the MIDI router working
Browse files Browse the repository at this point in the history
  • Loading branch information
ZILtoid1991 committed Jul 23, 2023
1 parent f38e364 commit 33b0653
Show file tree
Hide file tree
Showing 5 changed files with 182 additions and 8 deletions.
34 changes: 34 additions & 0 deletions test1/app.d
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import pixelperfectengine.system.common;
import pixelperfectengine.audio.base.handler;
import pixelperfectengine.audio.base.modulebase;
import pixelperfectengine.audio.base.config;
import pixelperfectengine.audio.base.midiseq;
//import pixelperfectengine.audio.modules.qm816;
import core.thread;
import iota.audio.midi;
Expand All @@ -43,6 +44,7 @@ import test1.audioconfig;
import test1.preseteditor;
import test1.modulerouter;
import test1.virtmidikeyb;
import test1.midiseq;

/**
* Audio subsystem test.
Expand Down Expand Up @@ -126,6 +128,8 @@ public class AudioDevKit : InputListener, SystemEventListener {
AudioSpecs aS;
SpriteLayer windowing;
MIDIInput midiIn;
SequencerM1 midiSeq;

WindowHandler wh;
Window tlw;
PresetEditor preEdit;
Expand Down Expand Up @@ -182,6 +186,13 @@ public class AudioDevKit : InputListener, SystemEventListener {
globalDefaultStyle.setImage(customGUIElems[28], "macroA");
globalDefaultStyle.setImage(customGUIElems[29], "macroB");
}
{
Bitmap8Bit[] customGUIElems = loadBitmapSheetFromFile!Bitmap8Bit("../system/concreteGUIE2.tga", 16, 16);
globalDefaultStyle.setImage(customGUIElems[0], "playA");
globalDefaultStyle.setImage(customGUIElems[1], "playB");
globalDefaultStyle.setImage(customGUIElems[2], "stopA");
globalDefaultStyle.setImage(customGUIElems[3], "stopB");
}

ih = new InputHandler();
ih.systemEventListener = this;
Expand Down Expand Up @@ -297,6 +308,9 @@ public class AudioDevKit : InputListener, SystemEventListener {
case "virtmidikeyb":
onVirtMIDIKeyb();
break;
case "sequencer":
openSequencer();
break;
default: break;
}
}
Expand Down Expand Up @@ -329,6 +343,11 @@ public class AudioDevKit : InputListener, SystemEventListener {
public void onCompileAudioConfig() {
try {
mcfg.compile(state.audioThreadRunning);
if (mcfg.midiRouting.length) {
midiSeq = new SequencerM1(mcfg.modules, mcfg.midiRouting, mcfg.midiGroups);
} else {
midiSeq = null;
}
} catch (Exception e) {
writeln(e);
}
Expand Down Expand Up @@ -379,6 +398,21 @@ public class AudioDevKit : InputListener, SystemEventListener {
debug writeln(e);
}
}
public void openSequencer() {
if (midiSeq !is null) {
wh.addWindow(new SequencerCtrl(this));
}
}
public void onMIDILoad() {
import pixelperfectengine.concrete.dialogs.filedialog;
wh.addWindow(new FileDialog("Load MIDI file.", "loadMidiDialog", &onMIDIFileLoad,
[FileDialog.FileAssociationDescriptor("MIDI file", ["*.mid"])], "./"));
}
public void onMIDIFileLoad(Event ev) {
import mididi;
FileEvent fe = cast(FileEvent)ev;
midiSeq.openMIDI(readMIDIFile(fe.getFullPath));
}
public void openRouter() {
if (router is null)
router = new ModuleRouter(this);
Expand Down
90 changes: 90 additions & 0 deletions test1/midirout.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
module test1.midirout;

import std.conv : to;

import pixelperfectengine.concrete.window;

import pixelperfectengine.audio.base.config;

public class MIDIRouting : Window {
ListView listView0;
SmallButton button_add;
SmallButton button_remove;
SmallButton button_moveUp;
SmallButton button_moveDown;
SmallButton button_save;

ModuleConfig mcfg;
public this(ModuleConfig mcfg){
super(Box(0, 0, 285, 235), "New Window");
listView0 = new ListView(new ListViewHeader(16, [40 ,223], ["Tr. Num" ,"Module Name"]), null, "listView0",
Box(5, 20, 280, 210));
listView0.editEnable = true;
button_add = new SmallButton("addB", "addA", "button_add", Box.bySize(5, 215, 16, 16));
button_remove = new SmallButton("removeB", "removeA", "button_remove", Box.bySize(5 + 16, 215, 16, 16));
button_moveUp = new SmallButton("upArrowB", "upArrowA", "button_moveUp", Box.bySize(5 + 32, 215, 16, 16));
button_moveDown = new SmallButton("downArrowB", "downArrowA", "button_moveDown", Box.bySize(5 + 48, 215, 16, 16));
button_save = new SmallButton("saveB", "saveA", "button_save", Box.bySize(5 + 80, 215, 16, 16));

this.addElement(listView0);
this.addElement(button_add);
this.addElement(button_remove);
this.addElement(button_moveUp);
this.addElement(button_moveDown);
this.addElement(button_save);

button_add.onMouseLClick = &button_add_onClick;
button_remove.onMouseLClick = &button_remove_onClick;
button_moveUp.onMouseLClick = &button_moveUp_onClick;
button_moveDown.onMouseLClick = &button_moveDown_onClick;
button_save.onMouseLClick = &onSave;

this.mcfg = mcfg;

foreach (size_t i, uint key; mcfg.midiRouting) {
listView0 ~= new ListViewItem(16, [to!dstring(i), to!dstring(mcfg.modNames[key])],
[TextInputFieldType.None, TextInputFieldType.ASCIIText]);
}
}

protected void refreshOrder() {
for (int i ; i < listView0.numEntries ; i++) {
listView0[i][0].text.text = to!dstring(i);
}
listView0.refresh();
}

protected void button_add_onClick(Event ev) {
listView0.insertAt(listView0.value >= 0 ? listView0.value : 0,
new ListViewItem(16, [""d, ""d], [TextInputFieldType.None, TextInputFieldType.ASCIIText]));
refreshOrder();
}

protected void button_remove_onClick(Event ev) {
listView0.removeEntry(listView0.value);
refreshOrder();
}

protected void button_moveUp_onClick(Event ev) {
if (listView0.value > 0) {
listView0.moveEntry(listView0.value, listView0.value - 1);
refreshOrder();
}
}

protected void button_moveDown_onClick(Event ev) {
if (listView0.value < listView0.numEntries) {
listView0.moveEntry(listView0.value, listView0.value + 1);
refreshOrder();
}
}

protected void onSave(Event ev) {
uint[] newRouting;
for (int i ; i < listView0.numEntries ; i++) {
newRouting ~= cast(uint)mcfg.getModuleNum(to!string(listView0[i][1].getText));
}
mcfg.setMIDIrouting(newRouting);
this.close();
}
}
37 changes: 37 additions & 0 deletions test1/midiseq.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
module test1.midiseq;

import pixelperfectengine.concrete.window;

import pixelperfectengine.audio.base.midiseq : SequencerM1;
import test1.app;

public class SequencerCtrl : Window {
SmallButton button_load;
SmallButton button_play;
SmallButton button_stop;
AudioDevKit adk;
SequencerM1 seq;

public this(AudioDevKit adk) {
this.adk = adk;
seq = adk.midiSeq;
super(Box.bySize(0, 0, 320, 32), "Test Sequencer");

button_load = new SmallButton("loadB", "loadA", "load", Box.bySize(0, 16, 16, 16));
button_play = new SmallButton("playB", "playA", "play", Box.bySize(16, 16, 16, 16));
button_stop = new SmallButton("stopB", "stopA", "stop", Box.bySize(32, 16, 16, 16));

addElement(button_load);
addElement(button_play);
addElement(button_stop);
}
protected void button_load_onClick(Event ev) {
adk.onMIDILoad();
}
protected void button_play_onClick(Event ev) {
seq.start();
}
protected void button_stop_onClick(Event ev) {
seq.stop();
}
}
10 changes: 8 additions & 2 deletions test1/modulerouter.d
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ public class ModuleRouter : Window {
Button button_preset;
Button button_sampleman;
Button button_audNode;
Button button_midiNode;
Button button_midiRout;
Button button_remNode;
AudioDevKit adk;
public this(AudioDevKit adk){
Expand All @@ -32,10 +32,12 @@ public class ModuleRouter : Window {
button_audNode = new Button("Add audio node"d, "button_audNode", Box(535, 180, 635, 200));
//button_midiNode = new Button("Add MIDI node"d, "button1", Box(535, 205, 635, 225));
button_remNode = new Button("Remove node"d, "button_remNode", Box(535, 205, 635, 225));
button_midiRout = new Button("Set MIDI..."d, "button_midiRout", Box(535, 230, 635, 250));
button_addMod.onMouseLClick = &button_addMod_onClick;
button_audNode.onMouseLClick = &button_addNode_onClick;
button_preset.onMouseLClick = &button_preset_onClick;
button_sampleman.onMouseLClick = &button_sampleman_onClick;
button_midiRout.onMouseLClick = &button_midiRout_onClick;
listView_modules.editEnable = true;
listView_modules.onTextInput = &listView_modules_onTextEdit;
listView_modules.onItemSelect = &listView_modules_onItemSelect;
Expand All @@ -49,7 +51,7 @@ public class ModuleRouter : Window {
addElement(button_sampleman);
addElement(button_preset);
addElement(button_audNode);
//addElement(button_midiNode);
addElement(button_midiRout);
addElement(button_remNode);

this.adk = adk;
Expand Down Expand Up @@ -111,6 +113,10 @@ public class ModuleRouter : Window {
ListViewItem item = cast(ListViewItem)e.aux;
adk.eventStack.addToTop(new AddModuleEvent(adk.mcfg, item[0].getText().to!string, item[1].getText().to!string));
}
private void button_midiRout_onClick(Event ev) {
import test1.midirout;
handler.addWindow(new MIDIRouting(adk.mcfg));
}
private void listView_routing_onTextEdit(Event e) {
ListViewItem item = cast(ListViewItem)e.aux;
if (item[0].getText != "!NONE!" && item[1].getText != "!NONE!") {
Expand Down
19 changes: 13 additions & 6 deletions test1/sampleman.d
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import pixelperfectengine.concrete.window;
import pixelperfectengine.audio.base.types;
import pixelperfectengine.audio.base.func;
import pixelperfectengine.audio.base.config;
import std.math : floor;
import std.math : floor, nearbyint;
import std.conv;
import test1.app;
import test1.editorevents;
Expand All @@ -22,9 +22,10 @@ public class WaveformViewer : WindowElement {
if (fmt.bitsPerSample == 8) {
waveform.length = src.length;
decode8bitPCM(cast(const(ubyte)[])src, waveform, wp);
} else if (fmt.bitsPerSample == 16)
} else if (fmt.bitsPerSample == 16) {
waveform.length = src.length / 2;
decode16bitPCM(cast(const(short)[])src, waveform, wp);
}
break;
case AudioFormat.ADPCM, AudioFormat.IMA_ADPCM:
waveform.length = src.length * 2;
Expand Down Expand Up @@ -53,15 +54,21 @@ public class WaveformViewer : WindowElement {
parent.drawBox(position, 24);
if (waveform.length) {
real ratio = cast(real)waveform.length / position.width;
const int divident = ushort.max / position.height();
const int divident = ushort.max / position.height() * -1;
{
Point o = Point(0, position.height / 2);
parent.drawLine(position.cornerUL + o, position.cornerUR + o, 23);
}
Point p0 = Point(position.left, (waveform[0] / divident) + position.top + (position.height / 2));
for (int i ; i < position.width ; i++) {
Point p =
Point(i + position.left, (waveform[cast(size_t)floor(i * ratio)]/divident) + position.top + (position.height / 2));
parent.drawLine(p, p, 0x1F);
/+Point p0 =
Point(i + position.left,
(waveform[cast(size_t)nearbyint(i * ratio)] / divident) + position.top + (position.height / 2));+/
const Point p1 =
Point(i + position.left + 1,
(waveform[cast(size_t)nearbyint(i * ratio) + 1] / divident) + position.top + (position.height / 2));
parent.drawLine(p0, p1, 0x1F);
p0 = p1;
}

if (isFocused) {
Expand Down

0 comments on commit 33b0653

Please sign in to comment.