/* * Hydrogen * Copyright(c) 2002-2008 by Alex >Comix< Cominu [comix@users.sourceforge.net] * * http://www.hydrogen-music.org * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY, without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ #include #include #include #include #include #include #include #include #include #include #ifdef LIBARCHIVE_SUPPORT #include // used for drumkit install #include // used for drumkit install #else //use libtar //disabled libtar on windows #ifndef WIN32 #include // used for drumkit install #include // used for drumkit install #endif #endif #include #include namespace H2Core { SoundLibrary::SoundLibrary() : Object( "SoundLibrary" ) { } SoundLibrary::~SoundLibrary() { } // :::::::::: Drumkit::Drumkit() : Object( "Drumkit" ) , m_pInstrumentList( NULL ) { } Drumkit::~Drumkit() { delete m_pInstrumentList; } Drumkit* Drumkit::load( const QString& sFilename ) { LocalFileMng mng; return mng.loadDrumkit( sFilename ); } std::vector Drumkit::getUserDrumkitList() { LocalFileMng mng; return mng.getUserDrumkitList(); } std::vector Drumkit::getSystemDrumkitList() { LocalFileMng mng; return mng.getSystemDrumkitList(); } void Drumkit::dump() { INFOLOG( "Drumkit dump" ); INFOLOG( "\t|- Name = " + m_sName ); INFOLOG( "\t|- Author = " + m_sAuthor ); INFOLOG( "\t|- Info = " + m_sInfo ); INFOLOG( "\t|- Instrument list" ); for ( unsigned nInstrument = 0; nInstrument < m_pInstrumentList->get_size(); ++nInstrument ) { Instrument *pInstr = m_pInstrumentList->get( nInstrument ); INFOLOG( "\t\t|- (" + to_string( nInstrument ) + " of " + to_string( m_pInstrumentList->get_size() ) + ") Name = " + pInstr->get_name() ); for ( unsigned nLayer = 0; nLayer < MAX_LAYERS; ++nLayer ) { InstrumentLayer *pLayer = pInstr->get_layer( nLayer ); if ( pLayer ) { Sample *pSample = pLayer->get_sample(); if ( pSample ) { INFOLOG( "\t\t |- " + pSample->get_filename() ); } else { INFOLOG( "\t\t |- NULL sample" ); } } else { INFOLOG( "\t\t |- NULL Layer" ); } } // cout << "\t\t" << i << " - " << instr->getSample()->getFilename() << endl; } } #ifdef LIBARCHIVE_SUPPORT void Drumkit::install( const QString& filename ) { _INFOLOG( "[Drumkit::install] drumkit = " + filename ); QString dataDir = Preferences::getInstance()->getDataDirectory() + "drumkits/"; int r; struct archive *drumkitFile; struct archive_entry *entry; char newpath[1024]; drumkitFile = archive_read_new(); archive_read_support_compression_all(drumkitFile); archive_read_support_format_all(drumkitFile); if (( r = archive_read_open_file(drumkitFile, filename.toAscii(), 10240) )) { _ERRORLOG( QString( "Error: %2, Could not open drumkit: %1" ) .arg( archive_errno(drumkitFile)) .arg( archive_error_string(drumkitFile)) ); archive_read_close(drumkitFile); archive_read_finish(drumkitFile); return; } while ( (r = archive_read_next_header(drumkitFile, &entry)) != ARCHIVE_EOF) { if (r != ARCHIVE_OK) { _ERRORLOG( QString( "Error reading drumkit file: %1") .arg(archive_error_string(drumkitFile))); break; } // insert data directory prefix QString np = dataDir + archive_entry_pathname(entry); strcpy( newpath, np.toAscii() ); archive_entry_set_pathname(entry, newpath); // extract tarball r = archive_read_extract(drumkitFile, entry, 0); if (r == ARCHIVE_WARN) { _WARNINGLOG( QString( "warning while extracting %1 (%2)").arg(filename).arg(archive_error_string(drumkitFile))); } else if (r != ARCHIVE_OK) { _ERRORLOG( QString( "error while extracting %1 (%2)").arg(filename).arg(archive_error_string(drumkitFile))); break; } } archive_read_close(drumkitFile); archive_read_finish(drumkitFile); } #else //use libtar #ifndef WIN32 void Drumkit::install( const QString& filename ) { _INFOLOG( "[Drumkit::install] drumkit = " + filename ); QString dataDir = Preferences::getInstance()->getDataDirectory() + "drumkits/"; // GUNZIP !!! QString gunzippedName = filename.left( filename.indexOf( "." ) ); gunzippedName += ".tar"; FILE *pGunzippedFile = fopen( gunzippedName.toAscii(), "wb" ); gzFile gzipFile = gzopen( filename.toAscii(), "rb" ); if ( !gzipFile ) { throw H2Exception( "Error opening gzip file" ); } uchar buf[4096]; while ( gzread( gzipFile, buf, 4096 ) > 0 ) { fwrite( buf, sizeof( uchar ), 4096, pGunzippedFile ); } gzclose( gzipFile ); fclose( pGunzippedFile ); // UNTAR !!! TAR *tarFile; char tarfilename[1024]; strcpy( tarfilename, gunzippedName.toAscii() ); if ( tar_open( &tarFile, tarfilename, NULL, O_RDONLY, 0, TAR_VERBOSE | TAR_GNU ) == -1 ) { _ERRORLOG( QString( "[Drumkit::install] tar_open(): %1" ).arg( strerror( errno ) ) ); return; } char destDir[1024]; strcpy( destDir, dataDir.toAscii() ); if ( tar_extract_all( tarFile, destDir ) != 0 ) { _ERRORLOG( QString( "[Drumkit::install] tar_extract_all(): %1" ).arg( strerror( errno ) ) ); } if ( tar_close( tarFile ) != 0 ) { _ERRORLOG( QString( "[Drumkit::install] tar_close(): %1" ).arg( strerror( errno ) ) ); } } #endif #endif void Drumkit::save( const QString& sName, const QString& sAuthor, const QString& sInfo, const QString& sLicense ) { _INFOLOG( "Saving drumkit" ); Drumkit *pDrumkitInfo = new Drumkit(); pDrumkitInfo->setName( sName ); pDrumkitInfo->setAuthor( sAuthor ); pDrumkitInfo->setInfo( sInfo ); pDrumkitInfo->setLicense( sLicense ); Song *pSong = Hydrogen::get_instance()->getSong(); InstrumentList *pSongInstrList = pSong->get_instrument_list(); InstrumentList *pInstrumentList = new InstrumentList(); for ( uint nInstrument = 0; nInstrument < pSongInstrList->get_size(); nInstrument++ ) { Instrument *pOldInstr = pSongInstrList->get( nInstrument ); Instrument *pNewInstr = new Instrument( pOldInstr->get_id(), pOldInstr->get_name(), new ADSR( *( pOldInstr->get_adsr() ) ) ); pNewInstr->set_volume( pOldInstr->get_volume() ); pNewInstr->set_pan_l( pOldInstr->get_pan_l() ); pNewInstr->set_pan_r( pOldInstr->get_pan_r() ); pNewInstr->set_muted( pOldInstr->is_muted() ); pNewInstr->set_random_pitch_factor( pOldInstr->get_random_pitch_factor() ); pNewInstr->set_mute_group( pOldInstr->get_mute_group() ); pNewInstr->set_filter_active( pOldInstr->is_filter_active() ); pNewInstr->set_filter_cutoff( pOldInstr->get_filter_cutoff() ); pNewInstr->set_filter_resonance( pOldInstr->get_filter_resonance() ); QString sInstrDrumkit = pOldInstr->get_drumkit_name(); for ( unsigned nLayer = 0; nLayer < MAX_LAYERS; nLayer++ ) { InstrumentLayer *pOldLayer = pOldInstr->get_layer( nLayer ); if ( pOldLayer ) { Sample *pSample = pOldLayer->get_sample(); Sample *pNewSample = new Sample( 0, pSample->get_filename() ); // is not a real sample, it contains only the filename information InstrumentLayer *pLayer = new InstrumentLayer( pNewSample ); pLayer->set_gain( pOldLayer->get_gain() ); pLayer->set_pitch( pOldLayer->get_pitch() ); pLayer->set_start_velocity( pOldLayer->get_start_velocity() ); pLayer->set_end_velocity( pOldLayer->get_end_velocity() ); pNewInstr->set_layer( pLayer, nLayer ); } else { pNewInstr->set_layer( NULL, nLayer ); } } pInstrumentList->add ( pNewInstr ); } pDrumkitInfo->setInstrumentList( pInstrumentList ); LocalFileMng fileMng; int err = fileMng.saveDrumkit( pDrumkitInfo ); if ( err != 0 ) { _ERRORLOG( "Error saving the drumkit" ); throw H2Exception( "Error saving the drumkit" ); } // delete the drumkit info delete pDrumkitInfo; pDrumkitInfo = NULL; } void Drumkit::removeDrumkit( const QString& sDrumkitName ) { _INFOLOG( "Removing drumkit: " + sDrumkitName ); QString dataDir = Preferences::getInstance()->getDataDirectory() + "drumkits/"; dataDir += sDrumkitName; QString cmd = QString( "rm -rf \"" ) + dataDir + "\""; _INFOLOG( cmd ); if ( system( cmd.toAscii() ) != 0 ) { _ERRORLOG( "Error executing '" + cmd + "'" ); throw H2Exception( QString( "Error executing '%1'" ).arg( cmd ) ); } } };