Audio transfer code marked up

This commit is contained in:
Alex Iadicicco 2022-12-09 20:47:05 -08:00 committed by Alexis King
parent e8b1a1ede9
commit 2c8eb3d550
18 changed files with 1699 additions and 1631 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,30 @@
package funorb.audio;
import funorb.data.NodeList;
public abstract class AudioSource extends NodeList.Node implements Iterable<AudioSource> {
public volatile boolean enabled = true;
public int lastP8_idk;
public AudioSource nextSource_idk;
public RawSampleS8 rawSample;
protected AudioSource() {}
public abstract void processAndWrite(int[] dataS16P8, int offset, int len);
public abstract void processAndDiscard(int len);
protected final void processAndWriteIfEnabled(final int[] dataS16P8, final int offset, final int len) {
if (this.enabled) {
this.processAndWrite(dataS16P8, offset, len);
} else {
this.processAndDiscard(len);
}
}
public abstract int returns_0_1_or_2();
public int someP8_idk() {
return 255;
}
}

View File

@ -1,38 +0,0 @@
package funorb.audio;
import funorb.data.NodeList;
import org.jetbrains.annotations.NotNull;
import java.util.Iterator;
public final class AudioSourceSum_idk extends AudioSource_idk {
private final NodeList<AudioSource_idk> inner = new NodeList<>();
@Override
public @NotNull Iterator<AudioSource_idk> iterator() {
return this.inner.iterator();
}
@Override
public int a784() {
return 0;
}
@Override
public synchronized void processAndDiscard(final int len) {
for (final AudioSource_idk gen : this.inner) {
gen.processAndDiscard(len);
}
}
public synchronized void addFirst(final AudioSamplePlayback_idk var1) {
this.inner.addFirst(var1);
}
@Override
public synchronized void processAndWrite(final int[] dest, final int offset, final int len) {
for (final AudioSource_idk gen : this.inner) {
gen.processAndWriteIfEnabled(dest, offset, len);
}
}
}

View File

@ -1,30 +0,0 @@
package funorb.audio;
import funorb.data.NodeList;
public abstract class AudioSource_idk extends NodeList.Node implements Iterable<AudioSource_idk> {
public volatile boolean enabled = true;
public int _i;
public AudioSource_idk _h;
public RawSampleS8 sampleData;
protected AudioSource_idk() {}
public abstract void processAndWrite(int[] dest, int offset, int len);
public abstract void processAndDiscard(int len);
protected final void processAndWriteIfEnabled(final int[] dest, final int offset, final int len) {
if (this.enabled) {
this.processAndWrite(dest, offset, len);
} else {
this.processAndDiscard(len);
}
}
public abstract int a784();
public int c784() {
return 255;
}
}

View File

@ -7,7 +7,7 @@ public final class AudioThread implements Runnable {
public static final int NUM_CHANNELS = 2;
public static AudioThread instance;
public final SampledAudioChannel[] channels = new SampledAudioChannel[NUM_CHANNELS];
public final SampledAudioChannelS16[] channels = new SampledAudioChannelS16[NUM_CHANNELS];
private final MessagePumpThread messagePumpThread;
public volatile boolean shutdownRequested = false;
public volatile boolean isRunning = false;
@ -22,7 +22,7 @@ public final class AudioThread implements Runnable {
try {
while (!this.shutdownRequested) {
for (int i = 0; i < NUM_CHANNELS; ++i) {
final SampledAudioChannel channel = this.channels[i];
final SampledAudioChannelS16 channel = this.channels[i];
if (channel != null) {
channel.doSomethingThatSeemsRelatedToAudio();
}

View File

@ -10,7 +10,7 @@ import java.util.Map;
// "play time" has units of tick-microseconds per quarter note, i.e. it has an extra factor of ticks per
// quarter note in it, which is constant for any given song
public final class MidiPlayer extends AudioSource_idk {
public final class MidiPlayer extends AudioSource {
private static final double PHASE_512_TO_RADIANS = 0.01227184630308513D;
public static final int FLAG_SUSTAIN = 0x0001;
@ -74,8 +74,8 @@ public final class MidiPlayer extends AudioSource_idk {
}
@Override
public @NotNull Iterator<AudioSource_idk> iterator() {
return Collections.<AudioSource_idk>singletonList(this.noteSet).iterator();
public @NotNull Iterator<AudioSource> iterator() {
return Collections.<AudioSource>singletonList(this.noteSet).iterator();
}
private void handleGeneral2(final int value, final int channel) {
@ -100,7 +100,7 @@ public final class MidiPlayer extends AudioSource_idk {
var3 += (int) ((double) pitch * vibrato);
}
pitch = (int) ((double) (256 * note.sampleData.sampleRate) * Math.pow(2.0D, 3.255208333333333E-4D * (double) var3) / (double) SampledAudioChannel.SAMPLES_PER_SECOND + 0.5D);
pitch = (int) ((double) (256 * note.sampleData.sampleRate) * Math.pow(2.0D, 3.255208333333333E-4D * (double) var3) / (double) SampledAudioChannelS16.SAMPLE_RATE + 0.5D);
return Math.max(pitch, 1);
}
@ -170,9 +170,9 @@ public final class MidiPlayer extends AudioSource_idk {
}
@Override
public synchronized void processAndWrite(final int[] dest, int offset, int len) {
public synchronized void processAndWrite(final int[] dataS16P8, int offset, int len) {
if (this.midiReader.isLoaded()) {
final int var4 = this.midiReader.ticksPerQuarterNote * this.microsecondsPerSecond / SampledAudioChannel.SAMPLES_PER_SECOND;
final int var4 = this.midiReader.ticksPerQuarterNote * this.microsecondsPerSecond / SampledAudioChannelS16.SAMPLE_RATE;
do {
final long var5 = this.lastBufferPlayTime + (long) len * (long) var4;
@ -183,20 +183,20 @@ public final class MidiPlayer extends AudioSource_idk {
final int var7 = (int) ((-this.lastBufferPlayTime + (this.currentPlayTime - (-((long) var4) + 1L))) / (long) var4);
this.lastBufferPlayTime += (long) var7 * (long) var4;
this.noteSet.processAndWrite(dest, offset, var7);
this.noteSet.processAndWrite(dataS16P8, offset, var7);
offset += var7;
len -= var7;
this.pumpEvents();
} while (this.midiReader.isLoaded());
}
this.noteSet.processAndWrite(dest, offset, len);
this.noteSet.processAndWrite(dataS16P8, offset, len);
}
@Override
public synchronized void processAndDiscard(int len) {
if (this.midiReader.isLoaded()) {
final int samplesToPlayTime = this.midiReader.ticksPerQuarterNote * this.microsecondsPerSecond / SampledAudioChannel.SAMPLES_PER_SECOND;
final int samplesToPlayTime = this.midiReader.ticksPerQuarterNote * this.microsecondsPerSecond / SampledAudioChannelS16.SAMPLE_RATE;
do {
final long bufferPlayTime = (long) len * (long) samplesToPlayTime + this.lastBufferPlayTime;
@ -231,7 +231,7 @@ public final class MidiPlayer extends AudioSource_idk {
for (final MidiPlayerNoteState_idk note : this.noteSet.notes) {
if (channel < 0 || channel == note.channel) {
if (note.playback != null) {
note.playback.g150(SampledAudioChannel.SAMPLES_PER_SECOND / 100);
note.playback.g150(SampledAudioChannelS16.SAMPLE_RATE / 100);
if (note.playback.volDeltaNonZero()) {
this.noteSet.sum.addFirst(note.playback);
}
@ -490,7 +490,7 @@ public final class MidiPlayer extends AudioSource_idk {
}
@Override
public synchronized int a784() {
public synchronized int returns_0_1_or_2() {
return 0;
}
@ -561,9 +561,9 @@ public final class MidiPlayer extends AudioSource_idk {
note._h = 0;
note._v = 0;
if (this.chGeneral1[channel] == 0) {
note.playback = AudioSamplePlayback_idk.start(sample, this.calcPitchX_idk(note), this.calcVolumeX_idk(note), this.calcPanX_idk(note));
note.playback = RawSamplePlayer.start(sample, this.calcPitchX_idk(note), this.calcVolumeX_idk(note), this.calcPanX_idk(note));
} else {
note.playback = AudioSamplePlayback_idk.start(sample, this.calcPitchX_idk(note), 0, this.calcPanX_idk(note));
note.playback = RawSamplePlayer.start(sample, this.calcPitchX_idk(note), 0, this.calcPanX_idk(note));
this.a559(note, instrument.noteTuning_idk[noteNumber] < 0);
}
@ -590,7 +590,7 @@ public final class MidiPlayer extends AudioSource_idk {
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
public boolean a543(final int var1, final int[] var2, final MidiPlayerNoteState_idk var4, final int var5) {
var4._p = SampledAudioChannel.SAMPLES_PER_SECOND / 100;
var4._p = SampledAudioChannelS16.SAMPLE_RATE / 100;
if (var4.notePlaying_idfk < 0 || var4.playback != null && !var4.playback.isPlayheadOutOfBounds()) {
int var6 = var4._pitch_fac_2;
if (var6 > 0) {
@ -602,7 +602,7 @@ public final class MidiPlayer extends AudioSource_idk {
var4._pitch_fac_2 = var6;
}
var4.playback.d150(this.calcPitchX_idk(var4));
var4.playback.setPitchX(this.calcPitchX_idk(var4));
final KeyParams_idk var7 = var4.keyParams_idk;
var4.vibratoPhase_idk += var7.vibratoPhaseSpeed_idk;
++var4._C;
@ -767,7 +767,7 @@ public final class MidiPlayer extends AudioSource_idk {
public void a559(final MidiPlayerNoteState_idk note, final boolean var3) {
int sampleLength = note.sampleData.data.length;
int sampleLength = note.sampleData.data_s8.length;
int playhead;
if (var3 && note.sampleData.isLooped_idk) {
final int var6 = -note.sampleData.loopStart_idfk + sampleLength + sampleLength;
@ -781,7 +781,7 @@ public final class MidiPlayer extends AudioSource_idk {
playhead = (int) ((long) this.chGeneral1[note.channel] * (long) sampleLength >> 6);
}
note.playback.setPlayhead(playhead);
note.playback.setPlayhead_p8(playhead);
}
private int calcVolumeX_idk(final MidiPlayerNoteState_idk note) {

View File

@ -6,9 +6,9 @@ import org.jetbrains.annotations.NotNull;
import java.util.Iterator;
import java.util.Objects;
public final class MidiPlayerNoteSet_idk extends AudioSource_idk {
public final class MidiPlayerNoteSet_idk extends AudioSource {
public final NodeList<MidiPlayerNoteState_idk> notes = new NodeList<>();
public final AudioSourceSum_idk sum = new AudioSourceSum_idk();
public final SoundManager sum = new SoundManager();
private final MidiPlayer midiPlayer;
public MidiPlayerNoteSet_idk(final MidiPlayer midiPlayer) {
@ -16,12 +16,12 @@ public final class MidiPlayerNoteSet_idk extends AudioSource_idk {
}
@Override
public @NotNull Iterator<AudioSource_idk> iterator() {
return this.notes.stream().<AudioSource_idk>map(var1 -> var1.playback).filter(Objects::nonNull).iterator();
public @NotNull Iterator<AudioSource> iterator() {
return this.notes.stream().<AudioSource>map(var1 -> var1.playback).filter(Objects::nonNull).iterator();
}
@Override
public int a784() {
public int returns_0_1_or_2() {
return 0;
}
@ -49,8 +49,8 @@ public final class MidiPlayerNoteSet_idk extends AudioSource_idk {
}
@Override
public void processAndWrite(final int[] dest, final int offset, final int len) {
this.sum.processAndWrite(dest, offset, len);
public void processAndWrite(final int[] dataS16P8, final int offset, final int len) {
this.sum.processAndWrite(dataS16P8, offset, len);
for (final MidiPlayerNoteState_idk note : this.notes) {
if (!this.midiPlayer.a258(note)) {
@ -59,15 +59,15 @@ public final class MidiPlayerNoteSet_idk extends AudioSource_idk {
do {
if (note._p >= var5) {
this.a829(dest, var4, note, var5, var4 + var5);
this.a829(dataS16P8, var4, note, var5, var4 + var5);
note._p -= var5;
break;
}
this.a829(dest, var4, note, note._p, var4 + var5);
this.a829(dataS16P8, var4, note, note._p, var4 + var5);
var5 -= note._p;
var4 += note._p;
} while (!this.midiPlayer.a543(var4, dest, note, var5));
} while (!this.midiPlayer.a543(var4, dataS16P8, note, var5));
}
}
@ -75,14 +75,14 @@ public final class MidiPlayerNoteSet_idk extends AudioSource_idk {
private void a222(final MidiPlayerNoteState_idk note, int totalLen) {
if ((MidiPlayer.FLAG_GENERAL_6 & this.midiPlayer.chFlags[note.channel]) != 0 && note.notePlaying_idfk < 0) {
final int var4 = this.midiPlayer._u[note.channel] / SampledAudioChannel.SAMPLES_PER_SECOND;
final int var4 = this.midiPlayer._u[note.channel] / SampledAudioChannelS16.SAMPLE_RATE;
final int var5 = (1048575 + var4 - note._j) / var4;
note._j = 1048575 & note._j + totalLen * var4;
if (var5 <= totalLen) {
if (this.midiPlayer.chGeneral1[note.channel] == 0) {
note.playback = AudioSamplePlayback_idk.start(note.sampleData, note.playback.getPitchX(), note.playback.getVolX(), note.playback.getPanX());
note.playback = RawSamplePlayer.start(note.sampleData, note.playback.getPitchX(), note.playback.getVol_p14(), note.playback.getPan_p14());
} else {
note.playback = AudioSamplePlayback_idk.start(note.sampleData, note.playback.getPitchX(), 0, note.playback.getPanX());
note.playback = RawSamplePlayer.start(note.sampleData, note.playback.getPitchX(), 0, note.playback.getPan_p14());
this.midiPlayer.a559(note, note.instrument.noteTuning_idk[note.note] < 0);
}
@ -101,7 +101,7 @@ public final class MidiPlayerNoteSet_idk extends AudioSource_idk {
private void a829(final int[] dest, int offset, final MidiPlayerNoteState_idk note, int totalLen, final int var6) {
if ((MidiPlayer.FLAG_GENERAL_6 & this.midiPlayer.chFlags[note.channel]) != 0 && note.notePlaying_idfk < 0) {
final int var7 = this.midiPlayer._u[note.channel] / SampledAudioChannel.SAMPLES_PER_SECOND;
final int var7 = this.midiPlayer._u[note.channel] / SampledAudioChannelS16.SAMPLE_RATE;
while (true) {
final int len = (-note._j + 0xfffff + var7) / var7;
@ -114,19 +114,19 @@ public final class MidiPlayerNoteSet_idk extends AudioSource_idk {
note._j += len * var7 - 0x100000;
offset += len;
totalLen -= len;
int var9 = SampledAudioChannel.SAMPLES_PER_SECOND / 100;
int var9 = SampledAudioChannelS16.SAMPLE_RATE / 100;
final int var10 = 0x40000 / var7;
if (var10 < var9) {
var9 = var10;
}
final AudioSamplePlayback_idk playback = note.playback;
final RawSamplePlayer playback = note.playback;
if (this.midiPlayer.chGeneral1[note.channel] == 0) {
note.playback = AudioSamplePlayback_idk.start(note.sampleData, playback.getPitchX(), playback.getVolX(), playback.getPanX());
note.playback = RawSamplePlayer.start(note.sampleData, playback.getPitchX(), playback.getVol_p14(), playback.getPan_p14());
} else {
note.playback = AudioSamplePlayback_idk.start(note.sampleData, playback.getPitchX(), 0, playback.getPanX());
note.playback = RawSamplePlayer.start(note.sampleData, playback.getPitchX(), 0, playback.getPan_p14());
this.midiPlayer.a559(note, note.instrument.noteTuning_idk[note.note] < 0);
note.playback.a093(var9, playback.getVolX());
note.playback.a093(var9, playback.getVol_p14());
}
if (note.instrument.noteTuning_idk[note.note] < 0) {

View File

@ -11,7 +11,7 @@ public final class MidiPlayerNoteState_idk extends NodeList.Node {
public int note;
public RawSampleS8 sampleData;
public KeyParams_idk keyParams_idk;
public AudioSamplePlayback_idk playback;
public RawSamplePlayer playback;
public MidiInstrument instrument;
public int _j;
public int _pitch_fac_1;

View File

@ -6,7 +6,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
public final class h_ extends AudioSource_idk {
public final class MusicManager extends AudioSource {
public final MidiPlayer midiPlayer1;
public final MidiPlayer midiPlayer2;
private int[] midiBuffer2;
@ -18,7 +18,7 @@ public final class h_ extends AudioSource_idk {
private int volume = 256;
private boolean _C;
public h_() {
public MusicManager() {
final MidiPlayer midiPlayer = new MidiPlayer();
this.midiPlayer2 = midiPlayer;
this.midiPlayer1 = new MidiPlayer(midiPlayer);
@ -29,7 +29,7 @@ public final class h_ extends AudioSource_idk {
}
@Override
public void processAndWrite(final int[] dest, final int offset, final int len) {
public void processAndWrite(final int[] dataS16P8, final int offset, final int len) {
if (this.volume <= 0) {
this.processAndDiscard(len);
} else {
@ -75,9 +75,9 @@ public final class h_ extends AudioSource_idk {
final int lenSamples = len << 1;
if (this.song2 != null || this.song1 != null) {
if (midiAmp2 == 256) {
this.midiPlayer2.processAndWrite(dest, offset, len);
this.midiPlayer2.processAndWrite(dataS16P8, offset, len);
} else if (midiAmp1 == 256) {
this.midiPlayer1.processAndWrite(dest, offset, len);
this.midiPlayer1.processAndWrite(dataS16P8, offset, len);
} else {
if (this.midiBuffer2 != null && this.midiBuffer2.length >= lenSamples) {
Arrays.fill(this.midiBuffer2, 0, lenSamples, 0);
@ -92,7 +92,7 @@ public final class h_ extends AudioSource_idk {
final int offsetSamples = offset << 1;
for (int i = 0; i < lenSamples; ++i) {
dest[offsetSamples + i] += this.midiBuffer1[i] * midiAmp1 + this.midiBuffer2[i] * midiAmp2 >> 8;
dataS16P8[offsetSamples + i] += this.midiBuffer1[i] * midiAmp1 + this.midiBuffer2[i] * midiAmp2 >> 8;
}
}
}
@ -159,12 +159,12 @@ public final class h_ extends AudioSource_idk {
}
@Override
public synchronized int a784() {
public synchronized int returns_0_1_or_2() {
return 2;
}
@Override
public @NotNull Iterator<AudioSource_idk> iterator() {
public @NotNull Iterator<AudioSource> iterator() {
return Collections.emptyIterator();
}

View File

@ -3,12 +3,12 @@ package funorb.audio;
import funorb.shatteredplans.client.Sounds;
public final class PlayingSound {
public final AudioSamplePlayback_idk _p;
public final RawSamplePlayer _p;
public int volume;
public PlayingSound(final AudioSamplePlayback_idk var1) {
public PlayingSound(final RawSamplePlayer var1) {
this._p = var1;
this.volume = var1.getVolX();
this.volume = var1.getVol_p14();
this._p.setVolume((128 + (this.volume * Sounds.soundVolume)) >> 8);
}

File diff suppressed because it is too large Load Diff

View File

@ -4,12 +4,12 @@ public final class RawSampleS8 {
public final int loopEnd_idfk;
public final int loopStart_idfk;
public final int sampleRate;
public final byte[] data;
public final byte[] data_s8;
public final boolean isLooped_idk;
public int _h;
public int someCounter_idk;
public RawSampleS8(final byte[] data, final int loopStart, final int loopEnd) {
this(SampledAudioChannel.SAMPLES_PER_SECOND, data, loopStart, loopEnd, false);
this(SampledAudioChannelS16.SAMPLE_RATE, data, loopStart, loopEnd, false);
}
public RawSampleS8(
@ -20,7 +20,7 @@ public final class RawSampleS8 {
final boolean isLooped
) {
this.sampleRate = sampleRate;
this.data = data;
this.data_s8 = data;
this.loopStart_idfk = loopStart;
this.loopEnd_idfk = loopEnd;
this.isLooped_idk = isLooped;

View File

@ -1,345 +0,0 @@
package funorb.audio;
import funorb.client.JagexBaseApplet;
import funorb.util.BitMath;
import funorb.util.PseudoMonotonicClock;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine.Info;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import java.io.Closeable;
import java.util.Arrays;
public final class SampledAudioChannel implements Closeable {
public static final int SAMPLES_PER_SECOND = 22050;
private static final int BYTES_PER_CHANNEL_PER_WRITE = 512;
private final AudioFormat format = new AudioFormat(SAMPLES_PER_SECOND, 16, 2, true, false);
private final byte[] buffer = new byte[1024];
private final AudioSource_idk[] _o = new AudioSource_idk[8];
private final AudioSource_idk[] _s = new AudioSource_idk[8];
public int[] data;
public int _g;
public int _b;
private SourceDataLine line;
private int lineBufferSizeInInts;
private boolean isShutdown = false;
private long _m = PseudoMonotonicClock.currentTimeMillis();
private AudioSource_idk source;
private int _r = 0;
private int _l = 0;
private boolean _n = true;
private int _e = 0;
private int _a = 0;
private long _p = 0L;
private int _u;
private long _q = 0L;
private static int popcount(final int var1) {
final int var2 = (var1 & 0x55555555) + ((var1 >>> 1) & 0xd5555555);
final int var3 = (var2 & 0x33333333) + ((var2 & 0xcccccccc) >>> 2);
final int var4 = (var3 + (var3 >>> 4)) & 0xf0f0f0f;
final int var5 = var4 + (var4 >>> 8);
final int var6 = var5 + (var5 >>> 16);
return var6 & 255;
}
private static void b446(final AudioSource_idk var0) {
var0.enabled = false;
if (var0.sampleData != null) {
var0.sampleData._h = 0;
}
var0.forEach(SampledAudioChannel::b446);
}
@Override
public void close() {
if (this.line != null) {
this.line.close();
this.line = null;
}
}
private int bufferedInts() {
return this.lineBufferSizeInInts - (this.line.available() / 4);
}
private void performWrite() {
for (int i = 0; i < BYTES_PER_CHANNEL_PER_WRITE; ++i) {
int var3 = this.data[i];
if (((var3 + 0x80_00_00) & 0xff_00_00_00) != 0) {
var3 = 0x7fffff ^ (var3 >> 31);
}
this.buffer[i * 2] = (byte) (var3 >> 8);
this.buffer[i * 2 + 1] = (byte) (var3 >> 16);
}
this.line.write(this.buffer, 0, BYTES_PER_CHANNEL_PER_WRITE * 2);
}
public void open(final int size) throws LineUnavailableException {
try {
final Info var2 = new Info(SourceDataLine.class, this.format, size * 4);
this.line = (SourceDataLine) AudioSystem.getLine(var2);
this.line.open();
this.line.start();
this.lineBufferSizeInInts = size;
} catch (final LineUnavailableException var3) {
if (popcount(size) == 1) {
this.line = null;
throw var3;
} else {
this.open(BitMath.nextLowestPowerOf2(size));
}
}
}
private void fillAudioBuffer(final int[] data) {
Arrays.fill(data, 0, BYTES_PER_CHANNEL_PER_WRITE, 0);
this._a -= 256;
if (this.source != null && this._a <= 0) {
this._a += 1378;
b446(this.source);
this.a607(this.source, this.source.c784());
int var4 = 0;
int var5 = 255;
AudioSource_idk var10;
label106:
for (int var6 = 7; var5 != 0; --var6) {
int var7;
int var8;
if (var6 < 0) {
var7 = var6 & 3;
var8 = -(var6 >> 2);
} else {
var7 = var6;
var8 = 0;
}
for (int var9 = (var5 >>> var7) & 0x11111111; var9 != 0; var9 >>>= 4) {
if ((var9 & 1) != 0) {
var5 &= ~(1 << var7);
var10 = null;
AudioSource_idk var11 = this._o[var7];
label100:
while (true) {
while (true) {
if (var11 == null) {
break label100;
}
final RawSampleS8 var12 = var11.sampleData;
if (var12 != null && var12._h > var8) {
var5 |= 1 << var7;
var10 = var11;
var11 = var11._h;
} else {
var11.enabled = true;
final int var13 = var11.a784();
var4 += var13;
if (var12 != null) {
var12._h += var13;
}
if (var4 >= 32) {
break label106;
}
final int var15 = var11._i;
var11.forEach(var14 -> this.a607(var14, var15 * var14.c784() >> 8));
final AudioSource_idk var18 = var11._h;
var11._h = null;
if (var10 == null) {
this._o[var7] = var18;
} else {
var10._h = var18;
}
if (var18 == null) {
this._s[var7] = var10;
}
var11 = var18;
}
}
}
}
var7 += 4;
++var8;
}
}
for (int var6 = 0; var6 < 8; ++var6) {
AudioSource_idk var16 = this._o[var6];
this._s[var6] = null;
for (this._o[var6] = null; var16 != null; var16 = var10) {
var10 = var16._h;
var16._h = null;
}
}
}
if (this._a < 0) {
this._a = 0;
}
if (this.source != null) {
this.source.processAndWrite(data, 0, 256);
}
this._m = PseudoMonotonicClock.currentTimeMillis();
}
private void b150() {
this._a -= 256;
if (this._a < 0) {
this._a = 0;
}
if (this.source != null) {
this.source.processAndDiscard(256);
}
}
private void a607(final AudioSource_idk var1, final int var2) {
final int i = var2 >> 5;
final AudioSource_idk var4 = this._s[i];
if (var4 == null) {
this._o[i] = var1;
} else {
var4._h = var1;
}
this._s[i] = var1;
var1._i = var2;
}
public synchronized void doSomethingThatSeemsRelatedToAudio() {
if (!this.isShutdown) {
long var1 = PseudoMonotonicClock.currentTimeMillis();
try {
if (var1 > this._m + 6000L) {
this._m = var1 - 6000L;
}
while (var1 > this._m + 5000L) {
this.b150();
this._m += 256000 / SAMPLES_PER_SECOND;
var1 = PseudoMonotonicClock.currentTimeMillis();
}
} catch (final Exception var6) {
this._m = var1;
}
if (this.data != null) {
try {
if (this._p != 0L) {
if (var1 < this._p) {
return;
}
this.open(this._g);
this._p = 0L;
this._n = true;
}
int var3 = this.bufferedInts();
if (this._r - var3 > this._l) {
this._l = this._r - var3;
}
int var4 = this._b + this._u;
if (var4 + 0x100 > 0x4000) {
var4 = 0x3f00;
}
if (var4 + 0x100 > this._g) {
this._g += 0x400;
if (this._g > 0x4000) {
this._g = 0x4000;
}
this.close();
this.open(this._g);
var3 = 0;
this._n = true;
if (var4 + 256 > this._g) {
var4 = this._g - 256;
this._u = var4 - this._b;
}
}
while (var3 < var4) {
this.fillAudioBuffer(this.data);
this.performWrite();
var3 += 256;
}
if (var1 > this._q) {
if (this._n) {
this._n = false;
} else {
if (this._l == 0 && this._e == 0) {
this.close();
this._p = var1 + 2000L;
return;
}
this._u = Math.min(this._e, this._l);
this._e = this._l;
}
this._l = 0;
this._q = var1 + 2000L;
}
this._r = var3;
} catch (final Exception var5) {
this.close();
this._p = var1 + 2000L;
}
}
}
}
public synchronized void setSource(final AudioSource_idk source) {
this.source = source;
}
public synchronized void shutdown() {
if (AudioThread.instance != null) {
boolean allChannelsShutdown = true;
for (int i = 0; i < AudioThread.NUM_CHANNELS; ++i) {
if (AudioThread.instance.channels[i] == this) {
AudioThread.instance.channels[i] = null;
}
if (AudioThread.instance.channels[i] != null) {
allChannelsShutdown = false;
}
}
if (allChannelsShutdown) {
AudioThread.instance.shutdownRequested = true;
while (AudioThread.instance.isRunning) {
JagexBaseApplet.maybeSleep(50L);
}
AudioThread.instance = null;
}
}
this.close();
this.data = null;
this.isShutdown = true;
}
}

View File

@ -0,0 +1,341 @@
package funorb.audio;
import funorb.client.JagexBaseApplet;
import funorb.util.BitMath;
import funorb.util.PseudoMonotonicClock;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine.Info;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import java.io.Closeable;
import java.util.Arrays;
public final class SampledAudioChannelS16 implements Closeable {
public static final int SAMPLE_RATE = 22050;
private static final int TOTAL_SAMPLES_PER_WRITE = 512;
private final AudioFormat format = new AudioFormat(SAMPLE_RATE, 16, 2, true, false);
private final byte[] buffer = new byte[1024];
private final AudioSource[] sourcesHeads_idk = new AudioSource[8];
private final AudioSource[] sourcesTail_idk = new AudioSource[8];
public int[] dataS16P8;
public int lineSize;
public int _b;
private SourceDataLine line;
private int lineBufferSizeInInts;
private boolean isShutdown = false;
private long fillMillis = PseudoMonotonicClock.currentTimeMillis();
private AudioSource source;
private int written_idk = 0;
private int _l = 0;
private boolean _n = true;
private int _e = 0;
private int toDiscard_idk = 0;
private long _p = 0L;
private int _u;
private long _q = 0L;
private static int popcount(final int var1) {
final int var2 = (var1 & 0x55555555) + ((var1 >>> 1) & 0xd5555555);
final int var3 = (var2 & 0x33333333) + ((var2 & 0xcccccccc) >>> 2);
final int var4 = (var3 + (var3 >>> 4)) & 0xf0f0f0f;
final int var5 = var4 + (var4 >>> 8);
final int var6 = var5 + (var5 >>> 16);
return var6 & 255;
}
private static void resetSource_idk(final AudioSource source) {
source.enabled = false;
if (source.rawSample != null) {
source.rawSample.someCounter_idk = 0;
}
source.forEach(SampledAudioChannelS16::resetSource_idk);
}
@Override
public void close() {
if (this.line != null) {
this.line.close();
this.line = null;
}
}
private int bufferedInts() {
return this.lineBufferSizeInInts - (this.line.available() / 4);
}
private void performWrite() {
for (int i = 0; i < TOTAL_SAMPLES_PER_WRITE; ++i) {
int sample = this.dataS16P8[i];
if (((sample + 0x80_00_00) & 0xff_00_00_00) != 0) {
sample = 0x7fffff ^ (sample >> 31);
}
this.buffer[i * 2] = (byte) (sample >> 8);
this.buffer[i * 2 + 1] = (byte) (sample >> 16);
}
this.line.write(this.buffer, 0, TOTAL_SAMPLES_PER_WRITE * 2);
}
public void openLine(final int size) throws LineUnavailableException {
try {
final Info info = new Info(SourceDataLine.class, this.format, size * 4);
this.line = (SourceDataLine) AudioSystem.getLine(info);
this.line.open();
this.line.start();
this.lineBufferSizeInInts = size;
} catch (final LineUnavailableException e) {
if (popcount(size) == 1) {
this.line = null;
throw e;
} else {
this.openLine(BitMath.nextLowestPowerOf2(size));
}
}
}
private void fillAudioBuffer(final int[] dataS16P8) {
Arrays.fill(dataS16P8, 0, TOTAL_SAMPLES_PER_WRITE, 0);
this.toDiscard_idk -= 256;
if (this.source != null && this.toDiscard_idk <= 0) {
this.toDiscard_idk += 1378;
resetSource_idk(this.source);
this.sourcesAppend(this.source, this.source.someP8_idk());
int breakAtOrAbove32 = 0;
int bitSet = 255;
AudioSource lastSource_idk;
outerLoop:
for (int var6 = 7; bitSet != 0; --var6) {
int bits;
int someThreshold_idk;
if (var6 < 0) {
bits = var6 & 3;
someThreshold_idk = -(var6 >> 2);
} else {
bits = var6;
someThreshold_idk = 0;
}
for (int var9 = (bitSet >>> bits) & 0x11111111; var9 != 0; var9 >>>= 4, bits += 4, someThreshold_idk++) {
if ((var9 & 1) == 0) {
continue;
}
bitSet &= ~(1 << bits);
lastSource_idk = null;
AudioSource source = this.sourcesHeads_idk[bits];
while (source != null) {
final RawSampleS8 sampleData = source.rawSample;
if (sampleData != null && sampleData.someCounter_idk > someThreshold_idk) {
bitSet |= 1 << bits;
lastSource_idk = source;
source = source.nextSource_idk;
} else {
source.enabled = true;
final int _0_1_or_2 = source.returns_0_1_or_2();
breakAtOrAbove32 += _0_1_or_2;
if (sampleData != null) {
sampleData.someCounter_idk += _0_1_or_2;
}
if (breakAtOrAbove32 >= 32) {
break outerLoop;
}
final int someP8_idk = source.lastP8_idk;
source.forEach(s -> this.sourcesAppend(s, someP8_idk * s.someP8_idk() >> 8));
final AudioSource nextSource = source.nextSource_idk;
source.nextSource_idk = null;
if (lastSource_idk == null) {
this.sourcesHeads_idk[bits] = nextSource;
} else {
lastSource_idk.nextSource_idk = nextSource;
}
if (nextSource == null) {
this.sourcesTail_idk[bits] = lastSource_idk;
}
source = nextSource;
}
}
}
}
for (int window = 0; window < 8; ++window) {
AudioSource source = this.sourcesHeads_idk[window];
this.sourcesTail_idk[window] = null;
this.sourcesHeads_idk[window] = null;
while (source != null) {
final AudioSource next = source.nextSource_idk;
source.nextSource_idk = null;
source = next;
}
}
}
if (this.toDiscard_idk < 0) {
this.toDiscard_idk = 0;
}
if (this.source != null) {
this.source.processAndWrite(dataS16P8, 0, 256);
}
this.fillMillis = PseudoMonotonicClock.currentTimeMillis();
}
private void processAndDiscard256() {
this.toDiscard_idk -= 256;
if (this.toDiscard_idk < 0) {
this.toDiscard_idk = 0;
}
if (this.source != null) {
this.source.processAndDiscard(256);
}
}
private void sourcesAppend(final AudioSource source, final int someP8_idk) {
final int partition = someP8_idk >> 5;
final AudioSource prev = this.sourcesTail_idk[partition];
if (prev == null) {
this.sourcesHeads_idk[partition] = source;
} else {
prev.nextSource_idk = source;
}
this.sourcesTail_idk[partition] = source;
source.lastP8_idk = someP8_idk;
}
public synchronized void doSomethingThatSeemsRelatedToAudio() {
if (this.isShutdown) {
return;
}
long now = PseudoMonotonicClock.currentTimeMillis();
try {
if (this.fillMillis + 6000L < now) {
this.fillMillis = now - 6000L;
}
while (this.fillMillis + 5000L < now) {
this.processAndDiscard256();
this.fillMillis += 256000 / SAMPLE_RATE;
now = PseudoMonotonicClock.currentTimeMillis();
}
} catch (final Exception e) {
this.fillMillis = now;
}
if (this.dataS16P8 == null) {
return;
}
try {
if (this._p != 0L) {
if (now < this._p) {
return;
}
this.openLine(this.lineSize);
this._p = 0L;
this._n = true;
}
int written_idk = this.bufferedInts();
if (this.written_idk - written_idk > this._l) {
this._l = this.written_idk - written_idk;
}
int toWrite_idk = this._b + this._u;
if (toWrite_idk + 256 > 16384) {
toWrite_idk = 16128;
}
if (toWrite_idk + 256 > this.lineSize) {
this.lineSize += 1024;
if (this.lineSize > 16384) {
this.lineSize = 16384;
}
this.close();
this.openLine(this.lineSize);
written_idk = 0;
this._n = true;
if (toWrite_idk + 256 > this.lineSize) {
toWrite_idk = this.lineSize - 256;
this._u = toWrite_idk - this._b;
}
}
while (written_idk < toWrite_idk) {
this.fillAudioBuffer(this.dataS16P8);
this.performWrite();
written_idk += 256;
}
if (now > this._q) {
if (this._n) {
this._n = false;
} else {
if (this._l == 0 && this._e == 0) {
this.close();
this._p = now + 2000L;
return;
}
this._u = Math.min(this._e, this._l);
this._e = this._l;
}
this._l = 0;
this._q = now + 2000L;
}
this.written_idk = written_idk;
} catch (final Exception e) {
this.close();
this._p = now + 2000L;
}
}
public synchronized void setSource(final AudioSource source) {
this.source = source;
}
public synchronized void shutdown() {
if (AudioThread.instance != null) {
boolean allChannelsShutdown = true;
for (int i = 0; i < AudioThread.NUM_CHANNELS; ++i) {
if (AudioThread.instance.channels[i] == this) {
AudioThread.instance.channels[i] = null;
}
if (AudioThread.instance.channels[i] != null) {
allChannelsShutdown = false;
}
}
if (allChannelsShutdown) {
AudioThread.instance.shutdownRequested = true;
while (AudioThread.instance.isRunning) {
JagexBaseApplet.maybeSleep(50L);
}
AudioThread.instance = null;
}
}
this.close();
this.dataS16P8 = null;
this.isShutdown = true;
}
}

View File

@ -0,0 +1,38 @@
package funorb.audio;
import funorb.data.NodeList;
import org.jetbrains.annotations.NotNull;
import java.util.Iterator;
public final class SoundManager extends AudioSource {
private final NodeList<AudioSource> inner = new NodeList<>();
@Override
public @NotNull Iterator<AudioSource> iterator() {
return this.inner.iterator();
}
@Override
public int returns_0_1_or_2() {
return 0;
}
@Override
public synchronized void processAndDiscard(final int len) {
for (final AudioSource gen : this.inner) {
gen.processAndDiscard(len);
}
}
public synchronized void addFirst(final RawSamplePlayer var1) {
this.inner.addFirst(var1);
}
@Override
public synchronized void processAndWrite(final int[] dataS16P8, final int offset, final int len) {
for (final AudioSource gen : this.inner) {
gen.processAndWriteIfEnabled(dataS16P8, offset, len);
}
}
}

View File

@ -39,13 +39,13 @@ public final class SynthFormat {
if (totalDurMs == 0) {
return new byte[0];
}
final int len = SampledAudioChannel.SAMPLES_PER_SECOND * totalDurMs / 1000;
final int len = SampledAudioChannelS16.SAMPLE_RATE * totalDurMs / 1000;
final byte[] dataS8 = new byte[len];
for (int i = 0; i < 10; ++i) {
if (this.oscs[i] != null) {
final int durSamples = this.oscs[i].lengthMs * SampledAudioChannel.SAMPLES_PER_SECOND / 1000;
final int delaySamples = this.oscs[i].posMs * SampledAudioChannel.SAMPLES_PER_SECOND / 1000;
final int durSamples = this.oscs[i].lengthMs * SampledAudioChannelS16.SAMPLE_RATE / 1000;
final int delaySamples = this.oscs[i].posMs * SampledAudioChannelS16.SAMPLE_RATE / 1000;
final int[] s16buf = this.oscs[i].generateS16(durSamples, this.oscs[i].lengthMs);
for (int j = 0; j < durSamples; ++j) {
@ -66,8 +66,8 @@ public final class SynthFormat {
final byte[] sampleData = this.toSampleDataS8();
return new RawSampleS8(
sampleData,
SampledAudioChannel.SAMPLES_PER_SECOND * this.loopStartMs / 1000,
SampledAudioChannel.SAMPLES_PER_SECOND * this.loopEndMs / 1000
SampledAudioChannelS16.SAMPLE_RATE * this.loopStartMs / 1000,
SampledAudioChannelS16.SAMPLE_RATE * this.loopEndMs / 1000
);
}
}

View File

@ -3,9 +3,9 @@ package funorb.shatteredplans.client;
import funorb.Strings;
import funorb.audio.AudioThread;
import funorb.audio.SongData;
import funorb.audio.SampledAudioChannel;
import funorb.audio.h_;
import funorb.audio.AudioSourceSum_idk;
import funorb.audio.SampledAudioChannelS16;
import funorb.audio.MusicManager;
import funorb.audio.SoundManager;
import funorb.awt.FullScreenCanvas;
import funorb.awt.KeyState;
import funorb.awt.MouseState;
@ -2261,7 +2261,7 @@ public final class ShatteredPlansClient extends JagexApplet {
cannotStartGameUntil = 0L;
}
private static SampledAudioChannel createAudioChannel(final int i, int var3) {
private static SampledAudioChannelS16 createAudioChannel(final int i, int var3) {
if (i < 0 || i >= 2) {
throw new IllegalArgumentException();
}
@ -2271,15 +2271,15 @@ public final class ShatteredPlansClient extends JagexApplet {
}
try {
final SampledAudioChannel channel = new SampledAudioChannel();
channel.data = new int[512];
final SampledAudioChannelS16 channel = new SampledAudioChannelS16();
channel.dataS16P8 = new int[512];
channel._b = var3;
channel._g = (var3 & 0xfffffc00) + 0x400;
if (channel._g > 0x4000) {
channel._g = 0x4000;
channel.lineSize = (var3 & 0xfffffc00) + 0x400;
if (channel.lineSize > 0x4000) {
channel.lineSize = 0x4000;
}
channel.open(channel._g);
channel.openLine(channel.lineSize);
if (AudioThread.instance == null) {
AudioThread.instance = new AudioThread(MessagePumpThread.instance);
MessagePumpThread.instance.sendSpawnThreadMessage(AudioThread.instance, 10);
@ -4262,16 +4262,16 @@ public final class ShatteredPlansClient extends JagexApplet {
public void initialize() {
super.initialize();
final h_ musicTn = new h_();
final MusicManager musicTn = new MusicManager();
musicTn.midiPlayer2.initialize();
musicTn.midiPlayer1.initialize();
musicTn.midiPlayer2.setVolume(Sounds.MAX_VOLUME);
musicTn.midiPlayer1.setVolume(Sounds.MAX_VOLUME);
Sounds.musicChannel = createAudioChannel(0, SampledAudioChannel.SAMPLES_PER_SECOND);
Sounds.musicChannel = createAudioChannel(0, SampledAudioChannelS16.SAMPLE_RATE);
Sounds.soundsChannel = createAudioChannel(1, 1102);
Sounds.soundsTn = new AudioSourceSum_idk();
Sounds.soundsTn = new SoundManager();
Sounds.soundsChannel.setSource(Sounds.soundsTn);
Sounds.musicTn = musicTn;
Sounds.musicTn.setVolume(Sounds.musicVolume);

View File

@ -2,13 +2,13 @@ package funorb.shatteredplans.client;
import funorb.audio.SongData;
import funorb.audio.PlayingSound;
import funorb.audio.SampledAudioChannel;
import funorb.audio.SampledAudioChannelS16;
import funorb.audio.SoundEffect;
import funorb.audio.SoundLoader;
import funorb.audio.AudioSamplePlayback_idk;
import funorb.audio.h_;
import funorb.audio.RawSamplePlayer;
import funorb.audio.MusicManager;
import funorb.audio.RawSampleS8;
import funorb.audio.AudioSourceSum_idk;
import funorb.audio.SoundManager;
import funorb.cache.ResourceLoader;
import java.util.ArrayList;
@ -34,10 +34,10 @@ public final class Sounds {
public static int musicVolume = 256;
public static final List<PlayingSound> playingSounds = new ArrayList<>();
public static AudioSourceSum_idk soundsTn;
public static h_ musicTn;
static SampledAudioChannel soundsChannel;
static SampledAudioChannel musicChannel;
public static SoundManager soundsTn;
public static MusicManager musicTn;
static SampledAudioChannelS16 soundsChannel;
static SampledAudioChannelS16 musicChannel;
public static void loadSoundEffects(final ResourceLoader loader1, final ResourceLoader loader2) {
SoundLoader.globalLoader = new SoundLoader(loader1, loader2);
@ -76,7 +76,7 @@ public final class Sounds {
}
private static PlayingSound play(final RawSampleS8 var1, final int volume) {
final AudioSamplePlayback_idk var01 = AudioSamplePlayback_idk.a638(var1, volume);
final RawSamplePlayer var01 = RawSamplePlayer.a638(var1, volume);
assert var01 != null;
final PlayingSound sound = new PlayingSound(var01);
playingSounds.add(sound);