static void update_meter_cfg(BalanceControl* self, int key, float val) { switch (key) { case 0: if (val >=0 && val <= self->peak_integrate_max) { self->peak_integrate_pref = val * self->samplerate; } reset_uicom(self); break; case 1: self->meter_falloff = MAX(0, val / UPDATE_FREQ); self->meter_falloff = MIN(self->meter_falloff, 1000); break; case 2: self->peak_hold = MAX(0, val * UPDATE_FREQ); self->peak_hold = MIN(self->peak_hold, 60 * UPDATE_FREQ); break; case 3: for (int i=0; i < CHANNELS; ++i) { if ( ((int)val)&1) { self->p_max_in[i] = -INFINITY; } if ( ((int)val)&2) { self->p_max_out[i] = -INFINITY; } } forge_kvcontrolmessage(&self->forge, &self->uris, PEAK_IN_LEFT, self->p_max_in[C_LEFT]); forge_kvcontrolmessage(&self->forge, &self->uris, PEAK_IN_RIGHT, self->p_max_in[C_RIGHT]); forge_kvcontrolmessage(&self->forge, &self->uris, PEAK_OUT_LEFT, self->p_max_out[C_LEFT]); forge_kvcontrolmessage(&self->forge, &self->uris, PEAK_OUT_RIGHT, self->p_max_out[C_RIGHT]); break; default: break; } }
static inline void postrun (B3S* b3s) { if (b3s->swap_instances) { #ifdef DEBUGPRINT fprintf(stderr, "swap instances..\n"); #endif struct worknfo w; w.cmd = CMD_FREE; /* swap engine instances */ struct b_instance *old = b3s->inst; b3s->inst = b3s->inst_offline; b3s->inst_offline = old; setControlFunctionCallback(b3s->inst_offline->midicfg, NULL, NULL); setControlFunctionCallback(b3s->inst->midicfg, mctl_cb, b3s); /* hide midi-maps, stop possibly pending midi-bind process */ forge_kvcontrolmessage(&b3s->forge, &b3s->uris, "special.midimap", (int32_t) 0); forge_kvcontrolmessage(&b3s->forge, &b3s->uris, "special.reinit", (int32_t) 1); b3s->schedule->schedule_work(b3s->schedule->handle, sizeof(struct worknfo), &w); b3s->update_gui_now = 1; b3s->swap_instances = 0; } }
static void forge_message_kv (BITui* ui, LV2_URID uri, int key, float value) { uint8_t obj_buf[1024]; if (ui->disable_signals) return; lv2_atom_forge_set_buffer (&ui->forge, obj_buf, 1024); LV2_Atom* msg = forge_kvcontrolmessage (&ui->forge, &ui->uris, uri, key, value); ui->write (ui->controller, 0, lv2_atom_total_size (msg), ui->uris.atom_eventTransfer, msg); }
static void rc_cb(int fnid, const char *key, const char *kv, unsigned char val, void *arg) { B3S* b3s = (B3S*)arg; #ifdef DEBUGPRINT fprintf(stderr, "RC CB %d %s %s %d\n", fnid, key, kv?kv:"-", val); #endif if (fnid >=0) { forge_kvcontrolmessage(&b3s->forge, &b3s->uris, key, (int32_t) val); } else { forge_kvconfigmessage(&b3s->forge, &b3s->uris, b3s->uris.sb3_cfgkv, key, kv); } }
static void mctl_cb(int fnid, const char *fn, unsigned char val, midiCCmap *mm, void *arg) { B3S* b3s = (B3S*)arg; #ifdef DEBUGPRINT fprintf(stderr, "xfn: %d (\"%s\", %d) mm:%s\n", fnid, fn, val, mm?"yes":"no"); #endif if (b3s->midiout && mm) { while (mm) { #ifdef DEBUGPRINT fprintf(stderr, "MIDI FEEDBACK %d %d %d\n", mm->channel, mm->param, val); #endif uint8_t msg[3]; msg[0] = 0xb0 | (mm->channel&0x0f); // Control Change msg[1] = mm->param; msg[2] = val; forge_midimessage(&b3s->forge, &b3s->uris, msg, 3); mm = mm->next; } } if (b3s->midiout && fn && !b3s->suspend_ui_msg) { forge_kvcontrolmessage(&b3s->forge, &b3s->uris, fn, (int32_t) val); } }
static void run(LV2_Handle instance, uint32_t n_samples) { B3S* b3s = (B3S*)instance; float* audio[2]; audio[0] = b3s->outL; audio[1] = b3s->outR; /* prepare outgoing MIDI */ const uint32_t capacity = b3s->midiout->atom.size; static bool warning_printed = false; if (!warning_printed && capacity < 4096) { warning_printed = true; fprintf(stderr, "B3LV2: LV message buffer is only %d bytes. Expect problems.\n", capacity); fprintf(stderr, "B3LV2: if your LV2 host allows one to configure a buffersize use at least 4kBytes.\n"); } lv2_atom_forge_set_buffer(&b3s->forge, (uint8_t*)b3s->midiout, capacity); lv2_atom_forge_sequence_head(&b3s->forge, &b3s->frame, 0); uint32_t written = 0; if (b3s->queue_panic) { b3s->queue_panic = 0; midi_panic(b3s->inst); } /* Process incoming events from GUI and handle MIDI events */ if (b3s->midiin) { LV2_Atom_Event* ev = lv2_atom_sequence_begin(&(b3s->midiin)->body); while(!lv2_atom_sequence_is_end(&(b3s->midiin)->body, (b3s->midiin)->atom.size, ev)) { if (ev->body.type == b3s->uris.midi_MidiEvent) { /* process midi messages from player */ if (written + BUFFER_SIZE_SAMPLES < ev->time.frames && ev->time.frames < n_samples) { /* first syntheize sound up until the message timestamp */ written = synthSound(b3s, written, ev->time.frames, audio); } /* send midi message to synth, CC's will trigger hook -> update GUI */ parse_raw_midi_data(b3s->inst, (uint8_t*)(ev+1), ev->body.size); } else if (ev->body.type == b3s->uris.atom_Blank || ev->body.type == b3s->uris.atom_Object) { /* process messages from GUI */ const LV2_Atom_Object* obj = (LV2_Atom_Object*)&ev->body; if (obj->body.otype == b3s->uris.sb3_uiinit) { b3s->update_gui_now = 1; } else if (obj->body.otype == b3s->uris.sb3_uimccquery) { midi_loopCCAssignment(b3s->inst->midicfg, 7, mcc_cb, b3s); } else if (obj->body.otype == b3s->uris.sb3_uimccset) { const LV2_Atom* cmd = NULL; const LV2_Atom* flags = NULL; lv2_atom_object_get(obj, b3s->uris.sb3_cckey, &flags, b3s->uris.sb3_ccval, &cmd, 0); if (cmd && flags) { midi_uiassign_cc(b3s->inst->midicfg, (const char*)LV2_ATOM_BODY(cmd), ((LV2_Atom_Int*)flags)->body); } } else if (obj->body.otype == b3s->uris.sb3_midipgm) { const LV2_Atom* key = NULL; lv2_atom_object_get(obj, b3s->uris.sb3_cckey, &key, 0); if (key) { installProgram(b3s->inst, ((LV2_Atom_Int*)key)->body); } } else if (obj->body.otype == b3s->uris.sb3_midisavepgm) { const LV2_Atom* pgm = NULL; const LV2_Atom* name = NULL; lv2_atom_object_get(obj, b3s->uris.sb3_cckey, &pgm, b3s->uris.sb3_ccval, &name, 0); if (pgm && name) { saveProgramm(b3s->inst, (int) ((LV2_Atom_Int*)pgm)->body, (char*) LV2_ATOM_BODY(name), 0); b3s->update_pgm_now = 1; } } else if (obj->body.otype == b3s->uris.sb3_loadpgm) { iowork(b3s, obj, CMD_LOADPGM); } else if (obj->body.otype == b3s->uris.sb3_loadcfg) { iowork(b3s, obj, CMD_LOADCFG); } else if (obj->body.otype == b3s->uris.sb3_savepgm) { iowork(b3s, obj, CMD_SAVEPGM); } else if (obj->body.otype == b3s->uris.sb3_savecfg) { iowork(b3s, obj, CMD_SAVECFG); } else if (obj->body.otype == b3s->uris.sb3_cfgstr) { if (!b3s->inst_offline) { advanced_config_set(b3s, obj); } } else if (obj->body.otype == b3s->uris.sb3_control) { b3s->suspend_ui_msg = 1; const LV2_Atom_Object* obj = (LV2_Atom_Object*)&ev->body; char *k; int v; if (!get_cc_key_value(&b3s->uris, obj, &k, &v)) { #ifdef DEBUGPRINT fprintf(stderr, "B3LV2: callMIDIControlFunction(..,\"%s\", %d);\n", k, v); #endif callMIDIControlFunction(b3s->inst->midicfg, k, v); } b3s->suspend_ui_msg = 0; } } ev = lv2_atom_sequence_next(ev); } } /* synthesize [remaining] sound */ synthSound(b3s, written, n_samples, audio); /* send active keys to GUI - IFF changed */ bool keychanged = false; for (int i = 0 ; i < MAX_KEYS/32; ++i) { if (b3s->active_keys[i] != b3s->inst->synth->_activeKeys[i]) { keychanged = true; } b3s->active_keys[i] = b3s->inst->synth->_activeKeys[i]; } if (keychanged) { LV2_Atom_Forge_Frame frame; lv2_atom_forge_frame_time(&b3s->forge, 0); x_forge_object(&b3s->forge, &frame, 1, b3s->uris.sb3_activekeys); lv2_atom_forge_property_head(&b3s->forge, b3s->uris.sb3_keyarrary, 0); lv2_atom_forge_vector(&b3s->forge, sizeof(unsigned int), b3s->uris.atom_Int, MAX_KEYS/32, b3s->active_keys); lv2_atom_forge_pop(&b3s->forge, &frame); } /* check for new instances */ postrun(b3s); if (b3s->update_gui_now) { b3s->update_gui_now = 0; b3s->update_pgm_now = 1; b3s->suspend_ui_msg = 1; rc_loop_state(b3s->inst->state, rc_cb, b3s); b3s->suspend_ui_msg = 0; forge_kvconfigmessage(&b3s->forge, &b3s->uris, b3s->uris.sb3_cfgkv, "lv2.info", b3s->lv2nfo); forge_kvcontrolmessage(&b3s->forge, &b3s->uris, "special.init", (int32_t) b3s->thirtysec); } else if (b3s->update_pgm_now) { b3s->update_pgm_now = 0; loopProgammes(b3s->inst->progs, 1, pgm_cb, b3s); } }
static void bim_run(LV2_Handle instance, uint32_t n_samples) { LV2meter* self = (LV2meter*)instance; const uint32_t capacity = self->notify->atom.size; assert(capacity > 920); lv2_atom_forge_set_buffer(&self->forge, (uint8_t*)self->notify, capacity); lv2_atom_forge_sequence_head(&self->forge, &self->frame, 0); if (self->send_state_to_ui && self->ui_active) { self->send_state_to_ui = false; forge_kvcontrolmessage(&self->forge, &self->uris, self->uris.mtr_control, CTL_SAMPLERATE, self->rate); } /* Process incoming events from GUI */ if (self->control) { LV2_Atom_Event* ev = lv2_atom_sequence_begin(&(self->control)->body); while(!lv2_atom_sequence_is_end(&(self->control)->body, (self->control)->atom.size, ev)) { if (ev->body.type == self->uris.atom_Blank || ev->body.type == self->uris.atom_Object) { const LV2_Atom_Object* obj = (LV2_Atom_Object*)&ev->body; if (obj->body.otype == self->uris.mtr_meters_on) { self->ui_active = true; self->send_state_to_ui = true; } else if (obj->body.otype == self->uris.mtr_meters_off) { self->ui_active = false; } else if (obj->body.otype == self->uris.mtr_meters_cfg) { int k; float v; get_cc_key_value(&self->uris, obj, &k, &v); switch (k) { case CTL_START: self->ebu_integrating = true; break; case CTL_PAUSE: self->ebu_integrating = false; break; case CTL_RESET: bim_reset(self); self->send_state_to_ui = true; break; case CTL_AVERAGE: self->bim_average = true; break; case CTL_WINDOWED: self->bim_average = false; break; default: break; } } } ev = lv2_atom_sequence_next(ev); } } #if 0 static uint32_t max_post = 0; if (self->notify->atom.size > max_post) { max_post = self->notify->atom.size; printf("new post parse: %d\n", max_post); } #endif /* process */ if (self->ebu_integrating && self->integration_time < 2147483647) { /* currently 'self->histS' is int32, * the max peak that can be recorded is 2^31, * for now we simply limit data-acquisition to at * most 2^31 points. */ if (self->integration_time > 2147483647 - n_samples) { self->integration_time = 2147483647; } else { for (uint32_t s = 0; s < n_samples; ++s) { float_stats(self, self->input[0] + s); } self->integration_time += n_samples; } } const int fps_limit = n_samples * ceil(self->rate / (5.f * n_samples)); // ~ 5fps self->radar_resync += n_samples; if (self->radar_resync >= fps_limit || self->send_state_to_ui) { self->radar_resync = self->radar_resync % fps_limit; if (self->ui_active && (self->ebu_integrating || self->send_state_to_ui)) { LV2_Atom_Forge_Frame frame; lv2_atom_forge_frame_time(&self->forge, 0); x_forge_object(&self->forge, &frame, 1, self->uris.bim_stats); lv2_atom_forge_property_head(&self->forge, self->uris.ebu_integr_time, 0); lv2_atom_forge_long(&self->forge, self->integration_time); lv2_atom_forge_property_head(&self->forge, self->uris.bim_zero, 0); lv2_atom_forge_int(&self->forge, self->bim_zero); lv2_atom_forge_property_head(&self->forge, self->uris.bim_pos, 0); lv2_atom_forge_int(&self->forge, self->bim_pos); lv2_atom_forge_property_head(&self->forge, self->uris.bim_max, 0); lv2_atom_forge_double(&self->forge, self->bim_max); lv2_atom_forge_property_head(&self->forge, self->uris.bim_min, 0); lv2_atom_forge_double(&self->forge, self->bim_min); lv2_atom_forge_property_head(&self->forge, self->uris.bim_nan, 0); lv2_atom_forge_int(&self->forge, self->bim_nan); lv2_atom_forge_property_head(&self->forge, self->uris.bim_inf, 0); lv2_atom_forge_int(&self->forge, self->bim_inf); lv2_atom_forge_property_head(&self->forge, self->uris.bim_den, 0); lv2_atom_forge_int(&self->forge, self->bim_den); lv2_atom_forge_property_head(&self->forge, self->uris.bim_data, 0); lv2_atom_forge_vector(&self->forge, sizeof(int32_t), self->uris.atom_Int, BIM_LAST, self->histS); lv2_atom_forge_pop(&self->forge, &frame); } if (self->ui_active) { LV2_Atom_Forge_Frame frame; lv2_atom_forge_frame_time(&self->forge, 0); x_forge_object(&self->forge, &frame, 1, self->uris.bim_information); lv2_atom_forge_property_head(&self->forge, self->uris.ebu_integrating, 0); lv2_atom_forge_bool(&self->forge, self->ebu_integrating); lv2_atom_forge_property_head(&self->forge, self->uris.bim_averaging, 0); lv2_atom_forge_bool(&self->forge, self->bim_average); lv2_atom_forge_pop(&self->forge, &frame); } if (!self->bim_average) { bim_clear (self); } } /* foward audio-data */ if (self->input[0] != self->output[0]) { memcpy(self->output[0], self->input[0], sizeof(float) * n_samples); } #if 0 //printf("forged %d bytes\n", self->notify->atom.size); static uint32_t max_cap = 0; if (self->notify->atom.size > max_cap) { max_cap = self->notify->atom.size; printf("new max: %d (of %d avail)\n", max_cap, capacity); } #endif }
static void run(LV2_Handle instance, uint32_t n_samples) { uint32_t i,c; BalanceControl* self = (BalanceControl*)instance; const float balance = *self->balance; const float trim = db_to_gain(*self->trim); float gain_left = 1.0; float gain_right = 1.0; const int ascnt = self->samplerate / UPDATE_FREQ; const uint32_t capacity = self->notify->atom.size; lv2_atom_forge_set_buffer(&self->forge, (uint8_t*)self->notify, capacity); lv2_atom_forge_sequence_head(&self->forge, &self->frame, 0); /* reset after state restore */ if (self->queue_stateswitch) { self->queue_stateswitch = 0; self->peak_integrate_pref = self->state[0] * self->samplerate; self->meter_falloff = self->state[1] / UPDATE_FREQ; self->peak_hold = self->state[2] * UPDATE_FREQ; self->peak_integrate_pref = MAX(0, self->peak_integrate_pref); self->peak_integrate_pref = MIN(self->peak_integrate_pref, self->peak_integrate_max); self->meter_falloff = MAX(0, self->meter_falloff); self->meter_falloff = MIN(self->meter_falloff, 1000); self->peak_hold = MAX(0, self->peak_hold); self->peak_hold = MIN(self->peak_hold, 60 * UPDATE_FREQ); reset_uicom(self); send_cfg_to_ui(self); } /* Process incoming events from GUI */ if (self->control) { LV2_Atom_Event* ev = lv2_atom_sequence_begin(&(self->control)->body); while(!lv2_atom_sequence_is_end(&(self->control)->body, (self->control)->atom.size, ev)) { if (ev->body.type == self->uris.atom_Blank || ev->body.type == self->uris.atom_Object) { const LV2_Atom_Object* obj = (LV2_Atom_Object*)&ev->body; if (obj->body.otype == self->uris.blc_meters_on) { if (self->uicom_active == 0) { reset_uicom(self); send_cfg_to_ui(self); self->uicom_active = 1; } } if (obj->body.otype == self->uris.blc_meters_off) { self->uicom_active = 0; } if (obj->body.otype == self->uris.blc_meters_cfg) { const LV2_Atom* key = NULL; const LV2_Atom* value = NULL; lv2_atom_object_get(obj, self->uris.blc_cckey, &key, self->uris.blc_ccval, &value, 0); if (value && key) { update_meter_cfg(self, ((LV2_Atom_Int*)key)->body, ((LV2_Atom_Float*)value)->body); } } } ev = lv2_atom_sequence_next(ev); } } /* pre-calculate parameters */ if (balance < 0) { gain_right = 1.0 + RAIL(balance, -1.0, 0.0); } else if (balance > 0) { gain_left = 1.0 - RAIL(balance, 0.0, 1.0); } switch ((int) *self->unitygain) { case 1: { /* maintain amplitude sum */ const double gaindiff = (gain_left - gain_right); gain_left = 1.0 + gaindiff; gain_right = 1.0 - gaindiff; } break; case 2: { /* equal power*/ if (balance < 0) { gain_right = MAX(.5, gain_right); gain_left = db_to_gain(-gain_to_db(gain_right)); } else { gain_left = MAX(.5, gain_left); gain_right = db_to_gain(-gain_to_db(gain_left)); } } case 0: /* 'tradidional' balance */ break; } if (*(self->phase[C_LEFT])) gain_left *=-1; if (*(self->phase[C_RIGHT])) gain_right *=-1; /* keep track of input levels -- only if GUI is visiable */ if (self->uicom_active) { for (c=0; c < CHANNELS; ++c) { for (i=0; i < n_samples; ++i) { /* input peak meter */ const float ps = fabsf(self->input[c][i]); if (ps > self->p_peak_in[c]) self->p_peak_in[c] = ps; if (self->peak_integrate_pref < 1) { const float psm = ps * ps; if (psm > self->p_peak_inM[c]) self->p_peak_inM[c] = psm; continue; } /* integrated level, peak */ const int pip = (self->peak_integrate_pos + i ) % self->peak_integrate_pref; const double p_sig = SQUARE(self->input[c][i]); self->p_peak_inP[c] += p_sig - self->p_peak_inPi[c][pip]; self->p_peak_inPi[c][pip] = p_sig; /* peak of integrated signal */ const float psm = self->p_peak_inP[c] / (double) self->peak_integrate_pref; if (psm > self->p_peak_inM[c]) self->p_peak_inM[c] = psm; } } } /* process audio -- delayline + balance & gain */ process_channel(self, gain_left * trim, C_LEFT, n_samples); process_channel(self, gain_right * trim, C_RIGHT, n_samples); /* swap/assign channels */ uint32_t pos = 0; if (self->c_monomode != (int) *self->monomode) { /* smooth change */ const uint32_t fade_len = (n_samples >= FADE_LEN) ? FADE_LEN : n_samples; for (; pos < fade_len; pos++) { const float gain = (float)pos / (float)fade_len; float x1[CHANNELS], x2[CHANNELS]; channel_map_change(self, self->c_monomode, pos, x1); channel_map_change(self, (int) *self->monomode, pos, x2); self->output[C_LEFT][pos] = x1[C_LEFT] * (1.0 - gain) + x2[C_LEFT] * gain; self->output[C_RIGHT][pos] = x1[C_RIGHT] * (1.0 - gain) + x2[C_RIGHT] * gain; } } channel_map(self, (int) *self->monomode, pos, n_samples); self->c_monomode = (int) *self->monomode; /* audio processing done */ if (!self->uicom_active) { return; } /* output peak meter */ for (c=0; c < CHANNELS; ++c) { for (i=0; i < n_samples; ++i) { /* peak */ const float ps = fabsf(self->output[c][i]); if (ps > self->p_peak_out[c]) self->p_peak_out[c] = ps; if (self->peak_integrate_pref < 1) { const float psm = ps * ps; if (psm > self->p_peak_outM[c]) self->p_peak_outM[c] = psm; continue; } /* integrated level, peak */ const int pip = (self->peak_integrate_pos + i ) % self->peak_integrate_pref; const double p_sig = SQUARE(self->output[c][i]); self->p_peak_outP[c] += p_sig - self->p_peak_outPi[c][pip]; self->p_peak_outPi[c][pip] = p_sig; /* peak of integrated signal */ const float psm = self->p_peak_outP[c] / (double) self->peak_integrate_pref; if (psm > self->p_peak_outM[c]) self->p_peak_outM[c] = psm; } } if (self->peak_integrate_pref > 0) { self->peak_integrate_pos = (self->peak_integrate_pos + n_samples ) % self->peak_integrate_pref; } /* simple output phase correlation */ for (i=0; i < n_samples; ++i) { const double p_pos = SQUARE(self->output[C_LEFT][i] + self->output[C_RIGHT][i]); const double p_neg = SQUARE(self->output[C_LEFT][i] - self->output[C_RIGHT][i]); /* integrate over 500ms */ self->p_phase_outP += p_pos - self->p_phase_outPi[self->phase_integrate_pos]; self->p_phase_outN += p_neg - self->p_phase_outNi[self->phase_integrate_pos]; self->p_phase_outPi[self->phase_integrate_pos] = p_pos; self->p_phase_outNi[self->phase_integrate_pos] = p_neg; self->phase_integrate_pos = (self->phase_integrate_pos + 1) % self->phase_integrate_max; } /* abs peak hold */ #define PKM(A,CHN,ID) \ { \ const float peak = VALTODB(self->p_peak_##A[CHN]); \ if (peak > self->p_max_##A[CHN]) { \ self->p_max_##A[CHN] = peak; \ self->p_tme_##A[CHN] = 0; \ forge_kvcontrolmessage(&self->forge, &self->uris, ID, self->p_max_##A[CHN]); \ } else if (self->peak_hold <= 0) { \ (self->p_tme_##A[CHN])=0; /* infinite hold */ \ } else if (self->p_tme_##A[CHN] <= self->peak_hold) { \ (self->p_tme_##A[CHN])++; \ } else if (self->meter_falloff == 0) { \ self->p_max_##A[CHN] = peak; \ forge_kvcontrolmessage(&self->forge, &self->uris, ID, self->p_max_##A[CHN]); \ } else { \ self->p_max_##A[CHN] -= self->meter_falloff; \ self->p_max_##A[CHN] = MAX(peak, self->p_max_##A[CHN]); \ forge_kvcontrolmessage(&self->forge, &self->uris, ID, self->p_max_##A[CHN]); \ } \ } /* RMS meter */ #define PKF(A,CHN,ID) \ { \ float dbp = VALTODB(sqrt(2.0 * self->p_peak_##A##M[CHN])); \ if (dbp > self->p_vpeak_##A[CHN]) { \ self->p_vpeak_##A[CHN] = dbp; \ } else if (self->meter_falloff == 0) { \ self->p_vpeak_##A[CHN] = dbp; \ } else { \ self->p_vpeak_##A[CHN] -= self->meter_falloff; \ self->p_vpeak_##A[CHN] = MAX(dbp, self->p_vpeak_##A[CHN]); \ } \ forge_kvcontrolmessage(&self->forge, &self->uris, ID, (self->p_vpeak_##A [CHN])); \ } /* report peaks to UI */ self->p_peakcnt += n_samples; if (self->p_peakcnt > ascnt) { PKF(in, C_LEFT, METER_IN_LEFT) PKF(in, C_RIGHT, METER_IN_RIGHT); PKF(out, C_LEFT, METER_OUT_LEFT); PKF(out, C_RIGHT, METER_OUT_RIGHT); PKM(in, C_LEFT, PEAK_IN_LEFT); PKM(in, C_RIGHT, PEAK_IN_RIGHT); PKM(out, C_LEFT, PEAK_OUT_LEFT); PKM(out, C_RIGHT, PEAK_OUT_RIGHT); #define RMSF(A) sqrt( ( (A) / (double)self->phase_integrate_max ) + 1.0e-12 ) double phase = 0.0; const double phasdiv = self->p_phase_outP + self->p_phase_outN; if (phasdiv >= 1.0e-6) { phase = (RMSF(self->p_phase_outP) - RMSF(self->p_phase_outN)) / RMSF(phasdiv); } else if (self->p_phase_outP > .001 && self->p_phase_outN > .001) { phase = 1.0; } forge_kvcontrolmessage(&self->forge, &self->uris, PHASE_OUT, phase); self->p_peakcnt -= ascnt; for (c=0; c < CHANNELS; ++c) { self->p_peak_in[c] = -INFINITY; self->p_peak_out[c] = -INFINITY; self->p_peak_inM[c] = -INFINITY; self->p_peak_outM[c] = -INFINITY; } } /* report values to UI - if changed*/ float bal = gain_to_db(fabsf(gain_left)); if (bal != self->p_bal[C_LEFT]) { forge_kvcontrolmessage(&self->forge, &self->uris, GAIN_LEFT, bal); } self->p_bal[C_LEFT] = bal; bal = gain_to_db(fabsf(gain_right)); if (bal != self->p_bal[C_RIGHT]) { forge_kvcontrolmessage(&self->forge, &self->uris, GAIN_RIGHT, bal); } self->p_bal[C_RIGHT] = bal; if (self->p_dly[C_LEFT] != self->c_dly[C_LEFT]) { forge_kvcontrolmessage(&self->forge, &self->uris, DELAY_LEFT, (float) self->c_dly[C_LEFT] / self->samplerate); } self->p_dly[C_LEFT] = self->c_dly[C_LEFT]; if (self->p_dly[C_RIGHT] != self->c_dly[C_RIGHT]) { forge_kvcontrolmessage(&self->forge, &self->uris, DELAY_RIGHT, (float) self->c_dly[C_RIGHT] / self->samplerate); } self->p_dly[C_RIGHT] = self->c_dly[C_RIGHT]; }
static void send_cfg_to_ui(BalanceControl* self) { forge_kvcontrolmessage(&self->forge, &self->uris, CFG_INTEGRATE, self->peak_integrate_pref / self->samplerate); forge_kvcontrolmessage(&self->forge, &self->uris, CFG_FALLOFF, self->meter_falloff * (float) UPDATE_FREQ); forge_kvcontrolmessage(&self->forge, &self->uris, CFG_HOLDTIME, self->peak_hold / (float) UPDATE_FREQ); }