blob: 91f8df33866fda1459de1330d5455f756b39ef95 [file] [log] [blame]
// Copyright 2020 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/media/audio/audio_core/tap_stage.h"
#include <trace/event.h>
#include "src/lib/syslog/cpp/logger.h"
namespace media::audio {
TapStage::TapStage(std::shared_ptr<Stream> source, std::shared_ptr<Stream> tap)
: Stream(source->format()), source_(std::move(source)), tap_(std::move(tap)) {
FX_DCHECK(source_->format() == tap_->format());
}
std::optional<Stream::Buffer> TapStage::LockBuffer(zx::time ref_time, int64_t frame,
uint32_t frame_count) {
TRACE_DURATION("audio", "TapStage::LockBuffer", "frame", frame, "length", frame_count);
auto input_buffer = source_->LockBuffer(ref_time, frame, frame_count);
if (!input_buffer) {
return std::nullopt;
}
uint8_t* input_ptr = reinterpret_cast<uint8_t*>(input_buffer->payload());
int64_t output_buffer_frame = input_buffer->start().Floor();
uint32_t output_frames_outstanding = input_buffer->length().Floor();
while (output_frames_outstanding > 0) {
auto output_buffer = tap_->LockBuffer(ref_time, output_buffer_frame, output_frames_outstanding);
if (!output_buffer) {
break;
}
uint32_t frames_copied = std::min(output_buffer->length().Floor(), output_frames_outstanding);
uint32_t bytes_copied = frames_copied * format().bytes_per_frame();
memcpy(output_buffer->payload(), input_ptr, bytes_copied);
input_ptr += bytes_copied;
output_buffer_frame += frames_copied;
output_frames_outstanding -= frames_copied;
}
return input_buffer;
}
} // namespace media::audio