|
|
|
@ -13,10 +13,14 @@ extern "C" { |
|
|
|
|
|
|
|
|
|
|
|
namespace { |
|
|
|
namespace { |
|
|
|
constexpr unsigned rate = 48000, framesPerPacket = 960, maxFrames = 8192, mapCapacity = 1024; |
|
|
|
constexpr unsigned rate = 48000, framesPerPacket = 960, maxFrames = 8192, mapCapacity = 1024; |
|
|
|
struct Span { double first = 0, last = 0, ptsFirst = 0, ptsLast = 0; }; |
|
|
|
struct Span { |
|
|
|
|
|
|
|
double first, last, ptsFirst, ptsLast; |
|
|
|
|
|
|
|
Span(double begin = 0, double end = 0, double ptsBegin = 0, double ptsEnd = 0) |
|
|
|
|
|
|
|
: first(begin), last(end), ptsFirst(ptsBegin), ptsLast(ptsEnd) {} |
|
|
|
|
|
|
|
}; |
|
|
|
double mapped(const Span& span, double position) { |
|
|
|
double mapped(const Span& span, double position) { |
|
|
|
if (span.last <= span.first) return span.ptsLast; |
|
|
|
if (span.last <= span.first) return span.ptsLast; |
|
|
|
double fraction = std::clamp((position - span.first) / (span.last - span.first), 0.0, 1.0); |
|
|
|
double fraction = std::max(0.0, std::min(1.0, (position - span.first) / (span.last - span.first))); |
|
|
|
return span.ptsFirst + fraction * (span.ptsLast - span.ptsFirst); |
|
|
|
return span.ptsFirst + fraction * (span.ptsLast - span.ptsFirst); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
@ -156,7 +160,8 @@ int stream_playback_audio_pull(struct stream_playback_audio* a, int16_t* pcm, un |
|
|
|
frames = std::min(frames, std::min(available, a->stretch.numSamples())); |
|
|
|
frames = std::min(frames, std::min(available, a->stretch.numSamples())); |
|
|
|
if (!frames) return 0; |
|
|
|
if (!frames) return 0; |
|
|
|
unsigned got = a->stretch.receiveSamples(a->samples, frames); |
|
|
|
unsigned got = a->stretch.receiveSamples(a->samples, frames); |
|
|
|
for (unsigned i = 0; i < got * 2; i++) pcm[i] = (int16_t)std::lrint(std::clamp(a->samples[i] * 32767.0f, -32768.0f, 32767.0f)); |
|
|
|
for (unsigned i = 0; i < got * 2; i++) |
|
|
|
|
|
|
|
pcm[i] = (int16_t)std::lrint(std::max(-32768.0f, std::min(32767.0f, a->samples[i] * 32767.0f))); |
|
|
|
double position = a->producedOutput, end = position + got; |
|
|
|
double position = a->producedOutput, end = position + got; |
|
|
|
for (unsigned i = 0; i < a->inputCount && position < end; i++) { |
|
|
|
for (unsigned i = 0; i < a->inputCount && position < end; i++) { |
|
|
|
const auto& span = a->input[(a->inputHead + i) % mapCapacity]; |
|
|
|
const auto& span = a->input[(a->inputHead + i) % mapCapacity]; |
|
|
|
|