1
0
Fork 0

add MIDI compat options + fix gui

This commit is contained in:
Sen 2025-09-03 22:09:35 +02:00
parent c698a030eb
commit f566d62bd8
Signed by: sen
GPG key ID: 3AC50A6F47D1B722
5 changed files with 30 additions and 13 deletions

View file

@ -680,6 +680,10 @@ public class Client implements IThreadListener {
public boolean midiDebug = false; public boolean midiDebug = false;
@Variable(name = "mid_visualizer", category = CVarCategory.SOUND, display = "Visualisation") @Variable(name = "mid_visualizer", category = CVarCategory.SOUND, display = "Visualisation")
public boolean midiVisualizer = true; public boolean midiVisualizer = true;
@Variable(name = "mid_ch_16_workaround", category = CVarCategory.SOUND, display = "Kanal 16 als Perkussion")
public boolean midiCh16Drums = false;
@Variable(name = "mid_allow_switch_perc_ch", category = CVarCategory.SOUND, display = "Perk.-Kanäle änderbar")
public boolean midiDrumProgs = false;
@Variable(name = "draw_use_shader", category = CVarCategory.RENDER, display = "Shader verwenden") @Variable(name = "draw_use_shader", category = CVarCategory.RENDER, display = "Shader verwenden")
public boolean useShader = false; public boolean useShader = false;

View file

@ -161,7 +161,7 @@ public class MidiDecoder {
return value; return value;
} }
public MidiDecoder(byte[] data, boolean nowait, int voices, MidiBank bank, boolean keep, boolean useunkn, int velofunc) throws IOException { public MidiDecoder(byte[] data, boolean nowait, int voices, MidiBank bank, boolean keep, boolean useunkn, boolean percsw, int velofunc, int[] percussion) throws IOException {
int size = data.length; int size = data.length;
if(size < 14) { if(size < 14) {
throw new IOException("Datei zu klein"); throw new IOException("Datei zu klein");
@ -222,7 +222,7 @@ public class MidiDecoder {
this.nowait = nowait; this.nowait = nowait;
this.setTempo(500000); this.setTempo(500000);
this.chip = new OPLChip(48000, voices, velofunc, 0, false, false); this.chip = new OPLChip(48000, voices, velofunc, 0, false, false);
this.bank = new MidiHandle(this.chip, bank.getData(), keep, useunkn); this.bank = new MidiHandle(this.chip, bank.getData(), keep, useunkn, percsw, percussion);
this.playing = true; this.playing = true;
} }
@ -231,7 +231,7 @@ public class MidiDecoder {
this.tpqn = note; this.tpqn = note;
this.nowait = false; this.nowait = false;
this.chip = new OPLChip(48000, 16, 0, 0, false, false); this.chip = new OPLChip(48000, 16, 0, 0, false, false);
this.bank = new MidiHandle(this.chip, bank.getData(), false, true); this.bank = new MidiHandle(this.chip, bank.getData(), false, true, false, new int[] {10});
this.ticktime = start; this.ticktime = start;
this.uspb = end; this.uspb = end;
this.time = (long)delay * 1000000L; this.time = (long)delay * 1000000L;

View file

@ -57,17 +57,23 @@ public class MidiHandle {
public final Instrument[] instruments; public final Instrument[] instruments;
public final boolean keep; public final boolean keep;
public final boolean useunkn; public final boolean useunkn;
public final boolean percsw;
public final boolean[] percussion = new boolean[16];
public int index; public int index;
public int used; public int used;
public MidiHandle(OPLChip chip, Instrument[] instr, boolean keep, boolean useunkn) { public MidiHandle(OPLChip chip, Instrument[] instr, boolean keep, boolean useunkn, boolean percsw, int[] percussion) {
this.keep = keep; this.keep = keep;
this.useunkn = useunkn; this.useunkn = useunkn;
this.percsw = percsw;
this.instruments = instr; this.instruments = instr;
this.voices = new Voice[chip.channel.length]; this.voices = new Voice[chip.channel.length];
for(int ch : percussion) {
this.percussion[ch - 1] = true;
}
for(int z = 0; z < this.channels.length; z++) { for(int z = 0; z < this.channels.length; z++) {
this.channels[z] = new Channel(z == 9); this.channels[z] = new Channel(this.percussion[z]);
} }
for(int z = 0; z < this.voices.length; z++) { for(int z = 0; z < this.voices.length; z++) {
this.voices[z] = new Voice(chip.channel[z]); this.voices[z] = new Voice(chip.channel[z]);
@ -252,7 +258,7 @@ public class MidiHandle {
// ch.pbank = 128; // ch.pbank = 128;
// } // }
// else { // else {
if(channel != 9) { if(this.percsw || !this.percussion[channel]) {
ch.pbank &= 0x007f; ch.pbank &= 0x007f;
ch.pbank |= (value << 7) & 0x3f80; ch.pbank |= (value << 7) & 0x3f80;
} }
@ -263,7 +269,7 @@ public class MidiHandle {
// ch.pbank = 128; // ch.pbank = 128;
// } // }
// else { // else {
if(channel != 9) { if(this.percsw || !this.percussion[channel]) {
ch.pbank &= 0x3f80; ch.pbank &= 0x3f80;
ch.pbank |= value & 0x007f; ch.pbank |= value & 0x007f;
} }
@ -278,7 +284,7 @@ public class MidiHandle {
this.levelupdate(ch); this.levelupdate(ch);
break; break;
case 0x79: // reset case 0x79: // reset
ch.pbank = (channel == 9) ? 128 : 0; ch.pbank = this.percussion[channel] ? 128 : 0;
ch.volume = 127; ch.volume = 127;
ch.pan = 0; ch.pan = 0;
this.progupdate(ch); this.progupdate(ch);

View file

@ -33,7 +33,7 @@ public class GuiPlayer extends GuiList<GuiPlayer.SongEntry> {
} }
public void draw(int x, int y, int width, int height, int mouseX, int mouseY, boolean hovered) { public void draw(int x, int y, int width, int height, int mouseX, int mouseY, boolean hovered) {
Drawing.drawText(this.file.getName(), x + 3, y, GuiPlayer.this.playing && GuiPlayer.this.entry == this ? (GuiPlayer.this.paused != null ? 0xffffff00 : 0xff00ff00) : 0xffffffff); Drawing.drawText(this.file.getName(), x + 3, y, GuiPlayer.this.playing && this.file.equals(GuiPlayer.this.entry) ? (GuiPlayer.this.paused != null ? 0xffffff00 : 0xff00ff00) : 0xffffffff);
} }
public void select(boolean dclick, int mx, int my) { public void select(boolean dclick, int mx, int my) {
@ -223,7 +223,7 @@ public class GuiPlayer extends GuiList<GuiPlayer.SongEntry> {
private final Random rand = new Random(); private final Random rand = new Random();
private MidiDecoder paused; private MidiDecoder paused;
private int position = -1; private int position = -1;
private SongEntry entry; private File entry;
private boolean playing; private boolean playing;
private RepeatMode mode = RepeatMode.REPEAT_OFF; private RepeatMode mode = RepeatMode.REPEAT_OFF;
private ActButton playButton; private ActButton playButton;
@ -240,12 +240,16 @@ public class GuiPlayer extends GuiList<GuiPlayer.SongEntry> {
this.modeButton.setText(this.mode.display); this.modeButton.setText(this.mode.display);
} }
private int[] getPercussionChannels() {
return this.gm.midiCh16Drums ? new int[] {10, 16} : new int[] {10};
}
public void playMidi(int index) { public void playMidi(int index) {
this.paused = null; this.paused = null;
this.playing = true; this.playing = true;
this.entry = this.getListEntry(this.position = index); this.entry = this.getListEntry(this.position = index).file;
this.updateDisplay(); this.updateDisplay();
File file = this.entry.file; File file = this.entry;
byte[] data; byte[] data;
try { try {
data = Files.readAllBytes(file.toPath()); data = Files.readAllBytes(file.toPath());
@ -256,7 +260,7 @@ public class GuiPlayer extends GuiList<GuiPlayer.SongEntry> {
} }
MidiDecoder midi; MidiDecoder midi;
try { try {
midi = new MidiDecoder(data, this.gm.midiNoWait, this.gm.midiVoices, this.gm.midiBank, this.gm.midiKeep, this.gm.midiUnknown, this.gm.midiVelocity); midi = new MidiDecoder(data, this.gm.midiNoWait, this.gm.midiVoices, this.gm.midiBank, this.gm.midiKeep, this.gm.midiUnknown, this.gm.midiDrumProgs, this.gm.midiVelocity, this.getPercussionChannels());
} }
catch(Throwable e) { catch(Throwable e) {
Log.SOUND.error(e, "Konnte MIDI '%s' nicht laden", file); Log.SOUND.error(e, "Konnte MIDI '%s' nicht laden", file);

View file

@ -42,6 +42,9 @@ public class GuiSound extends GuiOptions {
this.addSelector("mid_visualizer", 0, 190, 240, 0); this.addSelector("mid_visualizer", 0, 190, 240, 0);
this.addSelector("mid_debug_events", 242, 190, 240, 0); this.addSelector("mid_debug_events", 242, 190, 240, 0);
this.addSelector("mid_ch_16_workaround", 0, 210, 240, 0);
this.addSelector("mid_allow_switch_perc_ch", 242, 210, 240, 0);
super.init(width, height); super.init(width, height);
} }