shithub: aacenc

Download patch

ref: 4b298a9b06e46a6779676f50fc9263621dc5c49d
parent: e2304f6c74c5d578ce42c5511f1cbba833baf4b6
author: Krzysztof Nikiel <knik@users.sourceforge.net>
date: Wed Aug 16 06:36:36 EDT 2017

frontend: help/usage reorganized

--- a/frontend/main.c
+++ b/frontend/main.c
@@ -77,136 +77,145 @@
 #define FALSE 0
 #define TRUE 1
 
-#define fprintf if(verbose)fprintf
+enum flags
+{
+    SHORTCTL_FLAG = 300,
+    TNS_FLAG,
+    NO_TNS_FLAG,
+    MPEGVERS_FLAG,
+    OBJTYPE_FLAG,
+    NO_MIDSIDE_FLAG,
+    IGNORELEN_FLAG,
 
-const char *usage =
-    "Usage: %s [options] [-o outfile] infiles ...\n"
-    "\n"
-    "\t<infiles> and/or <outfile> can be \"-\", which means stdin/stdout.\n"
-    "\n"
-    "See also:\n"
-    "\t\"%s --help\" for short help on using FAAC\n"
-    "\t\"%s --long-help\" for a description of all options for FAAC.\n"
-    "\t\"%s --license\" for the license terms for FAAC.\n\n";
+    ARTIST_FLAG,
+    TITLE_FLAG,
+    GENRE_FLAG,
+    ALBUM_FLAG,
+    COMPILATION_FLAG,
+    TRACK_FLAG,
+    DISC_FLAG,
+    YEAR_FLAG,
+    COVER_ART_FLAG,
+    COMMENT_FLAG,
+    WRITER_FLAG,
+    TAG_FLAG,
+    HELP_QUAL,
+    HELP_IO,
+    HELP_MP4,
+    HELP_ADVANCED
+};
 
-const char *short_help =
-    "Usage: %s [options] infiles ...\n"
-    "Options:\n"
-    "  -q <quality>\tSet quantizer quality.\n"
-    "  -b <bitrate>\tSet average bitrate to x kbps. (ABR, lower quality mode)\n"
-    "  -c <freq>\tSet the bandwidth in Hz. (default=automatic)\n"
-    "  -o X\t\tSet output file to X (only for one input file)\n"
-    "  -v <verbose>\t\tverbosity level (-v0 is  quiet mode)\n"
-    "  -r\t\tUse RAW AAC output file.\n"
-    "  -P\t\tRaw PCM input mode (default 44100Hz 16bit stereo).\n"
-    "  -R\t\tRaw PCM input rate.\n"
-    "  -B\t\tRaw PCM input sample size (8, 16 (default), 24 or 32bits).\n"
-    "  -C\t\tRaw PCM input channels.\n"
-    "  -X\t\tRaw PCM swap input bytes\n"
-    "  -I <C,LF>\tInput channel config, default is 3,4 (Center third, LF fourth)\n"
-    "  --ignorelength\tIgnore wav length from header (useful with files over 4 GB)\n"
-    "\n"
-    "MP4 specific options:\n"
-    "  -w\t\tWrap AAC data in MP4 container. (default for *.mp4 and *.m4a)\n"
-    "  --tag <tagname,tagvalue> Add named tag (iTunes '----')\n"
-    "  --artist X\tSet artist to X\n"
-    "  --composer X\tSet composer to X\n"
-    "  --title X\tSet title to X\n"
-    "  --genre X\tSet genre number to X\n"
-    "  --album X\tSet album to X\n"
-    "  --compilation\tSet compilation\n"
-    "  --track X\tSet track to X (number/total)\n"
-    "  --disc X\tSet disc to X (number/total)\n"
-    "  --year X\tSet year to X\n"
-    "  --cover-art X\tRead cover art from file X\n"
-    "  --comment X\tSet comment to X\n"
-    "\n"
-    "Documentation:\n"
-    "  --license\tShow the FAAC license.\n"
-    "  --help\tShow this abbreviated help.\n"
-    "  --long-help\tShow complete help.\n"
-    "\n"
-    "  More tips can be found in the audiocoding.com Knowledge Base at\n"
-    "  <http://www.audiocoding.com/wiki/>\n" "\n";
+typedef struct {
+    char *shorthelp;
+    char *longhelp;
+} help_t;
 
-const char *long_help =
-    "Usage: %s [options] infiles ...\n"
-    "\n"
-    "Quality-related options:\n"
-    "  -q <quality>\tSet default variable bitrate (VBR) quantizer quality in percent.\n"
+const char *usage =
+    "Usage: %s [options] infile\n\n";
+
+static help_t help_qual[] = {
+    {"-q <quality>\tSet encoding quality.\n",
+    "\t\tSet default variable bitrate (VBR) quantizer quality in percent.\n"
     "\t\t(default: 100, averages at approx. 120 kbps VBR for a normal\n"
     "\t\tstereo input file with 16 bit and 44.1 kHz sample rate; max.\n"
-    "\t\tvalue 500, min. 10).\n"
-    "  -b <bitrate>\tSet average bitrate (ABR) to approximately <bitrate> kbps.\n"
+    "\t\tvalue 2000, min. 10).\n"},
+    {"-b <bitrate>\tSet average bitrate to x kbps. (ABR, lower quality mode)\n",
+    "\t\tSet average bitrate (ABR) to approximately <bitrate> kbps.\n"
     "\t\t(max. value 152 kbps/stereo with a 16 kHz cutoff, can be raised\n"
-    "\t\twith a higher -c setting).\n"
-    "  -c <freq>\tSet the bandwidth in Hz (default: automatic, i.e. adapts\n"
-    "\t\tmaximum value to input sample rate).\n"
-    "\n"
-    "Input/output options:\n"
-    "  -\t\t<stdin/stdout>: If you simply use a hyphen/minus sign instead\n"
-    "\t\tof an input file name, FAAC can encode directly from stdin,\n"
-    "\t\tthus enabling piping from other applications and utilities. The\n"
-    "\t\tsame works for stdout as well, so FAAC can pipe its output to\n"
-    "\t\tother apps such as a server.\n"
-    "  -o X\t\tSet output file to X (only for one input file)\n"
+    "\t\twith a higher -c setting).\n"},
+    {"-c <freq>\tSet the bandwidth in Hz. (default 0.42 of sampling freq)\n"},
+    {0}
+};
+
+static help_t help_io[] = {
+    {"-o <filename>\tSet output file to X (only for one input file)\n",
     "\t\tonly for one input file; you can use *.aac, *.mp4, *.m4a or\n"
     "\t\t*.m4b as file extension, and the file format will be set\n"
-    "\t\tautomatically to ADTS or MP4).\n"
-    "  -v <verbose>\tverbosity level (-v0 is quiet mode)\n"
-    "  -P\t\tRaw PCM input mode (default: off, i.e. expecting a WAV header;\n"
+    "\t\tautomatically to ADTS or MP4).\n"},
+    {"-\t\tUse stdin/stdout\n",
+    "\t\tIf you simply use a hyphen/minus sign instead\n"
+    "\t\tof a filename, FAAC can encode directly from stdin,\n"
+    "\t\tthus enabling piping from other applications and utilities. The\n"
+    "\t\tsame works for stdout as well, so FAAC can pipe its output to\n"
+    "\t\tother apps such as a server.\n"},
+    {"v <verbose>\t\tverbosity level (-v0 is  quiet mode)\n"},
+    {"-r\t\tUse RAW AAC output file.\n",
+    "\t\tGenerate raw AAC bitstream (i.e. without any headers).\n"
+    "\t\tNot advised!!!, RAW AAC files are practically useless!!!\n"},
+    {"-P\t\tRaw PCM input mode (default 44100Hz 16bit stereo).\n",
+    "\t\tRaw PCM input mode (default: off, i.e. expecting a WAV header;\n"
     "\t\tnecessary for input files or bitstreams without a header; using\n"
     "\t\tonly -P assumes the default values for -R, -B and -C in the\n"
-    "\t\tinput file).\n"
-    "  -R\t\tRaw PCM input sample rate in Hz (default: 44100 Hz, max. 96 kHz)\n"
-    "  -B\t\tRaw PCM input sample size (default: 16, also possible 8, 24, 32\n"
-    "\t\tbit fixed or float input).\n"
-    "  -C\t\tRaw PCM input channels (default: 2, max. 33 + 1 LFE).\n"
-    "  -X\t\tRaw PCM swap input bytes (default: bigendian).\n"
-    "  -I <C[,LFE]>\tInput multichannel configuration (default: 3,4 which means\n"
+    "\t\tinput file).\n"},
+    {"-R\t\tRaw PCM input rate.\n",
+    "\t\tRaw PCM input sample rate in Hz (default: 44100 Hz, max. 96 kHz)\n"},
+    {"-B\t\tRaw PCM input sample size (8, 16 (default), 24 or 32bits).\n",
+    "\t\tRaw PCM input sample size (default: 16, also possible 8, 24, 32\n"
+    "\t\tbit fixed or float input).\n"},
+    {"-C\t\tRaw PCM input channels.\n",
+    "\t\tRaw PCM input channels (default: 2, max. 33 + 1 LFE).\n"},
+    {"-X\t\tRaw PCM swap input bytes\n",
+    "\t\tRaw PCM swap input bytes (default: bigendian).\n"},
+    {"-I <C[,LFE]>\tInput channel config, default is 3,4 (Center third, LF fourth)\n",
+    "\t\tInput multichannel configuration (default: 3,4 which means\n"
     "\t\tCenter is third and LFE is fourth like in 5.1 WAV, so you only\n"
     "\t\thave to specify a different position of these two mono channels\n"
     "\t\tin your multichannel input files if they haven't been reordered\n"
-    "\t\talready).\n"
-    "\n"
-    "MP4 specific options:\n"
-    "  -w\t\tWrap AAC data in MP4 container. (default for *.mp4, *.m4a and\n"
-    "\t\t*.m4b)\n"
-    "  --artist X\tSet artist to X\n"
-    "  --composer X\tSet composer to X\n"
-    "  --title X\tSet title/track name to X\n"
-    "  --genre X\tSet genre number to X\n"
-    "  --album X\tSet album/performer to X\n"
-    "  --compilation\tMark as compilation\n"
-    "  --track X\tSet track to X (number/total)\n"
-    "  --disc X\tSet disc to X (number/total)\n"
-    "  --year X\tSet year to X\n"
-    "  --cover-art X\tRead cover art from file X\n"
-    "\t\tSupported image formats are GIF, JPEG, and PNG.\n"
-    "  --comment X\tSet comment to X\n"
-    "\n" "Expert options, only for testing purposes:\n"
+    "\t\talready).\n"},
+    {"--ignorelength\tIgnore wav length from header (useful with files over 4 GB)\n"},
+    {0}
+};
+
+static help_t help_mp4[] = {
+    {"-w\t\tWrap AAC data in MP4 container. (default for *.mp4 and *.m4a)\n",
+    "\t\tWrap AAC data in MP4 container. (default for *.mp4, *.m4a and\n"
+    "\t\t*.m4b)\n"},
+    {"--tag <tagname,tagvalue> Add named tag (iTunes '----')\n"},
+    {"--artist <name>\tSet artist name\n"},
+    {"--composer name\tSet composer name\n"},
+    {"--title <name>\tSet title/track name\n"},
+    {"--genre <number>\tSet genre number\n"},
+    {"--album <name>\tSet album/performer\n"},
+    {"--compilation\tMark as compilation\n"},
+    {"--track <number/total>\tSet track number\n"},
+    {"--disc <number/total>\tSet disc number\n"},
+    {"--year <number>\tSet year\n"},
+    {"--cover-art <filename>\tRead cover art from file X\n",
+    "\t\tSupported image formats are GIF, JPEG, and PNG.\n"},
+    {"--comment <string>\tSet comment\n"},
+    {0}
+};
+
+static help_t help_advanced[] = {
+    {
 #if !DEFAULT_TNS
-    "  --tns  \tEnable coding of TNS, temporal noise shaping.\n"
+    "--tns  \tEnable coding of TNS, temporal noise shaping.\n"
 #else
-    "  --no-tns\tDisable coding of TNS, temporal noise shaping.\n"
+    "--no-tns\tDisable coding of TNS, temporal noise shaping.\n"
 #endif
-    "  --no-midside\tDon\'t use mid/side coding.\n"
-    "  --mpeg-vers X\tForce AAC MPEG version, X can be 2 or 4\n"
-    "  --obj-type X\tAAC object type. (LC (Low Complexity, default), Main or LTP\n"
-    "\t\t(Long Term Prediction)\n"
-    "  --shortctl X\tEnforce block type (0 = both (default); 1 = no short; 2 = no\n"
-    "\t\tlong).\n"
-    "  -r\t\tGenerate raw AAC bitstream (i.e. without any headers).\n"
-    "\t\tNot advised!!!, RAW AAC files are practically useless!!!\n"
-    "\n"
-    "Documentation:\n"
-    "  --license\tShow the FAAC license.\n"
-    "  --help\tShow this abbreviated help.\n"
-    "  --long-help\tShow complete help.\n"
-    "\n"
-    "  More tips can be found in the audiocoding.com Knowledge Base at\n"
-    "  <http://www.audiocoding.com/wiki/>\n" "\n";
+    },
+    {"--no-midside\tDon\'t use mid/side coding.\n"},
+    {"--mpeg-vers X\tForce AAC MPEG version, X can be 2 or 4\n"},
+    {"--obj-type X\tAAC object type. (LC (Low Complexity, default), Main or LTP\n"
+    "\t\t(Long Term Prediction)\n"},
+    {" --shortctl X\tEnforce block type (0 = both (default); 1 = no short; 2 = no\n"
+    "\t\tlong).\n"},
+    {0}
+};
 
+static struct {
+    int id;
+    char *name;
+    char *option;
+    help_t *help;
+} g_help[] = {
+    {HELP_QUAL, "Quality-related options", "--help-qual", help_qual},
+    {HELP_IO, "Input/output options", "--help-io", help_io},
+    {HELP_MP4, "MP4 specific options", "--help-mp4", help_mp4},
+    {HELP_ADVANCED, "Advanced options, only for testing purposes", "--help-advanced", help_advanced},
+    {0}
+};
+
 char *license =
     "\nPlease note that the use of this software may require the payment of patent\n"
     "royalties. You need to consider this issue before you start building derivative\n"
@@ -289,30 +298,6 @@
     MP4_CONTAINER,
 };
 
-enum flags
-{
-    SHORTCTL_FLAG = 300,
-    TNS_FLAG,
-    NO_TNS_FLAG,
-    MPEGVERS_FLAG,
-    OBJTYPE_FLAG,
-    NO_MIDSIDE_FLAG,
-    IGNORELEN_FLAG,
-
-    ARTIST_FLAG,
-    TITLE_FLAG,
-    GENRE_FLAG,
-    ALBUM_FLAG,
-    COMPILATION_FLAG,
-    TRACK_FLAG,
-    DISC_FLAG,
-    YEAR_FLAG,
-    COVER_ART_FLAG,
-    COMMENT_FLAG,
-    WRITER_FLAG,
-    TAG_FLAG,
-};
-
 #ifndef _WIN32
 void signal_handler(int signal)
 {
@@ -320,6 +305,61 @@
 }
 #endif
 
+static void help0(help_t *h, int l)
+{
+    int cnt;
+
+    for (cnt = 0; h[cnt].shorthelp; cnt++)
+    {
+        printf("    %s", h[cnt].shorthelp);
+        if (l && h[cnt].longhelp)
+            printf("%s", h[cnt].longhelp);
+    }
+    printf("\n\n");
+}
+
+static void help(int mode)
+{
+    int cnt;
+    static const char *name = "faac";
+
+    printf(usage, name);
+    switch (mode)
+    {
+    case '?':
+        printf("Help options:\n"
+                "\t--help\t\tShort help on using FAAC\n"
+                "\t--long-help\tDescription of all options for FAAC.\n"
+                "\t--license\tLicense terms for FAAC.\n");
+        for (cnt = 0; g_help[cnt].id; cnt++)
+            printf("\t%s\t%s\n", g_help[cnt].option, g_help[cnt].name);
+        break;
+    case 'h':
+        for (cnt = 0; cnt < 2; cnt++)
+        {
+            printf("%s:\n", g_help[cnt].name);
+            help0(g_help[cnt].help, 0);
+        }
+        break;
+    case 'H':
+        for (cnt = 0; cnt < g_help[cnt].id; cnt++)
+        {
+            printf("%s:\n", g_help[cnt].name);
+            help0(g_help[cnt].help, 1);
+        }
+        break;
+    default:
+        for (cnt = 0; g_help[cnt].id; cnt++)
+            if (g_help[cnt].id == mode)
+            {
+                printf("%s:\n", g_help[cnt].name);
+                help0(g_help[cnt].help, 0);
+                break;
+            }
+        break;
+    }
+}
+
 static int check_image_header(const char *buf)
 {
     if (!strncmp(buf, "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A", 8))
@@ -383,6 +423,8 @@
     return map;
 }
 
+#define fprintf if(verbose)fprintf
+
 int main(int argc, char *argv[])
 {
     int frames, currentFrame;
@@ -450,11 +492,20 @@
 
     /* begin process command line */
     progName = argv[0];
+    if (argc < 2)
+    {
+        help('?');
+        return 1;
+    }
     while (1)
     {
         static struct option long_options[] = {
             {"help", 0, 0, 'h'},
-            {"long-help", 0, 0, 'H'},
+            {"help-long", 0, 0, 'H'},
+            {"help-qual", 0, 0, HELP_QUAL},
+            {"help-io", 0, 0, HELP_IO},
+            {"help-mp4", 0, 0, HELP_MP4},
+            {"help-advanced", 0, 0, HELP_ADVANCED},
             {"raw", 0, 0, 'r'},
             {"no-midside", 0, 0, NO_MIDSIDE_FLAG},
             {"cutoff", 1, 0, 'c'},
@@ -496,10 +547,7 @@
             break;
 
         if (!c)
-        {
-            dieMessage = usage;
-            break;
-        }
+            continue;
 
         switch (c)
         {
@@ -726,15 +774,19 @@
         case 'v':
             verbose = atoi(optarg);
             break;
+        case HELP_QUAL:
+        case HELP_IO:
+        case HELP_MP4:
+        case HELP_ADVANCED:
         case 'H':
-            dieMessage = long_help;
-            break;
         case 'h':
-            dieMessage = short_help;
+            help(c);
+            return 1;
             break;
         case '?':
         default:
-            dieMessage = usage;
+            help('?');
+            return 1;
             break;
         }
     }
@@ -759,8 +811,7 @@
 
     if (argc - optind < 1 || dieMessage)
     {
-        fprintf(stderr, dieMessage ? dieMessage : usage,
-                progName, progName, progName, progName);
+        fprintf(stderr, dieMessage, progName, progName, progName, progName);
         return 1;
     }