76 switch (m_operation) {
77 case SpectralOperation::FREQUENCY_SHIFT: {
78 auto shift_hz = get_parameter_or<double>(
"shift_hz", 0.0);
79 auto window_size = get_parameter_or<uint32_t>(
"window_size", 1024);
80 auto hop_size = get_parameter_or<uint32_t>(
"hop_size", 512);
81 auto sample_rate = get_parameter_or<double>(
"sample_rate", 48000.0);
83 auto low_freq = std::max(0.0, shift_hz);
84 auto high_freq = sample_rate / 2.0 + shift_hz;
86 if (this->is_in_place()) {
89 return create_output(
transform_spectral_filter(input, low_freq, high_freq, sample_rate, window_size, hop_size, m_working_buffer));
92 case SpectralOperation::PITCH_SHIFT: {
93 auto pitch_ratio = get_parameter_or<double>(
"pitch_ratio", 1.0);
94 auto window_size = get_parameter_or<uint32_t>(
"window_size", 1024);
95 auto hop_size = get_parameter_or<uint32_t>(
"hop_size", 512);
97 double semitones = 12.0 * std::log2(pitch_ratio);
99 if (this->is_in_place()) {
102 return create_output(
transform_pitch_shift(input, semitones, window_size, hop_size, m_working_buffer));
105 case SpectralOperation::SPECTRAL_FILTER: {
106 auto low_freq = get_parameter_or<double>(
"low_freq", 20.0);
107 auto high_freq = get_parameter_or<double>(
"high_freq", 20000.0);
108 auto window_size = get_parameter_or<uint32_t>(
"window_size", 1024);
109 auto hop_size = get_parameter_or<uint32_t>(
"hop_size", 512);
110 auto sample_rate = get_parameter_or<double>(
"sample_rate", 48000.0);
112 if (this->is_in_place()) {
115 return create_output(
transform_spectral_filter(input, low_freq, high_freq, sample_rate, window_size, hop_size, m_working_buffer));
118 case SpectralOperation::HARMONIC_ENHANCE: {
119 auto enhancement_factor = get_parameter_or<double>(
"enhancement_factor", 2.0);
120 auto window_size = get_parameter_or<uint32_t>(
"window_size", 1024);
121 auto hop_size = get_parameter_or<uint32_t>(
"hop_size", 512);
123 if (this->is_in_place()) {
124 auto [data_span, structure_info] = OperationHelper::extract_structured_double(input);
126 auto processor = [enhancement_factor](Eigen::VectorXcd& spectrum, size_t) {
127 for (
int i = 1; i < spectrum.size() / 2; ++i) {
128 double freq_factor = 1.0 + (enhancement_factor - 1.0) * (
double(i) / (spectrum.size() / 2));
129 spectrum[i] *= freq_factor;
130 spectrum[spectrum.size() - i] *= freq_factor;
134 for (
auto& span : data_span) {
136 std::ranges::copy(result, span.begin());
139 auto reconstructed_data = data_span
140 | std::views::transform([](
const auto& span) {
141 return std::vector<double>(span.begin(), span.end());
143 | std::ranges::to<std::vector>();
145 return create_output(OperationHelper::reconstruct_from_double<InputType>(reconstructed_data, structure_info));
148 auto [target_data, structure_info] = OperationHelper::setup_operation_buffer(input, m_working_buffer);
149 auto processor = [enhancement_factor](Eigen::VectorXcd& spectrum, size_t) {
150 for (
int i = 1; i < spectrum.size() / 2; ++i) {
151 double freq_factor = 1.0 + (enhancement_factor - 1.0) * (
double(i) / (spectrum.size() / 2));
152 spectrum[i] *= freq_factor;
153 spectrum[spectrum.size() - i] *= freq_factor;
157 for (
size_t i = 0; i < target_data.size(); ++i) {
159 m_working_buffer[i] = std::move(result);
162 return create_output(OperationHelper::reconstruct_from_double<InputType>(m_working_buffer, structure_info));
165 case SpectralOperation::SPECTRAL_GATE: {
166 auto threshold = get_parameter_or<double>(
"threshold", -40.0);
167 auto window_size = get_parameter_or<uint32_t>(
"window_size", 1024);
168 auto hop_size = get_parameter_or<uint32_t>(
"hop_size", 512);
170 double linear_threshold = std::pow(10.0, threshold / 20.0);
172 if (this->is_in_place()) {
173 auto [data_span, structure_info] = OperationHelper::extract_structured_double(input);
175 auto processor = [linear_threshold](Eigen::VectorXcd& spectrum, size_t) {
176 std::ranges::transform(spectrum, spectrum.begin(), [linear_threshold](
const std::complex<double>& bin) {
177 return (std::abs(bin) > linear_threshold) ? bin : std::complex<double>(0.0, 0.0);
181 for (
auto& span : data_span) {
183 std::ranges::copy(result, span.begin());
186 auto reconstructed_data = data_span
187 | std::views::transform([](
const auto& span) {
188 return std::vector<double>(span.begin(), span.end());
190 | std::ranges::to<std::vector>();
192 return create_output(OperationHelper::reconstruct_from_double<InputType>(reconstructed_data, structure_info));
195 auto [target_data, structure_info] = OperationHelper::setup_operation_buffer(input, m_working_buffer);
196 auto processor = [linear_threshold](Eigen::VectorXcd& spectrum, size_t) {
197 std::ranges::transform(spectrum, spectrum.begin(), [linear_threshold](
const std::complex<double>& bin) {
198 return (std::abs(bin) > linear_threshold) ? bin : std::complex<double>(0.0, 0.0);
202 for (
size_t i = 0; i < target_data.size(); ++i) {
204 m_working_buffer[i] = std::move(result);
207 return create_output(OperationHelper::reconstruct_from_double<InputType>(m_working_buffer, structure_info));
211 return create_output(input);