map

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

commit da7222f4e222f0a74eab06a3d22f2c2fc9d6b3f3
parent cd18d494d2f9ecf39183bf8774acbf96384125d1
Author: Thomas Philippe <dev@porkepik.fr>
Date:   Wed,  9 Sep 2020 17:04:16 +0200

change decoding file naming

Diffstat:
MMakefile | 2+-
MREADME | 2+-
Adecoding.c | 89+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Dflac.c | 83-------------------------------------------------------------------------------
Mmap.c | 81++++++++++++++++++++++++++++++-------------------------------------------------
Dmp3.c | 38--------------------------------------
Dsndio.c | 92-------------------------------------------------------------------------------
7 files changed, 122 insertions(+), 265 deletions(-)

diff --git a/Makefile b/Makefile @@ -2,7 +2,7 @@ PREFIX = /usr/local CFLAGS = -O2 -std=c99 -D_DEFAULT_SOURCE -Wall LDLIBS = -lasound -lsndfile -OBJ = alsa.o flac.o map.o mp3.o term.o +OBJ = alsa.o decoding.o map.o term.o BIN = map $(BIN): $(OBJ) diff --git a/README b/README @@ -2,7 +2,7 @@ map - minimalist audio player ============================= ALSA only. -Supports FLAC (dr_flac) and MP3 (dr_mp3). +Requires sndfile for decoding. controls -------- diff --git a/decoding.c b/decoding.c @@ -0,0 +1,89 @@ +#include <sys/select.h> +#include <err.h> +#include <limits.h> +#include <stdio.h> +#include <sndfile.h> + +static SNDFILE *sf; +static SF_INFO sfinfo; + +int +open_file(const char *filename, int *bits, int *rate, int *channels) +{ + sf = sf_open(filename, SFM_READ, &sfinfo); + if (!sf) { + warnx("sf_open_fd: failed"); + return -1; + } + + switch (sfinfo.format & 0xff) { + case SF_FORMAT_PCM_16: + *bits = 16; + break; + case SF_FORMAT_PCM_24: + *bits = 24; + break; + case SF_FORMAT_PCM_32: + *bits = 32; + break; + default: + warnx("sfinfo: unsupported format"); + goto err0; + } + + *rate = sfinfo.samplerate; + *channels = sfinfo.channels; + + return sfinfo.frames / sfinfo.samplerate; +err0: + sf_close(sf); + sf = NULL; + return -1; +} + +const char * +get_title(void) +{ + return sf_get_string(sf, SF_STR_TITLE); +} + +const char * +get_artist(void) +{ + return sf_get_string(sf, SF_STR_ARTIST); +} + +const char * +get_album(void) +{ + return sf_get_string(sf, SF_STR_ALBUM); +} + +void +seek(int sec) +{ + int offset = sfinfo.samplerate * sec; + sf_seek(sf, offset, SEEK_CUR); +} + +int +decode(void *buf, int nitems) +{ + return sf_read_float(sf, buf, nitems); +} + +int +close_file(void) +{ + int r = 0; + + if (sf) { + r = sf_close(sf); + if (r != 0) { + warnx("sf_close: failed"); + r = -1; + } + } + sf = NULL; + return r; +} diff --git a/flac.c b/flac.c @@ -1,83 +0,0 @@ -#include <sys/select.h> -#include <err.h> -#include <limits.h> -#include <stdio.h> -#include <sndfile.h> - -static SNDFILE *sf; -static SF_INFO sfinfo; - -int -flac_open(const char *filename, int *bits, int *rate, int *channels) -{ - sf = sf_open(filename, SFM_READ, &sfinfo); - if (!sf) { - warnx("sf_open_fd: failed"); - return -1; - } - - switch (sfinfo.format & 0xff) { - case SF_FORMAT_PCM_16: - *bits = 16; - break; - case SF_FORMAT_PCM_24: - *bits = 24; - break; - case SF_FORMAT_PCM_32: - *bits = 32; - break; - default: - warnx("sfinfo: unsupported format"); - goto err0; - } - - *rate = sfinfo.samplerate; - *channels = sfinfo.channels; - - return sfinfo.frames / sfinfo.samplerate; -err0: - sf_close(sf); - sf = NULL; - return -1; -} - -const char * -flac_artist(void) -{ - return sf_get_string(sf, SF_STR_ARTIST); -} - -const char * -flac_album(void) -{ - return sf_get_string(sf, SF_STR_ALBUM); -} - -void -flac_seek(int sec) -{ - int offset = sfinfo.samplerate * sec; - sf_seek(sf, offset, SEEK_CUR); -} - -int -flac_decode(void *buf, int nitems) -{ - return sf_read_float(sf, buf, nitems); -} - -int -flac_close(void) -{ - int r = 0; - - if (sf) { - r = sf_close(sf); - if (r != 0) { - warnx("sf_close: failed"); - r = -1; - } - } - sf = NULL; - return r; -} diff --git a/map.c b/map.c @@ -19,16 +19,13 @@ struct track { char *filename; - char *title; + char *name; + const char *title; const char *artist; const char *album; char *format; int length; int current; - int (*open)(const char *, int *, int *, int *); - long (*decode)(void *, int); - void (*seek)(int); - void (*close)(void); }; @@ -48,19 +45,14 @@ int alsa_open(int, int, int); int alsa_play(void *, int); void alsa_close(void); -/* flac.c */ -int flac_open(const char *, int *, int *, int *); -const char * flac_artist(void); -const char * flac_album(void); -long flac_decode(void *, int); -void flac_seek(int); -void flac_close(void); - -/* mp3.c */ -int mp3_open(const char *, int *, int *, int *); -long mp3_decode(void *, int); -void mp3_seek(int); -void mp3_close(void); +/* decoding.c */ +int open_file(const char *, int *, int *, int *); +const char * get_title(void); +const char * get_artist(void); +const char * get_album(void); +long decode(void *, int); +void seek(int); +void close_file(void); static int rows; @@ -92,9 +84,9 @@ print_playlist(struct track **tracks, int start_index, int cursorid) break; set_cursor(i - start_index + 1, 7); if (tracks[i]->current) - write_term("\x1b[1K\x1b[1m%s\x1b[0m", tracks[i]->title); + write_term("\x1b[1K\x1b[1m%s\x1b[0m", tracks[i]->name); else - write_term("\x1b[1K%s", tracks[i]->title); + write_term("\x1b[1K%s", tracks[i]->name); } print_cursor(cursorid, cursorid); } @@ -164,26 +156,15 @@ init_track(const char *path, const char *filename) strcat(tmp->filename, "/"); strcat(tmp->filename, filename); - if (strend(tmp->filename, ".mp3")) { - tmp->open = mp3_open; - tmp->decode = mp3_decode; - tmp->seek = mp3_seek; - tmp->close = mp3_close; - tmp->format = "MP3"; - } else if (strend(tmp->filename, ".flac")) { - tmp->open = flac_open; - tmp->decode = flac_decode; - tmp->seek = flac_seek; - tmp->close = flac_close; + if (strend(tmp->filename, ".flac")) tmp->format = "FLAC"; - } - tmp->title = malloc(strlen(strrchr(tmp->filename, '/'))); - if (!tmp->title) + tmp->name = malloc(strlen(strrchr(tmp->filename, '/'))); + if (!tmp->name) errx(1, "malloc failure"); - strcpy(tmp->title, strrchr(tmp->filename, '/') + 1); - if ((extension = strrchr(tmp->title, '.') - tmp->title)) - tmp->title[extension] = '\0'; + strcpy(tmp->name, strrchr(tmp->filename, '/') + 1); + if ((extension = strrchr(tmp->name, '.') - tmp->name)) + tmp->name[extension] = '\0'; return tmp; } @@ -205,8 +186,7 @@ get_tracks(const char *path) return; } while ((dir = readdir(d))) { - if (!strend(dir->d_name, ".flac") && - !strend(dir->d_name, ".mp3")) + if (!strend(dir->d_name, ".flac")) continue; tracks = realloc(tracks, sizeof(struct track *) * (ntracks+1)); tracks[ntracks++] = init_track(path, dir->d_name); @@ -241,13 +221,14 @@ opentrack(struct track *track) int bits, channels, rate; long bufsize; - track->length = track->open(track->filename, &bits, &rate, &channels); + track->length = open_file(track->filename, &bits, &rate, &channels); if (track->length < 0) errx(1, "failed opening: %s", track->filename); if (strcmp(track->format, "FLAC") == 0) { - track->artist = flac_artist(); - track->album = flac_album(); + track->title = get_title(); + track->artist = get_artist(); + track->album = get_album(); } if (alsa_open(bits, rate, channels) < 0) @@ -328,7 +309,7 @@ next: break; /* rewind */ case 'h': - curtrack.seek(SEEK_SEC * -1); + seek(SEEK_SEC * -1); if (timersec >= SEEK_SEC) start += SEEK_SEC; else @@ -351,7 +332,7 @@ next: break; /* skip */ case 'l': - curtrack.seek(SEEK_SEC); + seek(SEEK_SEC); start -= SEEK_SEC; break; /* quit */ @@ -376,18 +357,18 @@ next: } if (!gapless) { - done = curtrack.decode(buf, bufsize); + done = decode(buf, bufsize); if (trackid+1 < ntracks && done < bufsize) { tmpbuf_len = done; gapless = 1; - curtrack.close(); + close_file(); tracks[trackid]->current = 0; trackid++; goto next; } } else { newbuf = malloc((bufsize - tmpbuf_len) * sizeof(float)); - done = curtrack.decode(newbuf, bufsize - tmpbuf_len); + done = decode(newbuf, bufsize - tmpbuf_len); memcpy(buf + tmpbuf_len, newbuf, done * sizeof(float)); free(newbuf); gapless = 0; @@ -395,7 +376,7 @@ next: if (done < 0 || (done = alsa_play(buf, done)) < 0) { alsa_close(); - curtrack.close(); + close_file(); errx(1, "Error during decoding."); } @@ -405,7 +386,7 @@ next: trackid++; endtrack: - curtrack.close(); + close_file(); free(buf); } } @@ -435,7 +416,7 @@ main(int argc, char **argv) clear_term(); for (i = 0; i < ntracks; i++) { free(tracks[i]->filename); - free(tracks[i]->title); + free(tracks[i]->name); free(tracks[i]); } free(tracks); diff --git a/mp3.c b/mp3.c @@ -1,38 +0,0 @@ -#define DR_MP3_IMPLEMENTATION -#include "ext/dr_mp3.h" - -static drmp3 mp3; - -int -mp3_open(const char *filename, int *bits, int *rate, int *channels) -{ - if (!drmp3_init_file(&mp3, filename, NULL)) - return -1; - - *bits = 16; - *rate = mp3.sampleRate; - *channels = mp3.channels; - - return drmp3_get_pcm_frame_count(&mp3) / mp3.sampleRate; -} - -long -mp3_decode(void *buf, int nbytes) -{ - return drmp3_read_pcm_frames_s16(&mp3, nbytes / mp3.channels, buf); -} - -void -mp3_seek(int sec) -{ - long frame_index = mp3.currentPCMFrame + sec * (int) mp3.sampleRate; - if (frame_index < 0) - frame_index = 0; - drmp3_seek_to_pcm_frame(&mp3, frame_index); -} - -void -mp3_close(void) -{ - drmp3_uninit(&mp3); -} diff --git a/sndio.c b/sndio.c @@ -1,92 +0,0 @@ -#include <err.h> -#include <stdio.h> -#include <sndio.h> - -#define PCT_TO_SIO(pct) ((127 * (pct) + 50) / 100) - -static struct sio_hdl *hdl; -static int framesize; -static int sndio_started; - - -int -sndio_vol(int vol) -{ - if (!sio_setvol(hdl, PCT_TO_SIO(vol))) - return -1; - return 0; -} - -int -sndio_init(int vol) -{ - hdl = sio_open(SIO_DEVANY, SIO_PLAY, 0); - if (!hdl) - return -1; - sndio_vol(vol); - sndio_started = 0; - return 0; -} - -int -sndio_open(int bits, int rate, int channels) -{ - 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; - par.bps = SIO_BPS(bits); - par.rate = rate; - par.pchan = channels; - par.sig = 1; - par.le = SIO_LE_NATIVE; - framesize = par.bps * par.pchan; - - if (!sio_setpar(hdl, &par) || !sio_getpar(hdl, &par)) - goto err0; - if (par.bits != bits) - errx(1, "could not set proper precision"); - if (par.pchan != channels) - errx(1, "could not set proper number of channels"); - if (par.rate != rate) - errx(1, "could not set proper rate"); - if (par.sig != 1 || par.le != SIO_LE_NATIVE) - errx(1, "could not set proper format"); - - 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); - hdl = NULL; - return -1; -} - -int -sndio_play(void *buf, size_t nframes) -{ - return sio_write(hdl, buf, nframes * framesize); -} - -void -sndio_close(void) -{ - if (hdl) - sio_close(hdl); - hdl = NULL; -}