make gapless a bit better (dont think its perfect sadly)
This commit is contained in:
2
Makefile
2
Makefile
@@ -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)
|
||||
|
||||
44
src/main.c
44
src/main.c
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user