Main Page | Class Hierarchy | Compound List | File List | Compound Members | File Members | Related Pages

mixing.cpp

Go to the documentation of this file.
00001 //
00002 // /home/ms/sidplay/libsidplay/emu/RCS/mixing.cpp,v
00003 //
00004 
00005 //#include "mytypes.h"
00006 //#include "opstruct.h"
00007 #include "samples.h"
00008 #include "6581_.h"
00009 #include "mixing.h"
00010 
00011 
00012 //
00013 // this is local to the Mixer
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; // default
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         // Mixing formulas are optimized by sample input value.
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);  // optimized by (/2 *2);
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;  // optimized by (/2 * 512)
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 // -------------------------------------------------------------------- 8-bit
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                 // left
00169             *buffer8bit++ = mix8stereo[(unsigned)(mix8stereoMiddleIndex
00170                                                                                          +(iTheSidEmu->*optr1.outProc)(&optr1)
00171                                                                                          +(iTheSidEmu->*optr3.outProc)(&optr3))];
00172                 // right
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                 // left
00192                 *buffer8bit++ = zero8bit
00193                         +signedPanMix8[optr1.gainLeft+voice1data]
00194                     +signedPanMix8[optr2.gainLeft+voice2data]
00195                         +signedPanMix8[optr3.gainLeft+voice3data]
00196                         +signedPanMix8[voice4_gainLeft+voice4data];
00197                 // right
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                 // left
00219                 *buffer8bit++ = zero8bit
00220                         +signedPanMix8[optr1.gainLeft+voice1data]
00221                     +signedPanMix8[optr2.gainLeft+voice2data]
00222                         +signedPanMix8[optr3.gainLeft+voice3data]
00223                         +signedPanMix8[voice4_gainLeft+voice4data];
00224                 // right
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 // ------------------------------------------------------------------- 16-bit
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                 // left
00292             *buffer16bit++ = mix16stereo[(unsigned)(mix16stereoMiddleIndex
00293                                                                                          +(iTheSidEmu->*optr1.outProc)(&optr1)
00294                                                                                          +(iTheSidEmu->*optr3.outProc)(&optr3))];
00295                 // right
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                 // left
00315                 *buffer16bit++ = zero16bit
00316                         +signedPanMix16[optr1.gainLeft+voice1data]
00317                     +signedPanMix16[optr2.gainLeft+voice2data]
00318                         +signedPanMix16[optr3.gainLeft+voice3data]
00319                         +signedPanMix16[voice4_gainLeft+voice4data];
00320                 // right
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                 // left
00342                 *buffer16bit++ = zero16bit
00343                         +signedPanMix16[optr1.gainLeft+voice1data]
00344                     +signedPanMix16[optr2.gainLeft+voice2data]
00345                         +signedPanMix16[optr3.gainLeft+voice3data]
00346                         +signedPanMix16[voice4_gainLeft+voice4data];
00347                 // right
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 }

Generated on Tue Feb 8 04:13:58 2005 for Esidplay by doxygen 1.3.3