rhubarb-lip-sync/src/audio/processing.cpp

50 lines
1.6 KiB
C++

#include "processing.h"
using std::function;
using std::vector;
using std::unique_ptr;
// Converts a float in the range -1..1 to a signed 16-bit int
inline int16_t floatSampleToInt16(float sample) {
sample = std::max(sample, -1.0f);
sample = std::min(sample, 1.0f);
return static_cast<int16_t>(((sample + 1) / 2) * (INT16_MAX - INT16_MIN) + INT16_MIN);
}
void process16bitAudioClip(const AudioClip& audioClip, function<void(const vector<int16_t>&)> processBuffer, size_t bufferCapacity, ProgressSink& progressSink) {
// Process entire sound stream
vector<int16_t> buffer;
buffer.reserve(bufferCapacity);
int sampleCount = 0;
auto it = audioClip.begin();
auto end = audioClip.end();
do {
// Read to buffer
buffer.clear();
for (; buffer.size() < bufferCapacity && it != end; ++it) {
// Read sample to buffer
buffer.push_back(floatSampleToInt16(*it));
}
// Process buffer
processBuffer(buffer);
sampleCount += buffer.size();
progressSink.reportProgress(static_cast<double>(sampleCount) / audioClip.size());
} while (buffer.size());
}
void process16bitAudioClip(const AudioClip& audioClip, function<void(const vector<int16_t>&)> processBuffer, ProgressSink& progressSink) {
const size_t capacity = 1600; // 0.1 second capacity
process16bitAudioClip(audioClip, processBuffer, capacity, progressSink);
}
unique_ptr<vector<int16_t>> copyTo16bitBuffer(const AudioClip& audioClip) {
auto result = std::make_unique<vector<int16_t>>(static_cast<size_t>(audioClip.size()));
int index = 0;
for (float sample : audioClip) {
(*result)[index++] = floatSampleToInt16(sample);
}
return std::move(result);
}