125 lines
4.1 KiB
C++
125 lines
4.1 KiB
C++
#include <iostream>
|
|
|
|
#include "include/cgaborator.h"
|
|
#include "gaborator/gaborator.h"
|
|
#include <cmath>
|
|
|
|
const int C_ARRAY_SIZE = 300000 * 2;
|
|
|
|
struct GaboratorState {
|
|
gaborator::parameters* paramsRef;
|
|
gaborator::analyzer<float>* analyzerRef;
|
|
gaborator::coefs<float>* coefsRef;
|
|
|
|
int64_t t_in;
|
|
int min_band;
|
|
int sample_rate;
|
|
int64_t anal_support;
|
|
|
|
float cArray[C_ARRAY_SIZE];
|
|
};
|
|
|
|
void* gaborator_initialize(double sampleRate, int bandsPerOctave, double minimumFrequency, double maximumFrequency, double referenceFrequency){
|
|
|
|
auto state = new GaboratorState();
|
|
|
|
state->paramsRef = new gaborator::parameters(bandsPerOctave, minimumFrequency / sampleRate, referenceFrequency / sampleRate, 1.0, 1e-5);
|
|
state->analyzerRef = new gaborator::analyzer<float>(*(state->paramsRef));
|
|
state->coefsRef = new gaborator::coefs<float>(*(state->analyzerRef));
|
|
|
|
//converts frequency (ff_max) in hertz to the number of bands above the min frequency
|
|
//the ceil is used to end up at a full band
|
|
int interesting_bands = ceil(bandsPerOctave * log(maximumFrequency/minimumFrequency)/log(2.0f));
|
|
|
|
//since bands are ordered from high to low we are only interested in lower bands:
|
|
//fs/2.0 is the nyquist frequency
|
|
int total_bands = ceil(bandsPerOctave * log(sampleRate/2.0/minimumFrequency)/log(2.0f));
|
|
|
|
state->anal_support = (int64_t) ceil(state->analyzerRef->analysis_support());
|
|
state->min_band = total_bands - interesting_bands;
|
|
state->sample_rate = (int) sampleRate;
|
|
state->t_in = 0;
|
|
|
|
assert(state->t_in == 0);
|
|
|
|
return state;
|
|
}
|
|
|
|
long gaborator_get_anal_support(void* ptr) {
|
|
return reinterpret_cast<GaboratorState*>(ptr)->anal_support;
|
|
}
|
|
|
|
void gaborator_analyze(void* ptr, float* audio_block, int audio_block_length) {
|
|
auto state = reinterpret_cast<GaboratorState*>(ptr);
|
|
|
|
std::vector<float> buf(audio_block,audio_block + audio_block_length);
|
|
|
|
int output_index = 0;
|
|
|
|
state->analyzerRef->analyze(buf.data(), state->t_in, state->t_in + audio_block_length, *(state->coefsRef));
|
|
|
|
int64_t st0 = state->t_in - state->anal_support;
|
|
int64_t st1 = state->t_in - state->anal_support + audio_block_length;
|
|
|
|
apply(
|
|
*state->analyzerRef,
|
|
*state->coefsRef,
|
|
[&](std::complex<float> coef, int band, int64_t audioSampleIndex ) {
|
|
//ignores everything above the max_band
|
|
if(band >= state->min_band){
|
|
//printf("%f %d %ld\n",std::abs(coef),band,audioSampleIndex);
|
|
state->cArray[output_index++] = band;
|
|
state->cArray[output_index++] = audioSampleIndex;
|
|
state->cArray[output_index++] = std::abs(coef);
|
|
//printf("output_index: %d\n", output_index++);
|
|
//output_index++;
|
|
}
|
|
},st0,
|
|
st1);
|
|
|
|
state->t_in += (int64_t) audio_block_length;
|
|
|
|
int64_t t_out = state->t_in - state->anal_support;
|
|
|
|
forget_before(*state->analyzerRef, *state->coefsRef, t_out - audio_block_length);
|
|
}
|
|
|
|
float* gaborator_get_array(void* ptr) {
|
|
auto state = reinterpret_cast<GaboratorState*>(ptr);
|
|
return &state->cArray[0];
|
|
}
|
|
|
|
int gaborator_get_array_length(void* ptr) {
|
|
auto state = reinterpret_cast<GaboratorState*>(ptr);
|
|
return sizeof(state->cArray) / sizeof(state->cArray[0]);
|
|
}
|
|
|
|
int gaborator_bandcenters_array_length(void* ptr) {
|
|
auto state = reinterpret_cast<GaboratorState*>(ptr);
|
|
int max_band = state->analyzerRef->bandpass_bands_end();
|
|
return max_band+1;
|
|
}
|
|
|
|
void gaborator_bandcenters(void* ptr, float* band_centers) {
|
|
auto state = reinterpret_cast<GaboratorState*>(ptr);
|
|
int max_band = state->analyzerRef->bandpass_bands_end();
|
|
//band_centers = new float[max_band+1]; //TODO
|
|
|
|
for(int i = 0 ; i < max_band ; i++){
|
|
if(i<state->min_band){
|
|
band_centers[i]=-1;
|
|
}else{
|
|
band_centers[i]=state->analyzerRef->band_ff(i) * state->sample_rate;
|
|
}
|
|
}
|
|
}
|
|
|
|
void gaborator_release(void* ptr) {
|
|
auto state = reinterpret_cast<GaboratorState*>(ptr);
|
|
|
|
//cleanup memory
|
|
delete state->analyzerRef;
|
|
delete state->coefsRef;
|
|
delete state->paramsRef;
|
|
delete state;
|
|
} |