Exemplo n.º 1
0
  void ComputeSine(float * aOutput, TrackTicks ticks, uint32_t aStart, uint32_t aEnd)
  {
    for (uint32_t i = aStart; i < aEnd; ++i) {
      UpdateParametersIfNeeded(ticks, i);

      aOutput[i] = sin(mPhase);

      IncrementPhase();
    }
  }
Exemplo n.º 2
0
 void ComputeSquare(float * aOutput, TrackTicks ticks, uint32_t aStart, uint32_t aEnd)
 {
   for (uint32_t i = aStart; i < aEnd; ++i) {
     UpdateParametersIfNeeded(ticks, i);
     // Integration to get us a square. It turns out we can have a
     // pure integrator here.
     mSquare += BipolarBLIT();
     aOutput[i] = mSquare;
     // maybe we want to apply a gain, the wg has not decided yet
     aOutput[i] *= 1.5;
     IncrementPhase();
   }
 }
Exemplo n.º 3
0
  void ComputeCustom(float* aOutput,
                     TrackTicks ticks,
                     uint32_t aStart,
                     uint32_t aEnd)
  {
    MOZ_ASSERT(mPeriodicWave, "No custom waveform data");

    uint32_t periodicWaveSize = mPeriodicWave->periodicWaveSize();
    // Mask to wrap wave data indices into the range [0,periodicWaveSize).
    uint32_t indexMask = periodicWaveSize - 1;
    MOZ_ASSERT(periodicWaveSize && (periodicWaveSize & indexMask) == 0,
               "periodicWaveSize must be power of 2");
    float* higherWaveData = nullptr;
    float* lowerWaveData = nullptr;
    float tableInterpolationFactor;
    // Phase increment at frequency of 1 Hz.
    // mPhase runs [0,periodicWaveSize) here instead of [0,2*M_PI).
    float basePhaseIncrement =
      static_cast<float>(periodicWaveSize) / mSource->SampleRate();

    for (uint32_t i = aStart; i < aEnd; ++i) {
      UpdateParametersIfNeeded(ticks, i);
      mPeriodicWave->waveDataForFundamentalFrequency(mFinalFrequency,
                                                     lowerWaveData,
                                                     higherWaveData,
                                                     tableInterpolationFactor);
      // Bilinear interpolation between adjacent samples in each table.
      float floorPhase = floorf(mPhase);
      uint32_t j1 = floorPhase;
      j1 &= indexMask;
      uint32_t j2 = j1 + 1;
      j2 &= indexMask;

      float sampleInterpolationFactor = mPhase - floorPhase;

      float lower = (1.0f - sampleInterpolationFactor) * lowerWaveData[j1] +
                    sampleInterpolationFactor * lowerWaveData[j2];
      float higher = (1.0f - sampleInterpolationFactor) * higherWaveData[j1] +
                    sampleInterpolationFactor * higherWaveData[j2];
      aOutput[i] = (1.0f - tableInterpolationFactor) * lower +
                   tableInterpolationFactor * higher;

      // Calculate next phase position from wrapped value j1 to avoid loss of
      // precision at large values.
      mPhase =
        j1 + sampleInterpolationFactor + basePhaseIncrement * mFinalFrequency;
    }
  }
Exemplo n.º 4
0
  void ComputeSawtooth(float * aOutput, TrackTicks ticks, uint32_t aStart, uint32_t aEnd)
  {
    float dcoffset;
    for (uint32_t i = aStart; i < aEnd; ++i) {
      UpdateParametersIfNeeded(ticks, i);
      // DC offset so the Saw does not ramp up to infinity when integrating.
      dcoffset = mFinalFrequency / mSource->SampleRate();
      // Integrate and offset so we get mAmplitudeAtZero sawtooth. We have a
      // very low frequency component somewhere here, but I'm not sure where.
      mSaw += UnipolarBLIT() - dcoffset;
      // reverse the saw so we are spec compliant
      aOutput[i] = -mSaw * 1.5;

      IncrementPhase();
    }
  }
Exemplo n.º 5
0
  void ComputeTriangle(float * aOutput, TrackTicks ticks, uint32_t aStart, uint32_t aEnd)
  {
    for (uint32_t i = aStart; i < aEnd; ++i) {
      UpdateParametersIfNeeded(ticks, i);
      // Integrate to get a square
      mSquare += BipolarBLIT();
      // Leaky integrate to get a triangle. We get too much dc offset if we don't
      // leaky integrate here.
      // C6 = k0 / period
      // (period is samplingrate / frequency, k0 = (PI/2)/(2*PI)) = 0.25
      float C6 = 0.25 / (mSource->SampleRate() / mFinalFrequency);
      mTriangle = mTriangle * sLeak + mSquare + C6;
      // DC Block, and scale back to [-1.0; 1.0]
      aOutput[i] = mDCBlocker.Process(mTriangle) / (mSignalPeriod/2) * 1.5;

      IncrementPhase();
    }
  }
Exemplo n.º 6
0
  void ComputeCustom(float* aOutput,
                     TrackTicks ticks,
                     uint32_t aStart,
                     uint32_t aEnd)
  {
    MOZ_ASSERT(mPeriodicWave, "No custom waveform data");

    uint32_t periodicWaveSize = mPeriodicWave->periodicWaveSize();
    float* higherWaveData = nullptr;
    float* lowerWaveData = nullptr;
    float tableInterpolationFactor;
    float rate = 1.0 / mSource->SampleRate();

    for (uint32_t i = aStart; i < aEnd; ++i) {
      UpdateParametersIfNeeded(ticks, i);
      mPeriodicWave->waveDataForFundamentalFrequency(mFinalFrequency,
                                                     lowerWaveData,
                                                     higherWaveData,
                                                     tableInterpolationFactor);
      // mPhase runs 0..periodicWaveSize here instead of 0..2*M_PI.
      mPhase += periodicWaveSize * mFinalFrequency * rate;
      if (mPhase >= periodicWaveSize) {
        mPhase -= periodicWaveSize;
      }
      // Bilinear interpolation between adjacent samples in each table.
      uint32_t j1 = floor(mPhase);
      uint32_t j2 = j1 + 1;
      if (j2 >= periodicWaveSize) {
        j2 -= periodicWaveSize;
      }
      float sampleInterpolationFactor = mPhase - j1;
      float lower = sampleInterpolationFactor * lowerWaveData[j1] +
                    (1 - sampleInterpolationFactor) * lowerWaveData[j2];
      float higher = sampleInterpolationFactor * higherWaveData[j1] +
                    (1 - sampleInterpolationFactor) * higherWaveData[j2];
      aOutput[i] = tableInterpolationFactor * lower +
                   (1 - tableInterpolationFactor) * higher;
    }
  }