xiRetimer

fit recorded audio to a tempo
git clone https://git.ce9e.org/xiRetimer.git

commit
15ee73bbef874fa8d95d05295ddcc7bf3db1a137
parent
44f585ecc4802de858ca48722c3fc155948065a9
Author
Tobias Bengfort <tobias.bengfort@gmx.net>
Date
2010-11-06 16:20
rb keyframemap

Diffstat

M README 9 +++++----
M src/rbprocess.h 81 +++++++++++++++++++++++++++++--------------------------------
M xiRetimer 0

3 files changed, 43 insertions, 47 deletions


diff --git a/README b/README

@@ -6,13 +6,14 @@ I want to use this to fit recorded Audio exactly to a tempo.
    6     6 playback - sdl
    7     7 gui - wxwidgets
    8     8 xiRetimer
    9    -1 timestretch - rubberband
   -1     9 timestretch - rubberband (v>=1.5)
   10    10 
   11    11 
   12    12 TODO
   13    -1 
   -1    13 process (first and last marker should change tempo)
   -1    14 smooth interpolation
   14    15 always update gui
   -1    16 libmad
   15    17 exits with error
   16    -1 bugtracking
   17    -1 im/export different kinds of audio files (libmad)
   18    18 soundtouch
   -1    19 bugtracking

diff --git a/src/rbprocess.h b/src/rbprocess.h

@@ -4,67 +4,62 @@
    4     4 #include "marker.h"
    5     5 #include "sample.h"
    6     6 #include <rubberband/RubberBandStretcher.h>
   -1     7 #include <map>
    7     8 
    8     9 /*
    9    10 this is called by sample.process()
   10    11 this uses the rubberband library
   11    12 */
   12    13 
   13    -1 void RBprocess(float* odata, int olength, float* data, int length, Marker* marker, Sample* caller) {
   -1    14 void RBprocess(float* odata, int olength, float* data, int length, Marker* marker, Sample* caller, int n=1) {
   -1    15   // TODO other than linear
   14    16   
   15    -1   const int bufferLength=4096;
   16    17   float **ibuf = new float *[1];
   17    -1   ibuf[0]=new float[bufferLength];
   -1    18   ibuf[0]=odata;
   18    19   float **obuf = new float *[1];
   19    -1   int avail2=0; // position in data
   -1    20   obuf[0]=data;
   20    21 
   21    -1   for (int i=0; i<olength; i+=bufferLength) {
   22    -1     float ratio=marker->getRatio(i/(float)olength);
   23    -1 
   24    -1 
   25    -1     // load odata to ibuf
   26    -1     for (int j=0; j<bufferLength; ++j) {
   27    -1       if (i+j<olength)
   28    -1         ibuf[0][j]=odata[i+j];
   29    -1       else
   30    -1         ibuf[0][j]=0;
   -1    22   RubberBand::RubberBandStretcher ts(44100, 1, 0, marker->getRatio());
   -1    23   // map
   -1    24   std::map<unsigned int, unsigned int> fmap;
   -1    25   for (int i=0; i<marker->getLength(); ++i) {
   -1    26     fmap[int(marker->getOld(i)*olength)]=int(marker->getNew(i)*length);
   -1    27     // additional 
   -1    28     for (int j=1; j<n; ++j) {
   -1    29       float old=(marker->getOld(i+1)-marker->getOld(i))*j/(float)n;
   -1    30       fmap[int(old*olength)]=int(marker->new2nnew(marker->old2new(old))*length);
   31    31     }
   -1    32   }
   -1    33   ts.setKeyFrameMap(fmap);
   32    34 
   33    -1     // process ibuf
   34    -1     RubberBand::RubberBandStretcher ts(44100, 1, 0, ratio);
   35    -1     ts.setMaxProcessSize(bufferLength*10);
   36    -1     ts.study(ibuf, bufferLength, true);
   37    -1     int a1=-1;
   38    -1     int a2=0;
   39    -1     while (a1!=a2) {
   40    -1       ts.process(ibuf, ts.getSamplesRequired(), false);
   41    -1       a1=a2;
   42    -1       a2=ts.available();
   43    -1     }
   44    -1     ts.process(ibuf, bufferLength, true);
   45    -1     int avail=ts.available();
   46    -1     obuf[0]=new float[avail];
   47    -1     ts.retrieve(obuf, avail);
   -1    35   ts.study(ibuf, olength, true);
   -1    36   ts.setMaxProcessSize(olength);
   -1    37   int a1=-1;
   -1    38   int a2=0;
   -1    39   caller->setFinished(0.05);
   -1    40   while (a1!=a2) {
   -1    41     ts.process(ibuf, ts.getSamplesRequired(), false);
   -1    42     a1=a2;
   -1    43     a2=ts.available();
   -1    44     caller->setFinished(a2/(float)length*0.8+0.05); // TODO doesnt work
   -1    45   }
   -1    46   ts.process(ibuf, olength, true);
   -1    47   caller->setFinished(0.95);
   48    48 
   49    -1     // write obuf to data
   50    -1     for (int j=0; j<avail && j+avail2<length; ++j) {
   51    -1       float value = obuf[0][j];
   52    -1       if (value > 1.f) value = 1.f;
   53    -1       if (value < -1.f) value = -1.f;
   54    -1       data[avail2+j] = value;
   55    -1     }
   56    -1     avail2+=avail;
   -1    49   int avail=ts.available();
   -1    50   ts.retrieve(obuf, avail);
   57    51 
   58    -1     delete[] obuf[0];
   59    -1     
   60    -1     // update ProgressBar
   61    -1     caller->setFinished(i/(float)olength);
   -1    52   for (int j=0; j<avail; ++j) {
   -1    53     float value = obuf[0][j];
   -1    54     if (value > 1.f) value = 1.f;
   -1    55     if (value < -1.f) value = -1.f;
   -1    56     data[j] = value;
   62    57   }
   63    -1   for (int i=avail2; i<length; ++i) {
   -1    58 
   -1    59   for (int i=avail; i<length; ++i) {
   64    60     data[i]=0;
   65    61   }
   66    62 
   67    -1   delete[] ibuf[0];
   68    63   delete[] ibuf;
   69    64   delete[] obuf;
   70    65 

diff --git a/xiRetimer b/xiRetimer

Binary files differ.