File indexing completed on 2024-05-12 16:23:25
0001 /*************************************************************************** 0002 * Copyright (C) 2005-2013 by Linuxstopmotion contributors; * 0003 * see the AUTHORS file for details. * 0004 * * 0005 * This program is free software; you can redistribute it and/or modify * 0006 * it under the terms of the GNU General Public License as published by * 0007 * the Free Software Foundation; either version 2 of the License, or * 0008 * (at your option) any later version. * 0009 * * 0010 * This program is distributed in the hope that it will be useful, * 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0013 * GNU General Public License for more details. * 0014 * * 0015 * You should have received a copy of the GNU General Public License * 0016 * along with this program; if not, write to the * 0017 * Free Software Foundation, Inc., * 0018 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 0019 ***************************************************************************/ 0020 #include "frame.h" 0021 0022 #include "src/technical/audio/audiodriver.h" 0023 #include "src/domain/filenamevisitor.h" 0024 #include "src/domain/animation/errorhandler.h" 0025 #include "src/domain/animation/workspacefile.h" 0026 #include "src/foundation/logger.h" 0027 #include "src/config.h" 0028 #include "sound.h" 0029 0030 #include <assert.h> 0031 #include <string.h> 0032 #include <memory> 0033 #include <exception> 0034 #include <sstream> 0035 #include <string> 0036 0037 0038 class SoundOutOfRangeException : public std::exception { 0039 public: 0040 SoundOutOfRangeException() { 0041 } 0042 const char* what() const throw() { 0043 return "Internal error: Sound out of range!"; 0044 } 0045 }; 0046 0047 0048 Frame::Frame(WorkspaceFile& file) { 0049 assert(file.path() != NULL); 0050 imagePath.swap(file); 0051 } 0052 0053 0054 Frame::~Frame() { 0055 int numElem = sounds.size(); 0056 for (int i = 0; i < numElem; ++i) { 0057 delete sounds[i]; 0058 sounds[i] = NULL; 0059 } 0060 } 0061 0062 0063 const char* Frame::getImagePath() const { 0064 assert(imagePath.path() != NULL); 0065 return imagePath.path(); 0066 } 0067 0068 0069 const char* Frame::getBasename() const { 0070 assert(imagePath.basename() != 0); 0071 return imagePath.basename(); 0072 } 0073 0074 int Frame::newSound(WorkspaceFile& file) { 0075 Logger::get().logDebug("Adding sound in frame"); 0076 preallocateSounds(1); 0077 std::unique_ptr<Sound> sound(new Sound()); 0078 std::stringstream ss; 0079 std::stringstream::pos_type zeroOff = ss.tellp(); 0080 ss << "Sound" << WorkspaceFile::getSoundNumber(); 0081 int size = (ss.tellp() - zeroOff) + 1; 0082 char* soundName = new char[size]; 0083 std::string cs = ss.str(); 0084 strncpy(soundName, cs.c_str(), size); 0085 const char* oldName = sound->setName(soundName); 0086 assert(oldName == NULL); 0087 sound->open(file, *ErrorHandler::getThrower()); 0088 WorkspaceFile::nextSoundNumber(); 0089 sounds.push_back(sound.release()); 0090 0091 return 0; 0092 } 0093 0094 void Frame::addSound(int index, Sound* sound) { 0095 if (index < 0 || soundCount() < index) 0096 throw SoundOutOfRangeException(); 0097 sounds.insert(sounds.begin() + index, sound); 0098 } 0099 0100 void Frame::preallocateSounds(int extra) { 0101 sounds.reserve(soundCount() + extra); 0102 } 0103 0104 Sound* Frame::removeSound(int soundNumber) { 0105 if (soundNumber < 0 || soundCount() <= soundNumber) 0106 throw SoundOutOfRangeException(); 0107 Sound* s = sounds[soundNumber]; 0108 sounds.erase(sounds.begin() + soundNumber); 0109 return s; 0110 } 0111 0112 0113 Sound* Frame::getSound(int soundNumber) { 0114 if (soundNumber < 0 || soundCount() <= soundNumber) 0115 throw SoundOutOfRangeException(); 0116 return sounds[soundNumber]; 0117 } 0118 0119 0120 const Sound* Frame::getSound(int soundNumber) const { 0121 if (soundNumber < 0 || soundCount() <= soundNumber) 0122 throw SoundOutOfRangeException(); 0123 return sounds[soundNumber]; 0124 } 0125 0126 0127 int Frame::soundCount() const { 0128 return sounds.size(); 0129 } 0130 0131 0132 const char* Frame::setSoundName(int soundNumber, const char* soundName) { 0133 if (soundNumber < 0 || soundCount() <= soundNumber) 0134 throw SoundOutOfRangeException(); 0135 return sounds[soundNumber]->setName(soundName); 0136 } 0137 0138 0139 const char* Frame::getSoundName(int soundNumber) const { 0140 if (soundNumber < 0 || soundCount() <= soundNumber) 0141 throw SoundOutOfRangeException(); 0142 return sounds[soundNumber]->getName(); 0143 } 0144 0145 0146 void Frame::playSounds(AudioDriver *driver) const { 0147 SoundVector::const_iterator i = sounds.begin(); 0148 for (; i != sounds.end(); ++i) { 0149 (*i)->addToDriver(*driver); 0150 } 0151 if (i != sounds.begin()) 0152 driver->playInThread(); 0153 } 0154 0155 void Frame::replaceImage(WorkspaceFile& otherImage) { 0156 otherImage.swap(imagePath); 0157 } 0158 0159 void Frame::accept(FileNameVisitor& v) const { 0160 v.visitImage(imagePath.path()); 0161 for(SoundVector::const_iterator i = sounds.begin(); 0162 i != sounds.end(); 0163 ++i) { 0164 v.visitSound((*i)->getSoundPath()); 0165 } 0166 }