xiRetimer

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

commit
2fbadab87e33360d4f49eb04c59571a689395e00
parent
26ecaa375984e2837eb67a171940a53a58ebe899
Author
Tobias Bengfort <tobias.bengfort@gmx.net>
Date
2010-11-03 11:56
playback working

Diffstat

M src/gui/xiRTMainFrame.cpp 79 +++++++++++++++++++++++++++++--------------------------------
M src/gui/xiRTMainFrame.h 6 ++----
M src/make 2 +-
A src/playback.cpp 114 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A src/playback.h 20 ++++++++++++++++++++
M xiRetimer 0

6 files changed, 174 insertions, 47 deletions


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

@@ -11,14 +11,12 @@
   11    11 #include <iostream>
   12    12 
   13    13 xiRTMainFrame::xiRTMainFrame( wxWindow* parent ) : MainFrame( parent ) {
   14    -1   curve=new Curve();
   15    -1   sample=curve->sample;
   16    -1   playback=new Playback(sample);
   -1    14   curve;
   -1    15   playback=new Playback(curve.sample);
   17    16   width=100; // anything greater than 2
   18    17   height=100;
   19    18   Marker_move=false;
   20    19   Seeker_move=false;
   21    -1   _play=false;
   22    20 }
   23    21 
   24    22 xiRTMainFrame::~xiRTMainFrame() {}
@@ -27,19 +25,20 @@ xiRTMainFrame::~xiRTMainFrame() {}
   27    25 void xiRTMainFrame::OnLeftDown( wxMouseEvent& event ) {
   28    26   // check for Marker Select
   29    27   if (event.m_y<=MARKERWIDTH*4/5) {
   30    -1     for (int i=0; i<curve->getMarkerLength(); ++i) {
   31    -1       int n=int(curve->getMarker(i)*(width-1));
   -1    28     for (int i=0; i<curve.getMarkerLength(); ++i) {
   -1    29       int n=int(curve.getMarker(i)*(width-1));
   32    30       if (event.m_x<=n+MARKERWIDTH/2 && event.m_x>=n-MARKERWIDTH/2) {
   33    -1         curve->selectMarker(i);
   -1    31         curve.selectMarker(i);
   34    32         Marker_move=true;
   35    33         return;
   36    34       }
   37    35     }
   38    36   }
   39    37   // if not returned set Seeker
   40    -1   curve->setSeeker(event.m_x/(float)width);
   -1    38   curve.setSeeker(event.m_x/(float)width);
   -1    39   playback->setSeeker(curve.getSeeker());
   41    40   Seeker_move=true;
   42    -1   curve->selectMarker(-1);  //deselct
   -1    41   curve.selectMarker(-1);  //deselct
   43    42 }
   44    43 
   45    44 void xiRTMainFrame::OnLeftUp( wxMouseEvent& event ) {
@@ -50,75 +49,71 @@ void xiRTMainFrame::OnLeftUp( wxMouseEvent& event ) {
   50    49 void xiRTMainFrame::OnLeftDClick( wxMouseEvent& event ) {
   51    50   // check for Marker Select
   52    51   if (event.m_y<=MARKERWIDTH*4/5) {
   53    -1     for (int i=0; i<curve->getMarkerLength(); ++i) {
   54    -1       int n=int(curve->getMarker(i)*(width-1));
   -1    52     for (int i=0; i<curve.getMarkerLength(); ++i) {
   -1    53       int n=int(curve.getMarker(i)*(width-1));
   55    54       if (event.m_x<=n+MARKERWIDTH/2 && event.m_x>=n-MARKERWIDTH/2) {
   56    -1         curve->selectMarker(i);
   57    -1         curve->removeMarker();
   -1    55         curve.selectMarker(i);
   -1    56         curve.removeMarker();
   58    57         return;
   59    58       }
   60    59     }
   61    60   }
   62    -1   curve->setSeeker(event.m_x/(float)width);
   63    -1   curve->addMarker();
   -1    61   curve.setSeeker(event.m_x/(float)width);
   -1    62   curve.addMarker();
   64    63 }
   65    64 
   66    65 void xiRTMainFrame::OnMotion( wxMouseEvent& event ) {
   67    66   if (Marker_move)
   68    -1     curve->setMarker(event.m_x/(float)width);
   -1    67     curve.setMarker(event.m_x/(float)width);
   69    68   if (Seeker_move)
   70    -1     curve->setSeeker(event.m_x/(float)width);
   -1    69     curve.setSeeker(event.m_x/(float)width);
   71    70 }
   72    71 
   73    72 // ************  file  **************
   74    73 void xiRTMainFrame::OnOpenClick( wxCommandEvent& event )
   75    74 {
   76    75     wxFileDialog* dialog = new wxFileDialog( (wxWindow*)NULL );
   77    -1     dialog ->Show();
   -1    76     dialog->Show();
   78    77 
   79    78     if (dialog->ShowModal()==wxID_OK) {
   80    79       wxString filename=dialog->GetPath();
   81    -1       sample->loadFile(filename.mb_str());
   -1    80       curve.sample->loadFile(filename.mb_str());
   82    81     }
   83    82 }
   84    83 
   85    84 void xiRTMainFrame::OnExportClick( wxCommandEvent& event )
   86    85 {
   87    86     wxFileDialog* dialog = new wxFileDialog((wxWindow*)NULL, _T("Export As"), _T(""), _T(""), _T("*.wav"), wxSAVE | wxOVERWRITE_PROMPT);
   88    -1     dialog ->Show();
   -1    87     dialog->Show();
   89    88 
   90    89     if (dialog->ShowModal()==wxID_OK) {
   91    90       wxString filename=dialog->GetPath();
   92    -1       sample->process();
   93    -1       sample->writeFile(filename.mb_str());
   -1    91       curve.sample->process();
   -1    92       curve.sample->writeFile(filename.mb_str());
   94    93     }
   95    94 }
   96    95 
   97    96 // ************  playback  **************
   98    97 void xiRTMainFrame::OnStartClick( wxCommandEvent& event ) {
   99    -1   curve->setSeeker(0);
   -1    98   curve.setSeeker(0);
  100    99 }
  101   100 
  102   101 void xiRTMainFrame::OnPlayClick( wxCommandEvent& event ) {
  103    -1   if (_play) {
  104    -1     playback->stop();
  105    -1     _play=false;
  106    -1   }
  107    -1   else {
  108    -1     if (playback->start()==0)
  109    -1       _play=true;
  110    -1   }
   -1   102 std::cout << "play ";
   -1   103   int err;
   -1   104   err=playback->play();
   -1   105 std::cout << err << std::endl;
  111   106 }
  112   107 
  113   108 void xiRTMainFrame::OnEndClick( wxCommandEvent& event ) {
  114    -1   curve->setSeeker(1);
   -1   109   curve.setSeeker(1);
  115   110 }
  116   111 
  117   112 // ************  general  **************
  118   113 void xiRTMainFrame::OnPrefsClick( wxCommandEvent& event )
  119   114 {
  120   115     xiRTPrefsDialog* dialog = new xiRTPrefsDialog( (wxWindow*)NULL );
  121    -1     dialog ->Show();
   -1   116     dialog->Show();
  122   117 }
  123   118 
  124   119 void xiRTMainFrame::OnExitClick( wxCommandEvent& event )
@@ -130,12 +125,12 @@ void xiRTMainFrame::OnHelpClick( wxCommandEvent& event )
  130   125 {
  131   126 	// TODO: create Help
  132   127     xiRTAboutDialog* dialog = new xiRTAboutDialog( (wxWindow*)NULL );
  133    -1     dialog ->Show();
   -1   128     dialog->Show();
  134   129 }
  135   130 
  136   131 // ************  marker  **************
  137   132 void xiRTMainFrame::OnClearClick( wxCommandEvent& event ) {
  138    -1   curve->clearMarker();
   -1   133   curve.clearMarker();
  139   134 }
  140   135 
  141   136 
@@ -146,7 +141,7 @@ void xiRTMainFrame::OnProcessClick( wxCommandEvent& event ) {
  146   141     wxProgressDialog::wxProgressDialog* dialog = new wxProgressDialog( _T("processing..."), _T("please wait") );
  147   142     dialog ->Show();
  148   143 */
  149    -1     sample->process();
   -1   144     curve.sample->process();
  150   145 }
  151   146 
  152   147 void xiRTMainFrame::OnUpdateUI( wxUpdateUIEvent& event ) {paint();}
@@ -155,6 +150,7 @@ void xiRTMainFrame::OnUpdateUI( wxUpdateUIEvent& event ) {paint();}
  155   150 // ***********************************
  156   151 void xiRTMainFrame::paint() {
  157   152   // TODO dont repaint all the time
   -1   153   // TODO repaint also if UI update is not necessary, eg whe seeker is moving from playback
  158   154   wxClientDC dc2(this);
  159   155   dc2.GetSize(&width,&height);
  160   156   wxBufferedDC dc(&dc2,wxSize(width,height));
@@ -169,12 +165,11 @@ void xiRTMainFrame::paint() {
  169   165   dc.Clear();
  170   166   // TODO nicer looking shape
  171   167   for (int i=0; i<width-1; ++i) {
  172    -1     dc.DrawLine(i,int(curve->get(i/(float)(width-1))*h+height)/2,i+1,int(curve->get((i+1)/(float)(width-1))*h+height)/2);
   -1   168     dc.DrawLine(i,int(curve.get(i/(float)(width-1))*h+height)/2,i+1,int(curve.get((i+1)/(float)(width-1))*h+height)/2);
  173   169   }
  174    -1   // TODO display tempo bars !!!
  175   170   dc.SetPen(penMarker);
  176    -1   for (int i=0; i<curve->getMarkerLength(); ++i) {
  177    -1     int n=int(curve->getMarker(i)*(width-1));
   -1   171   for (int i=0; i<curve.getMarkerLength(); ++i) {
   -1   172     int n=int(curve.getMarker(i)*(width-1));
  178   173     dc.DrawLine(n,0,n,height);
  179   174     wxPoint ps[3];
  180   175     wxPoint p0(n-MARKERWIDTH/2,0);
@@ -187,11 +182,11 @@ void xiRTMainFrame::paint() {
  187   182   }
  188   183   // seeker
  189   184   dc.SetPen(penSeeker);
  190    -1   int seek=int(curve->getSeeker()*(width-1));
   -1   185   int seek=int(playback->getSeeker()*(width-1));
  191   186   dc.DrawLine(seek,0,seek,height);
  192   187   //beats
  193   188   dc.SetPen(penMarker);
  194    -1   int step=int(width/curve->getBars()/curve->getBeatResolution());
   -1   189   int step=int(width/curve.getBars()/curve.getBeatResolution());
  195   190   for (int i=0; i<width && step!=0; i+=step) {
  196   191     dc.DrawLine(i,0,i,BEAT);  
  197   192   }

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

@@ -42,14 +42,12 @@ protected:
   42    42   static const int MARKERWIDTH=15;
   43    43   static const int BEAT=15;
   44    44   
   45    -1   Sample *sample;
   46    -1   Curve *curve;
   47    -1   Playback *playback;
   -1    45   Curve curve;
   -1    46   Playback* playback;
   48    47   int width;
   49    48   int height;
   50    49   bool Marker_move;
   51    50   bool Seeker_move;
   52    -1   bool _play;
   53    51 	
   54    52 public:
   55    53 	/** Constructor */

diff --git a/src/make b/src/make

@@ -1,3 +1,3 @@
    1    -1 g++ *.h *.cpp gui/*.h gui/*.cpp `wx-config --cxxflags --libs` `sdl-config --cflags --libs` -lSDL_mixer `pkg-config --cflags --libs rubberband sndfile` -o ../xiRetimer
   -1     1 g++ *.h *.cpp gui/*.h gui/*.cpp `wx-config --cxxflags --libs` `sdl-config --cflags --libs` `pkg-config --cflags --libs rubberband sndfile` -o ../xiRetimer
    2     2 rm *.gch
    3     3 rm gui/*.gch

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

@@ -0,0 +1,114 @@
   -1     1 #include "playback.h"
   -1     2 
   -1     3 struct sample {
   -1     4     Uint8 *data;
   -1     5     Uint32 dpos;
   -1     6     Uint32 dlen;
   -1     7 } sounds;
   -1     8 
   -1     9   Sample* sample;
   -1    10   float seeker;
   -1    11   bool _play;
   -1    12 
   -1    13 Playback::Playback(Sample* s) {
   -1    14   sample=s;
   -1    15   _play=false;
   -1    16   seeker=0;
   -1    17 
   -1    18   extern void callback(void *unused, Uint8 *stream, int len);
   -1    19   SDL_AudioSpec fmt;
   -1    20 
   -1    21   /* Set 16-bit stereo audio at 22Khz */
   -1    22   fmt.freq = 44100/2; // TODO dont know why it takes the double sample-.frequenzy here // TODO link it to sample->sfinfo.samplerate
   -1    23   fmt.format = AUDIO_S16;
   -1    24   fmt.channels = 1;
   -1    25   fmt.samples = 1024;
   -1    26   fmt.callback = callback;
   -1    27   fmt.userdata = NULL;
   -1    28 
   -1    29   /* Open the audio device and start playing sound! */
   -1    30   if ( SDL_OpenAudio(&fmt, NULL) < 0 ) {
   -1    31     fprintf(stderr, "Unable to open audio: %s\n", SDL_GetError());
   -1    32     exit(1);
   -1    33   }
   -1    34   SDL_PauseAudio(0);
   -1    35 }
   -1    36 
   -1    37 Playback::~Playback() {
   -1    38   SDL_CloseAudio();
   -1    39 }
   -1    40 
   -1    41 int Playback::play() {
   -1    42   if (_play) {
   -1    43     stop();
   -1    44     _play=false;
   -1    45     return 0;
   -1    46   }
   -1    47   else {
   -1    48     int err=start();
   -1    49     if (err==0) _play=true;
   -1    50     return err;
   -1    51   }
   -1    52 }
   -1    53 
   -1    54 int Playback::start() {
   -1    55 //    if ( sounds.dpos != sounds.dlen )
   -1    56 //        return 1;
   -1    57 
   -1    58   SDL_LockAudio();
   -1    59 
   -1    60 //    if ( sounds.data ) {
   -1    61 //        free(sounds.data);
   -1    62 //    }
   -1    63 
   -1    64     int length=sample->getLength();
   -1    65     Uint8 idata[length];
   -1    66     for (int i=0; i<length; ++i) {
   -1    67       idata[i]=int(sample->data[i]*128);
   -1    68     }
   -1    69 std::cout << length << " ";
   -1    70     /* Put the sound data in the slot (it starts playing immediately) */
   -1    71     sounds.dlen = length;
   -1    72     sounds.data = idata;
   -1    73     sounds.dpos = int(seeker*length);
   -1    74 
   -1    75   SDL_UnlockAudio();
   -1    76 }
   -1    77 
   -1    78 void callback(void *udata, Uint8 *stream, int len) {
   -1    79   Uint32 amount;
   -1    80 
   -1    81   amount = (sounds.dlen-sounds.dpos);
   -1    82   if ( amount > len ) {
   -1    83     amount = len;
   -1    84   }
   -1    85   SDL_MixAudio(stream, &sounds.data[sounds.dpos], amount, SDL_MIX_MAXVOLUME);
   -1    86   sounds.dpos += amount;
   -1    87 
   -1    88   // update
   -1    89   if (sounds.dpos==sounds.dlen)
   -1    90     _play=false;
   -1    91   if (_play)
   -1    92     seeker=sounds.dpos/(float)sounds.dlen;
   -1    93 }
   -1    94 
   -1    95 void Playback::stop() {
   -1    96   seeker=sounds.dpos/(float)sounds.dlen;
   -1    97   SDL_LockAudio();
   -1    98   sounds.dpos=sounds.dlen;
   -1    99   SDL_UnlockAudio();
   -1   100 }
   -1   101 
   -1   102 void Playback::setSeeker(float nn) {
   -1   103   seeker=nn;
   -1   104   if (_play) {
   -1   105     SDL_LockAudio();
   -1   106     sounds.dpos = int(seeker*sounds.dlen);
   -1   107     SDL_UnlockAudio();
   -1   108   }
   -1   109 }
   -1   110 
   -1   111 float Playback::getSeeker() {
   -1   112   return seeker;
   -1   113 }
   -1   114 

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

@@ -0,0 +1,20 @@
   -1     1 #include <iostream>
   -1     2 
   -1     3 #include "SDL.h"
   -1     4 #include "SDL_audio.h"
   -1     5 
   -1     6 #include "sample.h"
   -1     7 
   -1     8 class Playback {
   -1     9 public:
   -1    10   Playback(Sample* s);
   -1    11   ~Playback();
   -1    12   int play();
   -1    13   void setSeeker(float nn);
   -1    14   float getSeeker();
   -1    15 private:
   -1    16   int start();
   -1    17   void stop();
   -1    18 };
   -1    19 
   -1    20 

diff --git a/xiRetimer b/xiRetimer

Binary files differ.