1 /*(LGPL) 2 --------------------------------------------------------------------------- 3 a_agw.h - "Algorithmically Generated Waveform" file support 4 --------------------------------------------------------------------------- 5 * Copyright (C) 2002, 2003, David Olofson 6 * 7 * This program is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU Lesser General Public License as published by 9 * the Free Software Foundation; either version 2.1 of the License, or (at 10 * your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public License 18 * along with this program; if not, write to the Free Software Foundation, 19 * Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 20 */ 21 22 /* 23 * The AGW v0.1 file format: 24 * 25 * This extension to the EEL language makes it possible 26 * to use EEL scripts to construct waveforms using the 27 * "Waveform Construction API" of the engine. 28 * 29 * Why!? 30 * Well, pages of hard-coded calls to the Waveform 31 * Construction API and recompiling for every turn 32 * while creating sounds got boring, so I decided to 33 * hack up something simple to get cleaner code and 34 * faster sound editing. 35 * 36 * Over a few weeks, the file format turned into an 37 * interpreted language, which I eventually cleaned up 38 * and separated from the engine. This language is 39 * called "EEL" - Extensible Embeddable Language, and 40 * is not tied to the audio engine. 41 * 42 * Built-in commands: 43 * // 44 * C++ style comment. 45 * 46 */ /* ... */ 47 /* C style comment. 48 * 49 * w_reset; 50 * Resets the AGW engine state to the default. 51 * This is done automatically before a script 52 * is executed after being loaded with w_load(). 53 * See below for default settings for w_env etc. 54 * 55 * w_format <wid>, <sformat>, <samplerate>; 56 * Set format of <wid> to <sformat>; 57 * <samplerate> samples per second. 58 * 59 * Supported sample formats: 60 * MONO8 STEREO8 61 * MONO16 STEREO16 62 * 63 * w_blank <wid>, <samples>, <loop>; 64 * Create <samples> samples of silent data 65 * for waveform <wid>. <loop> can be either 0 66 * or 1, and if it's 1, the waveform will be 67 * set up for looping playback. 68 * 69 * w_env <mod_target>[, <time>, <level>[, <time>, <level>...]]; 70 * w_env <mod_target>, <level>; 71 * Program the envelope generator modulating 72 * <mod_target> with the specified points. 73 * Times are in seconds, and levels are in Hz 74 * for frequency envelopes, while for other 75 * envelopes, 1.0 corresponds to 0 dB, "no 76 * change" etc. 77 * 78 * Calling w_env with two arguments sets up 79 * modulator 'mod_target' to the fixed level of 80 * the second argument - which obviously is *not* 81 * a duration in this case. 82 * 83 * Calling w_env with no other arguments than 84 * 'mod_target' resets the envelope generator 85 * for that destination to the default. 86 * 87 * Available modulation targets: 88 * (Defaults are constant levels.) 89 * 90 * Name Controls Default 91 * --------------------------------------------- 92 * AMPLITUDE Amplitude 1.0 93 * BALANCE Mixing control 0.0 94 * FREQUENCY f0/cut-off 100.0 95 * LIMIT Max overtone freq. 100000.0 96 * MOD1 PW ratio/FM depth/... 0.0 97 * MOD2 Various stuff... 0.0 98 * MOD3 Various stuff... 0.0 99 * 100 TODO: 101 * w_env_taper <mod_target>, <x_coeff>[, <x2_coeff>[, <x3_coeff>]]; 102 * Set transformation of the envelope for target 103 * 'mod_target' to the function: 104 * 105 * out = in * x_coeff + 106 * in*in * x2_coeff + 107 * in*in*in * x3_coeff; 108 * 109 * Examples: 110 * w_env_taper FREQUENCY, 1; 111 * w_env_taper AMPLITUDE, .5, .25, .25; 112 * 113 * w_mod <destination>, <frequency>, <amplitude>, <depth>; 114 * If f(t) is the envelope as defined with 115 * audio_wave_env(), and w(t) is the modulator phase, 116 * the final result will be 117 * 118 * sin(w(t)) * amplitude + f(t) * (1.0 + sin(w(t)) * depth) 119 * 120 * That is, the modulation will add a sine with 121 * 'amplitude' to the envelope, and it will also add 122 * a sine with an amplitude of 'depth', scaled by 123 * the envelope. (Or if you will, the second component 124 * offset by +1.0 will modulate the envelope.) 125 * 126 * w_osc <wid>, <waveform>, <mode>; 127 * Apply a sound using <mode> to waveform <wid>, 128 * generated using a <waveform> oscillator. 129 * Various parameters of the oscillator may 130 * be modulated. 131 * 132 * Available modes: 133 * WCA_ADD Add oscillator output to buffer 134 * WCA_MUL AM or ring modulate output with buffer 135 * ==> BALANCE: 0 ==> no effect 136 * 0.5 ==> AM 137 * 1.0 ==> Ring modulation 138 * 139 * WCA_FM FM oscillator with buffer, then overwrite 140 * the buffer with the result. Note that 141 * it's *not* the buffer that is modulated! 142 * ==> BALANCE controls FM depth. 143 * 144 * WCA_FM_ADD Like AMM_FM, but adds the result to the 145 * buffer instead of overwriting it. 146 * ==> BALANCE controls FM depth. 147 * 148 * WCA_SYNC Reset oscillator phase when a + -> - 149 * zero crossing is detected in the 150 * buffer. Overwrites the buffer with the 151 * result. 152 * 153 * WCA_SYNC_ADD Like AMM_SYNC, but adds the result to 154 * the buffer instead of overwriting it. 155 * 156 * Available waveforms: 157 * DC Add DC offset 158 * 159 * SINE 160 * ==> MOD1 sets 1.0f FM depth 161 * 162 * HALFSINE Half wave rectified sine 163 * ==> MOD1 sets zero clip level 164 * 165 * RECTSINE Full wave rectified sine 166 * ==> MOD1 sets zero limit level 167 * 168 * PULSE Oversampled PWM pulse oscillator. 169 * ==> MOD1 sets pulse width; 0.5 <==> square 170 * 171 * TRIANGLE 172 * ==> MOD1 ==> ramp up...tri...ramp down 173 * 174 * SINEMORPH Sine/square/sawtooth morph, using 175 * recursive FM. If the sum of MOD1 and 176 * MOD2 exceeds 1.0, they are balanced 177 * and scaled to restrict the total to 178 * 1.0 while preserving the saw/square 179 * ratio. MOD1 and MOD2 are also scaled 180 * according to the FREQUENCY/LIMIT 181 * ratio, to approximate bandlimiting. 182 * ==> MOD1 sets saw "amount" 183 * ==> MOD2 sets square "amount" 184 * 185 * BLMORPH Bandlimited sine/saw/square/triangle 186 * oscillator, based on additive synthesis 187 * using a bank of sine oscillators. 188 * The harmonics for the respective 189 * waveforms are scaled by MOD1, MOD2 and 190 * MOD3, and then are summed. The output 191 * is bandlimited to the frequency set by 192 * LIMIT, with a roll-off giving a 193 * harmonic at LIMIT a 12 dB attenuation. 194 * ==> MOD1 modulates sawtooth harmonics 195 * ==> MOD2 modulates square harmonics 196 * ==> MOD3 modulates triangle harmonics 197 * 198 * BLCROSS Bandlimited sine/saw/square/triangle 199 * oscillator, based on additive synthesis 200 * using a bank of sine oscillators. 201 * The harmonics for the respective 202 * waveforms are bandlimited by the 203 * respective MODn mapped from [0, 1] to 204 * [FREQUENCY, LIMIT], with a roll-off 205 * towards the high end, giving the 206 * highest harmonic of each waveform a 207 * 12 dB attenuation. 208 * ==> MOD1 controls sawtooth cut-off 209 * ==> MOD2 controls square cut-off 210 * ==> MOD3 controls triangle cut-off 211 * 212 * NOISE "White" noise (6581/SID style :-) 213 * The noise is generated by a pseudo 214 * random number generator that is polled 215 * for a new value at a rate of 2 * f, to 216 * achieve a minimum period corresponding 217 * to FREQUENCY. The pseudo random number 218 * generator is reset at the start of the 219 * waveform, to guarantee consistent 220 * results. (Obviously, this means that 221 * applying noise more than once is rather 222 * pointless, as it would just increase 223 * the amplitude!) 224 * ==> MOD1 sets *non-bandlimited* LP cutoff 225 * 226 * SPECTRUM Multiplying frequency spectrum. 227 * Overtone frequencies are calculated by 228 * recursively multiplying with MOD1. 229 * ==> f[n] = f[n-1] * MOD1 230 * ==> a[n] = a[n-1] * MOD2 231 * 232 * ASPECTRUM Adding frequency spectrum. MOD1 is 233 * the distance in Hz between adjacent 234 * overtones. As you might expect, an 235 * ASPECTRUM usually *will* hit the 236 * maximum # of overtones limit, unless 237 * you track it with LIMIT properly! 238 * ==> f[n] = f[n-1] + MOD1 239 * ==> a[n] = a[n-1] * MOD2 240 * 241 * HSPECTRUM Harmonic frequency spectrum with 242 * separate modulation of even and odd 243 * harmonics. 244 * ==> f[n] = f[1] * n 245 * ==> (Even n) a[n] = a[n-1] * MOD1 246 * ==> (Odd n) a[n] = a[n-1] * MOD2 247 * 248 * PHSPECTRUM Pseudo-Harmonic frequency spectrum. 249 * Basically a HSPECTRUM, where you 250 * redefine "harmonic" using MOD1. :-) 251 * MOD2 and MOD3 control even and odd 252 * harmonics respectively. 253 * ==> f[n] = f[1] * n * MOD1 254 * ==> (Even n) a[n] = a[n-1] * MOD2 255 * ==> (Odd n) a[n] = a[n-1] * MOD3 256 * 257 * w_filter <wid>, <type>; 258 * Apply filter of <type> to waveform <wid>. 259 * 260 * Supported filter types: 261 * ALLPASS (Currently a NOP) 262 * LOWPASS_6 263 * HIGHPASS_6 264 * LOWPASS_12 265 * HIGHPASS_12 266 * BANDPASS_12 267 * NOTCH_12 268 * PEAK_12 269 * 270 * w_gain <wid>; 271 * Scale the amplitude of waveform <wid> using the 272 * AMPLITUDE envelope. 273 * 274 * 275 * w_load <wid>, <filename>, <looped>; 276 * 277 * WARNING: This command is recursive! 278 * 279 * Load waveform, or load and execute AGW file 280 * <filename>, and put the result in waveform 281 * <wid>. It's recommended to pass either 282 * 'target', something calculated from 'target' 283 * (when loading "banks" of sounds), or 'tempN' 284 * for <wid>, although it's possible (but usually 285 * very nasty!) to specify your own waveform IDs. 286 FIXME: 287 The 'looped' argument is a remainder of the 288 old engine code, and should be replaced with 289 something sensible. 290 * 291 * Note that in the current implementation, there 292 * is no notion of "scope" - "loading" an AGW 293 * script from within another AGW script treats 294 * all variables as globals in all respects. 295 * 296 * w_save <wid>, <filename>; 297 * Save the rendered waveform 'wid' as 'filename'. 298 * 299 * w_convert <from_wid>, <to_wid>, <format>[, <rate>[, <resamp>]]; 300 * Convert 'from_wid' into 'format' and 'rate' 301 * using resampling method 'resamp' and render the 302 * result into 'to_wid'. Leaving out the rate, or 303 * setting it to 0 keeps the original rate. Leaving 304 * out 'inter' uses the generally best interpolation 305 * method available. 306 * 307 * Supported resampling methods: 308 * NEAREST Nearest sample ("useless") 309 * NEAREST4X Nearest with 4x oversampling 310 * LINEAR Linear Interpolation 311 * LINEAR2X LI w/ 2x oversampling 312 * LINEAR4X LI w/ 4x oversampling 313 * LINEAR8X LI w/ 8x oversampling 314 * LINEAR16X LI w/ 16x oversampling 315 * CUBIC Cubic interpolation 316 * 317 * WORST Worst available method 318 * MEDIUM Good performance/quality 319 * BEST Best available method 320 * 321 * w_enhance <wid>, <from_f>, <level>; 322 * 323 * w_gate <wid>, <cutoff>, <min>, <threshold>, <attenuation>; 324 * 325 * (See eel/eel.h for commands that are part of EEL.) 326 * 327 * w_mix <from_wid>, <to_wid>; 328 * Mix waveform <from_wid> into waveform <to_wid>. 329 * The amplitude envelope controls the mixing 330 * level, and the frequency envelope controls the 331 * playback frequency of the source waveform. 332 * 333 */ 334 335 #ifndef _A_AGW_H_ 336 #define _A_AGW_H_ 337 338 #ifdef __cplusplus 339 extern "C" { 340 #endif 341 342 int agw_open(void); 343 void agw_close(void); 344 345 /* 346 * Load and parse AGW script 'name', 347 * suggesting that the result be put 348 * in waveform 'wid'. 349 * 350 * Returns the actual id of the generated 351 * waveform, or -1 upon failure. 352 */ 353 int agw_load(int wid, const char *name); 354 355 #ifdef __cplusplus 356 }; 357 #endif 358 359 #endif /* _A_AGW_H_ */ 360