Re: [stella] TIA polynomials revisited

Subject: Re: [stella] TIA polynomials revisited
From: Adam Wozniak <adam@xxxxxxxxxxxxxxxx>
Date: Sun, 7 Dec 2003 07:57:42 -0800 (PST)
See if this is more palatable:


#include <stdio.h>

// sound.c
// version 0.5
//
// Copyright (c) 2003 Adam Wozniak (adam@xxxxxxxxxxxxxxxx)
// All Rights Reserved
//
// Permission granted to freely copy and use for any purpose, provided
// this copyright header remains intact.

#define DIV(name, hi, lo)                       \
int div_ ## name (void)                         \
{                                               \
   static int spot = 0;                         \
   static int count = 0;                        \
   static const int array[] = { hi, lo, -1 };   \
   static int lastval = 0;                      \
   count++;                                     \
   if (count == array[spot])                    \
   {                                            \
      spot++;                                   \
      count = 0;                                \
   }                                            \
   if (array[spot] == -1) spot = 0;             \
   if (lastval == !(spot^1))                    \
   {                                            \
      return 0;                                 \
   }                                            \
   else                                         \
   {                                            \
      lastval = !lastval;                       \
      return 1;                                 \
   }                                            \
}

#define LFSR(name, t1, t2)                                      \
int lfsr_ ## name (void)                                        \
{                                                               \
   static int lastval = 1;                                      \
   static int value = 1;                                        \
   static const int taps[] = { t1, t2 };                        \
   int next = ((value & (1 << (taps[0] - 1))) ? 1 : 0) ^        \
              ((value & (1 << (taps[1] - 1))) ? 1 : 0);         \
   value = value << 1;                                          \
   value |= next;                                               \
   if ((value & 1) == lastval)                                  \
   {                                                            \
      return 0;                                                 \
   }                                                            \
   else                                                         \
   {                                                            \
      lastval = !lastval;                                       \
      return 1;                                                 \
   }                                                            \
}

DIV(2,   1,   1);
DIV(6,   3,   3);
DIV(31,  13, 18);
LFSR(poly4,  4,   3);
LFSR(poly5,  5,   3);
LFSR(poly9,  9,   5);

int vardiv(int count)
{
   static int lastval = 1;
   static int value = 1;
   static int counter;

   counter++;
   if (counter >= count)
   {
      (value = !value);
      counter = -1;
   }

   if (value == lastval)
   {
      return 0;
   }
   else
   {
      lastval = !lastval;
      return 1;
   }
}

void TIASOUND_fill(int F, int V, int C, 
                   int infrequency, int outfrequency, int channels,
                   char *buf, int size)
{
   static int value = 1;
   static int rate = 0;

   while(size > 0)
   {
      switch (C)
      {
         case 0:
            value = 1;
            break;
         case 1:
            vardiv(F) && lfsr_poly4() && (value = !value);
            break;
         case 2:
            vardiv(F) && div_31() && lfsr_poly4() && (value = !value);
            break;
         case 3:
            vardiv(F) && lfsr_poly5() && lfsr_poly4() && (value = !value);
            break;
         case 4:
            vardiv(F) && div_2() && (value = !value);
            break;
         case 5:
            vardiv(F) && div_2() && (value = !value);
            break;
         case 6:
            vardiv(F) && div_31() && (value = !value);
            break;
         case 7:
            vardiv(F) && lfsr_poly5() && div_2() && (value = !value);
            // yes it looks different from 9, but it has the same output
            break;
         case 8:
            vardiv(F) && lfsr_poly9() && (value = !value);
            break;
         case 9:
            vardiv(F) && lfsr_poly5() && (value = !value);
            break;
         case 10:
            vardiv(F) && div_31() && (value = !value);
            break;
         case 11:
            value = 1;
            break;
         case 12:
            vardiv(F) && div_6() && (value = !value);
            break;
         case 13:
            vardiv(F) && div_6() && (value = !value);
            break;
         case 14:
            vardiv(F) && div_31() && div_6() && (value = !value);
            break;
         case 15:
            vardiv(F) && lfsr_poly5() && div_6() && (value = !value);
            break;
      }

      rate += outfrequency;

      while (rate >= infrequency && size)
      {
              *buf += value ? (V << 3) : 0;
              rate -= infrequency;

              buf += channels;
              size -= channels;
      }
   }
}

void main(int argc, char **argv)
{
        char buf[44100];
        int i;

        // usage
        if (argc != 4)
        {
           fprintf(stderr, "Usage: %s <F:0-31> <V:0-15> <C:0-15>\n", argv[0]);
           exit(-1);
        }

        // clear the buffer
        bzero(buf, sizeof(buf));

        // fill the buffer
        TIASOUND_fill(atoi(argv[1]),
                      atoi(argv[2]),
                      atoi(argv[3]),
                      31400, 44100, 1,
                      buf, sizeof(buf));

        // write it to stdout
        write(1, buf, sizeof(buf));
}

-- 
adam@xxxxxxxxxxxxxxxx        http://cuddlepuddle.org/~adam/pgp.html
Will code for food.          http://cuddlepuddle.org/~adam/resume.html
"The dinosaurs are not around today because they did not have a space program."
  -- Arthur C. Clarke

----------------------------------------------------------------------------------------------
Archives (includes files) at http://www.biglist.com/lists/stella/archives/
Unsub & more at http://www.biglist.com/lists/stella/


Current Thread