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)
|
SRCS := $(wildcard $(SRC_DIR)/*.c)
|
||||||
OBJS := $(patsubst $(SRC_DIR)/%.c,$(BUILD)/%.o,$(SRCS))
|
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)
|
CFLAGS += $(shell pkg-config --cflags libavformat libavcodec libavutil libswresample alsa)
|
||||||
|
|
||||||
LDFLAGS := $(shell pkg-config --libs 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;
|
AVPacket *pkt;
|
||||||
AVFrame *frm;
|
AVFrame *frm;
|
||||||
int stream;
|
int stream;
|
||||||
int64_t duration_samples;
|
int64_t duration_frames;
|
||||||
int64_t played_samples;
|
int64_t played_frames;
|
||||||
int eof;
|
int eof;
|
||||||
} Decoder;
|
} Decoder;
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ static int decoder_open(Decoder *d, const char *path) {
|
|||||||
swr_init(d->swr);
|
swr_init(d->swr);
|
||||||
|
|
||||||
if (s->duration != AV_NOPTS_VALUE)
|
if (s->duration != AV_NOPTS_VALUE)
|
||||||
d->duration_samples =
|
d->duration_frames =
|
||||||
av_rescale_q(s->duration, s->time_base, (AVRational){1, OUT_RATE});
|
av_rescale_q(s->duration, s->time_base, (AVRational){1, OUT_RATE});
|
||||||
|
|
||||||
d->pkt = av_packet_alloc();
|
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) {
|
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,
|
swr_convert(d->swr, out, max_samples, (const uint8_t **)d->frm->data,
|
||||||
d->frm->nb_samples);
|
d->frm->nb_samples);
|
||||||
d->played_samples += samples;
|
d->played_frames += frames;
|
||||||
return samples;
|
return frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (d->eof)
|
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);
|
av_samples_alloc(&buf, &linesize, OUT_CHANNELS, max_samples, OUT_FORMAT, 1);
|
||||||
|
|
||||||
while (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) {
|
if (!next_loaded && cur.duration_frames &&
|
||||||
snd_pcm_writei(pcm, buf, samples);
|
cur.duration_frames - cur.played_frames < PRELOAD_SEC * OUT_RATE &&
|
||||||
}
|
|
||||||
|
|
||||||
if (!next_loaded && cur.duration_samples &&
|
|
||||||
cur.duration_samples - cur.played_samples < PRELOAD_SEC * OUT_RATE &&
|
|
||||||
track < argc) {
|
track < argc) {
|
||||||
decoder_open(&next, argv[track++]);
|
decoder_open(&next, argv[track++]);
|
||||||
next_loaded = 1;
|
next_loaded = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (samples < max_samples && cur.eof) {
|
if (cur.eof) {
|
||||||
if (next_loaded) {
|
if (next_loaded) {
|
||||||
decoder_close(&cur);
|
decoder_close(&cur);
|
||||||
cur = next;
|
cur = next;
|
||||||
memset(&next, 0, sizeof(next));
|
memset(&next, 0, sizeof(next));
|
||||||
next_loaded = 0;
|
next_loaded = 0;
|
||||||
int samples_needed = max_samples - samples;
|
int samples_needed = max_samples - samples + 1;
|
||||||
samples = decode_pcm(&cur, &buf, samples_needed);
|
frames = decode_pcm(&cur, &buf, samples_needed);
|
||||||
printf("yo read %d samples\n", samples);
|
samples = frames * OUT_CHANNELS * 2;
|
||||||
if (samples > 0) {
|
printf("yo read %d frames\n", frames);
|
||||||
snd_pcm_writei(pcm, buf, samples);
|
if (frames > 0) {
|
||||||
|
memcpy(outbuffer+outbuffer_frames * OUT_CHANNELS * 2, buf, samples);
|
||||||
|
outbuffer_frames += frames;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
snd_pcm_writei(pcm, outbuffer, outbuffer_frames);
|
||||||
}
|
}
|
||||||
|
|
||||||
snd_pcm_drain(pcm);
|
snd_pcm_drain(pcm);
|
||||||
|
|||||||
Reference in New Issue
Block a user