main.c
来自「faac-1.25.rar音频编解码器demo」· C语言 代码 · 共 1,324 行 · 第 1/3 页
C
1,324 行
u_int8_t *art = NULL;
u_int64_t artSize = 0;
u_int64_t total_samples = 0;
u_int64_t encoded_samples = 0;
unsigned int delay_samples;
unsigned int frameSize;
#endif
char *faac_id_string;
char *faac_copyright_string;
#ifndef _WIN32 //vc中不起作用
// install signal handler
signal(SIGINT, signal_handler);
signal(SIGTERM, signal_handler);
#endif
// get faac version
if (faacEncGetVersion(&faac_id_string, &faac_copyright_string) == FAAC_CFG_VERSION)
{
fprintf(stderr, "Freeware Advanced Audio Coder\nFAAC %s\n\n", faac_id_string);
}
else
{
fprintf(stderr, __FILE__ "(%d): wrong libfaac version\n", __LINE__);
return 1;
}
/* begin process command line */
progName = argv[0];
while (1) {
static struct option long_options[] = {
{ "help", 0, 0, 'h'},
{ "long-help", 0, 0, 'H'},
{ "raw", 0, 0, 'r'},
{ "no-midside", 0, 0, NO_MIDSIDE_FLAG},
{ "cutoff", 1, 0, 'c'},
{ "quality", 1, 0, 'q'},
{ "pcmraw", 0, 0, 'P'},
{ "pcmsamplerate", 1, 0, 'R'},
{ "pcmsamplebits", 1, 0, 'B'},
{ "pcmchannels", 1, 0, 'C'},
{ "shortctl", 1, 0, SHORTCTL_FLAG},
{ "tns", 0, 0, TNS_FLAG},
{ "no-tns", 0, 0, NO_TNS_FLAG},
{ "mpeg-version", 1, 0, MPEGVERS_FLAG},
{ "obj-type", 1, 0, OBJTYPE_FLAG},
{ "license", 0, 0, 'L'},
#ifdef HAVE_LIBMP4V2
{ "createmp4", 0, 0, 'w'},
{ "artist", 1, 0, ARTIST_FLAG},
{ "title", 1, 0, TITLE_FLAG},
{ "album", 1, 0, ALBUM_FLAG},
{ "track", 1, 0, TRACK_FLAG},
{ "disc", 1, 0, DISC_FLAG},
{ "genre", 1, 0, GENRE_FLAG},
{ "year", 1, 0, YEAR_FLAG},
{ "cover-art", 1, 0, COVER_ART_FLAG},
{ "comment", 1, 0, COMMENT_FLAG},
{ "writer", 1, 0, WRITER_FLAG},
{ "compilation", 0, 0, COMPILATION_FLAG},
#endif
{ "pcmswapbytes", 0, 0, 'X'},
{ 0, 0, 0, 0}
};
int c = -1;
int option_index = 0;
c = getopt_long(argc, argv, "Hhb:m:o:rnc:q:PR:B:C:I:X"
#ifdef HAVE_LIBMP4V2
"w"
#endif
,long_options, &option_index);
if (c == -1)
break;
if (!c)
{
dieMessage = usage;
break;
}
switch (c) {
case 'o':
{
int l = strlen(optarg);
aacFileName = malloc(l+1);
memcpy(aacFileName, optarg, l);
aacFileName[l] = '\0';
aacFileNameGiven = 1;
}
break;
case 'r': {
stream = RAW_STREAM;
break;
}
case NO_MIDSIDE_FLAG: {
useMidSide = 0;
break;
}
case 'c': {
unsigned int i;
if (sscanf(optarg, "%u", &i) > 0) {
cutOff = i;
}
break;
}
case 'b': {
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;
}
#ifdef HAVE_LIBMP4V2
case 'w':
container = MP4_CONTAINER;
break;
case ARTIST_FLAG:
artist = optarg;
break;
case WRITER_FLAG:
writer = optarg;
break;
case TITLE_FLAG:
title = optarg;
break;
case ALBUM_FLAG:
album = optarg;
break;
case TRACK_FLAG:
sscanf(optarg, "%u/%u", &trackno, &ntracks);
break;
case DISC_FLAG:
sscanf(optarg, "%u/%u", &discno, &ndiscs);
break;
case COMPILATION_FLAG:
compilation = 0x1;
break;
case GENRE_FLAG:
genre = optarg;
break;
case YEAR_FLAG:
year = optarg;
break;
case COMMENT_FLAG:
comment = optarg;
break;
case COVER_ART_FLAG: {
FILE *artFile = fopen(optarg, "rb");
if(artFile) {
u_int64_t r;
fseek(artFile, 0, SEEK_END);
artSize = ftell(artFile);
art = malloc(artSize);
fseek(artFile, 0, SEEK_SET);
clearerr(artFile);
r = fread(art, artSize, 1, artFile);
if (r != 1) {
dieMessage = "Error reading cover art file!\n";
free(art);
art = NULL;
} else if (artSize < 12 || !check_image_header(art)) {
/* the above expression checks the image signature */
dieMessage = "Unsupported cover image file format!\n";
free(art);
art = NULL;
}
fclose(artFile);
} else {
dieMessage = "Error opening cover art file!\n";
}
break;
}
#endif
case SHORTCTL_FLAG:
shortctl = atoi(optarg);
break;
case TNS_FLAG:
useTns = 1;
break;
case NO_TNS_FLAG:
useTns = 0;
break;
case MPEGVERS_FLAG:
mpegVersion = atoi(optarg);
switch(mpegVersion)
{
case 2:
mpegVersion = MPEG2;
break;
case 4:
mpegVersion = MPEG4;
break;
default:
dieMessage = "Unrecognised MPEG version!\n";
}
break;
case OBJTYPE_FLAG:
if (!strcasecmp(optarg, "LC"))
objectType = LOW;
else if (!strcasecmp(optarg, "Main"))
objectType = MAIN;
else if (!strcasecmp(optarg, "LTP")) {
mpegVersion = MPEG4;
objectType = LTP;
} else
dieMessage = "Unrecognised object type!\n";
break;
case 'L':
fprintf(stderr, faac_copyright_string);
dieMessage = license;
break;
case 'X':
rawEndian = 0;
break;
case 'H':
dieMessage = long_help;
break;
case 'h':
dieMessage = short_help;
break;
case '?':
default:
dieMessage = usage;
break;
}
}
/* check that we have at least one non-option arguments */
if (!dieMessage && (argc - optind) > 1 && aacFileNameGiven)
dieMessage = "Cannot encode several input files to one output file.\n";
if (argc - optind < 1 || dieMessage)
{
fprintf(stderr, dieMessage ? dieMessage : usage,
progName, progName, progName, progName);
return 1;
}
while (argc - optind > 0) {
/* get the input file name */
audioFileName = argv[optind++];
/* generate the output file name, if necessary */
if (!aacFileNameGiven) {
char *t = strrchr(audioFileName, '.');
int l = t ? strlen(audioFileName) - strlen(t) : strlen(audioFileName);
#ifdef HAVE_LIBMP4V2
aacFileExt = container == MP4_CONTAINER ? ".m4a" : ".aac";
#else
aacFileExt = ".aac";
#endif
aacFileName = malloc(l+1+4);
memcpy(aacFileName, audioFileName, l);
memcpy(aacFileName + l, aacFileExt, 4);
aacFileName[l+4] = '\0';
} else {
aacFileExt = strrchr(aacFileName, '.');
if (aacFileExt && (!strcmp(".m4a", aacFileExt) || !strcmp(".m4b", aacFileExt) || !strcmp(".mp4", aacFileExt)))
#ifndef HAVE_LIBMP4V2
fprintf(stderr, "WARNING: MP4 support unavailable!\n");
#else
container = MP4_CONTAINER;
#endif
}
/* open the audio input file */
if (rawChans > 0) // use raw input
{
infile = wav_open_read(audioFileName, 1);
if (infile)
{
infile->bigendian = rawEndian;
infile->channels = rawChans;
infile->samplebytes = rawBits / 8;
infile->samplerate = rawRate;
infile->samples /= (infile->channels * infile->samplebytes);
}
}
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 encoder library */
hEncoder = faacEncOpen(infile->samplerate, infile->channels,
&samplesInput, &maxBytesOutput);
#ifdef HAVE_LIBMP4V2
if (container != MP4_CONTAINER && (ntracks || trackno || artist ||
title || album || year || art ||
genre || comment || discno || ndiscs ||
writer || compilation))
{
fprintf(stderr, "Metadata requires MP4 output!\n");
return 1;
}
if (container == MP4_CONTAINER)
{
mpegVersion = MPEG4;
stream = RAW_STREAM;
}
frameSize = samplesInput/infile->channels;
delay_samples = frameSize; // encoder delay 1024 samples
#endif
pcmbuf = (float *)malloc(samplesInput*sizeof(float));
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;
switch (shortctl)
{
case SHORTCTL_NOSHORT:
fprintf(stderr, "disabling short blocks\n");
myFormat->shortctl = shortctl;
break;
case SHORTCTL_NOLONG:
fprintf(stderr, "disabling long blocks\n");
myFormat->shortctl = shortctl;
break;
}
if (infile->channels >= 6)
myFormat->useLfe = 1;
myFormat->allowMidside = useMidSide;
if (bitRate)
myFormat->bitRate = bitRate / infile->channels;
myFormat->bandWidth = cutOff;
if (quantqual > 0)
myFormat->quantqual = quantqual;
myFormat->outputFormat = stream;
myFormat->inputFormat = FAAC_INPUT_FLOAT;
if (!faacEncSetConfiguration(hEncoder, myFormat)) {
fprintf(stderr, "Unsupported output format!\n");
#ifdef HAVE_LIBMP4V2
if (container == MP4_CONTAINER) MP4Close(MP4hFile);
#endif
return 1;
}
#ifdef HAVE_LIBMP4V2
/* initialize MP4 creation */
if (container == MP4_CONTAINER) {
unsigned char *ASC = 0;
unsigned long ASCLength = 0;
char *version_string;
#ifdef MP4_CREATE_EXTENSIBLE_FORMAT
/* hack to compile against libmp4v2 >= 1.0RC3
* why is there no version identifier in mp4.h? */
MP4hFile = MP4Create(aacFileName, MP4_DETAILS_ERROR, 0);
#else
MP4hFile = MP4Create(aacFileName, MP4_DETAILS_ERROR, 0, 0);
#endif
if (!MP4_IS_VALID_FILE_HANDLE(MP4hFile)) {
fprintf(stderr, "Couldn't create output file %s\n", aacFileName);
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?