JOrbisAudioStream.java
net.minecraft.client.sounds.JOrbisAudioStream
信息
- 全限定名:net.minecraft.client.sounds.JOrbisAudioStream
- 类型:public class
- 包:net.minecraft.client.sounds
- 源码路径:src/main/java/net/minecraft/client/sounds/JOrbisAudioStream.java
- 起始行号:L20
- 实现:FloatSampleSource
- 职责:
TODO
字段/常量
-
BUFSIZE- 类型:
int - 修饰符:
private static final - 源码定位:
L21 - 说明:
TODO
- 类型:
-
PAGEOUT_RECAPTURE- 类型:
int - 修饰符:
private static final - 源码定位:
L22 - 说明:
TODO
- 类型:
-
PAGEOUT_NEED_MORE_DATA- 类型:
int - 修饰符:
private static final - 源码定位:
L23 - 说明:
TODO
- 类型:
-
PAGEOUT_OK- 类型:
int - 修饰符:
private static final - 源码定位:
L24 - 说明:
TODO
- 类型:
-
PACKETOUT_ERROR- 类型:
int - 修饰符:
private static final - 源码定位:
L25 - 说明:
TODO
- 类型:
-
PACKETOUT_NEED_MORE_DATA- 类型:
int - 修饰符:
private static final - 源码定位:
L26 - 说明:
TODO
- 类型:
-
PACKETOUT_OK- 类型:
int - 修饰符:
private static final - 源码定位:
L27 - 说明:
TODO
- 类型:
-
syncState- 类型:
SyncState - 修饰符:
private final - 源码定位:
L28 - 说明:
TODO
- 类型:
-
page- 类型:
Page - 修饰符:
private final - 源码定位:
L29 - 说明:
TODO
- 类型:
-
streamState- 类型:
StreamState - 修饰符:
private final - 源码定位:
L30 - 说明:
TODO
- 类型:
-
packet- 类型:
Packet - 修饰符:
private final - 源码定位:
L31 - 说明:
TODO
- 类型:
-
info- 类型:
Info - 修饰符:
private final - 源码定位:
L32 - 说明:
TODO
- 类型:
-
dspState- 类型:
DspState - 修饰符:
private final - 源码定位:
L33 - 说明:
TODO
- 类型:
-
block- 类型:
Block - 修饰符:
private final - 源码定位:
L34 - 说明:
TODO
- 类型:
-
audioFormat- 类型:
AudioFormat - 修饰符:
private final - 源码定位:
L35 - 说明:
TODO
- 类型:
-
input- 类型:
InputStream - 修饰符:
private final - 源码定位:
L36 - 说明:
TODO
- 类型:
-
samplesWritten- 类型:
long - 修饰符:
private - 源码定位:
L37 - 说明:
TODO
- 类型:
-
totalSamplesInStream- 类型:
long - 修饰符:
private - 源码定位:
L38 - 说明:
TODO
- 类型:
内部类/嵌套类型
- 无
构造器
public JOrbisAudioStream(InputStream input) @ L40
- 构造器名:JOrbisAudioStream
- 源码定位:L40
- 修饰符:public
参数:
- input: InputStream
说明:
TODO
方法
下面的方法块按源码顺序生成。
private static boolean isError(int value) @ L69
- 方法名:isError
- 源码定位:L69
- 返回类型:boolean
- 修饰符:private static
参数:
- value: int
说明:
TODO
public AudioFormat getFormat() @ L73
- 方法名:getFormat
- 源码定位:L73
- 返回类型:AudioFormat
- 修饰符:public
参数:
- 无
说明:
TODO
private boolean readToBuffer() @ L78
- 方法名:readToBuffer
- 源码定位:L78
- 返回类型:boolean
- 修饰符:private
参数:
- 无
说明:
TODO
private Page readPage() @ L90
- 方法名:readPage
- 源码定位:L90
- 返回类型:Page
- 修饰符:private
参数:
- 无
说明:
TODO
private Packet readIdentificationPacket(Page firstPage) @ L114
- 方法名:readIdentificationPacket
- 源码定位:L114
- 返回类型:Packet
- 修饰符:private
参数:
- firstPage: Page
说明:
TODO
private Packet readPacket() @ L128
- 方法名:readPacket
- 源码定位:L128
- 返回类型:Packet
- 修饰符:private
参数:
- 无
说明:
TODO
private long getSamplesToWrite(int samples) @ L153
- 方法名:getSamplesToWrite
- 源码定位:L153
- 返回类型:long
- 修饰符:private
参数:
- samples: int
说明:
TODO
public boolean readChunk(FloatConsumer consumer) @ L167
- 方法名:readChunk
- 源码定位:L167
- 返回类型:boolean
- 修饰符:public
参数:
- consumer: FloatConsumer
说明:
TODO
private static void copyAnyChannels(float[][] samples, int channelCount, int[] offsets, long count, FloatConsumer output) @ L201
- 方法名:copyAnyChannels
- 源码定位:L201
- 返回类型:void
- 修饰符:private static
参数:
- samples: float[][]
- channelCount: int
- offsets: int[]
- count: long
- output: FloatConsumer
说明:
TODO
private static void copyMono(float[] samples, int offset, long count, FloatConsumer output) @ L211
- 方法名:copyMono
- 源码定位:L211
- 返回类型:void
- 修饰符:private static
参数:
- samples: float[]
- offset: int
- count: long
- output: FloatConsumer
说明:
TODO
private static void copyStereo(float[] samples1, int offset1, float[] samples2, int offset2, long count, FloatConsumer output) @ L217
- 方法名:copyStereo
- 源码定位:L217
- 返回类型:void
- 修饰符:private static
参数:
- samples1: float[]
- offset1: int
- samples2: float[]
- offset2: int
- count: long
- output: FloatConsumer
说明:
TODO
public void close() @ L224
- 方法名:close
- 源码定位:L224
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
public class JOrbisAudioStream implements FloatSampleSource {
private static final int BUFSIZE = 8192;
private static final int PAGEOUT_RECAPTURE = -1;
private static final int PAGEOUT_NEED_MORE_DATA = 0;
private static final int PAGEOUT_OK = 1;
private static final int PACKETOUT_ERROR = -1;
private static final int PACKETOUT_NEED_MORE_DATA = 0;
private static final int PACKETOUT_OK = 1;
private final SyncState syncState = new SyncState();
private final Page page = new Page();
private final StreamState streamState = new StreamState();
private final Packet packet = new Packet();
private final Info info = new Info();
private final DspState dspState = new DspState();
private final Block block = new Block(this.dspState);
private final AudioFormat audioFormat;
private final InputStream input;
private long samplesWritten;
private long totalSamplesInStream = Long.MAX_VALUE;
public JOrbisAudioStream(InputStream input) throws IOException {
this.input = input;
Comment comment = new Comment();
Page firstPage = this.readPage();
if (firstPage == null) {
throw new IOException("Invalid Ogg file - can't find first page");
} else {
Packet firstPacket = this.readIdentificationPacket(firstPage);
if (isError(this.info.synthesis_headerin(comment, firstPacket))) {
throw new IOException("Invalid Ogg identification packet");
} else {
for (int headerPacketCount = 0; headerPacketCount < 2; headerPacketCount++) {
firstPacket = this.readPacket();
if (firstPacket == null) {
throw new IOException("Unexpected end of Ogg stream");
}
if (isError(this.info.synthesis_headerin(comment, firstPacket))) {
throw new IOException("Invalid Ogg header packet " + headerPacketCount);
}
}
this.dspState.synthesis_init(this.info);
this.block.init(this.dspState);
this.audioFormat = new AudioFormat(this.info.rate, 16, this.info.channels, true, false);
}
}
}
private static boolean isError(int value) {
return value < 0;
}
@Override
public AudioFormat getFormat() {
return this.audioFormat;
}
private boolean readToBuffer() throws IOException {
int offset = this.syncState.buffer(8192);
byte[] buffer = this.syncState.data;
int bytes = this.input.read(buffer, offset, 8192);
if (bytes == -1) {
return false;
} else {
this.syncState.wrote(bytes);
return true;
}
}
private @Nullable Page readPage() throws IOException {
while (true) {
int pageOutResult = this.syncState.pageout(this.page);
switch (pageOutResult) {
case -1:
throw new IOException("Corrupt or missing data in bitstream");
case 0:
if (this.readToBuffer()) {
break;
}
return null;
case 1:
if (this.page.eos() != 0) {
this.totalSamplesInStream = this.page.granulepos();
}
return this.page;
default:
throw new IllegalStateException("Unknown page decode result: " + pageOutResult);
}
}
}
private Packet readIdentificationPacket(Page firstPage) throws IOException {
this.streamState.init(firstPage.serialno());
if (isError(this.streamState.pagein(firstPage))) {
throw new IOException("Failed to parse page");
} else {
int result = this.streamState.packetout(this.packet);
if (result != 1) {
throw new IOException("Failed to read identification packet: " + result);
} else {
return this.packet;
}
}
}
private @Nullable Packet readPacket() throws IOException {
while (true) {
int packetOutResult = this.streamState.packetout(this.packet);
switch (packetOutResult) {
case -1:
throw new IOException("Failed to parse packet");
case 0:
Page page = this.readPage();
if (page == null) {
return null;
}
if (!isError(this.streamState.pagein(page))) {
break;
}
throw new IOException("Failed to parse page");
case 1:
return this.packet;
default:
throw new IllegalStateException("Unknown packet decode result: " + packetOutResult);
}
}
}
private long getSamplesToWrite(int samples) {
long samplesAfterWrite = this.samplesWritten + samples;
long samplesToWrite;
if (samplesAfterWrite > this.totalSamplesInStream) {
samplesToWrite = this.totalSamplesInStream - this.samplesWritten;
this.samplesWritten = this.totalSamplesInStream;
} else {
this.samplesWritten = samplesAfterWrite;
samplesToWrite = samples;
}
return samplesToWrite;
}
@Override
public boolean readChunk(FloatConsumer consumer) throws IOException {
float[][][] pcmSampleOutput = new float[1][][];
int[] pcmOffsetOutput = new int[this.info.channels];
Packet packet = this.readPacket();
if (packet == null) {
return false;
} else if (isError(this.block.synthesis(packet))) {
throw new IOException("Can't decode audio packet");
} else {
this.dspState.synthesis_blockin(this.block);
int samples;
while ((samples = this.dspState.synthesis_pcmout(pcmSampleOutput, pcmOffsetOutput)) > 0) {
float[][] channelSamples = pcmSampleOutput[0];
long samplesToWrite = this.getSamplesToWrite(samples);
switch (this.info.channels) {
case 1:
copyMono(channelSamples[0], pcmOffsetOutput[0], samplesToWrite, consumer);
break;
case 2:
copyStereo(channelSamples[0], pcmOffsetOutput[0], channelSamples[1], pcmOffsetOutput[1], samplesToWrite, consumer);
break;
default:
copyAnyChannels(channelSamples, this.info.channels, pcmOffsetOutput, samplesToWrite, consumer);
}
this.dspState.synthesis_read(samples);
}
return true;
}
}
private static void copyAnyChannels(float[][] samples, int channelCount, int[] offsets, long count, FloatConsumer output) {
for (int j = 0; j < count; j++) {
for (int channel = 0; channel < channelCount; channel++) {
int offset = offsets[channel];
float val = samples[channel][offset + j];
output.accept(val);
}
}
}
private static void copyMono(float[] samples, int offset, long count, FloatConsumer output) {
for (int i = offset; i < offset + count; i++) {
output.accept(samples[i]);
}
}
private static void copyStereo(float[] samples1, int offset1, float[] samples2, int offset2, long count, FloatConsumer output) {
for (int i = 0; i < count; i++) {
output.accept(samples1[offset1 + i]);
output.accept(samples2[offset2 + i]);
}
}
@Override
public void close() throws IOException {
this.input.close();
}
}引用的其他类
-
- 引用位置:
参数/字段/构造调用/返回值 - 关联成员:
Page()
- 引用位置:
-
- 引用位置:
实现
- 引用位置:
-
- 引用位置:
字段/构造调用/返回值 - 关联成员:
Packet()
- 引用位置: