static void ann_predict_meanstd(uint16_t *pixels, float mean, float std) { int i, j; float ah[6]; float x, x_val, y_val; for (i = 0; i < num_hidden; i++) { ah[i] = BH(i); } uint16_t subsample; for (i = 0; i < num_subsample; i++) { subsample = pixels[i]; x = (float)(subsample - mean) / std; for (j = 0; j < num_hidden; j++) { float wih_tmp = WIH(i, j); ah[j] += x * wih_tmp; } } x_val = BO(0); y_val = BO(1); for (i = 0; i < num_hidden; i++) { x_val += WHO(i, 0) * tanh_approx(ah[i]); y_val += WHO(i, 1) * tanh_approx(ah[i]); } // pred = global for storing prediction values pred[PRED_X] = (unsigned short)((x_val * 112) + 0.5); pred[PRED_Y] = (unsigned short)((y_val * 111) + 0.5); return; }
void FlangerEffect::processChannel(const ChannelHandle& handle, FlangerGroupState* pState, const CSAMPLE* pInput, CSAMPLE* pOutput, const mixxx::EngineParameters& bufferParameters, const EffectEnableState enableState, const GroupFeatureState& groupFeatures) { Q_UNUSED(handle); double lfoPeriodParameter = m_pSpeedParameter->value(); double lfoPeriodFrames; if (groupFeatures.has_beat_length_sec) { // lfoPeriodParameter is a number of beats lfoPeriodParameter = std::max(roundToFraction(lfoPeriodParameter, 2.0), kMinLfoBeats); if (m_pTripletParameter->toBool()) { lfoPeriodParameter /= 3.0; } lfoPeriodFrames = lfoPeriodParameter * groupFeatures.beat_length_sec * bufferParameters.sampleRate(); } else { // lfoPeriodParameter is a number of seconds lfoPeriodFrames = std::max(lfoPeriodParameter, kMinLfoBeats) * bufferParameters.sampleRate(); } // When the period is changed, the position of the sound shouldn't // so time need to be recalculated if (pState->previousPeriodFrames != -1.0) { pState->lfoFrames *= lfoPeriodFrames / pState->previousPeriodFrames; } pState->previousPeriodFrames = lfoPeriodFrames; // lfoPeriodSamples is used to calculate the delay for each channel // independently in the loop below, so do not multiply lfoPeriodSamples by // the number of channels. CSAMPLE_GAIN mix = m_pMixParameter->value(); RampingValue<CSAMPLE_GAIN> mixRamped( pState->prev_mix, mix, bufferParameters.framesPerBuffer()); pState->prev_mix = mix; CSAMPLE_GAIN regen = m_pRegenParameter->value(); RampingValue<CSAMPLE_GAIN> regenRamped( pState->prev_regen, regen, bufferParameters.framesPerBuffer()); pState->prev_regen = regen; // With and Manual is limited by amount of amplitude that remains from width // to kMaxDelayMs double width = m_pWidthParameter->value(); double manual = m_pManualParameter->value(); double maxManual = kCenterDelayMs + (kMaxLfoWidthMs - width) / 2; double minManual = kCenterDelayMs - (kMaxLfoWidthMs - width) / 2; manual = math_clamp(manual, minManual, maxManual); RampingValue<double> widthRamped( pState->prev_width, width, bufferParameters.framesPerBuffer()); pState->prev_width = width; RampingValue<double> manualRamped( pState->prev_manual, manual, bufferParameters.framesPerBuffer()); pState->prev_manual = manual; CSAMPLE* delayLeft = pState->delayLeft; CSAMPLE* delayRight = pState->delayRight; for (unsigned int i = 0; i < bufferParameters.samplesPerBuffer(); i += bufferParameters.channelCount()) { CSAMPLE_GAIN mix_ramped = mixRamped.getNext(); CSAMPLE_GAIN regen_ramped = regenRamped.getNext(); double width_ramped = widthRamped.getNext(); double manual_ramped = manualRamped.getNext(); pState->lfoFrames++; if (pState->lfoFrames >= lfoPeriodFrames) { pState->lfoFrames = 0; } float periodFraction = static_cast<float>(pState->lfoFrames) / lfoPeriodFrames; double delayMs = manual_ramped + width_ramped / 2 * sin(M_PI * 2.0f * periodFraction); double delayFrames = delayMs * bufferParameters.sampleRate() / 1000; SINT framePrev = (pState->delayPos - static_cast<SINT>(floor(delayFrames)) + kBufferLenth) % kBufferLenth; SINT frameNext = (pState->delayPos - static_cast<SINT>(ceil(delayFrames)) + kBufferLenth) % kBufferLenth; CSAMPLE prevLeft = delayLeft[framePrev]; CSAMPLE nextLeft = delayLeft[frameNext]; CSAMPLE prevRight = delayRight[framePrev]; CSAMPLE nextRight = delayRight[frameNext]; CSAMPLE frac = delayFrames - floorf(delayFrames); CSAMPLE delayedSampleLeft = prevLeft + frac * (nextLeft - prevLeft); CSAMPLE delayedSampleRight = prevRight + frac * (nextRight - prevRight); delayLeft[pState->delayPos] = tanh_approx(pInput[i] + regen_ramped * delayedSampleLeft); delayRight[pState->delayPos] = tanh_approx(pInput[i + 1] + regen_ramped * delayedSampleRight); pState->delayPos = (pState->delayPos + 1) % kBufferLenth; double gain = (1 - mix_ramped + kGainCorrection * mix_ramped); pOutput[i] = (pInput[i] + mix_ramped * delayedSampleLeft) / gain; pOutput[i + 1] = (pInput[i + 1] + mix_ramped * delayedSampleRight) / gain; } if (enableState == EffectEnableState::Disabling) { SampleUtil::clear(delayLeft, kBufferLenth); SampleUtil::clear(delayRight, kBufferLenth); pState->previousPeriodFrames = -1; pState->prev_regen = 0; pState->prev_mix = 0; } }