新增sample_t和USE_DOUBLE_SAMPLE, 用于双精度渲染

This commit is contained in:
Nana 2024-05-28 10:33:29 +08:00
parent 62162fad92
commit 03353ac2c9
15 changed files with 58 additions and 32 deletions

View File

@ -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()
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 ()

View File

@ -17,7 +17,7 @@ int rt_audio_callback(void* output_buffer, void *input_buffer,
void* user_data)
{
auto* API = static_cast<audio_device_manager*>(user_data);
return API->stream_callback(static_cast<float*>(output_buffer), static_cast<float*>(input_buffer), frames_nums, stream_time, status);
return API->stream_callback(static_cast<sample_t*>(output_buffer), static_cast<sample_t*>(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;

View File

@ -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<circular_audio_buffer<float>> 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

View File

@ -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<float> audio_buffer::get_interleaved_buffer() {
std::vector<sample_t> audio_buffer::get_interleaved_buffer() {
std::scoped_lock lock(lock_);
std::vector<float> result;
std::vector<sample_t> 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++) {

View File

@ -6,8 +6,8 @@
class CORE_API audio_buffer {
public:
float** get_headers() { return headers_.data(); }
const std::vector<float*>& get_headers_vector() { return headers_; }
sample_t** get_headers() { return headers_.data(); }
const std::vector<sample_t*>& 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<float> get_interleaved_buffer();
[[nodiscard]] std::vector<sample_t> get_interleaved_buffer();
private:
std::vector<std::vector<float>> buffer_;
std::vector<float*> headers_{};
std::vector<std::vector<sample_t>> buffer_;
std::vector<sample_t*> headers_{};
std::mutex lock_{};
};

View File

@ -288,8 +288,8 @@ public:
}
};
using ui_buffer_type = circular_audio_buffer<float>;
using ui_buffer_vector_type = std::vector<ui_buffer_type>;
using circular_buffer_type = circular_audio_buffer<sample_t>;
using circular_buffer_vector_type = std::vector<circular_buffer_type>;
#undef checkf
#undef check

View File

@ -4,6 +4,8 @@
#include <string>
#include <vector>
#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<uint32_t, std::map<uint32_t, std::string>> input_channel_names_;
std::map<uint32_t, std::map<uint32_t, std::string>> output_channel_names_;
std::vector<float*> input_headers_;
std::vector<float*> output_headers_;
std::vector<sample_t*> input_headers_;
std::vector<sample_t*> output_headers_;
};
class mixer_channel_interface : public channel_interface {

View File

@ -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<float*>& null_channel_node::get_channel_headers() {
const std::vector<sample_t*>& null_channel_node::get_channel_headers() {
return g_mixer.zero_track->buffer.get_headers_vector();
}

View File

@ -2,6 +2,7 @@
#include <cstdint>
#include <string>
#include <vector>
#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<float*>& get_channel_headers() = 0;
virtual const std::vector<sample_t*>& 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<float*>& get_channel_headers() override { return channel_headers_; }
const std::vector<sample_t*>& 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<float*> channel_headers_;
std::vector<sample_t*> 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<float*>& get_channel_headers() override;
const std::vector<sample_t*>& get_channel_headers() override;
};

View File

@ -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);
}
}

View File

@ -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_buffer_vector_type>();
ui_buffers = std::make_shared<circular_buffer_vector_type>();
}
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_buffer_vector_type> ui_buffers;
std::shared_ptr<circular_buffer_vector_type> ui_buffers;
std::vector<plugin_host*> effects{};
std::vector<mixer_track_link> children{};
multicast_delegate<mixer_track*> on_processed;

View File

@ -9,10 +9,10 @@ plugin_host::~plugin_host() {
void plugin_host::on_update_buffer_size(int buffer_size)
{
ui_buffers = std::make_shared<ui_buffer_vector_type>();
ui_buffers = std::make_shared<circular_buffer_vector_type>();
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));
}
}

View File

@ -47,7 +47,7 @@ public:
channel_interface* channel = nullptr;
std::vector<mixer_track*> owner_tracks;
bool editor_opened = false;
std::shared_ptr<ui_buffer_vector_type> ui_buffers;
std::shared_ptr<circular_buffer_vector_type> ui_buffers;
protected:
void create_and_open_editor();
void destroy_editor();

View File

@ -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);

View File

@ -15,3 +15,9 @@
#else
#error Unsupported platform
#endif
#if USE_DOUBLE_SAMPLE
typedef double sample_t;
#else
typedef float sample_t;
#endif