refactor: reindent some files

This commit is contained in:
ChomeNS
2025-03-05 11:12:05 +07:00
parent 3b4c8f5fda
commit e9052c83da
7 changed files with 995 additions and 995 deletions

View File

@@ -2,48 +2,48 @@ package me.chayapak1.chomens_bot.song;
// Author: hhhzzzsss
public class Instrument {
public static final Instrument HARP = new Instrument(0, "harp", 54);
public static final Instrument BASEDRUM = new Instrument(1, "basedrum", 0);
public static final Instrument SNARE = new Instrument(2, "snare", 0);
public static final Instrument HAT = new Instrument(3, "hat", 0);
public static final Instrument BASS = new Instrument(4, "bass", 30);
public static final Instrument FLUTE = new Instrument(5, "flute", 66);
public static final Instrument BELL = new Instrument(6, "bell", 78);
public static final Instrument GUITAR = new Instrument(7, "guitar", 42);
public static final Instrument CHIME = new Instrument(8, "chime", 78);
public static final Instrument XYLOPHONE = new Instrument(9, "xylophone", 78);
public static final Instrument IRON_XYLOPHONE = new Instrument(10, "iron_xylophone", 54);
public static final Instrument COW_BELL = new Instrument(11, "cow_bell", 66);
public static final Instrument DIDGERIDOO = new Instrument(12, "didgeridoo", 30);
public static final Instrument BIT = new Instrument(13, "bit", 54);
public static final Instrument BANJO = new Instrument(14, "banjo", 54);
public static final Instrument PLING = new Instrument(15, "pling", 54);
public static final Instrument HARP = new Instrument(0, "harp", 54);
public static final Instrument BASEDRUM = new Instrument(1, "basedrum", 0);
public static final Instrument SNARE = new Instrument(2, "snare", 0);
public static final Instrument HAT = new Instrument(3, "hat", 0);
public static final Instrument BASS = new Instrument(4, "bass", 30);
public static final Instrument FLUTE = new Instrument(5, "flute", 66);
public static final Instrument BELL = new Instrument(6, "bell", 78);
public static final Instrument GUITAR = new Instrument(7, "guitar", 42);
public static final Instrument CHIME = new Instrument(8, "chime", 78);
public static final Instrument XYLOPHONE = new Instrument(9, "xylophone", 78);
public static final Instrument IRON_XYLOPHONE = new Instrument(10, "iron_xylophone", 54);
public static final Instrument COW_BELL = new Instrument(11, "cow_bell", 66);
public static final Instrument DIDGERIDOO = new Instrument(12, "didgeridoo", 30);
public static final Instrument BIT = new Instrument(13, "bit", 54);
public static final Instrument BANJO = new Instrument(14, "banjo", 54);
public static final Instrument PLING = new Instrument(15, "pling", 54);
public final int id;
public final String name;
public final int offset;
public final String sound;
public final int id;
public final String name;
public final int offset;
public final String sound;
private Instrument (int id, String name, int offset) {
this.id = id;
this.name = name;
this.offset = offset;
this.sound = "minecraft:block.note_block." + name;
}
private Instrument (int id, String name, int offset) {
this.id = id;
this.name = name;
this.offset = offset;
this.sound = "minecraft:block.note_block." + name;
}
public Instrument (int id, String name, int offset, String sound) {
this.id = id;
this.name = name;
this.offset = offset;
this.sound = sound;
}
public Instrument (int id, String name, int offset, String sound) {
this.id = id;
this.name = name;
this.offset = offset;
this.sound = sound;
}
public static Instrument of (String sound) {
return new Instrument(-1, null, 0, sound);
}
public static Instrument of (String sound) {
return new Instrument(-1, null, 0, sound);
}
private static final Instrument[] values = {HARP, BASEDRUM, SNARE, HAT, BASS, FLUTE, BELL, GUITAR, CHIME, XYLOPHONE, IRON_XYLOPHONE, COW_BELL, DIDGERIDOO, BIT, BANJO, PLING};
public static Instrument fromId (int id) {
return values[id];
}
private static final Instrument[] values = {HARP, BASEDRUM, SNARE, HAT, BASS, FLUTE, BELL, GUITAR, CHIME, XYLOPHONE, IRON_XYLOPHONE, COW_BELL, DIDGERIDOO, BIT, BANJO, PLING};
public static Instrument fromId (int id) {
return values[id];
}
}

View File

@@ -13,446 +13,446 @@ import static javax.sound.midi.ShortMessage.SYSTEM_RESET;
// Author: hhhzzzsss
// i modified this and some codes are stolen from https://github.com/RaphiMC/NoteBlockLib so thanks to them
public class MidiConverter implements Converter {
public static final int TEXT = 0x01;
public static final int TRACK_NAME = 0x03;
public static final int LYRICS = 0x05;
public static final int VOLUME_CONTROL_MSB = 0x07;
public static final int PAN_CONTROL_MSB = 0x0A;
public static final int SET_INSTRUMENT = 0xC0;
public static final int SET_TEMPO = 0x51;
public static final int RESET_CONTROLS = 0x79;
public static final int TEXT = 0x01;
public static final int TRACK_NAME = 0x03;
public static final int LYRICS = 0x05;
public static final int VOLUME_CONTROL_MSB = 0x07;
public static final int PAN_CONTROL_MSB = 0x0A;
public static final int SET_INSTRUMENT = 0xC0;
public static final int SET_TEMPO = 0x51;
public static final int RESET_CONTROLS = 0x79;
@Override
public Song getSongFromBytes(byte[] bytes, String name, Bot bot) throws InvalidMidiDataException, IOException {
Sequence sequence = MidiSystem.getSequence(new ByteArrayInputStream(bytes));
return getSong(sequence, name, bot);
}
public static Song getSong(Sequence sequence, String name, Bot bot) {
final Map<Long, String> lyrics = new HashMap<>();
long tpq = sequence.getResolution();
String songName = null;
final StringBuilder tracks = new StringBuilder();
final StringBuilder text = new StringBuilder();
boolean isFirst = true;
ArrayList<MidiEvent> tempoEvents = new ArrayList<>();
for (Track track : sequence.getTracks()) {
final int trackSize = track.size();
for (int i = 0; i < trackSize; i++) {
MidiEvent event = track.get(i);
MidiMessage message = event.getMessage();
if (message instanceof MetaMessage mm) {
if (mm.getType() == SET_TEMPO) {
tempoEvents.add(event);
} else if (mm.getType() == TRACK_NAME) {
final String stringTitle = new String(mm.getData(), StandardCharsets.UTF_8);
if (stringTitle.isBlank()) continue;
tracks.append(stringTitle);
tracks.append("\n");
if (isFirst) {
songName = stringTitle + " (" + name + ")"; // i have put the ` (filename)` just in case the sequence is getting sus (like Track 2 for example)
isFirst = false;
}
} else if (mm.getType() == TEXT) {
text.append(new String(mm.getData(), StandardCharsets.UTF_8));
text.append('\n');
} else if (mm.getType() == LYRICS) {
final String lyric = new String(mm.getMessage(), StandardCharsets.UTF_8);
lyrics.put(event.getTick(), lyric);
}
}
}
@Override
public Song getSongFromBytes(byte[] bytes, String name, Bot bot) throws InvalidMidiDataException, IOException {
Sequence sequence = MidiSystem.getSequence(new ByteArrayInputStream(bytes));
return getSong(sequence, name, bot);
}
String stringTracks = tracks.toString();
String stringText = text.toString();
public static Song getSong(Sequence sequence, String name, Bot bot) {
final Map<Long, String> lyrics = new HashMap<>();
if (stringText.endsWith("\n")) stringText = stringText.substring(0, stringText.length() - 1);
if (stringTracks.endsWith("\n")) stringTracks = stringTracks.substring(0, stringTracks.length() - 1);
long tpq = sequence.getResolution();
final Song song = new Song(name, bot, songName, null, null, stringText, stringTracks, false);
tempoEvents.sort(Comparator.comparingLong(MidiEvent::getTick));
String songName = null;
final int[] channelVolumes = new int[16];
final int[] channelPans = new int[16];
Arrays.fill(channelVolumes, 127);
Arrays.fill(channelPans, 64);
for (Track track : sequence.getTracks()) {
long microTime = 0;
int[] ids = new int[16];
int mpq = 500000;
int tempoEventIdx = 0;
long prevTick = 0;
final StringBuilder tracks = new StringBuilder();
final StringBuilder text = new StringBuilder();
final int trackSize = track.size();
boolean isFirst = true;
for (int i = 0; i < trackSize; i++) {
MidiEvent event = track.get(i);
MidiMessage message = event.getMessage();
while (tempoEventIdx < tempoEvents.size() && event.getTick() > tempoEvents.get(tempoEventIdx).getTick()) {
long deltaTick = tempoEvents.get(tempoEventIdx).getTick() - prevTick;
prevTick = tempoEvents.get(tempoEventIdx).getTick();
microTime += (mpq/tpq) * deltaTick;
MetaMessage mm = (MetaMessage) tempoEvents.get(tempoEventIdx).getMessage();
byte[] data = mm.getData();
int new_mpq = (data[2]&0xFF) | ((data[1]&0xFF)<<8) | ((data[0]&0xFF)<<16);
if (new_mpq != 0) mpq = new_mpq;
tempoEventIdx++;
}
if (message instanceof ShortMessage sm) {
if (sm.getCommand() == SET_INSTRUMENT) {
ids[sm.getChannel()] = sm.getData1();
}
else if (sm.getCommand() == ShortMessage.NOTE_ON) {
if (sm.getData2() == 0) continue;
int pitch = sm.getData1();
int velocity = sm.getData2();
float effectiveVelocity = (float) velocity * channelVolumes[sm.getChannel()] / 127;
int pan = channelPans[sm.getChannel()];
long deltaTick = event.getTick() - prevTick;
prevTick = event.getTick();
microTime += (mpq/tpq) * deltaTick;
ArrayList<MidiEvent> tempoEvents = new ArrayList<>();
for (Track track : sequence.getTracks()) {
final int trackSize = track.size();
Note note;
if (sm.getChannel() == 9) {
note = getMidiPercussionNote(pitch, effectiveVelocity, microTime, pan);
for (int i = 0; i < trackSize; i++) {
MidiEvent event = track.get(i);
MidiMessage message = event.getMessage();
if (message instanceof MetaMessage mm) {
if (mm.getType() == SET_TEMPO) {
tempoEvents.add(event);
} else if (mm.getType() == TRACK_NAME) {
final String stringTitle = new String(mm.getData(), StandardCharsets.UTF_8);
if (stringTitle.isBlank()) continue;
tracks.append(stringTitle);
tracks.append("\n");
if (isFirst) {
songName = stringTitle + " (" + name + ")"; // i have put the ` (filename)` just in case the sequence is getting sus (like Track 2 for example)
isFirst = false;
}
} else if (mm.getType() == TEXT) {
text.append(new String(mm.getData(), StandardCharsets.UTF_8));
text.append('\n');
} else if (mm.getType() == LYRICS) {
final String lyric = new String(mm.getMessage(), StandardCharsets.UTF_8);
lyrics.put(event.getTick(), lyric);
}
}
}
else {
note = getMidiInstrumentNote(ids[sm.getChannel()], pitch, effectiveVelocity, microTime, pan);
}
if (note != null) {
song.add(note);
}
long time = microTime / 1000L;
if (time > song.length) {
song.length = time;
}
}
else if (sm.getCommand() == ShortMessage.NOTE_OFF) {
long deltaTick = event.getTick() - prevTick;
prevTick = event.getTick();
microTime += (mpq/tpq) * deltaTick;
long time = microTime / 1000L;
if (time > song.length) {
song.length = time;
}
}
else if (sm.getCommand() == ShortMessage.CONTROL_CHANGE) {
if (sm.getData1() == VOLUME_CONTROL_MSB) {
channelVolumes[sm.getChannel()] = sm.getData2();
} else if (sm.getData1() == PAN_CONTROL_MSB) {
channelPans[sm.getChannel()] = sm.getData2();
} else if (sm.getData1() == RESET_CONTROLS) {
channelVolumes[sm.getChannel()] = 127;
channelPans[sm.getChannel()] = 64;
}
}
else if (sm.getCommand() == SYSTEM_RESET) {
Arrays.fill(channelVolumes, 127);
Arrays.fill(channelPans, 64);
}
}
if (lyrics.get(event.getTick()) != null) {
song.lyrics.put(microTime / 1000L, lyrics.get(event.getTick()));
String stringTracks = tracks.toString();
String stringText = text.toString();
if (stringText.endsWith("\n")) stringText = stringText.substring(0, stringText.length() - 1);
if (stringTracks.endsWith("\n")) stringTracks = stringTracks.substring(0, stringTracks.length() - 1);
final Song song = new Song(name, bot, songName, null, null, stringText, stringTracks, false);
tempoEvents.sort(Comparator.comparingLong(MidiEvent::getTick));
final int[] channelVolumes = new int[16];
final int[] channelPans = new int[16];
Arrays.fill(channelVolumes, 127);
Arrays.fill(channelPans, 64);
for (Track track : sequence.getTracks()) {
long microTime = 0;
int[] ids = new int[16];
int mpq = 500000;
int tempoEventIdx = 0;
long prevTick = 0;
final int trackSize = track.size();
for (int i = 0; i < trackSize; i++) {
MidiEvent event = track.get(i);
MidiMessage message = event.getMessage();
while (tempoEventIdx < tempoEvents.size() && event.getTick() > tempoEvents.get(tempoEventIdx).getTick()) {
long deltaTick = tempoEvents.get(tempoEventIdx).getTick() - prevTick;
prevTick = tempoEvents.get(tempoEventIdx).getTick();
microTime += (mpq/tpq) * deltaTick;
MetaMessage mm = (MetaMessage) tempoEvents.get(tempoEventIdx).getMessage();
byte[] data = mm.getData();
int new_mpq = (data[2]&0xFF) | ((data[1]&0xFF)<<8) | ((data[0]&0xFF)<<16);
if (new_mpq != 0) mpq = new_mpq;
tempoEventIdx++;
}
if (message instanceof ShortMessage sm) {
if (sm.getCommand() == SET_INSTRUMENT) {
ids[sm.getChannel()] = sm.getData1();
}
else if (sm.getCommand() == ShortMessage.NOTE_ON) {
if (sm.getData2() == 0) continue;
int pitch = sm.getData1();
int velocity = sm.getData2();
float effectiveVelocity = (float) velocity * channelVolumes[sm.getChannel()] / 127;
int pan = channelPans[sm.getChannel()];
long deltaTick = event.getTick() - prevTick;
prevTick = event.getTick();
microTime += (mpq/tpq) * deltaTick;
Note note;
if (sm.getChannel() == 9) {
note = getMidiPercussionNote(pitch, effectiveVelocity, microTime, pan);
}
else {
note = getMidiInstrumentNote(ids[sm.getChannel()], pitch, effectiveVelocity, microTime, pan);
}
if (note != null) {
song.add(note);
}
long time = microTime / 1000L;
if (time > song.length) {
song.length = time;
}
}
else if (sm.getCommand() == ShortMessage.NOTE_OFF) {
long deltaTick = event.getTick() - prevTick;
prevTick = event.getTick();
microTime += (mpq/tpq) * deltaTick;
long time = microTime / 1000L;
if (time > song.length) {
song.length = time;
}
}
else if (sm.getCommand() == ShortMessage.CONTROL_CHANGE) {
if (sm.getData1() == VOLUME_CONTROL_MSB) {
channelVolumes[sm.getChannel()] = sm.getData2();
} else if (sm.getData1() == PAN_CONTROL_MSB) {
channelPans[sm.getChannel()] = sm.getData2();
} else if (sm.getData1() == RESET_CONTROLS) {
channelVolumes[sm.getChannel()] = 127;
channelPans[sm.getChannel()] = 64;
}
}
else if (sm.getCommand() == SYSTEM_RESET) {
Arrays.fill(channelVolumes, 127);
Arrays.fill(channelPans, 64);
}
}
if (lyrics.get(event.getTick()) != null) {
song.lyrics.put(microTime / 1000L, lyrics.get(event.getTick()));
}
}
}
}
song.sort();
return song;
}
song.sort();
return song;
}
public static Note getMidiInstrumentNote(int midiInstrument, int midiPitch, float velocity, long microTime, int panning) {
Instrument shiftedInstrument = null;
Instrument[] instrumentList = instrumentMap.get(midiInstrument);
if (instrumentList != null) {
for (Instrument candidateInstrument : instrumentList) {
if (midiPitch >= candidateInstrument.offset && midiPitch <= candidateInstrument.offset+24) {
shiftedInstrument = candidateInstrument;
break;
}
}
public static Note getMidiInstrumentNote(int midiInstrument, int midiPitch, float velocity, long microTime, int panning) {
Instrument shiftedInstrument = null;
Instrument[] instrumentList = instrumentMap.get(midiInstrument);
if (instrumentList != null) {
for (Instrument candidateInstrument : instrumentList) {
if (midiPitch >= candidateInstrument.offset && midiPitch <= candidateInstrument.offset+24) {
shiftedInstrument = candidateInstrument;
break;
}
}
if (shiftedInstrument == null) {
if (shiftedInstrument == null) {
// shiftedInstrument = instrumentList[0];
// we are finding the closest instrument offset here and use that
// closest instrument as the instrument
// we are finding the closest instrument offset here and use that
// closest instrument as the instrument
final Integer[] offsets = Arrays.stream(instrumentList).map(ins -> ins.offset).toArray(Integer[]::new);
final Integer[] offsets = Arrays.stream(instrumentList).map(ins -> ins.offset).toArray(Integer[]::new);
// https://stackoverflow.com/questions/13318733/get-closest-value-to-a-number-in-array
int distance = Math.abs(offsets[0] - midiPitch);
int idx = 0;
for (int c = 1; c < offsets.length; c++) {
int cdistance = Math.abs(offsets[c] - midiPitch);
if (cdistance < distance) {
idx = c;
distance = cdistance;
}
// https://stackoverflow.com/questions/13318733/get-closest-value-to-a-number-in-array
int distance = Math.abs(offsets[0] - midiPitch);
int idx = 0;
for (int c = 1; c < offsets.length; c++) {
int cdistance = Math.abs(offsets[c] - midiPitch);
if (cdistance < distance) {
idx = c;
distance = cdistance;
}
}
final int closest = offsets[idx];
shiftedInstrument = Arrays.stream(instrumentList)
.filter(ins -> ins.offset == closest)
.findFirst()
.orElse(null);
}
}
final int closest = offsets[idx];
if (shiftedInstrument == null) {
return null;
}
shiftedInstrument = Arrays.stream(instrumentList)
.filter(ins -> ins.offset == closest)
.findFirst()
.orElse(null);
}
int shiftedInstrumentPitch = midiPitch - shiftedInstrument.offset;
int pitch = midiPitch - instrumentList[0].offset;
float volume = velocity / 127.0f;
long time = microTime / 1000L;
return new Note(instrumentList[0], shiftedInstrument, pitch, shiftedInstrumentPitch, midiPitch, volume, time, (int) ((panning - 64) / (float) 64) * 100, 100);
}
if (shiftedInstrument == null) {
return null;
private static Note getMidiPercussionNote (int midiPitch, float velocity, long microTime, int panning) {
if (percussionMap.containsKey(midiPitch)) {
int noteId = percussionMap.get(midiPitch);
int pitch = noteId % 25;
float volume = velocity / 127.0f;
Instrument instrument = Instrument.fromId(noteId / 25);
long time = microTime / 1000L;
return new Note(instrument, pitch, midiPitch, volume, time, (int) ((panning - 64) / (float) 64) * 100, 100);
}
return null;
}
int shiftedInstrumentPitch = midiPitch - shiftedInstrument.offset;
int pitch = midiPitch - instrumentList[0].offset;
public static final HashMap<Integer, Instrument[]> instrumentMap = new HashMap<>();
static {
// Piano (HARP BASS BELL)
instrumentMap.put(0, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Acoustic Grand Piano
instrumentMap.put(1, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Bright Acoustic Piano
instrumentMap.put(2, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL}); // Electric Grand Piano
instrumentMap.put(3, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Honky-tonk Piano
instrumentMap.put(4, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL}); // Electric Piano 1
instrumentMap.put(5, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL}); // Electric Piano 2
instrumentMap.put(6, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Harpsichord
instrumentMap.put(7, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Clavinet
float volume = velocity / 127.0f;
long time = microTime / 1000L;
// Chromatic Percussion (IRON_XYLOPHONE XYLOPHONE BASS)
instrumentMap.put(8, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Celesta
instrumentMap.put(9, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Glockenspiel
instrumentMap.put(10, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Music Box
instrumentMap.put(11, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Vibraphone
instrumentMap.put(12, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Marimba
instrumentMap.put(13, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Xylophone
instrumentMap.put(14, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Tubular Bells
instrumentMap.put(15, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Dulcimer
return new Note(instrumentList[0], shiftedInstrument, pitch, shiftedInstrumentPitch, midiPitch, volume, time, (int) ((panning - 64) / (float) 64) * 100, 100);
}
// Organ (BIT DIDGERIDOO BELL)
instrumentMap.put(16, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Drawbar Organ
instrumentMap.put(17, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Percussive Organ
instrumentMap.put(18, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Rock Organ
instrumentMap.put(19, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Church Organ
instrumentMap.put(20, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Reed Organ
instrumentMap.put(21, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Accordian
instrumentMap.put(22, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Harmonica
instrumentMap.put(23, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Tango Accordian
private static Note getMidiPercussionNote (int midiPitch, float velocity, long microTime, int panning) {
if (percussionMap.containsKey(midiPitch)) {
int noteId = percussionMap.get(midiPitch);
int pitch = noteId % 25;
float volume = velocity / 127.0f;
Instrument instrument = Instrument.fromId(noteId / 25);
long time = microTime / 1000L;
// Guitar (BIT DIDGERIDOO BELL)
instrumentMap.put(24, new Instrument[]{Instrument.GUITAR, Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Acoustic Guitar (nylon)
instrumentMap.put(25, new Instrument[]{Instrument.GUITAR, Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Acoustic Guitar (steel)
instrumentMap.put(26, new Instrument[]{Instrument.GUITAR, Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Electric Guitar (jazz)
instrumentMap.put(27, new Instrument[]{Instrument.GUITAR, Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Electric Guitar (clean)
instrumentMap.put(28, new Instrument[]{Instrument.GUITAR, Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Electric Guitar (muted)
instrumentMap.put(29, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Overdriven Guitar
instrumentMap.put(30, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Distortion Guitar
instrumentMap.put(31, new Instrument[]{Instrument.GUITAR, Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Guitar Harmonics
return new Note(instrument, pitch, midiPitch, volume, time, (int) ((panning - 64) / (float) 64) * 100, 100);
}
return null;
}
// Bass
instrumentMap.put(32, new Instrument[]{Instrument.BASS, Instrument.HARP, Instrument.BELL}); // Acoustic Bass
instrumentMap.put(33, new Instrument[]{Instrument.BASS, Instrument.HARP, Instrument.BELL}); // Electric Bass (finger)
instrumentMap.put(34, new Instrument[]{Instrument.BASS, Instrument.HARP, Instrument.BELL}); // Electric Bass (pick)
instrumentMap.put(35, new Instrument[]{Instrument.BASS, Instrument.HARP, Instrument.BELL}); // Fretless Bass
instrumentMap.put(36, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Slap Bass 1
instrumentMap.put(37, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Slap Bass 2
instrumentMap.put(38, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Synth Bass 1
instrumentMap.put(39, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Synth Bass 2
public static final HashMap<Integer, Instrument[]> instrumentMap = new HashMap<>();
static {
// Piano (HARP BASS BELL)
instrumentMap.put(0, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Acoustic Grand Piano
instrumentMap.put(1, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Bright Acoustic Piano
instrumentMap.put(2, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL}); // Electric Grand Piano
instrumentMap.put(3, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Honky-tonk Piano
instrumentMap.put(4, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL}); // Electric Piano 1
instrumentMap.put(5, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL}); // Electric Piano 2
instrumentMap.put(6, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Harpsichord
instrumentMap.put(7, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Clavinet
// Strings
instrumentMap.put(40, new Instrument[]{Instrument.FLUTE, Instrument.GUITAR, Instrument.BASS, Instrument.BELL}); // Violin
instrumentMap.put(41, new Instrument[]{Instrument.FLUTE, Instrument.GUITAR, Instrument.BASS, Instrument.BELL}); // Viola
instrumentMap.put(42, new Instrument[]{Instrument.FLUTE, Instrument.GUITAR, Instrument.BASS, Instrument.BELL}); // Cello
instrumentMap.put(43, new Instrument[]{Instrument.FLUTE, Instrument.GUITAR, Instrument.BASS, Instrument.BELL}); // Contrabass
instrumentMap.put(44, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL}); // Tremolo Strings
instrumentMap.put(45, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Pizzicato Strings
instrumentMap.put(46, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.CHIME}); // Orchestral Harp
instrumentMap.put(47, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Timpani
// Chromatic Percussion (IRON_XYLOPHONE XYLOPHONE BASS)
instrumentMap.put(8, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Celesta
instrumentMap.put(9, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Glockenspiel
instrumentMap.put(10, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Music Box
instrumentMap.put(11, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Vibraphone
instrumentMap.put(12, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Marimba
instrumentMap.put(13, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Xylophone
instrumentMap.put(14, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Tubular Bells
instrumentMap.put(15, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE}); // Dulcimer
// Ensenble
instrumentMap.put(48, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // String Ensemble 1
instrumentMap.put(49, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // String Ensemble 2
instrumentMap.put(50, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Synth Strings 1
instrumentMap.put(51, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Synth Strings 2
instrumentMap.put(52, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Choir Aahs
instrumentMap.put(53, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Voice Oohs
instrumentMap.put(54, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Synth Choir
instrumentMap.put(55, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Orchestra Hit
// Organ (BIT DIDGERIDOO BELL)
instrumentMap.put(16, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Drawbar Organ
instrumentMap.put(17, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Percussive Organ
instrumentMap.put(18, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Rock Organ
instrumentMap.put(19, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Church Organ
instrumentMap.put(20, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Reed Organ
instrumentMap.put(21, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Accordian
instrumentMap.put(22, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Harmonica
instrumentMap.put(23, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Tango Accordian
// Brass
instrumentMap.put(56, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
instrumentMap.put(57, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
instrumentMap.put(58, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
instrumentMap.put(59, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
instrumentMap.put(60, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
instrumentMap.put(61, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
instrumentMap.put(62, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
instrumentMap.put(63, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
// Guitar (BIT DIDGERIDOO BELL)
instrumentMap.put(24, new Instrument[]{Instrument.GUITAR, Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Acoustic Guitar (nylon)
instrumentMap.put(25, new Instrument[]{Instrument.GUITAR, Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Acoustic Guitar (steel)
instrumentMap.put(26, new Instrument[]{Instrument.GUITAR, Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Electric Guitar (jazz)
instrumentMap.put(27, new Instrument[]{Instrument.GUITAR, Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Electric Guitar (clean)
instrumentMap.put(28, new Instrument[]{Instrument.GUITAR, Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Electric Guitar (muted)
instrumentMap.put(29, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Overdriven Guitar
instrumentMap.put(30, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Distortion Guitar
instrumentMap.put(31, new Instrument[]{Instrument.GUITAR, Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Guitar Harmonics
// Reed
instrumentMap.put(64, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(65, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(66, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(67, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(68, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(69, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(70, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(71, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
// Bass
instrumentMap.put(32, new Instrument[]{Instrument.BASS, Instrument.HARP, Instrument.BELL}); // Acoustic Bass
instrumentMap.put(33, new Instrument[]{Instrument.BASS, Instrument.HARP, Instrument.BELL}); // Electric Bass (finger)
instrumentMap.put(34, new Instrument[]{Instrument.BASS, Instrument.HARP, Instrument.BELL}); // Electric Bass (pick)
instrumentMap.put(35, new Instrument[]{Instrument.BASS, Instrument.HARP, Instrument.BELL}); // Fretless Bass
instrumentMap.put(36, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Slap Bass 1
instrumentMap.put(37, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Slap Bass 2
instrumentMap.put(38, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Synth Bass 1
instrumentMap.put(39, new Instrument[]{Instrument.DIDGERIDOO, Instrument.BIT, Instrument.XYLOPHONE}); // Synth Bass 2
// Pipe
instrumentMap.put(72, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(73, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(74, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(75, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(76, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(77, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(78, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(79, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
// Strings
instrumentMap.put(40, new Instrument[]{Instrument.FLUTE, Instrument.GUITAR, Instrument.BASS, Instrument.BELL}); // Violin
instrumentMap.put(41, new Instrument[]{Instrument.FLUTE, Instrument.GUITAR, Instrument.BASS, Instrument.BELL}); // Viola
instrumentMap.put(42, new Instrument[]{Instrument.FLUTE, Instrument.GUITAR, Instrument.BASS, Instrument.BELL}); // Cello
instrumentMap.put(43, new Instrument[]{Instrument.FLUTE, Instrument.GUITAR, Instrument.BASS, Instrument.BELL}); // Contrabass
instrumentMap.put(44, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL}); // Tremolo Strings
instrumentMap.put(45, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Pizzicato Strings
instrumentMap.put(46, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.CHIME}); // Orchestral Harp
instrumentMap.put(47, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Timpani
// Synth Lead
instrumentMap.put(80, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(81, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(82, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(83, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(84, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(85, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(86, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(87, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
// Ensenble
instrumentMap.put(48, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // String Ensemble 1
instrumentMap.put(49, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // String Ensemble 2
instrumentMap.put(50, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Synth Strings 1
instrumentMap.put(51, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Synth Strings 2
instrumentMap.put(52, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Choir Aahs
instrumentMap.put(53, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Voice Oohs
instrumentMap.put(54, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Synth Choir
instrumentMap.put(55, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL}); // Orchestra Hit
// Synth Pad
instrumentMap.put(88, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(89, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(90, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(91, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(92, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(93, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(94, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(95, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
// Brass
instrumentMap.put(56, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
instrumentMap.put(57, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
instrumentMap.put(58, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
instrumentMap.put(59, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
instrumentMap.put(60, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
instrumentMap.put(61, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
instrumentMap.put(62, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
instrumentMap.put(63, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
// Reed
instrumentMap.put(64, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(65, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(66, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(67, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(68, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(69, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(70, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(71, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
// Pipe
instrumentMap.put(72, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(73, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(74, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(75, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(76, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(77, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(78, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
instrumentMap.put(79, new Instrument[]{Instrument.FLUTE, Instrument.DIDGERIDOO, Instrument.IRON_XYLOPHONE, Instrument.BELL});
// Synth Lead
instrumentMap.put(80, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(81, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(82, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(83, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(84, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(85, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(86, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(87, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
// Synth Pad
instrumentMap.put(88, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(89, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(90, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(91, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(92, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(93, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(94, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(95, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
// Synth Effects
// Synth Effects
// instrumentMap.put(96, new Instrument[]{});
// instrumentMap.put(97, new Instrument[]{});
instrumentMap.put(98, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
instrumentMap.put(99, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(100, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(101, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(102, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(103, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(98, new Instrument[]{Instrument.BIT, Instrument.DIDGERIDOO, Instrument.BELL});
instrumentMap.put(99, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(100, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(101, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(102, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
instrumentMap.put(103, new Instrument[]{Instrument.HARP, Instrument.BASS, Instrument.BELL});
// Ethnic
instrumentMap.put(104, new Instrument[]{Instrument.BANJO, Instrument.BASS, Instrument.BELL});
instrumentMap.put(105, new Instrument[]{Instrument.BANJO, Instrument.BASS, Instrument.BELL});
instrumentMap.put(106, new Instrument[]{Instrument.BANJO, Instrument.BASS, Instrument.BELL});
instrumentMap.put(107, new Instrument[]{Instrument.BANJO, Instrument.BASS, Instrument.BELL});
instrumentMap.put(108, new Instrument[]{Instrument.BANJO, Instrument.BASS, Instrument.BELL});
instrumentMap.put(109, new Instrument[]{Instrument.HARP, Instrument.DIDGERIDOO, Instrument.BELL});
instrumentMap.put(110, new Instrument[]{Instrument.HARP, Instrument.DIDGERIDOO, Instrument.BELL});
instrumentMap.put(111, new Instrument[]{Instrument.HARP, Instrument.DIDGERIDOO, Instrument.BELL});
// Ethnic
instrumentMap.put(104, new Instrument[]{Instrument.BANJO, Instrument.BASS, Instrument.BELL});
instrumentMap.put(105, new Instrument[]{Instrument.BANJO, Instrument.BASS, Instrument.BELL});
instrumentMap.put(106, new Instrument[]{Instrument.BANJO, Instrument.BASS, Instrument.BELL});
instrumentMap.put(107, new Instrument[]{Instrument.BANJO, Instrument.BASS, Instrument.BELL});
instrumentMap.put(108, new Instrument[]{Instrument.BANJO, Instrument.BASS, Instrument.BELL});
instrumentMap.put(109, new Instrument[]{Instrument.HARP, Instrument.DIDGERIDOO, Instrument.BELL});
instrumentMap.put(110, new Instrument[]{Instrument.HARP, Instrument.DIDGERIDOO, Instrument.BELL});
instrumentMap.put(111, new Instrument[]{Instrument.HARP, Instrument.DIDGERIDOO, Instrument.BELL});
// Percussive
instrumentMap.put(112, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
instrumentMap.put(113, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
instrumentMap.put(114, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
instrumentMap.put(115, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
instrumentMap.put(116, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
instrumentMap.put(117, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
instrumentMap.put(118, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
instrumentMap.put(119, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
}
// Percussive
instrumentMap.put(112, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
instrumentMap.put(113, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
instrumentMap.put(114, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
instrumentMap.put(115, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
instrumentMap.put(116, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
instrumentMap.put(117, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
instrumentMap.put(118, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
instrumentMap.put(119, new Instrument[]{Instrument.IRON_XYLOPHONE, Instrument.BASS, Instrument.XYLOPHONE});
}
public static final HashMap<Integer, Integer> percussionMap = new HashMap<>();
static {
percussionMap.put(35, 10 + 25*Instrument.BASEDRUM.id);
percussionMap.put(36, 6 + 25*Instrument.BASEDRUM.id);
percussionMap.put(37, 6 + 25*Instrument.HAT.id);
percussionMap.put(38, 8 + 25*Instrument.SNARE.id);
percussionMap.put(39, 6 + 25*Instrument.HAT.id);
percussionMap.put(40, 4 + 25*Instrument.SNARE.id);
percussionMap.put(41, 6 + 25*Instrument.BASEDRUM.id);
percussionMap.put(42, 22 + 25*Instrument.SNARE.id);
percussionMap.put(43, 13 + 25*Instrument.BASEDRUM.id);
percussionMap.put(44, 22 + 25*Instrument.SNARE.id);
percussionMap.put(45, 15 + 25*Instrument.BASEDRUM.id);
percussionMap.put(46, 18 + 25*Instrument.SNARE.id);
percussionMap.put(47, 20 + 25*Instrument.BASEDRUM.id);
percussionMap.put(48, 23 + 25*Instrument.BASEDRUM.id);
percussionMap.put(49, 17 + 25*Instrument.SNARE.id);
percussionMap.put(50, 23 + 25*Instrument.BASEDRUM.id);
percussionMap.put(51, 24 + 25*Instrument.SNARE.id);
percussionMap.put(52, 8 + 25*Instrument.SNARE.id);
percussionMap.put(53, 13 + 25*Instrument.SNARE.id);
percussionMap.put(54, 18 + 25*Instrument.HAT.id);
percussionMap.put(55, 18 + 25*Instrument.SNARE.id);
percussionMap.put(56, 1 + 25*Instrument.HAT.id);
percussionMap.put(57, 13 + 25*Instrument.SNARE.id);
percussionMap.put(58, 2 + 25*Instrument.HAT.id);
percussionMap.put(59, 13 + 25*Instrument.SNARE.id);
percussionMap.put(60, 9 + 25*Instrument.HAT.id);
percussionMap.put(61, 2 + 25*Instrument.HAT.id);
percussionMap.put(62, 8 + 25*Instrument.HAT.id);
percussionMap.put(63, 22 + 25*Instrument.BASEDRUM.id);
percussionMap.put(64, 15 + 25*Instrument.BASEDRUM.id);
percussionMap.put(65, 13 + 25*Instrument.SNARE.id);
percussionMap.put(66, 8 + 25*Instrument.SNARE.id);
percussionMap.put(67, 8 + 25*Instrument.HAT.id);
percussionMap.put(68, 3 + 25*Instrument.HAT.id);
percussionMap.put(69, 20 + 25*Instrument.HAT.id);
percussionMap.put(70, 23 + 25*Instrument.HAT.id);
percussionMap.put(71, 24 + 25*Instrument.HAT.id);
percussionMap.put(72, 24 + 25*Instrument.HAT.id);
percussionMap.put(73, 17 + 25*Instrument.HAT.id);
percussionMap.put(74, 11 + 25*Instrument.HAT.id);
percussionMap.put(75, 18 + 25*Instrument.HAT.id);
percussionMap.put(76, 9 + 25*Instrument.HAT.id);
percussionMap.put(77, 5 + 25*Instrument.HAT.id);
percussionMap.put(78, 22 + 25*Instrument.HAT.id);
percussionMap.put(79, 19 + 25*Instrument.SNARE.id);
percussionMap.put(80, 17 + 25*Instrument.HAT.id);
percussionMap.put(81, 22 + 25*Instrument.HAT.id);
percussionMap.put(82, 22 + 25*Instrument.SNARE.id);
percussionMap.put(83, 24 + 25*Instrument.CHIME.id);
percussionMap.put(84, 24 + 25*Instrument.CHIME.id);
percussionMap.put(85, 21 + 25*Instrument.HAT.id);
percussionMap.put(86, 14 + 25*Instrument.BASEDRUM.id);
percussionMap.put(87, 7 + 25*Instrument.BASEDRUM.id);
}
public static final HashMap<Integer, Integer> percussionMap = new HashMap<>();
static {
percussionMap.put(35, 10 + 25*Instrument.BASEDRUM.id);
percussionMap.put(36, 6 + 25*Instrument.BASEDRUM.id);
percussionMap.put(37, 6 + 25*Instrument.HAT.id);
percussionMap.put(38, 8 + 25*Instrument.SNARE.id);
percussionMap.put(39, 6 + 25*Instrument.HAT.id);
percussionMap.put(40, 4 + 25*Instrument.SNARE.id);
percussionMap.put(41, 6 + 25*Instrument.BASEDRUM.id);
percussionMap.put(42, 22 + 25*Instrument.SNARE.id);
percussionMap.put(43, 13 + 25*Instrument.BASEDRUM.id);
percussionMap.put(44, 22 + 25*Instrument.SNARE.id);
percussionMap.put(45, 15 + 25*Instrument.BASEDRUM.id);
percussionMap.put(46, 18 + 25*Instrument.SNARE.id);
percussionMap.put(47, 20 + 25*Instrument.BASEDRUM.id);
percussionMap.put(48, 23 + 25*Instrument.BASEDRUM.id);
percussionMap.put(49, 17 + 25*Instrument.SNARE.id);
percussionMap.put(50, 23 + 25*Instrument.BASEDRUM.id);
percussionMap.put(51, 24 + 25*Instrument.SNARE.id);
percussionMap.put(52, 8 + 25*Instrument.SNARE.id);
percussionMap.put(53, 13 + 25*Instrument.SNARE.id);
percussionMap.put(54, 18 + 25*Instrument.HAT.id);
percussionMap.put(55, 18 + 25*Instrument.SNARE.id);
percussionMap.put(56, 1 + 25*Instrument.HAT.id);
percussionMap.put(57, 13 + 25*Instrument.SNARE.id);
percussionMap.put(58, 2 + 25*Instrument.HAT.id);
percussionMap.put(59, 13 + 25*Instrument.SNARE.id);
percussionMap.put(60, 9 + 25*Instrument.HAT.id);
percussionMap.put(61, 2 + 25*Instrument.HAT.id);
percussionMap.put(62, 8 + 25*Instrument.HAT.id);
percussionMap.put(63, 22 + 25*Instrument.BASEDRUM.id);
percussionMap.put(64, 15 + 25*Instrument.BASEDRUM.id);
percussionMap.put(65, 13 + 25*Instrument.SNARE.id);
percussionMap.put(66, 8 + 25*Instrument.SNARE.id);
percussionMap.put(67, 8 + 25*Instrument.HAT.id);
percussionMap.put(68, 3 + 25*Instrument.HAT.id);
percussionMap.put(69, 20 + 25*Instrument.HAT.id);
percussionMap.put(70, 23 + 25*Instrument.HAT.id);
percussionMap.put(71, 24 + 25*Instrument.HAT.id);
percussionMap.put(72, 24 + 25*Instrument.HAT.id);
percussionMap.put(73, 17 + 25*Instrument.HAT.id);
percussionMap.put(74, 11 + 25*Instrument.HAT.id);
percussionMap.put(75, 18 + 25*Instrument.HAT.id);
percussionMap.put(76, 9 + 25*Instrument.HAT.id);
percussionMap.put(77, 5 + 25*Instrument.HAT.id);
percussionMap.put(78, 22 + 25*Instrument.HAT.id);
percussionMap.put(79, 19 + 25*Instrument.SNARE.id);
percussionMap.put(80, 17 + 25*Instrument.HAT.id);
percussionMap.put(81, 22 + 25*Instrument.HAT.id);
percussionMap.put(82, 22 + 25*Instrument.SNARE.id);
percussionMap.put(83, 24 + 25*Instrument.CHIME.id);
percussionMap.put(84, 24 + 25*Instrument.CHIME.id);
percussionMap.put(85, 21 + 25*Instrument.HAT.id);
percussionMap.put(86, 14 + 25*Instrument.BASEDRUM.id);
percussionMap.put(87, 7 + 25*Instrument.BASEDRUM.id);
}
}

View File

@@ -23,286 +23,286 @@ import java.util.Map;
// Author: hhhzzzsss
public class NBSConverter implements Converter {
public static final Instrument[] INSTRUMENT_INDEX = new Instrument[] {
Instrument.HARP,
Instrument.BASS,
Instrument.BASEDRUM,
Instrument.SNARE,
Instrument.HAT,
Instrument.GUITAR,
Instrument.FLUTE,
Instrument.BELL,
Instrument.CHIME,
Instrument.XYLOPHONE,
Instrument.IRON_XYLOPHONE,
Instrument.COW_BELL,
Instrument.DIDGERIDOO,
Instrument.BIT,
Instrument.BANJO,
Instrument.PLING,
};
public static final Instrument[] INSTRUMENT_INDEX = new Instrument[] {
Instrument.HARP,
Instrument.BASS,
Instrument.BASEDRUM,
Instrument.SNARE,
Instrument.HAT,
Instrument.GUITAR,
Instrument.FLUTE,
Instrument.BELL,
Instrument.CHIME,
Instrument.XYLOPHONE,
Instrument.IRON_XYLOPHONE,
Instrument.COW_BELL,
Instrument.DIDGERIDOO,
Instrument.BIT,
Instrument.BANJO,
Instrument.PLING,
};
public static final Map<String, String> CUSTOM_INSTRUMENT_REPLACEMENTS = new HashMap<>();
public static final Map<String, String> CUSTOM_INSTRUMENT_REPLACEMENTS = new HashMap<>();
static {
CUSTOM_INSTRUMENT_REPLACEMENTS.put("entity\\.firework\\.", "entity.firework_rocket.");
CUSTOM_INSTRUMENT_REPLACEMENTS.put(".*glass.*", "block.glass.break");
CUSTOM_INSTRUMENT_REPLACEMENTS.put(".*door.*", "block.wooden_door.open");
CUSTOM_INSTRUMENT_REPLACEMENTS.put(".*anvil.*", "block.anvil.fall");
CUSTOM_INSTRUMENT_REPLACEMENTS.put(".*piston.*", "block.piston.extend");
CUSTOM_INSTRUMENT_REPLACEMENTS.put(".*explode|explosion.*", "entity.generic.explode");
CUSTOM_INSTRUMENT_REPLACEMENTS.put(".*eye.*", "block.end_portal_frame.fill");
CUSTOM_INSTRUMENT_REPLACEMENTS.put("fizz", "block.sand.break"); // not really sure what this exactly is, but it exists in some NBSes
}
public static class NBSNote {
public int tick;
public short layer;
public byte instrument;
public byte key;
public byte velocity = 100;
public byte panning = 100;
public short pitch = 0;
}
public static class NBSLayer {
public String name;
public byte lock = 0;
public byte volume;
public byte stereo = 100;
}
private static class NBSCustomInstrument {
public String name;
public String file;
public byte pitch = 0;
public boolean key = false;
}
@Override
public Song getSongFromBytes(byte[] bytes, String fileName, Bot bot) throws IOException {
ByteBuffer buffer = ByteBuffer.wrap(bytes);
buffer.order(ByteOrder.LITTLE_ENDIAN);
short songLength;
byte format = 0;
byte vanillaInstrumentCount = 0;
songLength = buffer.getShort(); // If it's not 0, then it uses the old format
if (songLength == 0) {
format = buffer.get();
static {
CUSTOM_INSTRUMENT_REPLACEMENTS.put("entity\\.firework\\.", "entity.firework_rocket.");
CUSTOM_INSTRUMENT_REPLACEMENTS.put(".*glass.*", "block.glass.break");
CUSTOM_INSTRUMENT_REPLACEMENTS.put(".*door.*", "block.wooden_door.open");
CUSTOM_INSTRUMENT_REPLACEMENTS.put(".*anvil.*", "block.anvil.fall");
CUSTOM_INSTRUMENT_REPLACEMENTS.put(".*piston.*", "block.piston.extend");
CUSTOM_INSTRUMENT_REPLACEMENTS.put(".*explode|explosion.*", "entity.generic.explode");
CUSTOM_INSTRUMENT_REPLACEMENTS.put(".*eye.*", "block.end_portal_frame.fill");
CUSTOM_INSTRUMENT_REPLACEMENTS.put("fizz", "block.sand.break"); // not really sure what this exactly is, but it exists in some NBSes
}
if (format >= 1) {
vanillaInstrumentCount = buffer.get();
}
if (format >= 3) {
songLength = buffer.getShort();
public static class NBSNote {
public int tick;
public short layer;
public byte instrument;
public byte key;
public byte velocity = 100;
public byte panning = 100;
public short pitch = 0;
}
short layerCount = buffer.getShort();
String songName = getString(buffer, bytes.length);
String songAuthor = getString(buffer, bytes.length);
String songOriginalAuthor = getString(buffer, bytes.length);
String songDescription = getString(buffer, bytes.length);
short tempo = buffer.getShort();
byte autoSaving = buffer.get();
byte autoSavingDuration = buffer.get();
byte timeSignature = buffer.get();
int minutesSpent = buffer.getInt();
int leftClicks = buffer.getInt();
int rightClicks = buffer.getInt();
int blocksAdded = buffer.getInt();
int blocksRemoved = buffer.getInt();
String origFileName = getString(buffer, bytes.length);
byte loop = 0;
byte maxLoopCount = 0;
short loopStartTick = 0;
if (format >= 4) {
loop = buffer.get();
maxLoopCount = buffer.get();
loopStartTick = buffer.getShort();
public static class NBSLayer {
public String name;
public byte lock = 0;
public byte volume;
public byte stereo = 100;
}
ArrayList<NBSNote> nbsNotes = new ArrayList<>();
short tick = -1;
while (true) {
int tickJumps = buffer.getShort();
if (tickJumps == 0) break;
tick += (short) tickJumps;
private static class NBSCustomInstrument {
public String name;
public String file;
public byte pitch = 0;
public boolean key = false;
}
short layer = -1;
while (true) {
int layerJumps = buffer.getShort();
if (layerJumps == 0) break;
layer += (short) layerJumps;
NBSNote note = new NBSNote();
note.tick = tick;
note.layer = layer;
note.instrument = buffer.get();
note.key = buffer.get();
@Override
public Song getSongFromBytes(byte[] bytes, String fileName, Bot bot) throws IOException {
ByteBuffer buffer = ByteBuffer.wrap(bytes);
buffer.order(ByteOrder.LITTLE_ENDIAN);
short songLength;
byte format = 0;
byte vanillaInstrumentCount = 0;
songLength = buffer.getShort(); // If it's not 0, then it uses the old format
if (songLength == 0) {
format = buffer.get();
}
if (format >= 1) {
vanillaInstrumentCount = buffer.get();
}
if (format >= 3) {
songLength = buffer.getShort();
}
short layerCount = buffer.getShort();
String songName = getString(buffer, bytes.length);
String songAuthor = getString(buffer, bytes.length);
String songOriginalAuthor = getString(buffer, bytes.length);
String songDescription = getString(buffer, bytes.length);
short tempo = buffer.getShort();
byte autoSaving = buffer.get();
byte autoSavingDuration = buffer.get();
byte timeSignature = buffer.get();
int minutesSpent = buffer.getInt();
int leftClicks = buffer.getInt();
int rightClicks = buffer.getInt();
int blocksAdded = buffer.getInt();
int blocksRemoved = buffer.getInt();
String origFileName = getString(buffer, bytes.length);
byte loop = 0;
byte maxLoopCount = 0;
short loopStartTick = 0;
if (format >= 4) {
note.velocity = buffer.get();
note.panning = buffer.get();
note.pitch = buffer.getShort();
loop = buffer.get();
maxLoopCount = buffer.get();
loopStartTick = buffer.getShort();
}
nbsNotes.add(note);
}
}
ArrayList<NBSLayer> nbsLayers = new ArrayList<>();
if (buffer.hasRemaining()) {
for (int i=0; i<layerCount; i++) {
NBSLayer layer = new NBSLayer();
layer.name = getString(buffer, bytes.length);
if (format >= 4) {
layer.lock = buffer.get();
ArrayList<NBSNote> nbsNotes = new ArrayList<>();
short tick = -1;
while (true) {
int tickJumps = buffer.getShort();
if (tickJumps == 0) break;
tick += (short) tickJumps;
short layer = -1;
while (true) {
int layerJumps = buffer.getShort();
if (layerJumps == 0) break;
layer += (short) layerJumps;
NBSNote note = new NBSNote();
note.tick = tick;
note.layer = layer;
note.instrument = buffer.get();
note.key = buffer.get();
if (format >= 4) {
note.velocity = buffer.get();
note.panning = buffer.get();
note.pitch = buffer.getShort();
}
nbsNotes.add(note);
}
}
layer.volume = buffer.get();
if (format >= 2) {
layer.stereo = buffer.get();
ArrayList<NBSLayer> nbsLayers = new ArrayList<>();
if (buffer.hasRemaining()) {
for (int i=0; i<layerCount; i++) {
NBSLayer layer = new NBSLayer();
layer.name = getString(buffer, bytes.length);
if (format >= 4) {
layer.lock = buffer.get();
}
layer.volume = buffer.get();
if (format >= 2) {
layer.stereo = buffer.get();
}
nbsLayers.add(layer);
}
}
nbsLayers.add(layer);
}
}
ArrayList<NBSCustomInstrument> customInstruments = new ArrayList<>();
if (buffer.hasRemaining()) {
byte customInstrumentCount = buffer.get();
for (int i = 0; i < customInstrumentCount; i++) {
NBSCustomInstrument customInstrument = new NBSCustomInstrument();
customInstrument.name = getString(buffer, bytes.length);
customInstrument.file = getString(buffer, bytes.length);
customInstrument.pitch = buffer.get();
customInstrument.key = buffer.get() != 0;
customInstruments.add(customInstrument);
}
}
ArrayList<NBSCustomInstrument> customInstruments = new ArrayList<>();
if (buffer.hasRemaining()) {
byte customInstrumentCount = buffer.get();
for (int i = 0; i < customInstrumentCount; i++) {
NBSCustomInstrument customInstrument = new NBSCustomInstrument();
customInstrument.name = getString(buffer, bytes.length);
customInstrument.file = getString(buffer, bytes.length);
customInstrument.pitch = buffer.get();
customInstrument.key = buffer.get() != 0;
customInstruments.add(customInstrument);
}
}
final StringBuilder layerNames = new StringBuilder();
final StringBuilder layerNames = new StringBuilder();
for (NBSLayer layer : nbsLayers) {
layerNames.append(layer.name);
layerNames.append("\n");
}
for (NBSLayer layer : nbsLayers) {
layerNames.append(layer.name);
layerNames.append("\n");
}
final String stringLayerNames = layerNames.toString();
final String stringLayerNames = layerNames.toString();
Song song = new Song(!songName.isBlank() ? songName : fileName, bot, songName, songAuthor, songOriginalAuthor, songDescription, stringLayerNames.substring(0, stringLayerNames.length() - 1), true);
if (loop > 0) {
song.loopPosition = getMilliTime(loopStartTick, tempo);
Song song = new Song(!songName.isBlank() ? songName : fileName, bot, songName, songAuthor, songOriginalAuthor, songDescription, stringLayerNames.substring(0, stringLayerNames.length() - 1), true);
if (loop > 0) {
song.loopPosition = getMilliTime(loopStartTick, tempo);
// song.loopCount = maxLoopCount;
}
for (NBSNote note : nbsNotes) {
Instrument instrument;
double key = note.key;
if (note.instrument < INSTRUMENT_INDEX.length) {
instrument = INSTRUMENT_INDEX[note.instrument];
}
for (NBSNote note : nbsNotes) {
Instrument instrument;
double key = note.key;
if (note.instrument < INSTRUMENT_INDEX.length) {
instrument = INSTRUMENT_INDEX[note.instrument];
key = (double) ((note.key * 100) + note.pitch) / 100;
} else {
final int index = note.instrument - INSTRUMENT_INDEX.length;
key = (double) ((note.key * 100) + note.pitch) / 100;
} else {
final int index = note.instrument - INSTRUMENT_INDEX.length;
if (index >= customInstruments.size()) continue;
if (index >= customInstruments.size()) continue;
final NBSCustomInstrument customInstrument = customInstruments.get(index);
final NBSCustomInstrument customInstrument = customInstruments.get(index);
String name = customInstrument.name;
String file = Path.of(customInstrument.file).getFileName().toString();
String name = customInstrument.name;
String file = Path.of(customInstrument.file).getFileName().toString();
// should i hardcode the extension like this?
if (file.endsWith(".ogg")) file = file.substring(0, file.length() - ".ogg".length());
// should i hardcode the extension like this?
if (file.endsWith(".ogg")) file = file.substring(0, file.length() - ".ogg".length());
boolean replaced = false;
boolean replaced = false;
final String replacedName = StringUtilities.replaceAllWithMap(name.toLowerCase(), CUSTOM_INSTRUMENT_REPLACEMENTS);
final String replacedFile = StringUtilities.replaceAllWithMap(file.toLowerCase(), CUSTOM_INSTRUMENT_REPLACEMENTS);
final String replacedName = StringUtilities.replaceAllWithMap(name.toLowerCase(), CUSTOM_INSTRUMENT_REPLACEMENTS);
final String replacedFile = StringUtilities.replaceAllWithMap(file.toLowerCase(), CUSTOM_INSTRUMENT_REPLACEMENTS);
if (!file.equals(replacedFile)) {
file = replacedFile;
replaced = true;
} else if (!name.equals(replacedName)) {
name = replacedName;
replaced = true;
if (!file.equals(replacedFile)) {
file = replacedFile;
replaced = true;
} else if (!name.equals(replacedName)) {
name = replacedName;
replaced = true;
}
if (!sounds.contains(name) && !sounds.contains(file) && !replaced) {
final List<String> outputTitles = LevenshteinUtilities.searchTitles(name, subtitles.values());
final String bestMatch = outputTitles.isEmpty() ? "" : outputTitles.getFirst();
for (Map.Entry<String, String> entry : subtitles.entrySet()) {
if (!entry.getValue().equals(bestMatch)) continue;
name = entry.getKey().substring("subtitles.".length());
break;
}
}
if (!sounds.contains(name) && sounds.contains(file)) name = file;
instrument = Instrument.of(name);
key += (double) (customInstrument.pitch + note.pitch) / 100;
}
byte layerVolume = 100;
if (nbsLayers.size() > note.layer) {
layerVolume = nbsLayers.get(note.layer).volume;
}
double pitch = key - 33;
try {
song.add(new Note(instrument, pitch, key, (float) note.velocity * (float) layerVolume / 10000f, getMilliTime(note.tick, tempo), Byte.toUnsignedInt(note.panning), Byte.toUnsignedInt(nbsLayers.get(note.layer).stereo)));
} catch (Exception e) {
song.add(new Note(instrument, pitch, key, (float) note.velocity * (float) layerVolume / 10000f, getMilliTime(note.tick, tempo), -1, 100));
}
}
if (!sounds.contains(name) && !sounds.contains(file) && !replaced) {
final List<String> outputTitles = LevenshteinUtilities.searchTitles(name, subtitles.values());
song.length = song.get(song.size()-1).time + 50;
final String bestMatch = outputTitles.isEmpty() ? "" : outputTitles.getFirst();
return song;
}
for (Map.Entry<String, String> entry : subtitles.entrySet()) {
if (!entry.getValue().equals(bestMatch)) continue;
private static String getString (ByteBuffer buffer, int maxSize) throws IOException {
int length = buffer.getInt();
if (length > maxSize) {
throw new IOException("String is too large");
}
byte[] arr = new byte[length];
buffer.get(arr, 0, length);
return new String(arr, StandardCharsets.UTF_8);
}
name = entry.getKey().substring("subtitles.".length());
private static int getMilliTime(int tick, int tempo) {
return 1000 * tick * 100 / tempo;
}
break;
}
private static final Map<String, String> subtitles = new HashMap<>();
static {
for (Map.Entry<String, String> entry : ComponentUtilities.LANGUAGE.entrySet()) {
if (!entry.getKey().startsWith("subtitles.")) continue;
subtitles.put(entry.getKey(), entry.getValue());
}
}
private static final List<String> sounds = loadJsonStringArray("sounds.json");
private static List<String> loadJsonStringArray (String name) {
List<String> list = new ArrayList<>();
InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream(name);
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
JsonArray json = JsonParser.parseReader(reader).getAsJsonArray();
for (JsonElement entry : json) {
list.add(entry.getAsString());
}
if (!sounds.contains(name) && sounds.contains(file)) name = file;
instrument = Instrument.of(name);
key += (double) (customInstrument.pitch + note.pitch) / 100;
}
byte layerVolume = 100;
if (nbsLayers.size() > note.layer) {
layerVolume = nbsLayers.get(note.layer).volume;
}
double pitch = key - 33;
try {
song.add(new Note(instrument, pitch, key, (float) note.velocity * (float) layerVolume / 10000f, getMilliTime(note.tick, tempo), Byte.toUnsignedInt(note.panning), Byte.toUnsignedInt(nbsLayers.get(note.layer).stereo)));
} catch (Exception e) {
song.add(new Note(instrument, pitch, key, (float) note.velocity * (float) layerVolume / 10000f, getMilliTime(note.tick, tempo), -1, 100));
}
return list;
}
song.length = song.get(song.size()-1).time + 50;
return song;
}
private static String getString (ByteBuffer buffer, int maxSize) throws IOException {
int length = buffer.getInt();
if (length > maxSize) {
throw new IOException("String is too large");
}
byte[] arr = new byte[length];
buffer.get(arr, 0, length);
return new String(arr, StandardCharsets.UTF_8);
}
private static int getMilliTime(int tick, int tempo) {
return 1000 * tick * 100 / tempo;
}
private static final Map<String, String> subtitles = new HashMap<>();
static {
for (Map.Entry<String, String> entry : ComponentUtilities.LANGUAGE.entrySet()) {
if (!entry.getKey().startsWith("subtitles.")) continue;
subtitles.put(entry.getKey(), entry.getValue());
}
}
private static final List<String> sounds = loadJsonStringArray("sounds.json");
private static List<String> loadJsonStringArray (String name) {
List<String> list = new ArrayList<>();
InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream(name);
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
JsonArray json = JsonParser.parseReader(reader).getAsJsonArray();
for (JsonElement entry : json) {
list.add(entry.getAsString());
}
return list;
}
}

View File

@@ -2,60 +2,60 @@ package me.chayapak1.chomens_bot.song;
// Author: hhhzzzsss
public class Note implements Comparable<Note> {
public final Instrument instrument;
public final Instrument shiftedInstrument;
public final double pitch;
public final double shiftedPitch;
public final double originalPitch;
public final float volume;
public final long time;
public final int panning;
public final int stereo;
public final Instrument instrument;
public final Instrument shiftedInstrument;
public final double pitch;
public final double shiftedPitch;
public final double originalPitch;
public final float volume;
public final long time;
public final int panning;
public final int stereo;
public Note (
Instrument instrument,
double pitch,
double originalPitch,
float volume,
long time,
int panning,
int stereo
) {
this.instrument = instrument;
this.shiftedInstrument = this.instrument;
this.pitch = pitch;
this.shiftedPitch = this.pitch;
this.originalPitch = originalPitch;
this.volume = volume;
this.time = time;
this.panning = panning;
this.stereo = stereo;
}
public Note (
Instrument instrument,
double pitch,
double originalPitch,
float volume,
long time,
int panning,
int stereo
) {
this.instrument = instrument;
this.shiftedInstrument = this.instrument;
this.pitch = pitch;
this.shiftedPitch = this.pitch;
this.originalPitch = originalPitch;
this.volume = volume;
this.time = time;
this.panning = panning;
this.stereo = stereo;
}
public Note (
Instrument instrument,
Instrument shiftedInstrument,
double pitch,
double shiftedPitch,
double originalPitch,
float volume,
long time,
int panning,
int stereo
) {
this.instrument = instrument;
this.shiftedInstrument = shiftedInstrument;
this.pitch = pitch;
this.shiftedPitch = shiftedPitch;
this.originalPitch = originalPitch;
this.volume = volume;
this.time = time;
this.panning = panning;
this.stereo = stereo;
}
public Note (
Instrument instrument,
Instrument shiftedInstrument,
double pitch,
double shiftedPitch,
double originalPitch,
float volume,
long time,
int panning,
int stereo
) {
this.instrument = instrument;
this.shiftedInstrument = shiftedInstrument;
this.pitch = pitch;
this.shiftedPitch = shiftedPitch;
this.originalPitch = originalPitch;
this.volume = volume;
this.time = time;
this.panning = panning;
this.stereo = stereo;
}
@Override
public int compareTo(Note other) {
return Long.compare(time, other.time);
}
@Override
public int compareTo(Note other) {
return Long.compare(time, other.time);
}
}

View File

@@ -8,145 +8,145 @@ import static me.chayapak1.chomens_bot.util.StringUtilities.isNotNullAndNotBlank
// Author: hhhzzzsss & _ChipMC_ but i changed most of the stuff
public class Song {
public final ArrayList<Note> notes = new ArrayList<>();
public final String originalName;
public String name;
public String requester = "Unknown";
public int position = 0; // Current note index
public boolean paused = true;
public long startTime = 0; // Start time in millis since unix epoch
public long length = 0; // Milliseconds in the song
public long time = 0; // Time since start of song
public long loopPosition = 0; // Milliseconds into the song to start looping
public final ArrayList<Note> notes = new ArrayList<>();
public final String originalName;
public String name;
public String requester = "Unknown";
public int position = 0; // Current note index
public boolean paused = true;
public long startTime = 0; // Start time in millis since unix epoch
public long length = 0; // Milliseconds in the song
public long time = 0; // Time since start of song
public long loopPosition = 0; // Milliseconds into the song to start looping
public final Map<Long, String> lyrics = new HashMap<>();
public final Map<Long, String> lyrics = new HashMap<>();
public String songName;
public String songAuthor;
public String songOriginalAuthor;
public String songDescription;
public String songName;
public String songAuthor;
public String songOriginalAuthor;
public String songDescription;
public String tracks;
public String tracks;
public final boolean nbs;
public final boolean nbs;
// public int loopCount = 0; // Number of times to loop
// public int currentLoop = 0; // Number of loops so far
private final Bot bot;
private final Bot bot;
public Song (String originalName, Bot bot, String songName, String songAuthor, String songOriginalAuthor, String songDescription, String tracks, boolean nbs) {
this.originalName = originalName;
this.bot = bot;
this.songName = songName;
this.songAuthor = songAuthor;
this.songOriginalAuthor = songOriginalAuthor;
this.songDescription = songDescription;
this.tracks = tracks;
this.nbs = nbs;
public Song (String originalName, Bot bot, String songName, String songAuthor, String songOriginalAuthor, String songDescription, String tracks, boolean nbs) {
this.originalName = originalName;
this.bot = bot;
this.songName = songName;
this.songAuthor = songAuthor;
this.songOriginalAuthor = songOriginalAuthor;
this.songDescription = songDescription;
this.tracks = tracks;
this.nbs = nbs;
updateName();
}
public void updateName() {
String authorPart = null;
if (isNotNullAndNotBlank(songOriginalAuthor) && isNotNullAndNotBlank(songAuthor)) {
authorPart = String.format("%s/%s", songOriginalAuthor, songAuthor);
} else if (isNotNullAndNotBlank(songOriginalAuthor)) {
authorPart = songOriginalAuthor;
} else if (isNotNullAndNotBlank(songAuthor)) {
authorPart = songAuthor;
updateName();
}
String namePart = isNotNullAndNotBlank(songName) ? songName : originalName;
name = (authorPart != null) ? String.format("%s - %s", authorPart, namePart) : namePart;
}
public void updateName() {
String authorPart = null;
public Note get (int i) {
return notes.get(i);
}
public void add (Note e) {
notes.add(e);
}
public void sort () {
Collections.sort(notes);
}
/**
* Starts playing song (does nothing if already playing)
*/
public void play () {
if (paused) {
if (loopPosition != 0) bot.music.loop = Loop.CURRENT;
paused = false;
startTime = System.currentTimeMillis() - time;
}
}
/**
* Pauses song (does nothing if already paused)
*/
public void pause () {
if (!paused) {
paused = true;
// Recalculates time so that the song will continue playing after the exact point it was paused
advanceTime();
}
}
public void setTime (long t) {
time = t;
startTime = System.currentTimeMillis() - time;
position = 0;
while (position < notes.size() && notes.get(position).time < t) {
position++;
}
}
public void advanceTime () {
time = (long) ((System.currentTimeMillis() - startTime) * bot.music.speed);
}
public boolean reachedNextNote () {
if (position < notes.size()) {
return notes.get(position).time <= time * bot.music.speed;
} else {
if (finished() && bot.music.loop != Loop.OFF) {
if (position < notes.size()) {
return notes.get(position).time <= time * bot.music.speed;
} else {
return false;
if (isNotNullAndNotBlank(songOriginalAuthor) && isNotNullAndNotBlank(songAuthor)) {
authorPart = String.format("%s/%s", songOriginalAuthor, songAuthor);
} else if (isNotNullAndNotBlank(songOriginalAuthor)) {
authorPart = songOriginalAuthor;
} else if (isNotNullAndNotBlank(songAuthor)) {
authorPart = songAuthor;
}
} else {
return false;
}
String namePart = isNotNullAndNotBlank(songName) ? songName : originalName;
name = (authorPart != null) ? String.format("%s - %s", authorPart, namePart) : namePart;
}
}
public void loop () {
position = 0;
startTime += length - loopPosition;
time -= length - loopPosition;
while (position < notes.size() && notes.get(position).time < loopPosition) {
position++;
public Note get (int i) {
return notes.get(i);
}
}
public Note getNextNote () {
if (position >= notes.size()) {
if (bot.music.loop == Loop.OFF) return null;
public void add (Note e) {
notes.add(e);
}
return notes.get(position++);
}
public boolean finished () {
return (time * bot.music.speed) > length || position >= size();
}
public void sort () {
Collections.sort(notes);
}
public int size () {
return notes.size();
}
/**
* Starts playing song (does nothing if already playing)
*/
public void play () {
if (paused) {
if (loopPosition != 0) bot.music.loop = Loop.CURRENT;
paused = false;
startTime = System.currentTimeMillis() - time;
}
}
/**
* Pauses song (does nothing if already paused)
*/
public void pause () {
if (!paused) {
paused = true;
// Recalculates time so that the song will continue playing after the exact point it was paused
advanceTime();
}
}
public void setTime (long t) {
time = t;
startTime = System.currentTimeMillis() - time;
position = 0;
while (position < notes.size() && notes.get(position).time < t) {
position++;
}
}
public void advanceTime () {
time = (long) ((System.currentTimeMillis() - startTime) * bot.music.speed);
}
public boolean reachedNextNote () {
if (position < notes.size()) {
return notes.get(position).time <= time * bot.music.speed;
} else {
if (finished() && bot.music.loop != Loop.OFF) {
if (position < notes.size()) {
return notes.get(position).time <= time * bot.music.speed;
} else {
return false;
}
} else {
return false;
}
}
}
public void loop () {
position = 0;
startTime += length - loopPosition;
time -= length - loopPosition;
while (position < notes.size() && notes.get(position).time < loopPosition) {
position++;
}
}
public Note getNextNote () {
if (position >= notes.size()) {
if (bot.music.loop == Loop.OFF) return null;
}
return notes.get(position++);
}
public boolean finished () {
return (time * bot.music.speed) > length || position >= size();
}
public int size () {
return notes.size();
}
}

View File

@@ -2,12 +2,12 @@ package me.chayapak1.chomens_bot.song;
import net.kyori.adventure.text.Component;
// Author: _ChipMC_ or hhhzzzsss?
// Author: hhhzzzsss
public class SongLoaderException extends Exception {
public final Component message;
public final Component message;
public SongLoaderException (Component message) {
super();
this.message = message;
}
public SongLoaderException (Component message) {
super();
this.message = message;
}
}

View File

@@ -15,152 +15,152 @@ import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
// Author: _ChipMC_ & hhhzzzsss
// Author: _ChipMC_ & hhhzzzsss but modified
public class SongLoaderThread extends Thread {
// should the converters be here?
public static final List<Converter> converters = new ArrayList<>();
// should the converters be here?
public static final List<Converter> converters = new ArrayList<>();
static {
converters.add(new MidiConverter());
converters.add(new NBSConverter());
converters.add(new TextFileConverter());
converters.add(new SongPlayerConverter());
}
public final String fileName;
private Path songPath;
private URL songUrl;
public SongLoaderException exception;
public Song song;
private final Bot bot;
private final String requester;
private final boolean isUrl;
private byte[] data;
private boolean isItem = false;
private boolean isFolder = false;
public SongLoaderThread(URL location, Bot bot, String requester) {
this.bot = bot;
this.requester = requester;
isUrl = true;
songUrl = location;
fileName = location.getFile();
}
public SongLoaderThread(Path location, Bot bot, String requester) {
this.bot = bot;
this.requester = requester;
isUrl = false;
songPath = location;
isFolder = Files.isDirectory(songPath);
fileName = location.getFileName().toString();
}
public SongLoaderThread (byte[] data, Bot bot, String requester) {
this.bot = bot;
this.requester = requester;
this.data = data;
this.isItem = true;
this.isUrl = false;
fileName = requester + "'s song item";
}
@Override
public void run () {
if (isFolder && !isUrl && !isItem) {
try (Stream<Path> files = Files.list(songPath)) {
files.forEach((file) -> {
songPath = file;
processFile();
});
showAddedToQueue();
} catch (IOException e) {
bot.logger.error(e);
}
} else processFile();
}
private void processFile () {
if (bot.music.songQueue.size() > 100) return;
byte[] bytes;
String name;
try {
if (isUrl) {
bytes = DownloadUtilities.DownloadToByteArray(songUrl, 5 * 1024 * 1024);
final Path fileName = Paths.get(songUrl.toURI().getPath()).getFileName();
name = fileName == null ? "(root)" : fileName.toString();
} else if (isItem) {
bytes = data;
name = requester + "'s song item";
} else {
bytes = Files.readAllBytes(songPath);
name = !isFolder ? fileName : songPath.getFileName().toString();
}
} catch (Exception e) {
exception = new SongLoaderException(Component.text(e.getMessage()));
failed();
return;
static {
converters.add(new MidiConverter());
converters.add(new NBSConverter());
converters.add(new TextFileConverter());
converters.add(new SongPlayerConverter());
}
for (Converter converter : converters) {
if (song != null && !isFolder) break;
public final String fileName;
try {
song = converter.getSongFromBytes(bytes, name, bot);
} catch (Exception ignored) {}
private Path songPath;
private URL songUrl;
public SongLoaderException exception;
public Song song;
private final Bot bot;
private final String requester;
private final boolean isUrl;
private byte[] data;
private boolean isItem = false;
private boolean isFolder = false;
public SongLoaderThread(URL location, Bot bot, String requester) {
this.bot = bot;
this.requester = requester;
isUrl = true;
songUrl = location;
fileName = location.getFile();
}
if (song == null) {
exception = new SongLoaderException(Component.translatable("Invalid format"));
public SongLoaderThread(Path location, Bot bot, String requester) {
this.bot = bot;
this.requester = requester;
isUrl = false;
songPath = location;
failed();
} else {
song.requester = requester;
isFolder = Files.isDirectory(songPath);
bot.music.songQueue.add(song);
if (!isFolder) showAddedToQueue();
fileName = location.getFileName().toString();
}
bot.music.loaderThread = null;
}
public SongLoaderThread (byte[] data, Bot bot, String requester) {
this.bot = bot;
this.requester = requester;
this.data = data;
this.isItem = true;
this.isUrl = false;
private void showAddedToQueue () {
if (isFolder) {
bot.chat.tellraw(
Component.text(
"Added folder to the song queue"
).color(ColorUtilities.getColorByString(bot.config.colorPalette.defaultColor))
);
} else {
bot.chat.tellraw(
Component.translatable(
"Added %s to the song queue",
Component.empty().append(Component.text(song.name)).color(ColorUtilities.getColorByString(bot.config.colorPalette.secondary))
).color(ColorUtilities.getColorByString(bot.config.colorPalette.defaultColor))
);
fileName = requester + "'s song item";
}
}
private void failed() {
bot.logger.error(exception);
bot.chat.tellraw(Component.translatable("Failed to load song: %s", exception.message).color(NamedTextColor.RED));
bot.music.loaderThread = null;
}
@Override
public void run () {
if (isFolder && !isUrl && !isItem) {
try (Stream<Path> files = Files.list(songPath)) {
files.forEach((file) -> {
songPath = file;
processFile();
});
showAddedToQueue();
} catch (IOException e) {
bot.logger.error(e);
}
} else processFile();
}
private void processFile () {
if (bot.music.songQueue.size() > 100) return;
byte[] bytes;
String name;
try {
if (isUrl) {
bytes = DownloadUtilities.DownloadToByteArray(songUrl, 5 * 1024 * 1024);
final Path fileName = Paths.get(songUrl.toURI().getPath()).getFileName();
name = fileName == null ? "(root)" : fileName.toString();
} else if (isItem) {
bytes = data;
name = requester + "'s song item";
} else {
bytes = Files.readAllBytes(songPath);
name = !isFolder ? fileName : songPath.getFileName().toString();
}
} catch (Exception e) {
exception = new SongLoaderException(Component.text(e.getMessage()));
failed();
return;
}
for (Converter converter : converters) {
if (song != null && !isFolder) break;
try {
song = converter.getSongFromBytes(bytes, name, bot);
} catch (Exception ignored) {}
}
if (song == null) {
exception = new SongLoaderException(Component.translatable("Invalid format"));
failed();
} else {
song.requester = requester;
bot.music.songQueue.add(song);
if (!isFolder) showAddedToQueue();
}
bot.music.loaderThread = null;
}
private void showAddedToQueue () {
if (isFolder) {
bot.chat.tellraw(
Component.text(
"Added folder to the song queue"
).color(ColorUtilities.getColorByString(bot.config.colorPalette.defaultColor))
);
} else {
bot.chat.tellraw(
Component.translatable(
"Added %s to the song queue",
Component.empty().append(Component.text(song.name)).color(ColorUtilities.getColorByString(bot.config.colorPalette.secondary))
).color(ColorUtilities.getColorByString(bot.config.colorPalette.defaultColor))
);
}
}
private void failed() {
bot.logger.error(exception);
bot.chat.tellraw(Component.translatable("Failed to load song: %s", exception.message).color(NamedTextColor.RED));
bot.music.loaderThread = null;
}
}