Skip to content

Commit 36bd918

Browse files
committed
Only load actually needed custom instruments
1 parent 32fb03d commit 36bd918

File tree

9 files changed

+82
-67
lines changed

9 files changed

+82
-67
lines changed

src/main/java/net/raphimc/noteblocktool/audio/SoundMap.java

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,12 @@
1717
*/
1818
package net.raphimc.noteblocktool.audio;
1919

20+
import net.raphimc.noteblocklib.format.nbs.model.NbsCustomInstrument;
21+
import net.raphimc.noteblocklib.model.SongView;
2022
import net.raphimc.noteblocklib.util.Instrument;
21-
import net.raphimc.noteblocktool.util.SoundSampleUtil;
23+
import net.raphimc.noteblocklib.util.SongUtil;
24+
import net.raphimc.noteblocktool.util.IOUtil;
2225

23-
import javax.sound.sampled.AudioFormat;
2426
import java.io.File;
2527
import java.net.URL;
2628
import java.nio.file.Files;
@@ -31,7 +33,7 @@
3133
public class SoundMap {
3234

3335
public static final Map<Instrument, String> INSTRUMENT_SOUNDS = new EnumMap<>(Instrument.class);
34-
public static final Map<String, URL> SOUND_LOCATIONS = new HashMap<>();
36+
private static final Map<String, URL> ALL_SOUND_LOCATIONS = new HashMap<>();
3537

3638
static {
3739
INSTRUMENT_SOUNDS.put(Instrument.HARP, "harp.ogg");
@@ -55,9 +57,9 @@ public class SoundMap {
5557
}
5658

5759
public static void reload(final File customSoundsFolder) {
58-
SOUND_LOCATIONS.clear();
60+
ALL_SOUND_LOCATIONS.clear();
5961
for (Map.Entry<Instrument, String> entry : INSTRUMENT_SOUNDS.entrySet()) {
60-
SOUND_LOCATIONS.put(entry.getValue(), SoundMap.class.getResource("/noteblock_sounds/" + entry.getValue()));
62+
ALL_SOUND_LOCATIONS.put(entry.getValue(), SoundMap.class.getResource("/noteblock_sounds/" + entry.getValue()));
6163
}
6264

6365
if (customSoundsFolder != null && customSoundsFolder.exists() && customSoundsFolder.isDirectory()) {
@@ -68,7 +70,7 @@ public static void reload(final File customSoundsFolder) {
6870

6971
final String fileName = customSoundsFolder.toPath().relativize(path).toString();
7072
if (fileName.endsWith(".ogg") || fileName.endsWith(".wav")) {
71-
SOUND_LOCATIONS.put(fileName.replace(File.separatorChar, '/'), path.toUri().toURL());
73+
ALL_SOUND_LOCATIONS.put(fileName.replace(File.separatorChar, '/'), path.toUri().toURL());
7274
}
7375
} catch (Throwable e) {
7476
throw new RuntimeException("Error while loading custom sound sample", e);
@@ -80,13 +82,22 @@ public static void reload(final File customSoundsFolder) {
8082
}
8183
}
8284

83-
public static Map<String, int[]> loadInstrumentSamples(final AudioFormat targetFormat) {
85+
public static Map<String, byte[]> loadSoundData(final SongView<?> songView) {
8486
try {
85-
final Map<String, int[]> soundSamples = new HashMap<>();
86-
for (Map.Entry<String, URL> entry : SOUND_LOCATIONS.entrySet()) {
87-
soundSamples.put(entry.getKey(), SoundSampleUtil.readSamples(entry.getValue().openStream(), targetFormat));
87+
final Map<String, byte[]> soundData = new HashMap<>();
88+
for (Instrument instrument : SongUtil.getUsedVanillaInstruments(songView)) {
89+
final String sound = INSTRUMENT_SOUNDS.get(instrument);
90+
if (sound != null && ALL_SOUND_LOCATIONS.containsKey(sound)) {
91+
soundData.put(sound, IOUtil.readFully(ALL_SOUND_LOCATIONS.get(sound).openStream()));
92+
}
8893
}
89-
return soundSamples;
94+
for (NbsCustomInstrument customInstrument : SongUtil.getUsedCustomInstruments(songView)) {
95+
final String fileName = customInstrument.getSoundFileName().replace(File.separatorChar, '/');
96+
if (ALL_SOUND_LOCATIONS.containsKey(fileName)) {
97+
soundData.put(fileName, IOUtil.readFully(ALL_SOUND_LOCATIONS.get(fileName).openStream()));
98+
}
99+
}
100+
return soundData;
90101
} catch (Throwable e) {
91102
throw new RuntimeException("Failed to load sound samples", e);
92103
}

src/main/java/net/raphimc/noteblocktool/audio/export/impl/JavaxAudioExporter.java

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
import net.raphimc.noteblocktool.util.SoundSampleUtil;
2525

2626
import javax.sound.sampled.AudioFormat;
27+
import java.io.ByteArrayInputStream;
28+
import java.util.HashMap;
2729
import java.util.Map;
2830
import java.util.function.Consumer;
2931

@@ -34,8 +36,15 @@ public class JavaxAudioExporter extends AudioExporter {
3436

3537
public JavaxAudioExporter(final SongView<?> songView, final AudioFormat format, final float masterVolume, final Consumer<Float> progressConsumer) {
3638
super(songView, format, masterVolume, progressConsumer);
37-
this.sounds = SoundMap.loadInstrumentSamples(format);
38-
this.merger = new AudioBuffer(this.samplesPerTick * format.getChannels() * songView.getLength());
39+
try {
40+
this.sounds = new HashMap<>();
41+
for (Map.Entry<String, byte[]> entry : SoundMap.loadSoundData(songView).entrySet()) {
42+
this.sounds.put(entry.getKey(), SoundSampleUtil.readSamples(new ByteArrayInputStream(entry.getValue()), format));
43+
}
44+
this.merger = new AudioBuffer(this.samplesPerTick * format.getChannels() * songView.getLength());
45+
} catch (Throwable e) {
46+
throw new RuntimeException("Failed to initialize javax audio exporter", e);
47+
}
3948
}
4049

4150
@Override

src/main/java/net/raphimc/noteblocktool/audio/export/impl/OpenALAudioExporter.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package net.raphimc.noteblocktool.audio.export.impl;
1919

2020
import net.raphimc.noteblocklib.model.SongView;
21+
import net.raphimc.noteblocktool.audio.SoundMap;
2122
import net.raphimc.noteblocktool.audio.export.AudioExporter;
2223
import net.raphimc.noteblocktool.audio.soundsystem.impl.OpenALSoundSystem;
2324

@@ -28,9 +29,9 @@ public class OpenALAudioExporter extends AudioExporter {
2829

2930
private final OpenALSoundSystem soundSystem;
3031

31-
public OpenALAudioExporter(final OpenALSoundSystem soundSystem, final SongView<?> songView, final AudioFormat format, final float masterVolume, final Consumer<Float> progressConsumer) {
32+
public OpenALAudioExporter(final SongView<?> songView, final AudioFormat format, final float masterVolume, final Consumer<Float> progressConsumer) {
3233
super(songView, format, masterVolume, progressConsumer);
33-
this.soundSystem = soundSystem;
34+
this.soundSystem = OpenALSoundSystem.createCapture(SoundMap.loadSoundData(songView), 8192, format);
3435
}
3536

3637
@Override
@@ -51,7 +52,7 @@ protected void postTick() {
5152

5253
@Override
5354
protected void finish() {
54-
this.soundSystem.stopSounds();
55+
this.soundSystem.close();
5556
}
5657

5758
}

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

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
package net.raphimc.noteblocktool.audio.soundsystem.impl;
1919

2020
import com.sun.jna.ptr.FloatByReference;
21-
import net.raphimc.noteblocktool.audio.SoundMap;
2221
import net.raphimc.noteblocktool.audio.soundsystem.BassLibrary;
2322
import net.raphimc.noteblocktool.audio.soundsystem.SoundSystem;
2423
import net.raphimc.noteblocktool.util.IOUtil;
@@ -27,8 +26,7 @@
2726
import javax.sound.sampled.AudioFormat;
2827
import javax.sound.sampled.AudioInputStream;
2928
import javax.sound.sampled.AudioSystem;
30-
import java.io.InputStream;
31-
import java.net.URL;
29+
import java.io.ByteArrayInputStream;
3230
import java.util.ArrayList;
3331
import java.util.HashMap;
3432
import java.util.List;
@@ -38,14 +36,14 @@ public class BassSoundSystem extends SoundSystem {
3836

3937
private static BassSoundSystem instance;
4038

41-
public static BassSoundSystem createPlayback(final int maxSounds) {
39+
public static BassSoundSystem createPlayback(final Map<String, byte[]> soundData, final int maxSounds) {
4240
if (instance != null) {
4341
throw new IllegalStateException("BASS sound system already initialized");
4442
}
4543
if (!BassLibrary.isLoaded()) {
4644
throw new IllegalStateException("BASS library is not available");
4745
}
48-
instance = new BassSoundSystem(maxSounds);
46+
instance = new BassSoundSystem(soundData, maxSounds);
4947
return instance;
5048
}
5149

@@ -61,7 +59,7 @@ public static BassSoundSystem createPlayback(final int maxSounds) {
6159
}
6260
};
6361

64-
private BassSoundSystem(final int maxSounds) {
62+
private BassSoundSystem(final Map<String, byte[]> soundData, final int maxSounds) {
6563
super(maxSounds);
6664

6765
final int version = BassLibrary.INSTANCE.BASS_GetVersion();
@@ -80,8 +78,8 @@ private BassSoundSystem(final int maxSounds) {
8078
}
8179

8280
try {
83-
for (Map.Entry<String, URL> entry : SoundMap.SOUND_LOCATIONS.entrySet()) {
84-
this.soundSamples.put(entry.getKey(), this.loadAudioFile(entry.getValue().openStream()));
81+
for (Map.Entry<String, byte[]> entry : soundData.entrySet()) {
82+
this.soundSamples.put(entry.getKey(), this.loadAudioFile(entry.getValue()));
8583
}
8684
} catch (Throwable e) {
8785
throw new RuntimeException("Failed to load sound samples", e);
@@ -170,9 +168,9 @@ public synchronized void setMasterVolume(final float volume) {
170168
}
171169
}
172170

173-
private int loadAudioFile(final InputStream inputStream) {
171+
private int loadAudioFile(final byte[] data) {
174172
try {
175-
AudioInputStream audioInputStream = SoundSampleUtil.readAudioFile(inputStream);
173+
AudioInputStream audioInputStream = SoundSampleUtil.readAudioFile(new ByteArrayInputStream(data));
176174
final AudioFormat audioFormat = audioInputStream.getFormat();
177175
final AudioFormat targetFormat = new AudioFormat(audioFormat.getSampleRate(), 16, audioFormat.getChannels(), true, false);
178176
if (!audioFormat.matches(targetFormat)) audioInputStream = AudioSystem.getAudioInputStream(targetFormat, audioInputStream);

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,18 +17,15 @@
1717
*/
1818
package net.raphimc.noteblocktool.audio.soundsystem.impl;
1919

20-
import net.raphimc.noteblocktool.audio.SoundMap;
2120
import net.raphimc.noteblocktool.audio.soundsystem.SoundSystem;
2221
import net.raphimc.noteblocktool.util.CircularBuffer;
2322
import net.raphimc.noteblocktool.util.SoundSampleUtil;
2423

2524
import javax.sound.sampled.AudioFormat;
2625
import javax.sound.sampled.AudioSystem;
2726
import javax.sound.sampled.SourceDataLine;
28-
import java.util.ArrayList;
29-
import java.util.Arrays;
30-
import java.util.List;
31-
import java.util.Map;
27+
import java.io.ByteArrayInputStream;
28+
import java.util.*;
3229

3330
public class JavaxSoundSystem extends SoundSystem {
3431

@@ -42,11 +39,14 @@ public class JavaxSoundSystem extends SoundSystem {
4239
protected float[] volumeDividers;
4340
private final int volumeDividersLength;
4441

45-
public JavaxSoundSystem(final int maxSounds, final float playbackSpeed) {
42+
public JavaxSoundSystem(final Map<String, byte[]> soundData, final int maxSounds, final float playbackSpeed) {
4643
super(maxSounds);
4744

4845
try {
49-
this.sounds = SoundMap.loadInstrumentSamples(FORMAT);
46+
this.sounds = new HashMap<>();
47+
for (Map.Entry<String, byte[]> entry : soundData.entrySet()) {
48+
this.sounds.put(entry.getKey(), SoundSampleUtil.readSamples(new ByteArrayInputStream(entry.getValue()), FORMAT));
49+
}
5050
this.samplesPerTick = (int) (FORMAT.getSampleRate() / playbackSpeed) * FORMAT.getChannels();
5151
this.dataLine = AudioSystem.getSourceDataLine(FORMAT);
5252
this.dataLine.open(FORMAT, (int) FORMAT.getSampleRate());

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package net.raphimc.noteblocktool.audio.soundsystem.impl;
1919

2020
import java.util.Arrays;
21+
import java.util.Map;
2122
import java.util.Queue;
2223
import java.util.concurrent.ConcurrentLinkedQueue;
2324
import java.util.concurrent.Executors;
@@ -34,8 +35,8 @@ public class MultithreadedJavaxSoundSystem extends JavaxSoundSystem {
3435
private final int[][] threadOutputBuffers;
3536
private final int[][] threadMutationBuffers;
3637

37-
public MultithreadedJavaxSoundSystem(final int maxSounds, final float playbackSpeed) {
38-
super(maxSounds, playbackSpeed);
38+
public MultithreadedJavaxSoundSystem(final Map<String, byte[]> soundData, final int maxSounds, final float playbackSpeed) {
39+
super(soundData, maxSounds, playbackSpeed);
3940

4041
final int mergingThreads = Math.max(1, this.threadPool.getCorePoolSize() / 3);
4142
final int renderingThreads = this.threadPool.getCorePoolSize() - mergingThreads;

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

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
*/
1818
package net.raphimc.noteblocktool.audio.soundsystem.impl;
1919

20-
import net.raphimc.noteblocktool.audio.SoundMap;
2120
import net.raphimc.noteblocktool.audio.soundsystem.SoundSystem;
2221
import net.raphimc.noteblocktool.util.IOUtil;
2322
import net.raphimc.noteblocktool.util.SampleOutputStream;
@@ -27,8 +26,7 @@
2726

2827
import javax.sound.sampled.AudioFormat;
2928
import javax.sound.sampled.AudioInputStream;
30-
import java.io.InputStream;
31-
import java.net.URL;
29+
import java.io.ByteArrayInputStream;
3230
import java.nio.ByteBuffer;
3331
import java.util.ArrayList;
3432
import java.util.HashMap;
@@ -39,19 +37,19 @@ public class OpenALSoundSystem extends SoundSystem {
3937

4038
private static OpenALSoundSystem instance;
4139

42-
public static OpenALSoundSystem createPlayback(final int maxSounds) {
40+
public static OpenALSoundSystem createPlayback(final Map<String, byte[]> soundData, final int maxSounds) {
4341
if (instance != null) {
4442
throw new IllegalStateException("OpenAL sound system already initialized");
4543
}
46-
instance = new OpenALSoundSystem(maxSounds);
44+
instance = new OpenALSoundSystem(soundData, maxSounds);
4745
return instance;
4846
}
4947

50-
public static OpenALSoundSystem createCapture(final int maxSounds, final AudioFormat captureAudioFormat) {
48+
public static OpenALSoundSystem createCapture(final Map<String, byte[]> soundData, final int maxSounds, final AudioFormat captureAudioFormat) {
5149
if (instance != null) {
5250
throw new IllegalStateException("OpenAL sound system already initialized");
5351
}
54-
instance = new OpenALSoundSystem(maxSounds, captureAudioFormat);
52+
instance = new OpenALSoundSystem(soundData, maxSounds, captureAudioFormat);
5553
return instance;
5654
}
5755

@@ -64,11 +62,11 @@ public static OpenALSoundSystem createCapture(final int maxSounds, final AudioFo
6462
private Thread shutdownHook;
6563
private ByteBuffer captureBuffer;
6664

67-
private OpenALSoundSystem(final int maxSounds) {
68-
this(maxSounds, null);
65+
private OpenALSoundSystem(final Map<String, byte[]> soundData, final int maxSounds) {
66+
this(soundData, maxSounds, null);
6967
}
7068

71-
private OpenALSoundSystem(final int maxSounds, final AudioFormat captureAudioFormat) {
69+
private OpenALSoundSystem(final Map<String, byte[]> soundData, final int maxSounds, final AudioFormat captureAudioFormat) {
7270
super(maxSounds);
7371

7472
this.captureAudioFormat = captureAudioFormat;
@@ -128,8 +126,8 @@ private OpenALSoundSystem(final int maxSounds, final AudioFormat captureAudioFor
128126
this.checkALError("Failed to set listener orientation");
129127

130128
try {
131-
for (Map.Entry<String, URL> entry : SoundMap.SOUND_LOCATIONS.entrySet()) {
132-
this.soundBuffers.put(entry.getKey(), this.loadAudioFile(entry.getValue().openStream()));
129+
for (Map.Entry<String, byte[]> entry : soundData.entrySet()) {
130+
this.soundBuffers.put(entry.getKey(), this.loadAudioFile(entry.getValue()));
133131
}
134132
} catch (Throwable e) {
135133
throw new RuntimeException("Failed to load sound samples", e);
@@ -251,9 +249,9 @@ public synchronized void setMasterVolume(final float volume) {
251249
this.checkALError("Failed to set listener gain");
252250
}
253251

254-
private int loadAudioFile(final InputStream inputStream) {
252+
private int loadAudioFile(final byte[] data) {
255253
try {
256-
final AudioInputStream audioInputStream = SoundSampleUtil.readAudioFile(inputStream);
254+
final AudioInputStream audioInputStream = SoundSampleUtil.readAudioFile(new ByteArrayInputStream(data));
257255
final AudioFormat audioFormat = audioInputStream.getFormat();
258256
final byte[] audioBytes = IOUtil.readFully(audioInputStream);
259257

0 commit comments

Comments
 (0)