ability to import an FL Studio .zip package

git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@1991 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
Andrew Kelley
2009-02-02 02:27:30 +00:00
parent 15ecb74f38
commit 65ca28ddfc
10 changed files with 258 additions and 14 deletions

View File

@@ -64,6 +64,7 @@ OPTION(WANT_TAP "Include Tom's Audio Processing LADSPA plugins" ON)
OPTION(WANT_VST "Include VST support" ON)
OPTION(WANT_VST_NOWINE "Include partial VST support (without wine)" OFF)
OPTION(WANT_WINMM "Include WinMM MIDI support" OFF)
OPTION(WANT_ZIP "Include zip support" ON)
IF(LMMS_BUILD_WIN32)
SET(WANT_ALSA OFF)
@@ -164,7 +165,7 @@ IF(WANT_SDL)
SET(STATUS_SDL "OK")
ELSE(SDL_FOUND)
SET(STATUS_SDL "not found, please install libsdl1.2-dev (or similiar) "
"if your require SDL support")
"if you require SDL support")
ENDIF(SDL_FOUND)
ENDIF(WANT_SDL)
IF(NOT LMMS_HAVE_SDL)
@@ -175,6 +176,17 @@ ELSE(NOT LMMS_HAVE_SDL)
ENDIF(NOT SDL_INCLUDE_DIR)
ENDIF(NOT LMMS_HAVE_SDL)
# check for libzip
IF(WANT_ZIP)
FIND_PACKAGE(ZIP)
IF(ZIP_FOUND)
SET(LMMS_HAVE_ZIP TRUE)
SET(STATUS_ZIP "OK")
ELSE(ZIP_FOUND)
SET(STATUS_ZIP "not found, install libzip-dev (or similar) "
"if you want to import FL .zip files")
ENDIF(ZIP_FOUND)
ENDIF(WANT_ZIP)
# check for Stk
IF(WANT_STK)
@@ -185,7 +197,7 @@ IF(WANT_STK)
ELSE(STK_FOUND)
SET(STK_INCLUDE_DIR "")
SET(STATUS_STK "not found, please install libstk0-dev (or similiar) "
"if your require the Vibed Instrument")
"if you require the Vibed Instrument")
ENDIF(STK_FOUND)
ENDIF(WANT_STK)
@@ -198,7 +210,7 @@ ENDIF(WANT_STK)
# SET(STATUS_PORTAUDIO "OK")
# ELSE(PORTAUDIO_FOUND)
# SET(STATUS_PORTAUDIO "not found, please install libportaudio-dev (or similiar, version >= 1.8) "
# "if your require Portaudio support")
# "if you require Portaudio support")
# ENDIF(PORTAUDIO_FOUND)
#ENDIF(WANT_PORTAUDIO)
IF(NOT LMMS_HAVE_PORTAUDIO)
@@ -215,7 +227,7 @@ IF(WANT_PULSEAUDIO)
SET(STATUS_PULSEAUDIO "OK")
ELSE(PULSEAUDIO_FOUND)
SET(STATUS_PULSEAUDIO "not found, please install libpulse-dev (or similiar) "
"if your require PulseAudio support")
"if you require PulseAudio support")
ENDIF(PULSEAUDIO_FOUND)
ENDIF(WANT_PULSEAUDIO)
IF(NOT LMMS_HAVE_PULSEAUDIO)
@@ -468,9 +480,9 @@ ADD_SUBDIRECTORY(data)
#
ADD_DEFINITIONS(-D'LIB_DIR="${CMAKE_INSTALL_PREFIX}/${LIB_DIR}/"' -D'PLUGIN_DIR="${CMAKE_INSTALL_PREFIX}/${LIB_DIR}/lmms/"' ${PULSEAUDIO_DEFINITIONS} ${PORTAUDIO_DEFINITIONS})
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/include ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/include ${SDL_INCLUDE_DIR} ${PORTAUDIO_INCLUDE_DIR} ${PULSEAUDIO_INCLUDE_DIR} ${JACK_INCLUDE_DIRS} ${OGGVORBIS_INCLUDE_DIR} ${SAMPLERATE_INCLUDE_DIRS} ${SNDFILE_INCLUDE_DIRS})
INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR} ${CMAKE_BINARY_DIR}/include ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/include ${SDL_INCLUDE_DIR} ${PORTAUDIO_INCLUDE_DIR} ${PULSEAUDIO_INCLUDE_DIR} ${JACK_INCLUDE_DIRS} ${OGGVORBIS_INCLUDE_DIR} ${SAMPLERATE_INCLUDE_DIRS} ${SNDFILE_INCLUDE_DIRS} ${ZIP_INCLUDE_DIR})
LINK_DIRECTORIES(${CMAKE_INSTALL_PREFIX}/lib ${ASOUND_LIBRARY_DIR} ${JACK_LIBRARY_DIRS} ${SAMPLERATE_LIBRARY_DIRS} ${SNDFILE_LIBRARY_DIRS})
LINK_LIBRARIES(${QT_LIBRARIES} ${ASOUND_LIBRARY} ${SDL_LIBRARY} ${PORTAUDIO_LIBRARIES} ${PULSEAUDIO_LIBRARIES} ${JACK_LIBRARIES} ${OGGVORBIS_LIBRARIES} ${SAMPLERATE_LIBRARIES} ${SNDFILE_LIBRARIES})
LINK_LIBRARIES(${QT_LIBRARIES} ${ASOUND_LIBRARY} ${SDL_LIBRARY} ${PORTAUDIO_LIBRARIES} ${PULSEAUDIO_LIBRARIES} ${JACK_LIBRARIES} ${OGGVORBIS_LIBRARIES} ${SAMPLERATE_LIBRARIES} ${SNDFILE_LIBRARIES} ${ZIP_LIBRARIES})
ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_BINARY_DIR}/lmms.1.gz COMMAND gzip -c ${CMAKE_SOURCE_DIR}/lmms.1 > ${CMAKE_BINARY_DIR}/lmms.1.gz DEPENDS ${CMAKE_SOURCE_DIR}/lmms.1 COMMENT "Generating lmms.1.gz")
@@ -644,6 +656,7 @@ MESSAGE(
"* CMT LADSPA plugins : ${STATUS_CMT}\n"
"* TAP LADSPA plugins : ${STATUS_TAP}\n"
"* SWH LADSPA plugins : ${STATUS_SWH}\n"
"* FL .zip import : ${STATUS_ZIP}\n"
)
MESSAGE(

View File

@@ -1,3 +1,25 @@
2009-02-01 Andrew Kelley <superjoe30/at/gmail/dot/com>
* plugins/flp_import/flp_import.cpp:
* plugins/flp_import/flp_import.h:
* src/core/song.cpp:
* include/import_filter.h:
- flp import filter will look in the same directory as the
.flp file for samples if it cannot find them elsewhere
- added a zip import filter, which imports FLP zipped packages
- I tried not to change the import filter API but I needed
to be able to set which file was being imported. it is a
small addition to the API and I think it is acceptable.
* cmake/modules/FindZIP.cmake:
* lmmsconfig.h.in:
* CMakeLists.txt:
added an optional dependency on libzip for importing
the above mentioned .zip loop files
* configure:
added helpful tip
2009-01-31 Paul Giblock <drfaygo/at/gmail/dot/com>
* src/gui/cusis_style.cpp:
@@ -118,6 +140,7 @@
* src/gui/widgets/automatable_button.cpp:
fix drag support for button groups
>>>>>>> .r1984
2008-12-22 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
* CMakeLists.txt:

10
TODO
View File

@@ -52,6 +52,15 @@
- add FLAC as export-format?
Andrew Kelley's todo:
- add a Modulator class and a Humanizer tool to the piano roll
- global playback buttons, like in FL Studio
- when you add VSTi, have it automatically pop the find VST plugin dialog
- bug: you can use shift+left to move notes past the beginning
- make pitch bend range adjustable
- monophonic mode on 3xosc
- integrate pitanga's patch
- add dithering
- when looking at a piano roll, if the song is playing that pattern, move the position ticker to where it should be
- multiview button - show notes from every instrument in the current beat+bassline with different colors
- undo/redo for piano roll
@@ -80,3 +89,4 @@ Andrew Kelley's todo:
- make it so that 3xosc notes don't max out
- copy-pasted automation patterns have to be manually linked back to their knob for some reason
- fix memory leaks
- cloning a pattern in the song editor should copy automation tracks along with notes

View File

@@ -0,0 +1,25 @@
# - Find libzip
# Find the native libzip includes and library
#
# ZIP_INCLUDE_DIRS - where to find zip.h
# ZIP_LIBRARIES - List of libraries when using libzip.
# ZIP_FOUND - True if libzip found.
FIND_PATH(ZIP_INCLUDE_DIRS zip.h /usr/include)
FIND_LIBRARY(ZIP_LIBRARIES NAMES zip PATH /usr/lib /usr/local/lib)
IF(ZIP_INCLUDE_DIRS AND ZIP_LIBRARIES)
SET(ZIP_FOUND TRUE)
ENDIF(ZIP_INCLUDE_DIRS AND ZIP_LIBRARIES)
IF(ZIP_FOUND)
IF(NOT ZIP_FIND_QUIETLY)
MESSAGE(STATUS "Found libzip: ${ZIP_LIBRARIES}")
ENDIF(NOT ZIP_FIND_QUIETLY)
ELSE(ZIP_FOUND)
SET(ZIP_LIBRARIES "")
SET(ZIP_INCLUDE_DIRS "")
MESSAGE(STATUS "Could not find libzip")
ENDIF(ZIP_FOUND)
MARK_AS_ADVANCED( ZIP_LIBRARIES ZIP_INCLUDE_DIRS )

3
configure vendored
View File

@@ -7,4 +7,5 @@ echo " cmake . -DCMAKE_INSTALL_PREFIX=/usr"
echo ""
echo "or similiar instead."
echo ""
echo "LMMS recommends an out of tree build. See INSTALL file for details."
echo ""

View File

@@ -52,6 +52,11 @@ public:
protected:
virtual bool tryImport( trackContainer * _tc ) = 0;
inline void setFile( QString &_file )
{
m_file.setFileName( _file );
}
const QFile & file( void ) const
{

View File

@@ -17,6 +17,7 @@
#cmakedefine LMMS_HAVE_SDL
#cmakedefine LMMS_HAVE_STK
#cmakedefine LMMS_HAVE_VST
#cmakedefine LMMS_HAVE_ZIP
#cmakedefine LMMS_HAVE_STDINT_H
#cmakedefine LMMS_HAVE_STDBOOL_H

View File

@@ -57,6 +57,14 @@
#include "embed.h"
#include "lmmsconfig.h"
#ifdef LMMS_HAVE_ZIP
#include <QDir>
#include <QTemporaryFile>
#include <unistd.h>
#include <zip.h>
#endif
#ifdef LMMS_HAVE_CTYPE_H
#include <ctype.h>
#endif
@@ -576,6 +584,7 @@ struct FL_Project
flpImport::flpImport( const QString & _file ) :
importFilter( _file, &flpimport_plugin_descriptor )
{
m_fileBase = QFileInfo( _file ).path();
}
@@ -585,8 +594,138 @@ flpImport::~flpImport()
{
}
bool flpImport::tryImport( trackContainer * _tc )
{
#ifdef LMMS_HAVE_ZIP
return tryFLPImport( _tc ) || tryZIPImport( _tc );
#else
return tryFLPImport( _tc );
#endif
}
#ifdef LMMS_HAVE_ZIP
bool flpImport::tryZIPImport( trackContainer * _tc )
{
// see if the file is a zip file
closeFile();
const QFile &thefile = file();
int err = 0;
struct zip *zfile = zip_open(qPrintable(thefile.fileName()), 0, &err);
if( zfile == NULL )
{
if( err == ZIP_ER_NOZIP ) {
printf("flp import (zip): not a valid zip file\n");
}
else if( err == ZIP_ER_OPEN )
{
printf("flp import (zip): error opening file\n");
}
else if( err == ZIP_ER_READ || err == ZIP_ER_SEEK )
{
printf("flp import (zip): error reading file\n");
}
else
{
printf("flp import (zip): unknown error opening zip file\n");
}
return false;
}
// valid zip file
// get temporary directory
QString tmpName;
{
QTemporaryFile qtmp;
if( qtmp.open() )
{
tmpName = qtmp.fileName();
}
else
{
zip_close(zfile);
printf("flp import (zip): error getting temporary folder\n");
return false;
}
}
QDir tmpDir = QDir::temp();
tmpDir.mkdir(tmpName);
tmpDir.cd(tmpName);
// unzip everything to the temp folder
int buf_size = getpagesize();
char buf[buf_size];
int numFiles = zip_get_num_files(zfile);
int i;
bool foundFLP = false;
QString flpFile = "";
for( i=0; i<numFiles; ++i )
{
const char* fileName = zip_get_name(zfile, i, 0);
if( fileName != NULL )
{
struct zip_file *unzipFile = zip_fopen_index(zfile, i, 0);
if( unzipFile != NULL )
{
// we have a handle to read, now get a handle to the outfile
QFile out(tmpDir.absolutePath() + QDir::separator() +
fileName);
out.open(QIODevice::WriteOnly);
// ok we have handles on both, now do buffered writing
bool readErr = false;
while(true)
{
// read into buffer
int numRead = zip_fread(unzipFile, buf, buf_size);
if( numRead == -1 )
{
readErr = true;
printf("flp import (zip): error while reading %s "
"from zip file\n", fileName);
break;
}
out.write( buf, numRead );
if( numRead < buf_size ) break;
}
// we successfully read this file, check if it is
// the .flp file
QString qFileName(fileName);
if( qFileName.endsWith(".flp") )
{
foundFLP = true;
flpFile = out.fileName();
}
// clean up
out.close();
zip_fclose(unzipFile);
}
else
{
printf("flp import (zip): unable to get %s out of %s\n",
fileName, qPrintable(thefile.fileName()) );
}
}
}
zip_close(zfile);
// make sure there was a .flp file in the archive
if( ! foundFLP )
{
printf("flp import (zip): no .flp file found in archive\n");
return false;
}
// use the flp_import plugin to load the .flp file
// which was extracted to the temp dir
setFile(flpFile);
m_fileBase = QFileInfo( flpFile ).path();
return tryFLPImport( _tc );
}
#endif
bool flpImport::tryFLPImport( trackContainer * _tc )
{
const int mappedFilter[] =
{
@@ -1057,26 +1196,41 @@ if( p.currentEffectChannel <= NumFxChannels )
case FLP_Text_SampleFileName:
{
QString f = text;
QString f = "";
QString f_name = text;
/* if( f.mid( 1, 11 ) == "Instruments" )
{
f = "\\Patches\\Packs" +
f.mid( 12 );
}*/
f.replace( '\\', QDir::separator() );
bool foundFile = false;
f_name.replace( '\\', QDir::separator() );
if( QFileInfo( configManager::inst()->flDir() +
"/Data/" ).exists() )
{
f = configManager::inst()->flDir() +
"/Data/" + f;
"/Data/" + f_name;
foundFile = QFileInfo( f ).exists();
}
else
{
// FL 3 compat
f = configManager::inst()->flDir() +
"/Samples/" + f;
"/Samples/" + f_name;
foundFile = QFileInfo( f ).exists();
}
if( ! foundFile )
{
// look in same directory as .flp file
f = m_fileBase + "/" + QFileInfo( f_name ).fileName();
printf("looking in %s for samples\n", qPrintable(f));
foundFile = QFileInfo( f ).exists();
}
cc->sampleFileName = f;
break;
}

View File

@@ -51,7 +51,13 @@ public:
private:
QString m_fileBase;
virtual bool tryImport( trackContainer * _tc );
bool tryFLPImport( trackContainer * _tc );
#ifdef LMMS_HAVE_ZIP
bool tryZIPImport( trackContainer * _tc );
#endif
void processPluginParams( FL_Channel * _ch );
@@ -99,7 +105,7 @@ private:
}
}
friend class zipImport;
} ;

View File

@@ -1070,7 +1070,13 @@ void song::importProject( void )
{
QFileDialog ofd( NULL, tr( "Import file" ),
configManager::inst()->userProjectsDir(),
tr("MIDI sequences (*.mid *.rif);;FL Studio projects (*.flp)") );
tr("MIDI sequences (*.mid *.rif);;FL Studio projects (*.flp"
#ifdef LMMS_HAVE_ZIP
" *.zip)") );
#else
")") );
#endif
ofd.setFileMode( QFileDialog::ExistingFiles );
if( ofd.exec () == QDialog::Accepted && !ofd.selectedFiles().isEmpty() )
{