从pulseaudio

时间:2017-06-17 08:14:50

标签: c linux audio pulseaudio

我通过查看各种示例来编写此代码:Python pulseaudio monitorPavumeter sourceasync playback examplePacat source

我已经成功连接到接收器并且能够录制它,但我的问题是,我已经停留在获取音量值。如果我尝试从读取函数中打印值,我只会在一秒钟内得到一堆随机数。

现在我并没有要求有人为我完成代码编写,我只是喜欢一些提示,帮助我以便朝着正确的方向前进。如何检索音量值?

#include <stdio.h>
#include <string.h>
#include <math.h>
#include <pulse/pulseaudio.h>

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, &data, &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, &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", &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 < 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;
}

1 个答案:

答案 0 :(得分:0)

查看UNIX.StackExchange中的原始问题,您似乎正在尝试创建VU表。可以使用envelope detector来完成。您必须读取输入值,然后平均其整流值。一个简单的包络检测器可以作为指数移动平均滤波器来完成。

ABCMyFile.h
ABCMyFile.m
ABCMyFile1.h
ABCMyFile1.m
ABCMyFile2.h
ABCMyFile2.m

此处,float level = 0; // Init time const float alpha = COEFFICIENT; // See below ... // Inside sample loop float input_signal = fabsf(get_current_sample()); level = level + alpha * (input_signal - level); 是滤波器系数,可以计算为:

alpha

const float alpha = 1.0 - expf( (-2.0 * M_PI) / (TC * SAMPLE_RATE) ); 被称为&#34;时间常数&#34;参数,以秒为单位,用于定义您想要的速度&#34;关注&#34;信号。将它设置得太短会使VU表非常“颠簸”。设置太长会错过信号中的瞬变。 10 mS是一个很好的起点。