1 /*(LGPL)
2 ---------------------------------------------------------------------------
3 	a_voice.h - Audio Engine low level mixer voices
4 ---------------------------------------------------------------------------
5  * Copyright (C) 2001, 2002, 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  * How To Keep Track Of Your Voices (for patch programmers):
24  *	Before doing anything with a Voice, first check that it
25  *	still actually *is* your voice, and hasn't been stolen
26  *	by some one else. The 'channel' field will indicate this,
27  *	of course, but that's actually only half a solution!
28  *
29  *	Why? Well, if you're doing somethingn polyphonic, the
30  *	Voice allocator may steal *your* voices, just as any other
31  *	voices, which is why it's quite possible to lose voices to
32  *	your own channel.
33  *
34  *	To deal with this, each Voice has a 'tag' field that you
35  *	may use in any way you see fit. The idea is to write a
36  *	"locally unique" code into the 'tag' field whenever you
37  *	get a "new" voice from the allocator. That way, you can
38  *	just check that value later on, to see whether or not the
39  *	channel is still doing what you told it to, or if you or
40  *	someone else has started a new job on it.
41  *
42  *	As an example, MIDI code may store MIDI pitch in the
43  *	'tag' field upon NoteOn, as there can usually only be one
44  *	"voice context" (one or more voices) active for each MIDI
45  *	key of each MIDI channel. When receiving other messages,
46  *	just check for each voice before you touch, that 1) it's
47  *	still owned by the engine Channel the MIDI channel is
48  *	mapped to. When you eventually get the NoteOff, 2) check
49  *	that the 'tag' fields of voices match the MIDI pitch of
50  *	the NoteOff message.
51  *
52  *	Note that as long as everyone sticks with their own
53  *	Channels, it's ok to use the 'tag' fields in different
54  *	ways in the same engine, at the same time. Checking
55  *	'channel' fields *first* will avoid any confusion.
56  */
57 
58 #ifndef _A_VOICE_H_
59 #define _A_VOICE_H_
60 
61 #include "a_globals.h"
62 #include "a_types.h"
63 #include "a_events.h"
64 #include "a_patch.h"
65 
66 
67 typedef enum voice_states_t
68 {
69 	VS_STOPPED = 0,		/* "Detached" from the mixer */
70 	VS_RESERVED,		/* Just allocated; pending events */
71 	VS_PLAYING		/* Playing! */
72 } voice_states_t;
73 
74 
75 typedef enum voice_events_t
76 {
77 	VE_START = 0,		/* Start playing waveform <arg1>. */
78 	VE_STOP,		/* Stop and free voice, flush events.
79 				 * This *will* click unless you fade out first!
80 				 * NOTE: The voice disappears in a puff of
81 				 *       violet smoke after receiving this
82 				 *       event! Any subsequent events will
83 				 *       be deleted and IGNORED.
84 				 */
85 	VE_SET,			/* Set control <index> to <arg1>. */
86 //	VE_ISET,		/* Set interpolated control <index> to <arg1>. */
87 	VE_IRAMP		/* Ramp interpolated control <index> to <arg1>
88 				 * over <arg2> frames.
89 				 */
90 } voice_events_t;
91 
92 
93 /* Voice Controls that are *not* interpolated. */
94 typedef enum voice_controls_t
95 {
96 	VC_WAVE = 0,		/* (int) Waveform index (latched on loop) */
97 	VC_LOOP,		/* (boolean) */
98 
99 	VC_PITCH,		/* (fixp) linear frequency; int <==> MIDI */
100 
101 	VC_RETRIG,		/* (int) retrig after N samples */
102 	VC_RANDTRIG,		/* (fixp[0, 1]) random mod. to RETRIG */
103 
104 	VC_PRIM_BUS,		/* (int) target bus for ACC_VOLUME */
105 	VC_SEND_BUS,		/* (int) target bus for ACC_SEND */
106 
107 	VC_RESAMPLE,		/* (enum) Resampling mode */
108 
109 	VC_COUNT
110 } voice_controls_t;
111 
112 /* Voice Controls that *are* interpolated. */
113 typedef enum voice_icontrols_t
114 {
115 	VIC_LVOL = 0,		/* (fixp) Left volume */
116 	VIC_RVOL,		/* (fixp) Right volume */
117 	VIC_LSEND,		/* (fixp) Left send */
118 	VIC_RSEND,		/* (fixp) Right send */
119 
120 	VIC_COUNT
121 } voice_icontrols_t;
122 
123 
124 /* Voice control interpolator */
125 typedef struct voice_ci_t
126 {
127 	int	v;
128 	int	dv;
129 } voice_ci_t;
130 
131 
132 struct audio_channel_t;
133 
134 typedef struct audio_voice_t
135 {
136 	/* Voice Management */
137 	struct audio_voice_t *next;	/* For channel voice list */
138 	struct audio_voice_t *prev;
139 	struct audio_channel_t *channel;
140 	int		tag;		/* tag from patch */
141 	int		priority;	/* Stealing priority (from owner) */
142 
143 	/* Non-interpolated Controls */
144 	int		c[VC_COUNT];
145 
146 	/* Interpolated Controls */
147 	voice_ci_t	ic[VIC_COUNT];
148 
149 	/* Event Control */
150 	aev_port_t	port;		/* Event input port */
151 
152 	/* Oscillator */
153 	voice_states_t	state;
154 	int		wave;
155 	unsigned int	section_end;	/* index of section end point */
156 	unsigned int	position;	/* current pos, integer part */
157 	unsigned int	position_frac;	/* current pos, fractional part */
158 	unsigned int	step;		/* position inc per output frame */
159 #ifdef AUDIO_USE_VU
160 	int		vu;	/* Pre-volume, linear peak, [0, 65535].
161 				 * Reset or fade after reading!
162 				 */
163 #endif
164 	/* Output routing control */
165 	int		use_double;	/* Use double output mixers */
166 	int		fx1, fx2;	/* FX send bus indices */
167 
168 	patch_closure_t	closure;	/* Per-voice data for patch */
169 } audio_voice_t;
170 
171 /* Get a free voice, or steal one if necessary. */
172 int voice_alloc(struct audio_channel_t *c);
173 
174 /*
175  * The *real*, brutal stop action.
176  * No mercy. No click elimination.
177  * Use only in case of emergency.
178  */
179 void voice_kill(audio_voice_t *v);
180 
181 /* Dirty crap function used to "wake a voice up" if needed... */
182 void voice_check_retrig(audio_voice_t *v);
183 
184 /*
185  * Mix 'frames' stereo samples into one or more of the 'busses',
186  * as specified by the voice's output controls.
187  *
188  * (Can be driven directly "from outside" the engine. The Waveform
189  * Construction API does this for resampling/conversion, for example.)
190  */
191 void voice_process_mix(audio_voice_t *v, int *busses[], unsigned frames);
192 
193 /* Process all voices. Simple, eh? */
194 void voice_process_all(int *busses[], unsigned frames);
195 
196 void audio_voice_open(void);
197 void audio_voice_close(void);
198 
199 #endif /*_A_VOICE_H_*/
200