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
justburner 9369f1
#define TRK_M32 33
justburner 9369f1
#define TRK_S32 34
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()
Shinya Kitaoka 120a6e
    : TSmartObject(m_classCode)
Shinya Kitaoka 120a6e
    , m_parent(0)
Shinya Kitaoka 120a6e
    , m_buffer(0)
Shinya Kitaoka 120a6e
    , m_bufferOwner(false) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TSoundTrack::TSoundTrack(TUINT32 sampleRate, int bitPerSample, int channelCount,
justburner 9369f1
                         int sampleSize, TINT32 sampleCount, int sampleType)
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    : TSmartObject(m_classCode)
Shinya Kitaoka 120a6e
    , m_sampleRate(sampleRate)
Shinya Kitaoka 120a6e
    , m_sampleSize(sampleSize)
Shinya Kitaoka 120a6e
    , m_bitPerSample(bitPerSample)
Shinya Kitaoka 120a6e
    , m_sampleCount(sampleCount)
Shinya Kitaoka 120a6e
    , m_channelCount(channelCount)
Shinya Kitaoka 120a6e
    , m_parent(0)
Shinya Kitaoka 120a6e
    , m_bufferOwner(true) {
Shinya Kitaoka 120a6e
  m_buffer = (UCHAR *)malloc(sampleCount * m_sampleSize);
Shinya Kitaoka 120a6e
  if (!m_buffer) return;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // m_buffer = new UCHAR[sampleCount*m_sampleSize];
justburner 9369f1
  if (sampleType != TSound::UINT)
Shinya Kitaoka 120a6e
    memset(m_buffer, 0, sampleCount * sampleSize);
Shinya Kitaoka 120a6e
  else
Shinya Kitaoka 120a6e
    memset(m_buffer, 127, sampleCount * sampleSize);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TSoundTrack::TSoundTrack(TUINT32 sampleRate, int bitPerSample, int channelCount,
justburner 9369f1
                         int sampleSize, TINT32 sampleCount, int sampleType,
justburner 9369f1
                         UCHAR *buffer, TSoundTrack *parent)
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    : TSmartObject(m_classCode)
Shinya Kitaoka 120a6e
    , m_sampleRate(sampleRate)
Shinya Kitaoka 120a6e
    , m_sampleSize(sampleSize)
Shinya Kitaoka 120a6e
    , m_bitPerSample(bitPerSample)
Shinya Kitaoka 120a6e
    , m_sampleCount(sampleCount)
Shinya Kitaoka 120a6e
    , m_channelCount(channelCount)
justburner 9369f1
    , m_sampleType(sampleType)
Shinya Kitaoka 120a6e
    , m_parent(parent)
Shinya Kitaoka 120a6e
    , m_buffer(buffer)
Shinya Kitaoka 120a6e
    , m_bufferOwner(false) {
Shinya Kitaoka 120a6e
  if (m_parent) m_parent->addRef();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TSoundTrack::~TSoundTrack() {
Shinya Kitaoka 120a6e
  if (m_parent) m_parent->release();
Shinya Kitaoka 120a6e
  // if (m_buffer && m_bufferOwner) delete [] m_buffer;
Shinya Kitaoka 120a6e
  if (m_buffer && m_bufferOwner) free(m_buffer);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TSoundTrackP TSoundTrack::create(TUINT32 sampleRate, int bitPerSample,
Shinya Kitaoka 120a6e
                                 int channelCount, TINT32 sampleCount,
justburner 9369f1
                                 int sampleType) {
justburner 9369f1
  TSoundTrackP st = 0;
Shinya Kitaoka 120a6e
  int type = bitPerSample + channelCount;
Shinya Kitaoka 120a6e
  switch (type) {
Shinya Kitaoka 120a6e
  case TRK_M8:
justburner 9369f1
    if (sampleType == TSound::INT)
Shinya Kitaoka 120a6e
      st = new TSoundTrackMono8Signed(sampleRate, channelCount, sampleCount);
justburner 9369f1
    else if (sampleType == TSound::UINT)
Shinya Kitaoka 120a6e
      st = new TSoundTrackMono8Unsigned(sampleRate, channelCount, sampleCount);
Shinya Kitaoka 120a6e
    break;
justburner 9369f1
Shinya Kitaoka 120a6e
  case TRK_S8:
justburner 9369f1
    if (sampleType == TSound::INT)
Shinya Kitaoka 120a6e
      st = new TSoundTrackStereo8Signed(sampleRate, channelCount, sampleCount);
justburner 9369f1
    else if (sampleType == TSound::UINT)
Shinya Kitaoka 120a6e
      st =
Shinya Kitaoka 120a6e
          new TSoundTrackStereo8Unsigned(sampleRate, channelCount, sampleCount);
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case TRK_M16:
justburner 9369f1
    if (sampleType == TSound::INT)
justburner 9369f1
      st = new TSoundTrackMono16(sampleRate, channelCount, sampleCount);
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case TRK_S16:
justburner 9369f1
    if (sampleType == TSound::INT)
justburner 9369f1
      st = new TSoundTrackStereo16(sampleRate, channelCount, sampleCount);
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case TRK_M24:
justburner 9369f1
    if (sampleType == TSound::INT)
justburner 9369f1
      st = new TSoundTrackMono24(sampleRate, channelCount, sampleCount);
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case TRK_S24:
justburner 9369f1
    if (sampleType == TSound::INT)
justburner 9369f1
      st = new TSoundTrackStereo24(sampleRate, channelCount, sampleCount);
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
justburner 9369f1
  case TRK_M32:
justburner 9369f1
    if (sampleType == TSound::FLOAT)
justburner 9369f1
      st = new TSoundTrackMono32Float(sampleRate, channelCount, sampleCount);
justburner 9369f1
    break;
justburner 9369f1
justburner 9369f1
  case TRK_S32:
justburner 9369f1
    if (sampleType == TSound::FLOAT)
justburner 9369f1
      st = new TSoundTrackStereo32Float(sampleRate, channelCount, sampleCount);
justburner 9369f1
    break;
justburner 9369f1
  }
justburner 9369f1
justburner 9369f1
  if (!st) {
Shinya Kitaoka 120a6e
    std::string s;
Shinya Kitaoka 120a6e
    s = "Type " + std::to_string(sampleRate) + " Hz " +
Shinya Kitaoka 120a6e
        std::to_string(bitPerSample) + " bits ";
Shinya Kitaoka 120a6e
    if (channelCount == 1)
Shinya Kitaoka 120a6e
      s += "mono: ";
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      s += "stereo: ";
Shinya Kitaoka 120a6e
    s += "Unsupported\n";
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    throw TException(s);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (!st->getRawData()) {
Shinya Kitaoka 120a6e
    return 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return st;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TSoundTrackP TSoundTrack::create(TUINT32 sampleRate, int bitPerSample,
Shinya Kitaoka 120a6e
                                 int channelCount, TINT32 sampleCount,
justburner 9369f1
                                 int sampleType, void *buffer) {
Shinya Kitaoka 120a6e
  TSoundTrackP st;
Shinya Kitaoka 120a6e
  int type = bitPerSample + channelCount;
Shinya Kitaoka 120a6e
  switch (type) {
Shinya Kitaoka 120a6e
  case TRK_M8:
justburner 9369f1
    if (sampleType == TSound::INT)
Shinya Kitaoka 120a6e
      st = new TSoundTrackMono8Signed(sampleRate, channelCount, sampleCount,
Shinya Kitaoka 120a6e
                                      (TMono8SignedSample *)buffer, 0);
justburner 9369f1
    else if (sampleType == TSound::UINT)
Shinya Kitaoka 120a6e
      st = new TSoundTrackMono8Unsigned(sampleRate, channelCount, sampleCount,
Shinya Kitaoka 120a6e
                                        (TMono8UnsignedSample *)buffer, 0);
Shinya Kitaoka 120a6e
    break;
justburner 9369f1
Shinya Kitaoka 120a6e
  case TRK_S8:
justburner 9369f1
    if (sampleType == TSound::INT)
Shinya Kitaoka 120a6e
      st = new TSoundTrackStereo8Signed(sampleRate, channelCount, sampleCount,
Shinya Kitaoka 120a6e
                                        (TStereo8SignedSample *)buffer, 0);
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      st = new TSoundTrackStereo8Unsigned(sampleRate, channelCount, sampleCount,
Shinya Kitaoka 120a6e
                                          (TStereo8UnsignedSample *)buffer, 0);
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case TRK_M16:
justburner 9369f1
    if (sampleType == TSound::INT)
justburner 9369f1
      st = new TSoundTrackMono16(sampleRate, channelCount, sampleCount,
justburner 9369f1
                                 (TMono16Sample *)buffer, 0);
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case TRK_S16:
justburner 9369f1
    if (sampleType == TSound::INT)
justburner 9369f1
      st = new TSoundTrackStereo16(sampleRate, channelCount, sampleCount,
justburner 9369f1
                                   (TStereo16Sample *)buffer, 0);
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case TRK_M24:
justburner 9369f1
    if (sampleType == TSound::INT)
justburner 9369f1
      st = new TSoundTrackMono24(sampleRate, channelCount, sampleCount,
justburner 9369f1
                                 (TMono24Sample *)buffer, 0);
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  case TRK_S24:
justburner 9369f1
    if (sampleType == TSound::INT)
justburner 9369f1
      st = new TSoundTrackStereo24(sampleRate, channelCount, sampleCount,
justburner 9369f1
                                   (TStereo24Sample *)buffer, 0);
justburner 9369f1
    break;
justburner 9369f1
justburner 9369f1
  case TRK_M32:
justburner 9369f1
    if (sampleType == TSound::FLOAT)
justburner 9369f1
      st = new TSoundTrackMono32Float(sampleRate, channelCount, sampleCount,
justburner 9369f1
                                      (TMono32FloatSample *)buffer, 0);
Shinya Kitaoka 120a6e
    break;
Shinya Kitaoka 120a6e
justburner 9369f1
  case TRK_S32:
justburner 9369f1
    if (sampleType == TSound::FLOAT)
justburner 9369f1
      st = new TSoundTrackStereo32Float(sampleRate, channelCount, sampleCount,
justburner 9369f1
                                        (TStereo32FloatSample *)buffer, 0);
justburner 9369f1
    break;
justburner 9369f1
  }
justburner 9369f1
justburner 9369f1
  if (!st) {
Shinya Kitaoka 120a6e
    std::string s;
Shinya Kitaoka 120a6e
    s = "Type " + std::to_string(sampleRate) + " Hz " +
Shinya Kitaoka 120a6e
        std::to_string(bitPerSample) + " bits ";
Shinya Kitaoka 120a6e
    if (channelCount == 1)
Shinya Kitaoka 120a6e
      s += "mono: ";
Shinya Kitaoka 120a6e
    else
Shinya Kitaoka 120a6e
      s += "stereo: ";
Shinya Kitaoka 120a6e
    s += "Unsupported\n";
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    throw TException(s);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return st;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TSoundTrackP TSoundTrack::create(const TSoundTrackFormat &format,
Shinya Kitaoka 120a6e
                                 TINT32 sampleCount, void *buffer) {
Shinya Kitaoka 120a6e
  return TSoundTrack::create((int)format.m_sampleRate, format.m_bitPerSample,
justburner 9369f1
                             format.m_channelCount, sampleCount,
justburner 9369f1
                             format.m_sampleType, buffer);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TSoundTrackP TSoundTrack::create(const TSoundTrackFormat &format,
Shinya Kitaoka 120a6e
                                 TINT32 sampleCount) {
Shinya Kitaoka 120a6e
  return TSoundTrack::create((int)format.m_sampleRate, format.m_bitPerSample,
Shinya Kitaoka 120a6e
                             format.m_channelCount, sampleCount,
justburner 9369f1
                             format.m_sampleType);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TINT32 TSoundTrack::secondsToSamples(double s) const {
Shinya Kitaoka 120a6e
  double dsamp = s * m_sampleRate;
Shinya Kitaoka 120a6e
  TINT32 lsamp = (TINT32)dsamp;
Shinya Kitaoka 120a6e
  if ((double)lsamp < dsamp - TConsts::epsilon) lsamp++;
Shinya Kitaoka 120a6e
  return lsamp;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double TSoundTrack::samplesToSeconds(TINT32 f) const {
Shinya Kitaoka 120a6e
  return f / (double)m_sampleRate;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TSoundTrackFormat::operator==(const TSoundTrackFormat &rhs) {
Shinya Kitaoka 120a6e
  return (m_sampleRate == rhs.m_sampleRate &&
Shinya Kitaoka 120a6e
          m_bitPerSample == rhs.m_bitPerSample &&
Shinya Kitaoka 120a6e
          m_channelCount == rhs.m_channelCount &&
justburner 9369f1
          m_sampleType == rhs.m_sampleType);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
bool TSoundTrackFormat::operator!=(const TSoundTrackFormat &rhs) {
Shinya Kitaoka 120a6e
  return !operator==(rhs);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==============================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double TSoundTrack::getDuration() const {
Shinya Kitaoka 120a6e
  return samplesToSeconds(m_sampleCount);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TSoundTrackFormat TSoundTrack::getFormat() const {
Shinya Kitaoka 120a6e
  return TSoundTrackFormat(getSampleRate(), getBitPerSample(),
justburner 9369f1
                           getChannelCount(), getSampleType());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TSoundTrackP TSoundTrack::extract(double t0, double t1) {
Shinya Kitaoka 120a6e
  return extract(secondsToSamples(t0), secondsToSamples(t1));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TSoundTrack::copy(const TSoundTrackP &src, double dst_t0) {
Shinya Kitaoka 120a6e
  copy(src, secondsToSamples(dst_t0));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TSoundTrack::blank(double t0, double t1) {
Shinya Kitaoka 120a6e
  blank(secondsToSamples(t0), secondsToSamples(t1));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double TSoundTrack::getPressure(double second, TSound::Channel chan) const {
Shinya Kitaoka 120a6e
  return getPressure(secondsToSamples(second), chan);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TSoundTrack::getMinMaxPressure(double t0, double t1, TSound::Channel chan,
Shinya Kitaoka 120a6e
                                    double &min, double &max) const {
Shinya Kitaoka 120a6e
  getMinMaxPressure(secondsToSamples(t0), secondsToSamples(t1), chan, min, max);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void TSoundTrack::getMinMaxPressure(TSound::Channel chan, double &min,
Shinya Kitaoka 120a6e
                                    double &max) const {
Shinya Kitaoka 120a6e
  getMinMaxPressure(0, (TINT32)(getSampleCount() - 1), chan, min, max);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double TSoundTrack::getMaxPressure(double t0, double t1,
Shinya Kitaoka 120a6e
                                   TSound::Channel chan) const {
Shinya Kitaoka 120a6e
  return getMaxPressure(secondsToSamples(t0), secondsToSamples(t1), chan);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double TSoundTrack::getMaxPressure(TSound::Channel chan) const {
Shinya Kitaoka 120a6e
  return getMaxPressure(0, (TINT32)(getSampleCount() - 1), chan);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double TSoundTrack::getMinPressure(double t0, double t1,
Shinya Kitaoka 120a6e
                                   TSound::Channel chan) const {
Shinya Kitaoka 120a6e
  return getMinPressure(secondsToSamples(t0), secondsToSamples(t1), chan);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double TSoundTrack::getMinPressure(TSound::Channel chan) const {
Shinya Kitaoka 120a6e
  return getMinPressure(0, (TINT32)(getSampleCount() - 1), chan);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//------------------------------------------------------------------------------