diff options
Diffstat (limited to 'src/AudioPlayer.cpp')
-rw-r--r-- | src/AudioPlayer.cpp | 87 |
1 files changed, 87 insertions, 0 deletions
diff --git a/src/AudioPlayer.cpp b/src/AudioPlayer.cpp new file mode 100644 index 0000000..8d30ee6 --- /dev/null +++ b/src/AudioPlayer.cpp @@ -0,0 +1,87 @@ +#include "../include/AudioPlayer.hpp" + +#include <unistd.h> +#include <fcntl.h> +#include <stdio.h> +#include <string.h> + +#include <pulse/simple.h> +#include <pulse/error.h> + +#define BUFSIZE 4096 + +namespace gsr { + AudioPlayer::~AudioPlayer() { + if(thread.joinable()) { + stop_playing_audio = true; + thread.join(); + } + + if(audio_file_fd > 0) + close(audio_file_fd); + } + + bool AudioPlayer::play(const char *filepath) { + if(thread.joinable()) { + stop_playing_audio = true; + thread.join(); + } + + stop_playing_audio = false; + audio_file_fd = open(filepath, O_RDONLY); + if(audio_file_fd == -1) + return false; + + thread = std::thread([this]() { + const pa_sample_spec ss = { + .format = PA_SAMPLE_S16LE, + .rate = 48000, + .channels = 2 + }; + + pa_simple *s = NULL; + int error; + + /* Create a new playback stream */ + if(!(s = pa_simple_new(NULL, "gsr-ui-audio-playback", PA_STREAM_PLAYBACK, NULL, "playback", &ss, NULL, NULL, &error))) { + fprintf(stderr, __FILE__": pa_simple_new() failed: %s\n", pa_strerror(error)); + goto finish; + } + + uint8_t buf[BUFSIZE]; + for(;;) { + ssize_t r; + + if(stop_playing_audio) + goto finish; + + if((r = read(audio_file_fd, buf, sizeof(buf))) <= 0) { + if(r == 0) /* EOF */ + break; + + fprintf(stderr, __FILE__": read() failed: %s\n", strerror(errno)); + goto finish; + } + + if(pa_simple_write(s, buf, (size_t) r, &error) < 0) { + fprintf(stderr, __FILE__": pa_simple_write() failed: %s\n", pa_strerror(error)); + goto finish; + } + } + + if(pa_simple_drain(s, &error) < 0) { + fprintf(stderr, __FILE__": pa_simple_drain() failed: %s\n", pa_strerror(error)); + goto finish; + } + + finish: + if(s) + pa_simple_free(s); + + close(audio_file_fd); + audio_file_fd = -1; + }); + + return true; + } +}
\ No newline at end of file |