|
|
|
/*
|
|
|
|
* Copyright 2012 Google Inc.
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
// Resolve frequency signal (1.0 in Q24 format = 1 octave) to phase delta.
|
|
|
|
|
|
|
|
// The LUT is just a global, and we'll need the init function to be called before
|
|
|
|
// use.
|
|
|
|
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
#include "freqlut.h"
|
|
|
|
|
|
|
|
#define LG_N_SAMPLES 10
|
|
|
|
#define N_SAMPLES (1 << LG_N_SAMPLES)
|
|
|
|
#define SAMPLE_SHIFT (24 - LG_N_SAMPLES)
|
|
|
|
|
|
|
|
#define MAX_LOGFREQ_INT 20
|
|
|
|
|
|
|
|
int32_t lut[N_SAMPLES + 1];
|
|
|
|
|
|
|
|
void Freqlut::init(FRAC_NUM sample_rate) {
|
|
|
|
FRAC_NUM y = (1LL << (24 + MAX_LOGFREQ_INT)) / sample_rate;
|
|
|
|
FRAC_NUM inc = pow(2, 1.0 / N_SAMPLES);
|
|
|
|
for (int i = 0; i < N_SAMPLES + 1; i++) {
|
|
|
|
lut[i] = (int32_t)floor(y + 0.5);
|
|
|
|
y *= inc;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Note: if logfreq is more than 20.0, the results will be inaccurate. However,
|
|
|
|
// that will be many times the Nyquist rate.
|
|
|
|
int32_t Freqlut::lookup(int32_t logfreq) {
|
|
|
|
int ix = (logfreq & 0xffffff) >> SAMPLE_SHIFT;
|
|
|
|
|
|
|
|
int32_t y0 = lut[ix];
|
|
|
|
int32_t y1 = lut[ix + 1];
|
|
|
|
int lowbits = logfreq & ((1 << SAMPLE_SHIFT) - 1);
|
|
|
|
int32_t y = y0 + ((((int64_t)(y1 - y0) * (int64_t)lowbits)) >> SAMPLE_SHIFT);
|
|
|
|
int hibits = logfreq >> 24;
|
|
|
|
return y >> (MAX_LOGFREQ_INT - hibits);
|
|
|
|
}
|