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