Created
April 24, 2020 20:52
-
-
Save dsheeler/31efdbed746371f1e50803b594b5857c to your computer and use it in GitHub Desktop.
jack_mixer per output channel mute
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/channel.py b/channel.py | |
index c24702e..da163ae 100644 | |
--- a/channel.py | |
+++ b/channel.py | |
@@ -546,6 +546,12 @@ class OutputChannel(Channel): | |
break | |
self.label_name_event_box.modify_bg(gtk.STATE_NORMAL, self.color_tuple[1]) | |
self.vbox.pack_start(self.label_name_event_box, True) | |
+ self.mute = gtk.ToggleButton() | |
+ self.mute.set_label("M") | |
+ self.mute.set_active(self.channel.mute) | |
+ self.mute.connect("toggled", self.on_mute_toggled) | |
+ self.vbox.pack_start(self.mute, False) | |
+ | |
frame = gtk.Frame() | |
frame.set_shadow_type(gtk.SHADOW_IN) | |
frame.add(self.abspeak); | |
@@ -595,6 +601,10 @@ class OutputChannel(Channel): | |
if event.button == 1: | |
self.on_channel_properties() | |
+ def on_mute_toggled(self, button): | |
+ self.channel.out_mute = self.mute.get_active() | |
+ self.app.update_monitor(self.app.main_mix) | |
+ | |
def unrealize(self): | |
# remove control groups from input channels | |
for input_channel in self.app.channels: | |
@@ -674,6 +684,11 @@ class MainMixChannel(Channel): | |
self.label_name.set_text(self.channel_name) | |
self.label_name.set_size_request(0, -1) | |
self.vbox.pack_start(self.label_name, False) | |
+ self.mute = gtk.ToggleButton() | |
+ self.mute.set_label("M") | |
+ self.mute.set_active(self.channel.mute) | |
+ self.mute.connect("toggled", self.on_mute_toggled) | |
+ self.vbox.pack_start(self.mute, False) | |
frame = gtk.Frame() | |
frame.set_shadow_type(gtk.SHADOW_IN) | |
frame.add(self.abspeak); | |
@@ -708,6 +723,10 @@ class MainMixChannel(Channel): | |
self._init_muted_channels = None | |
self._init_solo_channels = None | |
+ def on_mute_toggled(self, button): | |
+ self.channel.out_mute = self.mute.get_active() | |
+ self.app.update_monitor(self.app.main_mix) | |
+ | |
def unrealize(self): | |
Channel.unrealize(self) | |
self.channel = False | |
diff --git a/jack_mixer.c b/jack_mixer.c | |
index 48cebf7..7842111 100644 | |
--- a/jack_mixer.c | |
+++ b/jack_mixer.c | |
@@ -58,6 +58,7 @@ struct channel | |
struct jack_mixer * mixer_ptr; | |
char * name; | |
bool stereo; | |
+ bool out_mute; | |
float volume_transition_seconds; | |
unsigned int num_volume_transition_steps; | |
float volume; | |
@@ -79,7 +80,8 @@ struct channel | |
jack_nframes_t peak_frames; | |
float peak_left; | |
float peak_right; | |
- | |
+ jack_default_audio_sample_t * tmp_mixed_frames_left; | |
+ jack_default_audio_sample_t * tmp_mixed_frames_right; | |
jack_default_audio_sample_t * frames_left; | |
jack_default_audio_sample_t * frames_right; | |
jack_default_audio_sample_t * prefader_frames_left; | |
@@ -479,6 +481,20 @@ channel_unmute( | |
output_channel_set_muted(channel_ptr->mixer_ptr->main_mix_channel, channel, false); | |
} | |
+void | |
+channel_out_mute( | |
+ jack_mixer_channel_t channel) | |
+{ | |
+ channel_ptr->out_mute = true; | |
+} | |
+ | |
+void | |
+channel_out_unmute( | |
+ jack_mixer_channel_t channel) | |
+{ | |
+ channel_ptr->out_mute = false; | |
+} | |
+ | |
void | |
channel_solo( | |
jack_mixer_channel_t channel) | |
@@ -502,6 +518,13 @@ channel_is_muted( | |
return false; | |
} | |
+bool | |
+channel_is_out_muted( | |
+ jack_mixer_channel_t channel) | |
+{ | |
+ return channel_ptr->out_mute; | |
+} | |
+ | |
bool | |
channel_is_soloed( | |
jack_mixer_channel_t channel) | |
@@ -557,12 +580,11 @@ mix_one( | |
for (i = start; i < end; i++) | |
{ | |
- mix_channel->left_buffer_ptr[i] = 0.0; | |
+ mix_channel->left_buffer_ptr[i] = mix_channel->tmp_mixed_frames_left[i] = 0.0; | |
if (mix_channel->stereo) | |
- mix_channel->right_buffer_ptr[i] = 0.0; | |
+ mix_channel->right_buffer_ptr[i] = mix_channel->tmp_mixed_frames_right[i] = 0.0; | |
} | |
- | |
for (node_ptr = channels_list; node_ptr; node_ptr = g_slist_next(node_ptr)) | |
{ | |
channel_ptr = node_ptr->data; | |
@@ -587,7 +609,7 @@ mix_one( | |
} | |
if (frame_left == NAN) | |
break; | |
- mix_channel->left_buffer_ptr[i] += frame_left; | |
+ mix_channel->tmp_mixed_frames_left[i] += frame_left; | |
if (mix_channel->stereo) | |
{ | |
@@ -599,7 +621,7 @@ mix_one( | |
if (frame_right == NAN) | |
break; | |
- mix_channel->right_buffer_ptr[i] += frame_right; | |
+ mix_channel->tmp_mixed_frames_right[i] += frame_right; | |
} | |
} | |
@@ -639,11 +661,11 @@ mix_one( | |
vol_l = vol * (1 - bal); | |
vol_r = vol * (1 + bal); | |
} | |
- mix_channel->left_buffer_ptr[i] *= vol_l; | |
- mix_channel->right_buffer_ptr[i] *= vol_r; | |
+ mix_channel->tmp_mixed_frames_left[i] *= vol_l; | |
+ mix_channel->tmp_mixed_frames_right[i] *= vol_r; | |
} | |
- frame_left = fabsf(mix_channel->left_buffer_ptr[i]); | |
+ frame_left = fabsf(mix_channel->tmp_mixed_frames_left[i]); | |
if (mix_channel->peak_left < frame_left) | |
{ | |
mix_channel->peak_left = frame_left; | |
@@ -656,7 +678,7 @@ mix_one( | |
if (mix_channel->stereo) | |
{ | |
- frame_right = fabsf(mix_channel->right_buffer_ptr[i]); | |
+ frame_right = fabsf(mix_channel->tmp_mixed_frames_right[i]); | |
if (mix_channel->peak_right < frame_right) | |
{ | |
mix_channel->peak_right = frame_right; | |
@@ -692,6 +714,11 @@ mix_one( | |
mix_channel->balance = mix_channel->balance_new; | |
mix_channel->balance_idx = 0; | |
} | |
+ | |
+ if (!mix_channel->out_mute) { | |
+ mix_channel->left_buffer_ptr[i] = mix_channel->tmp_mixed_frames_left[i]; | |
+ mix_channel->right_buffer_ptr[i] = mix_channel->tmp_mixed_frames_right[i]; | |
+ } | |
} | |
} | |
@@ -871,7 +898,6 @@ mix( | |
continue; | |
} | |
} | |
- | |
mix_one(output_channel_ptr, mixer_ptr->input_channels_list, start, end); | |
} | |
} | |
@@ -1368,7 +1394,8 @@ create_output_channel( | |
} | |
channel_ptr->stereo = stereo; | |
- | |
+ channel_ptr->out_mute = false; | |
+ | |
channel_ptr->volume_transition_seconds = VOLUME_TRANSITION_SECONDS; | |
channel_ptr->num_volume_transition_steps = | |
channel_ptr->volume_transition_seconds * | |
@@ -1385,6 +1412,8 @@ create_output_channel( | |
channel_ptr->peak_right = 0.0; | |
channel_ptr->peak_frames = 0; | |
+ channel_ptr->tmp_mixed_frames_left = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t)); | |
+ channel_ptr->tmp_mixed_frames_right = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t)); | |
channel_ptr->frames_left = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t)); | |
channel_ptr->frames_right = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t)); | |
channel_ptr->prefader_frames_left = calloc(MAX_BLOCK_SIZE, sizeof(jack_default_audio_sample_t)); | |
diff --git a/jack_mixer.h b/jack_mixer.h | |
index f56d9ae..82817c6 100644 | |
--- a/jack_mixer.h | |
+++ b/jack_mixer.h | |
@@ -160,6 +160,14 @@ void | |
channel_unmute( | |
jack_mixer_channel_t channel); | |
+void | |
+channel_out_mute( | |
+ jack_mixer_channel_t channel); | |
+ | |
+void | |
+channel_out_unmute( | |
+ jack_mixer_channel_t channel); | |
+ | |
void | |
channel_solo( | |
jack_mixer_channel_t channel); | |
@@ -172,6 +180,10 @@ bool | |
channel_is_muted( | |
jack_mixer_channel_t channel); | |
+bool | |
+channel_is_out_muted( | |
+ jack_mixer_channel_t channel); | |
+ | |
bool | |
channel_is_soloed( | |
jack_mixer_channel_t channel); | |
diff --git a/jack_mixer.py b/jack_mixer.py | |
index 51823af..d275b81 100755 | |
--- a/jack_mixer.py | |
+++ b/jack_mixer.py | |
@@ -568,10 +568,12 @@ class JackMixer(SerializedObject): | |
monitored_channel = property(get_monitored_channel, set_monitored_channel) | |
def update_monitor(self, channel): | |
+ print dir(jack_mixer_c.OutputChannel) | |
if self.monitored_channel is not channel: | |
return | |
self.monitor_channel.volume = channel.channel.volume | |
self.monitor_channel.balance = channel.channel.balance | |
+ self.monitor_channel.out_mute = channel.channel.mute | |
if type(self.monitored_channel) is OutputChannel: | |
# sync solo/muted channels | |
for input_channel in self.channels: | |
diff --git a/jack_mixer_c.c b/jack_mixer_c.c | |
index 00d0cb6..120cf81 100644 | |
--- a/jack_mixer_c.c | |
+++ b/jack_mixer_c.c | |
@@ -246,6 +246,21 @@ Channel_get_mute(ChannelObject *self, void *closure) | |
return result; | |
} | |
+static PyObject* | |
+Channel_get_out_mute(ChannelObject *self, void *closure) | |
+{ | |
+ PyObject *result; | |
+ | |
+ if (channel_is_out_muted(self->channel)) { | |
+ result = Py_True; | |
+ } else { | |
+ result = Py_False; | |
+ } | |
+ Py_INCREF(result); | |
+ return result; | |
+} | |
+ | |
+ | |
static int | |
Channel_set_mute(ChannelObject *self, PyObject *value, void *closure) | |
{ | |
@@ -257,6 +272,17 @@ Channel_set_mute(ChannelObject *self, PyObject *value, void *closure) | |
return 0; | |
} | |
+static int | |
+Channel_set_out_mute(ChannelObject *self, PyObject *value, void *closure) | |
+{ | |
+ if (value == Py_True) { | |
+ channel_out_mute(self->channel); | |
+ } else { | |
+ channel_out_unmute(self->channel); | |
+ } | |
+ return 0; | |
+} | |
+ | |
static PyObject* | |
Channel_get_solo(ChannelObject *self, void *closure) | |
{ | |
@@ -465,6 +491,9 @@ static PyGetSetDef Channel_getseters[] = { | |
{"mute", | |
(getter)Channel_get_mute, (setter)Channel_set_mute, | |
"mute", NULL}, | |
+ {"out_mute", | |
+ (getter)Channel_get_out_mute, (setter)Channel_set_out_mute, | |
+ "out_mute", NULL}, | |
{"solo", | |
(getter)Channel_get_solo, (setter)Channel_set_solo, | |
"solo", NULL}, |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment