shithub: mp3dec

Download patch

ref: 2856fedf8c917aecfbd935a41462a8646725d5db
parent: bfe8732f47fcaffc1450251df0f9cb44c7fca916
author: Sigrid Haflínudóttir <ftrvxmtrx@gmail.com>
date: Wed Sep 23 07:09:11 EDT 2020

plan 9 port; audio/mp3dec drop-in replacement

--- a/.gitignore
+++ b/.gitignore
@@ -4,4 +4,6 @@
 minimp3_arm
 *.gcda
 *.gcno
-*.gcov
\ No newline at end of file
+*.gcov
+[a0125678vqki].out
+*.[o0125678vqki]
--- a/minimp3.h
+++ b/minimp3.h
@@ -6,7 +6,18 @@
     This software is distributed without any warranty.
     See <http://creativecommons.org/publicdomain/zero/1.0/>.
 */
+#ifdef __plan9__
+typedef u8int uint8_t;
+typedef s16int int16_t;
+typedef u16int uint16_t;
+typedef s32int int32_t;
+typedef u32int uint32_t;
+typedef u64int uint64_t;
+typedef usize size_t;
+#define NULL nil
+#else
 #include <stdint.h>
+#endif
 
 #define MINIMP3_MAX_SAMPLES_PER_FRAME (1152*2)
 
@@ -43,8 +54,10 @@
 #if defined(MINIMP3_IMPLEMENTATION) && !defined(_MINIMP3_IMPLEMENTATION_GUARD)
 #define _MINIMP3_IMPLEMENTATION_GUARD
 
+#ifndef __plan9__
 #include <stdlib.h>
 #include <string.h>
+#endif
 
 #define MAX_FREE_FORMAT_FRAME_SIZE  2304    /* more than ISO spec's */
 #ifndef MAX_FRAME_SYNC_MATCHES
@@ -762,7 +775,7 @@
     static const int16_t tabindex[2*16] = { 0,32,64,98,0,132,180,218,292,364,426,538,648,746,0,1126,1460,1460,1460,1460,1460,1460,1460,1460,1842,1842,1842,1842,1842,1842,1842,1842 };
     static const uint8_t g_linbits[] =  { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,6,8,10,13,4,5,6,7,8,9,11,13 };
 
-#define PEEK_BITS(n)  (bs_cache >> (32 - n))
+#define PEEK_BITS(n)  (int)(bs_cache >> (32 - n))
 #define FLUSH_BITS(n) { bs_cache <<= (n); bs_sh += (n); }
 #define CHECK_BITS    while (bs_sh >= 0) { bs_cache |= (uint32_t)*bs_next_ptr++ << bs_sh; bs_sh -= 8; }
 #define BSPOS         ((bs_next_ptr - bs->buf)*8 - 24 + bs_sh)
--- a/minimp3_ex.h
+++ b/minimp3_ex.h
@@ -129,7 +129,11 @@
 #endif /*MINIMP3_EXT_H*/
 
 #ifdef MINIMP3_IMPLEMENTATION
+#ifdef __plan9__
+#define INT_MAX 0x7fffffff
+#else
 #include <limits.h>
+#endif
 
 static void mp3dec_skip_id3v1(const uint8_t *buf, size_t *pbuf_size)
 {
@@ -1197,7 +1201,7 @@
     if (!file)
         return MP3D_E_IOERROR;
     int res = MP3D_E_IOERROR;
-    long size = -1;
+    long size;
     if (fseek(file, 0, SEEK_END))
         goto error;
     size = ftell(file);
--- /dev/null
+++ b/mkfile
@@ -1,0 +1,16 @@
+</$objtype/mkfile
+
+TARG=mp3dec
+CFLAGS=$CFLAGS -p -D__plan9__
+BIN=/$objtype/bin/audio
+
+HFILES=\
+	minimp3.h\
+	minimp3_ex.h\
+
+OFILES=\
+	mp3dec.$O\
+
+default:V: all
+
+</sys/src/cmd/mkone
--- /dev/null
+++ b/mp3dec.c
@@ -1,0 +1,93 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#define MINIMP3_IMPLEMENTATION
+#include "minimp3_ex.h"
+
+static int noseek;
+static Biobuf in;
+static uchar inb[MINIMP3_BUF_SIZE];
+
+static size_t
+readcb(void *buf, size_t size, void *)
+{
+	int n;
+	n = Bread(&in, buf, size);
+	return n > 0 ? n : 0;
+}
+
+static int
+seekcb(uint64_t position, void *)
+{
+	if(!noseek)
+		Bseek(&in, position, 0);
+	return 0;
+}
+
+static void
+usage(void)
+{
+	fprint(2, "usage: %s [ -s SECONDS ]\n", argv0);
+	exits("usage");
+}
+
+static mp3dec_ex_t dec;
+static mp3dec_io_t io = {
+	.read = readcb,
+	.seek = seekcb,
+};
+static mp3d_sample_t buf[2*4410];
+
+void
+main(int argc, char **argv)
+{
+	size_t n;
+	double seekto;
+	int out, pfd[2], pid;
+	char fmt[32];
+
+	seekto = 0.0;
+	ARGBEGIN{
+	case 's':
+		seekto = atof(EARGF(usage()));
+		break;
+	default:
+		usage();
+	}ARGEND
+
+	if(Binits(&in, 0, OREAD, inb, sizeof(inb)) != 0)
+		sysfatal("Binits");
+	noseek = Bseek(&in, 0, 2) < 0;
+	if(!noseek)
+		Bseek(&in, 0, 0);
+	if(mp3dec_ex_open_cb(&dec, &io, MP3D_SEEK_TO_SAMPLE|MP3D_DO_NOT_SCAN) != 0)
+		sysfatal("mp3dec_ex_open_cb");
+	if(seekto != 0.0)
+		fprint(2, "time: %g\n", (noseek || mp3dec_ex_seek(&dec, seekto*dec.info.channels*dec.info.hz) != 0) ? 0.0 : seekto);
+
+	out = 1;
+	if(dec.info.channels != 2 || dec.info.hz != 44100){
+		pid = -1;
+		if(pipe(pfd) < 0 || (pid = fork()) < 0)
+			sysfatal("%r");
+		if(pid == 0){
+			dup(pfd[1], 0);
+			close(pfd[1]);
+			close(pfd[0]);
+			snprint(fmt, sizeof(fmt), "s16c%dr%d", dec.info.channels, dec.info.hz);
+			execl("/bin/audio/pcmconv", "pcmconv", "-i", fmt, nil);
+			sysfatal("%r");
+		}
+		close(1);
+		close(pfd[1]);
+		out = pfd[0];
+	}
+
+	while((n = mp3dec_ex_read(&dec, buf, nelem(buf))) > 0)
+		write(out, buf, n*sizeof(buf[0]));
+	Bterm(&in);
+	close(out);
+	mp3dec_ex_close(&dec);
+
+	exits(nil);
+}