tahoma2d/toonz/sources/common/tsound/tsound.cpp

370 lines
12 KiB
C++
Raw Normal View History

2016-03-19 06:57:51 +13:00
#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
2021-05-17 08:05:25 +12:00
#define TRK_M32 33
#define TRK_S32 34
2016-03-19 06:57:51 +13:00
//==============================================================================
DEFINE_CLASS_CODE(TSoundTrack, 12)
//------------------------------------------------------------------------------
TSoundTrack::TSoundTrack()
2016-06-15 18:43:10 +12:00
: TSmartObject(m_classCode)
, m_parent(0)
, m_buffer(0)
, m_bufferOwner(false) {}
2016-03-19 06:57:51 +13:00
//------------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TSoundTrack::TSoundTrack(TUINT32 sampleRate, int bitPerSample, int channelCount,
int sampleSize, TINT32 sampleCount,
2021-05-20 23:35:12 +12:00
bool isSampleSigned, int formatType)
2016-06-15 18:43:10 +12:00
: TSmartObject(m_classCode)
, m_sampleRate(sampleRate)
, m_sampleSize(sampleSize)
, m_bitPerSample(bitPerSample)
, m_sampleCount(sampleCount)
, m_channelCount(channelCount)
, m_parent(0)
2021-05-20 23:35:12 +12:00
, m_bufferOwner(true)
, m_formatType(formatType) {
2016-06-15 18:43:10 +12:00
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);
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TSoundTrack::TSoundTrack(TUINT32 sampleRate, int bitPerSample, int channelCount,
int sampleSize, TINT32 sampleCount, UCHAR *buffer,
2021-05-20 23:35:12 +12:00
TSoundTrack *parent, int formatType)
2016-06-15 18:43:10 +12:00
: TSmartObject(m_classCode)
, m_sampleRate(sampleRate)
, m_sampleSize(sampleSize)
, m_bitPerSample(bitPerSample)
, m_sampleCount(sampleCount)
, m_channelCount(channelCount)
, m_parent(parent)
, m_buffer(buffer)
2021-05-20 23:35:12 +12:00
, m_bufferOwner(false)
, m_formatType(formatType) {
2016-06-15 18:43:10 +12:00
if (m_parent) m_parent->addRef();
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TSoundTrack::~TSoundTrack() {
if (m_parent) m_parent->release();
// if (m_buffer && m_bufferOwner) delete [] m_buffer;
if (m_buffer && m_bufferOwner) free(m_buffer);
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TSoundTrackP TSoundTrack::create(TUINT32 sampleRate, int bitPerSample,
int channelCount, TINT32 sampleCount,
2021-05-20 23:35:12 +12:00
bool signedSample, int formatType) {
2016-06-15 18:43:10 +12:00
TSoundTrackP st;
int type = bitPerSample + channelCount;
switch (type) {
case TRK_M8:
if (signedSample)
2021-05-20 23:35:12 +12:00
st = new TSoundTrackMono8Signed(sampleRate, channelCount, sampleCount,
formatType);
2016-06-15 18:43:10 +12:00
else
2021-05-20 23:35:12 +12:00
st = new TSoundTrackMono8Unsigned(sampleRate, channelCount, sampleCount,
formatType);
2016-06-15 18:43:10 +12:00
break;
case TRK_S8:
if (signedSample)
2021-05-20 23:35:12 +12:00
st = new TSoundTrackStereo8Signed(sampleRate, channelCount, sampleCount,
formatType);
2016-06-15 18:43:10 +12:00
else
2021-05-20 23:35:12 +12:00
st = new TSoundTrackStereo8Unsigned(sampleRate, channelCount, sampleCount,
formatType);
2016-06-15 18:43:10 +12:00
break;
case TRK_M16:
2021-05-20 23:35:12 +12:00
st = new TSoundTrackMono16(sampleRate, channelCount, sampleCount,
formatType);
2016-06-15 18:43:10 +12:00
break;
case TRK_S16:
2021-05-20 23:35:12 +12:00
st = new TSoundTrackStereo16(sampleRate, channelCount, sampleCount,
formatType);
2016-06-15 18:43:10 +12:00
break;
case TRK_M24:
2021-05-20 23:35:12 +12:00
st = new TSoundTrackMono24(sampleRate, channelCount, sampleCount,
formatType);
2016-06-15 18:43:10 +12:00
break;
case TRK_S24:
2021-05-20 23:35:12 +12:00
st = new TSoundTrackStereo24(sampleRate, channelCount, sampleCount,
formatType);
2016-06-15 18:43:10 +12:00
break;
2021-05-17 08:05:25 +12:00
case TRK_M32:
2021-05-20 23:35:12 +12:00
if (formatType == WAVE_FORMAT_PCM)
st = new TSoundTrackMono32(sampleRate, channelCount, sampleCount,
formatType);
else
st = new TSoundTrackMono32float(sampleRate, channelCount, sampleCount,
formatType);
2021-05-17 08:05:25 +12:00
break;
case TRK_S32:
2021-05-20 23:35:12 +12:00
if (formatType == WAVE_FORMAT_PCM)
st = new TSoundTrackStereo32(sampleRate, channelCount, sampleCount,
formatType);
else
st = new TSoundTrackStereo32float(sampleRate, channelCount, sampleCount,
formatType);
2021-05-17 08:05:25 +12:00
break;
2016-06-15 18:43:10 +12:00
default:
std::string s;
s = "Type " + std::to_string(sampleRate) + " Hz " +
std::to_string(bitPerSample) + " bits ";
if (channelCount == 1)
s += "mono: ";
else
s += "stereo: ";
s += "Unsupported\n";
throw TException(s);
}
if (!st->getRawData()) {
return 0;
}
return st;
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TSoundTrackP TSoundTrack::create(TUINT32 sampleRate, int bitPerSample,
int channelCount, TINT32 sampleCount,
2021-05-20 23:35:12 +12:00
void *buffer, bool signedSample,
int formatType) {
2016-06-15 18:43:10 +12:00
TSoundTrackP st;
int type = bitPerSample + channelCount;
switch (type) {
case TRK_M8:
if (signedSample)
st = new TSoundTrackMono8Signed(sampleRate, channelCount, sampleCount,
2021-05-20 23:35:12 +12:00
(TMono8SignedSample *)buffer, 0,
formatType);
2016-06-15 18:43:10 +12:00
else
st = new TSoundTrackMono8Unsigned(sampleRate, channelCount, sampleCount,
2021-05-20 23:35:12 +12:00
(TMono8UnsignedSample *)buffer, 0,
formatType);
2016-06-15 18:43:10 +12:00
break;
case TRK_S8:
if (signedSample)
st = new TSoundTrackStereo8Signed(sampleRate, channelCount, sampleCount,
2021-05-20 23:35:12 +12:00
(TStereo8SignedSample *)buffer, 0,
formatType);
2016-06-15 18:43:10 +12:00
else
st = new TSoundTrackStereo8Unsigned(sampleRate, channelCount, sampleCount,
2021-05-20 23:35:12 +12:00
(TStereo8UnsignedSample *)buffer, 0,
formatType);
2016-06-15 18:43:10 +12:00
break;
case TRK_M16:
st = new TSoundTrackMono16(sampleRate, channelCount, sampleCount,
2021-05-20 23:35:12 +12:00
(TMono16Sample *)buffer, 0, formatType);
2016-06-15 18:43:10 +12:00
break;
case TRK_S16:
st = new TSoundTrackStereo16(sampleRate, channelCount, sampleCount,
2021-05-20 23:35:12 +12:00
(TStereo16Sample *)buffer, 0, formatType);
2016-06-15 18:43:10 +12:00
break;
case TRK_M24:
st = new TSoundTrackMono24(sampleRate, channelCount, sampleCount,
2021-05-20 23:35:12 +12:00
(TMono24Sample *)buffer, 0, formatType);
2016-06-15 18:43:10 +12:00
break;
case TRK_S24:
st = new TSoundTrackStereo24(sampleRate, channelCount, sampleCount,
2021-05-20 23:35:12 +12:00
(TStereo24Sample *)buffer, 0, formatType);
2016-06-15 18:43:10 +12:00
break;
2021-05-17 08:05:25 +12:00
case TRK_M32:
st = new TSoundTrackMono32(sampleRate, channelCount, sampleCount,
2021-05-20 23:35:12 +12:00
(TMono32Sample *)buffer, 0, formatType);
2021-05-17 08:05:25 +12:00
break;
case TRK_S32:
2021-05-20 23:35:12 +12:00
if (formatType == WAVE_FORMAT_PCM)
st = new TSoundTrackStereo32(sampleRate, channelCount, sampleCount,
(TStereo32Sample *)buffer, 0, formatType);
else
st = new TSoundTrackStereo32float(sampleRate, channelCount, sampleCount,
(TStereo32floatSample *)buffer, 0,
formatType);
2021-05-17 08:05:25 +12:00
break;
2016-06-15 18:43:10 +12:00
default:
std::string s;
s = "Type " + std::to_string(sampleRate) + " Hz " +
std::to_string(bitPerSample) + " bits ";
if (channelCount == 1)
s += "mono: ";
else
s += "stereo: ";
s += "Unsupported\n";
throw TException(s);
}
return st;
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
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,
2021-05-20 23:35:12 +12:00
format.m_signedSample, format.m_formatType);
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TSoundTrackP TSoundTrack::create(const TSoundTrackFormat &format,
TINT32 sampleCount) {
return TSoundTrack::create((int)format.m_sampleRate, format.m_bitPerSample,
format.m_channelCount, sampleCount,
2021-05-20 23:35:12 +12:00
format.m_signedSample, format.m_formatType);
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TINT32 TSoundTrack::secondsToSamples(double s) const {
double dsamp = s * m_sampleRate;
TINT32 lsamp = (TINT32)dsamp;
if ((double)lsamp < dsamp - TConsts::epsilon) lsamp++;
return lsamp;
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
double TSoundTrack::samplesToSeconds(TINT32 f) const {
return f / (double)m_sampleRate;
2016-03-19 06:57:51 +13:00
}
//==============================================================================
2016-06-15 18:43:10 +12:00
bool TSoundTrackFormat::operator==(const TSoundTrackFormat &rhs) {
return (m_sampleRate == rhs.m_sampleRate &&
m_bitPerSample == rhs.m_bitPerSample &&
m_channelCount == rhs.m_channelCount &&
2021-05-20 23:35:12 +12:00
m_signedSample == rhs.m_signedSample &&
m_formatType == rhs.m_formatType);
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
bool TSoundTrackFormat::operator!=(const TSoundTrackFormat &rhs) {
return !operator==(rhs);
2016-03-19 06:57:51 +13:00
}
//==============================================================================
2016-06-15 18:43:10 +12:00
double TSoundTrack::getDuration() const {
return samplesToSeconds(m_sampleCount);
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TSoundTrackFormat TSoundTrack::getFormat() const {
return TSoundTrackFormat(getSampleRate(), getBitPerSample(),
2021-05-20 23:35:12 +12:00
getChannelCount(), isSampleSigned(),
getFormatType());
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
TSoundTrackP TSoundTrack::extract(double t0, double t1) {
return extract(secondsToSamples(t0), secondsToSamples(t1));
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TSoundTrack::copy(const TSoundTrackP &src, double dst_t0) {
copy(src, secondsToSamples(dst_t0));
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TSoundTrack::blank(double t0, double t1) {
blank(secondsToSamples(t0), secondsToSamples(t1));
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
double TSoundTrack::getPressure(double second, TSound::Channel chan) const {
return getPressure(secondsToSamples(second), chan);
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TSoundTrack::getMinMaxPressure(double t0, double t1, TSound::Channel chan,
double &min, double &max) const {
getMinMaxPressure(secondsToSamples(t0), secondsToSamples(t1), chan, min, max);
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
void TSoundTrack::getMinMaxPressure(TSound::Channel chan, double &min,
double &max) const {
getMinMaxPressure(0, (TINT32)(getSampleCount() - 1), chan, min, max);
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
double TSoundTrack::getMaxPressure(double t0, double t1,
TSound::Channel chan) const {
return getMaxPressure(secondsToSamples(t0), secondsToSamples(t1), chan);
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
double TSoundTrack::getMaxPressure(TSound::Channel chan) const {
return getMaxPressure(0, (TINT32)(getSampleCount() - 1), chan);
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
double TSoundTrack::getMinPressure(double t0, double t1,
TSound::Channel chan) const {
return getMinPressure(secondsToSamples(t0), secondsToSamples(t1), chan);
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------------------
2016-06-15 18:43:10 +12:00
double TSoundTrack::getMinPressure(TSound::Channel chan) const {
return getMinPressure(0, (TINT32)(getSampleCount() - 1), chan);
2016-03-19 06:57:51 +13:00
}
//------------------------------------------------------------------------------