Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 30 additions & 3 deletions include/avnd/binding/gstreamer/texture_filter.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -347,9 +347,36 @@ struct element<T> : property_handler
{
GST_DEBUG_OBJECT(this, "fixate_caps direction=%d", direction);

// For dynamic resolution effects, we cannot predetermine output size
// Start with input size as baseline, actual size will be handled in transform
GstCaps* result = gst_caps_fixate(gst_caps_copy(othercaps));
// The src template advertises [1,MAX], so a plain fixate() picks 1x1.
// Default the output to the input resolution; size-changing effects
// renegotiate in transform().
othercaps = gst_caps_make_writable(othercaps);

if(gst_caps_get_size(caps) > 0 && gst_caps_get_size(othercaps) > 0)
{
GstStructure* ins = gst_caps_get_structure(caps, 0);
gint width = 0, height = 0, fps_n = 0, fps_d = 1;
const gboolean have_w = gst_structure_get_int(ins, "width", &width);
const gboolean have_h = gst_structure_get_int(ins, "height", &height);
const gboolean have_fps
= gst_structure_get_fraction(ins, "framerate", &fps_n, &fps_d);

const guint n = gst_caps_get_size(othercaps);
for(guint i = 0; i < n; i++)
{
GstStructure* outs = gst_caps_get_structure(othercaps, i);
if(have_w)
gst_structure_fixate_field_nearest_int(outs, "width", width);
if(have_h)
gst_structure_fixate_field_nearest_int(outs, "height", height);
if(have_fps)
gst_structure_fixate_field_nearest_fraction(
outs, "framerate", fps_n, fps_d);
}
}

// Fixate any remaining fields (format etc.)
GstCaps* result = gst_caps_fixate(othercaps);
return result;
}

Expand Down
24 changes: 20 additions & 4 deletions include/avnd/binding/touchdesigner/chop/audio_processor.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,24 @@ struct audio_processor<T> : public TD::CHOP_CPlusPlusBase
{
if constexpr(avnd::bus_introspection<T>::output_busses == 0)
{
// Analyzer (audio in -> control out): no audio output bus, but still
// prepare() so the scratch buffers exist -- skipping it crashed TD on cook.
auto in0 = inputs->getNumInputs() > 0 ? inputs->getInputCHOP(0) : nullptr;
const int in_ch = in0 ? updateAudioChannels(inputs) : 0;

info->numChannels = 0;
info->numSamples = 0;
info->numSamples = in0 ? in0->numSamples : 0;
info->startIndex = 0;
info->sampleRate = 0;
info->sampleRate = in0 ? in0->sampleRate : default_sample_rate;

avnd::process_setup setup_info{
.input_channels = in_ch,
.output_channels = 0,
.frames_per_buffer = default_buffer_size,
.rate = in0 ? (float)in0->sampleRate : (float)default_sample_rate};
processor.allocate_buffers(setup_info, float{});
implementation.init_channels(in0 ? in0->numChannels : 0, 0);
avnd::prepare(implementation, setup_info);
return true;
}
else if constexpr(avnd::bus_introspection<T>::output_busses >= 1)
Expand Down Expand Up @@ -240,10 +254,12 @@ struct audio_processor<T> : public TD::CHOP_CPlusPlusBase
const TD::OP_CHOPInput* input = inputs->getInputCHOP(0);
assert(input);

// Prepare input/output spans for processing
// Size by output->numChannels (what TD allocated), not
// get_output_channels(impl, 0): bus 0 doesn't exist for analyzers and its
// bogus count runs out_ptrs off the end of output->channels.
const int num_samples = output->numSamples;
const int num_in_channels = total_input_channels;
const int num_out_channels = channels.get_output_channels(implementation, 0);
const int num_out_channels = output->numChannels;

auto in_ptrs = (float**) alloca(sizeof(float*) * num_in_channels + 4);
auto out_ptrs = (float**) alloca(sizeof(float*) * num_out_channels + 4);
Expand Down
6 changes: 6 additions & 0 deletions include/avnd/wrappers/process/per_frame_port.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,10 @@ struct process_adapter<T>
avnd::generic_audio_frame_port<Field>
&& avnd::dynamic_poly_audio_port<Field>)
{
// Hosts that skip the channel manager leave channels==0; derive it
// from the buffer so we don't copy nothing into an uninit output.
if(field.channels <= 0)
field.channels = std::max(0, (int)in.size() - offset);
const int ch = avnd::get_channels(field);
if(offset + ch <= (int)this->m_input_frame_storage.size())
field.frame = this->m_input_frame_storage.data() + offset;
Expand All @@ -143,6 +147,8 @@ struct process_adapter<T>
avnd::generic_audio_frame_port<Field>
&& avnd::dynamic_poly_audio_port<Field>)
{
if(field.channels <= 0)
field.channels = std::max(0, (int)out.size() - offset);
const int ch = avnd::get_channels(field);
if(offset + ch <= (int)this->m_output_frame_storage.size())
field.frame = this->m_output_frame_storage.data() + offset;
Expand Down
Loading