From 58ecb109c45ecaf9c16dd808f60a485dfaad224b Mon Sep 17 00:00:00 2001 From: RaphiMC <50594595+RaphiMC@users.noreply.github.com> Date: Mon, 17 Jun 2024 01:24:27 +0200 Subject: [PATCH] Added 3 second trailer to exported songs --- .../{AudioMerger.java => AudioBuffer.java} | 27 ++++++++++--------- .../audio/export/AudioExporter.java | 6 +++++ .../audio/export/impl/JavaxAudioExporter.java | 10 +++---- .../noteblocktool/frames/ExportFrame.java | 2 +- 4 files changed, 27 insertions(+), 18 deletions(-) rename src/main/java/net/raphimc/noteblocktool/audio/export/{AudioMerger.java => AudioBuffer.java} (74%) diff --git a/src/main/java/net/raphimc/noteblocktool/audio/export/AudioMerger.java b/src/main/java/net/raphimc/noteblocktool/audio/export/AudioBuffer.java similarity index 74% rename from src/main/java/net/raphimc/noteblocktool/audio/export/AudioMerger.java rename to src/main/java/net/raphimc/noteblocktool/audio/export/AudioBuffer.java index 59b8250..3ebb59d 100644 --- a/src/main/java/net/raphimc/noteblocktool/audio/export/AudioMerger.java +++ b/src/main/java/net/raphimc/noteblocktool/audio/export/AudioBuffer.java @@ -19,25 +19,28 @@ import net.raphimc.noteblocktool.util.SoundSampleUtil; -public class AudioMerger { +public class AudioBuffer { - private final long[] samples; + private long[] samples; private int sampleIndex; - public AudioMerger(final int sampleCount) { - this.samples = new long[sampleCount]; + public AudioBuffer(final int initialSize) { + this.samples = new long[initialSize]; } - public void addSamples(final int[] samples) { + public void pushSamples(final int[] samples) { + if (this.sampleIndex + samples.length >= this.samples.length) { + final long[] newSamples = new long[this.sampleIndex + samples.length]; + System.arraycopy(this.samples, 0, newSamples, 0, this.samples.length); + this.samples = newSamples; + } + for (int i = 0; i < samples.length; i++) { - final int index = this.sampleIndex + i; - if (index >= this.samples.length) break; - final int sample = samples[i]; - this.samples[index] += sample; + this.samples[this.sampleIndex + i] += samples[i]; } } - public void pushSamples(final int samples) { + public void advanceIndex(final int samples) { this.sampleIndex += samples; } @@ -69,8 +72,8 @@ public int[] normalizeInts() { } private void normalize(final long maxValue) { - long max = SoundSampleUtil.getMax(this.samples); - float factor = (float) maxValue / max; + final long max = SoundSampleUtil.getMax(this.samples); + final float factor = (float) maxValue / max; for (int i = 0; i < this.samples.length; i++) { this.samples[i] = (long) (this.samples[i] * factor); } diff --git a/src/main/java/net/raphimc/noteblocktool/audio/export/AudioExporter.java b/src/main/java/net/raphimc/noteblocktool/audio/export/AudioExporter.java index 74ef3cd..427f81f 100644 --- a/src/main/java/net/raphimc/noteblocktool/audio/export/AudioExporter.java +++ b/src/main/java/net/raphimc/noteblocktool/audio/export/AudioExporter.java @@ -69,6 +69,12 @@ public void render() throws InterruptedException { this.progressConsumer.accept((float) this.processedNotes / this.noteCount); if (Thread.currentThread().isInterrupted()) throw new InterruptedException(); } + + final int threeSeconds = Math.round(this.songView.getSpeed() * 3); + for (int i = 0; i < threeSeconds; i++) { + this.writeSamples(); + } + this.finish(); } diff --git a/src/main/java/net/raphimc/noteblocktool/audio/export/impl/JavaxAudioExporter.java b/src/main/java/net/raphimc/noteblocktool/audio/export/impl/JavaxAudioExporter.java index 3b1d113..70ba3a6 100644 --- a/src/main/java/net/raphimc/noteblocktool/audio/export/impl/JavaxAudioExporter.java +++ b/src/main/java/net/raphimc/noteblocktool/audio/export/impl/JavaxAudioExporter.java @@ -19,8 +19,8 @@ import net.raphimc.noteblocklib.model.SongView; import net.raphimc.noteblocktool.audio.SoundMap; +import net.raphimc.noteblocktool.audio.export.AudioBuffer; import net.raphimc.noteblocktool.audio.export.AudioExporter; -import net.raphimc.noteblocktool.audio.export.AudioMerger; import net.raphimc.noteblocktool.util.SoundSampleUtil; import javax.sound.sampled.AudioFormat; @@ -30,24 +30,24 @@ public class JavaxAudioExporter extends AudioExporter { private final Map sounds; - private final AudioMerger merger; + private final AudioBuffer merger; public JavaxAudioExporter(final SongView songView, final AudioFormat format, final Consumer progressConsumer) { super(songView, format, progressConsumer); this.sounds = SoundMap.loadInstrumentSamples(format); - this.merger = new AudioMerger(this.samplesPerTick * format.getChannels() * songView.getLength()); + this.merger = new AudioBuffer(this.samplesPerTick * format.getChannels() * songView.getLength()); } @Override protected void processSound(final String sound, final float pitch, final float volume, final float panning) { if (!this.sounds.containsKey(sound)) return; - this.merger.addSamples(SoundSampleUtil.mutate(this.format, this.sounds.get(sound), pitch, volume, panning)); + this.merger.pushSamples(SoundSampleUtil.mutate(this.format, this.sounds.get(sound), pitch, volume, panning)); } @Override protected void writeSamples() { - this.merger.pushSamples(this.samplesPerTick * this.format.getChannels()); + this.merger.advanceIndex(this.samplesPerTick * this.format.getChannels()); } @Override diff --git a/src/main/java/net/raphimc/noteblocktool/frames/ExportFrame.java b/src/main/java/net/raphimc/noteblocktool/frames/ExportFrame.java index ec528e6..dedac30 100644 --- a/src/main/java/net/raphimc/noteblocktool/frames/ExportFrame.java +++ b/src/main/java/net/raphimc/noteblocktool/frames/ExportFrame.java @@ -59,7 +59,7 @@ public class ExportFrame extends JFrame { private final List loadedSongs; private final JComboBox format = new JComboBox<>(new String[]{"NBS", "WAV", "AIF"}); private final JLabel soundSystemLabel = new JLabel("Sound System:"); - private final JComboBox soundSystem = new JComboBox<>(new String[]{"OpenAL (better sound quality)", "Javax (multithreaded, normalized)"}); + private final JComboBox soundSystem = new JComboBox<>(new String[]{"OpenAL (better sound quality)", "Javax (parallel capable, normalized)"}); private final JLabel sampleRateLabel = new JLabel("Sample Rate:"); private final JSpinner sampleRate = new JSpinner(new SpinnerNumberModel(44_100, 8_000, 192_000, 1_000)); private final JLabel bitDepthLabel = new JLabel("PCM Bit Depth:");