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
Toshihiro Shimizu 890ddd
TXshSoundLevel::TXshSoundLevel(wstring name, int startOffset, int endOffset)
Toshihiro Shimizu 890ddd
	: TXshLevel(m_classCode, name), m_soundTrack(0), m_duration(0), m_samplePerFrame(0), m_frameSoundCount(0), m_fps(12), m_path()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TXshSoundLevel::~TXshSoundLevel()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TXshSoundLevel *TXshSoundLevel::clone() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TXshSoundLevel *sound = new TXshSoundLevel();
Toshihiro Shimizu 890ddd
	sound->setSoundTrack(m_soundTrack->clone());
Toshihiro Shimizu 890ddd
	sound->m_duration = m_duration;
Toshihiro Shimizu 890ddd
	sound->m_path = m_path;
Toshihiro Shimizu 890ddd
	sound->m_samplePerFrame = m_samplePerFrame;
Toshihiro Shimizu 890ddd
	sound->m_frameSoundCount = m_frameSoundCount;
Toshihiro Shimizu 890ddd
	sound->m_fps = m_fps;
Toshihiro Shimizu 890ddd
	return sound;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TXshSoundLevel::setScene(ToonzScene *scene)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(scene);
Toshihiro Shimizu 890ddd
	TXshLevel::setScene(scene);
Toshihiro Shimizu 890ddd
	TOutputProperties *properties = scene->getProperties()->getOutputProperties();
Toshihiro Shimizu 890ddd
	assert(properties);
Toshihiro Shimizu 890ddd
	setFrameRate(properties->getFrameRate());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TXshSoundLevel::loadSoundTrack()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	assert(getScene());
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	TSceneProperties *properties = getScene()->getProperties();
Toshihiro Shimizu 890ddd
	if (properties) {
Toshihiro Shimizu 890ddd
		TOutputProperties *outputProperties = properties->getOutputProperties();
Toshihiro Shimizu 890ddd
		if (outputProperties)
Toshihiro Shimizu 890ddd
			m_fps = outputProperties->getFrameRate();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	TFilePath path = getScene()->decodeFilePath(m_path);
Toshihiro Shimizu 890ddd
	try {
Toshihiro Shimizu 890ddd
		loadSoundTrack(path);
Toshihiro Shimizu 890ddd
	} catch (TException &e) {
Toshihiro Shimizu 890ddd
		throw TException(e.getMessage());
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TXshSoundLevel::loadSoundTrack(const TFilePath &fileName)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	try {
Toshihiro Shimizu 890ddd
		TSoundTrackP st;
Toshihiro Shimizu 890ddd
		TFilePath path(fileName);
Toshihiro Shimizu 890ddd
		bool ret = TSoundTrackReader::load(path, st);
Toshihiro Shimizu 890ddd
		if (ret) {
Toshihiro Shimizu 890ddd
			m_duration = st->getDuration();
Toshihiro Shimizu 890ddd
			setName(fileName.getWideName());
Toshihiro Shimizu 890ddd
			setSoundTrack(st);
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
	} catch (TException &) {
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TXshSoundLevel::load()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	loadSoundTrack();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TXshSoundLevel::save()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	save(m_path);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TXshSoundLevel::save(const TFilePath &path)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TSoundTrackWriter::save(path, m_soundTrack);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TXshSoundLevel::loadData(TIStream &is)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	is >> m_name;
Toshihiro Shimizu 890ddd
	setName(m_name);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	string tagName;
Toshihiro Shimizu 890ddd
	bool flag = false;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int type = UNKNOWN_XSHLEVEL;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	for (;;) {
Toshihiro Shimizu 890ddd
		if (is.matchTag(tagName)) {
Toshihiro Shimizu 890ddd
			if (tagName == "path") {
Toshihiro Shimizu 890ddd
				is >> m_path;
Toshihiro Shimizu 890ddd
				is.matchEndTag();
Toshihiro Shimizu 890ddd
			} else if (tagName == "type") {
Toshihiro Shimizu 890ddd
				string v;
Toshihiro Shimizu 890ddd
				is >> v;
Toshihiro Shimizu 890ddd
				if (v == "sound")
Toshihiro Shimizu 890ddd
					type = SND_XSHLEVEL;
Toshihiro Shimizu 890ddd
				is.matchEndTag();
Toshihiro Shimizu 890ddd
			} else
Toshihiro Shimizu 890ddd
				throw TException("unexpected tag " + tagName);
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	setType(type);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TXshSoundLevel::saveData(TOStream &os)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	os << m_name;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	map<string, string=""> attr;</string,>
Toshihiro Shimizu 890ddd
	os.child("type") << L"sound";
Toshihiro Shimizu 890ddd
	os.child("path") << m_path;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TXshSoundLevel::computeValues(int frameHeight)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (frameHeight == 0)
Toshihiro Shimizu 890ddd
		frameHeight = 1;
Toshihiro Shimizu 890ddd
	m_values.clear();
Toshihiro Shimizu 890ddd
	if (!m_soundTrack) {
Toshihiro Shimizu 890ddd
		m_frameSoundCount = 0;
Toshihiro Shimizu 890ddd
		m_samplePerFrame = 0;
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_samplePerFrame = m_soundTrack->getSampleRate() / m_fps;
Toshihiro Shimizu 890ddd
	double samplePerPixel = m_samplePerFrame / frameHeight;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	int sampleCount = m_soundTrack->getSampleCount();
Toshihiro Shimizu 890ddd
	if (sampleCount <= 0) // This was if(!sampleCount)  :(
Toshihiro Shimizu 890ddd
		return;			  //
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_frameSoundCount = tceil(sampleCount / m_samplePerFrame);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double maxPressure = 0.0;
Toshihiro Shimizu 890ddd
	double minPressure = 0.0;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	m_soundTrack->getMinMaxPressure(
Toshihiro Shimizu 890ddd
		TINT32(0), (TINT32)sampleCount, TSound::LEFT, minPressure, maxPressure);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	double absMaxPressure = tmax(fabs(minPressure), fabs(maxPressure));
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (absMaxPressure <= 0)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	// Adjusting using a fixed scaleFactor
Toshihiro Shimizu 890ddd
	double weightA = 20.0 / absMaxPressure;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	long i = 0, j;
Toshihiro Shimizu 890ddd
	long p = 0; //se p parte da zero notazione per pixel,
Toshihiro Shimizu 890ddd
				//se parte da 1 notazione per frame
Toshihiro Shimizu 890ddd
	while (i < m_frameSoundCount) {
Toshihiro Shimizu 890ddd
		for (j = 0; j < frameHeight - 1; ++j) {
Toshihiro Shimizu 890ddd
			double min = 0.0;
Toshihiro Shimizu 890ddd
			double max = 0.0;
Toshihiro Shimizu 890ddd
			m_soundTrack->getMinMaxPressure(
Toshihiro Shimizu 890ddd
				(TINT32)(i * m_samplePerFrame + j * samplePerPixel),
Toshihiro Shimizu 890ddd
				(TINT32)(i * m_samplePerFrame + (j + 1) * samplePerPixel - 1),
Toshihiro Shimizu 890ddd
				TSound::MONO, min, max);
Toshihiro Shimizu 890ddd
			m_values.insert(pair<int, double="" pair<double,="">>(p + j, pair<double, double="">(min * weightA, max * weightA)));</double,></int,>
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		double min = 0.0;
Toshihiro Shimizu 890ddd
		double max = 0.0;
Toshihiro Shimizu 890ddd
		m_soundTrack->getMinMaxPressure(
Toshihiro Shimizu 890ddd
			(TINT32)(i * m_samplePerFrame + j * samplePerPixel),
Toshihiro Shimizu 890ddd
			(TINT32)((i + 1) * m_samplePerFrame - 1),
Toshihiro Shimizu 890ddd
			TSound::MONO, min, max);
Toshihiro Shimizu 890ddd
		m_values.insert(pair<int, double="" pair<double,="">>(p + j, pair<double, double="">(min * weightA, max * weightA)));</double,></int,>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		++i;
Toshihiro Shimizu 890ddd
		p += frameHeight;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TXshSoundLevel::getValueAtPixel(int pixel, DoublePair &values) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	std::map<int, doublepair="">::const_iterator it = m_values.find(pixel);</int,>
Toshihiro Shimizu 890ddd
	if (it != m_values.end())
Toshihiro Shimizu 890ddd
		values = it->second;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TXshSoundLevel::setFrameRate(double fps)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_fps != fps) {
Toshihiro Shimizu 890ddd
		m_fps = fps;
Toshihiro Shimizu 890ddd
		computeValues();
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
int TXshSoundLevel::getFrameCount() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int frameCount = m_duration * m_fps;
Toshihiro Shimizu 890ddd
	return (frameCount == 0) ? 1 : frameCount;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
//Implementato per utilita'
Toshihiro Shimizu 890ddd
void TXshSoundLevel::getFids(std::vector<tframeid> &fids) const</tframeid>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	int i;
Toshihiro Shimizu 890ddd
	for (i = 0; i < getFrameCount(); i++)
Toshihiro Shimizu 890ddd
		fids.push_back(TFrameId(i));
Toshihiro Shimizu 890ddd
}