QMKhost/src/buffer/buffer.cpp
2022-06-23 11:32:19 -07:00

86 lines
1.7 KiB
C++

#include "buffer.hpp"
/*
A Buffer consists of three parts:
an incoming vector, a rollingbuffer, and an output vector.
Note that the RollingBuffer class does most of the work:
its `get` and `put` methods move the values in our
input and output vectors.
*/
Buffer::Buffer(
const char *pipe_file,
size_t buffer_size,
size_t output_size
):
buffer_size(buffer_size),
output_size(output_size),
pipe_file(pipe_file)
{
sample_con_rate = 5;
sample_con_rate_up_ctr = 0;
sample_con_rate_dn_ctr = 0;
incoming.resize(buffer_size);
rolling_buffer.resize(buffer_size);
output.resize(output_size);
}
void Buffer::update() {
// TODO:
// Disable and enable FIFO here to get rid of
// the difference between audio and visualization.
int fd = open(pipe_file, O_RDONLY);
ssize_t bytes_read = read(
fd,
incoming.data(),
sizeof(int16_t) * incoming.size()
);
const auto begin = incoming.begin();
const auto end = incoming.begin() + bytes_read/sizeof(int16_t);
// Autoscale here
rolling_buffer.put(begin, end);
// 44100 samples per second / fps = samples per frame
// 60 fps
// *2 if stereo
size_t requested_samples = (44100 / 60) * pow(1.1, sample_con_rate);
size_t new_samples = rolling_buffer.get(
requested_samples,
output
);
if (new_samples == 0) {
printf("no new samples\n");
return;
}
// A crude way to adjust the amount of samples consumed from the buffer
// depending on how fast the rendering is.
if (rolling_buffer.size() > 0) {
if (++sample_con_rate_up_ctr > 8) {
sample_con_rate_up_ctr = 0;
++sample_con_rate;
}
} else if (sample_con_rate > 0) {
if (++sample_con_rate_dn_ctr > 4) {
sample_con_rate_dn_ctr = 0;
--sample_con_rate;
}
sample_con_rate_up_ctr = 0;
}
if (fd >= 0) {
close(fd);
}
}