Skip to content

Commit 145cadc

Browse files
RaphiMCLenni0451
andauthored
Added song visualizer (#31)
* Added song visualizer window * Animate keys when they are pressed down * Use ratio instead of hardcoded sizes * Fixed rendering issues on Linux/AMD * Made key colors more vibrant * Improved keyboard design * Optimized map lookups * Improved piano visuals * Updated ThinGL API usage * Improved NBS renderer visuals * Removed MacOS OpenGL natives * Visualize tempo changes * Added button to open/close the visualizer window * Updated ThinGL --------- Co-authored-by: Lenni0451 <[email protected]>
1 parent 33e2b1b commit 145cadc

File tree

12 files changed

+763
-6
lines changed

12 files changed

+763
-6
lines changed

build.gradle

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,18 @@ dependencies {
4242
include "org.lwjgl:lwjgl-stb:3.3.6:$it"
4343
}
4444
include "net.java.dev.jna:jna:5.16.0"
45+
46+
include("net.raphimc:thingl:0.0.1-20250207.205058-20") {
47+
exclude group: "org.slf4j", module: "slf4j-api"
48+
}
49+
include "org.lwjgl:lwjgl-glfw:3.3.6"
50+
include "org.lwjgl:lwjgl-opengl:3.3.6"
51+
include "org.lwjgl:lwjgl-freetype:3.3.6"
52+
["natives-windows", "natives-windows-arm64", "natives-linux", "natives-linux-arm64"].each {
53+
include "org.lwjgl:lwjgl-glfw:3.3.6:$it"
54+
include "org.lwjgl:lwjgl-opengl:3.3.6:$it"
55+
include "org.lwjgl:lwjgl-freetype:3.3.6:$it"
56+
}
4557
}
4658

4759
application {

src/main/java/net/raphimc/noteblocktool/audio/soundsystem/impl/AudioMixerSoundSystem.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ public synchronized void close() {
8080
}
8181

8282
@Override
83-
public synchronized String getStatusLine() {
83+
public String getStatusLine() {
8484
return "Sounds: " + this.audioMixer.getMasterMixSound().getMixedSounds() + " / " + this.maxSounds;
8585
}
8686

src/main/java/net/raphimc/noteblocktool/audio/soundsystem/impl/MultithreadedAudioMixerSoundSystem.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ public synchronized void close() {
100100
}
101101

102102
@Override
103-
public synchronized String getStatusLine() {
103+
public String getStatusLine() {
104104
int mixedSounds = 0;
105105
for (AudioMixer audioMixer : this.audioMixers) {
106106
mixedSounds += audioMixer.getMasterMixSound().getMixedSounds();

src/main/java/net/raphimc/noteblocktool/frames/SongPlayerFrame.java

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import net.raphimc.noteblocktool.audio.soundsystem.impl.*;
2626
import net.raphimc.noteblocktool.elements.FastScrollPane;
2727
import net.raphimc.noteblocktool.elements.NewLineLabel;
28+
import net.raphimc.noteblocktool.frames.visualizer.VisualizerWindow;
2829
import net.raphimc.noteblocktool.util.SoundSystemSongPlayer;
2930

3031
import javax.swing.*;
@@ -36,7 +37,8 @@
3637

3738
public class SongPlayerFrame extends JFrame {
3839

39-
private static final String UNAVAILABLE_MESSAGE = "An error occurred while initializing the sound system.\nPlease make sure that your system supports the selected sound system.";
40+
private static final String SOUND_SYSTEM_UNAVAILABLE_MESSAGE = "An error occurred while initializing the sound system.\nPlease make sure that your system supports the selected sound system.";
41+
private static final String VISUALIZER_UNAVAILABLE_MESSAGE = "An error occurred while initializing the visualizer window.\nPlease make sure that your system supports at least OpenGL 4.5.";
4042
private static final DecimalFormat DECIMAL_FORMAT = new DecimalFormat("#.##");
4143
private static SongPlayerFrame instance;
4244
private static Point lastPosition;
@@ -76,6 +78,7 @@ public static void close() {
7678
private final JSlider volumeSlider = new JSlider(0, 100, lastVolume);
7779
private final JButton playStopButton = new JButton("Play");
7880
private final JButton pauseResumeButton = new JButton("Pause");
81+
private final JButton openVisualizerButton = new JButton("Open Visualizer");
7982
private final JSlider progressSlider = new JSlider(0, 100, 0);
8083
private final JLabel statusLine = new JLabel(" ");
8184
private final JLabel progressLabel = new JLabel("Current Position: 00:00:00");
@@ -215,6 +218,21 @@ private void initComponents() {
215218
this.soundSystem.stopSounds();
216219
}
217220
});
221+
buttonPanel.add(this.openVisualizerButton);
222+
this.openVisualizerButton.addActionListener(e -> {
223+
if (VisualizerWindow.getInstance().isVisible()) {
224+
this.openVisualizerButton.setText("Open Visualizer");
225+
VisualizerWindow.getInstance().hide();
226+
} else {
227+
VisualizerWindow.getInstance().open(this.songPlayer, this::toFront, () -> SwingUtilities.invokeLater(() -> this.openVisualizerButton.setText("Open Visualizer")));
228+
if (VisualizerWindow.getInstance().isRenderThreadAlive()) {
229+
this.openVisualizerButton.setText("Close Visualizer");
230+
} else {
231+
JOptionPane.showMessageDialog(this, VISUALIZER_UNAVAILABLE_MESSAGE, "Error", JOptionPane.ERROR_MESSAGE);
232+
this.openVisualizerButton.setEnabled(false);
233+
}
234+
}
235+
});
218236
GBC.create(southPanel).grid(0, gridy++).insets(5, 5, 5, 5).weightx(1).width(2).fill(GBC.HORIZONTAL).add(buttonPanel);
219237

220238
final JPanel statusBar = new JPanel();
@@ -240,7 +258,7 @@ private boolean initSoundSystem() {
240258
} else if (this.soundSystem == null) {
241259
currentIndex = -1;
242260
} else {
243-
throw new UnsupportedOperationException(UNAVAILABLE_MESSAGE);
261+
throw new UnsupportedOperationException(SOUND_SYSTEM_UNAVAILABLE_MESSAGE);
244262
}
245263

246264
try {
@@ -261,14 +279,14 @@ private boolean initSoundSystem() {
261279
} else if (this.soundSystemComboBox.getSelectedIndex() == 4) {
262280
this.soundSystem = new XAudio2SoundSystem(soundData, maxSounds);
263281
} else {
264-
throw new UnsupportedOperationException(UNAVAILABLE_MESSAGE);
282+
throw new UnsupportedOperationException(SOUND_SYSTEM_UNAVAILABLE_MESSAGE);
265283
}
266284
}
267285
return this.soundSystem != null;
268286
} catch (Throwable t) {
269287
this.soundSystem = null;
270288
t.printStackTrace();
271-
JOptionPane.showMessageDialog(this, UNAVAILABLE_MESSAGE, "Error", JOptionPane.ERROR_MESSAGE);
289+
JOptionPane.showMessageDialog(this, SOUND_SYSTEM_UNAVAILABLE_MESSAGE, "Error", JOptionPane.ERROR_MESSAGE);
272290
}
273291
return false;
274292
}
@@ -285,6 +303,7 @@ public void windowClosing(WindowEvent e) {
285303
public void windowClosed(WindowEvent e) {
286304
SongPlayerFrame.this.songPlayer.stop();
287305
SongPlayerFrame.this.updateTimer.stop();
306+
VisualizerWindow.getInstance().hide();
288307
if (SongPlayerFrame.this.soundSystem != null) SongPlayerFrame.this.soundSystem.close();
289308
}
290309
});

0 commit comments

Comments
 (0)