home *** CD-ROM | disk | FTP | other *** search
/ Inside Multimedia 1995 August / IMM0895.ISO01.iso / share / os2 / track061 / audio.c next >
C/C++ Source or Header  |  1992-10-27  |  5KB  |  209 lines

  1. /* audio.c */
  2.  
  3. /* modified by David Nichols for PM MOD player */
  4.  
  5. /* $Author: espie $
  6.  * $Id: audio.c,v 2.8 1991/12/03 21:24:53 espie Exp espie $
  7.  * $Revision: 2.8 $
  8.  * $Log: audio.c,v $
  9.  * Revision 2.8  1991/12/03  21:24:53  espie
  10.  * Added comments.
  11.  *
  12.  * Revision 2.7  1991/12/03  20:43:46  espie
  13.  * Added possibility to get back to MONO for the sgi.
  14.  *
  15.  * Revision 2.6  1991/12/03  18:07:38  espie
  16.  * Added stereo capabilities to the indigo version.
  17.  *
  18.  * Revision 2.5  1991/12/03  13:23:10  espie
  19.  * Minor bug: a SAMPLE_FAULT is a minor error,
  20.  * we should first check that there was no other
  21.  * error before setting it.
  22.  *
  23.  * Revision 2.4  1991/11/19  16:07:19  espie
  24.  * Added comments, moved minor stuff around.
  25.  *
  26.  * Revision 2.3  1991/11/18  14:10:30  espie
  27.  * New resample function coming from the player.
  28.  *
  29.  * Revision 2.2  1991/11/18  01:12:31  espie
  30.  * Added more notes.
  31.  *
  32.  * Revision 2.1  1991/11/17  23:07:58  espie
  33.  * Just computes some frequency-related parameters.
  34.  *
  35.  *
  36.  */
  37.  
  38. #include <math.h>
  39. #include <stdlib.h>
  40.  
  41. #include "defs.h"
  42.  
  43. /* creates a table for converting ``amiga'' pitch
  44.  * to a step rate at a given resampling frequency.
  45.  * For accuracy, we don't use floating point, but
  46.  * instead fixed point ( << ACCURACY).
  47.  */
  48.  
  49. #define ACCURACY 16
  50. #define AMIGA_CLOCKFREQ 3575872
  51.  
  52. int step_table[MAX_PITCH];
  53.  
  54.  /* holds the increment for finding the next sampled
  55.   * byte at a given pitch (see resample() ).
  56.   */
  57.  
  58. void create_step_table (int oversample, int output_fr)
  59.                         /* we sample oversample i for each byte output */
  60.                        /* output frequency */
  61. {
  62.   double note_fr;        /* note frequency (in Hz) */
  63.   double step;
  64.   int pitch;            /* amiga pitch */
  65.  
  66.   step_table[0] = 0;
  67.   for (pitch = 1; pitch < MAX_PITCH; pitch++)
  68.     {
  69.       note_fr = AMIGA_CLOCKFREQ / pitch;
  70.       /* int_to_fix(1) is the normalizing factor */
  71.       step = note_fr / output_fr * int_to_fix (1) / oversample;
  72.       step_table[pitch] = (int) step;
  73.     }
  74. }
  75.  
  76. /* the musical notes correspond to some specific pitch.
  77.  * It's useful to be able to find them back, at least for
  78.  * arpeggii.
  79.  */
  80.  
  81. int pitch_table[NUMBER_NOTES];
  82.  
  83. void create_notes_table (void)
  84. {
  85.   double base, pitch;
  86.   int i;
  87.  
  88.   base = AMIGA_CLOCKFREQ / 440;
  89.   for (i = 0; i < NUMBER_NOTES; i++)
  90.     {
  91.       pitch = base / pow (2.0, i / 12.0);
  92.       pitch_table[i] = pitch;
  93.     }
  94. }
  95.  
  96. void init_tables (int oversample, int frequency)
  97. {
  98.   create_step_table (oversample, frequency);
  99.   create_notes_table ();
  100. }
  101.  
  102. #define C fix_to_int(ch->pointer)
  103.  
  104. /* The playing mechanism itself.
  105.  * According to the current channel automata,
  106.  * we resample the instruments in real time to
  107.  * generate output.
  108.  */
  109.  
  110. void resample (struct channel *chan, int oversample, int number)
  111. {
  112.   int i;            /* sample counter */
  113.   int channel;            /* channel counter */
  114.   int sampling;            /* oversample counter */
  115.   SAMPLE sample;        /* sample from the channel */
  116.   int byte[NUMBER_TRACKS];
  117.  
  118.   /* recombinations of the various data */
  119.   struct channel *ch;
  120.  
  121.   /* check the existence of samples */
  122.   for (channel = 0; channel < NUMBER_TRACKS; channel++)
  123.     if (!chan[channel].samp->start)
  124.       {
  125.     if (!error)
  126.       error = SAMPLE_FAULT;
  127.     chan[channel].mode = DO_NOTHING;
  128.       }
  129.  
  130.   /* do the resampling, i.e., actually play sounds */
  131.   for (i = 0; i < number; i++)
  132.     {
  133.       for (channel = 0; channel < NUMBER_TRACKS; channel++)
  134.     {
  135.       byte[channel] = 0;
  136.       for (sampling = 0; sampling < oversample; sampling++)
  137.         {
  138.           ch = chan + channel;
  139.           switch (ch->mode)
  140.         {
  141.         case DO_NOTHING:
  142.           break;
  143.         case PLAY:
  144.           /* small liability: the sample may have
  145.                    * changed, and we may be out of range.
  146.                    * However, this routine is time-critical,
  147.                    * so we don't check for this very rare case.
  148.                    */
  149.           sample = ch->samp->start[C];
  150.           byte[channel] += sample * ch->volume;
  151.           ch->pointer += ch->step;
  152.           if (C >= ch->samp->length)
  153.             {
  154.               /* is there a replay ? */
  155.               if (ch->samp->rp_start)
  156.             {
  157.               ch->mode = REPLAY;
  158.               ch->pointer -= int_to_fix (ch->samp->length);
  159.             }
  160.               else
  161.             ch->mode = DO_NOTHING;
  162.             }
  163.           break;
  164.         case REPLAY:
  165.           /* small liability: the sample may have
  166.                    * changed, and we may be out of range.
  167.                    * However, this routine is time-critical,
  168.                    * so we don't check for this very rare case.
  169.                    */
  170.           sample = ch->samp->rp_start[C];
  171.           byte[channel] += sample * ch->volume;
  172.           ch->pointer += ch->step;
  173.           if (C >= ch->samp->rp_length)
  174.             ch->pointer -= int_to_fix (ch->samp->rp_length);
  175.           break;
  176.         }
  177.  
  178.         }
  179.     }
  180.       output_samples ((byte[0] + byte[3]) / oversample,
  181.               (byte[1] + byte[2]) / oversample);
  182.     }
  183.   flush_buffer ();
  184. }
  185.  
  186. /* setting up a given note */
  187.  
  188. void reset_note(struct channel *ch, int note, int pitch)
  189. {
  190.   ch->pointer = 0;
  191.   ch->mode = PLAY;
  192.   ch->pitch = pitch;
  193.   ch->step = step_table[pitch];
  194.   ch->note = note;
  195.   ch->viboffset = 0;
  196. }
  197.  
  198. /* changing the current pitch (value
  199.  * may be temporary, and not stored
  200.  * in channel pitch, for instance vibratos.
  201.  */
  202. void set_current_pitch (struct channel *ch, int pitch)
  203. {
  204.   ch->step = step_table[pitch];
  205. }
  206.  
  207.  
  208.  
  209.