Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.os.msdos.programmer > #633

Re: A (UK) celebration

From pete@nospam.demon.co.uk
Newsgroups comp.os.msdos.programmer
Subject Re: A (UK) celebration
Date 2012-06-05 13:39 +0000
Organization PDL
Message-ID <1338903545snz@nospam.demon.co.uk> (permalink)
References <1338709568snz@nospam.demon.co.uk> <jqgkir$7j5$1@speranza.aioe.org> <1338791474snz@nospam.demon.co.uk>

Show all headers | View raw


Just to put this thread to bed (for a few more years) I thought I 
would update Rod's deconstructed code to remove the obfuscation of the 
"long *" and "char *" (and modern compilers' need to explicitly cast 
them).  And also provide some support code for anyone else wanting to 
write "music" for the PC speaker.

1. Instead of the "long music[]" array, try this instead:

struct asbyte {
  unsigned char lo;
  unsigned char hi;
};

union DIVISOR {
  unsigned short w;
  struct asbyte b;
};

struct TUNE {
  union DIVISOR divisor;
  unsigned char ontime;
  unsigned char offtime;
};

initialised as:

struct TUNE music[] = {

  { { 0x08E9 }, 0x08, 0x01 },
  { { 0x08E9 }, 0x08, 0x01 },
  { { 0x07F0 }, 0x08, 0x01 },
  { { 0x096F }, 0x10, 0x01 },
  { { 0x08E9 }, 0x03, 0x01 },
  { { 0x07F0 }, 0x08, 0x02 },
  { { 0x0712 }, 0x08, 0x01 },
  { { 0x0712 }, 0x08, 0x01 },
  { { 0x06AD }, 0x08, 0x01 },
  { { 0x0712 }, 0x10, 0x01 },
  { { 0x07F0 }, 0x03, 0x01 },
  { { 0x08E9 }, 0x08, 0x02 },
  { { 0x07F0 }, 0x08, 0x01 },
  { { 0x08E9 }, 0x08, 0x01 },
  { { 0x096F }, 0x08, 0x01 },
  { { 0x08E9 }, 0x08, 0x02 },
  { { 0x08E9 }, 0x02, 0x01 },
  { { 0x07F0 }, 0x02, 0x01 },
  { { 0x0712 }, 0x02, 0x01 },
  { { 0x06AD }, 0x02, 0x02 },
  { { 0x05F1 }, 0x08, 0x01 },
  { { 0x05F1 }, 0x08, 0x01 },
  { { 0x05F1 }, 0x08, 0x01 },
  { { 0x05F1 }, 0x10, 0x01 },
  { { 0x06AD }, 0x03, 0x01 },
  { { 0x0712 }, 0x08, 0x02 },
  { { 0x06AD }, 0x08, 0x01 },
  { { 0x06AD }, 0x08, 0x01 },
  { { 0x06AD }, 0x08, 0x01 },
  { { 0x06AD }, 0x10, 0x01 },
  { { 0x0712 }, 0x03, 0x01 },
  { { 0x07F0 }, 0x08, 0x02 },
  { { 0x0712 }, 0x08, 0x01 },
  { { 0x06AD }, 0x02, 0x01 },
  { { 0x0712 }, 0x02, 0x01 },
  { { 0x07F0 }, 0x02, 0x01 },
  { { 0x08E9 }, 0x02, 0x01 },
  { { 0x0712 }, 0x10, 0x01 },
  { { 0x06AD }, 0x03, 0x01 },
  { { 0x05F1 }, 0x08, 0x02 },
  { { 0x054B }, 0x03, 0x01 },
  { { 0x06AD }, 0x03, 0x01 },
  { { 0x0712 }, 0x0C, 0x01 },
  { { 0x07F0 }, 0x0C, 0x01 },
  { { 0x08E9 }, 0x10, 0x01 },
};

#define NR_NOTES (sizeof(music)/sizeof(struct TUNE))

The note() and main() functions then become

void note(struct TUNE *song)
{
  outport(0x43,0xb6);
  outport(0x42,song->divisor.b.lo);
  outport(0x42,song->divisor.b.hi);
  outport(0x61,inport(0x61)|3);
  length(song->ontime);
  outport(0x61,inport(0x61)&~3);
  length(song->offtime);
}

int main(void)
{
  struct TUNE *play;

#ifdef __DJGPP__
  __djgpp_nearptr_enable();
#endif

  for (play = music; play < music + NR_NOTES; play++)
    note(play);

  return 0;
}

2. This program is an aid to establishing the correct timer divisor to 
produce the frequency of the desired notes:

#include <stdio.h>
#include <math.h>

double	timer_freq = 1193180.0; /* countdown timer freq */
double	middleC = 261.625;	/* frequency (Hz) of middle C */

char *octave[] = {
     "C ", "C#", "D ", "D#", "E ", "F ",
     "F#", "G ", "G#", "A ", "A#", "B "
};

#define OSIZE	(sizeof(octave)/sizeof(char *))

#define NR_OCTAVES  8   /* or however many you want */

int main()
{
  int     oct;
  double  startC;
  double  _12root2 = pow (2.0, 1.0/12.0); /* twelfth root of 2 */

  for (oct = 0, startC = middleC / 8.0; /* start 3 octaves lower */
       oct < NR_OCTAVES;
       oct++, startC *= 2.0)
  {
    int i;
    double freq = startC;

    printf ("---------\nOctave %d:\n---------\n", oct);

    for (i = 0; i < OSIZE; i++, freq *= _12root2)
    {
      double div = timer_freq / freq;
      printf ("%s freq = %7.2lf, divisor = %8.2lf [0x%04lx]\n",
                octave[i], freq, div, (long) (div + 0.5));
    }
  }
  return 0;
}

Pete
-- 
Believe those who are seeking the truth.
Doubt those who find it.  -  André Gide

Back to comp.os.msdos.programmer | Previous | NextPrevious in thread | Find similar | Unroll thread


Thread

A (UK) celebration pete@nospam.demon.co.uk - 2012-06-03 07:46 +0000
  Re: A (UK) celebration Nomen Nescio <nobody@dizum.com> - 2012-06-03 15:29 +0200
  Re: A (UK) celebration "Rod Pemberton" <do_not_have@notemailntt.cmm> - 2012-06-03 17:23 -0400
    Re: A (UK) celebration pete@nospam.demon.co.uk - 2012-06-04 06:31 +0000
      Re: A (UK) celebration pete@nospam.demon.co.uk - 2012-06-05 13:39 +0000

csiph-web