diff --git a/src/main/java/de/neemann/digital/core/io/Speaker.java b/src/main/java/de/neemann/digital/core/io/MIDI.java similarity index 66% rename from src/main/java/de/neemann/digital/core/io/Speaker.java rename to src/main/java/de/neemann/digital/core/io/MIDI.java index b7805f61b..2defa0ea2 100644 --- a/src/main/java/de/neemann/digital/core/io/Speaker.java +++ b/src/main/java/de/neemann/digital/core/io/MIDI.java @@ -22,30 +22,34 @@ import static de.neemann.digital.core.element.PinInfo.input; /** * The speaker. */ -public class Speaker extends Node implements Element { +public class MIDI extends Node implements Element { /** * The Speakers description */ public static final ElementTypeDescription DESCRIPTION - = new ElementTypeDescription(Speaker.class, input("N"), input("V"), input("en")) {} + = new ElementTypeDescription(MIDI.class, + input("N"), + input("V"), + input("OnOff"), + input("C").setClock()) .addAttribute(Keys.MIDICHANNEL) .addAttribute(Keys.ROTATE); private final int chanNum; private ObservableValue note; private ObservableValue volume; - private ObservableValue enable; + private ObservableValue clock; + private ObservableValue onOff; private MidiChannel channel; - private boolean lastEn = false; - private int notePlaying; + private boolean lastCl = false; /** * Creates a new instance * * @param attributes the elements attributes */ - public Speaker(ElementAttributes attributes) { + public MIDI(ElementAttributes attributes) { chanNum = attributes.get(Keys.MIDICHANNEL); } @@ -53,7 +57,8 @@ public class Speaker extends Node implements Element { public void setInputs(ObservableValues inputs) throws NodeException { note = inputs.get(0).checkBits(7, this, 0); volume = inputs.get(1).checkBits(7, this, 1); - enable = inputs.get(2).checkBits(1, this, 2).addObserverToValue(this); + onOff = inputs.get(2).checkBits(1, this, 2); + clock = inputs.get(3).checkBits(1, this, 3).addObserverToValue(this); } @Override @@ -63,17 +68,16 @@ public class Speaker extends Node implements Element { @Override public void readInputs() throws NodeException { - boolean en = enable.getBool(); - if (channel != null) { - if (!lastEn && en) { - notePlaying = (int) note.getValue(); + boolean cl = clock.getBool(); + if (!lastCl && cl) { + int note = (int) this.note.getValue(); + if (onOff.getBool()) { int v = (int) volume.getValue(); - channel.noteOn(notePlaying, v); - } else if (lastEn && !en) { - channel.noteOff(notePlaying); - } + channel.noteOn(note, v); + } else + channel.noteOff(note); } - lastEn = en; + lastCl = cl; } @Override @@ -86,10 +90,16 @@ public class Speaker extends Node implements Element { Synthesizer synth = MidiSystem.getSynthesizer(); synth.open(); MidiChannel[] channels = synth.getChannels(); - if (chanNum >= channels.length) - channel = channels[0]; - else - channel = channels[chanNum]; + if (chanNum >= channels.length) { + synth.close(); + throw new NodeException(Lang.get("err_midiChannel_N_NotAvailable", chanNum)); + } + + channel = channels[chanNum]; + if (channel == null) { + synth.close(); + throw new NodeException(Lang.get("err_midiChannel_N_NotAvailable", chanNum)); + } model.addObserver(event -> { if (event.equals(ModelEvent.STOPPED)) diff --git a/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java b/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java index 8ebe578f1..ee47e90ae 100644 --- a/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java +++ b/src/main/java/de/neemann/digital/draw/library/ElementLibrary.java @@ -141,7 +141,7 @@ public class ElementLibrary implements Iterable .add(RotEncoder.DESCRIPTION) .add(Keyboard.DESCRIPTION) .add(Terminal.DESCRIPTION) - .add(Speaker.DESCRIPTION))) + .add(MIDI.DESCRIPTION))) .add(new LibraryNode(Lang.get("lib_wires")) .add(Ground.DESCRIPTION) .add(VDD.DESCRIPTION) diff --git a/src/main/resources/lang/lang_de.xml b/src/main/resources/lang/lang_de.xml index d0dbb4b50..465ba9323 100644 --- a/src/main/resources/lang/lang_de.xml +++ b/src/main/resources/lang/lang_de.xml @@ -258,11 +258,13 @@ Über diesen Eingang werden die anzuzeigenden Daten an das Terminal weitergegeben. Ein High an diesem Eingang aktiviert den Takteingang. - Lautsprecher - Nutzt das MIDI-System, um Noten abzuspielen. - Note - Lautstärke - Wenn gesetzt, wird der Ton ausgegeben. + MIDI + Nutzt das MIDI-System, um Noten abzuspielen. + Note + Lautstärke + Wenn gesetzt, enspricht das dem Drücken eine Keyboard-Taste (key down). + Wenn nicht gesetzt, entspricht das einem Loslassen der Taste (key up). + Takteingang @@ -999,6 +1001,7 @@ Sind evtl. die Namen der Variablen nicht eindeutig? Wenn Programme in mehrere RAMs geladen werden sollen, müssen alle RAMs unterschiedliche Bezeichnungen haben. Die lexikalische Ordnung legt dann die Reihenfolge der RAMs fest. Das MIDI-System ist nicht verfügbar. + Der MIDI-Kanal {0} ist nicht verfügbar. Adress-Bits Anzahl der Adress-Bits, die verwendet werden. diff --git a/src/main/resources/lang/lang_en.xml b/src/main/resources/lang/lang_en.xml index 1e8ae4621..50e489782 100644 --- a/src/main/resources/lang/lang_en.xml +++ b/src/main/resources/lang/lang_en.xml @@ -263,11 +263,13 @@ The data to write to the terminal A high at this input enables the clock input. - Speaker - Uses the MIDI system to play notes. - Note - Valume - When set, the note is played. + MIDI + Uses the MIDI system to play notes. + Note + Volume + If set, this translates to pressing a keyboard key (key down event), + if not set, this translates to releasing the key (key up event). + Clock @@ -992,6 +994,7 @@ If programs are to be loaded into several RAMs, all RAMs must have different names. The lexical order then determines the order of the RAMs. The MIDI-System is not available. + The MIDI channel {0} is not available. Address Bits Number of address bits used. diff --git a/src/test/resources/dig/backtrack/AllComponents.dig b/src/test/resources/dig/backtrack/AllComponents.dig index 786c4d7e3..eba5835d4 100644 --- a/src/test/resources/dig/backtrack/AllComponents.dig +++ b/src/test/resources/dig/backtrack/AllComponents.dig @@ -579,11 +579,6 @@ - - Speaker - - - Const @@ -604,6 +599,11 @@ + + MIDI + + + @@ -836,6 +836,10 @@ + + + + @@ -1006,6 +1010,10 @@ + + + + @@ -1498,6 +1506,10 @@ + + + +