ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / sound / core / seq / oss / seq_oss_misc.c
1 /*----------------------------------------------------------------
2  * miscellaneous functions
3  *----------------------------------------------------------------*/
4
5 unsigned short snd_seq_oss_semitone_tuning[24] = 
6 {
7 /*   0 */ 10000, 10595, 11225, 11892, 12599, 13348, 14142, 14983, 
8 /*   8 */ 15874, 16818, 17818, 18877, 20000, 21189, 22449, 23784, 
9 /*  16 */ 25198, 26697, 28284, 29966, 31748, 33636, 35636, 37755
10 };
11
12 unsigned short snd_seq_oss_cent_tuning[100] =
13 {
14 /*   0 */ 10000, 10006, 10012, 10017, 10023, 10029, 10035, 10041, 
15 /*   8 */ 10046, 10052, 10058, 10064, 10070, 10075, 10081, 10087, 
16 /*  16 */ 10093, 10099, 10105, 10110, 10116, 10122, 10128, 10134, 
17 /*  24 */ 10140, 10145, 10151, 10157, 10163, 10169, 10175, 10181, 
18 /*  32 */ 10187, 10192, 10198, 10204, 10210, 10216, 10222, 10228, 
19 /*  40 */ 10234, 10240, 10246, 10251, 10257, 10263, 10269, 10275, 
20 /*  48 */ 10281, 10287, 10293, 10299, 10305, 10311, 10317, 10323, 
21 /*  56 */ 10329, 10335, 10341, 10347, 10353, 10359, 10365, 10371, 
22 /*  64 */ 10377, 10383, 10389, 10395, 10401, 10407, 10413, 10419, 
23 /*  72 */ 10425, 10431, 10437, 10443, 10449, 10455, 10461, 10467, 
24 /*  80 */ 10473, 10479, 10485, 10491, 10497, 10503, 10509, 10515, 
25 /*  88 */ 10521, 10528, 10534, 10540, 10546, 10552, 10558, 10564, 
26 /*  96 */ 10570, 10576, 10582, 10589
27 };
28
29 /* convert from MIDI note to frequency */
30 int
31 snd_seq_oss_note_to_freq(int note_num)
32 {
33
34         /*
35          * This routine converts a midi note to a frequency (multiplied by 1000)
36          */
37
38         int note, octave, note_freq;
39         static int notes[] = {
40                 261632, 277189, 293671, 311132, 329632, 349232,
41                 369998, 391998, 415306, 440000, 466162, 493880
42         };
43
44 #define BASE_OCTAVE     5
45
46         octave = note_num / 12;
47         note = note_num % 12;
48
49         note_freq = notes[note];
50
51         if (octave < BASE_OCTAVE)
52                 note_freq >>= (BASE_OCTAVE - octave);
53         else if (octave > BASE_OCTAVE)
54                 note_freq <<= (octave - BASE_OCTAVE);
55
56         /*
57          * note_freq >>= 1;
58          */
59
60         return note_freq;
61 }
62
63 unsigned long
64 snd_seq_oss_compute_finetune(unsigned long base_freq, int bend, int range, int vibrato_cents)
65 {
66         unsigned long amount;
67         int negative, semitones, cents, multiplier = 1;
68
69         if (!bend || !range || !base_freq)
70                 return base_freq;
71
72         if (range >= 8192)
73                 range = 8192;
74
75         bend = bend * range / 8192;     /* Convert to cents */
76         bend += vibrato_cents;
77
78         if (!bend)
79                 return base_freq;
80
81         negative = bend < 0 ? 1 : 0;
82
83         if (bend < 0)
84                 bend *= -1;
85         if (bend > range)
86                 bend = range;
87
88         /*
89            if (bend > 2399)
90            bend = 2399;
91          */
92         while (bend > 2399) {
93                 multiplier *= 4;
94                 bend -= 2400;
95         }
96
97         semitones = bend / 100;
98         if (semitones > 99)
99                 semitones = 99;
100         cents = bend % 100;
101
102         amount = (int) (snd_seq_oss_semitone_tuning[semitones] * multiplier *
103                         snd_seq_oss_cent_tuning[cents]) / 10000;
104
105         if (negative)
106                 return (base_freq * 10000) / amount;    /* Bend down */
107         else
108                 return (base_freq * amount) / 10000;    /* Bend up */
109 }
110