1 //
2 // /home/ms/source/sidplay/libsidplay/emu/RCS/mixing.cpp,v
3 //
4
5 #include "mytypes.h"
6 #include "opstruct.h"
7 #include "samples.h"
8
9
10 extern sidOperator optr1, optr2, optr3; // -> 6581_.cpp
11 extern uword voice4_gainLeft, voice4_gainRight;
12
13
14 static const int maxLogicalVoices = 4;
15
16 static const int mix8monoMiddleIndex = 256*maxLogicalVoices/2;
17 static ubyte mix8mono[256*maxLogicalVoices];
18
19 static const int mix8stereoMiddleIndex = 256*(maxLogicalVoices/2)/2;
20 static ubyte mix8stereo[256*(maxLogicalVoices/2)];
21
22 static const int mix16monoMiddleIndex = 256*maxLogicalVoices/2;
23 static uword mix16mono[256*maxLogicalVoices];
24
25 static const int mix16stereoMiddleIndex = 256*(maxLogicalVoices/2)/2;
26 static uword mix16stereo[256*(maxLogicalVoices/2)];
27
28 sbyte *signedPanMix8 = 0;
29 sword *signedPanMix16 = 0;
30
31 static ubyte zero8bit; // ``zero''-sample
32 static uword zero16bit; // either signed or unsigned
33 udword splitBufferLen;
34
35 void* fill8bitMono( void* buffer, udword numberOfSamples );
36 void* fill8bitMonoControl( void* buffer, udword numberOfSamples );
37 void* fill8bitStereo( void* buffer, udword numberOfSamples );
38 void* fill8bitStereoControl( void* buffer, udword numberOfSamples );
39 void* fill8bitStereoSurround( void* buffer, udword numberOfSamples );
40 void* fill8bitSplit( void* buffer, udword numberOfSamples );
41 void* fill16bitMono( void* buffer, udword numberOfSamples );
42 void* fill16bitMonoControl( void* buffer, udword numberOfSamples );
43 void* fill16bitStereo( void* buffer, udword numberOfSamples );
44 void* fill16bitStereoControl( void* buffer, udword numberOfSamples );
45 void* fill16bitStereoSurround( void* buffer, udword numberOfSamples );
46 void* fill16bitSplit( void* buffer, udword numberOfSamples );
47
48
MixerInit(bool threeVoiceAmplify,ubyte zero8,uword zero16)49 void MixerInit(bool threeVoiceAmplify, ubyte zero8, uword zero16)
50 {
51 zero8bit = zero8;
52 zero16bit = zero16;
53
54 long si;
55 uword ui;
56
57 long ampDiv = maxLogicalVoices;
58 if (threeVoiceAmplify)
59 {
60 ampDiv = (maxLogicalVoices-1);
61 }
62
63 // Mixing formulas are optimized by sample input value.
64
65 si = (-128*maxLogicalVoices);
66 for (ui = 0; ui < sizeof(mix8mono); ui++ )
67 {
68 mix8mono[ui] = (ubyte)(si/ampDiv) + zero8bit;
69 si++;
70 }
71
72 si = (-128*maxLogicalVoices); // optimized by (/2 *2);
73 for (ui = 0; ui < sizeof(mix8stereo); ui++ )
74 {
75 mix8stereo[ui] = (ubyte)(si/ampDiv) + zero8bit;
76 si+=2;
77 }
78
79 si = (-128*maxLogicalVoices) * 256;
80 for (ui = 0; ui < sizeof(mix16mono)/sizeof(uword); ui++ )
81 {
82 mix16mono[ui] = (uword)(si/ampDiv) + zero16bit;
83 si+=256;
84 }
85
86 si = (-128*maxLogicalVoices) * 256; // optimized by (/2 * 512)
87 for (ui = 0; ui < sizeof(mix16stereo)/sizeof(uword); ui++ )
88 {
89 mix16stereo[ui] = (uword)(si/ampDiv) + zero16bit;
90 si+=512;
91 }
92 }
93
94
syncEm()95 inline void syncEm()
96 {
97 extern sbyte waveCalcNormal(sidOperator* pVoice);
98 extern sbyte waveCalcRangeCheck(sidOperator* pVoice);
99 optr1.cycleLenCount--;
100 optr2.cycleLenCount--;
101 optr3.cycleLenCount--;
102 bool sync1 = (optr1.modulator->cycleLenCount <= 0);
103 bool sync2 = (optr2.modulator->cycleLenCount <= 0);
104 bool sync3 = (optr3.modulator->cycleLenCount <= 0);
105 if (optr1.sync && sync1)
106 {
107 optr1.cycleLenCount = 0;
108 optr1.outProc = &waveCalcNormal;
109 #if defined(DIRECT_FIXPOINT)
110 optr1.waveStep.l = 0;
111 #else
112 optr1.waveStep = (optr1.waveStepPnt = 0);
113 #endif
114 }
115 if (optr2.sync && sync2)
116 {
117 optr2.cycleLenCount = 0;
118 optr2.outProc = &waveCalcNormal;
119 #if defined(DIRECT_FIXPOINT)
120 optr2.waveStep.l = 0;
121 #else
122 optr2.waveStep = (optr2.waveStepPnt = 0);
123 #endif
124 }
125 if (optr3.sync && sync3)
126 {
127 optr3.cycleLenCount = 0;
128 optr3.outProc = &waveCalcNormal;
129 #if defined(DIRECT_FIXPOINT)
130 optr3.waveStep.l = 0;
131 #else
132 optr3.waveStep = (optr3.waveStepPnt = 0);
133 #endif
134 }
135 }
136
137
138 //
139 // -------------------------------------------------------------------- 8-bit
140 //
141
fill8bitMono(void * buffer,udword numberOfSamples)142 void* fill8bitMono( void* buffer, udword numberOfSamples )
143 {
144 ubyte* buffer8bit = (ubyte*)buffer;
145 for ( ; numberOfSamples > 0; numberOfSamples-- )
146 {
147 *buffer8bit++ = mix8mono[(unsigned)(mix8monoMiddleIndex
148 +(*optr1.outProc)(&optr1)
149 +(*optr2.outProc)(&optr2)
150 +(*optr3.outProc)(&optr3)
151 +(*sampleEmuRout)())];
152 syncEm();
153 }
154 return buffer8bit;
155 }
156
fill8bitMonoControl(void * buffer,udword numberOfSamples)157 void* fill8bitMonoControl( void* buffer, udword numberOfSamples )
158 {
159 ubyte* buffer8bit = (ubyte*)buffer;
160 for ( ; numberOfSamples > 0; numberOfSamples-- )
161 {
162 *buffer8bit++ = zero8bit
163 +signedPanMix8[optr1.gainLeft+(*optr1.outProc)(&optr1)]
164 +signedPanMix8[optr2.gainLeft+(*optr2.outProc)(&optr2)]
165 +signedPanMix8[optr3.gainLeft+(*optr3.outProc)(&optr3)]
166 +signedPanMix8[voice4_gainLeft+(*sampleEmuRout)()];
167 syncEm();
168 }
169 return buffer8bit;
170 }
171
fill8bitStereo(void * buffer,udword numberOfSamples)172 void* fill8bitStereo( void* buffer, udword numberOfSamples )
173 {
174 ubyte* buffer8bit = (ubyte*)buffer;
175 for ( ; numberOfSamples > 0; numberOfSamples-- )
176 {
177 // left
178 *buffer8bit++ = mix8stereo[(unsigned)(mix8stereoMiddleIndex
179 +(*optr1.outProc)(&optr1)
180 +(*optr3.outProc)(&optr3))];
181 // right
182 *buffer8bit++ = mix8stereo[(unsigned)(mix8stereoMiddleIndex
183 +(*optr2.outProc)(&optr2)
184 +(*sampleEmuRout)())];
185 syncEm();
186 }
187 return buffer8bit;
188 }
189
fill8bitStereoControl(void * buffer,udword numberOfSamples)190 void* fill8bitStereoControl( void* buffer, udword numberOfSamples )
191 {
192 ubyte* buffer8bit = (ubyte*)buffer;
193 sbyte voice1data, voice2data, voice3data, voice4data;
194 for ( ; numberOfSamples > 0; numberOfSamples-- )
195 {
196 voice1data = (*optr1.outProc)(&optr1);
197 voice2data = (*optr2.outProc)(&optr2);
198 voice3data = (*optr3.outProc)(&optr3);
199 voice4data = (*sampleEmuRout)();
200 // left
201 *buffer8bit++ = zero8bit
202 +signedPanMix8[optr1.gainLeft+voice1data]
203 +signedPanMix8[optr2.gainLeft+voice2data]
204 +signedPanMix8[optr3.gainLeft+voice3data]
205 +signedPanMix8[voice4_gainLeft+voice4data];
206 // right
207 *buffer8bit++ = zero8bit
208 +signedPanMix8[optr1.gainRight+voice1data]
209 +signedPanMix8[optr2.gainRight+voice2data]
210 +signedPanMix8[optr3.gainRight+voice3data]
211 +signedPanMix8[voice4_gainRight+voice4data];
212 syncEm();
213 }
214 return buffer8bit;
215 }
216
fill8bitStereoSurround(void * buffer,udword numberOfSamples)217 void* fill8bitStereoSurround( void* buffer, udword numberOfSamples )
218 {
219 ubyte* buffer8bit = (ubyte*)buffer;
220 sbyte voice1data, voice2data, voice3data, voice4data;
221 for ( ; numberOfSamples > 0; numberOfSamples-- )
222 {
223 voice1data = (*optr1.outProc)(&optr1);
224 voice2data = (*optr2.outProc)(&optr2);
225 voice3data = (*optr3.outProc)(&optr3);
226 voice4data = (*sampleEmuRout)();
227 // left
228 *buffer8bit++ = zero8bit
229 +signedPanMix8[optr1.gainLeft+voice1data]
230 +signedPanMix8[optr2.gainLeft+voice2data]
231 +signedPanMix8[optr3.gainLeft+voice3data]
232 +signedPanMix8[voice4_gainLeft+voice4data];
233 // right
234 *buffer8bit++ = zero8bit
235 -signedPanMix8[optr1.gainRight+voice1data]
236 -signedPanMix8[optr2.gainRight+voice2data]
237 -signedPanMix8[optr3.gainRight+voice3data]
238 -signedPanMix8[voice4_gainRight+voice4data];
239 syncEm();
240 }
241 return buffer8bit;
242 }
243
fill8bitSplit(void * buffer,udword numberOfSamples)244 void* fill8bitSplit( void* buffer, udword numberOfSamples )
245 {
246 ubyte* v1buffer8bit = (ubyte*)buffer;
247 ubyte* v2buffer8bit = v1buffer8bit + splitBufferLen;
248 ubyte* v3buffer8bit = v2buffer8bit + splitBufferLen;
249 ubyte* v4buffer8bit = v3buffer8bit + splitBufferLen;
250 for ( ; numberOfSamples > 0; numberOfSamples-- )
251 {
252 *v1buffer8bit++ = zero8bit+(*optr1.outProc)(&optr1);
253 *v2buffer8bit++ = zero8bit+(*optr2.outProc)(&optr2);
254 *v3buffer8bit++ = zero8bit+(*optr3.outProc)(&optr3);
255 *v4buffer8bit++ = zero8bit+(*sampleEmuRout)();
256 syncEm();
257 }
258 return v1buffer8bit;
259 }
260
261 //
262 // ------------------------------------------------------------------- 16-bit
263 //
264
fill16bitMono(void * buffer,udword numberOfSamples)265 void* fill16bitMono( void* buffer, udword numberOfSamples )
266 {
267 sword* buffer16bit = (sword*)buffer;
268 for ( ; numberOfSamples > 0; numberOfSamples-- )
269 {
270 *buffer16bit++ = mix16mono[(unsigned)(mix16monoMiddleIndex
271 +(*optr1.outProc)(&optr1)
272 +(*optr2.outProc)(&optr2)
273 +(*optr3.outProc)(&optr3)
274 +(*sampleEmuRout)())];
275 syncEm();
276 }
277 return buffer16bit;
278 }
279
fill16bitMonoControl(void * buffer,udword numberOfSamples)280 void* fill16bitMonoControl( void* buffer, udword numberOfSamples )
281 {
282 sword* buffer16bit = (sword*)buffer;
283 for ( ; numberOfSamples > 0; numberOfSamples-- )
284 {
285 *buffer16bit++ = zero16bit
286 +signedPanMix16[optr1.gainLeft+(*optr1.outProc)(&optr1)]
287 +signedPanMix16[optr2.gainLeft+(*optr2.outProc)(&optr2)]
288 +signedPanMix16[optr3.gainLeft+(*optr3.outProc)(&optr3)]
289 +signedPanMix16[voice4_gainLeft+(*sampleEmuRout)()];
290 syncEm();
291 }
292 return buffer16bit;
293 }
294
fill16bitStereo(void * buffer,udword numberOfSamples)295 void* fill16bitStereo( void* buffer, udword numberOfSamples )
296 {
297 sword* buffer16bit = (sword*)buffer;
298 for ( ; numberOfSamples > 0; numberOfSamples-- )
299 {
300 // left
301 *buffer16bit++ = mix16stereo[(unsigned)(mix16stereoMiddleIndex
302 +(*optr1.outProc)(&optr1)
303 +(*optr3.outProc)(&optr3))];
304 // right
305 *buffer16bit++ = mix16stereo[(unsigned)(mix16stereoMiddleIndex
306 +(*optr2.outProc)(&optr2)
307 +(*sampleEmuRout)())];
308 syncEm();
309 }
310 return buffer16bit;
311 }
312
fill16bitStereoControl(void * buffer,udword numberOfSamples)313 void* fill16bitStereoControl( void* buffer, udword numberOfSamples )
314 {
315 sword* buffer16bit = (sword*)buffer;
316 sbyte voice1data, voice2data, voice3data, voice4data;
317 for ( ; numberOfSamples > 0; numberOfSamples-- )
318 {
319 voice1data = (*optr1.outProc)(&optr1);
320 voice2data = (*optr2.outProc)(&optr2);
321 voice3data = (*optr3.outProc)(&optr3);
322 voice4data = (*sampleEmuRout)();
323 // left
324 *buffer16bit++ = zero16bit
325 +signedPanMix16[optr1.gainLeft+voice1data]
326 +signedPanMix16[optr2.gainLeft+voice2data]
327 +signedPanMix16[optr3.gainLeft+voice3data]
328 +signedPanMix16[voice4_gainLeft+voice4data];
329 // right
330 *buffer16bit++ = zero16bit
331 +signedPanMix16[optr1.gainRight+voice1data]
332 +signedPanMix16[optr2.gainRight+voice2data]
333 +signedPanMix16[optr3.gainRight+voice3data]
334 +signedPanMix16[voice4_gainRight+voice4data];
335 syncEm();
336 }
337 return buffer16bit;
338 }
339
fill16bitStereoSurround(void * buffer,udword numberOfSamples)340 void* fill16bitStereoSurround( void* buffer, udword numberOfSamples )
341 {
342 sword* buffer16bit = (sword*)buffer;
343 sbyte voice1data, voice2data, voice3data, voice4data;
344 for ( ; numberOfSamples > 0; numberOfSamples-- )
345 {
346 voice1data = (*optr1.outProc)(&optr1);
347 voice2data = (*optr2.outProc)(&optr2);
348 voice3data = (*optr3.outProc)(&optr3);
349 voice4data = (*sampleEmuRout)();
350 // left
351 *buffer16bit++ = zero16bit
352 +signedPanMix16[optr1.gainLeft+voice1data]
353 +signedPanMix16[optr2.gainLeft+voice2data]
354 +signedPanMix16[optr3.gainLeft+voice3data]
355 +signedPanMix16[voice4_gainLeft+voice4data];
356 // right
357 *buffer16bit++ = zero16bit
358 -signedPanMix16[optr1.gainRight+voice1data]
359 -signedPanMix16[optr2.gainRight+voice2data]
360 -signedPanMix16[optr3.gainRight+voice3data]
361 -signedPanMix16[voice4_gainRight+voice4data];
362 syncEm();
363 }
364 return buffer16bit;
365 }
366
fill16bitSplit(void * buffer,udword numberOfSamples)367 void* fill16bitSplit( void* buffer, udword numberOfSamples )
368 {
369 sword* v1buffer16bit = (sword*)buffer;
370 sword* v2buffer16bit = v1buffer16bit + splitBufferLen;
371 sword* v3buffer16bit = v2buffer16bit + splitBufferLen;
372 sword* v4buffer16bit = v3buffer16bit + splitBufferLen;
373 for ( ; numberOfSamples > 0; numberOfSamples-- )
374 {
375 *v1buffer16bit++ = zero16bit+((*optr1.outProc)(&optr1)<<8);
376 *v2buffer16bit++ = zero16bit+((*optr2.outProc)(&optr2)<<8);
377 *v3buffer16bit++ = zero16bit+((*optr3.outProc)(&optr3)<<8);
378 *v4buffer16bit++ = zero16bit+((*sampleEmuRout)()<<8);
379 syncEm();
380 }
381 return v1buffer16bit;
382 }
383