JNIEXPORT void JNICALL Java_de_jurihock_voicesmith_dsp_processors_NativeTimescaleProcessor_processFrame (JNIEnv *env, jobject, jlong handle, jfloatArray _frame) { Timescale* ts = (Timescale*)handle; if (ts->timescaleRatio == 1) return; float* frame = (float*)env->GetPrimitiveArrayCritical(_frame, 0); float re, im, abs; float nextPhaseA, nextPhaseS; float phaseDeltaA, phaseDeltaS; for (int i = 1; i < ts->fftSize; i++) { // Get source Re and Im parts re = frame[2 * i]; im = frame[2 * i + 1]; // Compute source phase nextPhaseA = atan2f(im, re); if (ts->timescaleRatio < 2) { // Compute phase deltas phaseDeltaA = princargf(nextPhaseA - (ts->prevPhaseA[i] + ts->omegaA[i])); phaseDeltaS = phaseDeltaA * ts->timescaleRatio; // Compute destination phase nextPhaseS = princargf((ts->prevPhaseS[i] + ts->omegaS[i]) + phaseDeltaS); // Save computed phase values ts->prevPhaseA[i] = nextPhaseA; ts->prevPhaseS[i] = nextPhaseS; } else { // Compute destination phase nextPhaseS = princargf(nextPhaseA * 2); } // Compute destination Re and Im parts abs = sqrtf(re * re + im * im); re = abs * cosf(nextPhaseS); im = abs * sinf(nextPhaseS); // Save new values frame[2 * i] = re; frame[2 * i + 1] = im; } env->ReleasePrimitiveArrayCritical(_frame, frame, 0); }
JNIEXPORT jfloat JNICALL Java_com_rameon_sing_dsp_Math_princarg (JNIEnv *, jclass, jfloat phase) { return princargf(phase); }