soundboard/src/samplereader.cpp

58 lines
1.5 KiB
C++

#include "samplereader.h"
#include <limits>
#include <Log.h>
#define CHANNELCOUNT 2
SampleReader::SampleReader() {}
//returns nullptr on error
SampleReader* SampleReader::createSampleReader(const std::string& filepath) {
SampleReader* sr = new SampleReader();
if (ma_decoder_init_file((filepath).c_str(), NULL, &(sr->decoder)) != MA_SUCCESS) {
Log::error << "Sound file: " << filepath << " could not be loaded";
delete sr;
return nullptr;
}
sr->decoderSize = ma_decoder_get_length_in_pcm_frames(&(sr->decoder));
return sr;
}
SampleReader::~SampleReader() {
ma_decoder_uninit(&decoder);
}
void SampleReader::setWidth(uint32_t w){
width = w;
stepSize = decoderSize / (double) w;
Log::info << "SampleReaderWidth: " << w << " " << stepSize;
}
float SampleReader::readSample(uint32_t pos) {
double acc = 0;
ma_decoder_seek_to_pcm_frame(&decoder, stepSize * pos);
int16_t* buffer = new int16_t[stepSize * decoder.outputChannels];
const uint64_t read = ma_decoder_read_pcm_frames(&decoder, buffer, stepSize);
if(read == 0) {
Log::error << "no sample could be read";
return 0;
}
for(uint64_t i = 0; i < read * decoder.outputChannels; i += decoder.outputChannels) {
acc += buffer[i];
}
delete[] buffer;
float avg = (float) ((acc / (double) (std::numeric_limits<int16_t>::max())) / (double) read);
if(avg > 1) avg = 1;
else if(avg < 0) avg = 0;
return avg;
}
uint64_t SampleReader::getLength() {
return decoderSize / (decoder.outputSampleRate / 1000);
}