Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "toonz/txshsoundlevel.h"
Toshihiro Shimizu 890ddd
#include "tsound_io.h"
Toshihiro Shimizu 890ddd
#include "toonz/toonzscene.h"
Toshihiro Shimizu 890ddd
#include "toonz/sceneproperties.h"
Toshihiro Shimizu 890ddd
#include "toonz/txshleveltypes.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tstream.h"
Toshihiro Shimizu 890ddd
#include "toutputproperties.h"
Toshihiro Shimizu 890ddd
#include "tconvert.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DEFINE_CLASS_CODE(TXshSoundLevel, 53)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
PERSIST_IDENTIFIER(TXshSoundLevel, "soundLevel")
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TXshSoundLevel::TXshSoundLevel(std::wstring name, int startOffset,
Shinya Kitaoka 120a6e
                               int endOffset)
Shinya Kitaoka 120a6e
    : TXshLevel(m_classCode, name)
Shinya Kitaoka 120a6e
    , m_soundTrack(0)
Shinya Kitaoka 120a6e
    , m_duration(0)
Shinya Kitaoka 120a6e
    , m_samplePerFrame(0)
Shinya Kitaoka 120a6e
    , m_frameSoundCount(0)
Shinya Kitaoka 120a6e
    , m_fps(12)
Shinya Kitaoka 120a6e
    , m_path() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TXshSoundLevel::~TXshSoundLevel() {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TXshSoundLevel *TXshSoundLevel::clone() const {
Shinya Kitaoka 120a6e
  TXshSoundLevel *sound = new TXshSoundLevel();
Shinya Kitaoka 120a6e
  sound->setSoundTrack(m_soundTrack->clone());
Shinya Kitaoka 120a6e
  sound->m_duration        = m_duration;
Shinya Kitaoka 120a6e
  sound->m_path            = m_path;
Shinya Kitaoka 120a6e
  sound->m_samplePerFrame  = m_samplePerFrame;
Shinya Kitaoka 120a6e
  sound->m_frameSoundCount = m_frameSoundCount;
Shinya Kitaoka 120a6e
  sound->m_fps             = m_fps;
Shinya Kitaoka 120a6e
  return sound;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXshSoundLevel::setScene(ToonzScene *scene) {
Shinya Kitaoka 120a6e
  assert(scene);
Shinya Kitaoka 120a6e
  TXshLevel::setScene(scene);
Shinya Kitaoka 120a6e
  TOutputProperties *properties = scene->getProperties()->getOutputProperties();
Shinya Kitaoka 120a6e
  assert(properties);
Shinya Kitaoka 120a6e
  setFrameRate(properties->getFrameRate());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXshSoundLevel::loadSoundTrack() {
Shinya Kitaoka 120a6e
  assert(getScene());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TSceneProperties *properties = getScene()->getProperties();
Shinya Kitaoka 120a6e
  if (properties) {
Shinya Kitaoka 120a6e
    TOutputProperties *outputProperties = properties->getOutputProperties();
Shinya Kitaoka 120a6e
    if (outputProperties) m_fps         = outputProperties->getFrameRate();
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  TFilePath path = getScene()->decodeFilePath(m_path);
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    loadSoundTrack(path);
Shinya Kitaoka 120a6e
  } catch (TException &e) {
Shinya Kitaoka 120a6e
    throw TException(e.getMessage());
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXshSoundLevel::loadSoundTrack(const TFilePath &fileName) {
Shinya Kitaoka 120a6e
  try {
Shinya Kitaoka 120a6e
    TSoundTrackP st;
Shinya Kitaoka 120a6e
    TFilePath path(fileName);
Shinya Kitaoka 120a6e
    bool ret = TSoundTrackReader::load(path, st);
Shinya Kitaoka 120a6e
    if (ret) {
Shinya Kitaoka 120a6e
      m_duration = st->getDuration();
Shinya Kitaoka 120a6e
      setName(fileName.getWideName());
Shinya Kitaoka 120a6e
      setSoundTrack(st);
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } catch (TException &) {
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXshSoundLevel::load() { loadSoundTrack(); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXshSoundLevel::save() { save(m_path); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXshSoundLevel::save(const TFilePath &path) {
Shinya Kitaoka 120a6e
  TSoundTrackWriter::save(path, m_soundTrack);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXshSoundLevel::loadData(TIStream &is) {
Shinya Kitaoka 120a6e
  is >> m_name;
Shinya Kitaoka 120a6e
  setName(m_name);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  std::string tagName;
Shinya Kitaoka 120a6e
  bool flag = false;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int type = UNKNOWN_XSHLEVEL;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  for (;;) {
Shinya Kitaoka 120a6e
    if (is.matchTag(tagName)) {
Shinya Kitaoka 120a6e
      if (tagName == "path") {
Shinya Kitaoka 120a6e
        is >> m_path;
Shinya Kitaoka 120a6e
        is.matchEndTag();
Shinya Kitaoka 120a6e
      } else if (tagName == "type") {
Shinya Kitaoka 120a6e
        std::string v;
Shinya Kitaoka 120a6e
        is >> v;
Shinya Kitaoka 120a6e
        if (v == "sound") type = SND_XSHLEVEL;
Shinya Kitaoka 120a6e
        is.matchEndTag();
Shinya Kitaoka 120a6e
      } else
Shinya Kitaoka 120a6e
        throw TException("unexpected tag " + tagName);
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  setType(type);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXshSoundLevel::saveData(TOStream &os) {
Shinya Kitaoka 120a6e
  os << m_name;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::map<std::string, std::string=""> attr;</std::string,>
Shinya Kitaoka 120a6e
  os.child("type") << L"sound";
Shinya Kitaoka 120a6e
  os.child("path") << m_path;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Jaroslav 203cc8
void TXshSoundLevel::computeValuesFor(const Orientation *o) {
Jaroslav 203cc8
  int frameHeight = o->dimension(PredefinedDimension::FRAME);  // time axis
Jaroslav 203cc8
  int index       = o->dimension(PredefinedDimension::INDEX);
Jaroslav 203cc8
  map<int, doublepair=""> &values = m_values[index];</int,>
Jaroslav 203cc8
Shinya Kitaoka 120a6e
  if (frameHeight == 0) frameHeight = 1;
Jaroslav 203cc8
  values.clear();
Shinya Kitaoka 120a6e
  if (!m_soundTrack) {
Shinya Kitaoka 120a6e
    m_frameSoundCount = 0;
Shinya Kitaoka 120a6e
    m_samplePerFrame  = 0;
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_samplePerFrame      = m_soundTrack->getSampleRate() / m_fps;
Shinya Kitaoka 120a6e
  double samplePerPixel = m_samplePerFrame / frameHeight;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int sampleCount = m_soundTrack->getSampleCount();
Shinya Kitaoka 120a6e
  if (sampleCount <= 0)  // This was if(!sampleCount)  :(
Shinya Kitaoka 120a6e
    return;              //
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_frameSoundCount = tceil(sampleCount / m_samplePerFrame);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double maxPressure = 0.0;
Shinya Kitaoka 120a6e
  double minPressure = 0.0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  m_soundTrack->getMinMaxPressure(TINT32(0), (TINT32)sampleCount, TSound::LEFT,
Shinya Kitaoka 120a6e
                                  minPressure, maxPressure);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double absMaxPressure = std::max(fabs(minPressure), fabs(maxPressure));
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (absMaxPressure <= 0) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Adjusting using a fixed scaleFactor
Jaroslav 203cc8
  int desiredAmplitude = o->dimension(PredefinedDimension::SOUND_AMPLITUDE);
Jaroslav 203cc8
  // results will be in range -desiredAmplitude .. +desiredAmplitude
Jaroslav 203cc8
  double weightA = desiredAmplitude / absMaxPressure;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  long i = 0, j;
Shinya Kitaoka 120a6e
  long p = 0;  // se p parte da zero notazione per pixel,
Shinya Kitaoka 120a6e
  // se parte da 1 notazione per frame
Shinya Kitaoka 120a6e
  while (i < m_frameSoundCount) {
Shinya Kitaoka 120a6e
    for (j = 0; j < frameHeight - 1; ++j) {
Shinya Kitaoka 120a6e
      double min = 0.0;
Shinya Kitaoka 120a6e
      double max = 0.0;
Shinya Kitaoka 120a6e
      m_soundTrack->getMinMaxPressure(
Shinya Kitaoka 120a6e
          (TINT32)(i * m_samplePerFrame + j * samplePerPixel),
Shinya Kitaoka 120a6e
          (TINT32)(i * m_samplePerFrame + (j + 1) * samplePerPixel - 1),
Shinya Kitaoka 120a6e
          TSound::MONO, min, max);
Jaroslav 203cc8
      values.insert(std::pair<int, double="" std::pair<double,="">>(</int,>
Shinya Kitaoka 120a6e
          p + j, std::pair<double, double="">(min * weightA, max * weightA)));</double,>
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    double min = 0.0;
Shinya Kitaoka 120a6e
    double max = 0.0;
Shinya Kitaoka 120a6e
    m_soundTrack->getMinMaxPressure(
Shinya Kitaoka 120a6e
        (TINT32)(i * m_samplePerFrame + j * samplePerPixel),
Shinya Kitaoka 120a6e
        (TINT32)((i + 1) * m_samplePerFrame - 1), TSound::MONO, min, max);
Jaroslav 203cc8
    values.insert(std::pair<int, double="" std::pair<double,="">>(</int,>
Shinya Kitaoka 120a6e
        p + j, std::pair<double, double="">(min * weightA, max * weightA)));</double,>
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    ++i;
Shinya Kitaoka 120a6e
    p += frameHeight;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Jaroslav 203cc8
void TXshSoundLevel::computeValues() {
Jaroslav 203cc8
  for (auto o : Orientations::all()) computeValuesFor(o);
Jaroslav 203cc8
}
Jaroslav 203cc8
Jaroslav 203cc8
//-----------------------------------------------------------------------------
Jaroslav 203cc8
Jaroslav 203cc8
void TXshSoundLevel::getValueAtPixel(const Orientation *o, int pixel,
Jaroslav 203cc8
                                     DoublePair &values) const {
Jaroslav 203cc8
  int index = o->dimension(PredefinedDimension::INDEX);
Jaroslav 203cc8
  std::map<int, doublepair="">::const_iterator it = m_values[index].find(pixel);</int,>
Jaroslav 203cc8
  if (it != m_values[index].end()) values = it->second;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TXshSoundLevel::setFrameRate(double fps) {
Shinya Kitaoka 120a6e
  if (m_fps != fps) {
Shinya Kitaoka 120a6e
    m_fps = fps;
Shinya Kitaoka 120a6e
    computeValues();
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
int TXshSoundLevel::getFrameCount() const {
Shinya Kitaoka 120a6e
  int frameCount = m_duration * m_fps;
Shinya Kitaoka 120a6e
  return (frameCount == 0) ? 1 : frameCount;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Shinya Kitaoka 120a6e
// Implementato per utilita'
Shinya Kitaoka 120a6e
void TXshSoundLevel::getFids(std::vector<tframeid> &fids) const {</tframeid>
Shinya Kitaoka 120a6e
  int i;
Shinya Kitaoka 120a6e
  for (i = 0; i < getFrameCount(); i++) fids.push_back(TFrameId(i));
Toshihiro Shimizu 890ddd
}