PusleAudio Demo
未分类 阅读(355)
```C #include <pulse/pulseaudio.h> #include <pulse/thread-mainloop.h> #include <stdio.h> #include <stdlib.h> // 创建上下文 static pa_context* create_context(pa_threaded_mainloop* m); // 等待上下文状态变为就绪 static int wait_context_state_ready(pa_threaded_mainloop* m, pa_context* ctx); // 回调函数,在上下文状态变化时发一个信号 static void context_state_change_callback(pa_context* ctx, void* userdata); // 回调函数,获取声卡信息 static void get_card_info_callback(pa_context *ctx, const pa_card_info* info, int state, void *userdata); int main() { pa_threaded_mainloop* m = pa_threaded_mainloop_new(); if(m == NULL) { printf("pa_threaded_mainloop_new() failed.\b"); return EXIT_FAILURE; } // 立即start pa_threaded_mainloop_start(m); // 创建上下文 pa_context* ctx = create_context(m); if(ctx == NULL) { printf("create_context() failed.\n"); return EXIT_FAILURE; } // 将上下文连接到服务进程 pa_threaded_mainloop_lock(m); if(pa_context_connect(ctx, NULL, PA_CONTEXT_NOFAIL, NULL) < 0) { printf("pa_context_connect() failed.\n"); return EXIT_FAILURE; } pa_threaded_mainloop_unlock(m); // 等待上下文就绪 // 可以简化为 // while(pa_context_get_state(ctx) != PA_CONTEXT_READY); int ret = wait_context_state_ready(m, ctx); if(ret == EXIT_SUCCESS) { // 获取声卡列表 int running = 1; pa_threaded_mainloop_lock(m); pa_operation* op = pa_context_get_card_info_list(ctx, get_card_info_callback, (void*)&running); pa_operation_unref(op); pa_threaded_mainloop_unlock(m); while(running); } // 释放 pa_context_unref(ctx); pa_threaded_mainloop_free(m); return ret; } // 创建上下文 static pa_context* create_context(pa_threaded_mainloop* m) { // 获取主循环API pa_threaded_mainloop_lock(m); pa_mainloop_api* mapi = pa_threaded_mainloop_get_api(m); pa_context* ctx = pa_context_new(mapi, "pulseaudio-demo"); pa_threaded_mainloop_unlock(m); return ctx; } // 等待上下文状态变为就绪 static int wait_context_state_ready(pa_threaded_mainloop* m, pa_context* ctx) { // 设置一个上下文状态改变的回调函数 pa_threaded_mainloop_lock(m); pa_context_set_state_callback(ctx, context_state_change_callback, m); pa_threaded_mainloop_unlock(m); int state; do { pa_threaded_mainloop_lock(m); pa_threaded_mainloop_wait(m); // 等待 pa_threaded_mainloop_signal 发出信号 state = pa_context_get_state(ctx); // 获取状态 pa_threaded_mainloop_unlock(m); if(state == PA_CONTEXT_FAILED || state == PA_CONTEXT_TERMINATED) { return EXIT_FAILURE; } } while (state != PA_CONTEXT_READY); return EXIT_SUCCESS; } // 回调函数,在上下文状态变化时发一个信号 static void context_state_change_callback(pa_context* ctx, void* userdata) { (void)ctx; pa_threaded_mainloop* loop = (pa_threaded_mainloop*)userdata; pa_threaded_mainloop_signal(loop, 0); // 发出一个信号,令 pa_threaded_mainloop_wait 返回 } // 回调函数,获取声卡信息 static void get_card_info_callback(pa_context *ctx, const pa_card_info* info, int state, void *userdata) { (void)ctx; if(state == 0) { printf("card name : %s\n",info->name); } else { (*(int*)userdata) = 0; // 令 running = 0 让程序结束 } } ```