1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
/*!********************************************************************
Audacity: A Digital Audio Editor
AudioSegmentSampleView.cpp
Matthieu Hodgkinson
**********************************************************************/
#include "AudioSegmentSampleView.h"
#include <algorithm>
#include <cassert>
#include <numeric>
AudioSegmentSampleView::AudioSegmentSampleView(
std::vector<BlockSampleView> blockViews, size_t start, size_t length)
: mBlockViews { std::move(blockViews) }
, mStart { start }
, mLength { length }
, mIsSilent { false }
{
assert(
start + length <=
std::accumulate(
mBlockViews.begin(), mBlockViews.end(), 0u,
[](size_t acc, const auto& block) { return acc + block->size(); }));
}
AudioSegmentSampleView::AudioSegmentSampleView(size_t length)
: mLength { length }
, mIsSilent { true }
{
}
void AudioSegmentSampleView::Copy(float* buffer, size_t bufferSize) const
{
mIsSilent ? std::fill(buffer, buffer + bufferSize, 0.f) :
DoCopy(buffer, bufferSize);
}
void AudioSegmentSampleView::AddTo(float* buffer, size_t bufferSize) const
{
if (mIsSilent)
return;
DoAdd(buffer, bufferSize);
}
size_t AudioSegmentSampleView::GetSampleCount() const
{
return mLength;
}
void AudioSegmentSampleView::DoCopy(float* buffer, size_t bufferSize) const
{
std::fill(buffer, buffer + bufferSize, 0.f);
DoAdd(buffer, bufferSize);
}
void AudioSegmentSampleView::DoAdd(float* buffer, size_t bufferSize) const
{
size_t toWrite { limitSampleBufferSize(bufferSize, mLength) };
size_t written = 0u;
size_t offset = mStart;
for (const auto& block : mBlockViews)
{
const auto toWriteFromBlock = std::min(block->size() - offset, toWrite);
const auto src = block->data() + offset;
const auto dst = buffer + written;
std::transform(src, src + toWriteFromBlock, dst, dst, std::plus {});
toWrite -= toWriteFromBlock;
written += toWriteFromBlock;
offset = 0;
}
}
|