123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358 |
- #include <QDomDocument>
- #include <QDir>
- #include <QApplication>
- #include <QMessageBox>
- #include <QProgressDialog>
- #include <QTextStream>
- #include <stdlib.h>
- #include "LocalFileMng.h"
- #include "HydrogenImport.h"
- #include "Song.h"
- #include "Engine.h"
- #include "Instrument.h"
- #include "InstrumentTrack.h"
- #include "Note.h"
- #include "Pattern.h"
- #include "Track.h"
- #include "BBTrack.h"
- #include "BBTrackContainer.h"
- #include "Instrument.h"
- #include "plugin_export.h"
- #define MAX_LAYERS 4
- extern "C"
- {
- Plugin::Descriptor PLUGIN_EXPORT hydrogenimport_plugin_descriptor =
- {
- STRINGIFY( PLUGIN_NAME ),
- "Hydrogen Import",
- QT_TRANSLATE_NOOP( "PluginBrowser",
- "Filter for importing Hydrogen files into LMMS" ),
- "frank mather",
- 0x0100,
- Plugin::ImportFilter,
- NULL,
- NULL,
- NULL
- } ;
- }
- QString filename;
- class NoteKey
- {
- public:
- enum Key {
- C = 0,
- Cs,
- D,
- Ef,
- E,
- F,
- Fs,
- G,
- Af,
- A,
- Bf,
- B,
- };
- static int stringToNoteKey( const QString& str )
- {
- int m_key = NoteKey::C;
- QString sKey = str.left( str.length() - 1 );
- QString sOct = str.mid( str.length() - 1, str.length() );
- if ( sKey.endsWith( "-" ) )
- {
- sKey.replace( "-", "" );
- sOct.insert( 0, "-" );
- }
- int nOctave = sOct.toInt();
- if ( sKey == "C" )
- {
- m_key = NoteKey::C;
- }
- else if ( sKey == "Cs" )
- {
- m_key = NoteKey::Cs;
- }
- else if ( sKey == "D" )
- {
- m_key = NoteKey::D;
- }
- else if ( sKey == "Ef" )
- {
- m_key = NoteKey::Ef;
- }
- else if ( sKey == "E" )
- {
- m_key = NoteKey::E;
- }
- else if ( sKey == "F" )
- {
- m_key = NoteKey::F;
- }
- else if ( sKey == "Fs" )
- {
- m_key = NoteKey::Fs;
- }
- else if ( sKey == "G" )
- {
- m_key = NoteKey::G;
- }
- else if ( sKey == "Af" )
- {
- m_key = NoteKey::Af;
- }
- else if ( sKey == "A" )
- {
- m_key = NoteKey::A;
- }
- else if ( sKey == "Bf" )
- {
- m_key = NoteKey::Bf;
- }
- else if ( sKey == "B" ) {
- m_key = NoteKey::B;
- }
- return m_key + (nOctave*12)+57;
- }
- };
- HydrogenImport::HydrogenImport( const QString & _file ) :
- ImportFilter( _file, &hydrogenimport_plugin_descriptor )
- {
- filename = _file;
- }
- HydrogenImport::~HydrogenImport()
- {
- }
- Instrument * ins;
- bool HydrogenImport::readSong()
- {
- QHash<QString, InstrumentTrack *> drum_track;
- QHash<QString, int> pattern_length;
- QHash<QString, int> pattern_id;
- Song *s = Engine::getSong();
- int song_num_tracks = s->tracks().size();
- if ( QFile( filename ).exists() == false )
- {
- printf( "Song file not found \n" );
- return false;
- }
- QDomDocument doc = LocalFileMng::openXmlDocument( filename );
- QDomNodeList nodeList = doc.elementsByTagName( "song" );
- if( nodeList.isEmpty() )
- {
- printf( "Error reading song: song node not found\n" );
- return false;
- }
- QDomNode songNode = nodeList.at( 0 );
- QString m_sSongVersion = LocalFileMng::readXmlString( songNode , "version", "Unknown version" );
- QString sName( LocalFileMng::readXmlString( songNode, "name", "Untitled Song" ) );
- QString sAuthor( LocalFileMng::readXmlString( songNode, "author", "Unknown Author" ) );
- QString sNotes( LocalFileMng::readXmlString( songNode, "notes", "..." ) );
- QString sLicense( LocalFileMng::readXmlString( songNode, "license", "Unknown license" ) );
- QString sMode = LocalFileMng::readXmlString( songNode, "mode", "pattern" );
- QDomNode instrumentListNode = songNode.firstChildElement( "instrumentList" );
- if ( ( ! instrumentListNode.isNull() ) )
- {
- int instrumentList_count = 0;
- QDomNode instrumentNode;
- instrumentNode = instrumentListNode.firstChildElement( "instrument" );
- while ( ! instrumentNode.isNull() )
- {
- instrumentList_count++;
- QString sId = LocalFileMng::readXmlString( instrumentNode, "id", "" ); // instrument id
- QString sDrumkit = LocalFileMng::readXmlString( instrumentNode, "drumkit", "" ); // drumkit
- QString sName = LocalFileMng::readXmlString( instrumentNode, "name", "" ); // name
- float fVolume = LocalFileMng::readXmlFloat( instrumentNode, "volume", 1.0 ); // volume
- float fPan_L = LocalFileMng::readXmlFloat( instrumentNode, "pan_L", 0.5 ); // pan L
- float fPan_R = LocalFileMng::readXmlFloat( instrumentNode, "pan_R", 0.5 ); // pan R
- if ( sId.isEmpty() ) {
- printf( "Empty ID for instrument. skipping \n" );
- instrumentNode = (QDomNode) instrumentNode.nextSiblingElement( "instrument" );
- continue;
- }
- QDomNode filenameNode = instrumentNode.firstChildElement( "filename" );
- if ( ! filenameNode.isNull() )
- {
- return false;
- }
- else
- {
- unsigned nLayer = 0;
- QDomNode instrumentComponentNode = instrumentNode.firstChildElement("instrumentComponent");
- if (instrumentComponentNode.isNull())
- {
- instrumentComponentNode = instrumentNode;
- }
- QDomNode layerNode = instrumentComponentNode.firstChildElement( "layer" );
- while ( ! layerNode.isNull() )
- {
- if ( nLayer >= MAX_LAYERS )
- {
- printf("nLayer >= MAX_LAYERS\n");
- break;
- }
- QString sFilename = LocalFileMng::readXmlString( layerNode, "filename", "" );
- QString sMode = LocalFileMng::readXmlString( layerNode, "smode", "forward" );
- if ( nLayer == 0 )
- {
- drum_track[sId] = ( InstrumentTrack * ) Track::create( Track::InstrumentTrack,Engine::getBBTrackContainer() );
- drum_track[sId]->volumeModel()->setValue( fVolume * 100 );
- drum_track[sId]->panningModel()->setValue( ( fPan_R - fPan_L ) * 100 );
- ins = drum_track[sId]->loadInstrument( "audiofileprocessor" );
- ins->loadFile( sFilename );
- }
- nLayer++;
- layerNode = ( QDomNode ) layerNode.nextSiblingElement( "layer" );
- }
- }
- instrumentNode = (QDomNode) instrumentNode.nextSiblingElement( "instrument" );
- }
- if ( instrumentList_count == 0 )
- {
- return false;
- }
- }
- else
- {
- return false;
- }
- QDomNode patterns = songNode.firstChildElement( "patternList" );
- int pattern_count = 0;
- int nbb = Engine::getBBTrackContainer()->numOfBBs();
- QDomNode patternNode = patterns.firstChildElement( "pattern" );
- int pn = 1;
- while ( !patternNode.isNull() )
- {
- if ( pn > 0 )
- {
- pattern_count++;
- s->addBBTrack();
- pn = 0;
- }
- QString sName; // name
- sName = LocalFileMng::readXmlString( patternNode, "name", sName );
- QString sCategory = ""; // category
- sCategory = LocalFileMng::readXmlString( patternNode, "category", sCategory ,false ,false );
- int nSize = -1;
- nSize = LocalFileMng::readXmlInt( patternNode, "size", nSize, false, false );
- pattern_length[sName] = nSize;
- QDomNode pNoteListNode = patternNode.firstChildElement( "noteList" );
- if ( ! pNoteListNode.isNull() ) {
- QDomNode noteNode = pNoteListNode.firstChildElement( "note" );
- while ( ! noteNode.isNull() ) {
- int nPosition = LocalFileMng::readXmlInt( noteNode, "position", 0 );
- float fVelocity = LocalFileMng::readXmlFloat( noteNode, "velocity", 0.8f );
- float fPan_L = LocalFileMng::readXmlFloat( noteNode, "pan_L", 0.5 );
- float fPan_R = LocalFileMng::readXmlFloat( noteNode, "pan_R", 0.5 );
- QString sKey = LocalFileMng::readXmlString( noteNode, "key", "C0", false, false );
- QString nNoteOff = LocalFileMng::readXmlString( noteNode, "note_off", "false", false, false );
- QString instrId = LocalFileMng::readXmlString( noteNode, "instrument", 0,false, false );
- int i = pattern_count - 1 + nbb;
- pattern_id[sName] = pattern_count - 1;
- Pattern*p = dynamic_cast<Pattern*>( drum_track[instrId]->getTCO( i ) );
- Note n;
- n.setPos( nPosition );
- if ( (nPosition + 48) <= nSize )
- {
- n.setLength( 48 );
- }
- else
- {
- n.setLength( nSize - nPosition );
- }
- n.setVolume( fVelocity * 100 );
- n.setPanning( ( fPan_R - fPan_L ) * 100 );
- n.setKey( NoteKey::stringToNoteKey( sKey ) );
- p->addNote( n,false );
- pn = pn + 1;
- noteNode = ( QDomNode ) noteNode.nextSiblingElement( "note" );
- }
- }
- patternNode = ( QDomNode ) patternNode.nextSiblingElement( "pattern" );
- }
- // Pattern sequence
- QDomNode patternSequenceNode = songNode.firstChildElement( "patternSequence" );
- QDomNode groupNode = patternSequenceNode.firstChildElement( "group" );
- int pos = 0;
- while ( !groupNode.isNull() )
- {
- int best_length = 0;
- QDomNode patternId = groupNode.firstChildElement( "patternID" );
- while ( !patternId.isNull() )
- {
- QString patId = patternId.firstChild().nodeValue();
- patternId = ( QDomNode ) patternId.nextSiblingElement( "patternID" );
- int i = pattern_id[patId]+song_num_tracks;
- Track *t = ( BBTrack * ) s->tracks().at( i );
- t->createTCO(pos);
- if ( pattern_length[patId] > best_length )
- {
- best_length = pattern_length[patId];
- }
- }
- pos = pos + best_length;
- groupNode = groupNode.nextSiblingElement( "group" );
- }
- if ( pattern_count == 0 )
- {
- return false;
- }
- return true;
- }
- bool HydrogenImport::tryImport( TrackContainer* tc )
- {
- if( openFile() == false )
- {
- return false;
- }
- return readSong();
- }
- extern "C"
- {
- // necessary for getting instance out of shared lib
- PLUGIN_EXPORT Plugin * lmms_plugin_main( Model *, void * _data )
- {
- return new HydrogenImport( QString::fromUtf8(
- static_cast<const char *>( _data ) ) );
- }
- }
|