111 lines
2.9 KiB
C++
111 lines
2.9 KiB
C++
#include <pulse/mainloop.h>
|
|
#include <pulse/mainloop-api.h>
|
|
#include <iostream>
|
|
#include <pulse/error.h>
|
|
#include <pulse/volume.h>
|
|
#include <pulse/stream.h>
|
|
#include <format>
|
|
|
|
// https://github.com/pulseaudio/pulseaudio/blob/master/src/pulse/simple.c
|
|
|
|
static void context_state_callback(pa_context *c, void *userdata)
|
|
{
|
|
switch(pa_context_get_state(c)) {
|
|
case PA_CONTEXT_READY:
|
|
case PA_CONTEXT_TERMINATED:
|
|
case PA_CONTEXT_FAILED:
|
|
case PA_CONTEXT_UNCONNECTED:
|
|
case PA_CONTEXT_CONNECTING:
|
|
case PA_CONTEXT_AUTHORIZING:
|
|
case PA_CONTEXT_SETTING_NAME:
|
|
default:
|
|
std::cerr << "The fuck?" << std::endl;
|
|
break;
|
|
}
|
|
}
|
|
|
|
|
|
int main(int argc, char* argv[]) {
|
|
if (argc == 1 || argv[1] == "-h" || argv[1] == "help") {
|
|
std::cout << "pacat - Tests playback of raw audio data via PulseAudio API." << std::endl;
|
|
std::cout << "usage: pacat <file> (presumably output.raw)\n" << std::endl;
|
|
}
|
|
|
|
static const pa_sample_spec ss = {
|
|
.format = PA_SAMPLE_S16LE,
|
|
.rate = 44100,
|
|
.channels = 2
|
|
};
|
|
|
|
|
|
int errno;
|
|
|
|
pa_mainloop *maneloop;
|
|
pa_context *ctx;
|
|
pa_stream *stream;
|
|
const pa_channel_map* map = NULL;
|
|
const pa_buffer_attr* attr = NULL;
|
|
|
|
const char* server = NULL;
|
|
const char* name = "This Dick";
|
|
pa_stream_direction_t dir = PA_STREAM_PLAYBACK;
|
|
const char* dev = NULL;
|
|
const char* stream_name = "playback";
|
|
|
|
|
|
if (!(maneloop = pa_mainloop_new()))
|
|
throw std::runtime_error("Failed to create a PulseAudio mainloop");
|
|
|
|
|
|
#pragma region Context Creation
|
|
if (!(ctx = pa_context_new(
|
|
pa_mainloop_get_api(maneloop),
|
|
"Sound Channel?")))
|
|
throw std::runtime_error("Failed to create a context");
|
|
|
|
pa_context_flags flags = pa_context_flags::PA_CONTEXT_NOAUTOSPAWN;
|
|
|
|
if (pa_context_connect(ctx, server, flags, NULL) < 0)
|
|
{
|
|
errno = pa_context_errno(ctx);
|
|
throw std::runtime_error(std::format("Failed to connect a context: {}", errno));
|
|
}
|
|
|
|
pa_context_set_state_callback(ctx, context_state_callback, NULL);
|
|
|
|
for (;;)
|
|
{
|
|
pa_context_state_t state;
|
|
state = pa_context_get_state(ctx);
|
|
|
|
if (state == PA_CONTEXT_READY)
|
|
break;
|
|
|
|
if (!PA_CONTEXT_IS_GOOD(state)) {
|
|
errno = pa_context_errno(ctx);
|
|
throw std::runtime_error(std::format("Context was not good! {}", errno));
|
|
}
|
|
|
|
// Wait until the context is ready
|
|
//pa_mainloop_wait(maneloop);
|
|
|
|
}
|
|
#pragma endregion
|
|
|
|
auto state = pa_context_get_state(ctx);
|
|
|
|
if (state != PA_CONTEXT_READY) {
|
|
|
|
}
|
|
|
|
if (!(stream = pa_stream_new(ctx, "This Dick", &ss, map)))
|
|
{
|
|
errno = pa_context_errno(ctx);
|
|
throw std::runtime_error(std::format("Failed to create a stream. Error code {}", errno));
|
|
}
|
|
|
|
//pa_stream_set_state_callback(stream, stream_state)
|
|
|
|
|
|
return 0;
|
|
} |