xiRetimer

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

commit
2d192a61744920741155490dbae6b0f7c69b1f43
parent
f060e6e48a9aea8a9b923dad44be5901f927a6ff
Author
xi <tobias.bengfort@gmx.net>
Date
2010-11-01 16:26
0-1 conversion

Diffstat

A gui/a.out 0
M gui/curve.cpp 49 ++++++++++++++++++++++++++++++-------------------
M gui/curve.h 26 ++++++++++++++++----------
M gui/xiRTMainFrame.cpp 41 ++++++++++++++++++++---------------------
M gui/xiRTMainFrame.h 1 -
M src/buffer.cpp 28 ++++++++++++++--------------
M src/buffer.h 2 +-
M src/marker.cpp 67 ++++++++++++++++++++++++++++++++++++++++++++++++++-----------
M src/marker.h 24 ++++++++++++++++++------
M src/sample.cpp 10 +++++++++-
M src/sample.h 3 +--

11 files changed, 164 insertions, 87 deletions


diff --git a/gui/a.out b/gui/a.out

Binary files differ.

diff --git a/gui/curve.cpp b/gui/curve.cpp

@@ -1,39 +1,50 @@
    1     1 #include "curve.h"
    2     2 
    3    -1 Curve::Curve(Sample* s) {
    4    -1   sample=s;
    5    -1   data=sample->data;
    6    -1   screenwidth=0;
   -1     3 #include <cmath>
   -1     4 
   -1     5 Curve::Curve() {
   -1     6   marker=new Marker();
   -1     7   sample=new Sample(marker);
    7     8   seeker=0;
   -1     9   tempo=90;
    8    10 }
    9    11 
   10    -1 Curve::~Curve() {}
   -1    12 Curve::~Curve() {
   -1    13   delete[] sample;
   -1    14   delete[] marker;
   -1    15 }
   11    16 
   12    -1 float Curve::get(int i) {
   13    -1   int n=int((float)i/screenwidth*getDataLength());
   14    -1   if (n>=0 && n<getDataLength())
   15    -1     return data[n];
   16    -1   else
   17    -1     return 0;
   -1    17 float Curve::get(float nn) {
   -1    18   // TODO interpolation?
   -1    19   return sample->get(nn);
   18    20 }
   19    21 
   20    22 float Curve::getSeeker() {return seeker;}
   21    -1 void Curve::setSeeker(float s) {
   22    -1   if (s>=0 && s<=1) seeker=s;
   -1    23 void Curve::setSeeker(float nn) {
   -1    24   if (nn>=0 && nn<=1) seeker=nn;
   -1    25 }
   -1    26 
   -1    27 void Curve::setTempo(int bpm) {tempo=bpm;}
   -1    28 int Curve::getTempo() {return tempo;}
   -1    29 
   -1    30 void Curve::addMarker() {
   -1    31   float n=marker->nnew2new(seeker);
   -1    32   marker->add(marker->new2old(n),n);
   23    33 }
   24    34 
   25    -1 void Curve::setScreenWidth(int w) {screenwidth=w;}
   -1    35 void Curve::removeMarker() {
   -1    36   int i=marker->getAreaNew(marker->nnew2new(seeker));
   -1    37   marker->remove(i);
   -1    38 }
   26    39 
   27    40 void Curve::print() {
   28    -1   for (int i=0; i<screenwidth; ++i) {
   -1    41   for (int i=0; i<100; ++i) { // 100 or any number 
   29    42     for (float j=-1; j<get(i); j+=0.1)
   30    43       std::cout << "+";
   31    -1     if (getSeeker()==i)
   -1    44     if (std::abs(getSeeker()-i)<0.01)
   32    45       std::cout << " *";
   33    46     std::cout << std::endl;
   34    47   }
   35    48 }
   36    49 
   37    -1 inline int Curve::getDataLength() {
   38    -1   return sample->getLength();
   39    -1 }
   -1    50 

diff --git a/gui/curve.h b/gui/curve.h

@@ -4,28 +4,34 @@
    4     4 #include <iostream>
    5     5 #include "../src/sample.h"
    6     6 
   -1     7 // main part of the gui
   -1     8 // layer between screen and backend. Converts everything to screen (0-1) values
    7     9 class Curve {
    8    10 public:
    9    -1   Curve(Sample* s); 
   -1    11   Curve(); 
   10    12   ~Curve();
   11    -1   float get(int i);
   12    13   float getSeeker();
   13    -1   void setSeeker(float s);
   14    -1   void setScreenWidth(int w);
   -1    14   void setSeeker(float nn);
   -1    15   void setTempo(int bpm);
   -1    16   int getTempo();
   15    17   void print();
   -1    18   // direct access to sample
   -1    19   Sample* sample;
   -1    20   // indirect access to sample
   -1    21   float get(float nn);
   -1    22   // indirect access to marker
   -1    23   void addMarker();
   -1    24   void removeMarker();
   -1    25   // TODO indirect acces for drawing
   16    26 private:
   17    -1   int screenwidth;  // pixel
   18    27   float seeker; // 0-1
   19    -1   float* data;
   20    -1   int getDataLength();
   21    -1   Sample* sample;
   -1    28   Marker* marker;
   -1    29   int tempo; // bpm
   22    30 };
   23    31 
   24    32 /*
   25    33 int main() {
   26    34   Marker* m=new Marker();
   27    -1   m->add(0,0);
   28    -1   m->add(1,1);
   29    35   Sample* s=new Sample(m);
   30    36   m->add(0.5,0.3);
   31    37   int error;

diff --git a/gui/xiRTMainFrame.cpp b/gui/xiRTMainFrame.cpp

@@ -9,18 +9,12 @@
    9     9 #include <wx/filedlg.h>
   10    10 
   11    11 xiRTMainFrame::xiRTMainFrame( wxWindow* parent ) : MainFrame( parent ) {
   12    -1   marker=new Marker();
   13    -1   marker->add(0,0);
   14    -1   marker->add(1,0.9);
   15    -1   sample=new Sample(marker);
   16    -1   curve=new Curve(sample);
   -1    12   curve=new Curve();
   -1    13   sample=curve->sample;
   17    14   curve->setSeeker(0.3);
   18    -1   marker->add(0.5,0.6);
   19    15 }
   20    16 
   21    17 xiRTMainFrame::~xiRTMainFrame() {
   22    -1   delete[] marker;
   23    -1   delete[] sample;
   24    18   delete[] curve;
   25    19 }
   26    20 
@@ -76,16 +70,22 @@ void xiRTMainFrame::OnProcessClick( wxCommandEvent& event ) {
   76    70 
   77    71 void xiRTMainFrame::OnMSetClick( wxCommandEvent& event )
   78    72 {
   79    -1 	// TODO: Implement OnMSetClick
   -1    73   curve->addMarker();
   80    74 }
   81    75 
   82    76 void xiRTMainFrame::OnMRmClick( wxCommandEvent& event )
   83    77 {
   84    -1 	// TODO: Implement OnMSetClick
   -1    78   curve->removeMarker();
   85    79 }
   86    80 
   87    81 void xiRTMainFrame::paint() {
   88    -1   wxClientDC dc(this);
   -1    82   // TODO BufferedDC
   -1    83   wxClientDC dc2(this);
   -1    84   int w=0;
   -1    85   int h=0;
   -1    86   dc2.GetSize(&w,&h);
   -1    87   wxBufferedDC dc(&dc2,wxSize(w,h));
   -1    88 
   89    89   wxBrush brush(*wxBLACK); // red pen of width 1
   90    90   dc.SetBackground(brush);
   91    91   wxPen penCurve(*wxBLUE,1);
@@ -93,18 +93,17 @@ void xiRTMainFrame::paint() {
   93    93   wxPen penMarker(wxColor(255,255,0),1);
   94    94   dc.SetPen(penCurve);
   95    95   dc.Clear();
   96    -1   int w=0;
   97    -1   int h=0;
   98    -1   dc.GetSize(&w,&h);
   99    -1   curve->setScreenWidth(w);
   -1    96   // TODO nicer looking shape
  100    97   for (int i=0; i<w-1; ++i) {
  101    -1     dc.DrawLine(i,int(curve->get(i)*h+h)/2,i+1,int(curve->get(i+1)*h+h)/2);
  102    -1   }
  103    -1   dc.SetPen(penMarker);
  104    -1   for (int i=0; i<marker->length(); ++i) {
  105    -1     int n=int(marker->getNew(i)*w/marker->getNew(marker->length()-1));
  106    -1     dc.DrawLine(n,0,n,h);
   -1    98     dc.DrawLine(i,int(curve->get(i/(float)(w-1))*h+h)/2,i+1,int(curve->get((i+1)/(float)(w-1))*h+h)/2);
  107    99   }
   -1   100   // TODO display tempo bars ...
   -1   101   // TODO display marker
   -1   102 //  dc.SetPen(penMarker);
   -1   103 //  for (int i=0; i<marker->getLength(); ++i) {
   -1   104 //    int n=int(marker->getNew(i)*w/marker->getNew(marker->getLength()-1));
   -1   105 //    dc.DrawLine(n,0,n,h);
   -1   106 //  }
  108   107   dc.SetPen(penSeeker);
  109   108   int seek=int(curve->getSeeker()*w);
  110   109   dc.DrawLine(seek,0,seek,h);

diff --git a/gui/xiRTMainFrame.h b/gui/xiRTMainFrame.h

@@ -29,7 +29,6 @@ protected:
   29    29         void OnUpdateUI( wxUpdateUIEvent& event );
   30    30         void paint();
   31    31   Sample* sample;
   32    -1   Marker* marker;
   33    32   Curve* curve;
   34    33 	
   35    34 public:

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

@@ -2,7 +2,7 @@
    2     2 
    3     3 Buffer::Buffer() {
    4     4   _length=0;
    5    -1   array=new float[length()];
   -1     5   array=new float[getLength()];
    6     6 }
    7     7 
    8     8 Buffer::~Buffer() {
@@ -10,23 +10,23 @@ Buffer::~Buffer() {
   10    10 }
   11    11 
   12    12 float Buffer::get(int i) {
   13    -1   if (i>=0 && i<length())
   -1    13   if (i>=0 && i<getLength())
   14    14     return array[i];
   15    15   else
   16    16     return NULL;
   17    17 }
   18    18 
   19    19 void Buffer::set(int i, float v) {
   20    -1   if (i>=0 && i<=length()) array[i]=v;
   -1    20   if (i>=0 && i<=getLength()) array[i]=v;
   21    21 }
   22    22 
   23    23 void Buffer::insert(int i,float v) {
   24    -1   if (i>=0 && i<=length()) {
   25    -1     float* tmpArray=new float[length()+1];
   -1    24   if (i>=0 && i<=getLength()) {
   -1    25     float* tmpArray=new float[getLength()+1];
   26    26     for (int ii=0; ii<i; ii++)
   27    27       tmpArray[ii]=array[ii];
   28    28     tmpArray[i]=v;
   29    -1     for (int ii=i; ii<length(); ii++)
   -1    29     for (int ii=i; ii<getLength(); ii++)
   30    30       tmpArray[ii+1]=array[ii];
   31    31     delete[] array;
   32    32     array=tmpArray;
@@ -35,15 +35,15 @@ void Buffer::insert(int i,float v) {
   35    35 }
   36    36 
   37    37 void Buffer::add(float v) {
   38    -1   insert(length(),v);
   -1    38   insert(getLength(),v);
   39    39 }
   40    40 
   41    41 void Buffer::remove(int i) {
   42    -1   if (i>=0 && i<length()) {
   43    -1     float* tmpArray=new float[length()-1];
   -1    42   if (i>=0 && i<getLength()) {
   -1    43     float* tmpArray=new float[getLength()-1];
   44    44     for (int ii=0; ii<i; ii++)
   45    45       tmpArray[ii]=array[ii];
   46    -1     for (int ii=i+1; ii<length(); ii++)
   -1    46     for (int ii=i+1; ii<getLength(); ii++)
   47    47       tmpArray[ii-1]=array[ii];
   48    48     delete[] array;
   49    49     array=tmpArray;
@@ -51,16 +51,16 @@ void Buffer::remove(int i) {
   51    51   }
   52    52 }
   53    53 
   54    -1 int Buffer::length() {
   -1    54 int Buffer::getLength() {
   55    55   return _length;
   56    56 }
   57    57 
   58    58 void Buffer::print() {
   59    59   std::cout << "[";
   60    -1   for (int i=0; i<length()-1; i++)
   -1    60   for (int i=0; i<getLength()-1; i++)
   61    61     std::cout << get(i) << " ";
   62    -1   if (length() > 0)
   63    -1     std::cout << get(length()-1);
   -1    62   if (getLength() > 0)
   -1    63     std::cout << get(getLength()-1);
   64    64   std::cout << "]";
   65    65 }
   66    66 

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

@@ -12,7 +12,7 @@ public:
   12    12   void add(float v);
   13    13   void insert(int i,float v);
   14    14   void remove(int i);
   15    -1   int length();
   -1    15   int getLength();
   16    16   void print();
   17    17   void println();
   18    18 private:

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

@@ -3,17 +3,22 @@
    3     3 Marker::Marker() {
    4     4   anew;
    5     5   aold;
   -1     6   add(0,0);
   -1     7   add(1,1);
    6     8 }
    7     9 
    8    10 Marker::~Marker() {
    9    11 }
   10    12 
   11    13 void Marker::add(float pold, float pnew) {
   -1    14   if (pold<0 || pold>1) return;
   -1    15   if (getAreaOld(pold)!=getAreaNew(pnew)) return;
   12    16   anew.add(pnew);
   13    17   aold.add(pold);
   14    18 }
   15    19   
   16    -1 void Marker::rm(int pi) {
   -1    20 void Marker::remove(int pi) {
   -1    21   if (getLength()<=2) return;
   17    22   anew.remove(resort(pi));
   18    23   anew.remove(resort(pi));
   19    24 }
@@ -31,21 +36,21 @@ void Marker::setNew(int pi, float pnew) {
   31    36 }
   32    37 
   33    38 float Marker::getRatio() {
   34    -1   if (length()>0)
   35    -1     return (getNew(length()-1)-getNew(0))/(getOld(length()-1)-getOld(0));
   -1    39   if (getLength()>0)
   -1    40     return (getNew(getLength()-1)-getNew(0))/(getOld(getLength()-1)-getOld(0));
   36    41   else
   37    42     return NULL;
   38    43 }
   39    44 
   40    45 float Marker::getRatio(int i) {
   41    -1   if (i>=0 && i<length()-1)
   -1    46   if (i>=0 && i<getLength()-1)
   42    47     return (getNew(i+1)-getNew(i))/(getOld(i+1)-getOld(i));
   43    48   else
   44    49     return NULL;
   45    50 }
   46    51 
   47    -1 int Marker::length() {
   48    -1   return anew.length();
   -1    52 int Marker::getLength() {
   -1    53   return anew.getLength();
   49    54 }
   50    55 
   51    56 void Marker::println() {
@@ -54,17 +59,17 @@ void Marker::println() {
   54    59 }
   55    60 
   56    61 int Marker::resort(int pi) {
   57    -1   if (!(pi>=0 && pi<length())) return -1;
   -1    62   if (!(pi>=0 && pi<getLength())) return -1;
   58    63   // write anew and indices into arrays
   59    -1   float tnew[length()];
   60    -1   int ti[length()];
   61    -1   for (int i=0; i<length(); i++) {
   -1    64   float tnew[getLength()];
   -1    65   int ti[getLength()];
   -1    66   for (int i=0; i<getLength(); i++) {
   62    67     tnew[i]=anew.get(i);
   63    68     ti[i]=i;
   64    69   }
   65    70   // sort arrays
   66    -1   for (int j=0; j<length()-1; j++) {
   67    -1     for (int i=0; i<length()-1-j; i++) {
   -1    71   for (int j=0; j<getLength()-1; j++) {
   -1    72     for (int i=0; i<getLength()-1-j; i++) {
   68    73       if (tnew[i]>tnew[i+1]) {
   69    74         // swap
   70    75         float ttf;
@@ -81,3 +86,41 @@ int Marker::resort(int pi) {
   81    86   return ti[pi];
   82    87 }
   83    88 
   -1    89 float Marker::old2new(float o) {
   -1    90 // converts old 0-1 values to new 0-1 values
   -1    91   int i=getAreaOld(o);
   -1    92   // linear interpolation
   -1    93   //      n    - n_i        o    - o_i
   -1    94   //   -------------- =  --------------
   -1    95   //   n_{i+1} - n_i     o_{i+1} - o_i
   -1    96   return (o-getOld(i))/(getOld(i+1)-getOld(i))*(getNew(i+1)-getNew(i))+getNew(i);
   -1    97 }
   -1    98 
   -1    99 float Marker::new2old(float n) {
   -1   100 // see old2new
   -1   101   int i=getAreaNew(n);
   -1   102   return (n-getNew(i))/(getNew(i+1)-getNew(i))*(getOld(i+1)-getOld(i))+getOld(i);
   -1   103 }
   -1   104 
   -1   105 float Marker::new2nnew(float n) {
   -1   106   // normalizing
   -1   107   return (n-getNew(0))/(getNew(getLength()-1)-getNew(0));
   -1   108 }
   -1   109 
   -1   110 float Marker::nnew2new(float nn) {
   -1   111   return nn*(getNew(getLength()-1)-getNew(0))+getNew(0);
   -1   112 }
   -1   113 
   -1   114 int Marker::getAreaNew(float n) {
   -1   115   int i=0;
   -1   116   while (i<getLength()-1 && n<getNew(i+1)) ++i; // TODO n=getNew(i)
   -1   117   return i;
   -1   118 }
   -1   119 
   -1   120 int Marker::getAreaOld(float o) {
   -1   121   int i=0;
   -1   122   while (i<getLength()-1 && o<getOld(i+1)) ++i; // TODO o=getOld(i)
   -1   123   return i;
   -1   124 }
   -1   125 
   -1   126 

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

@@ -4,19 +4,33 @@
    4     4 #include <iostream>
    5     5 #include "buffer.h"
    6     6 
   -1     7 /*
   -1     8 marker works with float values
   -1     9 it mapps old values from 0 (start) to 1 (end) to any new float values
   -1    10 nnew values are normalized new values
   -1    11 most classes apart from marker use nnew values. Never forget to convert them!
   -1    12 */
   -1    13 
    7    14 class Marker {
    8    15 public:
    9    16   Marker();
   10    17   ~Marker();
   11    18   void add(float pold, float pnew);
   12    -1   void rm(int pi);
   -1    19   void remove(int pi);
   13    20   float getNew(int pi);
   14    21   float getOld(int pi);
   15    22   void setNew(int pi, float pnew);
   16    -1   float getRatio();
   17    -1   float getRatio(int i);
   18    -1   int length();
   -1    23   float getRatio(); // factor by wich the whole sample is stretched; used to guess the length of the output array;
   -1    24   float getRatio(int i); // factor by wich the is area is stretched;
   -1    25   int getLength();
   19    26   void println();
   -1    27   // 0-1 conversion
   -1    28   float old2new(float o);
   -1    29   float new2old(float n);
   -1    30   float new2nnew(float n);
   -1    31   float nnew2new(float n);
   -1    32   int getAreaNew(float n);
   -1    33   int getAreaOld(float o);
   20    34 private:
   21    35   Buffer anew;
   22    36   Buffer aold;
@@ -26,8 +40,6 @@ private:
   26    40 /*
   27    41 int main() {
   28    42   Marker m;
   29    -1   m.add(0,0);
   30    -1   m.add(1,1);
   31    43   m.add(0.5,0.4);
   32    44   std::cout << m.getNew(1) << std::endl;
   33    45 }

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

@@ -16,6 +16,13 @@ int Sample::getLength() {
   16    16   return length;
   17    17 }
   18    18 
   -1    19 float Sample::get(float nn) {
   -1    20   // TODO interpolation?
   -1    21   int i=int((getLength()-1)*nn);
   -1    22   if (i<0 || i>=getLength()) return NULL;
   -1    23   return data[i];
   -1    24 }
   -1    25 
   19    26 int Sample::loadFile(const char* fileName) {
   20    27   SNDFILE *sndfile;
   21    28   sfinfo;
@@ -38,6 +45,7 @@ int Sample::loadFile(const char* fileName) {
   38    45     int count = sf_readf_float(sndfile, ptr, 10240);
   39    46     if (count <= 0) break;
   40    47     // save ptr in data
   -1    48     // TODO downmix (maybe several options, maybe multichannel support)
   41    49     for (int i=0; i<count*sfinfo.channels; i+=sfinfo.channels) {
   42    50       odata[count2]=ptr[i];
   43    51       count2++;
@@ -85,7 +93,7 @@ int Sample::process() {
   85    93   length=olength*marker->getRatio();
   86    94   delete[] data;
   87    95   data=new float[length];
   88    -1   for (int i=0; i<marker->length()-1; ++i) {
   -1    96   for (int i=0; i<marker->getLength()-1; ++i) {
   89    97     float ratio=marker->getRatio(i);
   90    98     int count=0; // position in section (o)
   91    99     int frames=int((marker->getOld(i+1)-marker->getOld(i))*olength); // length of section (o)

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

@@ -11,6 +11,7 @@ public:
   11    11   Sample(Marker* m);
   12    12   ~Sample();
   13    13   float *data;
   -1    14   float get(float nn); // nnew
   14    15   int getLength();
   15    16   int loadFile(const char* filename);
   16    17   int writeFile(const char* filename);
@@ -26,8 +27,6 @@ private:
   26    27 /*
   27    28 int main() {
   28    29   Marker* m=new Marker();
   29    -1   m->add(0,0);
   30    -1   m->add(1,1);
   31    30   Sample s(m);
   32    31   m->add(0.5,0.3);
   33    32   int error;