I have to synchonize a Metronome (wrote with libpd) and OpenGL graphics. I'd like to move some objects parallel with the metronome clicks. The language is C++, the Gui is made with WxWidgets, Threads with Poco, audio with RtAudio. The metronome works, OpenGL graphics too, I have only a problem with the synchronisation. I'm running both things with a Thread, but it actually doesn't works, the metronome run and the graphic is done after the metronome stops (and not parallel). i become the CGLError 10004 from OpenGL during the execution of the thread (if CLGError is = 0 the draw is going to be done). The object is moved when the thread is completed. Here is a part of the source code:
*************Threads***************** class MyThread : public Poco::Runnable { public: MyThread(BasicGLPane *pane, std::shared_ptr<SoundManager> man, std::shared_ptr<PdObject> obj);
virtual void run(); private: BasicGLPane *_pane; std::shared_ptr<SoundManager> _man; std::shared_ptr<PdObject> _obj; };
MyThread::MyThread(BasicGLPane *pane, std::shared_ptr<SoundManager> man, std::shared_ptr<PdObject> obj) { _pane = pane; _man = man; _obj = obj; }
void MyThread::run() { _man->play(); std::cout<<"MY Thread triangle_1"<<std::endl; //this is only for the test. I'm counting until 10 in PdObject, and then the execution will be stopped. The graphic should be moved during this time. while(_obj->getCounter()<10) _pane->startAnimation(); _man->stop(); }
****************Sound Manager**************** void SoundManager::init() { // Init pd if(!lpd->init(0, 2, sampleRate)) { std::cerr << "Could not init pd" << std::endl; exit(1); } if(audio->isStreamOpen()) { audio->closeStream(); } // Receive messages from pd lpd->setReceiver(object.get()); lpd->subscribe("metro-bang"); lpd->subscribe("switch");
std::cout << "\nRtAudio Version " << RtAudio::getVersion() << std::endl;
unsigned int devices = audio->getDeviceCount(); std::cout << "\nFound " << devices << " device(s) ...\n"; // Use the RtAudio API to connect to the default audio device. if(audio->getDeviceCount()==0){ std::cout << "There are no available sound devices." << std::endl; exit(1); }
parameters.deviceId = audio->getDefaultOutputDevice(); parameters.nChannels = 2;
options.streamName = "Pd Metronome"; options.flags = RTAUDIO_SCHEDULE_REALTIME; if ( audio->getCurrentApi() != RtAudio::MACOSX_CORE ) { options.flags |= RTAUDIO_MINIMIZE_LATENCY; // CoreAudio doesn't seem to like this } }
void SoundManager::play() { // send DSP 1 message to pd lpd->computeAudio(true); // load the patch open_patch("metro-main.pd"); try { audio->openStream( ¶meters, NULL, RTAUDIO_FLOAT32, sampleRate, &bufferFrames, &audioCallback, lpd.get(), &options ); audio->startStream(); } catch ( RtAudioError& e ) { std::cerr << e.getMessage() << std::endl; exit(1); } }
void SoundManager::stop() { lpd->sendBang("switch"); lpd->closePatch(patch); try { std::cout<<"close stream"<<std::endl; audio->closeStream(); } catch( RtAudioError& e) { e.printMessage(); } }
*********************GUI/OpenGL*****************
BasicGLPane::BasicGLPane(wxFrame* parent, int* args) : wxGLCanvas(parent, wxID_ANY, args, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE) { m_context = new wxGLContext(this);
//some code here, no important //enable Multithreading for OpenGL on OSX ctx = CGLGetCurrentContext(); err = CGLEnable( ctx, kCGLCEMPEngine); }
void BasicGLPane::startAnimation() { std::cout<<"Start Animation CGLError: "<<err<<std::endl; //Here I'moving the object. during the thread execution I become here the error CGLError 10004. For this reason the graphic is not draw until the thread is finished. if (err==0) { glTranslatef(p3->x, p3->y, 0); Refresh(); }
Refresh(); } //Thread execution. To test it, the thread is fired with the mouse right click. //The thread is fired, whitout any problems void BasicGLPane::rightClick(wxMouseEvent& event) { manager->init(); SLEEP(2000); startThread(); }
I have never work with libpd before. I don't have any Idea why this error occurrs, maybe is Rtaudio blocking the execution of OpenGL? It will be better to work with PortAudio? Or is my solution false? It would be nice to become some help. Regards. Luis