MythTV  0.27pre
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Groups Pages
TDStretch.cpp
Go to the documentation of this file.
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
11 
12 
13 
14 
15 //
16 // Last changed : $Date$
17 // File revision : $Revision$
18 //
19 // $Id$
20 //
22 //
23 // License :
24 //
25 // SoundTouch audio processing library
26 // Copyright (c) Olli Parviainen
27 //
28 // This library is free software; you can redistribute it and/or
29 // modify it under the terms of the GNU Lesser General Public
30 // License as published by the Free Software Foundation; either
31 // version 2.1 of the License, or (at your option) any later version.
32 //
33 // This library is distributed in the hope that it will be useful,
34 // but WITHOUT ANY WARRANTY; without even the implied warranty of
35 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
36 // Lesser General Public License for more details.
37 //
38 // You should have received a copy of the GNU Lesser General Public
39 // License along with this library; if not, write to the Free Software
40 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
41 //
43 
44 #include <string.h>
45 #include <stdlib.h>
46 #include <memory.h>
47 #include <limits.h>
48 #include <math.h>
49 #include <assert.h>
50 
51 #include "STTypes.h"
52 #include "cpu_detect.h"
53 #include "TDStretch.h"
54 
55 using namespace soundtouch;
56 
57 #ifndef min
58 #define min(a,b) ((a > b) ? b : a)
59 #define max(a,b) ((a < b) ? b : a)
60 #endif
61 
62 
63 
64 /*****************************************************************************
65  *
66  * Constant definitions
67  *
68  *****************************************************************************/
69 
70 
71 #define MAX_SCAN_DELTA 124
72 
73 // Table for the hierarchical mixing position seeking algorithm
74 int scanOffsets[4][24]={
75  { 124, 186, 248, 310, 372, 434, 496, 558, 620, 682, 744, 806,
76  868, 930, 992, 1054, 1116, 1178, 1240, 1302, 1364, 1426, 1488, 0},
77  {-100, -75, -50, -25, 25, 50, 75, 100, 0, 0, 0, 0,
78  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
79  { -20, -15, -10, -5, 5, 10, 15, 20, 0, 0, 0, 0,
80  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
81  { -4, -3, -2, -1, 1, 2, 3, 4, 0, 0, 0, 0,
82  0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}};
83 
84 /*****************************************************************************
85  *
86  * Implementation of the class 'TDStretch'
87  *
88  *****************************************************************************/
89 
90 
92 {
93  bQuickseek = FALSE;
94  channels = 2;
95  bMidBufferDirty = FALSE;
96 
97  pMidBuffer = NULL;
99  midBufferLength = 0;
100  overlapLength = 0;
101 
102  setParameters(44100, DEFAULT_SEQUENCE_MS, DEFAULT_SEEKWINDOW_MS, DEFAULT_OVERLAP_MS);
103 
104  setTempo(1.0f);
105 }
106 
107 
108 
109 
111 {
112  if (midBufferLength)
113  {
114  delete[] pMidBuffer;
115  delete[] pRefMidBufferUnaligned;
116  midBufferLength = 0;
117  }
118 }
119 
120 
121 
122 // Calculates the x having the closest 2^x value for the given value
123 static int _getClosest2Power(double value)
124 {
125  return (int)(log(value) / log(2.0) + 0.5);
126 }
127 
128 
129 
130 // Sets routine control parameters. These control are certain time constants
131 // defining how the sound is stretched to the desired duration.
132 //
133 // 'sampleRate' = sample rate of the sound
134 // 'sequenceMS' = one processing sequence length in milliseconds (default = 82 ms)
135 // 'seekwindowMS' = seeking window length for scanning the best overlapping
136 // position (default = 28 ms)
137 // 'overlapMS' = overlapping length (default = 12 ms)
138 
139 void TDStretch::setParameters(uint aSampleRate, uint aSequenceMS,
140  uint aSeekWindowMS, uint aOverlapMS)
141 {
142  this->sampleRate = aSampleRate;
143  this->sequenceMs = aSequenceMS;
144  this->seekWindowMs = aSeekWindowMS;
145  this->overlapMs = aOverlapMS;
146 
147  seekLength = (sampleRate * seekWindowMs) / 1000;
149 
151 
153 
154  // set tempo to recalculate 'sampleReq'
155  setTempo(tempo);
156 
157 }
158 
159 
160 
164 void TDStretch::getParameters(uint *pSampleRate, uint *pSequenceMs, uint *pSeekWindowMs, uint *pOverlapMs)
165 {
166  if (pSampleRate)
167  {
168  *pSampleRate = sampleRate;
169  }
170 
171  if (pSequenceMs)
172  {
173  *pSequenceMs = sequenceMs;
174  }
175 
176  if (pSeekWindowMs)
177  {
178  *pSeekWindowMs = seekWindowMs;
179  }
180 
181  if (pOverlapMs)
182  {
183  *pOverlapMs = overlapMs;
184  }
185 }
186 
187 
188 // Overlaps samples in 'midBuffer' with the samples in 'input'
189 void TDStretch::overlapMono(SAMPLETYPE *output, const SAMPLETYPE *input) const
190 {
191  int i, itemp;
192 
193  for (i = 0; i < (int)overlapLength ; i ++)
194  {
195  itemp = overlapLength - i;
196  output[i] = (input[i] * i + pMidBuffer[i] * itemp ) / overlapLength; // >> overlapDividerBits;
197  }
198 }
199 
200 
201 
203 {
205  {
206  memset(pMidBuffer, 0, channels * sizeof(SAMPLETYPE) * overlapLength);
207  bMidBufferDirty = FALSE;
208  }
209 }
210 
211 
213 {
214  inputBuffer.clear();
215  clearMidBuffer();
216 }
217 
218 
219 // Clears the sample buffers
221 {
223  inputBuffer.clear();
224  clearMidBuffer();
225 }
226 
227 
228 
229 // Enables/disables the quick position seeking algorithm. Zero to disable, nonzero
230 // to enable
232 {
233  bQuickseek = enable;
234 }
235 
236 
237 // Returns nonzero if the quick seeking algorithm is enabled.
239 {
240  return bQuickseek;
241 }
242 
243 
244 // Seeks for the optimal overlap-mixing position.
246 {
247 #ifdef MULTICHANNEL
248  if (channels > 2)
249  {
250  // stereo sound
251  if (bQuickseek)
252  {
253  return seekBestOverlapPositionMultiQuick(refPos);
254  }
255  else
256  {
257  return seekBestOverlapPositionMulti(refPos);
258  }
259  }
260  else
261 #endif
262  if (channels == 2)
263  {
264  // stereo sound
265  if (bQuickseek)
266  {
267  return seekBestOverlapPositionStereoQuick(refPos);
268  }
269  else
270  {
271  return seekBestOverlapPositionStereo(refPos);
272  }
273  }
274  else
275  {
276  // mono sound
277  if (bQuickseek)
278  {
279  return seekBestOverlapPositionMonoQuick(refPos);
280  }
281  else
282  {
283  return seekBestOverlapPositionMono(refPos);
284  }
285  }
286 }
287 
288 
289 
290 
291 // Overlaps samples in 'midBuffer' with the samples in 'inputBuffer' at position
292 // of 'ovlPos'.
293 inline void TDStretch::overlap(SAMPLETYPE *output, const SAMPLETYPE *input, uint ovlPos) const
294 {
295 #ifdef MULTICHANNEL
296  if (channels > 2)
297  {
298  overlapMulti(output, input + channels * ovlPos);
299  }
300  else
301 #endif
302  if (channels == 2)
303  {
304  // stereo sound
305  overlapStereo(output, input + 2 * ovlPos);
306  } else {
307  // mono sound.
308  overlapMono(output, input + ovlPos);
309  }
310 }
311 
312 
313 
314 
315 #ifdef MULTICHANNEL
316 // Seeks for the optimal overlap-mixing position. The 'stereo' version of the
317 // routine
318 //
319 // The best position is determined as the position where the two overlapped
320 // sample sequences are 'most alike', in terms of the highest cross-correlation
321 // value over the overlapping period
323 {
324  uint bestOffs;
325  LONG_SAMPLETYPE bestCorr, corr;
326  uint i;
327 
328  // Slopes the amplitudes of the 'midBuffer' samples
330 
331  bestCorr = INT_MIN;
332  bestOffs = 0;
333 
334  // Scans for the best correlation value by testing each possible position
335  // over the permitted range.
336  for (i = 0; i < seekLength; i ++)
337  {
338  // Calculates correlation value for the mixing position corresponding
339  // to 'i'
340  corr = calcCrossCorrMulti(refPos + channels * i, pRefMidBuffer);
341 
342  // Checks for the highest correlation value
343  if (corr > bestCorr)
344  {
345  bestCorr = corr;
346  bestOffs = i;
347  }
348  }
349  // clear cross correlation routine state if necessary (is so e.g. in MMX routines).
351 
352  return bestOffs;
353 }
354 
355 
356 // Seeks for the optimal overlap-mixing position. The 'stereo' version of the
357 // routine
358 //
359 // The best position is determined as the position where the two overlapped
360 // sample sequences are 'most alike', in terms of the highest cross-correlation
361 // value over the overlapping period
363 {
364  uint j;
365  uint bestOffs;
366  LONG_SAMPLETYPE bestCorr, corr;
367  uint scanCount, corrOffset, tempOffset;
368 
369  // Slopes the amplitude of the 'midBuffer' samples
371 
372  bestCorr = INT_MIN;
373  bestOffs = 0;
374  corrOffset = 0;
375  tempOffset = 0;
376 
377  // Scans for the best correlation value using four-pass hierarchical search.
378  //
379  // The look-up table 'scans' has hierarchical position adjusting steps.
380  // In first pass the routine searhes for the highest correlation with
381  // relatively coarse steps, then rescans the neighbourhood of the highest
382  // correlation with better resolution and so on.
383  for (scanCount = 0;scanCount < 4; scanCount ++)
384  {
385  j = 0;
386  while (scanOffsets[scanCount][j])
387  {
388  tempOffset = corrOffset + scanOffsets[scanCount][j];
389  if (tempOffset >= seekLength) break;
390 
391  // Calculates correlation value for the mixing position corresponding
392  // to 'tempOffset'
393  corr = calcCrossCorrMulti(refPos + channels * tempOffset, pRefMidBuffer);
394 
395  // Checks for the highest correlation value
396  if (corr > bestCorr)
397  {
398  bestCorr = corr;
399  bestOffs = tempOffset;
400  }
401  j ++;
402  }
403  corrOffset = bestOffs;
404  }
405  // clear cross correlation routine state if necessary (is so e.g. in MMX routines).
407 
408  return bestOffs;
409 }
410 #endif
411 
412 // Seeks for the optimal overlap-mixing position. The 'stereo' version of the
413 // routine
414 //
415 // The best position is determined as the position where the two overlapped
416 // sample sequences are 'most alike', in terms of the highest cross-correlation
417 // value over the overlapping period
419 {
420  uint bestOffs;
421  LONG_SAMPLETYPE bestCorr, corr;
422  uint i;
423 
424  // Slopes the amplitudes of the 'midBuffer' samples
426 
427  bestCorr = INT_MIN;
428  bestOffs = 0;
429 
430  // Scans for the best correlation value by testing each possible position
431  // over the permitted range.
432  for (i = 0; i < seekLength; i ++)
433  {
434  // Calculates correlation value for the mixing position corresponding
435  // to 'i'
436  corr = calcCrossCorrStereo(refPos + 2 * i, pRefMidBuffer);
437 
438  // Checks for the highest correlation value
439  if (corr > bestCorr)
440  {
441  bestCorr = corr;
442  bestOffs = i;
443  }
444  }
445  // clear cross correlation routine state if necessary (is so e.g. in MMX routines).
447 
448  return bestOffs;
449 }
450 
451 
452 // Seeks for the optimal overlap-mixing position. The 'stereo' version of the
453 // routine
454 //
455 // The best position is determined as the position where the two overlapped
456 // sample sequences are 'most alike', in terms of the highest cross-correlation
457 // value over the overlapping period
459 {
460  uint j;
461  uint bestOffs;
462  LONG_SAMPLETYPE bestCorr, corr;
463  uint scanCount, corrOffset, tempOffset;
464 
465  // Slopes the amplitude of the 'midBuffer' samples
467 
468  bestCorr = INT_MIN;
469  bestOffs = 0;
470  corrOffset = 0;
471  tempOffset = 0;
472 
473  // Scans for the best correlation value using four-pass hierarchical search.
474  //
475  // The look-up table 'scans' has hierarchical position adjusting steps.
476  // In first pass the routine searhes for the highest correlation with
477  // relatively coarse steps, then rescans the neighbourhood of the highest
478  // correlation with better resolution and so on.
479  for (scanCount = 0;scanCount < 4; scanCount ++)
480  {
481  j = 0;
482  while (scanOffsets[scanCount][j])
483  {
484  tempOffset = corrOffset + scanOffsets[scanCount][j];
485  if (tempOffset >= seekLength) break;
486 
487  // Calculates correlation value for the mixing position corresponding
488  // to 'tempOffset'
489  corr = calcCrossCorrStereo(refPos + 2 * tempOffset, pRefMidBuffer);
490 
491  // Checks for the highest correlation value
492  if (corr > bestCorr)
493  {
494  bestCorr = corr;
495  bestOffs = tempOffset;
496  }
497  j ++;
498  }
499  corrOffset = bestOffs;
500  }
501  // clear cross correlation routine state if necessary (is so e.g. in MMX routines).
503 
504  return bestOffs;
505 }
506 
507 
508 
509 // Seeks for the optimal overlap-mixing position. The 'mono' version of the
510 // routine
511 //
512 // The best position is determined as the position where the two overlapped
513 // sample sequences are 'most alike', in terms of the highest cross-correlation
514 // value over the overlapping period
516 {
517  uint bestOffs;
518  LONG_SAMPLETYPE bestCorr, corr;
519  uint tempOffset;
520  const SAMPLETYPE *compare;
521 
522  // Slopes the amplitude of the 'midBuffer' samples
524 
525  bestCorr = INT_MIN;
526  bestOffs = 0;
527 
528  // Scans for the best correlation value by testing each possible position
529  // over the permitted range.
530  for (tempOffset = 0; tempOffset < seekLength; tempOffset ++)
531  {
532  compare = refPos + tempOffset;
533 
534  // Calculates correlation value for the mixing position corresponding
535  // to 'tempOffset'
536  corr = calcCrossCorrMono(pRefMidBuffer, compare);
537 
538  // Checks for the highest correlation value
539  if (corr > bestCorr)
540  {
541  bestCorr = corr;
542  bestOffs = tempOffset;
543  }
544  }
545  // clear cross correlation routine state if necessary (is so e.g. in MMX routines).
547 
548  return bestOffs;
549 }
550 
551 
552 // Seeks for the optimal overlap-mixing position. The 'mono' version of the
553 // routine
554 //
555 // The best position is determined as the position where the two overlapped
556 // sample sequences are 'most alike', in terms of the highest cross-correlation
557 // value over the overlapping period
559 {
560  uint j;
561  uint bestOffs;
562  LONG_SAMPLETYPE bestCorr, corr;
563  uint scanCount, corrOffset, tempOffset;
564 
565  // Slopes the amplitude of the 'midBuffer' samples
567 
568  bestCorr = INT_MIN;
569  bestOffs = 0;
570  corrOffset = 0;
571  tempOffset = 0;
572 
573  // Scans for the best correlation value using four-pass hierarchical search.
574  //
575  // The look-up table 'scans' has hierarchical position adjusting steps.
576  // In first pass the routine searhes for the highest correlation with
577  // relatively coarse steps, then rescans the neighbourhood of the highest
578  // correlation with better resolution and so on.
579  for (scanCount = 0;scanCount < 4; scanCount ++)
580  {
581  j = 0;
582  while (scanOffsets[scanCount][j])
583  {
584  tempOffset = corrOffset + scanOffsets[scanCount][j];
585  if (tempOffset >= seekLength) break;
586 
587  // Calculates correlation value for the mixing position corresponding
588  // to 'tempOffset'
589  corr = calcCrossCorrMono(refPos + tempOffset, pRefMidBuffer);
590 
591  // Checks for the highest correlation value
592  if (corr > bestCorr)
593  {
594  bestCorr = corr;
595  bestOffs = tempOffset;
596  }
597  j ++;
598  }
599  corrOffset = bestOffs;
600  }
601  // clear cross correlation routine state if necessary (is so e.g. in MMX routines).
603 
604  return bestOffs;
605 }
606 
607 
610 {
611  // default implementation is empty.
612 }
613 
614 
615 // Sets new target tempo. Normal tempo = 'SCALE', smaller values represent slower
616 // tempo, larger faster tempo.
617 void TDStretch::setTempo(float newTempo)
618 {
619  uint intskip;
620 
621  tempo = newTempo;
622 
623  // Calculate ideal skip length (according to tempo value)
625  skipFract = 0;
626  intskip = (int)(nominalSkip + 0.5f);
627 
628  // Calculate how many samples are needed in the 'inputBuffer' to
629  // process another batch of samples
631 }
632 
633 
634 
635 // Sets the number of channels, 1 = mono, 2 = stereo
636 void TDStretch::setChannels(uint numChannels)
637 {
638  if (channels == numChannels) return;
639 #ifdef MULTICHANNEL
640  assert(numChannels >= 1 && numChannels <= MULTICHANNEL);
641 #else
642  assert(numChannels == 1 || numChannels == 2);
643 #endif
644 
645  channels = numChannels;
648 }
649 
650 
651 // nominal tempo, no need for processing, just pass the samples through
652 // to outputBuffer
654 {
655  assert(tempo == 1.0f);
656 
657  if (bMidBufferDirty)
658  {
659  // If there are samples in pMidBuffer waiting for overlapping,
660  // do a single sliding overlapping with them in order to prevent a
661  // clicking distortion in the output sound
663  {
664  // wait until we've got overlapLength input samples
665  return;
666  }
667  // Mix the samples in the beginning of 'inputBuffer' with the
668  // samples in 'midBuffer' using sliding overlapping
672  clearMidBuffer();
673  // now we've caught the nominal sample flow and may switch to
674  // bypass mode
675  }
676 
677  // Simply bypass samples from input to output
679 }
680 
681 
682 // Processes as many processing frames of the samples 'inputBuffer', store
683 // the result into 'outputBuffer'
685 {
686  uint ovlSkip, offset;
687  int temp;
688 
689  if (tempo == 1.0f)
690  {
691  // tempo not changed from the original, so bypass the processing
693  return;
694  }
695 
696  if (bMidBufferDirty == FALSE)
697  {
698  // if midBuffer is empty, move the first samples of the input stream
699  // into it
701  {
702  // wait until we've got overlapLength samples
703  return;
704  }
707  bMidBufferDirty = TRUE;
708  }
709 
710  // Process samples as long as there are enough samples in 'inputBuffer'
711  // to form a processing frame.
712  while (inputBuffer.numSamples() >= sampleReq)
713  {
714  // If tempo differs from the normal ('SCALE'), scan for the best overlapping
715  // position
717 
718  // Mix the samples in the 'inputBuffer' at position of 'offset' with the
719  // samples in 'midBuffer' using sliding overlapping
720  // ... first partially overlap with the end of the previous sequence
721  // (that's in 'midBuffer')
724 
725  // ... then copy sequence samples from 'inputBuffer' to output
726  temp = (seekWindowLength - 2 * overlapLength);// & 0xfffffffe;
727  if (temp > 0)
728  {
730  }
731 
732  // Copies the end of the current sequence from 'inputBuffer' to
733  // 'midBuffer' for being mixed with the beginning of the next
734  // processing sequence and so on
737  channels * sizeof(SAMPLETYPE) * overlapLength);
738  bMidBufferDirty = TRUE;
739 
740  // Remove the processed samples from the input buffer. Update
741  // the difference between integer & nominal skip step to 'skipFract'
742  // in order to prevent the error from accumulating over time.
743  skipFract += nominalSkip; // real skip size
744  ovlSkip = (int)skipFract; // rounded to integer skip
745  skipFract -= ovlSkip; // maintain the fraction part, i.e. real vs. integer skip
746  inputBuffer.receiveSamples(ovlSkip);
747  }
748 }
749 
750 
751 // Adds 'numsamples' pcs of samples from the 'samples' memory position into
752 // the input of the object.
754 {
755  // Add the samples into the input buffer
756  inputBuffer.putSamples(samples, numSamples);
757  // Process the samples in input buffer
758  processSamples();
759 }
760 
761 
762 
765 {
766  overlapLength = newOverlapLength;
767 
769  {
770  if (midBufferLength)
771  {
772  delete[] pMidBuffer;
773  delete[] pRefMidBufferUnaligned;
774  midBufferLength = 0;
775  }
776 
779  bMidBufferDirty = TRUE;
780  clearMidBuffer();
781 
783  // ensure that 'pRefMidBuffer' is aligned to 16 byte boundary for efficiency
784  pRefMidBuffer = (SAMPLETYPE *)((((ulong)pRefMidBufferUnaligned) + 15) & -16);
785  }
786 }
787 
788 
789 // Operator 'new' is overloaded so that it automatically creates a suitable instance
790 // depending on if we've a MMX/SSE/etc-capable CPU available or not.
791 void * TDStretch::operator new(size_t s)
792 {
793  // Notice! don't use "new TDStretch" directly, use "newInstance" to create a new instance instead!
794  assert(FALSE);
795  return NULL;
796 }
797 
798 
800 {
801  uint uExtensions;
802 
803  uExtensions = detectCPUextensions();
804 
805  // Check if MMX/SSE/3DNow! instruction set extensions supported by CPU
806 #ifdef ALLOW_SSE3
807  if (uExtensions & MM_SSE3)
808  {
809  // SSE support
810  return ::new TDStretchSSE3;
811  }
812  else
813 #endif // ALLOW_SSE3
814 #ifdef ALLOW_SSE2
815  if (uExtensions & MM_SSE2)
816  {
817  // SSE support
818  return ::new TDStretchSSE2;
819  }
820  else
821 #endif // ALLOW_SSE2
822  {
823  // ISA optimizations not supported, use plain C version
824  return ::new TDStretch;
825  }
826 }
827 
828 
830 //
831 // Integer arithmetics specific algorithm implementations.
832 //
834 
835 #ifdef INTEGER_SAMPLES
836 
837 #ifdef MULTICHANNEL
838 // Slopes the amplitude of the 'midBuffer' samples so that cross correlation
839 // is faster to calculate
841 {
842  int i,j;
843  int temp, temp2;
844  short *src = pMidBuffer;
845  short *dest = pRefMidBuffer;
846 
847  for (i=0 ; i < (int)overlapLength ;i ++)
848  {
849  temp = i * (overlapLength - i);
850 
851  for(j=0;j<channels;j++)
852  {
853  temp2 = (*src++ * temp) / slopingDivider;
854  *dest++ = (short)(temp2);
855  }
856  }
857 }
858 #endif
859 
860 // Slopes the amplitude of the 'midBuffer' samples so that cross correlation
861 // is faster to calculate
863 {
864  int i, cnt2;
865  int temp, temp2;
866 
867  for (i=0 ; i < (int)overlapLength ;i ++)
868  {
869  temp = i * (overlapLength - i);
870  cnt2 = i * 2;
871 
872  temp2 = (pMidBuffer[cnt2] * temp) / slopingDivider;
873  pRefMidBuffer[cnt2] = (short)(temp2);
874  temp2 = (pMidBuffer[cnt2 + 1] * temp) / slopingDivider;
875  pRefMidBuffer[cnt2 + 1] = (short)(temp2);
876  }
877 }
878 
879 
880 // Slopes the amplitude of the 'midBuffer' samples so that cross correlation
881 // is faster to calculate
883 {
884  int i;
885  long temp;
886  long temp2;
887 
888  for (i=0 ; i < (int)overlapLength ;i ++)
889  {
890  temp = i * (overlapLength - i);
891  temp2 = (pMidBuffer[i] * temp) / slopingDivider;
892  pRefMidBuffer[i] = (short)temp2;
893  }
894 }
895 
896 
897 // Overlaps samples in 'midBuffer' with the samples in 'input'. The 'Stereo'
898 // version of the routine.
899 void TDStretch::overlapStereo(short *output, const short *input) const
900 {
901  int i;
902  short temp;
903  uint cnt2;
904 
905  for (i = 0; i < (int)overlapLength ; i ++)
906  {
907  temp = (short)(overlapLength - i);
908  cnt2 = 2 * i;
909  output[cnt2] = (input[cnt2] * i + pMidBuffer[cnt2] * temp ) / overlapLength;
910  output[cnt2 + 1] = (input[cnt2 + 1] * i + pMidBuffer[cnt2 + 1] * temp ) / overlapLength;
911  }
912 }
913 
914 #ifdef MULTICHANNEL
915 // Overlaps samples in 'midBuffer' with the samples in 'input'. The 'Stereo'
916 // version of the routine.
917 void TDStretch::overlapMulti(short *output, const short *input) const
918 {
919  int i,j;
920  short temp;
921  //uint cnt2;
922  const short *ip = input;
923  short *op = output;
924  const short *md = pMidBuffer;
925 
926  for (i = 0; i < (int)overlapLength ; i ++)
927  {
928  temp = (short)(overlapLength - i);
929  for(j=0;j<channels;j++)
930  *op++ = (*ip++ * i + *md++ * temp ) / overlapLength;
931  }
932 }
933 #endif
934 
935 
940 {
941  uint newOvl;
942 
943  overlapDividerBits = _getClosest2Power((sampleRate * overlapMs) / 1000.0);
946  newOvl = (uint)pow(2, overlapDividerBits);
947 
948  acceptNewOverlapLength(newOvl);
949 
950  // calculate sloping divider so that crosscorrelation operation won't
951  // overflow 32-bit register. Max. sum of the crosscorrelation sum without
952  // divider would be 2^30*(N^3-N)/3, where N = overlap length
953  slopingDivider = (newOvl * newOvl - 1) / 3;
954 }
955 
956 
957 long TDStretch::calcCrossCorrMono(const short *mixingPos, const short *compare) const
958 {
959  long corr;
960  uint i;
961 
962  corr = 0;
963  for (i = 1; i < overlapLength; i ++)
964  {
965  corr += (mixingPos[i] * compare[i]) >> overlapDividerBits;
966  }
967 
968  return corr;
969 }
970 
971 
972 long TDStretch::calcCrossCorrStereo(const short *mixingPos, const short *compare) const
973 {
974  long corr;
975  uint i;
976 
977  corr = 0;
978  for (i = 2; i < 2 * overlapLength; i += 2)
979  {
980  corr += (mixingPos[i] * compare[i] +
981  mixingPos[i + 1] * compare[i + 1]) >> overlapDividerBits;
982  }
983 
984  return corr;
985 }
986 
987 #ifdef MULTICHANNEL
988 long TDStretch::calcCrossCorrMulti(const short *mixingPos, const short *compare) const
989 {
990  long corr;
991  uint i;
992 
993  corr = 0;
994  for (i = channels; i < channels * overlapLength; i++)
995  {
996  corr += (mixingPos[i] * compare[i]) >> overlapDividerBits;
997  }
998 
999  return corr;
1000 }
1001 #endif
1002 
1003 #endif // INTEGER_SAMPLES
1004 
1006 //
1007 // Floating point arithmetics specific algorithm implementations.
1008 //
1009 
1010 #ifdef FLOAT_SAMPLES
1011 
1012 // Slopes the amplitude of the 'midBuffer' samples so that cross correlation
1013 // is faster to calculate
1015 {
1016  int i, cnt2;
1017  float temp;
1018 
1019  for (i=0 ; i < (int)overlapLength ;i ++)
1020  {
1021  temp = (float)i * (float)(overlapLength - i);
1022  cnt2 = i * 2;
1023  pRefMidBuffer[cnt2] = (float)(pMidBuffer[cnt2] * temp);
1024  pRefMidBuffer[cnt2 + 1] = (float)(pMidBuffer[cnt2 + 1] * temp);
1025  }
1026 }
1027 
1028 #ifdef MULTICHANNEL
1029 // Slopes the amplitude of the 'midBuffer' samples so that cross correlation
1030 // is faster to calculate
1032 {
1033  int i,j;
1034  float temp, temp2;
1035  float *src = pMidBuffer;
1036  float *dest = pRefMidBuffer;
1037 
1038  for (i = 0 ; i < (int)overlapLength ; i++)
1039  {
1040  temp = (float)i * (float)(overlapLength - i);
1041 
1042  for(j = 0; j < channels; j++)
1043  {
1044  temp2 = (float)(*src++ * temp);
1045  *dest++ = temp2;
1046  }
1047  }
1048 }
1049 #endif
1050 
1051 // Slopes the amplitude of the 'midBuffer' samples so that cross correlation
1052 // is faster to calculate
1054 {
1055  int i;
1056  float temp;
1057 
1058  for (i=0 ; i < (int)overlapLength ;i ++)
1059  {
1060  temp = (float)i * (float)(overlapLength - i);
1061  pRefMidBuffer[i] = (float)(pMidBuffer[i] * temp);
1062  }
1063 }
1064 
1065 // SSE-optimized version of the function overlapStereo
1066 void TDStretch::overlapStereo(float *output, const float *input) const
1067 {
1068  int i;
1069  uint cnt2;
1070  float fTemp;
1071  float fScale;
1072  float fi;
1073 
1074  fScale = 1.0f / (float)overlapLength;
1075 
1076  for (i = 0; i < (int)overlapLength ; i ++)
1077  {
1078  fTemp = (float)(overlapLength - i) * fScale;
1079  fi = (float)i * fScale;
1080  cnt2 = 2 * i;
1081  output[cnt2 + 0] = input[cnt2 + 0] * fi + pMidBuffer[cnt2 + 0] * fTemp;
1082  output[cnt2 + 1] = input[cnt2 + 1] * fi + pMidBuffer[cnt2 + 1] * fTemp;
1083  }
1084 }
1085 
1086 #ifdef MULTICHANNEL
1087 // Overlaps samples in 'midBuffer' with the samples in 'input'.
1088 void TDStretch::overlapMulti(float *output, const float *input) const
1089 {
1090  int i,j;
1091  float temp;
1092  const float *ip = input;
1093  float *op = output;
1094  const float *md = pMidBuffer;
1095  float fScale = 1.0f / (float)overlapLength;
1096  float fi;
1097 
1098  for (i = 0; i < (int)overlapLength ; i ++)
1099  {
1100  temp = (float)(overlapLength - i) * fScale;
1101  fi = (float)i * fScale;
1102  for(j = 0; j < channels; j++)
1103  *op++ = (*ip++ * fi + *md++ * temp);
1104  }
1105 }
1106 #endif
1107 
1110 {
1111  uint newOvl;
1112 
1113  newOvl = (sampleRate * overlapMs) / 1000;
1114  if (newOvl < 16) newOvl = 16;
1115 
1116  // must be divisible by 8
1117  newOvl -= newOvl % 8;
1118 
1119  acceptNewOverlapLength(newOvl);
1120 }
1121 
1122 
1123 
1124 double TDStretch::calcCrossCorrMono(const float *mixingPos, const float *compare) const
1125 {
1126  double corr;
1127  uint i;
1128 
1129  corr = 0;
1130  for (i = 1; i < overlapLength; i ++)
1131  {
1132  corr += mixingPos[i] * compare[i];
1133  }
1134 
1135  return corr;
1136 }
1137 
1138 
1139 double TDStretch::calcCrossCorrStereo(const float *mixingPos, const float *compare) const
1140 {
1141  double corr;
1142  uint i;
1143 
1144  corr = 0;
1145  for (i = 2; i < 2 * overlapLength; i += 2)
1146  {
1147  corr += mixingPos[i] * compare[i] +
1148  mixingPos[i + 1] * compare[i + 1];
1149  }
1150 
1151  return corr;
1152 }
1153 
1154 #ifdef MULTICHANNEL
1155 double TDStretch::calcCrossCorrMulti(const float *mixingPos, const float *compare) const
1156 {
1157  double corr;
1158  uint i;
1159 
1160  corr = 0;
1161  for (i = channels; i < channels * overlapLength; i++)
1162  {
1163  corr += mixingPos[i] * compare[i];
1164  }
1165 
1166  return corr;
1167 }
1168 #endif
1169 
1170 #endif // FLOAT_SAMPLES