diff --git a/Makefile b/Makefile index 577489b..55a7538 100644 --- a/Makefile +++ b/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) diff --git a/src/main.c b/src/main.c index 01cf7ca..56b0f1b 100644 --- a/src/main.c +++ b/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);