[Solved]: Qt and asynchronous c++ midi library
-
wrote on 10 Nov 2011, 12:52 last edited by
Hi guys,
i'm looking for develop a simple app with a third part c++ library the libjdkmidi (http://www.jdkoftinoff.com/main/Free_Projects/C++_MIDI_Library/)
Now i'm studying an example of the library that play a midifile. It works well in a console app...
The problem (a common problem :-) is integrate it in GUI app.
I've this code :
@MIDIFileReadStreamFile rs ( "c:/temp/360.mid" );
MIDIMultiTrack tracks ( 64 );
MIDIFileReadMultiTrack track_loader ( &tracks );
MIDIFileRead reader ( &rs, &track_loader );
//MIDISequencerGUIEventNotifierText gui ( stdout );
MIDISequencer seq ( &tracks );
MIDIDriverWin32 driver ( 128 );
MIDIManager mgr ( &driver );
reader.Parse();
driver.StartTimer ( 20 );
driver.OpenMIDIOutPort ( MIDI_MAPPER );
seq.GoToZero();
mgr.SetSeq ( &seq );
mgr.SetTimeOffset ( timeGetTime() );
mgr.SeqPlay();
getchar();
mgr.SeqStop();@now, the mgr.SeqPlay play the midifile and the getchar() function wait for an input allowing the mgr.SeqPlay to finish play the midifile.
obviously the getchar() freeze the GUI and i (for now) fix replacing it with
@ while (mgr.IsSeqPlay()) {qApp->processEvents();};@The problem is it take a lot of CPU (50% on a dualcore) because the processEvents is a cpu intensive processment.
Can you give me a point of start about it? What i must use, thread ? QtConcurrent? and ... how ?
Thanks for your help!
Luca
-
wrote on 10 Nov 2011, 14:18 last edited by
Make derived class of QRunnable
Reimplement method run() in your class:
@void run()
{
MIDIFileReadStreamFile rs ( "c:/temp/360.mid" );
MIDIMultiTrack tracks ( 64 );
MIDIFileReadMultiTrack track_loader ( &tracks );
MIDIFileRead reader ( &rs, &track_loader );
//MIDISequencerGUIEventNotifierText gui ( stdout );
MIDISequencer seq ( &tracks );
MIDIDriverWin32 driver ( 128 );
MIDIManager mgr ( &driver );
reader.Parse();
driver.StartTimer ( 20 );
driver.OpenMIDIOutPort ( MIDI_MAPPER );
seq.GoToZero();
mgr.SetSeq ( &seq );
mgr.SetTimeOffset ( timeGetTime() );
mgr.SeqPlay();
}@
Its enough if calling SeqStop() procedure not necessary.
Somewhere call this method via start() -
wrote on 10 Nov 2011, 17:35 last edited by
@Peleron: thanks...
i've tried this (as few examples found on the network)
@PlayerRunnable *pl= new PlayerRunnable ();
pl->setAutoDelete(false);
QThreadPool::globalInstance()->start(pl);@after reimplemented method run() as you wrote, but it doesn't work. I think it quit after the mgr.SeqPlay
-
wrote on 10 Nov 2011, 17:47 last edited by
i've fixed it with:
@ QEventLoop q;
mgr.SeqPlay();
q.exec();@but not sure if it's correct or can be give me problems . What do you think ?
-
wrote on 11 Nov 2011, 06:50 last edited by
For me, it looks like midi playback is already done in a thread. so I would make MIDIManager a member of my class, call mgr.SeqPlay(); and then return from the slot.
So no need of process event, qrunnable, a thread or whatever. -
wrote on 11 Nov 2011, 19:07 last edited by
It works! Thanks.
-
wrote on 14 Dec 2014, 18:11 last edited by
Hi LuckyLiuk,
I have the same problem, trying to play a midi file but it does not work . I would appreciate if you share you class .
-
wrote on 14 Dec 2014, 18:11 last edited by
Hi LuckyLiuk,
I have the same problem, trying to play a midi file but it does not work . I would appreciate if you share you class .