diff options
| author | Louis Burda <quent.burda@gmail.com> | 2021-12-12 23:06:54 +0100 |
|---|---|---|
| committer | Louis Burda <quent.burda@gmail.com> | 2021-12-20 15:31:28 +0100 |
| commit | 1bd07952245e3fc8ed95af0c1eff45938098b40b (patch) | |
| tree | 92f96c57337f71b7ec46125806800ba91e3acac2 /player.c | |
| parent | 9fe644f0d99375ffd3011d8828f7dbd0fb103af0 (diff) | |
| download | tmus-1bd07952245e3fc8ed95af0c1eff45938098b40b.tar.gz tmus-1bd07952245e3fc8ed95af0c1eff45938098b40b.zip | |
Added playback via libmpdclient
Diffstat (limited to 'player.c')
| -rw-r--r-- | player.c | 219 |
1 files changed, 164 insertions, 55 deletions
@@ -2,112 +2,221 @@ #include "portaudio.h" #include "sndfile.h" +#include "util.h" +#include <mpd/song.h> +#include <mpd/status.h> +#include <stdbool.h> #include <stdlib.h> +#include <string.h> #include <sys/mman.h> #include <unistd.h> +#define PLAYER_STATUS(lvl, ...) do { \ + player->msglvl = lvl; \ + if (player->msg) free(player->msg); \ + player->msg = aprintf(__VA_ARGS__); \ + } while (0) + static struct player player_static; struct player *player; -struct player * -player_thread() +void +player_init(void) { - struct player *player; - pid_t pid; - - player = mmap(&player_static, sizeof(struct player), - PROT_READ | PROT_WRITE, MAP_SHARED, -1, 0); - player->action = PLAYER_NONE; - player->resp = PLAYER_NOTSET; - player->alive = 1; - - pid = fork(); - if (!pid) { - player_main(); - player->alive = 0; - exit(0); - } + player = malloc(sizeof(struct player)); + ASSERT(player != NULL); + + player->conn = mpd_connection_new(NULL, 0, 0); + ASSERT(player->conn != NULL); + + player->queue = LIST_HEAD; + player->track = NULL; + player->state = PLAYER_STATE_PAUSED; + + player->volume = 0; + player->time_pos = 0; + player->time_end = 0; + + player->msg = NULL; + player->msglvl = PLAYER_MSG_INFO; - player->pid = pid; + mpd_run_stop(player->conn); + mpd_run_clear(player->conn); +} - return player; +void +player_free(void) +{ + if (!player->conn) return; + mpd_run_stop(player->conn); + mpd_run_clear(player->conn); + mpd_connection_free(player->conn); } void -player_main(void) +player_update(void) { - PaStream *stream; - int status; - - if (Pa_Initialize() != paNoError) - return; - - while (player->action != PLAYER_EXIT) { - player->resp = PLAYER_NOTSET; - switch (player->action) { - case PLAYER_PLAY: - player->resp = player_play(); - break; - case PLAYER_PAUSE: - player->resp = player_pause(); - break; - case PLAYER_SKIP: - player->resp = player_skip(); - break; - case PLAYER_PREV: - player->resp = player_prev(); - break; - } - Pa_Sleep(100); + struct mpd_status *status; + struct mpd_song *song; + const char *tmp; + + status = mpd_run_status(player->conn); + ASSERT(status != NULL); + + player->state = mpd_status_get_state(status) == MPD_STATE_PLAY + ? PLAYER_STATE_PLAYING : PLAYER_STATE_PAUSED; + player->volume = mpd_status_get_volume(status); + + song = mpd_run_current_song(player->conn); + if (song) { + player->time_pos = mpd_status_get_elapsed_time(status); + player->time_end = mpd_song_get_duration(song); + mpd_song_free(song); + } else { + player->time_pos = 0; + player->time_end = 0; } - Pa_Terminate(); + mpd_status_free(status); } -int -player_alive(void) +void +player_queue_clear(void) { - return player->alive && !kill(player->pid, 0); + struct link *iter, *next;; + + for (iter = &player->queue; iter; ) { + next = iter->next; + free(UPCAST(iter, struct track_ref)); + iter = next; + } + + player->queue = LIST_HEAD; } void -player_loadfile(const char *file) +player_queue_append(struct track *track) { - ASSERT(player_alive()); - player_action(PLAYER_STOP); + player_queue_insert(track, list_len(&player->queue)); } void -player_action(int action) +player_queue_insert(struct track *track, size_t pos) +{ + struct track_ref *new; + struct link *iter; + int i; + + new = malloc(sizeof(struct track_ref)); + new->track = track; + new->link = LINK_EMPTY; + + iter = &player->queue; + for (i = 0; i < pos && iter->next; i++) + iter = iter->next; + + link_append(iter, &new->link); +} + +int +player_play_track(struct track *track) { - ASSERT(player_alive()); - player->action = action; + player_clear_msg(); + player->track = track; + mpd_run_stop(player->conn); + + if (!mpd_run_add(player->conn, player->track->fpath) + || !mpd_run_play(player->conn)) { + PLAYER_STATUS(PLAYER_MSG_ERR, "Playback failed"); + return PLAYER_ERR; + } + + return PLAYER_OK; } int -player_play(void) +player_toggle_pause(void) { + if (!mpd_run_toggle_pause(player->conn)) { + PLAYER_STATUS(PLAYER_MSG_ERR, "Pause toggle failed"); + return PLAYER_ERR; + } + return PLAYER_OK; } int player_pause(void) { + if (!mpd_run_pause(player->conn, true)) { + PLAYER_STATUS(PLAYER_MSG_ERR, "Pausing track failed"); + return PLAYER_ERR; + } + + return PLAYER_OK; +} + +int +player_resume(void) +{ + if (!mpd_run_pause(player->conn, false)) { + PLAYER_STATUS(PLAYER_MSG_ERR, "Resuming track failed"); + return PLAYER_ERR; + } + return PLAYER_OK; } int -player_skip(void) +player_next(void) { + if (!mpd_run_next(player->conn)) { + PLAYER_STATUS(PLAYER_MSG_ERR, "Playing next track failed"); + return PLAYER_ERR; + } + return PLAYER_OK; } int player_prev(void) { + if (!mpd_run_previous(player->conn)) { + PLAYER_STATUS(PLAYER_MSG_ERR, "Playing prev track failed"); + return PLAYER_ERR; + } + return PLAYER_OK; } +int +player_seek(int sec) +{ + /* TODO */ + return PLAYER_OK; +} +int +player_set_volume(unsigned int vol) +{ + if (player->volume == -1) { + PLAYER_STATUS(PLAYER_MSG_INFO, "Setting volume not supported"); + return PLAYER_ERR; + } + + if (!mpd_run_set_volume(player->conn, vol)) { + PLAYER_STATUS(PLAYER_MSG_ERR, "Setting volume failed"); + return PLAYER_ERR; + } + return PLAYER_OK; +} + +void +player_clear_msg(void) +{ + free(player->msg); + player->msg = NULL; + player->msglvl = PLAYER_MSG_NONE; +} |
