Skip to content

Instantly share code, notes, and snippets.

@dsheeler
Created April 24, 2020 20:52
Show Gist options
  • Save dsheeler/31efdbed746371f1e50803b594b5857c to your computer and use it in GitHub Desktop.
Save dsheeler/31efdbed746371f1e50803b594b5857c to your computer and use it in GitHub Desktop.
jack_mixer per output channel mute
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