get rid of the stream parsing that occurs in the Layer III decoder. BitStream.readFra...
authoryeom <yeom>
Thu, 11 Aug 2011 23:48:35 +0000 (23:48 +0000)
committeryeom <yeom>
Thu, 11 Aug 2011 23:48:35 +0000 (23:48 +0000)
Robust/src/Tests/ssJava/mp3decoder/BitStreamWrapper.java [new file with mode: 0644]
Robust/src/Tests/ssJava/mp3decoder/Bitstream.java
Robust/src/Tests/ssJava/mp3decoder/Decoder.java
Robust/src/Tests/ssJava/mp3decoder/Header.java
Robust/src/Tests/ssJava/mp3decoder/LayerIIIDecoder.java
Robust/src/Tests/ssJava/mp3decoder/SideInfoBuffer.java [new file with mode: 0644]

diff --git a/Robust/src/Tests/ssJava/mp3decoder/BitStreamWrapper.java b/Robust/src/Tests/ssJava/mp3decoder/BitStreamWrapper.java
new file mode 100644 (file)
index 0000000..046be7e
--- /dev/null
@@ -0,0 +1,17 @@
+public class BitStreamWrapper {
+
+  private static Bitstream stream;
+
+  public static void init(InputStream in) {
+    stream = new Bitstream(in);
+  }
+
+  public static Header readFrame() {
+    return stream.readFrame();
+  }
+
+  public static int get_bits(int number_of_bits) {
+    return stream.get_bits(number_of_bits);
+  }
+
+}
index 82c595c..daf25e2 100644 (file)
@@ -139,6 +139,10 @@ public final class Bitstream implements BitstreamErrors {
   @LOC("FF")
   private boolean firstframe = true;
 
+  private BitReserve br;
+  private int main_data_begin;
+  private int frame_start;
+
   /**
    * Construct a IBitstream that reads data from a given InputStream.
    * 
@@ -157,6 +161,9 @@ public final class Bitstream implements BitstreamErrors {
     closeFrame();
     // current_frame_number = -1;
     // last_frame_number = -1;
+
+    br = new BitReserve();
+
   }
 
   /**
@@ -370,6 +377,47 @@ public final class Bitstream implements BitstreamErrors {
     return get_bits(n);
   }
 
+  public int peek_bits(int number_of_bits) {
+
+    int peekbitindex = bitindex;
+    int peekPointer = wordpointer;
+
+    int returnvalue = 0;
+    int sum = peekbitindex + number_of_bits;
+
+    if (peekPointer < 0) {
+      peekPointer = 0;
+    }
+
+    if (sum <= 32) {
+      // all bits contained in *wordpointer
+      returnvalue = (framebuffer[peekPointer] >>> (32 - sum)) & bitmask[number_of_bits];
+      // returnvalue = (wordpointer[0] >> (32 - sum)) &
+      // bitmask[number_of_bits];
+      if ((peekbitindex += number_of_bits) == 32) {
+        peekbitindex = 0;
+        peekPointer++; // added by me!
+      }
+      return returnvalue;
+    }
+
+    // E.B : Check that ?
+    // ((short[])&returnvalue)[0] = ((short[])wordpointer + 1)[0];
+    // wordpointer++; // Added by me!
+    // ((short[])&returnvalue + 1)[0] = ((short[])wordpointer)[0];
+    int Right = (framebuffer[peekPointer] & 0x0000FFFF);
+    peekPointer++;
+    int Left = (framebuffer[peekPointer] & 0xFFFF0000);
+    returnvalue = ((Right << 16) & 0xFFFF0000) | ((Left >>> 16) & 0x0000FFFF);
+
+    returnvalue >>>= 48 - sum; // returnvalue >>= 16 - (number_of_bits - (32
+                               // - bitindex))
+    returnvalue &= bitmask[number_of_bits];
+    peekbitindex = sum - 32;
+    return returnvalue;
+
+  }
+
   public int readCheckedBits(int n) {
     // REVIEW: implement CRC check.
     return get_bits(n);
@@ -505,7 +553,7 @@ public final class Bitstream implements BitstreamErrors {
    */
   @LATTICE("OUT<RL,RL<THIS,THIS<IN,OUT*,THISLOC=THIS,RETURNLOC=OUT")
   public int get_bits(@LOC("IN") int number_of_bits) {
-    
+
     @LOC("OUT") int returnvalue = 0;
     @LOC("THIS,Bitstream.BI") int sum = bitindex + number_of_bits;
 
@@ -613,4 +661,70 @@ public final class Bitstream implements BitstreamErrors {
     }
     return totalBytesRead;
   }
+
+  public SideInfoBuffer getSideInfoBuffer(int channelType) {
+
+    if (wordpointer < 0)
+      wordpointer = 0;
+
+    SideInfoBuffer sib = new SideInfoBuffer();
+
+    // first, store main_data_begin from the side inforamtion
+    main_data_begin = peek_bits(9);
+    System.out.println("main_data_begin=" + main_data_begin);
+
+    int max;
+    if (channelType == 1) { // mono
+      max = wordpointer + 4;
+    } else {
+      max = wordpointer + 8;
+    }
+
+    try {
+      for (; wordpointer < max; wordpointer++) {
+        sib.setBuffer(wordpointer, framebuffer[wordpointer]);
+      }
+    } catch (ArrayIndexOutOfBoundsException e) {
+      System.out.print("wordpointer=" + wordpointer);
+      System.out.println("framebuffer length=" + framebuffer.length);
+    }
+
+    return sib;
+  }
+
+  public BitReserve getBitReserve(int nSlots) {
+
+    int flush_main;
+    int bytes_to_discard;
+    int i;
+
+    for (i = 0; i < nSlots; i++)
+      br.hputbuf(get_bits(8));
+
+    int 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 - main_data_begin;
+
+    frame_start += nSlots;
+
+    if (bytes_to_discard < 0) {
+      System.out.println("HERE?");
+      return null;
+    }
+
+    if (main_data_end > 4096) {
+      frame_start -= 4096;
+      br.rewindNbytes(4096);
+    }
+
+    for (; bytes_to_discard > 0; bytes_to_discard--)
+      br.hgetbits(8);
+
+    return br;
+  }
 }
index e871eec..363e2de 100644 (file)
@@ -248,8 +248,7 @@ public class Decoder implements DecoderErrors {
     case 3:\r
       if (l3decoder == null) {\r
         l3decoder =\r
-            new LayerIIIDecoder(stream, header, filter1, filter2, output,\r
-                OutputChannels.BOTH_CHANNELS);\r
+            new LayerIIIDecoder(header, filter1, filter2, output, OutputChannels.BOTH_CHANNELS);\r
       }\r
 \r
       return l3decoder;\r
index f4cef5c..4ffcada 100644 (file)
@@ -112,6 +112,9 @@ public final class Header {
   @LOC("T")\r
   private int _headerstring = -1; // E.B\r
 \r
+  private SideInfoBuffer sib;\r
+  private BitReserve br;\r
+\r
   Header() {\r
   }\r
 \r
@@ -802,4 +805,21 @@ public final class Header {
   public int intensity_stereo_bound() {\r
     return h_intensity_stereo_bound;\r
   }\r
+\r
+  public void setSideInfoBuf(SideInfoBuffer sib) {\r
+    this.sib = sib;\r
+  }\r
+\r
+  public void setBitReserve(BitReserve br) {\r
+    this.br = br;\r
+  }\r
+\r
+  public SideInfoBuffer getSideInfoBuffer() {\r
+    return sib;\r
+  }\r
+\r
+  public BitReserve getBitReserve() {\r
+    return br;\r
+  }\r
+\r
 }\r
index 5049170..055484b 100644 (file)
@@ -72,8 +72,6 @@ final class LayerIIIDecoder implements FrameDecoder {
   private float[][] k;
   @LOC("NZ")
   private int[] nonzero;
-  @LOC("ST")
-  private Bitstream stream;
   @LOC("HD")
   private Header header;
   @LOC("FT")
@@ -114,9 +112,8 @@ final class LayerIIIDecoder implements FrameDecoder {
   // REVIEW: these constructor arguments should be moved to the
   // decodeFrame() method, where possible, so that one
   @LATTICE("THIS<VAR,THIS<I,THIS<J,J<CH,I*,J*,CH*,THISLOC=THIS,GLOBALLOC=THIS")
-  public LayerIIIDecoder(@LOC("VAR") Bitstream stream0, @LOC("VAR") Header header0,
-      @LOC("VAR") SynthesisFilter filtera, @LOC("VAR") SynthesisFilter filterb,
-      @LOC("VAR") Obuffer buffer0, @LOC("VAR") int which_ch0) {
+  public LayerIIIDecoder(@LOC("VAR") Header header0, @LOC("VAR") SynthesisFilter filtera,
+      @LOC("VAR") SynthesisFilter filterb, @LOC("VAR") Obuffer buffer0, @LOC("VAR") int which_ch0) {
 
     huffcodetab.inithuff();
     is_1d = new int[SBLIMIT * SSLIMIT + 4];
@@ -209,7 +206,6 @@ final class LayerIIIDecoder implements FrameDecoder {
     scalefac_buffer = new int[54];
     // END OF scalefac_buffer
 
-    stream = stream0;
     header = header0;
     filter1 = filtera;
     filter2 = filterb;
@@ -309,43 +305,9 @@ final class LayerIIIDecoder implements FrameDecoder {
     @LOC("THIS,LayerIIIDecoder.BR,BitReserve.BIT") int bytes_to_discard;
     @LOC("C") int i;
 
-    get_side_info();
-
-    for (i = 0; i < nSlots; i++) {
-      br.hputbuf(stream.get_bits(8));
-      // LOC(stream.get_bits)=DELTA[Loc[decode.THIS],Loc[LayerIIIDecoder.ST]]
-      // param should be higher than br
-    }
-
-    main_data_end = br.hsstell() >>> 3;
-
-    if ((flush_main = (br.hsstell() & 7)) != 0) { // flush_main < br
-      br.hgetbits(8 - flush_main); // br < flush_main
-      main_data_end++; // main_data_end*
-    }
-
-    // bytes_to_discard < GLB(frame_start,main_data_end,si)
-    bytes_to_discard = frame_start - main_data_end - si.main_data_begin;
-
-    // frame_start should be *
-    frame_start += nSlots;
-
-    if (bytes_to_discard < 0) {
-      return;
-    }
-
-    if (main_data_end > 4096) { // main_data_end should be > than 'frame_start'
-                                // and 'br'
-      frame_start -= 4096;
-      br.rewindNbytes(4096);
-    }
-
-    for (; bytes_to_discard > 0; bytes_to_discard--) {
-      // bytes_to_discard > br
-      br.hgetbits(8);
-    }
-
-    // doing something from here
+    // modifications for linear type
+    get_side_info(header.getSideInfoBuffer());
+    br = header.getBitReserve();
 
     // here 'gr' and 'max_gr' should be higher than 'ch','channels', and more
     for (gr = 0; gr < max_gr; gr++) { // two granules per channel
@@ -459,47 +421,48 @@ final class LayerIIIDecoder implements FrameDecoder {
    * 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)
    */
-  @LATTICE("OUT<THIS,THISLOC=THIS,RETURNLOC=OUT")
-  private boolean get_side_info() {
-
-    @LOC("THIS,LayerIIIDecoder.CH0") int ch;
-    @LOC("THIS,LayerIIIDecoder.CH0") int gr;
-
+  private boolean get_side_info(SideInfoBuffer sib) {
+    int ch, gr;
+    // System.out.println("#get_side_info");
     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);
-      }
+      si.main_data_begin = sib.get_bits(9);
+      if (channels == 1)
+        si.private_bits = sib.get_bits(5);
+      else
+        si.private_bits = sib.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);
+        si.ch[ch].scfsi[0] = sib.get_bits(1);
+        si.ch[ch].scfsi[1] = sib.get_bits(1);
+        si.ch[ch].scfsi[2] = sib.get_bits(1);
+        si.ch[ch].scfsi[3] = sib.get_bits(1);
       }
 
+      // System.out.println("BEFORE GR,CH");
+
       for (gr = 0; gr < 2; gr++) {
+        // System.out.println("GR=" + 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);
+          // System.out.println("CH");
+          si.ch[ch].gr[gr].part2_3_length = sib.get_bits(12);
+          si.ch[ch].gr[gr].big_values = sib.get_bits(9);
+          si.ch[ch].gr[gr].global_gain = sib.get_bits(8);
+          si.ch[ch].gr[gr].scalefac_compress = sib.get_bits(4);
+          si.ch[ch].gr[gr].window_switching_flag = sib.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].block_type = sib.get_bits(2);
+            si.ch[ch].gr[gr].mixed_block_flag = sib.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].table_select[0] = sib.get_bits(5);
+            si.ch[ch].gr[gr].table_select[1] = sib.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);
+            si.ch[ch].gr[gr].subblock_gain[0] = sib.get_bits(3);
+            si.ch[ch].gr[gr].subblock_gain[1] = sib.get_bits(3);
+            si.ch[ch].gr[gr].subblock_gain[2] = sib.get_bits(3);
 
-            // Set region_count parameters since they are implicit in this case.
+            // 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
@@ -511,47 +474,48 @@ final class LayerIIIDecoder implements FrameDecoder {
             }
             si.ch[ch].gr[gr].region1_count = 20 - si.ch[ch].gr[gr].region0_count;
           } else {
-            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].table_select[2] = stream.get_bits(5);
-            si.ch[ch].gr[gr].region0_count = stream.get_bits(4);
-            si.ch[ch].gr[gr].region1_count = stream.get_bits(3);
+            si.ch[ch].gr[gr].table_select[0] = sib.get_bits(5);
+            si.ch[ch].gr[gr].table_select[1] = sib.get_bits(5);
+            si.ch[ch].gr[gr].table_select[2] = sib.get_bits(5);
+            si.ch[ch].gr[gr].region0_count = sib.get_bits(4);
+            si.ch[ch].gr[gr].region1_count = sib.get_bits(3);
             si.ch[ch].gr[gr].block_type = 0;
           }
-          si.ch[ch].gr[gr].preflag = stream.get_bits(1);
-          si.ch[ch].gr[gr].scalefac_scale = stream.get_bits(1);
-          si.ch[ch].gr[gr].count1table_select = stream.get_bits(1);
+          si.ch[ch].gr[gr].preflag = sib.get_bits(1);
+          si.ch[ch].gr[gr].scalefac_scale = sib.get_bits(1);
+          si.ch[ch].gr[gr].count1table_select = sib.get_bits(1);
         }
       }
 
     } else { // MPEG-2 LSF, SZD: MPEG-2.5 LSF
 
-      si.main_data_begin = stream.get_bits(8);
+      si.main_data_begin = sib.get_bits(8);
       if (channels == 1)
-        si.private_bits = stream.get_bits(1);
+        si.private_bits = sib.get_bits(1);
       else
-        si.private_bits = stream.get_bits(2);
+        si.private_bits = sib.get_bits(2);
 
       for (ch = 0; ch < channels; ch++) {
 
-        si.ch[ch].gr[0].part2_3_length = stream.get_bits(12);
-        si.ch[ch].gr[0].big_values = stream.get_bits(9);
-        si.ch[ch].gr[0].global_gain = stream.get_bits(8);
-        si.ch[ch].gr[0].scalefac_compress = stream.get_bits(9);
-        si.ch[ch].gr[0].window_switching_flag = stream.get_bits(1);
+        si.ch[ch].gr[0].part2_3_length = sib.get_bits(12);
+        si.ch[ch].gr[0].big_values = sib.get_bits(9);
+        si.ch[ch].gr[0].global_gain = sib.get_bits(8);
+        si.ch[ch].gr[0].scalefac_compress = sib.get_bits(9);
+        si.ch[ch].gr[0].window_switching_flag = sib.get_bits(1);
 
         if ((si.ch[ch].gr[0].window_switching_flag) != 0) {
 
-          si.ch[ch].gr[0].block_type = stream.get_bits(2);
-          si.ch[ch].gr[0].mixed_block_flag = stream.get_bits(1);
-          si.ch[ch].gr[0].table_select[0] = stream.get_bits(5);
-          si.ch[ch].gr[0].table_select[1] = stream.get_bits(5);
+          si.ch[ch].gr[0].block_type = sib.get_bits(2);
+          si.ch[ch].gr[0].mixed_block_flag = sib.get_bits(1);
+          si.ch[ch].gr[0].table_select[0] = sib.get_bits(5);
+          si.ch[ch].gr[0].table_select[1] = sib.get_bits(5);
 
-          si.ch[ch].gr[0].subblock_gain[0] = stream.get_bits(3);
-          si.ch[ch].gr[0].subblock_gain[1] = stream.get_bits(3);
-          si.ch[ch].gr[0].subblock_gain[2] = stream.get_bits(3);
+          si.ch[ch].gr[0].subblock_gain[0] = sib.get_bits(3);
+          si.ch[ch].gr[0].subblock_gain[1] = sib.get_bits(3);
+          si.ch[ch].gr[0].subblock_gain[2] = sib.get_bits(3);
 
-          // Set region_count parameters since they are implicit in this case.
+          // Set region_count parameters since they are implicit in
+          // this case.
 
           if (si.ch[ch].gr[0].block_type == 0) {
             // Side info bad: block_type == 0 in split block
@@ -564,16 +528,16 @@ final class LayerIIIDecoder implements FrameDecoder {
           }
 
         } else {
-          si.ch[ch].gr[0].table_select[0] = stream.get_bits(5);
-          si.ch[ch].gr[0].table_select[1] = stream.get_bits(5);
-          si.ch[ch].gr[0].table_select[2] = stream.get_bits(5);
-          si.ch[ch].gr[0].region0_count = stream.get_bits(4);
-          si.ch[ch].gr[0].region1_count = stream.get_bits(3);
+          si.ch[ch].gr[0].table_select[0] = sib.get_bits(5);
+          si.ch[ch].gr[0].table_select[1] = sib.get_bits(5);
+          si.ch[ch].gr[0].table_select[2] = sib.get_bits(5);
+          si.ch[ch].gr[0].region0_count = sib.get_bits(4);
+          si.ch[ch].gr[0].region1_count = sib.get_bits(3);
           si.ch[ch].gr[0].block_type = 0;
         }
 
-        si.ch[ch].gr[0].scalefac_scale = stream.get_bits(1);
-        si.ch[ch].gr[0].count1table_select = stream.get_bits(1);
+        si.ch[ch].gr[0].scalefac_scale = sib.get_bits(1);
+        si.ch[ch].gr[0].count1table_select = sib.get_bits(1);
       } // for(ch=0; ch<channels; ch++)
     } // if (header.version() == MPEG1)
     return true;
diff --git a/Robust/src/Tests/ssJava/mp3decoder/SideInfoBuffer.java b/Robust/src/Tests/ssJava/mp3decoder/SideInfoBuffer.java
new file mode 100644 (file)
index 0000000..d3a3e1d
--- /dev/null
@@ -0,0 +1,85 @@
+public class SideInfoBuffer {
+
+       /**
+        * The frame buffer that holds the data for the current frame.
+        */
+       private final int[] framebuffer = new int[BUFFER_INT_SIZE];
+
+       /**
+        * Maximum size of the frame buffer.
+        */
+       private static final int BUFFER_INT_SIZE = 433;
+
+       /**
+        * Index into <code>framebuffer</code> where the next bits are retrieved.
+        */
+       private int wordpointer;
+
+       /**
+        * Number (0-31, from MSB to LSB) of next bit for get_bits()
+        */
+       private int bitindex;
+
+       private int main_data_begin;
+
+       public int getMain_data_begin() {
+               return main_data_begin;
+       }
+
+       public void setMain_data_begin(int main_data_begin) {
+               this.main_data_begin = main_data_begin;
+       }
+
+       private final int bitmask[] = {
+                       0, // dummy
+                       0x00000001, 0x00000003, 0x00000007, 0x0000000F, 0x0000001F,
+                       0x0000003F, 0x0000007F, 0x000000FF, 0x000001FF, 0x000003FF,
+                       0x000007FF, 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF,
+                       0x0000FFFF, 0x0001FFFF };
+
+       public int get_bits(int number_of_bits) {
+               int returnvalue = 0;
+               int sum = bitindex + number_of_bits;
+               // System.out.println("bitindex=" + bitindex + " wordpointer="
+               // + wordpointer);
+               // E.B
+               // There is a problem here, wordpointer could be -1 ?!
+               if (wordpointer < 0)
+                       wordpointer = 0;
+               // E.B : End.
+
+               if (sum <= 32) {
+                       // all bits contained in *wordpointer
+                       returnvalue = (framebuffer[wordpointer] >>> (32 - sum))
+                                       & bitmask[number_of_bits];
+                       // returnvalue = (wordpointer[0] >> (32 - sum)) &
+                       // bitmask[number_of_bits];
+                       if ((bitindex += number_of_bits) == 32) {
+                               bitindex = 0;
+                               wordpointer++; // added by me!
+                       }
+                       return returnvalue;
+               }
+
+               // E.B : Check that ?
+               // ((short[])&returnvalue)[0] = ((short[])wordpointer + 1)[0];
+               // wordpointer++; // Added by me!
+               // ((short[])&returnvalue + 1)[0] = ((short[])wordpointer)[0];
+               int Right = (framebuffer[wordpointer] & 0x0000FFFF);
+               wordpointer++;
+               int Left = (framebuffer[wordpointer] & 0xFFFF0000);
+               returnvalue = ((Right << 16) & 0xFFFF0000)
+                               | ((Left >>> 16) & 0x0000FFFF);
+
+               returnvalue >>>= 48 - sum; // returnvalue >>= 16 - (number_of_bits - (32
+                                                                       // - bitindex))
+               returnvalue &= bitmask[number_of_bits];
+               bitindex = sum - 32;
+               return returnvalue;
+       }
+
+       public void setBuffer(int idx, int value) {
+               framebuffer[idx] = value;
+       }
+
+}