audiorenderer: fill destination buffer with zeroes before copying samples over
Ensures no uninitialized values end up in the audio cache.
This commit is contained in:
@@ -86,6 +86,11 @@ float **SampleBuffer::data()
|
||||
return data_;
|
||||
}
|
||||
|
||||
const float **SampleBuffer::const_data() const
|
||||
{
|
||||
return const_cast<const float**>(data_);
|
||||
}
|
||||
|
||||
float *SampleBuffer::channel_data(int channel)
|
||||
{
|
||||
return data_[channel];
|
||||
@@ -166,6 +171,44 @@ void SampleBuffer::speed(double speed)
|
||||
data_ = output_data;
|
||||
}
|
||||
|
||||
void SampleBuffer::fill(const float &f)
|
||||
{
|
||||
fill(f, 0, sample_count_per_channel_);
|
||||
}
|
||||
|
||||
void SampleBuffer::fill(const float &f, int start_sample, int end_sample)
|
||||
{
|
||||
if (!is_allocated()) {
|
||||
qWarning() << "Tried to fill an unallocated sample buffer";
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i=0;i<audio_params().channel_count();i++) {
|
||||
for (int j=start_sample;j<end_sample;j++) {
|
||||
data_[i][j] = f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SampleBuffer::set(const float **data, int sample_offset, int sample_length)
|
||||
{
|
||||
if (!is_allocated()) {
|
||||
qWarning() << "Tried to fill an unallocated sample buffer";
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i=0;i<audio_params().channel_count();i++) {
|
||||
for (int j=0;j<sample_length;j++) {
|
||||
data_[i][j + sample_offset] = data[i][j];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SampleBuffer::set(const float **data, int sample_length)
|
||||
{
|
||||
set(data, 0, sample_length);
|
||||
}
|
||||
|
||||
QByteArray SampleBuffer::toPackedData() const
|
||||
{
|
||||
QByteArray packed_data;
|
||||
|
||||
@@ -37,6 +37,7 @@ public:
|
||||
void set_sample_count_per_channel(const int &sample_count_per_channel);
|
||||
|
||||
float** data();
|
||||
const float** const_data() const;
|
||||
float* channel_data(int channel);
|
||||
float* sample_data(int index);
|
||||
|
||||
@@ -47,6 +48,12 @@ public:
|
||||
void reverse();
|
||||
void speed(double speed);
|
||||
|
||||
void fill(const float& f);
|
||||
void fill(const float& f, int start_sample, int end_sample);
|
||||
|
||||
void set(const float** data, int sample_offset, int sample_length);
|
||||
void set(const float** data, int sample_length);
|
||||
|
||||
QByteArray toPackedData() const;
|
||||
|
||||
private:
|
||||
|
||||
@@ -36,6 +36,7 @@ NodeValueTable AudioRenderWorker::RenderBlock(const TrackOutput *track, const Ti
|
||||
|
||||
// All these blocks will need to output to a buffer so we create one here
|
||||
SampleBufferPtr block_range_buffer = SampleBuffer::CreateAllocated(audio_params_, audio_params_.time_to_samples(range.length()));
|
||||
block_range_buffer->fill(0);
|
||||
|
||||
NodeValueTable merged_table;
|
||||
|
||||
@@ -44,17 +45,17 @@ NodeValueTable AudioRenderWorker::RenderBlock(const TrackOutput *track, const Ti
|
||||
TimeRange range_for_block(qMax(b->in(), range.in()),
|
||||
qMin(b->out(), range.out()));
|
||||
|
||||
int destination_offset = audio_params_.time_to_samples(range_for_block.in() - range.in());
|
||||
int max_dest_sz = audio_params_.time_to_samples(range_for_block.length());
|
||||
|
||||
// Destination buffer
|
||||
NodeValueTable table = ProcessNode(NodeDependency(b, range_for_block));
|
||||
QVariant sample_val = table.Take(NodeParam::kSamples);
|
||||
SampleBufferPtr samples_from_this_block;
|
||||
|
||||
if (sample_val.isNull()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
SampleBufferPtr samples_from_this_block = sample_val.value<SampleBufferPtr>();
|
||||
|
||||
if (!samples_from_this_block) {
|
||||
if (sample_val.isNull()
|
||||
|| !(samples_from_this_block = sample_val.value<SampleBufferPtr>())) {
|
||||
// If we retrieved no samples from this block, do nothing
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -70,23 +71,10 @@ NodeValueTable AudioRenderWorker::RenderBlock(const TrackOutput *track, const Ti
|
||||
samples_from_this_block->reverse();
|
||||
}
|
||||
|
||||
int destination_offset = audio_params_.time_to_samples(range_for_block.in() - range.in()) * sizeof(float);
|
||||
int max_dest_sz = audio_params_.time_to_samples(range_for_block.length()) * sizeof(float);
|
||||
int actual_copy_size = qMin(max_dest_sz, static_cast<int>(samples_from_this_block->sample_count_per_channel() * sizeof(float)));
|
||||
int copy_length = qMin(max_dest_sz, samples_from_this_block->sample_count_per_channel());
|
||||
|
||||
for (int i=0;i<audio_params_.channel_count();i++) {
|
||||
char* dst_ptr = reinterpret_cast<char*>(block_range_buffer->data()[i]) + destination_offset;
|
||||
|
||||
if (actual_copy_size > 0) {
|
||||
memcpy(dst_ptr,
|
||||
samples_from_this_block->data()[i],
|
||||
actual_copy_size);
|
||||
}
|
||||
|
||||
if (actual_copy_size < max_dest_sz) {
|
||||
memset(dst_ptr + actual_copy_size, 0, max_dest_sz - actual_copy_size);
|
||||
}
|
||||
}
|
||||
// Copy samples into destination buffer
|
||||
block_range_buffer->set(samples_from_this_block->const_data(), destination_offset, copy_length);
|
||||
|
||||
{
|
||||
// Save waveform to file
|
||||
|
||||
Reference in New Issue
Block a user