Skip to main content
Topic: Parsing ordered Codecbooks :-( (Read 1350 times) previous topic - next topic
0 Members and 1 Guest are viewing this topic.

Parsing ordered Codecbooks :-(

EDIT link to sample file

After someone notified me that AVI-Mux GUI does not read some vorbis files, I found that my parser does not handle ordered codebooks properly (I need to parse the entire header, since the information I need, the window sizes, are the very last elements), while unordered codebooks work properly.

Since the file can be played, and a file with broken codebooks would hardly be playable, I conclude that the file is valid.

Page numbers refer to the Vorbis_I_spec.pdf file now.

When trying to parse an ordered codebook, the result is that I don't have a syncword at the position where the next codebook should start. Even item 7 on page 14 { 7) if [current_entry] is greater than [codebook_entries] ERROR CONDITION;
the decoder will not be able to read this stream.
} does not work out. Even worse, I compared my code to the corresponding section in libvorbis, and I don't see any difference.

Note that I don't need the codebooks themselves, but that I just need to parse throw them to finally get the window sizes.

Here is the code which obviously does not work out:

   int i;
   packet->GetPos();
   int sync_word = packet->ReadBits(24,1);
   int codebook_dim = packet->ReadBits(16,1);
   int codebook_entries = packet->ReadBits(24,1);
   int ordered = packet->ReadBits(1,1);
   int length = 0;
   int* lengths = new int[codebook_entries];

   if (!ordered) {
      int sparse = packet->ReadBits(1,1);
      for (i=0;i<codebook_entries;i++) {
         if (sparse) {
            if (packet->ReadBits(1,1)) {
               // entry used
               length = packet->ReadBits(5,1)+1;
            }
         } else {
            length = packet->ReadBits(5,1)+1;
         }
         lengths = length;
      }
   } else {
      int current_entry = 0;
      int current_length = 1+packet->ReadBits(5,1);
      while (current_entry < codebook_entries) {
         int number = packet->ReadBits(ilog(codebook_entries - current_entry));
         current_entry += number;
         current_length++;
      }

      if (current_entry > codebook_entries) {
         Sleep(1); // B0rked !!  <= debugger breakpoint here
      }
   }

   int codebook_lookup_type = packet->ReadBits(4,1);

Since ordered codebooks work, the problem can only be someone within the indicated section, but I don't see any difference to the code of libvorbis, except that libvorbis does not report an error condition if the described algorithm on page 14 causes a violation of current_entry > codebook_entries (it rather uses an algorithm which is equivalent if the described one does not raise this error condition).

Does anyone see what is wrong in my code? Note: The currently available code on my homepage has an additional error (the line int sparse = packet->ReadBits(1,1); is misplaced, so that can't work).

More tests:
- unordered codebooks are correctly parsed with codebook_lookup_type 0 and 1. I have not yet seen a file with type 2. However, since the first codebook of the test file i got is unordered and uses codebook_lookup_type = 0, and the 2nd (ordered) codebook starts at a correct syncword, but is not parsed correctly, this cannot be the problem causing my code to malfunction.

 
SimplePortal 1.0.0 RC1 © 2008-2019