Skip to main content
Home Forums 68kMLA G3 Blue and White custom startup sound ROM hack -success!! — #9
Post #9 by dougg3
Source Forum68kMLA
CategoryDevelopment
Post DateTue, 3 Jul 2012 - 14:49
Original URLhttps://68kmla.org/bb/threads/g3-blue-and-white-custom-startup-sound-rom-hack-success.25758/
Post
I discovered the reason for the scratchiness -- I had a typo in my code that decodes the nibbles. I think I screwed it up when I was copying the code over from the original IMA documentation. Here's the original code:

Code:
    int diff = 0;
   if (s & 4)
       diff += step;
   if (s & 2)
       diff += step >> 1;
   if (s & 4)
       diff += step >> 2;
   diff += step >> 3;
   if (s & 
       diff = -diff;
Here's the fixed code:

Code:
    int diff = 0;
   if (s & 4)
       diff += step;
   if (s & 2)
       diff += step >> 1;
   if (s & 1)
       diff += step >> 2;
   diff += step >> 3;
   if (s & 
       diff = -diff;
Stupid typos!

Here's the fixed chime, sounding MUCH better and probably perfect. Below is the complete working code:

Code:
#include 
#include 

static const int ima_index_table[] = {
 -1, -1, -1, -1, 2, 4, 6, 8,
 -1, -1, -1, -1, 2, 4, 6, 8
}; 

static const int ima_step_table[] = { 
 7, 8, 9, 10, 11, 12, 13, 14, 16, 17, 
 19, 21, 23, 25, 28, 31, 34, 37, 41, 45, 
 50, 55, 60, 66, 73, 80, 88, 97, 107, 118, 
 130, 143, 157, 173, 190, 209, 230, 253, 279, 307,
 337, 371, 408, 449, 494, 544, 598, 658, 724, 796,
 876, 963, 1060, 1166, 1282, 1411, 1552, 1707, 1878, 2066, 
 2272, 2499, 2749, 3024, 3327, 3660, 4026, 4428, 4871, 5358,
 5894, 6484, 7132, 7845, 8630, 9493, 10442, 11487, 12635, 13899, 
 15289, 16818, 18500, 20350, 22385, 24623, 27086, 29794, 32767 
};
#define NUM_STEP_TABLE_ENTRIES (sizeof(ima_step_table)/sizeof(ima_step_table[0]))

static int predictor = 0;
static int step_index = 0;
static int step = 7;

void do_header(uint8_t h)
{
   predictor = (h << ;
   if (predictor & 0x8000)
   {
       predictor |= 0xFFFF0000;
   }
}

void do_header2(uint8_t h)
{   
   predictor |= (h & 0x80);
   step_index = h & 0x7F;

   if (step_index >= NUM_STEP_TABLE_ENTRIES)
   {
       printf("Header out of bounds\n");
       step_index = NUM_STEP_TABLE_ENTRIES - 1;
   }

   step = ima_step_table[step_index];
}

void do_sample(uint8_t s, FILE *w)
{
   step_index += ima_index_table[(uint8_t)s];
   if (step_index < 0)
   {
       printf("Sample out of bounds < 0\n");
       step_index = 0;
   }
   if (step_index >= NUM_STEP_TABLE_ENTRIES)
   {
       printf("Sample out of bounds >= %d\n", NUM_STEP_TABLE_ENTRIES);
       step_index = NUM_STEP_TABLE_ENTRIES - 1;
   }

   // Sign-extend the nibble
   if (s & 0x08){ s |= 0xF0; }

   //int diff = (s + 0.5) * step / 4;
   int diff = 0;
   if (s & 4)
       diff += step;
   if (s & 2)
       diff += step >> 1;
   if (s & 1)
       diff += step >> 2;
   diff += step >> 3;
   if (s & 
       diff = -diff;

   predictor = predictor + diff;
   if (predictor < -32768) predictor = -32768;
   if (predictor > 32767) predictor = 32767;
   step = ima_step_table[step_index];

   int16_t value = predictor;

   // This is me cheating to convert it back to big-endian for AIFF.
   // Probably don't need to do it the way I did it, but whatever...
   uint16_t tmpVal = (uint16_t)value;
   uint16_t tmpVal2 = ((tmpVal & 0xFF) <<  | (tmpVal >> ;

   fwrite(&tmpVal2, 2, 1, w);
}

int main(int argc, char *argv[])
{
  uint32_t headersFound = 0;
  uint32_t nibblesFound = 0;
  uint32_t upperHeadersFound = 0;

  FILE *f = fopen("SoundFile2.bin", "rb");
  FILE *w = fopen("SoundFile.out", "wb");
  int counter = 0;

  uint8_t s;

   while (fread(&s, 1, 1, f) > 0)
   {     
       if ((counter % 34) == 0)
       {
           do_header(s);
       }
       else if ((counter % 34) == 1)
       {
           do_header2(s);
       }
       else
       {
           uint8_t s1 = s >> 4;  // Most significant nibble
           uint8_t s2 = s & 0x0F; // Least significant nibble

           do_sample(s2, w);
           do_sample(s1, w);
       }

       counter++;
   }

   fclose(f);
   fclose(w);
}
I still get some warning printouts telling me the step index is less than 0 (which forces me to clamp it up to 0), but I think that's OK -- it's probably normal and just means the encoding wanted to keep it at 0. Anyway, great success on a Tuesday morning!

mp.ls