2#include <ossia/dataflow/graph_node.hpp>
3#include <ossia/dataflow/nodes/sound.hpp>
4#include <ossia/dataflow/nodes/sound_utils.hpp>
11 void set_start(std::size_t v) { start = v; }
13 void set_upmix(std::size_t v) { upmix = v; }
15 [[nodiscard]] std::size_t channels()
const {
return m_data.size(); }
17 [[nodiscard]] std::size_t duration()
const
19 return m_data.empty() ? 0 : m_data[0].size();
22 void transport(time_value date)
26 info->m_resampler.transport(
27 info->file_sample_for_model_time(date, 0., m_dataSampleRate));
30 void transport(time_value date,
const ossia::tick_transport_info& tinfo)
32 info->m_resampler.transport(info->file_sample_for_model_time(
33 date, tinfo.current_tempo, m_dataSampleRate));
37 void set_sound(audio_array data)
39 m_handle = std::make_shared<audio_data>();
40 m_handle->data = std::move(data);
43 m_dataSampleRate = 44100;
44 m_data.assign(m_handle->data.begin(), m_handle->data.end());
45 info->m_resampler.reset(
46 0, audio_stretch_mode::None, m_handle->data.size(), m_dataSampleRate,
51 void set_sound(
const audio_handle& hdl,
int channels,
int sampleRate)
57 m_dataSampleRate = sampleRate;
58 m_data.assign(m_handle->data.begin(), m_handle->data.end());
64 const int64_t start,
const int64_t samples_to_write,
65 T**
const audio_array)
const noexcept
67 read_audio_from_buffer(
68 m_data, start, samples_to_write, info->m_start_offset_samples,
69 info->m_loop_duration_samples, info->m_loops, audio_array);
73 void fetch_audio_backward(
74 const int64_t start,
const int64_t samples_to_write,
75 T**
const audio_array)
const noexcept
77 read_audio_from_buffer_backward(
78 m_data, start, samples_to_write, info->m_start_offset_samples,
79 info->m_loop_duration_samples, info->m_loops, audio_array);
82 void run(
const ossia::token_request& t, ossia::exec_state_facade e)
noexcept
87 const std::size_t chan = m_data.size();
88 const std::size_t len = m_data[0].size();
89 ossia::audio_port& ap = *audio_out;
90 ap.set_channels(std::max(this->upmix, chan));
92 const auto [samples_to_read, samples_to_write]
93 = snd::sample_info(e.bufferSize(), e.modelToSamples(), t);
99 if(samples_to_write <= 0)
102 assert(samples_to_write > 0);
104 const auto samples_offset = t.physical_start(e.modelToSamples());
108 if(t.prev_date < info->m_prev_date)
112 if(info->m_prev_date == ossia::time_value{ossia::time_value::infinite_min})
113 info->m_prev_date = t.prev_date;
115 transport(t.prev_date);
120 if(t.prev_date > info->m_prev_date)
122 if(info->m_prev_date == ossia::time_value{ossia::time_value::infinite_min})
123 info->m_prev_date = t.prev_date;
125 transport(t.prev_date);
129 for(std::size_t i = 0; i < chan; ++i)
131 ap.channel(i).resize(e.bufferSize());
134 const double rate_ratio = snd::rate_ratio(m_dataSampleRate, e.sampleRate());
135 const double stretch_ratio = info->update_stretch(t, e, rate_ratio);
136 const double abs_stretch_ratio = std::abs(stretch_ratio);
138 info->m_resampler.run(
139 *
this, t, e, stretch_ratio, rate_ratio, chan, len, samples_to_read,
140 samples_to_write, samples_offset, ap);
142 const bool start_discontinuous = t.start_discontinuous || (m_last_stretch > 70.);
143 const bool end_discontinuous = t.end_discontinuous || (abs_stretch_ratio > 70.);
144 if(abs_stretch_ratio > 70. && m_last_stretch > 70.)
147 for(std::size_t i = 0; i < chan; i++)
149 ossia::snd::do_zero(ap.channel(i), samples_offset, samples_to_write);
155 for(std::size_t i = 0; i < chan; i++)
158 start_discontinuous, end_discontinuous, ap.channel(i), samples_offset,
163 ossia::snd::perform_upmix(this->upmix, chan, ap);
164 ossia::snd::perform_start_offset(this->start, ap);
166 info->m_prev_date = t.date;
167 m_last_stretch = abs_stretch_ratio;
170 sound_processing_info* info{};
171 ossia::audio_port* audio_out{};
173 audio_span<float> m_data{};
178 std::size_t m_dataSampleRate{};
179 audio_handle m_handle{};
180 double m_last_stretch{1.0};