Channel.java

com.mojang.blaze3d.audio.Channel

信息

  • 全限定名:com.mojang.blaze3d.audio.Channel
  • 类型:public class
  • 包:com.mojang.blaze3d.audio
  • 源码路径:src/main/java/com/mojang/blaze3d/audio/Channel.java
  • 起始行号:L17
  • 职责:

    TODO

字段/常量

  • LOGGER

    • 类型: Logger
    • 修饰符: private static final
    • 源码定位: L18
    • 说明:

      TODO

  • QUEUED_BUFFER_COUNT

    • 类型: int
    • 修饰符: private static final
    • 源码定位: L19
    • 说明:

      TODO

  • BUFFER_DURATION_SECONDS

    • 类型: int
    • 修饰符: public static final
    • 源码定位: L20
    • 说明:

      TODO

  • source

    • 类型: int
    • 修饰符: private final
    • 源码定位: L21
    • 说明:

      TODO

  • initialized

    • 类型: AtomicBoolean
    • 修饰符: private final
    • 源码定位: L22
    • 说明:

      TODO

  • streamingBufferSize

    • 类型: int
    • 修饰符: private
    • 源码定位: L23
    • 说明:

      TODO

  • stream

    • 类型: AudioStream
    • 修饰符: private
    • 源码定位: L24
    • 说明:

      TODO

内部类/嵌套类型

构造器

private Channel(int src) @ L32

  • 构造器名:Channel
  • 源码定位:L32
  • 修饰符:private

参数:

  • src: int

说明:

TODO

方法

下面的方法块按源码顺序生成。

static Channel create() @ L26

  • 方法名:create
  • 源码定位:L26
  • 返回类型:Channel
  • 修饰符:static

参数:

说明:

TODO

public void destroy() @ L36

  • 方法名:destroy
  • 源码定位:L36
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public void play() @ L56

  • 方法名:play
  • 源码定位:L56
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

private int getState() @ L60

  • 方法名:getState
  • 源码定位:L60
  • 返回类型:int
  • 修饰符:private

参数:

说明:

TODO

public void pause() @ L64

  • 方法名:pause
  • 源码定位:L64
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public void unpause() @ L70

  • 方法名:unpause
  • 源码定位:L70
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public void stop() @ L76

  • 方法名:stop
  • 源码定位:L76
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public boolean playing() @ L83

  • 方法名:playing
  • 源码定位:L83
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public boolean stopped() @ L87

  • 方法名:stopped
  • 源码定位:L87
  • 返回类型:boolean
  • 修饰符:public

参数:

说明:

TODO

public void setSelfPosition(Vec3 newPosition) @ L91

  • 方法名:setSelfPosition
  • 源码定位:L91
  • 返回类型:void
  • 修饰符:public

参数:

  • newPosition: Vec3

说明:

TODO

public void setPitch(float pitch) @ L95

  • 方法名:setPitch
  • 源码定位:L95
  • 返回类型:void
  • 修饰符:public

参数:

  • pitch: float

说明:

TODO

public void setLooping(boolean looping) @ L99

  • 方法名:setLooping
  • 源码定位:L99
  • 返回类型:void
  • 修饰符:public

参数:

  • looping: boolean

说明:

TODO

public void setVolume(float volume) @ L103

  • 方法名:setVolume
  • 源码定位:L103
  • 返回类型:void
  • 修饰符:public

参数:

  • volume: float

说明:

TODO

public void disableAttenuation() @ L107

  • 方法名:disableAttenuation
  • 源码定位:L107
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public void linearAttenuation(float maxDistance) @ L111

  • 方法名:linearAttenuation
  • 源码定位:L111
  • 返回类型:void
  • 修饰符:public

参数:

  • maxDistance: float

说明:

TODO

public void setRelative(boolean relative) @ L118

  • 方法名:setRelative
  • 源码定位:L118
  • 返回类型:void
  • 修饰符:public

参数:

  • relative: boolean

说明:

TODO

public void attachStaticBuffer(SoundBuffer buffer) @ L122

  • 方法名:attachStaticBuffer
  • 源码定位:L122
  • 返回类型:void
  • 修饰符:public

参数:

  • buffer: SoundBuffer

说明:

TODO

public void attachBufferStream(AudioStream stream) @ L126

  • 方法名:attachBufferStream
  • 源码定位:L126
  • 返回类型:void
  • 修饰符:public

参数:

  • stream: AudioStream

说明:

TODO

private static int calculateBufferSize(AudioFormat format, int seconds) @ L133

  • 方法名:calculateBufferSize
  • 源码定位:L133
  • 返回类型:int
  • 修饰符:private static

参数:

  • format: AudioFormat
  • seconds: int

说明:

TODO

private void pumpBuffers(int size) @ L137

  • 方法名:pumpBuffers
  • 源码定位:L137
  • 返回类型:void
  • 修饰符:private

参数:

  • size: int

说明:

TODO

public void updateStream() @ L154

  • 方法名:updateStream
  • 源码定位:L154
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

private int removeProcessedBuffers() @ L161

  • 方法名:removeProcessedBuffers
  • 源码定位:L161
  • 返回类型:int
  • 修饰符:private

参数:

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
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(newId);
        return OpenAlUtil.checkALError("Allocate new source") ? null : new Channel(newId[0]);
    }
 
    private Channel(int src) {
        this.source = src;
    }
 
    public void destroy() {
        if (this.initialized.compareAndSet(true, false)) {
            AL10.alSourceStop(this.source);
            OpenAlUtil.checkALError("Stop");
            if (this.stream != null) {
                try {
                    this.stream.close();
                } catch (IOException var2) {
                    LOGGER.error("Failed to close audio stream", (Throwable)var2);
                }
 
                this.removeProcessedBuffers();
                this.stream = null;
            }
 
            AL10.alDeleteSources(new int[]{this.source});
            OpenAlUtil.checkALError("Cleanup");
        }
    }
 
    public void play() {
        AL10.alSourcePlay(this.source);
    }
 
    private int getState() {
        return !this.initialized.get() ? 4116 : AL10.alGetSourcei(this.source, 4112);
    }
 
    public void pause() {
        if (this.getState() == 4114) {
            AL10.alSourcePause(this.source);
        }
    }
 
    public void unpause() {
        if (this.getState() == 4115) {
            AL10.alSourcePlay(this.source);
        }
    }
 
    public void stop() {
        if (this.initialized.get()) {
            AL10.alSourceStop(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(this.source, 4100, new float[]{(float)newPosition.x, (float)newPosition.y, (float)newPosition.z});
    }
 
    public void setPitch(float pitch) {
        AL10.alSourcef(this.source, 4099, pitch);
    }
 
    public void setLooping(boolean looping) {
        AL10.alSourcei(this.source, 4103, looping ? 1 : 0);
    }
 
    public void setVolume(float volume) {
        AL10.alSourcef(this.source, 4106, volume);
    }
 
    public void disableAttenuation() {
        AL10.alSourcei(this.source, 53248, 0);
    }
 
    public void linearAttenuation(float maxDistance) {
        AL10.alSourcei(this.source, 53248, 53251);
        AL10.alSourcef(this.source, 4131, maxDistance);
        AL10.alSourcef(this.source, 4129, 1.0F);
        AL10.alSourcef(this.source, 4128, 0.0F);
    }
 
    public void setRelative(boolean relative) {
        AL10.alSourcei(this.source, 514, relative ? 1 : 0);
    }
 
    public void attachStaticBuffer(SoundBuffer buffer) {
        buffer.getAlBuffer().ifPresent(bufferId -> AL10.alSourcei(this.source, 4105, bufferId));
    }
 
    public void attachBufferStream(AudioStream stream) {
        this.stream = stream;
        AudioFormat format = stream.getFormat();
        this.streamingBufferSize = calculateBufferSize(format, 1);
        this.pumpBuffers(4);
    }
 
    private static int calculateBufferSize(AudioFormat format, int seconds) {
        return (int)(seconds * format.getSampleSizeInBits() / 8.0F * 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) {
                        new SoundBuffer(buffer, this.stream.getFormat())
                            .releaseAlBuffer()
                            .ifPresent(bufferId -> AL10.alSourceQueueBuffers(this.source, new int[]{bufferId}));
                    }
                }
            } catch (IOException var4) {
                LOGGER.error("Failed to read from audio stream", (Throwable)var4);
            }
        }
    }
 
    public void updateStream() {
        if (this.stream != null) {
            int processedBuffers = this.removeProcessedBuffers();
            this.pumpBuffers(processedBuffers);
        }
    }
 
    private int removeProcessedBuffers() {
        int processed = AL10.alGetSourcei(this.source, 4118);
        if (processed > 0) {
            int[] ids = new int[processed];
            AL10.alSourceUnqueueBuffers(this.source, ids);
            OpenAlUtil.checkALError("Unqueue buffers");
            AL10.alDeleteBuffers(ids);
            OpenAlUtil.checkALError("Remove processed buffers");
        }
 
        return processed;
    }
}

引用的其他类

  • OpenAlUtil

    • 引用位置: 方法调用
    • 关联成员: OpenAlUtil.checkALError()
  • SoundBuffer

    • 引用位置: 参数/构造调用
    • 关联成员: SoundBuffer()
  • AudioStream

    • 引用位置: 参数/字段
  • Vec3

    • 引用位置: 参数