Allow MIDI program change

This commit is contained in:
hneemann 2019-02-11 23:13:48 +01:00
parent 57593c1f6a
commit dbdb6f79a0
9 changed files with 2800 additions and 38 deletions

File diff suppressed because it is too large Load Diff

View File

@ -37,7 +37,7 @@
<int>15</int>
</entry>
</elementAttributes>
<pos x="100" y="240"/>
<pos x="100" y="260"/>
</visualElement>
<visualElement>
<elementName>Counter</elementName>
@ -113,7 +113,12 @@
</visualElement>
<visualElement>
<elementName>MIDI</elementName>
<elementAttributes/>
<elementAttributes>
<entry>
<string>midiInstrument</string>
<string>Accordion</string>
</entry>
</elementAttributes>
<pos x="580" y="180"/>
</visualElement>
<visualElement>
@ -121,6 +126,11 @@
<elementAttributes/>
<pos x="140" y="120"/>
</visualElement>
<visualElement>
<elementName>Const</elementName>
<elementAttributes/>
<pos x="560" y="240"/>
</visualElement>
</visualElements>
<wires>
<wire>
@ -132,16 +142,20 @@
<p2 x="480" y="160"/>
</wire>
<wire>
<p1 x="100" y="240"/>
<p2 x="120" y="240"/>
</wire>
<wire>
<p1 x="240" y="240"/>
<p1 x="560" y="240"/>
<p2 x="580" y="240"/>
</wire>
<wire>
<p1 x="120" y="240"/>
<p2 x="240" y="240"/>
<p1 x="100" y="260"/>
<p2 x="120" y="260"/>
</wire>
<wire>
<p1 x="120" y="260"/>
<p2 x="240" y="260"/>
</wire>
<wire>
<p1 x="240" y="260"/>
<p2 x="580" y="260"/>
</wire>
<wire>
<p1 x="560" y="180"/>
@ -205,7 +219,7 @@
</wire>
<wire>
<p1 x="240" y="140"/>
<p2 x="240" y="240"/>
<p2 x="240" y="260"/>
</wire>
<wire>
<p1 x="260" y="160"/>
@ -213,7 +227,7 @@
</wire>
<wire>
<p1 x="120" y="140"/>
<p2 x="120" y="240"/>
<p2 x="120" y="260"/>
</wire>
<wire>
<p1 x="120" y="100"/>

View File

@ -739,14 +739,20 @@ public final class Keys {
/**
* Selects the midi channel
*/
public static final Key.KeyInteger MIDICHANNEL =
new Key.KeyInteger("midiChannel", 0)
.setMin(0)
.setMax(15);
public static final Key.KeyInteger MIDI_CHANNEL =
new Key.KeyInteger("midiChannel", 1)
.setMin(1)
.setMax(16);
/**
* Selects the midi channel
*/
public static final Key<String> MIDIINSTRUMENT =
public static final Key<String> MIDI_INSTRUMENT =
new Key<>("midiInstrument", "");
/**
* Enables Program change
*/
public static final Key<Boolean> MIDI_PROG_CHANGE =
new Key<>("midiProgChange", false);
}

View File

@ -6,10 +6,7 @@
package de.neemann.digital.core.io;
import de.neemann.digital.core.*;
import de.neemann.digital.core.element.Element;
import de.neemann.digital.core.element.ElementAttributes;
import de.neemann.digital.core.element.ElementTypeDescription;
import de.neemann.digital.core.element.Keys;
import de.neemann.digital.core.element.*;
import javax.sound.midi.MidiChannel;
@ -24,21 +21,38 @@ public class MIDI extends Node implements Element {
* The Speakers description
*/
public static final ElementTypeDescription DESCRIPTION
= new ElementTypeDescription(MIDI.class,
input("N"),
input("V"),
input("OnOff"),
input("C").setClock())
= new ElementTypeDescription(MIDI.class) {
public PinDescriptions getInputDescription(ElementAttributes elementAttributes) throws NodeException {
if (elementAttributes.get(Keys.MIDI_PROG_CHANGE))
return new PinDescriptions(input("N"),
input("V"),
input("OnOff"),
input("PC"),
input("en"),
input("C").setClock()).setLangKey(getPinLangKey());
else
return new PinDescriptions(input("N"),
input("V"),
input("OnOff"),
input("en"),
input("C").setClock()).setLangKey(getPinLangKey());
}
}
.addAttribute(Keys.ROTATE)
.addAttribute(Keys.MIDICHANNEL)
.addAttribute(Keys.MIDIINSTRUMENT);
.addAttribute(Keys.LABEL)
.addAttribute(Keys.MIDI_CHANNEL)
.addAttribute(Keys.MIDI_INSTRUMENT)
.addAttribute(Keys.MIDI_PROG_CHANGE);
private final int chanNum;
private final String instrument;
private final boolean progChangeEnable;
private ObservableValue note;
private ObservableValue volume;
private ObservableValue clock;
private ObservableValue onOff;
private ObservableValue en;
private ObservableValue progChange;
private MidiChannel channel;
private boolean lastCl = false;
@ -48,8 +62,9 @@ public class MIDI extends Node implements Element {
* @param attributes the elements attributes
*/
public MIDI(ElementAttributes attributes) {
chanNum = attributes.get(Keys.MIDICHANNEL);
instrument = attributes.get(Keys.MIDIINSTRUMENT);
chanNum = attributes.get(Keys.MIDI_CHANNEL)-1;
instrument = attributes.get(Keys.MIDI_INSTRUMENT);
progChangeEnable = attributes.get(Keys.MIDI_PROG_CHANGE);
}
@Override
@ -57,7 +72,14 @@ public class MIDI extends Node implements Element {
note = inputs.get(0).checkBits(7, this, 0);
volume = inputs.get(1).checkBits(7, this, 1);
onOff = inputs.get(2).checkBits(1, this, 2);
clock = inputs.get(3).checkBits(1, this, 3).addObserverToValue(this);
if (progChangeEnable) {
progChange = inputs.get(3).checkBits(1, this, 3);
en = inputs.get(4).checkBits(1, this, 4);
clock = inputs.get(5).checkBits(1, this, 5).addObserverToValue(this);
} else {
en = inputs.get(3).checkBits(1, this, 3);
clock = inputs.get(4).checkBits(1, this, 4).addObserverToValue(this);
}
}
@Override
@ -68,13 +90,17 @@ public class MIDI extends Node implements Element {
@Override
public void readInputs() throws NodeException {
boolean cl = clock.getBool();
if (!lastCl && cl) {
if (!lastCl && cl && en.getBool()) {
int note = (int) this.note.getValue();
if (onOff.getBool()) {
int v = (int) volume.getValue();
channel.noteOn(note, v);
} else
channel.noteOff(note);
if (progChange != null && progChange.getBool()) {
channel.programChange(note);
} else {
if (onOff.getBool()) {
int v = (int) volume.getValue();
channel.noteOn(note, v);
} else
channel.noteOff(note);
}
}
lastCl = cl;
}

View File

@ -95,7 +95,7 @@ public final class EditorFactory {
* @return the editor
*/
public <T> Editor<T> create(Key<T> key, T value) {
if (key == Keys.MIDIINSTRUMENT)
if (key == Keys.MIDI_INSTRUMENT)
return (Editor<T>) new MidiInstrumentEditor(value.toString());
Class<? extends Editor> fac = map.get(key.getValueClass());

View File

@ -264,6 +264,8 @@
<string name="elem_MIDI_pin_V">Lautstärke</string>
<string name="elem_MIDI_pin_OnOff">Wenn gesetzt, enspricht das dem Drücken einer Keyboard-Taste (key down).
Wenn nicht gesetzt, entspricht das einem Loslassen der Taste (key up).</string>
<string name="elem_MIDI_pin_en">Wenn dieser eingang high ist, kann der Baustein angesprochen werden.</string>
<string name="elem_MIDI_pin_PC">Wenn gesetzt, wird mit dem Wert an Eingang N das Programm (Instrument) gewechselt.</string>
<string name="elem_MIDI_pin_C">Takteingang</string>
<!-- Leitungen -->
@ -1305,6 +1307,9 @@ Sind evtl. die Namen der Variablen nicht eindeutig?</string>
<string name="key_midiChannel_tt">Legt den MIDI-Kanal fest.</string>
<string name="key_midiInstrument">MIDI-Instrument</string>
<string name="key_midiInstrument_tt">Das MIDI-Instrument, welches verwendet werden soll.</string>
<string name="key_midiProgChange">Programmwechsel erlauben</string>
<string name="key_midiProgChange_tt">Fügt einen weiteren Eingang PC hinzu. Wird dieser Eingang auf High gesetzt,
wird mit dem Wert am Eingang N das Programm (Intrument) gewechselt.</string>
<string name="mod_insertWire">Leitung eingefügt.</string>
<string name="mod_insertCopied">Aus Zwischenablage eingefügt.</string>

View File

@ -269,6 +269,8 @@
<string name="elem_MIDI_pin_V">Volume</string>
<string name="elem_MIDI_pin_OnOff">If set, this translates to pressing a keyboard key (key down event),
if not set, this translates to releasing the key (key up event).</string>
<string name="elem_MIDI_pin_en">Enables the component</string>
<string name="elem_MIDI_pin_PC">If high, the value at N is used to change the program (instrument).</string>
<string name="elem_MIDI_pin_C">Clock</string>
<!-- Wires -->
@ -1293,6 +1295,9 @@
<string name="key_midiChannel_tt">Selects the MIDI channel to use.</string>
<string name="key_midiInstrument">MIDI instrument</string>
<string name="key_midiInstrument_tt">The MIDI instrument to use.</string>
<string name="key_midiProgChange">Allow program change</string>
<string name="key_midiProgChange_tt">Adds a new input PC. If this input is set to high,
the value at input N is used to change te program (instrument).</string>
<string name="mod_insertWire">Inserted wire.</string>
<string name="mod_insertCopied">Insert from clipboard.</string>

View File

@ -32,7 +32,7 @@ public class TestExamples extends TestCase {
*/
public void testDistExamples() throws Exception {
File examples = new File(Resources.getRoot().getParentFile().getParentFile(), "/main/dig");
assertEquals(249, new FileScanner(this::check).scan(examples));
assertEquals(250, new FileScanner(this::check).scan(examples));
assertEquals(170, testCasesInFiles);
}

View File

@ -1238,6 +1238,10 @@
<p1 x="940" y="380"/>
<p2 x="960" y="380"/>
</wire>
<wire>
<p1 x="280" y="1020"/>
<p2 x="300" y="1020"/>
</wire>
<wire>
<p1 x="640" y="500"/>
<p2 x="640" y="520"/>
@ -1510,6 +1514,10 @@
<p1 x="280" y="980"/>
<p2 x="280" y="1000"/>
</wire>
<wire>
<p1 x="280" y="1000"/>
<p2 x="280" y="1020"/>
</wire>
<wire>
<p1 x="220" y="220"/>
<p2 x="220" y="300"/>