|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Campbell Barton |
40cabe |
#include <cstring></cstring>
|
|
Campbell Barton |
40cabe |
|
|
Toshihiro Shimizu |
890ddd |
#include "tsop.h"
|
|
Toshihiro Shimizu |
890ddd |
#include "tsound_t.h"
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// TRop::ResampleFilterType Tau_resample_filter = Hamming3;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
typedef enum {
|
|
Shinya Kitaoka |
120a6e |
FLT_NONE,
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
FLT_TRIANGLE, /* triangle filter */
|
|
Shinya Kitaoka |
120a6e |
FLT_MITCHELL, /* Mitchell-Netravali filter */
|
|
Shinya Kitaoka |
120a6e |
FLT_CUBIC_5, /* cubic convolution, a = .5 */
|
|
Shinya Kitaoka |
120a6e |
FLT_CUBIC_75, /* cubic convolution, a = .75 */
|
|
Shinya Kitaoka |
120a6e |
FLT_CUBIC_1, /* cubic convolution, a = 1 */
|
|
Shinya Kitaoka |
120a6e |
FLT_HANN2, /* Hann window, rad = 2 */
|
|
Shinya Kitaoka |
120a6e |
FLT_HANN3, /* Hann window, rad = 3 */
|
|
Shinya Kitaoka |
120a6e |
FLT_HAMMING2, /* Hamming window, rad = 2 */
|
|
Shinya Kitaoka |
120a6e |
FLT_HAMMING3, /* Hamming window, rad = 3 */
|
|
Shinya Kitaoka |
120a6e |
FLT_LANCZOS2, /* Lanczos window, rad = 2 */
|
|
Shinya Kitaoka |
120a6e |
FLT_LANCZOS3, /* Lanczos window, rad = 3 */
|
|
Shinya Kitaoka |
120a6e |
FLT_GAUSS, /* Gaussian convolution */
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
FLT_HOW_MANY
|
|
Toshihiro Shimizu |
890ddd |
} FLT_TYPE;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
typedef enum {
|
|
Shinya Kitaoka |
120a6e |
RESORDER_NONE,
|
|
Shinya Kitaoka |
120a6e |
RESORDER_BITS_RATE_CHANS,
|
|
Shinya Kitaoka |
120a6e |
RESORDER_CHANS_RATE_BITS,
|
|
Shinya Kitaoka |
120a6e |
RESORDER_RATE_BITS_CHANS,
|
|
Shinya Kitaoka |
120a6e |
RESORDER_CHANS_BITS_RATE,
|
|
Shinya Kitaoka |
120a6e |
RESORDER_BITS_RATE,
|
|
Shinya Kitaoka |
120a6e |
RESORDER_RATE_BITS,
|
|
Shinya Kitaoka |
120a6e |
RESORDER_CHANS_RATE,
|
|
Shinya Kitaoka |
120a6e |
RESORDER_RATE_CHANS,
|
|
Shinya Kitaoka |
120a6e |
RESORDER_RATE,
|
|
Shinya Kitaoka |
120a6e |
RESORDER_SIGN,
|
|
Shinya Kitaoka |
120a6e |
RESORDER_HOW_MANY
|
|
Toshihiro Shimizu |
890ddd |
} RESORDER_TYPE;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
typedef struct {
|
|
Shinya Kitaoka |
120a6e |
int src_offset; /* of weight[0] relative to start of period */
|
|
Shinya Kitaoka |
120a6e |
int n_weights;
|
|
Shinya Kitaoka |
120a6e |
double *weight; /* [n_weights], -1.0 <= weight <= 1.0 */
|
|
Toshihiro Shimizu |
890ddd |
} WEIGHTSET;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
typedef struct {
|
|
Shinya Kitaoka |
120a6e |
int src_period; /* after a period src and dst are in step again */
|
|
Shinya Kitaoka |
120a6e |
int dst_period;
|
|
Shinya Kitaoka |
120a6e |
WEIGHTSET *weightset; /* [dst_period] */
|
|
Toshihiro Shimizu |
890ddd |
} FILTER;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
ee259f |
#define M_PIF float(M_PI)
|
|
Shinya Kitaoka |
ee259f |
#define SINC0(x, a) (sin((M_PI / (a)) * (x)) / ((M_PI / (a)) * (x)))
|
|
Toshihiro Shimizu |
890ddd |
#define SINC0F(x, a) (sinf((M_PIF / (a)) * (x)) / ((M_PIF / (a)) * (x)))
|
|
Toshihiro Shimizu |
890ddd |
#define SINC(x, a) ((x) == 0.0 ? 1.0 : SINC0(x, a))
|
|
Toshihiro Shimizu |
890ddd |
#define SINCF(x, a) ((x) == 0.0F ? 1.0F : SINC0F(x, a))
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#define FULL_INT_MUL_DIV(X, Y, Z) ((int)(((double)(X) * (Y) + ((Z)-1)) / (Z)))
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// prototipi
|
|
Toshihiro Shimizu |
890ddd |
void convert(TSoundTrackP &dst, const TSoundTrackP &src);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void simplifyRatio(int *p_a, int *p_b) {
|
|
Shinya Kitaoka |
120a6e |
int a = *p_a, b = *p_b;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (a != b)
|
|
Shinya Kitaoka |
120a6e |
if (a > b)
|
|
Shinya Kitaoka |
120a6e |
a -= b;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
b -= a;
|
|
Shinya Kitaoka |
120a6e |
if (a != 1) {
|
|
Shinya Kitaoka |
120a6e |
*p_a /= a;
|
|
Shinya Kitaoka |
120a6e |
*p_b /= a;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
int getFilterRadius(FLT_TYPE flt_type) {
|
|
Shinya Kitaoka |
120a6e |
int result = 0;
|
|
Shinya Kitaoka |
120a6e |
switch (flt_type) {
|
|
Shinya Kitaoka |
120a6e |
case FLT_TRIANGLE:
|
|
Shinya Kitaoka |
120a6e |
result = 1;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case FLT_MITCHELL:
|
|
Shinya Kitaoka |
120a6e |
result = 2;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case FLT_CUBIC_5:
|
|
Shinya Kitaoka |
120a6e |
result = 2;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case FLT_CUBIC_75:
|
|
Shinya Kitaoka |
120a6e |
result = 2;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case FLT_CUBIC_1:
|
|
Shinya Kitaoka |
120a6e |
result = 2;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case FLT_HANN2:
|
|
Shinya Kitaoka |
120a6e |
result = 2;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case FLT_HANN3:
|
|
Shinya Kitaoka |
120a6e |
result = 3;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case FLT_HAMMING2:
|
|
Shinya Kitaoka |
120a6e |
result = 2;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case FLT_HAMMING3:
|
|
Shinya Kitaoka |
120a6e |
result = 3;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case FLT_LANCZOS2:
|
|
Shinya Kitaoka |
120a6e |
result = 2;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case FLT_LANCZOS3:
|
|
Shinya Kitaoka |
120a6e |
result = 3;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
case FLT_GAUSS:
|
|
Shinya Kitaoka |
120a6e |
result = 2;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
default:
|
|
Shinya Kitaoka |
120a6e |
assert(!"bad filter type");
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return result;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
double filterValue(FLT_TYPE flt_type, double x) {
|
|
Shinya Kitaoka |
120a6e |
if (!x) return 1.0;
|
|
Shinya Kitaoka |
120a6e |
double result;
|
|
Shinya Kitaoka |
120a6e |
switch (flt_type) {
|
|
Shinya Kitaoka |
120a6e |
case FLT_TRIANGLE:
|
|
Shinya Kitaoka |
120a6e |
if (x < -1.0)
|
|
Shinya Kitaoka |
120a6e |
result = 0.0;
|
|
Shinya Kitaoka |
120a6e |
else if (x < 0.0)
|
|
Shinya Kitaoka |
120a6e |
result = 1.0 + x;
|
|
Shinya Kitaoka |
120a6e |
else if (x < 1.0)
|
|
Shinya Kitaoka |
120a6e |
result = 1.0 - x;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
result = 0.0;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case FLT_MITCHELL: {
|
|
Shinya Kitaoka |
120a6e |
static double p0, p2, p3, q0, q1, q2, q3;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!p0) {
|
|
Shinya Kitaoka |
120a6e |
const double b = 1.0 / 3.0;
|
|
Shinya Kitaoka |
120a6e |
const double c = 1.0 / 3.0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
p0 = (6.0 - 2.0 * b) / 6.0;
|
|
Shinya Kitaoka |
120a6e |
p2 = (-18.0 + 12.0 * b + 6.0 * c) / 6.0;
|
|
Shinya Kitaoka |
120a6e |
p3 = (12.0 - 9.0 * b - 6.0 * c) / 6.0;
|
|
Shinya Kitaoka |
120a6e |
q0 = (8.0 * b + 24.0 * c) / 6.0;
|
|
Shinya Kitaoka |
120a6e |
q1 = (-12.0 * b - 48.0 * c) / 6.0;
|
|
Shinya Kitaoka |
120a6e |
q2 = (6.0 * b + 30.0 * c) / 6.0;
|
|
Shinya Kitaoka |
120a6e |
q3 = (-b - 6.0 * c) / 6.0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
if (x < -2.0)
|
|
Shinya Kitaoka |
120a6e |
result = 0.0;
|
|
Shinya Kitaoka |
120a6e |
else if (x < -1.0)
|
|
Shinya Kitaoka |
120a6e |
result = (q0 - x * (q1 - x * (q2 - x * q3)));
|
|
Shinya Kitaoka |
120a6e |
else if (x < 0.0)
|
|
Shinya Kitaoka |
120a6e |
result = (p0 + x * x * (p2 - x * p3));
|
|
Shinya Kitaoka |
120a6e |
else if (x < 1.0)
|
|
Shinya Kitaoka |
120a6e |
result = (p0 + x * x * (p2 + x * p3));
|
|
Shinya Kitaoka |
120a6e |
else if (x < 2.0)
|
|
Shinya Kitaoka |
120a6e |
result = (q0 + x * (q1 + x * (q2 + x * q3)));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case FLT_CUBIC_5:
|
|
Shinya Kitaoka |
120a6e |
if (x < 0.0)
|
|
Shinya Kitaoka |
120a6e |
x = -x;
|
|
Shinya Kitaoka |
120a6e |
else if (x < 1.0)
|
|
Shinya Kitaoka |
120a6e |
result = 2.5 * x * x * x - 3.5 * x * x + 1;
|
|
Shinya Kitaoka |
120a6e |
else if (x < 2.0)
|
|
Shinya Kitaoka |
120a6e |
result = 0.5 * x * x * x - 2.5 * x * x + 4 * x - 2;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case FLT_CUBIC_75:
|
|
Shinya Kitaoka |
120a6e |
if (x < 0.0)
|
|
Shinya Kitaoka |
120a6e |
x = -x;
|
|
Shinya Kitaoka |
120a6e |
else if (x < 1.0)
|
|
Shinya Kitaoka |
120a6e |
result = 2.75 * x * x * x - 3.75 * x * x + 1;
|
|
Shinya Kitaoka |
120a6e |
else if (x < 2.0)
|
|
Shinya Kitaoka |
120a6e |
result = 0.75 * x * x * x - 3.75 * x * x + 6 * x - 3;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case FLT_CUBIC_1:
|
|
Shinya Kitaoka |
120a6e |
if (x < 0.0)
|
|
Shinya Kitaoka |
120a6e |
x = -x;
|
|
Shinya Kitaoka |
120a6e |
else if (x < 1.0)
|
|
Shinya Kitaoka |
120a6e |
result = 3 * x * x * x - 4 * x * x + 1;
|
|
Shinya Kitaoka |
120a6e |
else if (x < 2.0)
|
|
Shinya Kitaoka |
120a6e |
result = x * x * x - 5 * x * x + 8 * x - 4;
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case FLT_HANN2:
|
|
Shinya Kitaoka |
120a6e |
if (x <= -2.0)
|
|
Shinya Kitaoka |
120a6e |
result = 0.0;
|
|
Shinya Kitaoka |
120a6e |
else if (x < 2.0)
|
|
Shinya Kitaoka |
120a6e |
result = SINC0(x, 1) * (0.5 + 0.5 * cos(M_PI_2 * x));
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case FLT_HANN3:
|
|
Shinya Kitaoka |
120a6e |
if (x <= -3.0)
|
|
Shinya Kitaoka |
120a6e |
result = 0.0;
|
|
Shinya Kitaoka |
120a6e |
else if (x < 3.0)
|
|
Shinya Kitaoka |
120a6e |
result = SINC0(x, 1) * (0.5 + 0.5 * cos((M_PI / 3) * x));
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case FLT_HAMMING2:
|
|
Shinya Kitaoka |
120a6e |
if (x <= -2.0)
|
|
Shinya Kitaoka |
120a6e |
result = 0.0;
|
|
Shinya Kitaoka |
120a6e |
else if (x < 2.0)
|
|
Shinya Kitaoka |
120a6e |
result = SINC0(x, 1) * (0.54 + 0.46 * cos(M_PI_2 * x));
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case FLT_HAMMING3:
|
|
Shinya Kitaoka |
120a6e |
if (x <= -3.0)
|
|
Shinya Kitaoka |
120a6e |
result = 0.0;
|
|
Shinya Kitaoka |
120a6e |
else if (x < 3.0)
|
|
Shinya Kitaoka |
120a6e |
result = SINC0(x, 1) * (0.54 + 0.46 * cos((M_PI / 3) * x));
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case FLT_LANCZOS2:
|
|
Shinya Kitaoka |
120a6e |
if (x <= -2.0)
|
|
Shinya Kitaoka |
120a6e |
result = 0.0;
|
|
Shinya Kitaoka |
120a6e |
else if (x < 2.0)
|
|
Shinya Kitaoka |
120a6e |
result = SINC0(x, 1) * SINC0(x, 2);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case FLT_LANCZOS3:
|
|
Shinya Kitaoka |
120a6e |
if (x <= -3.0)
|
|
Shinya Kitaoka |
120a6e |
result = 0.0;
|
|
Shinya Kitaoka |
120a6e |
else if (x < 3.0)
|
|
Shinya Kitaoka |
120a6e |
result = SINC0(x, 1) * SINC0(x, 3);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case FLT_GAUSS:
|
|
Shinya Kitaoka |
120a6e |
if (x <= -2.0)
|
|
Shinya Kitaoka |
120a6e |
result = 0.0;
|
|
Shinya Kitaoka |
120a6e |
else if (x < 2.0)
|
|
Shinya Kitaoka |
120a6e |
result = exp((-M_PI) * x * x);
|
|
Shinya Kitaoka |
120a6e |
/* exp(-M_PI*2*2)~=3.5*10^-6 */
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
default:
|
|
Shinya Kitaoka |
120a6e |
assert(!"bad filter type");
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
return result;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//---------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class class="" t1,="" t2=""></class>
|
|
Shinya Kitaoka |
120a6e |
void convertSamplesT(TSoundTrackT<t1> &dst, const TSoundTrackT<t2> &src) {</t2></t1>
|
|
Shinya Kitaoka |
120a6e |
const T2 *srcSample = src.samples();
|
|
Shinya Kitaoka |
120a6e |
T1 *dstSample = dst.samples();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const T2 *srcEndSample =
|
|
Shinya Kitaoka |
120a6e |
srcSample + std::min(src.getSampleCount(), dst.getSampleCount());
|
|
Shinya Kitaoka |
120a6e |
while (srcSample < srcEndSample) {
|
|
Shinya Kitaoka |
120a6e |
*dstSample = T1::from(*srcSample);
|
|
Shinya Kitaoka |
120a6e |
++dstSample;
|
|
Shinya Kitaoka |
120a6e |
++srcSample;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
T *resampleT(T &src, TINT32 sampleRate, FLT_TYPE flt_type) {
|
|
Shinya Kitaoka |
120a6e |
typedef typename T::SampleType SampleType;
|
|
Shinya Kitaoka |
120a6e |
typedef typename T::SampleType::ChannelValueType ChannelValueType;
|
|
Shinya Kitaoka |
120a6e |
T *dst = new TSoundTrackT<sampletype>(</sampletype>
|
|
Shinya Kitaoka |
120a6e |
sampleRate, src.getChannelCount(),
|
|
Shinya Kitaoka |
120a6e |
(TINT32)(src.getSampleCount() *
|
|
Shinya Kitaoka |
120a6e |
(sampleRate / (double)src.getSampleRate())));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double src_rad, f, src_f0, src_to_f;
|
|
Shinya Kitaoka |
120a6e |
double weight, weightsum;
|
|
Shinya Kitaoka |
120a6e |
int iw, is, s0, ip, first, last;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
FILTER filter;
|
|
Shinya Kitaoka |
120a6e |
filter.src_period = (int)src.getSampleRate();
|
|
Shinya Kitaoka |
120a6e |
filter.dst_period = (int)dst->getSampleRate();
|
|
Shinya Kitaoka |
120a6e |
simplifyRatio(&filter.src_period, &filter.dst_period);
|
|
Shinya Kitaoka |
120a6e |
filter.weightset = new WEIGHTSET[filter.dst_period];
|
|
Shinya Kitaoka |
120a6e |
if (!filter.weightset) return 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int flt_rad = getFilterRadius(flt_type);
|
|
Shinya Kitaoka |
120a6e |
double dstRate = (double)dst->getSampleRate();
|
|
Shinya Kitaoka |
120a6e |
double srcRate = (double)src.getSampleRate();
|
|
Shinya Kitaoka |
120a6e |
double dst_to_src = srcRate / dstRate;
|
|
Shinya Kitaoka |
120a6e |
if (srcRate > dstRate) {
|
|
Shinya Kitaoka |
120a6e |
src_rad = flt_rad * dst_to_src;
|
|
Shinya Kitaoka |
120a6e |
src_to_f = dstRate / srcRate;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
src_rad = flt_rad;
|
|
Shinya Kitaoka |
120a6e |
src_to_f = 1.0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (ip = 0; ip < filter.dst_period; ip++) {
|
|
Shinya Kitaoka |
120a6e |
src_f0 = ip * dst_to_src;
|
|
Shinya Kitaoka |
120a6e |
if (ip == 0 && srcRate < dstRate)
|
|
Shinya Kitaoka |
120a6e |
first = last = 0;
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
first = intGT(src_f0 - src_rad);
|
|
Shinya Kitaoka |
120a6e |
last = intLT(src_f0 + src_rad);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
filter.weightset[ip].src_offset = first;
|
|
Shinya Kitaoka |
120a6e |
filter.weightset[ip].n_weights = last - first + 1;
|
|
Shinya Kitaoka |
120a6e |
filter.weightset[ip].weight = new double[filter.weightset[ip].n_weights];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!filter.weightset[ip].weight) return 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
weightsum = 0.0;
|
|
Shinya Kitaoka |
120a6e |
for (is = first; is <= last; is++) {
|
|
Shinya Kitaoka |
120a6e |
f = (is - src_f0) * src_to_f;
|
|
Shinya Kitaoka |
120a6e |
weight = filterValue(flt_type, f);
|
|
Shinya Kitaoka |
120a6e |
filter.weightset[ip].weight[is - first] = weight;
|
|
Shinya Kitaoka |
120a6e |
weightsum += weight;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
assert(weightsum);
|
|
Shinya Kitaoka |
120a6e |
for (is = first; is <= last; is++)
|
|
Shinya Kitaoka |
120a6e |
filter.weightset[ip].weight[is - first] /= weightsum;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ip = 0;
|
|
Shinya Kitaoka |
120a6e |
s0 = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (TINT32 id = 0; id < dst->getSampleCount(); id++) {
|
|
Shinya Kitaoka |
120a6e |
SampleType dstSample;
|
|
Shinya Kitaoka |
120a6e |
SampleType srcSample;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
is = s0 + filter.weightset[ip].src_offset;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int iwFirst, iwLast;
|
|
Shinya Kitaoka |
120a6e |
if (is > 0) {
|
|
Shinya Kitaoka |
120a6e |
iwFirst = 0;
|
|
Shinya Kitaoka |
120a6e |
iwLast = std::min<int>(filter.weightset[ip].n_weights,</int>
|
|
Shinya Kitaoka |
120a6e |
src.getSampleCount() - is);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
iwFirst = -is;
|
|
Shinya Kitaoka |
120a6e |
is = 0;
|
|
Shinya Kitaoka |
120a6e |
iwLast =
|
|
Shinya Kitaoka |
120a6e |
std::min<int>(filter.weightset[ip].n_weights, src.getSampleCount());</int>
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double dstChannel[2];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
dstChannel[0] = 0;
|
|
Shinya Kitaoka |
120a6e |
dstChannel[1] = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
dstSample = SampleType();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (iw = iwFirst; iw < iwLast; iw++, is++) {
|
|
Shinya Kitaoka |
120a6e |
weight = filter.weightset[ip].weight[iw];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
srcSample = *(src.samples() + is);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
T::SampleType tmp = srcSample*weight;
|
|
Shinya Kitaoka |
120a6e |
dstSample += tmp;
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < src.getChannelCount(); i++)
|
|
Shinya Kitaoka |
120a6e |
dstChannel[i] += (double)(srcSample.getValue(i) * weight);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// assert(dstSample.getValue(0) == dstChannel[0]);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (int i = 0; i < src.getChannelCount(); i++)
|
|
Shinya Kitaoka |
120a6e |
dstSample.setValue(i, (ChannelValueType)(tround(dstChannel[i])));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
*(dst->samples() + id) = dstSample;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ip++;
|
|
Shinya Kitaoka |
120a6e |
if (ip == filter.dst_period) {
|
|
Shinya Kitaoka |
120a6e |
ip = 0;
|
|
Shinya Kitaoka |
120a6e |
s0 += filter.src_period;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
for (ip = 0; ip < filter.dst_period; ip++)
|
|
Shinya Kitaoka |
120a6e |
delete[] filter.weightset[ip].weight;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
delete[] filter.weightset;
|
|
Shinya Kitaoka |
120a6e |
return dst;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class TSoundTrackResample final : public TSoundTransform {
|
|
Shinya Kitaoka |
120a6e |
TINT32 m_sampleRate;
|
|
Shinya Kitaoka |
120a6e |
FLT_TYPE m_filterType;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackResample(TINT32 sampleRate, FLT_TYPE filterType)
|
|
Shinya Kitaoka |
120a6e |
: TSoundTransform(), m_sampleRate(sampleRate), m_filterType(filterType) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
~TSoundTrackResample(){};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono8Signed &src) override {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackMono8Signed *dst = resampleT(
|
|
Shinya Kitaoka |
120a6e |
const_cast<tsoundtrackmono8signed &="">(src), m_sampleRate, m_filterType);</tsoundtrackmono8signed>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return TSoundTrackP(dst);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono8Unsigned &src) override {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackMono8Unsigned *dst =
|
|
Shinya Kitaoka |
120a6e |
resampleT(const_cast<tsoundtrackmono8unsigned &="">(src), m_sampleRate,</tsoundtrackmono8unsigned>
|
|
Shinya Kitaoka |
120a6e |
m_filterType);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return TSoundTrackP(dst);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo8Signed &src) override {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackStereo8Signed *dst =
|
|
Shinya Kitaoka |
120a6e |
resampleT(const_cast<tsoundtrackstereo8signed &="">(src), m_sampleRate,</tsoundtrackstereo8signed>
|
|
Shinya Kitaoka |
120a6e |
m_filterType);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return TSoundTrackP(dst);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo8Unsigned &src) override {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackStereo8Unsigned *dst =
|
|
Shinya Kitaoka |
120a6e |
resampleT(const_cast<tsoundtrackstereo8unsigned &="">(src), m_sampleRate,</tsoundtrackstereo8unsigned>
|
|
Shinya Kitaoka |
120a6e |
m_filterType);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return TSoundTrackP(dst);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono16 &src) override {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackMono16 *dst = resampleT(const_cast<tsoundtrackmono16 &="">(src),</tsoundtrackmono16>
|
|
Shinya Kitaoka |
120a6e |
m_sampleRate, m_filterType);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return TSoundTrackP(dst);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo16 &src) override {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackStereo16 *dst = resampleT(const_cast<tsoundtrackstereo16 &="">(src),</tsoundtrackstereo16>
|
|
Shinya Kitaoka |
120a6e |
m_sampleRate, m_filterType);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return TSoundTrackP(dst);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono24 &src) override {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackMono24 *dst = resampleT(const_cast<tsoundtrackmono24 &="">(src),</tsoundtrackmono24>
|
|
Shinya Kitaoka |
120a6e |
m_sampleRate, m_filterType);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return TSoundTrackP(dst);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo24 &src) override {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackStereo24 *dst = resampleT(const_cast<tsoundtrackstereo24 &="">(src),</tsoundtrackstereo24>
|
|
Shinya Kitaoka |
120a6e |
m_sampleRate, m_filterType);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return TSoundTrackP(dst);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSop::resample(TSoundTrackP src, TINT32 sampleRate) {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackResample *resample =
|
|
Shinya Kitaoka |
120a6e |
new TSoundTrackResample(sampleRate, FLT_HAMMING3);
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP dst = src->apply(resample);
|
|
Shinya Kitaoka |
120a6e |
delete resample;
|
|
Shinya Kitaoka |
120a6e |
return dst;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class src=""></class>
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP doConvertWithoutResamplingT(SRC *src,
|
|
Shinya Kitaoka |
120a6e |
const TSoundTrackFormat &dstFormat) {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP dst = TSoundTrack::create(dstFormat, src->getSampleCount());
|
|
Shinya Kitaoka |
120a6e |
if (!dst) return 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackMono8Unsigned *dstM8U =
|
|
Shinya Kitaoka |
120a6e |
dynamic_cast<tsoundtrackmono8unsigned *="">(dst.getPointer());</tsoundtrackmono8unsigned>
|
|
Shinya Kitaoka |
120a6e |
if (dstM8U) {
|
|
Shinya Kitaoka |
120a6e |
convertSamplesT(*dstM8U, *src);
|
|
Shinya Kitaoka |
120a6e |
return dstM8U;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackMono8Signed *dstM8S =
|
|
Shinya Kitaoka |
120a6e |
dynamic_cast<tsoundtrackmono8signed *="">(dst.getPointer());</tsoundtrackmono8signed>
|
|
Shinya Kitaoka |
120a6e |
if (dstM8S) {
|
|
Shinya Kitaoka |
120a6e |
convertSamplesT(*dstM8S, *src);
|
|
Shinya Kitaoka |
120a6e |
return dstM8S;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackStereo8Signed *dstS8S =
|
|
Shinya Kitaoka |
120a6e |
dynamic_cast<tsoundtrackstereo8signed *="">(dst.getPointer());</tsoundtrackstereo8signed>
|
|
Shinya Kitaoka |
120a6e |
if (dstS8S) {
|
|
Shinya Kitaoka |
120a6e |
convertSamplesT(*dstS8S, *src);
|
|
Shinya Kitaoka |
120a6e |
return dstS8S;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackStereo8Unsigned *dstS8U =
|
|
Shinya Kitaoka |
120a6e |
dynamic_cast<tsoundtrackstereo8unsigned *="">(dst.getPointer());</tsoundtrackstereo8unsigned>
|
|
Shinya Kitaoka |
120a6e |
if (dstS8U) {
|
|
Shinya Kitaoka |
120a6e |
convertSamplesT(*dstS8U, *src);
|
|
Shinya Kitaoka |
120a6e |
return dstS8U;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackMono16 *dstM16 =
|
|
Shinya Kitaoka |
120a6e |
dynamic_cast<tsoundtrackmono16 *="">(dst.getPointer());</tsoundtrackmono16>
|
|
Shinya Kitaoka |
120a6e |
if (dstM16) {
|
|
Shinya Kitaoka |
120a6e |
convertSamplesT(*dstM16, *src);
|
|
Shinya Kitaoka |
120a6e |
return dstM16;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackStereo16 *dstS16 =
|
|
Shinya Kitaoka |
120a6e |
dynamic_cast<tsoundtrackstereo16 *="">(dst.getPointer());</tsoundtrackstereo16>
|
|
Shinya Kitaoka |
120a6e |
if (dstS16) {
|
|
Shinya Kitaoka |
120a6e |
convertSamplesT(*dstS16, *src);
|
|
Shinya Kitaoka |
120a6e |
return dstS16;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackMono24 *dstM24 =
|
|
Shinya Kitaoka |
120a6e |
dynamic_cast<tsoundtrackmono24 *="">(dst.getPointer());</tsoundtrackmono24>
|
|
Shinya Kitaoka |
120a6e |
if (dstM24) {
|
|
Shinya Kitaoka |
120a6e |
convertSamplesT(*dstM24, *src);
|
|
Shinya Kitaoka |
120a6e |
return dstM24;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackStereo24 *dstS24 =
|
|
Shinya Kitaoka |
120a6e |
dynamic_cast<tsoundtrackstereo24 *="">(dst.getPointer());</tsoundtrackstereo24>
|
|
Shinya Kitaoka |
120a6e |
if (dstS24) {
|
|
Shinya Kitaoka |
120a6e |
convertSamplesT(*dstS24, *src);
|
|
Shinya Kitaoka |
120a6e |
return dstS24;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return 0;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class TSoundTrackConverterWithoutResampling final : public TSoundTransform {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackFormat m_format;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackConverterWithoutResampling(const TSoundTrackFormat &format)
|
|
Shinya Kitaoka |
120a6e |
: m_format(format) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
~TSoundTrackConverterWithoutResampling(){};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono8Signed &src) override {
|
|
Shinya Kitaoka |
120a6e |
return doConvertWithoutResamplingT(&src, m_format);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono8Unsigned &src) override {
|
|
Shinya Kitaoka |
120a6e |
return doConvertWithoutResamplingT(&src, m_format);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo8Signed &src) override {
|
|
Shinya Kitaoka |
120a6e |
return doConvertWithoutResamplingT(&src, m_format);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo8Unsigned &src) override {
|
|
Shinya Kitaoka |
120a6e |
return doConvertWithoutResamplingT(&src, m_format);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono16 &src) override {
|
|
Shinya Kitaoka |
120a6e |
return doConvertWithoutResamplingT(&src, m_format);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo16 &src) override {
|
|
Shinya Kitaoka |
120a6e |
return doConvertWithoutResamplingT(&src, m_format);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono24 &src) override {
|
|
Shinya Kitaoka |
120a6e |
return doConvertWithoutResamplingT(&src, m_format);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo24 &src) override {
|
|
Shinya Kitaoka |
120a6e |
return doConvertWithoutResamplingT(&src, m_format);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Shinya Kitaoka |
120a6e |
namespace {
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void convertWithoutResampling(TSoundTrackP &dst, const TSoundTrackP &src) {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackConverterWithoutResampling *converter;
|
|
Shinya Kitaoka |
120a6e |
converter = new TSoundTrackConverterWithoutResampling(dst->getFormat());
|
|
Shinya Kitaoka |
120a6e |
dst = src->apply(converter);
|
|
Shinya Kitaoka |
120a6e |
delete converter;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
} // namespace
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSop::convert(const TSoundTrackP &src,
|
|
Shinya Kitaoka |
120a6e |
const TSoundTrackFormat &dstFormat) {
|
|
Shinya Kitaoka |
120a6e |
TINT32 dstSampleCount =
|
|
Shinya Kitaoka |
120a6e |
(TINT32)(src->getSampleCount() *
|
|
Shinya Kitaoka |
120a6e |
(dstFormat.m_sampleRate / (double)src->getSampleRate()));
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP dst = TSoundTrack::create(dstFormat, dstSampleCount);
|
|
Shinya Kitaoka |
120a6e |
TSop::convert(dst, src);
|
|
Shinya Kitaoka |
120a6e |
return dst;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TSop::convert(TSoundTrackP &dst, const TSoundTrackP &src) {
|
|
Shinya Kitaoka |
120a6e |
int src_reslen, dst_reslen;
|
|
Shinya Kitaoka |
120a6e |
int src_bits, dst_bits;
|
|
Shinya Kitaoka |
120a6e |
int src_chans, dst_chans;
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP tmp, tmq;
|
|
Shinya Kitaoka |
120a6e |
RESORDER_TYPE order;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
assert(src->getSampleCount() >= 0 && dst->getSampleCount() >= 0);
|
|
Shinya Kitaoka |
120a6e |
if (!dst->getSampleCount()) return;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (!src->getSampleCount()) {
|
|
Shinya Kitaoka |
120a6e |
dst->blank(0L, (TINT32)(dst->getSampleCount() - 1));
|
|
Shinya Kitaoka |
120a6e |
return;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (src->getSampleRate() == dst->getSampleRate()) {
|
|
Shinya Kitaoka |
120a6e |
src_reslen = dst->getSampleCount();
|
|
Shinya Kitaoka |
120a6e |
notMoreThan((int)src->getSampleCount(), src_reslen);
|
|
Shinya Kitaoka |
120a6e |
dst_reslen = src_reslen;
|
|
Shinya Kitaoka |
120a6e |
convertWithoutResampling(dst, src);
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
src_reslen = FULL_INT_MUL_DIV(dst->getSampleCount(), src->getSampleRate(),
|
|
Shinya Kitaoka |
120a6e |
dst->getSampleRate());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (src_reslen > src->getSampleCount()) {
|
|
Shinya Kitaoka |
120a6e |
src_reslen = src->getSampleCount();
|
|
Shinya Kitaoka |
120a6e |
dst_reslen = FULL_INT_MUL_DIV(src_reslen, dst->getSampleRate(),
|
|
Shinya Kitaoka |
120a6e |
src->getSampleRate());
|
|
Shinya Kitaoka |
120a6e |
} else
|
|
Shinya Kitaoka |
120a6e |
dst_reslen = dst->getSampleCount();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
src_chans = src->getChannelCount();
|
|
Shinya Kitaoka |
120a6e |
dst_chans = dst->getChannelCount();
|
|
Shinya Kitaoka |
120a6e |
src_bits = src->getBitPerSample();
|
|
Shinya Kitaoka |
120a6e |
dst_bits = dst->getBitPerSample();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (src_chans == dst_chans && src_bits == dst_bits)
|
|
Shinya Kitaoka |
120a6e |
if (src->isSampleSigned() == dst->isSampleSigned())
|
|
Shinya Kitaoka |
120a6e |
order = RESORDER_RATE;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
order = RESORDER_SIGN;
|
|
Shinya Kitaoka |
120a6e |
else if (src_chans < dst_chans) {
|
|
Shinya Kitaoka |
120a6e |
if (src_bits < dst_bits)
|
|
Shinya Kitaoka |
120a6e |
order = RESORDER_BITS_RATE_CHANS;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
order = RESORDER_RATE_BITS_CHANS;
|
|
Shinya Kitaoka |
120a6e |
} else if (src_chans > dst_chans) {
|
|
Shinya Kitaoka |
120a6e |
if (src_bits > dst_bits)
|
|
Shinya Kitaoka |
120a6e |
order = RESORDER_CHANS_RATE_BITS;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
order = RESORDER_CHANS_BITS_RATE;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
if (src_bits > dst_bits)
|
|
Shinya Kitaoka |
120a6e |
order = RESORDER_RATE_BITS;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
order = RESORDER_BITS_RATE;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
switch (order) {
|
|
Shinya Kitaoka |
120a6e |
case RESORDER_CHANS_RATE_BITS:
|
|
Shinya Kitaoka |
120a6e |
case RESORDER_BITS_RATE_CHANS:
|
|
Shinya Kitaoka |
120a6e |
int chans, bitPerSample;
|
|
Shinya Kitaoka |
120a6e |
if (src->getChannelCount() <= dst->getChannelCount())
|
|
Shinya Kitaoka |
120a6e |
chans = src->getChannelCount();
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
chans = dst->getChannelCount();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (src->getBitPerSample() >= dst->getBitPerSample())
|
|
Shinya Kitaoka |
120a6e |
bitPerSample = src->getBitPerSample();
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
bitPerSample = dst->getBitPerSample();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
tmp = TSoundTrack::create((int)src->getSampleRate(), bitPerSample, chans,
|
|
Shinya Kitaoka |
120a6e |
src_reslen * src->getSampleSize());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
convertWithoutResampling(tmp, src);
|
|
Shinya Kitaoka |
120a6e |
tmq = TSop::resample(tmp, (TINT32)dst->getSampleRate());
|
|
Shinya Kitaoka |
120a6e |
convertWithoutResampling(dst, tmq);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case RESORDER_RATE_BITS_CHANS:
|
|
Shinya Kitaoka |
120a6e |
case RESORDER_RATE_BITS:
|
|
Shinya Kitaoka |
120a6e |
case RESORDER_RATE_CHANS:
|
|
Shinya Kitaoka |
120a6e |
tmp = TSop::resample(src, (TINT32)dst->getSampleRate());
|
|
Shinya Kitaoka |
120a6e |
convertWithoutResampling(dst, tmp);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case RESORDER_CHANS_BITS_RATE:
|
|
Shinya Kitaoka |
120a6e |
case RESORDER_BITS_RATE:
|
|
Shinya Kitaoka |
120a6e |
case RESORDER_CHANS_RATE:
|
|
Shinya Kitaoka |
120a6e |
case RESORDER_SIGN:
|
|
Shinya Kitaoka |
120a6e |
tmp = TSoundTrack::create((int)src->getSampleRate(),
|
|
Shinya Kitaoka |
120a6e |
dst->getBitPerSample(), dst->getChannelCount(),
|
|
Shinya Kitaoka |
120a6e |
src_reslen * dst->getSampleSize(),
|
|
Shinya Kitaoka |
120a6e |
dst->isSampleSigned());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
convertWithoutResampling(tmp, src);
|
|
Shinya Kitaoka |
120a6e |
dst = TSop::resample(tmp, (TINT32)dst->getSampleRate());
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
case RESORDER_RATE:
|
|
Shinya Kitaoka |
120a6e |
dst = TSop::resample(src, (TINT32)dst->getSampleRate());
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
default:
|
|
Shinya Kitaoka |
120a6e |
assert(false);
|
|
Shinya Kitaoka |
120a6e |
break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (dst_reslen < dst->getSampleCount())
|
|
Shinya Kitaoka |
120a6e |
dst->blank((TINT32)dst_reslen, (TINT32)(dst->getSampleCount() - 1));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP doReverb(TSoundTrackT<t> *src, double delayTime,</t>
|
|
Shinya Kitaoka |
120a6e |
double decayFactor, double extendTime) {
|
|
Shinya Kitaoka |
120a6e |
TINT32 dstSampleCount =
|
|
Shinya Kitaoka |
120a6e |
src->getSampleCount() + (TINT32)(src->getSampleRate() * extendTime);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackT<t> *dst = new TSoundTrackT<t>(</t></t>
|
|
Shinya Kitaoka |
120a6e |
src->getSampleRate(), src->getChannelCount(), dstSampleCount);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TINT32 sampleRate = (TINT32)src->getSampleRate();
|
|
Shinya Kitaoka |
120a6e |
TINT32 k = (TINT32)(sampleRate * delayTime);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
T *srcSample = src->samples();
|
|
Shinya Kitaoka |
120a6e |
T *dstSample = dst->samples();
|
|
Shinya Kitaoka |
120a6e |
T *endDstSample = dst->samples() + k;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (dstSample < endDstSample) *dstSample++ = *srcSample++;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// la formula del reverb e'
|
|
Shinya Kitaoka |
120a6e |
// out(i) = in(i) + decayFactor * out(i - k)
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// int channelCount = src->getChannelCount();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
endDstSample =
|
|
Shinya Kitaoka |
120a6e |
dst->samples() + std::min(dstSampleCount, (TINT32)src->getSampleCount());
|
|
Shinya Kitaoka |
120a6e |
while (dstSample < endDstSample) {
|
|
Shinya Kitaoka |
120a6e |
//*dstSample = *srcSample + *(dstSample - k)*decayFactor;
|
|
Shinya Kitaoka |
120a6e |
*dstSample = T::mix(*srcSample, 1, *(dstSample - k), decayFactor);
|
|
Shinya Kitaoka |
120a6e |
++dstSample;
|
|
Shinya Kitaoka |
120a6e |
++srcSample;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
endDstSample = dst->samples() + dstSampleCount;
|
|
Shinya Kitaoka |
120a6e |
while (dstSample < endDstSample) {
|
|
Shinya Kitaoka |
120a6e |
//*dstSample = *(dstSample - k)*decayFactor;
|
|
Shinya Kitaoka |
120a6e |
*dstSample = T::mix(T(), 0, *(dstSample - k), decayFactor);
|
|
Shinya Kitaoka |
120a6e |
++dstSample;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return TSoundTrackP(dst);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class TSoundReverb final : public TSoundTransform {
|
|
Shinya Kitaoka |
120a6e |
double m_delayTime;
|
|
Shinya Kitaoka |
120a6e |
double m_decayFactor;
|
|
Shinya Kitaoka |
120a6e |
double m_extendTime;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TSoundReverb(double delayTime, double decayFactor, double extendTime)
|
|
Shinya Kitaoka |
120a6e |
: m_delayTime(delayTime)
|
|
Shinya Kitaoka |
120a6e |
, m_decayFactor(decayFactor)
|
|
Shinya Kitaoka |
120a6e |
, m_extendTime(extendTime) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
~TSoundReverb() {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono8Signed &src) override {
|
|
Shinya Kitaoka |
120a6e |
return doReverb(const_cast<tsoundtrackmono8signed *="">(&src), m_delayTime,</tsoundtrackmono8signed>
|
|
Shinya Kitaoka |
120a6e |
m_decayFactor, m_extendTime);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono8Unsigned &src) override {
|
|
Shinya Kitaoka |
120a6e |
return doReverb(const_cast<tsoundtrackmono8unsigned *="">(&src), m_delayTime,</tsoundtrackmono8unsigned>
|
|
Shinya Kitaoka |
120a6e |
m_decayFactor, m_extendTime);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo8Signed &src) override {
|
|
Shinya Kitaoka |
120a6e |
return doReverb(const_cast<tsoundtrackstereo8signed *="">(&src), m_delayTime,</tsoundtrackstereo8signed>
|
|
Shinya Kitaoka |
120a6e |
m_decayFactor, m_extendTime);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo8Unsigned &src) override {
|
|
Shinya Kitaoka |
120a6e |
return doReverb(const_cast<tsoundtrackstereo8unsigned *="">(&src), m_delayTime,</tsoundtrackstereo8unsigned>
|
|
Shinya Kitaoka |
120a6e |
m_decayFactor, m_extendTime);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono16 &src) override {
|
|
Shinya Kitaoka |
120a6e |
return doReverb(const_cast<tsoundtrackmono16 *="">(&src), m_delayTime,</tsoundtrackmono16>
|
|
Shinya Kitaoka |
120a6e |
m_decayFactor, m_extendTime);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo16 &src) override {
|
|
Shinya Kitaoka |
120a6e |
return doReverb(const_cast<tsoundtrackstereo16 *="">(&src), m_delayTime,</tsoundtrackstereo16>
|
|
Shinya Kitaoka |
120a6e |
m_decayFactor, m_extendTime);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono24 &src) override {
|
|
Shinya Kitaoka |
120a6e |
return doReverb(const_cast<tsoundtrackmono24 *="">(&src), m_delayTime,</tsoundtrackmono24>
|
|
Shinya Kitaoka |
120a6e |
m_decayFactor, m_extendTime);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo24 &src) override {
|
|
Shinya Kitaoka |
120a6e |
return doReverb(const_cast<tsoundtrackstereo24 *="">(&src), m_delayTime,</tsoundtrackstereo24>
|
|
Shinya Kitaoka |
120a6e |
m_decayFactor, m_extendTime);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSop::reverb(TSoundTrackP src, double delayTime,
|
|
Shinya Kitaoka |
120a6e |
double decayFactor, double extendTime) {
|
|
Shinya Kitaoka |
120a6e |
TSoundReverb *reverb = new TSoundReverb(delayTime, decayFactor, extendTime);
|
|
Shinya Kitaoka |
120a6e |
assert(reverb);
|
|
Shinya Kitaoka |
120a6e |
if (!reverb) return TSoundTrackP();
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP dst = src->apply(reverb);
|
|
Shinya Kitaoka |
120a6e |
delete reverb;
|
|
Shinya Kitaoka |
120a6e |
return dst;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP doGate(TSoundTrackT<t> *src, double threshold, double holdTime,</t>
|
|
Shinya Kitaoka |
120a6e |
double /*releaseTime*/) {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackT<t> *dst = new TSoundTrackT<t>(</t></t>
|
|
Shinya Kitaoka |
120a6e |
src->getSampleRate(), src->getChannelCount(), src->getSampleCount());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double sampleExcursion_inv =
|
|
Shinya Kitaoka |
120a6e |
1.0 / (double)(src->getMaxPressure(0, src->getSampleCount() - 1, 0) -
|
|
Shinya Kitaoka |
120a6e |
src->getMinPressure(0, src->getSampleCount() - 1, 0));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TINT32 holdTimeSamples = src->secondsToSamples(holdTime);
|
|
Shinya Kitaoka |
120a6e |
TINT32 time = 0;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
const T *srcSample = src->samples();
|
|
Shinya Kitaoka |
120a6e |
const T *srcEndSample = srcSample + src->getSampleCount();
|
|
Shinya Kitaoka |
120a6e |
T *dstSample = dst->samples();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (srcSample < srcEndSample) {
|
|
Shinya Kitaoka |
120a6e |
if (fabs(srcSample->getValue(0) * sampleExcursion_inv) < threshold) {
|
|
Shinya Kitaoka |
120a6e |
if (time >= holdTimeSamples)
|
|
Shinya Kitaoka |
120a6e |
*dstSample = T();
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
*dstSample = *srcSample;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
++time;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
time = 0;
|
|
Shinya Kitaoka |
120a6e |
*dstSample = *srcSample;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
++srcSample;
|
|
Shinya Kitaoka |
120a6e |
++dstSample;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return dst;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class TSoundGate final : public TSoundTransform {
|
|
Shinya Kitaoka |
120a6e |
double m_threshold;
|
|
Shinya Kitaoka |
120a6e |
double m_holdTime;
|
|
Shinya Kitaoka |
120a6e |
double m_releaseTime;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TSoundGate(double threshold, double holdTime, double releaseTime)
|
|
Shinya Kitaoka |
120a6e |
: m_threshold(threshold)
|
|
Shinya Kitaoka |
120a6e |
, m_holdTime(holdTime)
|
|
Shinya Kitaoka |
120a6e |
, m_releaseTime(releaseTime) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
~TSoundGate() {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono8Signed &src) override {
|
|
Shinya Kitaoka |
120a6e |
return doGate(const_cast<tsoundtrackmono8signed *="">(&src), m_threshold,</tsoundtrackmono8signed>
|
|
Shinya Kitaoka |
120a6e |
m_holdTime, m_releaseTime);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono8Unsigned &src) override {
|
|
Shinya Kitaoka |
120a6e |
return doGate(const_cast<tsoundtrackmono8unsigned *="">(&src), m_threshold,</tsoundtrackmono8unsigned>
|
|
Shinya Kitaoka |
120a6e |
m_holdTime, m_releaseTime);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo8Signed &src) override {
|
|
Shinya Kitaoka |
120a6e |
return doGate(const_cast<tsoundtrackstereo8signed *="">(&src), m_threshold,</tsoundtrackstereo8signed>
|
|
Shinya Kitaoka |
120a6e |
m_holdTime, m_releaseTime);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo8Unsigned &src) override {
|
|
Shinya Kitaoka |
120a6e |
return doGate(const_cast<tsoundtrackstereo8unsigned *="">(&src), m_threshold,</tsoundtrackstereo8unsigned>
|
|
Shinya Kitaoka |
120a6e |
m_holdTime, m_releaseTime);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono16 &src) override {
|
|
Shinya Kitaoka |
120a6e |
return doGate(const_cast<tsoundtrackmono16 *="">(&src), m_threshold,</tsoundtrackmono16>
|
|
Shinya Kitaoka |
120a6e |
m_holdTime, m_releaseTime);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo16 &src) override {
|
|
Shinya Kitaoka |
120a6e |
return doGate(const_cast<tsoundtrackstereo16 *="">(&src), m_threshold,</tsoundtrackstereo16>
|
|
Shinya Kitaoka |
120a6e |
m_holdTime, m_releaseTime);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono24 &src) override {
|
|
Shinya Kitaoka |
120a6e |
return doGate(const_cast<tsoundtrackmono24 *="">(&src), m_threshold,</tsoundtrackmono24>
|
|
Shinya Kitaoka |
120a6e |
m_holdTime, m_releaseTime);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo24 &src) override {
|
|
Shinya Kitaoka |
120a6e |
return doGate(const_cast<tsoundtrackstereo24 *="">(&src), m_threshold,</tsoundtrackstereo24>
|
|
Shinya Kitaoka |
120a6e |
m_holdTime, m_releaseTime);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSop::gate(TSoundTrackP src, double threshold, double holdTime,
|
|
Shinya Kitaoka |
120a6e |
double releaseTime) {
|
|
Shinya Kitaoka |
120a6e |
TSoundGate *gate = new TSoundGate(threshold, holdTime, releaseTime);
|
|
Shinya Kitaoka |
120a6e |
assert(gate);
|
|
Shinya Kitaoka |
120a6e |
if (!gate) return TSoundTrackP();
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP dst = src->apply(gate);
|
|
Shinya Kitaoka |
120a6e |
delete gate;
|
|
Shinya Kitaoka |
120a6e |
return dst;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
luz paz |
dccc61 |
TSoundTrackP TSop::timeStretch(TSoundTrackP src, double ratio) {
|
|
Shinya Kitaoka |
120a6e |
TINT32 sampleRate = (TINT32)(src->getSampleRate() * ratio);
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (sampleRate > 100000) sampleRate = 100000;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP st;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
if (sampleRate > 0) {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackResample *resample =
|
|
Shinya Kitaoka |
120a6e |
new TSoundTrackResample(sampleRate, FLT_TRIANGLE);
|
|
Shinya Kitaoka |
120a6e |
st = src->apply(resample);
|
|
Shinya Kitaoka |
120a6e |
delete resample;
|
|
Shinya Kitaoka |
120a6e |
st->setSampleRate(src->getSampleRate());
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
return st;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//========================================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP doEcho(TSoundTrackT<t> *src, double delayTime, double decayFactor,</t>
|
|
Shinya Kitaoka |
120a6e |
double extendTime) {
|
|
Shinya Kitaoka |
120a6e |
typedef typename T::ChannelValueType ChannelValueType;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TINT32 dstSampleCount =
|
|
Shinya Kitaoka |
120a6e |
src->getSampleCount() + (TINT32)(src->getSampleRate() * extendTime);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackT<t> *dst = new TSoundTrackT<t>(</t></t>
|
|
Shinya Kitaoka |
120a6e |
src->getSampleRate(), src->getChannelCount(), dstSampleCount);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TINT32 sampleRate = (TINT32)src->getSampleRate();
|
|
Shinya Kitaoka |
120a6e |
TINT32 k = (TINT32)(sampleRate * delayTime);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
T *srcSample = src->samples();
|
|
Shinya Kitaoka |
120a6e |
T *dstSample = dst->samples();
|
|
Shinya Kitaoka |
120a6e |
T *endDstSample = dst->samples() + k;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (dstSample < endDstSample) *dstSample++ = *srcSample++;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// la formula dell'echo e'
|
|
Shinya Kitaoka |
120a6e |
// out(i) = in(i) + decayFactor * in(i - k)
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool chans = src->getChannelCount() == 2;
|
|
Shinya Kitaoka |
120a6e |
endDstSample =
|
|
Shinya Kitaoka |
120a6e |
dst->samples() + std::min(dstSampleCount, (TINT32)src->getSampleCount());
|
|
Shinya Kitaoka |
120a6e |
while (dstSample < endDstSample) {
|
|
Shinya Kitaoka |
120a6e |
//*dstSample = *srcSample + *(srcSample - k)*decayFactor;
|
|
Shinya Kitaoka |
120a6e |
ChannelValueType val = (ChannelValueType)(
|
|
Shinya Kitaoka |
120a6e |
(srcSample - k)->getValue(TSound::MONO) * decayFactor);
|
|
Shinya Kitaoka |
120a6e |
dstSample->setValue(TSound::MONO, srcSample->getValue(TSound::MONO) + val);
|
|
Shinya Kitaoka |
120a6e |
if (chans) {
|
|
Shinya Kitaoka |
120a6e |
ChannelValueType val = (ChannelValueType)(
|
|
Shinya Kitaoka |
120a6e |
(srcSample - k)->getValue(TSound::RIGHT) * decayFactor);
|
|
Shinya Kitaoka |
120a6e |
dstSample->setValue(TSound::RIGHT,
|
|
Shinya Kitaoka |
120a6e |
srcSample->getValue(TSound::RIGHT) + val);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
++dstSample;
|
|
Shinya Kitaoka |
120a6e |
++srcSample;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
endDstSample = dstSample + k;
|
|
Shinya Kitaoka |
120a6e |
while (dstSample < endDstSample) {
|
|
Shinya Kitaoka |
120a6e |
//*dstSample = *(srcSample - k)*decayFactor;
|
|
Shinya Kitaoka |
120a6e |
ChannelValueType val = (ChannelValueType)(
|
|
Shinya Kitaoka |
120a6e |
(srcSample - k)->getValue(TSound::MONO) * decayFactor);
|
|
Shinya Kitaoka |
120a6e |
dstSample->setValue(TSound::MONO, val);
|
|
Shinya Kitaoka |
120a6e |
if (chans) {
|
|
Shinya Kitaoka |
120a6e |
ChannelValueType val = (ChannelValueType)(
|
|
Shinya Kitaoka |
120a6e |
(srcSample - k)->getValue(TSound::RIGHT) * decayFactor);
|
|
Shinya Kitaoka |
120a6e |
dstSample->setValue(TSound::RIGHT, val);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
++dstSample;
|
|
Shinya Kitaoka |
120a6e |
++srcSample;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
srcSample = src->samples() + src->getSampleCount() - 1;
|
|
Shinya Kitaoka |
120a6e |
endDstSample = dst->samples() + dstSampleCount;
|
|
Shinya Kitaoka |
120a6e |
while (dstSample < endDstSample) {
|
|
Shinya Kitaoka |
120a6e |
//*dstSample = *(srcSample)*decayFactor;
|
|
Shinya Kitaoka |
120a6e |
ChannelValueType val =
|
|
Shinya Kitaoka |
120a6e |
(ChannelValueType)(srcSample->getValue(TSound::MONO) * decayFactor);
|
|
Shinya Kitaoka |
120a6e |
dstSample->setValue(TSound::MONO, val);
|
|
Shinya Kitaoka |
120a6e |
if (chans) {
|
|
Shinya Kitaoka |
120a6e |
ChannelValueType val =
|
|
Shinya Kitaoka |
120a6e |
(ChannelValueType)(srcSample->getValue(TSound::RIGHT) * decayFactor);
|
|
Shinya Kitaoka |
120a6e |
dstSample->setValue(TSound::RIGHT, val);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
++dstSample;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return TSoundTrackP(dst);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
void TSop::echo(TSoundTrackP &dst, const TSoundTrackP &src, double delayTime,
|
|
Shinya Kitaoka |
120a6e |
double decayFactor, double extendTime) {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackMono8Signed *srcM8S;
|
|
Shinya Kitaoka |
120a6e |
srcM8S = dynamic_cast<tsoundtrackmono8signed *="">(src.getPointer());</tsoundtrackmono8signed>
|
|
Shinya Kitaoka |
120a6e |
if (srcM8S)
|
|
Shinya Kitaoka |
120a6e |
dst = doEcho(srcM8S, delayTime, decayFactor, extendTime);
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackMono8Unsigned *srcM8U;
|
|
Shinya Kitaoka |
120a6e |
srcM8U = dynamic_cast<tsoundtrackmono8unsigned *="">(src.getPointer());</tsoundtrackmono8unsigned>
|
|
Shinya Kitaoka |
120a6e |
if (srcM8U)
|
|
Shinya Kitaoka |
120a6e |
dst = doEcho(srcM8U, delayTime, decayFactor, extendTime);
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackStereo8Signed *srcS8S;
|
|
Shinya Kitaoka |
120a6e |
srcS8S = dynamic_cast<tsoundtrackstereo8signed *="">(src.getPointer());</tsoundtrackstereo8signed>
|
|
Shinya Kitaoka |
120a6e |
if (srcS8S)
|
|
Shinya Kitaoka |
120a6e |
dst = doEcho(srcS8S, delayTime, decayFactor, extendTime);
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackStereo8Unsigned *srcS8U;
|
|
Shinya Kitaoka |
120a6e |
srcS8U = dynamic_cast<tsoundtrackstereo8unsigned *="">(src.getPointer());</tsoundtrackstereo8unsigned>
|
|
Shinya Kitaoka |
120a6e |
if (srcS8U)
|
|
Shinya Kitaoka |
120a6e |
dst = doEcho(srcS8U, delayTime, decayFactor, extendTime);
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackMono16 *srcM16;
|
|
Shinya Kitaoka |
120a6e |
srcM16 = dynamic_cast<tsoundtrackmono16 *="">(src.getPointer());</tsoundtrackmono16>
|
|
Shinya Kitaoka |
120a6e |
if (srcM16)
|
|
Shinya Kitaoka |
120a6e |
dst = doEcho(srcM16, delayTime, decayFactor, extendTime);
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackStereo16 *srcS16;
|
|
Shinya Kitaoka |
120a6e |
srcS16 = dynamic_cast<tsoundtrackstereo16 *="">(src.getPointer());</tsoundtrackstereo16>
|
|
Shinya Kitaoka |
120a6e |
if (srcS16)
|
|
Shinya Kitaoka |
120a6e |
dst = doEcho(srcS16, delayTime, decayFactor, extendTime);
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackMono24 *srcM24;
|
|
Shinya Kitaoka |
120a6e |
srcM24 = dynamic_cast<tsoundtrackmono24 *="">(src.getPointer());</tsoundtrackmono24>
|
|
Shinya Kitaoka |
120a6e |
if (srcM24)
|
|
Shinya Kitaoka |
120a6e |
dst = doEcho(srcM24, delayTime, decayFactor, extendTime);
|
|
Shinya Kitaoka |
120a6e |
else {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackStereo24 *srcS24;
|
|
Shinya Kitaoka |
120a6e |
srcS24 = dynamic_cast<tsoundtrackstereo24 *="">(src.getPointer());</tsoundtrackstereo24>
|
|
Shinya Kitaoka |
120a6e |
if (srcS24)
|
|
Shinya Kitaoka |
120a6e |
dst = doEcho(srcS24, delayTime, decayFactor, extendTime);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSop::insertBlank(TSoundTrackP src, TINT32 s0, TINT32 len) {
|
|
Shinya Kitaoka |
120a6e |
assert(len >= 0);
|
|
Shinya Kitaoka |
120a6e |
if (len == 0) return src;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TINT32 ss0 = tcrop<tint32>(s0, 0, src->getSampleCount());</tint32>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackFormat format = src->getFormat();
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP dst = TSoundTrack::create(format, (src->getSampleCount() + len));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
UCHAR *dstRawData = (UCHAR *)dst->getRawData();
|
|
Shinya Kitaoka |
120a6e |
UCHAR *srcRawData = (UCHAR *)src->getRawData();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
int bytePerSample = dst->getSampleSize();
|
|
Shinya Kitaoka |
120a6e |
memcpy(dstRawData, srcRawData, ss0 * bytePerSample);
|
|
Shinya Kitaoka |
120a6e |
if (format.m_signedSample)
|
|
Shinya Kitaoka |
120a6e |
memset(dstRawData + ss0 * bytePerSample, 0, len * bytePerSample);
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
memset(dstRawData + ss0 * bytePerSample, 127, len * bytePerSample);
|
|
Shinya Kitaoka |
120a6e |
memcpy(dstRawData + (ss0 + len) * bytePerSample,
|
|
Shinya Kitaoka |
120a6e |
srcRawData + ss0 * bytePerSample,
|
|
Shinya Kitaoka |
120a6e |
(src->getSampleCount() - ss0) * bytePerSample);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return dst;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSop::insertBlank(TSoundTrackP src, double t0, double len) {
|
|
Shinya Kitaoka |
120a6e |
return insertBlank(src, src->secondsToSamples(t0),
|
|
Shinya Kitaoka |
120a6e |
src->secondsToSamples(len));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSop::remove(TSoundTrackP src, TINT32 s0, TINT32 s1,
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP &paste) {
|
|
Shinya Kitaoka |
120a6e |
TINT32 ss0, ss1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ss0 = std::max<tint32>((TINT32)0, s0);</tint32>
|
|
Shinya Kitaoka |
120a6e |
ss1 = std::min(s1, (TINT32)(src->getSampleCount() - 1));
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP soundTrackSlice;
|
|
Shinya Kitaoka |
120a6e |
if (ss0 <= ss1) soundTrackSlice = src->extract(ss0, ss1);
|
|
Shinya Kitaoka |
120a6e |
if (!soundTrackSlice) {
|
|
Shinya Kitaoka |
120a6e |
paste = TSoundTrackP();
|
|
Shinya Kitaoka |
120a6e |
return src;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
paste = soundTrackSlice->clone();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackFormat format = src->getFormat();
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP dst =
|
|
Shinya Kitaoka |
120a6e |
TSoundTrack::create(format, (src->getSampleCount() - (ss1 - ss0 + 1)));
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TINT32 dstSampleSize = dst->getSampleSize();
|
|
Shinya Kitaoka |
120a6e |
UCHAR *newRowData = (UCHAR *)dst->getRawData();
|
|
Shinya Kitaoka |
120a6e |
UCHAR *srcRowData = (UCHAR *)src->getRawData();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
memcpy(newRowData, srcRowData, ss0 * dstSampleSize);
|
|
Shinya Kitaoka |
120a6e |
memcpy(newRowData + (ss0 * dstSampleSize),
|
|
Shinya Kitaoka |
120a6e |
srcRowData + (ss1 + 1) * dstSampleSize,
|
|
Shinya Kitaoka |
120a6e |
(src->getSampleCount() - ss1 - 1) * dst->getSampleSize());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return dst;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSop::remove(TSoundTrackP src, double t0, double t1,
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP &paste) {
|
|
Shinya Kitaoka |
120a6e |
return remove(src, src->secondsToSamples(t0), src->secondsToSamples(t1),
|
|
Shinya Kitaoka |
120a6e |
paste);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP mixT(TSoundTrackT<t> *st1, double a1, TSoundTrackT<t> *st2,</t></t>
|
|
Shinya Kitaoka |
120a6e |
double a2) {
|
|
Shinya Kitaoka |
120a6e |
TINT32 sampleCount = std::max(st1->getSampleCount(), st2->getSampleCount());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackT<t> *dst = new TSoundTrackT<t>(</t></t>
|
|
Shinya Kitaoka |
120a6e |
st1->getSampleRate(), st1->getChannelCount(), sampleCount);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
T *dstSample = dst->samples();
|
|
Shinya Kitaoka |
120a6e |
T *endDstSample =
|
|
Shinya Kitaoka |
120a6e |
dstSample + std::min(st1->getSampleCount(), st2->getSampleCount());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
T *st1Sample = st1->samples();
|
|
Shinya Kitaoka |
120a6e |
T *st2Sample = st2->samples();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (dstSample < endDstSample) {
|
|
Shinya Kitaoka |
120a6e |
*dstSample++ = T::mix(*st1Sample, a1, *st2Sample, a2);
|
|
Shinya Kitaoka |
120a6e |
++st1Sample;
|
|
Shinya Kitaoka |
120a6e |
++st2Sample;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
T *srcSample =
|
|
Shinya Kitaoka |
120a6e |
st1->getSampleCount() > st2->getSampleCount() ? st1Sample : st2Sample;
|
|
Shinya Kitaoka |
120a6e |
endDstSample = dst->samples() + sampleCount;
|
|
Shinya Kitaoka |
120a6e |
while (dstSample < endDstSample) *dstSample++ = *srcSample++;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return TSoundTrackP(dst);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class TSoundTrackMixer final : public TSoundTransform {
|
|
Shinya Kitaoka |
120a6e |
double m_alpha1, m_alpha2;
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP m_sndtrack;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackMixer(double a1, double a2, const TSoundTrackP &st2)
|
|
Shinya Kitaoka |
120a6e |
: TSoundTransform(), m_alpha1(a1), m_alpha2(a2), m_sndtrack(st2) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
~TSoundTrackMixer(){};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono8Signed &src) override {
|
|
Shinya Kitaoka |
120a6e |
assert(src.getFormat() == m_sndtrack->getFormat());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return (
|
|
Shinya Kitaoka |
120a6e |
mixT(const_cast<tsoundtrackmono8signed *="">(&src), m_alpha1,</tsoundtrackmono8signed>
|
|
Shinya Kitaoka |
120a6e |
dynamic_cast<tsoundtrackmono8signed *="">(m_sndtrack.getPointer()),</tsoundtrackmono8signed>
|
|
Shinya Kitaoka |
120a6e |
m_alpha2));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono8Unsigned &src) override {
|
|
Shinya Kitaoka |
120a6e |
assert(src.getFormat() == m_sndtrack->getFormat());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return (
|
|
Shinya Kitaoka |
120a6e |
mixT(const_cast<tsoundtrackmono8unsigned *="">(&src), m_alpha1,</tsoundtrackmono8unsigned>
|
|
Shinya Kitaoka |
120a6e |
dynamic_cast<tsoundtrackmono8unsigned *="">(m_sndtrack.getPointer()),</tsoundtrackmono8unsigned>
|
|
Shinya Kitaoka |
120a6e |
m_alpha2));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo8Signed &src) override {
|
|
Shinya Kitaoka |
120a6e |
assert(src.getFormat() == m_sndtrack->getFormat());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return (
|
|
Shinya Kitaoka |
120a6e |
mixT(const_cast<tsoundtrackstereo8signed *="">(&src), m_alpha1,</tsoundtrackstereo8signed>
|
|
Shinya Kitaoka |
120a6e |
dynamic_cast<tsoundtrackstereo8signed *="">(m_sndtrack.getPointer()),</tsoundtrackstereo8signed>
|
|
Shinya Kitaoka |
120a6e |
m_alpha2));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo8Unsigned &src) override {
|
|
Shinya Kitaoka |
120a6e |
assert(src.getFormat() == m_sndtrack->getFormat());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return (mixT(
|
|
Shinya Kitaoka |
120a6e |
const_cast<tsoundtrackstereo8unsigned *="">(&src), m_alpha1,</tsoundtrackstereo8unsigned>
|
|
Shinya Kitaoka |
120a6e |
dynamic_cast<tsoundtrackstereo8unsigned *="">(m_sndtrack.getPointer()),</tsoundtrackstereo8unsigned>
|
|
Shinya Kitaoka |
120a6e |
m_alpha2));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono16 &src) override {
|
|
Shinya Kitaoka |
120a6e |
assert(src.getFormat() == m_sndtrack->getFormat());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return (mixT(const_cast<tsoundtrackmono16 *="">(&src), m_alpha1,</tsoundtrackmono16>
|
|
Shinya Kitaoka |
120a6e |
dynamic_cast<tsoundtrackmono16 *="">(m_sndtrack.getPointer()),</tsoundtrackmono16>
|
|
Shinya Kitaoka |
120a6e |
m_alpha2));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo16 &src) override {
|
|
Shinya Kitaoka |
120a6e |
assert(src.getFormat() == m_sndtrack->getFormat());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return (mixT(const_cast<tsoundtrackstereo16 *="">(&src), m_alpha1,</tsoundtrackstereo16>
|
|
Shinya Kitaoka |
120a6e |
dynamic_cast<tsoundtrackstereo16 *="">(m_sndtrack.getPointer()),</tsoundtrackstereo16>
|
|
Shinya Kitaoka |
120a6e |
m_alpha2));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono24 &src) override {
|
|
Shinya Kitaoka |
120a6e |
assert(src.getFormat() == m_sndtrack->getFormat());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return (mixT(const_cast<tsoundtrackmono24 *="">(&src), m_alpha1,</tsoundtrackmono24>
|
|
Shinya Kitaoka |
120a6e |
dynamic_cast<tsoundtrackmono24 *="">(m_sndtrack.getPointer()),</tsoundtrackmono24>
|
|
Shinya Kitaoka |
120a6e |
m_alpha2));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo24 &src) override {
|
|
Shinya Kitaoka |
120a6e |
assert(src.getFormat() == m_sndtrack->getFormat());
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return (mixT(const_cast<tsoundtrackstereo24 *="">(&src), m_alpha1,</tsoundtrackstereo24>
|
|
Shinya Kitaoka |
120a6e |
dynamic_cast<tsoundtrackstereo24 *="">(m_sndtrack.getPointer()),</tsoundtrackstereo24>
|
|
Shinya Kitaoka |
120a6e |
m_alpha2));
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSop::mix(const TSoundTrackP &st1, const TSoundTrackP &st2,
|
|
Shinya Kitaoka |
120a6e |
double a1, double a2) {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackMixer *converter;
|
|
Shinya Kitaoka |
120a6e |
a1 = tcrop<double>(a1, 0.0, 1.0);</double>
|
|
Shinya Kitaoka |
120a6e |
a2 = tcrop<double>(a2, 0.0, 1.0);</double>
|
|
Shinya Kitaoka |
120a6e |
converter = new TSoundTrackMixer(a1, a2, st2);
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP snd = st1->apply(converter);
|
|
Shinya Kitaoka |
120a6e |
delete converter;
|
|
Shinya Kitaoka |
120a6e |
return (snd);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// TSop::FadeIn
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP doFadeIn(const TSoundTrackT<t> &track, double riseFactor) {</t>
|
|
Shinya Kitaoka |
120a6e |
typedef typename T::ChannelValueType ChannelValueType;
|
|
Shinya Kitaoka |
120a6e |
int sampleCount = (int)((double)track.getSampleCount() * riseFactor);
|
|
Shinya Kitaoka |
120a6e |
if (!sampleCount) sampleCount = 1;
|
|
Shinya Kitaoka |
120a6e |
assert(sampleCount);
|
|
Shinya Kitaoka |
120a6e |
int channelCount = track.getChannelCount();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackT<t> *out =</t>
|
|
Shinya Kitaoka |
120a6e |
new TSoundTrackT<t>(track.getSampleRate(), channelCount, sampleCount);</t>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double val[2], step[2];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
ChannelValueType chan[2];
|
|
Shinya Kitaoka |
120a6e |
const T *firstSample = track.samples();
|
|
Shinya Kitaoka |
120a6e |
for (int k = 0; k < channelCount; ++k) {
|
|
Shinya Kitaoka |
120a6e |
chan[k] = firstSample->getValue(k);
|
|
Shinya Kitaoka |
120a6e |
if (firstSample->isSampleSigned()) {
|
|
Shinya Kitaoka |
120a6e |
val[k] = 0;
|
|
Shinya Kitaoka |
120a6e |
step[k] = (double)chan[k] / (double)sampleCount;
|
|
Shinya Kitaoka |
120a6e |
} else {
|
|
Shinya Kitaoka |
120a6e |
val[k] = 127;
|
|
Shinya Kitaoka |
120a6e |
step[k] = (double)(chan[k] - 128) / (double)sampleCount;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
T *psample = out->samples();
|
|
Shinya Kitaoka |
120a6e |
T *end = psample + out->getSampleCount();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (psample < end) {
|
|
Shinya Kitaoka |
120a6e |
T sample;
|
|
Shinya Kitaoka |
120a6e |
for (int k = 0; k < channelCount; ++k) {
|
|
Shinya Kitaoka |
120a6e |
sample.setValue(k, (ChannelValueType)val[k]);
|
|
Shinya Kitaoka |
120a6e |
val[k] += step[k];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
*psample = sample;
|
|
Shinya Kitaoka |
120a6e |
++psample;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return out;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class TSoundTrackFaderIn final : public TSoundTransform {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackFaderIn(double riseFactor)
|
|
Shinya Kitaoka |
120a6e |
: TSoundTransform(), m_riseFactor(riseFactor) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono8Signed &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo8Signed &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono8Unsigned &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo8Unsigned &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono16 &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo16 &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono24 &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo24 &) override;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double m_riseFactor;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackFaderIn::compute(const TSoundTrackMono8Signed &track) {
|
|
Shinya Kitaoka |
120a6e |
return doFadeIn(track, m_riseFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackFaderIn::compute(
|
|
Shinya Kitaoka |
120a6e |
const TSoundTrackStereo8Signed &track) {
|
|
Shinya Kitaoka |
120a6e |
return doFadeIn(track, m_riseFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackFaderIn::compute(
|
|
Shinya Kitaoka |
120a6e |
const TSoundTrackMono8Unsigned &track) {
|
|
Shinya Kitaoka |
120a6e |
return doFadeIn(track, m_riseFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackFaderIn::compute(
|
|
Shinya Kitaoka |
120a6e |
const TSoundTrackStereo8Unsigned &track) {
|
|
Shinya Kitaoka |
120a6e |
return doFadeIn(track, m_riseFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackFaderIn::compute(const TSoundTrackMono16 &track) {
|
|
Shinya Kitaoka |
120a6e |
return doFadeIn(track, m_riseFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackFaderIn::compute(const TSoundTrackStereo16 &track) {
|
|
Shinya Kitaoka |
120a6e |
return doFadeIn(track, m_riseFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackFaderIn::compute(const TSoundTrackMono24 &track) {
|
|
Shinya Kitaoka |
120a6e |
return doFadeIn(track, m_riseFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackFaderIn::compute(const TSoundTrackStereo24 &track) {
|
|
Shinya Kitaoka |
120a6e |
return doFadeIn(track, m_riseFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSop::fadeIn(const TSoundTrackP src, double riseFactor) {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackFaderIn *fader = new TSoundTrackFaderIn(riseFactor);
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP out = src->apply(fader);
|
|
Shinya Kitaoka |
120a6e |
delete fader;
|
|
Shinya Kitaoka |
120a6e |
return out;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// TSop::FadeOut
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP doFadeOut(const TSoundTrackT<t> &track, double decayFactor) {</t>
|
|
Shinya Kitaoka |
120a6e |
typedef typename T::ChannelValueType ChannelValueType;
|
|
Shinya Kitaoka |
120a6e |
int sampleCount = (int)((double)track.getSampleCount() * decayFactor);
|
|
Shinya Kitaoka |
120a6e |
if (!sampleCount) sampleCount = 1;
|
|
Shinya Kitaoka |
120a6e |
assert(sampleCount);
|
|
Shinya Kitaoka |
120a6e |
int channelCount = track.getChannelCount();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackT<t> *out =</t>
|
|
Shinya Kitaoka |
120a6e |
new TSoundTrackT<t>(track.getSampleRate(), channelCount, sampleCount);</t>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double val[2], step[2];
|
|
Shinya Kitaoka |
120a6e |
ChannelValueType chan[2];
|
|
Shinya Kitaoka |
120a6e |
const T *lastSample = (track.samples() + track.getSampleCount() - 1);
|
|
Shinya Kitaoka |
120a6e |
for (int k = 0; k < channelCount; ++k) {
|
|
Shinya Kitaoka |
120a6e |
chan[k] = lastSample->getValue(k);
|
|
Shinya Kitaoka |
120a6e |
val[k] = (double)chan[k];
|
|
Shinya Kitaoka |
120a6e |
if (lastSample->isSampleSigned())
|
|
Shinya Kitaoka |
120a6e |
step[k] = (double)chan[k] / (double)sampleCount;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
step[k] = (double)(chan[k] - 128) / (double)sampleCount;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
T *psample = out->samples();
|
|
Shinya Kitaoka |
120a6e |
T *end = psample + out->getSampleCount();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (psample < end) {
|
|
Shinya Kitaoka |
120a6e |
T sample;
|
|
Shinya Kitaoka |
120a6e |
for (int k = 0; k < channelCount; ++k) {
|
|
Shinya Kitaoka |
120a6e |
sample.setValue(k, (ChannelValueType)val[k]);
|
|
Shinya Kitaoka |
120a6e |
val[k] -= step[k];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
*psample = sample;
|
|
Shinya Kitaoka |
120a6e |
++psample;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return out;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class TSoundTrackFaderOut final : public TSoundTransform {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackFaderOut(double decayFactor)
|
|
Shinya Kitaoka |
120a6e |
: TSoundTransform(), m_decayFactor(decayFactor) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono8Signed &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo8Signed &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono8Unsigned &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo8Unsigned &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono16 &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo16 &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono24 &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo24 &) override;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double m_decayFactor;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackFaderOut::compute(const TSoundTrackMono8Signed &track) {
|
|
Shinya Kitaoka |
120a6e |
return doFadeOut(track, m_decayFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackFaderOut::compute(
|
|
Shinya Kitaoka |
120a6e |
const TSoundTrackStereo8Signed &track) {
|
|
Shinya Kitaoka |
120a6e |
return doFadeOut(track, m_decayFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackFaderOut::compute(
|
|
Shinya Kitaoka |
120a6e |
const TSoundTrackMono8Unsigned &track) {
|
|
Shinya Kitaoka |
120a6e |
return doFadeOut(track, m_decayFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackFaderOut::compute(
|
|
Shinya Kitaoka |
120a6e |
const TSoundTrackStereo8Unsigned &track) {
|
|
Shinya Kitaoka |
120a6e |
return doFadeOut(track, m_decayFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackFaderOut::compute(const TSoundTrackMono16 &track) {
|
|
Shinya Kitaoka |
120a6e |
return doFadeOut(track, m_decayFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackFaderOut::compute(const TSoundTrackStereo16 &track) {
|
|
Shinya Kitaoka |
120a6e |
return doFadeOut(track, m_decayFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackFaderOut::compute(const TSoundTrackMono24 &track) {
|
|
Shinya Kitaoka |
120a6e |
return doFadeOut(track, m_decayFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackFaderOut::compute(const TSoundTrackStereo24 &track) {
|
|
Shinya Kitaoka |
120a6e |
return doFadeOut(track, m_decayFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSop::fadeOut(const TSoundTrackP src, double decayFactor) {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackFaderOut *fader = new TSoundTrackFaderOut(decayFactor);
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP out = src->apply(fader);
|
|
Shinya Kitaoka |
120a6e |
delete fader;
|
|
Shinya Kitaoka |
120a6e |
return out;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// TSop::CrossFade
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP doCrossFade(const TSoundTrackT<t> &track1, TSoundTrackT<t> *track2,</t></t>
|
|
Shinya Kitaoka |
120a6e |
double crossFactor) {
|
|
Shinya Kitaoka |
120a6e |
typedef typename T::ChannelValueType ChannelValueType;
|
|
Shinya Kitaoka |
120a6e |
int channelCount = track2->getChannelCount();
|
|
Shinya Kitaoka |
120a6e |
int sampleCount = (int)((double)track2->getSampleCount() * crossFactor);
|
|
Shinya Kitaoka |
120a6e |
if (!sampleCount) sampleCount = 1;
|
|
Shinya Kitaoka |
120a6e |
assert(sampleCount);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// ultimo campione di track1
|
|
Shinya Kitaoka |
120a6e |
ChannelValueType chanTrack1[2];
|
|
Shinya Kitaoka |
120a6e |
const T *lastSample = (track1.samples() + track1.getSampleCount() - 1);
|
|
Shinya Kitaoka |
120a6e |
int k;
|
|
Shinya Kitaoka |
120a6e |
for (k = 0; k < channelCount; ++k) chanTrack1[k] = lastSample->getValue(k);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double val[2], step[2];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// primo campione di track2
|
|
Shinya Kitaoka |
120a6e |
ChannelValueType chanTrack2[2];
|
|
Shinya Kitaoka |
120a6e |
const T *firstSample = track2->samples();
|
|
Shinya Kitaoka |
120a6e |
for (k = 0; k < channelCount; ++k) {
|
|
Shinya Kitaoka |
120a6e |
chanTrack2[k] = firstSample->getValue(k);
|
|
Shinya Kitaoka |
120a6e |
val[k] = chanTrack1[k] - chanTrack2[k];
|
|
Shinya Kitaoka |
120a6e |
step[k] = val[k] / (double)sampleCount;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackT<t> *out =</t>
|
|
Shinya Kitaoka |
120a6e |
new TSoundTrackT<t>(track2->getSampleRate(), channelCount, sampleCount);</t>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
T *psample = out->samples();
|
|
Shinya Kitaoka |
120a6e |
T *end = psample + out->getSampleCount();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (psample < end) {
|
|
Shinya Kitaoka |
120a6e |
T sample;
|
|
Shinya Kitaoka |
120a6e |
for (int k = 0; k < channelCount; ++k) {
|
|
Shinya Kitaoka |
120a6e |
double tot = (double)firstSample->getValue(k) + val[k];
|
|
Shinya Kitaoka |
120a6e |
ChannelValueType value = (ChannelValueType)tot;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
sample.setValue(k, value);
|
|
Shinya Kitaoka |
120a6e |
val[k] -= step[k];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
*psample = sample;
|
|
Shinya Kitaoka |
120a6e |
++psample;
|
|
Shinya Kitaoka |
120a6e |
//++firstSample;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return out;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class TSoundTrackCrossFader final : public TSoundTransform {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackCrossFader(TSoundTrackP src, double crossFactor)
|
|
Shinya Kitaoka |
120a6e |
: TSoundTransform(), m_st(src), m_crossFactor(crossFactor) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono8Signed &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo8Signed &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono8Unsigned &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo8Unsigned &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono16 &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo16 &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono24 &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo24 &) override;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP m_st;
|
|
Shinya Kitaoka |
120a6e |
double m_crossFactor;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackCrossFader::compute(const TSoundTrackMono8Signed &src) {
|
|
Shinya Kitaoka |
120a6e |
assert(src.getFormat() == m_st->getFormat());
|
|
Shinya Kitaoka |
120a6e |
return doCrossFade(src,
|
|
Shinya Kitaoka |
120a6e |
dynamic_cast<tsoundtrackmono8signed *="">(m_st.getPointer()),</tsoundtrackmono8signed>
|
|
Shinya Kitaoka |
120a6e |
m_crossFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackCrossFader::compute(
|
|
Shinya Kitaoka |
120a6e |
const TSoundTrackStereo8Signed &src) {
|
|
Shinya Kitaoka |
120a6e |
assert(src.getFormat() == m_st->getFormat());
|
|
Shinya Kitaoka |
120a6e |
return doCrossFade(
|
|
Shinya Kitaoka |
120a6e |
src, dynamic_cast<tsoundtrackstereo8signed *="">(m_st.getPointer()),</tsoundtrackstereo8signed>
|
|
Shinya Kitaoka |
120a6e |
m_crossFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackCrossFader::compute(
|
|
Shinya Kitaoka |
120a6e |
const TSoundTrackMono8Unsigned &src) {
|
|
Shinya Kitaoka |
120a6e |
assert(src.getFormat() == m_st->getFormat());
|
|
Shinya Kitaoka |
120a6e |
return doCrossFade(
|
|
Shinya Kitaoka |
120a6e |
src, dynamic_cast<tsoundtrackmono8unsigned *="">(m_st.getPointer()),</tsoundtrackmono8unsigned>
|
|
Shinya Kitaoka |
120a6e |
m_crossFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackCrossFader::compute(
|
|
Shinya Kitaoka |
120a6e |
const TSoundTrackStereo8Unsigned &src) {
|
|
Shinya Kitaoka |
120a6e |
assert(src.getFormat() == m_st->getFormat());
|
|
Shinya Kitaoka |
120a6e |
return doCrossFade(
|
|
Shinya Kitaoka |
120a6e |
src, dynamic_cast<tsoundtrackstereo8unsigned *="">(m_st.getPointer()),</tsoundtrackstereo8unsigned>
|
|
Shinya Kitaoka |
120a6e |
m_crossFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackCrossFader::compute(const TSoundTrackMono16 &src) {
|
|
Shinya Kitaoka |
120a6e |
assert(src.getFormat() == m_st->getFormat());
|
|
Shinya Kitaoka |
120a6e |
return doCrossFade(src, dynamic_cast<tsoundtrackmono16 *="">(m_st.getPointer()),</tsoundtrackmono16>
|
|
Shinya Kitaoka |
120a6e |
m_crossFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackCrossFader::compute(const TSoundTrackStereo16 &src) {
|
|
Shinya Kitaoka |
120a6e |
assert(src.getFormat() == m_st->getFormat());
|
|
Shinya Kitaoka |
120a6e |
return doCrossFade(src,
|
|
Shinya Kitaoka |
120a6e |
dynamic_cast<tsoundtrackstereo16 *="">(m_st.getPointer()),</tsoundtrackstereo16>
|
|
Shinya Kitaoka |
120a6e |
m_crossFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackCrossFader::compute(const TSoundTrackMono24 &src) {
|
|
Shinya Kitaoka |
120a6e |
assert(src.getFormat() == m_st->getFormat());
|
|
Shinya Kitaoka |
120a6e |
return doCrossFade(src, dynamic_cast<tsoundtrackmono24 *="">(m_st.getPointer()),</tsoundtrackmono24>
|
|
Shinya Kitaoka |
120a6e |
m_crossFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackCrossFader::compute(const TSoundTrackStereo24 &src) {
|
|
Shinya Kitaoka |
120a6e |
assert(src.getFormat() == m_st->getFormat());
|
|
Shinya Kitaoka |
120a6e |
return doCrossFade(src,
|
|
Shinya Kitaoka |
120a6e |
dynamic_cast<tsoundtrackstereo24 *="">(m_st.getPointer()),</tsoundtrackstereo24>
|
|
Shinya Kitaoka |
120a6e |
m_crossFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSop::crossFade(const TSoundTrackP src1, const TSoundTrackP src2,
|
|
Shinya Kitaoka |
120a6e |
double crossFactor) {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackCrossFader *fader = new TSoundTrackCrossFader(src2, crossFactor);
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP out = src1->apply(fader);
|
|
Shinya Kitaoka |
120a6e |
delete fader;
|
|
Shinya Kitaoka |
120a6e |
return out;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
// TSop::CrossFadeOverWrite
|
|
Toshihiro Shimizu |
890ddd |
//
|
|
Toshihiro Shimizu |
890ddd |
//==============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP doCrossFadeOverWrite(const TSoundTrackT<t> &track1,</t>
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackT<t> *track2, double crossFactor) {</t>
|
|
Shinya Kitaoka |
120a6e |
typedef typename T::ChannelValueType ChannelValueType;
|
|
Shinya Kitaoka |
120a6e |
int channelCount = track2->getChannelCount();
|
|
Shinya Kitaoka |
120a6e |
int sampleCount = (int)((double)track2->getSampleCount() * crossFactor);
|
|
Shinya Kitaoka |
120a6e |
int sampleCountT2 = track2->getSampleCount();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
if (sampleCount == 0 && sampleCountT2 == 1) return track2;
|
|
Shinya Kitaoka |
120a6e |
if (sampleCount == 0) sampleCount = 1;
|
|
Shinya Kitaoka |
120a6e |
assert(sampleCount);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// ultimo campione di track1
|
|
Shinya Kitaoka |
120a6e |
ChannelValueType chanTrack1[2];
|
|
Shinya Kitaoka |
120a6e |
const T *lastSample = (track1.samples() + track1.getSampleCount() - 1);
|
|
Shinya Kitaoka |
120a6e |
int k;
|
|
Shinya Kitaoka |
120a6e |
for (k = 0; k < channelCount; ++k) chanTrack1[k] = lastSample->getValue(k);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double val[2], step[2];
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
// primo campione di track2
|
|
Shinya Kitaoka |
120a6e |
ChannelValueType chanTrack2[2];
|
|
Shinya Kitaoka |
120a6e |
const T *firstSample = track2->samples() + sampleCount;
|
|
Shinya Kitaoka |
120a6e |
for (k = 0; k < channelCount; ++k) {
|
|
Shinya Kitaoka |
120a6e |
chanTrack2[k] = firstSample->getValue(k);
|
|
Shinya Kitaoka |
120a6e |
val[k] = chanTrack1[k] - chanTrack2[k];
|
|
Shinya Kitaoka |
120a6e |
step[k] = val[k] / (double)sampleCount;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackT<t> *out =</t>
|
|
Shinya Kitaoka |
120a6e |
new TSoundTrackT<t>(track2->getSampleRate(), channelCount, sampleCountT2);</t>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
T *psample = out->samples();
|
|
Shinya Kitaoka |
120a6e |
T *end = psample + sampleCount;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
while (psample < end) {
|
|
Shinya Kitaoka |
120a6e |
T sample;
|
|
Shinya Kitaoka |
120a6e |
for (int k = 0; k < channelCount; ++k) {
|
|
Shinya Kitaoka |
120a6e |
double tot = (double)firstSample->getValue(k) + val[k];
|
|
Shinya Kitaoka |
120a6e |
ChannelValueType value = (ChannelValueType)tot;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
sample.setValue(k, value);
|
|
Shinya Kitaoka |
120a6e |
val[k] -= step[k];
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
*psample = sample;
|
|
Shinya Kitaoka |
120a6e |
++psample;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
out->copy(track2->extract(sampleCount, sampleCountT2 - 1), sampleCount);
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
return out;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class TSoundTrackCrossFaderOverWrite final : public TSoundTransform {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackCrossFaderOverWrite(TSoundTrackP src, double crossFactor)
|
|
Shinya Kitaoka |
120a6e |
: TSoundTransform(), m_st(src), m_crossFactor(crossFactor) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono8Signed &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo8Signed &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono8Unsigned &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo8Unsigned &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono16 &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo16 &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackMono24 &) override;
|
|
Shinya Kitaoka |
473e70 |
TSoundTrackP compute(const TSoundTrackStereo24 &) override;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP m_st;
|
|
Shinya Kitaoka |
120a6e |
double m_crossFactor;
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackCrossFaderOverWrite::compute(
|
|
Shinya Kitaoka |
120a6e |
const TSoundTrackMono8Signed &src) {
|
|
Shinya Kitaoka |
120a6e |
assert(src.getFormat() == m_st->getFormat());
|
|
Shinya Kitaoka |
120a6e |
return doCrossFadeOverWrite(
|
|
Shinya Kitaoka |
120a6e |
src, dynamic_cast<tsoundtrackmono8signed *="">(m_st.getPointer()),</tsoundtrackmono8signed>
|
|
Shinya Kitaoka |
120a6e |
m_crossFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackCrossFaderOverWrite::compute(
|
|
Shinya Kitaoka |
120a6e |
const TSoundTrackStereo8Signed &src) {
|
|
Shinya Kitaoka |
120a6e |
assert(src.getFormat() == m_st->getFormat());
|
|
Shinya Kitaoka |
120a6e |
return doCrossFadeOverWrite(
|
|
Shinya Kitaoka |
120a6e |
src, dynamic_cast<tsoundtrackstereo8signed *="">(m_st.getPointer()),</tsoundtrackstereo8signed>
|
|
Shinya Kitaoka |
120a6e |
m_crossFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackCrossFaderOverWrite::compute(
|
|
Shinya Kitaoka |
120a6e |
const TSoundTrackMono8Unsigned &src) {
|
|
Shinya Kitaoka |
120a6e |
assert(src.getFormat() == m_st->getFormat());
|
|
Shinya Kitaoka |
120a6e |
return doCrossFadeOverWrite(
|
|
Shinya Kitaoka |
120a6e |
src, dynamic_cast<tsoundtrackmono8unsigned *="">(m_st.getPointer()),</tsoundtrackmono8unsigned>
|
|
Shinya Kitaoka |
120a6e |
m_crossFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackCrossFaderOverWrite::compute(
|
|
Shinya Kitaoka |
120a6e |
const TSoundTrackStereo8Unsigned &src) {
|
|
Shinya Kitaoka |
120a6e |
assert(src.getFormat() == m_st->getFormat());
|
|
Shinya Kitaoka |
120a6e |
return doCrossFadeOverWrite(
|
|
Shinya Kitaoka |
120a6e |
src, dynamic_cast<tsoundtrackstereo8unsigned *="">(m_st.getPointer()),</tsoundtrackstereo8unsigned>
|
|
Shinya Kitaoka |
120a6e |
m_crossFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackCrossFaderOverWrite::compute(
|
|
Shinya Kitaoka |
120a6e |
const TSoundTrackMono16 &src) {
|
|
Shinya Kitaoka |
120a6e |
assert(src.getFormat() == m_st->getFormat());
|
|
Shinya Kitaoka |
120a6e |
return doCrossFadeOverWrite(
|
|
Shinya Kitaoka |
120a6e |
src, dynamic_cast<tsoundtrackmono16 *="">(m_st.getPointer()), m_crossFactor);</tsoundtrackmono16>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackCrossFaderOverWrite::compute(
|
|
Shinya Kitaoka |
120a6e |
const TSoundTrackStereo16 &src) {
|
|
Shinya Kitaoka |
120a6e |
assert(src.getFormat() == m_st->getFormat());
|
|
Shinya Kitaoka |
120a6e |
return doCrossFadeOverWrite(
|
|
Shinya Kitaoka |
120a6e |
src, dynamic_cast<tsoundtrackstereo16 *="">(m_st.getPointer()),</tsoundtrackstereo16>
|
|
Shinya Kitaoka |
120a6e |
m_crossFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackCrossFaderOverWrite::compute(
|
|
Shinya Kitaoka |
120a6e |
const TSoundTrackMono24 &src) {
|
|
Shinya Kitaoka |
120a6e |
assert(src.getFormat() == m_st->getFormat());
|
|
Shinya Kitaoka |
120a6e |
return doCrossFadeOverWrite(
|
|
Shinya Kitaoka |
120a6e |
src, dynamic_cast<tsoundtrackmono24 *="">(m_st.getPointer()), m_crossFactor);</tsoundtrackmono24>
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSoundTrackCrossFaderOverWrite::compute(
|
|
Shinya Kitaoka |
120a6e |
const TSoundTrackStereo24 &src) {
|
|
Shinya Kitaoka |
120a6e |
assert(src.getFormat() == m_st->getFormat());
|
|
Shinya Kitaoka |
120a6e |
return doCrossFadeOverWrite(
|
|
Shinya Kitaoka |
120a6e |
src, dynamic_cast<tsoundtrackstereo24 *="">(m_st.getPointer()),</tsoundtrackstereo24>
|
|
Shinya Kitaoka |
120a6e |
m_crossFactor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//------------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP TSop::crossFade(double crossFactor, const TSoundTrackP src1,
|
|
Shinya Kitaoka |
120a6e |
const TSoundTrackP src2) {
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackCrossFaderOverWrite *fader =
|
|
Shinya Kitaoka |
120a6e |
new TSoundTrackCrossFaderOverWrite(src2, crossFactor);
|
|
Shinya Kitaoka |
120a6e |
TSoundTrackP out = src1->apply(fader);
|
|
Shinya Kitaoka |
120a6e |
delete fader;
|
|
Shinya Kitaoka |
120a6e |
return out;
|
|
Toshihiro Shimizu |
890ddd |
}
|