diff options
Diffstat (limited to 'dom/media/webaudio/blink')
38 files changed, 10488 insertions, 0 deletions
diff --git a/dom/media/webaudio/blink/Biquad.cpp b/dom/media/webaudio/blink/Biquad.cpp new file mode 100644 index 0000000000..51c3ec4487 --- /dev/null +++ b/dom/media/webaudio/blink/Biquad.cpp @@ -0,0 +1,439 @@ +/* + * 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 "DenormalDisabler.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() = default; + +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. + 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. +#ifndef HAVE_DENORMAL + for (int i = framesToProcess; i-- && fabsf(destP[i]) < FLT_MIN;) { + destP[i] = 0.0f; + } +#endif + } + // 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 + 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 + 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 0000000000..d64ed72b50 --- /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 0000000000..646482b74f --- /dev/null +++ b/dom/media/webaudio/blink/DenormalDisabler.h @@ -0,0 +1,170 @@ +/* + * 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 <cinttypes> +#include <cstring> +#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) +// Windows compiled using MSVC with SSE2 +# define HAVE_DENORMAL 1 +#endif + +#if defined(__GNUC__) && defined(__SSE__) +# define HAVE_DENORMAL 1 +#endif + +#if defined(__arm__) || defined(__aarch64__) +# define HAVE_DENORMAL 1 +#endif + +#ifdef HAVE_DENORMAL +class DenormalDisabler { + public: + DenormalDisabler() : m_savedCSR(0) { disableDenormals(); } + + ~DenormalDisabler() { restoreState(); } + + // This is a nop if we can flush denormals to zero in hardware. + static inline float flushDenormalFloatToZero(float f) { return f; } + + private: + unsigned m_savedCSR; + +# if defined(__GNUC__) && defined(__SSE__) + static inline bool isDAZSupported() { +# if defined(__x86_64__) + return true; +# else + static bool s_isInited = false; + static bool s_isSupported = false; + if (s_isInited) { + return s_isSupported; + } + + struct fxsaveResult { + uint8_t before[28]; + uint32_t CSRMask; + uint8_t after[480]; + } __attribute__((aligned(16))); + + fxsaveResult registerData; + memset(®isterData, 0, sizeof(fxsaveResult)); + asm volatile("fxsave %0" : "=m"(registerData)); + s_isSupported = registerData.CSRMask & 0x0040; + s_isInited = true; + return s_isSupported; +# endif + } + + inline void disableDenormals() { + m_savedCSR = getCSR(); + setCSR(m_savedCSR | (isDAZSupported() ? 0x8040 : 0x8000)); + } + + inline void restoreState() { setCSR(m_savedCSR); } + + 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)); + } + +# elif defined(XP_WIN) && defined(_MSC_VER) + inline void disableDenormals() { + // 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 unused; + _controlfp_s(&unused, _DN_FLUSH, _MCW_DN); + } + + inline void restoreState() { + unsigned unused; + _controlfp_s(&unused, m_savedCSR, _MCW_DN); + } +# elif defined(__arm__) || defined(__aarch64__) + inline void disableDenormals() { + m_savedCSR = getStatusWord(); + // Bit 24 is the flush-to-zero mode control bit. Setting it to 1 flushes + // denormals to 0. + setStatusWord(m_savedCSR | (1 << 24)); + } + + inline void restoreState() { setStatusWord(m_savedCSR); } + + inline int getStatusWord() { + int result; +# if defined(__aarch64__) + asm volatile("mrs %x[result], FPCR" : [result] "=r"(result)); +# else + asm volatile("vmrs %[result], FPSCR" : [result] "=r"(result)); +# endif + return result; + } + + inline void setStatusWord(int a) { +# if defined(__aarch64__) + asm volatile("msr FPCR, %x[src]" : : [src] "r"(a)); +# else + asm volatile("vmsr FPSCR, %[src]" : : [src] "r"(a)); +# endif + } + +# endif +}; + +#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 +#endif // DenormalDisabler_h diff --git a/dom/media/webaudio/blink/DynamicsCompressor.cpp b/dom/media/webaudio/blink/DynamicsCompressor.cpp new file mode 100644 index 0000000000..d31dfb3c17 --- /dev/null +++ b/dom/media/webaudio/blink/DynamicsCompressor.cpp @@ -0,0 +1,315 @@ +/* + * 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::AudioBlockCopyChannelWithScale; +using mozilla::WEBAUDIO_BLOCK_SIZE; + +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; + case 1: + m_sourceChannels[0] = + static_cast<const float*>(sourceChunk->mChannelData[0]); + break; + default: + MOZ_CRASH("not supported."); + } + + 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 0000000000..1838e268fe --- /dev/null +++ b/dom/media/webaudio/blink/DynamicsCompressor.h @@ -0,0 +1,135 @@ +/* + * 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 "mozilla/MemoryReporting.h" +#include "mozilla/UniquePtr.h" + +namespace mozilla { +class AudioBlock; +} // namespace mozilla + +namespace WebCore { + +using mozilla::AudioBlock; +using mozilla::UniquePtr; + +// 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; + + struct ZeroPoleFilterPack4 { + ZeroPole filters[4]; + size_t sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const { + return aMallocSizeOf(this); + } + }; + + // Per-channel emphasis filters. + nsTArray<UniquePtr<ZeroPoleFilterPack4> > m_preFilterPacks; + nsTArray<UniquePtr<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 0000000000..cffbe49967 --- /dev/null +++ b/dom/media/webaudio/blink/DynamicsCompressorKernel.cpp @@ -0,0 +1,494 @@ +/* + * 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 mozilla::dom; // for WebAudioUtils +using mozilla::MakeUnique; +using mozilla::PositiveInfinity; + +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 = std::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 (std::isnan(m_detectorAverage)) m_detectorAverage = 1; + if (std::isinf(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; + if (scaledDesiredGain == 0.0) { + compressionDiffDb = PositiveInfinity<float>(); + } else { + compressionDiffDb = WebAudioUtils::ConvertLinearToDecibels( + m_compressorGain / scaledDesiredGain, -1000.0f); + } + + if (isReleasing) { + // Release mode - compressionDiffDb should be negative dB + m_maxAttackCompressionDiffDb = -1; + + // Fix gremlins. + if (std::isnan(compressionDiffDb)) compressionDiffDb = -1; + if (std::isinf(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 = std::max(-12.0f, x); + x = std::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 (std::isnan(compressionDiffDb)) compressionDiffDb = 1; + if (std::isinf(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 = std::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 = std::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 = std::min(1.0f, detectorAverage); + + // Fix gremlins. + if (std::isnan(detectorAverage)) detectorAverage = 1; + if (std::isinf(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 = std::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 0000000000..bb7defbd7e --- /dev/null +++ b/dom/media/webaudio/blink/DynamicsCompressorKernel.h @@ -0,0 +1,125 @@ +/* + * 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 0000000000..2ade9031ce --- /dev/null +++ b/dom/media/webaudio/blink/FFTConvolver.cpp @@ -0,0 +1,118 @@ +/* + * 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 0000000000..d54b07f7a4 --- /dev/null +++ b/dom/media/webaudio/blink/FFTConvolver.h @@ -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. + */ + +#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 0000000000..54be5ea958 --- /dev/null +++ b/dom/media/webaudio/blink/HRTFDatabase.cpp @@ -0,0 +1,135 @@ +/* + * 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" + +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 0000000000..50cf2958bd --- /dev/null +++ b/dom/media/webaudio/blink/HRTFDatabase.h @@ -0,0 +1,104 @@ +/* + * 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); + + // clang-format off + // 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. + // clang-format on + 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 0000000000..3db455545e --- /dev/null +++ b/dom/media/webaudio/blink/HRTFDatabaseLoader.cpp @@ -0,0 +1,215 @@ +/* + * 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" +#include "GeckoProfiler.h" +#include "nsThreadUtils.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), + m_databaseLoaded(false) { + 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) + : mozilla::Runnable("WebCore::HRTFDatabaseLoader::ProxyReleaseEvent"), + mLoader(loader) {} + NS_IMETHOD Run() override { + mLoader->MainThreadRelease(); + return NS_OK; + } + + private: + // Ownership transferred by ProxyRelease + HRTFDatabaseLoader* MOZ_OWNING_REF mLoader; +}; + +void HRTFDatabaseLoader::ProxyRelease() { + nsCOMPtr<nsIEventTarget> mainTarget = GetMainThreadSerialEventTarget(); + if (MOZ_LIKELY(mainTarget)) { + RefPtr<ProxyReleaseEvent> event = new ProxyReleaseEvent(this); + DebugOnly<nsresult> rv = mainTarget->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) { + AUTO_PROFILER_REGISTER_THREAD("HRTFDatabaseLdr"); + NS_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); + m_databaseLoaded = true; + // 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 0000000000..5d4548d247 --- /dev/null +++ b/dom/media/webaudio/blink/HRTFDatabaseLoader.h @@ -0,0 +1,155 @@ +/* + * 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() { + if (!m_databaseLoaded) { + return nullptr; + } + 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; + } + + // The HRTFDatabaseLoader removes itself from s_loaderMap on destruction. + HRTFDatabaseLoader* MOZ_NON_OWNING_REF 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 MOZ_GUARDED_BY(m_threadLock); + + float m_databaseSampleRate; + mozilla::Atomic<bool> m_databaseLoaded; +}; + +} // 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 0000000000..af4e520384 --- /dev/null +++ b/dom/media/webaudio/blink/HRTFElevation.cpp @@ -0,0 +1,338 @@ +/* + * 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 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 = std::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 = std::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(std::move(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( + std::move(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 0000000000..cd54bbc04a --- /dev/null +++ b/dom/media/webaudio/blink/HRTFElevation.h @@ -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. + */ + +#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_kernelListL(std::move(kernelListL)), + m_elevationAngle(elevation), + m_sampleRate(sampleRate) {} + + // 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 0000000000..ecaa846a66 --- /dev/null +++ b/dom/media/webaudio/blink/HRTFKernel.cpp @@ -0,0 +1,109 @@ +/* + * 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 = mozilla::MakeUnique<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(); + + UniquePtr<FFTBlock> interpolatedFrame(FFTBlock::CreateInterpolatedBlock( + *kernel1->fftFrame(), *kernel2->fftFrame(), x)); + return HRTFKernel::create(std::move(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 0000000000..34479f6301 --- /dev/null +++ b/dom/media/webaudio/blink/HRTFKernel.h @@ -0,0 +1,129 @@ +/* + * 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 "nsAutoRef.h" +#include "nsTArray.h" +#include "mozilla/FFTBlock.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/UniquePtr.h" + +namespace WebCore { + +using mozilla::FFTBlock; +using mozilla::UniquePtr; + +// 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(UniquePtr<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(UniquePtr<FFTBlock> fftFrame, float frameDelay, float sampleRate) + : m_fftFrame(std::move(fftFrame)), + m_frameDelay(frameDelay), + m_sampleRate(sampleRate) {} + + UniquePtr<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(UniquePtr<FFTBlock> fftFrame, + float frameDelay, + float sampleRate) { + return nsReturnRef<HRTFKernel>( + new HRTFKernel(std::move(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 0000000000..3d01fb5b39 --- /dev/null +++ b/dom/media/webaudio/blink/HRTFPanner.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. + * + * 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 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 float MaxDelayTimeSeconds = 0.002f; + +const int UninitializedAzimuth = -1; + +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) { + 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; + + int numberOfAzimuths = HRTFDatabase::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 = std::max(0, desiredAzimuthIndex); + desiredAzimuthIndex = std::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. + float frameDelaysL[WEBAUDIO_BLOCK_SIZE]; + float 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 0000000000..b30689557b --- /dev/null +++ b/dom/media/webaudio/blink/HRTFPanner.h @@ -0,0 +1,120 @@ +/* + * 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 0000000000..8eaa461bc3 --- /dev/null +++ b/dom/media/webaudio/blink/IIRFilter.cpp @@ -0,0 +1,178 @@ +// 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 "DenormalDisabler.h" +#include "mozilla/FloatingPoint.h" + +#include <mozilla/Assertions.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() = default; + +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 + destP[n] = WebCore::DenormalDisabler::flushDenormalFloatToZero(yn); + MOZ_ASSERT(destP[n] == 0.0 || std::fabs(destP[n]) > FLT_MIN || + std::isnan(destP[n]), + "output should not be subnormal, but can be NaN"); + } +} + +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 0000000000..87522add06 --- /dev/null +++ b/dom/media/webaudio/blink/IIRFilter.h @@ -0,0 +1,62 @@ +// 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 + +#include "nsTArray.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 0000000000..37d731d3a2 --- /dev/null +++ b/dom/media/webaudio/blink/IRC_Composite_C_R0195-incl.cpp @@ -0,0 +1,4571 @@ +/* -*- 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 0000000000..52113a2d07 --- /dev/null +++ b/dom/media/webaudio/blink/PeriodicWave.cpp @@ -0,0 +1,353 @@ +/* + * 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 = + MakeUnique<AudioFloatArray>(numberOfComponents); + periodicWave->m_imagComponents = + MakeUnique<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 = + exp2f(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 = exp2(-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. + m_bandLimitedTables[rangeIndex] = + MakeUnique<AlignedAudioFloatArray>(m_periodicWaveSize); + + // 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) { + // See Bug 1424906, results need to be scaled by 0.5 even + // when normalization is disabled. + m_normalizationScale = 0.5; + } else if (!rangeIndex) { + float maxValue; + maxValue = AudioBufferPeakValue(data, m_periodicWaveSize); + + if (maxValue) m_normalizationScale = 1.0f / maxValue; + } + + // Apply normalization scale. + 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 = MakeUnique<AudioFloatArray>(halfSize); + m_imagComponents = MakeUnique<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: + MOZ_ASSERT_UNREACHABLE("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 0000000000..fd4e50287c --- /dev/null +++ b/dom/media/webaudio/blink/PeriodicWave.h @@ -0,0 +1,123 @@ +/* + * 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 "mozilla/UniquePtr.h" +#include <nsTArray.h> +#include "AlignedTArray.h" +#include "mozilla/MemoryReporting.h" + +namespace WebCore { + +typedef AlignedTArray<float> AlignedAudioFloatArray; +typedef nsTArray<float> AudioFloatArray; + +using mozilla::UniquePtr; + +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() = default; + + void generateBasicWaveform(mozilla::dom::OscillatorType); + + float m_sampleRate; + unsigned m_periodicWaveSize; + unsigned m_numberOfRanges; + float m_centsPerRange; + unsigned m_numberOfComponents; + UniquePtr<AudioFloatArray> m_realComponents; + UniquePtr<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<UniquePtr<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 0000000000..96d209dfc8 --- /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 0000000000..bd56a5af27 --- /dev/null +++ b/dom/media/webaudio/blink/Reverb.cpp @@ -0,0 +1,277 @@ +/* + * 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 = 0.00125f; +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(const nsTArray<const float*>& response, + size_t aLength, float sampleRate) { + // Normalize by RMS power + size_t numberOfChannels = response.Length(); + + float power = 0; + + for (size_t i = 0; i < numberOfChannels; ++i) { + float channelPower = AudioBufferSumOfSquares(response[i], aLength); + power += channelPower; + } + + power = sqrt(power / (numberOfChannels * aLength)); + + // Protect against accidental overload + if (!std::isfinite(power) || std::isnan(power) || power < MinPower) + power = MinPower; + + float scale = 1 / power; + + scale *= GainCalibration; // calibrate to make perceived volume same as + // unprocessed + + // Scale depends on sample-rate. + if (sampleRate) scale *= GainCalibrationSampleRate / sampleRate; + + // True-stereo compensation + if (numberOfChannels == 4) scale *= 0.5f; + + return scale; +} + +Reverb::Reverb(const AudioChunk& impulseResponse, size_t maxFFTSize, + bool useBackgroundThreads, bool normalize, float sampleRate, + bool* aAllocationFailure) { + MOZ_ASSERT(aAllocationFailure); + size_t impulseResponseBufferLength = impulseResponse.mDuration; + float scale = impulseResponse.mVolume; + + CopyableAutoTArray<const float*, 4> irChannels( + impulseResponse.ChannelData<float>()); + AutoTArray<float, 1024> tempBuf; + + if (normalize) { + scale = calculateNormalizationScale(irChannels, impulseResponseBufferLength, + sampleRate); + } + + if (scale != 1.0f) { + bool rv = tempBuf.SetLength( + irChannels.Length() * impulseResponseBufferLength, mozilla::fallible); + *aAllocationFailure = !rv; + if (*aAllocationFailure) { + return; + } + + for (uint32_t i = 0; i < irChannels.Length(); ++i) { + float* buf = &tempBuf[i * impulseResponseBufferLength]; + AudioBufferCopyWithScale(irChannels[i], scale, buf, + impulseResponseBufferLength); + irChannels[i] = buf; + } + } + + *aAllocationFailure = !initialize(irChannels, impulseResponseBufferLength, + maxFFTSize, 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; +} + +bool Reverb::initialize(const nsTArray<const float*>& impulseResponseBuffer, + size_t impulseResponseBufferLength, size_t maxFFTSize, + bool useBackgroundThreads) { + m_impulseResponseLength = impulseResponseBufferLength; + + // The reverb can handle a mono impulse response and still do stereo + // processing + size_t numResponseChannels = impulseResponseBuffer.Length(); + MOZ_ASSERT(numResponseChannels > 0); + // The number of convolvers required is at least the number of audio + // channels. Even if there is initially only one audio channel, another + // may be added later, and so a second convolver is created now while the + // impulse response is available. + size_t numConvolvers = std::max<size_t>(numResponseChannels, 2); + m_convolvers.SetCapacity(numConvolvers); + + int convolverRenderPhase = 0; + for (size_t i = 0; i < numConvolvers; ++i) { + size_t channelIndex = i < numResponseChannels ? i : 0; + const float* channel = impulseResponseBuffer[channelIndex]; + size_t length = impulseResponseBufferLength; + + bool allocationFailure; + UniquePtr<ReverbConvolver> convolver( + new ReverbConvolver(channel, length, maxFFTSize, convolverRenderPhase, + useBackgroundThreads, &allocationFailure)); + if (allocationFailure) { + return false; + } + m_convolvers.AppendElement(std::move(convolver)); + + 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); + } + return true; +} + +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 && numOutputChannels == 1) { + // 1 -> 1 -> 1 (Only one of the convolvers is used.) + 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 { + MOZ_ASSERT_UNREACHABLE("Unexpected Reverb configuration"); + 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 0000000000..16459532a9 --- /dev/null +++ b/dom/media/webaudio/blink/Reverb.h @@ -0,0 +1,80 @@ +/* + * 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 "nsTArray.h" +#include "AudioBlock.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/UniquePtr.h" + +namespace WebCore { + +using mozilla::UniquePtr; + +// 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). + // aAllocation failure is to be checked by the caller. If false, internal + // memory could not be allocated, and this Reverb instance is not to be + // used. + Reverb(const mozilla::AudioChunk& impulseResponseBuffer, size_t maxFFTSize, + bool useBackgroundThreads, bool normalize, float sampleRate, + bool* aAllocationFailure); + + void process(const mozilla::AudioBlock* sourceBus, + mozilla::AudioBlock* destinationBus); + + size_t impulseResponseLength() const { return m_impulseResponseLength; } + + size_t sizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; + + private: + bool initialize(const nsTArray<const float*>& impulseResponseBuffer, + size_t impulseResponseBufferLength, size_t maxFFTSize, + bool useBackgroundThreads); + + size_t m_impulseResponseLength; + + nsTArray<UniquePtr<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 0000000000..ec745c294f --- /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() + : m_readIndex(0), m_readTimeFrame(0) {} + +bool ReverbAccumulationBuffer::allocate(size_t length) { + if (!m_buffer.SetLength(length, fallible)) { + return false; + } + PodZero(m_buffer.Elements(), length); + return true; +} + +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::accumulate(const float* source, + size_t numberOfFrames, + size_t* 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; + + AudioBufferAddWithScale(source, 1.0f, destination + writeIndex, + numberOfFrames1); + if (numberOfFrames2 > 0) { + AudioBufferAddWithScale(source + numberOfFrames1, 1.0f, destination, + numberOfFrames2); + } +} + +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 0000000000..8883a56a73 --- /dev/null +++ b/dom/media/webaudio/blink/ReverbAccumulationBuffer.h @@ -0,0 +1,76 @@ +/* + * 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: + ReverbAccumulationBuffer(); + // Returns false on failure. + bool allocate(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 + void accumulate(const float* source, size_t numberOfFrames, size_t* readIndex, + size_t delayFrames); + + size_t readIndex() const { return m_readIndex; } + + 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 0000000000..6965a28535 --- /dev/null +++ b/dom/media/webaudio/blink/ReverbConvolver.cpp @@ -0,0 +1,273 @@ +/* + * 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, + bool* aAllocationFailure) + : m_impulseResponseLength(impulseResponseLength), + m_accumulationBuffer(), + m_inputBuffer(InputBufferSize), + m_backgroundThread("ConvolverWorker"), + m_backgroundThreadMonitor("ConvolverMonitor"), + m_useBackgroundThreads(useBackgroundThreads), + m_wantsToExit(false), + m_moreInputBuffered(false) { + *aAllocationFailure = !m_accumulationBuffer.allocate(impulseResponseLength + + WEBAUDIO_BLOCK_SIZE); + if (*aAllocationFailure) { + return; + } + // 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; + + UniquePtr<ReverbConvolverStage> stage(new ReverbConvolverStage( + response, totalResponseLength, reverbTotalLatency, stageOffset, + stageSize, fftSize, renderPhase, &m_accumulationBuffer)); + + bool isBackgroundStage = false; + + if (this->useBackgroundThreads() && stageOffset > RealtimeFrameLimit) { + m_backgroundStages.AppendElement(std::move(stage)); + isBackgroundStage = true; + } else + m_stages.AppendElement(std::move(stage)); + + // 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( + "WebCore::ReverbConvolver::backgroundThreadEntry", 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 + { + MonitorAutoLock locker(m_backgroundThreadMonitor); + m_moreInputBuffered = true; + m_backgroundThreadMonitor.Notify(); + } + + 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_backgroundThreadMonitor + return amount; +} + +void ReverbConvolver::backgroundThreadEntry() { + while (!m_wantsToExit) { + // Wait for realtime thread to give us more input + m_moreInputBuffered = false; + { + MonitorAutoLock locker(m_backgroundThreadMonitor); + while (!m_moreInputBuffered && !m_wantsToExit) + m_backgroundThreadMonitor.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 MonitorAutoLock 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_backgroundThreadMonitor.TryLock()) { + m_moreInputBuffered = true; + m_backgroundThreadMonitor.Notify(); + m_backgroundThreadMonitor.Unlock(); + } +} + +} // namespace WebCore diff --git a/dom/media/webaudio/blink/ReverbConvolver.h b/dom/media/webaudio/blink/ReverbConvolver.h new file mode 100644 index 0000000000..8000ba811e --- /dev/null +++ b/dom/media/webaudio/blink/ReverbConvolver.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 ReverbConvolver_h +#define ReverbConvolver_h + +#include "ReverbAccumulationBuffer.h" +#include "ReverbInputBuffer.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/Monitor.h" +#include "mozilla/UniquePtr.h" +#ifdef LOG +# undef LOG +#endif +#include "base/thread.h" +#include <atomic> + +namespace WebCore { + +using mozilla::UniquePtr; + +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, + bool* aAllocationFailure); + ~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<UniquePtr<ReverbConvolverStage> > m_stages; + nsTArray<UniquePtr<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; + mozilla::Monitor m_backgroundThreadMonitor MOZ_UNANNOTATED; + bool m_useBackgroundThreads; + std::atomic<bool> m_wantsToExit; + std::atomic<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 0000000000..56354f0271 --- /dev/null +++ b/dom/media/webaudio/blink/ReverbConvolverStage.cpp @@ -0,0 +1,101 @@ +/* + * 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 = MakeUnique<FFTBlock>(fftSize); + m_fftKernel->PadAndMakeScaledDFT(impulseResponse + stageOffset, stageLength); + m_fftConvolver = MakeUnique<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.get(), 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 0000000000..f770e76d45 --- /dev/null +++ b/dom/media/webaudio/blink/ReverbConvolverStage.h @@ -0,0 +1,84 @@ +/* + * 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 "nsTArray.h" +#include "mozilla/FFTBlock.h" +#include "mozilla/MemoryReporting.h" +#include "mozilla/UniquePtr.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: + mozilla::UniquePtr<FFTBlock> m_fftKernel; + mozilla::UniquePtr<FFTConvolver> m_fftConvolver; + + ReverbAccumulationBuffer* m_accumulationBuffer; + size_t 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 0000000000..d6a69263c9 --- /dev/null +++ b/dom/media/webaudio/blink/ReverbInputBuffer.cpp @@ -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. + */ + +#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) { + // m_writeIndex is atomic and checked by other threads, so only touch + // it at the start and end. + size_t bufferLength = m_buffer.Length(); + size_t index = m_writeIndex; + size_t newIndex = index + numberOfFrames; + + MOZ_RELEASE_ASSERT(newIndex <= bufferLength); + + memcpy(m_buffer.Elements() + index, sourceP, sizeof(float) * numberOfFrames); + + if (newIndex >= bufferLength) { + newIndex = 0; + } + m_writeIndex = newIndex; +} + +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 0000000000..93ef97a010 --- /dev/null +++ b/dom/media/webaudio/blink/ReverbInputBuffer.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 ReverbInputBuffer_h +#define ReverbInputBuffer_h + +#include "nsTArray.h" +#include "mozilla/Atomics.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; + mozilla::Atomic<size_t, mozilla::ReleaseAcquire> 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 0000000000..4d0888d758 --- /dev/null +++ b/dom/media/webaudio/blink/ZeroPole.cpp @@ -0,0 +1,83 @@ +/* + * 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 "DenormalDisabler.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. +#ifndef HAVE_DENORMAL + 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; + } + } +#endif + + 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 0000000000..07f3f04f53 --- /dev/null +++ b/dom/media/webaudio/blink/ZeroPole.h @@ -0,0 +1,63 @@ +/* + * 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 0000000000..5f00d01ed3 --- /dev/null +++ b/dom/media/webaudio/blink/moz.build @@ -0,0 +1,36 @@ +# -*- 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", +] |