mixer_track效果器

This commit is contained in:
Nanako 2024-06-04 13:52:39 +08:00
parent 86ced664f2
commit cd694d06b7
11 changed files with 247 additions and 26 deletions

View File

@ -12,5 +12,6 @@ void main_window::on_click() {
bool main_window::on_close_request() {
get_arona_application()->shutdown();
connection_.empty();
return Window::on_close_request();
}

View File

@ -7,7 +7,7 @@ public:
main_window() {
box_ = Gtk::Box(Gtk::Orientation::VERTICAL);
button_ = Gtk::Button("Hello, World!");
button_.signal_clicked().connect(mem_fun(*this, &main_window::on_click));
connection_ = button_.signal_clicked().connect(mem_fun(*this, &main_window::on_click));
box_.append(button_);
box_.append(mixer_list_);
@ -23,4 +23,5 @@ private:
Gtk::Box box_;
Gtk::Button button_;
w_mixer_list mixer_list_;
sigc::connection connection_;
};

View File

@ -7,7 +7,8 @@
#include "tool/delta_timer.h"
w_audio_buffer_bar::w_audio_buffer_bar() {
timer_ = std::make_shared<delta_timer>(mem_fun(*this, &w_audio_buffer_bar::on_timer), 1000.f / get_arona_application()->get_screen_refresh_rate());
float Interval = 1000.f / get_arona_application()->get_screen_refresh_rate();
timer_ = std::make_shared<delta_timer>(mem_fun(*this, &w_audio_buffer_bar::on_timer), Interval);
}
void w_audio_buffer_bar::set_buffers(weak_buffer in_buffers) {

View File

@ -1,15 +1,18 @@
#pragma once
#include "gtkmm/drawingarea.h"
#include "extern.h"
class w_volume_bar : public Gtk::DrawingArea {
public:
explicit w_volume_bar(bool vertical = false);
void set_value(double value) {
void set_value(sample_t value) {
if (value_ == value)
return;
value_ = value;
queue_draw();
}
const bool is_vertical;
private:
void on_draw(const Cairo::RefPtr<Cairo::Context>& cr, int width, int height);
double value_ = 0.;
sample_t value_ = 0.;
};

View File

@ -0,0 +1,53 @@
#include "w_effect_item.h"
#include "audio/plugin_host/plugin_host.h"
void w_effect_item::set_effect(plugin_host* in_effect) {
effect_ = in_effect;
effect_name_.set_label(effect_->name);
data_model_->remove_all();
uint32_t param_count = in_effect->get_param_count();
for (int i = 0; i < param_count; ++i) {
auto model_data = effect_value_model::create(in_effect, i);
if (model_data->is_valid())
data_model_->append(model_data);
}
}
w_effect_item::w_effect_item() : Gtk::Box(Gtk::Orientation::VERTICAL) {
data_model_ = Gio::ListStore<effect_value_model>::create();
selection_model_ = Gtk::SingleSelection::create(data_model_);
selection_model_->set_autoselect(true);
factory_ = Gtk::SignalListItemFactory::create();
factory_->signal_setup().connect(mem_fun(*this, &w_effect_item::on_setup_value_widget));
factory_->signal_bind().connect(mem_fun(*this, &w_effect_item::on_bind_value_widget));
list_view_.set_model(selection_model_);
list_view_.set_factory(factory_);
list_view_.set_orientation(Gtk::Orientation::VERTICAL);
append(effect_name_);
append(list_view_);
}
void w_effect_item::on_setup_value_widget(const Glib::RefPtr<Gtk::ListItem>& item) {
const auto widget = Gtk::make_managed<w_effect_value>();
item->set_child(*widget);
}
void w_effect_item::on_bind_value_widget(const Glib::RefPtr<Gtk::ListItem>& item) {
const auto index = item->get_position();
if (auto* widget = dynamic_cast<w_effect_value*>(item->get_child())) {
auto data = data_model_->get_item(index);
widget->set_value(data);
}
}
void w_effect_value::set_value(const Glib::RefPtr<effect_value_model>& in_param) {
param_ = in_param;
param_name_.set_label(in_param->get_name());
}
w_effect_value::w_effect_value() : Gtk::Box(Gtk::Orientation::HORIZONTAL) {
append(param_name_);
}

View File

@ -0,0 +1,54 @@
#pragma once
#include <gtkmm/box.h>
#include <gtkmm/listview.h>
#include <giomm/liststore.h>
#include <gtkmm/singleselection.h>
#include <gtkmm/signallistitemfactory.h>
#include <gtkmm/label.h>
#include "audio/plugin_host/host_param.h"
class plugin_host;
class effect_value_model : public Glib::Object {
public:
host_param param;
bool is_valid() const {
return param.is_valid();
}
const std::string& get_name() const {
return param.get_name();
}
static Glib::RefPtr<effect_value_model> create(plugin_host* in_effect, int32_t index) {
return Glib::make_refptr_for_instance(new effect_value_model(in_effect, index));
}
private:
explicit effect_value_model(plugin_host* in_effect, int32_t index) : param(in_effect, index) {}
};
class w_effect_value : public Gtk::Box {
public:
w_effect_value();
void set_value(const Glib::RefPtr<effect_value_model>& in_param);
private:
Glib::RefPtr<effect_value_model> param_;
Gtk::Label param_name_;
};
class w_effect_item : public Gtk::Box {
public:
w_effect_item();
void set_effect(plugin_host* in_effect);
protected:
void on_setup_value_widget(const Glib::RefPtr<Gtk::ListItem>& item);
void on_bind_value_widget(const Glib::RefPtr<Gtk::ListItem>& item);
private:
plugin_host* effect_;
Glib::RefPtr<Gio::ListStore<effect_value_model>> data_model_;
Glib::RefPtr<Gtk::SingleSelection> selection_model_;
Glib::RefPtr<Gtk::SignalListItemFactory> factory_;
Gtk::Label effect_name_;
Gtk::ListView list_view_;
};

View File

@ -0,0 +1,62 @@
#include "w_effect_list.h"
#include "audio/mixer/mixer_track.h"
#include "w_effect_item.h"
#include "audio/plugin_host/plugin_host_manager.h"
w_effect_list::w_effect_list() : Gtk::Box(Gtk::Orientation::HORIZONTAL), mixer_track_(nullptr) {
{
add_effect_.set_label("add_new_effect");
add_effect_.signal_clicked().connect(mem_fun(*this, &w_effect_list::add_new_effect));
}
data_model_ = Gio::ListStore<mixer_effect_model>::create();
selection_model_ = Gtk::SingleSelection::create(data_model_);
selection_model_->set_autoselect(true);
factory_ = Gtk::SignalListItemFactory::create();
factory_->signal_setup().connect(mem_fun(*this, &w_effect_list::on_setup_effect_widget));
factory_->signal_bind().connect(mem_fun(*this, &w_effect_list::on_bind_effect_widget));
list_view_.set_model(selection_model_);
list_view_.set_factory(factory_);
list_view_.set_orientation(Gtk::Orientation::HORIZONTAL);
append(list_view_);
append(add_effect_);
}
void w_effect_list::set_track(mixer_track* in_mixer_track) {
if (mixer_track_) {
mixer_track_->on_add_effect.remove_object(this);
}
mixer_track_ = in_mixer_track;
mixer_track_->on_add_effect.add_raw(this, &w_effect_list::on_add_effect);
data_model_->remove_all();
for (auto effect : mixer_track_->effects) {
on_add_effect(effect);
}
}
void w_effect_list::on_setup_effect_widget(const Glib::RefPtr<Gtk::ListItem>& item) {
const auto widget = Gtk::make_managed<w_effect_item>();
item->set_child(*widget);
}
void w_effect_list::on_bind_effect_widget(const Glib::RefPtr<Gtk::ListItem>& item) {
const auto index = item->get_position();
if (auto* widget = dynamic_cast<w_effect_item*>(item->get_child())) {
auto data = data_model_->get_item(index);
widget->set_effect(data->effect);
}
}
void w_effect_list::add_new_effect() {
if (!mixer_track_)
return;
auto* host = get_plugin_host_manager()->create_effect_plugin_host(R"(F:\VST\VST64\OTT_x64.dll)");
mixer_track_->add_effect(host);
}
void w_effect_list::on_add_effect(plugin_host* in_effect) {
data_model_->append(mixer_effect_model::create(in_effect));
}

View File

@ -0,0 +1,43 @@
#pragma once
#include <gtkmm/box.h>
#include <gtkmm/listview.h>
#include <giomm/liststore.h>
#include <gtkmm/singleselection.h>
#include <gtkmm/signallistitemfactory.h>
#include <gtkmm/button.h>
class mixer_track;
class plugin_host;
class mixer_effect_model : public Glib::Object {
public:
plugin_host* effect;
static Glib::RefPtr<mixer_effect_model> create(plugin_host* in_effect) {
return Glib::make_refptr_for_instance(new mixer_effect_model(in_effect));
}
protected:
explicit mixer_effect_model(plugin_host* in_effect) : effect(in_effect) {
}
};
class w_effect_list : public Gtk::Box {
public:
w_effect_list();
void set_track(mixer_track* in_mixer_track);
mixer_track* get_track() const { return mixer_track_; }
private:
void add_new_effect();
void on_setup_effect_widget(const Glib::RefPtr<Gtk::ListItem>& item);
void on_bind_effect_widget(const Glib::RefPtr<Gtk::ListItem>& item);
void on_add_effect(plugin_host* in_effect);
Gtk::ListView list_view_;
Glib::RefPtr<Gio::ListStore<mixer_effect_model>> data_model_;
Glib::RefPtr<Gtk::SingleSelection> selection_model_;
Glib::RefPtr<Gtk::SignalListItemFactory> factory_;
mixer_track* mixer_track_;
Gtk::Button add_effect_;
};

View File

@ -4,7 +4,7 @@
#include "audio/mixer/mixer.h"
#include "thread_message/thread_message_hubs.h"
w_mixer_list::w_mixer_list() {
w_mixer_list::w_mixer_list() : Gtk::Box(Gtk::Orientation::VERTICAL) {
mixer* mixer = get_mixer();
{
@ -20,6 +20,7 @@ w_mixer_list::w_mixer_list() {
data_model_ = Gio::ListStore<mixer_list_model>::create();
selection_model_ = Gtk::SingleSelection::create(data_model_);
selection_model_->set_autoselect(true);
selection_model_->signal_selection_changed().connect(mem_fun(*this, &w_mixer_list::on_selection_changed));
factory_ = Gtk::SignalListItemFactory::create();
factory_->signal_setup().connect(mem_fun(*this, &w_mixer_list::on_setup_track_widget));
@ -30,6 +31,7 @@ w_mixer_list::w_mixer_list() {
list_view_.set_orientation(Gtk::Orientation::HORIZONTAL);
append(list_view_);
append(effect_list_);
}
w_mixer_list::~w_mixer_list() {
@ -38,13 +40,15 @@ w_mixer_list::~w_mixer_list() {
mixer->on_remove_track.remove_object(this);
}
void w_mixer_list::on_add_track(mixer_track* mixer_track) {
data_model_->append(mixer_list_model::create(mixer_track));
void w_mixer_list::on_add_track(mixer_track* track) {
data_model_->append(mixer_list_model::create(track));
if (!effect_list_.get_track())
effect_list_.set_track(track);
}
void w_mixer_list::on_remove_track(mixer_track* mixer_track) {
void w_mixer_list::on_remove_track(mixer_track* track) {
for (int i = 0; i < data_model_->get_n_items(); ++i) {
if (data_model_->get_item(i)->mixer == mixer_track) {
if (data_model_->get_item(i)->mixer == track) {
data_model_->remove(i);
return;
}
@ -57,22 +61,19 @@ void w_mixer_list::on_setup_track_widget(const Glib::RefPtr<Gtk::ListItem>& item
}
void w_mixer_list::on_bind_track_widget(const Glib::RefPtr<Gtk::ListItem>& item) {
const auto index = item->get_position() + 1; // 0 is master track
const auto index = item->get_position();
if (auto* widget = dynamic_cast<w_mixer_track*>(item->get_child())) {
const std::vector<mixer_track*>& tracks = get_mixer()->get_tracks();
if (index >= tracks.size()) {
return;
}
widget->set_mixer_track(tracks[index]);
auto data = data_model_->get_item(index);
widget->set_mixer_track(data->mixer);
}
}
void w_mixer_list::on_selection_changed() {
const guint selected = selection_model_->get_selected();
const Glib::RefPtr<mixer_list_model>& selected_model = data_model_->get_item(selected);
void w_mixer_list::on_selection_changed(uint32_t position, uint32_t count) {
const Glib::RefPtr<mixer_list_model>& selected_model = data_model_->get_item(selection_model_->get_selected());
if (!selection_model_) {
return;
}
const mixer_track* track = selected_model->mixer;
mixer_track* track = selected_model->mixer;
spdlog::info("Selected track: {}", track->get_name());
effect_list_.set_track(track);
}

View File

@ -7,15 +7,16 @@
#include "w_mixer_track.h"
#include "audio/mixer/mixer_track.h"
#include "w_effect_list.h"
class mixer_list_model : public Glib::Object {
public:
mixer_track* mixer;
static Glib::RefPtr<mixer_list_model> create(mixer_track* mixer) {
return Glib::make_refptr_for_instance(new mixer_list_model(mixer));
static Glib::RefPtr<mixer_list_model> create(mixer_track* in_mixer) {
return Glib::make_refptr_for_instance(new mixer_list_model(in_mixer));
}
protected:
explicit mixer_list_model(mixer_track* mixer) : mixer(mixer) {}
explicit mixer_list_model(mixer_track* in_mixer) : mixer(in_mixer) {}
};
class w_mixer_list : public Gtk::Box {
@ -23,12 +24,12 @@ public:
w_mixer_list();
~w_mixer_list() override;
private:
void on_add_track(mixer_track* mixer_track);
void on_remove_track(mixer_track* mixer_track);
void on_add_track(mixer_track* track);
void on_remove_track(mixer_track* track);
void on_setup_track_widget(const Glib::RefPtr<Gtk::ListItem>& item);
void on_bind_track_widget(const Glib::RefPtr<Gtk::ListItem>& item);
void on_selection_changed();
void on_selection_changed(uint32_t position, uint32_t count);
Glib::RefPtr<Gio::ListStore<mixer_list_model>> data_model_;
Glib::RefPtr<Gtk::SingleSelection> selection_model_;
Glib::RefPtr<Gtk::SignalListItemFactory> factory_;
@ -36,4 +37,5 @@ private:
Gtk::ListView list_view_;
w_mixer_track* master_track_;
w_effect_list effect_list_;
};

@ -1 +1 @@
Subproject commit 03353ac2c928069792734091f78ef5e32732ac8b
Subproject commit 1b4ee22c9502b55cd063d96fa1c9f82a03cd33fd