faac.c
上传用户:sun1608
上传日期:2007-02-02
资源大小:6116k
文件大小:8k
源码类别:

流媒体/Mpeg4/MP4

开发平台:

Visual C++

  1. /*
  2.  * FAAC - Freeware Advanced Audio Coder
  3.  * Copyright (C) 2001 Menno Bakker
  4.  *
  5.  * This library is free software; you can redistribute it and/or
  6.  * modify it under the terms of the GNU Lesser General Public
  7.  * License as published by the Free Software Foundation; either
  8.  * version 2.1 of the License, or (at your option) any later version.
  9.  *
  10.  * This library is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  13.  * Lesser General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU Lesser General Public
  16.  * License along with this library; if not, write to the Free Software
  17.  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  18.  *
  19.  * $Id: faac.c,v 1.13 2002/04/24 22:25:41 wmay Exp $
  20.  */
  21. #include "systems.h"
  22. #ifdef HAVE_GETRUSAGE
  23. #include <sys/resource.h>
  24. #endif
  25. #ifdef HAVE_LIBSNDFILE
  26. #include <sndfile.h>
  27. #endif
  28. #include "faac.h"
  29. #include "util.h"
  30. int main(int argc, char *argv[])
  31. {
  32. int i, frames, currentFrame;
  33. faacEncHandle hEncoder;
  34. #ifdef HAVE_LIBSNDFILE
  35. SNDFILE *infile;
  36. SF_INFO sfinfo;
  37. #else
  38. FILE *infile;
  39. #endif
  40. faacEncConfiguration myFormat;
  41. unsigned long totalDesiredBitRate = 0;
  42. int rawInput = 0;
  43. unsigned long rawSampleRate = 44100;
  44. int swapRawBytes = 0;
  45. int channels;
  46. long samples;
  47. unsigned long samplesInput, maxBytesOutput;
  48. short *pcmbuf;
  49. unsigned char *bitbuf;
  50. int bytesInput = 0;
  51. FILE *outfile;
  52. #ifdef HAVE_GETRUSAGE
  53. struct rusage usage;
  54. #endif
  55. #ifndef _WIN32
  56. float totalSecs;
  57. int mins;
  58. #else
  59. long begin, end;
  60. int nTotSecs, nSecs;
  61. int nMins;
  62. #endif
  63. /* get the default encoder configuration values */
  64. hEncoder = faacEncOpen(44100, 2, &samplesInput, &maxBytesOutput);
  65. memcpy(&myFormat, faacEncGetCurrentConfiguration(hEncoder),
  66. sizeof(myFormat));
  67. faacEncClose(hEncoder);
  68. hEncoder = 0;
  69. printf("FAAC - command line demo of %sn", __DATE__);
  70. printf("Uses FAACLIB version: %.1f %snn", FAACENC_VERSION, (FAACENC_VERSIONB)?"beta":"");
  71. if (argc < 3)
  72. {
  73. printf("USAGE: %s -options infile outfilen", argv[0]);
  74. printf("Options:n");
  75. printf("  -mX   AAC MPEG version, X can be 2 or 4.n");
  76. printf("  -pX   AAC object type, X can be LC, MAIN or LTP.n");
  77. printf("  -nm   Don't use mid/side coding.n");
  78. printf("  -tns  Use TNS coding.n");
  79. printf("  -bX   Set the total bitrate, X in Kbps.nn");
  80. printf("  -brX  Set the bitrate per channel, X in bps.nn");
  81. printf("  -bwX  Set the bandwidth, X in Hz.n");
  82. printf("  -rX   Input is raw 16 bit stereo PCM at X Hz, default 44100.n");
  83. printf("  -x    Swap raw input bytes.n");
  84. return 1;
  85. }
  86. /* set other options */
  87. if (argc > 3)
  88. {
  89. for (i = 1; i < argc-2; i++) {
  90. if ((argv[i][0] == '-') || (argv[i][0] == '/')) {
  91. switch(argv[i][1]) {
  92. case 'p': case 'P':
  93. if ((argv[i][2] == 'l') || (argv[i][2] == 'L')) {
  94. if ((argv[i][3] == 'c') || (argv[i][3] == 'C')) {
  95. myFormat.aacObjectType = LOW;
  96. } else if ((argv[i][3] == 't') || (argv[i][3] == 'T')) {
  97. myFormat.aacObjectType = LTP;
  98. }
  99. } else if ((argv[i][2] == 'm') || (argv[i][2] == 'M')) {
  100. myFormat.aacObjectType = MAIN;
  101. }
  102. break;
  103. case 'm': case 'M':
  104. if (argv[i][2] == '4') {
  105. myFormat.mpegVersion = MPEG4;
  106. } else {
  107. myFormat.mpegVersion = MPEG2;
  108. }
  109. break;
  110. case 't': case 'T':
  111. if ((argv[i][2] == 'n') || (argv[i][2] == 'N'))
  112. myFormat.useTns = 1;
  113. break;
  114. case 'n': case 'N':
  115. if ((argv[i][2] == 'm') || (argv[i][2] == 'M'))
  116. myFormat.allowMidside = 0;
  117. break;
  118. case 'b': case 'B':
  119. if ((argv[i][2] == 'r') || (argv[i][2] == 'R'))
  120. {
  121. unsigned int bitrate = atol(&argv[i][3]);
  122. if (bitrate)
  123. {
  124. myFormat.bitRate = bitrate;
  125. }
  126. } else if ((argv[i][2] == 'w') || (argv[i][2] == 'W')) {
  127. unsigned int bandwidth = atol(&argv[i][3]);
  128. if (bandwidth)
  129. {
  130. myFormat.bandWidth = bandwidth;
  131. }
  132. } else if (isdigit(argv[i][2])) {
  133. unsigned int bitrate = atol(&argv[i][2]);
  134. if (bitrate)
  135. {
  136. totalDesiredBitRate = bitrate * 1000;
  137. }
  138. }
  139. break;
  140. case 'r':
  141. rawInput = 1;
  142. if (isdigit(argv[i][2])) {
  143. rawSampleRate = atol(&argv[i][2]);
  144. } else {
  145. rawSampleRate = 44100;
  146. }
  147. break;
  148. case 'x':
  149. swapRawBytes = 1;
  150. break;
  151. }
  152. }
  153. }
  154. }
  155. /* handle raw audio input */
  156.     if (rawInput) {
  157. #ifdef HAVE_LIBSNDFILE
  158. sfinfo.format =  SF_FORMAT_RAW;
  159. if (swapRawBytes) {
  160. if (IsBigEndian()) {
  161. sfinfo.format |= SF_FORMAT_PCM_LE;
  162. } else {
  163. sfinfo.format |= SF_FORMAT_PCM_BE;
  164. }
  165. } else {
  166. if (IsBigEndian()) {
  167. sfinfo.format |= SF_FORMAT_PCM_BE;
  168. } else {
  169. sfinfo.format |= SF_FORMAT_PCM_LE;
  170. }
  171. }
  172. sfinfo.pcmbitwidth = 16;
  173. sfinfo.channels = 2;
  174. sfinfo.samplerate = rawSampleRate;
  175. #else
  176. channels = 2;
  177. #endif
  178.     }
  179. #ifndef HAVE_LIBSNDFILE
  180.     else {
  181.       printf("Without libsndfile, only raw format is allowedn");
  182.       return 1;
  183.     }
  184. #endif
  185. /* open the audio input file */
  186. #ifdef HAVE_LIBSNDFILE
  187. infile = sf_open_read(argv[argc-2], &sfinfo);
  188. rawSampleRate = sfinfo.samplerate;
  189. channels = sfinfo.channels;
  190. samples = sfinfo.samples;
  191. #else
  192. infile = fopen(argv[argc-2], FOPEN_READ_BINARY);
  193. fseek(infile, 0, SEEK_END);
  194. samples = ftell(infile) / 2;
  195. fseek(infile, 0, SEEK_SET);
  196. #endif
  197. if (infile == NULL)
  198. {
  199. printf("couldn't open input file %sn", argv [argc-2]);
  200. return 1;
  201. }
  202. /* open the aac output file */
  203. outfile = fopen(argv[argc-1], FOPEN_WRITE_BINARY);
  204. if (!outfile)
  205. {
  206. printf("couldn't create output file %sn", argv [argc-1]);
  207. return 1;
  208. }
  209. /* open the encoder library */
  210. hEncoder = faacEncOpen(rawSampleRate, channels,
  211. &samplesInput, &maxBytesOutput);
  212. if (totalDesiredBitRate) {
  213. myFormat.bitRate = totalDesiredBitRate / channels;
  214. if (!faacEncSetConfiguration(hEncoder, &myFormat))
  215. fprintf(stderr, "unsupported output format!n");
  216. pcmbuf = (short*)malloc(samplesInput*sizeof(short));
  217. bitbuf = (unsigned char*)malloc(maxBytesOutput*sizeof(unsigned char));
  218. if (outfile)
  219. {
  220. #ifndef HAVE_GETRUSAGE
  221. begin = GetTickCount();
  222. #endif
  223. frames = (int)(samples/1024+0.5);
  224. currentFrame = 0;
  225. /* encoding loop */
  226. for ( ;; )
  227. {
  228. int bytesWritten;
  229. currentFrame++;
  230. #ifdef HAVE_LIBSNDFILE
  231. bytesInput = sf_read_short(infile, pcmbuf, samplesInput) * sizeof(short);
  232. #else
  233. bytesInput = fread(pcmbuf, 1, sizeof(short)* samplesInput, infile);
  234. if (swapRawBytes) {
  235.   unsigned long ix;
  236.   for (ix = 0; ix < samplesInput; ix++) {
  237.     unsigned short temp;
  238.     temp = pcmbuf[ix];
  239.     pcmbuf[ix] = ((temp >> 8) & 0xff) | (temp << 8);
  240.   }
  241. }
  242. #endif
  243. /* call the actual encoding routine */
  244. bytesWritten = faacEncEncode(hEncoder,
  245. pcmbuf,
  246. bytesInput/2,
  247. bitbuf,
  248. maxBytesOutput);
  249. #ifndef _DEBUG
  250. #ifndef MIN
  251. #define MIN(a,b) ((a) < (b) ? (a) : (b))
  252. #endif
  253. printf("%.2f%%tBusy encoding %s.r",
  254. MIN((double)(currentFrame*100)/frames,100), argv[argc-2]);
  255. #endif
  256. /* all done, bail out */
  257. if (!bytesInput && !bytesWritten)
  258. break ;
  259. if (bytesWritten < 0)
  260. {
  261. fprintf(stderr, "faacEncEncode() failedn");
  262. break ;
  263. }
  264. /* write bitstream to aac file */
  265. fwrite(bitbuf, 1, bytesWritten, outfile);
  266. }
  267. /* clean up */
  268. fclose(outfile);
  269. #ifdef _WIN32
  270. end = GetTickCount();
  271. nTotSecs = (end-begin)/1000;
  272. nMins = nTotSecs / 60;
  273. nSecs = nTotSecs - (60*nMins);
  274. printf("Encoding %s took:t%d:%.2dtn", argv[argc-2], nMins, nSecs);
  275. #else
  276. #ifdef HAVE_GETRUSAGE
  277. if (getrusage(RUSAGE_SELF, &usage) == 0) {
  278. totalSecs = usage.ru_utime.tv_sec;
  279. mins = totalSecs/60;
  280. printf("Encoding %s took: %i min, %.2f sec. of cpu-timen", argv[argc-2], mins, totalSecs - (60 * mins));
  281. }
  282. #else
  283. totalSecs = (float)(clock())/(float)CLOCKS_PER_SEC;
  284. mins = totalSecs/60;
  285. printf("Encoding %s took: %i min, %.2f sec.n", argv[argc-2], mins, totalSecs - (60 * mins));
  286. #endif
  287. #endif
  288. }
  289. faacEncClose(hEncoder);
  290. #ifdef HAVE_SNDFILE
  291. sf_close(infile);
  292. #else
  293. fclose(infile);
  294. #endif
  295. if (pcmbuf) free(pcmbuf);
  296. if (bitbuf) free(bitbuf);
  297. return 0;
  298. }