| |
| |
| #include "toonz/txshsoundlevel.h" |
| #include "tsound_io.h" |
| #include "toonz/toonzscene.h" |
| #include "toonz/sceneproperties.h" |
| #include "toonz/txshleveltypes.h" |
| |
| #include "tstream.h" |
| #include "toutputproperties.h" |
| #include "tconvert.h" |
| |
| |
| |
| DEFINE_CLASS_CODE(TXshSoundLevel, 53) |
| |
| PERSIST_IDENTIFIER(TXshSoundLevel, "soundLevel") |
| |
| |
| |
| TXshSoundLevel::TXshSoundLevel(wstring name, int startOffset, int endOffset) |
| : TXshLevel(m_classCode, name), m_soundTrack(0), m_duration(0), m_samplePerFrame(0), m_frameSoundCount(0), m_fps(12), m_path() |
| { |
| } |
| |
| |
| |
| TXshSoundLevel::~TXshSoundLevel() |
| { |
| } |
| |
| |
| |
| TXshSoundLevel *TXshSoundLevel::clone() const |
| { |
| TXshSoundLevel *sound = new TXshSoundLevel(); |
| sound->setSoundTrack(m_soundTrack->clone()); |
| sound->m_duration = m_duration; |
| sound->m_path = m_path; |
| sound->m_samplePerFrame = m_samplePerFrame; |
| sound->m_frameSoundCount = m_frameSoundCount; |
| sound->m_fps = m_fps; |
| return sound; |
| } |
| |
| |
| |
| void TXshSoundLevel::setScene(ToonzScene *scene) |
| { |
| assert(scene); |
| TXshLevel::setScene(scene); |
| TOutputProperties *properties = scene->getProperties()->getOutputProperties(); |
| assert(properties); |
| setFrameRate(properties->getFrameRate()); |
| } |
| |
| |
| |
| void TXshSoundLevel::loadSoundTrack() |
| { |
| assert(getScene()); |
| |
| TSceneProperties *properties = getScene()->getProperties(); |
| if (properties) { |
| TOutputProperties *outputProperties = properties->getOutputProperties(); |
| if (outputProperties) |
| m_fps = outputProperties->getFrameRate(); |
| } |
| TFilePath path = getScene()->decodeFilePath(m_path); |
| try { |
| loadSoundTrack(path); |
| } catch (TException &e) { |
| throw TException(e.getMessage()); |
| } |
| } |
| |
| |
| |
| void TXshSoundLevel::loadSoundTrack(const TFilePath &fileName) |
| { |
| try { |
| TSoundTrackP st; |
| TFilePath path(fileName); |
| bool ret = TSoundTrackReader::load(path, st); |
| if (ret) { |
| m_duration = st->getDuration(); |
| setName(fileName.getWideName()); |
| setSoundTrack(st); |
| } |
| } catch (TException &) { |
| return; |
| } |
| } |
| |
| |
| |
| void TXshSoundLevel::load() |
| { |
| loadSoundTrack(); |
| } |
| |
| |
| |
| void TXshSoundLevel::save() |
| { |
| save(m_path); |
| } |
| |
| |
| |
| void TXshSoundLevel::save(const TFilePath &path) |
| { |
| TSoundTrackWriter::save(path, m_soundTrack); |
| } |
| |
| |
| |
| void TXshSoundLevel::loadData(TIStream &is) |
| { |
| is >> m_name; |
| setName(m_name); |
| |
| string tagName; |
| bool flag = false; |
| |
| int type = UNKNOWN_XSHLEVEL; |
| |
| for (;;) { |
| if (is.matchTag(tagName)) { |
| if (tagName == "path") { |
| is >> m_path; |
| is.matchEndTag(); |
| } else if (tagName == "type") { |
| string v; |
| is >> v; |
| if (v == "sound") |
| type = SND_XSHLEVEL; |
| is.matchEndTag(); |
| } else |
| throw TException("unexpected tag " + tagName); |
| } else |
| break; |
| } |
| setType(type); |
| } |
| |
| |
| |
| void TXshSoundLevel::saveData(TOStream &os) |
| { |
| os << m_name; |
| |
| map<string, string> attr; |
| os.child("type") << L"sound"; |
| os.child("path") << m_path; |
| } |
| |
| |
| |
| void TXshSoundLevel::computeValues(int frameHeight) |
| { |
| if (frameHeight == 0) |
| frameHeight = 1; |
| m_values.clear(); |
| if (!m_soundTrack) { |
| m_frameSoundCount = 0; |
| m_samplePerFrame = 0; |
| return; |
| } |
| |
| m_samplePerFrame = m_soundTrack->getSampleRate() / m_fps; |
| double samplePerPixel = m_samplePerFrame / frameHeight; |
| |
| int sampleCount = m_soundTrack->getSampleCount(); |
| if (sampleCount <= 0) |
| return; |
| |
| m_frameSoundCount = tceil(sampleCount / m_samplePerFrame); |
| |
| double maxPressure = 0.0; |
| double minPressure = 0.0; |
| |
| m_soundTrack->getMinMaxPressure( |
| TINT32(0), (TINT32)sampleCount, TSound::LEFT, minPressure, maxPressure); |
| |
| double absMaxPressure = tmax(fabs(minPressure), fabs(maxPressure)); |
| |
| if (absMaxPressure <= 0) |
| return; |
| |
| |
| double weightA = 20.0 / absMaxPressure; |
| |
| long i = 0, j; |
| long p = 0; |
| |
| while (i < m_frameSoundCount) { |
| for (j = 0; j < frameHeight - 1; ++j) { |
| double min = 0.0; |
| double max = 0.0; |
| m_soundTrack->getMinMaxPressure( |
| (TINT32)(i * m_samplePerFrame + j * samplePerPixel), |
| (TINT32)(i * m_samplePerFrame + (j + 1) * samplePerPixel - 1), |
| TSound::MONO, min, max); |
| m_values.insert(pair<int, pair<double, double>>(p + j, pair<double, double>(min * weightA, max * weightA))); |
| } |
| |
| double min = 0.0; |
| double max = 0.0; |
| m_soundTrack->getMinMaxPressure( |
| (TINT32)(i * m_samplePerFrame + j * samplePerPixel), |
| (TINT32)((i + 1) * m_samplePerFrame - 1), |
| TSound::MONO, min, max); |
| m_values.insert(pair<int, pair<double, double>>(p + j, pair<double, double>(min * weightA, max * weightA))); |
| |
| ++i; |
| p += frameHeight; |
| } |
| } |
| |
| |
| |
| void TXshSoundLevel::getValueAtPixel(int pixel, DoublePair &values) const |
| { |
| std::map<int, DoublePair>::const_iterator it = m_values.find(pixel); |
| if (it != m_values.end()) |
| values = it->second; |
| } |
| |
| |
| |
| void TXshSoundLevel::setFrameRate(double fps) |
| { |
| if (m_fps != fps) { |
| m_fps = fps; |
| computeValues(); |
| } |
| } |
| |
| |
| |
| int TXshSoundLevel::getFrameCount() const |
| { |
| int frameCount = m_duration * m_fps; |
| return (frameCount == 0) ? 1 : frameCount; |
| } |
| |
| |
| |
| void TXshSoundLevel::getFids(std::vector<TFrameId> &fids) const |
| { |
| int i; |
| for (i = 0; i < getFrameCount(); i++) |
| fids.push_back(TFrameId(i)); |
| } |
| |