20 AudioSampleProcessor (
25 auto out_ref = dependencies.port_registry_.create_object<
dsp::AudioPort> (
26 u8
"Stereo Out", PortFlow::Output, AudioPort::BusLayout::Stereo, 2);
27 out_ref.get_object_as<
dsp::AudioPort> ()->set_symbol (u8
"stereo_out");
28 add_output_port (out_ref);
29 set_name (u8
"Audio Sample Processor");
37 struct PlayableSampleSingleChannel
39 using UnmutableSampleSpan = std::span<const float>;
40 PlayableSampleSingleChannel (
41 UnmutableSampleSpan buf,
45 std::source_location source_location)
47 start_offset_ (start_offset), source_location_ (source_location)
70 std::source_location source_location_;
73 using QueueSingleChannelSampleCallback =
86 if (sample.buf_.empty ()) [[unlikely]]
92 samples_to_play_.emplace_back (sample);
93 if (queue_sample_cb_.has_value ())
95 std::invoke (queue_sample_cb_.value (), sample);
99 void set_queue_sample_callback (QueueSingleChannelSampleCallback cb)
101 queue_sample_cb_ = std::move (cb);
104 auto get_output_audio_port_non_rt ()
const
109 auto get_output_audio_port_rt ()
const {
return audio_out_; }
115 const auto cycle_offset = time_nfo.local_offset_;
116 const auto nframes = time_nfo.nframes_;
118 auto * out_port = get_output_audio_port_rt ();
121 out_port->clear_buffer (cycle_offset, nframes);
124 for (
auto it = samples_to_play_.begin (); it != samples_to_play_.end ();)
129 if (sp.start_offset_ >= nframes)
131 sp.start_offset_ -= nframes;
136 const auto process_samples =
138 if (sp.channel_index_ < 2) [[likely]]
140 out_port->buffers ()->addFrom (
141 sp.channel_index_,
static_cast<int> (fader_buf_offset),
142 &sp.buf_[sp.offset_],
static_cast<int> (len), sp.volume_);
150 const auto max_frames =
151 std::min ((
nframes_t) (sp.buf_.size () - sp.offset_), nframes);
152 process_samples (cycle_offset, max_frames);
155 else if (sp.start_offset_ >= cycle_offset)
157 const auto max_frames = std::min (
159 (cycle_offset + nframes) - sp.start_offset_);
160 process_samples (sp.start_offset_, max_frames);
166 it = samples_to_play_.erase (it);
175 void custom_prepare_for_processing (
179 samples_to_play_.clear ();
180 audio_out_ = get_output_ports ()[0].get_object_as<
dsp::AudioPort> ();
183 void custom_release_resources ()
override
185 samples_to_play_.clear ();
186 audio_out_ =
nullptr;
195 boost::container::static_vector<PlayableSampleSingleChannel, 128>
203 std::optional<QueueSingleChannelSampleCallback> queue_sample_cb_;
205 AudioPort * audio_out_{};