00001
00002
00003
00004
00005
00006
00007 #include "samples.h"
00008 #include "6581_.h"
00009 #include "mixing.h"
00010
00011
00012
00013
00014
00015 #define optr1 (iTheSidEmu->optr1)
00016
00017 #define optr2 (iTheSidEmu->optr2)
00018 #define optr3 (iTheSidEmu->optr3)
00019
00020 #define voice4_gainLeft iTheSidEmu->voice4_gainLeft
00021 #define voice4_gainRight iTheSidEmu->voice4_gainRight
00022
00023
00024 Mixer::Mixer(emuEngine* aEmuEngine, sidEmu* aSidEmu)
00025 :iTheSidEmu(aSidEmu)
00026 ,signedPanMix8(0)
00027 ,signedPanMix16(0)
00028 {
00029 CTOR(Mixer);
00030
00031 sidEmuFillFunc = &Mixer::fill8bitMono;
00032
00033 iTheSampler = iTheSidEmu->iTheSampler;
00034 }
00035
00036 Mixer::~Mixer()
00037 {
00038 DTOR(Mixer);
00039 iTheSampler = NULL;
00040 }
00041
00042 void Mixer::MixerInit(bool threeVoiceAmplify, ubyte zero8, uword zero16)
00043 {
00044 zero8bit = zero8;
00045 zero16bit = zero16;
00046
00047 long si;
00048 uword ui;
00049
00050 long ampDiv = maxLogicalVoices;
00051 if (threeVoiceAmplify)
00052 {
00053 ampDiv = (maxLogicalVoices-1);
00054 }
00055
00056
00057
00058 si = (-128*maxLogicalVoices);
00059 for (ui = 0; ui < sizeof(mix8mono); ui++ )
00060 {
00061 mix8mono[ui] = (ubyte)(si/ampDiv) + zero8bit;
00062 si++;
00063 }
00064
00065 si = (-128*maxLogicalVoices);
00066 for (ui = 0; ui < sizeof(mix8stereo); ui++ )
00067 {
00068 mix8stereo[ui] = (ubyte)(si/ampDiv) + zero8bit;
00069 si+=2;
00070 }
00071
00072 si = (-128*maxLogicalVoices) * 256;
00073 for (ui = 0; ui < sizeof(mix16mono)/sizeof(uword); ui++ )
00074 {
00075 mix16mono[ui] = (uword)(si/ampDiv) + zero16bit;
00076 si+=256;
00077 }
00078
00079 si = (-128*maxLogicalVoices) * 256;
00080 for (ui = 0; ui < sizeof(mix16stereo)/sizeof(uword); ui++ )
00081 {
00082 mix16stereo[ui] = (uword)(si/ampDiv) + zero16bit;
00083 si+=512;
00084 }
00085 }
00086
00087
00088 inline void Mixer::syncEm()
00089 {
00090 optr1.cycleLenCount--;
00091 optr2.cycleLenCount--;
00092 optr3.cycleLenCount--;
00093 bool sync1 = (optr1.modulator->cycleLenCount <= 0);
00094 bool sync2 = (optr2.modulator->cycleLenCount <= 0);
00095 bool sync3 = (optr3.modulator->cycleLenCount <= 0);
00096 if (optr1.sync && sync1)
00097 {
00098 optr1.cycleLenCount = 0;
00099 optr1.outProc = &sidEmu::waveCalcNormal;
00100 #if defined(DIRECT_FIXPOINT)
00101 optr1.waveStep.l = 0;
00102 #else
00103 optr1.waveStep = (optr1.waveStepPnt = 0);
00104 #endif
00105 }
00106 if (optr2.sync && sync2)
00107 {
00108 optr2.cycleLenCount = 0;
00109 optr2.outProc = &sidEmu::waveCalcNormal;
00110 #if defined(DIRECT_FIXPOINT)
00111 optr2.waveStep.l = 0;
00112 #else
00113 optr2.waveStep = (optr2.waveStepPnt = 0);
00114 #endif
00115 }
00116 if (optr3.sync && sync3)
00117 {
00118 optr3.cycleLenCount = 0;
00119 optr3.outProc = &sidEmu::waveCalcNormal;
00120 #if defined(DIRECT_FIXPOINT)
00121 optr3.waveStep.l = 0;
00122 #else
00123 optr3.waveStep = (optr3.waveStepPnt = 0);
00124 #endif
00125 }
00126 }
00127
00128
00129
00130
00131
00132
00133 void* Mixer::fill8bitMono( void* buffer, udword numberOfSamples )
00134 {
00135 ubyte* buffer8bit = (ubyte*)buffer;
00136 for ( ; numberOfSamples > 0; numberOfSamples-- )
00137 {
00138 *buffer8bit++ = mix8mono[(unsigned)(mix8monoMiddleIndex
00139 +(iTheSidEmu->*optr1.outProc)(&optr1)
00140 +(iTheSidEmu->*optr2.outProc)(&optr2)
00141 +(iTheSidEmu->*optr3.outProc)(&optr3)
00142 +(iTheSampler->*(iTheSampler->sampleEmuRout))())];
00143 syncEm();
00144 }
00145 return buffer8bit;
00146 }
00147
00148 void* Mixer::fill8bitMonoControl( void* buffer, udword numberOfSamples )
00149 {
00150 ubyte* buffer8bit = (ubyte*)buffer;
00151 for ( ; numberOfSamples > 0; numberOfSamples-- )
00152 {
00153 *buffer8bit++ = zero8bit
00154 +signedPanMix8[optr1.gainLeft+(iTheSidEmu->*optr1.outProc)(&optr1)]
00155 +signedPanMix8[optr2.gainLeft+(iTheSidEmu->*optr2.outProc)(&optr2)]
00156 +signedPanMix8[optr3.gainLeft+(iTheSidEmu->*optr3.outProc)(&optr3)]
00157 +signedPanMix8[voice4_gainLeft+(iTheSampler->*(iTheSampler->sampleEmuRout))()];
00158 syncEm();
00159 }
00160 return buffer8bit;
00161 }
00162
00163 void* Mixer::fill8bitStereo( void* buffer, udword numberOfSamples )
00164 {
00165 ubyte* buffer8bit = (ubyte*)buffer;
00166 for ( ; numberOfSamples > 0; numberOfSamples-- )
00167 {
00168
00169 *buffer8bit++ = mix8stereo[(unsigned)(mix8stereoMiddleIndex
00170 +(iTheSidEmu->*optr1.outProc)(&optr1)
00171 +(iTheSidEmu->*optr3.outProc)(&optr3))];
00172
00173 *buffer8bit++ = mix8stereo[(unsigned)(mix8stereoMiddleIndex
00174 +(iTheSidEmu->*optr2.outProc)(&optr2)
00175 +(iTheSampler->*(iTheSampler->sampleEmuRout))())];
00176 syncEm();
00177 }
00178 return buffer8bit;
00179 }
00180
00181 void* Mixer::fill8bitStereoControl( void* buffer, udword numberOfSamples )
00182 {
00183 ubyte* buffer8bit = (ubyte*)buffer;
00184 sbyte voice1data, voice2data, voice3data, voice4data;
00185 for ( ; numberOfSamples > 0; numberOfSamples-- )
00186 {
00187 voice1data = (iTheSidEmu->*optr1.outProc)(&optr1);
00188 voice2data = (iTheSidEmu->*optr2.outProc)(&optr2);
00189 voice3data = (iTheSidEmu->*optr3.outProc)(&optr3);
00190 voice4data = (iTheSampler->*(iTheSampler->sampleEmuRout))();
00191
00192 *buffer8bit++ = zero8bit
00193 +signedPanMix8[optr1.gainLeft+voice1data]
00194 +signedPanMix8[optr2.gainLeft+voice2data]
00195 +signedPanMix8[optr3.gainLeft+voice3data]
00196 +signedPanMix8[voice4_gainLeft+voice4data];
00197
00198 *buffer8bit++ = zero8bit
00199 +signedPanMix8[optr1.gainRight+voice1data]
00200 +signedPanMix8[optr2.gainRight+voice2data]
00201 +signedPanMix8[optr3.gainRight+voice3data]
00202 +signedPanMix8[voice4_gainRight+voice4data];
00203 syncEm();
00204 }
00205 return buffer8bit;
00206 }
00207
00208 void* Mixer::fill8bitStereoSurround( void* buffer, udword numberOfSamples )
00209 {
00210 ubyte* buffer8bit = (ubyte*)buffer;
00211 sbyte voice1data, voice2data, voice3data, voice4data;
00212 for ( ; numberOfSamples > 0; numberOfSamples-- )
00213 {
00214 voice1data = (iTheSidEmu->*optr1.outProc)(&optr1);
00215 voice2data = (iTheSidEmu->*optr2.outProc)(&optr2);
00216 voice3data = (iTheSidEmu->*optr3.outProc)(&optr3);
00217 voice4data = (iTheSampler->*(iTheSampler->sampleEmuRout))();
00218
00219 *buffer8bit++ = zero8bit
00220 +signedPanMix8[optr1.gainLeft+voice1data]
00221 +signedPanMix8[optr2.gainLeft+voice2data]
00222 +signedPanMix8[optr3.gainLeft+voice3data]
00223 +signedPanMix8[voice4_gainLeft+voice4data];
00224
00225 *buffer8bit++ = zero8bit
00226 -signedPanMix8[optr1.gainRight+voice1data]
00227 -signedPanMix8[optr2.gainRight+voice2data]
00228 -signedPanMix8[optr3.gainRight+voice3data]
00229 -signedPanMix8[voice4_gainRight+voice4data];
00230 syncEm();
00231 }
00232 return buffer8bit;
00233 }
00234
00235 void* Mixer::fill8bitsplit( void* buffer, udword numberOfSamples )
00236 {
00237 ubyte* v1buffer8bit = (ubyte*)buffer;
00238 ubyte* v2buffer8bit = v1buffer8bit + iTheSidEmu->splitBufferLen;
00239 ubyte* v3buffer8bit = v2buffer8bit + iTheSidEmu->splitBufferLen;
00240 ubyte* v4buffer8bit = v3buffer8bit + iTheSidEmu->splitBufferLen;
00241 for ( ; numberOfSamples > 0; numberOfSamples-- )
00242 {
00243 *v1buffer8bit++ = zero8bit+(iTheSidEmu->*optr1.outProc)(&optr1);
00244 *v2buffer8bit++ = zero8bit+(iTheSidEmu->*optr2.outProc)(&optr2);
00245 *v3buffer8bit++ = zero8bit+(iTheSidEmu->*optr3.outProc)(&optr3);
00246 *v4buffer8bit++ = zero8bit+(iTheSampler->*(iTheSampler->sampleEmuRout))();
00247 syncEm();
00248 }
00249 return v1buffer8bit;
00250 }
00251
00252
00253
00254
00255
00256 void* Mixer::fill16bitMono( void* buffer, udword numberOfSamples )
00257 {
00258 sword* buffer16bit = (sword*)buffer;
00259 for ( ; numberOfSamples > 0; numberOfSamples-- )
00260 {
00261 *buffer16bit++ = mix16mono[(unsigned)(mix16monoMiddleIndex
00262 +(iTheSidEmu->*optr1.outProc)(&optr1)
00263 +(iTheSidEmu->*optr2.outProc)(&optr2)
00264 +(iTheSidEmu->*optr3.outProc)(&optr3)
00265 +(iTheSampler->*(iTheSampler->sampleEmuRout))())];
00266 syncEm();
00267 }
00268 return buffer16bit;
00269 }
00270
00271 void* Mixer::fill16bitMonoControl( void* buffer, udword numberOfSamples )
00272 {
00273 sword* buffer16bit = (sword*)buffer;
00274 for ( ; numberOfSamples > 0; numberOfSamples-- )
00275 {
00276 *buffer16bit++ = zero16bit
00277 +signedPanMix16[optr1.gainLeft+(iTheSidEmu->*optr1.outProc)(&optr1)]
00278 +signedPanMix16[optr2.gainLeft+(iTheSidEmu->*optr2.outProc)(&optr2)]
00279 +signedPanMix16[optr3.gainLeft+(iTheSidEmu->*optr3.outProc)(&optr3)]
00280 +signedPanMix16[voice4_gainLeft+(iTheSampler->*(iTheSampler->sampleEmuRout))()];
00281 syncEm();
00282 }
00283 return buffer16bit;
00284 }
00285
00286 void* Mixer::fill16bitStereo( void* buffer, udword numberOfSamples )
00287 {
00288 sword* buffer16bit = (sword*)buffer;
00289 for ( ; numberOfSamples > 0; numberOfSamples-- )
00290 {
00291
00292 *buffer16bit++ = mix16stereo[(unsigned)(mix16stereoMiddleIndex
00293 +(iTheSidEmu->*optr1.outProc)(&optr1)
00294 +(iTheSidEmu->*optr3.outProc)(&optr3))];
00295
00296 *buffer16bit++ = mix16stereo[(unsigned)(mix16stereoMiddleIndex
00297 +(iTheSidEmu->*optr2.outProc)(&optr2)
00298 +(iTheSampler->*(iTheSampler->sampleEmuRout))())];
00299 syncEm();
00300 }
00301 return buffer16bit;
00302 }
00303
00304 void* Mixer::fill16bitStereoControl( void* buffer, udword numberOfSamples )
00305 {
00306 sword* buffer16bit = (sword*)buffer;
00307 sbyte voice1data, voice2data, voice3data, voice4data;
00308 for ( ; numberOfSamples > 0; numberOfSamples-- )
00309 {
00310 voice1data = (iTheSidEmu->*optr1.outProc)(&optr1);
00311 voice2data = (iTheSidEmu->*optr2.outProc)(&optr2);
00312 voice3data = (iTheSidEmu->*optr3.outProc)(&optr3);
00313 voice4data = (iTheSampler->*(iTheSampler->sampleEmuRout))();
00314
00315 *buffer16bit++ = zero16bit
00316 +signedPanMix16[optr1.gainLeft+voice1data]
00317 +signedPanMix16[optr2.gainLeft+voice2data]
00318 +signedPanMix16[optr3.gainLeft+voice3data]
00319 +signedPanMix16[voice4_gainLeft+voice4data];
00320
00321 *buffer16bit++ = zero16bit
00322 +signedPanMix16[optr1.gainRight+voice1data]
00323 +signedPanMix16[optr2.gainRight+voice2data]
00324 +signedPanMix16[optr3.gainRight+voice3data]
00325 +signedPanMix16[voice4_gainRight+voice4data];
00326 syncEm();
00327 }
00328 return buffer16bit;
00329 }
00330
00331 void* Mixer::fill16bitStereoSurround( void* buffer, udword numberOfSamples )
00332 {
00333 sword* buffer16bit = (sword*)buffer;
00334 sbyte voice1data, voice2data, voice3data, voice4data;
00335 for ( ; numberOfSamples > 0; numberOfSamples-- )
00336 {
00337 voice1data = (iTheSidEmu->*optr1.outProc)(&optr1);
00338 voice2data = (iTheSidEmu->*optr2.outProc)(&optr2);
00339 voice3data = (iTheSidEmu->*optr3.outProc)(&optr3);
00340 voice4data = (iTheSampler->*(iTheSampler->sampleEmuRout))();
00341
00342 *buffer16bit++ = zero16bit
00343 +signedPanMix16[optr1.gainLeft+voice1data]
00344 +signedPanMix16[optr2.gainLeft+voice2data]
00345 +signedPanMix16[optr3.gainLeft+voice3data]
00346 +signedPanMix16[voice4_gainLeft+voice4data];
00347
00348 *buffer16bit++ = zero16bit
00349 -signedPanMix16[optr1.gainRight+voice1data]
00350 -signedPanMix16[optr2.gainRight+voice2data]
00351 -signedPanMix16[optr3.gainRight+voice3data]
00352 -signedPanMix16[voice4_gainRight+voice4data];
00353 syncEm();
00354 }
00355 return buffer16bit;
00356 }
00357
00358 void* Mixer::fill16bitsplit( void* buffer, udword numberOfSamples )
00359 {
00360 sword* v1buffer16bit = (sword*)buffer;
00361 sword* v2buffer16bit = v1buffer16bit + iTheSidEmu->splitBufferLen;
00362 sword* v3buffer16bit = v2buffer16bit + iTheSidEmu->splitBufferLen;
00363 sword* v4buffer16bit = v3buffer16bit + iTheSidEmu->splitBufferLen;
00364 for ( ; numberOfSamples > 0; numberOfSamples-- )
00365 {
00366 *v1buffer16bit++ = zero16bit+(iTheSidEmu->*optr1.outProc)(&optr1);
00367 *v2buffer16bit++ = zero16bit+(iTheSidEmu->*optr2.outProc)(&optr2);
00368 *v3buffer16bit++ = zero16bit+(iTheSidEmu->*optr3.outProc)(&optr3);
00369 *v4buffer16bit++ = zero16bit+(iTheSampler->*(iTheSampler->sampleEmuRout))();
00370 syncEm();
00371 }
00372 return v1buffer16bit;
00373 }