ref: d26591730d2b04b21ca6533c2635225dd67a043f
parent: bbe899330f463fc1fc79ab8af93327dc4e4e7908
author: Sigrid Haflínudóttir <ftrvxmtrx@gmail.com>
date: Thu Sep 10 13:44:07 EDT 2020
frontend: provide audio/aacdec
--- a/frontend/Makefile.am
+++ /dev/null
@@ -1,10 +1,0 @@
-bin_PROGRAMS = faad
-dist_man1_MANS = faad.man
-
-AM_CPPFLAGS = -I$(top_srcdir)/include
-
-faad_LDADD = $(top_builddir)/libfaad/libfaad.la
-
-faad_SOURCES = mp4read.c audio.c main.c audio.h mp4read.h unicode_support.c unicode_support.h
-
-EXTRA_faad_SOURCES = getopt.c getopt.h
--- a/frontend/audio.c
+++ /dev/null
@@ -1,510 +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: audio.c,v 1.30 2015/01/22 09:40:52 knik Exp $
-**/
-
-#ifdef _WIN32
-#include <io.h>
-#endif
-
-#ifdef __plan9__
-#include <u.h>
-#include <libc.h>
-typedef s32int int32_t;
-#else
-#include <stdlib.h>
-#include <fcntl.h>
-#include <math.h>
-#include <stdint.h>
-#endif
-#include <stdio.h>
-#include "unicode_support.h"
-#include <neaacdec.h>
-
-#include "audio.h"
-
-
-audio_file *open_audio_file(char *infile, int samplerate, int channels,
- int outputFormat, int fileType, long channelMask)
-{
- audio_file *aufile = malloc(sizeof(audio_file));
-
- aufile->outputFormat = outputFormat;
-
- aufile->samplerate = samplerate;
- aufile->channels = channels;
- aufile->total_samples = 0;
- aufile->fileType = fileType;
- aufile->channelMask = channelMask;
-
- switch (outputFormat)
- {
- case FAAD_FMT_16BIT:
- aufile->bits_per_sample = 16;
- break;
- case FAAD_FMT_24BIT:
- aufile->bits_per_sample = 24;
- break;
- case FAAD_FMT_32BIT:
- case FAAD_FMT_FLOAT:
- aufile->bits_per_sample = 32;
- break;
- default:
- if (aufile) free(aufile);
- return NULL;
- }
-
- if(infile[0] == '-')
- {
-#ifdef _WIN32
- _setmode(_fileno(stdout), O_BINARY);
-#endif
- aufile->sndfile = stdout;
- aufile->toStdio = 1;
- } else {
- aufile->toStdio = 0;
- aufile->sndfile = faad_fopen(infile, "wb");
- }
-
- if (aufile->sndfile == NULL)
- {
- if (aufile) free(aufile);
- return NULL;
- }
-
- if (aufile->fileType == OUTPUT_WAV)
- {
- if (aufile->channelMask)
- write_wav_extensible_header(aufile, aufile->channelMask);
- else
- write_wav_header(aufile);
- }
-
- return aufile;
-}
-
-int write_audio_file(audio_file *aufile, void *sample_buffer, int samples, int offset)
-{
- char *buf = (char *)sample_buffer;
- switch (aufile->outputFormat)
- {
- case FAAD_FMT_16BIT:
- return write_audio_16bit(aufile, buf + offset*2, samples);
- case FAAD_FMT_24BIT:
- return write_audio_24bit(aufile, buf + offset*4, samples);
- case FAAD_FMT_32BIT:
- return write_audio_32bit(aufile, buf + offset*4, samples);
- case FAAD_FMT_FLOAT:
- return write_audio_float(aufile, buf + offset*4, samples);
- default:
- return 0;
- }
-
- return 0;
-}
-
-void close_audio_file(audio_file *aufile)
-{
- if ((aufile->fileType == OUTPUT_WAV) && (aufile->toStdio == 0))
- {
- fseek(aufile->sndfile, 0, SEEK_SET);
-
- if (aufile->channelMask)
- write_wav_extensible_header(aufile, aufile->channelMask);
- else
- write_wav_header(aufile);
- }
-
- if (aufile->toStdio == 0)
- fclose(aufile->sndfile);
-
- if (aufile) free(aufile);
-}
-
-static int write_wav_header(audio_file *aufile)
-{
- unsigned char header[44];
- unsigned char* p = header;
- unsigned int bytes = (aufile->bits_per_sample + 7) / 8;
- float data_size = (float)bytes * aufile->total_samples;
- unsigned long word32;
-
- *p++ = 'R'; *p++ = 'I'; *p++ = 'F'; *p++ = 'F';
-
- word32 = (data_size + (44 - 8) < (float)MAXWAVESIZE) ?
- (unsigned long)data_size + (44 - 8) : (unsigned long)MAXWAVESIZE;
- *p++ = (unsigned char)(word32 >> 0);
- *p++ = (unsigned char)(word32 >> 8);
- *p++ = (unsigned char)(word32 >> 16);
- *p++ = (unsigned char)(word32 >> 24);
-
- *p++ = 'W'; *p++ = 'A'; *p++ = 'V'; *p++ = 'E';
-
- *p++ = 'f'; *p++ = 'm'; *p++ = 't'; *p++ = ' ';
-
- *p++ = 0x10; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00;
-
- if (aufile->outputFormat == FAAD_FMT_FLOAT)
- {
- *p++ = 0x03; *p++ = 0x00;
- } else {
- *p++ = 0x01; *p++ = 0x00;
- }
-
- *p++ = (unsigned char)(aufile->channels >> 0);
- *p++ = (unsigned char)(aufile->channels >> 8);
-
- word32 = (unsigned long)(aufile->samplerate + 0.5);
- *p++ = (unsigned char)(word32 >> 0);
- *p++ = (unsigned char)(word32 >> 8);
- *p++ = (unsigned char)(word32 >> 16);
- *p++ = (unsigned char)(word32 >> 24);
-
- word32 = aufile->samplerate * bytes * aufile->channels;
- *p++ = (unsigned char)(word32 >> 0);
- *p++ = (unsigned char)(word32 >> 8);
- *p++ = (unsigned char)(word32 >> 16);
- *p++ = (unsigned char)(word32 >> 24);
-
- word32 = bytes * aufile->channels;
- *p++ = (unsigned char)(word32 >> 0);
- *p++ = (unsigned char)(word32 >> 8);
-
- *p++ = (unsigned char)(aufile->bits_per_sample >> 0);
- *p++ = (unsigned char)(aufile->bits_per_sample >> 8);
-
- *p++ = 'd'; *p++ = 'a'; *p++ = 't'; *p++ = 'a';
-
- word32 = data_size < MAXWAVESIZE ?
- (unsigned long)data_size : (unsigned long)MAXWAVESIZE;
- *p++ = (unsigned char)(word32 >> 0);
- *p++ = (unsigned char)(word32 >> 8);
- *p++ = (unsigned char)(word32 >> 16);
- *p++ = (unsigned char)(word32 >> 24);
-
- return fwrite(header, sizeof(header), 1, aufile->sndfile);
-}
-
-static int write_wav_extensible_header(audio_file *aufile, long channelMask)
-{
- unsigned char header[68];
- unsigned char* p = header;
- unsigned int bytes = (aufile->bits_per_sample + 7) / 8;
- float data_size = (float)bytes * aufile->total_samples;
- unsigned long word32;
-
- *p++ = 'R'; *p++ = 'I'; *p++ = 'F'; *p++ = 'F';
-
- word32 = (data_size + (68 - 8) < (float)MAXWAVESIZE) ?
- (unsigned long)data_size + (68 - 8) : (unsigned long)MAXWAVESIZE;
- *p++ = (unsigned char)(word32 >> 0);
- *p++ = (unsigned char)(word32 >> 8);
- *p++ = (unsigned char)(word32 >> 16);
- *p++ = (unsigned char)(word32 >> 24);
-
- *p++ = 'W'; *p++ = 'A'; *p++ = 'V'; *p++ = 'E';
-
- *p++ = 'f'; *p++ = 'm'; *p++ = 't'; *p++ = ' ';
-
- *p++ = /*0x10*/0x28; *p++ = 0x00; *p++ = 0x00; *p++ = 0x00;
-
- /* WAVE_FORMAT_EXTENSIBLE */
- *p++ = 0xFE; *p++ = 0xFF;
-
- *p++ = (unsigned char)(aufile->channels >> 0);
- *p++ = (unsigned char)(aufile->channels >> 8);
-
- word32 = (unsigned long)(aufile->samplerate + 0.5);
- *p++ = (unsigned char)(word32 >> 0);
- *p++ = (unsigned char)(word32 >> 8);
- *p++ = (unsigned char)(word32 >> 16);
- *p++ = (unsigned char)(word32 >> 24);
-
- word32 = aufile->samplerate * bytes * aufile->channels;
- *p++ = (unsigned char)(word32 >> 0);
- *p++ = (unsigned char)(word32 >> 8);
- *p++ = (unsigned char)(word32 >> 16);
- *p++ = (unsigned char)(word32 >> 24);
-
- word32 = bytes * aufile->channels;
- *p++ = (unsigned char)(word32 >> 0);
- *p++ = (unsigned char)(word32 >> 8);
-
- *p++ = (unsigned char)(aufile->bits_per_sample >> 0);
- *p++ = (unsigned char)(aufile->bits_per_sample >> 8);
-
- /* cbSize */
- *p++ = (unsigned char)(22);
- *p++ = (unsigned char)(0);
-
- /* WAVEFORMATEXTENSIBLE */
-
- /* wValidBitsPerSample */
- *p++ = (unsigned char)(aufile->bits_per_sample >> 0);
- *p++ = (unsigned char)(aufile->bits_per_sample >> 8);
-
- /* dwChannelMask */
- word32 = channelMask;
- *p++ = (unsigned char)(word32 >> 0);
- *p++ = (unsigned char)(word32 >> 8);
- *p++ = (unsigned char)(word32 >> 16);
- *p++ = (unsigned char)(word32 >> 24);
-
- /* SubFormat */
- if (aufile->outputFormat == FAAD_FMT_FLOAT)
- {
- /* KSDATAFORMAT_SUBTYPE_IEEE_FLOAT: 00000003-0000-0010-8000-00aa00389b71 */
- *p++ = 0x03;
- *p++ = 0x00;
- *p++ = 0x00;
- *p++ = 0x00;
- *p++ = 0x00; *p++ = 0x00; *p++ = 0x10; *p++ = 0x00; *p++ = 0x80; *p++ = 0x00;
- *p++ = 0x00; *p++ = 0xaa; *p++ = 0x00; *p++ = 0x38; *p++ = 0x9b; *p++ = 0x71;
- } else {
- /* KSDATAFORMAT_SUBTYPE_PCM: 00000001-0000-0010-8000-00aa00389b71 */
- *p++ = 0x01;
- *p++ = 0x00;
- *p++ = 0x00;
- *p++ = 0x00;
- *p++ = 0x00; *p++ = 0x00; *p++ = 0x10; *p++ = 0x00; *p++ = 0x80; *p++ = 0x00;
- *p++ = 0x00; *p++ = 0xaa; *p++ = 0x00; *p++ = 0x38; *p++ = 0x9b; *p++ = 0x71;
- }
-
- /* end WAVEFORMATEXTENSIBLE */
-
- *p++ = 'd'; *p++ = 'a'; *p++ = 't'; *p++ = 'a';
-
- word32 = data_size < MAXWAVESIZE ?
- (unsigned long)data_size : (unsigned long)MAXWAVESIZE;
- *p++ = (unsigned char)(word32 >> 0);
- *p++ = (unsigned char)(word32 >> 8);
- *p++ = (unsigned char)(word32 >> 16);
- *p++ = (unsigned char)(word32 >> 24);
-
- return fwrite(header, sizeof(header), 1, aufile->sndfile);
-}
-
-static int write_audio_16bit(audio_file *aufile, void *sample_buffer,
- unsigned int samples)
-{
- int ret;
- unsigned int i;
- short *sample_buffer16 = (short*)sample_buffer;
- char *data = malloc(samples*aufile->bits_per_sample*sizeof(char)/8);
-
- aufile->total_samples += samples;
-
- if (aufile->channels == 6 && aufile->channelMask)
- {
- for (i = 0; i < samples; i += aufile->channels)
- {
- short r1, r2, r3, r4, r5, r6;
- r1 = sample_buffer16[i];
- r2 = sample_buffer16[i+1];
- r3 = sample_buffer16[i+2];
- r4 = sample_buffer16[i+3];
- r5 = sample_buffer16[i+4];
- r6 = sample_buffer16[i+5];
- sample_buffer16[i] = r2;
- sample_buffer16[i+1] = r3;
- sample_buffer16[i+2] = r1;
- sample_buffer16[i+3] = r6;
- sample_buffer16[i+4] = r4;
- sample_buffer16[i+5] = r5;
- }
- }
-
- for (i = 0; i < samples; i++)
- {
- data[i*2] = (char)(sample_buffer16[i] & 0xFF);
- data[i*2+1] = (char)((sample_buffer16[i] >> 8) & 0xFF);
- }
-
- ret = fwrite(data, samples, aufile->bits_per_sample/8, aufile->sndfile);
-
- if (data) free(data);
-
- return ret;
-}
-
-static int write_audio_24bit(audio_file *aufile, void *sample_buffer,
- unsigned int samples)
-{
- int ret;
- unsigned int i;
- int32_t *sample_buffer24 = (int32_t*)sample_buffer;
- char *data = malloc(samples*aufile->bits_per_sample*sizeof(char)/8);
-
- aufile->total_samples += samples;
-
- if (aufile->channels == 6 && aufile->channelMask)
- {
- for (i = 0; i < samples; i += aufile->channels)
- {
- long r1, r2, r3, r4, r5, r6;
- r1 = sample_buffer24[i];
- r2 = sample_buffer24[i+1];
- r3 = sample_buffer24[i+2];
- r4 = sample_buffer24[i+3];
- r5 = sample_buffer24[i+4];
- r6 = sample_buffer24[i+5];
- sample_buffer24[i] = r2;
- sample_buffer24[i+1] = r3;
- sample_buffer24[i+2] = r1;
- sample_buffer24[i+3] = r6;
- sample_buffer24[i+4] = r4;
- sample_buffer24[i+5] = r5;
- }
- }
-
- for (i = 0; i < samples; i++)
- {
- data[i*3] = (char)(sample_buffer24[i] & 0xFF);
- data[i*3+1] = (char)((sample_buffer24[i] >> 8) & 0xFF);
- data[i*3+2] = (char)((sample_buffer24[i] >> 16) & 0xFF);
- }
-
- ret = fwrite(data, samples, aufile->bits_per_sample/8, aufile->sndfile);
-
- if (data) free(data);
-
- return ret;
-}
-
-static int write_audio_32bit(audio_file *aufile, void *sample_buffer,
- unsigned int samples)
-{
- int ret;
- unsigned int i;
- int32_t *sample_buffer32 = (int32_t*)sample_buffer;
- char *data = malloc(samples*aufile->bits_per_sample*sizeof(char)/8);
-
- aufile->total_samples += samples;
-
- if (aufile->channels == 6 && aufile->channelMask)
- {
- for (i = 0; i < samples; i += aufile->channels)
- {
- long r1, r2, r3, r4, r5, r6;
- r1 = sample_buffer32[i];
- r2 = sample_buffer32[i+1];
- r3 = sample_buffer32[i+2];
- r4 = sample_buffer32[i+3];
- r5 = sample_buffer32[i+4];
- r6 = sample_buffer32[i+5];
- sample_buffer32[i] = r2;
- sample_buffer32[i+1] = r3;
- sample_buffer32[i+2] = r1;
- sample_buffer32[i+3] = r6;
- sample_buffer32[i+4] = r4;
- sample_buffer32[i+5] = r5;
- }
- }
-
- for (i = 0; i < samples; i++)
- {
- data[i*4] = (char)(sample_buffer32[i] & 0xFF);
- data[i*4+1] = (char)((sample_buffer32[i] >> 8) & 0xFF);
- data[i*4+2] = (char)((sample_buffer32[i] >> 16) & 0xFF);
- data[i*4+3] = (char)((sample_buffer32[i] >> 24) & 0xFF);
- }
-
- ret = fwrite(data, samples, aufile->bits_per_sample/8, aufile->sndfile);
-
- if (data) free(data);
-
- return ret;
-}
-
-static int write_audio_float(audio_file *aufile, void *sample_buffer,
- unsigned int samples)
-{
- int ret;
- unsigned int i;
- float *sample_buffer_f = (float*)sample_buffer;
- unsigned char *data = malloc(samples*aufile->bits_per_sample*sizeof(char)/8);
-
- aufile->total_samples += samples;
-
- if (aufile->channels == 6 && aufile->channelMask)
- {
- for (i = 0; i < samples; i += aufile->channels)
- {
- float r1, r2, r3, r4, r5, r6;
- r1 = sample_buffer_f[i];
- r2 = sample_buffer_f[i+1];
- r3 = sample_buffer_f[i+2];
- r4 = sample_buffer_f[i+3];
- r5 = sample_buffer_f[i+4];
- r6 = sample_buffer_f[i+5];
- sample_buffer_f[i] = r2;
- sample_buffer_f[i+1] = r3;
- sample_buffer_f[i+2] = r1;
- sample_buffer_f[i+3] = r6;
- sample_buffer_f[i+4] = r4;
- sample_buffer_f[i+5] = r5;
- }
- }
-
- for (i = 0; i < samples; i++)
- {
- int exponent, mantissa, negative = 0 ;
- float in = sample_buffer_f[i];
-
- data[i*4] = 0; data[i*4+1] = 0; data[i*4+2] = 0; data[i*4+3] = 0;
- if (in == 0.0)
- continue;
-
- if (in < 0.0)
- {
- in *= -1.0;
- negative = 1;
- }
- in = (float)frexp(in, &exponent);
- exponent += 126;
- in *= (float)0x1000000;
- mantissa = (((int)in) & 0x7FFFFF);
-
- if (negative)
- data[i*4+3] |= 0x80;
-
- if (exponent & 0x01)
- data[i*4+2] |= 0x80;
-
- data[i*4] = mantissa & 0xFF;
- data[i*4+1] = (mantissa >> 8) & 0xFF;
- data[i*4+2] |= (mantissa >> 16) & 0x7F;
- data[i*4+3] |= (exponent >> 1) & 0x7F;
- }
-
- ret = fwrite(data, samples, aufile->bits_per_sample/8, aufile->sndfile);
-
- if (data) free(data);
-
- return ret;
-}
--- a/frontend/audio.h
+++ /dev/null
@@ -1,75 +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: audio.h,v 1.19 2007/11/01 12:33:29 menno Exp $
-**/
-
-#ifndef AUDIO_H_INCLUDED
-#define AUDIO_H_INCLUDED
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define MAXWAVESIZE 4294967040LU
-
-#define OUTPUT_WAV 1
-#define OUTPUT_RAW 2
-
-typedef struct
-{
- int toStdio;
- int outputFormat;
- FILE *sndfile;
- unsigned int fileType;
- unsigned long samplerate;
- unsigned int bits_per_sample;
- unsigned int channels;
- unsigned long total_samples;
- long channelMask;
-} audio_file;
-
-audio_file *open_audio_file(char *infile, int samplerate, int channels,
- int outputFormat, int fileType, long channelMask);
-int write_audio_file(audio_file *aufile, void *sample_buffer, int samples, int offset);
-void close_audio_file(audio_file *aufile);
-static int write_wav_header(audio_file *aufile);
-static int write_wav_extensible_header(audio_file *aufile, long channelMask);
-static int write_audio_16bit(audio_file *aufile, void *sample_buffer,
- unsigned int samples);
-static int write_audio_24bit(audio_file *aufile, void *sample_buffer,
- unsigned int samples);
-static int write_audio_32bit(audio_file *aufile, void *sample_buffer,
- unsigned int samples);
-static int write_audio_float(audio_file *aufile, void *sample_buffer,
- unsigned int samples);
-
-
-#ifdef __cplusplus
-}
-#endif
-#endif
--- a/frontend/faad.man
+++ /dev/null
@@ -1,85 +1,0 @@
-.TH FAAD "1" "October 2006" "faad 2.5" ""
-.SH NAME
-faad \(em Process an Advanced Audio Codec stream
-
-.SH "SYNOPSIS"
-.B faad
-[options] [\-w | \-o <output_filename> | \-a <output_filename>] input_filename
-
-.SH "DESCRIPTION"
-This utility provides a command line interface to libfaad2. This program reads in MPEG\(hy4 AAC files, processes, and outputs them in either Microsoft WAV, MPEG\(hy4 AAC ADTS, or standard PCM formats.
-
-.SH "OPTIONS"
-.TP
-.BI \-a " <filename>" ", \-\^\-adtsout" " <filename>"
-Sets the processing to output to the specified file in MPEG\(hy4 AAC ADTS format
-.TP
-.BI \-b " <number>" ", \-\^\-bits" " <number>"
-Set the output (individual) sample format. The number takes one of the following values:
-.RS
-.RS
-1: 16\(hybit PCM data (default).
-.br
-2: 24\(hybit PCM data.
-.br
-3: 32\(hybit PCM data.
-.br
-4: 32\(hybit floating\(hypoint data.
-.br
-5: 64\(hybit floating\(hypoint data.
-.RE
-.RE
-.TP
-.B \-d ", \-\^\-downmix"
-Set the processing to downsample from 5.1 (surround sound and bass) channels to 2 channels (stereo).
-.TP
-.BI \-f " <number>" ", \-\^\-format" " <number>"
-Set the output file format. The number takes one of the following values:
-.RS
-.RS
-1: Microsoft WAV format (default).
-.br
-2: Raw PCM data.
-.RE
-.RE
-.TP
-.BI \-g
-Set the processing to not perform gapless decoding.
-.TP
-.B \-h ", \-\^\-help"
-Shows a usage summary.
-.TP
-.B \-i ", \-\^\-info"
-Shows information about the about the input file.
-.TP
-.BI \-l " <number>" ", \-\^\-objecttype" " <number>"
-Sets the MPEG\hy(4 profile and object type for the processing to use. The number takes one of the following values:
-.RS
-.RS
-1: Main object type.
-.br
-2: Low Complexity (LC) object type (default).
-.br
-4: Long Term Prediction (LTP) object type.
-.br
-23: Low Delay (LD) object type.
-.RE
-.RE
-.TP
-.BI \-o " <filename>" ", \-\^\-outfile" " <number>"
-Sets the filename for processing output.
-.TP
-.B \-q ", \-\^\-quiet"
-Quiet \- Suppresses status messages during processing.
-.TP
-.B \-t ", \-\^\-oldformat"
-Sets the processing to use the old MPEG\(hy4 AAC ADTS format when outputting in said format.
-.TP
-.B \-w ", \-\^\-stdio"
-Sets the processing output to be sent to the standard out.
-
-.SH "AUTHOR"
-Matthew W. S. Bell <matthew (at) bells23.org.uk>
-
-.SH "SEE ALSO"
-\fBfaac\fP(1)
\ No newline at end of file
--- a/frontend/getopt.c
+++ /dev/null
@@ -1,756 +1,0 @@
-/* Getopt for GNU.
- NOTE: getopt is now part of the C library, so if you don't know what
- "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu
- before changing it!
-
- Copyright (C) 1987, 88, 89, 90, 91, 92, 1993
- Free Software Foundation, Inc.
-
- 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, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifndef __STDC__
-# ifndef const
-# define const
-# endif
-#endif
-
-/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>. */
-#ifndef _NO_PROTO
-#define _NO_PROTO
-#endif
-
-#ifndef __plan9__
-#include <stdio.h>
-#endif
-
-/* Comment out all this code if we are using the GNU C Library, and are not
- actually compiling the library itself. This code is part of the GNU C
- Library, but also included in many other GNU distributions. Compiling
- and linking in this code is a waste when using the GNU C library
- (especially if it is a shared library). Rather than having every GNU
- program understand `configure --with-gnu-libc' and omit the object files,
- it is simpler to just do this in the source for each such file. */
-
-#if defined (_LIBC) || !defined (__GNU_LIBRARY__) || !__MacOSX__
-
-
-/* This needs to come after some library #include
- to get __GNU_LIBRARY__ defined. */
-#ifdef __GNU_LIBRARY__
-/* Don't include stdlib.h for non-GNU C libraries because some of them
- contain conflicting prototypes for getopt. */
-#include <stdlib.h>
-#endif /* GNU C library. */
-
-/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a
- long-named option. Because this is not POSIX.2 compliant, it is
- being phased out. */
-/* #define GETOPT_COMPAT */
-
-/* This version of `getopt' appears to the caller like standard Unix `getopt'
- but it behaves differently for the user, since it allows the user
- to intersperse the options with the other arguments.
-
- As `getopt' works, it permutes the elements of ARGV so that,
- when it is done, all the options precede everything else. Thus
- all application programs are extended to handle flexible argument order.
-
- Setting the environment variable POSIXLY_CORRECT disables permutation.
- Then the behavior is completely standard.
-
- GNU application programs can use a third alternative mode in which
- they can distinguish the relative order of options and other arguments. */
-
-#include "getopt.h"
-
-/* For communication from `getopt' to the caller.
- When `getopt' finds an option that takes an argument,
- the argument value is returned here.
- Also, when `ordering' is RETURN_IN_ORDER,
- each non-option ARGV-element is returned here. */
-
-char *optarg = 0;
-
-/* Index in ARGV of the next element to be scanned.
- This is used for communication to and from the caller
- and for communication between successive calls to `getopt'.
-
- On entry to `getopt', zero means this is the first call; initialize.
-
- When `getopt' returns EOF, this is the index of the first of the
- non-option elements that the caller should itself scan.
-
- Otherwise, `optind' communicates from one call to the next
- how much of ARGV has been scanned so far. */
-
-/* XXX 1003.2 says this must be 1 before any call. */
-int optind = 0;
-
-/* The next char to be scanned in the option-element
- in which the last option character we returned was found.
- This allows us to pick up the scan where we left off.
-
- If this is zero, or a null string, it means resume the scan
- by advancing to the next ARGV-element. */
-
-static char *nextchar;
-
-/* Callers store zero here to inhibit the error message
- for unrecognized options. */
-
-int opterr = 1;
-
-/* Set to an option character which was unrecognized.
- This must be initialized on some systems to avoid linking in the
- system's own getopt implementation. */
-
-#define BAD_OPTION '\0'
-int optopt = BAD_OPTION;
-
-/* Describe how to deal with options that follow non-option ARGV-elements.
-
- If the caller did not specify anything,
- the default is REQUIRE_ORDER if the environment variable
- POSIXLY_CORRECT is defined, PERMUTE otherwise.
-
- REQUIRE_ORDER means don't recognize them as options;
- stop option processing when the first non-option is seen.
- This is what Unix does.
- This mode of operation is selected by either setting the environment
- variable POSIXLY_CORRECT, or using `+' as the first character
- of the list of option characters.
-
- PERMUTE is the default. We permute the contents of ARGV as we scan,
- so that eventually all the non-options are at the end. This allows options
- to be given in any order, even with programs that were not written to
- expect this.
-
- RETURN_IN_ORDER is an option available to programs that were written
- to expect options and other ARGV-elements in any order and that care about
- the ordering of the two. We describe each non-option ARGV-element
- as if it were the argument of an option with character code 1.
- Using `-' as the first character of the list of option characters
- selects this mode of operation.
-
- The special argument `--' forces an end of option-scanning regardless
- of the value of `ordering'. In the case of RETURN_IN_ORDER, only
- `--' can cause `getopt' to return EOF with `optind' != ARGC. */
-
-static enum
-{
- REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
-} ordering;
-
-#ifdef __GNU_LIBRARY__
-/* We want to avoid inclusion of string.h with non-GNU libraries
- because there are many ways it can cause trouble.
- On some systems, it contains special magic macros that don't work
- in GCC. */
-#include <string.h>
-#define my_index strchr
-#define my_strlen strlen
-#else
-
-/* Avoid depending on library functions or files
- whose names are inconsistent. */
-
-#if __STDC__ || defined(PROTO)
-extern char *getenv(const char *name);
-extern int strcmp (const char *s1, const char *s2);
-
-static int my_strlen(const char *s);
-static char *my_index (const char *str, int chr);
-#else
-extern char *getenv ();
-#endif
-
-static int
-my_strlen (str)
- const char *str;
-{
- int n = 0;
- while (*str++)
- n++;
- return n;
-}
-
-static char *
-my_index (str, chr)
- const char *str;
- int chr;
-{
- while (*str)
- {
- if (*str == chr)
- return (char *) str;
- str++;
- }
- return 0;
-}
-
-#endif /* GNU C library. */
-
-/* Handle permutation of arguments. */
-
-/* Describe the part of ARGV that contains non-options that have
- been skipped. `first_nonopt' is the index in ARGV of the first of them;
- `last_nonopt' is the index after the last of them. */
-
-static int first_nonopt;
-static int last_nonopt;
-
-/* Exchange two adjacent subsequences of ARGV.
- One subsequence is elements [first_nonopt,last_nonopt)
- which contains all the non-options that have been skipped so far.
- The other is elements [last_nonopt,optind), which contains all
- the options processed since those non-options were skipped.
-
- `first_nonopt' and `last_nonopt' are relocated so that they describe
- the new indices of the non-options in ARGV after they are moved.
-
- To perform the swap, we first reverse the order of all elements. So
- all options now come before all non options, but they are in the
- wrong order. So we put back the options and non options in original
- order by reversing them again. For example:
- original input: a b c -x -y
- reverse all: -y -x c b a
- reverse options: -x -y c b a
- reverse non options: -x -y a b c
-*/
-
-#if __STDC__ || defined(PROTO)
-static void exchange (char **argv);
-#endif
-
-static void
-exchange (argv)
- char **argv;
-{
- char *temp, **first, **last;
-
- /* Reverse all the elements [first_nonopt, optind) */
- first = &argv[first_nonopt];
- last = &argv[optind-1];
- while (first < last) {
- temp = *first; *first = *last; *last = temp; first++; last--;
- }
- /* Put back the options in order */
- first = &argv[first_nonopt];
- first_nonopt += (optind - last_nonopt);
- last = &argv[first_nonopt - 1];
- while (first < last) {
- temp = *first; *first = *last; *last = temp; first++; last--;
- }
-
- /* Put back the non options in order */
- first = &argv[first_nonopt];
- last_nonopt = optind;
- last = &argv[last_nonopt-1];
- while (first < last) {
- temp = *first; *first = *last; *last = temp; first++; last--;
- }
-}
-
-/* Scan elements of ARGV (whose length is ARGC) for option characters
- given in OPTSTRING.
-
- If an element of ARGV starts with '-', and is not exactly "-" or "--",
- then it is an option element. The characters of this element
- (aside from the initial '-') are option characters. If `getopt'
- is called repeatedly, it returns successively each of the option characters
- from each of the option elements.
-
- If `getopt' finds another option character, it returns that character,
- updating `optind' and `nextchar' so that the next call to `getopt' can
- resume the scan with the following option character or ARGV-element.
-
- If there are no more option characters, `getopt' returns `EOF'.
- Then `optind' is the index in ARGV of the first ARGV-element
- that is not an option. (The ARGV-elements have been permuted
- so that those that are not options now come last.)
-
- OPTSTRING is a string containing the legitimate option characters.
- If an option character is seen that is not listed in OPTSTRING,
- return BAD_OPTION after printing an error message. If you set `opterr' to
- zero, the error message is suppressed but we still return BAD_OPTION.
-
- If a char in OPTSTRING is followed by a colon, that means it wants an arg,
- so the following text in the same ARGV-element, or the text of the following
- ARGV-element, is returned in `optarg'. Two colons mean an option that
- wants an optional arg; if there is text in the current ARGV-element,
- it is returned in `optarg', otherwise `optarg' is set to zero.
-
- If OPTSTRING starts with `-' or `+', it requests different methods of
- handling the non-option ARGV-elements.
- See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
-
- Long-named options begin with `--' instead of `-'.
- Their names may be abbreviated as long as the abbreviation is unique
- or is an exact match for some defined option. If they have an
- argument, it follows the option name in the same ARGV-element, separated
- from the option name by a `=', or else the in next ARGV-element.
- When `getopt' finds a long-named option, it returns 0 if that option's
- `flag' field is nonzero, the value of the option's `val' field
- if the `flag' field is zero.
-
- The elements of ARGV aren't really const, because we permute them.
- But we pretend they're const in the prototype to be compatible
- with other systems.
-
- LONGOPTS is a vector of `struct option' terminated by an
- element containing a name which is zero.
-
- LONGIND returns the index in LONGOPT of the long-named option found.
- It is only valid when a long-named option has been found by the most
- recent call.
-
- If LONG_ONLY is nonzero, '-' as well as '--' can introduce
- long-named options. */
-
-int
-_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
- int argc;
- char *const *argv;
- const char *optstring;
- const struct option *longopts;
- int *longind;
- int long_only;
-{
- int option_index;
-
- optarg = 0;
-
- /* Initialize the internal data when the first call is made.
- Start processing options with ARGV-element 1 (since ARGV-element 0
- is the program name); the sequence of previously skipped
- non-option ARGV-elements is empty. */
-
- if (optind == 0)
- {
- first_nonopt = last_nonopt = optind = 1;
-
- nextchar = NULL;
-
- /* Determine how to handle the ordering of options and nonoptions. */
-
- if (optstring[0] == '-')
- {
- ordering = RETURN_IN_ORDER;
- ++optstring;
- }
- else if (optstring[0] == '+')
- {
- ordering = REQUIRE_ORDER;
- ++optstring;
- }
- else if (getenv ("POSIXLY_CORRECT") != NULL)
- ordering = REQUIRE_ORDER;
- else
- ordering = PERMUTE;
- }
-
- if (nextchar == NULL || *nextchar == '\0')
- {
- if (ordering == PERMUTE)
- {
- /* If we have just processed some options following some non-options,
- exchange them so that the options come first. */
-
- if (first_nonopt != last_nonopt && last_nonopt != optind)
- exchange ((char **) argv);
- else if (last_nonopt != optind)
- first_nonopt = optind;
-
- /* Now skip any additional non-options
- and extend the range of non-options previously skipped. */
-
- while (optind < argc
- && (argv[optind][0] != '-' || argv[optind][1] == '\0')
-#ifdef GETOPT_COMPAT
- && (longopts == NULL
- || argv[optind][0] != '+' || argv[optind][1] == '\0')
-#endif /* GETOPT_COMPAT */
- )
- optind++;
- last_nonopt = optind;
- }
-
- /* Special ARGV-element `--' means premature end of options.
- Skip it like a null option,
- then exchange with previous non-options as if it were an option,
- then skip everything else like a non-option. */
-
- if (optind != argc && !strcmp (argv[optind], "--"))
- {
- optind++;
-
- if (first_nonopt != last_nonopt && last_nonopt != optind)
- exchange ((char **) argv);
- else if (first_nonopt == last_nonopt)
- first_nonopt = optind;
- last_nonopt = argc;
-
- optind = argc;
- }
-
- /* If we have done all the ARGV-elements, stop the scan
- and back over any non-options that we skipped and permuted. */
-
- if (optind == argc)
- {
- /* Set the next-arg-index to point at the non-options
- that we previously skipped, so the caller will digest them. */
- if (first_nonopt != last_nonopt)
- optind = first_nonopt;
- return EOF;
- }
-
- /* If we have come to a non-option and did not permute it,
- either stop the scan or describe it to the caller and pass it by. */
-
- if ((argv[optind][0] != '-' || argv[optind][1] == '\0')
-#ifdef GETOPT_COMPAT
- && (longopts == NULL
- || argv[optind][0] != '+' || argv[optind][1] == '\0')
-#endif /* GETOPT_COMPAT */
- )
- {
- if (ordering == REQUIRE_ORDER)
- return EOF;
- optarg = argv[optind++];
- return 1;
- }
-
- /* We have found another option-ARGV-element.
- Start decoding its characters. */
-
- nextchar = (argv[optind] + 1
- + (longopts != NULL && argv[optind][1] == '-'));
- }
-
- if (longopts != NULL
- && ((argv[optind][0] == '-'
- && (argv[optind][1] == '-' || long_only))
-#ifdef GETOPT_COMPAT
- || argv[optind][0] == '+'
-#endif /* GETOPT_COMPAT */
- ))
- {
- const struct option *p;
- char *s = nextchar;
- int exact = 0;
- int ambig = 0;
- const struct option *pfound = NULL;
- int indfound = 0;
-
- while (*s && *s != '=')
- s++;
-
- /* Test all options for either exact match or abbreviated matches. */
- for (p = longopts, option_index = 0; p->name;
- p++, option_index++)
- if (!strncmp (p->name, nextchar, s - nextchar))
- {
- if (s - nextchar == my_strlen (p->name))
- {
- /* Exact match found. */
- pfound = p;
- indfound = option_index;
- exact = 1;
- break;
- }
- else if (pfound == NULL)
- {
- /* First nonexact match found. */
- pfound = p;
- indfound = option_index;
- }
- else
- /* Second nonexact match found. */
- ambig = 1;
- }
-
- if (ambig && !exact)
- {
- if (opterr)
- fprintf (stderr, "%s: option `%s' is ambiguous\n",
- argv[0], argv[optind]);
- nextchar += my_strlen (nextchar);
- optind++;
- return BAD_OPTION;
- }
-
- if (pfound != NULL)
- {
- option_index = indfound;
- optind++;
- if (*s)
- {
- /* Don't test has_arg with >, because some C compilers don't
- allow it to be used on enums. */
- if (pfound->has_arg)
- optarg = s + 1;
- else
- {
- if (opterr)
- {
- if (argv[optind - 1][1] == '-')
- /* --option */
- fprintf (stderr,
- "%s: option `--%s' doesn't allow an argument\n",
- argv[0], pfound->name);
- else
- /* +option or -option */
- fprintf (stderr,
- "%s: option `%c%s' doesn't allow an argument\n",
- argv[0], argv[optind - 1][0], pfound->name);
- }
- nextchar += my_strlen (nextchar);
- return BAD_OPTION;
- }
- }
- else if (pfound->has_arg == 1)
- {
- if (optind < argc)
- optarg = argv[optind++];
- else
- {
- if (opterr)
- fprintf (stderr, "%s: option `%s' requires an argument\n",
- argv[0], argv[optind - 1]);
- nextchar += my_strlen (nextchar);
- return optstring[0] == ':' ? ':' : BAD_OPTION;
- }
- }
- nextchar += my_strlen (nextchar);
- if (longind != NULL)
- *longind = option_index;
- if (pfound->flag)
- {
- *(pfound->flag) = pfound->val;
- return 0;
- }
- return pfound->val;
- }
- /* Can't find it as a long option. If this is not getopt_long_only,
- or the option starts with '--' or is not a valid short
- option, then it's an error.
- Otherwise interpret it as a short option. */
- if (!long_only || argv[optind][1] == '-'
-#ifdef GETOPT_COMPAT
- || argv[optind][0] == '+'
-#endif /* GETOPT_COMPAT */
- || my_index (optstring, *nextchar) == NULL)
- {
- if (opterr)
- {
- if (argv[optind][1] == '-')
- /* --option */
- fprintf (stderr, "%s: unrecognized option `--%s'\n",
- argv[0], nextchar);
- else
- /* +option or -option */
- fprintf (stderr, "%s: unrecognized option `%c%s'\n",
- argv[0], argv[optind][0], nextchar);
- }
- nextchar = (char *) "";
- optind++;
- return BAD_OPTION;
- }
- }
-
- /* Look at and handle the next option-character. */
-
- {
- char c = *nextchar++;
- char *temp = my_index (optstring, c);
-
- /* Increment `optind' when we start to process its last character. */
- if (*nextchar == '\0')
- ++optind;
-
- if (temp == NULL || c == ':')
- {
- if (opterr)
- {
-#if 0
- if (c < 040 || c >= 0177)
- fprintf (stderr, "%s: unrecognized option, character code 0%o\n",
- argv[0], c);
- else
- fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c);
-#else
- /* 1003.2 specifies the format of this message. */
- fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c);
-#endif
- }
- optopt = c;
- return BAD_OPTION;
- }
- if (temp[1] == ':')
- {
- if (temp[2] == ':')
- {
- /* This is an option that accepts an argument optionally. */
- if (*nextchar != '\0')
- {
- optarg = nextchar;
- optind++;
- }
- else
- optarg = 0;
- nextchar = NULL;
- }
- else
- {
- /* This is an option that requires an argument. */
- if (*nextchar != '\0')
- {
- optarg = nextchar;
- /* If we end this ARGV-element by taking the rest as an arg,
- we must advance to the next element now. */
- optind++;
- }
- else if (optind == argc)
- {
- if (opterr)
- {
-#if 0
- fprintf (stderr, "%s: option `-%c' requires an argument\n",
- argv[0], c);
-#else
- /* 1003.2 specifies the format of this message. */
- fprintf (stderr, "%s: option requires an argument -- %c\n",
- argv[0], c);
-#endif
- }
- optopt = c;
- if (optstring[0] == ':')
- c = ':';
- else
- c = BAD_OPTION;
- }
- else
- /* We already incremented `optind' once;
- increment it again when taking next ARGV-elt as argument. */
- optarg = argv[optind++];
- nextchar = NULL;
- }
- }
- return c;
- }
-}
-
-int
-getopt (argc, argv, optstring)
- int argc;
- char *const *argv;
- const char *optstring;
-{
- return _getopt_internal (argc, argv, optstring,
- (const struct option *) 0,
- (int *) 0,
- 0);
-}
-
-int
-getopt_long (argc, argv, options, long_options, opt_index)
- int argc;
- char *const *argv;
- const char *options;
- const struct option *long_options;
- int *opt_index;
-{
- return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
-}
-
-#endif /* _LIBC or not __GNU_LIBRARY__. */
-
-#ifdef TEST
-
-/* Compile with -DTEST to make an executable for use in testing
- the above definition of `getopt'. */
-
-int
-main (argc, argv)
- int argc;
- char **argv;
-{
- int c;
- int digit_optind = 0;
-
- while (1)
- {
- int this_option_optind = optind ? optind : 1;
-
- c = getopt (argc, argv, "abc:d:0123456789");
- if (c == EOF)
- break;
-
- switch (c)
- {
- case '0':
- case '1':
- case '2':
- case '3':
- case '4':
- case '5':
- case '6':
- case '7':
- case '8':
- case '9':
- if (digit_optind != 0 && digit_optind != this_option_optind)
- printf ("digits occur in two different argv-elements.\n");
- digit_optind = this_option_optind;
- printf ("option %c\n", c);
- break;
-
- case 'a':
- printf ("option a\n");
- break;
-
- case 'b':
- printf ("option b\n");
- break;
-
- case 'c':
- printf ("option c with value `%s'\n", optarg);
- break;
-
- case BAD_OPTION:
- break;
-
- default:
- printf ("?? getopt returned character code 0%o ??\n", c);
- }
- }
-
- if (optind < argc)
- {
- printf ("non-option ARGV-elements: ");
- while (optind < argc)
- printf ("%s ", argv[optind++]);
- printf ("\n");
- }
-
- exit (0);
-}
-
-#endif /* TEST */
--- a/frontend/getopt.h
+++ /dev/null
@@ -1,130 +1,0 @@
-/* Declarations for getopt.
- Copyright (C) 1989, 1990, 1991, 1992, 1993 Free Software Foundation, Inc.
-
- 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, 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, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
-#ifndef _GETOPT_H
-#define _GETOPT_H 1
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#ifndef __MacOSX__
-
-/* For communication from `getopt' to the caller.
- When `getopt' finds an option that takes an argument,
- the argument value is returned here.
- Also, when `ordering' is RETURN_IN_ORDER,
- each non-option ARGV-element is returned here. */
-
-extern char *optarg;
-
-/* Index in ARGV of the next element to be scanned.
- This is used for communication to and from the caller
- and for communication between successive calls to `getopt'.
-
- On entry to `getopt', zero means this is the first call; initialize.
-
- When `getopt' returns EOF, this is the index of the first of the
- non-option elements that the caller should itself scan.
-
- Otherwise, `optind' communicates from one call to the next
- how much of ARGV has been scanned so far. */
-
-extern int optind;
-
-/* Callers store zero here to inhibit the error message `getopt' prints
- for unrecognized options. */
-
-extern int opterr;
-
-/* Set to an option character which was unrecognized. */
-
-extern int optopt;
-#endif
-
-/* Describe the long-named options requested by the application.
- The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
- of `struct option' terminated by an element containing a name which is
- zero.
-
- The field `has_arg' is:
- no_argument (or 0) if the option does not take an argument,
- required_argument (or 1) if the option requires an argument,
- optional_argument (or 2) if the option takes an optional argument.
-
- If the field `flag' is not NULL, it points to a variable that is set
- to the value given in the field `val' when the option is found, but
- left unchanged if the option is not found.
-
- To have a long-named option do something other than set an `int' to
- a compiled-in constant, such as set a value from `optarg', set the
- option's `flag' field to zero and its `val' field to a nonzero
- value (the equivalent single-letter option character, if there is
- one). For long options that have a zero `flag' field, `getopt'
- returns the contents of the `val' field. */
-
-struct option
-{
-#if __STDC__
- const char *name;
-#else
- char *name;
-#endif
- /* has_arg can't be an enum because some compilers complain about
- type mismatches in all the code that assumes it is an int. */
- int has_arg;
- int *flag;
- int val;
-};
-
-/* Names for the values of the `has_arg' field of `struct option'. */
-
-#define no_argument 0
-#define required_argument 1
-#define optional_argument 2
-
-//#if __STDC__ || defined(PROTO)
-#if defined(__GNU_LIBRARY__)
-/* Many other libraries have conflicting prototypes for getopt, with
- differences in the consts, in stdlib.h. To avoid compilation
- errors, only prototype getopt for the GNU C library. */
-extern int getopt (int argc, char *const *argv, const char *shortopts);
-#endif /* not __GNU_LIBRARY__ */
-extern int getopt_long (int argc, char *const *argv, const char *shortopts,
- const struct option *longopts, int *longind);
-extern int getopt_long_only (int argc, char *const *argv,
- const char *shortopts,
- const struct option *longopts, int *longind);
-
-/* Internal only. Users should not call this directly. */
-extern int _getopt_internal (int argc, char *const *argv,
- const char *shortopts,
- const struct option *longopts, int *longind,
- int long_only);
-//#else /* not __STDC__ */
-extern int getopt (int argc, char *const *argv, const char *shortopts);
-//extern int getopt_long ();
-//extern int getopt_long_only ();
-
-//extern int _getopt_internal ();
-//#endif /* not __STDC__ */
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /* _GETOPT_H */
--- a/frontend/main.c
+++ b/frontend/main.c
@@ -28,1361 +28,232 @@
** $Id: main.c,v 1.89 2015/01/19 09:46:12 knik Exp $
**/
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#ifdef _WIN32
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-#include <io.h>
-#ifndef __MINGW32__
-#define off_t __int64
-#endif
-#elif !defined(__plan9__)
-#include <time.h>
-#endif
-
-#ifdef __plan9__
#include <u.h>
#include <libc.h>
-#else
-#include <fcntl.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <string.h>
-#include <getopt.h>
-#endif
-#include <stdio.h>
-#include "unicode_support.h"
-
+#include <bio.h>
#include <neaacdec.h>
-#include "audio.h"
-#include "mp4read.h"
+#define min(a,b) ((a)<=(b)?(a):(b))
-#ifdef HAVE_GETOPT_H
-# include <getopt.h>
-#else
-# include "getopt.h"
-# include "getopt.c"
-#endif
+#define MAX_CHANNELS 6 /* make this higher to support files with more channels */
-#ifndef min
-#define min(a,b) ( (a) < (b) ? (a) : (b) )
-#endif
-
-#define MAX_CHANNELS 6 /* make this higher to support files with
- more channels */
-
-#define MAX_PERCENTS 384
-
-static int quiet = 0;
-
-static void faad_fprintf(FILE *stream, const char *fmt, ...)
-{
- va_list ap;
-
- if (!quiet)
- {
- va_start(ap, fmt);
- vfprintf(stream, fmt, ap);
- va_end(ap);
- }
-
-#ifdef _WIN32
- if (!_isatty(_fileno(stream)))
- {
- fflush(stream); /*ensure real-time progress output on Win32*/
- }
-#endif
-}
-
/* FAAD file buffering routines */
typedef struct {
- long bytes_into_buffer;
- long bytes_consumed;
- long file_offset;
- unsigned char *buffer;
- int at_eof;
- FILE *infile;
-} aac_buffer;
+ long bytes_into_buffer;
+ long bytes_consumed;
+ long file_offset;
+ unsigned char *buffer;
+ int at_eof;
+}aac_buffer;
+static int adts_sample_rates[] = {
+ 96000,
+ 88200,
+ 64000,
+ 48000,
+ 44100,
+ 32000,
+ 24000,
+ 22050,
+ 16000,
+ 12000,
+ 11025,
+ 8000,
+ 7350,
+ 0,
+ 0,
+ 0,
+};
+static Biobuf stdin, stdout;
-static int fill_buffer(aac_buffer *b)
+static int
+fill_buffer(aac_buffer *b)
{
- int bread;
+ int bread;
- if (b->bytes_consumed > 0)
- {
- if (b->bytes_into_buffer)
- {
- memmove((void*)b->buffer, (void*)(b->buffer + b->bytes_consumed),
- b->bytes_into_buffer*sizeof(unsigned char));
- }
+ 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 = fread((void*)(b->buffer + b->bytes_into_buffer), 1,
- b->bytes_consumed, b->infile);
+ 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;
+ }
- if (bread != b->bytes_consumed)
- b->at_eof = 1;
+ b->bytes_consumed = 0;
- b->bytes_into_buffer += bread;
- }
+ 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;
+ }
- b->bytes_consumed = 0;
-
- if (b->bytes_into_buffer > 3)
- {
- if (memcmp(b->buffer, "TAG", 3) == 0)
- b->bytes_into_buffer = 0;
- }
- if (b->bytes_into_buffer > 11)
- {
- if (memcmp(b->buffer, "LYRICSBEGIN", 11) == 0)
- b->bytes_into_buffer = 0;
- }
- if (b->bytes_into_buffer > 8)
- {
- if (memcmp(b->buffer, "APETAGEX", 8) == 0)
- b->bytes_into_buffer = 0;
- }
- }
-
- return 1;
+ return 1;
}
-static void advance_buffer(aac_buffer *b, int bytes)
+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);
+ 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;
+ bytes -= chunk;
+ b->file_offset += chunk;
+ b->bytes_consumed = chunk;
+ b->bytes_into_buffer -= chunk;
- if (b->bytes_into_buffer == 0)
- fill_buffer(b);
- }
+ if(b->bytes_into_buffer == 0)
+ fill_buffer(b);
+ }
}
-static void lookforheader(aac_buffer *b)
+static void
+lookforheader(aac_buffer *b)
{
- int i = 0;
- while (!b->at_eof )
- {
- if (b->bytes_into_buffer > 4)
- {
- if( ((b->buffer[0+i] == 0xff) && ((b->buffer[1+i] & 0xf6) == 0xf0)) ||
- (b->buffer[0+i] == 'A' && b->buffer[1+i] == 'D' && b->buffer[2+i] == 'I' && b->buffer[3+i] == 'F'))
- {
- fill_buffer(b);
- break;
- } else {
- i++;
- b->file_offset += 1;
- b->bytes_consumed += 1;
- b->bytes_into_buffer -= 1;
- }
- }
- else
- {
- fill_buffer(b);
- i = 0;
- }
- }
-}
+ int i = 0;
-static int adts_sample_rates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,7350,0,0,0};
-
-static int adts_parse(aac_buffer *b, int *bitrate, float *length)
-{
- int frames, frame_length;
- int t_framelength = 0;
- int samplerate;
- float frames_per_sec, bytes_per_frame;
-
- /* Read all frames to ensure correct time and bitrate */
- for (frames = 0; /* */; frames++)
- {
- fill_buffer(b);
-
- if (b->bytes_into_buffer > 7)
- {
- /* check syncword */
- if (!((b->buffer[0] == 0xFF)&&((b->buffer[1] & 0xF6) == 0xF0)))
- break;
-
- if (frames == 0)
- samplerate = adts_sample_rates[(b->buffer[2]&0x3c)>>2];
-
- frame_length = ((((unsigned int)b->buffer[3] & 0x3)) << 11)
- | (((unsigned int)b->buffer[4]) << 3) | (b->buffer[5] >> 5);
-
- t_framelength += frame_length;
-
- if (frame_length > b->bytes_into_buffer)
- break;
-
- advance_buffer(b, frame_length);
- } else {
- break;
- }
- }
-
- frames_per_sec = (float)samplerate/1024.0f;
- if (frames != 0)
- bytes_per_frame = (float)t_framelength/(float)(frames*1000);
- else
- bytes_per_frame = 0;
- *bitrate = (int)(8. * bytes_per_frame * frames_per_sec + 0.5);
- if (frames_per_sec != 0)
- *length = (float)frames/frames_per_sec;
- else
- *length = 1;
-
- return 1;
+ while(!b->at_eof ){
+ if(b->bytes_into_buffer > 4){
+ if((b->buffer[0+i] == 0xff && (b->buffer[1+i] & 0xf6) == 0xf0) ||
+ (b->buffer[0+i] == 'A' && b->buffer[1+i] == 'D' && b->buffer[2+i] == 'I' && b->buffer[3+i] == 'F')){
+ fill_buffer(b);
+ break;
+ }else{
+ b->file_offset++;
+ b->bytes_consumed++;
+ b->bytes_into_buffer--;
+ }
+ }else{
+ fill_buffer(b);
+ }
+ }
}
-
-
-uint32_t read_callback(void *user_data, void *buffer, uint32_t length)
+static int
+decode(void)
{
- return fread(buffer, 1, length, (FILE*)user_data);
-}
+ NeAACDecHandle hDecoder;
+ NeAACDecFrameInfo frameInfo;
+ NeAACDecConfigurationPtr config;
+ int tagsize;
+ unsigned long samplerate;
+ unsigned char channels;
+ void *sample_buffer;
+ int bread;
+ aac_buffer b;
-uint32_t seek_callback(void *user_data, uint64_t position)
-{
- return fseek((FILE*)user_data, position, SEEK_SET);
-}
+ 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);
-/* MicroSoft channel definitions */
-#define SPEAKER_FRONT_LEFT 0x1
-#define SPEAKER_FRONT_RIGHT 0x2
-#define SPEAKER_FRONT_CENTER 0x4
-#define SPEAKER_LOW_FREQUENCY 0x8
-#define SPEAKER_BACK_LEFT 0x10
-#define SPEAKER_BACK_RIGHT 0x20
-#define SPEAKER_FRONT_LEFT_OF_CENTER 0x40
-#define SPEAKER_FRONT_RIGHT_OF_CENTER 0x80
-#define SPEAKER_BACK_CENTER 0x100
-#define SPEAKER_SIDE_LEFT 0x200
-#define SPEAKER_SIDE_RIGHT 0x400
-#define SPEAKER_TOP_CENTER 0x800
-#define SPEAKER_TOP_FRONT_LEFT 0x1000
-#define SPEAKER_TOP_FRONT_CENTER 0x2000
-#define SPEAKER_TOP_FRONT_RIGHT 0x4000
-#define SPEAKER_TOP_BACK_LEFT 0x8000
-#define SPEAKER_TOP_BACK_CENTER 0x10000
-#define SPEAKER_TOP_BACK_RIGHT 0x20000
-#define SPEAKER_RESERVED 0x80000000
+ bread = Bread(&stdin, b.buffer, FAAD_MIN_STREAMSIZE*MAX_CHANNELS);
+ b.bytes_into_buffer = bread;
+ b.bytes_consumed = 0;
+ b.file_offset = 0;
-static long aacChannelConfig2wavexChannelMask(NeAACDecFrameInfo *hInfo)
-{
- if (hInfo->channels == 6 && hInfo->num_lfe_channels)
- {
- return SPEAKER_FRONT_LEFT + SPEAKER_FRONT_RIGHT +
- SPEAKER_FRONT_CENTER + SPEAKER_LOW_FREQUENCY +
- SPEAKER_BACK_LEFT + SPEAKER_BACK_RIGHT;
- } else {
- return 0;
- }
-}
+ if(bread != FAAD_MIN_STREAMSIZE*MAX_CHANNELS)
+ b.at_eof = 1;
-static char *position2string(int position)
-{
- switch (position)
- {
- case FRONT_CHANNEL_CENTER: return "Center front";
- case FRONT_CHANNEL_LEFT: return "Left front";
- case FRONT_CHANNEL_RIGHT: return "Right front";
- case SIDE_CHANNEL_LEFT: return "Left side";
- case SIDE_CHANNEL_RIGHT: return "Right side";
- case BACK_CHANNEL_LEFT: return "Left back";
- case BACK_CHANNEL_RIGHT: return "Right back";
- case BACK_CHANNEL_CENTER: return "Center back";
- case LFE_CHANNEL: return "LFE";
- case UNKNOWN_CHANNEL: return "Unknown";
- default: return "";
- }
+ if(!memcmp(b.buffer, "ID3", 3)){
+ /* high bit is not used */
+ tagsize = b.buffer[6]<<21 | b.buffer[7]<<14 | b.buffer[8]<<7 | b.buffer[9];
+ tagsize += 10;
+ advance_buffer(&b, tagsize);
+ fill_buffer(&b);
+ }
- return "";
-}
+ hDecoder = NeAACDecOpen();
-static void print_channel_info(NeAACDecFrameInfo *frameInfo)
-{
- /* print some channel info */
- int i;
- long channelMask = aacChannelConfig2wavexChannelMask(frameInfo);
+ config = NeAACDecGetCurrentConfiguration(hDecoder);
+ config->defSampleRate = 44100;
+ config->defObjectType = LC;
+ config->outputFormat = FAAD_FMT_16BIT;
+ config->downMatrix = 0;
+ config->useOldADTSFormat = 0;
+ NeAACDecSetConfiguration(hDecoder, config);
- faad_fprintf(stderr, " ---------------------\n");
- if (frameInfo->num_lfe_channels > 0)
- {
- faad_fprintf(stderr, " | Config: %2d.%d Ch |", frameInfo->channels-frameInfo->num_lfe_channels, frameInfo->num_lfe_channels);
- } else {
- faad_fprintf(stderr, " | Config: %2d Ch |", frameInfo->channels);
- }
- if (channelMask)
- faad_fprintf(stderr, " WARNING: channels are reordered according to\n");
- else
- faad_fprintf(stderr, "\n");
- faad_fprintf(stderr, " ---------------------");
- if (channelMask)
- faad_fprintf(stderr, " MS defaults defined in WAVE_FORMAT_EXTENSIBLE\n");
- else
- faad_fprintf(stderr, "\n");
- faad_fprintf(stderr, " | Ch | Position |\n");
- faad_fprintf(stderr, " ---------------------\n");
- for (i = 0; i < frameInfo->channels; i++)
- {
- faad_fprintf(stderr, " | %.2d | %-14s |\n", i, position2string((int)frameInfo->channel_position[i]));
- }
- faad_fprintf(stderr, " ---------------------\n");
- faad_fprintf(stderr, "\n");
-}
+ lookforheader(&b);
-static int FindAdtsSRIndex(int sr)
-{
- int i;
+ channels = 2;
+ samplerate = 44100;
+ if(b.buffer[0] == 0xff && (b.buffer[1]&0xf6) == 0xf0)
+ samplerate = adts_sample_rates[(b.buffer[2] & 0x3c) >> 2];
- for (i = 0; i < 16; i++)
- {
- if (sr == adts_sample_rates[i])
- return i;
- }
- return 16 - 1;
-}
+ 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);
-static unsigned char *MakeAdtsHeader(int *dataSize, NeAACDecFrameInfo *hInfo, int old_format)
-{
- unsigned char *data;
- int profile = (hInfo->object_type - 1) & 0x3;
- int sr_index = ((hInfo->sbr == SBR_UPSAMPLED) || (hInfo->sbr == NO_SBR_UPSAMPLED)) ?
- FindAdtsSRIndex(hInfo->samplerate / 2) : FindAdtsSRIndex(hInfo->samplerate);
- int skip = (old_format) ? 8 : 7;
- int framesize = skip + hInfo->bytesconsumed;
+ if(samplerate != 44100 || channels != 2){
+ int pfd[2], pid;
+ char fmt[32];
- if (hInfo->header_type == ADTS)
- framesize -= skip;
+ 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);
+ }
- *dataSize = 7;
+ for(;;){
+ sample_buffer = NeAACDecDecode(hDecoder, &frameInfo, b.buffer, b.bytes_into_buffer);
- data = malloc(*dataSize * sizeof(unsigned char));
- memset(data, 0, *dataSize * sizeof(unsigned char));
+ /* update buffer indices */
+ advance_buffer(&b, frameInfo.bytesconsumed);
- data[0] += 0xFF; /* 8b: syncword */
+ if(frameInfo.error != 0)
+ sysfatal("%s: %d", NeAACDecGetErrorMessage(frameInfo.error), frameInfo.error);
- data[1] += 0xF0; /* 4b: syncword */
- /* 1b: mpeg id = 0 */
- /* 2b: layer = 0 */
- data[1] += 1; /* 1b: protection absent */
+ if(frameInfo.samples > 0 && Bwrite(&stdout, sample_buffer, frameInfo.samples*2) != frameInfo.samples*2)
+ break;
- data[2] += ((profile << 6) & 0xC0); /* 2b: profile */
- data[2] += ((sr_index << 2) & 0x3C); /* 4b: sampling_frequency_index */
- /* 1b: private = 0 */
- data[2] += ((hInfo->channels >> 2) & 0x1); /* 1b: channel_configuration */
+ fill_buffer(&b);
- data[3] += ((hInfo->channels << 6) & 0xC0); /* 2b: channel_configuration */
- /* 1b: original */
- /* 1b: home */
- /* 1b: copyright_id */
- /* 1b: copyright_id_start */
- data[3] += ((framesize >> 11) & 0x3); /* 2b: aac_frame_length */
+ if(b.bytes_into_buffer == 0)
+ break;
+ }
- data[4] += ((framesize >> 3) & 0xFF); /* 8b: aac_frame_length */
+ NeAACDecClose(hDecoder);
- data[5] += ((framesize << 5) & 0xE0); /* 3b: aac_frame_length */
- data[5] += ((0x7FF >> 6) & 0x1F); /* 5b: adts_buffer_fullness */
+ if(b.buffer)
+ free(b.buffer);
- data[6] += ((0x7FF << 2) & 0x3F); /* 6b: adts_buffer_fullness */
- /* 2b: num_raw_data_blocks */
-
- return data;
+ return frameInfo.error;
}
-/* globals */
-char *progName;
-
-static const char *file_ext[] =
+static void
+usage(void)
{
- NULL,
- ".wav",
- ".aif",
- ".au",
- ".au",
- ".pcm",
- NULL
-};
-
-static void usage(void)
-{
- faad_fprintf(stdout, "\nUsage:\n");
- faad_fprintf(stdout, "%s [options] infile.aac\n", progName);
- faad_fprintf(stdout, "Options:\n");
- faad_fprintf(stdout, " -h Shows this help screen.\n");
- faad_fprintf(stdout, " -i Shows info about the input file.\n");
- faad_fprintf(stdout, " -a X Write MPEG-4 AAC ADTS output file.\n");
- faad_fprintf(stdout, " -t Assume old ADTS format.\n");
- faad_fprintf(stdout, " -o X Set output filename.\n");
- faad_fprintf(stdout, " -f X Set output format. Valid values for X are:\n");
- faad_fprintf(stdout, " 1: Microsoft WAV format (default).\n");
- faad_fprintf(stdout, " 2: RAW PCM data.\n");
- faad_fprintf(stdout, " -b X Set output sample format. Valid values for X are:\n");
- faad_fprintf(stdout, " 1: 16 bit PCM data (default).\n");
- faad_fprintf(stdout, " 2: 24 bit PCM data.\n");
- faad_fprintf(stdout, " 3: 32 bit PCM data.\n");
- faad_fprintf(stdout, " 4: 32 bit floating point data.\n");
- faad_fprintf(stdout, " 5: 64 bit floating point data.\n");
- faad_fprintf(stdout, " -s X Force the samplerate to X (for RAW files).\n");
- faad_fprintf(stdout, " -l X Set object type. Supported object types:\n");
- faad_fprintf(stdout, " 1: Main object type.\n");
- faad_fprintf(stdout, " 2: LC (Low Complexity) object type.\n");
- faad_fprintf(stdout, " 4: LTP (Long Term Prediction) object type.\n");
- faad_fprintf(stdout, " 23: LD (Low Delay) object type.\n");
- faad_fprintf(stdout, " -d Down matrix 5.1 to 2 channels\n");
- faad_fprintf(stdout, " -w Write output to stdio instead of a file.\n");
- faad_fprintf(stdout, " -g Disable gapless decoding.\n");
- faad_fprintf(stdout, " -q Quiet - suppresses status messages.\n");
- faad_fprintf(stdout, " -j X Jump - start output X seconds into track (MP4 files only).\n");
- faad_fprintf(stdout, "Example:\n");
- faad_fprintf(stdout, " %s infile.aac\n", progName);
- faad_fprintf(stdout, " %s infile.mp4\n", progName);
- faad_fprintf(stdout, " %s -o outfile.wav infile.aac\n", progName);
- faad_fprintf(stdout, " %s -w infile.aac > outfile.wav\n", progName);
- faad_fprintf(stdout, " %s -a outfile.aac infile.aac\n", progName);
- return;
+ print("usage: %s [-i] [options]\n", argv0);
+ return;
}
-static int decodeAACfile(char *aacfile, char *sndfile, char *adts_fn, int to_stdout,
- int def_srate, int object_type, int outputFormat, int fileType,
- int downMatrix, int infoOnly, int adts_out, int old_format,
- float *song_length)
+void
+main(int argc, char **argv)
{
- int tagsize;
- unsigned long samplerate;
- unsigned char channels;
- void *sample_buffer;
+ USED(argc); USED(argv);
- audio_file *aufile = NULL;
+ Binit(&stdin, 0, OREAD);
+ Binit(&stdout, 1, OWRITE);
- FILE *adtsFile = NULL;
- unsigned char *adtsData;
- int adtsDataSize;
-
- NeAACDecHandle hDecoder;
- NeAACDecFrameInfo frameInfo;
- NeAACDecConfigurationPtr config;
-
- char percents[MAX_PERCENTS];
- int percent, old_percent = -1;
- int bread, fileread;
- int header_type = 0;
- int bitrate = 0;
- float length = 0;
-
- int first_time = 1;
- int retval;
- int streaminput = 0;
-
- aac_buffer b;
-
- memset(&b, 0, sizeof(aac_buffer));
-
- if (adts_out)
- {
- adtsFile = faad_fopen(adts_fn, "wb");
- if (adtsFile == NULL)
- {
- faad_fprintf(stderr, "Error opening file: %s\n", adts_fn);
- return 1;
- }
- }
-
- if (0 == strcmp(aacfile, "-"))
- {
- b.infile = stdin;
-#ifdef _WIN32
- _setmode(_fileno(stdin), O_BINARY);
-#endif
-
- }
- else
- {
- b.infile = faad_fopen(aacfile, "rb");
- if (b.infile == NULL)
- {
- /* unable to open file */
- faad_fprintf(stderr, "Error opening file: %s\n", aacfile);
- return 1;
- }
- }
-
- retval = fseek(b.infile, 0, SEEK_END);
-#ifdef _WIN32
- if (0 == strcmp(aacfile, "-")) {
- retval = -1;
- }
-#endif
- if (retval )
- {
- faad_fprintf(stderr, "Input not seekable %s\n", aacfile);
- fileread = -1;
- streaminput = 1;
- } else {
- fileread = ftell(b.infile);
- fseek(b.infile, 0, SEEK_SET);
- };
-
- if (!(b.buffer = (unsigned char*)malloc(FAAD_MIN_STREAMSIZE*MAX_CHANNELS)))
- {
- faad_fprintf(stderr, "Memory allocation error\n");
- return 0;
- }
- memset(b.buffer, 0, FAAD_MIN_STREAMSIZE*MAX_CHANNELS);
-
- bread = fread(b.buffer, 1, FAAD_MIN_STREAMSIZE*MAX_CHANNELS, b.infile);
- b.bytes_into_buffer = bread;
- b.bytes_consumed = 0;
- b.file_offset = 0;
-
- if (bread != FAAD_MIN_STREAMSIZE*MAX_CHANNELS)
- b.at_eof = 1;
-
- tagsize = 0;
- if (!memcmp(b.buffer, "ID3", 3))
- {
- /* high bit is not used */
- tagsize = (b.buffer[6] << 21) | (b.buffer[7] << 14) |
- (b.buffer[8] << 7) | (b.buffer[9] << 0);
-
- tagsize += 10;
- advance_buffer(&b, tagsize);
- fill_buffer(&b);
- }
-
- hDecoder = NeAACDecOpen();
-
- /* Set the default object type and samplerate */
- /* This is useful for RAW AAC files */
- config = NeAACDecGetCurrentConfiguration(hDecoder);
- if (def_srate)
- config->defSampleRate = def_srate;
- config->defObjectType = object_type;
- config->outputFormat = outputFormat;
- config->downMatrix = downMatrix;
- config->useOldADTSFormat = old_format;
- //config->dontUpSampleImplicitSBR = 1;
- NeAACDecSetConfiguration(hDecoder, config);
-
- /* get AAC infos for printing */
- header_type = 0;
- if (streaminput == 1)
- lookforheader(&b);
-
- if ((b.buffer[0] == 0xFF) && ((b.buffer[1] & 0xF6) == 0xF0))
- {
- if (streaminput == 1)
- {
- int /*frames,*/ frame_length;
- int samplerate;
- float frames_per_sec, bytes_per_frame;
- channels = 2;
- samplerate = adts_sample_rates[(b.buffer[2]&0x3c)>>2];
- frame_length = ((((unsigned int)b.buffer[3] & 0x3)) << 11)
- | (((unsigned int)b.buffer[4]) << 3) | (b.buffer[5] >> 5);
- frames_per_sec = (float)samplerate/1024.0f;
- bytes_per_frame = (float)frame_length/(float)(1000);
- bitrate = (int)(8. * bytes_per_frame * frames_per_sec + 0.5);
- length = 1;
- faad_fprintf(stderr, "Streamed input format samplerate %d channels %d.\n", samplerate, channels);
- } else {
- adts_parse(&b, &bitrate, &length);
- fseek(b.infile, tagsize, SEEK_SET);
-
- bread = fread(b.buffer, 1, FAAD_MIN_STREAMSIZE*MAX_CHANNELS, b.infile);
- if (bread != FAAD_MIN_STREAMSIZE*MAX_CHANNELS)
- b.at_eof = 1;
- else
- b.at_eof = 0;
- b.bytes_into_buffer = bread;
- b.bytes_consumed = 0;
- b.file_offset = tagsize;
- }
-
- header_type = 1;
- }
- else if (memcmp(b.buffer, "ADIF", 4) == 0)
- {
- int skip_size = (b.buffer[4] & 0x80) ? 9 : 0;
- bitrate = ((unsigned int)(b.buffer[4 + skip_size] & 0x0F)<<19) |
- ((unsigned int)b.buffer[5 + skip_size]<<11) |
- ((unsigned int)b.buffer[6 + skip_size]<<3) |
- ((unsigned int)b.buffer[7 + skip_size] & 0xE0);
-
- length = (float)fileread;
- if (length != 0)
- {
- length = ((float)length*8.f)/((float)bitrate) + 0.5f;
- }
-
- bitrate = (int)((float)bitrate/1000.0f + 0.5f);
-
- header_type = 2;
- }
-
- *song_length = length;
-
- fill_buffer(&b);
- if ((bread = NeAACDecInit(hDecoder, b.buffer,
- b.bytes_into_buffer, &samplerate, &channels)) < 0)
- {
- /* If some error initializing occured, skip the file */
- faad_fprintf(stderr, "Error initializing decoder library.\n");
- if (b.buffer)
- free(b.buffer);
- NeAACDecClose(hDecoder);
- if (b.infile != stdin)
- fclose(b.infile);
- return 1;
- }
- advance_buffer(&b, bread);
- fill_buffer(&b);
-
- /* print AAC file info */
- faad_fprintf(stderr, "%s file info:\n", aacfile);
- switch (header_type)
- {
- case 0:
- faad_fprintf(stderr, "RAW\n\n");
- break;
- case 1:
- faad_fprintf(stderr, "ADTS, %.3f sec, %d kbps, %d Hz\n\n",
- length, bitrate, samplerate);
- break;
- case 2:
- faad_fprintf(stderr, "ADIF, %.3f sec, %d kbps, %d Hz\n\n",
- length, bitrate, samplerate);
- break;
- }
-
- if (infoOnly)
- {
- NeAACDecClose(hDecoder);
- if (b.infile != stdin)
- fclose(b.infile);
- if (b.buffer)
- free(b.buffer);
- return 0;
- }
-
- do
- {
- sample_buffer = NeAACDecDecode(hDecoder, &frameInfo,
- b.buffer, b.bytes_into_buffer);
-
- if (adts_out == 1)
- {
- int skip = (old_format) ? 8 : 7;
- adtsData = MakeAdtsHeader(&adtsDataSize, &frameInfo, old_format);
-
- /* write the adts header */
- fwrite(adtsData, 1, adtsDataSize, adtsFile);
-
- /* write the frame data */
- if (frameInfo.header_type == ADTS)
- fwrite(b.buffer + skip, 1, frameInfo.bytesconsumed - skip, adtsFile);
- else
- fwrite(b.buffer, 1, frameInfo.bytesconsumed, adtsFile);
- }
-
- /* update buffer indices */
- advance_buffer(&b, frameInfo.bytesconsumed);
-
- if (frameInfo.error > 0)
- {
- faad_fprintf(stderr, "Error: %s\n",
- NeAACDecGetErrorMessage(frameInfo.error));
- }
-
- /* open the sound file now that the number of channels are known */
- if (first_time && !frameInfo.error)
- {
- /* print some channel info */
- print_channel_info(&frameInfo);
-
- if (!adts_out)
- {
- /* open output file */
- if (!to_stdout)
- {
- aufile = open_audio_file(sndfile, frameInfo.samplerate, frameInfo.channels,
- outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo));
- } else {
- aufile = open_audio_file("-", frameInfo.samplerate, frameInfo.channels,
- outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo));
- }
- if (aufile == NULL)
- {
- if (b.buffer)
- free(b.buffer);
- NeAACDecClose(hDecoder);
- if (b.infile != stdin)
- fclose(b.infile);
- return 0;
- }
- } else {
- faad_fprintf(stderr, "Writing output MPEG-4 AAC ADTS file.\n\n");
- }
- first_time = 0;
- }
-
- percent = min((int)(b.file_offset*100)/fileread, 100);
- if (percent > old_percent)
- {
- old_percent = percent;
- snprintf(percents, MAX_PERCENTS, "%d%% decoding %s.", percent, aacfile);
- faad_fprintf(stderr, "%s\r", percents);
-#ifdef _WIN32
- SetConsoleTitle(percents);
-#endif
- }
-
- if ((frameInfo.error == 0) && (frameInfo.samples > 0) && (!adts_out))
- {
- if (write_audio_file(aufile, sample_buffer, frameInfo.samples, 0) == 0)
- break;
- }
-
- /* fill buffer */
- fill_buffer(&b);
-
- if (b.bytes_into_buffer == 0)
- sample_buffer = NULL; /* to make sure it stops now */
-
- } while (sample_buffer != NULL);
-
- NeAACDecClose(hDecoder);
-
- if (adts_out == 1)
- {
- fclose(adtsFile);
- }
-
- if (b.infile != stdin)
- fclose(b.infile);
-
- if (!first_time && !adts_out)
- close_audio_file(aufile);
-
- if (b.buffer)
- free(b.buffer);
-
- return frameInfo.error;
-}
-
-static const unsigned long srates[] =
-{
- 96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000,
- 12000, 11025, 8000
-};
-
-static int decodeMP4file(char *mp4file, char *sndfile, char *adts_fn, int to_stdout,
- int outputFormat, int fileType, int downMatrix, int noGapless,
- int infoOnly, int adts_out, float *song_length, float seek_to)
-{
- /*int track;*/
- unsigned long samplerate;
- unsigned char channels;
- void *sample_buffer;
-
- long sampleId, startSampleId;
-
- audio_file *aufile = NULL;
-
- FILE *adtsFile = NULL;
- unsigned char *adtsData;
- int adtsDataSize;
-
- NeAACDecHandle hDecoder;
- NeAACDecConfigurationPtr config;
- NeAACDecFrameInfo frameInfo;
- mp4AudioSpecificConfig mp4ASC;
-
- char percents[MAX_PERCENTS];
- int percent, old_percent = -1;
-
- int first_time = 1;
-
- /* for gapless decoding */
- unsigned int useAacLength = 1;
- unsigned int framesize;
- unsigned decoded;
-
- if (strcmp(mp4file, "-") == 0 ) {
- faad_fprintf(stderr, "Cannot open stdin for MP4 input \n");
- return 1;
- }
-
- if (!quiet)
- {
- mp4config.verbose.header = 1;
- mp4config.verbose.tags = 1;
- }
- if (mp4read_open(mp4file))
- {
- /* unable to open file */
- faad_fprintf(stderr, "Error opening file: %s\n", mp4file);
- return 1;
- }
-
- hDecoder = NeAACDecOpen();
-
- /* Set configuration */
- config = NeAACDecGetCurrentConfiguration(hDecoder);
- config->outputFormat = outputFormat;
- config->downMatrix = downMatrix;
- //config->dontUpSampleImplicitSBR = 1;
- NeAACDecSetConfiguration(hDecoder, config);
-
- if (adts_out)
- {
- adtsFile = faad_fopen(adts_fn, "wb");
- if (adtsFile == NULL)
- {
- faad_fprintf(stderr, "Error opening file: %s\n", adts_fn);
- return 1;
- }
- }
-
- if(NeAACDecInit2(hDecoder, mp4config.asc.buf, mp4config.asc.size,
- &samplerate, &channels) < 0)
- {
- /* If some error initializing occured, skip the file */
- faad_fprintf(stderr, "Error initializing decoder library.\n");
- NeAACDecClose(hDecoder);
- mp4read_close();
- return 1;
- }
-
- framesize = 1024;
- useAacLength = 0;
- decoded = 0;
-
- if (mp4config.asc.size)
- {
- if (NeAACDecAudioSpecificConfig(mp4config.asc.buf, mp4config.asc.size, &mp4ASC) >= 0)
- {
- if (mp4ASC.frameLengthFlag == 1) framesize = 960;
- if (mp4ASC.sbr_present_flag == 1) framesize *= 2;
- }
- }
-
- /* print some mp4 file info */
- faad_fprintf(stderr, "%s file info:\n\n", mp4file);
- {
- char *tag = NULL, *item = NULL;
- /*int k, j;*/
- char *ot[6] = { "NULL", "MAIN AAC", "LC AAC", "SSR AAC", "LTP AAC", "HE AAC" };
- float seconds;
- seconds = (float)mp4config.samples/(float)mp4ASC.samplingFrequency;
-
- *song_length = seconds;
-
- faad_fprintf(stderr, "%s\t%.3f secs, %d ch, %d Hz\n\n", ot[(mp4ASC.objectTypeIndex > 5)?0:mp4ASC.objectTypeIndex],
- seconds, mp4ASC.channelsConfiguration, mp4ASC.samplingFrequency);
- }
-
- if (infoOnly)
- {
- NeAACDecClose(hDecoder);
- mp4read_close();
- return 0;
- }
-
- startSampleId = 0;
- if (seek_to > 0.1)
- startSampleId = (int64_t)(seek_to * mp4config.samplerate / framesize);
-
- mp4read_seek(startSampleId);
- for (sampleId = startSampleId; sampleId < mp4config.frame.ents; sampleId++)
- {
- /*int rc;*/
- long dur;
- unsigned int sample_count;
- unsigned int delay = 0;
-
- if (mp4read_frame())
- break;
-
- sample_buffer = NeAACDecDecode(hDecoder, &frameInfo, mp4config.bitbuf.data, mp4config.bitbuf.size);
-
- if (!sample_buffer) {
- /* unable to decode file, abort */
- break;
- }
-
- if (adts_out == 1)
- {
- adtsData = MakeAdtsHeader(&adtsDataSize, &frameInfo, 0);
-
- /* write the adts header */
- fwrite(adtsData, 1, adtsDataSize, adtsFile);
-
- fwrite(mp4config.bitbuf.data, 1, frameInfo.bytesconsumed, adtsFile);
- }
-
- dur = frameInfo.samples / frameInfo.channels;
- decoded += dur;
-
- if (decoded > mp4config.samples)
- dur += mp4config.samples - decoded;
-
- if (dur > framesize)
- {
- faad_fprintf(stderr, "Warning: excess frame detected in MP4 file.\n");
- dur = framesize;
- }
-
- if (!noGapless)
- {
- if (useAacLength || (mp4config.samplerate != samplerate)) {
- sample_count = frameInfo.samples;
- } else {
- sample_count = (unsigned int)(dur * frameInfo.channels);
- if (sample_count > frameInfo.samples)
- sample_count = frameInfo.samples;
- }
- } else {
- sample_count = frameInfo.samples;
- }
-
- /* open the sound file now that the number of channels are known */
- if (first_time && !frameInfo.error)
- {
- /* print some channel info */
- print_channel_info(&frameInfo);
-
- if (!adts_out)
- {
- /* open output file */
- if(!to_stdout)
- {
- aufile = open_audio_file(sndfile, frameInfo.samplerate, frameInfo.channels,
- outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo));
- } else {
-#ifdef _WIN32
- _setmode(_fileno(stdout), O_BINARY);
-#endif
- aufile = open_audio_file("-", frameInfo.samplerate, frameInfo.channels,
- outputFormat, fileType, aacChannelConfig2wavexChannelMask(&frameInfo));
- }
- if (aufile == NULL)
- {
- NeAACDecClose(hDecoder);
- mp4read_close();
- return 0;
- }
- }
- first_time = 0;
- }
-
- percent = min((int)(sampleId*100)/mp4config.frame.ents, 100);
- if (percent > old_percent)
- {
- old_percent = percent;
- snprintf(percents, MAX_PERCENTS, "%d%% decoding %s.", percent, mp4file);
- faad_fprintf(stderr, "%s\r", percents);
-#ifdef _WIN32
- SetConsoleTitle(percents);
-#endif
- }
-
- if ((frameInfo.error == 0) && (sample_count > 0) && (!adts_out))
- {
- if (write_audio_file(aufile, sample_buffer, sample_count, delay) == 0)
- break;
- }
-
- if (frameInfo.error > 0)
- {
- faad_fprintf(stderr, "Warning: %s\n",
- NeAACDecGetErrorMessage(frameInfo.error));
- }
- }
-
- NeAACDecClose(hDecoder);
-
- if (adts_out == 1)
- {
- fclose(adtsFile);
- }
-
- mp4read_close();
-
- if (!first_time && !adts_out)
- close_audio_file(aufile);
-
- return frameInfo.error;
-}
-
-static int faad_main(int argc, char *argv[])
-{
- int result;
- int infoOnly = 0;
- int writeToStdio = 0;
- int readFromStdin = 0;
- int object_type = LC;
- int def_srate = 0;
- int downMatrix = 0;
- int format = 1;
- int outputFormat = FAAD_FMT_16BIT;
- int outfile_set = 0;
- int adts_out = 0;
- int old_format = 0;
- int showHelp = 0;
- int mp4file = 0;
- int noGapless = 0;
- char *fnp;
- char *aacFileName = NULL;
- char *audioFileName = NULL;
- char *adtsFileName = NULL;
- float seekTo = 0;
- unsigned char header[8];
- int bread;
- float length = 0;
- FILE *hMP4File;
- char *faad_id_string;
- char *faad_copyright_string;
-
-/* System dependant types */
-#ifdef _WIN32
- long begin;
-#else
- clock_t begin;
-#endif
-
- unsigned long cap = NeAACDecGetCapabilities();
-
-
- /* begin process command line */
- progName = argv[0];
- while (1) {
- int c = -1;
- int option_index = 0;
- static struct option long_options[] = {
- { "quiet", 0, 0, 'q' },
- { "outfile", 0, 0, 'o' },
- { "adtsout", 0, 0, 'a' },
- { "oldformat", 0, 0, 't' },
- { "format", 0, 0, 'f' },
- { "bits", 0, 0, 'b' },
- { "samplerate", 0, 0, 's' },
- { "objecttype", 0, 0, 'l' },
- { "downmix", 0, 0, 'd' },
- { "info", 0, 0, 'i' },
- { "stdio", 0, 0, 'w' },
- { "stdio", 0, 0, 'g' },
- { "seek", 1, 0, 'j' },
- { "help", 0, 0, 'h' },
- { 0, 0, 0, 0 }
- };
-
- c = getopt_long(argc, argv, "o:a:s:f:b:l:j:wgdhitq",
- long_options, &option_index);
-
- if (c == -1)
- break;
-
- switch (c) {
- case 'o':
- if (optarg)
- {
- outfile_set = 1;
- audioFileName = (char *) malloc(sizeof(char) * (strlen(optarg) + 1));
- if (audioFileName == NULL)
- {
- faad_fprintf(stderr, "Error allocating memory for audioFileName.\n");
- return 1;
- }
- strcpy(audioFileName, optarg);
- }
- break;
- case 'a':
- if (optarg)
- {
- adts_out = 1;
- adtsFileName = (char *) malloc(sizeof(char) * (strlen(optarg) + 1));
- if (adtsFileName == NULL)
- {
- faad_fprintf(stderr, "Error allocating memory for adtsFileName.\n");
- return 1;
- }
- strcpy(adtsFileName, optarg);
- }
- break;
- case 's':
- if (optarg)
- {
- char dr[10];
- if (sscanf(optarg, "%s", dr) < 1) {
- def_srate = 0;
- } else {
- def_srate = atoi(dr);
- }
- }
- break;
- case 'f':
- if (optarg)
- {
- char dr[10];
- if (sscanf(optarg, "%s", dr) < 1)
- {
- format = 1;
- } else {
- format = atoi(dr);
- if ((format < 1) || (format > 2))
- showHelp = 1;
- }
- }
- break;
- case 'b':
- if (optarg)
- {
- char dr[10];
- if (sscanf(optarg, "%s", dr) < 1)
- {
- outputFormat = FAAD_FMT_16BIT; /* just use default */
- } else {
- outputFormat = atoi(dr);
- if ((outputFormat < 1) || (outputFormat > 5))
- showHelp = 1;
- }
- }
- break;
- case 'l':
- if (optarg)
- {
- char dr[10];
- if (sscanf(optarg, "%s", dr) < 1)
- {
- object_type = LC; /* default */
- } else {
- object_type = atoi(dr);
- if ((object_type != LC) &&
- (object_type != MAIN) &&
- (object_type != LTP) &&
- (object_type != LD))
- {
- showHelp = 1;
- }
- }
- }
- break;
- case 'j':
- if (optarg)
- {
- seekTo = atof(optarg);
- }
- break;
- case 't':
- old_format = 1;
- break;
- case 'd':
- downMatrix = 1;
- break;
- case 'w':
- writeToStdio = 1;
- break;
- case 'g':
- noGapless = 1;
- break;
- case 'i':
- infoOnly = 1;
- break;
- case 'h':
- showHelp = 1;
- break;
- case 'q':
- quiet = 1;
- break;
- default:
- break;
- }
- }
-
- NeAACDecGetVersion(&faad_id_string, &faad_copyright_string);
-
- faad_fprintf(stderr, " *********** Ahead Software MPEG-4 AAC Decoder V%s ******************\n\n", faad_id_string);
-#ifndef BUILD_DATE
-#define BUILD_DATE __DATE__
-#endif
- faad_fprintf(stderr, " Build: %s\n", BUILD_DATE);
-#undef BUILD_DATE
- faad_fprintf(stderr, "%s", faad_copyright_string);
- if (cap & FIXED_POINT_CAP)
- faad_fprintf(stderr, " Fixed point version\n");
- else
- faad_fprintf(stderr, " Floating point version\n");
- faad_fprintf(stderr, "\n");
- faad_fprintf(stderr, " This program is free software; you can redistribute it and/or modify\n");
- faad_fprintf(stderr, " it under the terms of the GNU General Public License.\n");
- faad_fprintf(stderr, "\n");
- faad_fprintf(stderr, " **************************************************************************\n\n");
-
-
- /* check that we have at least two non-option arguments */
- /* Print help if requested */
- if (((argc - optind) < 1) || showHelp)
- {
- usage();
- return 1;
- }
-
-#if 0
- /* only allow raw data on stdio */
- if (writeToStdio == 1)
- {
- format = 2;
- }
-#endif
-
- /* point to the specified file name */
- aacFileName = (char *) malloc(sizeof(char) * (strlen(argv[optind]) + 1));
- if (aacFileName == NULL)
- {
- faad_fprintf(stderr, "Error allocating memory for aacFileName.\n");
- return 1;
- }
- strcpy(aacFileName, argv[optind]);
-
-#ifdef _WIN32
- begin = GetTickCount();
-#else
- begin = clock();
-#endif
-
- /* Only calculate the path and open the file for writing if
- we are not writing to stdout.
- */
- if(!writeToStdio && !outfile_set)
- {
- audioFileName = (char *) malloc(sizeof(char) * (strlen(aacFileName) + strlen(file_ext[format]) + 1));
- if (audioFileName == NULL)
- {
- faad_fprintf(stderr, "Error allocating memory for audioFileName.\n");
- return 1;
- }
- strcpy(audioFileName, aacFileName);
-
- fnp = (char *)strrchr(audioFileName,'.');
-
- if (fnp)
- fnp[0] = '\0';
-
- strcat(audioFileName, file_ext[format]);
- }
-
- /* check for mp4 file */
- if (0 == strcmp(aacFileName, "-")) {
- faad_fprintf(stderr, "Reading from stdin: %s\n", aacFileName);
- readFromStdin = 1;
- hMP4File = stdin;
-#ifdef _WIN32
- _setmode(_fileno(stdin), O_BINARY);
-#endif
-
- } else {
-
- mp4file = 0;
- hMP4File = faad_fopen(aacFileName, "rb");
- if (!hMP4File)
- {
- faad_fprintf(stderr, "Error opening file: %s\n", aacFileName);
- return 1;
- }
- }
-
- bread = fread(header, 1, 8, hMP4File);
-
- if (! readFromStdin )
- fclose(hMP4File);
-
- if (bread != 8) {
- faad_fprintf(stderr, "Error reading file.\n");
- return 1;
- }
-
- if (header[4] == 'f' && header[5] == 't' && header[6] == 'y' && header[7] == 'p')
- mp4file = 1;
-
- if (!mp4file && seekTo != 0) {
- faad_fprintf(stderr, "Warning: can only seek in MP4 files\n");
- }
-
- if (mp4file)
- {
- result = decodeMP4file(aacFileName, audioFileName, adtsFileName, writeToStdio,
- outputFormat, format, downMatrix, noGapless, infoOnly, adts_out, &length, seekTo);
- } else {
-
- if (readFromStdin == 1) {
- ungetc(header[7],hMP4File);
- ungetc(header[6],hMP4File);
- ungetc(header[5],hMP4File);
- ungetc(header[4],hMP4File);
- ungetc(header[3],hMP4File);
- ungetc(header[2],hMP4File);
- ungetc(header[1],hMP4File);
- ungetc(header[0],hMP4File);
- }
-
- result = decodeAACfile(aacFileName, audioFileName, adtsFileName, writeToStdio,
- def_srate, object_type, outputFormat, format, downMatrix, infoOnly, adts_out,
- old_format, &length);
- }
-
- if (audioFileName != NULL)
- free (audioFileName);
- if (adtsFileName != NULL)
- free (adtsFileName);
-
- if (!result && !infoOnly)
- {
-#ifdef _WIN32
- float dec_length = (float)(GetTickCount()-begin)/1000.0;
- SetConsoleTitle("FAAD");
-#else
- /* clock() grabs time since the start of the app but when we decode
- multiple files, each file has its own starttime (begin).
- */
- float dec_length = (float)(clock() - begin)/(float)CLOCKS_PER_SEC;
-#endif
- faad_fprintf(stderr, "Decoding %s took: %5.2f sec. %5.2fx real-time.\n", aacFileName,
- dec_length, (dec_length > 0.01) ? (length/dec_length) : 0.);
- }
-
- if (aacFileName != NULL)
- free (aacFileName);
-
- return 0;
-}
-
-int main(int argc, char *argv[])
-{
-#if defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64
- int argc_utf8, exit_code;
- char **argv_utf8;
- init_console_utf8(stderr);
- init_commandline_arguments_utf8(&argc_utf8, &argv_utf8);
- exit_code = faad_main(argc_utf8, argv_utf8);
- free_commandline_arguments_utf8(&argc_utf8, &argv_utf8);
- uninit_console_utf8();
- return exit_code;
-#else
- return faad_main(argc, argv);
-#endif
+ exits(decode() == 0 ? nil : "failed");
}
--- a/frontend/mkfile
+++ b/frontend/mkfile
@@ -3,17 +3,12 @@
TARG=aacdec
CFLAGS=$CFLAGS -p -D__plan9__
BIN=/$objtype/bin/audio
-MAN=/sys/man/1
HFILES=\
OFILES=\
main.$O\
- mp4read.$O\
- audio.$O\
default:V: all
</sys/src/cmd/mkone
-
-install:V: $MAN/$TARG
--- a/frontend/mp4read.c
+++ /dev/null
@@ -1,1054 +1,0 @@
-/****************************************************************************
- MP4 input module
-
- Copyright (C) 2017 Krzysztof Nikiel
-
- 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 3 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, see <http://www.gnu.org/licenses/>.
-****************************************************************************/
-
-#ifdef __plan9__
-#include <u.h>
-#include <libc.h>
-#else
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-#include <time.h>
-#include <limits.h>
-#endif
-#include <stdio.h>
-#include "unicode_support.h"
-
-#include "mp4read.h"
-
-enum ATOM_TYPE
-{
- ATOM_STOP = 0 /* end of atoms */ ,
- ATOM_NAME /* plain atom */ ,
- ATOM_DESCENT, /* starts group of children */
- ATOM_ASCENT, /* ends group */
- ATOM_DATA,
-};
-typedef struct
-{
- uint16_t opcode;
- void *data;
-} creator_t;
-
-
-mp4config_t mp4config = { 0 };
-
-static FILE *g_fin = NULL;
-
-static inline uint32_t bswap32(const uint32_t u32)
-{
-#ifndef WORDS_BIGENDIAN
-#if defined (__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 3)))
- return __builtin_bswap32(u32);
-#elif defined (_MSC_VER)
- return _byteswap_ulong(u32);
-#else
- return (u32 << 24) | ((u32 << 8) & 0xFF0000) | ((u32 >> 8) & 0xFF00) | (u32 >> 24);
-#endif
-#else
- return u32;
-#endif
-}
-
-static inline uint16_t bswap16(const uint16_t u16)
-{
-#ifndef WORDS_BIGENDIAN
-#if defined (__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)))
- return __builtin_bswap16(u16);
-#elif defined (_MSC_VER)
- return _byteswap_ushort(u16);
-#else
- return (u16 << 8) | (u16 >> 8);
-#endif
-#else
- return u16;
-#endif
-}
-
-enum {ERR_OK = 0, ERR_FAIL = -1, ERR_UNSUPPORTED = -2};
-
-static int datain(void *data, int size)
-{
- if (fread(data, 1, size, g_fin) != size)
- return ERR_FAIL;
- return size;
-}
-
-static int stringin(char *txt, int sizemax)
-{
- int size;
- for (size = 0; size < sizemax; size++)
- {
- if (fread(txt + size, 1, 1, g_fin) != 1)
- return ERR_FAIL;
- if (!txt[size])
- break;
- }
- txt[sizemax-1] = '\0';
-
- return size;
-}
-
-static uint32_t u32in(void)
-{
- uint32_t u32;
- datain(&u32, 4);
- u32 = bswap32(u32);
- return u32;
-}
-
-static uint16_t u16in(void)
-{
- uint16_t u16;
- datain(&u16, 2);
- u16 = bswap16(u16);
- return u16;
-}
-
-static int u8in(void)
-{
- uint8_t u8;
- datain(&u8, 1);
- return u8;
-}
-
-static int ftypin(int size)
-{
- enum {BUFSIZE = 40};
- char buf[BUFSIZE];
- uint32_t u32;
-
- buf[4] = 0;
- datain(buf, 4);
- u32 = u32in();
-
- if (mp4config.verbose.header)
- fprintf(stderr, "Brand:\t\t\t%s(version %d)\n", buf, u32);
-
- stringin(buf, BUFSIZE);
-
- if (mp4config.verbose.header)
- fprintf(stderr, "Compatible brands:\t%s\n", buf);
-
- return size;
-}
-
-enum
-{ SECSINDAY = 24 * 60 * 60 };
-static char *mp4time(time_t t)
-{
- int y;
-
- // subtract some seconds from the start of 1904 to the start of 1970
- for (y = 1904; y < 1970; y++)
- {
- t -= 365 * SECSINDAY;
- if (!(y & 3))
- t -= SECSINDAY;
- }
-#ifdef __plan9__
- return ctime(t);
-#else
- return ctime(&t);
-#endif
-}
-
-static int mdhdin(int size)
-{
- // version/flags
- u32in();
- // Creation time
- mp4config.ctime = u32in();
- // Modification time
- mp4config.mtime = u32in();
- // Time scale
- mp4config.samplerate = u32in();
- // Duration
- mp4config.samples = u32in();
- // Language
- u16in();
- // pre_defined
- u16in();
-
- return size;
-};
-
-static int hdlr1in(int size)
-{
- uint8_t buf[5];
-
- buf[4] = 0;
- // version/flags
- u32in();
- // pre_defined
- u32in();
- // Component subtype
- datain(buf, 4);
- if (mp4config.verbose.header)
- fprintf(stderr, "*track media type: '%s': ", buf);
- if (memcmp("soun", buf, 4))
- {
- if (mp4config.verbose.header)
- fprintf(stderr, "unsupported, skipping\n");
- return ERR_UNSUPPORTED;
- }
- else
- {
- if (mp4config.verbose.header)
- fprintf(stderr, "OK\n");
- }
- // reserved
- u32in();
- u32in();
- u32in();
- // name
- // null terminate
- u8in();
-
- return size;
-};
-
-static int stsdin(int size)
-{
- // version/flags
- u32in();
- // Number of entries(one 'mp4a')
- if (u32in() != 1) //fixme: error handling
- return ERR_FAIL;
-
- return size;
-};
-
-static int mp4ain(int size)
-{
- // Reserved (6 bytes)
- u32in();
- u16in();
- // Data reference index
- u16in();
- // Version
- u16in();
- // Revision level
- u16in();
- // Vendor
- u32in();
- // Number of channels
- mp4config.channels = u16in();
- // Sample size (bits)
- mp4config.bits = u16in();
- // Compression ID
- u16in();
- // Packet size
- u16in();
- // Sample rate (16.16)
- // fractional framerate, probably not for audio
- // rate integer part
- u16in();
- // rate reminder part
- u16in();
-
- return size;
-}
-
-
-static uint32_t getsize(void)
-{
- int cnt;
- uint32_t size = 0;
- for (cnt = 0; cnt < 4; cnt++)
- {
- int tmp = u8in();
-
- size <<= 7;
- size |= (tmp & 0x7f);
- if (!(tmp & 0x80))
- break;
- }
- return size;
-}
-
-static int esdsin(int size)
-{
- // descriptor tree:
- // MP4ES_Descriptor
- // MP4DecoderConfigDescriptor
- // MP4DecSpecificInfoDescriptor
- // MP4SLConfigDescriptor
- enum
- { TAG_ES = 3, TAG_DC = 4, TAG_DSI = 5, TAG_SLC = 6 };
-
- // version/flags
- u32in();
- if (u8in() != TAG_ES)
- return ERR_FAIL;
- getsize();
- // ESID
- u16in();
- // flags(url(bit 6); ocr(5); streamPriority (0-4)):
- u8in();
-
- if (u8in() != TAG_DC)
- return ERR_FAIL;
- getsize();
- if (u8in() != 0x40) /* not MPEG-4 audio */
- return ERR_FAIL;
- // flags
- u8in();
- // buffer size (24 bits)
- mp4config.buffersize = u16in() << 8;
- mp4config.buffersize |= u8in();
- // bitrate
- mp4config.bitratemax = u32in();
- mp4config.bitrateavg = u32in();
-
- if (u8in() != TAG_DSI)
- return ERR_FAIL;
- mp4config.asc.size = getsize();
- if (mp4config.asc.size > sizeof(mp4config.asc.buf))
- return ERR_FAIL;
- // get AudioSpecificConfig
- datain(mp4config.asc.buf, mp4config.asc.size);
-
- if (u8in() != TAG_SLC)
- return ERR_FAIL;
- getsize();
- // "predefined" (no idea)
- u8in();
-
- return size;
-}
-
-static int sttsin(int size)
-{
- if (size < 16) //min stts size
- return ERR_FAIL;
-
- return size;
-}
-
-static int stszin(int size)
-{
- int cnt;
- uint32_t ofs;
-
- // version/flags
- u32in();
- // Sample size
- u32in();
- // Number of entries
- mp4config.frame.ents = u32in();
-
- if (!(mp4config.frame.ents + 1))
- return ERR_FAIL;
-
- mp4config.frame.data = malloc(sizeof(*mp4config.frame.data)
- * (mp4config.frame.ents + 1));
-
- if (!mp4config.frame.data)
- return ERR_FAIL;
-
- ofs = 0;
- mp4config.frame.data[0] = ofs;
- for (cnt = 0; cnt < mp4config.frame.ents; cnt++)
- {
- uint32_t fsize = u32in();
-
- ofs += fsize;
- if (mp4config.frame.maxsize < fsize)
- mp4config.frame.maxsize = fsize;
-
- mp4config.frame.data[cnt + 1] = ofs;
-
- if (ofs < mp4config.frame.data[cnt])
- return ERR_FAIL;
- }
-
- return size;
-}
-
-static int stcoin(int size)
-{
- // version/flags
- u32in();
- // Number of entries
- if (u32in() < 1)
- return ERR_FAIL;
- // first chunk offset
- mp4config.mdatofs = u32in();
- // ignore the rest
-
- return size;
-}
-
-#if 0
-static int tagtxt(char *tagname, const char *tagtxt)
-{
- //int txtsize = strlen(tagtxt);
- int size = 0;
- //int datasize = txtsize + 16;
-
-#if 0
- size += u32out(datasize + 8);
- size += dataout(tagname, 4);
- size += u32out(datasize);
- size += dataout("data", 4);
- size += u32out(1);
- size += u32out(0);
- size += dataout(tagtxt, txtsize);
-#endif
-
- return size;
-}
-
-static int tagu32(char *tagname, int n /*number of stored fields*/)
-{
- //int numsize = n * 4;
- int size = 0;
- //int datasize = numsize + 16;
-
-#if 0
- size += u32out(datasize + 8);
- size += dataout(tagname, 4);
- size += u32out(datasize);
- size += dataout("data", 4);
- size += u32out(0);
- size += u32out(0);
-#endif
-
- return size;
-}
-#endif
-
-static int metain(int size)
-{
- // version/flags
- u32in();
-
- return ERR_OK;
-};
-
-static int hdlr2in(int size)
-{
- uint8_t buf[4];
-
- // version/flags
- u32in();
- // Predefined
- u32in();
- // Handler type
- datain(buf, 4);
- if (memcmp(buf, "mdir", 4))
- return ERR_FAIL;
- datain(buf, 4);
- if (memcmp(buf, "appl", 4))
- return ERR_FAIL;
- // Reserved
- u32in();
- u32in();
- // null terminator
- u8in();
-
- return size;
-};
-
-static int ilstin(int size)
-{
- enum {NUMSET = 1, GENRE, EXTAG};
- int read = 0;
-
- static struct {
- char *name;
- char *id;
- int flag;
- } tags[] = {
- {"Album ", "\xa9" "alb"},
- {"Album Artist", "aART"},
- {"Artist ", "\xa9" "ART"},
- {"Comment ", "\xa9" "cmt"},
- {"Cover image ", "covr"},
- {"Compilation ", "cpil"},
- {"Copyright ", "cprt"},
- {"Date ", "\xa9" "day"},
- {"Disc# ", "disk", NUMSET},
- {"Genre ", "gnre", GENRE},
- {"Grouping ", "\xa9" "grp"},
- {"Lyrics ", "\xa9" "lyr"},
- {"Title ", "\xa9" "nam"},
- {"Rating ", "rtng"},
- {"BPM ", "tmpo"},
- {"Encoder ", "\xa9" "too"},
- {"Track ", "trkn", NUMSET},
- {"Composer ", "\xa9" "wrt"},
- {0, "----", EXTAG},
- {0},
- };
-
- static const char *genres[] = {
- "Blues", "Classic Rock", "Country", "Dance",
- "Disco", "Funk", "Grunge", "Hip-Hop",
- "Jazz", "Metal", "New Age", "Oldies",
- "Other", "Pop", "R&B", "Rap",
- "Reggae", "Rock", "Techno", "Industrial",
- "Alternative", "Ska", "Death Metal", "Pranks",
- "Soundtrack", "Euro-Techno", "Ambient", "Trip-Hop",
- "Vocal", "Jazz+Funk", "Fusion", "Trance",
- "Classical", "Instrumental", "Acid", "House",
- "Game", "Sound Clip", "Gospel", "Noise",
- "Alternative Rock", "Bass", "Soul", "Punk",
- "Space", "Meditative", "Instrumental Pop", "Instrumental Rock",
- "Ethnic", "Gothic", "Darkwave", "Techno-Industrial",
- "Electronic", "Pop-Folk", "Eurodance", "Dream",
- "Southern Rock", "Comedy", "Cult", "Gangsta",
- "Top 40", "Christian Rap", "Pop/Funk", "Jungle",
- "Native US", "Cabaret", "New Wave", "Psychadelic",
- "Rave", "Showtunes", "Trailer", "Lo-Fi",
- "Tribal", "Acid Punk", "Acid Jazz", "Polka",
- "Retro", "Musical", "Rock & Roll", "Hard Rock",
- "Folk", "Folk-Rock", "National Folk", "Swing",
- "Fast Fusion", "Bebob", "Latin", "Revival",
- "Celtic", "Bluegrass", "Avantgarde", "Gothic Rock",
- "Progressive Rock", "Psychedelic Rock", "Symphonic Rock", "Slow Rock",
- "Big Band", "Chorus", "Easy Listening", "Acoustic",
- "Humour", "Speech", "Chanson", "Opera",
- "Chamber Music", "Sonata", "Symphony", "Booty Bass",
- "Primus", "Porn Groove", "Satire", "Slow Jam",
- "Club", "Tango", "Samba", "Folklore",
- "Ballad", "Power Ballad", "Rhythmic Soul", "Freestyle",
- "Duet", "Punk Rock", "Drum Solo", "Acapella",
- "Euro-House", "Dance Hall", "Goa", "Drum & Bass",
- "Club - House", "Hardcore", "Terror", "Indie",
- "BritPop", "Negerpunk", "Polsk Punk", "Beat",
- "Christian Gangsta Rap", "Heavy Metal", "Black Metal", "Crossover",
- "Contemporary Christian", "Christian Rock", "Merengue", "Salsa",
- "Thrash Metal", "Anime", "JPop", "Synthpop",
- "Unknown",
- };
-
- fprintf(stderr, "----------tag list-------------\n");
- while(read < size)
- {
- int asize, dsize;
- uint8_t id[5];
- int cnt;
- uint32_t type;
-
- id[4] = 0;
-
- asize = u32in();
- read += asize;
- asize -= 4;
- if (datain(id, 4) < 4)
- return ERR_FAIL;
- asize -= 4;
-
- for (cnt = 0; tags[cnt].id; cnt++)
- {
- if (!memcmp(id, tags[cnt].id, 4))
- break;
- }
-
- if (tags[cnt].name)
- fprintf(stderr, "%s : ", tags[cnt].name);
- else
- {
- if (tags[cnt].flag != EXTAG)
- fprintf(stderr, "'%s' : ", id);
- }
-
- dsize = u32in();
- asize -= 4;
- if (datain(id, 4) < 4)
- return ERR_FAIL;
- asize -= 4;
-
- if (tags[cnt].flag != EXTAG)
- {
- if (memcmp(id, "data", 4))
- return ERR_FAIL;
- }
- else
- {
- int spc;
-
- if (memcmp(id, "mean", 4))
- goto skip;
- dsize -= 8;
- while (dsize > 0)
- {
- u8in();
- asize--;
- dsize--;
- }
- if (asize >= 8)
- {
- dsize = u32in() - 8;
- asize -= 4;
- if (datain(id, 4) < 4)
- return ERR_FAIL;
- asize -= 4;
- if (memcmp(id, "name", 4))
- goto skip;
- u32in();
- asize -= 4;
- dsize -= 4;
- }
- spc = 13 - dsize;
- if (spc < 0) spc = 0;
- while (dsize > 0)
- {
- fprintf(stderr, "%c",u8in());
- asize--;
- dsize--;
- }
- while (spc--)
- fprintf(stderr, " ");
- fprintf(stderr, ": ");
- if (asize >= 8)
- {
- dsize = u32in() - 8;
- asize -= 4;
- if (datain(id, 4) < 4)
- return ERR_FAIL;
- asize -= 4;
- if (memcmp(id, "data", 4))
- goto skip;
- u32in();
- asize -= 4;
- dsize -= 4;
- }
- while (dsize > 0)
- {
- fprintf(stderr, "%c",u8in());
- asize--;
- dsize--;
- }
- fprintf(stderr, "\n");
-
- goto skip;
- }
- type = u32in();
- asize -= 4;
- u32in();
- asize -= 4;
-
- switch(type)
- {
- case 1:
- while (asize > 0)
- {
- fprintf(stderr, "%c",u8in());
- asize--;
- }
- break;
- case 0:
- switch(tags[cnt].flag)
- {
- case NUMSET:
- u16in();
- asize -= 2;
-
- fprintf(stderr, "%d", u16in());
- asize -= 2;
- fprintf(stderr, "/%d", u16in());
- asize -= 2;
- break;
- case GENRE:
- {
- uint8_t gnum = u16in();
- asize -= 2;
- if (!gnum)
- goto skip;
- gnum--;
- if (gnum >= 147)
- gnum = 147;
- fprintf(stderr, "%s", genres[gnum]);
- }
- break;
- default:
- while(asize > 0)
- {
- fprintf(stderr, "%d/", u16in());
- asize-=2;
- }
- }
- break;
- case 0x15:
- //fprintf(stderr, "(8bit data)");
- while(asize > 0)
- {
- fprintf(stderr, "%d", u8in());
- asize--;
- if (asize)
- fprintf(stderr, "/");
- }
- break;
- case 0xd:
- fprintf(stderr, "(image data)");
- break;
- default:
- fprintf(stderr, "(unknown data type)");
- break;
- }
- fprintf(stderr, "\n");
-
- skip:
- // skip to the end of atom
- while (asize > 0)
- {
- u8in();
- asize--;
- }
- }
- fprintf(stderr, "-------------------------------\n");
-
- return size;
-};
-
-static creator_t *g_atom = 0;
-static int parse(uint32_t *sizemax)
-{
- long apos = 0;
- long aposmax = ftell(g_fin) + *sizemax;
- uint32_t size;
-
- if (g_atom->opcode != ATOM_NAME)
- {
- fprintf(stderr, "parse error: root is not a 'name' opcode\n");
- return ERR_FAIL;
- }
- //fprintf(stderr, "looking for '%s'\n", (char *)g_atom->data);
-
- // search for atom in the file
- while (1)
- {
- char name[4];
- uint32_t tmp;
-
- apos = ftell(g_fin);
- if (apos >= (aposmax - 8))
- {
- fprintf(stderr, "parse error: atom '%s' not found\n", (char *)g_atom->data);
- return ERR_FAIL;
- }
- if ((tmp = u32in()) < 8)
- {
- fprintf(stderr, "invalid atom size %x @%lx\n", tmp, ftell(g_fin));
- return ERR_FAIL;
- }
-
- size = tmp;
- if (datain(name, 4) != 4)
- {
- // EOF
- fprintf(stderr, "can't read atom name @%lx\n", ftell(g_fin));
- return ERR_FAIL;
- }
-
- //fprintf(stderr, "atom: '%c%c%c%c'(%x)", name[0],name[1],name[2],name[3], size);
-
- if (!memcmp(name, g_atom->data, 4))
- {
- //fprintf(stderr, "OK\n");
- break;
- }
- //fprintf(stderr, "\n");
-
- fseek(g_fin, apos + size, SEEK_SET);
- }
- *sizemax = size;
- g_atom++;
- if (g_atom->opcode == ATOM_DATA)
- {
- int err = ((int (*)(int)) g_atom->data)(size - 8);
- if (err < ERR_OK)
- {
- fseek(g_fin, apos + size, SEEK_SET);
- return err;
- }
- g_atom++;
- }
- if (g_atom->opcode == ATOM_DESCENT)
- {
- long apos = ftell(g_fin);;
-
- //fprintf(stderr, "descent\n");
- g_atom++;
- while (g_atom->opcode != ATOM_STOP)
- {
- uint32_t subsize = size - 8;
- int ret;
- if (g_atom->opcode == ATOM_ASCENT)
- {
- g_atom++;
- break;
- }
- fseek(g_fin, apos, SEEK_SET);
- if ((ret = parse(&subsize)) < 0)
- return ret;
- }
- //fprintf(stderr, "ascent\n");
- }
-
- fseek(g_fin, apos + size, SEEK_SET);
-
- return ERR_OK;
-}
-
-
-
-static int moovin(int sizemax)
-{
- long apos = ftell(g_fin);
- uint32_t atomsize;
- creator_t *old_atom = g_atom;
- int err, ret = sizemax;
-
- static creator_t mvhd[] = {
- {ATOM_NAME, "mvhd"},
- {0}
- };
- static creator_t trak[] = {
- {ATOM_NAME, "trak"},
- {ATOM_DESCENT},
- {ATOM_NAME, "tkhd"},
- {ATOM_NAME, "mdia"},
- {ATOM_DESCENT},
- {ATOM_NAME, "mdhd"},
- {ATOM_DATA, mdhdin},
- {ATOM_NAME, "hdlr"},
- {ATOM_DATA, hdlr1in},
- {ATOM_NAME, "minf"},
- {ATOM_DESCENT},
- {ATOM_NAME, "smhd"},
- {ATOM_NAME, "dinf"},
- {ATOM_NAME, "stbl"},
- {ATOM_DESCENT},
- {ATOM_NAME, "stsd"},
- {ATOM_DATA, stsdin},
- {ATOM_DESCENT},
- {ATOM_NAME, "mp4a"},
- {ATOM_DATA, mp4ain},
- {ATOM_DESCENT},
- {ATOM_NAME, "esds"},
- {ATOM_DATA, esdsin},
- {ATOM_ASCENT},
- {ATOM_ASCENT},
- {ATOM_NAME, "stts"},
- {ATOM_DATA, sttsin},
- {ATOM_NAME, "stsc"},
- {ATOM_NAME, "stsz"},
- {ATOM_DATA, stszin},
- {ATOM_NAME, "stco"},
- {ATOM_DATA, stcoin},
- {0}
- };
-
- g_atom = mvhd;
- atomsize = sizemax + apos - ftell(g_fin);
- if (parse(&atomsize) < 0) {
- g_atom = old_atom;
- return ERR_FAIL;
- }
-
- fseek(g_fin, apos, SEEK_SET);
-
- while (1)
- {
- //fprintf(stderr, "TRAK\n");
- g_atom = trak;
- atomsize = sizemax + apos - ftell(g_fin);
- if (atomsize < 8)
- break;
- //fprintf(stderr, "PARSE(%x)\n", atomsize);
- err = parse(&atomsize);
- //fprintf(stderr, "SIZE: %x/%x\n", atomsize, sizemax);
- if (err >= 0)
- break;
- if (err != ERR_UNSUPPORTED) {
- ret = err;
- break;
- }
- //fprintf(stderr, "UNSUPP\n");
- }
-
- g_atom = old_atom;
- return ret;
-}
-
-
-static creator_t g_head[] = {
- {ATOM_NAME, "ftyp"},
- {ATOM_DATA, ftypin},
- {0}
-};
-
-static creator_t g_moov[] = {
- {ATOM_NAME, "moov"},
- {ATOM_DATA, moovin},
- //{ATOM_DESCENT},
- //{ATOM_NAME, "mvhd"},
- {0}
-};
-
-static creator_t g_meta1[] = {
- {ATOM_NAME, "moov"},
- {ATOM_DESCENT},
- {ATOM_NAME, "udta"},
- {ATOM_DESCENT},
- {ATOM_NAME, "meta"},
- {ATOM_DATA, metain},
- {ATOM_DESCENT},
- {ATOM_NAME, "hdlr"},
- {ATOM_DATA, hdlr2in},
- {ATOM_NAME, "ilst"},
- {ATOM_DATA, ilstin},
- {0}
-};
-
-static creator_t g_meta2[] = {
- {ATOM_NAME, "meta"},
- {ATOM_DATA, metain},
- {ATOM_DESCENT},
- {ATOM_NAME, "hdlr"},
- {ATOM_DATA, hdlr2in},
- {ATOM_NAME, "ilst"},
- {ATOM_DATA, ilstin},
- {0}
-};
-
-
-int mp4read_frame(void)
-{
- if (mp4config.frame.current >= mp4config.frame.ents)
- return ERR_FAIL;
-
- mp4config.bitbuf.size = mp4config.frame.data[mp4config.frame.current + 1]
- - mp4config.frame.data[mp4config.frame.current];
-
- if (fread(mp4config.bitbuf.data, 1, mp4config.bitbuf.size, g_fin)
- != mp4config.bitbuf.size)
- {
- fprintf(stderr, "can't read frame data(frame %d@0x%x)\n",
- mp4config.frame.current,
- mp4config.frame.data[mp4config.frame.current]);
-
- return ERR_FAIL;
- }
-
- mp4config.frame.current++;
-
- return ERR_OK;
-}
-
-int mp4read_seek(int framenum)
-{
- if (framenum > mp4config.frame.ents)
- return ERR_FAIL;
- if (fseek(g_fin, mp4config.mdatofs + mp4config.frame.data[framenum], SEEK_SET))
- return ERR_FAIL;
-
- mp4config.frame.current = framenum;
-
- return ERR_OK;
-}
-
-static void mp4info(void)
-{
- fprintf(stderr, "Modification Time:\t\t%s\n", mp4time(mp4config.mtime));
- fprintf(stderr, "Samplerate:\t\t%d\n", mp4config.samplerate);
- fprintf(stderr, "Total samples:\t\t%d\n", mp4config.samples);
- fprintf(stderr, "Total channels:\t\t%d\n", mp4config.channels);
- fprintf(stderr, "Bits per sample:\t%d\n", mp4config.bits);
- fprintf(stderr, "Buffer size:\t\t%d\n", mp4config.buffersize);
- fprintf(stderr, "Max bitrate:\t\t%d\n", mp4config.bitratemax);
- fprintf(stderr, "Average bitrate:\t%d\n", mp4config.bitrateavg);
- fprintf(stderr, "Samples per frame:\t%d\n", mp4config.framesamples);
- fprintf(stderr, "Frames:\t\t\t%d\n", mp4config.frame.ents);
- fprintf(stderr, "ASC size:\t\t%d\n", mp4config.asc.size);
- fprintf(stderr, "Duration:\t\t%.1f sec\n", (float)mp4config.samples/mp4config.samplerate);
- fprintf(stderr, "Data offset/size:\t%x/%x\n", mp4config.mdatofs, mp4config.mdatsize);
-}
-
-int mp4read_close(void)
-{
-#define FREE(x) if(x){free(x);x=0;}
- FREE(mp4config.frame.data);
- FREE(mp4config.bitbuf.data);
-
- return ERR_OK;
-}
-
-int mp4read_open(char *name)
-{
- uint32_t atomsize;
- int ret;
-
- mp4read_close();
-
- g_fin = faad_fopen(name, "rb");
- if (!g_fin)
- return ERR_FAIL;
-
- if (mp4config.verbose.header)
- fprintf(stderr, "**** MP4 header ****\n");
- g_atom = g_head;
- atomsize = INT_MAX;
- if (parse(&atomsize) < 0)
- goto err;
- g_atom = g_moov;
- atomsize = INT_MAX;
- rewind(g_fin);
- if ((ret = parse(&atomsize)) < 0)
- {
- fprintf(stderr, "parse:%d\n", ret);
- goto err;
- }
-
- // alloc frame buffer
- mp4config.bitbuf.data = malloc(mp4config.frame.maxsize);
-
- if (!mp4config.bitbuf.data)
- goto err;
-
- if (mp4config.verbose.header)
- {
- mp4info();
- fprintf(stderr, "********************\n");
- }
-
- if (mp4config.verbose.tags)
- {
- rewind(g_fin);
- g_atom = g_meta1;
- atomsize = INT_MAX;
- ret = parse(&atomsize);
- if (ret < 0)
- {
- rewind(g_fin);
- g_atom = g_meta2;
- atomsize = INT_MAX;
- ret = parse(&atomsize);
- }
- }
-
- return ERR_OK;
-err:
- mp4read_close();
- return ERR_FAIL;
-}
--- a/frontend/mp4read.h
+++ /dev/null
@@ -1,77 +1,0 @@
-/****************************************************************************
- MP4 input module
-
- Copyright (C) 2017 Krzysztof Nikiel
-
- 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 3 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, see <http://www.gnu.org/licenses/>.
-****************************************************************************/
-
-#ifdef __plan9__
-typedef u8int uint8_t;
-typedef u16int uint16_t;
-typedef u32int uint32_t;
-typedef u64int uint64_t;
-typedef s64int int64_t;
-typedef long time_t;
-typedef long clock_t;
-#define clock() (nsec()/1000000ULL)
-#define CLOCKS_PER_SEC 1000ULL
-#define INT_MAX 0x7fffffff
-#endif
-
-typedef struct
-{
- uint32_t ctime, mtime;
- uint32_t samplerate;
- // total sound samples
- uint32_t samples;
- uint32_t channels;
- // sample depth
- uint32_t bits;
- // buffer config
- uint16_t buffersize;
- uint32_t bitratemax;
- uint32_t bitrateavg;
- uint32_t framesamples;
- struct
- {
- uint32_t *data;
- uint32_t ents;
- int current;
- int maxsize;
- } frame;
- // AudioSpecificConfig data:
- struct
- {
- uint8_t buf[10];
- int size;
- } asc;
- uint32_t mdatofs;
- uint32_t mdatsize;
- struct {
- int size;
- uint8_t *data;
- } bitbuf;
- struct {
- int header;
- int tags;
- } verbose;
-} mp4config_t;
-
-extern mp4config_t mp4config;
-
-int mp4read_open(char *name);
-int mp4read_seek(int framenum);
-int mp4read_frame(void);
-int mp4read_close(void);
--- a/frontend/unicode_support.c
+++ /dev/null
@@ -1,172 +1,0 @@
-/* Copyright (c) 2004-2012 LoRd_MuldeR <mulder2@gmx.de>
- File: unicode_support.c
-
- This file was originally part of a patch included with LameXP,
- released under the same license as the original audio tools.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- - Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- - Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-#if defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64
-
-#include "unicode_support.h"
-
-#include <windows.h>
-#include <io.h>
-
-static UINT g_old_output_cp = ((UINT)-1);
-
-char *utf16_to_utf8(const wchar_t *input)
-{
- char *Buffer;
- int BuffSize = 0, Result = 0;
-
- BuffSize = WideCharToMultiByte(CP_UTF8, 0, input, -1, NULL, 0, NULL, NULL);
- Buffer = (char*) malloc(sizeof(char) * BuffSize);
- if(Buffer)
- {
- Result = WideCharToMultiByte(CP_UTF8, 0, input, -1, Buffer, BuffSize, NULL, NULL);
- }
-
- return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL;
-}
-
-char *utf16_to_ansi(const wchar_t *input)
-{
- char *Buffer;
- int BuffSize = 0, Result = 0;
-
- BuffSize = WideCharToMultiByte(CP_ACP, 0, input, -1, NULL, 0, NULL, NULL);
- Buffer = (char*) malloc(sizeof(char) * BuffSize);
- if(Buffer)
- {
- Result = WideCharToMultiByte(CP_ACP, 0, input, -1, Buffer, BuffSize, NULL, NULL);
- }
-
- return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL;
-}
-
-wchar_t *utf8_to_utf16(const char *input)
-{
- wchar_t *Buffer;
- int BuffSize = 0, Result = 0;
-
- BuffSize = MultiByteToWideChar(CP_UTF8, 0, input, -1, NULL, 0);
- Buffer = (wchar_t*) malloc(sizeof(wchar_t) * BuffSize);
- if(Buffer)
- {
- Result = MultiByteToWideChar(CP_UTF8, 0, input, -1, Buffer, BuffSize);
- }
-
- return ((Result > 0) && (Result <= BuffSize)) ? Buffer : NULL;
-}
-
-void init_commandline_arguments_utf8(int *argc, char ***argv)
-{
- int i, nArgs;
- LPWSTR *szArglist;
-
- szArglist = CommandLineToArgvW(GetCommandLineW(), &nArgs);
-
- if(NULL == szArglist)
- {
- fprintf(stderr, "\nFATAL: CommandLineToArgvW failed\n\n");
- exit(-1);
- }
-
- *argv = (char**) malloc(sizeof(char*) * nArgs);
- *argc = nArgs;
-
- if(NULL == *argv)
- {
- fprintf(stderr, "\nFATAL: Malloc failed\n\n");
- exit(-1);
- }
-
- for(i = 0; i < nArgs; i++)
- {
- (*argv)[i] = utf16_to_utf8(szArglist[i]);
- if(NULL == (*argv)[i])
- {
- fprintf(stderr, "\nFATAL: utf16_to_utf8 failed\n\n");
- exit(-1);
- }
- }
-
- LocalFree(szArglist);
-}
-
-void free_commandline_arguments_utf8(int *argc, char ***argv)
-{
- int i = 0;
-
- if(*argv != NULL)
- {
- for(i = 0; i < *argc; i++)
- {
- if((*argv)[i] != NULL)
- {
- free((*argv)[i]);
- (*argv)[i] = NULL;
- }
- }
- free(*argv);
- *argv = NULL;
- }
-}
-
-FILE *fopen_utf8(const char *filename_utf8, const char *mode_utf8)
-{
- FILE *ret = NULL;
- wchar_t *filename_utf16 = utf8_to_utf16(filename_utf8);
- wchar_t *mode_utf16 = utf8_to_utf16(mode_utf8);
-
- if(filename_utf16 && mode_utf16)
- {
- ret = _wfopen(filename_utf16, mode_utf16);
- }
-
- if(filename_utf16) free(filename_utf16);
- if(mode_utf16) free(mode_utf16);
-
- return ret;
-}
-
-void init_console_utf8(FILE *const stream)
-{
- if (_isatty(_fileno(stream)))
- {
- g_old_output_cp = GetConsoleOutputCP();
- SetConsoleOutputCP(CP_UTF8);
- }
-}
-
-void uninit_console_utf8(void)
-{
- if(g_old_output_cp != ((UINT)-1))
- {
- SetConsoleOutputCP(g_old_output_cp);
- }
-}
-
-#endif
\ No newline at end of file
--- a/frontend/unicode_support.h
+++ /dev/null
@@ -1,47 +1,0 @@
-/* Copyright (c) 2004-2012 LoRd_MuldeR <mulder2@gmx.de>
- File: unicode_support.h
-
- This file was originally part of a patch included with LameXP,
- released under the same license as the original audio tools.
-
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions
- are met:
-
- - Redistributions of source code must retain the above copyright
- notice, this list of conditions and the following disclaimer.
-
- - Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in the
- documentation and/or other materials provided with the distribution.
-
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR
- CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-*/
-#ifndef UNICODE_SUPPORT_H_INCLUDED
-#define UNICODE_SUPPORT_H_INCLUDED
-
-#if defined WIN32 || defined _WIN32 || defined WIN64 || defined _WIN64
-char *utf16_to_utf8(const wchar_t *input);
-char *utf16_to_ansi(const wchar_t *input);
-wchar_t *utf8_to_utf16(const char *input);
-void init_commandline_arguments_utf8(int *argc, char ***argv);
-void free_commandline_arguments_utf8(int *argc, char ***argv);
-FILE *fopen_utf8(const char *filename_utf8, const char *mode_utf8);
-void init_console_utf8(FILE *const stream);
-void uninit_console_utf8(void);
-#define faad_fopen(X,Y) fopen_utf8((X),(Y))
-#else
-#define faad_fopen(X,Y) fopen((X),(Y))
-#endif
-
-#endif //UNICODE_SUPPORT_H_INCLUDED
--- a/libfaad/ps_dec.c
+++ b/libfaad/ps_dec.c
@@ -1505,8 +1505,6 @@
beta = alpha * ( c_1 - c_2 ) / sqrt(2.0);
*/
- //printf("%d\n", ps->iid_index[env][bk]);
-
/* index range is supposed to be -7...7 or -15...15 depending on iid_mode
(Table 8.24, ISO/IEC 14496-3:2005).
if it is outside these boundaries, this is most likely an error. sanitize