diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index d22af90..d65283a 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -12,6 +12,7 @@ target_include_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_link_directories(${PROJECT_NAME} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) target_link_libraries(${PROJECT_NAME} PUBLIC rtaudio spdlog mempool Taskflow glfw) +option(USE_DOUBLE_SAMPLE "Use double sample" OFF) add_definitions(-Dcore_EXPORTS) if (MSVC) @@ -36,4 +37,10 @@ if (CMAKE_BUILD_TYPE MATCHES "Debug") target_compile_definitions(${PROJECT_NAME} PUBLIC BUILD_DEBUG=1) else() target_compile_definitions(${PROJECT_NAME} PUBLIC BUILD_DEBUG=0) -endif() \ No newline at end of file +endif() + +if (USE_DOUBLE_SAMPLE) + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_DOUBLE_SAMPLE=1) +else() + target_compile_definitions(${PROJECT_NAME} PUBLIC USE_DOUBLE_SAMPLE=0) +endif () \ No newline at end of file diff --git a/core/audio/device/audio_device_manager.cpp b/core/audio/device/audio_device_manager.cpp index 32b41e4..077ade9 100644 --- a/core/audio/device/audio_device_manager.cpp +++ b/core/audio/device/audio_device_manager.cpp @@ -17,7 +17,7 @@ int rt_audio_callback(void* output_buffer, void *input_buffer, void* user_data) { auto* API = static_cast(user_data); - return API->stream_callback(static_cast(output_buffer), static_cast(input_buffer), frames_nums, stream_time, status); + return API->stream_callback(static_cast(output_buffer), static_cast(input_buffer), frames_nums, stream_time, status); } void audio_device_manager::init(singleton_initliazer& initliazer) { @@ -47,7 +47,12 @@ void audio_device_manager::start() { log_current_device_info(); options_.flags = RTAUDIO_NONINTERLEAVED; - auto err = audio_->openStream(&output_params_, input_params, RTAUDIO_FLOAT32, get_sample_rate(), &buffer_size_, &rt_audio_callback, this, &options_); +#if USE_DOUBLE_SAMPLE + RtAudioFormat format = RTAUDIO_FLOAT64; +#else + RtAudioFormat format = RTAUDIO_FLOAT32; +#endif + auto err = audio_->openStream(&output_params_, input_params, format, get_sample_rate(), &buffer_size_, &rt_audio_callback, this, &options_); if (err != RTAUDIO_NO_ERROR) { spdlog::error("failed to open audio stream: {}", audio_->getErrorText()); return; @@ -86,7 +91,7 @@ uint32_t audio_device_manager::get_output_channel_count() const { return 2; // 现在是固定值, 以后可能会改 } -int audio_device_manager::stream_callback(float* output, float* input, unsigned long frame_count, double stream_time, RtAudioStreamStatus status) { +int audio_device_manager::stream_callback(sample_t* output, sample_t* input, unsigned long frame_count, double stream_time, RtAudioStreamStatus status) { if (render_buffers_[0].Num() < frame_count) { // spdlog::warn("render buffer underflow: {}", render_buffers_[0].Num()); return 0; diff --git a/core/audio/device/audio_device_manager.h b/core/audio/device/audio_device_manager.h index 018f426..8399b18 100644 --- a/core/audio/device/audio_device_manager.h +++ b/core/audio/device/audio_device_manager.h @@ -20,7 +20,7 @@ public: [[nodiscard]] CORE_API uint32_t get_input_channel_count() const; [[nodiscard]] CORE_API uint32_t get_output_channel_count() const; - int stream_callback(float* output, float* input, unsigned long frame_count, double stream_time, RtAudioStreamStatus status); + int stream_callback(sample_t* output, sample_t* input, unsigned long frame_count, double stream_time, RtAudioStreamStatus status); void log_all_devices(); void log_current_device_info(); protected: @@ -29,7 +29,7 @@ protected: void stop_render_thread(); void render_thread(); std::thread render_thread_; - std::vector> render_buffers_; + circular_buffer_vector_type render_buffers_; std::atomic_bool render_thread_running_ = false; std::atomic_bool render_thread_should_stop_ = false; #pragma endregion diff --git a/core/audio/misc/audio_buffer.cpp b/core/audio/misc/audio_buffer.cpp index 90e1aac..1fabee8 100644 --- a/core/audio/misc/audio_buffer.cpp +++ b/core/audio/misc/audio_buffer.cpp @@ -15,7 +15,7 @@ void audio_buffer::resize(uint32_t channel_num, uint32_t block_size) { void audio_buffer::clear() { std::scoped_lock lock(lock_); for (auto& channel : buffer_) { - std::memset(channel.data(), 0, channel.size() * sizeof(float)); + std::memset(channel.data(), 0, channel.size() * sizeof(sample_t)); } } @@ -41,9 +41,9 @@ void audio_buffer::multiple(float percent) { } } -std::vector audio_buffer::get_interleaved_buffer() { +std::vector audio_buffer::get_interleaved_buffer() { std::scoped_lock lock(lock_); - std::vector result; + std::vector result; result.reserve(buffer_[0].size() * buffer_.size()); for (uint32_t sample_index = 0; sample_index < buffer_[0].size(); sample_index++) { for (uint32_t channel_index = 0; channel_index < buffer_.size(); channel_index++) { diff --git a/core/audio/misc/audio_buffer.h b/core/audio/misc/audio_buffer.h index 45032f8..df0c96a 100644 --- a/core/audio/misc/audio_buffer.h +++ b/core/audio/misc/audio_buffer.h @@ -6,8 +6,8 @@ class CORE_API audio_buffer { public: - float** get_headers() { return headers_.data(); } - const std::vector& get_headers_vector() { return headers_; } + sample_t** get_headers() { return headers_.data(); } + const std::vector& get_headers_vector() { return headers_; } [[nodiscard]] uint32_t get_num_channels() const { return buffer_.size(); } [[nodiscard]] uint32_t get_num_samples() const { return buffer_[0].size(); } @@ -18,9 +18,9 @@ public: void mix(audio_buffer& in_buffer, float percent = 1.f); void multiple(float percent); - [[nodiscard]] std::vector get_interleaved_buffer(); + [[nodiscard]] std::vector get_interleaved_buffer(); private: - std::vector> buffer_; - std::vector headers_{}; + std::vector> buffer_; + std::vector headers_{}; std::mutex lock_{}; }; diff --git a/core/audio/misc/circular_audio_buffer.h b/core/audio/misc/circular_audio_buffer.h index 7c0e076..e429070 100644 --- a/core/audio/misc/circular_audio_buffer.h +++ b/core/audio/misc/circular_audio_buffer.h @@ -288,8 +288,8 @@ public: } }; -using ui_buffer_type = circular_audio_buffer; -using ui_buffer_vector_type = std::vector; +using circular_buffer_type = circular_audio_buffer; +using circular_buffer_vector_type = std::vector; #undef checkf #undef check \ No newline at end of file diff --git a/core/audio/mixer/channel_interface.h b/core/audio/mixer/channel_interface.h index f03cddd..788f690 100644 --- a/core/audio/mixer/channel_interface.h +++ b/core/audio/mixer/channel_interface.h @@ -4,6 +4,8 @@ #include #include +#include "extern.h" + class mixer_track; class channel_node; @@ -20,8 +22,8 @@ public: uint32_t get_input_node_index(channel_node* node); uint32_t get_output_node_index(channel_node* node); - float** get_input_headers() { return input_headers_.data(); } - float** get_output_headers() { return output_headers_.data(); } + sample_t** get_input_headers() { return input_headers_.data(); } + sample_t** get_output_headers() { return output_headers_.data(); } void set_input_channel_node_name(uint32_t node_index, uint32_t channel_index, const std::string& name); void set_output_channel_node_name(uint32_t node_index, uint32_t channel_index, const std::string& name); @@ -37,8 +39,8 @@ public: private: std::map> input_channel_names_; std::map> output_channel_names_; - std::vector input_headers_; - std::vector output_headers_; + std::vector input_headers_; + std::vector output_headers_; }; class mixer_channel_interface : public channel_interface { diff --git a/core/audio/mixer/channel_node.cpp b/core/audio/mixer/channel_node.cpp index 7be5565..0f5482a 100644 --- a/core/audio/mixer/channel_node.cpp +++ b/core/audio/mixer/channel_node.cpp @@ -13,6 +13,6 @@ mixer_channel_node::mixer_channel_node(channel_interface* in_owner, mixer_track* channel_headers_.push_back(headers[in_node_index * 2 + 1]); } -const std::vector& null_channel_node::get_channel_headers() { +const std::vector& null_channel_node::get_channel_headers() { return g_mixer.zero_track->buffer.get_headers_vector(); } diff --git a/core/audio/mixer/channel_node.h b/core/audio/mixer/channel_node.h index cbbaa49..af3d78f 100644 --- a/core/audio/mixer/channel_node.h +++ b/core/audio/mixer/channel_node.h @@ -2,6 +2,7 @@ #include #include #include +#include "extern.h" class mixer_track; class channel_interface; @@ -18,7 +19,7 @@ public: channel_node(channel_interface* in_owner, channel_node_type in_type) : owner(in_owner), type(in_type) {} - virtual const std::vector& get_channel_headers() = 0; + virtual const std::vector& get_channel_headers() = 0; virtual std::string get_name() = 0; channel_interface* owner; @@ -29,13 +30,13 @@ class mixer_channel_node : public channel_node { public: mixer_channel_node(channel_interface* in_owner, mixer_track* in_track, uint32_t in_node_index); - const std::vector& get_channel_headers() override { return channel_headers_; } + const std::vector& get_channel_headers() override { return channel_headers_; } std::string get_name() override { return "MixerChannelNode"; } [[nodiscard]] mixer_track* get_track() const { return track_; } private: mixer_track* track_; - std::vector channel_headers_; + std::vector channel_headers_; uint32_t node_index_; }; @@ -48,5 +49,5 @@ public: static null_channel_node* get() { return instance; } std::string get_name() override { return "NullChannelNode"; } - const std::vector& get_channel_headers() override; + const std::vector& get_channel_headers() override; }; diff --git a/core/audio/mixer/mixer_track.cpp b/core/audio/mixer/mixer_track.cpp index 3d8c8ae..4180ae9 100644 --- a/core/audio/mixer/mixer_track.cpp +++ b/core/audio/mixer/mixer_track.cpp @@ -57,7 +57,7 @@ void mixer_track::process(uint32_t in_frames) { void mixer_track::post_process(uint32_t in_frames) { buffer.multiple(get_volume()); for (int i = 0; i < buffer.get_num_channels(); ++i) { - ui_buffer_type& ui_buffer = (*ui_buffers)[i]; + auto& ui_buffer = (*ui_buffers)[i]; ui_buffer.Push(buffer.get_headers()[i], in_frames); } } diff --git a/core/audio/mixer/mixer_track.h b/core/audio/mixer/mixer_track.h index ca55690..5c5fc16 100644 --- a/core/audio/mixer/mixer_track.h +++ b/core/audio/mixer/mixer_track.h @@ -21,7 +21,7 @@ struct mixer_track_link { class mixer_track { public: explicit mixer_track(mixer_track_type in_type) : type_(in_type) { - ui_buffers = std::make_shared(); + ui_buffers = std::make_shared(); } virtual ~mixer_track(); @@ -37,7 +37,7 @@ public: virtual void rename(const std::string& in_name) = 0; [[nodiscard]] virtual std::string get_name() const = 0; - [[nodiscard]] float** get_headers() { return buffer.get_headers(); } + [[nodiscard]] sample_t** get_headers() { return buffer.get_headers(); } [[nodiscard]] mixer_track_type get_type() const { return type_; } @@ -47,7 +47,7 @@ public: [[nodiscard]] float get_volume() const { return volume; } audio_buffer buffer; - std::shared_ptr ui_buffers; + std::shared_ptr ui_buffers; std::vector effects{}; std::vector children{}; multicast_delegate on_processed; diff --git a/core/audio/plugin_host/plugin_host.cpp b/core/audio/plugin_host/plugin_host.cpp index d1e2204..67761e5 100644 --- a/core/audio/plugin_host/plugin_host.cpp +++ b/core/audio/plugin_host/plugin_host.cpp @@ -9,10 +9,10 @@ plugin_host::~plugin_host() { void plugin_host::on_update_buffer_size(int buffer_size) { - ui_buffers = std::make_shared(); + ui_buffers = std::make_shared(); for (uint32_t i = 0; i < get_output_channels(); i++) { - ui_buffer_type buffer(buffer_size * 3); + circular_buffer_type buffer(buffer_size * 3); ui_buffers->emplace_back(std::move(buffer)); } } diff --git a/core/audio/plugin_host/plugin_host.h b/core/audio/plugin_host/plugin_host.h index 744077a..b63d62c 100644 --- a/core/audio/plugin_host/plugin_host.h +++ b/core/audio/plugin_host/plugin_host.h @@ -47,7 +47,7 @@ public: channel_interface* channel = nullptr; std::vector owner_tracks; bool editor_opened = false; - std::shared_ptr ui_buffers; + std::shared_ptr ui_buffers; protected: void create_and_open_editor(); void destroy_editor(); diff --git a/core/audio/plugin_host/vst2/vst2_plugin_host.cpp b/core/audio/plugin_host/vst2/vst2_plugin_host.cpp index a477cd9..4176fc9 100644 --- a/core/audio/plugin_host/vst2/vst2_plugin_host.cpp +++ b/core/audio/plugin_host/vst2/vst2_plugin_host.cpp @@ -217,7 +217,12 @@ void vst2_plugin_host::update_channel_node_name() { void vst2_plugin_host::process(uint32_t frame_num) { // TODO send midi +#if USE_DOUBLE_SAMPLE + effect_->processDoubleReplacing(effect_, channel->get_input_headers(), channel->get_output_headers(), frame_num); +#else effect_->processReplacing(effect_, channel->get_input_headers(), channel->get_output_headers(), frame_num); +#endif + for (int i = 0; i < ui_buffers->size(); ++i) { ui_buffers->at(i).Push(channel->get_output_headers()[i], frame_num); diff --git a/core/extern.h b/core/extern.h index 93d09f5..63566a7 100644 --- a/core/extern.h +++ b/core/extern.h @@ -15,3 +15,9 @@ #else #error Unsupported platform #endif + +#if USE_DOUBLE_SAMPLE + typedef double sample_t; +#else + typedef float sample_t; +#endif