ref: 3dc0d39b312699a7d4af4e755ca088348305e499
parent: 97c465a910d8e377504b5e06fef136ea68cb798f
author: Sigrid Solveig Haflínudóttir <ftrvxmtrx@gmail.com>
date: Thu Apr 8 07:17:00 EDT 2021
add audio/m4adec
--- /dev/null
+++ b/frontend/aacdec.c
@@ -1,0 +1,212 @@
+/*
+** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
+** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
+**
+** This program is free software; you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation; either version 2 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program; if not, write to the Free Software
+** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+**
+** Any non-GPL usage of this software or parts of this software is strictly
+** forbidden.
+**
+** The "appropriate copyright message" mentioned in section 2c of the GPLv2
+** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
+**
+** Commercial non-GPL licensing of this software is possible.
+** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
+**
+** $Id: main.c,v 1.89 2015/01/19 09:46:12 knik Exp $
+**/
+
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <neaacdec.h>
+
+#define min(a,b) ((a)<=(b)?(a):(b))
+
+#define MAX_CHANNELS 6 /* make this higher to support files with more channels */
+
+/* FAAD file buffering routines */
+typedef struct {
+ long bytes_into_buffer;
+ long bytes_consumed;
+ long file_offset;
+ unsigned char *buffer;
+ int at_eof;
+}aac_buffer;
+
+static Biobuf stdin, stdout;
+
+static int
+fill_buffer(aac_buffer *b)
+{
+ int bread;
+
+ if(b->bytes_consumed > 0){
+ if(b->bytes_into_buffer)
+ memmove(b->buffer, b->buffer + b->bytes_consumed, b->bytes_into_buffer);
+
+ if(!b->at_eof){
+ bread = Bread(&stdin, (void*)(b->buffer + b->bytes_into_buffer), b->bytes_consumed);
+ if(bread != b->bytes_consumed)
+ b->at_eof = 1;
+ b->bytes_into_buffer += bread;
+ }
+
+ b->bytes_consumed = 0;
+
+ if(b->bytes_into_buffer > 3 && memcmp(b->buffer, "TAG", 3) == 0)
+ b->bytes_into_buffer = 0;
+ if(b->bytes_into_buffer > 11 && memcmp(b->buffer, "LYRICSBEGIN", 11) == 0)
+ b->bytes_into_buffer = 0;
+ if(b->bytes_into_buffer > 8 && memcmp(b->buffer, "APETAGEX", 8) == 0)
+ b->bytes_into_buffer = 0;
+ }
+
+ return 1;
+}
+
+static void
+advance_buffer(aac_buffer *b, int bytes)
+{
+ while(b->bytes_into_buffer > 0 && bytes > 0){
+ int chunk = min(bytes, b->bytes_into_buffer);
+
+ bytes -= chunk;
+ b->file_offset += chunk;
+ b->bytes_consumed = chunk;
+ b->bytes_into_buffer -= chunk;
+
+ if(b->bytes_into_buffer == 0)
+ fill_buffer(b);
+ }
+}
+
+static int
+decode(void)
+{
+ NeAACDecHandle hDecoder;
+ NeAACDecFrameInfo frameInfo;
+ NeAACDecConfigurationPtr config;
+ unsigned long samplerate;
+ unsigned char channels;
+ void *sample_buffer;
+ int bread;
+ aac_buffer b;
+
+ memset(&b, 0, sizeof(b));
+ if((b.buffer = malloc(FAAD_MIN_STREAMSIZE*MAX_CHANNELS)) == nil)
+ return -1;
+ memset(b.buffer, 0, FAAD_MIN_STREAMSIZE*MAX_CHANNELS);
+
+ bread = Bread(&stdin, b.buffer, FAAD_MIN_STREAMSIZE*MAX_CHANNELS);
+ b.bytes_into_buffer = bread;
+ b.bytes_consumed = 0;
+ b.file_offset = 0;
+
+ if(bread != FAAD_MIN_STREAMSIZE*MAX_CHANNELS)
+ b.at_eof = 1;
+
+ hDecoder = NeAACDecOpen();
+
+ config = NeAACDecGetCurrentConfiguration(hDecoder);
+ config->defSampleRate = 44100;
+ config->defObjectType = LC;
+ config->outputFormat = FAAD_FMT_16BIT;
+ config->downMatrix = 0;
+ config->useOldADTSFormat = 0;
+ NeAACDecSetConfiguration(hDecoder, config);
+
+ fill_buffer(&b);
+ if((bread = NeAACDecInit(hDecoder, b.buffer, b.bytes_into_buffer, &samplerate, &channels)) < 0){
+ sysfatal("NeAACDecInit failed: %d", bread);
+ if(b.buffer)
+ free(b.buffer);
+ NeAACDecClose(hDecoder);
+ return -1;
+ }
+ advance_buffer(&b, bread);
+ fill_buffer(&b);
+
+ if(samplerate != 44100 || channels != 2){
+ int pfd[2], pid;
+ char fmt[32];
+
+ 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%ld", channels, samplerate);
+ execl("/bin/audio/pcmconv", "pcmconv", "-i", fmt, nil);
+ sysfatal("%r");
+ }
+ close(pfd[1]);
+ Binit(&stdout, pfd[0], OWRITE);
+ }
+
+ for(;;){
+ sample_buffer = NeAACDecDecode(hDecoder, &frameInfo, b.buffer, b.bytes_into_buffer);
+
+ /* update buffer indices */
+ advance_buffer(&b, frameInfo.bytesconsumed);
+
+ if(frameInfo.error != 0)
+ sysfatal("%s: %d", NeAACDecGetErrorMessage(frameInfo.error), frameInfo.error);
+
+ if(frameInfo.samples > 0 && Bwrite(&stdout, sample_buffer, frameInfo.samples*2) != frameInfo.samples*2)
+ break;
+
+ fill_buffer(&b);
+
+ if(b.bytes_into_buffer == 0)
+ break;
+ }
+
+ NeAACDecClose(hDecoder);
+
+ if(b.buffer)
+ free(b.buffer);
+
+ return frameInfo.error;
+}
+
+static void
+usage(void)
+{
+ fprint(2, "usage: %s\n", argv0);
+ exits("usage");
+}
+
+void
+main(int argc, char **argv)
+{
+ int n;
+
+ ARGBEGIN{
+ default:
+ usage();
+ }ARGEND
+
+ Binit(&stdin, 0, OREAD);
+ Binit(&stdout, 1, OWRITE);
+
+ n = decode();
+ Bterm(&stdout);
+ waitpid();
+
+ exits(n == 0 ? nil : "failed");
+}
--- /dev/null
+++ b/frontend/m4adec.rc
@@ -1,0 +1,3 @@
+#!/bin/rc
+rfork ne
+mcfs -t audio $* | audio/aacdec
--- a/frontend/main.c
+++ /dev/null
@@ -1,212 +1,0 @@
-/*
-** FAAD2 - Freeware Advanced Audio (AAC) Decoder including SBR decoding
-** Copyright (C) 2003-2005 M. Bakker, Nero AG, http://www.nero.com
-**
-** This program is free software; you can redistribute it and/or modify
-** it under the terms of the GNU General Public License as published by
-** the Free Software Foundation; either version 2 of the License, or
-** (at your option) any later version.
-**
-** This program is distributed in the hope that it will be useful,
-** but WITHOUT ANY WARRANTY; without even the implied warranty of
-** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-** GNU General Public License for more details.
-**
-** You should have received a copy of the GNU General Public License
-** along with this program; if not, write to the Free Software
-** Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-**
-** Any non-GPL usage of this software or parts of this software is strictly
-** forbidden.
-**
-** The "appropriate copyright message" mentioned in section 2c of the GPLv2
-** must read: "Code from FAAD2 is copyright (c) Nero AG, www.nero.com"
-**
-** Commercial non-GPL licensing of this software is possible.
-** For more info contact Nero AG through Mpeg4AAClicense@nero.com.
-**
-** $Id: main.c,v 1.89 2015/01/19 09:46:12 knik Exp $
-**/
-
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <neaacdec.h>
-
-#define min(a,b) ((a)<=(b)?(a):(b))
-
-#define MAX_CHANNELS 6 /* make this higher to support files with more channels */
-
-/* FAAD file buffering routines */
-typedef struct {
- long bytes_into_buffer;
- long bytes_consumed;
- long file_offset;
- unsigned char *buffer;
- int at_eof;
-}aac_buffer;
-
-static Biobuf stdin, stdout;
-
-static int
-fill_buffer(aac_buffer *b)
-{
- int bread;
-
- if(b->bytes_consumed > 0){
- if(b->bytes_into_buffer)
- memmove(b->buffer, b->buffer + b->bytes_consumed, b->bytes_into_buffer);
-
- if(!b->at_eof){
- bread = Bread(&stdin, (void*)(b->buffer + b->bytes_into_buffer), b->bytes_consumed);
- if(bread != b->bytes_consumed)
- b->at_eof = 1;
- b->bytes_into_buffer += bread;
- }
-
- b->bytes_consumed = 0;
-
- if(b->bytes_into_buffer > 3 && memcmp(b->buffer, "TAG", 3) == 0)
- b->bytes_into_buffer = 0;
- if(b->bytes_into_buffer > 11 && memcmp(b->buffer, "LYRICSBEGIN", 11) == 0)
- b->bytes_into_buffer = 0;
- if(b->bytes_into_buffer > 8 && memcmp(b->buffer, "APETAGEX", 8) == 0)
- b->bytes_into_buffer = 0;
- }
-
- return 1;
-}
-
-static void
-advance_buffer(aac_buffer *b, int bytes)
-{
- while(b->bytes_into_buffer > 0 && bytes > 0){
- int chunk = min(bytes, b->bytes_into_buffer);
-
- bytes -= chunk;
- b->file_offset += chunk;
- b->bytes_consumed = chunk;
- b->bytes_into_buffer -= chunk;
-
- if(b->bytes_into_buffer == 0)
- fill_buffer(b);
- }
-}
-
-static int
-decode(void)
-{
- NeAACDecHandle hDecoder;
- NeAACDecFrameInfo frameInfo;
- NeAACDecConfigurationPtr config;
- unsigned long samplerate;
- unsigned char channels;
- void *sample_buffer;
- int bread;
- aac_buffer b;
-
- memset(&b, 0, sizeof(b));
- if((b.buffer = malloc(FAAD_MIN_STREAMSIZE*MAX_CHANNELS)) == nil)
- return -1;
- memset(b.buffer, 0, FAAD_MIN_STREAMSIZE*MAX_CHANNELS);
-
- bread = Bread(&stdin, b.buffer, FAAD_MIN_STREAMSIZE*MAX_CHANNELS);
- b.bytes_into_buffer = bread;
- b.bytes_consumed = 0;
- b.file_offset = 0;
-
- if(bread != FAAD_MIN_STREAMSIZE*MAX_CHANNELS)
- b.at_eof = 1;
-
- hDecoder = NeAACDecOpen();
-
- config = NeAACDecGetCurrentConfiguration(hDecoder);
- config->defSampleRate = 44100;
- config->defObjectType = LC;
- config->outputFormat = FAAD_FMT_16BIT;
- config->downMatrix = 0;
- config->useOldADTSFormat = 0;
- NeAACDecSetConfiguration(hDecoder, config);
-
- fill_buffer(&b);
- if((bread = NeAACDecInit(hDecoder, b.buffer, b.bytes_into_buffer, &samplerate, &channels)) < 0){
- sysfatal("NeAACDecInit failed: %d", bread);
- if(b.buffer)
- free(b.buffer);
- NeAACDecClose(hDecoder);
- return -1;
- }
- advance_buffer(&b, bread);
- fill_buffer(&b);
-
- if(samplerate != 44100 || channels != 2){
- int pfd[2], pid;
- char fmt[32];
-
- 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%ld", channels, samplerate);
- execl("/bin/audio/pcmconv", "pcmconv", "-i", fmt, nil);
- sysfatal("%r");
- }
- close(pfd[1]);
- Binit(&stdout, pfd[0], OWRITE);
- }
-
- for(;;){
- sample_buffer = NeAACDecDecode(hDecoder, &frameInfo, b.buffer, b.bytes_into_buffer);
-
- /* update buffer indices */
- advance_buffer(&b, frameInfo.bytesconsumed);
-
- if(frameInfo.error != 0)
- sysfatal("%s: %d", NeAACDecGetErrorMessage(frameInfo.error), frameInfo.error);
-
- if(frameInfo.samples > 0 && Bwrite(&stdout, sample_buffer, frameInfo.samples*2) != frameInfo.samples*2)
- break;
-
- fill_buffer(&b);
-
- if(b.bytes_into_buffer == 0)
- break;
- }
-
- NeAACDecClose(hDecoder);
-
- if(b.buffer)
- free(b.buffer);
-
- return frameInfo.error;
-}
-
-static void
-usage(void)
-{
- fprint(2, "usage: %s\n", argv0);
- exits("usage");
-}
-
-void
-main(int argc, char **argv)
-{
- int n;
-
- ARGBEGIN{
- default:
- usage();
- }ARGEND
-
- Binit(&stdin, 0, OREAD);
- Binit(&stdout, 1, OWRITE);
-
- n = decode();
- Bterm(&stdout);
- waitpid();
-
- exits(n == 0 ? nil : "failed");
-}
--- a/frontend/mkfile
+++ b/frontend/mkfile
@@ -1,14 +1,15 @@
</$objtype/mkfile
-TARG=aacdec
+TARG=\
+ aacdec\
+ m4adec\
+
CFLAGS=$CFLAGS -I../include -p -D__plan9__
BIN=/$objtype/bin/audio
-HFILES=\
+default:V: all
-OFILES=\
- main.$O\
+</sys/src/cmd/mkmany
-default:V: all
-
-</sys/src/cmd/mkone
+m4adec.install:V: m4adec.rc
+ cp m4adec.rc $BIN/m4adec