title: Getting volume value from pulseaudio
body: <p>I've written this code by looking at various examples: <a href="http://freshfoo.com/posts/pulseaudio_monitoring/%20%22Python%20pulseaudio%20monitor" rel="nofollow noreferrer">Python pulseaudio monitor</a>, <a href="https://github.com/orospakr/peephole/blob/master/examples/pulseaudio-vu/src/vumeter.cc" rel="nofollow noreferrer">Pavumeter source</a>, <a href="https://www.freedesktop.org/wiki/Software/PulseAudio/Documentation/Developer/Clients/Samples/AsyncPlayback/" rel="nofollow noreferrer">async playback example</a>, and <a href="https://github.com/pulseaudio/pulseaudio/blob/master/src/utils/pacat.c" rel="nofollow noreferrer">Pacat source</a>.</p>
  
  <p>I have successfully connected to a sink and am able to record it, but my problem is, I'm stuck at getting the volume value out. If I try printing value from the read function, I just get a bunch of random numbers at a second's interval.</p>
  
  <p>Now I'm not asking for someone to finish writing the code for me, I'd just like some tips, help so that I could head towards the right direction. How do I retrieve the volume value?</p>
  
  <pre><code>#include &lt;stdio.h&gt;
  #include &lt;string.h&gt;
  #include &lt;math.h&gt;
  #include &lt;pulse/pulseaudio.h&gt;
  
  static int latency = 20000; // start latency in micro seconds
  static int sampleoffs = 0;
  static short sampledata[300000];
  static pa_buffer_attr bufattr;
  static int underflows = 0;
  static pa_sample_spec ss;
  
  // This callback gets called when our context changes state.  We really only
  // care about when it's ready or if it has failed
  void pa_state_cb(pa_context *c, void *userdata) {
    pa_context_state_t state;
    int *pa_ready = userdata;
    state = pa_context_get_state(c);
    switch  (state) {
      // These are just here for reference
    case PA_CONTEXT_UNCONNECTED:
    case PA_CONTEXT_CONNECTING:
    case PA_CONTEXT_AUTHORIZING:
    case PA_CONTEXT_SETTING_NAME:
    default:
      break;
    case PA_CONTEXT_FAILED:
    case PA_CONTEXT_TERMINATED:
      *pa_ready = 2;
      break;
    case PA_CONTEXT_READY:
      *pa_ready = 1;
      break;
    }
  }
  
  static void stream_read_cb(pa_stream *s, size_t length, void *userdata) {
    const void *data;
    pa_stream_peek(s, &amp;data, &amp;length);
    data = (const unsigned char*) data;
    printf("%u", data);
    pa_stream_drop(s);
  }
  
  int main(int argc, char *argv[]) {
    pa_mainloop *pa_ml;
    pa_mainloop_api *pa_mlapi;
    pa_context *pa_ctx;
    pa_stream *recordstream;
    int r;
    int pa_ready = 0;
    int retval = 0;
    unsigned int a;
    double amp;
    int test = 0;
  
    // Create a mainloop API and connection to the default server
    pa_ml = pa_mainloop_new();
    pa_mlapi = pa_mainloop_get_api(pa_ml);
    pa_ctx = pa_context_new(pa_mlapi, "Simple PA test application");
    pa_context_connect(pa_ctx, NULL, 0, NULL);
  
    // This function defines a callback so the server will tell us it's state.
    // Our callback will wait for the state to be ready.  The callback will
    // modify the variable to 1 so we know when we have a connection and it's
    // ready.
    // If there's an error, the callback will set pa_ready to 2
    pa_context_set_state_callback(pa_ctx, pa_state_cb, &amp;pa_ready);
  
    // We can't do anything until PA is ready, so just iterate the mainloop
    // and continue
    while (pa_ready == 0) {
      pa_mainloop_iterate(pa_ml, 1, NULL);
    }
  
    if (pa_ready == 2) {
      retval = -1;
      goto exit;
    }
  
    ss.rate = 44100;
    ss.channels = 2;
    ss.format = PA_SAMPLE_U8;
    recordstream = pa_stream_new(pa_ctx, "Record", &amp;ss, NULL);
    if (!recordstream) {
      printf("pa_stream_new failed\n");
    }
  
    pa_stream_set_read_callback(recordstream, stream_read_cb, NULL);
    r = pa_stream_connect_record(recordstream, NULL, NULL, PA_STREAM_PEAK_DETECT);
  
    if (r &lt; 0) {
      printf("pa_stream_connect_playback failed\n");
      retval = -1;
      goto exit;
    }
  
    // Run the mainloop until pa_mainloop_quit() is called
    // (this example never calls it, so the mainloop runs forever).
    // printf("%s", "Running Loop");
    pa_mainloop_run(pa_ml, NULL);
  
  exit:
    // clean up and disconnect
    pa_context_disconnect(pa_ctx);
    pa_context_unref(pa_ctx);
    pa_mainloop_free(pa_ml);
    return retval;
  }
  </code></pre>