Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tsound.h"
Toshihiro Shimizu 890ddd
#include "tsound_t.h"
Toshihiro Shimizu 890ddd
#include "tconvert.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#define TRK_M8 9
Toshihiro Shimizu 890ddd
#define TRK_S8 10
Toshihiro Shimizu 890ddd
#define TRK_M16 17
Toshihiro Shimizu 890ddd
#define TRK_S16 18
Toshihiro Shimizu 890ddd
#define TRK_M24 25
Toshihiro Shimizu 890ddd
#define TRK_S24 26
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
DEFINE_CLASS_CODE(TSoundTrack, 12)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TSoundTrack::TSoundTrack()
Toshihiro Shimizu 890ddd
	: TSmartObject(m_classCode), m_parent(0), m_buffer(0), m_bufferOwner(false)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TSoundTrack::TSoundTrack(TUINT32 sampleRate,
Toshihiro Shimizu 890ddd
						 int bitPerSample,
Toshihiro Shimizu 890ddd
						 int channelCount,
Toshihiro Shimizu 890ddd
						 int sampleSize,
Toshihiro Shimizu 890ddd
						 TINT32 sampleCount,
Toshihiro Shimizu 890ddd
						 bool isSampleSigned)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	: TSmartObject(m_classCode), m_sampleRate(sampleRate), m_sampleSize(sampleSize), m_bitPerSample(bitPerSample), m_sampleCount(sampleCount), m_channelCount(channelCount), m_parent(0), m_bufferOwner(true)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	m_buffer = (UCHAR *)malloc(sampleCount * m_sampleSize);
Toshihiro Shimizu 890ddd
	if (!m_buffer)
Toshihiro Shimizu 890ddd
		return;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//m_buffer = new UCHAR[sampleCount*m_sampleSize];
Toshihiro Shimizu 890ddd
	if (isSampleSigned)
Toshihiro Shimizu 890ddd
		memset(m_buffer, 0, sampleCount * sampleSize);
Toshihiro Shimizu 890ddd
	else
Toshihiro Shimizu 890ddd
		memset(m_buffer, 127, sampleCount * sampleSize);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TSoundTrack::TSoundTrack(TUINT32 sampleRate,
Toshihiro Shimizu 890ddd
						 int bitPerSample,
Toshihiro Shimizu 890ddd
						 int channelCount,
Toshihiro Shimizu 890ddd
						 int sampleSize,
Toshihiro Shimizu 890ddd
						 TINT32 sampleCount,
Toshihiro Shimizu 890ddd
						 UCHAR *buffer,
Toshihiro Shimizu 890ddd
						 TSoundTrack *parent)
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	: TSmartObject(m_classCode), m_sampleRate(sampleRate), m_sampleSize(sampleSize), m_bitPerSample(bitPerSample), m_sampleCount(sampleCount), m_channelCount(channelCount), m_parent(parent), m_buffer(buffer), m_bufferOwner(false)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_parent)
Toshihiro Shimizu 890ddd
		m_parent->addRef();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TSoundTrack::~TSoundTrack()
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	if (m_parent)
Toshihiro Shimizu 890ddd
		m_parent->release();
Toshihiro Shimizu 890ddd
	//if (m_buffer && m_bufferOwner) delete [] m_buffer;
Toshihiro Shimizu 890ddd
	if (m_buffer && m_bufferOwner)
Toshihiro Shimizu 890ddd
		free(m_buffer);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TSoundTrackP TSoundTrack::create(
Toshihiro Shimizu 890ddd
	TUINT32 sampleRate, int bitPerSample,
Toshihiro Shimizu 890ddd
	int channelCount, TINT32 sampleCount,
Toshihiro Shimizu 890ddd
	bool signedSample)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TSoundTrackP st;
Toshihiro Shimizu 890ddd
	int type = bitPerSample + channelCount;
Toshihiro Shimizu 890ddd
	switch (type) {
Toshihiro Shimizu 890ddd
	case TRK_M8:
Toshihiro Shimizu 890ddd
		if (signedSample)
Toshihiro Shimizu 890ddd
			st = new TSoundTrackMono8Signed(
Toshihiro Shimizu 890ddd
				sampleRate, channelCount, sampleCount);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			st = new TSoundTrackMono8Unsigned(
Toshihiro Shimizu 890ddd
				sampleRate, channelCount, sampleCount);
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
	case TRK_S8:
Toshihiro Shimizu 890ddd
		if (signedSample)
Toshihiro Shimizu 890ddd
			st = new TSoundTrackStereo8Signed(
Toshihiro Shimizu 890ddd
				sampleRate, channelCount, sampleCount);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			st = new TSoundTrackStereo8Unsigned(
Toshihiro Shimizu 890ddd
				sampleRate, channelCount, sampleCount);
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	case TRK_M16:
Toshihiro Shimizu 890ddd
		st = new TSoundTrackMono16(
Toshihiro Shimizu 890ddd
			sampleRate, channelCount, sampleCount);
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	case TRK_S16:
Toshihiro Shimizu 890ddd
		st = new TSoundTrackStereo16(
Toshihiro Shimizu 890ddd
			sampleRate, channelCount, sampleCount);
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	case TRK_M24:
Toshihiro Shimizu 890ddd
		st = new TSoundTrackMono24(
Toshihiro Shimizu 890ddd
			sampleRate, channelCount, sampleCount);
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	case TRK_S24:
Toshihiro Shimizu 890ddd
		st = new TSoundTrackStereo24(
Toshihiro Shimizu 890ddd
			sampleRate, channelCount, sampleCount);
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	default:
Toshihiro Shimizu 890ddd
		string s;
Toshihiro Shimizu 890ddd
		s = "Type " + toString((int)sampleRate) + " Hz " + toString(bitPerSample) + " bits ";
Toshihiro Shimizu 890ddd
		if (channelCount == 1)
Toshihiro Shimizu 890ddd
			s += "mono: ";
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			s += "stereo: ";
Toshihiro Shimizu 890ddd
		s += "Unsupported\n";
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		throw TException(s);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (!st->getRawData()) {
Toshihiro Shimizu 890ddd
		return 0;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
	return st;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TSoundTrackP TSoundTrack::create(
Toshihiro Shimizu 890ddd
	TUINT32 sampleRate, int bitPerSample,
Toshihiro Shimizu 890ddd
	int channelCount, TINT32 sampleCount, void *buffer,
Toshihiro Shimizu 890ddd
	bool signedSample)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	TSoundTrackP st;
Toshihiro Shimizu 890ddd
	int type = bitPerSample + channelCount;
Toshihiro Shimizu 890ddd
	switch (type) {
Toshihiro Shimizu 890ddd
	case TRK_M8:
Toshihiro Shimizu 890ddd
		if (signedSample)
Toshihiro Shimizu 890ddd
			st = new TSoundTrackMono8Signed(
Toshihiro Shimizu 890ddd
				sampleRate, channelCount, sampleCount, (TMono8SignedSample *)buffer, 0);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			st = new TSoundTrackMono8Unsigned(
Toshihiro Shimizu 890ddd
				sampleRate, channelCount, sampleCount, (TMono8UnsignedSample *)buffer, 0);
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
	case TRK_S8:
Toshihiro Shimizu 890ddd
		if (signedSample)
Toshihiro Shimizu 890ddd
			st = new TSoundTrackStereo8Signed(
Toshihiro Shimizu 890ddd
				sampleRate, channelCount, sampleCount, (TStereo8SignedSample *)buffer, 0);
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			st = new TSoundTrackStereo8Unsigned(
Toshihiro Shimizu 890ddd
				sampleRate, channelCount, sampleCount, (TStereo8UnsignedSample *)buffer, 0);
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	case TRK_M16:
Toshihiro Shimizu 890ddd
		st = new TSoundTrackMono16(
Toshihiro Shimizu 890ddd
			sampleRate, channelCount, sampleCount, (TMono16Sample *)buffer, 0);
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	case TRK_S16:
Toshihiro Shimizu 890ddd
		st = new TSoundTrackStereo16(
Toshihiro Shimizu 890ddd
			sampleRate, channelCount, sampleCount, (TStereo16Sample *)buffer, 0);
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	case TRK_M24:
Toshihiro Shimizu 890ddd
		st = new TSoundTrackMono24(
Toshihiro Shimizu 890ddd
			sampleRate, channelCount, sampleCount, (TMono24Sample *)buffer, 0);
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	case TRK_S24:
Toshihiro Shimizu 890ddd
		st = new TSoundTrackStereo24(
Toshihiro Shimizu 890ddd
			sampleRate, channelCount, sampleCount, (TStereo24Sample *)buffer, 0);
Toshihiro Shimizu 890ddd
		break;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	default:
Toshihiro Shimizu 890ddd
		string s;
Toshihiro Shimizu 890ddd
		s = "Type " + toString((int)sampleRate) + " Hz " + toString(bitPerSample) + " bits ";
Toshihiro Shimizu 890ddd
		if (channelCount == 1)
Toshihiro Shimizu 890ddd
			s += "mono: ";
Toshihiro Shimizu 890ddd
		else
Toshihiro Shimizu 890ddd
			s += "stereo: ";
Toshihiro Shimizu 890ddd
		s += "Unsupported\n";
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		throw TException(s);
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return st;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TSoundTrackP TSoundTrack::create(const TSoundTrackFormat &format, TINT32 sampleCount, void *buffer)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return TSoundTrack::create(
Toshihiro Shimizu 890ddd
		(int)format.m_sampleRate,
Toshihiro Shimizu 890ddd
		format.m_bitPerSample,
Toshihiro Shimizu 890ddd
		format.m_channelCount,
Toshihiro Shimizu 890ddd
		sampleCount,
Toshihiro Shimizu 890ddd
		buffer,
Toshihiro Shimizu 890ddd
		format.m_signedSample);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TSoundTrackP TSoundTrack::create(const TSoundTrackFormat &format, TINT32 sampleCount)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return TSoundTrack::create(
Toshihiro Shimizu 890ddd
		(int)format.m_sampleRate,
Toshihiro Shimizu 890ddd
		format.m_bitPerSample,
Toshihiro Shimizu 890ddd
		format.m_channelCount,
Toshihiro Shimizu 890ddd
		sampleCount,
Toshihiro Shimizu 890ddd
		format.m_signedSample);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TINT32 TSoundTrack::secondsToSamples(double s) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	double dsamp = s * m_sampleRate;
Toshihiro Shimizu 890ddd
	TINT32 lsamp = (TINT32)dsamp;
Toshihiro Shimizu 890ddd
	if ((double)lsamp < dsamp - TConsts::epsilon)
Toshihiro Shimizu 890ddd
		lsamp++;
Toshihiro Shimizu 890ddd
	return lsamp;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
double TSoundTrack::samplesToSeconds(TINT32 f) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return f / (double)m_sampleRate;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TSoundTrackFormat::operator==(const TSoundTrackFormat &rhs)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return (m_sampleRate == rhs.m_sampleRate &&
Toshihiro Shimizu 890ddd
			m_bitPerSample == rhs.m_bitPerSample &&
Toshihiro Shimizu 890ddd
			m_channelCount == rhs.m_channelCount &&
Toshihiro Shimizu 890ddd
			m_signedSample == rhs.m_signedSample);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
bool TSoundTrackFormat::operator!=(const TSoundTrackFormat &rhs)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return !operator==(rhs);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
double TSoundTrack::getDuration() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return samplesToSeconds(m_sampleCount);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TSoundTrackFormat TSoundTrack::getFormat() const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return TSoundTrackFormat(
Toshihiro Shimizu 890ddd
		getSampleRate(),
Toshihiro Shimizu 890ddd
		getBitPerSample(),
Toshihiro Shimizu 890ddd
		getChannelCount(),
Toshihiro Shimizu 890ddd
		isSampleSigned());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
TSoundTrackP TSoundTrack::extract(double t0, double t1)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return extract(secondsToSamples(t0), secondsToSamples(t1));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TSoundTrack::copy(const TSoundTrackP &src, double dst_t0)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	copy(src, secondsToSamples(dst_t0));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TSoundTrack::blank(double t0, double t1)
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	blank(secondsToSamples(t0), secondsToSamples(t1));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
double TSoundTrack::getPressure(double second, TSound::Channel chan) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return getPressure(secondsToSamples(second), chan);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TSoundTrack::getMinMaxPressure(
Toshihiro Shimizu 890ddd
	double t0, double t1, TSound::Channel chan,
Toshihiro Shimizu 890ddd
	double &min, double &max) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	getMinMaxPressure(secondsToSamples(t0), secondsToSamples(t1), chan, min, max);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
void TSoundTrack::getMinMaxPressure(TSound::Channel chan, double &min, double &max) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	getMinMaxPressure(0, (TINT32)(getSampleCount() - 1), chan, min, max);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
double TSoundTrack::getMaxPressure(double t0, double t1, TSound::Channel chan) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return getMaxPressure(secondsToSamples(t0), secondsToSamples(t1), chan);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
double TSoundTrack::getMaxPressure(TSound::Channel chan) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return getMaxPressure(0, (TINT32)(getSampleCount() - 1), chan);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
double TSoundTrack::getMinPressure(double t0, double t1, TSound::Channel chan) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return getMinPressure(secondsToSamples(t0), secondsToSamples(t1), chan);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
double TSoundTrack::getMinPressure(TSound::Channel chan) const
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return getMinPressure(0, (TINT32)(getSampleCount() - 1), chan);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------