diff --git a/README.md b/README.md index 8d3d346..9af43ad 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Using it is very simple, just run the jar file, and it will start a user interfa - Work with multiple songs at once (Batch processing) - High performance and accurate song player - Lag free playback of very large songs - - Supports all NBS features except for custom instruments + - Supports all NBS features including custom instruments - Good MIDI importer - Supports most MIDI files - Supports velocity and panning @@ -34,7 +34,6 @@ Using it is very simple, just run the jar file, and it will start a user interfa ### Limitations - NBS layers are not preserved when doing anything other than editing the metadata - All editing is done on intermediary song objects which do not have layers -- NBS custom instruments aren't played back ## Usage ### Importing diff --git a/src/main/java/net/raphimc/noteblocktool/audio/soundsystem/impl/OpenALSoundSystem.java b/src/main/java/net/raphimc/noteblocktool/audio/soundsystem/impl/OpenALSoundSystem.java index 284a1b8..7f88050 100644 --- a/src/main/java/net/raphimc/noteblocktool/audio/soundsystem/impl/OpenALSoundSystem.java +++ b/src/main/java/net/raphimc/noteblocktool/audio/soundsystem/impl/OpenALSoundSystem.java @@ -69,11 +69,11 @@ public static OpenALSoundSystem createCapture(final int maxSounds, final AudioFo private Thread shutdownHook; private ByteBuffer captureBuffer; - private OpenALSoundSystem(final int maxSounds) { // Playback + private OpenALSoundSystem(final int maxSounds) { this(maxSounds, null); } - private OpenALSoundSystem(final int maxSounds, final AudioFormat captureAudioFormat) { // Capture + private OpenALSoundSystem(final int maxSounds, final AudioFormat captureAudioFormat) { super(maxSounds); this.audioFormat = captureAudioFormat; diff --git a/src/main/java/net/raphimc/noteblocktool/frames/ListFrame.java b/src/main/java/net/raphimc/noteblocktool/frames/ListFrame.java index 2d6828a..b02a76a 100644 --- a/src/main/java/net/raphimc/noteblocktool/frames/ListFrame.java +++ b/src/main/java/net/raphimc/noteblocktool/frames/ListFrame.java @@ -25,6 +25,7 @@ import net.raphimc.noteblocklib.model.Song; import net.raphimc.noteblocklib.model.SongView; import net.raphimc.noteblocklib.util.SongUtil; +import net.raphimc.noteblocktool.audio.SoundMap; import net.raphimc.noteblocktool.elements.FastScrollPane; import net.raphimc.noteblocktool.elements.TextOverlayPanel; import net.raphimc.noteblocktool.elements.drag.DragTable; @@ -52,6 +53,7 @@ public class ListFrame extends JFrame { private final DragTable table = new DragTable(); private final JButton addButton = new JButton("Add"); private final JButton removeButton = new JButton("Remove"); + private final JButton setCustomSoundsFolder = new JButton("Set Custom Sounds folder"); private final JButton editButton = new JButton("Edit"); private final JButton playButton = new JButton("Play"); private final JButton exportButton = new JButton("Export"); @@ -113,8 +115,24 @@ public void keyPressed(KeyEvent e) { } }); }); - GBC.create(buttonPanel).gridx(2).weightx(1).fill(GBC.HORIZONTAL).add(Box.createVerticalGlue()); - GBC.create(buttonPanel).gridx(3).insets(5, 5, 5, 0).anchor(GBC.LINE_START).add(this.editButton, () -> { + GBC.create(buttonPanel).gridx(2).insets(5, 5, 5, 0).anchor(GBC.LINE_START).add(this.setCustomSoundsFolder, () -> { + this.setCustomSoundsFolder.addActionListener(e -> { + JFileChooser fileChooser = new JFileChooser(); + fileChooser.setDialogTitle("Select Custom Sounds folder"); + fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + if (fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { + try { + SoundMap.reload(fileChooser.getSelectedFile()); + } catch (Throwable t) { + t.printStackTrace(); + JOptionPane.showMessageDialog(this, "Failed to load custom sounds:\n" + t.getMessage(), "Error", JOptionPane.ERROR_MESSAGE); + } + } + }); + }); + this.setCustomSoundsFolder.setToolTipText("Set the folder where sound files for custom instruments are located"); + GBC.create(buttonPanel).gridx(3).weightx(1).fill(GBC.HORIZONTAL).add(Box.createVerticalGlue()); + GBC.create(buttonPanel).gridx(4).insets(5, 5, 5, 0).anchor(GBC.LINE_START).add(this.editButton, () -> { this.editButton.addActionListener(e -> { final int[] rows = this.table.getSelectedRows(); if (rows.length > 0) { @@ -124,7 +142,7 @@ public void keyPressed(KeyEvent e) { } }); }); - GBC.create(buttonPanel).gridx(4).insets(5, 5, 5, 0).anchor(GBC.LINE_START).add(this.playButton, () -> { + GBC.create(buttonPanel).gridx(5).insets(5, 5, 5, 0).anchor(GBC.LINE_START).add(this.playButton, () -> { this.playButton.addActionListener(e -> { final int[] rows = this.table.getSelectedRows(); if (rows.length == 1) { @@ -133,7 +151,7 @@ public void keyPressed(KeyEvent e) { } }); }); - GBC.create(buttonPanel).gridx(5).insets(5, 5, 5, 5).anchor(GBC.LINE_START).add(this.exportButton, () -> { + GBC.create(buttonPanel).gridx(6).insets(5, 5, 5, 5).anchor(GBC.LINE_START).add(this.exportButton, () -> { this.exportButton.addActionListener(e -> { SongPlayerFrame.close(); this.setEnabled(false);