Hi Sebastian and other hydrogen friends ;-)

I made support for loading playlist in h2cli - and also a little patch around 
handling playlist. It works quiet well ..

.. but there is some problem , which I can't cope - it sometimes dump core :(

I hope you can find a bug. Steps for reproduce:
In h2cli , change songs on playlist few times - and then try to live (by 
pressing CTRL+C i.e. SIGINT signal) it got segfault on line 328 (delete song).

In hydrogen it fail after few fast song changes (via MIDI). Sometimes it can 
took a while. I assume that this two problem are related.

#0  NotePropertiesRuler::updateEditor (this=0x1dbd2f0) at 
/home/xj/Muzyka/hydrogen/src/gui/src/PatternEditor/NotePropertiesRuler.cpp:1249
#1  0x00000000004ec089 in HydrogenApp::onEventQueueTimer (this=0xb3f630) at 
/home/xj/Muzyka/hydrogen/src/gui/src/HydrogenApp.cpp:527
#2  0x00007ffff67b80ef in QMetaObject::activate(QObject*, QMetaObject const*, 
int, void**) () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#3  0x00007ffff67bd3ec in QObject::event(QEvent*) () from 
/usr/lib/x86_64-linux-gnu/libQtCore.so.4
#4  0x00007ffff700c8ec in QApplicationPrivate::notify_helper(QObject*, QEvent*) 
() from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#5  0x00007ffff700f25b in QApplication::notify(QObject*, QEvent*) () from 
/usr/lib/x86_64-linux-gnu/libQtGui.so.4
#6  0x00007ffff67a363e in QCoreApplication::notifyInternal(QObject*, QEvent*) 
() from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#7  0x00007ffff67d4b72 in ?? () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#8  0x00007ffff67d19a4 in ?? () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#9  0x00007ffff67d19c1 in ?? () from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#10 0x00007ffff3c08f05 in g_main_context_dispatch () from 
/lib/x86_64-linux-gnu/libglib-2.0.so.0
#11 0x00007ffff3c09248 in ?? () from /lib/x86_64-linux-gnu/libglib-2.0.so.0
#12 0x00007ffff3c09304 in g_main_context_iteration () from 
/lib/x86_64-linux-gnu/libglib-2.0.so.0
#13 0x00007ffff67d2016 in 
QEventDispatcherGlib::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () 
from /usr/lib/x86_64-linux-gnu/libQtCore.so.4
#14 0x00007ffff70b21ae in ?? () from /usr/lib/x86_64-linux-gnu/libQtGui.so.4
#15 0x00007ffff67a238f in 
QEventLoop::processEvents(QFlags<QEventLoop::ProcessEventsFlag>) () from 
/usr/lib/x86_64-linux-gnu/libQtCore.so.4
#16 0x00007ffff67a2618 in 
QEventLoop::exec(QFlags<QEventLoop::ProcessEventsFlag>) () from 
/usr/lib/x86_64-linux-gnu/libQtCore.so.4
#17 0x00007ffff67a7cf6 in QCoreApplication::exec() () from 
/usr/lib/x86_64-linux-gnu/libQtCore.so.4
#18 0x000000000044a61f in main (argc=5, argv=<optimized out>) at 
/home/xj/Muzyka/hydrogen/src/gui/src/main.cpp:431


Dnia Piątek, 21 Czerwca 2013 21:52 <[email protected]> napisał(a) 
> Hi Pawel!
> 
> I had a short look at the code that you've mentioned and it has really a 
> quite bad design. I don't have the time to refactor those parts, i would 
> rather spent my hydrogen-time on fixing bugs for 0.9.6. But if you want 
> to make a first try and clean up the code,  i can offer to help you with 
> that and have a look at your patches and help if you don't now how to 
> proceed.
> 
> So what has to be done? Basically, all non-gui stuff (setting the song, 
> storing it into the 'Preferences' class) should go definitely into the 
> core of hydrogen (class hydrogen in src/core/src) or into playlist.cpp. 
> The Event that you have found should trigger only the refreshing of the 
> gui elements which show song/playlist dependent stuff. I don't think 
> that the changes will be huge, since the playlist functionality is quite 
> small.
> 
> Hope that helps,
> Sebastian
> 
> On 2013-06-19 9:43, Pawel wrote:
> > Thanks Sebastian !
> > 
> > I was dig a little into code and looks that playlist code is strongly
> > bind to gui code. I was able to implement code for loading playlist ,
> > but this is not enough for load songs. For now there is only possible
> > to load first Song on start (because we can get path from playlist
> > array), but changing song is not possible , because related event:
> > EVENT_PLAYLIST_LOADSONG
> > 
> > Is handled by gui/src/HydrogenApp.cpp file. Unfortunately it's far
> > away from my C++/Hydrogen code knowledge to clean this mess (to many
> > dependencies).
> > 
> > Therefore I see two option:
> > - someone else clean this mess and then I provide patch for h2cli
> > (better option)
> > - I re-implement load playlist code and EVENT_PLAYLIST_LOADSONG event 
> > handling.
> > 
> > P.
> > 
> > Dnia Niedziela, 16 Czerwca 2013 21:21 <[email protected]> napisał(a)
> >> Hi Pawel,
> >> 
> >> thanks again for the patch! I've just pushed it into our git
> >> repository.
> >> About the playlist stuff: I haven't written the playlist code, so i
> >> don't have an answer to your question without looking closer at the
> >> code. But i guess if you look at main.cpp and MainForm.cpp, you should
> >> find the (gui) code for the playlist initialization (if there is 
> >> any..).
> >> If you have any problems with the integration just ask again, then i
> >> will have a deeper look at the code on the next weekend :)
> >> Best regards,
> >> Sebastian
> >> 
> >> On 15.06.2013 13:06, Pawel wrote:
> >> > Hi,
> >> >
> >> > I improved this patch to allow also map Program Change messages - so
> >> > now user can change songs using Program Change messages ;-)
> >> >
> >> > It is still possible to use PC messages as in previous version (for
> >> > select next pattern) if user map appropriate action.
> >> >
> >> > Please append it to official repo.
> >> >
> >> > BTW. my first question from previous mail is still valid.
> >> >
> >> > Pawel
> >> >
> >> > Dnia Poniedziałek, 10 Czerwca 2013 22:54 Pawel <[email protected]> napisał(a)
> >> >> Hi,
> >> >>
> >> >> I've done simple patch for handling playlist via MIDI. For my
> >> >> purpose I use it for precisely select song to play live (via CC). In
> >> >> my M-Audio Axiom I can set fixed MIDI CC value to buttons.
> >> >>
> >> >> Meantime I have two question:
> >> >> 1) I want to add support for playlist in h2cli. Please tell me it is
> >> >> enough to just call
> >> >> LocalFileMng::loadPlayList
> >> >>
> >> >> ?
> >> >>
> >> >> 2) Currently Program Change messages are restricted to pattern
> >> >> switching , will be OK for you to add support for mapping this
> >> >> messages ? I imagine scenario where I could load playlist in h2cli and
> >> >> change songs via Program Change messages - this is actually my long
> >> >> term goal ;-)
> >> >>
> >> >> Best Regards
> >> >> Xj
> >> 
> >> 
> >> ------------------------------------------------------------------------------
> >> This SF.net email is sponsored by Windows:
> >> 
> >> Build for Windows Store.
> >> 
> >> http://p.sf.net/sfu/windows-dev2dev
> >> _______________________________________________
> >> Hydrogen-devel mailing list
> >> [email protected]
> >> https://lists.sourceforge.net/lists/listinfo/hydrogen-devel
> > 
> > 
> > 
> > ------------------------------------------------------------------------------
> > This SF.net email is sponsored by Windows:
> > 
> > Build for Windows Store.
> > 
> > http://p.sf.net/sfu/windows-dev2dev
> > _______________________________________________
> > Hydrogen-devel mailing list
> > [email protected]
> > https://lists.sourceforge.net/lists/listinfo/hydrogen-devel
> 
> ------------------------------------------------------------------------------
> This SF.net email is sponsored by Windows:
> 
> Build for Windows Store.
> 
> http://p.sf.net/sfu/windows-dev2dev
> _______________________________________________
> Hydrogen-devel mailing list
> [email protected]
> https://lists.sourceforge.net/lists/listinfo/hydrogen-devel

diff --git a/src/cli/main.cpp b/src/cli/main.cpp
index ef0cf1f..279bdab 100644
--- a/src/cli/main.cpp
+++ b/src/cli/main.cpp
@@ -39,6 +39,7 @@
 #include <hydrogen/h2_exception.h>
 #include <hydrogen/playlist.h>
 #include <hydrogen/helpers/filesystem.h>
+#include <hydrogen/LocalFileMng.h>
 
 #include <iostream>
 #include <signal.h>
@@ -51,6 +52,7 @@ void showUsage();
 static struct option long_opts[] = {
 	{"driver", required_argument, NULL, 'd'},
 	{"song", required_argument, NULL, 's'},
+	{"playlist", required_argument, NULL, 'p'},
 	{"bits", required_argument, NULL, 'b'},
 	{"rate", required_argument, NULL, 'r'},
 	{"outfile", required_argument, NULL, 'o'},
@@ -93,6 +95,7 @@ int main(int argc, char *argv[])
 
 		// Deal with the options
 		QString songFilename;
+		QString playlistFilename;
 		QString outFilename = NULL;
 		QString sSelectedDriver;
 		bool showVersionOpt = false;
@@ -105,10 +108,9 @@ int main(int argc, char *argv[])
 		short interpolation = 0;
 
 		int c;
-		for (;;) {
+		while ( 1 ) {
 			c = getopt_long(argc, argv, opts, long_opts, NULL);
-			if (c == -1)
-				break;
+			if ( c == -1 ) break;
 
 			switch(c) {
 			case 'd':
@@ -117,6 +119,9 @@ int main(int argc, char *argv[])
 			case 's':
 				songFilename = QString::fromLocal8Bit(optarg);
 				break;
+			case 'p':
+				playlistFilename = QString::fromLocal8Bit(optarg);
+				break;
 			case 'o':
 				outFilename = QString::fromLocal8Bit(optarg);
 				break;
@@ -138,11 +143,7 @@ int main(int argc, char *argv[])
 				showVersionOpt = true;
 				break;
 			case 'V':
-				if ( optarg ) {
-					logLevelOpt = optarg;
-				} else {
-					logLevelOpt = "Warning";
-				}
+				logLevelOpt = (optarg) ? optarg : "Warning";
 				break;
 			case 'h':
 			case '?':
@@ -227,28 +228,48 @@ int main(int argc, char *argv[])
 		H2Core::Hydrogen::create_instance();
 		H2Core::Hydrogen *hydrogen = H2Core::Hydrogen::get_instance();
 
-		// Load default song
+		// Load playlist
 		H2Core::Song *song = NULL;
-		if ( !songFilename.isEmpty() ) {
-			song = H2Core::Song::load( songFilename );
-		}
-		else {
-			/* Try load last song */
-			bool restoreLastSong = preferences->isRestoreLastSongEnabled();
-			QString filename = preferences->getLastSongFilename();
-			if ( restoreLastSong && ( !filename.isEmpty() )) {
-				song = H2Core::Song::load( filename );
+		if( ! playlistFilename.isEmpty() ){
+			H2Core::LocalFileMng fileMng;
+			int err = fileMng.loadPlayList( playlistFilename.toLocal8Bit().constData() );
+			if ( err == 0 ) {
+				preferences->setLastPlaylistFilename( playlistFilename );
+				Playlist::get_instance()->setNextSongByNumber( 0 );
+				song = hydrogen->getSong();
+
+				if( hydrogen->m_PlayList.size() > 0){
+					for ( uint i = 0; i < hydrogen->m_PlayList.size(); ++i ) {
+						std::cout << i << "." << hydrogen->m_PlayList[i].m_hFile.toLocal8Bit().constData() << std::endl;
+					}
+				}
+			} else {
+				___ERRORLOG( "Error loading the playlist" );
 			}
 		}
 
-		if (! song) {
-			___INFOLOG("Starting with empty song");
-			song = H2Core::Song::get_empty_song();
-			song->set_filename( "" );
-		}
+		// Load song - if wasn't already loaded with playlist
+		if ( ! song ) {
+			if ( !songFilename.isEmpty() ) {
+				song = H2Core::Song::load( songFilename );
+			} else {
+				/* Try load last song */
+				bool restoreLastSong = preferences->isRestoreLastSongEnabled();
+				QString filename = preferences->getLastSongFilename();
+				if ( restoreLastSong && ( !filename.isEmpty() ))
+					song = H2Core::Song::load( filename );
+			}
 
-		hydrogen->setSong( song );
-		preferences->setLastSongFilename( songFilename );
+			/* Still not loaded */
+			if (! song) {
+				___INFOLOG("Starting with empty song");
+				song = H2Core::Song::get_empty_song();
+				song->set_filename( "" );
+			}
+		
+			hydrogen->setSong( song );
+			preferences->setLastSongFilename( songFilename );
+		}
 
 		if( ! drumkitToLoad.isEmpty() ){
 			H2Core::Drumkit* drumkitInfo = H2Core::Drumkit::load( H2Core::Filesystem::drumkit_path_search( drumkitToLoad ), true );
@@ -301,12 +322,11 @@ int main(int argc, char *argv[])
 			}
 		}
 
-		if ( (hydrogen->getState() == STATE_PLAYING) ) {
+		if ( hydrogen->getState() == STATE_PLAYING )
 			hydrogen->sequencer_stop();
-		}
 
-		delete Playlist::get_instance();
 		delete song;
+		delete Playlist::get_instance();
 
 		delete eQueue;
 		delete hydrogen;
@@ -360,6 +380,7 @@ void showUsage()
 	std::cout << "Usage: hydrogen [-v] [-h] -s file" << std::endl;
 	std::cout << "   -d, --driver AUDIODRIVER - Use the selected audio driver (jack, alsa, oss)" << std::endl;
 	std::cout << "   -s, --song FILE - Load a song (*.h2song) at startup" << std::endl;
+	std::cout << "   -p, --playlist FILE - Load a playlist (*.h2playlist) at startup" << std::endl;
 	std::cout << "   -o, --outfile FILE - Output to file (export)" << std::endl;
 	std::cout << "   -r, --rate RATE - Set bitrate while exporting file" << std::endl;
 	std::cout << "   -b, --bits BITS - Set bits depth while exporting file" << std::endl;
diff --git a/src/core/src/playlist.cpp b/src/core/src/playlist.cpp
index ad69db5..da32ccf 100644
--- a/src/core/src/playlist.cpp
+++ b/src/core/src/playlist.cpp
@@ -29,11 +29,8 @@
 #include <vector>
 #include <cstdlib>
 
-
-
 using namespace H2Core;
 
-
 Playlist* Playlist::__instance = NULL;
 
 const char* Playlist::__class_name = "Playlist";
@@ -53,16 +50,12 @@ Playlist::Playlist()
 	activeSongNumber = -1;
 }
 
-
-
 Playlist::~Playlist()
 {
 	//_INFOLOG( "[~Playlist]" );
 	__instance = NULL;
 }
 
-
-
 void Playlist::create_instance()
 {
 	if ( __instance == 0 ) {
@@ -70,48 +63,64 @@ void Playlist::create_instance()
 	}
 }
 
-
-
 void Playlist::setNextSongByNumber(int songNumber)
 {
+	Hydrogen *hydrogen = Hydrogen::get_instance();
 
-
-	if ( songNumber > (int)Hydrogen::get_instance()->m_PlayList.size() -1 || (int)Hydrogen::get_instance()->m_PlayList.size() == 0 )
+	if ( songNumber > (int) hydrogen->m_PlayList.size() -1 || (int) hydrogen->m_PlayList.size() == 0 )
 		return;
 
 	setSelectedSongNr( songNumber );
 	setActiveSongNumber( songNumber );
 
+	QString selected = hydrogen->m_PlayList[ songNumber ].m_hFile;
+     	Song *pSong = Song::load( selected );
+        if ( ! pSong ) return;
+
+	Song* oldSong = hydrogen->getSong();
+	if (oldSong != NULL) {
+		hydrogen->removeSong();
+		delete oldSong;
+		oldSong = NULL;
+	}
+
+	if ( hydrogen->getState() == STATE_PLAYING )
+		hydrogen->sequencer_stop();
+	hydrogen->m_timelinetagvector.clear();
+        hydrogen->setSelectedPatternNumber( 0 );
+        hydrogen->setSong( pSong );
+
+        Preferences *pPref = Preferences::get_instance();
+        Preferences::get_instance()->setLastSongFilename( pSong->get_filename() );
+        vector<QString> recentFiles = pPref->getRecentFiles();
+        recentFiles.insert( recentFiles.begin(), selected );
+        pPref->setRecentFiles( recentFiles );
+
 	EventQueue::get_instance()->push_event( EVENT_PLAYLIST_LOADSONG, songNumber);
 
 	execScript( songNumber );
 }
 
-
 void Playlist::setSelectedSongNr( int songNumber )
 {
 	selectedSongNumber = songNumber;
 }
 
-
 int Playlist::getSelectedSongNr()
 {
 	return selectedSongNumber;
 }
 
-
 void Playlist::setActiveSongNumber( int ActiveSongNumber)
 {
 	activeSongNumber = ActiveSongNumber ;
 }
 
-
 int Playlist::getActiveSongNumber()
 {
 	return activeSongNumber;
 }
 
-
 void Playlist::execScript( int index)
 {
 	QString file;
diff --git a/src/gui/src/MainForm.cpp b/src/gui/src/MainForm.cpp
index 0b0e354..c163118 100644
--- a/src/gui/src/MainForm.cpp
+++ b/src/gui/src/MainForm.cpp
@@ -1491,9 +1491,25 @@ void MainForm::errorEvent( int nErrorCode )
 
 void MainForm::playlistLoadSongEvent(int nIndex)
 {
+	Hydrogen *engine = Hydrogen::get_instance();
+
+	Song *pSong =  engine->getSong();
+	if ( ! pSong ) return;
+
+        h2app->getSongEditorPanel()->updateAll();
+        h2app->getPatternEditorPanel()->updateSLnameLabel();
+
+        QString songName( pSong->__name );
+        if( songName == "Untitled Song" && !pSong->get_filename().isEmpty() ){
+                songName = pSong->get_filename();
+                songName = songName.section( '/', -1 );
+        }
+        setWindowTitle( songName  );
+
+        h2app->getMainForm()->updateRecentUsedSongList();
+	h2app->closeFXProperties();
+	h2app->m_undoStack->clear();
 
-	QString selected = Hydrogen::get_instance()->m_PlayList[ nIndex ].m_hFile;
-	openSongFile(selected);
 	EventQueue::get_instance()->push_event( EVENT_METRONOME, 3 );
 	HydrogenApp::get_instance()->setScrollStatusBarMessage( trUtf8( "Playlist: Set song No. %1" ).arg( nIndex +1 ), 5000 );
 }
------------------------------------------------------------------------------
This SF.net email is sponsored by Windows:

Build for Windows Store.

http://p.sf.net/sfu/windows-dev2dev
_______________________________________________
Hydrogen-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/hydrogen-devel

Reply via email to