Wrote my own pasimple
This commit is contained in:
@@ -15,6 +15,7 @@
|
||||
#include <fcntl.h>
|
||||
|
||||
// https://github.com/pulseaudio/pulseaudio/blob/master/src/pulse/simple.c
|
||||
// https://habr.com/en/articles/663352/#linux-and-pulseaudio
|
||||
|
||||
struct pa_system
|
||||
{
|
||||
@@ -22,6 +23,7 @@ struct pa_system
|
||||
pa_context* context;
|
||||
pa_stream* stream;
|
||||
pa_stream_direction_t direction;
|
||||
pa_mainloop_api* api;
|
||||
|
||||
const void *read_data;
|
||||
size_t read_index, read_length;
|
||||
@@ -31,19 +33,33 @@ struct pa_system
|
||||
|
||||
static void context_state_cb(pa_context *c, void *userdata)
|
||||
{
|
||||
std::cout << "Received context state callback" << std::endl;
|
||||
std::cout << "context state callback: ";
|
||||
|
||||
auto *p = static_cast<pa_system *>(userdata);
|
||||
switch(pa_context_get_state(c)) {
|
||||
case PA_CONTEXT_READY:
|
||||
std::cout << "Context Ready" << std::endl;
|
||||
pa_threaded_mainloop_signal(p->mainloop, 0);
|
||||
break;
|
||||
case PA_CONTEXT_TERMINATED:
|
||||
std::cout << "Context Terminated" << std::endl;
|
||||
pa_threaded_mainloop_signal(p->mainloop, 0);
|
||||
break;
|
||||
case PA_CONTEXT_FAILED:
|
||||
std::cout << "Context Failed" << std::endl;
|
||||
pa_threaded_mainloop_signal(p->mainloop, 0);
|
||||
break;
|
||||
case PA_CONTEXT_UNCONNECTED:
|
||||
std::cout << "Context Unconnected" << std::endl;
|
||||
break;
|
||||
case PA_CONTEXT_CONNECTING:
|
||||
std::cout << "Context Connecting" << std::endl;
|
||||
break;
|
||||
case PA_CONTEXT_AUTHORIZING:
|
||||
std::cout << "Context Authorizing" << std::endl;
|
||||
break;
|
||||
case PA_CONTEXT_SETTING_NAME:
|
||||
std::cout << "Context Setting Name" << std::endl;
|
||||
break;
|
||||
default:
|
||||
std::cerr << "The fuck?" << std::endl;
|
||||
@@ -53,21 +69,29 @@ static void context_state_cb(pa_context *c, void *userdata)
|
||||
|
||||
static void stream_state_cb(pa_stream* s, void* userdata)
|
||||
{
|
||||
std::cout << "Received stream state callback" << std::endl;
|
||||
std::cout << "stream state callback: ";
|
||||
|
||||
auto *p = static_cast<pa_system *>(userdata);
|
||||
|
||||
|
||||
|
||||
auto state = pa_stream_get_state(s);
|
||||
switch(state) {
|
||||
case PA_STREAM_READY:
|
||||
std::cout << "Stream Ready" << std::endl;
|
||||
pa_threaded_mainloop_signal(p->mainloop, 0);
|
||||
break;
|
||||
case PA_STREAM_FAILED:
|
||||
std::cout << "Stream Failed" << std::endl;
|
||||
pa_threaded_mainloop_signal(p->mainloop, 0);
|
||||
break;
|
||||
case PA_STREAM_TERMINATED:
|
||||
std::cout << "Stream Terminated" << std::endl;
|
||||
pa_threaded_mainloop_signal(p->mainloop, 0);
|
||||
break;
|
||||
case PA_STREAM_UNCONNECTED:
|
||||
std::cout << "Stream Unconnected" << std::endl;
|
||||
break;
|
||||
case PA_STREAM_CREATING:
|
||||
std::cout << "Stream Creating" << std::endl;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -102,6 +126,7 @@ pa_system* pa_system_new(
|
||||
pa_system *p;
|
||||
|
||||
p = pa_xnew(pa_system, 1);
|
||||
p->direction = dir;
|
||||
|
||||
//const char *server = NULL;
|
||||
//const char *name = "This Dick";
|
||||
@@ -122,11 +147,14 @@ pa_system* pa_system_new(
|
||||
throw std::runtime_error("Failed to create a PulseAudio mainloop");
|
||||
// goto fail;
|
||||
|
||||
if (!(p->context = pa_context_new(
|
||||
pa_threaded_mainloop_get_api(p->mainloop),
|
||||
"Sound Channel?")))
|
||||
p->api = pa_threaded_mainloop_get_api(p->mainloop);
|
||||
|
||||
// TODO: Research pa_context_new_with_proplist
|
||||
if (!(p->context = pa_context_new( p->api, "Sound Channel?")))
|
||||
{
|
||||
// goto fail;
|
||||
throw std::runtime_error("Failed to create a context");
|
||||
// goto fail;
|
||||
}
|
||||
|
||||
pa_context_flags flags = pa_context_flags::PA_CONTEXT_NOAUTOSPAWN;
|
||||
|
||||
@@ -241,6 +269,61 @@ void pa_system_free(pa_system* p)
|
||||
}
|
||||
|
||||
|
||||
void on_device_sink(pa_context* c, const pa_sink_info* info, int eol, void* userdata)
|
||||
{
|
||||
if (eol != 0)
|
||||
{
|
||||
pa_system* p = static_cast<pa_system *>(userdata);
|
||||
pa_threaded_mainloop_signal(p->mainloop, 0);
|
||||
}
|
||||
|
||||
if (info)
|
||||
{
|
||||
const char* device_id = info->name;
|
||||
std::cout << "Device found: " << device_id << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void on_device_source(pa_context* c, const pa_source_info* info, int eol, void *userdata)
|
||||
{
|
||||
|
||||
if (eol != 0)
|
||||
{
|
||||
pa_system* p = static_cast<pa_system *>(userdata);
|
||||
pa_threaded_mainloop_signal(p->mainloop, 0);
|
||||
}
|
||||
if (info)
|
||||
{
|
||||
const char* device_id = info->name;
|
||||
std::cout << "Device found: " << device_id << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
int pa_system_enumerate_devices(pa_system* p)
|
||||
{
|
||||
pa_threaded_mainloop_lock(p->mainloop);
|
||||
|
||||
pa_operation * op;
|
||||
if (p->direction == PA_STREAM_PLAYBACK)
|
||||
op = pa_context_get_sink_info_list(p->context, on_device_sink, p);
|
||||
else
|
||||
op = pa_context_get_source_info_list(p->context, on_device_source, p);
|
||||
|
||||
for (;;) {
|
||||
int r = pa_operation_get_state(op);
|
||||
|
||||
if (r == PA_OPERATION_DONE || r == PA_OPERATION_CANCELLED || r == PA_OPERATION_CANCELED)
|
||||
break;
|
||||
|
||||
pa_threaded_mainloop_wait(p->mainloop);
|
||||
}
|
||||
|
||||
pa_operation_unref(op);
|
||||
|
||||
pa_threaded_mainloop_unlock(p->mainloop);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pa_system_write(pa_system* p, const void* data, size_t length, int *rerror)
|
||||
{
|
||||
pa_threaded_mainloop_lock(p->mainloop);
|
||||
@@ -317,12 +400,16 @@ static void success_cb(pa_stream *s, int success, void * userdata)
|
||||
|
||||
int pa_system_drain(pa_system* p, int *rerror)
|
||||
{
|
||||
pa_operation *o = NULL;
|
||||
pa_operation *o = nullptr;
|
||||
|
||||
pa_threaded_mainloop_lock(p->mainloop);
|
||||
|
||||
o = pa_stream_drain(p->stream, success_cb, p);
|
||||
|
||||
if (!o)
|
||||
{
|
||||
throw std::runtime_error("pa_stream_drain did not fill our pa_operation structure!");
|
||||
}
|
||||
p->operation_success = 0;
|
||||
|
||||
while (pa_operation_get_state(o) == PA_OPERATION_RUNNING) {
|
||||
@@ -450,6 +537,9 @@ int main(int argc, char* argv[]) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
|
||||
pa_system_enumerate_devices(s);
|
||||
|
||||
for (;;) {
|
||||
uint8_t buf[BUFSIZE];
|
||||
ssize_t r;
|
||||
|
Reference in New Issue
Block a user