- 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 Seeker40 -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 4445 -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