1 /* OpenCP Module Player
2  * copyright (c) '94-'10 Niklas Beisert <nbeisert@physik.tu-muenchen.de>
3  *
4  * Freqency calculation routines
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; either version 2 of the License, or
9  * (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19  *
20  * revision history: (please note changes here)
21  *  -nb980510   Niklas Beisert <nbeisert@physik.tu-muenchen.de>
22  *    -first release
23  */
24 #include "config.h"
25 #include "types.h"
26 #include "imsrtns.h"
27 
28 static uint32_t hnotetab6848[16]={11131415,4417505,1753088,695713,276094,109568,43482,17256,6848,2718,1078,428,170,67,27,11};
29 static uint32_t hnotetab8363[16]={13594045,5394801,2140928,849628,337175,133808,53102,21073,8363,3319,1317,523,207,82,33,13};
30 static uint16_t notetab[16]={32768,30929,29193,27554,26008,24548,23170,21870,20643,19484,18390,17358,16384,15464,14596,13777};
31 static uint16_t finetab[16]={32768,32650,32532,32415,32298,32182,32066,31950,31835,31720,31606,31492,31379,31266,31153,31041};
32 static uint16_t xfinetab[16]={32768,32761,32753,32746,32738,32731,32724,32716,32709,32702,32694,32687,32679,32672,32665,32657};
33 
mcpGetFreq8363(int note)34 int mcpGetFreq8363(int note)
35 {
36   note=-note;
37   return umulshr16(umulshr16(umulshr16(hnotetab8363[((note+0x8000)>>12)&0xF],notetab[(note>>8)&0xF]*2),finetab[(note>>4)&0xF]*2),xfinetab[note&0xF]*2);
38 }
39 
mcpGetFreq6848(int note)40 int mcpGetFreq6848(int note)
41 {
42   note=-note;
43   return umulshr16(umulshr16(umulshr16(hnotetab6848[((note+0x8000)>>12)&0xF],notetab[(note>>8)&0xF]*2),finetab[(note>>4)&0xF]*2),xfinetab[note&0xF]*2);
44 }
45 
mcpGetNote8363(unsigned int frq)46 int mcpGetNote8363(unsigned int frq)
47 {
48   int16_t x;
49   unsigned int i;
50   for (i=0; i<15; i++)
51     if (hnotetab8363[i+1]<frq)
52       break;
53   x=(i-8)*16*256;
54   frq=umuldiv(frq, 32768, hnotetab8363[i]);
55   for (i=0; i<15; i++)
56     if (notetab[i+1]<frq)
57       break;
58   x+=i*256;
59   frq=umuldiv(frq, 32768, notetab[i]);
60   for (i=0; i<15; i++)
61     if (finetab[i+1]<frq)
62       break;
63   x+=i*16;
64   frq=umuldiv(frq, 32768, finetab[i]);
65   for (i=0; i<15; i++)
66     if (xfinetab[i+1]<frq)
67       break;
68   return -x-i;
69 }
70 
mcpGetNote6848(unsigned int frq)71 int mcpGetNote6848(unsigned int frq)
72 {
73   int16_t x;
74   unsigned int i;
75   for (i=0; i<15; i++)
76     if (hnotetab6848[i+1]<frq)
77       break;
78   x=(i-8)*16*256;
79   frq=umuldiv(frq, 32768, hnotetab6848[i]);
80   for (i=0; i<15; i++)
81     if (notetab[i+1]<frq)
82       break;
83   x+=i*256;
84   frq=umuldiv(frq, 32768, notetab[i]);
85   for (i=0; i<15; i++)
86     if (finetab[i+1]<frq)
87       break;
88   x+=i*16;
89   frq=umuldiv(frq, 32768, finetab[i]);
90   for (i=0; i<15; i++)
91     if (xfinetab[i+1]<frq)
92       break;
93   return -x-i;
94 }
95