ref: 86551c041655e0e31b1c8e40efdcf58db76de981
parent: 3cb3f492ded0659b8b7ecbbd1ec3de9159ef6d7a
author: knik <knik>
date: Mon Aug 18 03:25:03 EDT 2003
second CLI frontend cloned from main.c
--- a/frontend/Makefile.am
+++ b/frontend/Makefile.am
@@ -1,6 +1,6 @@
bin_PROGRAMS = faac
-faac_SOURCES = main.c input.c
+faac_SOURCES = faac.c input.c
CXXFLAGS = -O2
CFLAGS = -O2 -Wall
--- /dev/null
+++ b/frontend/faac.c
@@ -1,0 +1,574 @@
+/*
+ * FAAC - Freeware Advanced Audio Coder
+ * Copyright (C) 2001 Menno Bakker
+ * Copyright (C) 2002,2003 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 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
+ *
+ * $Id: faac.c,v 1.1 2003/08/18 07:25:03 knik Exp $
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define DEFAULT_TNS 0
+
+#ifdef WIN32
+#include <windows.h>
+#include <fcntl.h>
+#endif
+
+#ifdef __unix__
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <unistd.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <math.h>
+
+#ifdef HAVE_GETOPT_H
+# include <getopt.h>
+#else
+# include "getopt.h"
+# include "getopt.c"
+#endif
+
+#include "input.h"
+
+#include <faac.h>
+
+#ifndef min
+#define min(a,b) ( (a) < (b) ? (a) : (b) )
+#endif
+
+/* globals */
+char* progName;
+
+
+static int *mkChanMap(int channels, int center, int lf)
+{
+ int *map;
+ int inpos;
+ int outpos;
+
+ if (!center && !lf)
+ return NULL;
+
+ if (channels < 3)
+ return NULL;
+
+ if (lf > 0)
+ lf--;
+ else
+ lf = channels - 1; // default AAC position
+
+ if (center > 0)
+ center--;
+ else
+ center = 0; // default AAC position
+
+ map = malloc(channels * sizeof(map[0]));
+ memset(map, 0, channels * sizeof(map[0]));
+
+ outpos = 0;
+ if ((center >= 0) && (center < channels))
+ map[outpos++] = center;
+
+ inpos = 0;
+ for (; outpos < (channels - 1); inpos++)
+ {
+ if (inpos == center)
+ continue;
+ if (inpos == lf)
+ continue;
+
+ map[outpos++] = inpos;
+ }
+ if (outpos < channels)
+ {
+ if ((lf >= 0) && (lf < channels))
+ map[outpos] = lf;
+ else
+ map[outpos] = inpos;
+ }
+
+ return map;
+}
+
+int main(int argc, char *argv[])
+{
+ int frames, currentFrame;
+ faacEncHandle hEncoder;
+ pcmfile_t *infile = NULL;
+
+ unsigned long samplesInput, maxBytesOutput;
+
+ faacEncConfigurationPtr myFormat;
+ unsigned int mpegVersion = MPEG2;
+ unsigned int objectType = LOW;
+ unsigned int useMidSide = 1;
+ static unsigned int useTns = DEFAULT_TNS;
+ unsigned int useAdts = 1;
+ int cutOff = -1;
+ int bitRate = 0;
+ unsigned long quantqual = 0;
+ int chanC = 3;
+ int chanLF = 4;
+ int addsilent = 1;
+
+ char *audioFileName;
+ char *aacFileName;
+
+ int32_t *pcmbuf;
+ int *chanmap = NULL;
+
+ unsigned char *bitbuf;
+ int samplesRead = 0;
+ int dieUsage = 0;
+
+ int rawChans = 0; // disabled by default
+ int rawBits = 16;
+ int rawRate = 44100;
+
+ FILE *outfile;
+
+ // get faac version
+ hEncoder = faacEncOpen(44100, 2, &samplesInput, &maxBytesOutput);
+ myFormat = faacEncGetCurrentConfiguration(hEncoder);
+ if (myFormat->version == FAAC_CFG_VERSION)
+ {
+ fprintf(stderr, "%s(see the faac.html file for more details)\n\n",
+ myFormat->copyright);
+ fprintf(stderr, "libfaac version %s\n", myFormat->name);
+ faacEncClose(hEncoder);
+ }
+ else
+ {
+ fprintf(stderr, __FILE__ "(%d): wrong libfaac version\n", __LINE__);
+ faacEncClose(hEncoder);
+ return 1;
+ }
+
+ /* begin process command line */
+ progName = argv[0];
+ while (1) {
+ static struct option long_options[] = {
+ { "mpeg", 0, 0, 'm' },
+ { "objecttype", 0, 0, 'o' },
+ { "raw", 0, 0, 'r' },
+ { "nomidside", 0, 0, 'n' },
+ { "tns", 0, &useTns, 1 },
+ { "notns", 0, &useTns, 0 },
+ { "cutoff", 1, 0, 'c' },
+ { "quality", 1, 0, 'q' },
+ { "pcmraw", 0, 0, 'P'},
+ { "pcmsamplerate", 1, 0, 'R'},
+ { "pcmsamplebits", 1, 0, 'B'},
+ { "pcmchannels", 1, 0, 'C'},
+ { "addsilent", 1, 0, 300},
+ { 0, 0, 0, 0}
+ };
+ int c = -1;
+ int option_index = 0;
+
+ c = getopt_long(argc, argv, "a:m:o:rnc:q:PR:B:C:I:",
+ long_options, &option_index);
+
+ if (c == -1)
+ break;
+
+ if (!c)
+ continue;
+
+ switch (c) {
+ case 'm':
+ mpegVersion = atoi(optarg);
+ switch(mpegVersion)
+ {
+ case 2:
+ mpegVersion = MPEG2;
+ break;
+ case 4:
+ mpegVersion = MPEG4;
+ break;
+ default:
+ mpegVersion = MPEG4;
+ }
+ break;
+ case 'o':
+ objectType = atoi(optarg);
+ switch (objectType)
+ {
+ case 1:
+ objectType = MAIN;
+ break;
+ case 2:
+ objectType = LTP;
+ break;
+ default:
+ objectType = LOW;
+ break;
+ }
+ break;
+ case 'r': {
+ useAdts = 0;
+ break;
+ }
+ case 'n': {
+ useMidSide = 0;
+ break;
+ }
+ case 'c': {
+ unsigned int i;
+ if (sscanf(optarg, "%u", &i) > 0) {
+ cutOff = i;
+ }
+ break;
+ }
+ case 'a': {
+ unsigned int i;
+ if (sscanf(optarg, "%u", &i) > 0)
+ {
+ bitRate = 1000 * i;
+ }
+ break;
+ }
+ case 'q':
+ {
+ unsigned int i;
+ if (sscanf(optarg, "%u", &i) > 0)
+ {
+ if (i > 0 && i < 1000)
+ quantqual = i;
+ }
+ break;
+ }
+ case 'I':
+ sscanf(optarg, "%d,%d", &chanC, &chanLF);
+ break;
+ case 'P':
+ rawChans = 2; // enable raw input
+ break;
+ case 'R':
+ {
+ unsigned int i;
+ if (sscanf(optarg, "%u", &i) > 0)
+ {
+ rawRate = i;
+ rawChans = (rawChans > 0) ? rawChans : 2;
+ }
+ break;
+ }
+ case 'B':
+ {
+ unsigned int i;
+ if (sscanf(optarg, "%u", &i) > 0)
+ {
+ if (i > 32)
+ i = 32;
+ if (i < 8)
+ i = 8;
+ rawBits = i;
+ rawChans = (rawChans > 0) ? rawChans : 2;
+ }
+ break;
+ }
+ case 'C':
+ {
+ unsigned int i;
+ if (sscanf(optarg, "%u", &i) > 0)
+ rawChans = i;
+ break;
+ }
+ case 300:
+ sscanf(optarg, "%u", &addsilent);
+ break;
+ case '?':
+ break;
+ default:
+ fprintf(stderr, "%s: unknown option specified, ignoring: %c\n",
+ progName, c);
+ }
+ }
+
+ /* check that we have at least two non-option arguments */
+ if ((argc - optind) < 2 || dieUsage == 1)
+ {
+ printf("\nUsage: %s -options infile outfile\n", progName);
+ printf("Options:\n");
+ printf(" -a <x>\tSet average bitrate to approximately x kbps/channel.\n");
+ printf(" -c <bandwidth>\tSet the bandwidth in Hz. (default=automatic)\n");
+ printf(" -q <quality>\tSet quantizer quality.\n");
+#if !DEFAULT_TNS
+ printf(" --tns \tEnable TNS coding.\n");
+#else
+ printf(" --notns\tDisable TNS coding.\n");
+#endif
+ printf(" -n Don\'t use mid/side coding.\n");
+ printf(" -m X AAC MPEG version, X can be 2 or 4.\n");
+ printf(" -o X AAC object type. (0=Low Complexity (default), 1=Main, 2=LTP)\n");
+ printf(" -r RAW AAC output file.\n");
+ printf(" -P Raw PCM input mode (default 44100Hz 16bit stereo).\n");
+ printf(" -R Raw PCM input rate.\n");
+ printf(" -B Raw PCM input sample size (16 default or 8bits).\n");
+ printf(" -C Raw PCM input channels.\n");
+ printf(" -I <C,LF> Input channel config, default is 3,4 (Center third, LF fourth)\n");
+ printf(" --addsilent <n> Add n silent frames at the end of output (default=%d)\n",
+ addsilent);
+ //printf("More details on FAAC usage can be found in the faac.html file.\n");
+ printf("More tips on FAAC usage can be found in Knowledge base at www.audiocoding.com\n");
+
+ return 1;
+ }
+
+ /* point to the specified file names */
+ audioFileName = argv[optind++];
+ aacFileName = argv[optind++];
+
+ /* open the audio input file */
+ if (rawChans > 0) // use raw input
+ {
+ infile = wav_open_read(audioFileName, 1);
+ if (infile)
+ {
+ infile->channels = rawChans;
+ infile->samplebytes = rawBits / 8;
+ infile->samplerate = rawRate;
+ }
+ }
+ else // header input
+ infile = wav_open_read(audioFileName, 0);
+
+ if (infile == NULL)
+ {
+ fprintf(stderr, "Couldn't open input file %s\n", audioFileName);
+ return 1;
+ }
+
+ /* open the aac output file */
+ outfile = fopen(aacFileName, "wb");
+ if (!outfile)
+ {
+ fprintf(stderr, "Couldn't create output file %s\n", aacFileName);
+ return 1;
+ }
+
+ /* open the encoder library */
+ hEncoder = faacEncOpen(infile->samplerate, infile->channels,
+ &samplesInput, &maxBytesOutput);
+
+ pcmbuf = (int32_t *)malloc(samplesInput*sizeof(int32_t));
+ bitbuf = (unsigned char*)malloc(maxBytesOutput*sizeof(unsigned char));
+ chanmap = mkChanMap(infile->channels, chanC, chanLF);
+ if (chanmap)
+ {
+ fprintf(stderr, "Remapping input channels: Center=%d, LFE=%d\n",
+ chanC, chanLF);
+ }
+
+ if (cutOff <= 0)
+ {
+ if (cutOff < 0) // default
+ cutOff = 0;
+ else // disabled
+ cutOff = infile->samplerate / 2;
+ }
+ if (cutOff > (infile->samplerate / 2))
+ cutOff = infile->samplerate / 2;
+
+ /* put the options in the configuration struct */
+ myFormat = faacEncGetCurrentConfiguration(hEncoder);
+ myFormat->aacObjectType = objectType;
+ myFormat->mpegVersion = mpegVersion;
+ myFormat->useTns = useTns;
+ myFormat->allowMidside = useMidSide;
+ if (bitRate)
+ myFormat->bitRate = bitRate;
+ myFormat->bandWidth = cutOff;
+ if (quantqual > 0)
+ myFormat->quantqual = quantqual;
+ myFormat->outputFormat = useAdts;
+ if (!faacEncSetConfiguration(hEncoder, myFormat)) {
+ fprintf(stderr, "Unsupported output format!\n");
+ return 1;
+ }
+
+ cutOff = myFormat->bandWidth;
+ quantqual = myFormat->quantqual;
+ bitRate = myFormat->bitRate;
+ if (bitRate)
+ fprintf(stderr, "Approximate ABR: %d kbps/channel\n", bitRate/1000);
+ fprintf(stderr, "Quantization quality: %ld\n", quantqual);
+ fprintf(stderr, "Bandwidth: %d Hz\n", cutOff);
+ fprintf(stderr, "Object type: ");
+ switch(objectType)
+ {
+ case LOW:
+ fprintf(stderr, "Low Complexity");
+ break;
+ case MAIN:
+ fprintf(stderr, "Main");
+ break;
+ case LTP:
+ fprintf(stderr, "LTP");
+ break;
+ }
+ fprintf(stderr, "(MPEG-%d)", (mpegVersion == MPEG4) ? 4 : 2);
+ if (myFormat->useTns)
+ fprintf(stderr, " + TNS");
+ if (myFormat->allowMidside)
+ fprintf(stderr, " + M/S");
+ fprintf(stderr, "\n");
+
+ if (outfile)
+ {
+ int showcnt = 0;
+#ifdef _WIN32
+ long begin = GetTickCount();
+#endif
+ if (infile->samples)
+ frames = (int)infile->samples / 1024 + 1 + addsilent;
+ else
+ frames = 0;
+ currentFrame = 0;
+
+ fprintf(stderr, "Encoding %s to %s\n", audioFileName, aacFileName);
+ if (frames != 0)
+ fprintf(stderr,
+ " frame | elapsed/estim | play/CPU | ETA\n");
+ else
+ fprintf(stderr,
+ " frame | elapsed | play/CPU\n");
+ /* encoding loop */
+ for ( ;; )
+ {
+ int bytesWritten;
+
+ samplesRead = wav_read_int24(infile, pcmbuf, samplesInput, chanmap);
+
+ if (!samplesRead)
+ {
+ if (addsilent)
+ {
+ addsilent--;
+ memset(pcmbuf, 0, samplesInput * sizeof(*pcmbuf));
+ samplesRead = samplesInput;
+ }
+ }
+
+ /* call the actual encoding routine */
+ bytesWritten = faacEncEncode(hEncoder,
+ pcmbuf,
+ samplesRead,
+ bitbuf,
+ maxBytesOutput);
+
+ if (bytesWritten)
+ {
+ currentFrame++;
+ showcnt--;
+ }
+
+ if ((showcnt <= 0) || !bytesWritten)
+ {
+ double timeused;
+#ifdef __unix__
+ struct rusage usage;
+#endif
+#ifdef _WIN32
+ char percent[MAX_PATH + 20];
+ timeused = (GetTickCount() - begin) * 1e-3;
+#else
+#ifdef __unix__
+ if (getrusage(RUSAGE_SELF, &usage) == 0) {
+ timeused = (double)usage.ru_utime.tv_sec +
+ (double)usage.ru_utime.tv_usec * 1e-6;
+ }
+ else
+ timeused = 0;
+#else
+ timeused = (double)clock() * (1.0 / CLOCKS_PER_SEC);
+#endif
+#endif
+ if (currentFrame && (timeused > 0.1))
+ {
+
+ showcnt += 50;
+
+ if (frames != 0)
+ fprintf(stderr,
+ "\r%5d/%-5d (%3d%%)| %6.1f/%-6.1f | %8.3f | %.1f ",
+ currentFrame, frames, currentFrame*100/frames,
+ timeused,
+ timeused * frames / currentFrame,
+ (1024.0 * currentFrame / infile->samplerate) / timeused,
+ timeused * (frames - currentFrame) / currentFrame);
+ else
+ fprintf(stderr,
+ "\r %5d | %6.1f | %8.3f ",
+ currentFrame,
+ timeused,
+ (1024.0 * currentFrame / infile->samplerate) / timeused);
+ fflush(stderr);
+#ifdef _WIN32
+ if (frames != 0)
+ {
+ sprintf(percent, "%.2f%% encoding %s",
+ 100.0 * currentFrame / frames, audioFileName);
+ SetConsoleTitle(percent);
+ }
+#endif
+ }
+ }
+
+ /* all done, bail out */
+ if (!samplesRead && !bytesWritten)
+ break ;
+
+ if (bytesWritten < 0)
+ {
+ fprintf(stderr, "faacEncEncode() failed\n");
+ break ;
+ }
+
+ /* write bitstream to aac file */
+ fwrite(bitbuf, 1, bytesWritten, outfile);
+ }
+ fprintf(stderr, "\n\n");
+
+ /* clean up */
+ fclose(outfile);
+ }
+
+ faacEncClose(hEncoder);
+
+ wav_close(infile);
+
+ if (pcmbuf) free(pcmbuf);
+ if (bitbuf) free(bitbuf);
+
+ return 0;
+}
+
+/*
+$Log: faac.c,v $
+Revision 1.1 2003/08/18 07:25:03 knik
+second CLI frontend cloned from main.c
+
+*/