1
Fork 0

tracks can now be muted

This commit is contained in:
Leonard Ritter 2010-09-06 19:52:56 +02:00
parent 239e851cb7
commit eaa740fb53
8 changed files with 74 additions and 18 deletions

View File

@ -74,6 +74,7 @@ void JSongWriter::collect(Json::Value &root, Loop &loop) {
void JSongWriter::collect(Json::Value &root, Track &track) {
root["midi_channel"] = track.midi_channel;
root["midi_port"] = track.midi_port;
root["mute"] = track.mute;
}
void JSongWriter::collect(Json::Value &root, Model &model) {
@ -218,6 +219,7 @@ void JSongReader::build(const Json::Value &root, Loop &loop) {
void JSongReader::build(const Json::Value &root, Track &track) {
extract(root["midi_channel"], track.midi_channel);
extract(root["midi_port"], track.midi_port);
extract(root["mute"], track.mute);
}
void JSongReader::build(const Json::Value &root, Model &model) {

View File

@ -761,7 +761,18 @@ public:
builder->get_widget_derived("track_view", track_view);
assert(track_view);
track_view->set_model(model);
track_view->set_model(model);
track_view->signal_mute_toggled().connect(
sigc::mem_fun(*this, &App::on_track_view_mute_toggled));
}
void on_track_view_mute_toggled(int index, bool mute) {
if (!player)
return;
if (mute) {
player->stop_events(index);
}
}
void init_timer() {

View File

@ -416,6 +416,7 @@ int Loop::get_end() const {
Track::Track() {
midi_port = 0;
midi_channel = 0;
mute = false;
}
//=============================================================================

View File

@ -237,6 +237,7 @@ class Track {
public:
int midi_port;
int midi_channel;
bool mute;
Track();
};

View File

@ -178,7 +178,7 @@ void Player::stop() {
playing = false;
seek(read_position);
for (size_t bus = 0; bus < model->tracks.size(); ++bus) {
rt_messages.all_notes_off(bus);
rt_messages.all_notes_off(bus);
}
}
@ -237,6 +237,10 @@ void Player::play_event(int track, const class PatternEvent &event) {
rt_messages.on_note(track, event.channel, note, ValueNone);
}
void Player::stop_events(int track) {
rt_messages.all_notes_off(track);
}
void Player::mix_events(MessageQueue &queue, int samples) {
assert(model);
@ -246,7 +250,7 @@ void Player::mix_events(MessageQueue &queue, int samples) {
// send status package
queue.status_msg();
mix_frame(queue);
long long framesize = get_frame_size();
long long framesize = get_frame_size();
queue.write_samples += framesize;
queue.position++;
if (model->enable_loop && (queue.position == model->loop.get_end())) {
@ -273,25 +277,29 @@ void Player::mix_frame(MessageQueue &queue) {
for (iter = events.begin(); iter != events.end(); ++iter) {
Song::Event &event = (*iter)->second;
Pattern &pattern = *event.pattern;
if (model->tracks[event.track].mute)
continue; // ignore event
Pattern::iterator row_iter = pattern.begin();
Pattern::Row row;
pattern.collect_events(queue.position - event.frame, row_iter, row);
// first run: process all cc events
for (int channel = 0; channel < pattern.get_channel_count(); ++channel) {
int command = row.get_value(channel, ParamCommand);
int ccindex = row.get_value(channel, ParamCCIndex);
int ccvalue = row.get_value(channel, ParamCCValue);
if (command != ValueNone) {
int value = row.get_value(channel, ParamValue);
if (command == Message::TypeCommandTempo) {
if (value != ValueNone)
model->beats_per_minute = std::max(1,value);
} else {
queue.on_command(event.track, channel, (Message::Type)command,
value, ccindex, ccvalue);
}
}
int command = row.get_value(channel, ParamCommand);
int ccindex = row.get_value(channel, ParamCCIndex);
int ccvalue = row.get_value(channel, ParamCCValue);
if (command != ValueNone) {
int value = row.get_value(channel, ParamValue);
if (command == Message::TypeCommandTempo) {
if (value != ValueNone)
model->beats_per_minute = std::max(1,value);
} else {
queue.on_command(event.track, channel, (Message::Type)command,
value, ccindex, ccvalue);
}
}
queue.on_cc(event.track, ccindex, ccvalue);
}
@ -299,7 +307,7 @@ void Player::mix_frame(MessageQueue &queue) {
for (int channel = 0; channel < pattern.get_channel_count(); ++channel) {
queue.on_note(event.track, channel,
row.get_value(channel, ParamNote),
row.get_value(channel, ParamVolume));
row.get_value(channel, ParamVolume));
}
}

View File

@ -96,6 +96,7 @@ public:
bool is_playing() const;
void play_event(int track, const class PatternEvent &event);
void stop_events(int track);
protected:
void premix();

View File

@ -67,6 +67,12 @@ TrackBar::TrackBar(int index, TrackView &view) {
port_eventbox.signal_button_press_event().connect(
sigc::mem_fun(*this, &TrackBar::on_port_button_press_event));
pack_start(port_eventbox, false, true);
mute.set_label("M");
mute.signal_toggled().connect(
sigc::mem_fun(*this, &TrackBar::on_mute_toggled));
view.group_mutes->add_widget(mute);
pack_start(mute, false, true);
update();
@ -80,6 +86,15 @@ TrackBar::~TrackBar() {
view->remove(*this);
}
void TrackBar::on_mute_toggled() {
bool active = mute.get_active();
if (model->tracks[index].mute == active)
return;
model->tracks[index].mute = active;
update();
view->_mute_toggled(index, active);
}
void TrackBar::on_channel(int channel) {
model->tracks[index].midi_channel = channel;
update();
@ -138,6 +153,8 @@ void TrackBar::update() {
sprintf(buffer, "port-%i", track.midi_port);
port.set_text(buffer);
mute.set_active(track.mute);
}
//=============================================================================
@ -149,6 +166,7 @@ TrackView::TrackView(BaseObjectType* cobject,
group_names = Gtk::SizeGroup::create(Gtk::SIZE_GROUP_HORIZONTAL);
group_channels = Gtk::SizeGroup::create(Gtk::SIZE_GROUP_HORIZONTAL);
group_ports = Gtk::SizeGroup::create(Gtk::SIZE_GROUP_HORIZONTAL);
group_mutes = Gtk::SizeGroup::create(Gtk::SIZE_GROUP_HORIZONTAL);
}
TrackView::~TrackView() {
@ -163,6 +181,10 @@ void TrackView::destroy_bars() {
}
TrackView::type_mute_toggled TrackView::signal_mute_toggled() {
return _mute_toggled;
}
void TrackView::set_model(class Model &model) {
this->model = &model;
}

View File

@ -31,6 +31,7 @@ public:
Gtk::Menu port_menu;
Gtk::Label port;
Gtk::RadioButtonGroup port_radio_group;
Gtk::ToggleButton mute;
Model *model;
class TrackView *view;
@ -40,6 +41,7 @@ public:
bool on_channel_button_press_event(GdkEventButton *event);
bool on_port_button_press_event(GdkEventButton *event);
bool on_name_button_press_event(GdkEventButton *event);
void on_mute_toggled();
void on_channel(int channel);
void on_port(int port);
@ -48,8 +50,10 @@ public:
//=============================================================================
class TrackView : public Gtk::VBox {
friend class TrackBar;
public:
typedef std::vector<TrackBar *> TrackBarArray;
typedef std::vector<TrackBar *> TrackBarArray;
typedef sigc::signal<void, int, bool> type_mute_toggled;
TrackView(BaseObjectType* cobject,
const Glib::RefPtr<Gtk::Builder>& builder);
@ -58,6 +62,7 @@ public:
Glib::RefPtr<Gtk::SizeGroup> group_names;
Glib::RefPtr<Gtk::SizeGroup> group_channels;
Glib::RefPtr<Gtk::SizeGroup> group_ports;
Glib::RefPtr<Gtk::SizeGroup> group_mutes;
Model *model;
TrackBarArray bars;
@ -65,6 +70,11 @@ public:
void destroy_bars();
void set_model(class Model &model);
void update_tracks();
type_mute_toggled signal_mute_toggled();
protected:
type_mute_toggled _mute_toggled;
};
//=============================================================================