22 #include <experimental/filesystem> 32 std::vector< float > table( N + 1, 0 );
33 for (
auto n = 0; n <= N; ++n )
41 inline auto create_kernels(
int N,
float lowpass_cutoff,
float highpass_cutoff )
43 std::vector< float > highpass_kernel( 2 * N, 0.f );
44 std::vector< float > lowpass_kernel( 2 * N, 0.f );
46 for (
auto i = 0; i <= M; ++i )
50 highpass_kernel[ i ] =
51 blackman_table[ M / 2 ] * ( 1.f -
wave_form::sinc( highpass_cutoff, 0 ) );
55 highpass_kernel[ i ] =
56 -blackman_table[ i ] *
wave_form::sinc( highpass_cutoff, ( i - M / 2 ) );
61 return std::make_pair( lowpass_kernel, highpass_kernel );
67 std::vector< float > lowpass_kernel;
68 std::vector< float > highpass_kernel;
69 std::tie( lowpass_kernel, highpass_kernel ) =
70 create_kernels< M >( N, lowpass_cutoff, highpass_cutoff );
71 auto low = std::async( std::launch::async, [&] {
return audio::fft( lowpass_kernel ); } );
72 auto high = std::async( std::launch::async, [&] {
return audio::fft( highpass_kernel ); } );
73 return std::make_pair( low.get(), high.get() );
78 return std::max( signal, 0.0 );
84 static constexpr
auto M = 256;
101 std::vector< float > osc( 2 * sub_sample_size, 0.f );
104 const auto pos = double( frame_pos ) /
sample_rate;
112 osc[ std::size_t( i ) ] = scale * ( *this )( pos );
118 for (
auto k = 0u; k < osc.size(); ++k )
120 sample_[ k ] += osc[ k ];
124 std::vector< std::pair< float, float > > result( sub_sample_size );
125 for (
auto k = 0u; k < result.size(); ++k )
127 result[ k ] =
delay( sample_[ k ] );
134 highpass_frequency = frequency;
140 lowpass_frequency = frequency;
146 auto [ lowpass_filter_response, highpass_filter_response ] =
147 create_filter_response< M >( N, lowpass_frequency /
sample_rate,
149 std::lock_guard lock{filter_mutex};
150 filter_spectrum.resize( lowpass_filter_response.size() );
151 for (
auto i = 0u; i < filter_spectrum.size(); ++i )
153 filter_spectrum[ i ] = lowpass_filter_response[ i ] * highpass_filter_response[ i ];
159 std::lock_guard lock{filter_mutex};
161 if ( filter_spectrum.size() != spectrum.size() )
165 for (
auto i = 0u; i < spectrum.size(); ++i )
167 spectrum[ i ] *= filter_spectrum[ i ];
187 mutable std::mutex filter_mutex;
195 const std::vector< float >& reverb )
197 std::vector< float > output( signal.size() + reverb.size(), 0 );
200 std::vector< std::future< void > > done;
201 const auto n_threads = 8;
202 const auto parallel_offset = output.size() / n_threads;
203 for (
auto l = 0; l < n_threads; ++l )
205 done.push_back( std::async( std::launch::async, [&, l] {
206 for (
auto j = l * parallel_offset; j < ( l + 1 ) * parallel_offset; ++j )
208 for (
auto k = std::max( 0,
int( j + 1 - reverb.size() ) );
209 k < std::min( j + 1, signal.size() ); ++k )
211 output[ j ] += reverb[ j - k ] * signal[ k ];
217 for (
auto& d : done )
227 template <
class spectrum_t >
230 const std::vector< std::pair< spectrum_t, spectrum_t > >& filters,
231 std::vector< std::future< std::pair< std::vector< float >, std::vector< float > > > >& done,
232 bool first_long_part )
294 auto lf = std::async( std::launch::async, [&] {
295 auto s = spectrum_left;
296 for (
auto k = 0u; k < s.size(); ++k )
298 s[ k ] *= 0.5f * filters[ 0 ].first[ k ];
302 auto s = spectrum_right;
303 for (
auto k = 0u; k < s.size(); ++k )
305 s[ k ] *= 0.5f * filters[ 0 ].first[ k ];
308 return std::tuple{lf.get(), rf};
344 template <
class ClockReceiver >
350 static constexpr
auto number_of_oscillators = 2u;
354 template <
class Callback >
356 : ClockReceiver{callback}, chains_( number_of_oscillators ), clock_dt_( 24, 0 )
358 for (
auto& chain : chains_ )
360 chain.update_filter_spectrum( sub_sample_size );
363 generating_thread_terminated_ = std::async( std::launch::async, [
this] {
367 const auto initial_size = buffer.frames.size();
371 std::vector< float > last_osc1( N, 0.f );
373 auto write_buffer = [&] {
374 using namespace std::chrono;
375 const auto start_time = steady_clock::now();
376 auto signal0_f = std::async( std::launch::async, [&] {
377 return chain( 0 ).get_sample( frame_pos_, sample_rate_ );
380 auto signal1 = chain( 1 ).get_sample( frame_pos_, sample_rate_ );
381 auto signal0 = signal0_f.get();
382 std::vector< float > left( 2 * sub_sample_size, 0 );
383 std::vector< float > right( 2 * sub_sample_size, 0 );
384 for (
auto k = 0u; k < signal0.size(); ++k )
386 left[ k ] = signal0[ k ].first + signal1[ k ].first;
387 right[ k ] = signal0[ k ].second + signal1[ k ].second;
390 bool use_reverb =
false;
391 spectrum_t spectrum_left;
392 spectrum_t spectrum_right;
394 std::lock_guard lock{reverb_mutex_};
395 if ( !reverb_spectra_.empty() )
399 auto spectrum0_f = std::async( std::launch::async,
402 spectrum_left = spectrum0_f.get();
403 const auto [ tmp_l, tmp_r ] =
405 sub_parts_, first_double_part_ );
408 std::lock_guard lock{left_mutex_};
409 for (
auto k = 0u; k < tmp_l.size(); ++k )
411 last_osc0_lhs_before_filter[ k ] += tmp_l[ k ];
415 std::lock_guard lock{right_mutex_};
416 for (
auto k = 0u; k < tmp_r.size(); ++k )
418 last_osc0_rhs_before_filter[ k ] += tmp_r[ k ];
421 if ( sub_parts_[ 0 ].valid() )
423 const auto [ lhs1, rhs1 ] = sub_parts_[ 0 ].get();
424 for (
auto k = 0u; k < lhs1.size(); ++k )
426 last_osc0_lhs_before_filter[ k ] += lhs1[ k ];
427 last_osc0_rhs_before_filter[ k ] += rhs1[ k ];
431 if ( sub_parts_[ 1 ].valid() && sub_parts_[ 2 ].valid() )
433 const auto [ lhs2, rhs2 ] =
434 sub_parts_[ first_double_part_ ? 1 : 2 ].get();
435 for (
auto k = 0u; k < lhs2.size(); ++k )
437 last_osc0_lhs_before_filter[ k ] += lhs2[ k ];
438 last_osc0_rhs_before_filter[ k ] += rhs2[ k ];
442 if ( sub_parts_[ 3 + quad_part_id_ ].valid() )
444 const auto [ lhs, rhs ] = sub_parts_[ 3 + quad_part_id_ ].get();
445 for (
auto k = 0u; k < lhs.size(); ++k )
447 last_osc0_lhs_before_filter[ k ] += lhs[ k ];
448 last_osc0_rhs_before_filter[ k ] += rhs[ k ];
455 buffer.frames.resize( initial_size );
458 for (
auto i = 0; i < N; ++i )
460 buffer.frames[
size_type( 2 * i ) ] = 0.5 * left[ i ];
461 buffer.frames[
size_type( 2 * i + 1 ) ] = 0.5 * right[ i ];
466 for (
auto i = 0; i < N; ++i )
469 0.5 * ( dry_reverb_ratio_ * left[ i ] +
470 wet_reverb_ratio_ * last_osc0_lhs_before_filter[ i ] );
471 buffer.frames[
size_type( 2 * i + 1 ) ] =
472 0.5 * ( dry_reverb_ratio_ * right[ i ] +
473 wet_reverb_ratio_ * last_osc0_rhs_before_filter[ i ] );
477 double_buffer_.swap_write_buffer( buffer );
479 std::cout <<
"elapsed: " 486 sub_parts_[ 0 ] = std::async( std::launch::async, [spectrum_left,
491 auto s = spectrum_left;
492 auto t = spectrum_right;
493 for (
auto k = 0u; k < s.size(); ++k )
495 s[ k ] *= 0.5f *
filter.first[ k ];
496 t[ k ] *= 0.5f *
filter.second[ k ];
501 sub_parts_[ first_double_part_ ? 1 : 2 ] =
502 std::async( std::launch::async, [spectrum_left, spectrum_right,
503 filter1 = reverb_spectra_[ 2 ],
504 filter2 = reverb_spectra_[ 3 ]] {
505 auto s = spectrum_left;
506 auto t = spectrum_right;
507 for (
auto k = 0u; k < s.size(); ++k )
509 s[ k ] *= 0.5f * filter1.first[ k ];
510 t[ k ] *= 0.5f * filter1.second[ k ];
515 const auto offset = left.size() / 2;
516 left.resize( left.size() + offset, 0 );
517 right.resize( right.size() + offset, 0 );
521 for (
auto k = 0u; k < s.size(); ++k )
523 s[ k ] *= 0.5f * filter2.first[ k ];
524 t[ k ] *= 0.5f * filter2.second[ k ];
529 for (
auto i = 0u; i < left2.size(); ++i )
531 left[ offset + i ] += left2[ i ];
532 right[ offset + i ] += right2[ i ];
535 return std::pair{std::move( left ), std::move( right )};
537 sub_parts_[ 3 + quad_part_id_ ] = std::async(
539 [spectrum_left = std::move( spectrum_left ),
540 spectrum_right = std::move( spectrum_right ),
this] {
541 auto s = spectrum_left;
542 auto t = spectrum_right;
543 for (
auto k = 0u; k < s.size(); ++k )
545 s[ k ] *= 0.5f * reverb_spectra_[ 4 ].first[ k ];
546 t[ k ] *= 0.5f * reverb_spectra_[ 4 ].second[ k ];
551 const auto offset = left.size() / 2;
552 left.resize( left.size() + 3 * offset, 0 );
553 right.resize( right.size() + 3 * offset, 0 );
557 for (
auto k = 0u; k < s.size(); ++k )
559 s[ k ] *= 0.5f * reverb_spectra_[ 5 ].first[ k ];
560 t[ k ] *= 0.5f * reverb_spectra_[ 5 ].second[ k ];
565 for (
auto i = 0u; i < left2.size(); ++i )
567 left[ offset + i ] += left2[ i ];
568 right[ offset + i ] += right2[ i ];
573 for (
auto k = 0u; k < s.size(); ++k )
575 s[ k ] *= 0.5f * reverb_spectra_[ 6 ].first[ k ];
576 t[ k ] *= 0.5f * reverb_spectra_[ 6 ].second[ k ];
581 for (
auto i = 0u; i < left2.size(); ++i )
583 left[ 2 * offset + i ] += left2[ i ];
584 right[ 2 * offset + i ] += right2[ i ];
589 for (
auto k = 0u; k < s.size(); ++k )
591 s[ k ] *= 0.5f * reverb_spectra_[ 7 ].first[ k ];
592 t[ k ] *= 0.5f * reverb_spectra_[ 7 ].second[ k ];
597 for (
auto i = 0u; i < left2.size(); ++i )
599 left[ 3 * offset + i ] += left2[ i ];
600 right[ 3 * offset + i ] += right2[ i ];
603 return std::pair{std::move( left ), std::move( right )};
605 first_double_part_ = !first_double_part_;
606 quad_part_id_ = ( ++quad_part_id_ ) % 4;
608 std::lock_guard lock_left{left_mutex_};
609 std::lock_guard lock_right{right_mutex_};
610 last_osc0_lhs_before_filter.clean_and_move( N );
611 last_osc0_rhs_before_filter.clean_and_move( N );
619 if ( running_ && !double_buffer_.has_new_data() )
623 double_buffer_reader_->set_continue_reading(
false );
626 double_buffer_.swap_buffers();
637 generating_thread_terminated_.wait();
642 return chains_[ idx ];
647 return chains_[ idx ];
652 if ( device_id_ < 0 )
656 std::lock_guard lock{stream_mutex_};
657 if ( stream_.is_active() )
663 const auto parameters = portaudio_.get_parameters( device_id_ );
664 stream_.open_output_stream( parameters, sample_rate_, frames_per_buffer_,
666 std::decay_t< decltype( *double_buffer_reader_ ) > >,
667 double_buffer_reader_.get() );
677 std::lock_guard lock{stream_mutex_};
678 if ( stream_.is_active() )
691 device_id_ = device_id;
697 return portaudio_.get_device_names();
703 if constexpr ( N == 1 )
707 clock_dt_[ clock_dt_counter_++ ] = dt;
708 if ( clock_dt_counter_ == clock_dt_.size() )
710 clock_dt_counter_ = 0;
711 auto beat_dt = std::accumulate( begin( clock_dt_ ), end( clock_dt_ ), 0.0 );
712 const auto bpm = int( std::round( 60 / beat_dt * 10 ) +
713 std::numeric_limits< double >::epsilon() ) /
721 if constexpr ( N == 3 )
726 chain( 0 ).silent_ =
false;
727 chain( 1 ).silent_ =
false;
732 chain( 0 ).silent_ =
true;
733 chain( 1 ).silent_ =
true;
735 chain( 0 ).osc_fade_out_ = chain( 0 ).fade_sample_count_;
736 chain( 1 ).osc_fade_out_ = chain( 1 ).fade_sample_count_;
750 reverb_banks_.clear();
751 std::vector< std::string > folders;
752 const auto path = std::experimental::filesystem::current_path() /
753 std::experimental::filesystem::path(
754 "impulse_responses/EchoThiefImpulseResponseLibrary/" );
755 for (
auto& entry : std::experimental::filesystem::directory_iterator( path ) )
757 if ( !entry.path().has_extension() )
759 reverb_banks_.emplace_back( entry.path() );
760 folders.emplace_back( entry.path().filename() );
771 current_reverb_bank_ = reverb_banks_[
id - 1 ];
773 set_reverb_type_id( 0 );
778 if ( current_reverb_bank_.empty() )
783 std::vector< std::string > reverbs;
784 reverb_files_.clear();
786 std::experimental::filesystem::directory_iterator( current_reverb_bank_ ) )
788 if ( entry.path().has_stem() )
790 const auto filename = entry.path().filename();
791 if ( filename.has_extension() && filename.extension() ==
".wav" )
793 reverb_files_.emplace_back( entry.path() );
794 reverbs.emplace_back( filename.stem() );
803 if (
id <= 0 || current_reverb_bank_.empty() )
805 std::lock_guard lock{reverb_mutex_};
806 reverb_spectra_.clear();
807 std::lock_guard lock_left{left_mutex_};
809 std::lock_guard lock_right{right_mutex_};
816 reverb_channels[ 0 ].resize( 32 * 1024 );
817 reverb_channels[ 1 ].resize( 32 * 1024 );
819 const auto start_time = std::chrono::steady_clock::now();
820 const auto n_filters = reverb_channels[ 0 ].size() / (
sub_sample_size );
821 const auto filter_offset = reverb_channels[ 0 ].size() / n_filters;
822 std::vector< std::future< std::pair< spectrum_t, spectrum_t > > > done;
823 for (
auto i = 0u; i < n_filters; ++i )
826 std::async( std::launch::async, [i, filter_offset, &reverb_channels] {
827 auto left = std::vector< float >(
828 begin( reverb_channels[ 0 ] ) + i * filter_offset,
829 begin( reverb_channels[ 0 ] ) + ( i + 1 ) * filter_offset );
830 auto right = std::vector< float >(
831 begin( reverb_channels[ 1 ] ) + i * filter_offset,
832 begin( reverb_channels[ 1 ] ) + ( i + 1 ) * filter_offset );
833 left.resize( 2 * filter_offset, 0 );
834 right.resize( 2 * filter_offset, 0 );
838 sub_parts_.resize( 7 );
840 std::lock_guard lock{reverb_mutex_};
841 reverb_spectra_.resize( n_filters );
842 for (
auto i = 0; i < n_filters; ++i )
844 reverb_spectra_[ i ] = done[ i ].get();
848 std::chrono::steady_clock::now() - start_time )
850 std::cout <<
"set reverb in " << elapsed <<
"ms" << std::endl;
851 std::lock_guard lock_left{left_mutex_};
852 last_osc0_lhs_before_filter =
854 std::lock_guard lock_right{right_mutex_};
855 last_osc0_rhs_before_filter =
867 std::mutex stream_mutex_{};
869 std::vector< chain_t > chains_{};
871 std::shared_ptr< audio::double_buffer_reader_t > double_buffer_reader_{
872 std::make_shared< audio::double_buffer_reader_t >( double_buffer_ )};
873 std::future< void > generating_thread_terminated_;
874 int sample_rate_{44100};
876 std::atomic_int frame_pos_{0};
877 std::size_t frames_per_buffer_{256};
878 std::atomic_bool running_{
false};
879 std::atomic_bool stopped_{
false};
880 std::function< void( beat_duration ) > set_bpm_ = [](
beat_duration ) {};
881 std::vector< double > clock_dt_;
882 std::vector< double >::size_type clock_dt_counter_{0};
884 std::mutex reverb_mutex_;
885 using spectrum_t = std::vector< std::complex< float > >;
886 std::vector< std::pair< spectrum_t, spectrum_t > > reverb_spectra_;
888 std::mutex left_mutex_;
889 std::mutex right_mutex_;
893 std::vector< std::experimental::filesystem::path > reverb_banks_{};
894 std::vector< std::experimental::filesystem::path > reverb_files_{};
895 std::experimental::filesystem::path current_reverb_bank_{};
897 std::atomic< double > dry_reverb_ratio_{1};
898 std::atomic< double > wet_reverb_ratio_{0};
900 std::vector< std::future< std::pair< std::vector< float >, std::vector< float > > > >
902 bool first_double_part_{
true};
903 int quad_part_id_{0};
void set_lowpass_frequency(double frequency)
Definition: synth.hpp:138
std::vector< std::complex< float > > spectrum_t
Definition: synth.hpp:86
std::vector< std::complex< T > > fft(const std::vector< T > &x)
Definition: fft.hpp:167
constexpr T compute_wet_ratio(T x) noexcept
Definition: dry_wet.hpp:30
Definition: synth.hpp:345
chain_t & chain(size_type idx) noexcept
Definition: synth.hpp:640
constexpr message_t< 1 > realtime_clock() noexcept
Definition: realtime.hpp:8
copyable_atomic< double > highpass_gain
Definition: synth.hpp:179
const auto F
Definition: note.hpp:40
auto get_sample(int frame_pos, int sample_rate)
Definition: synth.hpp:98
void set_dry_wet_ratio(double ratio) noexcept
Definition: synth.hpp:859
Definition: portaudio.hpp:105
std::vector< chain_t >::size_type size_type
Definition: synth.hpp:348
void start() noexcept
Definition: synth.hpp:650
Definition: oscillator.hpp:20
std::conditional_t< greater_than< number_of_bytes, 0 >::value, std::array< std::byte, number_of_bytes >, std::vector< std::byte > > message_t
Definition: message_type.hpp:18
double blackman(int n, int N)
Definition: transfer_function.hpp:74
#define SEQUENCER_ASSERT(cond)
Definition: assert.hpp:8
backend_t(Callback callback)
Definition: synth.hpp:355
static constexpr auto sub_sample_size
Definition: synth.hpp:83
audio::dry_wet_t< audio::oscillator_t > frequency_modulation
Definition: synth.hpp:173
Definition: beat_duration.hpp:13
std::chrono::duration< double, std::milli > milliseconds
Definition: units.hpp:7
auto overlay_add_sub(const spectrum_t &spectrum_left, const spectrum_t &spectrum_right, const std::vector< std::pair< spectrum_t, spectrum_t > > &filters, std::vector< std::future< std::pair< std::vector< float >, std::vector< float > > > > &done, bool first_long_part)
Definition: synth.hpp:228
Definition: envelope.hpp:11
void update_filter_spectrum(int N)
Definition: synth.hpp:144
auto create_filter_response(int N, float lowpass_cutoff, float highpass_cutoff)
Definition: synth.hpp:65
Definition: sample.hpp:74
std::vector< float > create_blackman_table(int N)
Definition: synth.hpp:30
audio::dry_wet_t< audio::oscillator_t > ring_modulation
Definition: synth.hpp:172
void stop() noexcept
Definition: synth.hpp:673
void clean_and_move(size_type N) noexcept
Definition: ring_buffer.hpp:115
void receive_message(double dt, const midi::message_t< N > &message)
Definition: synth.hpp:701
constexpr double make_vca(double signal)
Definition: synth.hpp:76
Definition: portaudio.hpp:29
double operator()(double pos)
Definition: synth.hpp:88
auto convolution(const std::vector< float > &signal, const std::vector< float > &reverb)
Definition: synth.hpp:194
copyable_atomic< int > sample_rate
Definition: synth.hpp:180
std::vector< std::string > available_reverb_banks()
Definition: synth.hpp:748
std::atomic_int osc_fade_out_
Definition: synth.hpp:183
auto create_kernels(int N, float lowpass_cutoff, float highpass_cutoff)
Definition: synth.hpp:41
void set_reverb_type_id(int id)
Definition: synth.hpp:801
int fade_sample_count_
Definition: synth.hpp:184
void set_reverb_bank_id(int id)
Definition: synth.hpp:766
std::atomic_bool silent_
Definition: synth.hpp:182
Definition: dry_wet.hpp:36
copyable_atomic< double > lowpass_gain
Definition: synth.hpp:178
constexpr auto note_on
Definition: byte.hpp:9
void filter(spectrum_t &spectrum) const
Definition: synth.hpp:157
void set_bpm_functor(F f)
Definition: synth.hpp:743
std::vector< T > inverse_fft(const std::vector< std::complex< T > > &x)
Definition: fft.hpp:260
constexpr auto note_off
Definition: byte.hpp:10
audio::dry_wet_t< audio::stereo_repeated_delay_t, true > delay
Definition: synth.hpp:175
copyable_atomic< bool > vca_mode
Definition: synth.hpp:176
int play_callback(const void *, void *output_buffer, unsigned long frames_per_buffer, const PaStreamCallbackTimeInfo *, PaStreamCallbackFlags, void *user_data)
Definition: portaudio.hpp:178
static constexpr auto M
Definition: synth.hpp:84
audio::oscillator_t oscillator
Definition: synth.hpp:171
void set_device(int device_id)
Definition: synth.hpp:689
std::vector< std::vector< float > > read(const std::vector< std::uint8_t > &data)
Definition: wave_reader.hpp:91
copyable_atomic< bool > vca_enabled
Definition: synth.hpp:177
void set_highpass_frequency(double frequency)
Definition: synth.hpp:132
Definition: double_buffer.hpp:11
void trigger() noexcept
Definition: synth.hpp:684
std::vector< std::string > available_audio_devices() const
Definition: synth.hpp:695
~backend_t()
Definition: synth.hpp:634
constexpr T compute_dry_ratio(T x) noexcept
Definition: dry_wet.hpp:24
audio::envelope_t envelope
Definition: synth.hpp:174
std::vector< std::string > available_reverbs()
Definition: synth.hpp:776
const chain_t & chain(size_type idx) const noexcept
Definition: synth.hpp:645