xiRetimer

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

commit
6437567d274cafb8c276ad0e4b604b4daab1ef4f
parent
4a20eb83bddf2e2191fdf86aa8ccd6a740a16efd
Author
Tobias Bengfort <tobias.bengfort@gmx.net>
Date
2010-10-31 14:32
sample

Diffstat

D rb_expermients/fio.cpp 1 -
D rb_expermients/fio.h 125 ------------------------------------------------------------
D rb_expermients/rb1 6 ------
D rb_expermients/rb2 41 -----------------------------------------
D rb_expermients/rb3 28 ----------------------------
D rb_expermients/rtlayer.cpp 8 --------
D rb_expermients/rtlayer.h 41 -----------------------------------------
A src/sample.cpp 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A src/sample.h 37 +++++++++++++++++++++++++++++++++++++

9 files changed, 168 insertions, 250 deletions


diff --git a/rb_expermients/fio.cpp b/rb_expermients/fio.cpp

@@ -1 +0,0 @@
    1    -1 #include "fio.h"

diff --git a/rb_expermients/fio.h b/rb_expermients/fio.h

@@ -1,125 +0,0 @@
    1    -1 #ifndef __XIFIO_H
    2    -1 #define __XIFIO_H
    3    -1 
    4    -1 #include <sndfile.h>
    5    -1 #include <iostream>
    6    -1 #include "../src/marker.h"
    7    -1 #include <rubberband/RubberBandStretcher.h>
    8    -1 
    9    -1 using namespace std;
   10    -1 
   11    -1 class fio{
   12    -1   
   13    -1 };
   14    -1 
   15    -1 int main() {
   16    -1   // create marker
   17    -1   Marker marker;
   18    -1   marker.add(0,0);
   19    -1   marker.add(0.05,0.1);
   20    -1   marker.add(0.5,0.4);
   21    -1   marker.add(1,0.9);
   22    -1 
   23    -1   // load files
   24    -1 
   25    -1   const char *fileName="test.wav";
   26    -1   const char *fileNameOut="testo.wav";
   27    -1 
   28    -1   SNDFILE *sndfile;
   29    -1   SNDFILE *sndfileOut;
   30    -1   SF_INFO sfinfo;
   31    -1   SF_INFO sfinfoOut;
   32    -1 
   33    -1   sndfile = sf_open(fileName, SFM_READ, &sfinfo);
   34    -1     if (!sndfile) {
   35    -1       cerr << "ERROR: Failed to open input file \"" << fileName << "\": "
   36    -1       << sf_strerror(sndfile) << endl;
   37    -1     return 1;
   38    -1   }
   39    -1 
   40    -1   int channels= sfinfo.channels;
   41    -1 
   42    -1 //  int outFrames=int(marker.getRatio()*sfinfo.frames);
   43    -1   sfinfoOut.channels = sfinfo.channels;
   44    -1   sfinfoOut.format = sfinfo.format;
   45    -1 //  sfinfoOut.frames = outFrames;
   46    -1   sfinfoOut.samplerate = sfinfo.samplerate;
   47    -1   sfinfoOut.sections = sfinfo.sections;
   48    -1   sfinfoOut.seekable = sfinfo.seekable;
   49    -1 
   50    -1   sndfileOut = sf_open(fileNameOut, SFM_WRITE, &sfinfoOut) ;
   51    -1   if (!sndfileOut) {
   52    -1     cerr << "ERROR: Failed to open output file \"" << fileNameOut << "\" for writing: "
   53    -1     << sf_strerror(sndfileOut) << endl;
   54    -1     return 1;
   55    -1   }
   56    -1   const int bufferLength=100000;  // important
   57    -1   float ptr[bufferLength];
   58    -1   float **ibuf = new float *[channels];
   59    -1   for (size_t i = 0; i < channels; ++i) ibuf[i] = new float[bufferLength/channels];
   60    -1 
   61    -1   // *************************************** 
   62    -1   //  The reading is seperated in sections between markers and in buffer to save ram
   63    -1   //
   64    -1   for (int i=0; i<marker.length()-1; ++i) {
   65    -1     unsigned long frames=int((marker.getOld(i+1)-marker.getOld(i))*sfinfo.frames*channels); // number of frames to read
   66    -1     unsigned int count = 0; // # of read frames in this loop
   67    -1     unsigned long count2 = 0; // # of read frames alltogether
   68    -1     unsigned int frames2=0; // # of frames to read in this loop
   69    -1     float ratio=marker.getRatio(i);
   70    -1     while (count2<frames) {
   71    -1       if (frames-count2 < bufferLength)
   72    -1         frames2=frames-count2;
   73    -1       else
   74    -1         frames2=bufferLength;
   75    -1       count = sf_readf_float(sndfile, ptr, frames2/channels);
   76    -1       count2 += count;
   77    -1       if (count <=0) break;
   78    -1 
   79    -1       // float[] to **float
   80    -1       for (int c=0; c<channels; ++c) for (int j=0; j<bufferLength/channels; ++j) ibuf[c][j]=ptr[j*channels+c];
   81    -1 
   82    -1       float **ibuf2 = new float *[channels];
   83    -1       for (size_t j = 0; j < channels; ++j) ibuf2[j] = new float[int(bufferLength/channels*ratio)];
   84    -1 
   85    -1       RubberBand::RubberBandStretcher ts(sfinfo.samplerate, channels, 0, ratio);
   86    -1       int avail=int(bufferLength/channels*ratio);
   87    -1       ts.setMaxProcessSize(count*10);
   88    -1       ts.study(ibuf, count, true);
   89    -1       int a1=-1;
   90    -1       int a2=0;
   91    -1       while (a1!=a2) {
   92    -1         ts.process(ibuf, ts.getSamplesRequired(), false);
   93    -1         a1=a2;
   94    -1         a2=ts.available();
   95    -1       }
   96    -1       ts.process(ibuf, count, true); // hope two times is enough
   97    -1       ts.retrieve(ibuf2, avail);
   98    -1 
   99    -1       // **float to float[] and cutting
  100    -1       float ptr2[avail*channels];
  101    -1       for (size_t c = 0; c < channels; ++c) {
  102    -1         for (int j = 0; j < avail; ++j) {
  103    -1           float value = ibuf2[c][j];
  104    -1           if (value > 1.f) value = 1.f;
  105    -1           if (value < -1.f) value = -1.f;
  106    -1           ptr2[j*channels+c] = value;
  107    -1         }
  108    -1       }
  109    -1       for (int j=0; j<channels; ++j) delete[] ibuf2[j];
  110    -1       delete[] ibuf2;
  111    -1 
  112    -1       // write to file
  113    -1       sf_write_float(sndfileOut, ptr2, avail*channels);
  114    -1     }
  115    -1   }
  116    -1 
  117    -1   for (int i=0; i<channels; ++i) delete[] ibuf[i];
  118    -1   delete[] ibuf;
  119    -1 
  120    -1   sf_close(sndfile);
  121    -1   sf_close(sndfileOut);
  122    -1 
  123    -1 }
  124    -1 
  125    -1 #endif

diff --git a/rb_expermients/rb1 b/rb_expermients/rb1

@@ -1,6 +0,0 @@
    1    -1 include
    2    -1 
    3    -1 // für jeden Abschnitt wird ein Stretcher erstellt, der den Abschnitt anpasst
    4    -1 rb=new RubberBandStretcher(44100,1,DefaultOptions,ratio);
    5    -1 rb.study(abschnitt,abschnitt.length,true);
    6    -1 rb.process(abschnitt,abschnitt.length,true);

diff --git a/rb_expermients/rb2 b/rb_expermients/rb2

@@ -1,41 +0,0 @@
    1    -1 
    2    -1     SNDFILE *sndfile;
    3    -1     SNDFILE *sndfileOut;
    4    -1     SF_INFO sfinfo;
    5    -1     SF_INFO sfinfoOut;
    6    -1 
    7    -1     sndfile = sf_open(fileName, SFM_READ, &sfinfo);
    8    -1 
    9    -1     sfinfoOut.channels = sfinfo.channels;
   10    -1     sfinfoOut.format = sfinfo.format;
   11    -1     sfinfoOut.frames = int(sfinfo.frames * ratio + 0.1);
   12    -1     sfinfoOut.samplerate = sfinfo.samplerate;
   13    -1     sfinfoOut.sections = sfinfo.sections;
   14    -1     sfinfoOut.seekable = sfinfo.seekable;
   15    -1 
   16    -1     sndfileOut = sf_open(fileNameOut, SFM_WRITE, &sfinfoOut) 
   17    -1 
   18    -1     RubberBandStretcher ts(sfinfo.samplerate, channels, options,
   19    -1                            ratio, frequencyshift);
   20    -1 
   21    -1     float *fbuf = new float[channels * ibs];
   22    -1     float **ibuf = new float *[channels];
   23    -1     for (size_t i = 0; i < channels; ++i) ibuf[i] = new float[ibs];
   24    -1 
   25    -1         if ((count = sf_readf_float(sndfile, fbuf, ibs)) < 0) break;
   26    -1 
   27    -1             for (size_t c = 0; c < channels; ++c) {
   28    -1                 for (int i = 0; i < count; ++i) {
   29    -1                     float value = fbuf[i * channels + c];
   30    -1                     ibuf[c][i] = value;
   31    -1                 }
   32    -1             }
   33    -1 
   34    -1             ts.study(ibuf, count, final);
   35    -1         ts.process(ibuf, count, final);
   36    -1 
   37    -1 
   38    -1             sf_writef_float(sndfileOut, fobf, avail);
   39    -1 
   40    -1     sf_close(sndfile);
   41    -1     sf_close(sndfileOut);

diff --git a/rb_expermients/rb3 b/rb_expermients/rb3

@@ -1,28 +0,0 @@
    1    -1 
    2    -1 double getRatio(int i) {
    3    -1   float o1=marger.getOld(i);
    4    -1   float n1=marger.getNew(i);
    5    -1   float o2=marger.getOld(i+1);
    6    -1   float n2=marger.getNew(i+1);
    7    -1   return (n2-n1)/(o2-o1);
    8    -1 }
    9    -1 
   10    -1 int samples=10000000;
   11    -1 int sample_rate=44100
   12    -1 float[] raw=new float[samples];
   13    -1 
   14    -1 Marker marker=new Marker();
   15    -1 
   16    -1 marker.add(0,0);
   17    -1 marker.add(0.4,0.5);
   18    -1 marker.add(1,1);
   19    -1 
   20    -1 
   21    -1 for (int i=0; i<marker.length()-1; i++) {
   22    -1   RubberBandStretcher ts(sample_rate, 1, DefaultOptions, getRatio(i), 0);
   23    -1   ts.study(raw, raw.length, true);
   24    -1   ts.process(raw, raw.length, true);
   25    -1   int avail=ts.available();
   26    -1   float[] tmpRaw=new tmpRaw[avail];
   27    -1   addRaw(ts.recieve(tmpRaw,avail));
   28    -1 }

diff --git a/rb_expermients/rtlayer.cpp b/rb_expermients/rtlayer.cpp

@@ -1,8 +0,0 @@
    1    -1 #include "rtlayer.h"
    2    -1 
    3    -1 RTlayer::RTlayer() {
    4    -1   marker;
    5    -1 }
    6    -1 
    7    -1 RTlayer::~RTlayer() {
    8    -1 }

diff --git a/rb_expermients/rtlayer.h b/rb_expermients/rtlayer.h

@@ -1,41 +0,0 @@
    1    -1 #ifndef __XILAYER_H
    2    -1 #define __XILAYER_H
    3    -1 
    4    -1 #include <iostream>
    5    -1 #include "../src/marker.h"
    6    -1 #include <rubberband/RubberBandStretcher.h>
    7    -1 
    8    -1 
    9    -1 class RTlayer {
   10    -1 public:
   11    -1   RTlayer();
   12    -1   ~RTlayer();
   13    -1   Marker marker;
   14    -1 };
   15    -1 
   16    -1 
   17    -1 int main() {
   18    -1 
   19    -1   RTlayer layer;
   20    -1 
   21    -1   int samples=10000000;
   22    -1   int sample_rate=1024;
   23    -1   float* raw=new float[samples];
   24    -1 
   25    -1   layer.marker.add(0,0);
   26    -1   layer.marker.add(0.4,0.5);
   27    -1   layer.marker.add(1,1);
   28    -1 
   29    -1   for (int i=0; i<layer.marker.length()-1; i++) {
   30    -1     RubberBand::RubberBandStretcher ts(44100, 1, DefaultOptions);
   31    -1     ts.study(raw, raw.length, true);
   32    -1     ts.process(raw, raw.length, true);
   33    -1     int avail=ts.available();
   34    -1     float[] tmpRaw=new tmpRaw[avail];
   35    -1     addRaw(ts.recieve(tmpRaw,avail));
   36    -1   }
   37    -1 
   38    -1 }
   39    -1 
   40    -1 
   41    -1 #endif

diff --git a/src/sample.cpp b/src/sample.cpp

@@ -0,0 +1,131 @@
   -1     1 #include "sample.h"
   -1     2 
   -1     3 Sample::Sample(Marker* m) {
   -1     4   marker=m;
   -1     5   length=0;
   -1     6   data=new float[0];
   -1     7   olength=0;
   -1     8   odata=new float[0];
   -1     9 }
   -1    10 
   -1    11 Sample::~Sample() {
   -1    12   delete[] data;
   -1    13 }
   -1    14 
   -1    15 int Sample::getLength() {
   -1    16   return length;
   -1    17 }
   -1    18 
   -1    19 int Sample::loadFile(const char* fileName) {
   -1    20   SNDFILE *sndfile;
   -1    21   sfinfo;
   -1    22   // open file
   -1    23   sndfile = sf_open(fileName, SFM_READ, &sfinfo);
   -1    24   if (!sndfile) {
   -1    25     std::cerr << "ERROR: Failed to open input file \"" << fileName << "\": "
   -1    26     << sf_strerror(sndfile) << std::endl;
   -1    27     return 1;
   -1    28   }
   -1    29   // setup data
   -1    30   olength=sfinfo.frames; // apropriate length
   -1    31   delete[] odata;
   -1    32   odata=new float[olength];
   -1    33   
   -1    34   // read file into data
   -1    35   float ptr[10240*sfinfo.channels];
   -1    36   int count2=0;
   -1    37   while (true) {
   -1    38     int count = sf_readf_float(sndfile, ptr, 10240);
   -1    39     if (count <= 0) break;
   -1    40     // save ptr in data
   -1    41     for (int i=0; i<count*sfinfo.channels; i+=sfinfo.channels) {
   -1    42       odata[count2]=ptr[i];
   -1    43       count2++;
   -1    44     }
   -1    45   }
   -1    46   sf_close(sndfile);
   -1    47   olength=count2; // exact length
   -1    48   // fill data 
   -1    49   process();
   -1    50 }
   -1    51 
   -1    52 int Sample::writeFile(const char* fileNameOut) {  
   -1    53   if (length<=0) {
   -1    54     std::cerr << "ERROR: Load a file first" << std::endl;
   -1    55     return 1;
   -1    56   }
   -1    57   SNDFILE *sndfileOut;
   -1    58   SF_INFO sfinfoOut; 
   -1    59   // open file
   -1    60   sfinfoOut.channels = 1;
   -1    61   sfinfoOut.format = sfinfo.format;
   -1    62   sfinfoOut.samplerate = sfinfo.samplerate;
   -1    63   sfinfoOut.sections = sfinfo.sections;
   -1    64   sfinfoOut.seekable = sfinfo.seekable;
   -1    65 
   -1    66   sndfileOut = sf_open(fileNameOut, SFM_WRITE, &sfinfoOut) ;
   -1    67   if (!sndfileOut) {
   -1    68     std::cerr << "ERROR: Failed to open output file \"" << fileNameOut << "\" for writing: "
   -1    69     << sf_strerror(sndfileOut) << std::endl;
   -1    70     return 1;
   -1    71   }
   -1    72   sf_write_float(sndfileOut, data, length);
   -1    73   sf_close(sndfileOut);
   -1    74 }
   -1    75 
   -1    76 int Sample::process() {
   -1    77   //reads from odata and writes to data
   -1    78   const int bufferLength=100000;  // important
   -1    79   float **ibuf = new float *[1];
   -1    80   ibuf[0]=new float[bufferLength];
   -1    81   float **obuf = new float *[1];
   -1    82   int count2=0; // position in odata
   -1    83   int avail2=0; // position in data
   -1    84   // setup data
   -1    85   length=olength*marker->getRatio();
   -1    86   delete[] data;
   -1    87   data=new float[length];
   -1    88   for (int i=0; i<marker->length()-1; ++i) {
   -1    89     float ratio=marker->getRatio(i);
   -1    90     int count=0; // position in section (o)
   -1    91     int frames=int((marker->getOld(i+1)-marker->getOld(i))*olength); // length of section (o)
   -1    92     while (count<frames && count2<olength && avail2<length) {
   -1    93       // load odata to ibuf
   -1    94       for (int j=0; j<bufferLength && count2+j<olength; ++j) {
   -1    95         ibuf[0][j]=odata[count2+j];
   -1    96         count++;
   -1    97       }
   -1    98       count2+=bufferLength;
   -1    99       // process ibuf
   -1   100       RubberBand::RubberBandStretcher ts(sfinfo.samplerate, 1, 0, ratio);
   -1   101       ts.setMaxProcessSize(bufferLength*10);
   -1   102       ts.study(ibuf, bufferLength, true);
   -1   103       int a1=-1;
   -1   104       int a2=0;
   -1   105       while (a1!=a2) {
   -1   106         ts.process(ibuf, ts.getSamplesRequired(), false);
   -1   107         a1=a2;
   -1   108         a2=ts.available();
   -1   109       }
   -1   110       ts.process(ibuf, bufferLength, true); // hope two times is enough
   -1   111       int avail=ts.available();
   -1   112 
   -1   113       obuf[0]=new float[avail];
   -1   114       ts.retrieve(obuf, avail);
   -1   115       // write obuf to data
   -1   116       for (int j=0; j<avail && j+avail2<length; ++j) {
   -1   117         float value = obuf[0][j];
   -1   118         if (value > 1.f) value = 1.f;
   -1   119         if (value < -1.f) value = -1.f;
   -1   120         data[j+avail2] = value;
   -1   121       }
   -1   122       avail2+=avail;
   -1   123       delete[] obuf[0];
   -1   124     }
   -1   125   }
   -1   126   delete[] ibuf[0];
   -1   127   delete[] ibuf;
   -1   128   delete[] obuf;
   -1   129 }
   -1   130 
   -1   131 

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

@@ -0,0 +1,37 @@
   -1     1 #ifndef __XISAMPLE_H
   -1     2 #define __XISAMPLE_H
   -1     3 
   -1     4 #include <sndfile.h>
   -1     5 #include <iostream>
   -1     6 #include "marker.h"
   -1     7 #include <rubberband/RubberBandStretcher.h>
   -1     8 
   -1     9 class Sample {
   -1    10 public:
   -1    11   Sample(Marker* m);
   -1    12   ~Sample();
   -1    13   float *data;
   -1    14   int getLength();
   -1    15   int loadFile(const char* filename);
   -1    16   int writeFile(const char* filename);
   -1    17   int process();
   -1    18 private:
   -1    19   int length;
   -1    20   Marker* marker;
   -1    21   int olength;
   -1    22   float *odata;
   -1    23   SF_INFO sfinfo;
   -1    24 };
   -1    25 
   -1    26 int main() {
   -1    27   Marker* m=new Marker();
   -1    28   m->add(0,0);
   -1    29   m->add(1,1);
   -1    30   Sample s(m);
   -1    31   m->add(0.5,0.3);
   -1    32   int error;
   -1    33   error=s.loadFile("test.wav");
   -1    34   error=s.writeFile("testo.wav");
   -1    35 }
   -1    36 
   -1    37 #endif