82 switch (m_operation) {
84 case SpectralOperation::FREQUENCY_SHIFT: {
85 const auto shift_hz = get_parameter_or<double>(
"shift_hz", 0.0);
86 const auto window_size = get_parameter_or<uint32_t>(
"window_size", 1024);
87 const auto hop_size = get_parameter_or<uint32_t>(
"hop_size", 512);
88 const auto sample_rate = get_parameter_or<double>(
"sample_rate", 48000.0);
89 const double lo = std::max(0.0, shift_hz);
90 const double hi = sample_rate / 2.0 + shift_hz;
92 return apply_per_channel(input,
93 [lo, hi, sample_rate, window_size, hop_size](std::span<double> ch) {
94 return D::spectral_filter(ch, lo, hi, sample_rate, window_size, hop_size);
98 case SpectralOperation::PITCH_SHIFT: {
99 const auto pitch_ratio = get_parameter_or<double>(
"pitch_ratio", 1.0);
100 const auto window_size = get_parameter_or<uint32_t>(
"window_size", 2048);
101 const auto hop_size = get_parameter_or<uint32_t>(
"hop_size", 512);
102 const double semitones = 12.0 * std::log2(pitch_ratio);
104 return apply_per_channel(input,
105 [semitones, window_size, hop_size](std::span<double> ch) {
106 return D::pitch_shift(ch, semitones, window_size, hop_size);
110 case SpectralOperation::SPECTRAL_FILTER: {
111 const auto lo_freq = get_parameter_or<double>(
"low_freq", 20.0);
112 const auto hi_freq = get_parameter_or<double>(
"high_freq", 20000.0);
113 const auto sample_rate = get_parameter_or<double>(
"sample_rate", 48000.0);
114 const auto window_size = get_parameter_or<uint32_t>(
"window_size", 1024);
115 const auto hop_size = get_parameter_or<uint32_t>(
"hop_size", 512);
117 return apply_per_channel(input,
118 [lo_freq, hi_freq, sample_rate, window_size, hop_size](std::span<double> ch) {
119 return D::spectral_filter(ch, lo_freq, hi_freq, sample_rate, window_size, hop_size);
123 case SpectralOperation::HARMONIC_ENHANCE: {
124 const auto factor = get_parameter_or<double>(
"enhancement_factor", 2.0);
125 const auto window_size = get_parameter_or<uint32_t>(
"window_size", 1024);
126 const auto hop_size = get_parameter_or<uint32_t>(
"hop_size", 512);
128 return apply_per_channel(input,
129 [factor, window_size, hop_size](std::span<double> ch) {
130 return D::harmonic_enhance(ch, factor, window_size, hop_size);
134 case SpectralOperation::SPECTRAL_GATE: {
135 const auto threshold = get_parameter_or<double>(
"threshold", -40.0);
136 const auto window_size = get_parameter_or<uint32_t>(
"window_size", 1024);
137 const auto hop_size = get_parameter_or<uint32_t>(
"hop_size", 512);
139 return apply_per_channel(input,
140 [threshold, window_size, hop_size](std::span<double> ch) {
141 return D::spectral_gate(ch, threshold, window_size, hop_size);
146 return create_output(input);
200 auto [channels, structure_info] = OperationHelper::extract_structured_double(input);
201 m_working_buffer.resize(channels.size());
202 for (
size_t i = 0; i < channels.size(); ++i)
203 m_working_buffer[i] = func(channels[i]);
205 if (this->is_in_place())
206 for (
size_t i = 0; i < channels.size(); ++i)
207 std::ranges::copy(m_working_buffer[i], channels[i].begin());
209 return create_output(
210 OperationHelper::reconstruct_from_double<InputType>(m_working_buffer, structure_info));