diff options
Diffstat (limited to 'dom/media/webaudio/blink')
38 files changed, 6234 insertions, 0 deletions
diff --git a/dom/media/webaudio/blink/Biquad.cpp b/dom/media/webaudio/blink/Biquad.cpp new file mode 100644 index 000000000..3aa526072 --- /dev/null +++ b/dom/media/webaudio/blink/Biquad.cpp @@ -0,0 +1,469 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "Biquad.h" + +#include <float.h> +#include <algorithm> +#include <math.h> + +namespace WebCore { + +Biquad::Biquad() +{ + // Initialize as pass-thru (straight-wire, no filter effect) + setNormalizedCoefficients(1, 0, 0, 1, 0, 0); + + reset(); // clear filter memory +} + +Biquad::~Biquad() +{ +} + +void Biquad::process(const float* sourceP, float* destP, size_t framesToProcess) +{ + // Create local copies of member variables + double x1 = m_x1; + double x2 = m_x2; + double y1 = m_y1; + double y2 = m_y2; + + double b0 = m_b0; + double b1 = m_b1; + double b2 = m_b2; + double a1 = m_a1; + double a2 = m_a2; + + for (size_t i = 0; i < framesToProcess; ++i) { + // FIXME: this can be optimized by pipelining the multiply adds... + double x = sourceP[i]; + double y = b0*x + b1*x1 + b2*x2 - a1*y1 - a2*y2; + + destP[i] = y; + + // Update state variables + x2 = x1; + x1 = x; + y2 = y1; + y1 = y; + } + + // Avoid introducing a stream of subnormals when input is silent and the + // tail approaches zero. + // TODO: Remove this code when Bug 1157635 is fixed. + if (x1 == 0.0 && x2 == 0.0 && (y1 != 0.0 || y2 != 0.0) && + fabs(y1) < FLT_MIN && fabs(y2) < FLT_MIN) { + // Flush future values to zero (until there is new input). + y1 = y2 = 0.0; + // Flush calculated values. + for (int i = framesToProcess; i-- && fabsf(destP[i]) < FLT_MIN; ) { + destP[i] = 0.0f; + } + } + // Local variables back to member. + m_x1 = x1; + m_x2 = x2; + m_y1 = y1; + m_y2 = y2; +} + +void Biquad::reset() +{ + m_x1 = m_x2 = m_y1 = m_y2 = 0; +} + +void Biquad::setLowpassParams(double cutoff, double resonance) +{ + // Limit cutoff to 0 to 1. + cutoff = std::max(0.0, std::min(cutoff, 1.0)); + + if (cutoff == 1) { + // When cutoff is 1, the z-transform is 1. + setNormalizedCoefficients(1, 0, 0, + 1, 0, 0); + } else if (cutoff > 0) { + // Compute biquad coefficients for lowpass filter + resonance = std::max(0.0, resonance); // can't go negative + double g = pow(10.0, -0.05 * resonance); + double w0 = M_PI * cutoff; + double cos_w0 = cos(w0); + double alpha = 0.5 * sin(w0) * g; + + double b1 = 1.0 - cos_w0; + double b0 = 0.5 * b1; + double b2 = b0; + double a0 = 1.0 + alpha; + double a1 = -2.0 * cos_w0; + double a2 = 1.0 - alpha; + + setNormalizedCoefficients(b0, b1, b2, a0, a1, a2); + } else { + // When cutoff is zero, nothing gets through the filter, so set + // coefficients up correctly. + setNormalizedCoefficients(0, 0, 0, + 1, 0, 0); + } +} + +void Biquad::setHighpassParams(double cutoff, double resonance) +{ + // Limit cutoff to 0 to 1. + cutoff = std::max(0.0, std::min(cutoff, 1.0)); + + if (cutoff == 1) { + // The z-transform is 0. + setNormalizedCoefficients(0, 0, 0, + 1, 0, 0); + } else if (cutoff > 0) { + // Compute biquad coefficients for highpass filter + resonance = std::max(0.0, resonance); // can't go negative + double g = pow(10.0, -0.05 * resonance); + double w0 = M_PI * cutoff; + double cos_w0 = cos(w0); + double alpha = 0.5 * sin(w0) * g; + + double b1 = -1.0 - cos_w0; + double b0 = -0.5 * b1; + double b2 = b0; + double a0 = 1.0 + alpha; + double a1 = -2.0 * cos_w0; + double a2 = 1.0 - alpha; + + setNormalizedCoefficients(b0, b1, b2, a0, a1, a2); + } else { + // When cutoff is zero, we need to be careful because the above + // gives a quadratic divided by the same quadratic, with poles + // and zeros on the unit circle in the same place. When cutoff + // is zero, the z-transform is 1. + setNormalizedCoefficients(1, 0, 0, + 1, 0, 0); + } +} + +void Biquad::setNormalizedCoefficients(double b0, double b1, double b2, double a0, double a1, double a2) +{ + double a0Inverse = 1 / a0; + + m_b0 = b0 * a0Inverse; + m_b1 = b1 * a0Inverse; + m_b2 = b2 * a0Inverse; + m_a1 = a1 * a0Inverse; + m_a2 = a2 * a0Inverse; +} + +void Biquad::setLowShelfParams(double frequency, double dbGain) +{ + // Clip frequencies to between 0 and 1, inclusive. + frequency = std::max(0.0, std::min(frequency, 1.0)); + + double A = pow(10.0, dbGain / 40); + + if (frequency == 1) { + // The z-transform is a constant gain. + setNormalizedCoefficients(A * A, 0, 0, + 1, 0, 0); + } else if (frequency > 0) { + double w0 = M_PI * frequency; + double S = 1; // filter slope (1 is max value) + double alpha = 0.5 * sin(w0) * sqrt((A + 1 / A) * (1 / S - 1) + 2); + double k = cos(w0); + double k2 = 2 * sqrt(A) * alpha; + double aPlusOne = A + 1; + double aMinusOne = A - 1; + + double b0 = A * (aPlusOne - aMinusOne * k + k2); + double b1 = 2 * A * (aMinusOne - aPlusOne * k); + double b2 = A * (aPlusOne - aMinusOne * k - k2); + double a0 = aPlusOne + aMinusOne * k + k2; + double a1 = -2 * (aMinusOne + aPlusOne * k); + double a2 = aPlusOne + aMinusOne * k - k2; + + setNormalizedCoefficients(b0, b1, b2, a0, a1, a2); + } else { + // When frequency is 0, the z-transform is 1. + setNormalizedCoefficients(1, 0, 0, + 1, 0, 0); + } +} + +void Biquad::setHighShelfParams(double frequency, double dbGain) +{ + // Clip frequencies to between 0 and 1, inclusive. + frequency = std::max(0.0, std::min(frequency, 1.0)); + + double A = pow(10.0, dbGain / 40); + + if (frequency == 1) { + // The z-transform is 1. + setNormalizedCoefficients(1, 0, 0, + 1, 0, 0); + } else if (frequency > 0) { + double w0 = M_PI * frequency; + double S = 1; // filter slope (1 is max value) + double alpha = 0.5 * sin(w0) * sqrt((A + 1 / A) * (1 / S - 1) + 2); + double k = cos(w0); + double k2 = 2 * sqrt(A) * alpha; + double aPlusOne = A + 1; + double aMinusOne = A - 1; + + double b0 = A * (aPlusOne + aMinusOne * k + k2); + double b1 = -2 * A * (aMinusOne + aPlusOne * k); + double b2 = A * (aPlusOne + aMinusOne * k - k2); + double a0 = aPlusOne - aMinusOne * k + k2; + double a1 = 2 * (aMinusOne - aPlusOne * k); + double a2 = aPlusOne - aMinusOne * k - k2; + + setNormalizedCoefficients(b0, b1, b2, a0, a1, a2); + } else { + // When frequency = 0, the filter is just a gain, A^2. + setNormalizedCoefficients(A * A, 0, 0, + 1, 0, 0); + } +} + +void Biquad::setPeakingParams(double frequency, double Q, double dbGain) +{ + // Clip frequencies to between 0 and 1, inclusive. + frequency = std::max(0.0, std::min(frequency, 1.0)); + + // Don't let Q go negative, which causes an unstable filter. + Q = std::max(0.0, Q); + + double A = pow(10.0, dbGain / 40); + + if (frequency > 0 && frequency < 1) { + if (Q > 0) { + double w0 = M_PI * frequency; + double alpha = sin(w0) / (2 * Q); + double k = cos(w0); + + double b0 = 1 + alpha * A; + double b1 = -2 * k; + double b2 = 1 - alpha * A; + double a0 = 1 + alpha / A; + double a1 = -2 * k; + double a2 = 1 - alpha / A; + + setNormalizedCoefficients(b0, b1, b2, a0, a1, a2); + } else { + // When Q = 0, the above formulas have problems. If we look at + // the z-transform, we can see that the limit as Q->0 is A^2, so + // set the filter that way. + setNormalizedCoefficients(A * A, 0, 0, + 1, 0, 0); + } + } else { + // When frequency is 0 or 1, the z-transform is 1. + setNormalizedCoefficients(1, 0, 0, + 1, 0, 0); + } +} + +void Biquad::setAllpassParams(double frequency, double Q) +{ + // Clip frequencies to between 0 and 1, inclusive. + frequency = std::max(0.0, std::min(frequency, 1.0)); + + // Don't let Q go negative, which causes an unstable filter. + Q = std::max(0.0, Q); + + if (frequency > 0 && frequency < 1) { + if (Q > 0) { + double w0 = M_PI * frequency; + double alpha = sin(w0) / (2 * Q); + double k = cos(w0); + + double b0 = 1 - alpha; + double b1 = -2 * k; + double b2 = 1 + alpha; + double a0 = 1 + alpha; + double a1 = -2 * k; + double a2 = 1 - alpha; + + setNormalizedCoefficients(b0, b1, b2, a0, a1, a2); + } else { + // When Q = 0, the above formulas have problems. If we look at + // the z-transform, we can see that the limit as Q->0 is -1, so + // set the filter that way. + setNormalizedCoefficients(-1, 0, 0, + 1, 0, 0); + } + } else { + // When frequency is 0 or 1, the z-transform is 1. + setNormalizedCoefficients(1, 0, 0, + 1, 0, 0); + } +} + +void Biquad::setNotchParams(double frequency, double Q) +{ + // Clip frequencies to between 0 and 1, inclusive. + frequency = std::max(0.0, std::min(frequency, 1.0)); + + // Don't let Q go negative, which causes an unstable filter. + Q = std::max(0.0, Q); + + if (frequency > 0 && frequency < 1) { + if (Q > 0) { + double w0 = M_PI * frequency; + double alpha = sin(w0) / (2 * Q); + double k = cos(w0); + + double b0 = 1; + double b1 = -2 * k; + double b2 = 1; + double a0 = 1 + alpha; + double a1 = -2 * k; + double a2 = 1 - alpha; + + setNormalizedCoefficients(b0, b1, b2, a0, a1, a2); + } else { + // When Q = 0, the above formulas have problems. If we look at + // the z-transform, we can see that the limit as Q->0 is 0, so + // set the filter that way. + setNormalizedCoefficients(0, 0, 0, + 1, 0, 0); + } + } else { + // When frequency is 0 or 1, the z-transform is 1. + setNormalizedCoefficients(1, 0, 0, + 1, 0, 0); + } +} + +void Biquad::setBandpassParams(double frequency, double Q) +{ + // No negative frequencies allowed. + frequency = std::max(0.0, frequency); + + // Don't let Q go negative, which causes an unstable filter. + Q = std::max(0.0, Q); + + if (frequency > 0 && frequency < 1) { + double w0 = M_PI * frequency; + if (Q > 0) { + double alpha = sin(w0) / (2 * Q); + double k = cos(w0); + + double b0 = alpha; + double b1 = 0; + double b2 = -alpha; + double a0 = 1 + alpha; + double a1 = -2 * k; + double a2 = 1 - alpha; + + setNormalizedCoefficients(b0, b1, b2, a0, a1, a2); + } else { + // When Q = 0, the above formulas have problems. If we look at + // the z-transform, we can see that the limit as Q->0 is 1, so + // set the filter that way. + setNormalizedCoefficients(1, 0, 0, + 1, 0, 0); + } + } else { + // When the cutoff is zero, the z-transform approaches 0, if Q + // > 0. When both Q and cutoff are zero, the z-transform is + // pretty much undefined. What should we do in this case? + // For now, just make the filter 0. When the cutoff is 1, the + // z-transform also approaches 0. + setNormalizedCoefficients(0, 0, 0, + 1, 0, 0); + } +} + +void Biquad::setZeroPolePairs(const Complex &zero, const Complex &pole) +{ + double b0 = 1; + double b1 = -2 * zero.real(); + + double zeroMag = abs(zero); + double b2 = zeroMag * zeroMag; + + double a1 = -2 * pole.real(); + + double poleMag = abs(pole); + double a2 = poleMag * poleMag; + setNormalizedCoefficients(b0, b1, b2, 1, a1, a2); +} + +void Biquad::setAllpassPole(const Complex &pole) +{ + Complex zero = Complex(1, 0) / pole; + setZeroPolePairs(zero, pole); +} + +void Biquad::getFrequencyResponse(int nFrequencies, + const float* frequency, + float* magResponse, + float* phaseResponse) +{ + // Evaluate the Z-transform of the filter at given normalized + // frequency from 0 to 1. (1 corresponds to the Nyquist + // frequency.) + // + // The z-transform of the filter is + // + // H(z) = (b0 + b1*z^(-1) + b2*z^(-2))/(1 + a1*z^(-1) + a2*z^(-2)) + // + // Evaluate as + // + // b0 + (b1 + b2*z1)*z1 + // -------------------- + // 1 + (a1 + a2*z1)*z1 + // + // with z1 = 1/z and z = exp(j*pi*frequency). Hence z1 = exp(-j*pi*frequency) + + // Make local copies of the coefficients as a micro-optimization. + double b0 = m_b0; + double b1 = m_b1; + double b2 = m_b2; + double a1 = m_a1; + double a2 = m_a2; + + for (int k = 0; k < nFrequencies; ++k) { + double omega = -M_PI * frequency[k]; + Complex z = Complex(cos(omega), sin(omega)); + Complex numerator = b0 + (b1 + b2 * z) * z; + Complex denominator = Complex(1, 0) + (a1 + a2 * z) * z; + // Strangely enough, using complex division: + // e.g. Complex response = numerator / denominator; + // fails on our test machines, yielding infinities and NaNs, so we do + // things the long way here. + double n = norm(denominator); + double r = (real(numerator)*real(denominator) + imag(numerator)*imag(denominator)) / n; + double i = (imag(numerator)*real(denominator) - real(numerator)*imag(denominator)) / n; + std::complex<double> response = std::complex<double>(r, i); + + magResponse[k] = static_cast<float>(abs(response)); + phaseResponse[k] = static_cast<float>(atan2(imag(response), real(response))); + } +} + +} // namespace WebCore + diff --git a/dom/media/webaudio/blink/Biquad.h b/dom/media/webaudio/blink/Biquad.h new file mode 100644 index 000000000..f266af441 --- /dev/null +++ b/dom/media/webaudio/blink/Biquad.h @@ -0,0 +1,108 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef Biquad_h +#define Biquad_h + +#include <complex> + +namespace WebCore { + +typedef std::complex<double> Complex; + +// A basic biquad (two-zero / two-pole digital filter) +// +// It can be configured to a number of common and very useful filters: +// lowpass, highpass, shelving, parameteric, notch, allpass, ... + +class Biquad { +public: + Biquad(); + ~Biquad(); + + void process(const float* sourceP, float* destP, size_t framesToProcess); + + // frequency is 0 - 1 normalized, resonance and dbGain are in decibels. + // Q is a unitless quality factor. + void setLowpassParams(double frequency, double resonance); + void setHighpassParams(double frequency, double resonance); + void setBandpassParams(double frequency, double Q); + void setLowShelfParams(double frequency, double dbGain); + void setHighShelfParams(double frequency, double dbGain); + void setPeakingParams(double frequency, double Q, double dbGain); + void setAllpassParams(double frequency, double Q); + void setNotchParams(double frequency, double Q); + + // Set the biquad coefficients given a single zero (other zero will be conjugate) + // and a single pole (other pole will be conjugate) + void setZeroPolePairs(const Complex& zero, const Complex& pole); + + // Set the biquad coefficients given a single pole (other pole will be conjugate) + // (The zeroes will be the inverse of the poles) + void setAllpassPole(const Complex& pole); + + // Return true iff the next output block will contain sound even with + // silent input. + bool hasTail() const { return m_y1 || m_y2 || m_x1 || m_x2; } + + // Resets filter state + void reset(); + + // Filter response at a set of n frequencies. The magnitude and + // phase response are returned in magResponse and phaseResponse. + // The phase response is in radians. + void getFrequencyResponse(int nFrequencies, + const float* frequency, + float* magResponse, + float* phaseResponse); +private: + void setNormalizedCoefficients(double b0, double b1, double b2, double a0, double a1, double a2); + + // Filter coefficients. The filter is defined as + // + // y[n] + m_a1*y[n-1] + m_a2*y[n-2] = m_b0*x[n] + m_b1*x[n-1] + m_b2*x[n-2]. + double m_b0; + double m_b1; + double m_b2; + double m_a1; + double m_a2; + + // Filter memory + // + // Double precision for the output values is valuable because errors can + // accumulate. Input values are also stored as double so they need not be + // converted again for computation. + double m_x1; // input delayed by 1 sample + double m_x2; // input delayed by 2 samples + double m_y1; // output delayed by 1 sample + double m_y2; // output delayed by 2 samples +}; + +} // namespace WebCore + +#endif // Biquad_h diff --git a/dom/media/webaudio/blink/DenormalDisabler.h b/dom/media/webaudio/blink/DenormalDisabler.h new file mode 100644 index 000000000..241220732 --- /dev/null +++ b/dom/media/webaudio/blink/DenormalDisabler.h @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2011, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DenormalDisabler_h +#define DenormalDisabler_h + +#include <cmath> +#include <float.h> + +namespace WebCore { + +// Deal with denormals. They can very seriously impact performance on x86. + +// Define HAVE_DENORMAL if we support flushing denormals to zero. +#if defined(XP_WIN) && defined(_MSC_VER) +#define HAVE_DENORMAL +#endif + +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) +#define HAVE_DENORMAL +#endif + +#ifdef HAVE_DENORMAL +class DenormalDisabler { +public: + DenormalDisabler() + : m_savedCSR(0) + { +#if defined(XP_WIN) && defined(_MSC_VER) + // Save the current state, and set mode to flush denormals. + // + // http://stackoverflow.com/questions/637175/possible-bug-in-controlfp-s-may-not-restore-control-word-correctly + _controlfp_s(&m_savedCSR, 0, 0); + unsigned int unused; + _controlfp_s(&unused, _DN_FLUSH, _MCW_DN); +#else + m_savedCSR = getCSR(); + setCSR(m_savedCSR | 0x8040); +#endif + } + + ~DenormalDisabler() + { +#if defined(XP_WIN) && defined(_MSC_VER) + unsigned int unused; + _controlfp_s(&unused, m_savedCSR, _MCW_DN); +#else + setCSR(m_savedCSR); +#endif + } + + // This is a nop if we can flush denormals to zero in hardware. + static inline float flushDenormalFloatToZero(float f) + { +#if defined(XP_WIN) && defined(_MSC_VER) && _M_IX86_FP + // For systems using x87 instead of sse, there's no hardware support + // to flush denormals automatically. Hence, we need to flush + // denormals to zero manually. + return (fabs(f) < FLT_MIN) ? 0.0f : f; +#else + return f; +#endif + } +private: +#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) + inline int getCSR() + { + int result; + asm volatile("stmxcsr %0" : "=m" (result)); + return result; + } + + inline void setCSR(int a) + { + int temp = a; + asm volatile("ldmxcsr %0" : : "m" (temp)); + } + +#endif + + unsigned int m_savedCSR; +}; + +#else +// FIXME: add implementations for other architectures and compilers +class DenormalDisabler { +public: + DenormalDisabler() { } + + // Assume the worst case that other architectures and compilers + // need to flush denormals to zero manually. + static inline float flushDenormalFloatToZero(float f) + { + return (fabs(f) < FLT_MIN) ? 0.0f : f; + } +}; + +#endif + +} // namespace WebCore + +#undef HAVE_DENORMAL +#endif // DenormalDisabler_h diff --git a/dom/media/webaudio/blink/DynamicsCompressor.cpp b/dom/media/webaudio/blink/DynamicsCompressor.cpp new file mode 100644 index 000000000..8f18913c0 --- /dev/null +++ b/dom/media/webaudio/blink/DynamicsCompressor.cpp @@ -0,0 +1,321 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "DynamicsCompressor.h" +#include "AlignmentUtils.h" +#include "AudioBlock.h" + +#include <cmath> +#include "AudioNodeEngine.h" +#include "nsDebug.h" + +using mozilla::WEBAUDIO_BLOCK_SIZE; +using mozilla::AudioBlockCopyChannelWithScale; + +namespace WebCore { + +DynamicsCompressor::DynamicsCompressor(float sampleRate, unsigned numberOfChannels) + : m_numberOfChannels(numberOfChannels) + , m_sampleRate(sampleRate) + , m_compressor(sampleRate, numberOfChannels) +{ + // Uninitialized state - for parameter recalculation. + m_lastFilterStageRatio = -1; + m_lastAnchor = -1; + m_lastFilterStageGain = -1; + + setNumberOfChannels(numberOfChannels); + initializeParameters(); +} + +size_t DynamicsCompressor::sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const +{ + size_t amount = aMallocSizeOf(this); + amount += m_preFilterPacks.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (size_t i = 0; i < m_preFilterPacks.Length(); i++) { + if (m_preFilterPacks[i]) { + amount += m_preFilterPacks[i]->sizeOfIncludingThis(aMallocSizeOf); + } + } + + amount += m_postFilterPacks.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (size_t i = 0; i < m_postFilterPacks.Length(); i++) { + if (m_postFilterPacks[i]) { + amount += m_postFilterPacks[i]->sizeOfIncludingThis(aMallocSizeOf); + } + } + + amount += aMallocSizeOf(m_sourceChannels.get()); + amount += aMallocSizeOf(m_destinationChannels.get()); + amount += m_compressor.sizeOfExcludingThis(aMallocSizeOf); + return amount; +} + +void DynamicsCompressor::setParameterValue(unsigned parameterID, float value) +{ + MOZ_ASSERT(parameterID < ParamLast); + if (parameterID < ParamLast) + m_parameters[parameterID] = value; +} + +void DynamicsCompressor::initializeParameters() +{ + // Initializes compressor to default values. + + m_parameters[ParamThreshold] = -24; // dB + m_parameters[ParamKnee] = 30; // dB + m_parameters[ParamRatio] = 12; // unit-less + m_parameters[ParamAttack] = 0.003f; // seconds + m_parameters[ParamRelease] = 0.250f; // seconds + m_parameters[ParamPreDelay] = 0.006f; // seconds + + // Release zone values 0 -> 1. + m_parameters[ParamReleaseZone1] = 0.09f; + m_parameters[ParamReleaseZone2] = 0.16f; + m_parameters[ParamReleaseZone3] = 0.42f; + m_parameters[ParamReleaseZone4] = 0.98f; + + m_parameters[ParamFilterStageGain] = 4.4f; // dB + m_parameters[ParamFilterStageRatio] = 2; + m_parameters[ParamFilterAnchor] = 15000 / nyquist(); + + m_parameters[ParamPostGain] = 0; // dB + m_parameters[ParamReduction] = 0; // dB + + // Linear crossfade (0 -> 1). + m_parameters[ParamEffectBlend] = 1; +} + +float DynamicsCompressor::parameterValue(unsigned parameterID) +{ + MOZ_ASSERT(parameterID < ParamLast); + return m_parameters[parameterID]; +} + +void DynamicsCompressor::setEmphasisStageParameters(unsigned stageIndex, float gain, float normalizedFrequency /* 0 -> 1 */) +{ + float gk = 1 - gain / 20; + float f1 = normalizedFrequency * gk; + float f2 = normalizedFrequency / gk; + float r1 = expf(-f1 * M_PI); + float r2 = expf(-f2 * M_PI); + + MOZ_ASSERT(m_numberOfChannels == m_preFilterPacks.Length()); + + for (unsigned i = 0; i < m_numberOfChannels; ++i) { + // Set pre-filter zero and pole to create an emphasis filter. + ZeroPole& preFilter = m_preFilterPacks[i]->filters[stageIndex]; + preFilter.setZero(r1); + preFilter.setPole(r2); + + // Set post-filter with zero and pole reversed to create the de-emphasis filter. + // If there were no compressor kernel in between, they would cancel each other out (allpass filter). + ZeroPole& postFilter = m_postFilterPacks[i]->filters[stageIndex]; + postFilter.setZero(r2); + postFilter.setPole(r1); + } +} + +void DynamicsCompressor::setEmphasisParameters(float gain, float anchorFreq, float filterStageRatio) +{ + setEmphasisStageParameters(0, gain, anchorFreq); + setEmphasisStageParameters(1, gain, anchorFreq / filterStageRatio); + setEmphasisStageParameters(2, gain, anchorFreq / (filterStageRatio * filterStageRatio)); + setEmphasisStageParameters(3, gain, anchorFreq / (filterStageRatio * filterStageRatio * filterStageRatio)); +} + +void DynamicsCompressor::process(const AudioBlock* sourceChunk, AudioBlock* destinationChunk, unsigned framesToProcess) +{ + // Though numberOfChannels is retrived from destinationBus, we still name it numberOfChannels instead of numberOfDestinationChannels. + // It's because we internally match sourceChannels's size to destinationBus by channel up/down mix. Thus we need numberOfChannels + // to do the loop work for both m_sourceChannels and m_destinationChannels. + + unsigned numberOfChannels = destinationChunk->ChannelCount(); + unsigned numberOfSourceChannels = sourceChunk->ChannelCount(); + + MOZ_ASSERT(numberOfChannels == m_numberOfChannels && numberOfSourceChannels); + + if (numberOfChannels != m_numberOfChannels || !numberOfSourceChannels) { + destinationChunk->SetNull(WEBAUDIO_BLOCK_SIZE); + return; + } + + switch (numberOfChannels) { + case 2: // stereo + m_sourceChannels[0] = static_cast<const float*>(sourceChunk->mChannelData[0]); + + if (numberOfSourceChannels > 1) + m_sourceChannels[1] = static_cast<const float*>(sourceChunk->mChannelData[1]); + else + // Simply duplicate mono channel input data to right channel for stereo processing. + m_sourceChannels[1] = m_sourceChannels[0]; + + break; + default: + // FIXME : support other number of channels. + NS_WARNING("Support other number of channels"); + destinationChunk->SetNull(WEBAUDIO_BLOCK_SIZE); + return; + } + + for (unsigned i = 0; i < numberOfChannels; ++i) + m_destinationChannels[i] = const_cast<float*>(static_cast<const float*>( + destinationChunk->mChannelData[i])); + + float filterStageGain = parameterValue(ParamFilterStageGain); + float filterStageRatio = parameterValue(ParamFilterStageRatio); + float anchor = parameterValue(ParamFilterAnchor); + + if (filterStageGain != m_lastFilterStageGain || filterStageRatio != m_lastFilterStageRatio || anchor != m_lastAnchor) { + m_lastFilterStageGain = filterStageGain; + m_lastFilterStageRatio = filterStageRatio; + m_lastAnchor = anchor; + + setEmphasisParameters(filterStageGain, anchor, filterStageRatio); + } + + float sourceWithVolume[WEBAUDIO_BLOCK_SIZE + 4]; + float* alignedSourceWithVolume = ALIGNED16(sourceWithVolume); + ASSERT_ALIGNED16(alignedSourceWithVolume); + + // Apply pre-emphasis filter. + // Note that the final three stages are computed in-place in the destination buffer. + for (unsigned i = 0; i < numberOfChannels; ++i) { + const float* sourceData; + if (sourceChunk->mVolume == 1.0f) { + // Fast path, the volume scale doesn't need to get taken into account + sourceData = m_sourceChannels[i]; + } else { + AudioBlockCopyChannelWithScale(m_sourceChannels[i], + sourceChunk->mVolume, + alignedSourceWithVolume); + sourceData = alignedSourceWithVolume; + } + + float* destinationData = m_destinationChannels[i]; + ZeroPole* preFilters = m_preFilterPacks[i]->filters; + + preFilters[0].process(sourceData, destinationData, framesToProcess); + preFilters[1].process(destinationData, destinationData, framesToProcess); + preFilters[2].process(destinationData, destinationData, framesToProcess); + preFilters[3].process(destinationData, destinationData, framesToProcess); + } + + float dbThreshold = parameterValue(ParamThreshold); + float dbKnee = parameterValue(ParamKnee); + float ratio = parameterValue(ParamRatio); + float attackTime = parameterValue(ParamAttack); + float releaseTime = parameterValue(ParamRelease); + float preDelayTime = parameterValue(ParamPreDelay); + + // This is effectively a master volume on the compressed signal (pre-blending). + float dbPostGain = parameterValue(ParamPostGain); + + // Linear blending value from dry to completely processed (0 -> 1) + // 0 means the signal is completely unprocessed. + // 1 mixes in only the compressed signal. + float effectBlend = parameterValue(ParamEffectBlend); + + float releaseZone1 = parameterValue(ParamReleaseZone1); + float releaseZone2 = parameterValue(ParamReleaseZone2); + float releaseZone3 = parameterValue(ParamReleaseZone3); + float releaseZone4 = parameterValue(ParamReleaseZone4); + + // Apply compression to the pre-filtered signal. + // The processing is performed in place. + m_compressor.process(m_destinationChannels.get(), + m_destinationChannels.get(), + numberOfChannels, + framesToProcess, + + dbThreshold, + dbKnee, + ratio, + attackTime, + releaseTime, + preDelayTime, + dbPostGain, + effectBlend, + + releaseZone1, + releaseZone2, + releaseZone3, + releaseZone4 + ); + + // Update the compression amount. + setParameterValue(ParamReduction, m_compressor.meteringGain()); + + // Apply de-emphasis filter. + for (unsigned i = 0; i < numberOfChannels; ++i) { + float* destinationData = m_destinationChannels[i]; + ZeroPole* postFilters = m_postFilterPacks[i]->filters; + + postFilters[0].process(destinationData, destinationData, framesToProcess); + postFilters[1].process(destinationData, destinationData, framesToProcess); + postFilters[2].process(destinationData, destinationData, framesToProcess); + postFilters[3].process(destinationData, destinationData, framesToProcess); + } +} + +void DynamicsCompressor::reset() +{ + m_lastFilterStageRatio = -1; // for recalc + m_lastAnchor = -1; + m_lastFilterStageGain = -1; + + for (unsigned channel = 0; channel < m_numberOfChannels; ++channel) { + for (unsigned stageIndex = 0; stageIndex < 4; ++stageIndex) { + m_preFilterPacks[channel]->filters[stageIndex].reset(); + m_postFilterPacks[channel]->filters[stageIndex].reset(); + } + } + + m_compressor.reset(); +} + +void DynamicsCompressor::setNumberOfChannels(unsigned numberOfChannels) +{ + if (m_preFilterPacks.Length() == numberOfChannels) + return; + + m_preFilterPacks.Clear(); + m_postFilterPacks.Clear(); + for (unsigned i = 0; i < numberOfChannels; ++i) { + m_preFilterPacks.AppendElement(new ZeroPoleFilterPack4()); + m_postFilterPacks.AppendElement(new ZeroPoleFilterPack4()); + } + + m_sourceChannels = mozilla::MakeUnique<const float* []>(numberOfChannels); + m_destinationChannels = mozilla::MakeUnique<float* []>(numberOfChannels); + + m_compressor.setNumberOfChannels(numberOfChannels); + m_numberOfChannels = numberOfChannels; +} + +} // namespace WebCore diff --git a/dom/media/webaudio/blink/DynamicsCompressor.h b/dom/media/webaudio/blink/DynamicsCompressor.h new file mode 100644 index 000000000..f460836b4 --- /dev/null +++ b/dom/media/webaudio/blink/DynamicsCompressor.h @@ -0,0 +1,131 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DynamicsCompressor_h +#define DynamicsCompressor_h + +#include "DynamicsCompressorKernel.h" +#include "ZeroPole.h" + +#include "nsTArray.h" +#include "nsAutoPtr.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/UniquePtr.h" + +namespace mozilla { +class AudioBlock; +} // namespace mozilla + +namespace WebCore { + +using mozilla::AudioBlock; + +// DynamicsCompressor implements a flexible audio dynamics compression effect such as +// is commonly used in musical production and game audio. It lowers the volume +// of the loudest parts of the signal and raises the volume of the softest parts, +// making the sound richer, fuller, and more controlled. + +class DynamicsCompressor { +public: + enum { + ParamThreshold, + ParamKnee, + ParamRatio, + ParamAttack, + ParamRelease, + ParamPreDelay, + ParamReleaseZone1, + ParamReleaseZone2, + ParamReleaseZone3, + ParamReleaseZone4, + ParamPostGain, + ParamFilterStageGain, + ParamFilterStageRatio, + ParamFilterAnchor, + ParamEffectBlend, + ParamReduction, + ParamLast + }; + + DynamicsCompressor(float sampleRate, unsigned numberOfChannels); + + void process(const AudioBlock* sourceChunk, AudioBlock* destinationChunk, unsigned framesToProcess); + void reset(); + void setNumberOfChannels(unsigned); + unsigned numberOfChannels() const { return m_numberOfChannels; } + + void setParameterValue(unsigned parameterID, float value); + float parameterValue(unsigned parameterID); + + float sampleRate() const { return m_sampleRate; } + float nyquist() const { return m_sampleRate / 2; } + + double tailTime() const { return 0; } + double latencyTime() const { return m_compressor.latencyFrames() / static_cast<double>(sampleRate()); } + + size_t sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + +protected: + unsigned m_numberOfChannels; + + // m_parameters holds the tweakable compressor parameters. + float m_parameters[ParamLast]; + void initializeParameters(); + + float m_sampleRate; + + // Emphasis filter controls. + float m_lastFilterStageRatio; + float m_lastAnchor; + float m_lastFilterStageGain; + + typedef struct { + ZeroPole filters[4]; + size_t sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const + { + return aMallocSizeOf(this); + } + } ZeroPoleFilterPack4; + + // Per-channel emphasis filters. + nsTArray<nsAutoPtr<ZeroPoleFilterPack4> > m_preFilterPacks; + nsTArray<nsAutoPtr<ZeroPoleFilterPack4> > m_postFilterPacks; + + mozilla::UniquePtr<const float*[]> m_sourceChannels; + mozilla::UniquePtr<float*[]> m_destinationChannels; + + void setEmphasisStageParameters(unsigned stageIndex, float gain, float normalizedFrequency /* 0 -> 1 */); + void setEmphasisParameters(float gain, float anchorFreq, float filterStageRatio); + + // The core compressor. + DynamicsCompressorKernel m_compressor; +}; + +} // namespace WebCore + +#endif // DynamicsCompressor_h diff --git a/dom/media/webaudio/blink/DynamicsCompressorKernel.cpp b/dom/media/webaudio/blink/DynamicsCompressorKernel.cpp new file mode 100644 index 000000000..e5b4aba2f --- /dev/null +++ b/dom/media/webaudio/blink/DynamicsCompressorKernel.cpp @@ -0,0 +1,491 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "DynamicsCompressorKernel.h" + +#include "DenormalDisabler.h" +#include <algorithm> +#include <cmath> + +#include "mozilla/FloatingPoint.h" +#include "WebAudioUtils.h" + +using namespace std; + +using namespace mozilla::dom; // for WebAudioUtils +using mozilla::IsInfinite; +using mozilla::IsNaN; +using mozilla::MakeUnique; + +namespace WebCore { + + +// Metering hits peaks instantly, but releases this fast (in seconds). +const float meteringReleaseTimeConstant = 0.325f; + +const float uninitializedValue = -1; + +DynamicsCompressorKernel::DynamicsCompressorKernel(float sampleRate, unsigned numberOfChannels) + : m_sampleRate(sampleRate) + , m_lastPreDelayFrames(DefaultPreDelayFrames) + , m_preDelayReadIndex(0) + , m_preDelayWriteIndex(DefaultPreDelayFrames) + , m_ratio(uninitializedValue) + , m_slope(uninitializedValue) + , m_linearThreshold(uninitializedValue) + , m_dbThreshold(uninitializedValue) + , m_dbKnee(uninitializedValue) + , m_kneeThreshold(uninitializedValue) + , m_kneeThresholdDb(uninitializedValue) + , m_ykneeThresholdDb(uninitializedValue) + , m_K(uninitializedValue) +{ + setNumberOfChannels(numberOfChannels); + + // Initializes most member variables + reset(); + + m_meteringReleaseK = + static_cast<float>(WebAudioUtils::DiscreteTimeConstantForSampleRate(meteringReleaseTimeConstant, sampleRate)); +} + +size_t DynamicsCompressorKernel::sizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const +{ + size_t amount = 0; + amount += m_preDelayBuffers.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (size_t i = 0; i < m_preDelayBuffers.Length(); i++) { + amount += aMallocSizeOf(m_preDelayBuffers[i].get()); + } + + return amount; +} + +void DynamicsCompressorKernel::setNumberOfChannels(unsigned numberOfChannels) +{ + if (m_preDelayBuffers.Length() == numberOfChannels) + return; + + m_preDelayBuffers.Clear(); + for (unsigned i = 0; i < numberOfChannels; ++i) + m_preDelayBuffers.AppendElement(MakeUnique<float[]>(MaxPreDelayFrames)); +} + +void DynamicsCompressorKernel::setPreDelayTime(float preDelayTime) +{ + // Re-configure look-ahead section pre-delay if delay time has changed. + unsigned preDelayFrames = preDelayTime * sampleRate(); + if (preDelayFrames > MaxPreDelayFrames - 1) + preDelayFrames = MaxPreDelayFrames - 1; + + if (m_lastPreDelayFrames != preDelayFrames) { + m_lastPreDelayFrames = preDelayFrames; + for (unsigned i = 0; i < m_preDelayBuffers.Length(); ++i) + memset(m_preDelayBuffers[i].get(), 0, sizeof(float) * MaxPreDelayFrames); + + m_preDelayReadIndex = 0; + m_preDelayWriteIndex = preDelayFrames; + } +} + +// Exponential curve for the knee. +// It is 1st derivative matched at m_linearThreshold and asymptotically approaches the value m_linearThreshold + 1 / k. +float DynamicsCompressorKernel::kneeCurve(float x, float k) +{ + // Linear up to threshold. + if (x < m_linearThreshold) + return x; + + return m_linearThreshold + (1 - expf(-k * (x - m_linearThreshold))) / k; +} + +// Full compression curve with constant ratio after knee. +float DynamicsCompressorKernel::saturate(float x, float k) +{ + float y; + + if (x < m_kneeThreshold) + y = kneeCurve(x, k); + else { + // Constant ratio after knee. + float xDb = WebAudioUtils::ConvertLinearToDecibels(x, -1000.0f); + float yDb = m_ykneeThresholdDb + m_slope * (xDb - m_kneeThresholdDb); + + y = WebAudioUtils::ConvertDecibelsToLinear(yDb); + } + + return y; +} + +// Approximate 1st derivative with input and output expressed in dB. +// This slope is equal to the inverse of the compression "ratio". +// In other words, a compression ratio of 20 would be a slope of 1/20. +float DynamicsCompressorKernel::slopeAt(float x, float k) +{ + if (x < m_linearThreshold) + return 1; + + float x2 = x * 1.001; + + float xDb = WebAudioUtils::ConvertLinearToDecibels(x, -1000.0f); + float x2Db = WebAudioUtils::ConvertLinearToDecibels(x2, -1000.0f); + + float yDb = WebAudioUtils::ConvertLinearToDecibels(kneeCurve(x, k), -1000.0f); + float y2Db = WebAudioUtils::ConvertLinearToDecibels(kneeCurve(x2, k), -1000.0f); + + float m = (y2Db - yDb) / (x2Db - xDb); + + return m; +} + +float DynamicsCompressorKernel::kAtSlope(float desiredSlope) +{ + float xDb = m_dbThreshold + m_dbKnee; + float x = WebAudioUtils::ConvertDecibelsToLinear(xDb); + + // Approximate k given initial values. + float minK = 0.1f; + float maxK = 10000; + float k = 5; + + for (int i = 0; i < 15; ++i) { + // A high value for k will more quickly asymptotically approach a slope of 0. + float slope = slopeAt(x, k); + + if (slope < desiredSlope) { + // k is too high. + maxK = k; + } else { + // k is too low. + minK = k; + } + + // Re-calculate based on geometric mean. + k = sqrtf(minK * maxK); + } + + return k; +} + +float DynamicsCompressorKernel::updateStaticCurveParameters(float dbThreshold, float dbKnee, float ratio) +{ + if (dbThreshold != m_dbThreshold || dbKnee != m_dbKnee || ratio != m_ratio) { + // Threshold and knee. + m_dbThreshold = dbThreshold; + m_linearThreshold = WebAudioUtils::ConvertDecibelsToLinear(dbThreshold); + m_dbKnee = dbKnee; + + // Compute knee parameters. + m_ratio = ratio; + m_slope = 1 / m_ratio; + + float k = kAtSlope(1 / m_ratio); + + m_kneeThresholdDb = dbThreshold + dbKnee; + m_kneeThreshold = WebAudioUtils::ConvertDecibelsToLinear(m_kneeThresholdDb); + + m_ykneeThresholdDb = WebAudioUtils::ConvertLinearToDecibels(kneeCurve(m_kneeThreshold, k), -1000.0f); + + m_K = k; + } + return m_K; +} + +void DynamicsCompressorKernel::process(float* sourceChannels[], + float* destinationChannels[], + unsigned numberOfChannels, + unsigned framesToProcess, + + float dbThreshold, + float dbKnee, + float ratio, + float attackTime, + float releaseTime, + float preDelayTime, + float dbPostGain, + float effectBlend, /* equal power crossfade */ + + float releaseZone1, + float releaseZone2, + float releaseZone3, + float releaseZone4 + ) +{ + MOZ_ASSERT(m_preDelayBuffers.Length() == numberOfChannels); + + float sampleRate = this->sampleRate(); + + float dryMix = 1 - effectBlend; + float wetMix = effectBlend; + + float k = updateStaticCurveParameters(dbThreshold, dbKnee, ratio); + + // Makeup gain. + float fullRangeGain = saturate(1, k); + float fullRangeMakeupGain = 1 / fullRangeGain; + + // Empirical/perceptual tuning. + fullRangeMakeupGain = powf(fullRangeMakeupGain, 0.6f); + + float masterLinearGain = WebAudioUtils::ConvertDecibelsToLinear(dbPostGain) * fullRangeMakeupGain; + + // Attack parameters. + attackTime = max(0.001f, attackTime); + float attackFrames = attackTime * sampleRate; + + // Release parameters. + float releaseFrames = sampleRate * releaseTime; + + // Detector release time. + float satReleaseTime = 0.0025f; + float satReleaseFrames = satReleaseTime * sampleRate; + + // Create a smooth function which passes through four points. + + // Polynomial of the form + // y = a + b*x + c*x^2 + d*x^3 + e*x^4; + + float y1 = releaseFrames * releaseZone1; + float y2 = releaseFrames * releaseZone2; + float y3 = releaseFrames * releaseZone3; + float y4 = releaseFrames * releaseZone4; + + // All of these coefficients were derived for 4th order polynomial curve fitting where the y values + // match the evenly spaced x values as follows: (y1 : x == 0, y2 : x == 1, y3 : x == 2, y4 : x == 3) + float kA = 0.9999999999999998f*y1 + 1.8432219684323923e-16f*y2 - 1.9373394351676423e-16f*y3 + 8.824516011816245e-18f*y4; + float kB = -1.5788320352845888f*y1 + 2.3305837032074286f*y2 - 0.9141194204840429f*y3 + 0.1623677525612032f*y4; + float kC = 0.5334142869106424f*y1 - 1.272736789213631f*y2 + 0.9258856042207512f*y3 - 0.18656310191776226f*y4; + float kD = 0.08783463138207234f*y1 - 0.1694162967925622f*y2 + 0.08588057951595272f*y3 - 0.00429891410546283f*y4; + float kE = -0.042416883008123074f*y1 + 0.1115693827987602f*y2 - 0.09764676325265872f*y3 + 0.028494263462021576f*y4; + + // x ranges from 0 -> 3 0 1 2 3 + // -15 -10 -5 0db + + // y calculates adaptive release frames depending on the amount of compression. + + setPreDelayTime(preDelayTime); + + const int nDivisionFrames = 32; + + const int nDivisions = framesToProcess / nDivisionFrames; + + unsigned frameIndex = 0; + for (int i = 0; i < nDivisions; ++i) { + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Calculate desired gain + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + // Fix gremlins. + if (IsNaN(m_detectorAverage)) + m_detectorAverage = 1; + if (IsInfinite(m_detectorAverage)) + m_detectorAverage = 1; + + float desiredGain = m_detectorAverage; + + // Pre-warp so we get desiredGain after sin() warp below. + float scaledDesiredGain = asinf(desiredGain) / (0.5f * M_PI); + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Deal with envelopes + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + // envelopeRate is the rate we slew from current compressor level to the desired level. + // The exact rate depends on if we're attacking or releasing and by how much. + float envelopeRate; + + bool isReleasing = scaledDesiredGain > m_compressorGain; + + // compressionDiffDb is the difference between current compression level and the desired level. + float compressionDiffDb = WebAudioUtils::ConvertLinearToDecibels(m_compressorGain / scaledDesiredGain, -1000.0f); + + if (isReleasing) { + // Release mode - compressionDiffDb should be negative dB + m_maxAttackCompressionDiffDb = -1; + + // Fix gremlins. + if (IsNaN(compressionDiffDb)) + compressionDiffDb = -1; + if (IsInfinite(compressionDiffDb)) + compressionDiffDb = -1; + + // Adaptive release - higher compression (lower compressionDiffDb) releases faster. + + // Contain within range: -12 -> 0 then scale to go from 0 -> 3 + float x = compressionDiffDb; + x = max(-12.0f, x); + x = min(0.0f, x); + x = 0.25f * (x + 12); + + // Compute adaptive release curve using 4th order polynomial. + // Normal values for the polynomial coefficients would create a monotonically increasing function. + float x2 = x * x; + float x3 = x2 * x; + float x4 = x2 * x2; + float releaseFrames = kA + kB * x + kC * x2 + kD * x3 + kE * x4; + +#define kSpacingDb 5 + float dbPerFrame = kSpacingDb / releaseFrames; + + envelopeRate = WebAudioUtils::ConvertDecibelsToLinear(dbPerFrame); + } else { + // Attack mode - compressionDiffDb should be positive dB + + // Fix gremlins. + if (IsNaN(compressionDiffDb)) + compressionDiffDb = 1; + if (IsInfinite(compressionDiffDb)) + compressionDiffDb = 1; + + // As long as we're still in attack mode, use a rate based off + // the largest compressionDiffDb we've encountered so far. + if (m_maxAttackCompressionDiffDb == -1 || m_maxAttackCompressionDiffDb < compressionDiffDb) + m_maxAttackCompressionDiffDb = compressionDiffDb; + + float effAttenDiffDb = max(0.5f, m_maxAttackCompressionDiffDb); + + float x = 0.25f / effAttenDiffDb; + envelopeRate = 1 - powf(x, 1 / attackFrames); + } + + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + // Inner loop - calculate shaped power average - apply compression. + // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + { + int preDelayReadIndex = m_preDelayReadIndex; + int preDelayWriteIndex = m_preDelayWriteIndex; + float detectorAverage = m_detectorAverage; + float compressorGain = m_compressorGain; + + int loopFrames = nDivisionFrames; + while (loopFrames--) { + float compressorInput = 0; + + // Predelay signal, computing compression amount from un-delayed version. + for (unsigned i = 0; i < numberOfChannels; ++i) { + float* delayBuffer = m_preDelayBuffers[i].get(); + float undelayedSource = sourceChannels[i][frameIndex]; + delayBuffer[preDelayWriteIndex] = undelayedSource; + + float absUndelayedSource = undelayedSource > 0 ? undelayedSource : -undelayedSource; + if (compressorInput < absUndelayedSource) + compressorInput = absUndelayedSource; + } + + // Calculate shaped power on undelayed input. + + float scaledInput = compressorInput; + float absInput = scaledInput > 0 ? scaledInput : -scaledInput; + + // Put through shaping curve. + // This is linear up to the threshold, then enters a "knee" portion followed by the "ratio" portion. + // The transition from the threshold to the knee is smooth (1st derivative matched). + // The transition from the knee to the ratio portion is smooth (1st derivative matched). + float shapedInput = saturate(absInput, k); + + float attenuation = absInput <= 0.0001f ? 1 : shapedInput / absInput; + + float attenuationDb = -WebAudioUtils::ConvertLinearToDecibels(attenuation, -1000.0f); + attenuationDb = max(2.0f, attenuationDb); + + float dbPerFrame = attenuationDb / satReleaseFrames; + + float satReleaseRate = WebAudioUtils::ConvertDecibelsToLinear(dbPerFrame) - 1; + + bool isRelease = (attenuation > detectorAverage); + float rate = isRelease ? satReleaseRate : 1; + + detectorAverage += (attenuation - detectorAverage) * rate; + detectorAverage = min(1.0f, detectorAverage); + + // Fix gremlins. + if (IsNaN(detectorAverage)) + detectorAverage = 1; + if (IsInfinite(detectorAverage)) + detectorAverage = 1; + + // Exponential approach to desired gain. + if (envelopeRate < 1) { + // Attack - reduce gain to desired. + compressorGain += (scaledDesiredGain - compressorGain) * envelopeRate; + } else { + // Release - exponentially increase gain to 1.0 + compressorGain *= envelopeRate; + compressorGain = min(1.0f, compressorGain); + } + + // Warp pre-compression gain to smooth out sharp exponential transition points. + float postWarpCompressorGain = sinf(0.5f * M_PI * compressorGain); + + // Calculate total gain using master gain and effect blend. + float totalGain = dryMix + wetMix * masterLinearGain * postWarpCompressorGain; + + // Calculate metering. + float dbRealGain = 20 * log10(postWarpCompressorGain); + if (dbRealGain < m_meteringGain) + m_meteringGain = dbRealGain; + else + m_meteringGain += (dbRealGain - m_meteringGain) * m_meteringReleaseK; + + // Apply final gain. + for (unsigned i = 0; i < numberOfChannels; ++i) { + float* delayBuffer = m_preDelayBuffers[i].get(); + destinationChannels[i][frameIndex] = delayBuffer[preDelayReadIndex] * totalGain; + } + + frameIndex++; + preDelayReadIndex = (preDelayReadIndex + 1) & MaxPreDelayFramesMask; + preDelayWriteIndex = (preDelayWriteIndex + 1) & MaxPreDelayFramesMask; + } + + // Locals back to member variables. + m_preDelayReadIndex = preDelayReadIndex; + m_preDelayWriteIndex = preDelayWriteIndex; + m_detectorAverage = DenormalDisabler::flushDenormalFloatToZero(detectorAverage); + m_compressorGain = DenormalDisabler::flushDenormalFloatToZero(compressorGain); + } + } +} + +void DynamicsCompressorKernel::reset() +{ + m_detectorAverage = 0; + m_compressorGain = 1; + m_meteringGain = 1; + + // Predelay section. + for (unsigned i = 0; i < m_preDelayBuffers.Length(); ++i) + memset(m_preDelayBuffers[i].get(), 0, sizeof(float) * MaxPreDelayFrames); + + m_preDelayReadIndex = 0; + m_preDelayWriteIndex = DefaultPreDelayFrames; + + m_maxAttackCompressionDiffDb = -1; // uninitialized state +} + +} // namespace WebCore diff --git a/dom/media/webaudio/blink/DynamicsCompressorKernel.h b/dom/media/webaudio/blink/DynamicsCompressorKernel.h new file mode 100644 index 000000000..39449949c --- /dev/null +++ b/dom/media/webaudio/blink/DynamicsCompressorKernel.h @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef DynamicsCompressorKernel_h +#define DynamicsCompressorKernel_h + +#include "nsTArray.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/UniquePtr.h" + +namespace WebCore { + +class DynamicsCompressorKernel { +public: + DynamicsCompressorKernel(float sampleRate, unsigned numberOfChannels); + + void setNumberOfChannels(unsigned); + + // Performs stereo-linked compression. + void process(float* sourceChannels[], + float* destinationChannels[], + unsigned numberOfChannels, + unsigned framesToProcess, + + float dbThreshold, + float dbKnee, + float ratio, + float attackTime, + float releaseTime, + float preDelayTime, + float dbPostGain, + float effectBlend, + + float releaseZone1, + float releaseZone2, + float releaseZone3, + float releaseZone4 + ); + + void reset(); + + unsigned latencyFrames() const { return m_lastPreDelayFrames; } + + float sampleRate() const { return m_sampleRate; } + + float meteringGain() const { return m_meteringGain; } + + size_t sizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + +protected: + float m_sampleRate; + + float m_detectorAverage; + float m_compressorGain; + + // Metering + float m_meteringReleaseK; + float m_meteringGain; + + // Lookahead section. + enum { MaxPreDelayFrames = 1024 }; + enum { MaxPreDelayFramesMask = MaxPreDelayFrames - 1 }; + enum { DefaultPreDelayFrames = 256 }; // setPreDelayTime() will override this initial value + unsigned m_lastPreDelayFrames; + void setPreDelayTime(float); + + nsTArray<mozilla::UniquePtr<float[]>> m_preDelayBuffers; + int m_preDelayReadIndex; + int m_preDelayWriteIndex; + + float m_maxAttackCompressionDiffDb; + + // Static compression curve. + float kneeCurve(float x, float k); + float saturate(float x, float k); + float slopeAt(float x, float k); + float kAtSlope(float desiredSlope); + + float updateStaticCurveParameters(float dbThreshold, float dbKnee, float ratio); + + // Amount of input change in dB required for 1 dB of output change. + // This applies to the portion of the curve above m_kneeThresholdDb (see below). + float m_ratio; + float m_slope; // Inverse ratio. + + // The input to output change below the threshold is linear 1:1. + float m_linearThreshold; + float m_dbThreshold; + + // m_dbKnee is the number of dB above the threshold before we enter the "ratio" portion of the curve. + // m_kneeThresholdDb = m_dbThreshold + m_dbKnee + // The portion between m_dbThreshold and m_kneeThresholdDb is the "soft knee" portion of the curve + // which transitions smoothly from the linear portion to the ratio portion. + float m_dbKnee; + float m_kneeThreshold; + float m_kneeThresholdDb; + float m_ykneeThresholdDb; + + // Internal parameter for the knee portion of the curve. + float m_K; +}; + +} // namespace WebCore + +#endif // DynamicsCompressorKernel_h diff --git a/dom/media/webaudio/blink/FFTConvolver.cpp b/dom/media/webaudio/blink/FFTConvolver.cpp new file mode 100644 index 000000000..8694073ae --- /dev/null +++ b/dom/media/webaudio/blink/FFTConvolver.cpp @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "FFTConvolver.h" +#include "mozilla/PodOperations.h" + +using namespace mozilla; + +namespace WebCore { + +FFTConvolver::FFTConvolver(size_t fftSize, size_t renderPhase) + : m_frame(fftSize) + , m_readWriteIndex(renderPhase % (fftSize / 2)) +{ + MOZ_ASSERT(fftSize >= 2 * WEBAUDIO_BLOCK_SIZE); + m_inputBuffer.SetLength(fftSize); + PodZero(m_inputBuffer.Elements(), fftSize); + m_outputBuffer.SetLength(fftSize); + PodZero(m_outputBuffer.Elements(), fftSize); + m_lastOverlapBuffer.SetLength(fftSize / 2); + PodZero(m_lastOverlapBuffer.Elements(), fftSize / 2); +} + +size_t FFTConvolver::sizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const +{ + size_t amount = 0; + amount += m_frame.SizeOfExcludingThis(aMallocSizeOf); + amount += m_inputBuffer.ShallowSizeOfExcludingThis(aMallocSizeOf); + amount += m_outputBuffer.ShallowSizeOfExcludingThis(aMallocSizeOf); + amount += m_lastOverlapBuffer.ShallowSizeOfExcludingThis(aMallocSizeOf); + return amount; +} + +size_t FFTConvolver::sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const +{ + return aMallocSizeOf(this) + sizeOfExcludingThis(aMallocSizeOf); +} + +const float* FFTConvolver::process(FFTBlock* fftKernel, const float* sourceP) +{ + size_t halfSize = fftSize() / 2; + + // WEBAUDIO_BLOCK_SIZE must be an exact multiple of halfSize, + // halfSize must be a multiple of WEBAUDIO_BLOCK_SIZE + // and > WEBAUDIO_BLOCK_SIZE. + MOZ_ASSERT(halfSize % WEBAUDIO_BLOCK_SIZE == 0 && + WEBAUDIO_BLOCK_SIZE <= halfSize); + + // Copy samples to input buffer (note contraint above!) + float* inputP = m_inputBuffer.Elements(); + + MOZ_ASSERT(sourceP && inputP && m_readWriteIndex + WEBAUDIO_BLOCK_SIZE <= m_inputBuffer.Length()); + + memcpy(inputP + m_readWriteIndex, sourceP, sizeof(float) * WEBAUDIO_BLOCK_SIZE); + + float* outputP = m_outputBuffer.Elements(); + m_readWriteIndex += WEBAUDIO_BLOCK_SIZE; + + // Check if it's time to perform the next FFT + if (m_readWriteIndex == halfSize) { + // The input buffer is now filled (get frequency-domain version) + m_frame.PerformFFT(m_inputBuffer.Elements()); + m_frame.Multiply(*fftKernel); + m_frame.GetInverseWithoutScaling(m_outputBuffer.Elements()); + + // Overlap-add 1st half from previous time + AudioBufferAddWithScale(m_lastOverlapBuffer.Elements(), 1.0f, + m_outputBuffer.Elements(), halfSize); + + // Finally, save 2nd half of result + MOZ_ASSERT(m_outputBuffer.Length() == 2 * halfSize && m_lastOverlapBuffer.Length() == halfSize); + + memcpy(m_lastOverlapBuffer.Elements(), m_outputBuffer.Elements() + halfSize, sizeof(float) * halfSize); + + // Reset index back to start for next time + m_readWriteIndex = 0; + } + + return outputP + m_readWriteIndex; +} + +void FFTConvolver::reset() +{ + PodZero(m_lastOverlapBuffer.Elements(), m_lastOverlapBuffer.Length()); + m_readWriteIndex = 0; +} + +size_t FFTConvolver::latencyFrames() const +{ + return std::max<size_t>(fftSize()/2, WEBAUDIO_BLOCK_SIZE) - + WEBAUDIO_BLOCK_SIZE; +} + +} // namespace WebCore diff --git a/dom/media/webaudio/blink/FFTConvolver.h b/dom/media/webaudio/blink/FFTConvolver.h new file mode 100644 index 000000000..118c6baef --- /dev/null +++ b/dom/media/webaudio/blink/FFTConvolver.h @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef FFTConvolver_h +#define FFTConvolver_h + +#include "nsTArray.h" +#include "mozilla/FFTBlock.h" +#include "mozilla/MemoryReporting.h" + +namespace WebCore { + +typedef AlignedTArray<float> AlignedAudioFloatArray; +using mozilla::FFTBlock; + +class FFTConvolver { +public: + // |fftSize| must be a power of two. + // + // |renderPhase| is the initial offset in the initially zero input buffer. + // It is coordinated with the other stages, so they don't all do their + // FFTs at the same time. + explicit FFTConvolver(size_t fftSize, size_t renderPhase = 0); + + // Process WEBAUDIO_BLOCK_SIZE elements of array |sourceP| and return a + // pointer to an output array of the same size. + // + // |fftKernel| must be pre-scaled for FFTBlock::GetInverseWithoutScaling(). + // + // FIXME: Later, we can do more sophisticated buffering to relax this requirement... + const float* process(FFTBlock* fftKernel, const float* sourceP); + + void reset(); + + size_t fftSize() const { return m_frame.FFTSize(); } + + // The input to output latency is up to fftSize / 2, but alignment of the + // FFTs with the blocks reduces this by one block. + size_t latencyFrames() const; + + size_t sizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + size_t sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + +private: + FFTBlock m_frame; + + // Buffer input until we get fftSize / 2 samples then do an FFT + size_t m_readWriteIndex; + AlignedAudioFloatArray m_inputBuffer; + + // Stores output which we read a little at a time + AlignedAudioFloatArray m_outputBuffer; + + // Saves the 2nd half of the FFT buffer, so we can do an overlap-add with the 1st half of the next one + AlignedAudioFloatArray m_lastOverlapBuffer; +}; + +} // namespace WebCore + +#endif // FFTConvolver_h diff --git a/dom/media/webaudio/blink/HRTFDatabase.cpp b/dom/media/webaudio/blink/HRTFDatabase.cpp new file mode 100644 index 000000000..ef236c855 --- /dev/null +++ b/dom/media/webaudio/blink/HRTFDatabase.cpp @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "HRTFDatabase.h" + +#include "HRTFElevation.h" + +using namespace std; + +namespace WebCore { + +const int HRTFDatabase::MinElevation = -45; +const int HRTFDatabase::MaxElevation = 90; +const unsigned HRTFDatabase::RawElevationAngleSpacing = 15; +const unsigned HRTFDatabase::NumberOfRawElevations = 10; // -45 -> +90 (each 15 degrees) +const unsigned HRTFDatabase::InterpolationFactor = 1; +const unsigned HRTFDatabase::NumberOfTotalElevations = NumberOfRawElevations * InterpolationFactor; + +nsReturnRef<HRTFDatabase> HRTFDatabase::create(float sampleRate) +{ + return nsReturnRef<HRTFDatabase>(new HRTFDatabase(sampleRate)); +} + +HRTFDatabase::HRTFDatabase(float sampleRate) + : m_sampleRate(sampleRate) +{ + m_elevations.SetLength(NumberOfTotalElevations); + + unsigned elevationIndex = 0; + for (int elevation = MinElevation; elevation <= MaxElevation; elevation += RawElevationAngleSpacing) { + nsAutoRef<HRTFElevation> hrtfElevation(HRTFElevation::createBuiltin(elevation, sampleRate)); + MOZ_ASSERT(hrtfElevation.get()); + if (!hrtfElevation.get()) + return; + + m_elevations[elevationIndex] = hrtfElevation.out(); + elevationIndex += InterpolationFactor; + } + + // Now, go back and interpolate elevations. + if (InterpolationFactor > 1) { + for (unsigned i = 0; i < NumberOfTotalElevations; i += InterpolationFactor) { + unsigned j = (i + InterpolationFactor); + if (j >= NumberOfTotalElevations) + j = i; // for last elevation interpolate with itself + + // Create the interpolated convolution kernels and delays. + for (unsigned jj = 1; jj < InterpolationFactor; ++jj) { + float x = static_cast<float>(jj) / static_cast<float>(InterpolationFactor); + m_elevations[i + jj] = HRTFElevation::createByInterpolatingSlices(m_elevations[i].get(), m_elevations[j].get(), x, sampleRate); + MOZ_ASSERT(m_elevations[i + jj].get()); + } + } + } +} + +size_t HRTFDatabase::sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const +{ + size_t amount = aMallocSizeOf(this); + amount += m_elevations.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (size_t i = 0; i < m_elevations.Length(); i++) { + amount += m_elevations[i]->sizeOfIncludingThis(aMallocSizeOf); + } + + return amount; +} + +void HRTFDatabase::getKernelsFromAzimuthElevation(double azimuthBlend, unsigned azimuthIndex, double elevationAngle, HRTFKernel* &kernelL, HRTFKernel* &kernelR, + double& frameDelayL, double& frameDelayR) +{ + unsigned elevationIndex = indexFromElevationAngle(elevationAngle); + MOZ_ASSERT(elevationIndex < m_elevations.Length() && m_elevations.Length() > 0); + + if (!m_elevations.Length()) { + kernelL = 0; + kernelR = 0; + return; + } + + if (elevationIndex > m_elevations.Length() - 1) + elevationIndex = m_elevations.Length() - 1; + + HRTFElevation* hrtfElevation = m_elevations[elevationIndex].get(); + MOZ_ASSERT(hrtfElevation); + if (!hrtfElevation) { + kernelL = 0; + kernelR = 0; + return; + } + + hrtfElevation->getKernelsFromAzimuth(azimuthBlend, azimuthIndex, kernelL, kernelR, frameDelayL, frameDelayR); +} + +unsigned HRTFDatabase::indexFromElevationAngle(double elevationAngle) +{ + // Clamp to allowed range. + elevationAngle = mozilla::clamped(elevationAngle, + static_cast<double>(MinElevation), + static_cast<double>(MaxElevation)); + + unsigned elevationIndex = static_cast<int>(InterpolationFactor * (elevationAngle - MinElevation) / RawElevationAngleSpacing); + return elevationIndex; +} + +} // namespace WebCore diff --git a/dom/media/webaudio/blink/HRTFDatabase.h b/dom/media/webaudio/blink/HRTFDatabase.h new file mode 100644 index 000000000..400763b8f --- /dev/null +++ b/dom/media/webaudio/blink/HRTFDatabase.h @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef HRTFDatabase_h +#define HRTFDatabase_h + +#include "HRTFElevation.h" +#include "nsAutoRef.h" +#include "nsTArray.h" +#include "mozilla/MemoryReporting.h" + +namespace WebCore { + +class HRTFKernel; + +class HRTFDatabase { +public: + static nsReturnRef<HRTFDatabase> create(float sampleRate); + + // getKernelsFromAzimuthElevation() returns a left and right ear kernel, and an interpolated left and right frame delay for the given azimuth and elevation. + // azimuthBlend must be in the range 0 -> 1. + // Valid values for azimuthIndex are 0 -> HRTFElevation::NumberOfTotalAzimuths - 1 (corresponding to angles of 0 -> 360). + // Valid values for elevationAngle are MinElevation -> MaxElevation. + void getKernelsFromAzimuthElevation(double azimuthBlend, unsigned azimuthIndex, double elevationAngle, HRTFKernel* &kernelL, HRTFKernel* &kernelR, double& frameDelayL, double& frameDelayR); + + // Returns the number of different azimuth angles. + static unsigned numberOfAzimuths() { return HRTFElevation::NumberOfTotalAzimuths; } + + float sampleRate() const { return m_sampleRate; } + + // Number of elevations loaded from resource. + static const unsigned NumberOfRawElevations; + + size_t sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + +private: + HRTFDatabase(const HRTFDatabase& other) = delete; + void operator=(const HRTFDatabase& other) = delete; + + explicit HRTFDatabase(float sampleRate); + + // Minimum and maximum elevation angles (inclusive) for a HRTFDatabase. + static const int MinElevation; + static const int MaxElevation; + static const unsigned RawElevationAngleSpacing; + + // Interpolates by this factor to get the total number of elevations from every elevation loaded from resource. + static const unsigned InterpolationFactor; + + // Total number of elevations after interpolation. + static const unsigned NumberOfTotalElevations; + + // Returns the index for the correct HRTFElevation given the elevation angle. + static unsigned indexFromElevationAngle(double); + + nsTArray<nsAutoRef<HRTFElevation> > m_elevations; + float m_sampleRate; +}; + +} // namespace WebCore + +template <> +class nsAutoRefTraits<WebCore::HRTFDatabase> : + public nsPointerRefTraits<WebCore::HRTFDatabase> { +public: + static void Release(WebCore::HRTFDatabase* ptr) { delete(ptr); } +}; + +#endif // HRTFDatabase_h diff --git a/dom/media/webaudio/blink/HRTFDatabaseLoader.cpp b/dom/media/webaudio/blink/HRTFDatabaseLoader.cpp new file mode 100644 index 000000000..090e1b217 --- /dev/null +++ b/dom/media/webaudio/blink/HRTFDatabaseLoader.cpp @@ -0,0 +1,223 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "HRTFDatabaseLoader.h" +#include "HRTFDatabase.h" + +using namespace mozilla; + +namespace WebCore { + +// Singleton +nsTHashtable<HRTFDatabaseLoader::LoaderByRateEntry>* + HRTFDatabaseLoader::s_loaderMap = nullptr; + +size_t HRTFDatabaseLoader::sizeOfLoaders(mozilla::MallocSizeOf aMallocSizeOf) +{ + return s_loaderMap ? s_loaderMap->SizeOfIncludingThis(aMallocSizeOf) : 0; +} + +already_AddRefed<HRTFDatabaseLoader> HRTFDatabaseLoader::createAndLoadAsynchronouslyIfNecessary(float sampleRate) +{ + MOZ_ASSERT(NS_IsMainThread()); + + RefPtr<HRTFDatabaseLoader> loader; + + if (!s_loaderMap) { + s_loaderMap = new nsTHashtable<LoaderByRateEntry>(); + } + + LoaderByRateEntry* entry = s_loaderMap->PutEntry(sampleRate); + loader = entry->mLoader; + if (loader) { // existing entry + MOZ_ASSERT(sampleRate == loader->databaseSampleRate()); + return loader.forget(); + } + + loader = new HRTFDatabaseLoader(sampleRate); + entry->mLoader = loader; + + loader->loadAsynchronously(); + + return loader.forget(); +} + +HRTFDatabaseLoader::HRTFDatabaseLoader(float sampleRate) + : m_refCnt(0) + , m_threadLock("HRTFDatabaseLoader") + , m_databaseLoaderThread(nullptr) + , m_databaseSampleRate(sampleRate) +{ + MOZ_ASSERT(NS_IsMainThread()); +} + +HRTFDatabaseLoader::~HRTFDatabaseLoader() +{ + MOZ_ASSERT(NS_IsMainThread()); + + waitForLoaderThreadCompletion(); + m_hrtfDatabase.reset(); + + if (s_loaderMap) { + // Remove ourself from the map. + s_loaderMap->RemoveEntry(m_databaseSampleRate); + if (s_loaderMap->Count() == 0) { + delete s_loaderMap; + s_loaderMap = nullptr; + } + } +} + +size_t HRTFDatabaseLoader::sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const +{ + size_t amount = aMallocSizeOf(this); + + // NB: Need to make sure we're not competing with the loader thread. + const_cast<HRTFDatabaseLoader*>(this)->waitForLoaderThreadCompletion(); + + if (m_hrtfDatabase) { + amount += m_hrtfDatabase->sizeOfIncludingThis(aMallocSizeOf); + } + + return amount; +} + +class HRTFDatabaseLoader::ProxyReleaseEvent final : public Runnable { +public: + explicit ProxyReleaseEvent(HRTFDatabaseLoader* loader) : mLoader(loader) {} + NS_IMETHOD Run() override + { + mLoader->MainThreadRelease(); + return NS_OK; + } +private: + HRTFDatabaseLoader* mLoader; +}; + +void HRTFDatabaseLoader::ProxyRelease() +{ + nsCOMPtr<nsIThread> mainThread = do_GetMainThread(); + if (MOZ_LIKELY(mainThread)) { + RefPtr<ProxyReleaseEvent> event = new ProxyReleaseEvent(this); + DebugOnly<nsresult> rv = + mainThread->Dispatch(event, NS_DISPATCH_NORMAL); + MOZ_ASSERT(NS_SUCCEEDED(rv), "Failed to dispatch release event"); + } else { + // Should be in XPCOM shutdown. + MOZ_ASSERT(NS_IsMainThread(), + "Main thread is not available for dispatch."); + MainThreadRelease(); + } +} + +void HRTFDatabaseLoader::MainThreadRelease() +{ + MOZ_ASSERT(NS_IsMainThread()); + int count = --m_refCnt; + MOZ_ASSERT(count >= 0, "extra release"); + NS_LOG_RELEASE(this, count, "HRTFDatabaseLoader"); + if (count == 0) { + // It is safe to delete here as the first reference can only be added + // on this (main) thread. + delete this; + } +} + +// Asynchronously load the database in this thread. +static void databaseLoaderEntry(void* threadData) +{ + PR_SetCurrentThreadName("HRTFDatabaseLdr"); + + HRTFDatabaseLoader* loader = reinterpret_cast<HRTFDatabaseLoader*>(threadData); + MOZ_ASSERT(loader); + loader->load(); +} + +void HRTFDatabaseLoader::load() +{ + MOZ_ASSERT(!NS_IsMainThread()); + MOZ_ASSERT(!m_hrtfDatabase.get(), "Called twice"); + // Load the default HRTF database. + m_hrtfDatabase = HRTFDatabase::create(m_databaseSampleRate); + // Notifies the main thread of completion. See loadAsynchronously(). + Release(); +} + +void HRTFDatabaseLoader::loadAsynchronously() +{ + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(m_refCnt, "Must not be called before a reference is added"); + + // Add a reference so that the destructor won't run and wait for the + // loader thread, until load() has completed. + AddRef(); + + MutexAutoLock locker(m_threadLock); + + MOZ_ASSERT(!m_hrtfDatabase.get() && !m_databaseLoaderThread, + "Called twice"); + // Start the asynchronous database loading process. + m_databaseLoaderThread = + PR_CreateThread(PR_USER_THREAD, databaseLoaderEntry, this, + PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, + PR_JOINABLE_THREAD, 0); +} + +bool HRTFDatabaseLoader::isLoaded() const +{ + return m_hrtfDatabase.get(); +} + +void HRTFDatabaseLoader::waitForLoaderThreadCompletion() +{ + MutexAutoLock locker(m_threadLock); + + // waitForThreadCompletion() should not be called twice for the same thread. + if (m_databaseLoaderThread) { + DebugOnly<PRStatus> status = PR_JoinThread(m_databaseLoaderThread); + MOZ_ASSERT(status == PR_SUCCESS, "PR_JoinThread failed"); + } + m_databaseLoaderThread = nullptr; +} + +void HRTFDatabaseLoader::shutdown() +{ + MOZ_ASSERT(NS_IsMainThread()); + if (s_loaderMap) { + // Set s_loaderMap to nullptr so that the hashtable is not modified on + // reference release during enumeration. + nsTHashtable<LoaderByRateEntry>* loaderMap = s_loaderMap; + s_loaderMap = nullptr; + for (auto iter = loaderMap->Iter(); !iter.Done(); iter.Next()) { + iter.Get()->mLoader->waitForLoaderThreadCompletion(); + } + delete loaderMap; + } +} + +} // namespace WebCore diff --git a/dom/media/webaudio/blink/HRTFDatabaseLoader.h b/dom/media/webaudio/blink/HRTFDatabaseLoader.h new file mode 100644 index 000000000..50a875b18 --- /dev/null +++ b/dom/media/webaudio/blink/HRTFDatabaseLoader.h @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef HRTFDatabaseLoader_h +#define HRTFDatabaseLoader_h + +#include "nsHashKeys.h" +#include "mozilla/RefPtr.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/Mutex.h" +#include "HRTFDatabase.h" + +template <class EntryType> class nsTHashtable; +template <class T> class nsAutoRef; + +namespace WebCore { + +// HRTFDatabaseLoader will asynchronously load the default HRTFDatabase in a new thread. + +class HRTFDatabaseLoader { +public: + // Lazily creates a HRTFDatabaseLoader (if not already created) for the given sample-rate + // and starts loading asynchronously (when created the first time). + // Returns the HRTFDatabaseLoader. + // Must be called from the main thread. + static already_AddRefed<HRTFDatabaseLoader> createAndLoadAsynchronouslyIfNecessary(float sampleRate); + + // AddRef and Release may be called from any thread. + void AddRef() + { +#if defined(DEBUG) || defined(NS_BUILD_REFCNT_LOGGING) + int count = +#endif + ++m_refCnt; + MOZ_ASSERT(count > 0, "invalid ref count"); + NS_LOG_ADDREF(this, count, "HRTFDatabaseLoader", sizeof(*this)); + } + + void Release() + { + // The last reference can't be removed on a non-main thread because + // the object can be accessed on the main thread from the hash + // table via createAndLoadAsynchronouslyIfNecessary(). + int count = m_refCnt; + MOZ_ASSERT(count > 0, "extra release"); + // Optimization attempt to possibly skip proxying the release to the + // main thread. + if (count != 1 && m_refCnt.compareExchange(count, count - 1)) { + NS_LOG_RELEASE(this, count - 1, "HRTFDatabaseLoader"); + return; + } + + ProxyRelease(); + } + + // Returns true once the default database has been completely loaded. + bool isLoaded() const; + + // waitForLoaderThreadCompletion() may be called more than once, + // on any thread except m_databaseLoaderThread. + void waitForLoaderThreadCompletion(); + + HRTFDatabase* database() { return m_hrtfDatabase.get(); } + + float databaseSampleRate() const { return m_databaseSampleRate; } + + static void shutdown(); + + // Called in asynchronous loading thread. + void load(); + + // Sums the size of all cached database loaders. + static size_t sizeOfLoaders(mozilla::MallocSizeOf aMallocSizeOf); + +private: + // Both constructor and destructor must be called from the main thread. + explicit HRTFDatabaseLoader(float sampleRate); + ~HRTFDatabaseLoader(); + + size_t sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + + void ProxyRelease(); // any thread + void MainThreadRelease(); // main thread only + class ProxyReleaseEvent; + + // If it hasn't already been loaded, creates a new thread and initiates asynchronous loading of the default database. + // This must be called from the main thread. + void loadAsynchronously(); + + // Map from sample-rate to loader. + class LoaderByRateEntry : public nsFloatHashKey { + public: + explicit LoaderByRateEntry(KeyTypePointer aKey) + : nsFloatHashKey(aKey) + , mLoader() // so PutEntry() will zero-initialize + { + } + + size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const + { + return mLoader ? mLoader->sizeOfIncludingThis(aMallocSizeOf) : 0; + } + + HRTFDatabaseLoader* mLoader; + }; + + // Keeps track of loaders on a per-sample-rate basis. + static nsTHashtable<LoaderByRateEntry> *s_loaderMap; // singleton + + mozilla::Atomic<int> m_refCnt; + + nsAutoRef<HRTFDatabase> m_hrtfDatabase; + + // Holding a m_threadLock is required when accessing m_databaseLoaderThread. + mozilla::Mutex m_threadLock; + PRThread* m_databaseLoaderThread; + + float m_databaseSampleRate; +}; + +} // namespace WebCore + +#endif // HRTFDatabaseLoader_h diff --git a/dom/media/webaudio/blink/HRTFElevation.cpp b/dom/media/webaudio/blink/HRTFElevation.cpp new file mode 100644 index 000000000..2300872f3 --- /dev/null +++ b/dom/media/webaudio/blink/HRTFElevation.cpp @@ -0,0 +1,328 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "HRTFElevation.h" + +#include <speex/speex_resampler.h> +#include "mozilla/PodOperations.h" +#include "AudioSampleFormat.h" + +#include "IRC_Composite_C_R0195-incl.cpp" + +using namespace std; +using namespace mozilla; + +namespace WebCore { + +const int elevationSpacing = irc_composite_c_r0195_elevation_interval; +const int firstElevation = irc_composite_c_r0195_first_elevation; +const int numberOfElevations = MOZ_ARRAY_LENGTH(irc_composite_c_r0195); + +const unsigned HRTFElevation::NumberOfTotalAzimuths = 360 / 15 * 8; + +const int rawSampleRate = irc_composite_c_r0195_sample_rate; + +// Number of frames in an individual impulse response. +const size_t ResponseFrameSize = 256; + +size_t HRTFElevation::sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const +{ + size_t amount = aMallocSizeOf(this); + + amount += m_kernelListL.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (size_t i = 0; i < m_kernelListL.Length(); i++) { + amount += m_kernelListL[i]->sizeOfIncludingThis(aMallocSizeOf); + } + + return amount; +} + +size_t HRTFElevation::fftSizeForSampleRate(float sampleRate) +{ + // The IRCAM HRTF impulse responses were 512 sample-frames @44.1KHz, + // but these have been truncated to 256 samples. + // An FFT-size of twice impulse response size is used (for convolution). + // So for sample rates of 44.1KHz an FFT size of 512 is good. + // We double the FFT-size only for sample rates at least double this. + // If the FFT size is too large then the impulse response will be padded + // with zeros without the fade-out provided by HRTFKernel. + MOZ_ASSERT(sampleRate > 1.0 && sampleRate < 1048576.0); + + // This is the size if we were to use all raw response samples. + unsigned resampledLength = + floorf(ResponseFrameSize * sampleRate / rawSampleRate); + // Keep things semi-sane, with max FFT size of 1024. + unsigned size = min(resampledLength, 1023U); + // Ensure a minimum of 2 * WEBAUDIO_BLOCK_SIZE (with the size++ below) for + // FFTConvolver and set the 8 least significant bits for rounding up to + // the next power of 2 below. + size |= 2 * WEBAUDIO_BLOCK_SIZE - 1; + // Round up to the next power of 2, making the FFT size no more than twice + // the impulse response length. This doubles size for values that are + // already powers of 2. This works by filling in alls bit to right of the + // most significant bit. The most significant bit is no greater than + // 1 << 9, and the least significant 8 bits were already set above, so + // there is at most one bit to add. + size |= (size >> 1); + size++; + MOZ_ASSERT((size & (size - 1)) == 0); + + return size; +} + +nsReturnRef<HRTFKernel> HRTFElevation::calculateKernelForAzimuthElevation(int azimuth, int elevation, SpeexResamplerState* resampler, float sampleRate) +{ + int elevationIndex = (elevation - firstElevation) / elevationSpacing; + MOZ_ASSERT(elevationIndex >= 0 && elevationIndex <= numberOfElevations); + + int numberOfAzimuths = irc_composite_c_r0195[elevationIndex].count; + int azimuthSpacing = 360 / numberOfAzimuths; + MOZ_ASSERT(numberOfAzimuths * azimuthSpacing == 360); + + int azimuthIndex = azimuth / azimuthSpacing; + MOZ_ASSERT(azimuthIndex * azimuthSpacing == azimuth); + + const int16_t (&impulse_response_data)[ResponseFrameSize] = + irc_composite_c_r0195[elevationIndex].azimuths[azimuthIndex]; + + // When libspeex_resampler is compiled with FIXED_POINT, samples in + // speex_resampler_process_float are rounded directly to int16_t, which + // only works well if the floats are in the range +/-32767. On such + // platforms it's better to resample before converting to float anyway. +#ifdef MOZ_SAMPLE_TYPE_S16 +# define RESAMPLER_PROCESS speex_resampler_process_int + const int16_t* response = impulse_response_data; + const int16_t* resampledResponse; +#else +# define RESAMPLER_PROCESS speex_resampler_process_float + float response[ResponseFrameSize]; + ConvertAudioSamples(impulse_response_data, response, ResponseFrameSize); + float* resampledResponse; +#endif + + // Note that depending on the fftSize returned by the panner, we may be truncating the impulse response. + const size_t resampledResponseLength = fftSizeForSampleRate(sampleRate) / 2; + + AutoTArray<AudioDataValue, 2 * ResponseFrameSize> resampled; + if (sampleRate == rawSampleRate) { + resampledResponse = response; + MOZ_ASSERT(resampledResponseLength == ResponseFrameSize); + } else { + resampled.SetLength(resampledResponseLength); + resampledResponse = resampled.Elements(); + speex_resampler_skip_zeros(resampler); + + // Feed the input buffer into the resampler. + spx_uint32_t in_len = ResponseFrameSize; + spx_uint32_t out_len = resampled.Length(); + RESAMPLER_PROCESS(resampler, 0, response, &in_len, + resampled.Elements(), &out_len); + + if (out_len < resampled.Length()) { + // The input should have all been processed. + MOZ_ASSERT(in_len == ResponseFrameSize); + // Feed in zeros get the data remaining in the resampler. + spx_uint32_t out_index = out_len; + in_len = speex_resampler_get_input_latency(resampler); + out_len = resampled.Length() - out_index; + RESAMPLER_PROCESS(resampler, 0, nullptr, &in_len, + resampled.Elements() + out_index, &out_len); + out_index += out_len; + // There may be some uninitialized samples remaining for very low + // sample rates. + PodZero(resampled.Elements() + out_index, + resampled.Length() - out_index); + } + + speex_resampler_reset_mem(resampler); + } + +#ifdef MOZ_SAMPLE_TYPE_S16 + AutoTArray<float, 2 * ResponseFrameSize> floatArray; + floatArray.SetLength(resampledResponseLength); + float *floatResponse = floatArray.Elements(); + ConvertAudioSamples(resampledResponse, + floatResponse, resampledResponseLength); +#else + float *floatResponse = resampledResponse; +#endif +#undef RESAMPLER_PROCESS + + return HRTFKernel::create(floatResponse, resampledResponseLength, sampleRate); +} + +// The range of elevations for the IRCAM impulse responses varies depending on azimuth, but the minimum elevation appears to always be -45. +// +// Here's how it goes: +static int maxElevations[] = { + // Azimuth + // + 90, // 0 + 45, // 15 + 60, // 30 + 45, // 45 + 75, // 60 + 45, // 75 + 60, // 90 + 45, // 105 + 75, // 120 + 45, // 135 + 60, // 150 + 45, // 165 + 75, // 180 + 45, // 195 + 60, // 210 + 45, // 225 + 75, // 240 + 45, // 255 + 60, // 270 + 45, // 285 + 75, // 300 + 45, // 315 + 60, // 330 + 45 // 345 +}; + +nsReturnRef<HRTFElevation> HRTFElevation::createBuiltin(int elevation, float sampleRate) +{ + if (elevation < firstElevation || + elevation > firstElevation + numberOfElevations * elevationSpacing || + (elevation / elevationSpacing) * elevationSpacing != elevation) + return nsReturnRef<HRTFElevation>(); + + // Spacing, in degrees, between every azimuth loaded from resource. + // Some elevations do not have data for all these intervals. + // See maxElevations. + static const unsigned AzimuthSpacing = 15; + static const unsigned NumberOfRawAzimuths = 360 / AzimuthSpacing; + static_assert(AzimuthSpacing * NumberOfRawAzimuths == 360, + "Not a multiple"); + static const unsigned InterpolationFactor = + NumberOfTotalAzimuths / NumberOfRawAzimuths; + static_assert(NumberOfTotalAzimuths == + NumberOfRawAzimuths * InterpolationFactor, "Not a multiple"); + + HRTFKernelList kernelListL; + kernelListL.SetLength(NumberOfTotalAzimuths); + + SpeexResamplerState* resampler = sampleRate == rawSampleRate ? nullptr : + speex_resampler_init(1, rawSampleRate, sampleRate, + SPEEX_RESAMPLER_QUALITY_MIN, nullptr); + + // Load convolution kernels from HRTF files. + int interpolatedIndex = 0; + for (unsigned rawIndex = 0; rawIndex < NumberOfRawAzimuths; ++rawIndex) { + // Don't let elevation exceed maximum for this azimuth. + int maxElevation = maxElevations[rawIndex]; + int actualElevation = min(elevation, maxElevation); + + kernelListL[interpolatedIndex] = calculateKernelForAzimuthElevation(rawIndex * AzimuthSpacing, actualElevation, resampler, sampleRate); + + interpolatedIndex += InterpolationFactor; + } + + if (resampler) + speex_resampler_destroy(resampler); + + // Now go back and interpolate intermediate azimuth values. + for (unsigned i = 0; i < NumberOfTotalAzimuths; i += InterpolationFactor) { + int j = (i + InterpolationFactor) % NumberOfTotalAzimuths; + + // Create the interpolated convolution kernels and delays. + for (unsigned jj = 1; jj < InterpolationFactor; ++jj) { + float x = float(jj) / float(InterpolationFactor); // interpolate from 0 -> 1 + + kernelListL[i + jj] = HRTFKernel::createInterpolatedKernel(kernelListL[i], kernelListL[j], x); + } + } + + return nsReturnRef<HRTFElevation>(new HRTFElevation(&kernelListL, elevation, sampleRate)); +} + +nsReturnRef<HRTFElevation> HRTFElevation::createByInterpolatingSlices(HRTFElevation* hrtfElevation1, HRTFElevation* hrtfElevation2, float x, float sampleRate) +{ + MOZ_ASSERT(hrtfElevation1 && hrtfElevation2); + if (!hrtfElevation1 || !hrtfElevation2) + return nsReturnRef<HRTFElevation>(); + + MOZ_ASSERT(x >= 0.0 && x < 1.0); + + HRTFKernelList kernelListL; + kernelListL.SetLength(NumberOfTotalAzimuths); + + const HRTFKernelList& kernelListL1 = hrtfElevation1->kernelListL(); + const HRTFKernelList& kernelListL2 = hrtfElevation2->kernelListL(); + + // Interpolate kernels of corresponding azimuths of the two elevations. + for (unsigned i = 0; i < NumberOfTotalAzimuths; ++i) { + kernelListL[i] = HRTFKernel::createInterpolatedKernel(kernelListL1[i], kernelListL2[i], x); + } + + // Interpolate elevation angle. + double angle = (1.0 - x) * hrtfElevation1->elevationAngle() + x * hrtfElevation2->elevationAngle(); + + return nsReturnRef<HRTFElevation>(new HRTFElevation(&kernelListL, static_cast<int>(angle), sampleRate)); +} + +void HRTFElevation::getKernelsFromAzimuth(double azimuthBlend, unsigned azimuthIndex, HRTFKernel* &kernelL, HRTFKernel* &kernelR, double& frameDelayL, double& frameDelayR) +{ + bool checkAzimuthBlend = azimuthBlend >= 0.0 && azimuthBlend < 1.0; + MOZ_ASSERT(checkAzimuthBlend); + if (!checkAzimuthBlend) + azimuthBlend = 0.0; + + unsigned numKernels = m_kernelListL.Length(); + + bool isIndexGood = azimuthIndex < numKernels; + MOZ_ASSERT(isIndexGood); + if (!isIndexGood) { + kernelL = 0; + kernelR = 0; + return; + } + + // Return the left and right kernels, + // using symmetry to produce the right kernel. + kernelL = m_kernelListL[azimuthIndex]; + int azimuthIndexR = (numKernels - azimuthIndex) % numKernels; + kernelR = m_kernelListL[azimuthIndexR]; + + frameDelayL = kernelL->frameDelay(); + frameDelayR = kernelR->frameDelay(); + + int azimuthIndex2L = (azimuthIndex + 1) % numKernels; + double frameDelay2L = m_kernelListL[azimuthIndex2L]->frameDelay(); + int azimuthIndex2R = (numKernels - azimuthIndex2L) % numKernels; + double frameDelay2R = m_kernelListL[azimuthIndex2R]->frameDelay(); + + // Linearly interpolate delays. + frameDelayL = (1.0 - azimuthBlend) * frameDelayL + azimuthBlend * frameDelay2L; + frameDelayR = (1.0 - azimuthBlend) * frameDelayR + azimuthBlend * frameDelay2R; +} + +} // namespace WebCore diff --git a/dom/media/webaudio/blink/HRTFElevation.h b/dom/media/webaudio/blink/HRTFElevation.h new file mode 100644 index 000000000..e50947b12 --- /dev/null +++ b/dom/media/webaudio/blink/HRTFElevation.h @@ -0,0 +1,103 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef HRTFElevation_h +#define HRTFElevation_h + +#include "HRTFKernel.h" +#include "nsAutoRef.h" +#include "mozilla/MemoryReporting.h" + +struct SpeexResamplerState_; +typedef struct SpeexResamplerState_ SpeexResamplerState; + +namespace WebCore { + +// HRTFElevation contains all of the HRTFKernels (one left ear and one right ear per azimuth angle) for a particular elevation. + +class HRTFElevation { +public: + // Loads and returns an HRTFElevation with the given HRTF database subject name and elevation from browser (or WebKit.framework) resources. + // Normally, there will only be a single HRTF database set, but this API supports the possibility of multiple ones with different names. + // Interpolated azimuths will be generated based on InterpolationFactor. + // Valid values for elevation are -45 -> +90 in 15 degree increments. + static nsReturnRef<HRTFElevation> createBuiltin(int elevation, float sampleRate); + + // Given two HRTFElevations, and an interpolation factor x: 0 -> 1, returns an interpolated HRTFElevation. + static nsReturnRef<HRTFElevation> createByInterpolatingSlices(HRTFElevation* hrtfElevation1, HRTFElevation* hrtfElevation2, float x, float sampleRate); + + double elevationAngle() const { return m_elevationAngle; } + unsigned numberOfAzimuths() const { return NumberOfTotalAzimuths; } + float sampleRate() const { return m_sampleRate; } + + // Returns the left and right kernels for the given azimuth index. + // The interpolated delays based on azimuthBlend: 0 -> 1 are returned in frameDelayL and frameDelayR. + void getKernelsFromAzimuth(double azimuthBlend, unsigned azimuthIndex, HRTFKernel* &kernelL, HRTFKernel* &kernelR, double& frameDelayL, double& frameDelayR); + + // Total number of azimuths after interpolation. + static const unsigned NumberOfTotalAzimuths; + + static size_t fftSizeForSampleRate(float sampleRate); + + size_t sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + +private: + HRTFElevation(const HRTFElevation& other) = delete; + void operator=(const HRTFElevation& other) = delete; + + HRTFElevation(HRTFKernelList *kernelListL, int elevation, float sampleRate) + : m_elevationAngle(elevation) + , m_sampleRate(sampleRate) + { + m_kernelListL.SwapElements(*kernelListL); + } + + // Returns the list of left ear HRTFKernels for all the azimuths going from 0 to 360 degrees. + const HRTFKernelList& kernelListL() { return m_kernelListL; } + + // Given a specific azimuth and elevation angle, returns the left HRTFKernel. + // Values for azimuth must be multiples of 15 in 0 -> 345, + // but not all azimuths are available for elevations > +45. + // Valid values for elevation are -45 -> +90 in 15 degree increments. + static nsReturnRef<HRTFKernel> calculateKernelForAzimuthElevation(int azimuth, int elevation, SpeexResamplerState* resampler, float sampleRate); + + HRTFKernelList m_kernelListL; + double m_elevationAngle; + float m_sampleRate; +}; + +} // namespace WebCore + +template <> +class nsAutoRefTraits<WebCore::HRTFElevation> : + public nsPointerRefTraits<WebCore::HRTFElevation> { +public: + static void Release(WebCore::HRTFElevation* ptr) { delete(ptr); } +}; + +#endif // HRTFElevation_h diff --git a/dom/media/webaudio/blink/HRTFKernel.cpp b/dom/media/webaudio/blink/HRTFKernel.cpp new file mode 100644 index 000000000..3ee5e63a3 --- /dev/null +++ b/dom/media/webaudio/blink/HRTFKernel.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "HRTFKernel.h" +namespace WebCore { + +// Takes the input audio channel |impulseP| as an input impulse response and calculates the average group delay. +// This represents the initial delay before the most energetic part of the impulse response. +// The sample-frame delay is removed from the |impulseP| impulse response, and this value is returned. +// The |length| of the passed in |impulseP| must be must be a power of 2. +static float extractAverageGroupDelay(float* impulseP, size_t length) +{ + // Check for power-of-2. + MOZ_ASSERT(length && (length & (length - 1)) == 0); + + FFTBlock estimationFrame(length); + estimationFrame.PerformFFT(impulseP); + + float frameDelay = static_cast<float>(estimationFrame.ExtractAverageGroupDelay()); + estimationFrame.GetInverse(impulseP); + + return frameDelay; +} + +HRTFKernel::HRTFKernel(float* impulseResponse, size_t length, float sampleRate) + : m_frameDelay(0) + , m_sampleRate(sampleRate) +{ + AlignedTArray<float> buffer; + // copy to a 32-byte aligned buffer + if (((uintptr_t)impulseResponse & 31) != 0) { + buffer.SetLength(length); + mozilla::PodCopy(buffer.Elements(), impulseResponse, length); + impulseResponse = buffer.Elements(); + } + + // Determine the leading delay (average group delay) for the response. + m_frameDelay = extractAverageGroupDelay(impulseResponse, length); + + // The FFT size (with zero padding) needs to be twice the response length + // in order to do proper convolution. + unsigned fftSize = 2 * length; + + // Quick fade-out (apply window) at truncation point + // because the impulse response has been truncated. + unsigned numberOfFadeOutFrames = static_cast<unsigned>(sampleRate / 4410); // 10 sample-frames @44.1KHz sample-rate + MOZ_ASSERT(numberOfFadeOutFrames < length); + if (numberOfFadeOutFrames < length) { + for (unsigned i = length - numberOfFadeOutFrames; i < length; ++i) { + float x = 1.0f - static_cast<float>(i - (length - numberOfFadeOutFrames)) / numberOfFadeOutFrames; + impulseResponse[i] *= x; + } + } + + m_fftFrame = new FFTBlock(fftSize); + m_fftFrame->PadAndMakeScaledDFT(impulseResponse, length); +} + +// Interpolates two kernels with x: 0 -> 1 and returns the result. +nsReturnRef<HRTFKernel> HRTFKernel::createInterpolatedKernel(HRTFKernel* kernel1, HRTFKernel* kernel2, float x) +{ + MOZ_ASSERT(kernel1 && kernel2); + if (!kernel1 || !kernel2) + return nsReturnRef<HRTFKernel>(); + + MOZ_ASSERT(x >= 0.0 && x < 1.0); + x = mozilla::clamped(x, 0.0f, 1.0f); + + float sampleRate1 = kernel1->sampleRate(); + float sampleRate2 = kernel2->sampleRate(); + MOZ_ASSERT(sampleRate1 == sampleRate2); + if (sampleRate1 != sampleRate2) + return nsReturnRef<HRTFKernel>(); + + float frameDelay = (1 - x) * kernel1->frameDelay() + x * kernel2->frameDelay(); + + nsAutoPtr<FFTBlock> interpolatedFrame( + FFTBlock::CreateInterpolatedBlock(*kernel1->fftFrame(), *kernel2->fftFrame(), x)); + return HRTFKernel::create(interpolatedFrame, frameDelay, sampleRate1); +} + +} // namespace WebCore diff --git a/dom/media/webaudio/blink/HRTFKernel.h b/dom/media/webaudio/blink/HRTFKernel.h new file mode 100644 index 000000000..940e69b13 --- /dev/null +++ b/dom/media/webaudio/blink/HRTFKernel.h @@ -0,0 +1,119 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef HRTFKernel_h +#define HRTFKernel_h + +#include "nsAutoPtr.h" +#include "nsAutoRef.h" +#include "nsTArray.h" +#include "mozilla/FFTBlock.h" +#include "mozilla/MemoryReporting.h" + +namespace WebCore { + +using mozilla::FFTBlock; + +// HRTF stands for Head-Related Transfer Function. +// HRTFKernel is a frequency-domain representation of an impulse-response used as part of the spatialized panning system. +// For a given azimuth / elevation angle there will be one HRTFKernel for the left ear transfer function, and one for the right ear. +// The leading delay (average group delay) for each impulse response is extracted: +// m_fftFrame is the frequency-domain representation of the impulse response with the delay removed +// m_frameDelay is the leading delay of the original impulse response. +class HRTFKernel { +public: + // Note: this is destructive on the passed in |impulseResponse|. + // The |length| of |impulseResponse| must be a power of two. + // The size of the DFT will be |2 * length|. + static nsReturnRef<HRTFKernel> create(float* impulseResponse, size_t length, float sampleRate); + + static nsReturnRef<HRTFKernel> create(nsAutoPtr<FFTBlock> fftFrame, float frameDelay, float sampleRate); + + // Given two HRTFKernels, and an interpolation factor x: 0 -> 1, returns an interpolated HRTFKernel. + static nsReturnRef<HRTFKernel> createInterpolatedKernel(HRTFKernel* kernel1, HRTFKernel* kernel2, float x); + + FFTBlock* fftFrame() { return m_fftFrame.get(); } + + size_t fftSize() const { return m_fftFrame->FFTSize(); } + float frameDelay() const { return m_frameDelay; } + + float sampleRate() const { return m_sampleRate; } + double nyquist() const { return 0.5 * sampleRate(); } + + size_t sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const + { + size_t amount = aMallocSizeOf(this); + amount += m_fftFrame->SizeOfIncludingThis(aMallocSizeOf); + return amount; + } + +private: + HRTFKernel(const HRTFKernel& other) = delete; + void operator=(const HRTFKernel& other) = delete; + + // Note: this is destructive on the passed in |impulseResponse|. + HRTFKernel(float* impulseResponse, size_t fftSize, float sampleRate); + + HRTFKernel(nsAutoPtr<FFTBlock> fftFrame, float frameDelay, float sampleRate) + : m_fftFrame(fftFrame) + , m_frameDelay(frameDelay) + , m_sampleRate(sampleRate) + { + } + + nsAutoPtr<FFTBlock> m_fftFrame; + float m_frameDelay; + float m_sampleRate; +}; + +typedef nsTArray<nsAutoRef<HRTFKernel> > HRTFKernelList; + +} // namespace WebCore + +template <> +class nsAutoRefTraits<WebCore::HRTFKernel> : + public nsPointerRefTraits<WebCore::HRTFKernel> { +public: + static void Release(WebCore::HRTFKernel* ptr) { delete(ptr); } +}; + +namespace WebCore { + +inline nsReturnRef<HRTFKernel> HRTFKernel::create(float* impulseResponse, size_t length, float sampleRate) +{ + return nsReturnRef<HRTFKernel>(new HRTFKernel(impulseResponse, length, sampleRate)); +} + +inline nsReturnRef<HRTFKernel> HRTFKernel::create(nsAutoPtr<FFTBlock> fftFrame, float frameDelay, float sampleRate) +{ + return nsReturnRef<HRTFKernel>(new HRTFKernel(fftFrame, frameDelay, sampleRate)); +} + +} // namespace WebCore + +#endif // HRTFKernel_h diff --git a/dom/media/webaudio/blink/HRTFPanner.cpp b/dom/media/webaudio/blink/HRTFPanner.cpp new file mode 100644 index 000000000..c97ce4767 --- /dev/null +++ b/dom/media/webaudio/blink/HRTFPanner.cpp @@ -0,0 +1,324 @@ +/* + * Copyright (C) 2010, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "HRTFPanner.h" +#include "HRTFDatabaseLoader.h" + +#include "FFTConvolver.h" +#include "HRTFDatabase.h" +#include "AudioBlock.h" + +using namespace std; +using namespace mozilla; +using dom::ChannelInterpretation; + +namespace WebCore { + +// The value of 2 milliseconds is larger than the largest delay which exists in any HRTFKernel from the default HRTFDatabase (0.0136 seconds). +// We ASSERT the delay values used in process() with this value. +const double MaxDelayTimeSeconds = 0.002; + +const int UninitializedAzimuth = -1; +const unsigned RenderingQuantum = WEBAUDIO_BLOCK_SIZE; + +HRTFPanner::HRTFPanner(float sampleRate, already_AddRefed<HRTFDatabaseLoader> databaseLoader) + : m_databaseLoader(databaseLoader) + , m_sampleRate(sampleRate) + , m_crossfadeSelection(CrossfadeSelection1) + , m_azimuthIndex1(UninitializedAzimuth) + , m_azimuthIndex2(UninitializedAzimuth) + // m_elevation1 and m_elevation2 are initialized in pan() + , m_crossfadeX(0) + , m_crossfadeIncr(0) + , m_convolverL1(HRTFElevation::fftSizeForSampleRate(sampleRate)) + , m_convolverR1(m_convolverL1.fftSize()) + , m_convolverL2(m_convolverL1.fftSize()) + , m_convolverR2(m_convolverL1.fftSize()) + , m_delayLine(MaxDelayTimeSeconds * sampleRate, 1.0) +{ + MOZ_ASSERT(m_databaseLoader); + MOZ_COUNT_CTOR(HRTFPanner); +} + +HRTFPanner::~HRTFPanner() +{ + MOZ_COUNT_DTOR(HRTFPanner); +} + +size_t HRTFPanner::sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const +{ + size_t amount = aMallocSizeOf(this); + + // NB: m_databaseLoader can be shared, so it is not measured here + amount += m_convolverL1.sizeOfExcludingThis(aMallocSizeOf); + amount += m_convolverR1.sizeOfExcludingThis(aMallocSizeOf); + amount += m_convolverL2.sizeOfExcludingThis(aMallocSizeOf); + amount += m_convolverR2.sizeOfExcludingThis(aMallocSizeOf); + amount += m_delayLine.SizeOfExcludingThis(aMallocSizeOf); + + return amount; +} + +void HRTFPanner::reset() +{ + m_azimuthIndex1 = UninitializedAzimuth; + m_azimuthIndex2 = UninitializedAzimuth; + // m_elevation1 and m_elevation2 are initialized in pan() + m_crossfadeSelection = CrossfadeSelection1; + m_crossfadeX = 0.0f; + m_crossfadeIncr = 0.0f; + m_convolverL1.reset(); + m_convolverR1.reset(); + m_convolverL2.reset(); + m_convolverR2.reset(); + m_delayLine.Reset(); +} + +int HRTFPanner::calculateDesiredAzimuthIndexAndBlend(double azimuth, double& azimuthBlend) +{ + // Convert the azimuth angle from the range -180 -> +180 into the range 0 -> 360. + // The azimuth index may then be calculated from this positive value. + if (azimuth < 0) + azimuth += 360.0; + + HRTFDatabase* database = m_databaseLoader->database(); + MOZ_ASSERT(database); + + int numberOfAzimuths = database->numberOfAzimuths(); + const double angleBetweenAzimuths = 360.0 / numberOfAzimuths; + + // Calculate the azimuth index and the blend (0 -> 1) for interpolation. + double desiredAzimuthIndexFloat = azimuth / angleBetweenAzimuths; + int desiredAzimuthIndex = static_cast<int>(desiredAzimuthIndexFloat); + azimuthBlend = desiredAzimuthIndexFloat - static_cast<double>(desiredAzimuthIndex); + + // We don't immediately start using this azimuth index, but instead approach this index from the last index we rendered at. + // This minimizes the clicks and graininess for moving sources which occur otherwise. + desiredAzimuthIndex = max(0, desiredAzimuthIndex); + desiredAzimuthIndex = min(numberOfAzimuths - 1, desiredAzimuthIndex); + return desiredAzimuthIndex; +} + +void HRTFPanner::pan(double desiredAzimuth, double elevation, const AudioBlock* inputBus, AudioBlock* outputBus) +{ +#ifdef DEBUG + unsigned numInputChannels = + inputBus->IsNull() ? 0 : inputBus->ChannelCount(); + + MOZ_ASSERT(numInputChannels <= 2); + MOZ_ASSERT(inputBus->GetDuration() == WEBAUDIO_BLOCK_SIZE); +#endif + + bool isOutputGood = outputBus && outputBus->ChannelCount() == 2 && outputBus->GetDuration() == WEBAUDIO_BLOCK_SIZE; + MOZ_ASSERT(isOutputGood); + + if (!isOutputGood) { + if (outputBus) + outputBus->SetNull(outputBus->GetDuration()); + return; + } + + HRTFDatabase* database = m_databaseLoader->database(); + if (!database) { // not yet loaded + outputBus->SetNull(outputBus->GetDuration()); + return; + } + + // IRCAM HRTF azimuths values from the loaded database is reversed from the panner's notion of azimuth. + double azimuth = -desiredAzimuth; + + bool isAzimuthGood = azimuth >= -180.0 && azimuth <= 180.0; + MOZ_ASSERT(isAzimuthGood); + if (!isAzimuthGood) { + outputBus->SetNull(outputBus->GetDuration()); + return; + } + + // Normally, we'll just be dealing with mono sources. + // If we have a stereo input, implement stereo panning with left source processed by left HRTF, and right source by right HRTF. + + // Get destination pointers. + float* destinationL = + static_cast<float*>(const_cast<void*>(outputBus->mChannelData[0])); + float* destinationR = + static_cast<float*>(const_cast<void*>(outputBus->mChannelData[1])); + + double azimuthBlend; + int desiredAzimuthIndex = calculateDesiredAzimuthIndexAndBlend(azimuth, azimuthBlend); + + // Initially snap azimuth and elevation values to first values encountered. + if (m_azimuthIndex1 == UninitializedAzimuth) { + m_azimuthIndex1 = desiredAzimuthIndex; + m_elevation1 = elevation; + } + if (m_azimuthIndex2 == UninitializedAzimuth) { + m_azimuthIndex2 = desiredAzimuthIndex; + m_elevation2 = elevation; + } + + // Cross-fade / transition over a period of around 45 milliseconds. + // This is an empirical value tuned to be a reasonable trade-off between + // smoothness and speed. + const double fadeFrames = sampleRate() <= 48000 ? 2048 : 4096; + + // Check for azimuth and elevation changes, initiating a cross-fade if needed. + if (!m_crossfadeX && m_crossfadeSelection == CrossfadeSelection1) { + if (desiredAzimuthIndex != m_azimuthIndex1 || elevation != m_elevation1) { + // Cross-fade from 1 -> 2 + m_crossfadeIncr = 1 / fadeFrames; + m_azimuthIndex2 = desiredAzimuthIndex; + m_elevation2 = elevation; + } + } + if (m_crossfadeX == 1 && m_crossfadeSelection == CrossfadeSelection2) { + if (desiredAzimuthIndex != m_azimuthIndex2 || elevation != m_elevation2) { + // Cross-fade from 2 -> 1 + m_crossfadeIncr = -1 / fadeFrames; + m_azimuthIndex1 = desiredAzimuthIndex; + m_elevation1 = elevation; + } + } + + // Get the HRTFKernels and interpolated delays. + HRTFKernel* kernelL1; + HRTFKernel* kernelR1; + HRTFKernel* kernelL2; + HRTFKernel* kernelR2; + double frameDelayL1; + double frameDelayR1; + double frameDelayL2; + double frameDelayR2; + database->getKernelsFromAzimuthElevation(azimuthBlend, m_azimuthIndex1, m_elevation1, kernelL1, kernelR1, frameDelayL1, frameDelayR1); + database->getKernelsFromAzimuthElevation(azimuthBlend, m_azimuthIndex2, m_elevation2, kernelL2, kernelR2, frameDelayL2, frameDelayR2); + + bool areKernelsGood = kernelL1 && kernelR1 && kernelL2 && kernelR2; + MOZ_ASSERT(areKernelsGood); + if (!areKernelsGood) { + outputBus->SetNull(outputBus->GetDuration()); + return; + } + + MOZ_ASSERT(frameDelayL1 / sampleRate() < MaxDelayTimeSeconds && frameDelayR1 / sampleRate() < MaxDelayTimeSeconds); + MOZ_ASSERT(frameDelayL2 / sampleRate() < MaxDelayTimeSeconds && frameDelayR2 / sampleRate() < MaxDelayTimeSeconds); + + // Crossfade inter-aural delays based on transitions. + double frameDelaysL[WEBAUDIO_BLOCK_SIZE]; + double frameDelaysR[WEBAUDIO_BLOCK_SIZE]; + { + float x = m_crossfadeX; + float incr = m_crossfadeIncr; + for (unsigned i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) { + frameDelaysL[i] = (1 - x) * frameDelayL1 + x * frameDelayL2; + frameDelaysR[i] = (1 - x) * frameDelayR1 + x * frameDelayR2; + x += incr; + } + } + + // First run through delay lines for inter-aural time difference. + m_delayLine.Write(*inputBus); + // "Speakers" means a mono input is read into both outputs (with possibly + // different delays). + m_delayLine.ReadChannel(frameDelaysL, outputBus, 0, + ChannelInterpretation::Speakers); + m_delayLine.ReadChannel(frameDelaysR, outputBus, 1, + ChannelInterpretation::Speakers); + m_delayLine.NextBlock(); + + bool needsCrossfading = m_crossfadeIncr; + + const float* convolutionDestinationL1; + const float* convolutionDestinationR1; + const float* convolutionDestinationL2; + const float* convolutionDestinationR2; + + // Now do the convolutions. + // Note that we avoid doing convolutions on both sets of convolvers if we're not currently cross-fading. + + if (m_crossfadeSelection == CrossfadeSelection1 || needsCrossfading) { + convolutionDestinationL1 = + m_convolverL1.process(kernelL1->fftFrame(), destinationL); + convolutionDestinationR1 = + m_convolverR1.process(kernelR1->fftFrame(), destinationR); + } + + if (m_crossfadeSelection == CrossfadeSelection2 || needsCrossfading) { + convolutionDestinationL2 = + m_convolverL2.process(kernelL2->fftFrame(), destinationL); + convolutionDestinationR2 = + m_convolverR2.process(kernelR2->fftFrame(), destinationR); + } + + if (needsCrossfading) { + // Apply linear cross-fade. + float x = m_crossfadeX; + float incr = m_crossfadeIncr; + for (unsigned i = 0; i < WEBAUDIO_BLOCK_SIZE; ++i) { + destinationL[i] = (1 - x) * convolutionDestinationL1[i] + x * convolutionDestinationL2[i]; + destinationR[i] = (1 - x) * convolutionDestinationR1[i] + x * convolutionDestinationR2[i]; + x += incr; + } + // Update cross-fade value from local. + m_crossfadeX = x; + + if (m_crossfadeIncr > 0 && fabs(m_crossfadeX - 1) < m_crossfadeIncr) { + // We've fully made the crossfade transition from 1 -> 2. + m_crossfadeSelection = CrossfadeSelection2; + m_crossfadeX = 1; + m_crossfadeIncr = 0; + } else if (m_crossfadeIncr < 0 && fabs(m_crossfadeX) < -m_crossfadeIncr) { + // We've fully made the crossfade transition from 2 -> 1. + m_crossfadeSelection = CrossfadeSelection1; + m_crossfadeX = 0; + m_crossfadeIncr = 0; + } + } else { + const float* sourceL; + const float* sourceR; + if (m_crossfadeSelection == CrossfadeSelection1) { + sourceL = convolutionDestinationL1; + sourceR = convolutionDestinationR1; + } else { + sourceL = convolutionDestinationL2; + sourceR = convolutionDestinationR2; + } + PodCopy(destinationL, sourceL, WEBAUDIO_BLOCK_SIZE); + PodCopy(destinationR, sourceR, WEBAUDIO_BLOCK_SIZE); + } +} + +int HRTFPanner::maxTailFrames() const +{ + // Although the ideal tail time would be the length of the impulse + // response, there is additional tail time from the approximations in the + // implementation. Because HRTFPanner is implemented with a DelayKernel + // and a FFTConvolver, the tailTime of the HRTFPanner is the sum of the + // tailTime of the DelayKernel and the tailTime of the FFTConvolver. The + // FFTs of the convolver are fftSize(), half of which is latency, but this + // is aligned with blocks and so is reduced by the one block which is + // processed immediately. + return m_delayLine.MaxDelayTicks() + + m_convolverL1.fftSize()/2 + m_convolverL1.latencyFrames(); +} + +} // namespace WebCore diff --git a/dom/media/webaudio/blink/HRTFPanner.h b/dom/media/webaudio/blink/HRTFPanner.h new file mode 100644 index 000000000..f56d0d423 --- /dev/null +++ b/dom/media/webaudio/blink/HRTFPanner.h @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2010, Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef HRTFPanner_h +#define HRTFPanner_h + +#include "FFTConvolver.h" +#include "DelayBuffer.h" +#include "mozilla/MemoryReporting.h" + +namespace mozilla { +class AudioBlock; +} // namespace mozilla + +namespace WebCore { + +typedef nsTArray<float> AudioFloatArray; + +class HRTFDatabaseLoader; + +using mozilla::AudioBlock; + +class HRTFPanner { +public: + HRTFPanner(float sampleRate, already_AddRefed<HRTFDatabaseLoader> databaseLoader); + ~HRTFPanner(); + + // chunk durations must be 128 + void pan(double azimuth, double elevation, const AudioBlock* inputBus, AudioBlock* outputBus); + void reset(); + + size_t fftSize() const { return m_convolverL1.fftSize(); } + + float sampleRate() const { return m_sampleRate; } + + int maxTailFrames() const; + + size_t sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + +private: + // Given an azimuth angle in the range -180 -> +180, returns the corresponding azimuth index for the database, + // and azimuthBlend which is an interpolation value from 0 -> 1. + int calculateDesiredAzimuthIndexAndBlend(double azimuth, double& azimuthBlend); + + RefPtr<HRTFDatabaseLoader> m_databaseLoader; + + float m_sampleRate; + + // We maintain two sets of convolvers for smooth cross-faded interpolations when + // then azimuth and elevation are dynamically changing. + // When the azimuth and elevation are not changing, we simply process with one of the two sets. + // Initially we use CrossfadeSelection1 corresponding to m_convolverL1 and m_convolverR1. + // Whenever the azimuth or elevation changes, a crossfade is initiated to transition + // to the new position. So if we're currently processing with CrossfadeSelection1, then + // we transition to CrossfadeSelection2 (and vice versa). + // If we're in the middle of a transition, then we wait until it is complete before + // initiating a new transition. + + // Selects either the convolver set (m_convolverL1, m_convolverR1) or (m_convolverL2, m_convolverR2). + enum CrossfadeSelection { + CrossfadeSelection1, + CrossfadeSelection2 + }; + + CrossfadeSelection m_crossfadeSelection; + + // azimuth/elevation for CrossfadeSelection1. + int m_azimuthIndex1; + double m_elevation1; + + // azimuth/elevation for CrossfadeSelection2. + int m_azimuthIndex2; + double m_elevation2; + + // A crossfade value 0 <= m_crossfadeX <= 1. + float m_crossfadeX; + + // Per-sample-frame crossfade value increment. + float m_crossfadeIncr; + + FFTConvolver m_convolverL1; + FFTConvolver m_convolverR1; + FFTConvolver m_convolverL2; + FFTConvolver m_convolverR2; + + mozilla::DelayBuffer m_delayLine; + + AudioFloatArray m_tempL1; + AudioFloatArray m_tempR1; + AudioFloatArray m_tempL2; + AudioFloatArray m_tempR2; +}; + +} // namespace WebCore + +#endif // HRTFPanner_h diff --git a/dom/media/webaudio/blink/IIRFilter.cpp b/dom/media/webaudio/blink/IIRFilter.cpp new file mode 100644 index 000000000..94ec129c7 --- /dev/null +++ b/dom/media/webaudio/blink/IIRFilter.cpp @@ -0,0 +1,166 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "IIRFilter.h" + +#include <complex> + +namespace blink { + +// The length of the memory buffers for the IIR filter. This MUST be a power of two and must be +// greater than the possible length of the filter coefficients. +const int kBufferLength = 32; +static_assert(kBufferLength >= IIRFilter::kMaxOrder + 1, + "Internal IIR buffer length must be greater than maximum IIR Filter order."); + +IIRFilter::IIRFilter(const AudioDoubleArray* feedforwardCoef, const AudioDoubleArray* feedbackCoef) + : m_bufferIndex(0) + , m_feedback(feedbackCoef) + , m_feedforward(feedforwardCoef) +{ + m_xBuffer.SetLength(kBufferLength); + m_yBuffer.SetLength(kBufferLength); + reset(); +} + +IIRFilter::~IIRFilter() +{ +} + +void IIRFilter::reset() +{ + memset(m_xBuffer.Elements(), 0, m_xBuffer.Length() * sizeof(double)); + memset(m_yBuffer.Elements(), 0, m_yBuffer.Length() * sizeof(double)); +} + +static std::complex<double> evaluatePolynomial(const double* coef, std::complex<double> z, int order) +{ + // Use Horner's method to evaluate the polynomial P(z) = sum(coef[k]*z^k, k, 0, order); + std::complex<double> result = 0; + + for (int k = order; k >= 0; --k) + result = result * z + std::complex<double>(coef[k]); + + return result; +} + +void IIRFilter::process(const float* sourceP, float* destP, size_t framesToProcess) +{ + // Compute + // + // y[n] = sum(b[k] * x[n - k], k = 0, M) - sum(a[k] * y[n - k], k = 1, N) + // + // where b[k] are the feedforward coefficients and a[k] are the feedback coefficients of the + // filter. + + // This is a Direct Form I implementation of an IIR Filter. Should we consider doing a + // different implementation such as Transposed Direct Form II? + const double* feedback = m_feedback->Elements(); + const double* feedforward = m_feedforward->Elements(); + + MOZ_ASSERT(feedback); + MOZ_ASSERT(feedforward); + + // Sanity check to see if the feedback coefficients have been scaled appropriately. It must + // be EXACTLY 1! + MOZ_ASSERT(feedback[0] == 1); + + int feedbackLength = m_feedback->Length(); + int feedforwardLength = m_feedforward->Length(); + int minLength = std::min(feedbackLength, feedforwardLength); + + double* xBuffer = m_xBuffer.Elements(); + double* yBuffer = m_yBuffer.Elements(); + + for (size_t n = 0; n < framesToProcess; ++n) { + // To help minimize roundoff, we compute using double's, even though the filter coefficients + // only have single precision values. + double yn = feedforward[0] * sourceP[n]; + + // Run both the feedforward and feedback terms together, when possible. + for (int k = 1; k < minLength; ++k) { + int n = (m_bufferIndex - k) & (kBufferLength - 1); + yn += feedforward[k] * xBuffer[n]; + yn -= feedback[k] * yBuffer[n]; + } + + // Handle any remaining feedforward or feedback terms. + for (int k = minLength; k < feedforwardLength; ++k) + yn += feedforward[k] * xBuffer[(m_bufferIndex - k) & (kBufferLength - 1)]; + + for (int k = minLength; k < feedbackLength; ++k) + yn -= feedback[k] * yBuffer[(m_bufferIndex - k) & (kBufferLength - 1)]; + + // Save the current input and output values in the memory buffers for the next output. + m_xBuffer[m_bufferIndex] = sourceP[n]; + m_yBuffer[m_bufferIndex] = yn; + + m_bufferIndex = (m_bufferIndex + 1) & (kBufferLength - 1); + + // Avoid introducing a stream of subnormals + // TODO: Remove this code when Bug 1157635 is fixed. + if (fabs(yn) >= FLT_MIN) { + destP[n] = yn; + } else { + destP[n] = 0.0; + } + } +} + +void IIRFilter::getFrequencyResponse(int nFrequencies, const float* frequency, float* magResponse, float* phaseResponse) +{ + // Evaluate the z-transform of the filter at the given normalized frequencies from 0 to 1. (One + // corresponds to the Nyquist frequency.) + // + // The z-tranform of the filter is + // + // H(z) = sum(b[k]*z^(-k), k, 0, M) / sum(a[k]*z^(-k), k, 0, N); + // + // The desired frequency response is H(exp(j*omega)), where omega is in [0, 1). + // + // Let P(x) = sum(c[k]*x^k, k, 0, P) be a polynomial of order P. Then each of the sums in H(z) + // is equivalent to evaluating a polynomial at the point 1/z. + + for (int k = 0; k < nFrequencies; ++k) { + // zRecip = 1/z = exp(-j*frequency) + double omega = -M_PI * frequency[k]; + std::complex<double> zRecip = std::complex<double>(cos(omega), sin(omega)); + + std::complex<double> numerator = evaluatePolynomial(m_feedforward->Elements(), zRecip, m_feedforward->Length() - 1); + std::complex<double> denominator = evaluatePolynomial(m_feedback->Elements(), zRecip, m_feedback->Length() - 1); + // Strangely enough, using complex division: + // e.g. Complex response = numerator / denominator; + // fails on our test machines, yielding infinities and NaNs, so we do + // things the long way here. + double n = norm(denominator); + double r = (real(numerator)*real(denominator) + imag(numerator)*imag(denominator)) / n; + double i = (imag(numerator)*real(denominator) - real(numerator)*imag(denominator)) / n; + std::complex<double> response = std::complex<double>(r, i); + + magResponse[k] = static_cast<float>(abs(response)); + phaseResponse[k] = static_cast<float>(atan2(imag(response), real(response))); + } +} + +bool IIRFilter::buffersAreZero() +{ + double* xBuffer = m_xBuffer.Elements(); + double* yBuffer = m_yBuffer.Elements(); + + for (size_t k = 0; k < m_feedforward->Length(); ++k) { + if (xBuffer[(m_bufferIndex - k) & (kBufferLength - 1)] != 0.0) { + return false; + } + } + + for (size_t k = 0; k < m_feedback->Length(); ++k) { + if (fabs(yBuffer[(m_bufferIndex - k) & (kBufferLength - 1)]) >= FLT_MIN) { + return false; + } + } + + return true; +} + +} // namespace blink diff --git a/dom/media/webaudio/blink/IIRFilter.h b/dom/media/webaudio/blink/IIRFilter.h new file mode 100644 index 000000000..5656d959a --- /dev/null +++ b/dom/media/webaudio/blink/IIRFilter.h @@ -0,0 +1,58 @@ +// Copyright 2016 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef IIRFilter_h +#define IIRFilter_h + +typedef nsTArray<double> AudioDoubleArray; + +namespace blink { + +class IIRFilter final { +public: + // The maximum IIR filter order. This also limits the number of feedforward coefficients. The + // maximum number of coefficients is 20 according to the spec. + const static size_t kMaxOrder = 19; + IIRFilter(const AudioDoubleArray* feedforwardCoef, const AudioDoubleArray* feedbackCoef); + ~IIRFilter(); + + void process(const float* sourceP, float* destP, size_t framesToProcess); + + void reset(); + + void getFrequencyResponse(int nFrequencies, + const float* frequency, + float* magResponse, + float* phaseResponse); + + bool buffersAreZero(); + +private: + // Filter memory + // + // For simplicity, we assume |m_xBuffer| and |m_yBuffer| have the same length, and the length is + // a power of two. Since the number of coefficients has a fixed upper length, the size of + // xBuffer and yBuffer is fixed. |m_xBuffer| holds the old input values and |m_yBuffer| holds + // the old output values needed to compute the new output value. + // + // m_yBuffer[m_bufferIndex] holds the most recent output value, say, y[n]. Then + // m_yBuffer[m_bufferIndex - k] is y[n - k]. Similarly for m_xBuffer. + // + // To minimize roundoff, these arrays are double's instead of floats. + AudioDoubleArray m_xBuffer; + AudioDoubleArray m_yBuffer; + + // Index into the xBuffer and yBuffer arrays where the most current x and y values should be + // stored. xBuffer[bufferIndex] corresponds to x[n], the current x input value and + // yBuffer[bufferIndex] is where y[n], the current output value. + int m_bufferIndex; + + // Coefficients of the IIR filter. + const AudioDoubleArray* m_feedback; + const AudioDoubleArray* m_feedforward; +}; + +} // namespace blink + +#endif // IIRFilter_h diff --git a/dom/media/webaudio/blink/IRC_Composite_C_R0195-incl.cpp b/dom/media/webaudio/blink/IRC_Composite_C_R0195-incl.cpp new file mode 100644 index 000000000..daffb114f --- /dev/null +++ b/dom/media/webaudio/blink/IRC_Composite_C_R0195-incl.cpp @@ -0,0 +1,449 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim:set ts=2 sw=2 sts=2 et cindent: */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/** + * The sample data in the arrays here was derived for Webkit by Chris Rogers + * through averaging of impulse responses from the IRCAM Listen HRTF Database. + * The responses here are half the length of the Listen responses. This + * sample data has been granted to the Public Domain. + * + * This file is intended to be included in compilation of a single + * implementation file. + * + * Each elevation (p) contains impulse responses at a varying number of + * equally spaced azimuths for the left ear, ordered clockwise from in front + * the listener. + */ + +#include "mozilla/ArrayUtils.h" + +using mozilla::ArrayLength; + +const int16_t irc_composite_c_r0195_p315[][256] = + {/* IRC_Composite_C_R0195_T000_P315.wav */ + {-37,37,-38,39,-39,40,-41,42,-42,43,-43,44,-44,44,-44,44,-43,42,-39,36,-31,23,-10,-10,5,-655,-410,-552,-353,-474,-1525,-758,656,-263,70,1414,-1528,-731,-1811,1646,1312,-1501,-407,8893,-1543,7696,8084,2629,-2452,-234,3799,1676,177,-1077,-474,-1325,3527,985,265,-884,373,971,1024,-412,507,-173,259,-799,635,-628,507,-344,394,-359,178,-276,349,-201,137,-249,377,-311,263,-404,284,-244,173,-243,330,-320,112,-150,164,-142,174,-300,158,-197,13,-141,85,-190,64,-122,41,-122,60,-195,125,-163,10,-67,-6,-122,77,-133,26,-71,-42,-156,48,-152,-12,-89,-120,-104,-37,-154,-57,-139,-80,-165,-95,-242,-81,-146,-111,-178,-109,-208,-48,-178,-131,-163,-68,-169,-94,-190,-139,-190,-118,-204,-160,-220,-140,-204,-171,-238,-126,-203,-114,-209,-138,-177,-124,-184,-130,-175,-170,-185,-180,-231,-189,-233,-210,-236,-245,-288,-208,-329,-246,-274,-199,-273,-189,-267,-208,-215,-199,-187,-209,-206,-210,-123,-197,-156,-173,-142,-97,-123,-97,-107,-73,-84,-39,-50,-66,-11,-50,-12,-51,8,-27,19,-48,-9,-18,5,-42,-15,-35,-31,-27,-27,-64,-33,-54,-1,-98,-47,-56,-7,-76,-47,-70,-42,-54,-65,-76,-43,-57,-9,-61,-39,-58,33,-39,3,-34,20,-19,4,-71,61,-22,10}, + /* IRC_Composite_C_R0195_T015_P315.wav */ + {81,-82,83,-84,84,-85,86,-87,87,-87,87,-87,87,-86,84,-82,78,-72,63,-49,23,33,-344,-481,-563,-443,-265,-1527,-713,251,-1453,939,2510,-1221,-1282,-1307,806,585,-990,-82,9029,-4621,9096,11230,4611,-3051,400,2105,749,1644,165,-1556,-1521,3009,1430,723,-902,933,187,28,480,951,-214,122,-730,-95,-137,573,-593,558,-692,-62,28,16,-505,426,-283,227,-320,210,-374,303,-435,127,-128,76,-349,106,-364,139,-348,184,-425,-36,-441,91,-413,93,-444,33,-257,-74,-414,93,-379,19,-327,-43,-366,79,-293,20,-199,-76,-207,149,-239,68,-247,66,-219,61,-232,38,-212,36,-209,-27,-209,-58,-227,-6,-309,-12,-225,-60,-199,-10,-277,19,-207,-69,-211,-30,-261,-24,-233,-102,-217,-131,-247,-144,-229,-111,-256,-104,-254,-130,-241,-66,-249,-88,-223,-144,-199,-148,-229,-101,-242,-189,-240,-163,-308,-147,-285,-217,-239,-224,-291,-173,-269,-220,-209,-208,-240,-180,-212,-201,-217,-169,-184,-174,-178,-146,-209,-108,-186,-96,-108,-90,-120,-44,-101,-49,-39,-22,-44,1,-58,3,-19,-21,-8,-6,-22,-9,18,-15,-7,-23,-12,-24,-11,-43,-33,-33,-31,-57,-5,-64,-22,-45,-16,-87,-8,-40,-45,-57,-14,-53,-5,-47,-21,-45,-8,-33,13,-16,3,-29,6,-18,23,-31,24,-41}, + /* IRC_Composite_C_R0195_T030_P315.wav */ + {9,-9,8,-8,8,-8,8,-7,7,-6,5,-4,3,-2,0,2,-5,9,-14,23,-127,-380,-922,-742,-548,257,-2362,972,-1653,1079,1193,1855,-423,-3573,-1945,3974,274,-2796,11656,-988,5085,9362,10293,-750,-3105,-1864,2111,2283,-318,-221,-1158,-110,2923,410,-981,900,122,-303,833,532,-152,20,-462,17,-48,336,235,63,-647,577,-362,-19,-259,102,168,-103,-338,-333,24,-9,-458,287,-470,-273,-216,46,-484,13,-220,-143,-392,-290,-340,-198,-301,-237,-241,-176,-489,-201,-271,-252,-335,-60,-395,-225,-412,-191,-198,-164,-259,-64,-380,-75,-287,-9,-159,-126,-100,-116,-155,-96,-113,-23,-100,-117,-115,-164,-180,8,-173,-57,-208,-89,-129,-73,-188,-102,-184,-93,-204,-81,-217,-128,-180,-66,-279,-127,-244,-206,-146,-178,-190,-135,-228,-154,-205,-100,-196,-143,-185,-140,-235,-135,-209,-144,-158,-250,-202,-234,-227,-157,-214,-201,-260,-180,-244,-184,-234,-151,-192,-198,-223,-199,-199,-202,-189,-164,-233,-143,-220,-175,-186,-107,-156,-84,-181,-106,-116,-72,-63,-29,-76,-11,-83,15,-65,30,-2,-4,-41,4,-49,38,-44,57,-2,9,-61,11,-29,35,-27,2,-50,-23,-17,1,-57,2,-26,-14,-67,-39,-9,-30,-30,-21,-44,-39,-75,-12,-27,-13,-32,13,-22,-16,5,-2,23,-25,48,-24,-32,-30}, + /* IRC_Composite_C_R0195_T045_P315.wav */ + {52,-54,57,-59,62,-64,67,-71,74,-78,82,-86,91,-95,100,-104,107,-105,80,-502,-332,-993,-162,-1907,1505,-2021,-314,756,-842,5057,-1148,-2263,-3462,3639,-1435,4503,-272,9367,494,8006,14353,933,-5033,-2453,2315,1073,2918,-1236,-3010,2416,371,1956,-531,-1294,-177,691,1104,-312,402,-1300,693,-586,315,-26,538,-594,294,-267,-119,-580,378,28,261,-1010,385,-342,8,-224,217,-399,43,-603,-1,-295,-252,167,-340,-419,-328,-348,-86,-497,-57,-294,-381,-499,-201,-454,-232,-518,-17,-717,-310,-542,-84,-458,-96,-313,-154,-496,-112,-226,-165,-242,-163,-234,-306,-270,-70,-238,-108,-139,-101,-251,-218,-175,-17,-215,-23,-205,-109,-221,-12,-131,-27,-205,-45,-264,-158,-151,-4,-169,-113,-251,-102,-247,-100,-151,-158,-212,-170,-190,-217,-220,-105,-182,-191,-216,-210,-208,-188,-144,-93,-288,-132,-248,-124,-281,-112,-217,-92,-321,-80,-343,-94,-222,-100,-231,-229,-216,-139,-209,-164,-138,-158,-204,-180,-171,-145,-125,-68,-150,-139,-133,-97,-43,-133,-83,-49,-109,-53,-101,-20,-84,23,-64,-10,-116,38,-50,15,-23,-2,-3,-27,-28,3,14,36,-13,-21,-18,-38,28,-26,9,-12,-28,-46,-29,-8,8,18,-21,-12,-47,16,-23,-21,-22,-28,-21,-46,-32,37,-14,-1,-31,11,-4,-17,51,-42,23,-30,55}, + /* IRC_Composite_C_R0195_T060_P315.wav */ + {-9,10,-10,10,-11,11,-11,12,-12,13,-13,14,-14,14,-15,15,-14,14,-237,-853,-211,-839,-537,-1171,1035,-1099,1039,294,-1596,6549,-2739,-2660,-4050,4749,2134,7195,4024,6882,-1377,13010,8996,-6905,-3319,-3088,4606,2892,2461,-4423,-1310,1787,1273,1672,-1868,-79,1190,70,-141,-131,222,-677,570,-820,675,-811,128,-382,165,-353,-183,-560,68,-440,-382,-163,-67,-467,-152,-570,177,-472,-46,-374,-58,-324,-179,-380,-114,-308,-223,-231,-266,-228,-188,-382,-93,-468,-172,-439,-277,-467,-233,-484,-158,-431,-177,-375,-153,-360,-208,-377,-90,-359,-252,-321,-261,-288,-236,-352,-117,-397,-126,-318,-103,-229,-203,-302,-132,-152,-113,-159,-188,-103,-160,-141,-121,-237,-158,-186,-215,-126,-180,-203,-129,-258,-131,-232,-90,-192,-139,-222,-58,-238,-81,-214,-111,-210,-119,-232,-97,-257,-79,-254,-124,-244,-169,-224,-170,-218,-187,-194,-208,-142,-212,-136,-216,-224,-142,-210,-181,-238,-144,-243,-81,-233,-107,-193,-82,-124,-113,-114,-86,-61,-72,-88,-74,-42,-62,-68,-57,-28,-20,-32,-42,-4,-55,-25,11,-34,-17,-21,12,-38,-17,-4,-21,-19,-51,-19,-40,-1,-58,-23,-65,-46,-5,-23,-26,-24,-22,36,-42,4,-20,73,-50,19,-61,15,-46,1,-36,-37,-6,-9,13,-34,18,-10,58,-13,38,32,29,4,16,-6}, + /* IRC_Composite_C_R0195_T075_P315.wav */ + {-13,13,-14,14,-14,14,-14,14,-14,13,-13,11,-9,5,2,-16,50,-741,214,-932,242,-1432,-236,-662,1347,-571,-1196,4105,-1805,3633,-3512,-1059,-3340,6144,8904,2949,-3056,13761,4639,6581,1016,-7994,-537,2069,9498,-3772,-2314,-3272,3945,434,437,-1200,-83,923,138,258,258,-7,455,-141,284,-478,398,-1090,528,-789,-29,-665,-287,-554,-73,-808,-317,-229,-409,-754,-201,-562,103,-767,-233,-393,90,-725,-54,-341,-112,-375,-320,-304,-39,-501,-232,-150,-220,-432,-164,-401,-81,-462,-293,-278,-139,-468,-172,-335,-180,-318,-233,-226,-103,-361,-214,-194,-168,-399,-129,-254,-92,-285,-156,-134,-28,-353,-136,-218,-68,-245,-164,-257,-128,-294,-188,-259,-264,-283,-216,-266,-192,-249,-243,-221,-193,-297,-159,-234,-247,-176,-224,-169,-180,-199,-220,-117,-192,-112,-197,-146,-176,-92,-190,-108,-218,-108,-210,-116,-237,-105,-215,-104,-222,-112,-224,-93,-273,-105,-266,-128,-293,-88,-283,-37,-279,-49,-211,-28,-227,20,-197,2,-189,32,-205,58,-176,59,-144,57,-167,132,-119,93,-104,104,-78,87,-109,101,-75,67,-98,89,-87,61,-85,56,-78,56,-103,66,-107,43,-101,53,-122,26,-89,31,-77,5,-71,25,-79,9,-93,21,-74,23,-83,51,-92,20,-72,56,-59,56,-36,38,19,39,4,62,-17,56,-23,68}, + /* IRC_Composite_C_R0195_T090_P315.wav */ + {87,-92,97,-103,109,-116,123,-131,140,-150,162,-174,189,-205,224,-244,266,-286,51,-859,535,-1364,139,-1195,1589,-390,911,-1048,4305,473,-5108,558,766,2725,10227,-95,2100,7357,10939,4034,-9033,1273,-876,7923,448,-413,-5710,1509,967,2067,-1395,-1318,853,624,-242,51,284,401,299,341,-114,602,-538,101,-460,-168,-515,-276,-591,-395,-537,-566,-206,-633,-470,-595,-421,-387,-497,-528,-554,-277,-415,-451,-399,-376,-198,-441,-287,-406,-190,-420,-196,-316,-218,-371,-230,-316,-251,-337,-304,-180,-217,-314,-203,-175,-197,-285,-220,-238,-109,-305,-167,-234,-146,-316,-92,-192,-70,-236,-136,-80,-80,-227,-175,-115,-77,-157,-162,-216,-61,-249,-168,-273,-182,-316,-207,-288,-178,-282,-287,-286,-206,-333,-257,-356,-226,-357,-253,-372,-144,-341,-201,-306,-120,-225,-145,-256,-69,-151,-103,-191,-78,-159,-72,-231,-86,-209,-102,-254,-75,-225,-131,-246,-122,-189,-129,-238,-123,-178,-85,-185,-80,-172,-78,-165,-42,-131,-62,-158,-35,-137,-15,-123,-23,-84,14,-68,23,-29,8,12,-7,21,17,-7,6,-12,18,-60,33,-67,51,-69,41,-34,41,-45,33,-37,31,-56,11,-29,-2,-76,4,-43,17,-73,-1,-63,19,-62,-23,-71,-23,-50,-30,-62,24,-59,23,-75,63,-53,35,-32,38,-9,16,4,53,-2,34,-15}, + /* IRC_Composite_C_R0195_T105_P315.wav */ + {-4,4,-4,4,-4,4,-4,4,-5,5,-5,6,-7,9,-11,17,-28,67,21,-444,-141,-224,-503,-492,56,581,659,-254,970,3243,-1085,-4435,2584,328,6386,5564,-809,5990,6762,10583,-5626,-2592,332,5216,4379,-2326,-2369,-2841,2364,794,414,-2336,841,434,185,-245,467,54,226,66,291,109,-14,-250,-37,-434,-55,-468,-301,-501,-528,-390,-260,-361,-561,-460,-370,-387,-354,-670,-414,-508,-325,-671,-240,-470,-287,-539,-267,-403,-309,-523,-407,-423,-444,-437,-347,-265,-394,-345,-296,-231,-221,-203,-113,-208,-173,-209,-71,-127,-120,-168,-119,-150,-164,-160,-171,-155,-129,-132,-133,-114,-84,-152,-145,-150,-50,-140,-100,-199,-121,-188,-145,-209,-221,-240,-266,-216,-273,-254,-311,-241,-309,-303,-306,-288,-304,-324,-325,-280,-286,-254,-285,-213,-282,-199,-235,-168,-198,-151,-152,-157,-138,-157,-155,-189,-176,-212,-179,-192,-145,-184,-171,-174,-110,-150,-113,-170,-84,-115,-76,-135,-71,-161,-62,-153,-49,-144,-73,-126,-80,-100,-82,-63,-82,-57,-74,14,-40,-10,-30,25,-21,31,-22,45,-26,43,-15,48,-18,20,-19,34,-32,26,-30,33,-39,33,-38,25,-62,21,-45,-12,-65,-6,-49,-13,-61,8,-71,9,-80,15,-87,37,-62,49,-58,33,-30,20,-31,-30,-19,-18,-22,12,-19,18,-18,62,-6,19}, + /* IRC_Composite_C_R0195_T120_P315.wav */ + {-8,8,-9,10,-10,11,-12,13,-14,15,-17,18,-20,22,-24,27,-30,33,-36,-6,-353,-241,59,-307,-656,81,435,931,-462,1098,2228,1185,-5297,2389,1039,4366,5054,563,5052,5065,10308,-3912,-1912,-658,6384,3010,-2420,-2503,-2288,1665,1300,-465,-1526,865,689,-244,192,664,-256,-73,265,-57,-312,-7,-322,-127,-354,-230,-494,-275,-378,-331,-253,-267,-433,-173,-259,-320,-294,-344,-567,-293,-505,-543,-515,-293,-398,-306,-402,-421,-360,-360,-466,-547,-514,-519,-327,-326,-417,-471,-219,-314,-177,-232,-161,-243,-135,-249,-154,-136,-89,-210,-64,-203,-123,-169,-90,-247,-100,-141,-68,-108,-41,-101,-97,-95,-145,-67,-56,-122,-193,-178,-180,-188,-181,-281,-271,-252,-234,-263,-302,-242,-343,-214,-391,-204,-407,-189,-457,-208,-383,-206,-352,-186,-336,-183,-268,-158,-243,-145,-229,-99,-205,-110,-223,-83,-256,-120,-241,-124,-258,-103,-238,-73,-205,-48,-194,-12,-168,-14,-161,-15,-200,-2,-184,-29,-168,-39,-203,-35,-143,-59,-138,-57,-120,-39,-78,-38,-71,4,-85,25,-41,42,-65,60,-35,71,-28,56,-41,66,-43,40,-26,-6,-23,-11,-1,-28,3,-16,-8,-25,-4,-23,-19,-21,-43,6,-38,-12,-49,4,-21,-1,-32,9,-8,22,-23,-1,-11,-14,-32,-12,-40,-9,-31,23,-39,25,-13,20,-8,9}, + /* IRC_Composite_C_R0195_T135_P315.wav */ + {-23,24,-24,24,-24,24,-24,24,-24,24,-24,24,-24,23,-23,22,-21,19,-17,12,2,-321,142,-352,-116,-71,-511,212,1241,-690,1132,1447,1818,-2325,-1459,2842,2322,3950,-401,7294,1799,9821,384,-3014,-458,4980,4067,-3265,-1817,-2557,1536,1050,141,-1408,467,945,477,-318,841,-225,-162,-191,333,-541,-289,-847,48,-224,-228,-453,-42,-332,-101,-393,-171,-405,-103,-444,-70,-591,-149,-459,-69,-570,-117,-584,-95,-396,-42,-496,-210,-651,-204,-618,-333,-581,-255,-540,-313,-471,-202,-369,-230,-385,-202,-278,-178,-259,-149,-205,-123,-195,-100,-150,-73,-188,-126,-225,-124,-193,-92,-182,-65,-172,-74,-168,-103,-186,-57,-178,-89,-280,-140,-220,-97,-251,-226,-268,-204,-268,-271,-286,-293,-290,-360,-269,-322,-274,-307,-261,-331,-275,-290,-250,-261,-307,-242,-239,-199,-225,-211,-141,-180,-148,-189,-147,-163,-178,-155,-195,-114,-193,-96,-201,-69,-171,-54,-158,-66,-130,-90,-112,-83,-108,-98,-108,-90,-89,-94,-103,-90,-117,-87,-105,-51,-97,-64,-70,-56,-23,-79,7,-88,34,-80,43,-77,63,-50,59,-68,43,-51,41,-54,60,-92,29,-102,48,-85,28,-79,9,-67,13,-66,37,-57,38,-64,47,-47,53,-38,54,-42,32,-33,27,-15,13,-24,-26,-34,-6,-41,23,-23,1,-31,23,-1,22,-48,-14}, + /* IRC_Composite_C_R0195_T150_P315.wav */ + {-14,14,-14,14,-14,14,-14,14,-14,14,-15,15,-15,15,-15,15,-15,15,-15,15,-14,13,-9,-299,105,-109,-149,-174,-101,123,928,331,409,1091,1957,-1219,-1800,2020,2641,4225,-365,6765,1276,7468,2095,-1421,-1941,2847,4183,-2838,-2013,-2585,1301,1369,1048,-1018,299,712,620,-358,419,-160,-391,-365,85,-244,-278,-735,101,-159,-46,-323,-112,-300,-73,-375,-177,-408,-241,-349,-232,-359,-171,-320,-131,-293,-2,-318,-62,-331,-78,-385,-166,-449,-212,-441,-266,-408,-251,-382,-246,-414,-254,-434,-274,-407,-251,-444,-252,-399,-189,-349,-176,-289,-151,-238,-106,-181,-45,-201,-17,-170,-8,-151,12,-150,-68,-196,-148,-187,-145,-232,-247,-286,-284,-266,-250,-295,-275,-287,-281,-302,-308,-288,-299,-267,-330,-280,-301,-267,-269,-255,-300,-276,-267,-240,-267,-229,-279,-186,-258,-159,-229,-176,-170,-148,-137,-189,-140,-182,-128,-193,-123,-144,-95,-99,-87,-75,-90,-47,-89,-71,-115,-103,-102,-112,-110,-131,-87,-120,-99,-104,-130,-68,-115,-50,-116,-33,-115,-23,-91,-20,-77,-32,-46,-36,-20,-19,-1,-1,-16,2,-30,-4,-10,2,-12,-25,-22,-46,-39,-40,-29,-51,-40,-76,-30,-47,-17,-48,-11,-52,8,-41,31,-26,41,1,54,-33,53,-2,35,-28,34,-23,25,-31,33,-25,-2,-7,10,-26,-60,-40}, + /* IRC_Composite_C_R0195_T165_P315.wav */ + {-17,17,-18,19,-19,20,-21,21,-22,23,-24,25,-26,27,-29,30,-32,33,-35,37,-39,42,-45,48,-52,67,-40,152,75,-119,-31,837,302,348,1063,1535,471,-104,-785,1551,1039,5803,545,3679,3043,5986,50,-1878,1830,-1451,2642,-2294,-1114,-2432,2146,1209,-135,-693,285,141,308,-50,-77,-237,196,-409,80,-447,-119,-467,-15,-415,-52,-429,-63,-216,-215,-423,-211,-250,-99,-343,-232,-231,-78,-380,-66,-225,10,-172,-61,-149,-128,-331,-281,-369,-348,-420,-336,-400,-303,-402,-320,-360,-377,-402,-338,-363,-356,-382,-392,-353,-371,-352,-344,-280,-280,-250,-233,-166,-154,-160,-136,-102,-71,-93,-69,-118,-111,-164,-179,-223,-230,-272,-255,-285,-312,-330,-270,-347,-306,-400,-338,-356,-324,-353,-315,-327,-313,-301,-321,-289,-309,-258,-317,-227,-285,-196,-252,-189,-237,-155,-182,-95,-165,-128,-123,-87,-127,-113,-150,-118,-122,-92,-114,-79,-90,-44,-70,-19,-82,-37,-76,-88,-84,-86,-94,-117,-109,-92,-108,-75,-136,-74,-119,-62,-120,-51,-126,-38,-97,-20,-110,-3,-105,29,-72,41,-66,43,-69,58,-54,55,-37,38,-45,18,-47,10,-73,-1,-104,15,-120,0,-103,12,-106,19,-73,20,-41,43,-9,42,-5,48,-4,46,3,29,-8,24,11,13,-8,11,55,13,32,16,31,9,-51,-42}, + /* IRC_Composite_C_R0195_T180_P315.wav */ + {24,-25,26,-27,28,-30,31,-33,34,-36,38,-40,42,-45,47,-50,53,-57,61,-65,70,-76,82,-90,100,-116,158,-120,110,-47,143,-200,288,-83,509,566,678,584,1717,-752,-218,-645,3620,1547,2553,2618,2850,3932,1154,2478,-3553,2655,-1012,521,-1943,-220,418,465,358,-445,32,572,410,189,111,242,-109,240,99,120,-178,-44,-146,-12,-251,-169,-110,-64,-56,-37,-65,38,137,-75,-42,-159,-127,-127,-11,-39,-7,-121,-97,-173,-207,-322,-357,-395,-311,-334,-329,-369,-303,-285,-259,-281,-323,-274,-364,-264,-415,-314,-459,-317,-463,-346,-399,-298,-323,-239,-217,-185,-167,-162,-146,-115,-142,-125,-194,-139,-196,-150,-224,-208,-224,-201,-206,-219,-254,-241,-239,-289,-306,-358,-320,-362,-312,-398,-353,-429,-362,-421,-352,-421,-332,-364,-272,-351,-188,-256,-150,-222,-109,-165,-57,-142,-72,-111,-54,-116,-66,-134,-87,-132,-39,-149,-55,-144,-3,-111,-37,-108,-57,-98,-89,-106,-109,-135,-117,-147,-114,-137,-99,-140,-85,-140,-56,-119,-68,-119,-57,-94,-53,-95,-61,-85,-42,-76,-22,-61,-39,-37,-44,-27,-31,-14,-37,-23,-16,-39,0,-62,-11,-92,2,-64,-27,-61,-33,-39,-34,-35,-26,-27,5,-20,14,-33,30,-28,12,-27,25,-7,7,29,-15,24,-9,67,32,52,-7,19,-10,-34}, + /* IRC_Composite_C_R0195_T195_P315.wav */ + {-3,3,-4,4,-4,4,-4,4,-4,4,-4,4,-5,5,-5,5,-5,5,-6,6,-6,7,-7,8,-10,16,-53,-21,71,-52,123,66,-67,138,16,149,471,552,491,879,834,185,-864,886,1624,2747,1377,2335,2675,2476,2941,-204,-424,-902,1080,-594,-652,-972,-15,737,158,15,-103,673,669,117,134,496,369,6,174,211,204,39,24,7,-16,8,-20,185,63,80,52,87,-18,-50,-107,-83,-58,-90,-149,-191,-215,-179,-280,-228,-426,-325,-403,-260,-377,-309,-454,-294,-358,-263,-350,-288,-312,-298,-376,-336,-392,-351,-440,-368,-423,-300,-356,-221,-309,-156,-237,-133,-233,-159,-209,-147,-233,-211,-247,-210,-236,-217,-261,-238,-270,-208,-309,-227,-327,-269,-364,-336,-391,-375,-368,-412,-407,-388,-417,-354,-411,-328,-386,-273,-319,-198,-244,-162,-205,-101,-178,-129,-177,-104,-161,-77,-156,-48,-139,-49,-168,-54,-132,-40,-129,-49,-113,-43,-97,-66,-144,-76,-174,-72,-177,-115,-186,-100,-175,-109,-149,-106,-124,-101,-86,-76,-56,-81,-27,-107,3,-87,-27,-99,-52,-77,-57,-80,-68,-65,-62,-77,-17,-71,-16,-67,-12,-47,-11,-33,-14,-33,-31,-4,-26,-4,-79,6,-73,-6,-74,-4,-61,-7,-62,10,-50,33,-27,0,-4,51,21,29,16,43,17,21,38,16,70,-26,47,-23}, + /* IRC_Composite_C_R0195_T210_P315.wav */ + {6,-6,6,-6,6,-6,6,-6,6,-6,6,-7,7,-7,7,-7,7,-7,8,-8,8,-8,9,-9,9,-9,9,-9,9,-6,-16,-81,-27,-64,-11,-116,37,-7,308,224,339,624,595,47,-450,456,1108,1630,1528,1730,2147,2381,2098,1287,-731,283,215,213,-551,-518,308,203,729,-194,652,579,759,441,763,571,528,360,442,343,364,229,431,125,293,81,275,88,238,45,215,155,198,82,61,12,5,-51,-58,-119,-156,-200,-208,-255,-244,-261,-244,-232,-236,-252,-249,-226,-258,-256,-283,-248,-281,-296,-308,-266,-304,-256,-333,-220,-281,-198,-262,-186,-220,-164,-184,-148,-198,-168,-234,-150,-270,-190,-317,-221,-358,-246,-358,-268,-356,-277,-357,-276,-375,-272,-357,-257,-384,-239,-370,-230,-374,-258,-374,-262,-363,-281,-344,-263,-317,-224,-292,-194,-243,-172,-216,-149,-196,-138,-151,-112,-138,-121,-140,-121,-158,-136,-149,-135,-124,-140,-124,-136,-125,-160,-126,-165,-139,-151,-144,-151,-125,-132,-116,-99,-80,-92,-84,-64,-97,-68,-84,-76,-83,-93,-75,-65,-93,-87,-89,-70,-103,-55,-102,-68,-112,-68,-70,-61,-55,-62,-34,-41,-24,-58,-48,-63,-63,-52,-80,-56,-81,-54,-68,-55,-48,-48,-24,-69,-21,-60,-6,-21,-10,-12,-6,14,-8,19,1,57,22,38,15,27,32,33}, + /* IRC_Composite_C_R0195_T225_P315.wav */ + {-7,7,-8,8,-8,8,-8,8,-8,8,-8,8,-8,8,-8,8,-8,8,-8,9,-9,9,-9,9,-9,9,-9,9,-6,33,28,58,51,52,71,102,56,94,137,218,326,455,483,632,249,92,428,904,1132,1053,1398,1725,1892,1761,996,419,-35,393,230,-426,83,187,561,443,405,624,567,778,322,714,220,555,133,272,57,175,33,-14,10,34,86,73,113,24,-32,-47,-92,-107,-159,-198,-236,-286,-255,-307,-290,-357,-323,-402,-335,-423,-329,-409,-335,-383,-288,-312,-274,-328,-286,-276,-227,-303,-252,-323,-243,-382,-269,-374,-281,-400,-300,-362,-289,-363,-292,-337,-287,-341,-275,-329,-275,-353,-270,-350,-272,-365,-283,-346,-284,-356,-310,-344,-298,-351,-295,-331,-289,-350,-307,-364,-293,-334,-305,-333,-280,-301,-259,-287,-211,-253,-202,-233,-185,-196,-178,-176,-188,-164,-153,-127,-135,-117,-145,-120,-134,-127,-143,-116,-126,-80,-113,-89,-119,-102,-89,-86,-92,-78,-108,-66,-94,-63,-86,-58,-73,-44,-52,-66,-55,-76,-50,-92,-33,-91,-19,-106,-44,-97,-52,-76,-62,-65,-52,-53,-56,-64,-38,-57,-27,-67,-32,-61,-26,-56,-44,-40,-36,-27,-22,-5,-13,-6,12,-15,8,-1,18,1,-3,6,-13,24,6,33,17,44,11,63,31,57,47,73,42,34,14,5}, + /* IRC_Composite_C_R0195_T240_P315.wav */ + {0,0,0,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,2,58,78,16,22,51,114,84,41,96,70,113,111,119,154,190,332,340,437,381,393,351,291,690,869,1203,1249,1386,1308,1507,1378,1185,595,424,365,626,420,458,252,382,637,446,207,255,488,305,321,49,221,53,63,79,-40,108,-82,101,-101,-13,-203,-152,-221,-220,-235,-289,-282,-281,-296,-224,-344,-241,-368,-252,-366,-268,-359,-308,-318,-288,-298,-317,-264,-285,-261,-303,-269,-298,-270,-320,-331,-336,-351,-327,-351,-348,-331,-347,-276,-351,-246,-372,-243,-370,-280,-365,-300,-410,-295,-413,-330,-447,-345,-440,-333,-430,-333,-415,-326,-403,-318,-379,-309,-372,-303,-357,-286,-300,-274,-299,-260,-274,-222,-258,-207,-249,-178,-228,-179,-202,-181,-164,-194,-132,-181,-100,-149,-105,-124,-85,-117,-92,-115,-104,-129,-96,-119,-72,-137,-65,-104,-51,-87,-75,-80,-56,-63,-66,-73,-81,-74,-88,-75,-87,-74,-68,-80,-63,-77,-50,-74,-36,-76,-42,-77,-46,-59,-47,-48,-54,-32,-62,-21,-50,-24,-43,-33,-23,-40,-10,-7,-13,-16,-4,2,7,17,-10,37,-7,35,11,27,-4,32,-1,15,-21,-1,-28,7,-9,16,21,30,38,52,37,48,38,34,3}, + /* IRC_Composite_C_R0195_T255_P315.wav */ + {-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-3,3,-3,3,-3,4,-6,74,75,79,61,128,72,79,70,94,189,182,258,204,285,366,406,480,409,503,603,776,875,1073,1366,1703,1601,1585,1344,1253,1054,708,209,184,245,471,220,82,328,234,143,-43,229,63,146,52,46,143,-26,108,-162,-81,-337,-290,-357,-257,-274,-266,-282,-295,-253,-242,-177,-217,-241,-242,-180,-187,-261,-282,-286,-285,-278,-318,-290,-350,-241,-329,-216,-356,-250,-344,-253,-301,-333,-307,-381,-310,-406,-310,-398,-327,-389,-328,-383,-321,-397,-364,-416,-386,-447,-400,-469,-437,-477,-423,-470,-435,-472,-439,-441,-374,-396,-361,-359,-340,-300,-318,-278,-293,-236,-257,-203,-214,-171,-197,-164,-178,-159,-160,-150,-162,-167,-187,-166,-177,-176,-193,-156,-159,-125,-174,-110,-158,-92,-129,-96,-113,-107,-94,-103,-101,-73,-98,-45,-93,-27,-108,-14,-122,-36,-134,-52,-131,-66,-121,-83,-114,-73,-107,-51,-91,-32,-79,2,-74,2,-68,4,-68,20,-45,9,-63,-6,-50,8,-15,-2,-22,-9,6,4,25,-11,21,-12,18,-6,-1,-16,-16,-15,-8,7,8,-10,14,-14,21,-9,18,-34,-11,0,0,38,9,28,24,33,41,32,56,10,45}, + /* IRC_Composite_C_R0195_T270_P315.wav */ + {5,-5,5,-5,5,-5,5,-6,6,-6,6,-6,6,-6,7,-7,7,-7,8,-8,8,-9,9,-10,10,-11,12,-13,14,-16,19,-24,35,-112,-87,-172,-147,-119,-127,-152,-113,-103,-89,-113,-68,-116,-46,22,42,151,321,392,548,700,898,1192,1367,1289,1342,1432,1348,1134,1055,823,716,745,988,819,628,418,468,438,382,415,357,462,457,454,331,457,286,349,199,216,110,272,103,141,96,107,157,39,151,90,143,187,135,145,132,119,90,29,67,9,33,-99,-4,-78,-31,-119,-118,-125,-133,-39,-116,6,-53,-9,-2,-28,-8,-68,-109,-175,-231,-243,-320,-296,-388,-312,-439,-323,-431,-308,-403,-341,-379,-320,-333,-304,-317,-322,-321,-302,-340,-277,-367,-233,-348,-216,-344,-197,-304,-195,-255,-199,-226,-173,-179,-167,-168,-175,-177,-169,-197,-168,-238,-156,-231,-167,-240,-168,-219,-192,-218,-202,-205,-205,-186,-197,-157,-172,-143,-163,-152,-143,-150,-149,-177,-148,-159,-149,-150,-163,-154,-183,-160,-189,-132,-190,-124,-156,-96,-125,-92,-99,-99,-74,-85,-61,-83,-67,-68,-74,-62,-91,-54,-91,-46,-108,-22,-86,-15,-70,-6,-63,-3,-43,-35,-76,-52,-91,-99,-89,-83,-72,-67,-70,-42,-53,-31,-59,-32,-49,-39,-55,-65,-43,-43,-36,-50,-25,-39,-34,-26,-31}, + /* IRC_Composite_C_R0195_T285_P315.wav */ + {0,0,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,2,-2,2,-2,3,-3,0,-53,-54,-56,-85,-47,-114,-135,-181,-153,-193,-267,-244,-55,-96,1,65,-104,-149,-27,77,318,544,620,776,1096,1388,1457,1232,925,941,734,587,918,901,616,762,669,803,637,587,517,641,585,459,366,454,473,472,377,381,369,477,434,303,311,258,424,217,330,203,348,239,206,163,147,190,93,131,3,88,29,61,25,-4,30,-29,-32,-79,-68,-48,-73,-75,-119,-13,-30,17,-48,5,-35,5,-39,-80,-142,-105,-167,-166,-226,-200,-281,-233,-317,-276,-334,-290,-353,-338,-366,-316,-342,-297,-343,-306,-273,-252,-266,-278,-281,-276,-239,-265,-258,-270,-226,-250,-191,-215,-181,-217,-149,-202,-131,-195,-119,-225,-148,-263,-146,-220,-148,-221,-170,-215,-156,-215,-188,-262,-202,-269,-194,-235,-202,-241,-188,-209,-153,-204,-154,-203,-167,-217,-151,-214,-172,-225,-158,-182,-145,-170,-150,-164,-121,-136,-87,-134,-90,-102,-41,-87,-63,-73,-53,-73,-60,-73,-67,-76,-98,-68,-64,-72,-69,-72,-35,-71,-32,-55,-37,-56,-47,-39,-69,-58,-90,-53,-99,-57,-83,-34,-50,-55,-58,-67,-57,-63,-70,-62,-74,-53,-70,-30,-49,-56,-37,-35,-21,-10,-19,-29}, + /* IRC_Composite_C_R0195_T300_P315.wav */ + {2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-3,4,-10,-133,-133,-170,-242,-249,-433,-299,-139,-159,192,133,-70,22,-303,18,-19,635,218,706,1507,1430,1383,2387,1796,1075,392,368,909,611,309,-168,353,2,566,420,570,464,600,533,643,640,611,592,536,352,641,435,676,299,466,377,487,301,349,330,262,326,234,228,152,89,163,56,54,-10,7,-78,-45,-66,-85,-68,-104,-18,4,-26,41,2,31,0,79,5,36,26,46,69,42,-19,-67,-82,-80,-133,-166,-222,-198,-222,-228,-274,-302,-279,-261,-261,-282,-253,-280,-237,-241,-240,-230,-249,-229,-231,-221,-230,-219,-245,-228,-234,-188,-202,-201,-222,-167,-182,-137,-203,-165,-172,-150,-180,-163,-208,-169,-194,-164,-229,-193,-245,-204,-252,-223,-246,-236,-257,-266,-272,-274,-271,-280,-267,-251,-243,-225,-207,-200,-174,-184,-165,-180,-160,-164,-160,-158,-167,-156,-169,-151,-138,-125,-125,-108,-104,-80,-94,-71,-82,-75,-85,-57,-68,-57,-49,-58,-52,-65,-51,-59,-53,-74,-44,-57,-44,-43,-49,-55,-42,-57,-55,-65,-60,-62,-53,-54,-78,-70,-64,-55,-66,-73,-66,-48,-68,-87,-49,-57,-32,-77,-35,-66,-33,-71,-35,-70,15,-17,-11,-33}, + /* IRC_Composite_C_R0195_T315_P315.wav */ + {-3,3,-4,4,-4,4,-4,4,-4,4,-4,5,-5,5,-5,5,-5,5,-6,6,-6,6,-6,6,-6,6,-5,3,2,-152,-177,-483,-235,-110,-653,-348,-150,-38,208,331,33,-385,-315,-27,364,811,-94,2504,888,2086,3574,3328,531,314,789,729,404,-337,56,36,119,405,418,656,613,503,327,557,477,459,703,343,212,405,546,432,317,280,459,304,364,271,334,99,204,199,155,38,34,17,94,27,75,-28,51,-48,69,-29,44,-56,45,-30,20,5,41,-28,41,31,56,13,68,19,90,-37,31,-65,21,-87,-51,-142,-103,-155,-98,-191,-137,-221,-116,-207,-139,-209,-136,-203,-147,-207,-168,-209,-164,-226,-176,-243,-198,-258,-194,-267,-197,-246,-196,-229,-191,-208,-190,-182,-197,-201,-171,-193,-170,-221,-151,-220,-141,-245,-167,-251,-184,-255,-210,-246,-238,-245,-223,-258,-247,-284,-254,-278,-249,-311,-255,-297,-217,-263,-193,-236,-176,-198,-176,-178,-155,-172,-140,-181,-132,-195,-91,-184,-92,-165,-90,-121,-68,-117,-88,-97,-47,-73,-55,-70,-16,-46,-13,-61,-26,-38,-50,-48,-41,-43,-40,-60,-49,-55,-58,-57,-47,-68,-57,-81,-49,-74,-61,-74,-29,-70,-35,-79,-39,-87,-35,-94,-49,-86,-55,-65,-49,-58,-43,-30,-32,-23,-33,-5,-23,19,-13,-17}, + /* IRC_Composite_C_R0195_T330_P315.wav */ + {-7,7,-7,7,-7,7,-7,7,-7,7,-7,7,-7,7,-7,7,-7,8,-8,8,-8,9,-9,9,-10,11,-11,-55,-296,-386,-360,-162,-486,-689,-594,323,-279,489,253,-225,-799,-208,-290,1653,-875,1421,3185,831,3972,4758,3089,-835,674,981,1685,-351,-114,-17,248,390,777,359,517,535,503,290,712,58,681,346,142,-203,198,199,331,-307,34,132,139,70,114,91,13,123,184,191,4,23,205,163,125,72,141,-40,14,124,-28,33,-51,40,-5,35,-58,73,-52,-16,56,78,-40,-37,45,32,27,55,-7,-15,-18,29,-29,22,-117,6,-57,-69,-79,-66,-162,-105,-133,-121,-164,-165,-210,-152,-236,-167,-217,-215,-247,-204,-244,-201,-239,-194,-273,-180,-249,-181,-223,-192,-224,-139,-212,-188,-198,-169,-226,-134,-219,-153,-208,-148,-204,-149,-219,-168,-214,-162,-245,-160,-257,-219,-229,-208,-279,-218,-292,-266,-282,-268,-275,-227,-298,-216,-236,-164,-238,-151,-226,-142,-217,-147,-203,-145,-177,-146,-138,-122,-131,-73,-151,-51,-110,-31,-107,-6,-86,-9,-40,-10,-36,-1,-49,-9,-42,-8,-74,2,-73,3,-80,-26,-79,6,-86,-19,-76,-29,-75,-32,-78,-38,-65,-46,-77,-46,-88,-55,-75,-74,-82,-34,-77,-58,-74,-44,-61,-16,-21,-21,-1,-32,25,-5,-9,-4}, + /* IRC_Composite_C_R0195_T345_P315.wav */ + {-3,3,-3,3,-3,3,-3,3,-3,3,-2,2,-2,2,-1,1,0,0,1,-2,3,-4,6,-9,13,-23,-205,-456,-570,-178,-609,-516,-1049,-349,515,157,-280,1141,-1675,-135,-1096,1502,703,-567,2409,4580,1615,5569,6660,-925,461,21,3064,-94,275,-939,176,137,1125,718,-145,338,911,169,330,365,552,148,369,-393,179,-127,204,80,-84,-339,8,81,-65,-288,145,50,-22,-24,61,62,45,-71,194,159,54,-19,226,-56,24,48,99,-31,-91,-8,53,24,-79,12,113,-69,-3,43,52,-53,25,22,42,-13,-5,-1,64,-132,-15,-42,-12,-176,-19,-103,-113,-146,-76,-99,-119,-177,-139,-96,-193,-229,-107,-210,-181,-214,-106,-219,-211,-156,-157,-151,-246,-153,-144,-151,-254,-173,-147,-195,-202,-155,-196,-154,-199,-151,-187,-147,-192,-144,-157,-216,-170,-139,-200,-196,-193,-158,-269,-172,-256,-190,-293,-226,-252,-229,-318,-238,-250,-265,-306,-166,-254,-191,-300,-137,-229,-129,-286,-136,-186,-156,-221,-108,-162,-109,-143,-76,-137,-51,-129,-13,-99,-24,-56,17,-62,-20,-41,40,-86,44,-52,39,-123,42,-65,39,-115,-16,-46,0,-101,-28,-69,-10,-115,-27,-101,20,-128,3,-110,13,-133,-3,-101,-28,-103,-3,-79,-10,-82,10,-56,27,-77,25,-50,57,-33,20,-49,39}}; + +const int16_t irc_composite_c_r0195_p330[][256] = + {/* IRC_Composite_C_R0195_T000_P330.wav */ + {-59,61,-63,65,-67,69,-71,73,-76,78,-81,83,-86,89,-92,95,-98,100,-102,103,-103,99,-90,66,27,-206,-447,-812,-1040,-532,-532,-221,-2282,2737,-1254,634,-40,577,-3131,-820,-289,5598,-4456,4514,11627,-957,5804,7393,108,-5260,1410,3318,1621,-1983,2287,284,1686,1238,2060,-1196,399,489,1551,51,439,-136,620,290,-51,26,548,-418,535,-429,119,-693,256,-317,191,-412,18,-258,-48,-331,42,-245,-151,-84,-244,-168,-112,-248,56,-243,-130,-346,3,-311,-140,-201,-205,-208,-164,-257,-153,-216,-142,-212,-32,-240,-169,-200,-80,-259,-56,-266,-49,-259,-153,-247,-131,-186,-180,-157,-174,-170,-168,-133,-130,-144,-118,-156,-112,-157,-115,-125,-52,-108,-95,-100,-113,-69,-143,-89,-121,-105,-124,-163,-161,-185,-102,-218,-93,-213,-136,-158,-144,-182,-122,-122,-161,-147,-153,-151,-116,-162,-100,-155,-94,-176,-98,-138,-94,-127,-119,-122,-158,-125,-151,-130,-178,-168,-144,-200,-186,-199,-181,-157,-192,-201,-216,-176,-230,-170,-197,-219,-207,-194,-203,-187,-195,-174,-204,-175,-205,-170,-207,-182,-206,-156,-195,-149,-193,-165,-200,-125,-166,-120,-182,-142,-113,-73,-137,-86,-97,-75,-88,-72,-83,-37,-82,-24,-72,-40,-53,24,-38,-23,-48,32,10,7,-19,18,7,43,7,34,32,65,53,56,21,94,55,42}, + /* IRC_Composite_C_R0195_T015_P330.wav */ + {-33,32,-32,31,-31,30,-28,27,-25,22,-19,15,-10,4,5,-16,31,-53,84,-136,240,-673,177,-174,-1030,-1321,-76,-1250,-372,289,-2348,2418,1442,-314,-2260,351,-1076,96,-4201,12653,-2793,350,16253,7416,-1734,373,1945,-1722,32,2367,1990,-2906,2200,2573,955,-397,1580,-424,684,371,1473,401,8,-1088,1156,-110,164,-526,361,-233,-337,-706,160,-330,-24,-130,132,-810,170,-491,242,-434,33,-622,355,-505,-308,-68,-61,-264,-71,-244,-294,-284,-179,-295,41,-462,-220,-369,-36,-507,-206,-424,-65,-416,-180,-392,-246,-316,-59,-245,-204,-339,-224,-205,-78,-425,-107,-254,-66,-399,-77,-350,46,-239,-96,-256,-101,-268,-138,-142,-190,-179,-136,-172,-84,-261,-40,-173,25,-283,-32,-282,9,-234,-87,-198,-101,-238,-154,-207,-159,-166,-106,-164,-136,-199,-109,-121,-73,-175,-65,-149,-73,-162,-108,-135,-78,-99,-124,-126,-179,-91,-133,-84,-188,-122,-167,-148,-155,-182,-183,-160,-158,-219,-207,-224,-181,-161,-192,-206,-207,-174,-243,-140,-189,-173,-194,-138,-203,-173,-192,-143,-155,-154,-216,-158,-170,-138,-202,-110,-182,-132,-154,-83,-201,-104,-130,-44,-129,-80,-139,-19,-72,-80,-88,-16,-110,-20,-46,-35,-88,15,-32,6,-67,-9,-16,52,-18,27,27,26,-2,60,51,76,28,98,40,77,33,94,11,62}, + /* IRC_Composite_C_R0195_T030_P330.wav */ + {15,-16,18,-19,21,-23,26,-29,32,-36,41,-47,54,-62,73,-86,104,-126,155,-102,601,-1085,-197,-1634,218,-1892,836,-1472,627,332,2248,1679,-4388,-1076,2778,-5228,3611,10385,-5976,10952,11266,9110,-4453,651,-313,-354,33,2898,-224,-1072,2571,1824,-115,539,940,-84,401,1263,337,3,-171,-426,685,-69,-27,-94,-916,-1001,131,-752,-458,-101,-74,-99,-305,-309,-166,-102,238,-512,98,-429,-43,-482,424,-183,-138,-249,-301,-240,-13,-418,-203,-184,-296,-341,-269,-474,-99,-447,-210,-601,-403,-560,-148,-418,-397,-430,-241,-495,-140,-391,-94,-358,-170,-431,-28,-368,-72,-337,-69,-376,-11,-267,-144,-348,-177,-200,-156,-317,-161,-307,-97,-238,-69,-237,-166,-271,-82,-187,-69,-237,-35,-248,-105,-213,-38,-207,-108,-284,-91,-256,-64,-223,-92,-227,-52,-205,-48,-178,-94,-174,-26,-226,-71,-202,-71,-184,-34,-207,-88,-154,-79,-180,-41,-222,-49,-215,-56,-245,-90,-251,-51,-260,-109,-246,-150,-229,-109,-239,-125,-253,-146,-228,-85,-219,-106,-252,-82,-250,-58,-194,-116,-232,-74,-193,-81,-184,-110,-195,-65,-162,-92,-193,-65,-199,-29,-203,0,-193,28,-151,-16,-159,-4,-109,-9,-90,-21,-99,36,-92,27,-82,30,-74,71,-74,64,-43,102,-28,93,18,88,22,98,29,116,21,126,-20,133,-40,143,-66}, + /* IRC_Composite_C_R0195_T045_P330.wav */ + {60,-60,60,-60,60,-60,59,-57,55,-51,47,-40,30,-15,-9,50,-138,582,-538,-783,-136,149,-1756,-848,-253,-449,1379,-797,1611,1075,2352,-3846,-4473,1829,1877,4778,13625,-4798,10293,11126,4895,-5087,-2315,-1117,-112,3354,2968,-606,-2642,2599,370,2356,-155,634,-118,50,-430,371,-366,83,83,846,-691,615,-552,-124,-1033,-101,-1482,300,-868,142,-849,-166,-356,234,-620,-26,-586,234,-687,38,-602,184,-537,-8,-502,109,-408,41,-516,144,-611,54,-513,-33,-440,-242,-381,-176,-498,-276,-575,-140,-578,-79,-706,-148,-475,-195,-498,-214,-378,-197,-385,-257,-315,-80,-443,-59,-376,-102,-363,-123,-440,-39,-442,-136,-304,-144,-309,-84,-271,-165,-242,-238,-200,-117,-273,-150,-258,-130,-283,-92,-309,-42,-296,-47,-253,-76,-218,8,-252,-78,-168,-84,-181,-86,-207,-54,-197,-48,-239,-19,-220,-19,-245,-20,-221,-34,-247,-31,-246,-93,-181,-96,-211,-94,-210,-85,-235,-118,-230,-101,-229,-107,-245,-109,-215,-112,-220,-113,-204,-100,-188,-108,-185,-89,-182,-62,-197,-34,-195,-28,-194,-18,-182,-55,-157,-81,-141,-90,-141,-91,-129,-74,-112,-85,-107,-64,-103,-64,-86,-50,-93,-43,-62,-35,-57,-57,-38,-24,-28,-39,-24,-20,-16,22,2,35,17,56,35,75,47,56,59,88,45,61,91,80,67,62,68,59}, + /* IRC_Composite_C_R0195_T060_P330.wav */ + {-16,18,-21,24,-27,30,-34,39,-45,51,-59,68,-79,93,-109,120,-488,-209,-843,-446,581,-2538,150,-1048,1674,-298,921,-422,4633,-1379,-3456,-5235,5897,-232,13802,4771,-1871,13790,9150,509,-7321,-2062,426,4376,2825,-66,-4120,2160,1014,1965,-182,10,-66,1012,-1092,605,-694,-103,-630,876,-1446,848,-616,147,-237,208,-605,430,-846,156,-639,-33,-577,-169,-800,-107,-681,-261,-491,-122,-613,-72,-646,-89,-523,-258,-835,-111,-630,-192,-684,-120,-546,-114,-589,-198,-484,-123,-592,-31,-441,-137,-356,-160,-262,-88,-337,-230,-206,-197,-286,-158,-371,-90,-386,-164,-357,-120,-396,-123,-371,-159,-394,-268,-385,-156,-411,-140,-387,-213,-351,-179,-344,-165,-326,-182,-213,-154,-216,-130,-224,-133,-226,-137,-212,-88,-294,-83,-283,-112,-241,-166,-252,-129,-207,-171,-148,-189,-146,-134,-197,-75,-135,-114,-111,-109,-99,-40,-137,-112,-65,-123,-140,-104,-208,-112,-191,-189,-188,-164,-205,-119,-255,-149,-161,-150,-183,-173,-162,-174,-126,-195,-97,-145,-155,-118,-129,-86,-145,-98,-141,-61,-119,-118,-63,-133,-28,-155,2,-161,-3,-128,-39,-100,-78,-65,-82,-72,-98,-47,-85,-70,-46,-75,-12,-101,21,-108,22,-100,40,-92,45,-75,34,-63,31,-40,44,-41,58,-23,74,-14,74,-19,131,-21,113,30,101,49,110,57,108,51}, + /* IRC_Composite_C_R0195_T075_P330.wav */ + {19,-20,21,-23,25,-26,28,-31,33,-36,39,-42,45,-49,49,-225,-118,-411,-201,-767,-125,-1198,-1086,1587,699,-114,366,4108,-2207,1045,-7292,822,4055,16836,-2188,1091,15052,6204,1571,-5363,-5126,3112,6714,709,-1466,-3132,1975,682,2154,-1147,580,-537,152,-77,-200,-771,391,-354,-354,-457,389,-921,324,-902,497,-455,-10,-125,532,-709,91,-249,-171,-384,-149,-591,-267,-649,-63,-714,-477,-400,-204,-742,-437,-554,-445,-510,-517,-561,-379,-611,-347,-592,-417,-611,-301,-482,-385,-503,-245,-302,-310,-258,-221,-225,-194,-239,-127,-248,-118,-185,-116,-277,-78,-132,-151,-167,-94,-212,-171,-287,-162,-301,-224,-259,-202,-317,-238,-263,-235,-226,-328,-285,-227,-274,-225,-257,-270,-272,-203,-280,-198,-229,-168,-195,-197,-135,-134,-188,-159,-143,-143,-184,-122,-175,-115,-188,-85,-144,-140,-133,-147,-139,-167,-127,-183,-140,-187,-127,-176,-160,-172,-135,-190,-179,-159,-144,-201,-142,-175,-140,-206,-117,-148,-146,-179,-121,-175,-129,-135,-92,-156,-126,-159,-68,-176,-108,-129,-91,-133,-75,-91,-67,-116,-63,-52,-31,-122,-11,-115,3,-129,15,-110,-22,-119,-11,-83,-62,-34,-39,-48,-27,-43,-19,-79,23,-48,-1,-86,40,-64,16,-37,23,-6,-6,9,18,18,23,24,45,17,82,40,87,28,105,40,116,77,81,80,85}, + /* IRC_Composite_C_R0195_T090_P330.wav */ + {6,-4,3,-1,0,3,-5,8,-11,16,-21,29,-39,57,-101,-332,89,-835,-16,8,-1022,-629,-474,1050,924,-984,2683,3640,-2207,-5863,2261,-3476,15168,2953,-3266,10727,14390,3174,-8455,-1966,1449,7129,3075,-3700,-2692,1997,423,1234,-1087,216,-471,1061,-1107,458,-1402,142,319,-88,-425,76,-1043,226,-230,12,-536,-207,-663,129,-455,253,-222,-284,-472,86,-636,265,-368,-261,-539,-160,-407,43,-778,-256,-683,-475,-586,-306,-628,-455,-647,-525,-513,-416,-500,-430,-812,-419,-489,-274,-452,-386,-597,-258,-363,-159,-236,-327,-241,-259,-214,-139,-145,-206,-216,-123,-79,-29,-96,-65,-217,-263,-177,-100,-202,-186,-272,-223,-240,-138,-180,-221,-352,-224,-206,-195,-213,-254,-233,-244,-227,-156,-224,-178,-249,-190,-199,-133,-154,-164,-183,-191,-143,-185,-101,-190,-166,-201,-98,-150,-133,-119,-165,-142,-178,-120,-115,-180,-149,-197,-152,-187,-75,-218,-143,-264,-128,-205,-139,-221,-148,-269,-159,-215,-126,-214,-123,-256,-105,-233,-71,-203,-97,-215,-79,-182,-53,-120,-82,-122,-49,-119,20,-120,24,-141,6,-133,24,-115,14,-116,-39,-71,-8,-71,6,-93,-11,-108,40,-59,43,-147,22,-98,28,-64,17,-87,-13,-67,63,-36,44,-53,62,-77,123,-52,145,-81,82,-33,141,-4,116,8,98,14,137,56,139,-7,138,4}, + /* IRC_Composite_C_R0195_T105_P330.wav */ + {61,-61,61,-61,62,-62,62,-62,63,-63,63,-64,64,-65,67,-301,294,-741,-246,-201,457,-1576,-144,-73,2001,-1275,1763,1153,6179,-10039,184,1999,2771,10917,-378,522,13686,11704,-7376,-5609,1748,7382,4547,-1426,-5565,-24,2068,630,-441,-1191,186,450,-243,220,-909,-111,-78,770,-727,124,-899,-156,-79,202,-685,-336,-650,-314,-474,-53,-350,-261,-756,191,-463,128,-417,-139,-484,-53,-226,-113,-375,-280,-491,-342,-457,-195,-589,-428,-623,-328,-572,-393,-551,-458,-577,-399,-453,-401,-526,-392,-496,-278,-442,-319,-518,-259,-377,-158,-346,-171,-366,-187,-308,-53,-156,-44,-233,-111,-203,-9,-156,-124,-286,-249,-248,-172,-147,-210,-273,-296,-215,-151,-154,-166,-209,-170,-207,-76,-118,-174,-253,-208,-154,-172,-145,-172,-242,-211,-169,-70,-176,-103,-198,-93,-133,-36,-100,-118,-191,-149,-134,-127,-138,-220,-229,-254,-179,-191,-192,-230,-211,-235,-161,-158,-161,-230,-195,-206,-174,-165,-144,-216,-190,-173,-127,-136,-156,-157,-179,-150,-128,-122,-138,-124,-152,-83,-109,-30,-73,-66,-103,-55,-77,-32,-75,-113,-125,-86,-47,-60,-39,-89,-29,-60,20,-18,-21,-32,-8,-50,24,-43,-1,-69,-6,-57,11,-53,21,-58,-2,-13,35,-10,30,5,44,12,60,31,79,-4,79,46,97,47,97,36,128,43,132,30,81,38}, + /* IRC_Composite_C_R0195_T120_P330.wav */ + {1,4,-8,14,-20,27,-35,44,-54,66,-79,95,-114,135,-159,177,-87,615,-830,163,-909,1304,-1626,-325,297,1206,69,-817,4405,1017,-2560,-616,-3770,4387,14092,-5772,3858,10124,9882,-2074,-2959,-3337,7410,7437,-1780,-6636,-2212,2639,1700,-1078,-1371,-262,1153,-566,417,-320,27,-39,-111,485,-441,-792,-288,-146,-108,-616,-333,-464,-419,-367,-303,-262,-308,-516,-133,-270,-200,-382,-324,-225,-347,-205,-250,-254,-201,-400,-249,-330,-242,-364,-366,-273,-444,-377,-352,-336,-480,-405,-375,-496,-436,-362,-461,-436,-395,-354,-445,-362,-274,-397,-353,-222,-328,-290,-351,-239,-329,-117,-69,-109,-182,-35,-73,-135,-239,-228,-363,-234,-203,-243,-333,-218,-233,-231,-229,-116,-190,-172,-177,-158,-144,-144,-172,-173,-215,-124,-180,-106,-203,-150,-185,-121,-123,-149,-106,-93,-132,-84,-116,-33,-138,-72,-186,-81,-187,-113,-205,-194,-255,-235,-238,-195,-263,-202,-264,-198,-268,-158,-241,-175,-267,-183,-249,-160,-199,-167,-203,-153,-184,-118,-137,-101,-164,-93,-143,-66,-128,-30,-127,-42,-113,-31,-78,-23,-59,-78,-78,-48,-79,-53,-70,-40,-106,-22,-46,-9,-51,-12,-37,-31,-54,-23,-49,-43,-68,-43,-55,-39,-14,-29,-16,-13,-8,32,0,28,5,31,33,68,33,69,42,71,38,89,64,82,64,81,94,57,103,62,51,87}, + /* IRC_Composite_C_R0195_T135_P330.wav */ + {13,-11,8,-5,2,2,-7,12,-18,26,-34,45,-58,75,-96,126,-173,263,-756,239,-382,327,-504,374,-988,304,-762,1963,32,1243,612,772,3408,-6680,-2100,10509,4890,-1044,6633,2426,10000,1888,-3554,-3952,7154,5846,-3202,-5792,-2133,1379,2382,-1044,-683,-846,1056,-24,511,18,303,-710,-25,-39,-85,-861,-206,-321,-34,-428,-245,-428,-30,-639,-166,-459,-198,-463,-354,-339,-255,-329,-348,-224,-286,-255,-287,-204,-181,-232,-210,-296,-199,-313,-262,-347,-268,-316,-307,-365,-310,-360,-308,-316,-324,-335,-371,-355,-377,-361,-310,-401,-283,-402,-244,-368,-238,-331,-274,-247,-165,-162,-178,-185,-197,-205,-193,-250,-203,-288,-187,-284,-187,-262,-183,-219,-206,-232,-196,-178,-177,-216,-242,-166,-214,-147,-219,-161,-195,-148,-178,-168,-190,-170,-141,-148,-164,-119,-116,-35,-121,-54,-95,-56,-120,-107,-112,-149,-152,-172,-185,-195,-227,-175,-253,-211,-280,-223,-250,-252,-243,-251,-235,-239,-213,-184,-218,-176,-225,-139,-205,-123,-184,-114,-154,-113,-98,-100,-89,-89,-91,-67,-61,-32,-65,-41,-68,-21,-70,-18,-87,-13,-97,-10,-79,-5,-41,-42,-23,-67,8,-74,15,-75,-43,-63,-41,-18,-81,-7,-69,6,-49,2,-9,-7,21,-8,24,-11,44,32,44,38,36,66,51,91,52,103,44,90,55,87,41,60,28,49}, + /* IRC_Composite_C_R0195_T150_P330.wav */ + {15,-18,20,-22,25,-28,31,-35,38,-42,47,-52,57,-63,70,-76,84,-91,97,-95,51,-395,348,-546,384,-515,230,-347,78,797,314,1274,475,2177,1227,-4216,-2348,10076,258,3084,3609,6149,5472,3566,-4049,-1019,5212,3739,-5321,-3637,-1580,2270,1066,-633,-1395,-136,1340,-32,75,-243,507,-628,158,108,-226,-702,-291,-112,-126,-404,-330,-254,-212,-362,-151,-436,-14,-424,-215,-583,-44,-508,-144,-379,-62,-360,-158,-295,-27,-305,-69,-339,-66,-367,-167,-326,-112,-361,-177,-468,-151,-402,-103,-407,-145,-397,-208,-387,-142,-366,-207,-368,-232,-411,-224,-349,-159,-358,-152,-366,-101,-313,-105,-307,-196,-327,-268,-341,-250,-319,-245,-350,-228,-325,-151,-267,-108,-294,-109,-251,-84,-251,-104,-207,-91,-253,-103,-244,-91,-252,-85,-272,-130,-311,-129,-241,-94,-173,-90,-147,-80,-140,-35,-126,-79,-186,-118,-197,-120,-210,-155,-272,-176,-269,-156,-268,-151,-277,-170,-275,-153,-283,-181,-265,-186,-257,-194,-217,-154,-209,-128,-189,-106,-201,-80,-156,-34,-154,-17,-151,12,-97,27,-70,9,-39,-39,-3,-46,-29,-50,-61,-28,-93,-9,-89,-8,-103,1,-74,-1,-70,-9,-35,-44,-51,-51,-29,-31,-30,-13,-35,10,8,7,-4,11,13,35,12,38,37,49,36,56,47,69,81,52,69,15,90,11,52,-17,56}, + /* IRC_Composite_C_R0195_T165_P330.wav */ + {-38,38,-39,39,-39,40,-40,41,-42,43,-44,46,-47,49,-52,55,-59,64,-70,79,-90,108,-143,381,-197,374,-312,378,-424,566,-428,1134,331,1309,501,1274,2077,-920,-3821,4175,5452,953,5098,2533,5399,3026,943,-4554,1848,1742,-912,-4176,-875,-267,1882,-418,-1283,-863,1021,217,-28,-198,445,-494,-277,-183,13,-551,-347,-206,-115,-218,-241,-334,-209,-134,-196,-318,-365,-189,-242,-376,-315,-159,-285,-247,-217,-119,-295,-192,-233,-63,-298,-72,-221,-78,-309,-142,-336,-207,-384,-220,-389,-223,-371,-217,-392,-165,-378,-175,-375,-156,-391,-200,-346,-196,-386,-169,-293,-171,-325,-127,-312,-180,-413,-244,-413,-275,-437,-268,-434,-258,-381,-194,-377,-183,-352,-126,-339,-126,-286,-92,-262,-50,-229,-59,-226,-70,-231,-92,-226,-106,-251,-108,-219,-79,-217,-73,-199,-48,-168,-54,-223,-113,-224,-121,-228,-134,-243,-180,-267,-148,-265,-176,-290,-166,-274,-160,-279,-151,-277,-159,-262,-146,-233,-125,-202,-129,-198,-90,-162,-74,-165,-69,-153,-33,-141,-13,-136,2,-114,40,-123,47,-102,43,-95,48,-108,50,-112,44,-100,32,-92,18,-95,22,-82,17,-82,23,-102,19,-84,22,-128,24,-87,44,-69,35,-66,63,-29,79,-26,54,-19,109,-9,110,-5,137,-8,111,4,120,34,92,-13,96,-16,93,-54,92}, + /* IRC_Composite_C_R0195_T180_P330.wav */ + {-26,26,-26,25,-25,25,-24,23,-23,22,-21,20,-19,17,-16,14,-11,8,-4,-1,7,-15,27,-46,89,61,-145,147,-71,284,-270,217,-379,526,177,1579,111,1304,-624,3003,-1570,-1854,2371,5215,2766,3717,2594,2071,4289,53,-1269,-2397,2282,-1207,-426,-1536,-96,41,749,-948,-416,181,838,-208,144,-15,-109,-323,76,15,16,-276,4,-8,-1,-123,-108,-209,-91,-130,71,-58,-162,-230,-119,-177,-166,-207,-161,-106,-120,-36,-71,-88,-115,-141,-23,-102,-161,-225,-242,-194,-306,-250,-347,-260,-382,-276,-340,-235,-319,-231,-283,-196,-267,-199,-293,-242,-296,-261,-227,-164,-163,-202,-268,-256,-325,-304,-440,-389,-451,-306,-367,-292,-374,-282,-281,-248,-233,-251,-211,-225,-190,-161,-223,-149,-241,-144,-229,-124,-173,-155,-158,-194,-95,-175,-83,-151,-123,-82,-138,-35,-195,-70,-203,-140,-178,-222,-181,-287,-200,-285,-259,-281,-289,-246,-302,-246,-260,-227,-227,-242,-189,-224,-180,-220,-169,-184,-146,-121,-121,-86,-121,-59,-86,-47,-78,-63,-71,-90,-66,-82,-53,-82,-82,-54,-72,-16,-90,-24,-88,-44,-31,-45,-32,-70,-43,-25,-59,-33,-76,-24,-59,-46,-55,-45,-56,-56,-64,-32,-54,-6,-57,-1,-22,23,2,9,-2,35,54,34,72,22,84,15,94,10,75,34,67,47,21,57,14,36}, + /* IRC_Composite_C_R0195_T195_P330.wav */ + {19,-19,19,-20,20,-21,21,-22,23,-23,24,-24,25,-26,26,-27,27,-28,29,-29,30,-30,30,-29,28,-25,18,14,179,64,-45,11,282,14,-136,-276,1166,711,738,-60,1508,162,166,165,449,1532,5355,3392,931,2171,2302,2446,-1456,-644,-2020,1267,216,-603,-1662,-126,427,-150,-158,310,15,459,-99,240,14,137,-140,123,54,92,-77,39,37,33,-11,20,88,136,-9,51,-50,-40,-148,-156,-244,-108,-193,-138,-117,-78,-113,-124,-103,-88,-193,-190,-214,-191,-267,-312,-314,-321,-363,-318,-371,-313,-329,-304,-279,-293,-244,-274,-270,-284,-268,-270,-226,-229,-218,-220,-244,-283,-323,-321,-343,-387,-412,-395,-369,-338,-385,-339,-361,-243,-279,-233,-263,-196,-226,-166,-214,-179,-210,-188,-205,-188,-194,-186,-176,-189,-187,-188,-151,-148,-132,-148,-138,-144,-161,-155,-165,-177,-165,-222,-217,-269,-237,-294,-251,-318,-235,-297,-234,-275,-203,-229,-195,-221,-176,-219,-151,-204,-120,-189,-136,-166,-97,-148,-79,-121,-68,-94,-95,-78,-72,-67,-80,-75,-79,-69,-70,-61,-76,-83,-71,-84,-52,-102,-40,-87,-65,-74,-59,-59,-44,-53,-35,-32,-38,-24,-30,-33,-41,-31,-32,-32,-53,-10,-53,7,-39,3,11,-3,30,29,44,32,63,46,79,39,81,48,51,38,73,36,50,22,77,-11}, + /* IRC_Composite_C_R0195_T210_P330.wav */ + {4,-4,4,-4,4,-4,4,-4,4,-4,4,-4,4,-4,4,-4,4,-4,4,-3,3,-3,2,-2,1,0,-1,4,-7,14,-37,-66,67,-14,-33,-186,91,-96,90,124,958,676,187,107,-283,310,1299,1265,1017,1358,3762,3924,898,885,85,1188,235,180,-1266,-91,662,-183,-222,-323,535,278,681,120,382,366,409,299,413,216,314,49,299,205,244,15,349,134,369,-25,355,37,155,-122,149,-90,17,-126,0,-119,-101,-98,-45,-101,-108,-137,-41,-165,-128,-190,-90,-220,-248,-213,-218,-183,-289,-234,-287,-213,-287,-181,-291,-252,-334,-216,-249,-215,-305,-231,-259,-234,-279,-267,-321,-303,-381,-272,-334,-278,-372,-241,-327,-217,-356,-191,-320,-190,-311,-163,-271,-146,-273,-141,-249,-181,-245,-176,-249,-177,-262,-171,-258,-201,-269,-174,-249,-165,-249,-157,-236,-157,-222,-150,-201,-185,-232,-186,-231,-212,-272,-199,-268,-197,-269,-185,-248,-203,-236,-188,-226,-202,-206,-202,-200,-198,-175,-174,-139,-154,-129,-144,-119,-116,-115,-116,-101,-118,-88,-110,-115,-124,-128,-104,-139,-117,-161,-110,-128,-96,-116,-100,-91,-78,-46,-54,-38,-54,-28,-28,-31,-22,-47,-22,-45,-45,-34,-47,-26,-63,-19,-69,15,-46,17,-34,36,-7,28,11,12,21,18,27,33,12,47,14,27,2,38,-2}, + /* IRC_Composite_C_R0195_T225_P330.wav */ + {-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,2,-68,-59,-5,-96,48,-93,-175,-114,61,113,32,173,565,369,-5,6,42,629,908,1232,1079,1509,2842,2279,709,505,658,652,456,31,-132,16,714,22,392,243,724,581,610,769,414,780,295,589,257,440,139,342,210,326,138,213,205,269,65,206,39,192,-75,77,-72,119,-93,32,-98,-25,-124,-61,-115,-124,-100,-152,-32,-169,-66,-171,-60,-174,-142,-204,-153,-209,-250,-258,-282,-284,-268,-319,-270,-333,-243,-293,-243,-293,-258,-255,-244,-253,-268,-246,-247,-251,-255,-254,-239,-252,-237,-244,-241,-235,-232,-243,-208,-257,-193,-268,-204,-268,-227,-248,-235,-265,-257,-230,-233,-218,-240,-222,-215,-193,-210,-173,-175,-183,-176,-191,-180,-202,-196,-223,-223,-252,-229,-258,-254,-257,-250,-252,-220,-262,-227,-250,-215,-243,-223,-230,-208,-202,-158,-170,-134,-160,-123,-166,-123,-164,-100,-174,-109,-180,-112,-164,-109,-168,-131,-171,-106,-158,-104,-162,-121,-153,-114,-132,-112,-125,-95,-82,-74,-52,-73,-50,-54,-44,-32,-38,-20,-57,-17,-36,-14,-46,-36,-11,-10,-23,-34,-7,-16,7,-20,-30,-21,-13,-19,-3,-32,-10,-25,9,-16,17,18,-2,23}, + /* IRC_Composite_C_R0195_T240_P330.wav */ + {6,-6,6,-6,6,-6,6,-6,7,-7,7,-7,7,-7,7,-7,7,-7,7,-7,8,-8,8,-8,8,-8,8,-8,1,-47,-37,-124,-93,-95,-58,-38,-70,-58,-105,-121,-151,-76,14,175,104,51,147,291,191,-40,158,429,1090,1311,1373,1241,1326,1526,1181,419,583,828,657,621,656,466,551,572,739,747,685,612,423,667,583,601,619,480,483,323,428,299,276,192,162,105,83,89,89,51,98,-46,97,-2,117,-65,34,-69,1,-69,-69,-127,-170,-131,-173,-121,-145,-147,-134,-204,-102,-232,-83,-273,-123,-325,-159,-309,-183,-275,-249,-249,-252,-185,-266,-178,-245,-201,-259,-208,-248,-243,-270,-238,-253,-227,-254,-209,-249,-203,-269,-184,-271,-141,-258,-121,-230,-113,-188,-120,-198,-167,-178,-200,-214,-242,-233,-264,-244,-276,-244,-267,-267,-261,-267,-239,-274,-233,-272,-226,-277,-260,-268,-247,-282,-253,-289,-226,-270,-213,-255,-189,-247,-158,-192,-146,-173,-170,-171,-177,-143,-184,-151,-187,-146,-147,-141,-154,-121,-150,-139,-166,-139,-155,-135,-176,-141,-174,-144,-174,-160,-177,-162,-156,-152,-157,-114,-126,-89,-103,-86,-98,-78,-68,-62,-53,-84,-35,-53,-7,-51,-15,-38,-6,-34,-13,-34,-15,-32,-28,-35,-19,-32,1,-19,7,-27,9,3,4,-14,3,-5,36,2,41}, + /* IRC_Composite_C_R0195_T255_P330.wav */ + {-1,1,-1,1,-1,1,-2,2,-2,2,-2,2,-2,2,-2,2,-2,3,-3,3,-3,3,-3,4,-4,4,-5,5,-6,7,-8,10,-13,22,-83,-97,-106,-152,-99,-59,-90,-92,-128,-74,-117,-122,-12,68,86,137,156,199,190,329,533,767,1036,1233,1574,1651,1491,1169,954,781,906,1168,950,370,704,786,629,605,494,653,561,698,550,738,501,619,385,441,218,218,189,132,100,39,147,27,91,-38,77,-24,27,-36,-30,-17,-41,-95,-49,-122,-68,-169,-78,-186,-103,-225,-135,-197,-120,-153,-145,-183,-142,-167,-150,-231,-159,-244,-153,-214,-165,-219,-193,-224,-173,-215,-157,-238,-162,-231,-149,-238,-155,-243,-185,-203,-182,-175,-206,-184,-214,-165,-184,-162,-168,-165,-138,-160,-133,-192,-158,-236,-216,-272,-273,-290,-295,-306,-316,-279,-301,-261,-303,-259,-299,-287,-289,-292,-273,-302,-247,-283,-207,-253,-202,-230,-201,-189,-205,-172,-192,-162,-193,-165,-169,-166,-191,-174,-179,-167,-155,-172,-157,-151,-142,-148,-140,-156,-161,-162,-168,-167,-172,-156,-177,-164,-174,-152,-168,-156,-171,-153,-173,-152,-171,-139,-162,-124,-144,-85,-111,-53,-108,-40,-71,-33,-75,-21,-62,-20,-68,0,-50,5,-37,-3,-30,28,-23,3,-23,12,-19,28,-12,24,-5,41,17,24,-7,17,-24,23}, + /* IRC_Composite_C_R0195_T270_P330.wav */ + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,-1,1,-1,1,-1,1,-2,3,-127,-152,-188,-165,-160,-178,-195,-131,-72,-37,-53,-57,-34,48,106,135,127,188,385,765,884,1201,1389,1575,1756,1541,1264,1282,908,615,982,1053,498,403,667,706,647,681,663,732,712,700,422,527,505,426,401,192,156,184,190,100,26,-34,55,-50,19,-119,28,-59,-54,-94,-103,-24,-139,-24,-165,-13,-154,-5,-159,-81,-104,-118,-99,-136,-98,-118,-106,-89,-142,-101,-168,-112,-178,-178,-148,-180,-114,-217,-134,-255,-104,-252,-140,-238,-148,-235,-187,-236,-202,-242,-197,-183,-140,-137,-108,-143,-129,-142,-128,-211,-166,-246,-182,-269,-212,-271,-233,-292,-267,-287,-263,-282,-269,-312,-249,-304,-257,-293,-240,-287,-230,-257,-242,-248,-234,-224,-236,-219,-241,-188,-227,-176,-221,-206,-210,-185,-185,-166,-179,-163,-176,-164,-168,-164,-186,-168,-180,-154,-159,-141,-142,-150,-142,-147,-152,-145,-159,-150,-168,-167,-187,-177,-186,-176,-192,-163,-197,-167,-186,-164,-170,-159,-148,-137,-112,-102,-104,-88,-70,-56,-50,-28,-30,-11,-12,-16,-10,-21,-31,-4,-26,2,15,8,10,-3,-2,5,10,12,-9,0,-5,9,-13,-19,-29,-16}, + /* IRC_Composite_C_R0195_T285_P330.wav */ + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,-1,1,-1,1,-1,1,-1,2,-2,3,-6,13,-111,-184,-215,-184,-140,-139,-179,-220,-168,-247,-124,1,-91,-84,42,-80,17,-54,56,218,634,881,967,1181,1587,1636,1273,1643,1650,702,357,915,823,759,711,555,754,615,798,685,720,707,793,638,630,510,595,460,429,211,188,178,148,102,16,162,0,142,-40,140,-32,103,24,-7,-30,11,-24,-1,-87,12,-168,51,-103,64,-105,39,-118,10,-91,-91,-119,-125,-90,-149,-75,-130,-138,-153,-195,-185,-254,-205,-313,-223,-303,-243,-266,-224,-223,-230,-188,-216,-155,-167,-129,-140,-137,-102,-110,-74,-146,-82,-177,-89,-192,-110,-215,-160,-231,-232,-220,-242,-237,-262,-238,-271,-237,-259,-263,-234,-261,-228,-278,-222,-281,-252,-268,-270,-265,-263,-228,-244,-187,-230,-176,-214,-164,-194,-141,-175,-152,-173,-143,-161,-171,-179,-174,-184,-157,-194,-163,-211,-148,-196,-144,-205,-158,-219,-155,-190,-162,-178,-166,-174,-156,-186,-169,-200,-161,-200,-167,-208,-167,-218,-158,-186,-143,-155,-119,-123,-104,-117,-86,-101,-54,-82,-39,-73,-25,-68,-7,-55,-18,-42,23,-14,19,-21,7,-24,19,-4,2,-14,7,-10,12,-14,13,-7,26,-23,8,-14}, + /* IRC_Composite_C_R0195_T300_P330.wav */ + {-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,4,-4,4,-4,4,-4,4,-5,-62,-157,-83,-247,-284,-202,-303,-294,-235,-54,-305,15,156,241,-112,-479,-226,774,-232,495,1765,1236,1265,2221,2705,1763,850,505,963,731,757,546,519,206,795,441,708,577,742,596,545,491,526,666,413,377,307,300,457,188,260,34,250,133,251,58,87,249,132,194,-1,200,55,156,95,139,122,50,62,57,84,-3,-71,-62,-99,-113,-176,-122,-254,-180,-227,-166,-230,-202,-293,-196,-279,-248,-326,-256,-320,-217,-260,-211,-244,-154,-191,-125,-171,-113,-160,-81,-135,-55,-102,-70,-95,-24,-42,-53,-78,-73,-93,-89,-149,-139,-195,-180,-235,-192,-245,-233,-268,-234,-245,-224,-256,-221,-249,-225,-220,-233,-215,-250,-226,-218,-236,-221,-224,-181,-198,-176,-191,-173,-185,-156,-184,-162,-178,-171,-172,-156,-184,-183,-174,-192,-186,-179,-189,-180,-212,-184,-191,-167,-199,-217,-182,-203,-172,-210,-178,-224,-155,-220,-185,-224,-199,-194,-203,-201,-206,-192,-196,-188,-165,-158,-177,-147,-145,-112,-128,-98,-113,-74,-77,-54,-65,-67,-32,-44,-10,-54,-13,-29,-7,-15,-1,-23,19,-18,10,-27,11,-16,8,2,12,-12,4,-1,37,18,19,17,36}, + /* IRC_Composite_C_R0195_T315_P330.wav */ + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,2,-3,-227,-204,-310,-344,-179,-311,-505,-298,-88,-402,115,712,-76,-577,-211,9,558,-404,914,2627,1047,2118,4245,2542,908,788,1382,865,422,674,-11,248,192,1314,191,817,366,966,306,467,192,289,334,100,222,7,227,236,315,254,209,305,479,300,240,335,445,260,199,112,202,84,42,63,85,-45,-100,-80,-73,-157,-181,-120,-209,-167,-259,-161,-262,-234,-281,-209,-243,-208,-221,-245,-173,-195,-197,-241,-151,-201,-166,-240,-132,-182,-104,-150,-85,-104,-75,-148,-59,-141,-36,-144,-33,-133,-71,-89,-7,-47,-109,-70,-108,-44,-152,-113,-164,-122,-182,-216,-170,-212,-172,-263,-155,-228,-178,-252,-176,-207,-200,-242,-206,-220,-204,-208,-195,-218,-188,-193,-156,-217,-159,-200,-119,-211,-133,-181,-131,-177,-169,-158,-166,-171,-195,-175,-181,-214,-193,-224,-184,-218,-204,-219,-183,-222,-197,-222,-197,-226,-215,-204,-205,-207,-216,-212,-210,-224,-222,-213,-210,-205,-202,-194,-174,-155,-148,-134,-144,-126,-89,-101,-75,-94,-84,-69,-47,-37,-69,-67,-26,-35,-13,-29,-17,-23,-3,13,-18,-8,-26,22,-30,20,-15,30,-13,8,-11,23,49,30,39,22,36,16}, + /* IRC_Composite_C_R0195_T330_P330.wav */ + {9,-9,9,-10,10,-10,10,-11,11,-12,12,-12,13,-13,14,-15,15,-16,17,-17,18,-19,20,-22,23,-25,30,-50,-332,-388,-131,-617,-214,-313,-733,-659,255,-155,-66,699,-77,-372,-1255,-242,2041,-707,-6,4736,2036,2809,3545,4509,22,-72,1207,1973,-173,508,959,302,542,540,656,123,461,665,400,314,251,504,190,265,35,373,467,91,154,128,447,203,170,90,232,80,149,193,21,-6,-90,-101,-59,-80,-255,-144,-154,-358,-29,-238,-96,-237,-126,-195,15,-288,-107,-147,-89,-276,-120,-223,-134,-174,-181,-152,-158,-179,-71,-138,-116,-177,-93,-189,-60,-206,-162,-159,-113,-111,-150,-123,-93,-106,-83,-101,-52,-113,-43,-99,-10,-99,-66,-88,-58,-127,-64,-152,-99,-152,-144,-200,-127,-259,-116,-227,-129,-245,-98,-258,-94,-239,-152,-227,-154,-225,-147,-242,-169,-202,-172,-212,-140,-232,-141,-182,-139,-168,-130,-205,-127,-137,-140,-176,-175,-160,-166,-171,-205,-188,-193,-212,-199,-238,-185,-248,-173,-246,-186,-227,-206,-245,-184,-218,-210,-235,-210,-228,-175,-238,-206,-213,-189,-196,-171,-200,-159,-123,-146,-114,-128,-128,-81,-88,-83,-80,-52,-124,-70,-58,-40,-45,-69,-50,-10,-13,-16,-42,-4,-25,50,-37,11,-37,37,-4,24,-11,12,-7,33,10,69,29,60,20,87,-1}, + /* IRC_Composite_C_R0195_T345_P330.wav */ + {1,0,0,0,-1,1,-2,2,-3,4,-5,6,-7,8,-9,11,-13,15,-17,20,-24,28,-33,40,-47,52,-211,-235,-688,-550,-297,-690,-704,-444,713,-1568,989,470,-39,-1205,323,-714,276,-2380,5748,2929,602,8080,5302,-453,-722,3812,715,-74,-365,1626,369,1163,1544,781,-4,229,668,441,364,676,214,441,36,409,174,565,-210,423,-90,172,-132,46,-99,78,-186,159,-181,96,-244,13,-280,-20,-156,-41,-291,-109,-365,-55,-322,-117,-274,-136,-169,-159,-189,-140,-191,12,-178,0,-295,-70,-206,-88,-236,-75,-169,-78,-191,-95,-204,-87,-146,-66,-185,-107,-238,-113,-249,-119,-185,-98,-187,-131,-176,-95,-137,-31,-142,-17,-163,-50,-120,-40,-114,-19,-100,-43,-142,-64,-163,-81,-167,-107,-184,-140,-220,-122,-200,-146,-203,-155,-165,-178,-177,-198,-166,-175,-153,-160,-161,-178,-163,-171,-143,-138,-136,-139,-146,-131,-151,-132,-167,-143,-153,-146,-165,-157,-219,-159,-215,-151,-222,-190,-225,-204,-218,-208,-214,-189,-218,-191,-221,-190,-214,-185,-216,-196,-215,-178,-200,-217,-218,-194,-162,-182,-170,-189,-185,-152,-157,-123,-144,-122,-111,-99,-99,-89,-76,-63,-81,-56,-61,-31,-49,-85,-23,-30,-14,-9,-21,-45,-18,-1,16,3,5,-5,5,8,-5,64,39,55,37,73,42,56,31,84}}; + +const int16_t irc_composite_c_r0195_p345[][256] = + {/* IRC_Composite_C_R0195_T000_P345.wav */ + {2,-1,1,-1,1,-1,1,-1,0,0,0,0,-1,1,-2,2,-3,4,-5,7,-9,11,-15,21,-203,-88,-927,-196,-604,-22,-2141,-496,-650,1585,-548,803,-263,412,-5131,5346,-2103,-7267,12288,1672,1403,10338,7456,-3182,-874,2680,1965,-5296,1356,1865,68,-578,2523,1092,1554,2056,2530,1058,1432,379,1062,-82,-380,-971,369,-376,62,-56,669,-390,190,379,537,98,-46,-35,315,348,110,183,491,-38,19,211,170,-22,-231,-125,-221,138,-512,-336,-126,10,-387,-311,-283,-176,-241,-345,-432,-207,-330,-489,-386,-392,-351,-423,-274,-457,-352,-361,-311,-213,-391,-323,-302,-143,-325,-378,-206,-229,-190,-319,-334,-196,-236,-126,-387,-117,-339,-105,-264,-135,-207,-172,-176,-254,-160,-183,-177,-200,-218,-201,-189,-116,-205,-120,-224,-113,-159,-119,-241,-118,-127,-119,-188,-91,-119,-15,-186,-30,-132,28,-213,-19,-166,21,-190,-46,-185,-49,-159,-65,-168,-65,-190,-59,-218,-46,-217,-24,-231,-74,-204,-52,-181,-89,-211,-94,-196,-70,-219,-104,-200,-55,-181,-86,-186,-39,-155,-66,-178,-1,-187,-47,-188,6,-142,-11,-161,-5,-114,-9,-113,6,-145,-7,-123,-21,-161,-34,-116,-47,-173,-82,-145,-76,-157,-72,-137,-75,-186,-79,-163,-31,-131,-17,-156,-51,-99,26,-74,-5,-101,37,-82,48,-83,35,-130,20}, + /* IRC_Composite_C_R0195_T015_P345.wav */ + {-8,8,-9,9,-9,10,-10,11,-11,12,-13,14,-15,17,-19,21,-23,26,-30,34,-31,-453,-1036,-33,-665,328,-1202,-749,-1695,-16,154,1160,807,430,-250,202,-9659,9217,1210,-9352,17225,6331,1506,7124,7939,-4308,-4730,1188,3176,-2475,1424,-48,-469,790,3944,1309,680,1752,2484,1048,341,-282,654,-429,-824,-317,110,-114,-77,514,87,-336,314,152,794,-136,169,-632,188,-172,280,-21,-59,-628,-366,-701,125,-342,195,-484,14,-385,142,-203,-25,-63,-111,-438,-237,-144,-19,-603,-408,-283,-225,-622,-635,-157,-385,-331,-577,-30,-389,-404,-427,-106,-226,-443,-405,-162,-392,-396,-469,17,-462,-322,-529,-39,-465,-308,-396,-19,-390,-307,-364,11,-326,-213,-317,-16,-354,-213,-313,-60,-343,-187,-297,-56,-344,-144,-249,-9,-231,-112,-162,-24,-173,-102,-136,27,-150,-25,-210,56,-219,64,-254,58,-220,23,-244,-12,-203,-8,-244,-39,-226,-35,-259,-51,-231,-34,-263,-76,-247,-60,-275,-44,-227,-27,-295,-46,-242,-22,-251,-17,-192,-18,-252,-5,-165,49,-233,62,-170,73,-217,68,-124,45,-174,23,-102,4,-167,36,-98,28,-187,19,-138,2,-165,-15,-133,-54,-155,-42,-139,-76,-178,-15,-149,-36,-176,14,-154,-30,-174,22,-136,-10,-157,29,-146,8,-148,67,-147,48,-150,87,-144,95,-120,68}, + /* IRC_Composite_C_R0195_T030_P345.wav */ + {-5,4,-2,1,1,-3,5,-8,11,-14,18,-22,28,-33,40,-47,52,-40,-408,-1246,-239,-636,412,-1166,-641,-1047,-627,-510,85,1903,1495,1980,-2101,-8149,8335,-7570,2561,15248,-2261,7441,12350,8152,-6960,-897,-1312,-80,35,3139,-1223,-111,782,2694,1229,2248,830,1733,-78,616,211,239,-1106,180,-577,174,-80,366,-414,-235,48,899,-101,-343,251,6,-139,-259,84,-149,-439,-392,-377,-353,-641,-180,-347,-645,-512,18,-444,-412,-353,-372,29,-540,-286,-340,91,-270,81,-387,-257,-287,-105,-191,-258,-436,11,-476,-269,-411,-52,-449,-147,-462,-317,-370,-394,-207,-298,-370,-445,-321,-432,-282,-273,-429,-392,-579,-276,-340,-267,-422,-237,-397,-288,-363,-183,-311,-252,-339,-167,-369,-181,-301,-85,-308,-243,-297,-206,-198,-141,-225,-133,-188,-51,-81,-5,-156,39,-131,-42,-137,-12,-105,-59,-165,-33,-91,-103,-131,-61,-132,-15,-166,-70,-196,-74,-136,-77,-240,-119,-181,-167,-207,-153,-210,-116,-267,-128,-236,-136,-218,-68,-191,-86,-215,-66,-87,-41,-115,-57,-149,39,-73,32,-134,21,-60,58,-96,16,-33,13,-37,-10,-59,0,-62,-11,-108,-26,-126,5,-173,-25,-133,-22,-188,-62,-152,-27,-144,-75,-133,-61,-105,-49,-114,-43,-128,-43,-94,-30,-105,-18,-125,-14,-97,30,-123,23,-65,42,-66,35,-56}, + /* IRC_Composite_C_R0195_T045_P345.wav */ + {-8,9,-9,10,-11,12,-14,15,-17,18,-20,23,-26,29,-32,27,-914,-992,248,-1147,746,-600,-1411,-744,-565,-282,187,2409,2683,-221,-1093,-6934,4033,-4276,11276,-297,4328,20553,5592,-1738,-1835,48,-2700,3273,333,-1462,-612,3497,663,1061,1222,2492,754,1168,-36,273,-1174,-272,-1054,891,-844,132,-415,315,-117,257,-335,440,-662,37,-141,164,-657,106,-514,-245,-612,-181,-587,-119,-354,-272,-370,70,-460,-182,-631,-316,-708,-110,-803,-99,-670,-498,-427,-54,-498,-454,-369,-295,-361,-311,-286,-279,-189,-173,-337,-51,-132,-118,-321,-115,-360,-197,-296,-134,-359,-223,-370,-154,-278,-322,-354,-297,-436,-355,-372,-287,-465,-352,-358,-269,-478,-297,-336,-244,-461,-251,-336,-244,-377,-295,-277,-241,-357,-246,-212,-210,-283,-149,-224,-96,-233,-70,-163,-39,-261,-32,-98,-58,-219,-32,-96,-67,-134,7,-101,-50,-139,18,-115,-50,-164,-70,-125,-101,-200,-71,-185,-130,-181,-136,-176,-132,-203,-147,-173,-138,-199,-159,-176,-127,-141,-96,-163,-71,-143,-38,-126,-27,-77,-59,-103,5,-43,-32,-25,-36,-5,-42,40,-34,18,-45,1,-59,7,-47,-28,-49,-55,-63,-33,-55,-79,-59,-82,-109,-94,-40,-81,-89,-121,-82,-83,-49,-111,-62,-79,-97,-59,-52,-74,-97,-50,-98,-31,-116,11,-85,32,-106,43,-88,79,-70}, + /* IRC_Composite_C_R0195_T060_P345.wav */ + {2,0,-1,2,-4,7,-10,13,-18,24,-33,46,-69,124,-1066,18,-1103,-58,-112,-921,-201,357,-2572,-292,84,3712,705,1846,-3182,733,-1997,-2694,2428,-595,23701,7754,-2253,5078,3945,-1381,793,-3491,-1163,3714,3613,-2506,296,680,1730,1310,1740,569,508,99,-722,-392,-453,-871,66,-328,-669,-71,-484,-147,-35,146,49,-532,-397,-139,-139,-522,-373,-116,-571,-415,-445,-69,-274,-275,-429,-422,-271,-360,-287,-382,-22,-407,-385,-428,-388,-334,-422,-213,-696,-500,-450,-310,-488,-360,-442,-369,-341,-387,-436,-315,-312,-227,-524,-284,-360,-145,-448,-103,-329,-255,-335,-170,-226,-169,-275,-186,-277,-175,-313,-153,-328,-106,-340,-187,-359,-196,-395,-186,-410,-204,-401,-242,-445,-212,-399,-269,-333,-214,-369,-275,-249,-157,-224,-209,-240,-93,-196,-87,-134,-136,-170,-118,-141,-152,-108,-143,-171,-122,-121,-75,-167,-118,-171,-34,-161,-63,-166,-73,-182,-54,-115,-102,-170,-130,-176,-78,-151,-106,-187,-132,-212,-115,-143,-110,-184,-158,-155,-100,-103,-72,-126,-49,-120,-26,-63,20,-83,6,-50,25,-17,26,-29,39,-31,8,-37,34,-77,20,-77,4,-80,-26,-93,-19,-70,-86,-71,-70,-82,-94,-51,-114,-61,-80,-78,-73,-90,-68,-70,-42,-80,-51,-78,-111,-16,-79,-18,-107,-18,-114,-3,-27,-1,-36,-19,-21,-10,39}, + /* IRC_Composite_C_R0195_T075_P345.wav */ + {13,-13,13,-13,13,-13,13,-14,14,-14,14,-14,13,-149,-486,-602,-335,-455,-212,-518,0,-1171,-540,-311,1579,3683,3360,-5772,-426,-1232,-715,5798,-5995,21017,15656,-2523,-3222,5350,1893,1313,-2953,-885,4326,1209,-279,-1161,869,861,1767,953,-85,210,-139,-663,-17,-553,268,-673,-215,-760,-236,-646,-139,-393,-427,-462,-55,-562,-131,-287,-193,-567,-273,-625,-345,-491,-150,-487,-111,-512,-283,-603,-50,-418,-328,-443,-111,-346,-355,-349,-35,-305,-248,-516,-491,-547,-144,-443,-470,-467,-394,-484,-216,-365,-370,-505,-259,-440,-318,-386,-196,-476,-376,-474,-304,-362,-195,-334,-380,-413,-292,-310,-213,-289,-263,-333,-155,-255,-179,-252,-180,-265,-153,-285,-190,-264,-147,-236,-237,-304,-248,-194,-182,-204,-186,-250,-173,-172,-144,-229,-114,-172,-167,-183,-136,-161,-106,-122,-161,-186,-139,-156,-91,-182,-139,-216,-134,-193,-139,-180,-115,-198,-155,-201,-90,-175,-115,-207,-160,-200,-119,-149,-119,-195,-93,-130,-96,-135,-84,-130,-121,-106,-85,-107,-61,-110,-53,-77,2,-45,-15,-51,-20,4,33,-23,-40,-36,1,-53,16,-46,-46,-69,1,-46,-34,-47,-35,-46,-45,-73,-11,-76,-35,-107,-21,-105,-57,-70,-68,-101,-73,-74,-59,-95,-48,-78,-69,-89,-82,-50,-61,-44,-75,-23,-52,-44,10,-43,-23,-47,63,-13,31,19}, + /* IRC_Composite_C_R0195_T090_P345.wav */ + {-40,45,-52,60,-69,79,-92,108,-129,156,-197,267,-462,-149,208,-635,-826,268,-390,-920,244,-62,-1260,-320,2937,4521,-564,-4829,2706,-6796,9962,-6783,6356,23745,4526,-4606,-155,5413,3814,-1343,-3207,4343,2939,-733,-2665,998,738,1892,332,-416,-415,112,-618,265,-680,-48,-750,405,-729,216,-673,-99,-730,-121,-855,-310,-693,-146,-680,-198,-695,-260,-522,-283,-523,-143,-597,-333,-173,-342,-516,-211,-519,-364,-344,-136,-671,-213,-411,-202,-398,-103,-578,-290,-294,-138,-306,-230,-402,-283,-321,-289,-337,-289,-473,-414,-279,-358,-413,-275,-431,-453,-313,-307,-448,-301,-341,-461,-354,-322,-417,-358,-269,-383,-284,-242,-302,-305,-257,-285,-308,-182,-268,-314,-270,-212,-228,-190,-249,-276,-158,-168,-143,-161,-146,-207,-91,-103,-158,-110,-126,-88,-73,-13,-110,-35,-46,-106,-57,-116,-140,-215,-98,-197,-197,-174,-246,-265,-202,-185,-227,-181,-218,-214,-125,-146,-175,-178,-153,-217,-80,-87,-137,-151,-98,-122,-94,-88,-136,-141,-168,-115,-121,-70,-143,-102,-56,-76,-36,6,-27,-49,15,48,-26,23,-19,19,-21,34,-59,8,-22,-47,2,-38,-69,-64,-5,-74,-105,-59,-66,-97,-94,-96,-78,-97,-52,-113,-64,-142,-56,-66,-39,-129,-40,-66,-56,-70,5,-96,-30,-55,4,-41,13,-55,20,-26,32,-22,71,-18,17,30}, + /* IRC_Composite_C_R0195_T105_P345.wav */ + {-67,70,-74,77,-81,86,-90,96,-101,108,-115,124,-133,69,-792,-387,271,-596,-717,859,-864,-953,-174,2178,-1005,1282,2249,6443,-10856,1162,-3444,7735,12493,-6470,12789,13090,-1110,-7098,1720,6128,6522,-3157,-2418,823,2649,-1545,-82,75,412,176,-227,-1102,-27,27,-108,-705,430,-492,-144,-623,458,-659,-400,-488,-145,-709,-561,-722,-446,-592,-392,-773,-320,-376,-219,-435,-230,-433,-344,-257,-282,-422,-405,-416,-298,-443,-368,-500,-217,-519,-166,-433,-279,-366,-130,-440,-244,-224,-238,-388,-222,-308,-238,-178,-169,-397,-297,-264,-256,-355,-298,-417,-426,-330,-305,-333,-364,-344,-434,-356,-283,-355,-382,-364,-318,-364,-236,-292,-356,-334,-239,-297,-263,-218,-274,-335,-226,-222,-269,-272,-264,-249,-207,-170,-177,-194,-173,-129,-105,-104,-107,-136,-46,-4,64,55,23,-30,-30,-40,-113,-234,-240,-226,-142,-197,-242,-304,-222,-141,-127,-177,-202,-148,-92,-95,-154,-222,-191,-141,-114,-142,-174,-129,-161,-67,-128,-34,-186,-89,-116,-46,-141,-77,-118,-122,-94,-41,-91,-117,-59,-17,-48,-43,-49,-43,-26,26,1,-33,-44,-8,1,24,-53,-52,-67,-16,-53,-12,-77,-55,-119,-25,-52,-50,-119,-50,-99,-48,-93,-38,-125,-90,-97,-23,-111,-77,-96,-23,-117,-28,-57,-25,-82,-14,-37,-3,-37,48,-10,30,-29,94,17,67}, + /* IRC_Composite_C_R0195_T120_P345.wav */ + {-3,4,-6,7,-9,12,-14,18,-21,26,-32,40,-51,68,-105,-237,-115,-196,-240,-710,503,-404,-299,-610,1573,-1052,1538,3156,4734,-10274,2428,47,3883,7208,-4454,16464,10228,-4264,-5316,5989,6995,2607,-3203,-668,1640,904,-2642,-469,203,1050,-729,-1586,-33,324,-227,138,-165,-76,50,-374,-903,385,-637,-751,-371,7,-958,-172,-379,-347,-638,-287,-600,-251,-397,-596,-514,-222,-363,-323,-357,-509,-371,-223,-433,-356,-378,-472,-223,-149,-381,-362,-256,-360,-249,-245,-414,-343,-215,-318,-296,-253,-281,-260,-186,-267,-334,-184,-218,-221,-298,-323,-280,-235,-266,-346,-291,-364,-250,-269,-330,-407,-337,-288,-297,-291,-367,-331,-313,-227,-277,-310,-324,-354,-249,-294,-307,-326,-246,-243,-266,-239,-219,-134,-170,-168,-181,-178,-179,-104,-105,-182,-117,-16,21,-1,-16,-123,-97,-70,-125,-190,-191,-224,-174,-191,-187,-240,-111,-186,-142,-146,-92,-134,-84,-176,-166,-110,-109,-146,-139,-231,-119,-73,-70,-193,-83,-143,-72,-63,-63,-163,-69,-90,-96,-97,-84,-157,-37,-91,-88,-116,-29,-99,-31,-73,-68,-76,24,-65,-8,-90,-71,-32,33,-119,-46,-74,-20,-92,37,-144,-45,-100,37,-86,3,-132,2,-42,-29,-104,-4,-152,-16,-85,-19,-175,14,-94,-9,-106,-24,-72,42,-77,-27,-22,2,-33,78,-29,-21,21,111,-5}, + /* IRC_Composite_C_R0195_T135_P345.wav */ + {-8,8,-9,9,-9,10,-10,11,-11,11,-12,12,-12,13,-12,12,-14,-199,-345,194,-292,-20,-363,219,-924,441,900,798,-558,3720,1651,-3208,-514,-4991,13814,1350,-1342,10873,8019,1098,-3160,1031,6880,5706,-3917,-4208,1661,708,-1088,-1854,-201,229,-177,-273,-648,-82,475,5,-734,169,-151,-581,-653,471,-491,-236,-587,-109,-475,-248,-581,-317,-480,-514,-555,-293,-524,-197,-571,-212,-393,-202,-577,-116,-375,-344,-418,-218,-355,-263,-348,-305,-348,-210,-371,-214,-394,-179,-361,-184,-347,-189,-348,-251,-234,-293,-267,-213,-252,-242,-269,-147,-370,-183,-325,-201,-333,-191,-269,-230,-243,-283,-228,-273,-293,-252,-342,-267,-359,-215,-428,-224,-365,-239,-330,-269,-348,-257,-251,-286,-250,-246,-272,-177,-242,-155,-277,-116,-236,-94,-218,-96,-109,-104,-71,-63,-76,-143,-84,-111,-151,-139,-218,-149,-229,-159,-185,-165,-192,-165,-156,-158,-137,-140,-159,-114,-167,-123,-164,-97,-148,-122,-112,-140,-90,-115,-78,-111,-104,-86,-114,-49,-142,12,-166,-28,-168,-17,-113,-58,-89,-81,-116,-67,-58,-65,-96,-68,-92,-33,-99,-37,-87,-67,-90,-37,-68,-114,-65,-87,-50,-124,-30,-83,-1,-96,-4,-55,-19,-87,13,-80,-10,-90,-5,-84,-42,-79,4,-67,-63,-38,-27,-36,-23,-7,11,-34,14,-18,51,-74,41,9,19,-7}, + /* IRC_Composite_C_R0195_T150_P345.wav */ + {9,-10,11,-12,13,-14,16,-18,20,-22,25,-28,32,-36,41,-48,57,-69,92,-187,-93,-65,148,-471,61,62,-108,-513,1146,660,197,907,4643,-2481,-3069,2384,-436,10331,-1444,3529,10790,4133,-3114,1101,5334,2231,175,-4639,-668,1364,-942,-1832,-179,106,-201,-621,-288,256,-14,7,-70,10,-62,-163,-538,-397,250,-662,-393,-549,-98,-597,-308,-388,-216,-452,-393,-291,-335,-411,-150,-445,-160,-290,-89,-416,-142,-299,-403,-360,-239,-271,-373,-246,-311,-338,-233,-221,-259,-317,-192,-311,-255,-207,-237,-276,-272,-275,-277,-233,-252,-250,-181,-293,-170,-245,-207,-274,-163,-258,-249,-201,-205,-239,-243,-229,-292,-303,-216,-288,-278,-312,-241,-345,-256,-284,-302,-346,-258,-265,-246,-271,-236,-265,-215,-277,-207,-240,-196,-255,-168,-178,-155,-144,-107,-152,-110,-104,-74,-180,-121,-180,-122,-196,-144,-245,-129,-207,-127,-182,-107,-225,-82,-192,-124,-217,-97,-227,-156,-196,-108,-174,-119,-141,-77,-130,-30,-126,-49,-162,-24,-161,-3,-167,-53,-117,-53,-120,-68,-81,-70,-85,-45,-100,-52,-108,-40,-95,-39,-123,-50,-123,-64,-117,-58,-114,-101,-106,-61,-84,-90,-69,-81,-96,-40,-52,-52,-64,-50,-43,-17,-37,-37,-34,-28,-67,-18,-49,-26,-48,-2,-23,-34,-24,7,4,-14,13,9,-1,-21,7,5,3,-11,-9}, + /* IRC_Composite_C_R0195_T165_P345.wav */ + {-16,16,-16,16,-16,17,-17,17,-17,18,-18,18,-18,19,-19,19,-19,19,-19,19,-18,15,-25,-180,39,144,-199,84,-114,-19,-188,1254,741,544,587,3703,-1657,-2617,2350,59,8499,1392,3068,7765,4121,-1476,-112,3753,-281,908,-3882,-912,-13,232,-1645,225,-231,30,-284,242,364,101,-416,-192,-215,-224,-211,-588,-413,94,-532,-410,-203,-224,-476,-149,-162,-206,-299,-157,-323,-203,-258,-155,-285,-195,-259,-160,-310,-161,-188,-219,-325,-228,-252,-329,-249,-318,-288,-289,-215,-279,-273,-237,-265,-253,-240,-166,-308,-223,-268,-204,-257,-185,-200,-214,-215,-169,-225,-233,-270,-224,-251,-229,-254,-245,-245,-239,-242,-271,-250,-255,-257,-319,-229,-320,-280,-334,-233,-335,-241,-307,-225,-319,-212,-265,-239,-293,-245,-235,-213,-218,-190,-158,-146,-114,-164,-138,-176,-126,-194,-163,-222,-185,-202,-181,-221,-210,-185,-167,-169,-169,-149,-149,-121,-122,-91,-166,-97,-138,-90,-161,-94,-134,-93,-167,-101,-146,-89,-171,-96,-130,-90,-122,-75,-116,-77,-102,-73,-86,-102,-91,-92,-79,-122,-82,-99,-73,-113,-89,-86,-78,-89,-91,-110,-85,-90,-61,-78,-110,-68,-88,-12,-123,-18,-120,12,-117,12,-119,3,-74,28,-74,-4,-63,7,-46,0,-67,7,-52,21,-52,5,-33,17,5,-5,-18,-6,3,-14,-17,-13,-5}, + /* IRC_Composite_C_R0195_T180_P345.wav */ + {14,-14,15,-15,15,-16,16,-17,18,-18,19,-20,20,-21,22,-23,25,-26,28,-31,33,-37,43,-53,84,-38,163,-71,-158,103,194,-92,53,482,91,607,1972,2332,-1572,-66,-260,1180,4049,-804,6508,7047,3077,-817,1693,1744,560,329,-3303,313,-242,-704,-831,249,-87,-229,183,93,110,39,-28,-382,-360,-250,-254,-387,-156,-146,-568,-151,-222,7,-192,-113,-168,-1,-224,-13,-332,-98,-241,-68,-295,-42,-210,-57,-298,-57,-251,-128,-317,-192,-299,-254,-305,-255,-341,-262,-251,-237,-260,-298,-266,-251,-226,-202,-261,-186,-262,-164,-227,-165,-247,-142,-218,-142,-250,-192,-303,-264,-330,-282,-325,-281,-325,-258,-295,-215,-312,-214,-308,-229,-274,-251,-309,-306,-294,-311,-271,-299,-256,-284,-250,-220,-205,-223,-287,-266,-239,-195,-135,-147,-134,-149,-99,-176,-199,-275,-263,-263,-286,-264,-295,-223,-247,-187,-176,-146,-128,-120,-103,-115,-67,-85,-89,-116,-143,-100,-117,-73,-127,-58,-97,-32,-121,-65,-147,-77,-157,-103,-172,-126,-140,-135,-140,-152,-146,-132,-154,-119,-152,-105,-161,-118,-130,-105,-117,-95,-88,-108,-66,-84,-63,-104,-55,-48,-36,-55,-20,-46,-8,-40,5,-55,-25,-61,-13,-59,-44,-51,-47,-33,-43,-29,-37,-41,-40,-27,-26,-28,-32,-23,-2,-7,24,-14,-21,-16,-7,-26,-52,-44}, + /* IRC_Composite_C_R0195_T195_P345.wav */ + {6,-6,6,-7,7,-7,7,-7,7,-7,8,-8,8,-8,9,-9,9,-10,10,-11,11,-12,14,-15,17,-21,38,-16,75,-220,-59,106,197,-177,5,-30,-104,721,1540,1146,-1007,1149,558,-528,530,189,5406,5771,1722,1227,2989,2251,-549,199,-1093,649,351,-1192,-797,86,474,-276,161,-98,513,-55,324,-259,35,-250,203,-294,-48,-254,-20,-107,43,-102,74,7,58,5,31,16,-81,-113,-13,-32,-61,-116,-90,-161,-57,-141,-149,-200,-221,-127,-211,-175,-301,-256,-303,-211,-249,-283,-281,-255,-186,-218,-164,-228,-189,-224,-141,-185,-133,-235,-194,-211,-160,-216,-234,-256,-252,-243,-263,-310,-294,-327,-270,-308,-298,-307,-298,-251,-283,-236,-306,-260,-308,-239,-300,-271,-297,-271,-265,-262,-234,-272,-265,-257,-272,-222,-275,-166,-216,-116,-201,-132,-209,-165,-253,-247,-300,-289,-266,-286,-274,-274,-215,-180,-166,-157,-142,-89,-78,-66,-105,-65,-95,-58,-92,-79,-99,-64,-63,-57,-120,-89,-112,-118,-168,-135,-190,-134,-199,-134,-197,-155,-189,-166,-196,-156,-193,-139,-163,-148,-164,-142,-130,-130,-110,-101,-105,-93,-75,-95,-30,-101,-23,-80,-12,-54,-3,-54,-21,-40,-15,-43,-40,-44,-53,-61,-41,-51,-45,-65,-44,-54,-43,-56,-70,-49,-64,-4,-42,4,-66,5,-19,28,-23,-34,-32,-54}, + /* IRC_Composite_C_R0195_T210_P345.wav */ + {-2,2,-2,2,-2,2,-2,1,-1,1,-1,1,-1,0,0,0,1,-1,1,-2,3,-3,4,-6,7,-9,13,-20,43,-89,-222,10,103,-107,-34,-36,142,-400,-30,464,582,998,189,-102,357,928,-496,3,2407,3014,4127,2156,97,2572,2367,192,-1077,553,225,383,-471,-511,-191,662,222,22,339,294,362,131,306,286,107,75,262,201,100,126,189,137,172,10,156,70,103,-4,-19,-25,-76,-86,-32,-105,-27,-153,-34,-185,-5,-211,-79,-248,-114,-227,-127,-231,-155,-259,-155,-256,-173,-269,-198,-265,-178,-210,-163,-209,-150,-214,-137,-236,-119,-268,-155,-295,-185,-296,-225,-287,-248,-275,-270,-274,-255,-294,-292,-305,-257,-323,-287,-335,-263,-321,-272,-309,-253,-288,-250,-283,-256,-298,-279,-264,-275,-235,-286,-206,-259,-185,-242,-173,-250,-179,-242,-182,-246,-189,-235,-187,-222,-180,-217,-154,-198,-159,-175,-140,-165,-133,-123,-114,-152,-125,-126,-116,-132,-139,-111,-130,-90,-128,-110,-154,-128,-148,-134,-149,-163,-162,-154,-157,-161,-181,-160,-162,-162,-166,-161,-175,-145,-160,-146,-183,-159,-151,-121,-142,-111,-108,-118,-82,-70,-76,-70,-81,-45,-58,-32,-55,-61,-50,-56,-13,-58,-19,-65,-23,-55,-34,-79,-47,-53,-75,-77,-59,-49,-49,-45,-23,-65,-15,-50,-1,-35,-44,-51,-18}, + /* IRC_Composite_C_R0195_T225_P345.wav */ + {4,-4,4,-4,5,-5,5,-5,5,-5,5,-5,5,-5,5,-6,6,-6,6,-6,6,-6,7,-7,7,-7,8,-8,8,-8,9,-22,-68,-102,-39,-33,-2,-125,-43,-65,-81,-88,504,491,271,136,50,242,413,575,246,1154,3270,2343,1173,1360,1386,1335,693,41,-16,626,497,-208,385,-141,534,407,815,196,540,538,608,534,497,553,348,395,314,320,191,167,89,75,-22,80,-26,77,-33,113,-103,86,-85,66,-164,-34,-138,-32,-150,-66,-143,-81,-162,-134,-151,-126,-180,-176,-206,-176,-215,-184,-242,-174,-257,-171,-240,-144,-234,-156,-238,-145,-213,-186,-241,-198,-236,-200,-304,-237,-309,-223,-315,-256,-320,-273,-306,-276,-282,-301,-281,-293,-281,-297,-281,-281,-278,-300,-296,-308,-282,-258,-291,-257,-276,-228,-231,-194,-203,-185,-194,-181,-173,-165,-183,-152,-208,-152,-227,-158,-213,-156,-222,-165,-206,-169,-192,-153,-170,-166,-179,-180,-153,-149,-139,-152,-153,-126,-111,-90,-107,-114,-128,-119,-123,-144,-150,-167,-156,-182,-180,-204,-160,-191,-173,-198,-185,-178,-167,-163,-174,-180,-175,-186,-163,-152,-140,-147,-132,-122,-102,-97,-72,-79,-75,-66,-54,-46,-62,-28,-64,-26,-69,-23,-69,-28,-68,-48,-80,-55,-84,-64,-71,-62,-66,-82,-71,-59,-36,-53,-39,-61,-45,-48,-32,-64}, + /* IRC_Composite_C_R0195_T240_P345.wav */ + {1,-1,1,-1,1,-1,1,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,3,-3,3,-3,4,-4,5,-7,11,-87,-91,-69,-34,-17,-83,-130,-72,-103,-104,-134,114,-4,-17,85,373,202,-49,-101,219,365,876,782,785,1628,2056,1505,913,728,668,1183,655,491,465,893,831,430,584,712,1020,649,708,723,730,613,504,566,414,315,187,278,133,226,116,259,129,186,116,185,45,88,-32,30,-121,-4,-138,-59,-242,-77,-196,-88,-164,-95,-154,-158,-144,-123,-166,-155,-131,-163,-193,-126,-158,-197,-221,-177,-191,-199,-207,-207,-232,-259,-213,-257,-223,-245,-210,-232,-214,-199,-250,-237,-259,-286,-308,-300,-276,-316,-306,-323,-315,-283,-322,-259,-334,-262,-308,-246,-279,-237,-252,-210,-235,-204,-211,-204,-216,-219,-187,-208,-184,-188,-172,-182,-147,-178,-171,-209,-148,-207,-140,-214,-153,-202,-132,-178,-141,-158,-129,-140,-132,-148,-104,-170,-94,-160,-103,-179,-127,-186,-148,-195,-164,-196,-178,-176,-178,-191,-206,-200,-201,-208,-201,-208,-200,-195,-166,-167,-160,-164,-138,-176,-171,-170,-145,-157,-125,-127,-91,-104,-77,-96,-65,-75,-71,-96,-65,-84,-60,-84,-57,-72,-49,-85,-51,-85,-52,-82,-51,-93,-48,-69,-42,-81,-54,-69,-69,-69,-62,-61,-61,-54,-82,-67}, + /* IRC_Composite_C_R0195_T255_P345.wav */ + {1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,2,-2,2,-2,2,-2,3,-3,5,-29,-81,-145,-126,-102,-79,-99,-83,-32,26,-25,-104,-85,-9,-133,-67,-57,165,465,613,590,447,814,1074,1050,1231,1480,1384,1691,1545,721,693,1027,967,911,897,961,823,595,850,817,872,522,568,476,335,222,147,215,189,255,142,248,142,175,30,4,8,-59,-17,-77,-20,-108,-60,-97,-148,-132,-187,-115,-138,-127,-111,-127,-113,-156,-101,-162,-102,-180,-108,-179,-120,-179,-195,-199,-229,-185,-270,-215,-278,-237,-258,-241,-261,-210,-244,-198,-260,-213,-287,-247,-340,-255,-344,-240,-343,-221,-330,-201,-299,-199,-288,-250,-262,-234,-258,-219,-245,-213,-243,-209,-226,-210,-206,-229,-185,-199,-171,-204,-168,-186,-151,-175,-154,-197,-147,-168,-130,-180,-149,-171,-122,-158,-129,-152,-132,-156,-139,-160,-164,-170,-174,-154,-162,-126,-151,-134,-162,-148,-177,-191,-199,-212,-200,-209,-220,-215,-220,-217,-209,-214,-187,-188,-163,-169,-145,-176,-134,-160,-141,-157,-132,-139,-118,-136,-115,-131,-104,-132,-107,-134,-96,-102,-76,-89,-80,-83,-80,-72,-65,-58,-64,-74,-61,-66,-46,-79,-66,-94,-77,-85,-74,-86,-77,-80,-67,-80,-78,-81,-61,-58}, + /* IRC_Composite_C_R0195_T270_P345.wav */ + {1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,2,-2,2,-2,2,-2,2,-2,2,-3,3,-3,3,-3,4,-4,5,-5,7,-13,-9,25,107,159,235,223,228,197,135,148,180,104,249,332,345,533,679,812,953,1029,929,1077,1230,1424,1718,1696,1725,1631,997,986,1012,146,-166,111,353,347,-6,-43,73,193,90,62,-93,-92,-338,-310,-405,-336,-407,-441,-401,-511,-347,-531,-317,-432,-349,-454,-400,-327,-440,-322,-442,-318,-433,-382,-424,-384,-375,-393,-396,-458,-428,-480,-383,-434,-382,-464,-371,-432,-337,-394,-307,-399,-335,-417,-322,-442,-324,-436,-303,-449,-304,-409,-298,-363,-284,-317,-307,-308,-323,-288,-319,-293,-322,-285,-281,-248,-239,-242,-269,-244,-286,-239,-275,-228,-281,-236,-270,-215,-230,-183,-189,-147,-168,-142,-140,-138,-148,-145,-122,-112,-122,-100,-101,-92,-130,-111,-155,-125,-154,-111,-187,-117,-190,-95,-171,-106,-163,-109,-148,-117,-153,-132,-173,-135,-163,-114,-185,-122,-191,-116,-168,-92,-150,-108,-141,-94,-122,-95,-150,-97,-145,-88,-132,-65,-125,-53,-97,-33,-83,-12,-48,-5,-27,7,-11,35,-15,26,-18,26,-29,3,-32,-9,-39,15,11,7,13,12,6,12,11,20,5,2,4,3,-12,-24,-23,-5,-3,-22,4,5,1,4}, + /* IRC_Composite_C_R0195_T285_P345.wav */ + {0,0,0,0,0,0,0,0,0,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-2,2,-2,2,-2,3,-3,3,-4,5,-6,8,-11,22,-196,-173,-113,-87,-175,-179,-137,-214,-236,-209,-197,-203,-89,115,94,63,76,-21,-123,-58,550,837,1139,1631,2133,1768,1607,1992,1501,200,482,1172,950,840,796,772,845,1106,940,1271,764,758,561,601,592,456,196,274,22,269,50,133,94,119,18,4,153,30,97,24,85,20,33,14,-38,-26,-152,-46,-172,-60,-155,-115,-148,-198,-89,-195,-112,-261,-100,-214,-212,-183,-197,-150,-219,-140,-179,-164,-230,-178,-187,-230,-226,-257,-158,-281,-201,-228,-189,-261,-210,-220,-259,-267,-256,-233,-276,-267,-249,-227,-294,-254,-243,-276,-267,-297,-257,-292,-260,-305,-245,-279,-264,-243,-230,-212,-214,-151,-148,-130,-127,-88,-74,-103,-75,-88,-67,-122,-69,-96,-106,-123,-96,-146,-128,-172,-140,-152,-152,-190,-154,-179,-153,-191,-155,-209,-127,-197,-114,-197,-134,-193,-131,-195,-130,-172,-126,-176,-158,-191,-169,-206,-154,-203,-183,-230,-172,-205,-185,-204,-179,-196,-157,-166,-116,-150,-115,-126,-82,-123,-71,-85,-83,-83,-68,-72,-63,-78,-79,-49,-75,-79,-92,-70,-98,-66,-95,-75,-105,-104,-85,-82,-92,-105,-73,-107,-87,-82,-75,-79,-91}, + /* IRC_Composite_C_R0195_T300_P345.wav */ + {-1,1,-1,1,-1,1,-1,1,-1,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,3,-3,3,-3,4,-4,5,-6,8,-10,16,-33,4,109,115,258,119,96,128,286,309,258,544,795,778,461,339,836,601,406,1682,1975,1154,2276,2834,1223,701,931,69,-668,-254,489,635,-539,173,339,531,396,94,191,-102,150,-127,-75,-251,-176,-409,-489,-562,-686,-623,-666,-571,-644,-520,-569,-434,-437,-442,-489,-355,-376,-438,-545,-399,-497,-467,-538,-479,-549,-412,-479,-420,-458,-466,-435,-392,-372,-360,-342,-413,-353,-363,-348,-419,-344,-451,-370,-415,-367,-468,-389,-500,-406,-491,-367,-474,-360,-481,-350,-435,-296,-421,-285,-402,-267,-363,-222,-350,-221,-334,-215,-270,-177,-235,-146,-214,-118,-175,-89,-140,-81,-133,-96,-92,-54,-91,-56,-86,-58,-64,-32,-51,-40,-76,-57,-55,-36,-113,-96,-83,-105,-91,-129,-152,-109,-131,-124,-142,-150,-156,-119,-136,-143,-152,-125,-140,-130,-126,-129,-99,-125,-119,-110,-121,-109,-118,-102,-117,-98,-117,-101,-93,-114,-105,-94,-69,-112,-75,-86,-60,-49,-25,-59,6,-33,-1,-8,8,-2,17,23,0,29,13,17,24,18,21,18,23,-13,11,-8,15,5,10,-10,8,-24,7,1,-11,1,27,-4,48,5,53,24,86,43,68,50,99}, + /* IRC_Composite_C_R0195_T315_P345.wav */ + {1,-1,1,-1,1,-1,1,-1,1,-1,1,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-1,0,6,-137,-110,-314,-483,-264,-184,-467,-482,89,-336,204,277,141,-93,-770,-71,819,-837,1577,3127,1312,2383,3512,2495,-80,350,890,699,71,561,954,294,1113,1117,1259,495,984,849,877,553,746,524,537,393,441,428,542,429,296,210,204,231,133,-55,33,-7,-111,-11,-91,34,-190,-56,-131,39,-14,66,-79,58,-96,105,-60,169,-64,84,-143,118,-100,-84,-157,-91,-304,-233,-224,-201,-251,-259,-309,-306,-307,-286,-299,-265,-407,-357,-301,-345,-348,-313,-294,-342,-334,-338,-298,-266,-288,-261,-298,-254,-268,-227,-236,-260,-244,-223,-227,-260,-233,-195,-202,-171,-228,-156,-170,-114,-170,-107,-146,-105,-89,-96,-83,-40,-73,-59,-66,-65,-71,-53,-107,-74,-75,-92,-122,-102,-105,-87,-130,-86,-139,-115,-142,-131,-148,-147,-160,-144,-151,-139,-173,-139,-186,-126,-170,-147,-194,-137,-189,-141,-184,-162,-186,-151,-208,-180,-195,-172,-186,-165,-204,-165,-157,-155,-139,-132,-141,-108,-126,-89,-110,-98,-101,-113,-94,-111,-133,-99,-126,-121,-126,-97,-115,-103,-122,-84,-114,-58,-120,-106,-109,-97,-103,-75,-128,-91,-104,-73,-91,-53,-59,-46,-63,-33,-22,-14}, + /* IRC_Composite_C_R0195_T330_P345.wav */ + {-9,9,-9,9,-9,9,-9,9,-9,9,-9,9,-9,9,-9,9,-9,9,-9,10,-10,10,-10,10,-10,10,-10,10,-7,-378,-458,118,-356,-539,-320,-251,-977,-150,272,171,262,290,-552,-354,-2031,2393,-54,-667,4888,3245,1575,3792,4173,-210,-907,432,1658,-334,338,623,940,723,1598,1314,1216,764,1038,976,401,116,250,473,239,334,528,294,340,65,340,194,348,152,304,92,279,123,93,-24,89,-192,-125,-56,-130,68,194,-86,77,174,220,128,98,-234,-216,-168,-160,-251,-283,-410,-399,-240,-227,-363,-327,-361,-302,-370,-271,-312,-309,-428,-402,-318,-223,-266,-304,-253,-264,-272,-246,-203,-278,-299,-319,-254,-236,-260,-281,-188,-203,-212,-220,-185,-220,-178,-230,-207,-215,-227,-248,-182,-197,-163,-179,-101,-143,-112,-138,-84,-115,-82,-111,-83,-102,-83,-51,-69,-49,-89,-18,-67,-73,-108,-72,-63,-79,-111,-167,-94,-130,-99,-166,-109,-181,-121,-156,-124,-154,-131,-162,-169,-165,-170,-136,-151,-159,-185,-163,-122,-139,-141,-175,-141,-148,-148,-172,-157,-130,-154,-150,-148,-142,-153,-141,-116,-159,-97,-155,-91,-162,-92,-141,-53,-134,-97,-132,-68,-111,-97,-127,-98,-128,-105,-137,-81,-141,-76,-120,-73,-136,-97,-105,-48,-102,-73,-108,-56,-97,-41,-75,-56,-70,-20,-33,-9,-51,-32}, + /* IRC_Composite_C_R0195_T345_P345.wav */ + {1,-2,2,-3,4,-4,5,-6,7,-8,9,-10,11,-13,14,-16,17,-19,21,-22,24,-25,25,-22,13,15,-152,-764,140,-602,18,-900,-519,-1092,-545,489,261,706,-1198,1895,-1912,-2689,2900,30,-3177,8188,3071,2405,4243,6073,615,-3233,507,1858,-510,-537,1688,110,230,1724,2185,1547,1263,1871,1145,573,342,-23,261,-614,-9,-121,805,-137,38,285,272,-29,312,280,184,234,346,-32,603,80,194,153,323,-216,458,198,10,-275,28,-275,-40,-248,-266,-416,-305,-349,-213,-336,-338,-460,-267,-400,-247,-403,-303,-379,-264,-460,-298,-347,-227,-420,-309,-405,-246,-238,-250,-319,-267,-250,-266,-221,-240,-318,-184,-236,-175,-305,-161,-225,-161,-213,-190,-219,-158,-206,-155,-198,-165,-211,-169,-178,-141,-180,-148,-191,-154,-191,-120,-222,-141,-171,-68,-131,-104,-142,-95,-72,-93,-71,-91,-94,-90,-92,-83,-97,-91,-117,-108,-109,-102,-101,-101,-116,-95,-82,-119,-115,-158,-119,-137,-108,-151,-151,-163,-123,-125,-148,-167,-118,-168,-149,-196,-146,-169,-130,-179,-147,-164,-153,-114,-109,-119,-128,-121,-82,-111,-89,-98,-81,-102,-105,-71,-85,-85,-116,-85,-98,-76,-124,-102,-118,-107,-84,-126,-141,-114,-78,-80,-110,-127,-121,-93,-112,-96,-109,-98,-90,-55,-53,-66,-54,-41,-26,-18,-19,-5,-33,-57,-33}}; + +const int16_t irc_composite_c_r0195_p000[][256] = + {/* IRC_Composite_C_R0195_T000_P000.wav */ + {1,-1,1,-1,0,0,0,0,0,1,-1,2,-2,2,-3,4,-5,6,-7,9,-11,14,-20,33,-756,-534,-348,102,-1032,-582,-1506,65,-959,133,-210,1928,576,-291,-5368,5774,-6962,-2265,14308,-3483,7090,10599,2076,-2731,3149,-192,-3412,-1652,3866,548,-1226,-1088,2012,2077,1960,-209,1087,1404,1871,1150,1665,536,626,1200,1268,592,-114,-160,-95,133,-37,-246,158,-144,-190,-548,421,96,105,-192,181,129,158,143,73,-164,-261,-64,-147,-128,-55,-166,-60,98,349,-253,126,-172,110,-391,-118,265,-317,256,-97,416,-62,274,-244,-355,-104,-427,-357,-741,-368,-489,-365,-418,-498,-150,-384,-361,-530,-257,-297,-381,-491,-511,-393,-429,-294,-395,-373,-408,-292,-342,-260,-297,-286,-427,-324,-291,-291,-276,-319,-244,-386,-221,-241,-141,-260,-273,-231,-153,-86,-203,-202,-152,-95,-140,-176,-127,-110,-156,-237,-148,-139,-94,-248,-190,-202,-85,-155,-205,-223,-169,-158,-183,-216,-167,-164,-146,-219,-103,-162,-71,-220,-10,-169,7,-134,32,-76,-42,-100,-66,-50,-44,-71,-88,-122,-40,-75,21,-78,-18,-125,-33,-69,53,-77,-22,-138,-41,-62,-55,-92,-83,-99,-115,-150,-17,-53,-12,-184,-50,-96,28,-81,-1,-78,-41,-118,-14,-66,38,-82,-29,-104,29,5,34,-62,14,7,47,-61,67,-43,51,-145,61}, + /* IRC_Composite_C_R0195_T015_P000.wav */ + {123,-125,127,-129,131,-133,135,-137,138,-140,141,-141,141,-140,137,-131,122,-106,76,-10,-238,-830,-319,-1069,17,-859,165,-1424,-309,-2002,526,695,3378,-155,-423,-6705,9134,-12025,1719,14823,-7846,16119,11510,-1243,-4202,5454,-1293,-2996,-1156,2894,-853,-440,-59,2319,814,827,428,2620,1829,1181,817,1748,469,1133,599,1385,-490,316,-1523,369,-621,391,-835,160,-740,77,-149,751,-195,-103,-622,191,-100,342,-303,-90,-465,82,62,259,-409,-385,44,87,-50,21,54,-467,-207,-79,-324,-108,-90,-152,-620,71,-110,47,-749,-161,-523,-153,-446,-157,-336,40,-137,-86,-507,-177,-322,-14,-430,-277,-557,-360,-326,-296,-274,-463,-359,-502,-263,-388,-316,-369,-353,-459,-464,-335,-293,-324,-333,-369,-324,-380,-288,-268,-287,-294,-317,-270,-395,-181,-204,-149,-383,-214,-212,-113,-188,-174,-211,-188,-99,-166,-173,-203,-111,-134,-148,-226,-166,-126,-86,-216,-199,-234,-119,-193,-118,-250,-172,-245,-101,-156,-114,-172,-153,-162,-98,-70,-71,-106,-70,-81,-14,-14,37,-38,-36,-107,-3,-9,52,-91,-63,-116,20,-50,18,-151,-37,-125,57,-97,31,-149,5,-133,4,-141,9,-132,-7,-168,9,-124,33,-144,22,-166,15,-117,46,-156,11,-127,36,-124,23,-58,69,-65,71,-34,110,-36,130,-45,96,-68,96,-59,38,-71}, + /* IRC_Composite_C_R0195_T030_P000.wav */ + {-63,66,-69,73,-76,80,-84,89,-93,98,-102,107,-110,111,-108,95,-54,-154,-785,-302,-1153,268,-1139,240,-1422,320,-2283,272,-629,4046,237,3112,-7137,2285,231,-13166,20036,-5068,11914,16533,2581,-5753,2916,1267,-3077,-1961,1642,-123,210,665,1080,1069,485,1122,1846,1948,901,1486,921,1132,470,865,-186,-57,-358,-153,-489,-118,-724,-365,-517,-156,-335,155,-255,96,-315,376,-169,22,-435,5,-544,-35,-484,-12,-457,280,-453,-177,-399,435,-423,-188,-484,161,-217,-38,-732,-416,-157,73,-480,-440,-302,-140,-260,-335,-490,-420,-470,-291,-617,-112,-315,20,-559,-210,-412,154,-162,-102,-453,-225,-205,-23,-247,-203,-409,-147,-366,-147,-367,-150,-477,-326,-502,-222,-390,-294,-498,-249,-423,-313,-510,-239,-382,-176,-516,-351,-496,-92,-337,-150,-462,-212,-366,-74,-288,-94,-322,-110,-334,-53,-240,11,-306,-108,-332,-45,-271,-52,-295,-76,-308,-99,-319,-57,-226,-50,-303,-130,-254,-54,-183,-89,-261,-98,-193,-6,-184,-12,-164,45,-175,27,-120,129,-69,82,-89,120,-26,113,-48,59,-77,18,-85,-3,-107,0,-78,-29,-159,0,-62,67,-139,-9,-138,19,-136,-3,-124,-27,-149,-30,-136,-11,-97,-7,-137,-19,-96,20,-84,15,-64,28,-92,9,15,121,-12,24,-32,74,36,98,-9,3,-30,36,-42,4}, + /* IRC_Composite_C_R0195_T045_P000.wav */ + {72,-74,77,-79,82,-86,91,-96,102,-111,121,-134,152,-179,228,-635,490,-1252,-114,-1202,742,-1779,495,-1563,532,-2895,2675,1167,4718,-4709,4646,-5559,-6673,7608,-8298,21201,11442,4596,920,5308,-1818,-1353,-1082,-283,-725,2349,-984,-140,614,1696,1859,2003,557,2080,1067,416,1112,525,38,-87,-851,-336,38,-375,-495,-291,-403,-90,-299,-393,-130,-647,-37,-270,-227,-182,-2,-485,-21,-380,-221,-179,-364,-244,-343,-247,-161,-213,-443,-201,-386,-349,-198,-453,-401,-479,-187,-349,-331,-486,-40,-343,-132,-248,-346,-150,-185,-498,-200,-280,-512,-271,-152,-472,-405,-421,-235,-444,-272,-369,-299,-285,-209,-483,-192,-140,-287,-241,-120,-328,36,-232,-275,-345,-26,-488,-78,-319,-205,-488,22,-390,-294,-391,-131,-450,-198,-416,-347,-391,-95,-530,-266,-359,-162,-403,-129,-438,-172,-313,-124,-327,-146,-338,-102,-245,-121,-328,-124,-244,-79,-277,-128,-320,-47,-241,-144,-306,-70,-274,-85,-274,-147,-219,-71,-212,-78,-214,-60,-127,0,-182,-21,-106,67,-97,35,-113,84,16,65,-67,99,-24,79,7,29,-85,99,-35,17,-91,57,-100,58,-112,-18,-130,73,-160,-25,-148,6,-136,45,-217,2,-142,79,-180,64,-198,81,-156,114,-200,98,-162,123,-120,152,-170,176,-85,130,-107,189,-99,158,-113,138,-127,161,-140,111,-221}, + /* IRC_Composite_C_R0195_T060_P000.wav */ + {123,-132,142,-153,166,-180,196,-215,238,-264,296,-338,397,-545,-26,-1070,548,-1189,312,-1132,-540,-593,703,-1932,23,1834,2821,3650,-4896,2244,-8990,3547,-3667,11688,19991,4002,-67,5265,-1066,-618,257,-237,-93,2490,-1554,-1096,1601,944,1501,1048,1374,1754,1792,566,335,-350,932,-271,-1525,-771,-646,-466,146,-610,113,-1035,510,-222,-23,-608,-443,-725,203,-887,-434,-589,-19,-438,-40,-610,14,-467,-137,-372,-214,-629,-55,-580,-263,-517,-350,-563,-317,-499,-281,-660,-233,-369,6,-533,-180,-457,-90,-331,-140,-395,-150,-246,-124,-225,-134,-388,-151,-322,-330,-363,-280,-394,-241,-503,-138,-532,-169,-402,-263,-433,-255,-363,-244,-372,-271,-364,-268,-337,-126,-472,-58,-441,6,-373,-75,-345,-91,-290,-171,-369,-128,-311,-189,-312,-183,-241,-230,-309,-78,-303,-168,-337,-178,-236,-164,-270,-238,-313,-113,-261,-195,-270,-208,-224,-136,-312,-153,-332,-79,-287,-193,-257,-149,-227,-124,-297,-82,-209,-107,-181,-87,-173,-18,-146,9,-126,28,-74,-22,-25,22,-50,40,-41,25,-17,-14,5,9,-67,23,-34,57,-46,5,3,37,-39,6,-36,11,-54,-39,-69,-61,-79,-35,-99,-38,-98,-29,-88,-12,-86,-19,-71,-19,-37,-12,-58,7,-41,34,-37,47,-22,42,-26,97,2,68,-13,74,7,35,-6,34,-1,0,-38}, + /* IRC_Composite_C_R0195_T075_P000.wav */ + {30,-35,41,-47,55,-63,72,-84,97,-113,134,-162,202,-472,-304,-372,274,-1176,-371,-433,-535,-54,364,-1802,1909,3073,5773,-6217,-2323,-1631,-4047,10163,-533,23315,9574,-7064,764,4451,279,-686,938,2910,-1594,-781,31,2302,-241,1013,1336,1127,1162,699,28,761,380,-426,-314,-917,-750,-202,-732,-632,-472,-517,-73,-213,-19,-699,-215,-440,-368,-595,-354,-716,-262,-604,-448,-306,-492,-226,-481,-404,-393,-315,-472,-290,-442,-401,-227,-459,-350,-606,-194,-594,-308,-438,-436,-423,-217,-461,-220,-298,-300,-185,-218,-342,-120,-282,-142,-260,-82,-276,-46,-282,-219,-258,-93,-447,-193,-418,-296,-377,-249,-479,-177,-358,-304,-416,-185,-366,-179,-486,-287,-406,-134,-512,-167,-454,-201,-352,-195,-386,-169,-289,-223,-334,-186,-280,-123,-302,-167,-268,-36,-301,-139,-264,-133,-195,-111,-276,-131,-175,-123,-195,-148,-226,-77,-211,-165,-231,-123,-257,-132,-285,-135,-289,-147,-278,-141,-274,-166,-238,-154,-189,-134,-212,-101,-127,-6,-142,-21,-106,41,-81,41,-105,54,-54,6,-41,-3,-62,27,-57,-25,-42,29,-39,10,-90,56,-38,43,-106,38,-63,27,-58,-21,-110,-19,-82,-36,-124,-57,-83,23,-113,9,-73,55,-109,34,-55,45,-13,62,-54,27,-33,52,12,35,-34,72,-19,33,-32,74,-59,39,-25,53,1,10,-3}, + /* IRC_Composite_C_R0195_T090_P000.wav */ + {-3,3,-4,5,-6,7,-9,11,-13,17,-23,36,-967,38,-432,430,-1179,327,-1275,279,-1297,1913,-1800,360,826,8131,-4106,182,-6660,-1308,8763,-6147,21004,13661,-1493,-3341,815,6070,1330,-1696,3689,487,-871,-2812,2923,1220,319,-441,2019,161,1147,-214,819,-1063,179,-1133,125,-1120,701,-1109,-441,-308,-3,-1227,135,-661,-529,-162,-375,-951,-262,-371,-533,-415,-491,-644,-459,-451,-508,-551,-360,-465,-434,-399,-416,-458,-204,-423,-358,-363,-290,-434,-346,-447,-174,-475,-424,-400,-239,-439,-175,-468,-418,-188,-90,-409,-214,-233,-225,-147,-140,-439,-299,-104,-157,-229,-145,-201,-232,-109,-193,-310,-284,-271,-306,-318,-342,-330,-320,-362,-208,-295,-346,-295,-212,-394,-231,-297,-357,-348,-177,-356,-301,-275,-291,-319,-184,-255,-307,-178,-245,-228,-206,-194,-280,-137,-218,-191,-183,-203,-186,-105,-193,-151,-164,-132,-164,-77,-203,-113,-167,-192,-164,-75,-239,-194,-160,-166,-186,-77,-232,-182,-148,-63,-204,-92,-164,-69,-54,4,-140,-18,-43,36,-61,41,-116,-2,-92,42,-126,-61,-150,-8,-117,-15,-62,-69,-114,61,-14,10,-74,8,-25,119,-37,0,-69,10,-56,37,-94,-111,-86,30,-107,-71,-119,4,-92,38,-125,29,-50,58,-57,64,-84,92,-4,67,-73,54,-8,88,-67,71,21,64,-36,123,-7,23,-36,115}, + /* IRC_Composite_C_R0195_T105_P000.wav */ + {67,-63,58,-51,43,-33,19,-1,-24,61,-121,244,-927,183,-686,327,-496,-330,-486,-340,-314,396,182,-1212,1259,6063,-556,-2378,-2582,-3838,9614,-8512,18557,14219,-782,-2750,529,5714,4180,-1314,2811,874,-1413,-2611,2334,2590,-537,-811,436,1284,515,-112,-879,-106,-221,-558,-955,-184,-84,-312,-553,-219,-379,-172,-456,-790,-576,-350,-708,-606,-553,-357,-404,-422,-537,-414,-291,-515,-518,-625,-263,-417,-492,-719,-360,-360,-368,-573,-481,-304,-142,-306,-536,-356,-164,-154,-398,-429,-388,-147,-288,-315,-532,-144,-267,-143,-527,-186,-329,6,-447,-226,-375,20,-329,-159,-444,-77,-329,-143,-450,-93,-327,2,-390,-87,-374,55,-418,-96,-445,-37,-436,-129,-505,-118,-444,-152,-487,-172,-395,-135,-432,-170,-368,-96,-414,-145,-394,-32,-326,-123,-434,-83,-276,-94,-355,-149,-242,-56,-256,-166,-269,-75,-228,-119,-313,-87,-207,-58,-304,-97,-234,-23,-285,-126,-259,-11,-242,-91,-247,-1,-204,-10,-242,-5,-194,74,-169,102,-92,170,-62,135,-93,108,-134,5,-190,-8,-203,-47,-223,16,-187,1,-174,58,-131,78,-113,75,-130,98,-75,44,-121,101,-58,53,-146,47,-70,70,-128,-19,-108,21,-89,-23,-119,-27,-39,31,-124,-51,-37,65,-45,0,4,66,6,17,11,14,30,64,44,27,-16,79,-9,-11,-60,55}, + /* IRC_Composite_C_R0195_T120_P000.wav */ + {-76,75,-75,74,-72,69,-65,59,-49,35,-14,-21,85,-263,347,27,-533,-67,-385,-42,-335,645,-2065,1305,1033,1922,-2255,6706,-3555,1838,-9048,1510,15767,522,6485,7416,2582,-1635,-1123,7704,6890,-3746,-2349,-815,4058,-1305,633,-1081,2060,-1086,490,-1435,1038,-465,-103,-1558,594,-576,-246,-797,-411,-729,216,-627,-444,-642,122,-670,-147,-796,-255,-906,76,-717,-449,-584,-119,-685,-337,-606,-352,-326,-478,-502,-420,-468,-445,-428,-466,-351,-293,-513,-155,-443,-243,-371,-82,-573,-58,-388,-209,-303,-195,-394,-165,-220,-376,-192,-262,-255,-289,-234,-278,-284,-271,-328,-227,-325,-185,-358,-162,-289,-168,-301,-148,-278,-221,-237,-227,-212,-236,-164,-236,-223,-147,-209,-256,-222,-209,-360,-125,-328,-206,-254,-219,-307,-162,-296,-276,-174,-324,-187,-268,-155,-286,-159,-317,-134,-252,-195,-181,-236,-204,-162,-148,-226,-141,-227,-132,-141,-218,-189,-165,-114,-288,-111,-256,-76,-252,-50,-308,-80,-158,-63,-217,-126,-102,12,-10,-77,13,74,33,49,-22,50,-56,57,-177,-13,-201,19,-144,-101,-181,59,-32,-49,-45,-72,-16,32,-40,-48,-33,-42,-45,64,-145,8,-69,33,-144,44,-92,56,-118,-2,-60,8,-77,-3,-91,-37,-73,-11,-53,0,-49,56,-45,17,-73,100,6,64,-7,125,-47,94,22,33,-55,12,-30,7}, + /* IRC_Composite_C_R0195_T135_P000.wav */ + {-47,46,-46,44,-43,40,-37,33,-28,21,-12,-1,20,-48,94,-206,95,-290,-258,153,-592,203,-293,297,-1153,1348,644,1791,-1433,6094,-3856,-260,-5383,6042,11744,-1699,5991,8208,1865,-2201,2510,6226,4590,-5126,-1361,782,2433,-2030,854,-833,853,-1117,568,-1205,680,-1070,-374,-797,196,-738,-381,-460,54,-509,80,-809,-117,-538,-17,-916,203,-876,-170,-815,-257,-782,-178,-520,-324,-433,-344,-353,-383,-382,-403,-522,-240,-512,-312,-523,-189,-533,-114,-477,-247,-366,-173,-363,-247,-204,-351,-273,-220,-239,-329,-247,-257,-330,-207,-331,-212,-342,-200,-298,-246,-261,-277,-228,-264,-213,-328,-212,-273,-219,-256,-244,-234,-265,-159,-264,-191,-244,-157,-229,-190,-221,-203,-203,-265,-198,-238,-189,-235,-164,-189,-220,-183,-216,-189,-257,-194,-227,-199,-234,-209,-214,-214,-195,-212,-179,-255,-200,-207,-151,-257,-182,-194,-172,-200,-169,-219,-215,-208,-180,-207,-192,-215,-173,-203,-137,-219,-101,-232,-121,-175,-4,-148,-45,-92,5,-35,0,-5,-45,0,8,10,-53,-107,-5,-81,6,-157,3,-130,19,-128,39,-138,5,-65,57,-90,7,-52,45,-79,13,-78,29,-109,14,-79,25,-126,7,-61,-11,-75,1,-51,-46,-64,-35,-74,-40,-48,36,-46,3,-64,53,-59,33,-26,105,4,63,13,64,-28,24,-1,3,-80,-21}, + /* IRC_Composite_C_R0195_T150_P000.wav */ + {-5,6,-7,7,-8,9,-10,11,-12,13,-15,16,-17,19,-20,20,-17,1,-234,227,-421,117,-50,-175,-40,33,-222,178,1388,586,910,1027,4228,-7050,1223,2017,6153,4669,1121,8628,6102,-3597,1339,6488,2001,-1618,-2670,715,665,-9,-1202,163,-501,22,-977,268,-483,330,-922,182,-469,62,-791,-223,-334,-215,-485,-347,-491,-176,-429,-178,-696,-63,-705,-191,-727,-100,-715,-18,-605,-161,-531,-137,-475,-197,-485,-201,-433,-135,-408,-232,-404,-136,-441,-131,-469,-151,-475,-144,-469,-155,-431,-165,-416,-207,-381,-199,-342,-208,-344,-172,-301,-189,-339,-193,-297,-159,-303,-169,-283,-144,-295,-190,-323,-198,-312,-172,-324,-214,-279,-169,-264,-159,-230,-157,-232,-160,-206,-167,-240,-200,-232,-191,-234,-175,-238,-189,-225,-142,-206,-214,-206,-200,-152,-232,-176,-232,-184,-217,-152,-205,-194,-188,-192,-160,-199,-163,-211,-186,-234,-194,-218,-212,-270,-194,-202,-181,-219,-182,-202,-169,-194,-142,-192,-142,-138,-58,-121,-63,-104,-7,-62,-12,-40,0,-55,-16,-33,-41,-87,-38,-71,-48,-89,-7,-81,-22,-59,5,-41,-28,-47,-20,-14,-23,-20,-10,-31,-22,-25,-11,-55,-34,-32,-33,-44,-53,1,-30,-56,-58,-29,-61,-47,-27,-44,-54,-52,-32,-37,-63,-16,18,1,-3,18,72,0,21,9,42,-23,-7,-40,-42}, + /* IRC_Composite_C_R0195_T165_P000.wav */ + {-31,31,-31,31,-30,30,-30,29,-28,27,-25,23,-20,16,-12,5,5,-18,40,-78,187,-74,-49,55,-110,112,-199,218,-425,530,199,1304,62,2352,168,2823,-5315,837,4953,2252,4624,4623,6361,3213,-1540,938,5698,-601,-1840,-1321,415,-514,-55,-892,3,-75,186,-753,471,-260,192,-752,21,-345,-220,-374,-258,-349,-282,-436,-427,-398,-253,-570,-291,-449,-37,-524,-88,-564,-148,-493,-85,-435,-73,-317,-105,-359,-181,-335,-176,-321,-195,-365,-206,-391,-180,-383,-187,-437,-200,-456,-199,-434,-221,-404,-185,-335,-239,-304,-221,-288,-247,-317,-222,-256,-192,-283,-227,-290,-193,-268,-185,-298,-185,-261,-149,-305,-194,-283,-162,-272,-207,-271,-209,-214,-185,-206,-201,-195,-156,-200,-178,-267,-179,-273,-180,-271,-149,-245,-175,-193,-143,-182,-204,-213,-175,-213,-191,-252,-204,-249,-193,-210,-188,-202,-194,-140,-186,-146,-188,-134,-188,-186,-187,-199,-210,-191,-202,-211,-250,-183,-225,-176,-254,-154,-188,-96,-150,-85,-102,-69,-80,-63,-71,-81,-74,-55,-81,-81,-69,-57,-79,-51,-37,-34,-57,-26,-18,6,-12,5,-5,22,-15,19,-13,6,-49,9,-38,-32,-76,-25,-65,-43,-75,-1,-82,-14,-96,-21,-95,-25,-47,-4,-67,-76,-41,-67,-39,-53,-5,-25,-37,30,14,61,-21,72,-39,30,-59,25,-48,-21}, + /* IRC_Composite_C_R0195_T180_P000.wav */ + {9,-9,9,-10,10,-11,11,-12,13,-13,14,-15,16,-17,18,-19,20,-21,22,-24,25,-26,25,-17,104,-114,196,-98,54,-126,232,-41,337,459,418,1258,2024,1306,-3081,2067,-322,1935,2599,4829,7530,3384,-1993,2649,3619,-256,-653,-863,-84,-381,-1124,-459,826,-56,-554,-375,247,362,403,-767,-54,-307,253,-528,-72,-499,-251,-538,-224,-365,-429,-387,-270,-98,-240,-189,-323,-221,-114,-200,-172,-265,-34,-233,-42,-325,-228,-392,-171,-360,-298,-341,-265,-231,-220,-299,-332,-289,-282,-307,-286,-295,-293,-265,-194,-288,-280,-341,-219,-319,-258,-367,-240,-308,-190,-294,-215,-308,-212,-271,-223,-283,-231,-230,-192,-212,-231,-187,-195,-184,-197,-212,-220,-239,-198,-224,-201,-254,-209,-229,-205,-256,-239,-265,-231,-229,-194,-202,-206,-179,-140,-169,-205,-189,-208,-194,-220,-219,-227,-219,-190,-210,-179,-230,-143,-194,-136,-216,-131,-181,-147,-210,-176,-226,-209,-222,-193,-214,-206,-190,-190,-205,-213,-200,-179,-148,-109,-85,-53,-73,-40,-100,-69,-150,-91,-144,-106,-152,-99,-85,-54,-38,-16,3,2,19,74,35,28,11,42,13,8,-18,-32,-36,-29,-19,-47,-86,-72,-66,-42,-83,-71,-83,-83,-72,-54,-20,-67,-68,-58,-74,-64,-79,-16,-60,-46,-42,-7,11,22,53,51,32,-13,33,28,3,-22,-46}, + /* IRC_Composite_C_R0195_T195_P000.wav */ + {12,-12,12,-12,12,-12,12,-12,12,-12,12,-12,12,-12,12,-12,11,-11,10,-9,8,-6,4,-1,-5,16,-58,-48,-46,77,37,-65,-49,-7,-27,197,332,255,848,1561,1608,-2167,729,-55,1458,1975,2964,6210,4289,99,1163,3083,300,-110,-1053,97,-72,-273,-635,580,371,-146,-5,150,225,128,22,74,-75,62,-60,-62,-162,-184,-359,-146,-99,33,-264,-53,-91,-68,-97,-68,-107,-168,-116,-102,-205,-156,-272,-180,-287,-225,-284,-228,-198,-203,-177,-240,-212,-239,-265,-245,-245,-239,-269,-232,-261,-248,-259,-262,-292,-271,-282,-251,-272,-265,-298,-265,-285,-267,-290,-263,-263,-239,-279,-219,-264,-196,-232,-191,-206,-170,-181,-179,-220,-200,-244,-184,-248,-231,-259,-234,-254,-249,-268,-279,-250,-255,-219,-236,-226,-171,-197,-163,-222,-176,-205,-187,-189,-200,-188,-195,-184,-172,-221,-174,-245,-154,-259,-156,-238,-169,-237,-202,-213,-230,-237,-242,-223,-236,-210,-202,-201,-217,-219,-206,-204,-158,-180,-128,-112,-64,-38,-58,-71,-95,-94,-116,-117,-160,-118,-117,-105,-102,-88,-47,-31,-21,-9,0,24,-11,6,-19,6,1,-16,-22,-27,-22,-10,-73,-58,-79,-51,-76,-65,-82,-99,-73,-70,-36,-82,-58,-110,-76,-105,-83,-46,-122,-54,-86,17,-33,15,14,-1,0,13,44,23,-6,2,-42}, + /* IRC_Composite_C_R0195_T210_P000.wav */ + {6,-6,6,-6,7,-7,7,-7,7,-7,7,-7,8,-8,8,-8,8,-9,9,-9,10,-10,10,-11,12,-12,13,-13,-3,-140,-62,16,74,-75,-81,-9,-154,52,75,214,374,933,1063,-50,-424,1215,-28,199,1671,2854,5292,2238,1086,1897,2061,-301,-116,-17,89,220,-368,-4,403,517,47,242,331,363,284,327,289,188,152,291,134,170,136,286,56,186,15,53,-103,44,-142,-179,-241,-86,-171,-94,-229,-133,-165,-58,-222,-146,-225,-113,-173,-105,-202,-191,-235,-184,-216,-202,-258,-257,-241,-211,-214,-256,-271,-278,-250,-239,-276,-254,-285,-245,-277,-265,-277,-285,-295,-284,-275,-264,-248,-242,-249,-215,-225,-190,-221,-208,-231,-195,-210,-191,-211,-203,-222,-199,-222,-228,-234,-247,-238,-233,-235,-232,-214,-216,-211,-201,-215,-188,-250,-191,-224,-183,-218,-210,-195,-212,-196,-217,-202,-221,-224,-225,-263,-219,-268,-220,-277,-225,-254,-223,-243,-232,-228,-229,-221,-217,-194,-205,-169,-170,-122,-124,-95,-89,-83,-76,-91,-74,-103,-96,-96,-80,-91,-101,-107,-123,-107,-115,-88,-113,-70,-93,-25,-70,-18,-56,-11,-38,-15,-23,-20,-23,-29,-31,-55,-70,-58,-57,-52,-93,-74,-95,-46,-80,-63,-97,-83,-108,-85,-90,-88,-102,-101,-88,-79,-54,-29,-30,-33,-9,-5,-3,24,-9,7,-23}, + /* IRC_Composite_C_R0195_T225_P000.wav */ + {-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-2,2,-2,2,-3,4,-4,6,-9,17,-16,-98,-60,-77,48,3,-81,-121,-43,-55,1,19,93,305,537,631,131,-260,545,567,27,1207,2128,2827,2558,1188,1325,1915,744,102,304,255,211,393,327,58,643,377,590,456,611,727,425,704,395,620,277,569,148,252,218,128,12,-134,-32,-106,-54,-94,-7,3,-19,-31,-59,-78,-49,-114,-79,-187,-72,-177,-103,-203,-112,-200,-151,-256,-183,-276,-182,-258,-181,-256,-202,-239,-241,-240,-281,-205,-284,-252,-257,-288,-259,-319,-259,-309,-239,-302,-232,-305,-231,-282,-235,-251,-227,-244,-183,-227,-177,-216,-169,-213,-156,-216,-165,-230,-183,-214,-199,-211,-207,-215,-203,-236,-236,-213,-269,-197,-284,-219,-271,-227,-256,-210,-245,-209,-247,-203,-231,-195,-235,-194,-248,-194,-245,-212,-237,-203,-241,-198,-226,-200,-216,-221,-205,-209,-210,-188,-216,-146,-202,-108,-186,-110,-157,-108,-129,-121,-125,-129,-118,-125,-104,-120,-104,-95,-101,-78,-84,-57,-71,-28,-65,-16,-83,-25,-68,-41,-63,-42,-59,-29,-46,-33,-54,-48,-58,-50,-85,-80,-93,-89,-117,-98,-103,-82,-104,-94,-118,-105,-87,-86,-85,-96,-100,-64,-69,-48,-63,-65,-45,-15,-39,-27,-55,-31}, + /* IRC_Composite_C_R0195_T240_P000.wav */ + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,1,-1,1,-1,1,-1,2,-2,2,-3,5,-9,-97,-133,-196,-147,-157,-47,-93,37,-29,1,0,59,-116,-55,150,274,295,91,361,1004,1112,1011,1324,1700,2156,1559,331,574,1032,523,614,629,882,990,1087,1066,943,977,621,691,470,536,382,281,280,209,295,117,203,196,393,300,250,185,141,127,-15,-42,-136,-73,-208,-111,-261,-80,-157,-42,-115,-38,-121,-105,-155,-167,-199,-209,-235,-206,-227,-259,-253,-267,-251,-281,-214,-260,-213,-271,-234,-259,-192,-277,-204,-294,-201,-341,-226,-327,-238,-309,-206,-263,-189,-240,-185,-208,-186,-211,-192,-209,-158,-223,-155,-231,-165,-251,-159,-233,-168,-259,-189,-266,-206,-255,-200,-268,-211,-290,-218,-286,-233,-302,-227,-283,-216,-289,-207,-262,-193,-248,-196,-236,-182,-219,-173,-221,-200,-230,-207,-207,-205,-216,-209,-217,-217,-212,-207,-184,-207,-178,-189,-131,-147,-115,-129,-101,-99,-95,-93,-92,-108,-91,-105,-77,-114,-73,-104,-68,-90,-52,-74,-36,-70,-50,-80,-45,-81,-54,-78,-26,-78,-29,-94,-58,-114,-94,-144,-115,-134,-101,-99,-82,-78,-81,-65,-58,-71,-110,-125,-130,-133,-109,-102,-88,-107,-78,-90,-39,-58,-31,-64,-17,-39,-13}, + /* IRC_Composite_C_R0195_T255_P000.wav */ + {2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-3,3,-3,3,-3,3,-3,3,-3,4,-4,4,-5,5,-6,9,-19,-71,-126,-111,-131,-223,-213,-179,-73,-136,-101,-19,30,101,69,89,95,323,406,515,721,768,1140,1389,925,919,1504,1350,1027,1508,1800,2083,1870,1354,950,539,490,494,392,378,293,344,461,473,522,375,344,271,237,162,56,42,11,83,-5,55,-30,81,-3,71,-18,-50,0,-151,-66,-240,-143,-251,-198,-256,-250,-192,-239,-205,-271,-195,-240,-195,-267,-238,-257,-227,-242,-241,-251,-226,-256,-185,-246,-212,-252,-224,-227,-235,-216,-249,-192,-222,-170,-209,-167,-231,-184,-255,-188,-250,-181,-283,-185,-279,-146,-264,-164,-273,-161,-261,-181,-298,-216,-272,-226,-251,-181,-242,-222,-248,-216,-260,-249,-302,-271,-289,-255,-276,-256,-246,-225,-218,-198,-202,-222,-210,-223,-219,-210,-230,-209,-218,-149,-175,-141,-182,-152,-139,-146,-160,-169,-152,-140,-120,-129,-130,-102,-120,-59,-92,-67,-121,-84,-93,-62,-69,-69,-85,-101,-60,-94,-80,-123,-92,-126,-73,-83,-80,-90,-79,-71,-42,-42,-54,-59,-77,-88,-83,-86,-100,-126,-130,-119,-130,-124,-145,-127,-148,-111,-124,-92,-85,-75,-85,-70,-68,-66,-66,-59,-78,-67,-59,-65}, + /* IRC_Composite_C_R0195_T270_P000.wav */ + {-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,2,-2,2,-2,3,-4,9,-91,-159,-163,-111,-130,-163,-90,-102,-89,-163,-184,-188,-171,-83,30,36,169,298,65,214,405,559,898,896,1271,2043,2157,2404,2912,2261,1344,1103,1268,1220,756,484,263,283,379,505,398,413,455,527,338,482,334,406,255,187,211,119,189,4,182,-16,145,-56,26,-74,-83,-100,-148,-133,-197,-139,-191,-198,-217,-194,-192,-215,-224,-197,-182,-180,-242,-199,-243,-153,-261,-180,-264,-151,-250,-164,-239,-176,-235,-178,-231,-191,-258,-227,-259,-218,-280,-188,-268,-159,-259,-154,-260,-137,-244,-185,-245,-228,-251,-260,-250,-247,-239,-233,-209,-205,-224,-262,-274,-268,-248,-262,-263,-277,-234,-255,-222,-233,-226,-262,-221,-257,-211,-267,-218,-251,-186,-221,-179,-224,-195,-213,-161,-226,-193,-212,-178,-219,-191,-204,-183,-190,-175,-182,-165,-164,-140,-131,-97,-107,-80,-102,-45,-85,-60,-81,-66,-74,-59,-82,-82,-91,-88,-102,-100,-120,-85,-122,-72,-129,-98,-137,-55,-101,-62,-69,-41,-72,-56,-83,-69,-90,-53,-98,-81,-105,-80,-107,-83,-112,-102,-115,-97,-125,-111,-136,-123,-145,-118,-131,-95,-114,-62,-70,-59,-73,-48,-57}, + /* IRC_Composite_C_R0195_T285_P000.wav */ + {-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-3,3,-4,6,-9,19,-100,-184,-163,-233,-161,-194,-211,-190,-252,-368,-121,58,37,-12,35,111,-96,-223,-19,464,559,1425,2382,1927,1709,2204,1586,984,1062,1267,1442,1113,1078,1182,1130,1148,848,575,534,584,541,405,456,300,346,294,405,279,183,240,258,176,160,100,-27,100,-24,93,-139,0,-270,60,-268,20,-249,-123,-250,-178,-127,-185,-84,-288,-109,-237,-116,-161,-179,-137,-193,-134,-189,-164,-211,-174,-211,-244,-187,-259,-227,-263,-160,-220,-206,-234,-213,-214,-205,-225,-212,-266,-182,-254,-229,-238,-166,-272,-223,-282,-263,-305,-287,-272,-261,-288,-239,-247,-227,-247,-224,-236,-226,-259,-230,-256,-220,-217,-226,-224,-232,-214,-225,-205,-261,-251,-252,-219,-235,-230,-230,-236,-236,-209,-203,-226,-221,-222,-180,-160,-190,-161,-159,-154,-156,-97,-111,-129,-127,-107,-66,-95,-69,-92,-64,-55,-64,-43,-78,-65,-103,-71,-87,-110,-101,-114,-93,-117,-90,-112,-88,-109,-72,-82,-69,-68,-63,-65,-90,-69,-67,-77,-62,-56,-47,-91,-59,-73,-34,-101,-70,-91,-61,-105,-91,-128,-154,-149,-128,-150,-140,-142,-93,-111,-108,-78,-62,-77,-59,-62}, + /* IRC_Composite_C_R0195_T300_P000.wav */ + {4,-4,4,-4,4,-4,4,-4,4,-5,5,-5,5,-5,5,-5,5,-6,6,-6,6,-6,6,-7,7,-7,8,-8,8,-9,10,-11,13,-16,24,-75,-192,-243,-206,-121,-200,-413,-335,-275,-203,-85,-38,193,-95,-382,283,-596,-531,1085,630,1024,2620,2194,1518,1499,1392,607,112,846,1164,950,675,1005,1305,1174,1521,1142,1208,859,1074,771,735,552,498,679,274,454,160,457,127,176,172,280,101,64,67,-27,98,11,3,-150,-68,-72,-105,-163,-160,-139,-135,-141,-133,-136,-55,-184,-109,-200,-81,-104,-78,-213,-147,-100,-188,-136,-214,-162,-281,-139,-265,-190,-228,-184,-320,-138,-205,-130,-238,-158,-209,-100,-297,-175,-328,-233,-318,-199,-385,-256,-355,-254,-336,-269,-310,-262,-286,-237,-272,-206,-279,-217,-262,-212,-280,-260,-296,-269,-321,-249,-293,-297,-294,-263,-252,-259,-248,-231,-189,-223,-204,-205,-214,-202,-172,-186,-170,-216,-162,-160,-149,-167,-137,-119,-139,-138,-127,-91,-90,-111,-123,-105,-94,-88,-92,-101,-104,-94,-87,-104,-82,-106,-68,-106,-75,-113,-53,-76,-65,-86,-59,-75,-81,-73,-84,-59,-75,-52,-59,-73,-55,-69,-45,-87,-49,-62,-47,-76,-53,-57,-57,-74,-83,-72,-109,-94,-135,-114,-127,-112,-128,-125,-121,-104,-114,-94,-97,-102,-114,-98,-73,-61,-46,-72}, + /* IRC_Composite_C_R0195_T315_P000.wav */ + {-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-4,4,-4,4,-4,4,-5,5,-5,6,-7,8,-10,14,-29,-234,-230,-266,-204,-305,-247,-524,-359,-150,55,142,71,572,-570,-1004,861,-803,-374,3189,1120,2120,3144,2428,636,1026,1269,59,-187,571,1369,181,332,532,1375,1240,1554,1033,1045,866,1172,1026,1022,606,720,597,671,349,376,201,259,47,222,146,93,-124,20,-35,-174,-23,6,-91,-108,-18,6,38,-2,-118,67,-77,-79,-121,-96,-206,-171,-74,-193,-141,-167,-54,-168,-65,-180,-137,-281,-209,-164,-172,-178,-158,-127,-188,-174,-11,-152,-142,-222,-182,-348,-203,-338,-287,-380,-316,-332,-319,-347,-297,-281,-364,-362,-314,-304,-376,-347,-321,-343,-330,-367,-276,-306,-278,-290,-268,-295,-267,-229,-264,-248,-290,-244,-263,-201,-223,-197,-193,-189,-154,-159,-137,-178,-126,-217,-115,-163,-129,-166,-130,-150,-147,-107,-147,-129,-143,-117,-141,-126,-115,-135,-99,-146,-90,-112,-81,-119,-52,-80,-79,-84,-83,-64,-59,-53,-89,-91,-74,-101,-29,-121,-49,-139,-64,-94,-23,-57,-36,-29,-38,-50,-50,-47,-30,-53,-56,-81,-58,-97,-62,-69,-56,-82,-74,-103,-94,-111,-122,-150,-117,-148,-135,-117,-104,-87,-95,-77,-107,-55,-89,-56,-82,-65,-70,-36,-13}, + /* IRC_Composite_C_R0195_T330_P000.wav */ + {-15,15,-15,15,-15,15,-15,16,-16,16,-16,16,-16,16,-16,16,-16,16,-16,16,-16,15,-15,14,-13,11,-8,5,0,-7,12,-293,-526,-71,-505,-401,-1003,-83,-138,277,-121,450,638,-529,-2538,1974,-1021,-928,6018,1862,2117,4170,3177,-540,80,773,465,-382,760,707,287,-96,895,1260,1490,749,709,1138,1758,1405,855,490,661,833,888,382,366,310,491,203,204,155,246,122,-32,-122,-37,50,94,-114,-242,-173,94,-97,-233,-239,44,3,91,-64,-78,-19,148,9,2,-196,62,-119,-154,-277,128,-102,-103,-182,-189,-136,-49,51,-260,-285,-17,-46,-344,-260,-264,-310,-481,-356,-385,-299,-442,-338,-388,-433,-413,-352,-281,-444,-379,-419,-361,-361,-316,-320,-407,-371,-354,-283,-325,-263,-281,-264,-300,-242,-200,-218,-231,-208,-283,-185,-218,-137,-254,-173,-210,-124,-178,-189,-155,-197,-150,-148,-83,-183,-134,-157,-104,-154,-134,-133,-118,-172,-161,-120,-119,-156,-145,-96,-143,-172,-117,-71,-107,-120,-113,-53,-111,-85,-65,-51,-97,-63,-15,-77,-94,-67,-18,-45,-126,-60,-101,-21,-115,3,-114,-45,-90,-5,-69,-55,-89,-42,-99,-38,-100,-24,-95,-21,-116,-37,-113,-13,-85,-64,-143,-57,-122,-61,-126,-85,-123,-78,-94,-71,-113,-55,-72,-37,-93,-41,-42,-10,-34,-37,-13,-34}, + /* IRC_Composite_C_R0195_T345_P000.wav */ + {-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-2,2,-3,-196,-727,-30,-506,-136,-1125,-612,-692,-135,283,619,802,-51,-2221,1398,-964,-5308,8059,961,2013,8066,4451,-858,1438,1808,-955,-2183,475,1387,742,458,140,184,1030,1768,1316,965,1001,1155,1147,1222,1301,1124,461,289,297,592,383,273,-220,-259,-53,323,264,-32,-200,42,191,421,77,-195,-257,18,-154,-38,-140,-135,-290,-47,107,49,-29,-98,-94,-50,49,264,36,153,-148,86,-24,287,-156,101,-86,125,-186,-182,-278,-236,-501,-636,-484,-401,-330,-428,-463,-554,-283,-366,-318,-494,-441,-375,-318,-358,-465,-416,-438,-337,-400,-344,-393,-247,-308,-313,-356,-181,-229,-204,-374,-214,-320,-200,-307,-179,-339,-189,-252,-152,-246,-143,-210,-166,-196,-69,-139,-172,-216,-103,-73,-127,-214,-116,-118,-96,-247,-135,-187,-78,-264,-166,-235,-95,-173,-142,-167,-169,-129,-117,-114,-125,-125,-103,-137,-47,-110,-26,-121,-21,-72,-15,-71,-68,-34,-53,-38,-72,-96,-96,-90,-11,-126,-33,-166,-22,-92,18,-75,-35,-69,-60,-67,-82,-72,-61,-96,-68,-103,-26,-100,-19,-108,0,-110,-34,-106,-39,-54,-75,-76,-83,-35,-42,-69,-51,-59,-38,-55,19,-49,-3,-43,27,-14,-5,-46,-24}}; + +const int16_t irc_composite_c_r0195_p015[][256] = + {/* IRC_Composite_C_R0195_T000_P015.wav */ + {4,-4,4,-4,4,-4,4,-4,4,-4,4,-5,5,-5,4,-4,4,-4,3,-2,1,2,-5,-101,-665,-424,-897,-170,-507,-460,-1001,-828,-356,47,474,980,404,2103,-3700,-5968,7765,-9133,9741,10867,71,6925,3456,-1455,-2458,2718,-170,-1201,-1751,1809,507,632,-1165,1945,1684,1705,-450,1152,360,1527,269,952,644,931,727,1576,725,835,741,915,186,162,327,384,20,24,-311,60,225,484,-123,-28,-210,118,15,76,-335,-153,-249,49,-120,24,-200,-169,-213,-175,-235,-158,-280,-399,-410,-304,-104,-355,-319,-311,-79,-366,-75,-79,-120,-487,147,-42,-198,-175,135,-242,55,233,123,-314,-58,-179,-96,-352,-26,7,11,-105,-129,125,-110,-293,-276,-461,-507,-406,-422,-497,-481,-446,-459,-325,-336,-443,-420,-320,-391,-360,-309,-407,-375,-288,-289,-385,-315,-272,-292,-271,-256,-318,-173,-220,-185,-329,-142,-239,-76,-219,-117,-277,-107,-204,-117,-233,-199,-220,-177,-238,-171,-170,-187,-285,-154,-168,-145,-192,-131,-239,-194,-170,-109,-205,-155,-164,-163,-187,-126,-85,-138,-195,-140,-189,-84,-134,-22,-177,-51,-128,-26,-105,26,-144,-65,-123,-28,-136,19,-69,-43,-112,40,-43,59,-67,32,-35,97,-21,99,-27,90,23,141,21,38,39,61,12,10,-1,37,-3,7,2,41,-19,-12,-12,16,-53}, + /* IRC_Composite_C_R0195_T015_P015.wav */ + {100,-101,102,-102,102,-102,102,-102,101,-99,96,-93,88,-81,71,-58,37,-6,-46,154,-587,-280,-52,-712,-530,-842,-228,-637,-217,-1535,-463,274,2688,1298,-390,-2760,4349,-16532,13572,-2117,2580,22789,-850,559,1346,2618,-4202,397,316,686,-1654,1356,-848,1484,164,1873,376,1720,39,1069,309,1623,748,807,488,1192,547,1364,679,594,48,334,-179,362,98,-149,-587,-275,-81,371,-430,-372,-369,412,-126,-39,-294,169,-117,61,-209,-100,-271,-40,-262,-244,-406,12,-243,-253,-484,54,-243,-283,-575,-138,-358,-262,-307,-61,-567,-206,25,51,-696,-10,-132,-245,-388,187,-132,-194,-316,-92,-71,-291,-374,27,-295,-84,-4,145,-576,122,-217,-153,-724,53,-337,-126,-502,-305,-401,-138,-372,-296,-502,-318,-375,-140,-645,-283,-375,-217,-529,-172,-316,-324,-287,-239,-309,-305,-230,-228,-310,-332,-289,-168,-302,-286,-241,-197,-266,-181,-156,-260,-272,-185,-148,-225,-221,-239,-178,-223,-142,-203,-226,-260,-124,-148,-200,-259,-124,-203,-182,-207,-78,-186,-163,-136,-74,-179,-123,-45,-87,-180,-103,-28,-117,-135,-64,-29,-148,-90,-13,-28,-111,-40,7,-42,-98,-26,-4,-57,-22,22,-38,-72,76,67,1,-21,80,49,39,63,66,26,23,62,97,29,39,49,28,-1,52,74,-6,-4,19,15,-15,-12,17,-50}, + /* IRC_Composite_C_R0195_T030_P015.wav */ + {-101,102,-103,105,-105,106,-106,106,-104,102,-97,90,-79,62,-35,-12,109,-431,-649,311,-951,117,-1193,10,-1439,943,-1996,57,-1866,3892,-160,3817,-4940,7695,-14389,320,6811,-6312,29122,1548,2820,2754,2735,-5703,-20,838,313,-2387,2394,-1371,1731,262,1937,34,1456,-294,1713,221,997,660,1535,549,1179,928,928,293,321,-76,273,-164,-356,-622,24,-278,-26,-520,-116,-436,-61,-412,-21,-436,-263,-534,-25,-24,127,-328,-77,-189,107,-200,-313,-487,-278,-245,-413,-269,-216,-100,-434,-149,-238,-270,-527,-94,-144,-244,-529,-94,-120,-125,-544,-205,-477,-214,-375,-52,-404,-184,-361,-14,-189,-53,-346,-89,-276,-127,-233,-126,-417,-169,-225,-263,-470,-227,-238,-276,-329,-339,-304,-226,-209,-212,-255,-261,-275,-96,-168,-289,-298,-134,-296,-334,-291,-248,-272,-268,-362,-278,-286,-108,-360,-215,-330,-76,-394,-179,-365,-104,-449,-206,-420,-128,-409,-167,-434,-175,-416,-105,-318,-125,-408,-157,-270,-45,-277,-160,-326,-56,-220,-114,-280,-69,-199,-100,-242,-24,-143,-39,-214,3,-104,20,-184,20,-140,-7,-183,31,-135,-21,-164,13,-128,42,-188,49,-113,71,-189,90,-97,102,-87,84,-61,147,-63,149,-94,170,-108,183,-108,208,-150,179,-163,250,-98,215,-137,235,-107,214,-135,246,-126,201,-171,186,-149,135,-194,121}, + /* IRC_Composite_C_R0195_T045_P015.wav */ + {-146,153,-161,170,-179,189,-200,212,-224,238,-252,266,-278,280,-241,-262,-1208,369,-877,618,-1865,344,-1624,1098,-2418,1166,-2204,3338,-287,6351,-5670,4490,-9471,-5595,10415,-3658,26422,6163,571,640,3020,-3458,345,262,-17,-2379,1504,-915,2155,96,1778,-36,1408,800,1533,117,618,355,1940,474,1443,116,436,-13,320,-248,-589,-590,-422,-164,-365,-343,-251,-474,20,-343,-59,-619,-421,-460,-72,-443,-399,-435,-238,-311,-325,-256,-210,-285,-282,-222,-283,-212,-374,-178,-386,-213,-343,-35,-317,-276,-390,-79,-244,-300,-445,-222,-296,-233,-458,-263,-403,-259,-462,-188,-423,-283,-371,-78,-225,-208,-380,-203,-156,-140,-307,-202,-208,-86,-293,-179,-233,-185,-390,-305,-381,-170,-416,-344,-426,-229,-331,-201,-370,-183,-273,-88,-257,-116,-206,-60,-298,-72,-233,-115,-304,-131,-336,-187,-271,-44,-375,-190,-355,-35,-321,-189,-400,-136,-365,-198,-383,-200,-395,-244,-401,-188,-398,-184,-393,-179,-365,-150,-314,-118,-327,-118,-291,-73,-272,-87,-247,-52,-258,-27,-226,25,-210,8,-202,51,-136,62,-162,35,-135,61,-156,-12,-167,55,-165,15,-174,47,-131,28,-125,76,-91,69,-71,126,-60,104,-40,141,-51,117,-33,141,-58,103,-38,158,-48,95,-52,149,-45,86,-47,120,-68,88,-39,116,-45,74,-35,89,-68,62,-90,53}, + /* IRC_Composite_C_R0195_T060_P015.wav */ + {29,-34,39,-45,52,-59,69,-80,93,-110,131,-160,205,-308,-459,-920,-171,388,-674,-719,-1064,350,-1149,552,-1891,2109,-28,5773,-3032,5413,-11840,194,-1388,1646,23561,8535,2547,1107,-66,257,913,517,-131,-1162,-856,344,2136,-879,1332,-592,2048,385,1977,174,2217,-131,2091,-69,1390,-1343,963,-905,515,-1176,-81,-1557,250,-301,-119,-467,-479,-337,138,-523,-373,-525,-22,-558,-74,-857,-193,-765,-208,-1034,-15,-947,-96,-803,45,-665,15,-523,-1,-312,49,-446,-141,-311,-126,-246,-344,-467,-27,-388,-328,-427,-198,-495,-118,-356,-277,-493,-134,-525,-71,-411,-262,-445,-175,-367,-96,-400,-267,-383,-49,-313,-260,-205,-179,-166,-56,-272,-194,-146,-166,-310,-204,-405,-207,-321,-211,-468,-223,-383,-150,-326,-281,-312,-146,-220,-208,-241,-286,-189,-157,-134,-243,-213,-136,-145,-92,-188,-205,-244,-73,-253,-131,-321,-224,-277,-194,-364,-238,-342,-254,-284,-301,-272,-246,-239,-245,-226,-236,-207,-220,-191,-251,-189,-226,-188,-154,-195,-171,-163,-122,-121,-97,-111,-91,-108,-20,-120,-59,-33,-136,-42,-55,-62,-49,-97,-100,16,-97,-13,-104,7,-74,-20,-54,27,-6,45,-12,56,35,24,86,33,48,24,68,72,-3,50,22,52,12,43,-32,109,-68,106,-66,49,-61,102,-74,44,-72,28,-60,21,-71,-4,-76,16}, + /* IRC_Composite_C_R0195_T075_P015.wav */ + {19,-16,12,-7,2,4,-11,18,-27,36,-47,59,-68,37,-553,36,-916,-89,-13,-916,-389,-1224,572,-284,1453,853,1354,3254,1573,-10498,-1005,-5881,20609,10333,4130,9878,-3085,-1702,1001,5191,773,-2104,-1269,-41,1645,-349,309,387,447,1304,620,1533,360,1697,867,1545,-94,149,-359,473,-1422,-432,-1225,-246,-886,186,-914,-144,-892,309,-602,60,-603,-112,-520,-150,-750,-486,-681,-262,-736,-448,-1017,-103,-734,-305,-903,-61,-752,39,-644,-19,-565,33,-324,-70,-458,-205,-229,-182,-403,-322,-245,-211,-302,-350,-295,-222,-298,-293,-385,-263,-357,-235,-379,-252,-470,-139,-429,-84,-457,-178,-385,-120,-380,-232,-339,-192,-273,-205,-196,-146,-164,-174,-129,-218,-203,-145,-229,-290,-273,-262,-283,-222,-302,-215,-314,-150,-291,-151,-311,-154,-281,-177,-260,-179,-190,-177,-222,-159,-209,-215,-215,-185,-191,-224,-214,-221,-182,-209,-269,-260,-254,-234,-284,-241,-293,-201,-269,-218,-264,-188,-203,-199,-218,-207,-118,-151,-146,-184,-126,-92,-92,-129,-108,-109,-42,-120,-57,-144,-45,-102,-23,-164,-63,-98,-36,-106,-81,-3,-74,-55,-79,-49,-60,-59,-60,-31,-36,-35,57,-37,99,-7,135,-26,115,14,154,-6,78,28,119,-3,53,-48,80,-38,55,-56,13,-65,74,-45,19,-79,50,-39,24,-95,40,-41,15,-61,55,-129}, + /* IRC_Composite_C_R0195_T090_P015.wav */ + {106,-108,111,-113,116,-119,121,-123,125,-125,121,-102,-150,-386,-21,-846,-117,203,-762,-759,-425,-20,26,535,183,3678,866,180,877,-12284,4742,-888,21444,10158,-2546,4612,-145,-630,3778,3819,1940,-4361,-1372,2229,1116,-1596,-423,1713,840,536,1040,2123,618,888,-302,898,-618,52,-845,240,-1279,-435,-1143,105,-929,-50,-1077,-180,-541,98,-930,-161,-671,-158,-656,-338,-774,-263,-620,-260,-792,-238,-787,-172,-874,-235,-797,-199,-767,-178,-702,-101,-607,-63,-479,-72,-504,-49,-400,-118,-387,-113,-404,-73,-442,-100,-429,-15,-496,-79,-480,-58,-494,-80,-498,-112,-411,-138,-447,-136,-406,-145,-485,-166,-440,-131,-485,-87,-417,-104,-413,-102,-426,-31,-350,-62,-299,27,-272,-36,-302,-22,-320,-120,-364,-124,-307,-111,-382,-185,-231,-108,-275,-163,-225,-123,-157,-158,-254,-183,-208,-146,-274,-183,-229,-148,-301,-148,-275,-212,-388,-177,-304,-193,-358,-180,-265,-195,-243,-171,-184,-212,-200,-212,-156,-173,-149,-232,-145,-162,-100,-147,-119,-102,-57,-53,-87,-18,-36,-11,-87,-46,-46,17,-89,-82,-57,6,-100,-61,-101,-38,-60,-46,-108,-40,-41,19,-104,-21,-14,77,-24,51,22,136,25,103,19,102,3,92,-42,26,-51,25,-38,-15,-65,-12,-35,-8,28,24,-31,-1,36,92,2,6,8,52,-33,-7,-25,-27}, + /* IRC_Composite_C_R0195_T105_P015.wav */ + {16,-19,23,-28,34,-40,48,-57,68,-82,100,-121,33,-823,199,-561,-96,-481,741,-1752,-67,-480,1840,-966,591,1601,5280,-3652,770,-7901,214,10553,2446,18816,1377,-3359,-1411,6633,5595,-115,-232,1823,-2575,-717,-242,2719,-2255,509,511,2747,225,1585,549,951,-478,-34,-731,-13,-1246,-512,-881,-341,-1127,207,-442,-495,-702,-517,-566,35,-620,-983,-450,-179,-571,-441,-658,-297,-211,-340,-730,-514,-334,-479,-562,-662,-463,-524,-336,-537,-522,-336,-226,-483,-343,-332,-364,-181,-306,-365,-271,-175,-316,-213,-283,-326,-115,-221,-216,-290,-146,-290,-98,-334,-301,-279,-138,-349,-278,-318,-250,-285,-237,-388,-326,-257,-206,-416,-256,-293,-207,-350,-156,-397,-149,-314,-125,-323,-153,-327,-64,-258,-145,-241,-10,-249,-51,-197,-108,-234,33,-286,-138,-267,-26,-273,-117,-347,-77,-229,-117,-301,-119,-229,-104,-247,-175,-311,-162,-227,-248,-287,-181,-293,-170,-318,-206,-285,-159,-334,-167,-232,-161,-235,-76,-246,-154,-204,-10,-221,-106,-229,14,-182,-12,-251,30,-154,32,-190,61,-152,90,-145,48,-122,71,-96,29,-121,6,-57,66,-80,40,-49,59,-112,-8,-129,54,-18,76,-21,97,37,171,23,59,-61,75,-37,21,-127,1,-154,68,-112,-12,-180,86,-58,91,-120,128,-28,129,-100,167,-17,106,-84,94,-49,76,-37}, + /* IRC_Composite_C_R0195_T120_P015.wav */ + {39,-39,39,-39,39,-38,38,-37,35,-32,27,-19,0,-223,40,-675,329,-841,457,-348,-274,-1647,1770,432,-494,3,4260,289,887,-4454,-3947,7446,-2378,15614,7773,95,-2028,2409,7171,2953,950,1439,-1677,-1118,-1770,1575,491,137,-1226,1181,2451,1325,-149,862,100,-196,-613,-302,-1148,-1325,-632,-731,-1011,-688,174,-67,-430,-378,-168,-383,-445,-570,-934,-576,-71,-333,-939,-576,-180,-299,-551,-542,-536,-312,-421,-506,-398,-463,-360,-423,-342,-463,-390,-485,-299,-416,-291,-519,-227,-313,-272,-376,-199,-241,-176,-354,-259,-245,-94,-289,-288,-266,-79,-203,-210,-332,-200,-224,-227,-331,-258,-315,-219,-293,-232,-358,-231,-306,-201,-298,-234,-413,-216,-295,-220,-417,-228,-272,-126,-326,-197,-254,-104,-275,-161,-280,-75,-215,-110,-276,-33,-130,-19,-261,-8,-171,30,-242,-55,-229,-65,-254,-74,-218,-134,-301,-99,-211,-155,-300,-156,-234,-131,-322,-164,-311,-142,-349,-229,-334,-148,-297,-165,-289,-133,-215,-100,-254,-101,-185,-51,-234,-38,-186,-6,-168,0,-111,-29,-125,29,-96,-23,-153,22,-59,-32,-103,28,-118,11,-64,83,-103,41,-112,28,-109,99,-41,39,-86,157,43,121,-15,157,-11,121,-30,90,-113,25,-109,38,-172,-47,-151,15,-102,21,-97,16,-33,104,12,59,-55,121,-5,63,-116,114,-30,115,-85}, + /* IRC_Composite_C_R0195_T135_P015.wav */ + {15,-17,19,-21,24,-28,32,-37,43,-50,60,-73,90,-115,157,-297,361,-673,287,-116,-598,-544,1021,-902,-263,1113,1563,-848,3395,810,-1816,-1445,-4755,10984,3295,5362,6262,2589,-529,1444,7698,4758,-2233,-2138,-1622,980,-226,100,-517,871,952,682,983,1138,-542,-341,-164,-377,-526,-992,-910,-828,-413,-830,-380,-392,-124,-316,-225,-315,-25,-678,-691,-468,-412,-545,-395,-676,-301,-467,-356,-548,-300,-516,-260,-553,-295,-485,-232,-525,-220,-421,-217,-488,-227,-455,-268,-426,-269,-474,-232,-395,-199,-378,-219,-372,-176,-401,-202,-354,-114,-340,-124,-267,-86,-322,-166,-298,-181,-316,-179,-307,-163,-290,-175,-321,-186,-325,-234,-372,-200,-335,-202,-352,-199,-268,-180,-319,-236,-296,-200,-331,-209,-300,-142,-273,-118,-226,-91,-203,-97,-250,-91,-176,-72,-201,-65,-156,-22,-171,-59,-200,-36,-210,-93,-201,-48,-197,-73,-185,-73,-195,-95,-266,-166,-294,-169,-299,-216,-315,-187,-265,-167,-287,-146,-275,-175,-265,-144,-282,-127,-249,-66,-222,-39,-146,-32,-126,-20,-76,5,-92,18,-56,21,-91,13,-119,-23,-127,37,-71,16,-116,10,-105,12,-96,55,-69,43,-76,137,-20,86,-3,123,28,100,8,49,-58,60,-31,-10,-117,-15,-44,-19,-89,2,-51,-18,-51,62,-39,31,-46,59,-59,67,-57,112,-72,62,-22}, + /* IRC_Composite_C_R0195_T150_P015.wav */ + {22,-23,24,-24,25,-26,27,-27,28,-28,28,-28,26,-24,19,-9,-13,134,-205,5,10,-146,-122,-75,-78,-152,345,-100,1711,198,1882,367,2730,-6333,870,5933,2367,6468,4276,4587,970,719,5822,3692,-1207,-2971,-1058,797,482,-202,-740,507,536,875,480,668,-204,-211,-690,500,-1107,-874,-841,-223,-910,-122,-465,-407,-494,-192,-244,-202,-337,-294,-451,-519,-512,-353,-580,-345,-407,-307,-608,-176,-450,-303,-475,-205,-453,-277,-342,-237,-284,-212,-314,-272,-380,-283,-368,-307,-417,-297,-337,-321,-374,-329,-283,-379,-283,-310,-317,-249,-232,-217,-269,-190,-252,-183,-270,-238,-227,-187,-286,-191,-260,-230,-245,-233,-289,-230,-246,-218,-241,-208,-260,-204,-276,-211,-286,-243,-284,-211,-281,-227,-258,-199,-238,-185,-241,-133,-220,-133,-189,-80,-190,-65,-146,-88,-167,-80,-129,-110,-166,-124,-142,-139,-178,-111,-146,-116,-143,-102,-118,-138,-137,-152,-173,-190,-174,-190,-193,-230,-208,-208,-216,-246,-203,-231,-209,-216,-167,-210,-170,-158,-128,-148,-142,-127,-104,-88,-98,-82,-75,-58,-53,-46,-85,-53,-56,-1,-14,17,-80,-58,-41,-57,-6,-70,6,-78,37,-14,58,10,69,35,20,45,42,27,3,3,-29,-5,-10,26,-54,-21,-21,39,-58,-58,-23,10,-16,-35,6,-22,2,-8,54,-13,7,-2,51,6}, + /* IRC_Composite_C_R0195_T165_P015.wav */ + {20,-21,21,-22,23,-23,24,-25,26,-26,27,-28,29,-29,30,-30,29,-28,22,-5,163,-209,156,-276,329,-325,157,-151,120,93,1138,522,872,2060,255,503,-4749,3937,3841,3248,5654,4851,3110,1024,1230,4380,981,-2433,-2102,345,461,292,-696,50,937,951,-195,227,100,-111,-682,-242,-295,-695,-542,-371,-167,-471,-237,-441,-313,-257,-355,-428,-338,-330,-347,-256,-340,-455,-298,-395,-419,-365,-319,-336,-313,-224,-306,-223,-245,-277,-258,-289,-268,-318,-289,-331,-299,-363,-319,-390,-363,-384,-327,-342,-339,-372,-297,-284,-259,-319,-264,-296,-233,-297,-258,-289,-255,-235,-239,-231,-238,-221,-219,-255,-237,-261,-205,-265,-219,-253,-180,-250,-196,-250,-200,-248,-207,-278,-194,-276,-219,-261,-199,-283,-219,-241,-187,-217,-180,-196,-141,-180,-121,-175,-110,-181,-79,-171,-84,-195,-62,-164,-99,-185,-115,-180,-164,-155,-140,-152,-147,-164,-113,-154,-117,-178,-132,-201,-137,-183,-162,-227,-171,-200,-151,-199,-165,-161,-150,-178,-144,-157,-158,-179,-144,-176,-163,-168,-98,-168,-122,-152,-52,-148,-86,-125,-9,-56,-37,-107,-79,-44,-26,-30,-92,-55,-14,29,14,24,62,67,48,30,48,10,57,-9,40,-55,25,-77,17,-96,25,-64,21,-101,-1,4,58,-21,25,24,70,3,30,9,36,-16,6,-21,-39,-15}, + /* IRC_Composite_C_R0195_T180_P015.wav */ + {-9,9,-9,9,-10,10,-10,10,-11,11,-11,11,-12,12,-13,13,-14,15,-15,16,-17,19,-21,50,-66,25,121,28,-120,155,-168,335,416,671,222,2210,806,1236,-2882,612,2593,898,4860,6139,4465,870,-196,3886,2840,-2197,-1283,-67,115,-435,2,221,731,-37,-52,179,744,-513,-450,-510,328,-437,-225,-503,1,-204,-76,-530,-331,-379,-166,-435,-279,-284,-151,-266,-225,-384,-293,-305,-154,-293,-219,-273,-134,-244,-264,-371,-311,-317,-245,-345,-336,-343,-237,-329,-370,-441,-342,-336,-321,-387,-336,-319,-260,-281,-304,-299,-268,-249,-331,-318,-306,-253,-254,-267,-280,-263,-244,-262,-278,-297,-251,-213,-235,-246,-260,-197,-223,-206,-272,-188,-228,-176,-268,-213,-279,-202,-229,-233,-258,-216,-166,-186,-223,-208,-202,-136,-198,-161,-225,-147,-174,-123,-192,-165,-169,-119,-164,-157,-169,-110,-156,-134,-190,-131,-196,-117,-175,-127,-176,-95,-111,-96,-149,-112,-153,-144,-212,-161,-218,-171,-217,-170,-191,-155,-154,-114,-156,-141,-134,-77,-145,-152,-168,-124,-167,-164,-158,-156,-173,-143,-139,-75,-112,-48,-151,-85,-139,-30,-81,-70,-106,-105,-40,-41,29,15,57,54,103,128,65,65,35,45,-4,-23,-56,-53,-39,-44,-11,-66,11,-23,53,-3,44,26,45,23,36,66,32,13,3,39,11,-14,8,-12}, + /* IRC_Composite_C_R0195_T195_P015.wav */ + {3,-3,4,-4,4,-5,5,-5,6,-6,7,-7,8,-9,9,-10,11,-13,14,-16,19,-22,27,-33,44,-87,114,-132,102,-154,155,-97,-20,-37,-29,363,412,474,853,1336,1092,-788,-1724,2098,1099,2640,4844,4905,2895,-39,1681,2632,175,-1400,-248,325,22,-206,196,419,561,41,192,277,401,-173,2,-114,106,-178,-24,-176,30,-91,54,-173,-183,-124,-65,-136,-127,-106,-163,-59,-115,-115,-267,-191,-291,-145,-314,-229,-397,-205,-300,-229,-373,-215,-360,-218,-346,-234,-397,-220,-360,-257,-382,-254,-389,-213,-322,-234,-324,-214,-345,-227,-381,-255,-363,-174,-354,-207,-318,-230,-299,-263,-316,-271,-243,-219,-239,-195,-263,-183,-262,-181,-310,-210,-258,-227,-229,-243,-215,-263,-194,-269,-182,-235,-184,-209,-147,-196,-148,-196,-147,-207,-155,-221,-187,-223,-184,-221,-208,-205,-186,-173,-165,-148,-132,-141,-127,-151,-120,-154,-131,-136,-104,-119,-115,-117,-108,-145,-140,-188,-146,-212,-174,-199,-183,-203,-176,-190,-174,-178,-155,-183,-156,-192,-139,-178,-158,-185,-162,-172,-198,-158,-136,-126,-116,-127,-125,-157,-109,-154,-85,-152,-60,-135,-26,-117,10,-26,16,-15,36,69,64,91,41,52,-5,31,-40,-16,-60,-3,-25,-20,-13,18,23,6,15,15,42,21,45,37,32,17,30,46,26,13,23,-19}, + /* IRC_Composite_C_R0195_T210_P015.wav */ + {5,-5,6,-6,6,-6,6,-6,6,-6,7,-7,7,-7,7,-8,8,-8,8,-9,9,-9,9,-9,9,-9,7,-1,-45,-76,21,-111,31,-35,-9,-141,17,-81,104,351,414,314,1167,1284,-698,-334,-392,1578,2039,2332,5286,3230,840,735,2013,886,-250,-668,388,293,-154,194,485,539,373,247,362,554,379,14,200,206,243,111,161,197,127,193,183,265,-4,123,-60,64,-188,-26,-316,-89,-293,-150,-287,-153,-256,-136,-244,-221,-246,-144,-274,-195,-276,-224,-307,-223,-340,-289,-302,-287,-323,-301,-317,-303,-243,-292,-298,-294,-312,-280,-306,-243,-309,-226,-276,-214,-262,-251,-287,-252,-261,-239,-268,-241,-251,-220,-263,-226,-289,-222,-266,-235,-299,-243,-268,-249,-232,-227,-224,-212,-188,-201,-205,-192,-215,-147,-197,-162,-188,-158,-182,-181,-170,-210,-185,-204,-179,-201,-174,-187,-176,-157,-173,-157,-158,-147,-138,-131,-123,-128,-126,-106,-147,-126,-173,-126,-184,-147,-199,-168,-203,-173,-188,-192,-200,-201,-192,-187,-199,-212,-196,-185,-179,-192,-178,-197,-173,-188,-148,-169,-132,-157,-149,-165,-140,-138,-136,-123,-135,-83,-122,-54,-79,-22,-60,-30,-15,-6,29,-8,28,-22,45,-13,39,-33,30,5,20,-21,0,10,30,-5,10,-9,35,17,55,16,50,34,50,43,21,55,18,41}, + /* IRC_Composite_C_R0195_T225_P015.wav */ + {3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-2,2,-2,2,-1,1,0,-5,-60,-132,-64,-20,-85,-7,-176,-5,-52,-74,-72,84,430,320,474,759,338,-353,-244,418,1855,1977,2351,3573,2234,1049,638,1145,830,98,-47,162,541,334,496,426,623,595,701,586,611,652,468,517,289,478,320,343,117,277,121,176,-24,22,-90,-30,-74,-66,-98,-115,-117,-110,-81,-130,-60,-133,-100,-189,-113,-212,-176,-266,-224,-323,-264,-344,-286,-346,-280,-345,-296,-322,-294,-296,-283,-287,-282,-269,-247,-271,-247,-275,-227,-292,-244,-283,-265,-275,-259,-269,-255,-263,-256,-260,-233,-264,-234,-273,-263,-267,-260,-261,-252,-268,-235,-241,-202,-245,-183,-233,-168,-240,-165,-221,-162,-203,-155,-192,-162,-177,-157,-183,-162,-190,-153,-205,-157,-215,-152,-221,-147,-199,-142,-182,-144,-171,-142,-156,-148,-173,-154,-163,-157,-167,-170,-162,-167,-179,-174,-184,-178,-180,-174,-206,-178,-198,-188,-207,-204,-201,-199,-190,-214,-206,-229,-200,-212,-173,-192,-170,-215,-166,-189,-131,-174,-137,-168,-105,-105,-64,-83,-43,-48,2,-25,-6,-28,14,-21,8,-16,16,3,33,17,37,28,49,34,62,28,60,13,34,6,35,-8,13,-2,6,11,8,6,-3,12}, + /* IRC_Composite_C_R0195_T240_P015.wav */ + {0,0,0,0,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,2,-2,2,-2,2,-2,3,-3,3,-4,4,-5,6,-7,9,-12,19,-47,-65,-42,-103,-56,-86,-61,-84,-136,-84,-125,-76,46,139,205,243,514,311,-296,-329,431,1034,1553,1739,2266,2575,1097,709,1340,1199,680,407,592,719,747,950,891,924,905,835,742,679,646,246,443,284,396,76,270,79,360,141,234,132,176,91,44,66,-33,37,-24,-26,-52,-140,-134,-171,-129,-209,-205,-236,-225,-189,-236,-238,-284,-228,-319,-232,-313,-237,-314,-261,-304,-270,-301,-338,-291,-284,-273,-275,-283,-246,-253,-222,-299,-253,-305,-231,-286,-251,-299,-224,-259,-244,-287,-247,-273,-229,-277,-233,-278,-222,-256,-210,-244,-213,-226,-197,-200,-180,-187,-177,-191,-166,-184,-157,-198,-181,-196,-166,-179,-163,-184,-173,-192,-155,-187,-160,-198,-161,-183,-151,-173,-150,-191,-183,-210,-175,-205,-187,-208,-163,-185,-168,-170,-162,-180,-159,-180,-156,-158,-160,-186,-181,-225,-214,-217,-218,-234,-238,-231,-223,-221,-238,-230,-217,-206,-178,-170,-207,-185,-183,-154,-152,-154,-148,-132,-105,-76,-64,-31,-49,-9,-20,6,-12,13,19,25,27,32,34,31,31,36,25,9,26,16,20,-7,0,-5,22,12,4,3,18,14,9,-1,-12,-43}, + /* IRC_Composite_C_R0195_T255_P015.wav */ + {1,-1,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,3,-3,3,-3,3,-4,5,-6,10,-30,-120,-103,-93,-24,-84,-108,-106,-140,-67,-76,-73,-121,-133,-119,68,29,241,313,294,61,72,517,913,1238,1676,2099,2348,2019,1198,861,1666,1655,972,1040,933,753,835,866,579,456,471,608,472,520,250,352,304,298,249,242,223,199,145,120,235,93,122,49,3,-39,-15,-81,-71,-213,-81,-243,-130,-266,-181,-248,-213,-210,-258,-180,-292,-166,-311,-258,-301,-258,-288,-304,-246,-283,-255,-296,-284,-260,-336,-252,-351,-234,-370,-214,-328,-219,-303,-234,-296,-242,-261,-235,-272,-252,-263,-194,-230,-174,-222,-179,-253,-165,-264,-178,-236,-165,-217,-158,-210,-155,-187,-164,-190,-169,-218,-178,-196,-162,-199,-188,-233,-170,-224,-161,-189,-146,-207,-166,-198,-168,-188,-182,-169,-203,-189,-199,-180,-192,-203,-183,-200,-212,-208,-215,-216,-240,-188,-209,-178,-223,-162,-198,-167,-209,-211,-239,-196,-203,-168,-214,-197,-239,-145,-209,-149,-231,-167,-214,-131,-185,-129,-161,-129,-137,-105,-119,-97,-124,-84,-109,-56,-30,29,13,51,35,66,39,42,23,8,-3,12,8,29,13,32,3,26,10,21,-16,-7,-1,7,2,-5,-3,-3,-1}, + /* IRC_Composite_C_R0195_T270_P015.wav */ + {-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-2,2,-2,3,-5,38,41,81,155,185,109,43,168,195,276,233,321,381,601,818,813,1005,694,582,706,813,1380,2408,2859,3417,3192,1234,164,601,379,145,-151,-609,-543,-195,49,-120,-111,136,61,-67,-105,-152,-114,-346,-267,-397,-310,-240,-454,-334,-493,-338,-595,-418,-579,-472,-506,-514,-489,-592,-416,-592,-471,-574,-491,-531,-515,-529,-526,-514,-446,-512,-519,-497,-434,-454,-430,-467,-415,-434,-400,-422,-405,-387,-422,-391,-428,-343,-360,-326,-389,-310,-335,-241,-318,-246,-341,-202,-264,-207,-278,-221,-234,-239,-210,-224,-186,-240,-226,-220,-207,-184,-222,-220,-245,-206,-189,-231,-234,-238,-195,-237,-129,-227,-188,-216,-145,-224,-225,-241,-252,-274,-214,-216,-202,-212,-164,-190,-171,-187,-134,-175,-141,-168,-164,-167,-150,-174,-138,-128,-101,-135,-76,-112,-70,-116,-70,-102,-92,-120,-98,-123,-112,-146,-92,-145,-88,-135,-96,-115,-84,-87,-67,-61,-82,-42,-48,11,-13,5,25,35,52,70,95,98,101,116,108,116,94,137,109,102,83,89,88,89,64,59,40,43,14,53,3,16,-3,7,12,-13,16,-2,28,6,37,18}, + /* IRC_Composite_C_R0195_T285_P015.wav */ + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,-1,1,-1,1,-1,2,-3,6,-109,-159,-182,-252,-225,-252,-209,-220,-323,-249,-123,27,108,237,39,-227,-176,-141,26,983,1563,1989,2256,2042,1443,1643,1525,1088,1602,1474,1170,1150,824,708,924,1176,1036,269,443,781,769,425,308,405,367,433,461,448,234,194,163,218,246,100,-62,56,-52,109,-114,68,-271,33,-231,-10,-251,-107,-211,-189,-193,-271,-173,-258,-220,-344,-246,-222,-245,-241,-310,-276,-282,-207,-275,-244,-325,-317,-257,-224,-252,-269,-249,-255,-262,-227,-233,-233,-271,-256,-189,-188,-164,-249,-173,-198,-150,-210,-124,-172,-127,-154,-156,-239,-193,-248,-200,-220,-169,-212,-123,-176,-157,-249,-249,-297,-272,-295,-303,-316,-296,-263,-235,-217,-173,-234,-208,-250,-182,-255,-227,-234,-247,-244,-205,-187,-219,-199,-160,-156,-146,-178,-163,-199,-166,-183,-164,-214,-208,-196,-160,-168,-196,-193,-160,-204,-162,-188,-175,-206,-218,-198,-177,-203,-194,-169,-169,-172,-168,-160,-149,-149,-113,-128,-93,-92,-23,-69,-13,-56,-10,-44,8,-28,9,-21,0,13,41,16,24,3,43,28,54,11,12,-13,29,-17,4,-27,25,-15,29,-5,31,21,23}, + /* IRC_Composite_C_R0195_T300_P015.wav */ + {3,-3,3,-3,3,-3,3,-3,4,-4,4,-4,4,-4,4,-4,4,-4,5,-5,5,-5,5,-6,6,-6,6,-7,7,-8,9,-10,13,-17,28,-93,-234,-180,-207,-251,-293,-262,-250,-346,-376,-130,67,-6,108,-151,-710,-124,223,55,1941,2161,1520,2079,1404,552,750,680,497,384,1277,1177,733,896,1394,1657,1268,1283,1309,1208,892,805,954,655,670,296,482,320,570,596,507,445,118,348,106,469,16,25,-157,191,5,47,-157,-78,-270,-124,-129,-61,-219,-206,-188,-118,-157,-193,-216,-244,-222,-155,-190,-248,-263,-189,-260,-255,-305,-285,-272,-179,-250,-320,-353,-177,-207,-158,-311,-279,-294,-136,-181,-176,-231,-183,-184,-86,-72,-138,-172,-154,-185,-208,-132,-194,-245,-197,-155,-169,-170,-257,-250,-273,-291,-308,-267,-292,-322,-261,-262,-223,-282,-280,-302,-284,-249,-260,-293,-276,-203,-199,-209,-219,-251,-230,-225,-236,-239,-254,-234,-253,-179,-216,-170,-211,-150,-212,-180,-190,-146,-198,-192,-173,-159,-174,-166,-187,-188,-211,-146,-166,-163,-201,-184,-171,-129,-130,-154,-144,-145,-167,-132,-161,-149,-160,-132,-127,-113,-104,-89,-73,-95,-76,-83,-55,-53,-22,-5,-13,-3,5,22,0,15,5,-11,-15,15,-13,-5,-8,7,-15,26,37,33,12,52,50,45,34,80,35,79,31}, + /* IRC_Composite_C_R0195_T315_P015.wav */ + {-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,2,-2,2,-3,-145,-419,-273,-234,-320,-494,-368,-332,-137,23,435,141,-274,189,-707,-1152,1545,415,1656,4094,1604,1580,2053,473,-525,351,1046,431,4,613,555,843,494,1071,1048,1375,1139,994,1431,1283,1617,838,1011,491,1146,716,701,358,388,443,310,457,32,-5,-93,169,269,-27,91,-165,86,-189,135,-120,-103,-270,-74,-56,-217,-55,-238,-119,-288,-120,-263,-264,-223,-279,-179,-302,-173,-211,-262,-189,-255,-177,-382,-172,-263,-206,-302,-155,-222,-165,-156,-91,-226,-129,-208,-104,-116,-7,-182,-57,-43,-59,-165,-192,-254,-334,-329,-222,-307,-218,-299,-183,-230,-153,-307,-262,-341,-352,-360,-306,-320,-349,-329,-284,-313,-262,-287,-276,-348,-332,-282,-281,-235,-311,-213,-232,-205,-232,-209,-189,-252,-237,-224,-214,-199,-229,-157,-205,-196,-185,-173,-156,-212,-157,-188,-156,-172,-131,-151,-175,-157,-139,-172,-126,-151,-157,-177,-123,-115,-119,-116,-103,-151,-157,-157,-103,-111,-83,-143,-134,-106,-78,-57,-83,-76,-143,-96,-110,-30,-81,-37,-72,-10,-21,-9,18,1,-1,-42,21,2,14,26,52,25,26,34,53,32,44,40,74,42,66,49,90,62,69,50}, + /* IRC_Composite_C_R0195_T330_P015.wav */ + {1,-1,1,0,0,0,0,0,0,0,0,1,-1,1,-2,2,-2,3,-3,4,-5,6,-7,9,-11,14,-18,25,-38,72,-494,-377,-163,-458,-490,-5,-649,-505,-448,737,42,720,-5,-1466,655,-1957,-272,3638,1401,3790,5414,320,1005,1351,716,-1658,736,755,629,-241,367,775,655,1313,522,711,607,1017,814,1153,1014,727,1072,1193,1369,911,877,665,747,788,602,389,-2,301,79,299,235,78,-171,-171,-12,-204,-96,-124,-285,-390,-109,136,-127,-79,-244,-125,-236,-21,-257,-313,-264,-266,-248,-188,-112,-345,-304,-50,-265,-235,-235,-38,-345,-176,-119,-52,-156,-49,-98,-184,-269,-46,-139,-85,-206,-15,-64,-75,-25,28,-69,-306,-216,-145,-321,-127,-396,-359,-364,-161,-402,-370,-313,-329,-419,-337,-409,-317,-386,-319,-505,-396,-337,-244,-368,-365,-380,-286,-289,-230,-330,-297,-331,-175,-233,-184,-243,-195,-204,-144,-176,-187,-238,-158,-239,-170,-186,-124,-214,-122,-133,-166,-196,-122,-151,-204,-200,-147,-209,-159,-148,-140,-151,-108,-106,-148,-137,-107,-109,-157,-138,-152,-159,-152,-143,-132,-169,-84,-121,-99,-110,-53,-57,-49,-65,-56,-59,-72,-39,-80,-76,-50,-24,-78,-31,-4,10,-54,43,12,18,43,54,13,-6,86,38,22,50,62,50,38,99,31,62,60,58,29,11,38}, + /* IRC_Composite_C_R0195_T345_P015.wav */ + {-11,11,-12,12,-13,13,-14,15,-16,16,-17,18,-19,20,-22,23,-24,26,-27,29,-32,34,-38,43,-52,76,-328,-363,-214,-611,-509,-335,-643,-447,-869,31,57,1040,355,-374,1188,-2297,-4332,5821,-1811,4636,8422,1800,2573,2446,333,-2543,348,441,1038,-1221,-120,503,1705,557,994,621,1108,529,1387,553,713,268,987,1168,1373,742,1063,633,1079,800,733,478,430,-8,448,243,389,-34,240,-156,40,-68,208,-262,-163,-284,-85,-119,4,-292,-169,-173,-9,-177,-185,-284,-261,-239,-151,-333,-444,-278,-212,-269,-320,-207,-353,-167,-122,5,-101,-146,-236,26,158,-193,-6,31,-110,-13,194,-336,-291,166,-187,-339,71,83,-256,-36,64,-291,-253,-258,-423,-483,-404,-542,-450,-398,-404,-517,-415,-395,-300,-370,-455,-406,-370,-334,-365,-318,-452,-367,-267,-228,-288,-345,-283,-288,-195,-237,-211,-198,-242,-243,-148,-120,-215,-182,-175,-171,-178,-118,-143,-239,-153,-169,-160,-247,-180,-208,-203,-145,-188,-199,-188,-106,-162,-137,-157,-131,-109,-183,-154,-130,-109,-197,-150,-64,-168,-155,-207,-78,-176,15,-176,-113,-192,-34,-58,-13,-144,-90,-50,-81,-89,24,-35,-100,-56,-23,-9,29,37,-35,-51,58,55,55,-8,24,51,71,28,39,46,49,51,27,-11,48,41,22,-3,23,-14,20,-19,-13}}; + +const int16_t irc_composite_c_r0195_p030[][256] = + {/* IRC_Composite_C_R0195_T000_P030.wav */ + {-54,55,-55,56,-57,57,-58,58,-58,59,-58,58,-58,56,-55,52,-48,42,-34,21,1,-38,103,-854,-293,-223,-413,-662,-699,-525,-649,-153,-821,-339,218,2022,2054,-2330,-2792,1747,-9777,10764,1443,5425,12121,258,-1458,190,2417,73,-781,460,-747,-560,1297,150,875,435,1456,292,1300,-209,948,616,962,-100,649,571,794,577,979,597,904,611,978,804,976,113,890,241,591,176,615,-381,92,-14,208,-196,144,-25,-87,-290,-51,-201,-11,-376,13,-401,6,-326,16,-348,-73,-269,-196,-276,-77,-266,-298,-332,-42,-326,-208,-519,-147,-423,-93,-432,-257,-451,-109,-270,-192,-375,-151,-315,-188,-206,-37,-459,-168,-241,-10,-278,-73,-257,87,-155,-18,-234,-126,-305,-82,-294,-405,-294,-172,-409,-47,-89,-22,-89,128,-65,30,48,-38,-108,-174,-371,-254,-219,-255,-366,-375,-485,-192,-333,-204,-374,-171,-415,-254,-437,-213,-353,-257,-320,-265,-229,-230,-199,-344,-342,-208,-291,-328,-415,-224,-366,-172,-311,-156,-289,-178,-259,-84,-212,-136,-195,-136,-204,-23,-192,-135,-219,-38,-190,-41,-200,-34,-195,-41,-117,-47,-160,-96,-111,-97,-131,-73,-186,-78,-137,-70,-202,-93,-119,-55,-149,-67,-139,-48,-119,-34,-122,-39,-119,-31,-62,-1,-61,-28,-48,31,6,17,-8,75,29,40,45,65,21,45,14}, + /* IRC_Composite_C_R0195_T015_P030.wav */ + {45,-49,52,-57,61,-66,71,-77,83,-90,98,-107,116,-126,138,-150,164,-177,188,-179,-73,-966,-102,-989,560,-1173,-327,-1684,597,-1115,259,-1628,2183,1183,3440,-5302,3131,-10502,-529,12738,-6827,21598,5258,-7,-3187,1963,495,327,502,-665,-1769,1964,-371,1009,596,896,151,1819,-137,401,915,974,249,114,559,962,751,584,371,576,838,1123,906,351,-23,332,521,427,-138,-265,-100,55,-54,59,-205,-261,-77,2,-107,-229,-219,-403,-235,-134,-143,-470,-234,-177,-61,-236,-83,-258,-197,-192,-101,-300,-331,-254,-216,-242,-271,-289,-310,-261,-262,-333,-321,-293,-270,-333,-255,-243,-275,-316,-256,-252,-176,-243,-182,-212,-172,-289,-118,-228,-303,-307,-77,-225,-298,-230,-122,-403,-282,-152,-387,-451,8,13,-160,-49,124,-112,-104,87,-45,-358,-217,-135,-206,-167,-172,-229,-317,-197,-162,-307,-272,-363,-290,-325,-168,-360,-289,-359,-212,-286,-239,-278,-241,-270,-234,-333,-266,-308,-234,-344,-218,-357,-274,-331,-208,-244,-205,-284,-219,-226,-149,-177,-181,-201,-159,-198,-109,-172,-113,-218,-95,-145,-67,-151,-73,-148,-84,-129,-52,-118,-51,-142,-54,-113,-29,-150,-66,-118,-44,-150,-8,-105,-59,-133,-10,-103,-51,-102,-26,-114,2,-62,-14,-78,24,-62,35,-36,28,-33,74,-22,57,13,101,-23,94,36,50,32}, + /* IRC_Composite_C_R0195_T030_P030.wav */ + {22,-22,22,-22,22,-22,21,-21,20,-19,18,-16,13,-9,3,6,-23,62,-927,-68,-994,540,-922,-246,-1369,328,-1205,-194,-1442,1439,570,2758,-885,3393,-4925,-8851,7444,-11725,26992,7407,2376,4575,-342,-2312,-724,2866,-938,-1366,86,-585,1150,1637,627,500,364,713,726,1042,-231,616,243,1337,315,722,212,833,509,1128,741,763,-23,706,-315,392,-241,100,-771,-188,-212,298,-422,-413,-205,37,-281,-130,-523,-88,-503,-112,-573,-211,-454,-80,-504,-132,-294,-80,-239,-22,-204,-163,-320,-82,-296,-297,-476,-149,-313,-195,-414,-189,-328,-173,-333,-197,-351,-236,-353,-212,-335,-289,-358,-212,-232,-235,-269,-127,-247,-255,-385,-167,-387,-267,-392,-201,-373,-245,-334,-180,-331,-245,-322,-210,-238,-125,-198,-59,-138,-44,-137,-3,-58,9,-199,-115,-324,-112,-304,-122,-334,-195,-342,-88,-186,-146,-296,-157,-238,-181,-256,-164,-321,-198,-320,-193,-346,-189,-318,-169,-297,-240,-369,-178,-273,-261,-370,-222,-299,-226,-327,-186,-311,-192,-283,-157,-277,-144,-267,-140,-249,-109,-220,-95,-203,-109,-172,-51,-152,-88,-149,-49,-133,-83,-123,-30,-107,-62,-145,-55,-94,-23,-81,-49,-86,-1,-42,-24,-119,-38,-58,-5,-105,-50,-71,1,-68,-36,-53,-6,-19,20,-14,18,-29,55,-17,56,-9,73,3,81,35,97,32,73}, + /* IRC_Composite_C_R0195_T045_P030.wav */ + {9,-7,5,-3,0,3,-7,12,-18,25,-34,45,-60,79,-107,151,-363,-677,-240,-871,518,-941,-269,-1276,265,-1859,1187,-1350,2149,1,5698,-4523,4866,-12427,-2128,5167,3666,25146,2435,401,417,1825,-3164,2605,613,-1851,-1719,979,-329,2301,-426,1606,-126,1675,119,1149,-57,595,-80,1644,19,793,-129,1326,678,1045,-17,856,-22,267,-380,190,-844,-146,-664,199,-735,-167,-428,32,-402,-217,-411,-308,-427,-284,-543,-438,-454,-307,-561,-259,-430,-199,-381,-181,-382,-148,-228,-87,-405,-169,-303,-91,-361,-175,-378,-291,-318,-127,-301,-269,-260,-171,-316,-164,-268,-241,-361,-178,-341,-229,-322,-201,-335,-221,-314,-343,-328,-221,-321,-372,-308,-210,-400,-380,-322,-269,-386,-304,-356,-223,-292,-166,-317,-192,-91,-100,-158,-51,-73,-116,-23,-56,-150,-243,-92,-175,-169,-181,-177,-294,-169,-187,-210,-286,-130,-227,-213,-253,-159,-238,-150,-211,-249,-260,-144,-232,-247,-283,-227,-289,-178,-293,-252,-299,-148,-285,-211,-271,-197,-276,-200,-222,-204,-252,-176,-235,-205,-223,-107,-218,-119,-198,-109,-182,-35,-149,-101,-171,-62,-123,-44,-128,-75,-141,-37,-172,-54,-143,-11,-144,-27,-104,26,-103,23,-105,37,-73,18,-74,15,-63,4,-83,16,-68,-5,-50,47,-28,24,-35,41,-27,78,-21,77,-17,105,16,96,7,122,24}, + /* IRC_Composite_C_R0195_T060_P030.wav */ + {8,-7,7,-6,5,-5,4,-3,3,-3,3,-3,5,-9,20,86,-790,103,-872,55,-678,-196,-962,-387,-893,162,722,1609,608,2929,1713,-6837,-667,-12691,15713,13906,9242,5982,83,-1809,1076,1596,1326,-1529,-1392,-366,731,78,1368,-246,850,592,521,699,1115,310,930,973,592,664,159,708,710,489,-74,485,-697,374,-695,249,-1252,204,-915,137,-777,-91,-241,-403,-350,-466,-269,-521,-499,-540,-380,-320,-709,-233,-517,-228,-634,-244,-652,-290,-447,-147,-545,-241,-352,5,-488,-69,-437,53,-465,-6,-353,-78,-525,-24,-335,-157,-418,-27,-367,-103,-287,-241,-397,-158,-276,-304,-351,-181,-369,-225,-401,-209,-512,-184,-447,-153,-476,-152,-484,-76,-492,-243,-498,-127,-515,-186,-392,-135,-408,-53,-239,-82,-191,13,-138,-32,-118,-6,-177,-44,-187,-143,-246,-50,-262,-108,-264,-71,-256,-48,-325,-90,-349,-63,-352,-110,-280,-159,-311,-153,-350,-187,-295,-152,-318,-137,-192,-178,-252,-142,-284,-157,-277,-190,-286,-151,-282,-119,-257,-91,-310,-54,-224,-93,-207,-75,-245,-9,-203,-48,-237,12,-182,-40,-201,33,-146,-26,-200,-37,-156,-43,-159,-28,-130,-32,-114,20,-143,6,-113,12,-126,58,-103,21,-121,59,-91,44,-108,59,-43,47,-58,60,-38,52,-61,83,-36,62,3,66,27,84,84,65,66,103}, + /* IRC_Composite_C_R0195_T075_P030.wav */ + {100,-103,106,-109,112,-115,118,-120,122,-122,119,-110,88,-25,53,-874,378,-897,369,-1226,537,-1263,224,-1798,1274,98,2195,-462,4170,361,-3989,-3149,-11328,17722,9812,11683,3944,-511,-808,1931,2611,1751,-2704,-605,-430,728,-349,908,612,941,-687,931,759,-66,894,2123,310,1489,449,746,475,494,-493,-725,213,-1074,381,-1100,-205,-670,-115,-645,-170,-469,-431,31,-824,-248,-707,-458,-476,-267,-901,-228,-228,-601,-420,-335,-514,-545,-367,-632,-446,-566,-351,-391,-306,-444,-134,-388,-144,-333,-243,-194,-98,-434,-105,-173,-206,-249,-121,-377,-102,-345,-159,-256,-146,-470,-106,-327,-152,-330,-205,-368,-192,-409,-197,-444,-310,-359,-229,-461,-161,-393,-318,-351,-227,-387,-261,-314,-291,-270,-249,-242,-213,-299,-192,-269,-108,-253,-73,-278,80,-171,-11,-111,7,-198,-30,-155,-148,-117,-164,-168,-181,-155,-172,-221,-156,-207,-176,-229,-130,-292,-171,-280,-233,-288,-132,-237,-242,-209,-166,-245,-147,-263,-160,-240,-126,-261,-109,-276,-150,-274,-92,-247,-135,-225,-43,-207,-57,-174,-33,-157,-10,-172,-20,-116,-56,-146,22,-132,-61,-119,-53,-166,-22,-107,-81,-99,-40,-65,-89,-70,-32,-77,-31,-75,-25,-75,36,-146,3,-52,3,-100,13,-55,-5,-17,13,-41,5,-12,59,-13,32,3,61,44,107,53,129,85,118,95}, + /* IRC_Composite_C_R0195_T090_P030.wav */ + {-85,89,-94,98,-102,107,-112,116,-119,121,-119,106,-58,-455,60,99,-1054,-36,-88,242,-1635,433,-1255,1196,-1210,2540,-840,5344,-2798,4670,-10472,-874,1281,9198,19443,266,2404,-1705,3816,1662,3038,83,-1499,-2490,1368,-37,500,-334,1490,-626,909,-15,1075,678,1886,658,852,386,1418,146,400,-1073,-338,-633,-165,-1024,-383,-1251,-264,-407,-25,-1062,-140,-559,70,-716,-459,-642,-96,-725,-472,-412,-384,-647,-281,-605,-395,-572,-399,-706,-351,-583,-297,-495,-434,-423,-201,-406,-407,-323,-268,-341,-186,-360,-201,-241,-141,-313,-94,-257,-169,-208,-194,-224,-147,-275,-276,-255,-215,-224,-195,-256,-265,-271,-252,-352,-290,-430,-350,-309,-268,-387,-267,-289,-271,-262,-303,-332,-237,-287,-328,-292,-220,-307,-211,-297,-184,-216,-183,-248,-116,-180,-163,-187,-112,-160,-80,-117,-46,-81,-25,-91,-53,-114,-120,-176,-181,-173,-184,-205,-224,-154,-233,-229,-178,-204,-243,-197,-188,-194,-206,-154,-204,-205,-213,-116,-191,-127,-210,-145,-216,-173,-183,-177,-263,-209,-141,-116,-148,-107,-124,-68,-87,-45,-121,-68,-134,-77,-87,-29,-115,-67,-117,-46,-114,-27,-115,-45,-100,-16,-82,-32,-85,-17,-74,-28,-41,-27,-85,-23,-68,-40,-47,-15,-96,-13,-38,11,-39,-38,-19,1,-19,-3,-8,-15,-22,28,17,70,76,128,80,124,112,151}, + /* IRC_Composite_C_R0195_T105_P030.wav */ + {104,-111,117,-125,133,-143,153,-166,180,-197,218,-245,288,-401,132,-429,-287,-538,503,-701,-185,-1083,867,-1151,1236,-192,2589,704,2171,-548,-4634,-1245,-3979,18483,6281,7009,-196,501,1762,4063,3838,-1,-2732,-1085,-409,884,444,-393,-9,733,362,138,1179,1594,1300,947,317,734,700,55,-900,-943,-310,-712,-521,-933,-377,-1554,-143,-410,48,-924,-152,-440,-212,-554,-286,-601,-527,-371,-454,-653,-533,-426,-450,-579,-486,-483,-369,-609,-354,-543,-201,-457,-293,-586,-146,-430,-339,-522,-196,-439,-324,-340,-141,-423,-157,-344,-39,-390,-88,-363,-66,-244,-152,-284,-176,-153,-268,-264,-245,-148,-256,-290,-221,-325,-190,-340,-211,-490,-165,-333,-238,-471,-203,-235,-228,-397,-218,-264,-147,-365,-267,-367,-142,-319,-211,-356,-158,-290,-141,-243,-127,-217,-86,-135,-64,-128,-75,-153,-67,-155,-25,-190,-45,-193,-18,-259,1,-235,-77,-284,-88,-227,-151,-250,-186,-245,-111,-256,-126,-274,-46,-272,-88,-254,-32,-214,-71,-201,-144,-187,-98,-154,-182,-196,-78,-154,-85,-159,-36,-221,-26,-121,-4,-188,-47,-127,-22,-132,-24,-158,-49,-155,-2,-158,-21,-135,-30,-121,10,-87,-16,-118,10,-48,-22,-86,-12,-80,14,-80,13,-86,50,-103,29,-96,64,-85,45,-104,50,-45,64,-67,-11,-39,117,-14,158,27,234,13,225,68}, + /* IRC_Composite_C_R0195_T120_P030.wav */ + {28,-28,29,-29,29,-29,29,-27,25,-21,15,-5,-12,43,-140,88,-559,-189,139,-567,198,-314,-739,-383,1538,-450,794,642,4608,-2302,1277,-7331,2563,5148,5379,12280,2713,-323,-1693,7682,3305,1850,-1530,-2098,-1411,1431,-392,275,-715,741,-246,1255,618,1870,987,1146,368,730,-169,18,-891,-805,-1522,-439,-421,-616,-1006,-319,-441,-263,-511,-164,-630,-92,-636,-184,-746,-202,-725,-323,-658,-347,-529,-471,-673,-383,-415,-310,-627,-358,-521,-225,-567,-258,-424,-264,-432,-273,-312,-333,-413,-308,-330,-340,-367,-280,-273,-329,-276,-223,-220,-254,-266,-200,-177,-199,-276,-232,-217,-244,-204,-238,-182,-299,-214,-297,-195,-311,-235,-299,-177,-299,-241,-285,-222,-309,-277,-284,-244,-293,-235,-236,-241,-258,-206,-250,-223,-292,-255,-245,-224,-254,-179,-205,-152,-237,-116,-146,-78,-191,-75,-140,-27,-176,-63,-134,-82,-199,-79,-164,-84,-202,-123,-164,-105,-201,-110,-207,-105,-211,-126,-202,-134,-203,-129,-204,-131,-154,-100,-194,-94,-163,-74,-166,-82,-216,-107,-149,-27,-161,-56,-129,-40,-130,-55,-114,-53,-102,-63,-77,-31,-89,-106,-127,-83,-123,-74,-94,-24,-173,-31,-94,11,-133,-8,-83,-23,-88,12,-65,-46,-111,25,-94,13,-117,28,-88,37,-79,24,-35,51,-27,22,7,50,-3,53,7,103,86,163,91,162,75}, + /* IRC_Composite_C_R0195_T135_P030.wav */ + {6,-6,7,-7,8,-8,9,-9,10,-10,11,-12,13,-14,16,-18,-114,-234,-98,-110,-115,-173,-170,-232,-274,363,317,1353,133,2229,1323,703,-7423,4287,1521,5913,8831,4880,804,-872,5713,3941,3130,-2817,-2290,-315,304,-50,-26,-209,494,295,1100,751,1288,533,716,964,54,-449,-399,-528,-808,-934,-947,-951,-457,-538,-157,-625,-308,-385,-95,-571,-310,-374,-278,-494,-514,-429,-461,-556,-433,-529,-432,-535,-327,-580,-236,-492,-287,-555,-216,-430,-280,-451,-246,-351,-270,-341,-290,-325,-254,-404,-265,-383,-232,-420,-232,-398,-198,-399,-199,-300,-210,-291,-213,-230,-263,-273,-261,-215,-220,-262,-203,-257,-189,-275,-199,-298,-243,-292,-198,-258,-246,-263,-220,-238,-243,-271,-259,-242,-227,-263,-220,-247,-166,-281,-180,-274,-165,-251,-184,-245,-176,-216,-217,-207,-158,-156,-155,-166,-106,-127,-108,-139,-81,-152,-98,-167,-88,-170,-109,-150,-125,-150,-119,-119,-124,-135,-111,-142,-113,-144,-112,-168,-76,-193,-154,-199,-103,-124,-149,-137,-125,-90,-105,-96,-120,-90,-84,-94,-99,-96,-69,-90,-69,-82,-94,-80,-67,-60,-94,-70,-110,-76,-102,-51,-103,-55,-74,-38,-105,-57,-91,-76,-96,-51,-36,-59,-52,-57,-56,-61,-46,-70,-31,-32,-25,-47,6,-6,17,-33,-1,20,49,32,43,24,63,112,138,114,43,112}, + /* IRC_Composite_C_R0195_T150_P030.wav */ + {40,-42,44,-47,49,-53,56,-60,64,-69,75,-82,90,-99,110,-125,148,-207,85,-316,199,-301,148,-341,137,-377,122,76,967,463,1542,593,2935,-2335,-3746,3892,1126,7018,5853,6116,-1287,2364,4148,3574,181,-2393,-1125,-178,512,-398,-17,-462,310,1083,929,1228,538,479,431,450,-124,-446,-926,-681,-484,-854,-858,-886,-425,-380,-163,-187,-475,-333,-267,-193,-398,-286,-470,-331,-472,-511,-390,-535,-398,-443,-447,-458,-316,-355,-323,-348,-312,-366,-331,-282,-304,-410,-276,-324,-270,-334,-288,-347,-263,-345,-283,-348,-294,-324,-322,-384,-264,-346,-287,-352,-258,-326,-246,-345,-247,-332,-220,-276,-243,-276,-171,-257,-208,-277,-184,-237,-184,-265,-186,-245,-165,-259,-201,-253,-180,-238,-198,-272,-176,-246,-187,-277,-161,-252,-150,-275,-137,-267,-126,-254,-141,-241,-149,-227,-151,-206,-151,-203,-126,-181,-101,-170,-85,-185,-87,-146,-87,-170,-106,-170,-90,-160,-111,-150,-107,-140,-90,-144,-63,-132,-90,-238,-87,-160,-61,-203,-110,-165,-57,-102,-36,-116,-53,-98,-41,-96,-62,-105,-61,-102,-70,-120,-86,-109,-103,-103,-70,-67,-72,-85,-74,-124,-64,-94,-56,-139,-102,-99,-75,-97,-58,-61,-30,-94,-25,-74,-43,-104,-48,-76,-56,-75,-27,-39,-24,-3,21,-10,-1,6,97,22,44,1,101,93,134,63,82,45}, + /* IRC_Composite_C_R0195_T165_P030.wav */ + {-5,5,-6,6,-6,6,-6,7,-7,7,-8,8,-9,9,-10,11,-12,14,-17,25,-163,17,-80,12,2,-73,14,-200,92,163,755,471,1371,723,2348,-678,-3403,2150,1314,5172,5430,6608,508,1066,3048,2691,1177,-1954,-1312,-864,1114,-99,-395,-170,755,800,840,925,689,-7,-2,-92,-86,-565,-703,-538,-415,-580,-306,-607,-337,-594,-235,-197,-71,-393,-276,-461,-131,-367,-319,-372,-331,-590,-309,-448,-316,-391,-370,-330,-202,-345,-331,-285,-252,-333,-332,-343,-285,-341,-299,-355,-341,-319,-335,-324,-306,-321,-304,-329,-296,-343,-321,-372,-317,-381,-294,-371,-299,-341,-289,-334,-273,-311,-239,-276,-234,-285,-217,-256,-202,-250,-169,-221,-150,-205,-167,-217,-204,-247,-225,-236,-214,-247,-214,-207,-155,-197,-183,-192,-155,-160,-191,-236,-192,-219,-188,-240,-195,-229,-141,-216,-140,-210,-108,-198,-110,-186,-131,-164,-118,-161,-128,-132,-117,-113,-132,-130,-137,-165,-120,-157,-110,-125,-107,-149,-159,-131,-114,-123,-178,-132,-136,-75,-82,-32,-23,-71,-33,-49,-17,-94,-64,-87,-53,-94,-80,-79,-100,-87,-113,-66,-94,-109,-102,-113,-90,-94,-92,-105,-128,-124,-129,-89,-94,-67,-93,-83,-95,-80,-94,-87,-89,-91,-53,-81,-31,-57,18,-49,-13,-37,25,-7,9,-13,-1,53,58,59,79,109,133,124,84,60}, + /* IRC_Composite_C_R0195_T180_P030.wav */ + {11,-12,12,-12,13,-13,14,-14,15,-15,16,-17,18,-19,20,-21,23,-25,28,-33,39,-51,85,16,-87,129,-81,94,33,-96,-40,382,84,940,857,674,1733,496,-329,-2997,2450,4178,3824,5230,3832,1334,27,2852,1755,841,-2811,-750,709,798,-492,-489,295,1105,873,238,383,361,52,-483,-293,-277,-430,-468,-128,-283,-308,-272,-363,-267,-297,-189,-289,-143,-258,-242,-373,-291,-355,-331,-315,-246,-385,-325,-276,-197,-314,-270,-313,-267,-313,-307,-364,-269,-366,-341,-361,-328,-371,-363,-339,-357,-363,-329,-335,-334,-353,-302,-358,-291,-419,-330,-381,-332,-384,-319,-331,-309,-321,-276,-296,-256,-286,-256,-306,-268,-277,-214,-200,-211,-199,-179,-152,-213,-196,-243,-196,-273,-196,-241,-183,-226,-151,-195,-173,-198,-169,-171,-172,-166,-179,-179,-198,-192,-224,-204,-227,-203,-207,-198,-181,-177,-142,-148,-122,-136,-110,-124,-113,-120,-142,-140,-137,-157,-161,-213,-116,-179,-81,-164,-112,-182,-121,-113,-114,-132,-189,-130,-138,-73,-121,-47,-93,-7,-49,37,-29,-7,-77,-47,-80,-70,-85,-99,-107,-91,-49,-61,-81,-124,-69,-122,-37,-160,-57,-192,-64,-193,-77,-181,-87,-158,-111,-159,-105,-113,-89,-109,-88,-83,-83,-88,-75,-44,-73,-39,-53,-1,-6,52,20,54,20,68,72,99,107,107,128,102,141,66}, + /* IRC_Composite_C_R0195_T195_P030.wav */ + {-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,1,-1,1,-1,0,0,-1,2,-3,4,-1,20,-103,88,-97,77,-98,0,-92,123,108,628,541,868,946,950,-323,-2426,1960,1868,3655,4432,4145,1520,425,2257,2243,324,-1505,-101,360,566,-340,-97,521,852,598,427,177,417,31,149,-102,-24,-395,-11,-98,-149,-157,-72,-31,-41,-10,-27,-82,-183,-287,-120,-245,-255,-309,-131,-235,-200,-246,-222,-253,-210,-246,-249,-280,-281,-300,-278,-328,-316,-325,-352,-332,-302,-334,-406,-331,-345,-314,-353,-298,-355,-316,-331,-341,-377,-390,-356,-375,-325,-347,-301,-303,-263,-297,-274,-288,-262,-288,-280,-284,-231,-214,-205,-233,-199,-221,-205,-231,-218,-253,-209,-218,-203,-211,-199,-179,-191,-186,-199,-201,-193,-181,-187,-195,-182,-193,-188,-207,-197,-194,-197,-186,-192,-163,-178,-160,-165,-142,-165,-124,-155,-125,-159,-112,-160,-116,-190,-111,-165,-107,-172,-122,-190,-155,-169,-127,-164,-144,-157,-122,-135,-85,-113,-68,-116,-46,-67,-29,-54,-47,-65,-70,-92,-108,-92,-118,-99,-92,-87,-77,-99,-78,-106,-86,-118,-92,-123,-105,-136,-119,-126,-128,-143,-162,-171,-163,-154,-125,-147,-120,-134,-91,-125,-91,-103,-88,-80,-77,-45,-46,-3,16,24,24,27,58,42,84,85,129,127,141,127,125}, + /* IRC_Composite_C_R0195_T210_P030.wav */ + {-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,4,-4,4,-4,4,-4,5,-5,6,-6,7,-9,12,-23,-83,-41,-51,-44,-54,-36,-72,-62,13,62,362,515,745,618,964,123,-1474,242,1605,2935,3779,3927,2051,644,1570,1770,938,-679,-243,210,595,104,204,284,657,698,453,338,507,437,72,227,224,63,-55,88,141,215,131,225,97,158,60,38,-69,-107,-265,-85,-124,-202,-245,-131,-257,-191,-192,-178,-241,-145,-269,-233,-270,-235,-338,-254,-338,-292,-359,-271,-388,-290,-377,-344,-357,-293,-419,-370,-380,-349,-397,-346,-388,-357,-344,-302,-335,-306,-279,-276,-246,-273,-284,-282,-237,-264,-250,-226,-225,-248,-218,-230,-247,-240,-246,-259,-217,-216,-201,-233,-193,-207,-183,-205,-202,-228,-190,-207,-213,-222,-215,-237,-186,-220,-176,-235,-136,-217,-116,-201,-133,-200,-133,-159,-165,-150,-164,-152,-134,-165,-144,-175,-119,-164,-116,-139,-114,-152,-126,-132,-128,-147,-152,-173,-154,-145,-152,-115,-135,-100,-99,-65,-75,-79,-71,-101,-104,-126,-96,-135,-132,-139,-125,-80,-131,-108,-168,-90,-142,-81,-142,-146,-133,-121,-109,-142,-113,-121,-117,-148,-144,-150,-144,-150,-171,-140,-133,-106,-126,-118,-107,-114,-61,-79,-59,-59,-5,-31,13,-2,37,21,52,67,76,116,109,131,125}, + /* IRC_Composite_C_R0195_T225_P030.wav */ + {-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,2,-2,2,-2,2,-2,2,-2,3,-3,3,-4,5,-7,14,-133,-89,-52,-68,-90,-53,-98,-77,-65,-141,-33,-38,144,467,407,586,730,265,-702,-561,1147,2053,3022,3625,2128,1090,1205,1750,1123,130,-65,370,545,406,83,446,636,787,529,661,549,526,605,368,384,101,455,156,304,149,290,238,156,207,48,113,-86,-57,-36,-176,-93,-129,-107,-209,-107,-181,-195,-158,-169,-157,-239,-205,-240,-206,-253,-259,-282,-324,-296,-377,-347,-379,-340,-400,-365,-377,-398,-363,-379,-335,-398,-330,-337,-283,-328,-250,-335,-246,-279,-228,-301,-284,-299,-253,-272,-251,-277,-231,-269,-213,-274,-207,-256,-219,-248,-212,-205,-234,-191,-244,-197,-238,-194,-226,-213,-226,-214,-216,-219,-201,-233,-193,-216,-184,-183,-195,-171,-198,-136,-183,-121,-177,-126,-151,-131,-156,-138,-160,-140,-152,-130,-143,-109,-146,-113,-168,-114,-165,-123,-191,-139,-186,-143,-163,-101,-126,-91,-147,-80,-140,-85,-158,-107,-181,-100,-149,-100,-152,-116,-152,-120,-144,-111,-159,-127,-155,-129,-148,-146,-173,-157,-145,-134,-136,-128,-146,-120,-128,-115,-125,-133,-149,-144,-153,-151,-147,-139,-128,-113,-110,-89,-78,-59,-67,-27,-39,-8,-19,9,9,34,44,63,65,98,113}, + /* IRC_Composite_C_R0195_T240_P030.wav */ + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,1,-97,-166,-68,-82,-98,-145,6,-178,-148,-79,-61,-4,226,289,466,695,150,-363,-564,127,1778,2371,2730,2418,1314,1333,1958,1573,362,208,618,691,672,358,520,767,841,691,635,738,675,472,476,447,387,278,358,303,322,169,236,146,167,153,93,161,-50,82,-137,22,-215,-48,-220,-102,-183,-156,-150,-189,-134,-246,-183,-293,-242,-320,-276,-333,-344,-324,-341,-336,-359,-336,-345,-340,-353,-365,-331,-325,-327,-353,-302,-293,-288,-330,-303,-271,-296,-272,-313,-253,-304,-231,-298,-228,-279,-211,-267,-230,-276,-219,-263,-229,-267,-208,-254,-187,-265,-150,-261,-152,-276,-148,-255,-165,-256,-184,-237,-198,-227,-197,-220,-180,-224,-157,-210,-127,-200,-118,-181,-83,-171,-100,-162,-99,-139,-124,-137,-122,-137,-107,-131,-113,-152,-146,-173,-133,-190,-141,-182,-105,-142,-132,-151,-164,-146,-160,-134,-193,-153,-203,-128,-188,-144,-178,-164,-173,-166,-129,-130,-161,-160,-179,-136,-174,-125,-201,-162,-176,-100,-152,-132,-174,-152,-170,-137,-167,-127,-157,-111,-151,-85,-120,-73,-114,-88,-97,-72,-75,-82,-80,-55,-47,-53,-51,-32,-31,18,-8,35,22,73,65}, + /* IRC_Composite_C_R0195_T255_P030.wav */ + {1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,2,-2,2,-2,2,-2,3,-3,4,-4,5,-6,8,-12,21,-67,-186,-86,-78,-102,-151,-102,-59,-120,-188,-201,-77,-93,-133,190,315,388,642,206,-429,-627,-41,1512,2532,2996,2313,1394,1764,1723,1247,1241,976,437,321,813,834,517,405,589,1007,744,553,490,641,609,429,381,224,460,347,308,191,277,332,175,143,27,143,-12,2,-104,-86,-53,-114,-79,-254,-137,-211,-109,-349,-252,-297,-195,-348,-341,-330,-262,-295,-325,-316,-289,-220,-305,-292,-333,-256,-294,-316,-394,-312,-314,-286,-387,-317,-323,-233,-326,-302,-311,-250,-238,-292,-290,-296,-199,-259,-241,-292,-230,-245,-240,-270,-264,-223,-199,-230,-230,-203,-176,-179,-217,-226,-180,-203,-190,-239,-188,-230,-173,-226,-190,-237,-149,-184,-187,-190,-158,-126,-139,-130,-127,-103,-111,-83,-113,-124,-148,-136,-140,-136,-138,-118,-132,-127,-165,-140,-179,-161,-224,-175,-209,-159,-182,-149,-200,-170,-196,-150,-218,-152,-222,-177,-254,-168,-210,-186,-215,-137,-166,-128,-166,-128,-184,-106,-195,-174,-233,-137,-162,-153,-164,-155,-113,-146,-99,-141,-92,-113,-93,-86,-120,-80,-115,-69,-118,-75,-88,-73,-78,-77,-48,-78,-41,-54,-26,-50,-11,-21,13,14,31}, + /* IRC_Composite_C_R0195_T270_P030.wav */ + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,-1,2,-2,4,-6,13,-118,-205,-234,-125,-147,-202,-210,-154,-149,-302,-174,-138,74,139,366,494,501,-30,-788,-660,656,2336,3548,2933,1466,1698,2087,1596,1331,660,745,348,609,649,510,592,471,837,634,881,692,658,657,499,658,390,588,291,406,283,323,211,84,205,87,193,12,79,-62,28,-174,-101,-266,-102,-288,-156,-317,-186,-313,-245,-324,-271,-272,-274,-260,-294,-238,-276,-248,-278,-258,-319,-271,-317,-281,-337,-312,-324,-337,-313,-331,-296,-324,-287,-323,-272,-287,-250,-300,-247,-285,-236,-292,-228,-244,-210,-272,-214,-253,-227,-239,-213,-239,-229,-229,-214,-226,-214,-215,-199,-227,-177,-203,-180,-193,-178,-164,-152,-146,-149,-125,-151,-141,-143,-150,-155,-139,-130,-168,-120,-114,-108,-126,-125,-154,-199,-182,-165,-181,-236,-178,-180,-150,-191,-167,-205,-200,-201,-200,-203,-212,-213,-204,-217,-180,-215,-180,-171,-178,-161,-169,-169,-194,-215,-198,-197,-181,-198,-150,-180,-147,-175,-139,-160,-138,-133,-143,-113,-144,-115,-133,-126,-110,-112,-106,-129,-97,-110,-96,-107,-98,-88,-83,-69,-93,-79,-84,-51,-65,-56,-47,-41,-18,-38,4,-20,19,6}, + /* IRC_Composite_C_R0195_T285_P030.wav */ + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,1,-1,1,-1,1,-1,2,-2,3,-3,4,-7,13,-190,-183,-235,-156,-218,-208,-304,-188,-211,-199,-139,-161,153,336,233,-123,-164,-557,-685,1147,1908,2035,3160,1492,785,1242,1667,1506,818,1143,817,1178,780,1057,657,807,713,683,790,563,729,595,855,599,704,615,614,540,520,362,304,245,337,219,250,133,197,59,126,-65,-70,-160,-89,-159,-231,-254,-291,-203,-274,-185,-304,-208,-285,-189,-264,-256,-331,-243,-311,-262,-308,-280,-304,-246,-335,-250,-318,-269,-309,-282,-300,-260,-340,-268,-307,-236,-284,-269,-325,-251,-300,-247,-310,-244,-277,-183,-239,-198,-269,-229,-228,-237,-229,-245,-249,-264,-220,-228,-201,-208,-179,-162,-96,-70,-76,-134,-147,-121,-145,-142,-175,-192,-136,-108,-69,-153,-156,-210,-206,-236,-198,-320,-233,-263,-173,-277,-125,-224,-144,-166,-131,-224,-164,-197,-216,-260,-240,-244,-177,-196,-187,-157,-155,-171,-202,-195,-206,-203,-187,-195,-236,-200,-188,-186,-176,-232,-177,-163,-133,-189,-164,-179,-140,-153,-146,-152,-146,-135,-108,-114,-110,-119,-88,-135,-96,-118,-89,-127,-122,-110,-95,-72,-108,-98,-91,-59,-48,-71,-44,-52,-26,-30,-20,-36,-34,-3,-13,9,16}, + /* IRC_Composite_C_R0195_T300_P030.wav */ + {1,-1,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-3,3,-3,3,-3,3,-4,4,-4,5,-5,5,-6,7,-8,9,-10,12,-16,27,-117,-227,-314,-248,-219,-228,-232,-272,-389,-204,-111,300,56,366,86,-1011,-298,44,-215,2477,2714,2032,2711,645,499,536,1654,449,374,611,764,837,821,1350,980,1002,808,1149,967,761,841,707,633,745,777,758,579,642,512,570,444,429,371,457,296,276,181,191,36,17,10,-72,-108,-107,-232,-151,-205,-165,-300,-163,-265,-253,-269,-203,-258,-301,-275,-269,-292,-272,-260,-302,-297,-289,-229,-300,-264,-305,-243,-283,-264,-269,-279,-280,-287,-259,-269,-276,-247,-263,-262,-247,-231,-256,-218,-280,-241,-295,-239,-252,-218,-256,-230,-258,-241,-251,-148,-189,-159,-149,-45,-91,-37,-119,-83,-194,-47,-124,-58,-134,-130,-231,-259,-239,-276,-269,-285,-258,-248,-198,-188,-240,-206,-250,-202,-249,-205,-247,-163,-226,-240,-217,-219,-189,-209,-212,-237,-257,-142,-184,-180,-176,-167,-213,-202,-187,-188,-191,-235,-229,-241,-179,-197,-185,-210,-199,-189,-160,-163,-174,-186,-151,-189,-138,-133,-147,-130,-137,-107,-118,-101,-102,-120,-113,-110,-78,-102,-64,-110,-74,-76,-59,-92,-76,-85,-71,-79,-43,-88,-39,-85,-19,-81,13,-60,8,-26,31,8,16,23}, + /* IRC_Composite_C_R0195_T315_P030.wav */ + {-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-3,3,-4,4,-4,4,-4,5,-5,6,-7,10,-15,27,-80,-353,-110,-370,-400,-195,-345,-309,-394,-97,-188,193,754,56,-290,-194,-1922,214,1653,1159,4327,2754,1527,1212,743,317,539,1293,-56,-21,321,1262,295,442,708,1213,856,813,872,1000,917,1073,730,897,944,834,864,775,610,537,692,383,605,370,536,245,348,155,280,101,83,31,90,-127,-63,-179,-119,-272,-116,-304,-232,-233,-212,-345,-176,-295,-247,-334,-204,-342,-233,-195,-284,-324,-229,-236,-255,-304,-258,-323,-258,-297,-224,-323,-252,-263,-224,-317,-252,-224,-255,-281,-221,-218,-205,-288,-209,-253,-193,-244,-249,-201,-218,-210,-200,-172,-180,-181,-84,-203,-75,-54,19,-108,-2,-46,-171,-209,-203,-294,-294,-286,-264,-295,-154,-187,-222,-182,-252,-197,-249,-211,-305,-232,-289,-224,-284,-267,-256,-184,-221,-260,-295,-281,-237,-233,-228,-269,-251,-203,-162,-193,-192,-189,-166,-237,-188,-201,-208,-209,-181,-224,-228,-151,-192,-200,-209,-131,-196,-159,-162,-159,-166,-116,-160,-151,-131,-47,-142,-119,-122,-73,-93,-108,-96,-133,-90,-84,-86,-83,-90,-56,-96,-65,-65,-48,-80,-67,-79,-50,-60,-46,-63,-39,-44,-12,-27,9,-35,23,-3,24,6,41}, + /* IRC_Composite_C_R0195_T330_P030.wav */ + {-5,5,-5,5,-5,5,-5,5,-5,6,-6,6,-6,6,-6,6,-6,6,-7,7,-7,7,-8,8,-9,9,-11,14,-26,-447,-195,-107,-505,-457,-480,-118,-514,-260,-345,82,416,511,1319,-1763,-994,103,-1768,3014,4385,2231,5234,1274,290,-49,1679,111,-604,148,524,573,-122,973,360,1000,586,1035,552,578,788,885,854,618,749,894,854,1021,930,968,502,1006,765,768,438,460,339,388,236,299,159,177,-65,162,-6,-74,-134,-51,-230,-132,-193,-105,-327,-152,-257,-191,-291,-227,-315,-280,-252,-192,-306,-253,-281,-182,-326,-252,-283,-225,-353,-255,-282,-258,-322,-236,-271,-288,-246,-248,-299,-265,-254,-312,-330,-129,-295,-141,-204,-129,-190,-22,-154,-203,-125,-172,-156,-188,-111,-223,-112,-106,-241,-86,-37,-262,-238,-193,-103,-105,-7,-250,-241,-39,-63,-184,-238,-261,-364,-243,-263,-310,-361,-286,-407,-227,-301,-289,-311,-319,-263,-215,-201,-304,-287,-339,-226,-246,-239,-335,-276,-276,-181,-234,-181,-257,-180,-234,-151,-165,-203,-213,-194,-170,-205,-157,-164,-191,-168,-154,-86,-133,-128,-162,-96,-147,-81,-165,-68,-173,-90,-164,-64,-127,-68,-162,-97,-99,-50,-115,-84,-111,-102,-87,-74,-80,-123,-76,-57,-95,-59,-42,-45,-74,-38,-27,-9,-30,0,-55,36,-23,58,-21,61,-7,59,29}, + /* IRC_Composite_C_R0195_T345_P030.wav */ + {0,0,0,0,0,0,0,1,-1,1,-1,2,-2,2,-3,3,-4,5,-5,6,-7,8,-9,10,-10,-1,-563,-328,-175,-595,-424,-853,130,-981,36,-843,608,167,1104,1422,-2010,-2282,1073,-3818,6278,4848,2400,7303,1229,-443,-1130,2494,95,-616,-743,335,108,968,417,599,684,1073,630,810,221,839,469,1136,218,739,427,945,692,942,955,757,852,1008,762,614,598,745,200,403,51,357,29,333,-147,-65,9,35,-114,-161,-231,-52,-197,-139,-202,-61,-310,-211,-214,-165,-307,-207,-293,-261,-259,-204,-201,-310,-323,-244,-250,-260,-335,-226,-421,-206,-333,-191,-401,-188,-244,-264,-283,-225,-208,-338,-233,-69,-304,-181,-213,-18,-265,39,-68,-82,-113,-107,16,-329,-80,-324,-205,-399,-184,-328,-391,-87,-9,36,1,59,-85,124,-60,-143,-307,-231,-406,-296,-456,-311,-297,-269,-433,-350,-189,-283,-277,-303,-343,-325,-287,-213,-328,-275,-279,-293,-296,-268,-217,-284,-286,-294,-277,-236,-247,-201,-305,-195,-224,-135,-244,-185,-128,-225,-126,-186,-74,-235,-93,-209,-95,-133,-90,-131,-165,-80,-89,-69,-148,-104,-72,-157,-77,-134,-88,-171,-67,-113,-124,-110,-76,-110,-130,-59,-96,-88,-119,-61,-109,-81,-81,-67,-82,-54,-22,-49,-19,-18,2,-15,25,13,24,8,45,57,4,20,23,60}}; + +const int16_t irc_composite_c_r0195_p045[][256] = + {/* IRC_Composite_C_R0195_T000_P045.wav */ + {-30,30,-31,32,-33,34,-35,36,-37,38,-39,40,-41,42,-43,43,-44,44,-42,38,-28,-9,-568,-169,-659,-127,-629,-131,-879,-529,-702,-207,-686,-146,757,1500,46,1169,-4599,-1790,163,-4363,15423,4884,3940,951,722,-172,1158,1933,-227,-750,303,-613,1137,856,493,193,1077,347,1002,300,420,882,521,444,512,395,442,484,453,404,610,620,839,826,758,649,736,767,608,484,493,147,169,427,10,204,-311,19,-245,98,-241,0,-167,16,-127,-26,-105,-158,-191,-79,-246,-206,-268,-177,-349,-216,-328,-216,-366,-178,-332,-214,-308,-168,-352,-204,-312,-132,-301,-215,-309,-152,-304,-202,-336,-200,-308,-229,-340,-205,-331,-196,-326,-240,-274,-198,-310,-200,-321,-159,-282,-190,-264,-176,-207,-74,-246,-157,-167,-77,-245,18,-155,-133,-274,-40,-289,-273,-267,-139,-520,-214,-265,-252,-317,-46,-133,-17,38,121,-153,151,27,-13,-114,13,-297,-74,-188,-147,-332,-197,-268,-297,-199,-221,-310,-309,-263,-206,-258,-237,-414,-155,-291,-200,-367,-189,-287,-139,-241,-261,-247,-142,-190,-233,-239,-158,-249,-110,-242,-173,-207,-82,-217,-136,-180,-136,-164,-112,-177,-97,-134,-40,-164,-32,-115,-16,-91,-12,-112,4,-81,-19,-100,-20,-70,-21,-87,-6,-59,22,-68,-7,-66,36,-20,13,-47,-2,-27,28,-4,13}, + /* IRC_Composite_C_R0195_T015_P045.wav */ + {16,-14,12,-9,7,-4,1,3,-7,12,-17,22,-29,36,-45,56,-69,85,-107,143,-247,-403,-616,-230,-517,-270,-663,-670,-583,-556,-570,-300,850,1495,298,1490,-1579,-5393,1137,-9580,17573,8715,3526,4288,-490,-1083,280,3534,-555,-1021,-341,-114,804,1521,139,355,844,673,325,735,-35,1245,91,909,-18,912,280,465,82,792,554,703,257,849,594,952,381,794,169,438,96,219,18,183,-220,-11,-303,284,-345,-44,-429,-44,-355,-58,-224,-155,-342,-30,-264,-140,-360,-95,-355,-133,-396,-161,-354,-174,-312,-65,-314,-194,-357,-142,-289,-170,-390,-213,-337,-152,-369,-215,-364,-191,-332,-194,-330,-206,-298,-234,-318,-198,-344,-225,-368,-198,-333,-240,-308,-215,-230,-223,-291,-224,-258,-133,-220,-212,-260,-84,-207,-164,-294,-157,-248,-263,-285,-134,-218,-267,-295,-223,-237,-192,-163,-155,-68,86,-74,-67,-51,-46,-49,-45,-144,-181,-126,-51,-106,-136,-213,-189,-163,-189,-238,-230,-238,-276,-288,-300,-274,-264,-268,-228,-288,-202,-201,-180,-232,-217,-238,-174,-222,-220,-242,-187,-203,-190,-211,-143,-223,-148,-187,-110,-202,-179,-175,-124,-140,-207,-165,-148,-117,-138,-129,-91,-111,-52,-96,-31,-72,-57,-38,-41,-39,-63,-12,-65,-2,-67,12,-64,37,-48,34,-49,20,-4,26,-16,4,-9,34,-12,34,-23}, + /* IRC_Composite_C_R0195_T030_P045.wav */ + {53,-54,56,-58,59,-62,64,-67,70,-73,77,-81,87,-93,100,-110,122,-140,176,-592,-266,-620,-93,-807,111,-1033,-244,-1451,661,-1378,1038,309,3279,-1940,4376,-7187,-1452,-4658,38,22380,4913,3629,1106,-370,-1337,2958,848,-390,-2691,1295,-1155,2599,-36,956,635,787,53,821,200,581,67,983,274,565,247,646,211,751,653,273,546,759,707,776,230,704,98,258,-440,41,-44,-99,-570,-276,125,-89,-316,-287,-67,-256,-409,-175,-243,-300,-369,-371,-102,-291,-350,-382,-109,-199,-343,-360,-210,-168,-316,-283,-194,-249,-97,-252,-166,-374,-161,-245,-317,-297,-364,-202,-337,-267,-324,-305,-165,-347,-151,-302,-171,-371,-213,-207,-334,-383,-313,-191,-297,-398,-235,-273,-140,-391,-214,-292,-119,-316,-254,-221,-194,-227,-232,-269,-229,-362,-187,-364,-206,-335,-144,-247,-146,-237,-158,-174,-97,-117,50,-80,66,-91,178,-80,-68,-202,-96,-198,-132,-223,-177,-186,-153,-217,-140,-249,-182,-298,-91,-285,-230,-334,-153,-250,-218,-295,-154,-260,-140,-294,-141,-233,-87,-273,-133,-222,-68,-214,-169,-225,-107,-209,-114,-264,-92,-242,-49,-295,-99,-226,-66,-252,-85,-193,-65,-189,-57,-171,-14,-172,-4,-179,85,-157,3,-134,92,-113,-4,-109,69,-51,13,-79,68,-27,61,-58,66,-43,79,-23,54,-24,30,-27,66,-41}, + /* IRC_Composite_C_R0195_T045_P045.wav */ + {-71,74,-76,79,-82,84,-87,90,-93,96,-99,101,-102,102,-97,85,-52,-97,-607,-227,-812,438,-1024,-204,-760,95,-1636,140,-766,2279,-763,3056,150,2120,-5760,-6480,1711,-14,24602,5276,1036,-813,1031,1166,848,674,-478,-1487,-945,687,1855,-292,799,1002,786,207,559,505,363,364,343,530,502,11,500,785,837,217,463,907,599,564,357,380,-197,84,-367,169,-530,-810,-282,-180,-171,-519,-179,-442,-72,-160,-239,-494,-294,-88,-553,-268,-512,-278,-503,-198,-473,-229,-317,-213,-370,-187,-331,-249,-344,-154,-381,-135,-317,-147,-279,-176,-355,-133,-274,-305,-330,-235,-314,-312,-303,-290,-257,-159,-269,-234,-243,-173,-350,-204,-383,-239,-309,-233,-404,-183,-289,-321,-344,-212,-319,-251,-253,-168,-303,-204,-277,-189,-284,-216,-333,-204,-348,-208,-298,-166,-339,-189,-186,-273,-152,-87,-184,-166,10,48,-40,2,0,-18,-97,-3,-134,-124,-166,-216,-161,-149,-234,-162,-175,-239,-198,-150,-294,-241,-224,-190,-303,-189,-150,-236,-232,-162,-159,-199,-136,-231,-166,-169,-136,-155,-152,-125,-146,-133,-100,-123,-156,-121,-135,-145,-164,-174,-157,-151,-189,-118,-198,-112,-121,-108,-138,-101,-93,-63,-79,-82,-83,-26,-44,-58,-96,20,-91,-15,-43,22,-69,29,5,6,-19,24,3,1,25,26,26,17,31,13,22,22}, + /* IRC_Composite_C_R0195_T060_P045.wav */ + {59,-58,56,-55,52,-49,45,-40,34,-25,14,1,-23,55,-108,214,-619,-300,-123,-537,-172,-393,-415,-586,-104,-1306,69,-335,1375,535,2761,-686,3824,-8072,-1237,-7735,11382,19138,4865,2658,-2047,1916,571,2806,-624,-694,-1625,70,232,950,-64,1404,-414,1196,34,1403,-261,1089,343,834,-188,587,-251,1086,518,827,135,641,494,842,-31,161,-360,-291,-317,171,-783,-241,-1031,130,-617,-201,-704,-152,-418,-199,-454,-247,-285,-342,-410,-378,-429,-306,-467,-327,-419,-184,-471,-188,-474,-157,-446,-174,-469,-146,-371,-239,-326,-267,-268,-265,-279,-218,-230,-216,-236,-148,-289,-212,-358,-216,-330,-124,-259,-173,-298,-166,-287,-241,-319,-291,-323,-261,-320,-293,-286,-298,-318,-332,-305,-269,-323,-212,-266,-206,-301,-143,-304,-236,-268,-212,-344,-239,-265,-225,-364,-157,-292,-187,-206,-129,-241,-186,-152,-141,-106,-103,-15,-115,56,-68,26,-47,-92,-125,-141,-154,-176,-196,-181,-250,-197,-136,-112,-240,-89,-180,-145,-235,-146,-223,-248,-178,-229,-152,-219,-112,-250,-98,-141,-152,-155,-116,-137,-150,-110,-137,-128,-94,-113,-72,-189,-29,-176,-93,-125,-129,-123,-190,-65,-169,-92,-169,-68,-159,-48,-109,-46,-109,-25,-81,-31,-72,-27,-71,7,-65,-16,-30,-30,-44,30,-39,8,-56,53,-36,81,-51,97,-64,95,-35,60,-30}, + /* IRC_Composite_C_R0195_T075_P045.wav */ + {7,-7,6,-6,5,-5,4,-3,2,0,-2,5,-9,14,-23,45,-729,-86,-463,-18,-765,398,-1336,518,-1262,-130,-544,1878,-781,3861,-694,2694,-2479,-6040,-3168,1816,21907,5475,5383,-2274,1082,1645,3196,-180,-862,-1506,-288,-182,870,-91,1493,-388,779,238,870,64,614,1007,850,122,95,413,1397,214,480,297,844,-36,272,27,-433,-791,-467,60,-441,-446,-697,-441,-417,-402,-239,-587,-268,-547,-343,-464,-296,-435,-388,-347,-416,-430,-420,-403,-296,-406,-376,-408,-228,-422,-330,-353,-273,-416,-325,-234,-301,-372,-327,-219,-336,-296,-307,-215,-240,-202,-250,-161,-199,-207,-315,-154,-247,-142,-267,-158,-266,-221,-313,-201,-303,-302,-339,-264,-278,-318,-314,-301,-319,-312,-315,-204,-334,-223,-340,-127,-300,-165,-343,-198,-307,-246,-285,-207,-293,-254,-293,-183,-246,-202,-252,-100,-213,-78,-138,-60,-197,-164,-160,-109,-141,-50,-142,2,-155,50,-176,0,-217,-67,-265,-39,-241,-180,-198,-196,-186,-182,-111,-135,-134,-125,-176,-98,-184,-100,-212,-114,-228,-113,-95,-140,-143,-141,-78,-133,-100,-67,-178,-75,-161,-2,-319,35,-236,-7,-269,53,-223,-47,-143,-20,-108,-80,-80,-54,-96,-67,-96,-24,-164,-15,-108,-24,-125,-8,-47,-26,-57,4,-8,-39,-35,32,-69,30,-49,58,-82,89,-80,107,-80,104,-56,112}, + /* IRC_Composite_C_R0195_T090_P045.wav */ + {82,-84,86,-88,90,-91,93,-94,95,-95,94,-92,87,-78,61,-33,-240,-426,56,-683,113,-744,373,-1306,284,-1194,1644,-667,2652,-291,4245,-2423,-2014,-4070,-4168,13696,10251,10475,-3031,1940,668,3850,1809,-625,-1492,-994,-456,184,563,568,-96,1027,330,539,32,648,1068,571,102,392,437,1555,535,636,312,223,-470,382,-426,-676,-1277,-176,-342,-251,-706,-452,-477,-459,-100,-511,-346,-481,-454,-509,-470,-397,-448,-337,-587,-233,-611,-143,-563,-280,-521,-364,-455,-244,-466,-275,-326,-321,-388,-219,-441,-210,-415,-297,-415,-244,-390,-213,-373,-184,-325,-193,-152,-257,-243,-230,-170,-254,-69,-214,-166,-228,-242,-227,-305,-281,-292,-232,-343,-218,-305,-280,-254,-331,-243,-363,-249,-287,-245,-320,-255,-262,-272,-215,-275,-191,-269,-200,-292,-200,-287,-217,-267,-214,-217,-218,-189,-189,-148,-203,-120,-154,-118,-165,-102,-132,-161,-134,-144,-132,-168,-94,-134,-87,-100,-96,-67,-104,-58,-178,-114,-154,-134,-226,-145,-224,-215,-130,-174,-117,-174,-71,-88,-63,-109,-58,-78,-120,-50,-84,-79,-101,-63,-97,-110,-65,-129,-123,-160,-83,-162,-109,-152,-92,-143,-76,-108,-73,-110,-42,-74,-64,-99,-35,-69,-11,-79,-57,-78,-51,-41,-69,-60,-68,-23,-64,48,-114,27,-96,75,-109,79,-84,99,-121,109,-64,69,-52,115,-98}, + /* IRC_Composite_C_R0195_T105_P045.wav */ + {28,-30,31,-33,35,-38,40,-43,47,-51,55,-60,67,-75,85,-99,111,-72,-376,-88,-540,307,-524,-278,-931,669,115,481,924,2601,65,2397,-5614,-1324,-2647,10799,8614,10099,118,-2294,4895,2386,2569,-875,-924,-2723,797,264,147,-195,968,521,465,-376,1032,858,1253,-135,495,389,792,755,975,0,305,-239,-39,-629,-469,-1320,-587,-582,-54,-751,-376,-721,-115,-425,-260,-335,-443,-566,-430,-612,-353,-563,-240,-666,-197,-569,-261,-523,-199,-719,-213,-574,-181,-663,-112,-511,-96,-492,-191,-414,-208,-419,-314,-403,-269,-455,-207,-442,-146,-453,-78,-424,-85,-318,-146,-327,-204,-254,-94,-214,-119,-280,-105,-318,-172,-355,-253,-350,-232,-337,-213,-346,-174,-337,-196,-365,-187,-307,-214,-347,-231,-304,-233,-293,-202,-273,-150,-270,-125,-278,-116,-278,-165,-297,-205,-241,-198,-221,-169,-202,-83,-240,-100,-225,-103,-190,-146,-171,-133,-169,-147,-152,-62,-157,-83,-150,-63,-116,-82,-115,-86,-88,-91,-126,-129,-161,-111,-196,-127,-178,-79,-197,-117,-103,-73,-136,-26,-65,-11,-114,16,-69,41,-165,27,-83,-32,-83,-83,-89,-127,-138,-85,-115,-105,-151,-76,-90,-77,-130,-45,-81,-85,-105,-60,-35,-80,-62,-86,-27,-81,-18,-56,-46,-45,-2,5,-61,-31,-63,-14,-64,-36,8,-66,36,-43,73,-62,61,-61,80}, + /* IRC_Composite_C_R0195_T120_P045.wav */ + {-12,12,-13,13,-14,14,-15,16,-17,18,-20,22,-25,29,-34,41,-54,124,-315,231,-915,409,-381,76,-1011,336,-106,1161,-312,2462,834,1649,-538,-4939,-381,2968,10089,6155,8410,-2705,920,4167,3787,745,-2352,-1802,-28,292,-651,645,868,-434,709,424,388,1070,1285,-64,322,849,520,234,673,260,-252,-169,-219,-404,-898,-522,-1000,-760,-659,-37,-489,-625,-480,-117,-279,-318,-554,-444,-479,-476,-447,-397,-506,-426,-374,-367,-517,-341,-428,-392,-509,-321,-429,-316,-424,-291,-372,-230,-336,-266,-337,-314,-357,-245,-417,-326,-393,-223,-400,-276,-346,-207,-347,-196,-289,-214,-324,-195,-253,-149,-240,-179,-253,-165,-279,-187,-327,-224,-367,-235,-338,-247,-316,-185,-311,-218,-272,-162,-301,-187,-304,-196,-322,-148,-322,-157,-312,-104,-274,-142,-240,-141,-246,-193,-235,-171,-192,-186,-214,-189,-212,-181,-191,-123,-229,-156,-208,-159,-193,-117,-178,-146,-179,-127,-164,-97,-166,-64,-139,-51,-149,-26,-150,-13,-111,-43,-117,-85,-121,-102,-128,-113,-107,-143,-80,-75,-82,-86,-55,-52,-89,-61,-20,-13,-63,41,-66,-14,-65,-25,-99,-66,-90,-83,-119,-73,-60,-96,-94,-16,-118,-43,-110,-43,-94,-27,-153,-76,-126,-21,-94,-45,-92,-51,-33,3,-63,-11,-52,-9,-73,9,-41,-20,-40,3,-44,-34,0,0,-32,16}, + /* IRC_Composite_C_R0195_T135_P045.wav */ + {15,-16,17,-18,19,-20,21,-22,23,-24,25,-27,28,-29,29,-28,24,-11,-117,-145,-90,-121,-109,-173,-39,-435,83,-128,1107,344,1609,548,3339,-3005,-2346,-79,2825,6596,9304,4876,-1449,2789,1884,4671,84,-2193,-1608,-211,-70,580,333,233,35,298,-56,1401,612,725,299,829,803,425,-150,290,-261,-139,-438,-491,-740,-322,-692,-659,-1013,-400,-489,-130,-431,-461,-332,-161,-302,-454,-443,-489,-403,-443,-472,-442,-454,-357,-427,-305,-456,-382,-411,-333,-418,-365,-303,-376,-334,-316,-292,-311,-265,-339,-352,-281,-323,-329,-379,-310,-346,-316,-320,-334,-291,-274,-280,-297,-290,-272,-270,-230,-233,-229,-239,-263,-224,-254,-270,-293,-279,-264,-289,-263,-287,-260,-261,-232,-231,-207,-225,-198,-204,-183,-223,-189,-221,-183,-247,-188,-250,-189,-248,-190,-209,-183,-176,-163,-144,-170,-178,-173,-185,-158,-195,-164,-234,-222,-222,-206,-165,-198,-160,-175,-170,-167,-137,-130,-154,-126,-141,-104,-142,-91,-116,-80,-71,-71,-88,-42,-93,-59,-74,-48,-70,-66,-85,-79,-76,-90,-60,-94,-51,-65,-11,-46,-25,-16,-13,-19,-24,-51,-74,-67,-91,-21,-96,-77,-66,2,-73,-36,-56,-44,-134,-42,-35,-70,-118,-47,-68,-116,-72,-82,-75,-136,-24,-85,-36,-90,1,-62,-4,-20,-33,-14,1,-17,-33,-28,-35,-37,-9,-16}, + /* IRC_Composite_C_R0195_T150_P045.wav */ + {13,-14,16,-17,19,-20,22,-25,27,-30,34,-38,42,-48,55,-63,75,-91,119,-208,14,-179,43,-143,14,-237,127,-445,347,318,882,1092,671,2337,-2,-2406,-2033,3403,2686,9080,6065,1654,-385,2378,3537,1656,-964,-2514,-65,-61,604,313,-548,8,506,751,592,750,799,256,788,738,691,-486,-503,-169,-52,-560,-771,-513,-275,-418,-623,-527,-620,-550,-389,-73,-175,-357,-452,-335,-134,-523,-381,-574,-280,-554,-346,-501,-295,-395,-265,-376,-302,-406,-287,-380,-314,-400,-273,-369,-283,-407,-233,-368,-270,-408,-280,-353,-282,-379,-324,-362,-292,-349,-288,-317,-293,-299,-273,-329,-303,-342,-223,-328,-247,-359,-217,-332,-232,-362,-243,-293,-224,-266,-223,-255,-188,-248,-204,-263,-170,-234,-148,-228,-150,-221,-123,-200,-152,-223,-169,-222,-177,-244,-174,-210,-124,-206,-129,-206,-127,-177,-96,-151,-166,-237,-192,-200,-169,-204,-186,-233,-213,-217,-169,-178,-153,-156,-130,-156,-129,-136,-88,-131,-105,-128,-101,-129,-90,-83,-84,-106,-52,-43,-49,-65,-44,-66,-38,-70,26,-76,6,-88,-13,-82,-34,-41,-4,-34,-1,-14,9,-50,-23,-69,-16,-101,-10,-110,-17,-119,-37,-74,-19,-102,-24,-41,-56,-111,-39,-111,-124,-147,-53,-65,-109,-46,-41,-68,-52,-7,-29,-64,-43,-18,-36,-49,-47,1,-26,-14,-36,-17}, + /* IRC_Composite_C_R0195_T165_P045.wav */ + {-5,6,-6,7,-7,8,-9,9,-10,11,-13,14,-16,18,-20,23,-27,31,-37,45,-57,83,-131,98,-140,102,-154,88,-172,82,24,745,704,1159,942,1377,685,-3350,-75,2310,5071,6483,6504,-342,276,2310,3436,1307,-1968,-1879,-504,1149,580,-184,-486,250,728,683,585,651,265,901,267,694,-240,-105,-607,-269,-676,-500,-479,-378,-278,-303,-345,-367,-327,-471,-422,-217,-111,-233,-480,-413,-399,-332,-479,-354,-471,-387,-344,-260,-374,-267,-230,-298,-347,-353,-301,-344,-328,-357,-343,-372,-361,-346,-368,-366,-338,-358,-344,-365,-318,-353,-318,-336,-351,-319,-335,-289,-334,-309,-321,-326,-336,-348,-335,-354,-321,-327,-304,-329,-269,-270,-235,-245,-249,-208,-236,-185,-237,-214,-241,-196,-206,-169,-200,-166,-161,-150,-185,-187,-205,-193,-210,-166,-170,-138,-171,-155,-201,-170,-152,-109,-129,-189,-178,-185,-130,-167,-150,-206,-233,-222,-196,-166,-206,-190,-201,-159,-173,-138,-175,-147,-160,-114,-124,-105,-119,-77,-100,-117,-136,-90,-111,-91,-103,-87,-79,-69,-28,-22,-44,-41,-25,-6,-27,-13,-21,-10,-27,9,1,-13,14,-2,20,6,-17,-7,-23,-45,-82,-88,-89,-86,-91,-67,-101,-82,-96,-74,-71,-81,-64,-98,-60,-94,-66,-105,-103,-119,-65,-33,-28,-21,-24,-24,-66,-22,-25,-29,-63,-45,-61,-77}, + /* IRC_Composite_C_R0195_T180_P045.wav */ + {1,-1,1,-1,2,-2,2,-2,2,-2,2,-2,3,-3,3,-3,3,-4,4,-4,4,-4,3,-2,9,-9,70,-59,121,-126,127,-45,222,619,653,1289,587,1432,300,-1888,-1240,3381,3947,6141,5035,479,-148,2113,2998,773,-1353,-1664,690,1041,-58,-664,-159,711,746,445,284,522,787,289,291,216,96,-622,-296,-616,-684,-562,-153,-193,-156,-160,-230,-111,-119,-291,-584,-298,-144,-240,-398,-579,-379,-509,-208,-402,-311,-292,-227,-267,-259,-266,-213,-263,-327,-375,-294,-371,-362,-434,-364,-436,-381,-431,-375,-404,-373,-398,-329,-365,-326,-409,-345,-385,-333,-367,-288,-357,-297,-388,-309,-398,-314,-430,-330,-408,-271,-349,-243,-310,-230,-234,-197,-214,-201,-187,-203,-238,-232,-238,-212,-225,-205,-211,-176,-179,-201,-211,-228,-202,-224,-150,-202,-129,-214,-123,-184,-94,-133,-120,-193,-166,-163,-113,-144,-135,-197,-168,-225,-183,-213,-177,-199,-157,-207,-155,-195,-92,-173,-121,-200,-130,-155,-103,-148,-111,-166,-85,-143,-56,-147,-56,-154,-59,-141,-36,-120,-42,-95,-13,-67,16,-28,44,-44,24,-33,43,-27,82,-21,103,-17,122,-2,81,-69,27,-35,-19,-94,-112,-111,-109,-91,-94,-119,-134,-85,-80,-83,-129,-79,-97,-58,-112,-41,-119,-24,-104,-33,-99,-41,-79,-41,-68,-44,-36,-44,-71,-84,-70}, + /* IRC_Composite_C_R0195_T195_P045.wav */ + {-10,11,-11,11,-12,12,-12,13,-13,14,-14,15,-15,16,-17,17,-18,19,-20,21,-22,23,-24,26,-28,29,-70,1,21,-50,-12,7,-98,118,-221,432,295,945,530,962,1220,-497,-1827,293,2669,3717,6133,2421,667,647,2517,2286,876,-1019,-811,715,567,146,-552,68,761,748,406,192,794,584,428,293,114,-104,-113,-153,-376,-408,-234,-64,-66,-15,75,-43,-32,-84,-58,-289,-255,-381,-227,-301,-267,-362,-351,-257,-250,-265,-197,-240,-267,-205,-195,-288,-234,-313,-331,-391,-314,-376,-403,-414,-376,-388,-386,-415,-381,-386,-367,-392,-359,-382,-358,-395,-338,-337,-339,-329,-314,-348,-381,-383,-383,-385,-396,-353,-328,-277,-291,-244,-249,-220,-237,-207,-212,-209,-222,-227,-219,-186,-196,-201,-196,-190,-194,-210,-219,-243,-209,-201,-163,-195,-186,-186,-145,-123,-130,-154,-175,-167,-170,-122,-126,-124,-185,-179,-196,-160,-179,-161,-199,-183,-176,-134,-131,-147,-153,-166,-151,-161,-167,-166,-166,-160,-162,-139,-166,-135,-153,-143,-142,-125,-105,-102,-94,-90,-78,-72,-57,-50,-51,-21,-44,-9,-31,-16,-46,-3,-13,24,10,27,32,25,66,-13,-17,-41,-15,-51,-100,-128,-126,-123,-107,-116,-127,-132,-96,-99,-88,-127,-87,-121,-70,-130,-87,-96,-70,-95,-94,-64,-80,-73,-64,-54,-55,-52,-44,-57}, + /* IRC_Composite_C_R0195_T210_P045.wav */ + {-1,1,-1,1,-1,1,-1,1,-2,2,-2,2,-2,2,-2,3,-3,3,-3,4,-4,4,-5,5,-6,6,-7,9,-41,-44,-65,-30,-65,-8,-83,-60,-92,30,110,507,445,762,568,1174,-1167,-1019,628,2221,3797,4340,2039,369,1655,2128,2575,-74,-532,-44,828,327,-261,-60,394,940,522,463,465,701,615,239,186,177,226,24,55,-107,-121,-144,122,80,101,60,168,75,69,-42,-103,-208,-202,-275,-257,-213,-175,-274,-214,-201,-239,-203,-186,-264,-269,-249,-233,-294,-292,-329,-314,-341,-364,-402,-341,-398,-395,-448,-334,-429,-332,-431,-329,-423,-331,-395,-337,-340,-332,-347,-337,-368,-357,-389,-353,-376,-312,-331,-265,-307,-238,-251,-202,-250,-204,-228,-195,-243,-216,-235,-186,-234,-184,-216,-198,-218,-214,-243,-226,-238,-184,-210,-192,-215,-154,-146,-144,-168,-181,-177,-171,-140,-114,-169,-137,-193,-142,-178,-151,-186,-152,-183,-144,-144,-116,-143,-141,-149,-130,-174,-129,-185,-122,-193,-143,-180,-134,-169,-148,-166,-136,-141,-122,-130,-103,-114,-106,-102,-72,-91,-60,-67,-53,-70,-51,-40,-61,-20,-57,16,-56,22,-58,21,-49,-10,-48,3,-48,-36,-55,-46,-67,-83,-96,-101,-127,-82,-139,-122,-145,-101,-121,-109,-139,-130,-124,-118,-116,-120,-95,-97,-71,-73,-66,-58,-48,-24,-31,-11}, + /* IRC_Composite_C_R0195_T225_P045.wav */ + {-3,3,-3,3,-3,3,-3,4,-4,4,-4,4,-4,4,-4,5,-5,5,-5,5,-6,6,-6,7,-7,8,-9,10,-13,20,-75,-97,-66,-47,-85,-74,-101,-34,-123,-132,-22,222,292,490,466,903,275,-1049,-389,584,2358,3669,3152,1258,1261,1738,2331,1624,37,-28,186,674,40,219,313,646,713,656,528,603,598,473,348,444,144,373,151,223,11,95,112,186,158,153,282,115,221,30,18,-91,-32,-200,-106,-202,-164,-212,-141,-234,-274,-248,-205,-234,-252,-279,-220,-289,-259,-337,-286,-358,-337,-398,-361,-383,-377,-397,-403,-387,-416,-383,-391,-375,-383,-384,-351,-350,-337,-371,-325,-339,-314,-362,-307,-327,-273,-302,-260,-293,-265,-270,-253,-272,-249,-242,-222,-243,-203,-221,-193,-215,-188,-249,-219,-244,-222,-251,-227,-225,-219,-214,-206,-186,-149,-158,-170,-204,-178,-182,-146,-152,-156,-169,-175,-163,-157,-142,-159,-167,-156,-155,-165,-170,-148,-148,-131,-118,-114,-117,-133,-119,-145,-148,-151,-147,-145,-167,-157,-166,-139,-171,-158,-145,-135,-121,-133,-97,-119,-63,-84,-67,-101,-69,-67,-57,-75,-59,-62,-49,-63,-41,-77,-33,-68,-14,-83,-22,-64,-11,-77,-48,-83,-73,-129,-98,-117,-128,-152,-116,-144,-123,-154,-107,-170,-138,-138,-97,-115,-107,-82,-89,-65,-72,-83,-58,-72,-30}, + /* IRC_Composite_C_R0195_T240_P045.wav */ + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,-1,1,-1,1,-1,2,-5,-83,-84,-72,-135,-73,-91,-109,-87,-133,-84,-173,-91,-36,199,307,354,685,469,-284,-594,-516,1131,3046,2851,2215,1571,1578,1884,1712,836,241,420,708,320,266,499,693,588,631,732,645,553,384,505,486,415,335,428,309,250,327,166,248,139,364,147,249,184,201,90,89,-4,-84,-57,-140,-149,-268,-170,-229,-181,-241,-235,-260,-225,-272,-259,-355,-270,-344,-221,-429,-254,-394,-305,-443,-348,-406,-390,-405,-383,-420,-382,-385,-345,-366,-308,-315,-295,-317,-301,-307,-307,-319,-316,-337,-273,-310,-260,-332,-260,-287,-238,-267,-235,-236,-259,-223,-218,-231,-226,-221,-205,-245,-216,-236,-203,-244,-208,-224,-221,-211,-210,-180,-186,-192,-188,-204,-183,-150,-161,-144,-182,-151,-199,-152,-176,-159,-170,-168,-142,-147,-118,-110,-117,-97,-125,-84,-116,-88,-125,-124,-122,-160,-117,-177,-157,-199,-179,-171,-156,-148,-174,-137,-139,-117,-130,-135,-112,-124,-104,-131,-80,-123,-82,-99,-80,-101,-46,-83,-75,-90,-80,-63,-59,-51,-122,-65,-82,-66,-92,-66,-83,-92,-88,-117,-122,-158,-126,-150,-152,-142,-139,-83,-139,-101,-146,-84,-121,-95,-110,-91,-88,-79,-72,-47}, + /* IRC_Composite_C_R0195_T255_P045.wav */ + {-1,1,-1,1,-1,1,-1,1,-2,2,-2,2,-2,2,-2,2,-3,3,-3,3,-4,4,-4,5,-5,6,-6,7,-8,10,-12,15,-21,35,-138,-127,-91,-119,-131,-100,-136,-154,-123,-162,-225,-17,208,157,422,539,315,-186,-874,-513,1317,2834,3212,2035,1165,1380,1985,1825,760,470,698,708,299,840,390,551,566,771,555,435,745,529,606,365,682,399,459,406,443,291,358,302,320,305,286,249,233,146,69,90,0,-26,-85,-106,-54,-197,-179,-210,-226,-306,-252,-328,-293,-273,-273,-342,-265,-302,-315,-353,-309,-387,-325,-457,-297,-442,-355,-408,-318,-407,-303,-346,-296,-308,-269,-329,-219,-337,-263,-338,-282,-364,-295,-326,-281,-306,-274,-302,-265,-294,-241,-286,-262,-250,-230,-264,-201,-225,-215,-219,-198,-213,-212,-205,-209,-201,-251,-202,-242,-212,-196,-186,-200,-172,-211,-195,-206,-149,-217,-164,-212,-147,-189,-117,-143,-88,-129,-55,-121,-125,-117,-90,-114,-92,-138,-75,-136,-123,-181,-119,-197,-132,-134,-131,-172,-162,-136,-187,-159,-156,-181,-172,-159,-163,-167,-116,-199,-172,-135,-102,-126,-131,-78,-101,-129,-76,-94,-120,-143,-86,-127,-74,-98,-46,-113,-79,-97,-44,-125,-131,-113,-86,-115,-124,-120,-129,-130,-91,-134,-118,-138,-78,-131,-110,-118,-103,-103,-97,-94,-71,-62,-45}, + /* IRC_Composite_C_R0195_T270_P045.wav */ + {-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,2,-2,3,-3,4,-4,6,-9,16,-64,-161,-143,-126,-145,-185,-145,-161,-193,-254,-120,-230,-52,146,316,329,329,253,-502,-967,-275,2022,3347,2710,947,1504,1884,1375,1901,809,618,609,671,737,376,610,640,652,766,573,669,526,783,441,547,504,550,598,531,667,314,551,275,554,115,507,96,221,103,170,93,44,90,-71,5,-109,-137,-246,-250,-241,-295,-289,-315,-295,-325,-258,-316,-295,-327,-300,-348,-332,-372,-354,-355,-374,-324,-355,-324,-341,-316,-283,-312,-268,-304,-257,-336,-239,-313,-303,-322,-321,-295,-351,-234,-324,-242,-342,-262,-303,-265,-288,-272,-254,-289,-193,-250,-195,-234,-188,-219,-212,-194,-217,-186,-231,-179,-233,-211,-209,-215,-227,-234,-228,-223,-193,-202,-196,-175,-156,-144,-145,-108,-127,-113,-111,-50,-105,-58,-119,-95,-117,-140,-166,-165,-130,-150,-114,-120,-117,-146,-129,-172,-175,-166,-189,-168,-160,-197,-193,-208,-220,-186,-186,-158,-220,-160,-145,-123,-177,-155,-188,-132,-141,-109,-129,-71,-127,-88,-107,-92,-141,-124,-132,-136,-104,-99,-93,-109,-90,-81,-97,-101,-102,-111,-126,-107,-115,-121,-123,-88,-123,-117,-104,-75,-79,-90,-92,-70,-77,-68,-59}, + /* IRC_Composite_C_R0195_T285_P045.wav */ + {5,-5,5,-5,5,-5,5,-5,5,-5,5,-5,5,-5,5,-5,5,-5,5,-5,5,-5,5,-5,5,-5,6,-6,6,-7,8,-12,29,101,50,50,117,188,58,104,258,239,166,306,686,455,833,834,700,494,424,49,743,2627,3265,3156,1306,-112,1114,559,356,246,113,-51,-113,695,8,344,126,384,-46,304,134,58,125,-42,60,-117,150,-115,60,-66,-74,-290,-174,-222,-336,-410,-393,-454,-500,-436,-457,-579,-566,-638,-618,-691,-652,-777,-695,-736,-701,-743,-633,-655,-650,-600,-573,-602,-585,-524,-544,-563,-496,-527,-483,-513,-414,-513,-387,-442,-351,-441,-335,-395,-360,-389,-346,-380,-350,-337,-339,-350,-286,-303,-303,-289,-278,-317,-289,-279,-256,-274,-224,-223,-201,-206,-165,-204,-151,-205,-147,-195,-148,-200,-177,-178,-170,-179,-162,-156,-149,-146,-135,-109,-105,-142,-94,-76,-93,-61,-56,-26,-52,-21,-71,-105,-113,-130,-140,-154,-74,-110,-107,-129,-114,-156,-108,-147,-143,-197,-121,-103,-164,-177,-160,-133,-135,-137,-138,-104,-105,-75,-105,-83,-126,-87,-67,-44,-97,-18,-59,-13,-45,-23,-53,-56,-43,-12,-14,-6,-40,1,-18,27,-19,35,-53,6,-9,7,11,2,-8,-3,22,16,-2,32,44,18,-5,28,17,14,19,9,27,26,56,44,54,64,65,88}, + /* IRC_Composite_C_R0195_T300_P045.wav */ + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,-2,6,-170,-102,-259,-234,-199,-268,-51,-528,-137,-354,-180,92,-180,340,604,11,-371,-583,-984,10,2699,3142,3080,1412,327,1987,956,830,764,347,196,382,1091,294,859,889,945,523,1199,597,582,854,625,694,469,918,446,675,763,646,482,552,534,540,563,394,300,434,396,321,144,359,-94,142,-43,165,-138,6,-183,-179,-221,-161,-328,-285,-267,-402,-333,-327,-294,-327,-363,-296,-325,-259,-291,-320,-304,-304,-298,-291,-297,-314,-280,-329,-297,-314,-281,-234,-352,-241,-283,-217,-315,-280,-263,-279,-310,-268,-299,-296,-261,-277,-280,-277,-225,-216,-261,-203,-214,-192,-239,-227,-233,-213,-266,-208,-195,-200,-197,-191,-188,-186,-205,-150,-205,-153,-112,-151,-87,-35,-120,-124,-179,-137,-157,-174,-117,-144,-171,-153,-152,-138,-131,-174,-135,-128,-150,-114,-214,-174,-206,-228,-215,-210,-194,-196,-208,-219,-189,-187,-156,-164,-222,-168,-262,-148,-197,-176,-237,-214,-212,-100,-129,-146,-213,-165,-123,-124,-133,-162,-159,-151,-116,-118,-122,-155,-138,-137,-123,-99,-108,-104,-101,-84,-78,-75,-64,-83,-84,-92,-41,-94,-60,-107,-53,-86,-49,-66,-60,-68,-31,-65,-31,-29}, + /* IRC_Composite_C_R0195_T315_P045.wav */ + {-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,2,-2,4,-7,17,-100,-204,-340,-371,-160,-344,-275,-415,-419,-249,41,-182,77,891,131,2,-1052,-1535,924,162,4003,4715,1544,1179,621,1424,674,1203,-197,55,273,545,402,710,753,673,897,715,647,832,758,686,732,814,620,688,779,690,604,649,586,620,586,617,478,512,430,467,385,389,275,162,250,131,159,97,100,-42,-92,-107,-156,-193,-270,-280,-274,-295,-312,-336,-301,-367,-310,-306,-332,-327,-275,-299,-308,-302,-264,-320,-240,-345,-250,-325,-245,-353,-231,-309,-234,-308,-240,-335,-236,-284,-266,-330,-242,-316,-259,-281,-275,-309,-222,-254,-279,-277,-236,-254,-242,-235,-247,-199,-188,-240,-203,-141,-139,-214,-131,-200,-170,-111,-70,-193,-145,-148,-101,-173,-117,-218,-163,-214,-197,-208,-111,-206,-113,-191,-104,-100,-70,-142,-89,-169,-106,-184,-156,-187,-185,-255,-195,-151,-192,-223,-180,-149,-215,-245,-216,-248,-232,-230,-274,-292,-203,-223,-171,-218,-208,-215,-141,-139,-194,-204,-163,-184,-155,-159,-154,-164,-134,-151,-130,-134,-130,-152,-122,-129,-133,-120,-106,-118,-102,-72,-84,-69,-84,-65,-68,-55,-55,-56,-72,-45,-57,-43,-50,-64,-34,-44,-40,-36,-22,-14,-32,2}, + /* IRC_Composite_C_R0195_T330_P045.wav */ + {0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,-1,1,-1,1,-1,1,-2,2,-2,3,-4,5,-8,-246,-348,-392,-294,-392,-112,-819,-204,-558,205,-381,275,768,476,319,-1186,-2693,1397,173,2904,7126,2191,1840,-141,1440,643,1148,280,-721,280,227,474,413,704,690,753,889,309,920,476,802,503,682,628,623,869,602,783,626,695,707,691,850,635,757,447,558,418,394,227,133,146,217,152,239,143,20,23,13,-113,-130,-110,-235,-231,-231,-223,-290,-311,-279,-339,-297,-335,-258,-358,-326,-332,-275,-283,-293,-287,-240,-279,-296,-244,-248,-261,-257,-280,-251,-271,-271,-291,-272,-276,-292,-293,-287,-273,-297,-261,-259,-291,-282,-238,-254,-285,-269,-242,-239,-234,-237,-211,-232,-160,-167,-153,-54,-121,-133,-68,-127,-55,-93,-170,-253,-307,-209,-255,-315,-307,-329,-320,-102,-172,-106,-41,-45,45,-125,12,-25,-98,-177,-185,-220,-166,-179,-213,-164,-210,-152,-240,-217,-183,-300,-182,-230,-224,-316,-238,-276,-217,-287,-209,-290,-207,-191,-176,-237,-198,-251,-191,-184,-201,-245,-147,-177,-164,-190,-112,-183,-108,-171,-100,-163,-85,-153,-101,-137,-74,-146,-57,-120,-58,-110,-43,-90,-50,-94,-38,-79,-64,-64,-54,-43,-59,-47,-30,-23,-30,-38,-10,-18,12,-13,10,-24,5}, + /* IRC_Composite_C_R0195_T345_P045.wav */ + {16,-16,16,-16,16,-16,16,-16,16,-15,15,-14,14,-13,11,-9,7,-4,0,5,-13,25,-45,84,-233,-338,-363,-485,-200,-447,-145,-898,-330,-612,95,-690,294,625,1287,-151,69,-4722,1521,-1345,1556,10396,3052,2742,68,1282,287,1583,813,-614,-309,335,28,768,552,558,584,902,480,734,438,738,500,576,491,546,493,681,435,611,561,752,683,864,812,738,819,537,703,581,367,218,0,254,20,344,-127,37,-166,211,-28,-62,-54,-160,-27,-117,-166,-287,-249,-103,-237,-262,-426,-232,-222,-305,-355,-320,-241,-298,-264,-311,-247,-264,-248,-253,-288,-211,-240,-212,-321,-248,-261,-248,-306,-335,-270,-295,-235,-360,-279,-274,-198,-287,-320,-253,-257,-194,-270,-236,-243,-201,-255,-169,-230,-203,-38,-204,-189,64,-47,-32,-96,-24,-149,-249,-211,-363,-445,-322,-199,-451,-374,-212,-206,-56,-101,52,-41,90,144,4,-84,38,-111,-234,-118,-217,-227,-246,-157,-274,-235,-253,-192,-341,-200,-287,-253,-258,-299,-242,-317,-247,-273,-208,-264,-246,-273,-176,-209,-205,-204,-238,-186,-184,-158,-218,-216,-193,-143,-174,-141,-179,-144,-152,-78,-161,-124,-122,-54,-126,-102,-95,-62,-64,-102,-54,-75,-51,-32,-78,-64,-53,-39,-81,-33,-75,-14,-32,-27,-68,2,-35,2,-22,5,-24,24,-12,-6,0}}; + +const int16_t irc_composite_c_r0195_p060[][256] = + {/* IRC_Composite_C_R0195_T000_P060.wav */ + {6,-6,6,-6,6,-6,6,-6,6,-6,6,-6,6,-6,5,-5,5,-6,7,-9,18,-62,-477,-304,-336,-458,-335,-491,-402,-829,-409,-707,-293,-66,983,571,504,539,-3665,-1218,-4247,2405,12687,3792,3387,222,562,745,2239,1323,-741,-286,-83,813,783,665,-6,1300,432,669,373,824,513,741,332,740,326,679,126,625,66,777,213,737,590,515,621,819,662,597,612,571,221,378,180,456,-17,193,-19,201,-103,188,-114,-50,-223,41,-272,-7,-204,-73,-274,-27,-179,-118,-266,-52,-236,-150,-298,-185,-328,-211,-330,-359,-321,-288,-288,-390,-233,-301,-238,-287,-186,-257,-179,-231,-185,-249,-207,-244,-242,-257,-261,-239,-326,-213,-312,-252,-311,-214,-308,-230,-270,-210,-269,-227,-231,-256,-281,-231,-249,-231,-210,-238,-174,-214,-204,-218,-156,-225,-179,-158,-114,-151,-171,-128,-150,-184,-87,-97,-145,-171,-201,-199,-179,-259,-239,-309,-310,-314,-227,-196,-170,-192,-26,-115,43,-61,74,-180,-52,-139,-83,-192,-18,-187,-104,-111,-67,-175,-118,-149,-164,-160,-118,-201,-219,-161,-187,-241,-189,-199,-195,-205,-163,-179,-154,-122,-150,-171,-167,-152,-190,-183,-192,-193,-159,-180,-150,-160,-87,-151,-131,-124,-50,-117,-92,-81,-58,-70,-16,-38,-34,-12,39,-10,47,38,87,17,83,31,82,15,52,1}, + /* IRC_Composite_C_R0195_T030_P060.wav */ + {20,-21,22,-23,24,-25,26,-28,29,-31,33,-35,37,-40,44,-49,57,-69,99,-268,-386,-296,-341,-306,-439,-461,-219,-926,-450,-515,-185,-151,2064,-248,2208,-557,-2551,-2664,-6482,6173,13499,9000,-215,137,1397,897,1847,1331,-989,-1152,-31,458,894,968,314,922,758,306,312,862,265,458,604,466,114,555,424,349,321,475,497,583,497,442,464,481,505,592,441,239,76,20,163,45,-273,-262,-336,-166,-64,-152,-189,-166,-140,-223,-230,-243,-348,-277,-328,-243,-252,-223,-247,-223,-225,-225,-211,-310,-229,-259,-253,-320,-259,-356,-330,-309,-289,-302,-271,-256,-257,-245,-269,-281,-283,-267,-256,-268,-267,-280,-263,-261,-261,-284,-289,-275,-272,-247,-274,-279,-271,-276,-305,-292,-268,-282,-266,-248,-248,-229,-247,-221,-202,-217,-233,-213,-204,-239,-209,-216,-194,-227,-155,-201,-185,-243,-159,-264,-210,-189,-201,-282,-175,-151,-178,-186,-73,-151,-201,-182,-71,-254,-132,-94,-52,-235,-22,-27,-101,-159,-17,-130,-166,-55,-23,-206,-132,-126,-159,-211,-63,-187,-189,-148,-84,-174,-142,-124,-126,-185,-149,-155,-156,-187,-149,-205,-136,-153,-105,-164,-138,-137,-75,-158,-128,-135,-115,-148,-94,-125,-133,-123,-51,-120,-102,-85,-18,-84,-52,-42,8,-51,10,0,9,-20,40,16,14,24,69,21,25,23,33,2}, + /* IRC_Composite_C_R0195_T060_P060.wav */ + {49,-49,50,-50,49,-49,48,-47,45,-43,39,-34,27,-17,1,24,-67,158,-573,27,-273,-533,-199,-358,-57,-1237,277,-801,-585,81,1678,-52,2584,-635,2281,-6550,-1907,-4733,12287,16138,2134,560,-1141,3390,1047,2071,-850,-288,-1730,541,499,654,282,1081,13,1053,-59,982,296,639,439,387,97,735,-102,457,298,541,229,951,144,642,-123,725,239,371,-407,173,-217,5,-418,64,-709,-238,-708,-195,-402,-221,-414,-199,-238,-175,-279,-243,-447,-227,-531,-270,-429,-178,-455,-173,-350,-170,-312,-238,-284,-268,-355,-248,-402,-300,-358,-251,-472,-244,-350,-274,-353,-195,-309,-279,-276,-243,-232,-248,-185,-198,-344,-177,-263,-274,-355,-198,-341,-222,-358,-178,-344,-238,-289,-271,-338,-286,-218,-316,-206,-256,-230,-264,-214,-239,-277,-261,-259,-225,-268,-221,-134,-246,-182,-192,-154,-260,-116,-218,-234,-234,-227,-254,-254,-224,-164,-220,-284,-56,-257,-45,-289,-17,-299,22,-225,103,-264,-36,-33,-158,-37,-147,39,-238,-62,-117,-69,-262,42,-153,-162,-86,-22,-214,-31,-193,-19,-225,-87,-128,-143,-84,-102,-114,-95,-106,-146,-143,-5,-308,-86,-140,-102,-254,41,-68,-208,37,-26,-47,-124,31,-99,-131,-35,-104,-59,-141,32,-115,3,-48,1,-54,32,-67,-4,-31,-40,-50,45,-30,-17,43,3,8,10,37}, + /* IRC_Composite_C_R0195_T090_P060.wav */ + {20,-22,23,-25,26,-28,30,-33,35,-38,41,-45,49,-54,60,-66,75,-87,-10,-413,-67,-233,-277,-289,-247,-282,-617,-150,-183,967,613,1964,132,3132,-4890,-30,-7492,6867,13211,9263,1898,-2424,3417,1010,3400,-250,-877,-1856,320,-121,560,520,754,353,491,-65,931,362,494,135,792,604,460,-39,664,258,476,82,671,151,141,64,562,-256,-248,-550,-170,-357,-396,-602,-158,-390,-415,-610,-298,-495,-302,-712,-205,-411,-237,-411,-197,-452,-250,-501,-239,-421,-284,-481,-170,-438,-181,-420,-184,-419,-262,-417,-218,-376,-336,-394,-333,-356,-335,-390,-304,-355,-247,-352,-237,-395,-250,-384,-156,-227,-147,-266,-148,-197,-207,-288,-280,-286,-312,-317,-266,-316,-238,-306,-223,-320,-187,-342,-177,-339,-198,-318,-212,-319,-219,-304,-241,-273,-207,-279,-190,-248,-107,-255,-126,-251,-112,-272,-95,-249,-163,-250,-133,-247,-177,-254,-198,-235,-194,-229,-212,-194,-191,-142,-191,-92,-153,-45,-145,-65,-138,-64,-93,-82,-65,-113,-49,-140,-78,-118,-32,-137,-37,-107,-30,-59,-142,-106,-132,-11,-240,49,-159,20,-179,55,-117,-17,-81,-27,-68,-101,-72,-98,-48,-107,-136,-19,-93,-74,-119,94,-211,28,-129,49,-157,78,-96,21,-143,105,-58,-15,-28,13,-42,14,-40,-16,-41,-38,-39,21,-40,-15,-19,-23,-62,3}, + /* IRC_Composite_C_R0195_T120_P060.wav */ + {-11,11,-11,11,-11,10,-10,10,-9,9,-8,7,-6,4,-1,-4,11,-23,54,-588,228,-347,10,-393,78,-279,-133,-619,373,107,880,1033,1066,2024,-241,-1833,-4036,1812,3742,13338,5090,1325,-1146,2733,2814,1516,-118,-2246,-488,96,262,192,815,13,476,529,495,181,475,265,780,210,341,81,498,784,541,47,-30,-8,36,-29,-17,-592,-609,-210,-251,-604,-616,-485,-190,-407,-234,-662,-290,-550,-301,-639,-361,-458,-250,-462,-279,-431,-205,-390,-287,-423,-271,-396,-265,-443,-263,-432,-176,-477,-278,-447,-188,-475,-218,-453,-216,-462,-223,-420,-282,-431,-248,-385,-293,-403,-276,-425,-204,-367,-74,-400,-116,-375,-65,-372,-120,-338,-171,-350,-192,-321,-226,-351,-196,-350,-234,-344,-164,-341,-158,-306,-138,-338,-156,-268,-116,-265,-176,-243,-204,-212,-198,-229,-226,-192,-144,-137,-153,-181,-152,-194,-135,-178,-195,-187,-227,-175,-208,-170,-244,-159,-254,-137,-245,-163,-226,-152,-162,-107,-156,-107,-123,-75,-95,-2,-107,-23,-62,-12,-74,-60,-54,-88,-41,-86,-11,-107,-13,-74,-29,-98,-23,-52,-89,-64,-61,-71,-89,-73,19,-96,13,-86,41,-106,92,-5,1,-25,-7,-37,-56,34,-91,-24,-86,10,-49,-33,-31,-56,10,-83,56,-62,45,-72,47,-53,7,-38,12,-40,-11,-4,-41,-34,-33,-33}, + /* IRC_Composite_C_R0195_T150_P060.wav */ + {-16,16,-17,17,-18,18,-19,20,-20,21,-21,22,-22,23,-23,23,-23,22,-20,15,-1,-129,61,-83,-118,-17,-51,-30,-188,-95,109,510,730,1005,940,2137,-1039,-410,-2971,1165,5406,9365,3937,2137,-649,991,4216,933,-931,-1885,270,39,471,-2,92,175,614,97,357,338,829,636,315,-32,510,435,434,61,257,-175,-293,-260,-101,-474,-492,-360,-265,-315,-367,-291,-300,-567,-400,-366,-215,-495,-451,-522,-369,-523,-275,-402,-310,-403,-263,-346,-267,-319,-256,-370,-300,-367,-298,-401,-295,-443,-304,-417,-322,-444,-298,-381,-312,-439,-329,-390,-317,-384,-301,-362,-302,-383,-295,-368,-322,-392,-272,-324,-246,-326,-211,-303,-225,-323,-240,-326,-214,-295,-235,-325,-259,-307,-231,-265,-204,-266,-221,-283,-193,-226,-150,-215,-156,-235,-140,-226,-173,-226,-138,-181,-139,-211,-149,-228,-146,-230,-122,-202,-104,-157,-89,-169,-122,-180,-141,-172,-119,-242,-182,-247,-146,-221,-160,-209,-160,-222,-134,-194,-158,-172,-105,-115,-90,-104,-68,-78,-70,-76,-8,-32,19,-27,16,-5,-14,-32,0,-60,-11,-71,10,-79,-60,-81,-34,-99,-28,-10,-16,0,23,9,-66,-19,-7,-4,-45,41,7,-5,-25,-4,7,-31,-3,22,-19,-42,6,-62,-7,-36,56,-32,47,-21,39,-84,-6,-47,-14,-45,33,-19,-3,-57}, + /* IRC_Composite_C_R0195_T180_P060.wav */ + {10,-10,10,-11,11,-10,10,-10,10,-10,10,-10,9,-9,8,-7,6,-5,3,-1,-2,6,-12,19,-22,153,-20,-54,110,44,10,-80,172,36,605,639,998,719,1758,-623,-249,-1810,1268,4590,6942,3540,1131,148,816,4013,533,-755,-1438,271,-13,605,142,55,202,291,-131,465,665,844,217,120,213,663,92,-57,-100,67,-191,-270,-528,-381,-572,-177,-319,-6,-278,-198,-211,58,-313,-463,-592,-248,-465,-368,-496,-344,-514,-270,-361,-242,-341,-263,-349,-193,-335,-278,-416,-272,-416,-335,-439,-313,-451,-348,-453,-349,-443,-392,-472,-363,-430,-386,-408,-312,-392,-320,-379,-310,-370,-331,-403,-335,-385,-348,-366,-269,-311,-276,-302,-234,-290,-316,-341,-275,-241,-217,-208,-227,-228,-238,-222,-184,-224,-208,-241,-186,-232,-205,-245,-203,-214,-163,-151,-128,-135,-145,-180,-187,-204,-171,-188,-145,-158,-112,-157,-75,-116,-69,-149,-129,-160,-136,-115,-133,-152,-184,-177,-167,-165,-197,-218,-169,-194,-138,-205,-133,-162,-112,-132,-87,-117,-57,-79,-38,-55,-39,-50,-29,-58,-18,2,13,-3,31,17,9,8,29,-11,-10,-3,19,-49,-35,-14,-39,-21,-64,-32,-53,-24,-15,-14,-23,27,17,51,-9,-15,-18,18,-37,5,-74,-13,-18,63,0,46,7,63,-15,19,-10,7,-30,-32,-44,-79,-107}, + /* IRC_Composite_C_R0195_T210_P060.wav */ + {-5,5,-5,5,-5,5,-5,5,-5,5,-5,5,-5,5,-5,5,-5,5,-5,5,-5,5,-4,4,-4,4,-4,-36,-70,2,-43,-45,-73,17,-83,-76,-100,274,192,709,499,1049,474,192,-1587,-214,1449,4357,5043,2092,784,976,2790,1402,1131,-633,70,310,385,217,300,87,393,309,640,644,573,357,469,403,414,393,291,95,9,177,41,-38,-147,-145,-178,-91,51,-23,82,6,81,-66,-34,-205,-207,-298,-223,-348,-275,-305,-257,-377,-308,-322,-230,-324,-269,-300,-305,-334,-286,-346,-334,-384,-351,-411,-405,-389,-413,-415,-387,-382,-401,-384,-393,-405,-388,-417,-364,-399,-357,-398,-374,-392,-376,-343,-359,-316,-314,-243,-324,-280,-326,-283,-293,-262,-262,-275,-249,-231,-206,-195,-215,-224,-241,-210,-220,-242,-276,-255,-264,-198,-192,-190,-189,-210,-164,-172,-169,-172,-189,-153,-193,-127,-166,-117,-158,-112,-128,-133,-107,-136,-117,-161,-108,-110,-142,-127,-184,-138,-172,-147,-192,-188,-193,-158,-153,-183,-168,-189,-142,-164,-152,-151,-135,-105,-91,-78,-46,-70,-9,-22,-10,6,-3,11,9,0,-18,-34,-49,-47,-78,-56,-80,-88,-84,-41,-76,-89,-89,-34,-62,21,-11,29,-63,38,13,32,-26,-6,-18,-15,-14,-11,-43,-37,-18,40,-10,3,-52,3,-65,-18,-66,-33,-83,-53}, + /* IRC_Composite_C_R0195_T240_P060.wav */ + {-5,5,-5,5,-5,6,-6,6,-6,6,-6,6,-6,6,-6,6,-6,6,-6,6,-6,7,-7,7,-6,6,-6,4,1,-68,-141,-43,-120,-98,-71,-122,-111,-111,-115,-151,-61,253,299,522,567,502,242,-1198,-647,857,3187,4265,2111,1152,1068,2588,1288,1124,171,189,245,613,495,306,631,410,664,513,726,614,455,361,493,538,415,305,397,398,328,162,355,127,167,95,91,92,127,159,137,126,136,112,42,-54,-59,-214,-99,-334,-210,-340,-229,-357,-264,-345,-232,-312,-253,-294,-304,-352,-288,-347,-349,-364,-352,-373,-394,-376,-368,-434,-376,-402,-393,-434,-406,-412,-357,-430,-351,-354,-374,-337,-289,-323,-276,-287,-233,-304,-270,-311,-283,-321,-267,-321,-256,-305,-231,-272,-202,-256,-217,-272,-229,-238,-234,-247,-261,-261,-253,-218,-198,-218,-190,-226,-148,-209,-150,-201,-174,-181,-174,-172,-158,-155,-141,-131,-122,-138,-117,-118,-119,-130,-144,-143,-130,-146,-135,-155,-149,-172,-147,-158,-167,-175,-169,-144,-176,-150,-108,-129,-129,-136,-93,-143,-97,-99,-87,-71,-74,-15,-38,-48,-75,-66,-95,-101,-91,-93,-103,-154,-122,-128,-116,-84,-70,-79,-65,-51,-28,-23,-20,-21,-53,-15,-9,15,-49,5,-40,-18,-42,-33,-30,-86,-81,-68,-62,-85,-44,-26,-89,-49,-55,-24,-61,-16}, + /* IRC_Composite_C_R0195_T270_P060.wav */ + {5,-5,6,-6,6,-6,6,-6,7,-7,7,-7,8,-8,8,-9,9,-10,10,-11,12,-12,13,-15,16,-19,22,-27,38,-79,-217,-116,-99,-179,-211,-36,-231,-204,-130,-219,-231,-133,80,277,396,430,429,-88,-768,-1080,327,3345,4354,1751,849,1821,1217,1828,885,517,269,311,1017,365,820,357,716,549,590,621,516,736,326,780,263,770,281,705,378,636,371,475,311,429,255,409,238,273,140,314,213,208,138,105,115,-23,74,-205,-25,-248,-155,-287,-280,-252,-297,-307,-288,-293,-267,-333,-245,-352,-304,-348,-348,-351,-433,-337,-451,-334,-472,-324,-423,-375,-381,-372,-314,-375,-276,-267,-321,-301,-279,-273,-291,-287,-302,-304,-304,-290,-236,-296,-289,-263,-294,-284,-324,-265,-281,-292,-245,-245,-266,-260,-214,-224,-254,-200,-260,-209,-252,-220,-200,-254,-196,-233,-158,-228,-136,-185,-148,-205,-143,-175,-148,-149,-166,-120,-148,-104,-128,-140,-125,-152,-101,-130,-77,-199,-88,-178,-108,-197,-126,-198,-117,-194,-113,-172,-133,-128,-87,-131,-57,-112,-60,-136,-71,-150,-125,-162,-106,-205,-139,-165,-138,-149,-118,-134,-84,-134,-83,-120,-64,-109,-79,-116,-53,-90,-64,-49,-97,-69,-54,-86,-38,-63,-120,-64,-43,-89,-78,-45,-32,-110,-9,-49,-30,-91,-36,-87,-34,-90,-12,-62,-20,-67}, + /* IRC_Composite_C_R0195_T300_P060.wav */ + {5,-5,5,-5,6,-6,6,-6,6,-6,6,-6,6,-7,7,-7,7,-7,7,-8,8,-8,8,-9,9,-9,10,-11,16,-103,-316,-221,-172,-255,-229,-364,-48,-533,-236,-67,-300,259,642,185,100,427,-1196,-1745,476,2467,5309,2589,680,1682,925,1569,1041,949,-237,234,798,421,371,569,750,604,969,544,826,529,786,297,628,582,490,514,782,585,536,518,533,446,484,585,264,478,477,367,328,417,65,219,65,246,-91,156,-64,72,-138,50,-297,-48,-254,-210,-356,-206,-256,-287,-317,-214,-367,-254,-373,-339,-401,-317,-430,-376,-368,-350,-418,-316,-298,-353,-273,-305,-281,-287,-227,-371,-293,-252,-310,-323,-260,-272,-324,-243,-257,-310,-290,-276,-297,-255,-201,-324,-280,-270,-230,-282,-221,-248,-298,-222,-268,-241,-260,-255,-277,-235,-187,-236,-210,-172,-224,-173,-145,-191,-157,-155,-157,-126,-186,-84,-150,-177,-153,-72,-128,-133,-127,-100,-229,-197,-160,-241,-236,-171,-176,-120,-75,-47,-120,-105,-128,-76,-160,-120,-127,-109,-139,-135,-144,-192,-179,-152,-203,-173,-143,-161,-61,-179,-143,-104,-126,-147,-78,-176,-138,-177,-87,-160,-110,-137,-186,-155,-86,-135,-127,-105,-97,-124,-34,-111,-50,-117,-72,-123,-75,-65,-94,-51,-83,-75,-56,-47,-45,-13,-39,-55,20,-56,36,-41,12,-24}, + /* IRC_Composite_C_R0195_T330_P060.wav */ + {3,-3,4,-4,4,-4,5,-5,5,-6,6,-6,7,-7,8,-9,10,-11,13,-15,18,-22,28,-41,71,-233,-373,-96,-345,-318,-371,-265,-252,-594,-439,-312,-197,197,323,301,1318,-757,-1616,-868,-2081,2422,6337,5378,1528,381,1195,1007,1545,810,158,-165,224,315,652,555,370,728,945,600,540,730,606,560,567,567,493,662,473,574,547,639,468,638,527,625,475,584,476,643,403,465,284,372,243,235,43,108,49,102,20,-28,-86,-48,-49,-120,-149,-133,-123,-173,-198,-229,-246,-291,-242,-300,-328,-373,-296,-357,-299,-377,-351,-356,-276,-311,-324,-289,-282,-268,-271,-255,-256,-273,-249,-285,-230,-270,-219,-299,-282,-269,-275,-287,-307,-267,-290,-268,-297,-284,-263,-248,-257,-244,-243,-257,-290,-273,-259,-265,-237,-261,-238,-273,-209,-234,-171,-171,-157,-118,-120,-137,-80,-115,-96,-166,-45,-140,-79,-126,-114,-259,-243,-265,-228,-274,-267,-264,-220,-203,-117,-137,-118,-112,-33,-82,-41,-93,-102,-121,-120,-145,-175,-177,-147,-143,-65,-127,-138,-136,-94,-127,-130,-217,-183,-159,-168,-202,-184,-203,-240,-202,-146,-195,-160,-147,-169,-143,-72,-128,-191,-139,-128,-170,-166,-129,-160,-152,-97,-112,-123,-68,-72,-87,-76,-27,-63,-48,-50,-16,-43,16,-15,-10,-1,57,47,30,49,50,35,14}}; + +const int16_t irc_composite_c_r0195_p075[][256] = + {/* IRC_Composite_C_R0195_T000_P075.wav */ + {12,-12,13,-13,13,-13,13,-13,14,-14,14,-14,14,-14,15,-15,14,-14,13,-12,7,8,-224,-367,-189,-595,-344,-165,-801,-581,-302,-836,-618,407,530,134,1455,-966,-265,-4329,-4113,4525,6992,8542,304,-199,2762,1323,1544,1359,195,-1272,815,548,454,489,1188,303,1217,433,606,486,940,200,865,394,415,452,439,167,687,262,388,668,618,250,776,505,518,525,594,287,552,461,358,276,304,160,239,30,35,-21,-62,-125,-17,-31,-371,39,-211,-122,-197,40,-391,72,-166,-93,-262,-84,-337,-76,-325,-174,-301,-196,-378,-120,-367,-324,-293,-268,-402,-208,-271,-377,-322,-212,-314,-262,-200,-245,-294,-186,-222,-275,-226,-280,-246,-300,-262,-182,-254,-272,-206,-217,-307,-182,-214,-248,-250,-184,-258,-303,-196,-229,-312,-240,-213,-256,-268,-167,-202,-256,-145,-174,-141,-306,-39,-235,-192,-132,-161,-142,-205,-78,-192,-93,-268,-65,-239,-166,-229,-88,-215,-227,-134,-262,-99,-230,-94,-297,-147,-247,-15,-245,-197,-51,-171,-94,-46,-60,-97,-14,-100,14,-99,-80,-92,-24,-178,55,-112,-23,-104,47,-121,-73,-80,-27,-196,-98,-74,-188,-162,-54,-110,-182,-133,-30,-121,-83,-72,-116,-145,-93,-89,-136,-159,-163,-75,-145,-145,-85,-61,-103,-107,5,-74,-43,-3,-22,-72,-26,-24,6,-85,5}, + /* IRC_Composite_C_R0195_T060_P075.wav */ + {-14,15,-15,16,-17,18,-19,20,-21,22,-23,24,-25,27,-28,30,-32,35,-42,65,-281,-389,123,-583,-268,-119,-384,-436,-660,282,-1424,931,-191,1870,-113,1526,243,-2974,-2922,-3038,6766,14120,3000,-177,427,2482,2472,607,1128,-2092,683,-982,2038,-839,1456,-30,1050,188,720,669,391,864,257,483,214,493,238,321,378,114,592,45,886,-9,646,103,701,13,345,57,116,121,-88,171,-386,97,-335,-262,-369,-373,-308,-409,33,-533,5,-484,24,-435,-237,-319,-208,-233,-416,-146,-317,-166,-309,-232,-304,-340,-158,-439,-169,-482,-113,-521,-200,-450,-258,-409,-296,-298,-425,-296,-402,-280,-434,-185,-317,-227,-279,-194,-241,-311,-232,-320,-314,-306,-233,-329,-276,-236,-245,-297,-256,-187,-267,-262,-210,-246,-287,-248,-205,-331,-278,-229,-232,-260,-191,-174,-217,-208,-141,-202,-243,-151,-110,-284,-132,-132,-134,-277,-115,-207,-229,-254,-153,-213,-329,-111,-236,-248,-245,-82,-281,-102,-144,-93,-133,-52,-82,-139,-23,-121,-40,-135,7,-127,-34,-127,-9,-67,-119,-37,-34,-134,4,-70,-77,-81,-62,-64,-127,-18,-109,11,-156,60,-224,27,-77,-130,6,-101,-38,-151,93,-175,-123,0,-32,-129,-111,115,-229,-48,12,-46,-196,-37,-14,-163,-83,-1,-137,-48,-101,91,-141,15,-60,28,-35,-33,-10,-28}, + /* IRC_Composite_C_R0195_T120_P075.wav */ + {-13,13,-14,14,-15,15,-16,16,-17,17,-18,18,-19,19,-20,20,-19,19,-16,12,-1,-57,-48,-189,-132,-75,-227,-56,-343,28,-501,199,201,917,964,1130,545,1226,-3782,-981,-1166,8252,10379,3341,-521,-669,4572,428,2096,-1386,-405,-1098,1383,-2,236,525,510,124,361,340,604,403,459,20,703,550,361,4,507,76,379,200,87,66,-36,226,133,30,-418,-183,-144,-119,-262,-333,-294,-550,-263,-353,-297,-518,-525,-481,-405,-172,-382,-282,-383,-195,-329,-205,-358,-340,-304,-296,-417,-305,-321,-319,-400,-254,-454,-283,-418,-294,-482,-262,-427,-329,-482,-271,-419,-319,-403,-345,-351,-373,-409,-381,-310,-297,-225,-271,-290,-302,-223,-252,-250,-249,-220,-293,-267,-259,-270,-267,-281,-238,-321,-208,-300,-203,-357,-197,-295,-169,-277,-177,-273,-210,-234,-196,-252,-188,-188,-144,-221,-121,-160,-150,-180,-111,-124,-171,-110,-188,-133,-213,-124,-220,-168,-203,-176,-182,-229,-156,-255,-117,-221,-99,-240,-61,-158,-122,-129,-39,-92,-133,4,-74,-53,-77,35,-129,8,-50,5,-61,-24,-33,-46,31,-56,58,-35,39,-37,57,-74,2,-108,-10,-136,18,-141,8,-114,4,-132,-22,-37,-31,-20,-71,79,-149,14,-32,50,-85,-47,94,-59,21,-39,82,-145,47,-47,-14,-82,-16,-3,-58,-48,-44,-22,-40}, + /* IRC_Composite_C_R0195_T180_P075.wav */ + {-17,17,-17,17,-16,16,-16,16,-15,15,-15,14,-14,14,-13,12,-12,11,-10,9,-7,5,-2,-2,11,164,-118,156,-74,171,-166,281,-259,331,-163,647,483,1342,96,2125,-652,369,-2506,1012,3788,6928,5436,-854,927,1011,2973,419,642,-1377,-224,371,309,-128,78,268,228,233,434,427,397,-91,692,541,379,-60,222,-23,131,178,60,-172,-56,-82,-145,-311,-297,-431,-248,-412,-107,-371,-72,-353,-277,-448,-332,-408,-362,-461,-379,-530,-388,-407,-290,-364,-334,-409,-288,-419,-285,-384,-338,-447,-343,-386,-344,-453,-378,-390,-377,-502,-386,-429,-361,-457,-343,-463,-441,-462,-348,-398,-369,-416,-375,-435,-312,-336,-244,-309,-307,-321,-263,-272,-272,-262,-236,-196,-217,-232,-215,-261,-261,-304,-256,-296,-220,-241,-218,-248,-199,-190,-206,-213,-223,-195,-209,-182,-150,-161,-155,-165,-145,-155,-129,-127,-102,-102,-126,-107,-145,-133,-143,-141,-131,-140,-117,-119,-86,-121,-100,-131,-130,-130,-139,-142,-162,-155,-148,-128,-171,-136,-140,-117,-101,-76,-112,-44,-78,-20,-37,-38,-18,15,-6,2,39,44,55,-20,46,41,30,8,37,20,-14,0,-10,0,-57,-38,-55,-62,-113,-27,-88,-33,-69,-21,-80,1,-86,62,-11,16,23,128,6,102,-12,152,3,46,29,36,-97,2,-15,22,-109,-54}, + /* IRC_Composite_C_R0195_T240_P075.wav */ + {3,-3,3,-3,3,-3,3,-2,2,-2,2,-2,1,-1,1,0,0,1,-2,3,-4,5,-7,10,-13,20,-42,-111,-129,-71,-115,-137,-61,-159,-123,-192,-19,-219,406,390,680,549,886,-353,-736,-1471,543,4694,6064,1476,785,1081,2341,1848,567,793,-1054,878,-19,694,-27,624,453,574,713,561,524,289,447,341,517,436,227,504,311,411,259,396,204,319,114,96,38,-78,39,-23,9,123,-104,210,-61,44,-245,-60,-225,-163,-284,-292,-366,-364,-318,-284,-326,-284,-257,-269,-279,-348,-246,-376,-367,-329,-388,-355,-428,-316,-418,-375,-426,-318,-396,-436,-393,-407,-383,-405,-383,-442,-422,-393,-344,-375,-309,-340,-270,-311,-270,-269,-256,-268,-233,-283,-233,-230,-236,-283,-256,-265,-301,-274,-317,-261,-298,-265,-239,-262,-221,-248,-188,-287,-192,-249,-152,-246,-140,-231,-148,-218,-130,-170,-165,-154,-171,-127,-181,-99,-138,-109,-120,-99,-88,-129,-61,-150,-63,-199,-44,-206,-106,-201,-113,-189,-182,-146,-180,-174,-177,-146,-150,-167,-103,-131,-76,-138,-14,-119,-32,-66,-17,-34,-48,8,-80,-30,-22,-34,-12,-52,1,-29,-7,12,-34,-30,-36,-43,-95,-29,-80,-102,-17,-119,-24,-119,10,-78,-16,-105,-38,-66,-45,-15,9,-36,-32,33,-12,-9,-66,-12,-59,8,-23,-10,-6,-22}, + /* IRC_Composite_C_R0195_T300_P075.wav */ + {5,-5,5,-6,6,-6,6,-7,7,-7,8,-8,9,-9,10,-10,11,-12,13,-14,16,-19,23,-30,49,-174,-216,-220,-266,-146,-276,-310,-167,-398,-257,-446,-119,2,150,904,282,399,-249,-994,-2605,51,5569,5353,3304,-294,1237,2394,748,1912,84,-494,511,465,372,641,761,120,1277,373,764,283,1087,-27,731,558,213,625,490,578,331,755,261,576,308,533,270,531,241,337,345,292,249,254,130,252,95,124,0,-94,22,-124,-166,-120,-222,-195,-188,-102,-288,-138,-247,-177,-285,-135,-368,-230,-298,-370,-301,-355,-365,-394,-255,-460,-300,-338,-376,-356,-289,-388,-412,-303,-449,-224,-403,-214,-327,-319,-233,-280,-268,-283,-281,-308,-227,-300,-251,-210,-330,-195,-309,-196,-294,-197,-342,-211,-310,-249,-268,-272,-295,-243,-275,-237,-249,-206,-274,-172,-248,-191,-211,-154,-258,-145,-194,-183,-134,-143,-154,-131,-111,-163,-86,-129,-136,-111,-159,-135,-153,-128,-194,-126,-204,-111,-239,-106,-205,-215,-163,-175,-185,-155,-144,-130,-163,-92,-105,-142,-4,-111,-109,-19,-118,13,-189,9,-76,-118,-8,-6,-126,-54,46,-138,-64,43,-92,-25,-132,48,-164,-57,-43,-117,-199,-11,-164,-58,-105,-75,-100,-150,-59,-62,-137,-80,-148,-65,-126,-49,-62,-33,-77,-10,-18,-11,-21,-15,-36,-38,-38,9}}; + +const int16_t irc_composite_c_r0195_p090[][256] = + {/* IRC_Composite_C_R0195_T000_P090.wav */ + {-1,1,-1,1,-1,1,-1,2,-2,2,-3,3,-3,4,-5,5,-7,8,-10,14,-25,-385,-133,-356,-344,-390,-312,-438,-400,-852,-107,-995,-245,-186,1358,-771,1473,28,-1710,-3762,-3025,4119,8200,5927,-785,1558,2250,1837,2098,631,-318,150,-77,1215,-23,792,865,600,981,659,366,950,511,766,502,516,589,299,331,571,105,609,462,485,538,594,470,640,393,432,325,604,259,355,336,454,33,263,182,-24,-124,121,-231,-50,-93,49,-230,-101,25,-196,-123,-21,-160,-161,-132,-136,-155,-268,-121,-146,-311,-112,-328,-201,-220,-280,-214,-304,-233,-227,-250,-242,-334,-256,-283,-393,-267,-285,-332,-331,-224,-295,-279,-171,-151,-361,-199,-239,-227,-317,-168,-211,-370,-182,-150,-343,-204,-192,-224,-319,-203,-137,-357,-146,-223,-237,-276,-162,-201,-262,-186,-209,-147,-267,-46,-252,-162,-146,-182,-199,-143,-218,-204,-108,-250,-163,-90,-241,-137,-125,-122,-272,-111,-188,-211,-160,-160,-164,-201,-231,-114,-175,-180,-212,-172,-181,-129,-130,-77,-150,-114,-39,12,-122,-9,-11,-46,-21,-4,7,-73,-20,-50,-21,-80,-102,2,-103,-66,-67,-8,-41,-119,-26,29,-208,3,-108,-34,-228,114,-196,-84,-28,1,-109,-92,77,-169,-27,48,-12,-79,3,-100,-44,-53,13,-103,-90,-14,-91,-23,-64,-21,-116}}; + +struct Elevation +{ + /** + * An array of |count| impulse responses of 256 samples for the left ear. + * The impulse responses in each elevation are at equally spaced azimuths + * for a full 360 degree revolution, ordered clockwise from in front the + * listener. + */ + const int16_t (*azimuths)[256]; + int count; +}; + +/** + * irc_composite_c_r0195 is an array with each element containing data for one + * elevation. + */ +const Elevation irc_composite_c_r0195[] = + {{irc_composite_c_r0195_p315, MOZ_ARRAY_LENGTH(irc_composite_c_r0195_p315)}, + {irc_composite_c_r0195_p330, MOZ_ARRAY_LENGTH(irc_composite_c_r0195_p330)}, + {irc_composite_c_r0195_p345, MOZ_ARRAY_LENGTH(irc_composite_c_r0195_p345)}, + {irc_composite_c_r0195_p000, MOZ_ARRAY_LENGTH(irc_composite_c_r0195_p000)}, + {irc_composite_c_r0195_p015, MOZ_ARRAY_LENGTH(irc_composite_c_r0195_p015)}, + {irc_composite_c_r0195_p030, MOZ_ARRAY_LENGTH(irc_composite_c_r0195_p030)}, + {irc_composite_c_r0195_p045, MOZ_ARRAY_LENGTH(irc_composite_c_r0195_p045)}, + {irc_composite_c_r0195_p060, MOZ_ARRAY_LENGTH(irc_composite_c_r0195_p060)}, + {irc_composite_c_r0195_p075, MOZ_ARRAY_LENGTH(irc_composite_c_r0195_p075)}, + {irc_composite_c_r0195_p090, MOZ_ARRAY_LENGTH(irc_composite_c_r0195_p090)}}; + +const int irc_composite_c_r0195_first_elevation = -45; /* degrees */ +const int irc_composite_c_r0195_elevation_interval = 15; /* degrees */ +const int irc_composite_c_r0195_sample_rate = 44100; /* Hz */ diff --git a/dom/media/webaudio/blink/PeriodicWave.cpp b/dom/media/webaudio/blink/PeriodicWave.cpp new file mode 100644 index 000000000..3f949207a --- /dev/null +++ b/dom/media/webaudio/blink/PeriodicWave.cpp @@ -0,0 +1,358 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "PeriodicWave.h" +#include <algorithm> +#include <cmath> +#include <limits> +#include "mozilla/FFTBlock.h" + +const unsigned MinPeriodicWaveSize = 4096; // This must be a power of two. +const unsigned MaxPeriodicWaveSize = 8192; // This must be a power of two. +const float CentsPerRange = 1200 / 3; // 1/3 Octave. + +using namespace mozilla; +using mozilla::dom::OscillatorType; + +namespace WebCore { + +already_AddRefed<PeriodicWave> +PeriodicWave::create(float sampleRate, + const float* real, + const float* imag, + size_t numberOfComponents, + bool disableNormalization) +{ + bool isGood = real && imag && numberOfComponents > 0; + MOZ_ASSERT(isGood); + if (isGood) { + RefPtr<PeriodicWave> periodicWave = + new PeriodicWave(sampleRate, numberOfComponents, + disableNormalization); + + // Limit the number of components used to those for frequencies below the + // Nyquist of the fixed length inverse FFT. + size_t halfSize = periodicWave->m_periodicWaveSize / 2; + numberOfComponents = std::min(numberOfComponents, halfSize); + periodicWave->m_numberOfComponents = numberOfComponents; + periodicWave->m_realComponents = new AudioFloatArray(numberOfComponents); + periodicWave->m_imagComponents = new AudioFloatArray(numberOfComponents); + memcpy(periodicWave->m_realComponents->Elements(), real, + numberOfComponents * sizeof(float)); + memcpy(periodicWave->m_imagComponents->Elements(), imag, + numberOfComponents * sizeof(float)); + + return periodicWave.forget(); + } + return nullptr; +} + +already_AddRefed<PeriodicWave> +PeriodicWave::createSine(float sampleRate) +{ + RefPtr<PeriodicWave> periodicWave = + new PeriodicWave(sampleRate, MinPeriodicWaveSize, false); + periodicWave->generateBasicWaveform(OscillatorType::Sine); + return periodicWave.forget(); +} + +already_AddRefed<PeriodicWave> +PeriodicWave::createSquare(float sampleRate) +{ + RefPtr<PeriodicWave> periodicWave = + new PeriodicWave(sampleRate, MinPeriodicWaveSize, false); + periodicWave->generateBasicWaveform(OscillatorType::Square); + return periodicWave.forget(); +} + +already_AddRefed<PeriodicWave> +PeriodicWave::createSawtooth(float sampleRate) +{ + RefPtr<PeriodicWave> periodicWave = + new PeriodicWave(sampleRate, MinPeriodicWaveSize, false); + periodicWave->generateBasicWaveform(OscillatorType::Sawtooth); + return periodicWave.forget(); +} + +already_AddRefed<PeriodicWave> +PeriodicWave::createTriangle(float sampleRate) +{ + RefPtr<PeriodicWave> periodicWave = + new PeriodicWave(sampleRate, MinPeriodicWaveSize, false); + periodicWave->generateBasicWaveform(OscillatorType::Triangle); + return periodicWave.forget(); +} + +PeriodicWave::PeriodicWave(float sampleRate, size_t numberOfComponents, bool disableNormalization) + : m_sampleRate(sampleRate) + , m_centsPerRange(CentsPerRange) + , m_maxPartialsInBandLimitedTable(0) + , m_normalizationScale(1.0f) + , m_disableNormalization(disableNormalization) +{ + float nyquist = 0.5 * m_sampleRate; + + if (numberOfComponents <= MinPeriodicWaveSize) { + m_periodicWaveSize = MinPeriodicWaveSize; + } else { + unsigned npow2 = powf(2.0f, floorf(logf(numberOfComponents - 1.0)/logf(2.0f) + 1.0f)); + m_periodicWaveSize = std::min(MaxPeriodicWaveSize, npow2); + } + + m_numberOfRanges = (unsigned)(3.0f*logf(m_periodicWaveSize)/logf(2.0f)); + m_bandLimitedTables.SetLength(m_numberOfRanges); + m_lowestFundamentalFrequency = nyquist / maxNumberOfPartials(); + m_rateScale = m_periodicWaveSize / m_sampleRate; +} + +size_t PeriodicWave::sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const +{ + size_t amount = aMallocSizeOf(this); + + amount += m_bandLimitedTables.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (size_t i = 0; i < m_bandLimitedTables.Length(); i++) { + if (m_bandLimitedTables[i]) { + amount += m_bandLimitedTables[i]->ShallowSizeOfIncludingThis(aMallocSizeOf); + } + } + + return amount; +} + +void PeriodicWave::waveDataForFundamentalFrequency(float fundamentalFrequency, float* &lowerWaveData, float* &higherWaveData, float& tableInterpolationFactor) +{ + + // Negative frequencies are allowed, in which case we alias + // to the positive frequency. + fundamentalFrequency = fabsf(fundamentalFrequency); + + // We only need to rebuild to the tables if the new fundamental + // frequency is low enough to allow for more partials below the + // Nyquist frequency. + unsigned numberOfPartials = numberOfPartialsForRange(0); + float nyquist = 0.5 * m_sampleRate; + if (fundamentalFrequency != 0.0) { + numberOfPartials = std::min(numberOfPartials, (unsigned)(nyquist / fundamentalFrequency)); + } + if (numberOfPartials > m_maxPartialsInBandLimitedTable) { + for (unsigned rangeIndex = 0; rangeIndex < m_numberOfRanges; ++rangeIndex) { + m_bandLimitedTables[rangeIndex] = 0; + } + + // We need to create the first table to determine the normalization + // constant. + createBandLimitedTables(fundamentalFrequency, 0); + m_maxPartialsInBandLimitedTable = numberOfPartials; + } + + // Calculate the pitch range. + float ratio = fundamentalFrequency > 0 ? fundamentalFrequency / m_lowestFundamentalFrequency : 0.5; + float centsAboveLowestFrequency = logf(ratio)/logf(2.0f) * 1200; + + // Add one to round-up to the next range just in time to truncate + // partials before aliasing occurs. + float pitchRange = 1 + centsAboveLowestFrequency / m_centsPerRange; + + pitchRange = std::max(pitchRange, 0.0f); + pitchRange = std::min(pitchRange, static_cast<float>(m_numberOfRanges - 1)); + + // The words "lower" and "higher" refer to the table data having + // the lower and higher numbers of partials. It's a little confusing + // since the range index gets larger the more partials we cull out. + // So the lower table data will have a larger range index. + unsigned rangeIndex1 = static_cast<unsigned>(pitchRange); + unsigned rangeIndex2 = rangeIndex1 < m_numberOfRanges - 1 ? rangeIndex1 + 1 : rangeIndex1; + + if (!m_bandLimitedTables[rangeIndex1].get()) + createBandLimitedTables(fundamentalFrequency, rangeIndex1); + + if (!m_bandLimitedTables[rangeIndex2].get()) + createBandLimitedTables(fundamentalFrequency, rangeIndex2); + + lowerWaveData = m_bandLimitedTables[rangeIndex2]->Elements(); + higherWaveData = m_bandLimitedTables[rangeIndex1]->Elements(); + + // Ranges from 0 -> 1 to interpolate between lower -> higher. + tableInterpolationFactor = rangeIndex2 - pitchRange; +} + +unsigned PeriodicWave::maxNumberOfPartials() const +{ + return m_periodicWaveSize / 2; +} + +unsigned PeriodicWave::numberOfPartialsForRange(unsigned rangeIndex) const +{ + // Number of cents below nyquist where we cull partials. + float centsToCull = rangeIndex * m_centsPerRange; + + // A value from 0 -> 1 representing what fraction of the partials to keep. + float cullingScale = pow(2, -centsToCull / 1200); + + // The very top range will have all the partials culled. + unsigned numberOfPartials = cullingScale * maxNumberOfPartials(); + + return numberOfPartials; +} + +// Convert into time-domain wave buffers. +// One table is created for each range for non-aliasing playback +// at different playback rates. Thus, higher ranges have more +// high-frequency partials culled out. +void PeriodicWave::createBandLimitedTables(float fundamentalFrequency, + unsigned rangeIndex) +{ + unsigned fftSize = m_periodicWaveSize; + unsigned i; + + const float *realData = m_realComponents->Elements(); + const float *imagData = m_imagComponents->Elements(); + + // This FFTBlock is used to cull partials (represented by frequency bins). + FFTBlock frame(fftSize); + + // Find the starting bin where we should start culling the aliasing + // partials for this pitch range. We need to clear out the highest + // frequencies to band-limit the waveform. + unsigned numberOfPartials = numberOfPartialsForRange(rangeIndex); + // Also limit to the number of components that are provided. + numberOfPartials = std::min(numberOfPartials, m_numberOfComponents - 1); + + // Limit number of partials to those below Nyquist frequency + float nyquist = 0.5 * m_sampleRate; + if (fundamentalFrequency != 0.0) { + numberOfPartials = std::min(numberOfPartials, + (unsigned)(nyquist / fundamentalFrequency)); + } + + // Copy from loaded frequency data and generate complex conjugate + // because of the way the inverse FFT is defined. + // The coefficients of higher partials remain zero, as initialized in + // the FFTBlock constructor. + for (i = 0; i < numberOfPartials + 1; ++i) { + frame.RealData(i) = realData[i]; + frame.ImagData(i) = -imagData[i]; + } + + // Clear any DC-offset. + frame.RealData(0) = 0; + // Clear value which has no effect. + frame.ImagData(0) = 0; + + // Create the band-limited table. + AlignedAudioFloatArray* table = new AlignedAudioFloatArray(m_periodicWaveSize); + m_bandLimitedTables[rangeIndex] = table; + + // Apply an inverse FFT to generate the time-domain table data. + float* data = m_bandLimitedTables[rangeIndex]->Elements(); + frame.GetInverseWithoutScaling(data); + + // For the first range (which has the highest power), calculate + // its peak value then compute normalization scale. + if (!m_disableNormalization && !rangeIndex) { + float maxValue; + maxValue = AudioBufferPeakValue(data, m_periodicWaveSize); + + if (maxValue) + m_normalizationScale = 1.0f / maxValue; + } + + // Apply normalization scale. + if (!m_disableNormalization) { + AudioBufferInPlaceScale(data, m_normalizationScale, m_periodicWaveSize); + } +} + +void PeriodicWave::generateBasicWaveform(OscillatorType shape) +{ + const float piFloat = float(M_PI); + unsigned fftSize = periodicWaveSize(); + unsigned halfSize = fftSize / 2; + + m_numberOfComponents = halfSize; + m_realComponents = new AudioFloatArray(halfSize); + m_imagComponents = new AudioFloatArray(halfSize); + float* realP = m_realComponents->Elements(); + float* imagP = m_imagComponents->Elements(); + + // Clear DC and imag value which is ignored. + realP[0] = 0; + imagP[0] = 0; + + for (unsigned n = 1; n < halfSize; ++n) { + float omega = 2 * piFloat * n; + float invOmega = 1 / omega; + + // Fourier coefficients according to standard definition. + float a; // Coefficient for cos(). + float b; // Coefficient for sin(). + + // Calculate Fourier coefficients depending on the shape. + // Note that the overall scaling (magnitude) of the waveforms + // is normalized in createBandLimitedTables(). + switch (shape) { + case OscillatorType::Sine: + // Standard sine wave function. + a = 0; + b = (n == 1) ? 1 : 0; + break; + case OscillatorType::Square: + // Square-shaped waveform with the first half its maximum value + // and the second half its minimum value. + a = 0; + b = invOmega * ((n & 1) ? 2 : 0); + break; + case OscillatorType::Sawtooth: + // Sawtooth-shaped waveform with the first half ramping from + // zero to maximum and the second half from minimum to zero. + a = 0; + b = -invOmega * cos(0.5 * omega); + break; + case OscillatorType::Triangle: + // Triangle-shaped waveform going from its maximum value to + // its minimum value then back to the maximum value. + a = 0; + if (n & 1) { + b = 2 * (2 / (n * piFloat) * 2 / (n * piFloat)) * ((((n - 1) >> 1) & 1) ? -1 : 1); + } else { + b = 0; + } + break; + default: + NS_NOTREACHED("invalid oscillator type"); + a = 0; + b = 0; + break; + } + + realP[n] = a; + imagP[n] = b; + } +} + +} // namespace WebCore diff --git a/dom/media/webaudio/blink/PeriodicWave.h b/dom/media/webaudio/blink/PeriodicWave.h new file mode 100644 index 000000000..47381d450 --- /dev/null +++ b/dom/media/webaudio/blink/PeriodicWave.h @@ -0,0 +1,118 @@ +/* + * Copyright (C) 2012 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef PeriodicWave_h +#define PeriodicWave_h + +#include "mozilla/dom/OscillatorNodeBinding.h" +#include <nsAutoPtr.h> +#include <nsTArray.h> +#include "AlignedTArray.h" +#include "mozilla/MemoryReporting.h" + +namespace WebCore { + +typedef AlignedTArray<float> AlignedAudioFloatArray; +typedef nsTArray<float> AudioFloatArray; + +class PeriodicWave { +public: + NS_INLINE_DECL_THREADSAFE_REFCOUNTING(WebCore::PeriodicWave); + + static already_AddRefed<PeriodicWave> createSine(float sampleRate); + static already_AddRefed<PeriodicWave> createSquare(float sampleRate); + static already_AddRefed<PeriodicWave> createSawtooth(float sampleRate); + static already_AddRefed<PeriodicWave> createTriangle(float sampleRate); + + // Creates an arbitrary periodic wave given the frequency components + // (Fourier coefficients). + static already_AddRefed<PeriodicWave> create(float sampleRate, + const float* real, + const float* imag, + size_t numberOfComponents, + bool disableNormalization); + + // Returns pointers to the lower and higher wave data for the pitch range + // containing the given fundamental frequency. These two tables are in + // adjacent "pitch" ranges where the higher table will have the maximum + // number of partials which won't alias when played back at this + // fundamental frequency. The lower wave is the next range containing fewer + // partials than the higher wave. Interpolation between these two tables + // can be made according to tableInterpolationFactor. Where values + // from 0 -> 1 interpolate between lower -> higher. + void waveDataForFundamentalFrequency(float, float* &lowerWaveData, float* &higherWaveData, float& tableInterpolationFactor); + + // Returns the scalar multiplier to the oscillator frequency to calculate + // wave buffer phase increment. + float rateScale() const { return m_rateScale; } + + unsigned periodicWaveSize() const { return m_periodicWaveSize; } + float sampleRate() const { return m_sampleRate; } + + size_t sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + +private: + explicit PeriodicWave(float sampleRate, size_t numberOfComponents, bool disableNormalization); + ~PeriodicWave() {} + + void generateBasicWaveform(mozilla::dom::OscillatorType); + + float m_sampleRate; + unsigned m_periodicWaveSize; + unsigned m_numberOfRanges; + float m_centsPerRange; + unsigned m_numberOfComponents; + nsAutoPtr<AudioFloatArray> m_realComponents; + nsAutoPtr<AudioFloatArray> m_imagComponents; + + // The lowest frequency (in Hertz) where playback will include all of the + // partials. Playing back lower than this frequency will gradually lose + // more high-frequency information. + // This frequency is quite low (~10Hz @ // 44.1KHz) + float m_lowestFundamentalFrequency; + + float m_rateScale; + + unsigned numberOfRanges() const { return m_numberOfRanges; } + + // Maximum possible number of partials (before culling). + unsigned maxNumberOfPartials() const; + + unsigned numberOfPartialsForRange(unsigned rangeIndex) const; + + // Creates table for specified index based on fundamental frequency. + void createBandLimitedTables(float fundamentalFrequency, unsigned rangeIndex); + unsigned m_maxPartialsInBandLimitedTable; + float m_normalizationScale; + bool m_disableNormalization; + nsTArray<nsAutoPtr<AlignedAudioFloatArray> > m_bandLimitedTables; +}; + +} // namespace WebCore + +#endif // PeriodicWave_h diff --git a/dom/media/webaudio/blink/README b/dom/media/webaudio/blink/README new file mode 100644 index 000000000..96d209dfc --- /dev/null +++ b/dom/media/webaudio/blink/README @@ -0,0 +1,24 @@ +This directory contains the code originally borrowed from the Blink Web Audio +implementation. We are forking the code here because in many cases the burden +of adopting Blink specific utilities is too large compared to the prospect of +importing upstream fixes by just copying newer versions of the code in the +future. + +The process of borrowing code from Blink is as follows: + +* Try to borrow utility classes only, and avoid borrowing code which depends + too much on the Blink specific utilities. +* First, import the pristine files from the Blink repository before adding + them to the build system, noting the SVN revision of Blink from which the + original files were copied in the commit message. +* In a separate commit, add the imported source files to the build system, + and apply the necessary changes to make it build successfully. +* Use the code in a separate commit. +* Never add headers as exported headers. All headers should be included + using the following convention: #include "blink/Header.h". +* Leave the imported code in the WebCore namespace, and import the needed + names into the Mozilla code via `using'. +* Cherry-pick upsteam fixes manually when needed. In case you fix a problem + that is not Mozilla specific locally, try to upstream your changes into + Blink. +* Ping ehsan for any questions. diff --git a/dom/media/webaudio/blink/Reverb.cpp b/dom/media/webaudio/blink/Reverb.cpp new file mode 100644 index 000000000..4fca0822b --- /dev/null +++ b/dom/media/webaudio/blink/Reverb.cpp @@ -0,0 +1,243 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "Reverb.h" +#include "ReverbConvolverStage.h" + +#include <math.h> +#include "ReverbConvolver.h" +#include "mozilla/FloatingPoint.h" + +using namespace mozilla; + +namespace WebCore { + +// Empirical gain calibration tested across many impulse responses to ensure perceived volume is same as dry (unprocessed) signal +const float GainCalibration = -58; +const float GainCalibrationSampleRate = 44100; + +// A minimum power value to when normalizing a silent (or very quiet) impulse response +const float MinPower = 0.000125f; + +static float calculateNormalizationScale(ThreadSharedFloatArrayBufferList* response, size_t aLength, float sampleRate) +{ + // Normalize by RMS power + size_t numberOfChannels = response->GetChannels(); + + float power = 0; + + for (size_t i = 0; i < numberOfChannels; ++i) { + float channelPower = AudioBufferSumOfSquares(static_cast<const float*>(response->GetData(i)), aLength); + power += channelPower; + } + + power = sqrt(power / (numberOfChannels * aLength)); + + // Protect against accidental overload + if (!IsFinite(power) || IsNaN(power) || power < MinPower) + power = MinPower; + + float scale = 1 / power; + + scale *= powf(10, GainCalibration * 0.05f); // calibrate to make perceived volume same as unprocessed + + // Scale depends on sample-rate. + if (sampleRate) + scale *= GainCalibrationSampleRate / sampleRate; + + // True-stereo compensation + if (response->GetChannels() == 4) + scale *= 0.5f; + + return scale; +} + +Reverb::Reverb(ThreadSharedFloatArrayBufferList* impulseResponse, size_t impulseResponseBufferLength, size_t maxFFTSize, size_t numberOfChannels, bool useBackgroundThreads, bool normalize, float sampleRate) +{ + float scale = 1; + + AutoTArray<const float*,4> irChannels; + for (size_t i = 0; i < impulseResponse->GetChannels(); ++i) { + irChannels.AppendElement(impulseResponse->GetData(i)); + } + AutoTArray<float,1024> tempBuf; + + if (normalize) { + scale = calculateNormalizationScale(impulseResponse, impulseResponseBufferLength, sampleRate); + + if (scale) { + tempBuf.SetLength(irChannels.Length()*impulseResponseBufferLength); + for (uint32_t i = 0; i < irChannels.Length(); ++i) { + float* buf = &tempBuf[i*impulseResponseBufferLength]; + AudioBufferCopyWithScale(irChannels[i], scale, buf, + impulseResponseBufferLength); + irChannels[i] = buf; + } + } + } + + initialize(irChannels, impulseResponseBufferLength, + maxFFTSize, numberOfChannels, useBackgroundThreads); +} + +size_t Reverb::sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const +{ + size_t amount = aMallocSizeOf(this); + amount += m_convolvers.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (size_t i = 0; i < m_convolvers.Length(); i++) { + if (m_convolvers[i]) { + amount += m_convolvers[i]->sizeOfIncludingThis(aMallocSizeOf); + } + } + + amount += m_tempBuffer.SizeOfExcludingThis(aMallocSizeOf, false); + return amount; +} + + +void Reverb::initialize(const nsTArray<const float*>& impulseResponseBuffer, + size_t impulseResponseBufferLength, + size_t maxFFTSize, size_t numberOfChannels, bool useBackgroundThreads) +{ + m_impulseResponseLength = impulseResponseBufferLength; + + // The reverb can handle a mono impulse response and still do stereo processing + size_t numResponseChannels = impulseResponseBuffer.Length(); + m_convolvers.SetCapacity(numberOfChannels); + + int convolverRenderPhase = 0; + for (size_t i = 0; i < numResponseChannels; ++i) { + const float* channel = impulseResponseBuffer[i]; + size_t length = impulseResponseBufferLength; + + nsAutoPtr<ReverbConvolver> convolver(new ReverbConvolver(channel, length, maxFFTSize, convolverRenderPhase, useBackgroundThreads)); + m_convolvers.AppendElement(convolver.forget()); + + convolverRenderPhase += WEBAUDIO_BLOCK_SIZE; + } + + // For "True" stereo processing we allocate a temporary buffer to avoid repeatedly allocating it in the process() method. + // It can be bad to allocate memory in a real-time thread. + if (numResponseChannels == 4) { + m_tempBuffer.AllocateChannels(2); + WriteZeroesToAudioBlock(&m_tempBuffer, 0, WEBAUDIO_BLOCK_SIZE); + } +} + +void Reverb::process(const AudioBlock* sourceBus, AudioBlock* destinationBus) +{ + // Do a fairly comprehensive sanity check. + // If these conditions are satisfied, all of the source and destination pointers will be valid for the various matrixing cases. + bool isSafeToProcess = sourceBus && destinationBus && sourceBus->ChannelCount() > 0 && destinationBus->mChannelData.Length() > 0 + && WEBAUDIO_BLOCK_SIZE <= MaxFrameSize && WEBAUDIO_BLOCK_SIZE <= size_t(sourceBus->GetDuration()) && WEBAUDIO_BLOCK_SIZE <= size_t(destinationBus->GetDuration()); + + MOZ_ASSERT(isSafeToProcess); + if (!isSafeToProcess) + return; + + // For now only handle mono or stereo output + MOZ_ASSERT(destinationBus->ChannelCount() <= 2); + + float* destinationChannelL = static_cast<float*>(const_cast<void*>(destinationBus->mChannelData[0])); + const float* sourceBusL = static_cast<const float*>(sourceBus->mChannelData[0]); + + // Handle input -> output matrixing... + size_t numInputChannels = sourceBus->ChannelCount(); + size_t numOutputChannels = destinationBus->ChannelCount(); + size_t numReverbChannels = m_convolvers.Length(); + + if (numInputChannels == 2 && numReverbChannels == 2 && numOutputChannels == 2) { + // 2 -> 2 -> 2 + const float* sourceBusR = static_cast<const float*>(sourceBus->mChannelData[1]); + float* destinationChannelR = static_cast<float*>(const_cast<void*>(destinationBus->mChannelData[1])); + m_convolvers[0]->process(sourceBusL, destinationChannelL); + m_convolvers[1]->process(sourceBusR, destinationChannelR); + } else if (numInputChannels == 1 && numOutputChannels == 2 && numReverbChannels == 2) { + // 1 -> 2 -> 2 + for (int i = 0; i < 2; ++i) { + float* destinationChannel = static_cast<float*>(const_cast<void*>(destinationBus->mChannelData[i])); + m_convolvers[i]->process(sourceBusL, destinationChannel); + } + } else if (numInputChannels == 1 && numReverbChannels == 1 && numOutputChannels == 2) { + // 1 -> 1 -> 2 + m_convolvers[0]->process(sourceBusL, destinationChannelL); + + // simply copy L -> R + float* destinationChannelR = static_cast<float*>(const_cast<void*>(destinationBus->mChannelData[1])); + bool isCopySafe = destinationChannelL && destinationChannelR && size_t(destinationBus->GetDuration()) >= WEBAUDIO_BLOCK_SIZE; + MOZ_ASSERT(isCopySafe); + if (!isCopySafe) + return; + PodCopy(destinationChannelR, destinationChannelL, WEBAUDIO_BLOCK_SIZE); + } else if (numInputChannels == 1 && numReverbChannels == 1 && numOutputChannels == 1) { + // 1 -> 1 -> 1 + m_convolvers[0]->process(sourceBusL, destinationChannelL); + } else if (numInputChannels == 2 && numReverbChannels == 4 && numOutputChannels == 2) { + // 2 -> 4 -> 2 ("True" stereo) + const float* sourceBusR = static_cast<const float*>(sourceBus->mChannelData[1]); + float* destinationChannelR = static_cast<float*>(const_cast<void*>(destinationBus->mChannelData[1])); + + float* tempChannelL = static_cast<float*>(const_cast<void*>(m_tempBuffer.mChannelData[0])); + float* tempChannelR = static_cast<float*>(const_cast<void*>(m_tempBuffer.mChannelData[1])); + + // Process left virtual source + m_convolvers[0]->process(sourceBusL, destinationChannelL); + m_convolvers[1]->process(sourceBusL, destinationChannelR); + + // Process right virtual source + m_convolvers[2]->process(sourceBusR, tempChannelL); + m_convolvers[3]->process(sourceBusR, tempChannelR); + + AudioBufferAddWithScale(tempChannelL, 1.0f, destinationChannelL, sourceBus->GetDuration()); + AudioBufferAddWithScale(tempChannelR, 1.0f, destinationChannelR, sourceBus->GetDuration()); + } else if (numInputChannels == 1 && numReverbChannels == 4 && numOutputChannels == 2) { + // 1 -> 4 -> 2 (Processing mono with "True" stereo impulse response) + // This is an inefficient use of a four-channel impulse response, but we should handle the case. + float* destinationChannelR = static_cast<float*>(const_cast<void*>(destinationBus->mChannelData[1])); + + float* tempChannelL = static_cast<float*>(const_cast<void*>(m_tempBuffer.mChannelData[0])); + float* tempChannelR = static_cast<float*>(const_cast<void*>(m_tempBuffer.mChannelData[1])); + + // Process left virtual source + m_convolvers[0]->process(sourceBusL, destinationChannelL); + m_convolvers[1]->process(sourceBusL, destinationChannelR); + + // Process right virtual source + m_convolvers[2]->process(sourceBusL, tempChannelL); + m_convolvers[3]->process(sourceBusL, tempChannelR); + + AudioBufferAddWithScale(tempChannelL, 1.0f, destinationChannelL, sourceBus->GetDuration()); + AudioBufferAddWithScale(tempChannelR, 1.0f, destinationChannelR, sourceBus->GetDuration()); + } else { + // Handle gracefully any unexpected / unsupported matrixing + // FIXME: add code for 5.1 support... + destinationBus->SetNull(destinationBus->GetDuration()); + } +} + +} // namespace WebCore diff --git a/dom/media/webaudio/blink/Reverb.h b/dom/media/webaudio/blink/Reverb.h new file mode 100644 index 000000000..35e72283d --- /dev/null +++ b/dom/media/webaudio/blink/Reverb.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef Reverb_h +#define Reverb_h + +#include "ReverbConvolver.h" +#include "nsAutoPtr.h" +#include "nsTArray.h" +#include "AudioBlock.h" +#include "mozilla/MemoryReporting.h" + +namespace mozilla { +class ThreadSharedFloatArrayBufferList; +} // namespace mozilla + +namespace WebCore { + +// Multi-channel convolution reverb with channel matrixing - one or more ReverbConvolver objects are used internally. + +class Reverb { +public: + enum { MaxFrameSize = 256 }; + + // renderSliceSize is a rendering hint, so the FFTs can be optimized to not all occur at the same time (very bad when rendering on a real-time thread). + Reverb(mozilla::ThreadSharedFloatArrayBufferList* impulseResponseBuffer, + size_t impulseResponseBufferLength, size_t maxFFTSize, + size_t numberOfChannels, bool useBackgroundThreads, bool normalize, + float sampleRate); + + void process(const mozilla::AudioBlock* sourceBus, + mozilla::AudioBlock* destinationBus); + + size_t impulseResponseLength() const { return m_impulseResponseLength; } + + size_t sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + +private: + void initialize(const nsTArray<const float*>& impulseResponseBuffer, + size_t impulseResponseBufferLength, size_t maxFFTSize, + size_t numberOfChannels, bool useBackgroundThreads); + + size_t m_impulseResponseLength; + + nsTArray<nsAutoPtr<ReverbConvolver> > m_convolvers; + + // For "True" stereo processing + mozilla::AudioBlock m_tempBuffer; +}; + +} // namespace WebCore + +#endif // Reverb_h diff --git a/dom/media/webaudio/blink/ReverbAccumulationBuffer.cpp b/dom/media/webaudio/blink/ReverbAccumulationBuffer.cpp new file mode 100644 index 000000000..4405164b2 --- /dev/null +++ b/dom/media/webaudio/blink/ReverbAccumulationBuffer.cpp @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "ReverbAccumulationBuffer.h" +#include "AudioNodeEngine.h" +#include "mozilla/PodOperations.h" +#include <algorithm> + +using namespace mozilla; + +namespace WebCore { + +ReverbAccumulationBuffer::ReverbAccumulationBuffer(size_t length) + : m_readIndex(0) + , m_readTimeFrame(0) +{ + m_buffer.SetLength(length); + PodZero(m_buffer.Elements(), length); +} + +void ReverbAccumulationBuffer::readAndClear(float* destination, size_t numberOfFrames) +{ + size_t bufferLength = m_buffer.Length(); + bool isCopySafe = m_readIndex <= bufferLength && numberOfFrames <= bufferLength; + + MOZ_ASSERT(isCopySafe); + if (!isCopySafe) + return; + + size_t framesAvailable = bufferLength - m_readIndex; + size_t numberOfFrames1 = std::min(numberOfFrames, framesAvailable); + size_t numberOfFrames2 = numberOfFrames - numberOfFrames1; + + float* source = m_buffer.Elements(); + memcpy(destination, source + m_readIndex, sizeof(float) * numberOfFrames1); + memset(source + m_readIndex, 0, sizeof(float) * numberOfFrames1); + + // Handle wrap-around if necessary + if (numberOfFrames2 > 0) { + memcpy(destination + numberOfFrames1, source, sizeof(float) * numberOfFrames2); + memset(source, 0, sizeof(float) * numberOfFrames2); + } + + m_readIndex = (m_readIndex + numberOfFrames) % bufferLength; + m_readTimeFrame += numberOfFrames; +} + +void ReverbAccumulationBuffer::updateReadIndex(int* readIndex, size_t numberOfFrames) const +{ + // Update caller's readIndex + *readIndex = (*readIndex + numberOfFrames) % m_buffer.Length(); +} + +int ReverbAccumulationBuffer::accumulate(const float* source, size_t numberOfFrames, int* readIndex, size_t delayFrames) +{ + size_t bufferLength = m_buffer.Length(); + + size_t writeIndex = (*readIndex + delayFrames) % bufferLength; + + // Update caller's readIndex + *readIndex = (*readIndex + numberOfFrames) % bufferLength; + + size_t framesAvailable = bufferLength - writeIndex; + size_t numberOfFrames1 = std::min(numberOfFrames, framesAvailable); + size_t numberOfFrames2 = numberOfFrames - numberOfFrames1; + + float* destination = m_buffer.Elements(); + + bool isSafe = writeIndex <= bufferLength && numberOfFrames1 + writeIndex <= bufferLength && numberOfFrames2 <= bufferLength; + MOZ_ASSERT(isSafe); + if (!isSafe) + return 0; + + AudioBufferAddWithScale(source, 1.0f, destination + writeIndex, numberOfFrames1); + if (numberOfFrames2 > 0) { + AudioBufferAddWithScale(source + numberOfFrames1, 1.0f, destination, numberOfFrames2); + } + + return writeIndex; +} + +void ReverbAccumulationBuffer::reset() +{ + PodZero(m_buffer.Elements(), m_buffer.Length()); + m_readIndex = 0; + m_readTimeFrame = 0; +} + +} // namespace WebCore diff --git a/dom/media/webaudio/blink/ReverbAccumulationBuffer.h b/dom/media/webaudio/blink/ReverbAccumulationBuffer.h new file mode 100644 index 000000000..a37741a2e --- /dev/null +++ b/dom/media/webaudio/blink/ReverbAccumulationBuffer.h @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ReverbAccumulationBuffer_h +#define ReverbAccumulationBuffer_h + +#include "AlignedTArray.h" +#include "mozilla/MemoryReporting.h" + +namespace WebCore { + +// ReverbAccumulationBuffer is a circular delay buffer with one client reading from it and multiple clients +// writing/accumulating to it at different delay offsets from the read position. The read operation will zero the memory +// just read from the buffer, so it will be ready for accumulation the next time around. +class ReverbAccumulationBuffer { +public: + explicit ReverbAccumulationBuffer(size_t length); + + // This will read from, then clear-out numberOfFrames + void readAndClear(float* destination, size_t numberOfFrames); + + // Each ReverbConvolverStage will accumulate its output at the appropriate delay from the read position. + // We need to pass in and update readIndex here, since each ReverbConvolverStage may be running in + // a different thread than the realtime thread calling ReadAndClear() and maintaining m_readIndex + // Returns the writeIndex where the accumulation took place + int accumulate(const float* source, size_t numberOfFrames, int* readIndex, size_t delayFrames); + + size_t readIndex() const { return m_readIndex; } + void updateReadIndex(int* readIndex, size_t numberOfFrames) const; + + size_t readTimeFrame() const { return m_readTimeFrame; } + + void reset(); + + size_t sizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const + { + return m_buffer.ShallowSizeOfExcludingThis(aMallocSizeOf); + } + +private: + AlignedTArray<float, 16> m_buffer; + size_t m_readIndex; + size_t m_readTimeFrame; // for debugging (frame on continuous timeline) +}; + +} // namespace WebCore + +#endif // ReverbAccumulationBuffer_h diff --git a/dom/media/webaudio/blink/ReverbConvolver.cpp b/dom/media/webaudio/blink/ReverbConvolver.cpp new file mode 100644 index 000000000..e739400ae --- /dev/null +++ b/dom/media/webaudio/blink/ReverbConvolver.cpp @@ -0,0 +1,265 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "ReverbConvolver.h" +#include "ReverbConvolverStage.h" + +using namespace mozilla; + +namespace WebCore { + +const int InputBufferSize = 8 * 16384; + +// We only process the leading portion of the impulse response in the real-time thread. We don't exceed this length. +// It turns out then, that the background thread has about 278msec of scheduling slop. +// Empirically, this has been found to be a good compromise between giving enough time for scheduling slop, +// while still minimizing the amount of processing done in the primary (high-priority) thread. +// This was found to be a good value on Mac OS X, and may work well on other platforms as well, assuming +// the very rough scheduling latencies are similar on these time-scales. Of course, this code may need to be +// tuned for individual platforms if this assumption is found to be incorrect. +const size_t RealtimeFrameLimit = 8192 + 4096 // ~278msec @ 44.1KHz + - WEBAUDIO_BLOCK_SIZE; +// First stage will have size MinFFTSize - successive stages will double in +// size each time until we hit the maximum size. +const size_t MinFFTSize = 256; +// If we are using background threads then don't exceed this FFT size for the +// stages which run in the real-time thread. This avoids having only one or +// two large stages (size 16384 or so) at the end which take a lot of time +// every several processing slices. This way we amortize the cost over more +// processing slices. +const size_t MaxRealtimeFFTSize = 4096; + +ReverbConvolver::ReverbConvolver(const float* impulseResponseData, + size_t impulseResponseLength, + size_t maxFFTSize, + size_t convolverRenderPhase, + bool useBackgroundThreads) + : m_impulseResponseLength(impulseResponseLength) + , m_accumulationBuffer(impulseResponseLength + WEBAUDIO_BLOCK_SIZE) + , m_inputBuffer(InputBufferSize) + , m_backgroundThread("ConvolverWorker") + , m_backgroundThreadCondition(&m_backgroundThreadLock) + , m_useBackgroundThreads(useBackgroundThreads) + , m_wantsToExit(false) + , m_moreInputBuffered(false) +{ + // For the moment, a good way to know if we have real-time constraint is to check if we're using background threads. + // Otherwise, assume we're being run from a command-line tool. + bool hasRealtimeConstraint = useBackgroundThreads; + + const float* response = impulseResponseData; + size_t totalResponseLength = impulseResponseLength; + + // The total latency is zero because the first FFT stage is small enough + // to return output in the first block. + size_t reverbTotalLatency = 0; + + size_t stageOffset = 0; + size_t stagePhase = 0; + size_t fftSize = MinFFTSize; + while (stageOffset < totalResponseLength) { + size_t stageSize = fftSize / 2; + + // For the last stage, it's possible that stageOffset is such that we're straddling the end + // of the impulse response buffer (if we use stageSize), so reduce the last stage's length... + if (stageSize + stageOffset > totalResponseLength) { + stageSize = totalResponseLength - stageOffset; + // Use smallest FFT that is large enough to cover the last stage. + fftSize = MinFFTSize; + while (stageSize * 2 > fftSize) { + fftSize *= 2; + } + } + + // This "staggers" the time when each FFT happens so they don't all happen at the same time + int renderPhase = convolverRenderPhase + stagePhase; + + nsAutoPtr<ReverbConvolverStage> stage + (new ReverbConvolverStage(response, totalResponseLength, + reverbTotalLatency, stageOffset, stageSize, + fftSize, renderPhase, + &m_accumulationBuffer)); + + bool isBackgroundStage = false; + + if (this->useBackgroundThreads() && stageOffset > RealtimeFrameLimit) { + m_backgroundStages.AppendElement(stage.forget()); + isBackgroundStage = true; + } else + m_stages.AppendElement(stage.forget()); + + // Figure out next FFT size + fftSize *= 2; + + stageOffset += stageSize; + + if (hasRealtimeConstraint && !isBackgroundStage + && fftSize > MaxRealtimeFFTSize) { + fftSize = MaxRealtimeFFTSize; + // Custom phase positions for all but the first of the realtime + // stages of largest size. These spread out the work of the + // larger realtime stages. None of the FFTs of size 1024, 2048 or + // 4096 are performed when processing the same block. The first + // MaxRealtimeFFTSize = 4096 stage, at the end of the doubling, + // performs its FFT at block 7. The FFTs of size 2048 are + // performed in blocks 3 + 8 * n and size 1024 at 1 + 4 * n. + const uint32_t phaseLookup[] = { 14, 0, 10, 4 }; + stagePhase = WEBAUDIO_BLOCK_SIZE * + phaseLookup[m_stages.Length() % ArrayLength(phaseLookup)]; + } else if (fftSize > maxFFTSize) { + fftSize = maxFFTSize; + // A prime offset spreads out FFTs in a way that all + // available phase positions will be used if there are sufficient + // stages. + stagePhase += 5 * WEBAUDIO_BLOCK_SIZE; + } else if (stageSize > WEBAUDIO_BLOCK_SIZE) { + // As the stages are doubling in size, the next FFT will occur + // mid-way between FFTs for this stage. + stagePhase = stageSize - WEBAUDIO_BLOCK_SIZE; + } + } + + // Start up background thread + // FIXME: would be better to up the thread priority here. It doesn't need to be real-time, but higher than the default... + if (this->useBackgroundThreads() && m_backgroundStages.Length() > 0) { + if (!m_backgroundThread.Start()) { + NS_WARNING("Cannot start convolver thread."); + return; + } + m_backgroundThread.message_loop()->PostTask(NewNonOwningRunnableMethod(this, + &ReverbConvolver::backgroundThreadEntry)); + } +} + +ReverbConvolver::~ReverbConvolver() +{ + // Wait for background thread to stop + if (useBackgroundThreads() && m_backgroundThread.IsRunning()) { + m_wantsToExit = true; + + // Wake up thread so it can return + { + AutoLock locker(m_backgroundThreadLock); + m_moreInputBuffered = true; + m_backgroundThreadCondition.Signal(); + } + + m_backgroundThread.Stop(); + } +} + +size_t ReverbConvolver::sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const +{ + size_t amount = aMallocSizeOf(this); + amount += m_stages.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (size_t i = 0; i < m_stages.Length(); i++) { + if (m_stages[i]) { + amount += m_stages[i]->sizeOfIncludingThis(aMallocSizeOf); + } + } + + amount += m_backgroundStages.ShallowSizeOfExcludingThis(aMallocSizeOf); + for (size_t i = 0; i < m_backgroundStages.Length(); i++) { + if (m_backgroundStages[i]) { + amount += m_backgroundStages[i]->sizeOfIncludingThis(aMallocSizeOf); + } + } + + // NB: The buffer sizes are static, so even though they might be accessed + // in another thread it's safe to measure them. + amount += m_accumulationBuffer.sizeOfExcludingThis(aMallocSizeOf); + amount += m_inputBuffer.sizeOfExcludingThis(aMallocSizeOf); + + // Possible future measurements: + // - m_backgroundThread + // - m_backgroundThreadLock + // - m_backgroundThreadCondition + return amount; +} + +void ReverbConvolver::backgroundThreadEntry() +{ + while (!m_wantsToExit) { + // Wait for realtime thread to give us more input + m_moreInputBuffered = false; + { + AutoLock locker(m_backgroundThreadLock); + while (!m_moreInputBuffered && !m_wantsToExit) + m_backgroundThreadCondition.Wait(); + } + + // Process all of the stages until their read indices reach the input buffer's write index + int writeIndex = m_inputBuffer.writeIndex(); + + // Even though it doesn't seem like every stage needs to maintain its own version of readIndex + // we do this in case we want to run in more than one background thread. + int readIndex; + + while ((readIndex = m_backgroundStages[0]->inputReadIndex()) != writeIndex) { // FIXME: do better to detect buffer overrun... + // Accumulate contributions from each stage + for (size_t i = 0; i < m_backgroundStages.Length(); ++i) + m_backgroundStages[i]->processInBackground(this); + } + } +} + +void ReverbConvolver::process(const float* sourceChannelData, + float* destinationChannelData) +{ + const float* source = sourceChannelData; + float* destination = destinationChannelData; + bool isDataSafe = source && destination; + MOZ_ASSERT(isDataSafe); + if (!isDataSafe) + return; + + // Feed input buffer (read by all threads) + m_inputBuffer.write(source, WEBAUDIO_BLOCK_SIZE); + + // Accumulate contributions from each stage + for (size_t i = 0; i < m_stages.Length(); ++i) + m_stages[i]->process(source); + + // Finally read from accumulation buffer + m_accumulationBuffer.readAndClear(destination, WEBAUDIO_BLOCK_SIZE); + + // Now that we've buffered more input, wake up our background thread. + + // Not using a MutexLocker looks strange, but we use a tryLock() instead because this is run on the real-time + // thread where it is a disaster for the lock to be contended (causes audio glitching). It's OK if we fail to + // signal from time to time, since we'll get to it the next time we're called. We're called repeatedly + // and frequently (around every 3ms). The background thread is processing well into the future and has a considerable amount of + // leeway here... + if (m_backgroundThreadLock.Try()) { + m_moreInputBuffered = true; + m_backgroundThreadCondition.Signal(); + m_backgroundThreadLock.Release(); + } +} + +} // namespace WebCore diff --git a/dom/media/webaudio/blink/ReverbConvolver.h b/dom/media/webaudio/blink/ReverbConvolver.h new file mode 100644 index 000000000..b7eea45b8 --- /dev/null +++ b/dom/media/webaudio/blink/ReverbConvolver.h @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ReverbConvolver_h +#define ReverbConvolver_h + +#include "ReverbAccumulationBuffer.h" +#include "ReverbInputBuffer.h" +#include "nsAutoPtr.h" +#include "mozilla/MemoryReporting.h" +#ifdef LOG +#undef LOG +#endif +#include "base/condition_variable.h" +#include "base/lock.h" +#include "base/thread.h" + +namespace WebCore { + +class ReverbConvolverStage; + +class ReverbConvolver { +public: + // maxFFTSize can be adjusted (from say 2048 to 32768) depending on how much precision is necessary. + // For certain tweaky de-convolving applications the phase errors add up quickly and lead to non-sensical results with + // larger FFT sizes and single-precision floats. In these cases 2048 is a good size. + // If not doing multi-threaded convolution, then should not go > 8192. + ReverbConvolver(const float* impulseResponseData, + size_t impulseResponseLength, size_t maxFFTSize, + size_t convolverRenderPhase, bool useBackgroundThreads); + ~ReverbConvolver(); + + void process(const float* sourceChannelData, + float* destinationChannelData); + + size_t impulseResponseLength() const { return m_impulseResponseLength; } + + ReverbInputBuffer* inputBuffer() { return &m_inputBuffer; } + + bool useBackgroundThreads() const { return m_useBackgroundThreads; } + void backgroundThreadEntry(); + + size_t sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; +private: + nsTArray<nsAutoPtr<ReverbConvolverStage> > m_stages; + nsTArray<nsAutoPtr<ReverbConvolverStage> > m_backgroundStages; + size_t m_impulseResponseLength; + + ReverbAccumulationBuffer m_accumulationBuffer; + + // One or more background threads read from this input buffer which is fed from the realtime thread. + ReverbInputBuffer m_inputBuffer; + + // Background thread and synchronization + base::Thread m_backgroundThread; + Lock m_backgroundThreadLock; + ConditionVariable m_backgroundThreadCondition; + bool m_useBackgroundThreads; + bool m_wantsToExit; + bool m_moreInputBuffered; +}; + +} // namespace WebCore + +#endif // ReverbConvolver_h diff --git a/dom/media/webaudio/blink/ReverbConvolverStage.cpp b/dom/media/webaudio/blink/ReverbConvolverStage.cpp new file mode 100644 index 000000000..055098e88 --- /dev/null +++ b/dom/media/webaudio/blink/ReverbConvolverStage.cpp @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "ReverbConvolverStage.h" + +#include "ReverbAccumulationBuffer.h" +#include "ReverbConvolver.h" +#include "ReverbInputBuffer.h" +#include "mozilla/PodOperations.h" + +using namespace mozilla; + +namespace WebCore { + +ReverbConvolverStage::ReverbConvolverStage(const float* impulseResponse, size_t, + size_t reverbTotalLatency, + size_t stageOffset, + size_t stageLength, + size_t fftSize, size_t renderPhase, + ReverbAccumulationBuffer* accumulationBuffer) + : m_accumulationBuffer(accumulationBuffer) + , m_accumulationReadIndex(0) + , m_inputReadIndex(0) +{ + MOZ_ASSERT(impulseResponse); + MOZ_ASSERT(accumulationBuffer); + + m_fftKernel = new FFTBlock(fftSize); + m_fftKernel->PadAndMakeScaledDFT(impulseResponse + stageOffset, stageLength); + m_fftConvolver = new FFTConvolver(fftSize, renderPhase); + + // The convolution stage at offset stageOffset needs to have a corresponding delay to cancel out the offset. + size_t totalDelay = stageOffset + reverbTotalLatency; + + // But, the FFT convolution itself incurs latency, so subtract this out... + size_t fftLatency = m_fftConvolver->latencyFrames(); + MOZ_ASSERT(totalDelay >= fftLatency); + totalDelay -= fftLatency; + + m_postDelayLength = totalDelay; +} + +size_t ReverbConvolverStage::sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const +{ + size_t amount = aMallocSizeOf(this); + + if (m_fftKernel) { + amount += m_fftKernel->SizeOfIncludingThis(aMallocSizeOf); + } + + if (m_fftConvolver) { + amount += m_fftConvolver->sizeOfIncludingThis(aMallocSizeOf); + } + + return amount; +} + +void ReverbConvolverStage::processInBackground(ReverbConvolver* convolver) +{ + ReverbInputBuffer* inputBuffer = convolver->inputBuffer(); + float* source = inputBuffer->directReadFrom(&m_inputReadIndex, + WEBAUDIO_BLOCK_SIZE); + process(source); +} + +void ReverbConvolverStage::process(const float* source) +{ + MOZ_ASSERT(source); + if (!source) + return; + + // Now, run the convolution (into the delay buffer). + // An expensive FFT will happen every fftSize / 2 frames. + const float* output = m_fftConvolver->process(m_fftKernel, source); + + // Now accumulate into reverb's accumulation buffer. + m_accumulationBuffer->accumulate(output, WEBAUDIO_BLOCK_SIZE, + &m_accumulationReadIndex, + m_postDelayLength); +} + +} // namespace WebCore diff --git a/dom/media/webaudio/blink/ReverbConvolverStage.h b/dom/media/webaudio/blink/ReverbConvolverStage.h new file mode 100644 index 000000000..0ebc33f3a --- /dev/null +++ b/dom/media/webaudio/blink/ReverbConvolverStage.h @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ReverbConvolverStage_h +#define ReverbConvolverStage_h + +#include "FFTConvolver.h" + +#include "nsAutoPtr.h" +#include "nsTArray.h" +#include "mozilla/FFTBlock.h" +#include "mozilla/MemoryReporting.h" + +namespace WebCore { + +using mozilla::FFTBlock; + +class ReverbAccumulationBuffer; +class ReverbConvolver; + +// A ReverbConvolverStage represents the convolution associated with a sub-section of a large impulse response. +// It incorporates a delay line to account for the offset of the sub-section within the larger impulse response. +class ReverbConvolverStage { +public: + // renderPhase is useful to know so that we can manipulate the pre versus post delay so that stages will perform + // their heavy work (FFT processing) on different slices to balance the load in a real-time thread. + ReverbConvolverStage(const float* impulseResponse, size_t responseLength, size_t reverbTotalLatency, size_t stageOffset, size_t stageLength, size_t fftSize, size_t renderPhase, ReverbAccumulationBuffer*); + + // |source| must point to an array of WEBAUDIO_BLOCK_SIZE elements. + void process(const float* source); + + void processInBackground(ReverbConvolver* convolver); + + // Useful for background processing + int inputReadIndex() const { return m_inputReadIndex; } + + size_t sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + +private: + nsAutoPtr<FFTBlock> m_fftKernel; + nsAutoPtr<FFTConvolver> m_fftConvolver; + + ReverbAccumulationBuffer* m_accumulationBuffer; + int m_accumulationReadIndex; + int m_inputReadIndex; + + size_t m_postDelayLength; + + nsTArray<float> m_temporaryBuffer; +}; + +} // namespace WebCore + +#endif // ReverbConvolverStage_h diff --git a/dom/media/webaudio/blink/ReverbInputBuffer.cpp b/dom/media/webaudio/blink/ReverbInputBuffer.cpp new file mode 100644 index 000000000..8221f8151 --- /dev/null +++ b/dom/media/webaudio/blink/ReverbInputBuffer.cpp @@ -0,0 +1,87 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "ReverbInputBuffer.h" +#include "mozilla/PodOperations.h" + +using namespace mozilla; + +namespace WebCore { + +ReverbInputBuffer::ReverbInputBuffer(size_t length) + : m_writeIndex(0) +{ + m_buffer.SetLength(length); + PodZero(m_buffer.Elements(), length); +} + +void ReverbInputBuffer::write(const float* sourceP, size_t numberOfFrames) +{ + size_t bufferLength = m_buffer.Length(); + bool isCopySafe = m_writeIndex + numberOfFrames <= bufferLength; + MOZ_ASSERT(isCopySafe); + if (!isCopySafe) + return; + + memcpy(m_buffer.Elements() + m_writeIndex, sourceP, sizeof(float) * numberOfFrames); + + m_writeIndex += numberOfFrames; + MOZ_ASSERT(m_writeIndex <= bufferLength); + + if (m_writeIndex >= bufferLength) + m_writeIndex = 0; +} + +float* ReverbInputBuffer::directReadFrom(int* readIndex, size_t numberOfFrames) +{ + size_t bufferLength = m_buffer.Length(); + bool isPointerGood = readIndex && *readIndex >= 0 && *readIndex + numberOfFrames <= bufferLength; + MOZ_ASSERT(isPointerGood); + if (!isPointerGood) { + // Should never happen in practice but return pointer to start of buffer (avoid crash) + if (readIndex) + *readIndex = 0; + return m_buffer.Elements(); + } + + float* sourceP = m_buffer.Elements(); + float* p = sourceP + *readIndex; + + // Update readIndex + *readIndex = (*readIndex + numberOfFrames) % bufferLength; + + return p; +} + +void ReverbInputBuffer::reset() +{ + PodZero(m_buffer.Elements(), m_buffer.Length()); + m_writeIndex = 0; +} + +} // namespace WebCore diff --git a/dom/media/webaudio/blink/ReverbInputBuffer.h b/dom/media/webaudio/blink/ReverbInputBuffer.h new file mode 100644 index 000000000..906021c0d --- /dev/null +++ b/dom/media/webaudio/blink/ReverbInputBuffer.h @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2010 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ReverbInputBuffer_h +#define ReverbInputBuffer_h + +#include "nsTArray.h" +#include "mozilla/MemoryReporting.h" + +namespace WebCore { + +// ReverbInputBuffer is used to buffer input samples for deferred processing by the background threads. +class ReverbInputBuffer { +public: + explicit ReverbInputBuffer(size_t length); + + // The realtime audio thread keeps writing samples here. + // The assumption is that the buffer's length is evenly divisible by numberOfFrames (for nearly all cases this will be fine). + // FIXME: remove numberOfFrames restriction... + void write(const float* sourceP, size_t numberOfFrames); + + // Background threads can call this to check if there's anything to read... + size_t writeIndex() const { return m_writeIndex; } + + // The individual background threads read here (and hope that they can keep up with the buffer writing). + // readIndex is updated with the next readIndex to read from... + // The assumption is that the buffer's length is evenly divisible by numberOfFrames. + // FIXME: remove numberOfFrames restriction... + float* directReadFrom(int* readIndex, size_t numberOfFrames); + + void reset(); + + size_t sizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const + { + return m_buffer.ShallowSizeOfExcludingThis(aMallocSizeOf); + } + + +private: + nsTArray<float> m_buffer; + size_t m_writeIndex; +}; + +} // namespace WebCore + +#endif // ReverbInputBuffer_h diff --git a/dom/media/webaudio/blink/ZeroPole.cpp b/dom/media/webaudio/blink/ZeroPole.cpp new file mode 100644 index 000000000..ac0b15c7a --- /dev/null +++ b/dom/media/webaudio/blink/ZeroPole.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "ZeroPole.h" + +#include <cmath> +#include <float.h> + +namespace WebCore { + +void ZeroPole::process(const float *source, float *destination, int framesToProcess) +{ + float zero = m_zero; + float pole = m_pole; + + // Gain compensation to make 0dB @ 0Hz + const float k1 = 1 / (1 - zero); + const float k2 = 1 - pole; + + // Member variables to locals. + float lastX = m_lastX; + float lastY = m_lastY; + + for (int i = 0; i < framesToProcess; ++i) { + float input = source[i]; + + // Zero + float output1 = k1 * (input - zero * lastX); + lastX = input; + + // Pole + float output2 = k2 * output1 + pole * lastY; + lastY = output2; + + destination[i] = output2; + } + + // Locals to member variables. Flush denormals here so we don't + // slow down the inner loop above. + if (lastX == 0.0f && lastY != 0.0f && fabsf(lastY) < FLT_MIN) { + // Flush future values to zero (until there is new input). + lastY = 0.0; + // Flush calculated values. + for (int i = framesToProcess; i-- && fabsf(destination[i]) < FLT_MIN; ) { + destination[i] = 0.0f; + } + } + + m_lastX = lastX; + m_lastY = lastY; +} + +} // namespace WebCore diff --git a/dom/media/webaudio/blink/ZeroPole.h b/dom/media/webaudio/blink/ZeroPole.h new file mode 100644 index 000000000..7381bde3d --- /dev/null +++ b/dom/media/webaudio/blink/ZeroPole.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2011 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of + * its contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef ZeroPole_h +#define ZeroPole_h + +namespace WebCore { + +// ZeroPole is a simple filter with one zero and one pole. + +class ZeroPole { +public: + ZeroPole() + : m_zero(0) + , m_pole(0) + , m_lastX(0) + , m_lastY(0) + { + } + + void process(const float *source, float *destination, int framesToProcess); + + // Reset filter state. + void reset() { m_lastX = 0; m_lastY = 0; } + + void setZero(float zero) { m_zero = zero; } + void setPole(float pole) { m_pole = pole; } + + float zero() const { return m_zero; } + float pole() const { return m_pole; } + +private: + float m_zero; + float m_pole; + float m_lastX; + float m_lastY; +}; + +} // namespace WebCore + +#endif // ZeroPole_h diff --git a/dom/media/webaudio/blink/moz.build b/dom/media/webaudio/blink/moz.build new file mode 100644 index 000000000..385614de7 --- /dev/null +++ b/dom/media/webaudio/blink/moz.build @@ -0,0 +1,39 @@ +# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*- +# vim: set filetype=python: +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +UNIFIED_SOURCES += [ + 'Biquad.cpp', + 'DynamicsCompressor.cpp', + 'DynamicsCompressorKernel.cpp', + 'FFTConvolver.cpp', + 'HRTFDatabase.cpp', + 'HRTFDatabaseLoader.cpp', + 'HRTFElevation.cpp', + 'HRTFKernel.cpp', + 'HRTFPanner.cpp', + 'IIRFilter.cpp', + 'PeriodicWave.cpp', + 'Reverb.cpp', + 'ReverbAccumulationBuffer.cpp', + 'ReverbConvolver.cpp', + 'ReverbConvolverStage.cpp', + 'ReverbInputBuffer.cpp', + 'ZeroPole.cpp', +] + +# Are we targeting x86 or x64? If so, build SSE2 files. +if CONFIG['INTEL_ARCHITECTURE']: + DEFINES['USE_SSE2'] = True + +include('/ipc/chromium/chromium-config.mozbuild') + +FINAL_LIBRARY = 'xul' +LOCAL_INCLUDES += [ + '/dom/media/webaudio', +] + +if CONFIG['GNU_CXX']: + CXXFLAGS += ['-Wno-shadow'] |