make gapless a bit better (dont think its perfect sadly)

This commit is contained in:
William Bell
2025-12-28 01:01:28 +00:00
parent 3250a97cca
commit 5e65e4d932
2 changed files with 26 additions and 20 deletions

View File

@@ -6,7 +6,7 @@ BUILD := build
SRCS := $(wildcard $(SRC_DIR)/*.c)
OBJS := $(patsubst $(SRC_DIR)/%.c,$(BUILD)/%.o,$(SRCS))
CFLAGS := -Wall -Wextra -O3
CFLAGS := -Wall -Wextra -g
CFLAGS += $(shell pkg-config --cflags libavformat libavcodec libavutil libswresample alsa)
LDFLAGS := $(shell pkg-config --libs libavformat libavcodec libavutil libswresample alsa)

View File

@@ -22,8 +22,8 @@ typedef struct {
AVPacket *pkt;
AVFrame *frm;
int stream;
int64_t duration_samples;
int64_t played_samples;
int64_t duration_frames;
int64_t played_frames;
int eof;
} Decoder;
@@ -65,7 +65,7 @@ static int decoder_open(Decoder *d, const char *path) {
swr_init(d->swr);
if (s->duration != AV_NOPTS_VALUE)
d->duration_samples =
d->duration_frames =
av_rescale_q(s->duration, s->time_base, (AVRational){1, OUT_RATE});
d->pkt = av_packet_alloc();
@@ -99,11 +99,11 @@ static int decode_pcm(Decoder *d, uint8_t **out, int max_samples) {
}
if (avcodec_receive_frame(d->dec, d->frm) == 0) {
int samples =
int frames =
swr_convert(d->swr, out, max_samples, (const uint8_t **)d->frm->data,
d->frm->nb_samples);
d->played_samples += samples;
return samples;
d->played_frames += frames;
return frames;
}
if (d->eof)
@@ -137,35 +137,41 @@ int main(int argc, char **argv) {
av_samples_alloc(&buf, &linesize, OUT_CHANNELS, max_samples, OUT_FORMAT, 1);
while (1) {
int samples = decode_pcm(&cur, &buf, max_samples);
uint8_t outbuffer[max_samples*2];
int outbuffer_frames = 0;
// memset(outbuffer, 0, max_samples);
int frames = decode_pcm(&cur, &buf, max_samples);
int samples = frames * OUT_CHANNELS * 2;
memcpy(outbuffer, buf, samples);
outbuffer_frames += frames;
if (samples > 0) {
snd_pcm_writei(pcm, buf, samples);
}
if (!next_loaded && cur.duration_samples &&
cur.duration_samples - cur.played_samples < PRELOAD_SEC * OUT_RATE &&
if (!next_loaded && cur.duration_frames &&
cur.duration_frames - cur.played_frames < PRELOAD_SEC * OUT_RATE &&
track < argc) {
decoder_open(&next, argv[track++]);
next_loaded = 1;
}
if (samples < max_samples && cur.eof) {
if (cur.eof) {
if (next_loaded) {
decoder_close(&cur);
cur = next;
memset(&next, 0, sizeof(next));
next_loaded = 0;
int samples_needed = max_samples - samples;
samples = decode_pcm(&cur, &buf, samples_needed);
printf("yo read %d samples\n", samples);
if (samples > 0) {
snd_pcm_writei(pcm, buf, samples);
int samples_needed = max_samples - samples + 1;
frames = decode_pcm(&cur, &buf, samples_needed);
samples = frames * OUT_CHANNELS * 2;
printf("yo read %d frames\n", frames);
if (frames > 0) {
memcpy(outbuffer+outbuffer_frames * OUT_CHANNELS * 2, buf, samples);
outbuffer_frames += frames;
}
continue;
}
break;
}
snd_pcm_writei(pcm, outbuffer, outbuffer_frames);
}
snd_pcm_drain(pcm);