[Solved]: Qt and asynchronous c++ midi library



  • 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



  • 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()



  • @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



  • [quote author="LuckyLiuk" date="1320946506"]@Peleron: thanks...

    but it doesn't work.

    [/quote]

    The player doesn't sound



  • 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 ?



  • 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.



  • @Gerolf

    Hmmm i think you have the reason. I'll try . Tnx



  • It works! Thanks.



  • 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 .



  • 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 .


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.