shithub: aacenc

Download patch

ref: 150fb2e5d1e0bc5670032b79df66d4787181bcce
parent: 0503e7b63126d65d34b7415595099e31f7b168fe
author: knik <knik>
date: Fri Aug 9 12:29:41 EDT 2002

improved psychoacoustic model selection

--- a/frontend/main.c
+++ b/frontend/main.c
@@ -16,7 +16,7 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * $Id: main.c,v 1.24 2002/08/07 18:19:20 knik Exp $
+ * $Id: main.c,v 1.25 2002/08/09 16:29:41 knik Exp $
  */
 
 #ifdef _WIN32
@@ -31,6 +31,7 @@
 
 #include <stdio.h>
 #include <stdlib.h>
+#include <ctype.h>
 
 #include <sndfile.h>
 #include <getopt.h>
@@ -78,6 +79,7 @@
     unsigned int useAdts = 1;
     unsigned int cutOff = 0;
     unsigned long bitRate = 64000;
+    int psymodelidx = -1;
 
     char *audioFileName;
     char *aacFileName;
@@ -194,11 +196,12 @@
             break;
         }
 	case 'p':
-	  if (!strcmp(optarg, "1"))
-	    psymodel = &psymodel1;
-	  else if (!strcmp(optarg, "2"))
-	    psymodel = &psymodel2;
+	  {
+	    unsigned int i;
+	    if (sscanf(optarg, "%u", &i) > 0)
+	      psymodelidx = i;
 	  break;
+	  }
         case '?':
             break;
         default:
@@ -210,14 +213,22 @@
     /* check that we have at least two non-option arguments */
     if ((argc - optind) < 2)
     {
+      int i;
+
+      // get available psymodels
+      hEncoder = faacEncOpen(44100, 2, &samplesInput, &maxBytesOutput);
+      myFormat = faacEncGetCurrentConfiguration(hEncoder);
+
         fprintf(stderr, "USAGE: %s -options infile outfile\n", progName);
         fprintf(stderr, "Options:\n");
         fprintf(stderr, "  -m X   AAC MPEG version, X can be 2 or 4.\n");
         fprintf(stderr, "  -o X   AAC object type, X can be LC, MAIN or LTP.\n");
-	fprintf(stderr, "  -p 1   Use ISO psychoacoustic model.%s\n",
-		(psymodel == &psymodel1) ? " (default)" : "");
-	fprintf(stderr, "  -p 2   Use kpsycho psychoacoustic.%s\n",
-		(psymodel == &psymodel2) ? " (default)" : "");
+	for (i = 0; myFormat->psymodellist[i].ptr; i++)
+	{
+	  fprintf(stderr, "  -p %d   Use %s.%s\n", i,
+		  myFormat->psymodellist[i].name,
+		  (i == myFormat->psymodelidx) ? " (default)" : "");
+	}
         fprintf(stderr, "  -n     Don\'t use mid/side coding.\n");
         fprintf(stderr, "  -r     RAW AAC output file.\n");
         fprintf(stderr, "  -t     Use TNS coding.\n");
@@ -224,6 +235,9 @@
     fprintf(stderr,
 	    "  -c X   Set the bandwidth, X in Hz. (default=automatic)\n");
     fprintf(stderr, "  -b X   Set the bitrate per channel, X in kbps.\n\n");
+
+    faacEncClose(hEncoder);
+
         return 1;
     }
 
@@ -266,6 +280,8 @@
     myFormat->bitRate = bitRate;
     myFormat->bandWidth = cutOff;
     myFormat->outputFormat = useAdts;
+    if (psymodelidx >= 0)
+      myFormat->psymodelidx = psymodelidx;
     if (!faacEncSetConfiguration(hEncoder, myFormat)) {
         fprintf(stderr, "Unsupported output format!\n");
         return 1;
--- a/include/faac.h
+++ b/include/faac.h
@@ -16,7 +16,7 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * $Id: faac.h,v 1.19 2002/08/07 18:18:49 knik Exp $
+ * $Id: faac.h,v 1.20 2002/08/09 16:28:13 knik Exp $
  */
 
 #ifndef FAACLIB_H
@@ -81,30 +81,17 @@
 	*/
 	unsigned int outputFormat;
 
+	// psychoacoustic model list
+	const struct {
+	  void *ptr;
+	  char *name;
+	} *psymodellist;
+	// selected index in psymodellist
+	unsigned int psymodelidx;
+
 } faacEncConfiguration, *faacEncConfigurationPtr;
 
 typedef void *faacEncHandle;
-
-typedef struct {
-  void (*PsyInit) (void *gpsyInfo, void *psyInfo,
-		   unsigned int numChannels, unsigned int sampleRate,
-		   int *cb_width_long, int num_cb_long,
-		   int *cb_width_short, int num_cb_short);
-  void (*PsyEnd) (void *gpsyInfo, void *psyInfo,
-		  unsigned int numChannels);
-  void (*PsyCalculate) (void *channelInfo, void *gpsyInfo,
-			void *psyInfo, int *cb_width_long, int num_cb_long,
-			int *cb_width_short, int num_cb_short,
-			unsigned int numChannels);
-  void (*PsyBufferUpdate) (void *gpsyInfo, void *psyInfo,
-			   double *newSamples, unsigned int bandwidth);
-  void (*BlockSwitch) (void *coderInfo, void *psyInfo,
-		       unsigned int numChannels);
-} psymodel_t;
-
-extern psymodel_t *psymodel;
-extern psymodel_t psymodel1;
-extern psymodel_t psymodel2;
 
 faacEncConfigurationPtr FAACAPI faacEncGetCurrentConfiguration(faacEncHandle hEncoder);
 int FAACAPI faacEncSetConfiguration (faacEncHandle hEncoder, faacEncConfigurationPtr config);
--- a/libfaac/frame.c
+++ b/libfaac/frame.c
@@ -16,7 +16,7 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * $Id: frame.c,v 1.27 2002/08/07 18:11:34 knik Exp $
+ * $Id: frame.c,v 1.28 2002/08/09 16:27:20 knik Exp $
  */
 
 /*
@@ -46,7 +46,11 @@
 #include "ltp.h"
 #include "backpred.h"
 
-psymodel_t *psymodel = &psymodel2;
+static const psymodellist_t psymodellist[] = {
+  {&psymodel2, "knipsycho psychoacoustic"},
+  {&psymodel1, "ISO psychoacoustic model"},
+  {NULL}
+};
 
 static SR_INFO srInfo[12+1];
 
@@ -136,6 +140,17 @@
     if (hEncoder->config.bandWidth > (hEncoder->sampleRate / 2))
       hEncoder->config.bandWidth = hEncoder->sampleRate / 2;
 
+    // reset psymodel
+    hEncoder->psymodel->PsyEnd(&hEncoder->gpsyInfo, hEncoder->psyInfo, hEncoder->numChannels);
+    if (config->psymodelidx >= (sizeof(psymodellist) / sizeof(psymodellist[0]) - 1))
+      config->psymodelidx = (sizeof(psymodellist) / sizeof(psymodellist[0])) - 2;
+    hEncoder->config.psymodelidx = config->psymodelidx;
+    hEncoder->psymodel = psymodellist[hEncoder->config.psymodelidx].model;
+    hEncoder->psymodel->PsyInit(&hEncoder->gpsyInfo, hEncoder->psyInfo, hEncoder->numChannels,
+	      hEncoder->sampleRate, hEncoder->srInfo->cb_width_long,
+	      hEncoder->srInfo->num_cb_long, hEncoder->srInfo->cb_width_short,
+	      hEncoder->srInfo->num_cb_short);
+
     /* OK */
     return 1;
 }
@@ -170,6 +185,10 @@
     hEncoder->config.useTns = 0;
     hEncoder->config.bitRate = 64000; /* default bitrate / channel */
     hEncoder->config.bandWidth = hEncoder->config.bitRate / 4;
+    hEncoder->config.psymodellist = psymodellist;
+    hEncoder->config.psymodelidx = 0;
+    hEncoder->psymodel =
+      hEncoder->config.psymodellist[hEncoder->config.psymodelidx].model;
 
 	/*
 		by default we have to be compatible with all previous software
@@ -199,7 +218,7 @@
     }
 
     /* Initialize coder functions */
-    psymodel->PsyInit(&hEncoder->gpsyInfo, hEncoder->psyInfo, hEncoder->numChannels,
+    hEncoder->psymodel->PsyInit(&hEncoder->gpsyInfo, hEncoder->psyInfo, hEncoder->numChannels,
         hEncoder->sampleRate, hEncoder->srInfo->cb_width_long,
         hEncoder->srInfo->num_cb_long, hEncoder->srInfo->cb_width_short,
         hEncoder->srInfo->num_cb_short); 
@@ -225,7 +244,7 @@
     unsigned int channel;
 
     /* Deinitialize coder functions */
-    psymodel->PsyEnd(&hEncoder->gpsyInfo, hEncoder->psyInfo, hEncoder->numChannels);
+    hEncoder->psymodel->PsyEnd(&hEncoder->gpsyInfo, hEncoder->psyInfo, hEncoder->numChannels);
 
     FilterBankEnd(hEncoder);
 
@@ -323,7 +342,7 @@
 
         /* Psychoacoustics */
         /* Update buffers and run FFT on new samples */
-	psymodel->PsyBufferUpdate(&hEncoder->gpsyInfo, &hEncoder->psyInfo[channel],
+	hEncoder->psymodel->PsyBufferUpdate(&hEncoder->gpsyInfo, &hEncoder->psyInfo[channel],
 				  hEncoder->next3SampleBuff[channel], bandWidth);
     }
 
@@ -331,12 +350,12 @@
         return 0;
 
     /* Psychoacoustics */
-    psymodel->PsyCalculate(channelInfo, &hEncoder->gpsyInfo, hEncoder->psyInfo,
+    hEncoder->psymodel->PsyCalculate(channelInfo, &hEncoder->gpsyInfo, hEncoder->psyInfo,
         hEncoder->srInfo->cb_width_long, hEncoder->srInfo->num_cb_long,
         hEncoder->srInfo->cb_width_short,
         hEncoder->srInfo->num_cb_short, numChannels);
 
-    psymodel->BlockSwitch(coderInfo, hEncoder->psyInfo, numChannels);
+    hEncoder->psymodel->BlockSwitch(coderInfo, hEncoder->psyInfo, numChannels);
 
     /* AAC Filterbank, MDCT with overlap and add */
     for (channel = 0; channel < numChannels; channel++) {
--- a/libfaac/frame.h
+++ b/libfaac/frame.h
@@ -16,7 +16,7 @@
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
- * $Id: frame.h,v 1.16 2002/08/07 18:12:08 knik Exp $
+ * $Id: frame.h,v 1.17 2002/08/09 16:27:20 knik Exp $
  */
 
 #ifndef FRAME_H
@@ -41,6 +41,11 @@
   #endif
 #endif
 
+typedef struct {
+  psymodel_t *model;
+  char *name;
+} psymodellist_t;
+
 typedef struct faacEncConfiguration
 {
     /* MPEG version, 2 or 4 */
@@ -72,6 +77,11 @@
 	*/
 	unsigned int outputFormat;
 
+	// psychoacoustic model list
+	const psymodellist_t *psymodellist;
+	// selected index in psymodellist
+	unsigned int psymodelidx;
+
 } faacEncConfiguration, *faacEncConfigurationPtr;
 
 typedef struct {
@@ -118,6 +128,8 @@
 
     /* Configuration data */
     faacEncConfiguration config;
+
+    psymodel_t *psymodel;
 
 } faacEncStruct, *faacEncHandle;