/* periods.c */ /* Computes the period table */ /* $Author: Espie $ * $Date: 91/05/12 19:54:18 $ * $Revision: 1.7 $ * $Log: periods.c,v $ * Revision 1.7 91/05/12 19:54:18 Espie * Experimental find_note, handle stray periods with less space. * * Revision 1.6 91/05/06 23:34:24 Espie * New finetunes from 0 to 15 with 8 as default value. * Gives an idea that something is wrong in the window * title bar. * * Revision 1.5 91/05/05 19:07:07 Espie * *** empty log message *** * * Revision 1.4 91/05/05 15:39:58 Espie * The period_table to fill is now an argument. * * Revision 1.3 91/04/30 00:36:03 Espie * Stable version III. * * Revision 1.2 91/04/28 22:54:30 Espie * Now computes the periods. * * Revision 1.1 91/04/21 20:03:33 Espie * Initial revision * */ #include #include #include "proto.h" #include "periods.h" /* This file computes the period for all notes with all tuning. * It is also able to find a note from a given period. * Standard tuning has been moved to a middle value (8). */ /* to compute the note periods, we deal with finite precision arithmetic * note/2^precision ~ 2^(1/12), adjust/2^precision ~ 2^(1/96) */ #define precision (16) #define note 69433 #define adjust 66011 #define rounded_div(a,b) ((a+b/2)/b) #define rounded_shift(a,i) ((a+(1<<((i)-1)))>>(i)) LOCAL UWORD **lookup_table; void init_periods(UWORD **period_table) { int i, k; /* everything MUST be unsigned */ unsigned long starting_period, period; ULONG buffer[12]; lookup_table = period_table; starting_period = rounded_div(3579545, 440) < 1) { i = (a+b)/2; if (t[i] == period) return i; if (t[i] > period) a = i; else b = i; } /* at that point we have t[b]<= period <= t[a] * We want to allow for rounding errors. */ check_abort(); if (t[a] - 2 <= period) return a; if (t[b] + 2 >= period) return b; temporary_title("Read problem"); t = lookup_table[NUMBER_TUNING-1]; for (a = 1; a < t[0]; a++) if (period - t[a] <= 2 && period - t[a] >= -2) { return FINE_PERIOD + a; } t[t[0]] = period; if (t[0] >= NUMBER_NOTES - 1) return 0; return FINE_PERIOD + t[0]++; } /* remap the tuning so that 8 is now in the middle... MUCH more sensible. */ LOCAL BYTE remap_tunes[16] = {8,9,10,11,12,13,14,15,0,1,2,3,4,5,6,7}; BYTE normalize_finetune(UBYTE fine) { if (fine > 15) return -1; else return remap_tunes[fine]; }