?? layeriiidecoder.java
字號:
/*
* 11/19/04 1.0 moved to LGPL.
*
* 18/06/01 Michael Scheerer, Fixed bugs which causes
* negative indexes in method huffmann_decode and in method
* dequanisize_sample.
*
* 16/07/01 Michael Scheerer, Catched a bug in method
* huffmann_decode, which causes an outOfIndexException.
* Cause : Indexnumber of 24 at SfBandIndex,
* which has only a length of 22. I have simply and dirty
* fixed the index to <= 22, because I'm not really be able
* to fix the bug. The Indexnumber is taken from the MP3
* file and the origin Ma-Player with the same code works
* well.
*
* 02/19/99 Java Conversion by E.B, javalayer@javazoom.net
*-----------------------------------------------------------------------
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as published
* by the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*----------------------------------------------------------------------
*/
package javazoom.jl.decoder;
/**
* Class Implementing Layer 3 Decoder.
*
* @since 0.0
*/
final class LayerIIIDecoder implements FrameDecoder
{
final double d43 = (4.0/3.0);
public int[] scalefac_buffer;
// MDM: removed, as this wasn't being used.
//private float CheckSumOut1d = 0.0f;
private int CheckSumHuff = 0;
private int[] is_1d;
private float[][][] ro;
private float[][][] lr;
private float[] out_1d;
private float[][] prevblck;
private float[][] k;
private int[] nonzero;
private Bitstream stream;
private Header header;
private SynthesisFilter filter1, filter2;
private Obuffer buffer;
private int which_channels;
private BitReserve br;
private III_side_info_t si;
private temporaire2[] III_scalefac_t;
private temporaire2[] scalefac;
// private III_scalefac_t scalefac;
private int max_gr;
private int frame_start;
private int part2_start;
private int channels;
private int first_channel;
private int last_channel;
private int sfreq;
/**
* Constructor.
*/
// REVIEW: these constructor arguments should be moved to the
// decodeFrame() method, where possible, so that one
public LayerIIIDecoder(Bitstream stream0, Header header0,
SynthesisFilter filtera, SynthesisFilter filterb,
Obuffer buffer0, int which_ch0)
{
huffcodetab.inithuff();
is_1d = new int[SBLIMIT*SSLIMIT+4];
ro = new float[2][SBLIMIT][SSLIMIT];
lr = new float[2][SBLIMIT][SSLIMIT];
out_1d = new float[SBLIMIT*SSLIMIT];
prevblck = new float[2][SBLIMIT*SSLIMIT];
k = new float[2][SBLIMIT*SSLIMIT];
nonzero = new int[2];
//III_scalefact_t
III_scalefac_t = new temporaire2[2];
III_scalefac_t[0] = new temporaire2();
III_scalefac_t[1] = new temporaire2();
scalefac = III_scalefac_t;
// L3TABLE INIT
sfBandIndex = new SBI[9]; // SZD: MPEG2.5 +3 indices
int[] l0 = {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576};
int[] s0 = {0,4,8,12,18,24,32,42,56,74,100,132,174,192};
int[] l1 = {0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576};
int[] s1 = {0,4,8,12,18,26,36,48,62,80,104,136,180,192};
int[] l2 = {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576};
int[] s2 = {0,4,8,12,18,26,36,48,62,80,104,134,174,192};
int[] l3 = {0,4,8,12,16,20,24,30,36,44,52,62,74,90,110,134,162,196,238,288,342,418,576};
int[] s3 = {0,4,8,12,16,22,30,40,52,66,84,106,136,192};
int[] l4 = {0,4,8,12,16,20,24,30,36,42,50,60,72,88,106,128,156,190,230,276,330,384,576};
int[] s4 = {0,4,8,12,16,22,28,38,50,64,80,100,126,192};
int[] l5 = {0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576};
int[] s5 = {0,4,8,12,16,22,30,42,58,78,104,138,180,192};
// SZD: MPEG2.5
int[] l6 = {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576};
int[] s6 = {0,4,8,12,18,26,36,48,62,80,104,134,174,192};
int[] l7 = {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576};
int[] s7 = {0,4,8,12,18,26,36,48,62,80,104,134,174,192};
int[] l8 = {0,12,24,36,48,60,72,88,108,132,160,192,232,280,336,400,476,566,568,570,572,574,576};
int[] s8 = {0,8,16,24,36,52,72,96,124,160,162,164,166,192};
sfBandIndex[0]= new SBI(l0,s0);
sfBandIndex[1]= new SBI(l1,s1);
sfBandIndex[2]= new SBI(l2,s2);
sfBandIndex[3]= new SBI(l3,s3);
sfBandIndex[4]= new SBI(l4,s4);
sfBandIndex[5]= new SBI(l5,s5);
//SZD: MPEG2.5
sfBandIndex[6]= new SBI(l6,s6);
sfBandIndex[7]= new SBI(l7,s7);
sfBandIndex[8]= new SBI(l8,s8);
// END OF L3TABLE INIT
if(reorder_table == null) { // SZD: generate LUT
reorder_table = new int[9][];
for(int i = 0; i < 9; i++)
reorder_table[i] = reorder(sfBandIndex[i].s);
}
// Sftable
int[] ll0 = {0, 6, 11, 16, 21};
int[] ss0 = {0, 6, 12};
sftable = new Sftable(ll0,ss0);
// END OF Sftable
// scalefac_buffer
scalefac_buffer = new int[54];
// END OF scalefac_buffer
stream = stream0;
header = header0;
filter1 = filtera;
filter2 = filterb;
buffer = buffer0;
which_channels = which_ch0;
frame_start = 0;
channels = (header.mode() == Header.SINGLE_CHANNEL) ? 1 : 2;
max_gr = (header.version() == Header.MPEG1) ? 2 : 1;
sfreq = header.sample_frequency() +
((header.version() == Header.MPEG1) ? 3 :
(header.version() == Header.MPEG25_LSF) ? 6 : 0); // SZD
if (channels == 2)
{
switch (which_channels)
{
case OutputChannels.LEFT_CHANNEL:
case OutputChannels.DOWNMIX_CHANNELS:
first_channel = last_channel = 0;
break;
case OutputChannels.RIGHT_CHANNEL:
first_channel = last_channel = 1;
break;
case OutputChannels.BOTH_CHANNELS:
default:
first_channel = 0;
last_channel = 1;
break;
}
}
else
{
first_channel = last_channel = 0;
}
for(int ch=0;ch<2;ch++)
for (int j=0; j<576; j++)
prevblck[ch][j] = 0.0f;
nonzero[0] = nonzero[1] = 576;
br = new BitReserve();
si = new III_side_info_t();
}
/**
* Notify decoder that a seek is being made.
*/
public void seek_notify()
{
frame_start = 0;
for(int ch=0;ch<2;ch++)
for (int j=0; j<576; j++)
prevblck[ch][j] = 0.0f;
br = new BitReserve();
}
public void decodeFrame()
{
decode();
}
/**
* Decode one frame, filling the buffer with the output samples.
*/
// subband samples are buffered and passed to the
// SynthesisFilter in one go.
private float[] samples1 = new float[32];
private float[] samples2 = new float[32];
public void decode()
{
int nSlots = header.slots();
int flush_main;
int gr, ch, ss, sb, sb18;
int main_data_end;
int bytes_to_discard;
int i;
get_side_info();
for (i=0; i<nSlots; i++)
br.hputbuf(stream.get_bits(8));
main_data_end = br.hsstell() >>> 3; // of previous frame
if ((flush_main = (br.hsstell() & 7)) != 0) {
br.hgetbits(8 - flush_main);
main_data_end++;
}
bytes_to_discard = frame_start - main_data_end
- si.main_data_begin;
frame_start += nSlots;
if (bytes_to_discard < 0)
return;
if (main_data_end > 4096) {
frame_start -= 4096;
br.rewindNbytes(4096);
}
for (; bytes_to_discard > 0; bytes_to_discard--)
br.hgetbits(8);
for (gr=0;gr<max_gr;gr++) {
for (ch=0; ch<channels; ch++) {
part2_start = br.hsstell();
if (header.version() == Header.MPEG1)
get_scale_factors(ch, gr);
else // MPEG-2 LSF, SZD: MPEG-2.5 LSF
get_LSF_scale_factors(ch, gr);
huffman_decode(ch, gr);
// System.out.println("CheckSum HuffMan = " + CheckSumHuff);
dequantize_sample(ro[ch], ch, gr);
}
stereo(gr);
if ((which_channels == OutputChannels.DOWNMIX_CHANNELS) && (channels > 1))
do_downmix();
for (ch=first_channel; ch<=last_channel; ch++) {
reorder(lr[ch], ch, gr);
antialias(ch, gr);
//for (int hb = 0;hb<576;hb++) CheckSumOut1d = CheckSumOut1d + out_1d[hb];
//System.out.println("CheckSumOut1d = "+CheckSumOut1d);
hybrid(ch, gr);
//for (int hb = 0;hb<576;hb++) CheckSumOut1d = CheckSumOut1d + out_1d[hb];
//System.out.println("CheckSumOut1d = "+CheckSumOut1d);
for (sb18=18;sb18<576;sb18+=36) // Frequency inversion
for (ss=1;ss<SSLIMIT;ss+=2)
out_1d[sb18 + ss] = -out_1d[sb18 + ss];
if ((ch == 0) || (which_channels == OutputChannels.RIGHT_CHANNEL)) {
for (ss=0;ss<SSLIMIT;ss++) { // Polyphase synthesis
sb = 0;
for (sb18=0; sb18<576; sb18+=18) {
samples1[sb] = out_1d[sb18+ss];
//filter1.input_sample(out_1d[sb18+ss], sb);
sb++;
}
filter1.input_samples(samples1);
filter1.calculate_pcm_samples(buffer);
}
} else {
for (ss=0;ss<SSLIMIT;ss++) { // Polyphase synthesis
sb = 0;
for (sb18=0; sb18<576; sb18+=18) {
samples2[sb] = out_1d[sb18+ss];
//filter2.input_sample(out_1d[sb18+ss], sb);
sb++;
}
filter2.input_samples(samples2);
filter2.calculate_pcm_samples(buffer);
}
}
} // channels
} // granule
// System.out.println("Counter = ................................."+counter);
//if (counter < 609)
//{
counter++;
buffer.write_buffer(1);
//}
//else if (counter == 609)
//{
// buffer.close();
// counter++;
//}
//else
//{
//}
}
/**
* Reads the side info from the stream, assuming the entire.
* frame has been read already.
* Mono : 136 bits (= 17 bytes)
* Stereo : 256 bits (= 32 bytes)
*/
private boolean get_side_info()
{
int ch, gr;
if (header.version() == Header.MPEG1)
{
si.main_data_begin = stream.get_bits(9);
if (channels == 1)
si.private_bits = stream.get_bits(5);
else si.private_bits = stream.get_bits(3);
for (ch=0; ch<channels; ch++) {
si.ch[ch].scfsi[0] = stream.get_bits(1);
si.ch[ch].scfsi[1] = stream.get_bits(1);
si.ch[ch].scfsi[2] = stream.get_bits(1);
si.ch[ch].scfsi[3] = stream.get_bits(1);
}
for (gr=0; gr<2; gr++) {
for (ch=0; ch<channels; ch++) {
si.ch[ch].gr[gr].part2_3_length = stream.get_bits(12);
si.ch[ch].gr[gr].big_values = stream.get_bits(9);
si.ch[ch].gr[gr].global_gain = stream.get_bits(8);
si.ch[ch].gr[gr].scalefac_compress = stream.get_bits(4);
si.ch[ch].gr[gr].window_switching_flag = stream.get_bits(1);
if ((si.ch[ch].gr[gr].window_switching_flag) != 0) {
si.ch[ch].gr[gr].block_type = stream.get_bits(2);
si.ch[ch].gr[gr].mixed_block_flag = stream.get_bits(1);
si.ch[ch].gr[gr].table_select[0] = stream.get_bits(5);
si.ch[ch].gr[gr].table_select[1] = stream.get_bits(5);
si.ch[ch].gr[gr].subblock_gain[0] = stream.get_bits(3);
si.ch[ch].gr[gr].subblock_gain[1] = stream.get_bits(3);
si.ch[ch].gr[gr].subblock_gain[2] = stream.get_bits(3);
// Set region_count parameters since they are implicit in this case.
if (si.ch[ch].gr[gr].block_type == 0) {
// Side info bad: block_type == 0 in split block
return false;
} else if (si.ch[ch].gr[gr].block_type == 2
&& si.ch[ch].gr[gr].mixed_block_flag == 0) {
si.ch[ch].gr[gr].region0_count = 8;
} else {
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -