static void
sink_subscribe_cb(pa_core *c, pa_subscription_event_type_t t, uint32_t idx,
                  void *userdata)
{
  struct userdata *u = (struct userdata *)userdata;

  if (t == PA_SUBSCRIPTION_EVENT_CHANGE)
  {
    pa_sink *sink = PA_SINK(pa_idxset_get_by_index(c->sinks, idx));

    if (sink)
    {
      if (u->master_sink == sink)
      {
        const pa_cvolume *vol = pa_sink_get_volume(sink, 0, 0);
        int aep_step;

        u->linear_q15_master_volume_L = lrint(pa_sw_volume_to_linear(vol->values[0]) * 32767.0);

        if (vol->channels == 1)
          u->linear_q15_master_volume_R = lrint(pa_sw_volume_to_linear(vol->values[0]) * 32767.0);
        else
          u->linear_q15_master_volume_R = lrint(pa_sw_volume_to_linear(vol->values[1]) * 32767.0);

        aep_step = voice_pa_vol_to_aep_step(u, vol->values[0]);

        if (voice_cmt_ul_is_active_iothread(u) ||
            (u->voip_source && PA_SOURCE_IS_LINKED(u->voip_source->state) && pa_source_used_by(u->voip_source)))
        {
          if (aep_step <= 0)
          {
            voice_update_aep_volume(0);
            voice_update_sidetone_gain(0);
          }
          else
          {
            voice_update_aep_volume(aep_step - 1);
            voice_update_sidetone_gain(aep_step - 1);
          }
        }

        xprot_change_volume(u->xprot, u->linear_q15_master_volume_L, u->linear_q15_master_volume_R);
      }
    }
  }
}
Example #2
0
double pa_sw_volume_to_dB(pa_volume_t v) {

    pa_return_val_if_fail(PA_VOLUME_IS_VALID(v), PA_DECIBEL_MININFTY);

    if (v <= PA_VOLUME_MUTED)
        return PA_DECIBEL_MININFTY;

    return linear_to_dB(pa_sw_volume_to_linear(v));
}
Example #3
0
File: mix.c Project: Thread974/pa
static void calc_linear_float_volume(float linear[], const pa_cvolume *volume) {
    unsigned channel, nchannels, padding;

    pa_assert(linear);
    pa_assert(volume);

    nchannels = volume->channels;

    for (channel = 0; channel < nchannels; channel++)
        linear[channel] = (float) pa_sw_volume_to_linear(volume->values[channel]);

    for (padding = 0; padding < VOLUME_PADDING; padding++, channel++)
        linear[channel] = linear[padding];
}
Example #4
0
File: mix.c Project: Thread974/pa
static void calc_linear_integer_volume(int32_t linear[], const pa_cvolume *volume) {
    unsigned channel, nchannels, padding;

    pa_assert(linear);
    pa_assert(volume);

    nchannels = volume->channels;

    for (channel = 0; channel < nchannels; channel++)
        linear[channel] = (int32_t) lrint(pa_sw_volume_to_linear(volume->values[channel]) * 0x10000);

    for (padding = 0; padding < VOLUME_PADDING; padding++, channel++)
        linear[channel] = linear[padding];
}
Example #5
0
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;
}
Example #6
0
/**
 * @brief Callback function called when the information on the
 *        context's sink is retrieved.
 * @param ctx Context which operation has succeeded
 * @param info Structure containing the sink's information
 * @param this_gen pulse_driver_t pointer for the PulseAudio output
 *        instance.
 *
 * This function saves the volume field of the passed structure to the
 * @c cvolume variable of the output instance and send an update volume
 * event to the frontend.
 */
static void __xine_pa_sink_info_callback(pa_context *c, const pa_sink_input_info *info,
                                         int is_last, void *userdata) {

  pulse_driver_t *const this = (pulse_driver_t *) userdata;

  if (is_last < 0) {
    xprintf (this->xine, XINE_VERBOSITY_DEBUG, "audio_pulse_out: Failed to get sink input info: %s\n",
             pa_strerror(pa_context_errno(this->context)));
    return;
  }

  if (!info)
      return;

  this->cvolume = info->volume;
  this->swvolume = pa_cvolume_avg(&info->volume);
#if PA_PROTOCOL_VERSION >= 11
  /* PulseAudio 0.9.7 and newer */
  this->muted = info->mute;
#else
  this->muted = pa_cvolume_is_muted (&this->cvolume);
#endif

  /* send update volume event to frontend */

  xine_event_t              event;
  xine_audio_level_data_t   data;
  xine_stream_t            *stream;
  xine_list_iterator_t      ite;

  data.right        = data.left = (int) (pa_sw_volume_to_linear(this->swvolume)*100);

  data.mute         = this->muted;

  event.type        = XINE_EVENT_AUDIO_LEVEL;
  event.data        = &data;
  event.data_length = sizeof(data);

  pthread_mutex_lock(&this->xine->streams_lock);
  for(ite = xine_list_front(this->xine->streams); ite; ite =
    xine_list_next(this->xine->streams, ite)) {
    stream = xine_list_get_value(this->xine->streams, ite);
    event.stream = stream;
    xine_event_send(stream, &event);
  }
  pthread_mutex_unlock(&this->xine->streams_lock);
}
Example #7
0
File: mix.c Project: Thread974/pa
static void calc_linear_float_stream_volumes(pa_mix_info streams[], unsigned nstreams, const pa_cvolume *volume, const pa_sample_spec *spec) {
    unsigned k, channel;
    float linear[PA_CHANNELS_MAX + VOLUME_PADDING];

    pa_assert(streams);
    pa_assert(spec);
    pa_assert(volume);

    calc_linear_float_volume(linear, volume);

    for (k = 0; k < nstreams; k++) {

        for (channel = 0; channel < spec->channels; channel++) {
            pa_mix_info *m = streams + k;
            m->linear[channel].f = (float) (pa_sw_volume_to_linear(m->volume.values[channel]) * linear[channel]);
        }
    }
}
Example #8
0
static void
gst_pulsesrc_source_output_info_cb (pa_context * c,
    const pa_source_output_info * i, int eol, void *userdata)
{
  GstPulseSrc *psrc;

  psrc = GST_PULSESRC_CAST (userdata);

  if (!i)
    goto done;

  /* If the index doesn't match our current stream,
   * it implies we just recreated the stream (caps change)
   */
  if (i->index == psrc->source_output_idx) {
    psrc->volume = pa_sw_volume_to_linear (pa_cvolume_max (&i->volume));
    psrc->mute = i->mute;
  }

done:
  pa_threaded_mainloop_signal (psrc->mainloop, 0);
}
Example #9
0
pa_volume_t pa_sw_volume_multiply(pa_volume_t a, pa_volume_t b) {
    return pa_sw_volume_from_linear(pa_sw_volume_to_linear(a)* pa_sw_volume_to_linear(b));
}
Example #10
0
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;
}