pa_volume_t pa_sw_volume_from_linear(double v) { if (v <= 0) return PA_VOLUME_MUTED; if (v > .999 && v < 1.001) return PA_VOLUME_NORM; return pa_sw_volume_from_dB(20*log10(v)); }
int sa_stream_set_volume_abs(sa_stream_t *s, float vol) { pa_cvolume cv; if (s == NULL || s->stream == NULL) { return SA_ERROR_NO_INIT; } pa_cvolume_set(&cv, s->sample_spec.channels, pa_sw_volume_from_dB(vol)); return SA_SUCCESS; }
int main(PA_GCC_UNUSED int argc, PA_GCC_UNUSED char *argv[]) { pa_volume_t v; for (v = PA_VOLUME_MUTED; v <= PA_VOLUME_NORM*2; v += 256) { double dB = pa_sw_volume_to_dB(v); double f = pa_sw_volume_to_linear(v); printf("Volume: %3i; percent: %i%%; decibel %0.2f; linear = %0.2f; volume(decibel): %3i; volume(linear): %3i\n", v, (v*100)/PA_VOLUME_NORM, dB, f, pa_sw_volume_from_dB(dB), pa_sw_volume_from_linear(f)); } return 0; }
void mv_normalize_steps(struct mv_volume_steps *steps) { unsigned i = 0; pa_assert(steps); pa_assert(steps->n_steps > 0); /* if first step is less than equal to -20000 mB (PA_DECIBEL_MININFTY if * INFINITY is not defined), set it directly to PA_VOLUME_MUTED */ if (steps->step[0] <= -20000) { steps->step[0] = PA_VOLUME_MUTED; i = 1; } /* convert mB step values to software volume values. * divide mB values by 100.0 to get dB */ for (; i < steps->n_steps; i++) { double value = (double)steps->step[i]; steps->step[i] = pa_sw_volume_from_dB(value / 100.0); } }
/** * Volume adjusted (from within showtime), send update to PA * * Lock for PA mainloop is already held */ static void set_mastervol(void *opaque, float value) { pa_audio_mode_t *pam = opaque; pa_operation *o; pa_cvolume cv; pam->mastervol = pa_sw_volume_from_dB(value); if(pam->stream == NULL || pa_stream_get_state(pam->stream) != PA_STREAM_READY) return; memset(&cv, 0, sizeof(cv)); pa_cvolume_set(&cv, pam->ss.channels, pam->mastervol); o = pa_context_set_sink_input_volume(pam->context, pa_stream_get_index(pam->stream), &cv, NULL, NULL); if(o != NULL) pa_operation_unref(o); }
int main(int argc, char *argv[]) { pa_volume_t v; pa_cvolume cv; float b; pa_channel_map map; pa_volume_t md = 0; unsigned mdn = 0; if (!getenv("MAKE_CHECK")) pa_log_set_level(PA_LOG_DEBUG); pa_log("Attenuation of sample 1 against 32767: %g dB", 20.0*log10(1.0/32767.0)); pa_log("Smallest possible attenuation > 0 applied to 32767: %li", lrint(32767.0*pa_sw_volume_to_linear(1))); for (v = PA_VOLUME_MUTED; v <= PA_VOLUME_NORM*2; v += 256) { double dB = pa_sw_volume_to_dB(v); double f = pa_sw_volume_to_linear(v); pa_log_debug("Volume: %3i; percent: %i%%; decibel %0.2f; linear = %0.2f; volume(decibel): %3i; volume(linear): %3i", v, (v*100)/PA_VOLUME_NORM, dB, f, pa_sw_volume_from_dB(dB), pa_sw_volume_from_linear(f)); } for (v = PA_VOLUME_MUTED; v <= PA_VOLUME_NORM*2; v += 256) { char s[PA_CVOLUME_SNPRINT_MAX], t[PA_SW_CVOLUME_SNPRINT_DB_MAX]; pa_cvolume_set(&cv, 2, v); pa_log_debug("Volume: %3i [%s] [%s]", v, pa_cvolume_snprint(s, sizeof(s), &cv), pa_sw_cvolume_snprint_dB(t, sizeof(t), &cv)); } map.channels = cv.channels = 2; map.map[0] = PA_CHANNEL_POSITION_LEFT; map.map[1] = PA_CHANNEL_POSITION_RIGHT; for (cv.values[0] = PA_VOLUME_MUTED; cv.values[0] <= PA_VOLUME_NORM*2; cv.values[0] += 4096) for (cv.values[1] = PA_VOLUME_MUTED; cv.values[1] <= PA_VOLUME_NORM*2; cv.values[1] += 4096) { char s[PA_CVOLUME_SNPRINT_MAX]; pa_log_debug("Volume: [%s]; balance: %2.1f", pa_cvolume_snprint(s, sizeof(s), &cv), pa_cvolume_get_balance(&cv, &map)); } for (cv.values[0] = PA_VOLUME_MUTED+4096; cv.values[0] <= PA_VOLUME_NORM*2; cv.values[0] += 4096) for (cv.values[1] = PA_VOLUME_MUTED; cv.values[1] <= PA_VOLUME_NORM*2; cv.values[1] += 4096) for (b = -1.0f; b <= 1.0f; b += 0.2f) { char s[PA_CVOLUME_SNPRINT_MAX]; pa_cvolume r; float k; pa_log_debug("Before: volume: [%s]; balance: %2.1f", pa_cvolume_snprint(s, sizeof(s), &cv), pa_cvolume_get_balance(&cv, &map)); r = cv; pa_cvolume_set_balance(&r, &map,b); k = pa_cvolume_get_balance(&r, &map); pa_log_debug("After: volume: [%s]; balance: %2.1f (intended: %2.1f) %s", pa_cvolume_snprint(s, sizeof(s), &r), k, b, k < b-.05 || k > b+.5 ? "MISMATCH" : ""); } for (v = PA_VOLUME_MUTED; v <= PA_VOLUME_NORM*2; v += 51) { double l = pa_sw_volume_to_linear(v); pa_volume_t k = pa_sw_volume_from_linear(l); double db = pa_sw_volume_to_dB(v); pa_volume_t r = pa_sw_volume_from_dB(db); pa_volume_t w; pa_assert(k == v); pa_assert(r == v); for (w = PA_VOLUME_MUTED; w < PA_VOLUME_NORM*2; w += 37) { double t = pa_sw_volume_to_linear(w); double db2 = pa_sw_volume_to_dB(w); pa_volume_t p, p1, p2; double q, qq; p = pa_sw_volume_multiply(v, w); qq = db + db2; p2 = pa_sw_volume_from_dB(qq); q = l*t; p1 = pa_sw_volume_from_linear(q); if (p2 > p && p2 - p > md) md = p2 - p; if (p2 < p && p - p2 > md) md = p - p2; if (p1 > p && p1 - p > md) md = p1 - p; if (p1 < p && p - p1 > md) md = p - p1; if (p1 != p || p2 != p) mdn++; } } pa_log("max deviation: %lu n=%lu", (unsigned long) md, (unsigned long) mdn); pa_assert(md <= 1); pa_assert(mdn <= 251); return 0; }
void voice_update_parameters(struct userdata *u) { pa_sink *sink; const char *s; double tmp_d, old_d; int tmp, old; size_t nbytes; const void *data; ENTER(); sink = voice_get_original_master_sink(u); if (!sink) { pa_log_warn("Original master sink not found, parameters not updated."); return; } u->updating_parameters = TRUE; if (!pa_proplist_get(sink->proplist, "x-maemo.xprot.parameters.left", &data, &nbytes)) xprot_change_params(u->xprot, data, nbytes, 0); if (!pa_proplist_get(sink->proplist,"x-maemo.xprot.parameters.right", &data, &nbytes)) xprot_change_params(u->xprot, data, nbytes, 1); s = voice_pa_proplist_gets(sink->proplist, "x-maemo.cmt.ul_timing_advance"); old = u->ul_timing_advance; if (!pa_atoi(s, &tmp) && tmp > -5000 && tmp < 5000) u->ul_timing_advance = tmp; pa_log_debug("cmt_ul_timing_advance \"%s\" %d %d", s, u->ul_timing_advance, old); s = voice_pa_proplist_gets(sink->proplist, "x-maemo.alt_mixer_compensation"); /* CHECKME */ old_d = u->alt_mixer_compensation; if (!pa_atod(s, &tmp_d) && tmp_d > 0.0 && tmp_d <= 60.0) /* < 60.0 ? */ u->alt_mixer_compensation = pa_sw_volume_from_dB(tmp_d); pa_log_debug("alt_mixer_compensation \"%s\" %d %f", s, u->alt_mixer_compensation, old_d); s = voice_pa_proplist_gets(sink->proplist, "x-maemo.ear_ref_padding"); old = u->ear_ref.loop_padding_usec ; if (!pa_atoi(s, &tmp) && tmp > -10000 && tmp < 199999) u->ear_ref.loop_padding_usec = tmp; pa_log_debug("ear_ref_padding \"%s\" %d %d", s, u->ear_ref.loop_padding_usec, old); voice_parse_aep_steps(u, voice_pa_proplist_gets(sink->proplist, "x-maemo.audio_aep_mb_steps")); s = voice_pa_proplist_gets(sink->proplist, "x-maemo.nrec"); u->nrec_enable = pa_parse_boolean(s); if (u->master_source && pa_proplist_gets(u->master_source->proplist, "bluetooth.nrec")) { /* WTF ?!? */ u->sidetone_enable = pa_parse_boolean(s) && u->nrec_enable; } if (!pa_proplist_get(sink->proplist, "x-maemo.aep.switches", (const void **)&data, &nbytes) ) { uint16_t *as = (uint16_t *)data; aep_switches.field_0 = as[0]; aep_switches.field_2 = as[1]; aep_switches.field_4 = 0; if ( aep_switches.field_0 & 0x400 ) aep_switches.field_4 = 0x30; if (aep_switches.field_0 & 1) aep_switches.field_4 |= 0x300u; aep_switches.field_4 |= 0x1800u; } if (!pa_proplist_get(sink->proplist, "x-maemo.aep.parameters", &data, &nbytes)) { const char *argv[7] = { "../execute/d4gnt560", "b-ai-1n------0---u", "/dev/null", "/dev/null", "/dev/null", "/dev/null", "/dev/null", }; if (strlen(aep_runtime_switch) >= strlen(argv[1])) argv[1] = aep_runtime_switch; fprintf(stderr, "AEP runtime switch %s\n", argv[1]); current_aep_tuning = (void *)data; init_main(7, argv); voice_aep_ear_ref_loop_reset(u); } sidetone_write_parameters(u); if (!pa_proplist_get(sink->proplist, "x-maemo.wb_meq.parameters", &data, &nbytes)) iir_eq_change_params(u->wb_mic_iir_eq, data, nbytes); if (!pa_proplist_get(sink->proplist, "x-maemo.nb_meq.parameters", &data, &nbytes) ) iir_eq_change_params(u->nb_mic_iir_eq, data, nbytes); if (!pa_proplist_get(sink->proplist,"x-maemo.wb_eeq.parameters", &data, &nbytes)) fir_eq_change_params(u->wb_ear_iir_eq, data, nbytes); if (!pa_proplist_get(sink->proplist, "x-maemo.nb_eeq.parameters", &data, &nbytes)) iir_eq_change_params(u->nb_ear_iir_eq, data, nbytes); u->aep_enable = voice_pa_proplist_get_bool(sink->proplist, "x-maemo.aep"); u->wb_meq_enable = voice_pa_proplist_get_bool(sink->proplist, "x-maemo.wb_meq"); u->wb_eeq_enable = voice_pa_proplist_get_bool(sink->proplist, "x-maemo.wb_eeq"); u->nb_meq_enable = voice_pa_proplist_get_bool(sink->proplist, "x-maemo.nb_meq"); u->nb_eeq_enable = voice_pa_proplist_get_bool(sink->proplist, "x-maemo.nb_eeq"); u->xprot->displ_limit = voice_pa_proplist_get_bool(sink->proplist, "x-maemo.xprot.displacement"); u->xprot->temp_limit = voice_pa_proplist_get_bool(sink->proplist, "x-maemo.xprot.temperature"); u->xprot_enable = u->xprot->displ_limit || u->xprot->temp_limit; u->updating_parameters = FALSE; }