home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / MM1 / SOUNDUTILS / mm1_tracker.lzh / TRACKER4.6 / notes.c < prev    next >
Text File  |  1994-11-24  |  3KB  |  137 lines

  1. /* notes.c 
  2.     vi:ts=3 sw=3:
  3.  */
  4.  
  5. /* $Id: notes.c,v 4.3 1994/11/15 16:11:01 espie Exp espie $
  6.  * $Log: notes.c,v $
  7.  * Revision 4.3  1994/11/15  16:11:01  espie
  8.  * *** empty log message ***
  9.  *
  10.  *
  11.  * Revision 4.0  1994/01/11  17:50:04  espie
  12.  * Makes use of autoinit. Uses less memory, starts up faster.
  13.  * auto_init'd create_notes_table(),
  14.  * suppressed note_name static table,
  15.  * use name_of_note() instead (about 120 * 8 bytes gain).
  16.  * Amiga support.
  17.  * Added finetune.
  18.  */
  19.  
  20. #include "defs.h"
  21.  
  22. #ifdef MALLOC_NOT_IN_STDLIB
  23. #include <malloc.h>
  24. #else
  25. #include <stdlib.h>
  26. #endif
  27. #include <stdio.h>
  28. #include <string.h>
  29. #include <ctype.h>
  30. #include <assert.h>
  31. #include <math.h>
  32.  
  33. #include "song.h"
  34. #include "channel.h"
  35. #include "extern.h"
  36.  
  37. ID("$Id: notes.c,v 4.3 1994/11/15 16:11:01 espie Exp espie $")
  38.  
  39.  
  40. /* we can put it autoinit since find_note is ALWAYS called
  41.  * prior to finding note values !
  42.  */
  43. LOCAL void create_notes_table P((void));
  44. LOCAL void (*INIT)P((void)) = create_notes_table;
  45.  
  46.  
  47. /* the musical notes correspond to some specific pitch.
  48.  * It's useful to be able to find them back, at least for
  49.  * arpeggii.
  50.  */
  51. short pitch_table[NUMBER_NOTES][NUMBER_FINETUNES];
  52.  
  53. LOCAL char *note_template = "C-C#D-D#E-F-F#G-G#A-A#B-";
  54.  
  55. /* find_note(pitch): find note corresponding to the stated pitch */
  56. int find_note(pitch)
  57. int pitch;
  58.    {
  59.    int a, b, i;
  60.    
  61.    INIT_ONCE;
  62.  
  63.    if (pitch == 0)
  64.       return -1;
  65.    a = 0;
  66.    b = NUMBER_NOTES-1;
  67.    while(b-a > 1)
  68.       {
  69.       i = (a+b)/2;
  70.       if (pitch_table[i][0] == pitch)
  71.          return i;
  72.       if (pitch_table[i][0] > pitch)
  73.          a = i;
  74.       else
  75.          b = i;
  76.       }
  77.    if (pitch_table[a][0] - FUZZ <= pitch)
  78.       return a;
  79.    if (pitch_table[b][0] + FUZZ >= pitch)
  80.       return b;
  81.    return NO_NOTE;
  82.    }
  83.  
  84. LOCAL void create_notes_table()
  85.    {
  86.    double base, pitch;
  87.    int i, j, k;
  88.  
  89.    for (j = -8; j < 8; j++)
  90.       {
  91.       k = j < 0 ? j + 16 : j;
  92.       base = AMIGA_CLOCKFREQ/440.0/4.0 / pow(2.0, j/96.0);
  93.  
  94.       for (i = 0; i < NUMBER_NOTES; i++)
  95.          {
  96.          pitch = base / pow(2.0, i/12.0);
  97.          pitch_table[i][k] = floor(pitch + 0.5);
  98.          }
  99.       }
  100.     }
  101.  
  102. char *name_of_note(i)
  103. int i;
  104.    {
  105.    static char name[4];
  106.  
  107.    if (i == NO_NOTE)
  108.       return "   ";
  109.    else 
  110.       {
  111.       name[0] = note_template[(i+9)%12 * 2];
  112.       name[1] = note_template[(i+9)%12 * 2 +1];
  113.       name[2] = '0' + (i-3)/12;
  114.       name[3] = 0;
  115.       return name;
  116.       }
  117.    }
  118.    
  119. int transpose_song(s, transpose)
  120. struct song *s;
  121. int transpose;
  122.    {
  123.    int oldt;
  124.    int i, j, n;
  125.  
  126.    if (!s)
  127.       return 0;
  128.    oldt = s->info.transpose;
  129.    for (n = 0; n < s->info.maxpat; n++)
  130.       for (i = 0; i < BLOCK_LENGTH; i++)
  131.          for (j = 0; j < NUMBER_TRACKS; j++)
  132.             if (s->info.pblocks[n].e[j][i].note != NO_NOTE)
  133.                s->info.pblocks[n].e[j][i].note += transpose - oldt;
  134.    s->info.transpose = transpose;
  135.    return oldt;
  136.    }
  137.