Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
lDEVinux
GitHub Repository: lDEVinux/eaglercraft
Path: blob/main/src/lwjgl/java/javazoom/mp3spi/DecodedMpegAudioInputStream.java
8644 views
1
/*
2
* DecodedMpegAudioInputStream.
3
*
4
* JavaZOOM : [email protected]
5
* http://www.javazoom.net
6
*
7
* Copyright (c) 2012 by fireandfuel from Cuina Team (http://www.cuina.byethost12.com/)
8
*
9
*-----------------------------------------------------------------------------
10
* This program is free software; you can redistribute it and/or modify
11
* it under the terms of the GNU Library General Public License as published
12
* by the Free Software Foundation; either version 2 of the License, or
13
* (at your option) any later version.
14
*
15
* This program is distributed in the hope that it will be useful,
16
* but WITHOUT ANY WARRANTY; without even the implied warranty of
17
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18
* GNU Library General Public License for more details.
19
*
20
* You should have received a copy of the GNU Library General Public
21
* License along with this program; if not, write to the Free Software
22
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23
*------------------------------------------------------------------------
24
*/
25
26
package javazoom.mp3spi;
27
28
import java.io.IOException;
29
import java.io.InputStream;
30
import javax.sound.sampled.AudioFormat;
31
import javax.sound.sampled.AudioInputStream;
32
33
import tritonus.TAsynchronousFilteredAudioInputStream;
34
35
import javazoom.jl.decoder.Bitstream;
36
import javazoom.jl.decoder.BitstreamException;
37
import javazoom.jl.decoder.Decoder;
38
import javazoom.jl.decoder.DecoderException;
39
import javazoom.jl.decoder.Header;
40
import javazoom.jl.decoder.Obuffer;
41
42
/**
43
* Main decoder.
44
*/
45
public class DecodedMpegAudioInputStream extends TAsynchronousFilteredAudioInputStream
46
{
47
private InputStream m_encodedStream;
48
private Bitstream m_bitstream;
49
private Decoder m_decoder;
50
private Header m_header;
51
private DMAISObuffer m_oBuffer;
52
53
// Bytes info.
54
private long byteslength = -1;
55
private long currentByte = 0;
56
// Frame info.
57
private int frameslength = -1;
58
private long currentFrame = 0;
59
private int currentFramesize = 0;
60
61
public DecodedMpegAudioInputStream(AudioFormat outputFormat,
62
AudioInputStream bufferedInputStream)
63
{
64
super(outputFormat, -1);
65
66
try
67
{
68
// Try to find out inputstream length to allow skip.
69
byteslength = bufferedInputStream.available();
70
} catch (IOException e)
71
{
72
byteslength = -1;
73
}
74
m_encodedStream = bufferedInputStream;
75
m_bitstream = new Bitstream(bufferedInputStream);
76
m_decoder = new Decoder(null);
77
// m_equalizer = new Equalizer();
78
// m_equalizer_values = new float[32];
79
// for (int b=0;b<m_equalizer.getBandCount();b++)
80
// {
81
// m_equalizer_values[b] = m_equalizer.getBand(b);
82
// }
83
// m_decoder.setEqualizer(m_equalizer);
84
m_oBuffer = new DMAISObuffer(outputFormat.getChannels());
85
m_decoder.setOutputBuffer(m_oBuffer);
86
try
87
{
88
m_header = m_bitstream.readFrame();
89
if((m_header != null) && (frameslength == -1) && (byteslength > 0))
90
frameslength = m_header.max_number_of_frames((int) byteslength);
91
} catch (BitstreamException e)
92
{
93
94
byteslength = -1;
95
}
96
}
97
98
public void execute()// if( reverseBytes )
99
// reverseBytes( smallBuffer, 0, bytesRead );
100
{
101
102
try
103
{
104
// Following line hangs when FrameSize is available in AudioFormat.
105
Header header = null;
106
if(m_header == null)
107
header = m_bitstream.readFrame();
108
else header = m_header;
109
110
if(header == null)
111
{
112
113
getCircularBuffer().close();
114
return;
115
}
116
currentFrame++;
117
currentFramesize = header.calculate_framesize();
118
currentByte = currentByte + currentFramesize;
119
// Obuffer decoderOutput =
120
m_decoder.decodeFrame(header, m_bitstream);
121
m_bitstream.closeFrame();
122
getCircularBuffer().write(m_oBuffer.getBuffer(), 0, m_oBuffer.getCurrentBufferSize());
123
m_oBuffer.reset();
124
if(m_header != null)
125
m_header = null;
126
} catch (BitstreamException e)
127
{
128
129
} catch (DecoderException e)
130
{
131
132
}
133
134
}
135
136
public long skip(long bytes)
137
{
138
if((byteslength > 0) && (frameslength > 0))
139
{
140
float ratio = bytes * 1.0f / byteslength * 1.0f;
141
long bytesread = skipFrames((long) (ratio * frameslength));
142
currentByte = currentByte + bytesread;
143
m_header = null;
144
return bytesread;
145
} else return -1;
146
}
147
148
/**
149
* Skip frames. You don't need to call it severals times, it will exactly
150
* skip given frames number.
151
*
152
* @param frames
153
* @return bytes length skipped matching to frames skipped.
154
*/
155
public long skipFrames(long frames)
156
{
157
158
int framesRead = 0;
159
int bytesReads = 0;
160
try
161
{
162
for(int i = 0; i < frames; i++)
163
{
164
Header header = m_bitstream.readFrame();
165
if(header != null)
166
{
167
int fsize = header.calculate_framesize();
168
bytesReads = bytesReads + fsize;
169
}
170
m_bitstream.closeFrame();
171
framesRead++;
172
}
173
} catch (BitstreamException e)
174
{
175
176
}
177
178
currentFrame = currentFrame + framesRead;
179
return bytesReads;
180
}
181
182
private boolean isBigEndian()
183
{
184
return getFormat().isBigEndian();
185
}
186
187
public void close() throws IOException
188
{
189
super.close();
190
m_encodedStream.close();
191
}
192
193
private class DMAISObuffer extends Obuffer
194
{
195
private int m_nChannels;
196
private byte[] m_abBuffer;
197
private int[] m_anBufferPointers;
198
private boolean m_bIsBigEndian;
199
200
public DMAISObuffer(int nChannels)
201
{
202
m_nChannels = nChannels;
203
m_abBuffer = new byte[OBUFFERSIZE * nChannels];
204
m_anBufferPointers = new int[nChannels];
205
reset();
206
m_bIsBigEndian = DecodedMpegAudioInputStream.this.isBigEndian();
207
}
208
209
public void append(int nChannel, short sValue)
210
{
211
byte bFirstByte;
212
byte bSecondByte;
213
if(m_bIsBigEndian)
214
{
215
bFirstByte = (byte) ((sValue >>> 8) & 0xFF);
216
bSecondByte = (byte) (sValue & 0xFF);
217
} else
218
// little endian
219
{
220
bFirstByte = (byte) (sValue & 0xFF);
221
bSecondByte = (byte) ((sValue >>> 8) & 0xFF);
222
}
223
m_abBuffer[m_anBufferPointers[nChannel]] = bFirstByte;
224
m_abBuffer[m_anBufferPointers[nChannel] + 1] = bSecondByte;
225
m_anBufferPointers[nChannel] += m_nChannels * 2;
226
}
227
228
public void set_stop_flag()
229
{
230
}
231
232
public void close()
233
{
234
}
235
236
public void write_buffer(int nValue)
237
{
238
}
239
240
public void clear_buffer()
241
{
242
}
243
244
public byte[] getBuffer()
245
{
246
return m_abBuffer;
247
}
248
249
public int getCurrentBufferSize()
250
{
251
return m_anBufferPointers[0];
252
}
253
254
public void reset()
255
{
256
for(int i = 0; i < m_nChannels; i++)
257
{
258
/*
259
* Points to byte location, implicitely assuming 16 bit samples.
260
*/
261
m_anBufferPointers[i] = i * 2;
262
}
263
}
264
}
265
}
266
267