mirror of
https://github.com/hneemann/Digital.git
synced 2025-09-15 07:48:29 -04:00
improved the MIDI component
This commit is contained in:
parent
39c0c921ee
commit
9bc188d69e
@ -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))
|
@ -141,7 +141,7 @@ public class ElementLibrary implements Iterable<ElementLibrary.ElementContainer>
|
||||
.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)
|
||||
|
@ -258,11 +258,13 @@
|
||||
<string name="elem_Terminal_pin_D">Über diesen Eingang werden die anzuzeigenden Daten an das Terminal weitergegeben.</string>
|
||||
<string name="elem_Terminal_pin_en">Ein High an diesem Eingang aktiviert den Takteingang.</string>
|
||||
|
||||
<string name="elem_Speaker">Lautsprecher</string>
|
||||
<string name="elem_Speaker_tt">Nutzt das MIDI-System, um Noten abzuspielen.</string>
|
||||
<string name="elem_Speaker_pin_N">Note</string>
|
||||
<string name="elem_Speaker_pin_V">Lautstärke</string>
|
||||
<string name="elem_Speaker_pin_en">Wenn gesetzt, wird der Ton ausgegeben.</string>
|
||||
<string name="elem_MIDI">MIDI</string>
|
||||
<string name="elem_MIDI_tt">Nutzt das MIDI-System, um Noten abzuspielen.</string>
|
||||
<string name="elem_MIDI_pin_N">Note</string>
|
||||
<string name="elem_MIDI_pin_V">Lautstärke</string>
|
||||
<string name="elem_MIDI_pin_OnOff">Wenn gesetzt, enspricht das dem Drücken eine Keyboard-Taste (key down).
|
||||
Wenn nicht gesetzt, entspricht das einem Loslassen der Taste (key up).</string>
|
||||
<string name="elem_MIDI_pin_C">Takteingang</string>
|
||||
|
||||
<!-- Leitungen -->
|
||||
|
||||
@ -999,6 +1001,7 @@ Sind evtl. die Namen der Variablen nicht eindeutig?</string>
|
||||
<string name="err_ProgMemLabelsNotDifferent">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.</string>
|
||||
<string name="err_midiSystemNotAvailable">Das MIDI-System ist nicht verfügbar.</string>
|
||||
<string name="err_midiChannel_N_NotAvailable">Der MIDI-Kanal {0} ist nicht verfügbar.</string>
|
||||
|
||||
<string name="key_AddrBits">Adress-Bits</string><!-- ROM, RAMDualPort, RAMSinglePort, RAMSinglePortSel, EEPROM -->
|
||||
<string name="key_AddrBits_tt">Anzahl der Adress-Bits, die verwendet werden.</string>
|
||||
|
@ -263,11 +263,13 @@
|
||||
<string name="elem_Terminal_pin_D">The data to write to the terminal</string>
|
||||
<string name="elem_Terminal_pin_en">A high at this input enables the clock input.</string>
|
||||
|
||||
<string name="elem_Speaker">Speaker</string>
|
||||
<string name="elem_Speaker_tt">Uses the MIDI system to play notes.</string>
|
||||
<string name="elem_Speaker_pin_N">Note</string>
|
||||
<string name="elem_Speaker_pin_V">Valume</string>
|
||||
<string name="elem_Speaker_pin_en">When set, the note is played.</string>
|
||||
<string name="elem_MIDI">MIDI</string>
|
||||
<string name="elem_MIDI_tt">Uses the MIDI system to play notes.</string>
|
||||
<string name="elem_MIDI_pin_N">Note</string>
|
||||
<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_C">Clock</string>
|
||||
|
||||
<!-- Wires -->
|
||||
|
||||
@ -992,6 +994,7 @@
|
||||
<string name="err_ProgMemLabelsNotDifferent">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.</string>
|
||||
<string name="err_midiSystemNotAvailable">The MIDI-System is not available.</string>
|
||||
<string name="err_midiChannel_N_NotAvailable">The MIDI channel {0} is not available.</string>
|
||||
|
||||
<string name="key_AddrBits">Address Bits</string><!-- ROM, RAMDualPort, RAMSinglePort, RAMSinglePortSel, EEPROM -->
|
||||
<string name="key_AddrBits_tt">Number of address bits used.</string>
|
||||
|
@ -579,11 +579,6 @@
|
||||
<elementAttributes/>
|
||||
<pos x="120" y="900"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Speaker</elementName>
|
||||
<elementAttributes/>
|
||||
<pos x="300" y="940"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>Const</elementName>
|
||||
<elementAttributes>
|
||||
@ -604,6 +599,11 @@
|
||||
</elementAttributes>
|
||||
<pos x="280" y="960"/>
|
||||
</visualElement>
|
||||
<visualElement>
|
||||
<elementName>MIDI</elementName>
|
||||
<elementAttributes/>
|
||||
<pos x="300" y="940"/>
|
||||
</visualElement>
|
||||
</visualElements>
|
||||
<wires>
|
||||
<wire>
|
||||
@ -836,6 +836,10 @@
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="240" y="980"/>
|
||||
<p2 x="280" y="980"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="280" y="980"/>
|
||||
<p2 x="300" y="980"/>
|
||||
</wire>
|
||||
<wire>
|
||||
@ -1006,6 +1010,10 @@
|
||||
<p1 x="1140" y="360"/>
|
||||
<p2 x="1160" y="360"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="280" y="1000"/>
|
||||
<p2 x="300" y="1000"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="1080" y="940"/>
|
||||
<p2 x="1100" y="940"/>
|
||||
@ -1498,6 +1506,10 @@
|
||||
<p1 x="920" y="100"/>
|
||||
<p2 x="920" y="620"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="280" y="980"/>
|
||||
<p2 x="280" y="1000"/>
|
||||
</wire>
|
||||
<wire>
|
||||
<p1 x="220" y="220"/>
|
||||
<p2 x="220" y="300"/>
|
||||
|
Loading…
x
Reference in New Issue
Block a user