Wrote my own pasimple

This commit is contained in:
2024-08-22 22:35:41 -04:00
parent 146c21d586
commit 08edd2503f

View File

@@ -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;