256 lines
6.3 KiB
C++
256 lines
6.3 KiB
C++
|
|
||
|
|
||
|
#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) // This was if(!sampleCount) :(
|
||
|
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;
|
||
|
|
||
|
// Adjusting using a fixed scaleFactor
|
||
|
double weightA = 20.0 / absMaxPressure;
|
||
|
|
||
|
long i = 0, j;
|
||
|
long p = 0; //se p parte da zero notazione per pixel,
|
||
|
//se parte da 1 notazione per frame
|
||
|
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;
|
||
|
}
|
||
|
|
||
|
//-----------------------------------------------------------------------------
|
||
|
//Implementato per utilita'
|
||
|
void TXshSoundLevel::getFids(std::vector<TFrameId> &fids) const
|
||
|
{
|
||
|
int i;
|
||
|
for (i = 0; i < getFrameCount(); i++)
|
||
|
fids.push_back(TFrameId(i));
|
||
|
}
|