<div dir="ltr"><div class="gmail_quote"><div dir="ltr"><div><div><div>I have to synchonize a Metronome (wrote with libpd) and OpenGL graphics. I'd like to move some objects parallel with the metronome clicks.<br></div><div>The language is C++, the Gui is made with WxWidgets, Threads with Poco, audio with RtAudio.<br></div>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.<br></div>Here is a part of the source code:<br><br></div>*************Threads*****************<br><div>class MyThread : public Poco::Runnable {<br>public:<br> MyThread(BasicGLPane *pane, std::shared_ptr<SoundManager> man, std::shared_ptr<PdObject> obj);<br> <br> virtual void run();<br>private:<br> BasicGLPane *_pane;<br> std::shared_ptr<SoundManager> _man;<br> std::shared_ptr<PdObject> _obj;<br>};<br><br>MyThread::MyThread(BasicGLPane *pane, std::shared_ptr<SoundManager> man, std::shared_ptr<PdObject> obj) {<br> _pane = pane;<br> _man = man;<br> _obj = obj;<br>}<br><br>void MyThread::run() {<br> _man->play();<br> std::cout<<"MY Thread triangle_1"<<std::endl;<br> //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.<br> while(_obj->getCounter()<10)<br> _pane->startAnimation();<br> _man->stop();<br>}<br><br></div><div>****************Sound Manager****************<br>void SoundManager::init() {<br> // Init pd<br> if(!lpd->init(0, 2, sampleRate)) {<br> std::cerr << "Could not init pd" << std::endl;<br> exit(1);<br> }<br> if(audio->isStreamOpen()) {<br> audio->closeStream();<br> }<br> // Receive messages from pd<br> lpd->setReceiver(object.get());<br> lpd->subscribe("metro-bang");<br> lpd->subscribe("switch"); <br> <br> std::cout << "\nRtAudio Version " << RtAudio::getVersion() << std::endl;<br> <br> unsigned int devices = audio->getDeviceCount();<br> std::cout << "\nFound " << devices << " device(s) ...\n";<br> // Use the RtAudio API to connect to the default audio device.<br> if(audio->getDeviceCount()==0){<br> std::cout << "There are no available sound devices." << std::endl;<br> exit(1);<br> }<br> <br> parameters.deviceId = audio->getDefaultOutputDevice();<br> parameters.nChannels = 2;<br> <br> options.streamName = "Pd Metronome";<br> options.flags = RTAUDIO_SCHEDULE_REALTIME;<br> if ( audio->getCurrentApi() != RtAudio::MACOSX_CORE ) {<br> options.flags |= RTAUDIO_MINIMIZE_LATENCY; // CoreAudio doesn't seem to like this<br> }<br>}<br><br>void SoundManager::play() {<br> // send DSP 1 message to pd<br> lpd->computeAudio(true); <br> // load the patch<br> open_patch("metro-main.pd");<br> try {<br> audio->openStream( ¶meters, NULL, RTAUDIO_FLOAT32, sampleRate, &bufferFrames, &audioCallback, lpd.get(), &options );<br> audio->startStream();<br> }<br> catch ( RtAudioError& e ) {<br> std::cerr << e.getMessage() << std::endl;<br> exit(1);<br> }<br>}<br><br>void SoundManager::stop() {<br> lpd->sendBang("switch"); <br> lpd->closePatch(patch);<br> try {<br> std::cout<<"close stream"<<std::endl;<br> audio->closeStream();<br> }<br> catch( RtAudioError& e) {<br> e.printMessage();<br> }<br>}<br><br></div><div>*********************GUI/OpenGL*****************<br><br>BasicGLPane::BasicGLPane(wxFrame* parent, int* args) :<br>wxGLCanvas(parent, wxID_ANY, args, wxDefaultPosition, wxDefaultSize, wxFULL_REPAINT_ON_RESIZE) {<br> m_context = new wxGLContext(this);<br> <br></div><div> //some code here, no important<br></div><div> //enable Multithreading for OpenGL on OSX<br></div><div> ctx = CGLGetCurrentContext();<br> err = CGLEnable( ctx, kCGLCEMPEngine);<br>}<br><br>void BasicGLPane::startAnimation() { <br> std::cout<<"Start Animation CGLError: "<<err<<std::endl;<br></div><div> //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.<br></div><div> if (err==0) { <br> glTranslatef(p3->x, p3->y, 0);<br> Refresh();<br> }<br> <br> Refresh();<br>}<br></div><div>//Thread execution. To test it, the thread is fired with the mouse right click.<br></div><div>//The thread is fired, whitout any problems<br></div><div>void BasicGLPane::rightClick(wxMouseEvent& event) {<br> manager->init();<br> SLEEP(2000);<br> startThread();<br>} <br><br></div><div>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?<br></div><div>It would be nice to become some help.<br></div><div>Regards.<br></div><div>Luis <br></div></div>
</div><br></div>