/* * Copyright (C) 2002 - David W. Durham * * This file is part of ReZound, an audio editing application. * * ReZound 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. * * ReZound 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 "ASoundTranslator.h" #include "CSound.h" #include "AStatusComm.h" #include vector ASoundTranslator::registeredTranslators; ASoundTranslator::ASoundTranslator() { } ASoundTranslator::~ASoundTranslator() { } bool ASoundTranslator::loadSound(const string filename,CSound *sound) const { sound->lockForResize(); try { // use working file if it exists if(!sound->createFromWorkingPoolFileIfExists(filename)) { sound->enableCueAdjustmentsOnSpaceChanges(false); if(!onLoadSound(filename,sound)) { sound->unlockForResize(); sound->closeSound(); // this removes the working poolfile return false; // cancelled } sound->setIsModified(false); } // ??? could check various other things if(!sound->poolFile.isOpen()) throw runtime_error(string(__func__)+" -- internal error -- no pool file was open after loading file"); sound->enableCueAdjustmentsOnSpaceChanges(true); sound->unlockForResize(); } catch(...) { sound->enableCueAdjustmentsOnSpaceChanges(true); sound->unlockForResize(); throw; } return true; } bool ASoundTranslator::saveSound(const string filename,const CSound *sound,bool useLastUserPrefs) const { return saveSound(filename,sound,0,sound->getLength(),useLastUserPrefs); } bool ASoundTranslator::saveSound(const string filename,const CSound *sound,const sample_pos_t saveStart,const sample_pos_t saveLength,bool useLastUserPrefs) const { sound->lockSize(); try { /* * ??? A nice feature that would be good now that saving a file can be cancelled * is for onSaveSound to be passed two files.. one to display in error msgs and on dialogs and such * and another to actually write to.. then this code would do a move after everything was successful. * The only problem might be running out of space... Perhaps if space is low, or there isn't * enough for raw PCM size on that directory, then I should prompt the user * * Another solution is to rename the current file that exists and then do the same.. when the * save is successful, delete the original, or if the save is cancelled, then rename the original * back again. * * ESPECIALLY since saving a file can be cancelled thus killing the original */ if(saveLength>sound->getLength() || (sound->getLength()-saveLength)unlockSize(); return ret; } catch(...) { sound->unlockSize(); throw; } } // --- static methods -------------------------------------------- /* just a thought: ??? This method could be given some abstract stream class pointer instead of a filename which could access a file or a network URL. Then the translators would also have to be changed to read from that stream instead of the file, and libaudiofile et al would at this point in time have trouble doing that. */ #include const ASoundTranslator *ASoundTranslator::findTranslator(const string filename,bool byExtensionOnly,bool isRaw) { if(registeredTranslators.size()<=0) buildRegisteredTranslatorsVector(); const ASoundTranslator *rawTranslator=findRawTranslator(); if(isRaw && rawTranslator) return rawTranslator; if(!byExtensionOnly) { /* 'regular file' stuff deals with Sample Dump Standard being opened from /dev/midi */ /* it's not perfect.. it would be best to know if the file being opened is a midi device for sure */ CPath path(filename); if(path.exists() && path.isRegularFile()) { // try to determine from the contents of the file for(size_t t=0;tsupportsFormat(filename)) return ASoundTranslator::registeredTranslators[t]; } } } // either file doesn't exist or no supportsFormat was implemented and recognized it, so attempt to determine the translater based on the file extension const string extension=istring(CPath(filename).extension()).lower(); for(size_t t=0;thandlesExtension(extension,filename)) return ASoundTranslator::registeredTranslators[t]; } // if raw translator exists, ask the user if they want to use it if(rawTranslator) { if(Question(_("No handler found to support the format for ")+filename+"\n"+_("Would you like to use a raw format?"),yesnoQues)==yesAns) return rawTranslator; } throw runtime_error(string(__func__)+_(" -- unhandled format/extension for the filename")+" '"+filename+"'"); } // find a translator that handles raw formats, or return NULL if none is found const ASoundTranslator *ASoundTranslator::findRawTranslator() { for(size_t t=0;thandlesRaw()) return ASoundTranslator::registeredTranslators[t]; } return NULL; } const vector ASoundTranslator::getTranslators() { if(registeredTranslators.size()<=0) buildRegisteredTranslatorsVector(); return registeredTranslators; } const vector ASoundTranslator::getFlatFormatList() { vector v; for(size_t t=0;t formatNames=registeredTranslators[t]->getFormatNames(); const vector > formatFileMasks=registeredTranslators[t]->getFormatFileMasks(); for(size_t i=0;i