commit d256de1e728ec329c95868d99b047c0b820a6545
parent 45236051aa622b2050080dcc7e20a9e3c3ee4f4e
Author: lostd <lostd@2f30.org>
Date: Wed, 16 Nov 2016 23:49:33 +0000
Add on-air state that applies fade effect on toggle
If on-air is toggled before the previous fade is finished we change
direction and complete the fade faster than the full fade.
Diffstat:
M | mixerd.c | | | 59 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | ncmixerc.c | | | 30 | ++++++++++++++++++++++++++++++ |
M | proto.h | | | 8 | +++++++- |
3 files changed, 96 insertions(+), 1 deletion(-)
diff --git a/mixerd.c b/mixerd.c
@@ -37,12 +37,18 @@
#define NSAMPLES 128
#define BUFFER_TIME_MS 100
#define TIMEO_MS 40
+#define FADE_LOW 0.25f
+#define FADE_DUR_MS 1500
char *argv0;
int debug;
/* mixer state */
float xf_pos = 0.0f; /* values in [-1.0, 1.0] */
+float fade = 1.0f; /* values in [FADE_LOW, 1.0] */
+float fadeold;
+struct timespec airtp; /* when air direction changed */
+int onair = 0;
/* forward decls */
struct input;
@@ -229,6 +235,44 @@ attenuate(struct input *in, float factor)
}
}
+void
+applyfade(struct input *in)
+{
+ struct timespec tp;
+ float complete;
+ int durationms;
+ int deltams;
+ short *buf;
+ int i;
+
+ if ((onair && fade > FADE_LOW) || (!onair && fade < 1.0f)) {
+ clock_gettime(CLOCK_MONOTONIC, &tp);
+ deltams = (tp.tv_sec * 1000 + tp.tv_nsec / 1000000)
+ - (airtp.tv_sec * 1000 + airtp.tv_nsec / 1000000);
+ /* fade should complete faster if it was interrupted */
+ if (onair)
+ durationms = (fadeold - FADE_LOW) * FADE_DUR_MS;
+ else
+ durationms = (1.0f - fadeold) * FADE_DUR_MS;
+ durationms /= 1.0f - FADE_LOW;
+ complete = (float)deltams / durationms;
+ fade = fadeold;
+ if (onair) {
+ fade -= (1.0f - FADE_LOW) * complete;
+ fade = MAX(fade, FADE_LOW);
+ } else {
+ fade += (1.0f - FADE_LOW) * complete;
+ fade = MIN(fade, 1.0f);
+ }
+ }
+
+ buf = (short *)in->attenuated_buf;
+ for (i = 0; i < in->nsamples; i++) {
+ *buf *= fade;
+ buf++;
+ }
+}
+
int
mix_master(struct output *out, struct input *in0, struct input *in1)
{
@@ -382,6 +426,17 @@ msg_handler(int fd)
msg.m_output_on = outputs[msg.m_output_index].sio_hdl != NULL;
tx_reply = 1;
break;
+ case SET_AIR:
+ if (msg.m_air_on != onair) {
+ clock_gettime(CLOCK_MONOTONIC, &airtp);
+ fadeold = fade;
+ }
+ onair = msg.m_air_on;
+ break;
+ case GET_AIR:
+ msg.m_air_on = onair;
+ tx_reply = 1;
+ break;
default:
log_msg(LOG_WARNING, "unknown message type: %d", msg.type);
break;
@@ -525,6 +580,10 @@ loop(void)
attenuate(&inputs[1], 1.0f);
}
+ /* apply fade effect for on-air toggle */
+ applyfade(&inputs[0]);
+ applyfade(&inputs[1]);
+
/* play dat shit! */
for (i = 0; i < LEN(outputs); i++) {
out = &outputs[i];
diff --git a/ncmixerc.c b/ncmixerc.c
@@ -47,6 +47,7 @@ int in0_on;
int in1_on;
int out0_on;
int out1_on;
+int air_on;
int sock;
void
@@ -195,6 +196,27 @@ get_output_on(int index, int *on)
}
void
+get_air_on(int *on)
+{
+ struct msg msg;
+
+ msg.type = GET_AIR;
+ tx_msg(&msg);
+ rx_msg(&msg);
+ *on = msg.m_air_on;
+}
+
+void
+set_air_on(int on)
+{
+ struct msg msg;
+
+ msg.type = SET_AIR;
+ msg.m_air_on = on;
+ tx_msg(&msg);
+}
+
+void
kb_handler(void)
{
int c;
@@ -268,6 +290,11 @@ kb_handler(void)
ch1_level = MIN(ch1_level + level_step, 1.0f);
set_vol_level(1, ch1_level);
break;
+ case CONTROL('A'):
+ get_air_on(&air_on);
+ air_on = !air_on;
+ set_air_on(air_on);
+ break;
case 'x':
curses_exit();
exit(0);
@@ -376,11 +403,14 @@ draw_outputs(void)
get_output_on(0, &out0_on);
get_output_on(1, &out1_on);
+ get_air_on(&air_on);
move(getcury(stdscr), center - strlen(" master: off") / 2);
printw(" master: %s\n", out0_on ? "on" : "off");
move(getcury(stdscr), center - strlen("monitor: off") / 2);
printw("monitor: %s\n", out1_on ? "on" : "off");
+ move(getcury(stdscr), center - strlen(" air: off") / 2);
+ printw(" onair: %s\n", air_on ? "on" : "off");
}
void
diff --git a/proto.h b/proto.h
@@ -6,7 +6,9 @@ enum {
SET_VOL,
GET_VOL,
GET_IN,
- GET_OUT
+ GET_OUT,
+ SET_AIR,
+ GET_AIR
};
struct msg {
@@ -31,6 +33,9 @@ struct msg {
int index; /* in */
int on; /* out */
} output;
+ struct {
+ int on; /* in/out */
+ } air;
} u;
};
#define m_xf_pos u.xf.pos
@@ -42,3 +47,4 @@ struct msg {
#define m_input_on u.input.on
#define m_output_index u.output.index
#define m_output_on u.output.on
+#define m_air_on u.air.on