3 Ann Hell Ex Machina - Music Software
4 Copyright (C) 2003/2004 Angel Ortega <angel@triptico.com>
6 core.c - Core functions
8 This program is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 as published by the Free Software Foundation; either version 2
11 of the License, or (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 http://www.triptico.com
38 /* main output frequency */
41 /* interpolation type: 0, none; 1, linear; 2, cubic spline; 3, lagrange */
47 /* note frequencies */
48 double _middle_A_freq
=440.0;
49 static double _note_frequency
[NUM_NOTES
];
56 * note_frequency - MIDI note to frequency converter
57 * @note: the MIDI note
59 * Accepts a MIDI note number (range 0 to 127) and
60 * returns its frequency in Hz.
62 double note_frequency(int note
)
69 /* builds the table if empty */
70 if(_note_frequency
[0] == 0.0)
72 for(n
=0;n
< NUM_NOTES
;n
++)
73 _note_frequency
[n
]=(_middle_A_freq
/ 32.0) *
74 pow(2.0, (((double)n
- 9.0) / 12.0));
77 return(_note_frequency
[note
]);
82 * get_sample - Reads a sample from a wave buffer.
83 * @wave: the wave PCM data
84 * @size: size of the wave in samples
85 * @offset: sample number to be returned
87 * Returns the sample number @offset from the @wave buffer
88 * of @size size, doing interpolation if @offset
91 float get_sample(float * wave
, double size
, double offset
)
98 switch(_interpolation
)
101 /* no interpolation */
106 /* linear interpolation */
107 d
=(float)(offset
- floor(offset
));
109 if(offset
+ 1 > size
) o
=0; else o
++;
110 s2
=(wave
[o
] - s1
) * d
;
116 /* cubic spline (borrowed from timidity) */
117 if(offset
< 1 || offset
> size
- 2)
130 d
=(float)(offset
- floor(offset
));
133 ((5.0 * s3
- 11.0 * s2
+ 7.0 * s1
- s0
) / 4.0) *
134 (d
+ 1.0) * (d
- 1.0)) * d
;
137 ((5.0 * s0
- 11.0 * s1
+ 7.0 * t
- s3
) / 4.0) *
138 d
* (d
- 2.0)) * (1.0 - d
) + s2
) / 6.0;
146 /* lagrange (borrowed from timidity) */
147 if(offset
< 1 || offset
> size
- 2)
158 d
=(float)(offset
- floor(offset
));
160 s3
+= -3.0 * s2
+ 3.0 * s1
- s0
;
161 s3
*= (d
- 2.0) / 6.0;
162 s3
+= s2
- 2.0 * s1
+ s0
;
163 s3
*= (d
- 1.0) / 2.0;
179 * wave_resample - Resamples a wave.
180 * @freq: original frequency of the wave
181 * @size: size of the wave in samples
182 * @n_channels: number of channels
183 * @wave: the wave PCM data
185 * Resamples the @wave from its original @freq frequency to
186 * the global output frequency. The resampled wave is stored
189 * Returns the conversion ratio; the original size (and other
190 * pointers to the data as loop starts and ends) should be
191 * divided by this number to match the new wave.
193 double wave_resample(int freq
, double size
, int n_channels
, float * wave
[])
201 ratio
=(double) freq
/ (double) _frequency
;
202 new_size
=(int)(size
/ ratio
);
204 printf("wave_resample: ratio %f\n", (float)ratio
);
206 for(n
=0;n
< n_channels
;n
++)
209 wave
[n
]=(float *) malloc(new_size
* sizeof(float));
211 for(m
=i
=0;m
< new_size
;m
++,i
+=ratio
)
212 wave
[n
][m
]=get_sample(old_wave
, size
, i
);
214 /* free the old wave */