- audio_filter_.reset(new audio_filter(
- boost::rational<int>(1, source_->samplerate()),
- source_->samplerate(),
- source_sampleformat_,
- av_get_default_channel_layout(source_num_channels_),
- sink_->supported_samplerates(),
- sink_->supported_sample_formats(),
- {},
- afilter_));
+ std::vector<audio_input_pad> input_pads;
+ std::vector<audio_output_pad> output_pads;
+
+ for (auto& source_audio_stream : source_audio_streams_)
+ {
+ input_pads.emplace_back(
+ boost::rational<int>(1, source_->samplerate()),
+ source_->samplerate(),
+ source_audio_stream.sampleformat,
+ av_get_default_channel_layout(source_audio_stream.num_channels));
+ }
+
+ auto total_num_channels = cpplinq::from(source_audio_streams_)
+ .select([](const audio_stream_info& info) { return info.num_channels; })
+ .aggregate(0, std::plus<int>());
+
+ if (total_num_channels > 1 && sink_->wanted_num_audio_streams() > 1)
+ CASPAR_THROW_EXCEPTION(invalid_operation()
+ << msg_info("only one-to-many or many-to-one audio stream conversion supported."));
+
+ std::wstring amerge;
+
+ if (sink_->wanted_num_audio_streams() == 1 && !sink_->wanted_num_channels_per_stream())
+ {
+ output_pads.emplace_back(
+ sink_->supported_samplerates(),
+ sink_->supported_sample_formats(),
+ std::vector<int64_t>({ av_get_default_channel_layout(total_num_channels) }));
+
+ if (source_audio_streams_.size() > 1)
+ {
+ for (int i = 0; i < source_audio_streams_.size(); ++i)
+ amerge += L"[a:" + boost::lexical_cast<std::wstring>(i) + L"]";
+
+ amerge += L"amerge=inputs=" + boost::lexical_cast<std::wstring>(source_audio_streams_.size());
+ }
+ }
+
+ std::wstring afilter = u16(afilter_);
+
+ if (!amerge.empty())
+ {
+ afilter = prepend_filter(u16(afilter), amerge);
+ afilter += L"[aout:0]";
+ }
+
+ audio_filter_.reset(new audio_filter(input_pads, output_pads, u8(afilter)));