mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-14 15:26:52 -04:00
Allow MIDI program change
This commit is contained in:
parent
57593c1f6a
commit
dbdb6f79a0
2698
src/main/dig/misc/BillieJean.dig
Normal file
2698
src/main/dig/misc/BillieJean.dig
Normal file
File diff suppressed because it is too large
Load Diff
@ -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"/>
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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());
|
||||
|
@ -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>
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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"/>
|
||||
|
Loading…
x
Reference in New Issue
Block a user