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 }