#include "samplereader.h" #include #include #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::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); }