2025-11-24 22:52:51 +03:00

185 lines
5.9 KiB
Java

/*
* Decompiled with CFR 0.152.
*
* Could not load the following classes:
* com.mojang.logging.LogUtils
* org.jspecify.annotations.Nullable
* org.lwjgl.openal.AL10
* org.slf4j.Logger
*/
package com.mojang.blaze3d.audio;
import com.mojang.blaze3d.audio.OpenAlUtil;
import com.mojang.blaze3d.audio.SoundBuffer;
import com.mojang.logging.LogUtils;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.concurrent.atomic.AtomicBoolean;
import javax.sound.sampled.AudioFormat;
import net.minecraft.client.sounds.AudioStream;
import net.minecraft.world.phys.Vec3;
import org.jspecify.annotations.Nullable;
import org.lwjgl.openal.AL10;
import org.slf4j.Logger;
public class Channel {
private static final Logger LOGGER = LogUtils.getLogger();
private static final int QUEUED_BUFFER_COUNT = 4;
public static final int BUFFER_DURATION_SECONDS = 1;
private final int source;
private final AtomicBoolean initialized = new AtomicBoolean(true);
private int streamingBufferSize = 16384;
private @Nullable AudioStream stream;
static @Nullable Channel create() {
int[] newId = new int[1];
AL10.alGenSources((int[])newId);
if (OpenAlUtil.checkALError("Allocate new source")) {
return null;
}
return new Channel(newId[0]);
}
private Channel(int src) {
this.source = src;
}
public void destroy() {
if (this.initialized.compareAndSet(true, false)) {
AL10.alSourceStop((int)this.source);
OpenAlUtil.checkALError("Stop");
if (this.stream != null) {
try {
this.stream.close();
}
catch (IOException e) {
LOGGER.error("Failed to close audio stream", (Throwable)e);
}
this.removeProcessedBuffers();
this.stream = null;
}
AL10.alDeleteSources((int[])new int[]{this.source});
OpenAlUtil.checkALError("Cleanup");
}
}
public void play() {
AL10.alSourcePlay((int)this.source);
}
private int getState() {
if (!this.initialized.get()) {
return 4116;
}
return AL10.alGetSourcei((int)this.source, (int)4112);
}
public void pause() {
if (this.getState() == 4114) {
AL10.alSourcePause((int)this.source);
}
}
public void unpause() {
if (this.getState() == 4115) {
AL10.alSourcePlay((int)this.source);
}
}
public void stop() {
if (this.initialized.get()) {
AL10.alSourceStop((int)this.source);
OpenAlUtil.checkALError("Stop");
}
}
public boolean playing() {
return this.getState() == 4114;
}
public boolean stopped() {
return this.getState() == 4116;
}
public void setSelfPosition(Vec3 newPosition) {
AL10.alSourcefv((int)this.source, (int)4100, (float[])new float[]{(float)newPosition.x, (float)newPosition.y, (float)newPosition.z});
}
public void setPitch(float pitch) {
AL10.alSourcef((int)this.source, (int)4099, (float)pitch);
}
public void setLooping(boolean looping) {
AL10.alSourcei((int)this.source, (int)4103, (int)(looping ? 1 : 0));
}
public void setVolume(float volume) {
AL10.alSourcef((int)this.source, (int)4106, (float)volume);
}
public void disableAttenuation() {
AL10.alSourcei((int)this.source, (int)53248, (int)0);
}
public void linearAttenuation(float maxDistance) {
AL10.alSourcei((int)this.source, (int)53248, (int)53251);
AL10.alSourcef((int)this.source, (int)4131, (float)maxDistance);
AL10.alSourcef((int)this.source, (int)4129, (float)1.0f);
AL10.alSourcef((int)this.source, (int)4128, (float)0.0f);
}
public void setRelative(boolean relative) {
AL10.alSourcei((int)this.source, (int)514, (int)(relative ? 1 : 0));
}
public void attachStaticBuffer(SoundBuffer buffer) {
buffer.getAlBuffer().ifPresent(bufferId -> AL10.alSourcei((int)this.source, (int)4105, (int)bufferId));
}
public void attachBufferStream(AudioStream stream) {
this.stream = stream;
AudioFormat format = stream.getFormat();
this.streamingBufferSize = Channel.calculateBufferSize(format, 1);
this.pumpBuffers(4);
}
private static int calculateBufferSize(AudioFormat format, int seconds) {
return (int)((float)(seconds * format.getSampleSizeInBits()) / 8.0f * (float)format.getChannels() * format.getSampleRate());
}
private void pumpBuffers(int size) {
if (this.stream != null) {
try {
for (int i = 0; i < size; ++i) {
ByteBuffer buffer = this.stream.read(this.streamingBufferSize);
if (buffer == null) continue;
new SoundBuffer(buffer, this.stream.getFormat()).releaseAlBuffer().ifPresent(bufferId -> AL10.alSourceQueueBuffers((int)this.source, (int[])new int[]{bufferId}));
}
}
catch (IOException e) {
LOGGER.error("Failed to read from audio stream", (Throwable)e);
}
}
}
public void updateStream() {
if (this.stream != null) {
int processedBuffers = this.removeProcessedBuffers();
this.pumpBuffers(processedBuffers);
}
}
private int removeProcessedBuffers() {
int processed = AL10.alGetSourcei((int)this.source, (int)4118);
if (processed > 0) {
int[] ids = new int[processed];
AL10.alSourceUnqueueBuffers((int)this.source, (int[])ids);
OpenAlUtil.checkALError("Unqueue buffers");
AL10.alDeleteBuffers((int[])ids);
OpenAlUtil.checkALError("Remove processed buffers");
}
return processed;
}
}