Pastebin launched a little side project called HostCabi.net, check it out ;-)Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on Mar 28th, 2012  |  syntax: C++  |  size: 3.02 KB  |  hits: 16  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. //! These types just make the code easier to understand
  2. //! ... for me, anyway =P
  3. typedef unsigned char      u8;  //! Unsigned 8-bit
  4. typedef unsigned short     u16; //! Unsigned 16-bit
  5. typedef unsigned int       u32; //! Unsigned 32-bit
  6. typedef unsigned long long u64; //! Unsigned 64-bit
  7.  
  8. //! Sound type
  9. typedef struct {
  10.     u32   numBlk;       //! Number of sample blocks
  11.     float pCoef[16][2]; //! Global prediction coefficients [16 pairs]
  12.  
  13.     //! Each sample block is composed of 32/8 [4] frames of sample data.
  14.     //! Each frame, in turn, is composed of 64/4 [16] sample nibbles and
  15.     //! an 8-bit header:
  16.     //!  Bit0-3: Coefficient selection
  17.     //!  Bit4-7: Shift scale
  18.     //! Basically, the 'coefficient selection' chooses the pair of
  19.     //! coefficients [from the header] that best predicts the data in
  20.     //! the frame, while the 'shift scale' provides error correction
  21.     //! scaling. [the data is in the range of -32768..+32767]
  22.     //! Since there's only 16 coefficient pairs, prediction will never
  23.     //! be exact, so there's error correction.
  24.     //! Each nibble is a value [-8..+7] that is multiplied by the shift
  25.     //! scale [which is really 2^n] in order to more closely match the
  26.     //! original sound data.
  27.     //! The data is packed in a nifty way so that it is properly aligned
  28.     //! [if you remember, a frame has an 8-bit header] to a DWORD.
  29.     struct {
  30.         u8  frameHeader[32/8]; //! 32 = sizeof(DWORD). Four frames.
  31.         u64 frameData  [32/8]; //! Ditto.
  32.     } block[];
  33. } sound_t;
  34.  
  35. //! Decoding the sample data
  36. void Decode(sound_t *snd, float *dest) {
  37.     //! storage for the last two samples [for prediction]
  38.     float old[2] = {0.f,0.f};
  39.  
  40.     //! decode each block
  41.     for(int blk = 0 ; blk < snd->numBlk ; blk++) {
  42.         //! decode each frame
  43.         for(int frm = 0 ; frm < 32/8; frm++) {
  44.             //! read frame header
  45.             u32   frameHead  = snd->block[blk].frameHeader[frm];
  46.             u32   coefSelect = frameHead & 0xF;
  47.             float errorScale = pow(2.f, (float)(frameHead>>4));
  48.  
  49.             //! read frame data
  50.             u64 frameData = snd->block[blk].frameData[frm];
  51.  
  52.             //! make a shortcut to the coefficients
  53.             //! [makes code slightly cleaner]
  54.             float *coef = snd->pCoef[coefSelect];
  55.  
  56.             //! decode each sample
  57.             for(int i = 0 ; i < 64/4; i++) {
  58.                 //! find predicted data
  59.                 float predict = coef[0]*old[0] + coef[1]*old[1];
  60.  
  61.                 //! find the sample correction data
  62.                 float corNib = (float)(frameData & 0xF) * errorScale;
  63.  
  64.                 //! find the corrected sample
  65.                 float sample = predict + corNib;
  66.  
  67.                 //! output this sample
  68.                 *dest++ = sample;
  69.  
  70.                 //! shuffle the data
  71.                 old[1] = old[0],
  72.                 old[0] = sample;
  73.  
  74.                 //! shift out the old nibble to get the next sample
  75.                 frameData >>= 4ULL;
  76.             }
  77.         }
  78.     }
  79. }