Blob Blame Raw


#include "tsound.h"
#include "tsound_t.h"
#include "tconvert.h"

#define TRK_M8 9
#define TRK_S8 10
#define TRK_M16 17
#define TRK_S16 18
#define TRK_M24 25
#define TRK_S24 26

//==============================================================================

DEFINE_CLASS_CODE(TSoundTrack, 12)

//------------------------------------------------------------------------------

TSoundTrack::TSoundTrack()
	: TSmartObject(m_classCode), m_parent(0), m_buffer(0), m_bufferOwner(false)
{
}

//------------------------------------------------------------------------------

TSoundTrack::TSoundTrack(TUINT32 sampleRate,
						 int bitPerSample,
						 int channelCount,
						 int sampleSize,
						 TINT32 sampleCount,
						 bool isSampleSigned)

	: TSmartObject(m_classCode), m_sampleRate(sampleRate), m_sampleSize(sampleSize), m_bitPerSample(bitPerSample), m_sampleCount(sampleCount), m_channelCount(channelCount), m_parent(0), m_bufferOwner(true)
{
	m_buffer = (UCHAR *)malloc(sampleCount * m_sampleSize);
	if (!m_buffer)
		return;

	//m_buffer = new UCHAR[sampleCount*m_sampleSize];
	if (isSampleSigned)
		memset(m_buffer, 0, sampleCount * sampleSize);
	else
		memset(m_buffer, 127, sampleCount * sampleSize);
}

//------------------------------------------------------------------------------

TSoundTrack::TSoundTrack(TUINT32 sampleRate,
						 int bitPerSample,
						 int channelCount,
						 int sampleSize,
						 TINT32 sampleCount,
						 UCHAR *buffer,
						 TSoundTrack *parent)

	: 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)
{
	if (m_parent)
		m_parent->addRef();
}

//------------------------------------------------------------------------------

TSoundTrack::~TSoundTrack()
{
	if (m_parent)
		m_parent->release();
	//if (m_buffer && m_bufferOwner) delete [] m_buffer;
	if (m_buffer && m_bufferOwner)
		free(m_buffer);
}

//------------------------------------------------------------------------------

TSoundTrackP TSoundTrack::create(
	TUINT32 sampleRate, int bitPerSample,
	int channelCount, TINT32 sampleCount,
	bool signedSample)
{
	TSoundTrackP st;
	int type = bitPerSample + channelCount;
	switch (type) {
	case TRK_M8:
		if (signedSample)
			st = new TSoundTrackMono8Signed(
				sampleRate, channelCount, sampleCount);
		else
			st = new TSoundTrackMono8Unsigned(
				sampleRate, channelCount, sampleCount);
		break;
	case TRK_S8:
		if (signedSample)
			st = new TSoundTrackStereo8Signed(
				sampleRate, channelCount, sampleCount);
		else
			st = new TSoundTrackStereo8Unsigned(
				sampleRate, channelCount, sampleCount);
		break;

	case TRK_M16:
		st = new TSoundTrackMono16(
			sampleRate, channelCount, sampleCount);
		break;

	case TRK_S16:
		st = new TSoundTrackStereo16(
			sampleRate, channelCount, sampleCount);
		break;

	case TRK_M24:
		st = new TSoundTrackMono24(
			sampleRate, channelCount, sampleCount);
		break;

	case TRK_S24:
		st = new TSoundTrackStereo24(
			sampleRate, channelCount, sampleCount);
		break;

	default:
		string s;
		s = "Type " + toString((int)sampleRate) + " Hz " + toString(bitPerSample) + " bits ";
		if (channelCount == 1)
			s += "mono: ";
		else
			s += "stereo: ";
		s += "Unsupported\n";

		throw TException(s);
	}

	if (!st->getRawData()) {
		return 0;
	}
	return st;
}

//------------------------------------------------------------------------------

TSoundTrackP TSoundTrack::create(
	TUINT32 sampleRate, int bitPerSample,
	int channelCount, TINT32 sampleCount, void *buffer,
	bool signedSample)
{
	TSoundTrackP st;
	int type = bitPerSample + channelCount;
	switch (type) {
	case TRK_M8:
		if (signedSample)
			st = new TSoundTrackMono8Signed(
				sampleRate, channelCount, sampleCount, (TMono8SignedSample *)buffer, 0);
		else
			st = new TSoundTrackMono8Unsigned(
				sampleRate, channelCount, sampleCount, (TMono8UnsignedSample *)buffer, 0);
		break;
	case TRK_S8:
		if (signedSample)
			st = new TSoundTrackStereo8Signed(
				sampleRate, channelCount, sampleCount, (TStereo8SignedSample *)buffer, 0);
		else
			st = new TSoundTrackStereo8Unsigned(
				sampleRate, channelCount, sampleCount, (TStereo8UnsignedSample *)buffer, 0);
		break;

	case TRK_M16:
		st = new TSoundTrackMono16(
			sampleRate, channelCount, sampleCount, (TMono16Sample *)buffer, 0);
		break;

	case TRK_S16:
		st = new TSoundTrackStereo16(
			sampleRate, channelCount, sampleCount, (TStereo16Sample *)buffer, 0);
		break;

	case TRK_M24:
		st = new TSoundTrackMono24(
			sampleRate, channelCount, sampleCount, (TMono24Sample *)buffer, 0);
		break;

	case TRK_S24:
		st = new TSoundTrackStereo24(
			sampleRate, channelCount, sampleCount, (TStereo24Sample *)buffer, 0);
		break;

	default:
		string s;
		s = "Type " + toString((int)sampleRate) + " Hz " + toString(bitPerSample) + " bits ";
		if (channelCount == 1)
			s += "mono: ";
		else
			s += "stereo: ";
		s += "Unsupported\n";

		throw TException(s);
	}

	return st;
}

//------------------------------------------------------------------------------

TSoundTrackP TSoundTrack::create(const TSoundTrackFormat &format, TINT32 sampleCount, void *buffer)
{
	return TSoundTrack::create(
		(int)format.m_sampleRate,
		format.m_bitPerSample,
		format.m_channelCount,
		sampleCount,
		buffer,
		format.m_signedSample);
}

//------------------------------------------------------------------------------

TSoundTrackP TSoundTrack::create(const TSoundTrackFormat &format, TINT32 sampleCount)
{
	return TSoundTrack::create(
		(int)format.m_sampleRate,
		format.m_bitPerSample,
		format.m_channelCount,
		sampleCount,
		format.m_signedSample);
}

//------------------------------------------------------------------------------

TINT32 TSoundTrack::secondsToSamples(double s) const
{
	double dsamp = s * m_sampleRate;
	TINT32 lsamp = (TINT32)dsamp;
	if ((double)lsamp < dsamp - TConsts::epsilon)
		lsamp++;
	return lsamp;
}

//------------------------------------------------------------------------------

double TSoundTrack::samplesToSeconds(TINT32 f) const
{
	return f / (double)m_sampleRate;
}

//==============================================================================

bool TSoundTrackFormat::operator==(const TSoundTrackFormat &rhs)
{
	return (m_sampleRate == rhs.m_sampleRate &&
			m_bitPerSample == rhs.m_bitPerSample &&
			m_channelCount == rhs.m_channelCount &&
			m_signedSample == rhs.m_signedSample);
}

//------------------------------------------------------------------------------

bool TSoundTrackFormat::operator!=(const TSoundTrackFormat &rhs)
{
	return !operator==(rhs);
}

//==============================================================================

double TSoundTrack::getDuration() const
{
	return samplesToSeconds(m_sampleCount);
}

//------------------------------------------------------------------------------

TSoundTrackFormat TSoundTrack::getFormat() const
{
	return TSoundTrackFormat(
		getSampleRate(),
		getBitPerSample(),
		getChannelCount(),
		isSampleSigned());
}

//------------------------------------------------------------------------------

TSoundTrackP TSoundTrack::extract(double t0, double t1)
{
	return extract(secondsToSamples(t0), secondsToSamples(t1));
}

//------------------------------------------------------------------------------

void TSoundTrack::copy(const TSoundTrackP &src, double dst_t0)
{
	copy(src, secondsToSamples(dst_t0));
}

//------------------------------------------------------------------------------

void TSoundTrack::blank(double t0, double t1)
{
	blank(secondsToSamples(t0), secondsToSamples(t1));
}
//------------------------------------------------------------------------------

double TSoundTrack::getPressure(double second, TSound::Channel chan) const
{
	return getPressure(secondsToSamples(second), chan);
}

//------------------------------------------------------------------------------

void TSoundTrack::getMinMaxPressure(
	double t0, double t1, TSound::Channel chan,
	double &min, double &max) const
{
	getMinMaxPressure(secondsToSamples(t0), secondsToSamples(t1), chan, min, max);
}

//------------------------------------------------------------------------------

void TSoundTrack::getMinMaxPressure(TSound::Channel chan, double &min, double &max) const
{
	getMinMaxPressure(0, (TINT32)(getSampleCount() - 1), chan, min, max);
}

//------------------------------------------------------------------------------

double TSoundTrack::getMaxPressure(double t0, double t1, TSound::Channel chan) const
{
	return getMaxPressure(secondsToSamples(t0), secondsToSamples(t1), chan);
}

//------------------------------------------------------------------------------

double TSoundTrack::getMaxPressure(TSound::Channel chan) const
{
	return getMaxPressure(0, (TINT32)(getSampleCount() - 1), chan);
}

//------------------------------------------------------------------------------

double TSoundTrack::getMinPressure(double t0, double t1, TSound::Channel chan) const
{
	return getMinPressure(secondsToSamples(t0), secondsToSamples(t1), chan);
}

//------------------------------------------------------------------------------

double TSoundTrack::getMinPressure(TSound::Channel chan) const
{
	return getMinPressure(0, (TINT32)(getSampleCount() - 1), chan);
}

//------------------------------------------------------------------------------