ref: d7dbf2b7cf98d98c8daf835f97509eb9b0e9ddd4
parent: abd42b5a145fe513b01082cc200543b86b5e29e9
author: menno <menno>
date: Sat Aug 16 11:06:07 EDT 2003
Case: - More input options - MP4 output
--- a/frontend/faac.dsp
+++ b/frontend/faac.dsp
@@ -42,7 +42,7 @@
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
-# ADD CPP /nologo /MD /W3 /O2 /I "../include" /I "../common/libsndfile/src" /I "../common/getopt" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+# ADD CPP /nologo /MD /W3 /O2 /I "../include" /I "../common/libsndfile/src" /I "../common/getopt" /I "../../faad2/common/mp4v2" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD BASE RSC /l 0x413 /d "NDEBUG"
# ADD RSC /l 0x413 /d "NDEBUG"
BSC32=bscmake.exe
@@ -50,7 +50,7 @@
# ADD BSC32 /nologo
LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib /nologo /subsystem:console /machine:I386
# SUBTRACT LINK32 /profile /debug /nodefaultlib
!ELSEIF "$(CFG)" == "faac - Win32 Debug"
@@ -67,7 +67,7 @@
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../include" /I "../common/libsndfile/src" /I "../common/getopt" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
+# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /I "../include" /I "../common/libsndfile/src" /I "../common/getopt" /I "../../faad2/common/mp4v2" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD BASE RSC /l 0x413 /d "_DEBUG"
# ADD RSC /l 0x413 /d "_DEBUG"
BSC32=bscmake.exe
@@ -75,7 +75,7 @@
# ADD BSC32 /nologo
LINK32=xilink6.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
-# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
+# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ws2_32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
!ENDIF
--- a/frontend/faac.dsw
+++ b/frontend/faac.dsw
@@ -17,11 +17,26 @@
Begin Project Dependency
Project_Dep_Name libsndfile
End Project Dependency
+ Begin Project Dependency
+ Project_Dep_Name libmp4v2_st
+ End Project Dependency
}}}
###############################################################################
Project: "libfaac"=..\LIBFAAC\libfaac.dsp - Package Owner=<4>
+
+Package=<5>
+{{{
+}}}
+
+Package=<4>
+{{{
+}}}
+
+###############################################################################
+
+Project: "libmp4v2_st"=..\..\faad2\common\mp4v2\libmp4v2_st60.dsp - Package Owner=<4>
Package=<5>
{{{
--- a/frontend/input.c
+++ b/frontend/input.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: input.c,v 1.8 2003/07/28 17:12:57 menno Exp $
+ * $Id: input.c,v 1.10 2003/08/17 19:38:15 menno Exp $
*/
#ifdef HAVE_CONFIG_H
@@ -27,6 +27,7 @@
#include <stdlib.h>
#ifdef WIN32
+#include <io.h>
#include <fcntl.h>
#endif
@@ -60,6 +61,7 @@
riffsub_t;
#define WAVE_FORMAT_PCM 1
+#define WAVE_FORMAT_FLOAT 3
#define WAVE_FORMAT_EXTENSIBLE 0xfffe
typedef struct
{
@@ -163,22 +165,22 @@
for (skip = riffsub.len; skip > 0; skip--)
fgetc(wave_f);
}
- if (UINT16(wave.Format.wFormatTag) != WAVE_FORMAT_PCM)
+ if (UINT16(wave.Format.wFormatTag) != WAVE_FORMAT_PCM && UINT16(wave.Format.wFormatTag) != WAVE_FORMAT_FLOAT)
{
if (UINT16(wave.Format.wFormatTag) == WAVE_FORMAT_EXTENSIBLE)
{
- if (UINT16(wave.Format.cbSize) < 22) // struct too small
- return NULL;
- if (memcmp(wave.SubFormat, waveformat_pcm_guid, 16))
- {
+ if (UINT16(wave.Format.cbSize) < 22) // struct too small
+ return NULL;
+ if (memcmp(wave.SubFormat, waveformat_pcm_guid, 16))
+ {
unsuperr(name);
- return NULL;
- }
+ return NULL;
+ }
}
else
{
- unsuperr(name);
- return NULL;
+ unsuperr(name);
+ return NULL;
}
}
}
@@ -186,6 +188,7 @@
sndf = malloc(sizeof(*sndf));
memset(sndf, 0, sizeof(*sndf));
sndf->f = wave_f;
+ sndf->isfloat = (UINT16(wave.Format.wFormatTag) == WAVE_FORMAT_FLOAT);
if (rawinput)
{
sndf->bigendian = 1;
@@ -224,6 +227,117 @@
for (chn = 0; chn < channels; chn++)
buf[i * channels + chn] = tmp[map[chn]];
}
+}
+
+size_t wav_read_float32(pcmfile_t *sndf, float *buf, size_t num, int *map)
+{
+ size_t i = 0;
+ unsigned char bufi[8];
+
+ if ((sndf->samplebytes > 8) || (sndf->samplebytes < 1))
+ return 0;
+
+ while (i<num) {
+ if (fread(bufi, sndf->samplebytes, 1, sndf->f) != 1)
+ break;
+
+ if (sndf->isfloat)
+ {
+ switch (sndf->samplebytes) {
+ case 4:
+ buf[i] = (*(float *)&bufi) * (float)32768;
+ break;
+
+ case 8:
+ buf[i] = (float)((*(double *)&bufi) * (float)32768);
+ break;
+
+ default:
+ return 0;
+ }
+ }
+ else
+ {
+ // convert to 32 bit float
+ // fix endianness
+ switch (sndf->samplebytes) {
+ case 1:
+ /* this is endian clean */
+ buf[i] = ((float)bufi[0] - 128) * (float)256;
+ break;
+
+ case 2:
+#ifdef WORDS_BIGENDIAN
+ if (!sndf->bigendian)
+#else
+ if (sndf->bigendian)
+#endif
+ {
+ // swap bytes
+ int16_t s = ((int16_t *)bufi)[0];
+ s = SWAP16(s);
+ buf[i] = (float)s;
+ }
+ else
+ {
+ // no swap
+ int s = ((int16_t *)bufi)[0];
+ buf[i] = (float)s;
+ }
+ break;
+
+ case 3:
+ if (!sndf->bigendian)
+ {
+ int s = bufi[0] | (bufi[1] << 8) | (bufi[2] << 16);
+
+ // fix sign
+ if (s & 0x800000)
+ s |= 0xff000000;
+
+ buf[i] = (float)s / 256;
+ }
+ else // big endian input
+ {
+ int s = (bufi[0] << 16) | (bufi[1] << 8) | bufi[2];
+
+ // fix sign
+ if (s & 0x800000)
+ s |= 0xff000000;
+
+ buf[i] = (float)s / 256;
+ }
+ break;
+
+ case 4:
+#ifdef WORDS_BIGENDIAN
+ if (!sndf->bigendian)
+#else
+ if (sndf->bigendian)
+#endif
+ {
+ // swap bytes
+ int s = *(int *)&bufi;
+ buf[i] = (float)SWAP32(s) / 65536;
+ }
+ else
+ {
+ int s = *(int *)&bufi;
+ buf[i] = (float)s / 65536;
+ }
+ break;
+
+ default:
+ return 0;
+ }
+ }
+ i++;
+ }
+
+ if (map)
+ chan_remap((int32_t *)buf, sndf->channels, i / sndf->channels, map);
+
+ return i;
}
size_t wav_read_int24(pcmfile_t *sndf, int32_t *buf, size_t num, int *map)
--- a/frontend/input.h
+++ b/frontend/input.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: input.h,v 1.3 2003/07/10 19:18:58 knik Exp $
+ * $Id: input.h,v 1.5 2003/08/17 19:38:15 menno Exp $
*/
#ifndef _INPUT_H
@@ -64,9 +64,11 @@
int samplerate;
int samples;
int bigendian;
+ int isfloat;
} pcmfile_t;
pcmfile_t *wav_open_read(const char *path, int rawchans);
+size_t wav_read_float32(pcmfile_t *sndf, float *buf, size_t num, int *map);
size_t wav_read_int24(pcmfile_t *sndf, int32_t *buf, size_t num, int *map);
int wav_close(pcmfile_t *file);
--- a/frontend/main.c
+++ b/frontend/main.c
@@ -16,9 +16,11 @@
* 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.41 2003/08/15 11:43:14 knik Exp $
+ * $Id: main.c,v 1.42 2003/08/16 15:06:07 menno Exp $
*/
+#include <mp4.h>
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -134,7 +136,8 @@
char *audioFileName;
char *aacFileName;
- int32_t *pcmbuf;
+ //int32_t *pcmbuf;
+ float *floatbuf;
int *chanmap = NULL;
unsigned char *bitbuf;
@@ -147,6 +150,12 @@
FILE *outfile;
+ MP4FileHandle MP4hFile = MP4_INVALID_FILE_HANDLE;
+ MP4TrackId MP4track = 0;
+ int mp4 = 0;
+ u_int64_t total_samples = 0;
+ u_int64_t encoded_samples = 0;
+
// get faac version
hEncoder = faacEncOpen(44100, 2, &samplesInput, &maxBytesOutput);
myFormat = faacEncGetCurrentConfiguration(hEncoder);
@@ -181,12 +190,13 @@
{ "pcmsamplebits", 1, 0, 'B'},
{ "pcmchannels", 1, 0, 'C'},
{ "addsilent", 1, 0, 300},
+ { "createmp4", 0, 0, 'w'},
{ 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:",
+ c = getopt_long(argc, argv, "a:m:o:rnwc:q:PR:B:C:I:",
long_options, &option_index);
if (c == -1)
@@ -298,6 +308,9 @@
case 300:
sscanf(optarg, "%u", &addsilent);
break;
+ case 'w':
+ mp4 = 1;
+ break;
case '?':
break;
default:
@@ -325,9 +338,10 @@
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(" -B Raw PCM input sample size (8, 16 (default), 24 or 32bits).\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(" -w Wrap AAC data in MP4 container\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");
@@ -360,12 +374,10 @@
return 1;
}
- /* open the aac output file */
- outfile = fopen(aacFileName, "wb");
- if (!outfile)
+ if (mp4)
{
- fprintf(stderr, "Couldn't create output file %s\n", aacFileName);
- return 1;
+ mpegVersion = MPEG4;
+ useAdts = 0;
}
/* open the encoder library */
@@ -372,7 +384,8 @@
hEncoder = faacEncOpen(infile->samplerate, infile->channels,
&samplesInput, &maxBytesOutput);
- pcmbuf = (int32_t *)malloc(samplesInput*sizeof(int32_t));
+ //pcmbuf = (int32_t *)malloc(samplesInput*sizeof(int32_t));
+ floatbuf = (float *)malloc(samplesInput*sizeof(float));
bitbuf = (unsigned char*)malloc(maxBytesOutput*sizeof(unsigned char));
chanmap = mkChanMap(infile->channels, chanC, chanLF);
if (chanmap)
@@ -396,6 +409,7 @@
myFormat->aacObjectType = objectType;
myFormat->mpegVersion = mpegVersion;
myFormat->useTns = useTns;
+ if (infile->channels >= 6) myFormat->useLfe = 1;
myFormat->allowMidside = useMidSide;
if (bitRate)
myFormat->bitRate = bitRate;
@@ -403,11 +417,42 @@
if (quantqual > 0)
myFormat->quantqual = quantqual;
myFormat->outputFormat = useAdts;
+ myFormat->inputFormat = FAAC_INPUT_FLOAT;
if (!faacEncSetConfiguration(hEncoder, myFormat)) {
fprintf(stderr, "Unsupported output format!\n");
+ if (mp4) MP4Close(MP4hFile);
return 1;
}
+ /* initialize MP4 creation */
+ if (mp4) {
+ u_int8_t *ASC = 0;
+ u_int32_t ASCLength = 0;
+
+ MP4hFile = MP4Create(aacFileName, 0, 0, 0);
+ if (MP4hFile == MP4_INVALID_FILE_HANDLE) {
+ fprintf(stderr, "Couldn't create output file %s\n", aacFileName);
+ return 1;
+ }
+
+ MP4SetTimeScale(MP4hFile, 90000);
+ MP4track = MP4AddAudioTrack(MP4hFile, infile->samplerate, MP4_INVALID_DURATION, MP4_MPEG4_AUDIO_TYPE);
+ MP4SetAudioProfileLevel(MP4hFile, 0x0F);
+ //MP4AV_AacGetConfiguration(&ASC, &ASCLength, (u_int8_t)objectType, (u_int32_t)infile->samplerate, (u_int8_t)infile->channels);
+ faacEncGetDecoderSpecificInfo(hEncoder, &ASC, &ASCLength);
+ MP4SetTrackESConfiguration(MP4hFile, MP4track, ASC, ASCLength);
+ }
+ else
+ {
+ /* open the aac output file */
+ outfile = fopen(aacFileName, "wb");
+ if (!outfile)
+ {
+ fprintf(stderr, "Couldn't create output file %s\n", aacFileName);
+ return 1;
+ }
+ }
+
cutOff = myFormat->bandWidth;
quantqual = myFormat->quantqual;
bitRate = myFormat->bitRate;
@@ -435,7 +480,7 @@
fprintf(stderr, " + M/S");
fprintf(stderr, "\n");
- if (outfile)
+ if (outfile || MP4hFile != MP4_INVALID_FILE_HANDLE)
{
int showcnt = 0;
#ifdef _WIN32
@@ -459,14 +504,18 @@
{
int bytesWritten;
- samplesRead = wav_read_int24(infile, pcmbuf, samplesInput, chanmap);
+ //samplesRead = wav_read_int24(infile, pcmbuf, samplesInput, chanmap);
+ samplesRead = wav_read_float32(infile, floatbuf, samplesInput, chanmap);
+ total_samples += samplesRead / infile->channels;
+
if (!samplesRead)
{
if (addsilent)
{
addsilent--;
- memset(pcmbuf, 0, samplesInput * sizeof(*pcmbuf));
+ //memset(pcmbuf, 0, samplesInput * sizeof(*pcmbuf));
+ memset(floatbuf, 0, samplesInput * sizeof(*floatbuf));
samplesRead = samplesInput;
}
}
@@ -473,7 +522,8 @@
/* call the actual encoding routine */
bytesWritten = faacEncEncode(hEncoder,
- pcmbuf,
+ //pcmbuf,
+ floatbuf,
samplesRead,
bitbuf,
maxBytesOutput);
@@ -546,13 +596,33 @@
break ;
}
- /* write bitstream to aac file */
- fwrite(bitbuf, 1, bytesWritten, outfile);
+ if (bytesWritten > 0)
+ {
+ unsigned int samples = ((total_samples - encoded_samples) < (samplesInput/infile->channels))
+ ? (total_samples - encoded_samples)
+ : (samplesInput/infile->channels);
+
+ if (mp4)
+ {
+ /* write bitstream to mp4 file */
+ MP4WriteSample(MP4hFile, MP4track, bitbuf, bytesWritten, samples, 0, 1);
+ }
+ else
+ {
+ /* write bitstream to aac file */
+ fwrite(bitbuf, 1, bytesWritten, outfile);
+ }
+
+ encoded_samples += samples;
+ }
}
fprintf(stderr, "\n\n");
/* clean up */
- fclose(outfile);
+ if (mp4)
+ MP4Close(MP4hFile);
+ else
+ fclose(outfile);
}
faacEncClose(hEncoder);
@@ -559,7 +629,8 @@
wav_close(infile);
- if (pcmbuf) free(pcmbuf);
+ //if (pcmbuf) free(pcmbuf);
+ if (floatbuf) free(floatbuf);
if (bitbuf) free(bitbuf);
return 0;
@@ -567,6 +638,11 @@
/*
$Log: main.c,v $
+Revision 1.42 2003/08/16 15:06:07 menno
+Case:
+- More input options
+- MP4 output
+
Revision 1.41 2003/08/15 11:43:14 knik
Option to add a number of silent frames at the end of output.
Small TNS option fix.