map

minimalist audio player
git clone https://git.porkepik.fr/map
Log | Files | Refs | README | LICENSE

commit a31ac5398ee890c2825eb50b87e5764352d1f5e5
parent 5366291d5ef79b8797175100ec1483f2670fc87a
Author: Thomas Philippe <dev@porkepik.fr>
Date:   Tue, 19 May 2020 05:46:36 +0200

gapless playblack

Diffstat:
Mmap.c | 77++++++++++++++++++++++++++++++++++++++++++++++++++++-------------------------
Msndio.c | 30++++++++++++++++++------------
2 files changed, 70 insertions(+), 37 deletions(-)

diff --git a/map.c b/map.c @@ -43,7 +43,6 @@ char poll_key_event(void); int sndio_init(void); int sndio_open(int, int, int); int sndio_play(void *, int); -void sndio_stop(void); void sndio_close(void); /* flac.c */ @@ -76,10 +75,12 @@ print_cursor(int oldx, int newx) static void print_playlist(struct track **tracks, int start_index) { + int i; + set_cursor(rows - 3, 1); write_term("\x1b[1J"); - for (int i = start_index; i < start_index + rows - 5; i++) { + for (i = start_index; i < start_index + rows - 5; i++) { if (i == ntracks) break; set_cursor(i - start_index + 1, 7); @@ -203,29 +204,28 @@ opentrack(struct track *track) return buf_size; } -static int -playtrack(struct track curtrack, struct player player, int trackid) +static void +play(struct player player) { - static int cursorid = 1, toptrack = 0; - int timersec = 0; - long done, buf_size; - long *buffer; - time_t start, pausetime = 0; - + int trackid = 0, cursorid = 1, toptrack, timersec; + int gapless = 0; + long done, buf_size, tempbuf_len; + long *buffer, *newbuf; + time_t start, pausetime; + struct track curtrack; + + while (trackid < ntracks) { +next: + pausetime = toptrack = timersec = 0; start = time(NULL); + + curtrack = *player.tracks[trackid]; buf_size = opentrack(&curtrack); + if (!gapless) + buffer = malloc(buf_size * sizeof(long)); print_info(player.curdir, curtrack); - buffer = malloc(buf_size * sizeof(long)); do { - if(get_term_size(&rows, &cols)) { - clear_term(); - print_playlist(player.tracks, 0); - cursorid = 1; - toptrack = 0; - print_info(player.curdir, curtrack); - } - switch (poll_key_event()) { /* cursor move */ case 'j': @@ -287,13 +287,36 @@ playtrack(struct track curtrack, struct player player, int trackid) goto endtrack; } + if(get_term_size(&rows, &cols)) { + clear_term(); + print_playlist(player.tracks, 0); + cursorid = 1; + toptrack = 0; + print_info(player.curdir, curtrack); + } + if (pausetime) { print_pause(); usleep(10 * 1000); continue; } - done = curtrack.decode(buffer, buf_size); + if (!gapless) { + done = curtrack.decode(buffer, buf_size); + if (trackid+1 < ntracks && done < buf_size / 2) { + tempbuf_len = done * 2; + gapless = 1; + curtrack.close(); + trackid++; + goto next; + } + } else { + newbuf = malloc((buf_size - tempbuf_len) * sizeof(long)); + done = curtrack.decode(newbuf, buf_size - tempbuf_len); + memcpy(buffer + tempbuf_len, newbuf, (buf_size - tempbuf_len) * sizeof(long)); + free(newbuf); + gapless = 0; + } if (done < 0 || sndio_play(buffer, done) < 0) { sndio_close(); curtrack.close(); @@ -307,15 +330,14 @@ playtrack(struct track curtrack, struct player player, int trackid) curtrack.close(); trackid++; endtrack: - sndio_stop(); free(buffer); - return trackid; + } } int main(int argc, char **argv) { - int trackid = 0; + int i; struct player player; if (argc > 1) @@ -332,11 +354,16 @@ main(int argc, char **argv) if (sndio_init() < 0) errx(1, "Could not initialize sndio.\n"); - while (trackid < ntracks) - trackid = playtrack(*player.tracks[trackid], player, trackid); + play(player); sndio_close(); end_term(); + for (i = 0; i < ntracks; i++) { + free(player.tracks[i]->filename); + free(player.tracks[i]->name); + free(player.tracks[i]); + } + free(player.tracks); return 0; } diff --git a/sndio.c b/sndio.c @@ -3,6 +3,8 @@ static struct sio_hdl *hdl; static int framesize; +static int sndio_started; + int sndio_vol(long vol) @@ -18,14 +20,24 @@ sndio_init(void) hdl = sio_open(SIO_DEVANY, SIO_PLAY, 0); if (!hdl) return -1; + sndio_started = 0; return 0; } int sndio_open(int bits, int rate, int channels) { - struct sio_par par; - int buf_size; + static struct sio_par par; + static int buf_size; + + if (sndio_started) { + if (bits != par.bits || rate != par.rate || + channels != par.pchan) { + sio_stop(hdl); + } else { + return buf_size; + } + } sio_initpar(&par); par.bits = bits; @@ -37,12 +49,13 @@ sndio_open(int bits, int rate, int channels) if (!sio_setpar(hdl, &par) || !sio_getpar(hdl, &par)) goto err0; - buf_size = (0.1 * par.rate) + par.round - 1; - buf_size -= buf_size % par.round; - if (!sio_start(hdl)) goto err0; + sndio_started = 1; + buf_size = (0.1 * par.rate) + par.round - 1; + buf_size -= buf_size % par.round; + return buf_size; err0: sio_close(hdl); @@ -57,13 +70,6 @@ sndio_play(void *buf, size_t nframes) } void -sndio_stop(void) -{ - if (hdl) - sio_stop(hdl); -} - -void sndio_close(void) { if (hdl)