static t_int *aubiotempo_tilde_perform(t_int *w) { t_aubiotempo_tilde *x = (t_aubiotempo_tilde *)(w[1]); t_sample *in = (t_sample *)(w[2]); int n = (int)(w[3]); int j; for (j=0;j<n;j++) { /* write input to datanew */ fvec_write_sample(x->vec, in[j], 0, x->pos); /*time for fft*/ if (x->pos == x->hopsize-1) { /* block loop */ aubio_tempo (x->t, x->vec, x->output); if (x->output->data[0][0]) { outlet_bang(x->tempobang); } if (x->output->data[0][1]) { outlet_bang(x->onsetbang); } /* end of block loop */ x->pos = -1; /* so it will be zero next j loop */ } x->pos++; } return (w+4); }
int aubio_process(float **input, float **output, int nframes) { unsigned int i; /*channels*/ unsigned int j; /*frames*/ for (j=0;j<(unsigned)nframes;j++) { if(usejack) { for (i=0;i<channels;i++) { /* write input to datanew */ fvec_write_sample(ibuf, input[i][j], i, pos); /* put synthnew in output */ output[i][j] = fvec_read_sample(obuf, i, pos); } } /*time for fft*/ if (pos == overlap_size-1) { /* block loop */ aubio_tempo(bt,ibuf,out); if (out->data[0][0]==1) istactus = 1; else istactus = 0; if (istactus) { for (pos = 0; pos < overlap_size; pos++) obuf->data[0][pos] = woodblock->data[0][pos]; } else { for (pos = 0; pos < overlap_size; pos++) obuf->data[0][pos] = 0.; } /* end of block loop */ pos = -1; /* so it will be zero next j loop */ } pos++; } return 1; }
AubioBeatDetector::AubioBeatDetector(std::unique_ptr<NUClear::Environment> environment) : Reactor(std::move(environment)) { on<Trigger<messages::input::SoundChunkSettings>>([this](const messages::input::SoundChunkSettings& settings) { // Store the settings of the sound chunks m->sampleRate = settings.sampleRate; m->channels = settings.channels; m->chunkSize = settings.chunkSize; // Build our audio tempo tracker can set to (aubio_onset_kl or aubio_onset_complex onset tracking) m->tempoTracker = new_aubio_tempo(aubio_onset_kl, WINDOW_SIZE, HOP_SIZE, m->channels); m->outputData = new_fvec(HOP_SIZE, m->channels); m->inputData = new_fvec(HOP_SIZE, m->channels); }); on<Trigger<messages::input::SoundChunk>>([this](const messages::input::SoundChunk& chunk) { for (size_t i = 0; i < m->chunkSize; ++i) { // Write to our vector size_t index = (i + m->offset) % HOP_SIZE; fvec_write_sample(m->inputData, chunk.data[i * m->channels], 0, index); // If we are done filling this hop chunk if(index == HOP_SIZE - 1) { aubio_tempo(m->tempoTracker, m->inputData, m->outputData); for (int i = 1; i <= m->outputData->data[0][0]; ++i) { auto beatTime = std::make_unique<BeatTime>(); // Work out how many samples from the end we are in total const size_t position = ((i - HOP_SIZE) + (m->outputData->data[0][i])); // Start at our end time and go back beatTime->time = chunk.endTime - NUClear::clock::duration(int(NUClear::clock::period::den * (double(position) / m->sampleRate))); emit(std::move(beatTime)); } } } m->offset = (m->chunkSize + m->offset) % HOP_SIZE; }); on<Trigger<Last<2, BeatTime>>>([this](const std::vector<std::shared_ptr<const BeatTime>>& lastTwoBeats) { if(lastTwoBeats.size() == 2) { auto beat = std::make_unique<messages::audio::Beat>(); beat->time = lastTwoBeats[0]->time; //apparently the latest one is 0 beat->period = lastTwoBeats[0]->time - lastTwoBeats[1]->time; emit(std::move(beat)); } }); on<Trigger<Shutdown>>([this](const Shutdown&) { del_aubio_tempo(m->tempoTracker); del_fvec(m->inputData); del_fvec(m->outputData); }); }