<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( &parameters, 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>