/[svn]/linuxsampler/trunk/src/engines/gig/Synthesizer.h
ViewVC logotype

Diff of /linuxsampler/trunk/src/engines/gig/Synthesizer.h

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 685 by persson, Tue Jul 5 19:30:37 2005 UTC revision 738 by schoenebeck, Tue Aug 16 17:14:25 2005 UTC
# Line 31  Line 31 
31  #include "Filter.h"  #include "Filter.h"
32  #include "Voice.h"  #include "Voice.h"
33    
34  #define SYNTHESIS_MODE_SET_CONSTPITCH(iMode,bVal)       if (bVal) iMode |= 0x01; else iMode &= ~0x01   /* (un)set mode bit 0 */  
35  #define SYNTHESIS_MODE_SET_LOOP(iMode,bVal)             if (bVal) iMode |= 0x02; else iMode &= ~0x02   /* (un)set mode bit 1 */  #define SYNTHESIS_MODE_SET_INTERPOLATE(iMode,bVal)      if (bVal) iMode |= 0x01; else iMode &= ~0x01   /* (un)set mode bit 0 */
36  #define SYNTHESIS_MODE_SET_INTERPOLATE(iMode,bVal)      if (bVal) iMode |= 0x04; else iMode &= ~0x04   /* (un)set mode bit 2 */  #define SYNTHESIS_MODE_SET_FILTER(iMode,bVal)           if (bVal) iMode |= 0x02; else iMode &= ~0x02   /* (un)set mode bit 1 */
37  #define SYNTHESIS_MODE_SET_FILTER(iMode,bVal)           if (bVal) iMode |= 0x08; else iMode &= ~0x08   /* (un)set mode bit 3 */  #define SYNTHESIS_MODE_SET_LOOP(iMode,bVal)             if (bVal) iMode |= 0x04; else iMode &= ~0x04   /* (un)set mode bit 2 */
38  #define SYNTHESIS_MODE_SET_CHANNELS(iMode,bVal)         if (bVal) iMode |= 0x10; else iMode &= ~0x10   /* (un)set mode bit 4 */  #define SYNTHESIS_MODE_SET_CHANNELS(iMode,bVal)         if (bVal) iMode |= 0x08; else iMode &= ~0x08   /* (un)set mode bit 3 */
39  #define SYNTHESIS_MODE_SET_IMPLEMENTATION(iMode,bVal)   if (bVal) iMode |= 0x20; else iMode &= ~0x20   /* (un)set mode bit 5 */  #define SYNTHESIS_MODE_SET_IMPLEMENTATION(iMode,bVal)   if (bVal) iMode |= 0x10; else iMode &= ~0x10   /* (un)set mode bit 4 */
40  #define SYNTHESIS_MODE_SET_PROFILING(iMode,bVal)        if (bVal) iMode |= 0x40; else iMode &= ~0x40   /* (un)set mode bit 6 */  #define SYNTHESIS_MODE_SET_PROFILING(iMode,bVal)        if (bVal) iMode |= 0x20; else iMode &= ~0x20   /* (un)set mode bit 5 */
41    
42  #define SYNTHESIS_MODE_GET_CONSTPITCH(iMode)            iMode & 0x01  #define SYNTHESIS_MODE_GET_INTERPOLATE(iMode)           iMode & 0x01
43  #define SYNTHESIS_MODE_GET_LOOP(iMode)                  iMode & 0x02  #define SYNTHESIS_MODE_GET_FILTER(iMode)                iMode & 0x02
44  #define SYNTHESIS_MODE_GET_INTERPOLATE(iMode)           iMode & 0x04  #define SYNTHESIS_MODE_GET_LOOP(iMode)                  iMode & 0x04
45  #define SYNTHESIS_MODE_GET_FILTER(iMode)                iMode & 0x08  #define SYNTHESIS_MODE_GET_CHANNELS(iMode)              iMode & 0x08
46  #define SYNTHESIS_MODE_GET_CHANNELS(iMode)              iMode & 0x10  #define SYNTHESIS_MODE_GET_IMPLEMENTATION(iMode)        iMode & 0x10
 #define SYNTHESIS_MODE_GET_IMPLEMENTATION(iMode)        iMode & 0x20  
47    
48  // that's usually gig::Voice of course, but we make it a macro so we can  // that's usually gig::Voice of course, but we make it a macro so we can
49  // include this code for our synthesis benchmark which uses fake data  // include this code for our synthesis benchmark which uses fake data
# Line 71  namespace LinuxSampler { namespace gig { Line 70  namespace LinuxSampler { namespace gig {
70       * format capable sampler engine. This means resampling / interpolation       * format capable sampler engine. This means resampling / interpolation
71       * for pitching the audio signal, looping, filter and amplification.       * for pitching the audio signal, looping, filter and amplification.
72       */       */
73      template<implementation_t IMPLEMENTATION, channels_t CHANNELS, bool USEFILTER, bool INTERPOLATE, bool DOLOOP, bool CONSTPITCH>      template<implementation_t IMPLEMENTATION, channels_t CHANNELS, bool DOLOOP, bool USEFILTER, bool INTERPOLATE>
74      class Synthesizer : public __RTMath<IMPLEMENTATION>, public LinuxSampler::Resampler<INTERPOLATE> {      class Synthesizer : public __RTMath<IMPLEMENTATION>, public LinuxSampler::Resampler<INTERPOLATE> {
75    
76              // declarations of derived functions (see "Name lookup,              // declarations of derived functions (see "Name lookup,
# Line 93  namespace LinuxSampler { namespace gig { Line 92  namespace LinuxSampler { namespace gig {
92               * This is the toplevel method of this class.               * This is the toplevel method of this class.
93               */                           */            
94              template<typename VOICE_T>              template<typename VOICE_T>
95              inline static void SynthesizeFragment(VOICE_T& Voice, uint Samples, sample_t* pSrc, uint i) {              inline static void SynthesizeSubFragment(VOICE_T& Voice, uint Samples, sample_t* pSrc, uint i) {
96                  const float panLeft  = Mul(Voice.PanLeft,  Voice.pEngineChannel->GlobalPanLeft);                  const float panLeft  = Mul(Voice.fFinalVolume, Mul(Voice.PanLeft,  Voice.pEngineChannel->GlobalPanLeft));
97                  const float panRight = Mul(Voice.PanRight, Voice.pEngineChannel->GlobalPanRight);                  const float panRight = Mul(Voice.fFinalVolume, Mul(Voice.PanRight, Voice.pEngineChannel->GlobalPanRight));
98                  if (IMPLEMENTATION == ASM_X86_MMX_SSE) {                  if (IMPLEMENTATION == ASM_X86_MMX_SSE) {
99                      float fPos = (float) Voice.Pos;                      float fPos = (float) Voice.Pos;
100                      SynthesizeFragment(Voice, Samples, pSrc, i, Voice.pSample->LoopPlayCount,                      SynthesizeSubFragment(Voice, Samples, pSrc, i, Voice.pSample->LoopPlayCount,
101                                         Voice.pSample->LoopStart,                                         Voice.pSample->LoopStart,
102                                         Voice.pSample->LoopEnd,                                         Voice.pSample->LoopEnd,
103                                         Voice.pSample->LoopSize,                                         Voice.pSample->LoopSize,
104                                         Voice.LoopCyclesLeft,                                         Voice.LoopCyclesLeft,
105                                         (void *)&fPos,                                         (void *)&fPos,
106                                         Voice.PitchBase,                                         &Voice.fFinalPitch,
                                        Voice.PitchBend,  
107                                         &panLeft, &panRight);                                         &panLeft, &panRight);
108                      #if CONFIG_ASM && ARCH_X86                      #if CONFIG_ASM && ARCH_X86
109                      if (INTERPOLATE) EMMS;                      if (INTERPOLATE) EMMS;
110                      #endif                      #endif
111                      Voice.Pos = (double) fPos;                      Voice.Pos = (double) fPos;
112                  } else {                  } else {
113                      SynthesizeFragment(Voice, Samples, pSrc, i, Voice.pSample->LoopPlayCount,                      SynthesizeSubFragment(Voice, Samples, pSrc, i, Voice.pSample->LoopPlayCount,
114                                         Voice.pSample->LoopStart,                                         Voice.pSample->LoopStart,
115                                         Voice.pSample->LoopEnd,                                         Voice.pSample->LoopEnd,
116                                         Voice.pSample->LoopSize,                                         Voice.pSample->LoopSize,
117                                         Voice.LoopCyclesLeft,                                         Voice.LoopCyclesLeft,
118                                         (void *)&Voice.Pos,                                         (void *)&Voice.Pos,
119                                         Voice.PitchBase,                                         &Voice.fFinalPitch,
                                        Voice.PitchBend,  
120                                         &panLeft, &panRight);                                         &panLeft, &panRight);
121                  }                  }
122              }              }
# Line 131  namespace LinuxSampler { namespace gig { Line 128  namespace LinuxSampler { namespace gig {
128               * Will be called by the toplevel SynthesizeFragment() method.               * Will be called by the toplevel SynthesizeFragment() method.
129               */                 */  
130              template<typename VOICE_T>              template<typename VOICE_T>
131              inline static void SynthesizeFragment(VOICE_T& Voice, uint Samples, sample_t* pSrc, uint& i, uint& LoopPlayCount, uint LoopStart, uint LoopEnd, uint LoopSize, uint& LoopCyclesLeft, void* Pos, float& PitchBase, float& PitchBend, const float* PanLeft, const float* PanRight) {              inline static void SynthesizeSubFragment(VOICE_T& Voice, uint Samples, sample_t* pSrc, uint& i, uint& LoopPlayCount, uint LoopStart, uint LoopEnd, uint LoopSize, uint& LoopCyclesLeft, void* Pos, const float* Pitch, const float* PanLeft, const float* PanRight) {
132                  const float loopEnd = Float(LoopEnd);                  const float loopEnd = Float(LoopEnd);
                 const float PBbyPB = Mul(PitchBase, PitchBend);  
133                  const float f_LoopStart = Float(LoopStart);                  const float f_LoopStart = Float(LoopStart);
134                  const float f_LoopSize = Float(LoopSize);                  const float f_LoopSize = Float(LoopSize);
135                  if (DOLOOP) {                  if (DOLOOP) {
136                      if (LoopPlayCount) {                      if (LoopPlayCount) {
137                          // render loop (loop count limited)                          // render loop (loop count limited)
138                          while (i < Samples && LoopCyclesLeft) {                          while (i < Samples && LoopCyclesLeft) {
139                              if (CONSTPITCH) {                              const uint processEnd = Min(Samples, i + DiffToLoopEnd(loopEnd,Pos, *Pitch) + 1); //TODO: instead of +1 we could also round up
140                                  const uint processEnd = Min(Samples, i + DiffToLoopEnd(loopEnd,Pos, PBbyPB) + 1); //TODO: instead of +1 we could also round up                              while (i < processEnd) Synthesize(Voice, Pos, pSrc, i, PanLeft, PanRight);
141                                  while (i < processEnd) Synthesize(Voice, Pos, pSrc, i, PanLeft, PanRight);                              LoopCyclesLeft -= WrapLoop(f_LoopStart, f_LoopSize, loopEnd, Pos);
                             }  
                             else Synthesize(Voice, Pos, pSrc, i, PanLeft, PanRight);  
                             if (WrapLoop(f_LoopStart, f_LoopSize, loopEnd, Pos)) LoopCyclesLeft--;  
142                          }                          }
143                          // render on without loop                          // render on without loop
144                          while (i < Samples) Synthesize(Voice, Pos, pSrc, i, PanLeft, PanRight);                          while (i < Samples) Synthesize(Voice, Pos, pSrc, i, PanLeft, PanRight);
145                      }                      }
146                      else { // render loop (endless loop)                      else { // render loop (endless loop)
147                          while (i < Samples) {                          while (i < Samples) {
148                              if (CONSTPITCH) {                              const uint processEnd = Min(Samples, i + DiffToLoopEnd(loopEnd, Pos, *Pitch) + 1); //TODO: instead of +1 we could also round up
149                                  const uint processEnd = Min(Samples, i + DiffToLoopEnd(loopEnd, Pos, PBbyPB) + 1); //TODO: instead of +1 we could also round up                              while (i < processEnd) Synthesize(Voice, Pos, pSrc, i, PanLeft, PanRight);
                                 while (i < processEnd) Synthesize(Voice, Pos, pSrc, i, PanLeft, PanRight);  
                             }  
                             else Synthesize(Voice, Pos, pSrc, i, PanLeft, PanRight);  
150                              WrapLoop(f_LoopStart, f_LoopSize, loopEnd, Pos);                              WrapLoop(f_LoopStart, f_LoopSize, loopEnd, Pos);
151                          }                          }
152                      }                      }
153                  }                  }
154                  else { // no looping                  else { // no looping
155                      while (i < Samples) { Synthesize(Voice, Pos, pSrc, i, PanLeft, PanRight);}                      while (i < Samples) { Synthesize(Voice, Pos, pSrc, i, PanLeft, PanRight); }
156                  }                  }
157              }              }
158    
# Line 175  namespace LinuxSampler { namespace gig { Line 165  namespace LinuxSampler { namespace gig {
165              template<typename VOICE_T>              template<typename VOICE_T>
166              inline static void Synthesize(VOICE_T& Voice, void* Pos, sample_t* pSrc, uint& i, const float* PanLeft, const float* PanRight) {              inline static void Synthesize(VOICE_T& Voice, void* Pos, sample_t* pSrc, uint& i, const float* PanLeft, const float* PanRight) {
167                  Synthesize(pSrc, Pos,                  Synthesize(pSrc, Pos,
168                             Voice.pEngine->pSynthesisParameters[Event::destination_vco][i],                             Voice.fFinalPitch,
169                             Voice.pEngineChannel->pOutputLeft,                             Voice.pEngineChannel->pOutputLeft,
170                             Voice.pEngineChannel->pOutputRight,                             Voice.pEngineChannel->pOutputRight,
171                             i,                             i,
                            Voice.pEngine->pSynthesisParameters[Event::destination_vca],  
172                             PanLeft,                             PanLeft,
173                             PanRight,                             PanRight,
174                             Voice.FilterLeft,                             Voice.FilterLeft,
175                             Voice.FilterRight,                             Voice.FilterRight);
                            Voice.pEngine->pBasicFilterParameters[i],  
                            Voice.pEngine->pMainFilterParameters[i]);  
176              }              }
177    
178              /**              /**
# Line 216  namespace LinuxSampler { namespace gig { Line 203  namespace LinuxSampler { namespace gig {
203                  }                  }
204              }              }
205    
206                //TODO: this method is not in use yet, it's intended to be used for pitch=x.0f where we could use integer instead of float as playback position variable
207                inline static int WrapLoop(const int& LoopStart, const int& LoopSize, const int& LoopEnd, int& Pos) {
208                    switch (IMPLEMENTATION) {
209                        // pure C++ implementation (thus platform independent)
210                        default: { //TODO: we can easily eliminate the branch here
211                            if (Pos < LoopEnd) return 0;
212                            Pos = (Pos - LoopEnd) % LoopSize + LoopStart;
213                            return 1;
214                        }
215                    }
216                }
217    
218              /**              /**
219               * This method handles looping of the RAM playback part of the               * This method handles looping of the RAM playback part of the
220               * sample, thus repositioning the playback position once the               * sample, thus repositioning the playback position once the
# Line 274  namespace LinuxSampler { namespace gig { Line 273  namespace LinuxSampler { namespace gig {
273               * point, whereas for the MMX/SSE implementation this means               * point, whereas for the MMX/SSE implementation this means
274               * rendering 4 sample points.               * rendering 4 sample points.
275               */               */
276              inline static void Synthesize(sample_t* pSrc, void* Pos, float& Pitch, float* pOutL, float* pOutR, uint& i, float* Volume, const float* PanL, const float* PanR, Filter& FilterL, Filter& FilterR, biquad_param_t& bqBase, biquad_param_t& bqMain) {              inline static void Synthesize(sample_t* pSrc, void* Pos, float& Pitch, float* pOutL, float* pOutR, uint& i, const float* PanL, const float* PanR, Filter& FilterL, Filter& FilterR) {
277                  switch (IMPLEMENTATION) {                  switch (IMPLEMENTATION) {
278                      // pure C++ implementation (thus platform independent)                      // pure C++ implementation (thus platform independent)
279                      case CPP: {                      case CPP: {
280                          switch (CHANNELS) {                          switch (CHANNELS) {
281                              case MONO: {                              case MONO: {
282                                  float samplePoint = GetNextSampleMonoCPP(pSrc, (double *)Pos, Pitch);                                  float samplePoint = GetNextSampleMonoCPP(pSrc, (double *)Pos, Pitch);
283                                  if (USEFILTER) samplePoint = FilterL.Apply(&bqBase, &bqMain, samplePoint);                                  if (USEFILTER) samplePoint = FilterL.Apply(samplePoint);
284                                  pOutL[i] += samplePoint * Volume[i] * *PanL;                                  pOutL[i] += samplePoint * *PanL;
285                                  pOutR[i] += samplePoint * Volume[i] * *PanR;                                  pOutR[i] += samplePoint * *PanR;
286                                  i++;                                  i++;
287                                  break;                                  break;
288                              }                              }
289                              case STEREO: {                              case STEREO: {
290                                  stereo_sample_t samplePoint = GetNextSampleStereoCPP(pSrc, (double *)Pos, Pitch);                                  stereo_sample_t samplePoint = GetNextSampleStereoCPP(pSrc, (double *)Pos, Pitch);
291                                  if (USEFILTER) {                                  if (USEFILTER) {
292                                      samplePoint.left  = FilterL.Apply(&bqBase, &bqMain, samplePoint.left);                                      samplePoint.left  = FilterL.Apply(samplePoint.left);
293                                      samplePoint.right = FilterR.Apply(&bqBase, &bqMain, samplePoint.right);                                      samplePoint.right = FilterR.Apply(samplePoint.right);
294                                  }                                  }
295                                  pOutL[i] += samplePoint.left  * Volume[i] * *PanL;                                  pOutL[i] += samplePoint.left  * *PanL;
296                                  pOutR[i] += samplePoint.right * Volume[i] * *PanR;                                  pOutR[i] += samplePoint.right * *PanR;
297                                  i++;                                  i++;
298                                  break;                                  break;
299                              }                              }

Legend:
Removed from v.685  
changed lines
  Added in v.738

  ViewVC Help
Powered by ViewVC