ref: f8b39149f76c85a5277558b2b64aac7589a7b93a
dir: /frontend/main.c/
/* * FAAC - Freeware Advanced Audio Coder * Copyright (C) 2001 Menno Bakker * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * You should have received a copy of the GNU Lesser General Public * 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.28 2002/08/30 16:20:45 knik Exp $ */ #ifdef _WIN32 #include <windows.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 <sndfile.h> #include <getopt.h> #include <faac.h> #ifndef min #define min(a,b) ( (a) < (b) ? (a) : (b) ) #endif /* globals */ char* progName; int StringCompI(char const *str1, char const *str2, unsigned long len) { signed int c1 = 0, c2 = 0; while (len--) { c1 = tolower(*str1++); c2 = tolower(*str2++); if (c1 == 0 || c1 != c2) break; } return c1 - c2; } int main(int argc, char *argv[]) { int frames, currentFrame; faacEncHandle hEncoder; SNDFILE *infile; SF_INFO sfinfo; unsigned int sr, chan; unsigned long samplesInput, maxBytesOutput; faacEncConfigurationPtr myFormat; unsigned int mpegVersion = MPEG2; unsigned int objectType = LOW; unsigned int useMidSide = 1; unsigned int useTns = 0; unsigned int useAdts = 1; int cutOff = -1; unsigned long bitRate = 0; int psymodelidx = -1; char *audioFileName; char *aacFileName; short *pcmbuf; unsigned char *bitbuf; int bytesInput = 0; FILE *outfile; fprintf(stderr, "FAAC version " FAACENC_VERSION " (" __DATE__ ")\n"); /* begin process command line */ progName = argv[0]; while (1) { int c = -1; int option_index = 0; static struct option long_options[] = { { "mpeg", 0, 0, 'm' }, { "objecttype", 0, 0, 'o' }, { "raw", 0, 0, 'r' }, { "nomidside", 0, 0, 'n' }, { "usetns", 0, 0, 't' }, { "cutoff", 1, 0, 'c' }, { "bitrate", 1, 0, 'b' } }; c = getopt_long(argc, argv, "m:o:rntc:b:p:", long_options, &option_index); if (c == -1) break; switch (c) { case 'm': { unsigned int i; if (optarg) { if (sscanf(optarg, "%u", &i) < 1) { mpegVersion = MPEG2; } else { if (i == 2) mpegVersion = MPEG2; else mpegVersion = MPEG4; } } else { mpegVersion = MPEG2; } break; } case 'o': { unsigned char i[10]; if (optarg) { if (sscanf(optarg, "%s", i) < 1) { objectType = LOW; } else { if (StringCompI(i, "MAIN", 4) == 0) objectType = MAIN; else if (StringCompI(i, "LTP", 3) == 0) objectType = LTP; else objectType = LOW; } } else { objectType = LOW; } break; } case 'r': { useAdts = 0; break; } case 'n': { useMidSide = 0; break; } case 't': { useTns = 1; 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) { if (i > 0 && i < 1000) bitRate = i * 1000; } break; } case 'p': { unsigned int i; if (sscanf(optarg, "%u", &i) > 0) psymodelidx = i; 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) { int i; // get available psymodels hEncoder = faacEncOpen(44100, 2, &samplesInput, &maxBytesOutput); myFormat = faacEncGetCurrentConfiguration(hEncoder); fprintf(stderr, "\nUsage: %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"); 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"); 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." " (default is auto)\n\n"); faacEncClose(hEncoder); return 1; } /* point to the specified file names */ audioFileName = argv[optind++]; aacFileName = argv[optind++]; /* open the audio input file */ infile = sf_open_read(audioFileName, &sfinfo); 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; } /* determine input file parameters */ sr = sfinfo.samplerate; chan = sfinfo.channels; /* open the encoder library */ hEncoder = faacEncOpen(sr, chan, &samplesInput, &maxBytesOutput); pcmbuf = (short*)malloc(samplesInput*sizeof(short)); bitbuf = (unsigned char*)malloc(maxBytesOutput*sizeof(unsigned char)); if (!bitRate) { bitRate = ((sr * 2) / 1000) * 1000; if (bitRate > 64000) bitRate = 64000; } if (cutOff <= 0) { if (cutOff < 0) // default cutOff = bitRate / 4; else // disabled cutOff = sr / 2; } if (cutOff > (sr / 2)) cutOff = sr / 2; fprintf(stderr, "Bit rate: %ld bps per channel\n", bitRate); fprintf(stderr, "Cutoff frequency is "); if (cutOff == sr / 2) fprintf(stderr, "disabled\n"); else fprintf(stderr, "%d Hz\n", cutOff); /* put the options in the configuration struct */ myFormat = faacEncGetCurrentConfiguration(hEncoder); myFormat->aacObjectType = objectType; myFormat->mpegVersion = mpegVersion; myFormat->useTns = useTns; myFormat->allowMidside = useMidSide; 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; } if (outfile) { int showcnt = 0; #ifdef _WIN32 long begin = GetTickCount(); #endif frames = (int)sfinfo.samples / 1024 + 2; currentFrame = 0; fprintf(stderr, "Encoding %s\n", audioFileName); fprintf(stderr, " frame | elapsed/estim | play/CPU | ETA\n"); /* encoding loop */ for ( ;; ) { int bytesWritten; bytesInput = sf_read_short(infile, pcmbuf, samplesInput) * sizeof(short); /* call the actual encoding routine */ bytesWritten = faacEncEncode(hEncoder, pcmbuf, bytesInput/2, bitbuf, maxBytesOutput); if (bytesWritten) { currentFrame++; showcnt--; } if ((showcnt <= 0) || !bytesWritten) { double timeused; #ifdef __unix__ struct rusage usage; #endif #ifdef _WIN32 char percent[50]; 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; 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 / sr) / timeused, timeused * (frames - currentFrame) / currentFrame); fflush(stderr); #ifdef _WIN32 sprintf(percent, "%.2f%% encoding %s", 100.0 * currentFrame / frames, audioFileName); SetConsoleTitle(percent); #endif } } /* all done, bail out */ if (!bytesInput && !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); sf_close(infile); if (pcmbuf) free(pcmbuf); if (bitbuf) free(bitbuf); return 0; } /* $Log: main.c,v $ Revision 1.28 2002/08/30 16:20:45 knik misplaced #endif Revision 1.27 2002/08/19 16:33:54 knik automatic bitrate setting more advanced status line */