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