From 183c79ca76e425e70df2d874752bf20d0cc38010 Mon Sep 17 00:00:00 2001 From: Chip <65827213+ChipmunkMC@users.noreply.github.com> Date: Mon, 20 Feb 2023 20:25:41 -0500 Subject: [PATCH] Begin work on adding custom instruments --- .../chipmunkbot/plugins/SongPlayer.java | 2 +- .../chipmunk/chipmunkbot/song/Instrument.java | 55 ++++++++++++------- .../chipmunkbot/song/MidiConverter.java | 2 +- .../chipmunkbot/song/NBSConverter.java | 36 ++++++++++-- 4 files changed, 66 insertions(+), 29 deletions(-) diff --git a/src/main/java/land/chipmunk/chipmunkbot/plugins/SongPlayer.java b/src/main/java/land/chipmunk/chipmunkbot/plugins/SongPlayer.java index da4d714..00a8f9f 100644 --- a/src/main/java/land/chipmunk/chipmunkbot/plugins/SongPlayer.java +++ b/src/main/java/land/chipmunk/chipmunkbot/plugins/SongPlayer.java @@ -164,7 +164,7 @@ public class SongPlayer extends SessionAdapter { final double floatingPitch = Math.pow(2, (note.pitch - 12) / 12.0); - client.core().run("execute as @a at @s run playsound minecraft:block.note_block." + note.instrument.name + " record @s ~ ~ ~ 1 " + floatingPitch); + client.core().run("execute as @a at @s run playsound " + note.instrument.sound + " record @s ~ ~ ~ 1 " + floatingPitch); } } } diff --git a/src/main/java/land/chipmunk/chipmunkbot/song/Instrument.java b/src/main/java/land/chipmunk/chipmunkbot/song/Instrument.java index 9071d96..1ec83ff 100644 --- a/src/main/java/land/chipmunk/chipmunkbot/song/Instrument.java +++ b/src/main/java/land/chipmunk/chipmunkbot/song/Instrument.java @@ -1,35 +1,48 @@ package land.chipmunk.chipmunkbot.song; -public enum Instrument {//{"harp", "basedrum", "snare", "hat", "bass", "flute", "bell", "guitar", "chime", "xylophone", "iron_xylophone", "cow_bell", "didgeridoo", "bit", "banjo", "pling"}; - HARP(0, "harp", 54), - BASEDRUM(1, "basedrum", 0), - SNARE(2, "snare", 0), - HAT(3, "hat", 0), - BASS(4, "bass", 30), - FLUTE(5, "flute", 66), - BELL(6, "bell", 78), - GUITAR(7, "guitar", 42), - CHIME(8, "chime", 78), - XYLOPHONE(9, "xylophone", 78), - IRON_XYLOPHONE(10, "iron_xylophone", 54), - COW_BELL(11, "cow_bell", 66), - DIDGERIDOO(12, "didgeridoo", 30), - BIT(13, "bit", 54), - BANJO(14, "banjo", 54), - PLING(15, "pling", 54); +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 final int id; public final String name; public final int offset; + public final String sound; - Instrument (int id, String name, int offset) { + private Instrument (int id, String name, int offset, String sound) { this.id = id; this.name = name; this.offset = offset; + this.sound = name; } - private static Instrument[] values = values(); - public static Instrument getInstrumentFromId (int instrumentId) { - return values[instrumentId]; + 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 static Instrument of (String sound) { + return new Instrument(-1, null, 0, sound); + } + + private static 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]; } } diff --git a/src/main/java/land/chipmunk/chipmunkbot/song/MidiConverter.java b/src/main/java/land/chipmunk/chipmunkbot/song/MidiConverter.java index 705a444..e2fb072 100644 --- a/src/main/java/land/chipmunk/chipmunkbot/song/MidiConverter.java +++ b/src/main/java/land/chipmunk/chipmunkbot/song/MidiConverter.java @@ -149,7 +149,7 @@ public class MidiConverter { if (percussionMap.containsKey(midiPitch)) { int noteId = percussionMap.get(midiPitch); int pitch = noteId % 25; - Instrument instrument = Instrument.getInstrumentFromId(noteId / 25); + Instrument instrument = Instrument.fromId(noteId / 25); long time = microTime / 1000L; return new Note(instrument, pitch, time); diff --git a/src/main/java/land/chipmunk/chipmunkbot/song/NBSConverter.java b/src/main/java/land/chipmunk/chipmunkbot/song/NBSConverter.java index 5528dd2..6c87e31 100644 --- a/src/main/java/land/chipmunk/chipmunkbot/song/NBSConverter.java +++ b/src/main/java/land/chipmunk/chipmunkbot/song/NBSConverter.java @@ -42,6 +42,13 @@ public class NBSConverter { public byte stereo = 100; } + private static class NBSCustomInstrument { + public String name; + public String file; + public byte pitch = 0; + public boolean key = false; + } + public static Song getSongFromBytes(byte[] bytes, String fileName) throws IOException { ByteBuffer buffer = ByteBuffer.wrap(bytes); buffer.order(ByteOrder.LITTLE_ENDIAN); @@ -128,6 +135,19 @@ public class NBSConverter { } } + ArrayList 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 ? false : true; + customInstruments.add(customInstrument); + } + } + Song song = new Song(songName.trim().length() > 0 ? songName : fileName); if (loop > 0) { song.looping = true; @@ -136,14 +156,18 @@ public class NBSConverter { } for (NBSNote note : nbsNotes) { Instrument instrument; + int key = note.key; if (note.instrument < instrumentIndex.length) { instrument = instrumentIndex[note.instrument]; - } - else { - continue; + } else { + int index = note.instrument - instrumentIndex.length; + if (index >= customInstruments.size()) continue; + NBSCustomInstrument customInstrument = customInstruments.get(index); + instrument = Instrument.of(customInstrument.name); + key += customInstrument.pitch; } - if (note.key < 33 || note.key > 57) { + if (key < 33 || key > 57) { continue; } @@ -152,7 +176,7 @@ public class NBSConverter { layerVolume = nbsLayers.get(note.layer).volume; } - int pitch = note.key-33; + int pitch = key-33; song.add(new Note(instrument, pitch, getMilliTime(note.tick, tempo))); } @@ -161,7 +185,7 @@ public class NBSConverter { return song; } - private static String getString(ByteBuffer buffer, int maxSize) throws IOException { + private static String getString (ByteBuffer buffer, int maxSize) throws IOException { int length = buffer.getInt(); if (length > maxSize) { throw new IOException("String is too large");