⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 faac-1.25.rar音频编解码器demo
💻 C
字号:
/*
 * FAAC - Freeware Advanced Audio Coder
 * Copyright (C) 2001 Menno Bakker
 * Copyright (C) 2002-2004 Krzysztof Nikiel
 * Copyright (C) 2004 Dan Villiom P. Christiansen
 *
 * 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.78 2004/12/08 11:07:17 menno Exp $
 */

#ifdef _MSC_VER
# define HAVE_LIBMP4V2  1
#endif

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#define DEFAULT_TNS     0

#ifdef _WIN32
#include <windows.h>
#include <fcntl.h>
#else
#include <signal.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <math.h>
#include <string.h>

#include "DS.h"

#ifdef HAVE_GETOPT_H
# include <getopt.h>
#else
# include "getopt.h"
# include "getopt.c"
#endif

#if !defined(HAVE_STRCASECMP) && !defined(_WIN32)
# define strcasecmp strcmp
#endif

#ifdef _WIN32
# undef stderr
# define stderr stdout
#endif

#include "input.h"

#include <faac.h>

/* globals */
char* progName;

enum stream_format {
  RAW_STREAM = 0,
  ADTS_STREAM = 1,
};

enum flags {
  SHORTCTL_FLAG = 300,
  TNS_FLAG = 301,
  NO_TNS_FLAG = 302,
  MPEGVERS_FLAG = 303,
  OBJTYPE_FLAG = 304,
  NO_MIDSIDE_FLAG = 306,
};


static int *mkChanMap(int channels, int center, int lf)
{
    int *map;
    int inpos;
    int outpos;

    if (!center && !lf)
        return NULL;

    if (channels < 3)
        return NULL;

    if (lf > 0)
        lf--;
    else
        lf = channels - 1; // default AAC position

    if (center > 0)
        center--;
    else
        center = 0; // default AAC position

    map = malloc(channels * sizeof(map[0]));
    memset(map, 0, channels * sizeof(map[0]));

    outpos = 0;
    if ((center >= 0) && (center < channels))
        map[outpos++] = center;

    inpos = 0;
    for (; outpos < (channels - 1); inpos++)
    {
        if (inpos == center)
            continue;
        if (inpos == lf)
            continue;

        map[outpos++] = inpos;
    }
    if (outpos < channels)
    {
        if ((lf >= 0) && (lf < channels))
            map[outpos] = lf;
        else
            map[outpos] = inpos;
    }

    return map;
}

int main(int argc, char *argv[])
{
    int frames, currentFrame;
    faacEncHandle hEncoder;
    pcmfile_t *infile = NULL;

    unsigned long samplesInput, maxBytesOutput, totalBytesWritten=0;

    faacEncConfigurationPtr myFormat;
    unsigned int mpegVersion = MPEG2;
    unsigned int objectType = LOW;
    unsigned int useMidSide = 1;
    static unsigned int useTns = DEFAULT_TNS;
    enum stream_format stream = ADTS_STREAM;
    int cutOff = -1;
    int bitRate = 0;
    unsigned long quantqual = 0;
    int chanC = 3;
    int chanLF = 4;

    char *audioFileName = ".\\Debug\\2.wav";
    char *aacFileName = "2.aac";

    float *pcmbuf;
    int *chanmap = NULL;

    unsigned char *bitbuf;
    int samplesRead = 0;    
    int rawChans = 0; // disabled by default
    int rawBits = 16;
    int rawRate = 44100;
    int rawEndian = 1;
    int shortctl = SHORTCTL_NORMAL;
    FILE *outfile = NULL;

    u_int64_t total_samples = 0;
    u_int64_t encoded_samples = 0;
    unsigned int delay_samples;
    unsigned int frameSize;
    char *faac_id_string;
    char *faac_copyright_string;

    // 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;
    }
	
    /* 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);
    
    frameSize = samplesInput/infile->channels;
    delay_samples = frameSize; // encoder delay 1024 samples

    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;
    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");
        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;
	}
    
	cutOff = myFormat->bandWidth;
    quantqual = myFormat->quantqual;
    bitRate = myFormat->bitRate;
    
    if (outfile)
    {
        int showcnt = 0;
        if (infile->samples)
            frames = ((infile->samples + 1023) / 1024) + 1;
        else
            frames = 0;
        currentFrame = 0;

        /* encoding loop */
		for (;;)
        {
            int bytesWritten;

            samplesRead = wav_read_float32(infile, pcmbuf, samplesInput, chanmap);//要改写
            total_samples += samplesRead / infile->channels;

            /* call the actual encoding routine */
            bytesWritten = faacEncEncode(hEncoder,
									(int32_t *)pcmbuf,
									samplesRead,
									bitbuf,
									maxBytesOutput);
            if (bytesWritten)
            {
                currentFrame++;
                showcnt--;
				totalBytesWritten += bytesWritten;
            }            

            /* all done, bail out */
            if (!samplesRead && !bytesWritten)
                break ;
            if (bytesWritten < 0)
            {
                fprintf(stderr, "faacEncEncode() failed\n");
                break ;
            }
            if (bytesWritten > 0)
            {
                u_int64_t samples_left = total_samples - encoded_samples + delay_samples;
                u_int64_t dur = samples_left > frameSize ? frameSize : samples_left;
                u_int64_t ofs = encoded_samples > 0 ? 0 : delay_samples;
				
				/* write bitstream to aac file */
				fwrite(bitbuf, 1, bytesWritten, outfile);//要改写
                encoded_samples += dur;
            }
        }
		fclose(outfile);
    }

    faacEncClose(hEncoder);
    wav_close(infile);

    if (pcmbuf) free(pcmbuf);
    if (bitbuf) free(bitbuf);
	if(chanmap) free(chanmap);

    return 0;
}

/*
$Log: main.c,v $
Revision 1.78  2004/12/08 11:07:17  menno
Make long help work again

Revision 1.77  2004/08/19 15:33:30  menno
typo
it's not bad to have this option, but people should be warned that they can get severe playback problems with RAW AAC files (anything other then 44100 will not be decoded properly unless you know that it has that samplerate). Seeking is also not possible on these files.

Revision 1.76  2004/08/19 13:18:44  menno
Removed stupid comment in help of FAAC. RAW AAC files are USELESS, it seems that already some people encoded their collection using the -r option.

Revision 1.75  2004/08/06 19:33:19  danchr
TNS is no longer enabled by default (reported by guruboolez)
documentation fixes in frontend
default to mp4 for *.m4b as well

Revision 1.74  2004/08/03 00:08:51  danchr
fix --shortctl documentation

Revision 1.73  2004/08/02 20:53:23  danchr
*BSD portability fix

Revision 1.72  2004/08/02 20:41:59  danchr
NetBSD portability fix + fixing metadata bugs w/ sscanf()

Revision 1.71  2004/07/28 08:18:21  danchr
Darwin portability fixes, should help on Linux too

Revision 1.70  2004/05/03 11:39:05  danchr
fix documentation bugs (per Hans-J黵gen's suggestions)
enable (preliminary) multiple output file support

Revision 1.69  2004/04/22 14:07:14  danchr
set copyright notice to my full name

Revision 1.68  2004/04/16 14:51:10  danchr
don't use stderr on Windows

Revision 1.67  2004/04/16 09:49:10  danchr
change -a <kbps/channel> to -b <kbps>
Darwin portability fixes
Make LTP imply MPEG-4 AAC
silence a few warnings

Revision 1.66  2004/04/13 13:47:05  danchr
compilation and composer patch by Jordan Breeding
undocumented single-letter switches removed
numerous bug-fixes

Revision 1.65  2004/04/03 17:47:40  danchr
fix typo + add GIF support

Revision 1.64  2004/04/03 15:54:48  danchr
make TNS default

Revision 1.63  2004/04/03 15:50:05  danchr
non-backwards compatible revamp of the FAAC command line interface
cover art metadata support based on patch by Jordan Breeding (jordan breeding (a) mac com)

Revision 1.62  2004/03/29 14:02:04  danchr
MP4 bug fixes by Jordan Breeding (jordan breeding (a) mac com)
Document long options for metadata - they are much more intuitive.

Revision 1.61  2004/03/27 13:44:24  danchr
minor compile-time bugfix for Win32

Revision 1.60  2004/03/24 15:44:08  danchr
fixing WIN32 -> _WIN32

Revision 1.59  2004/03/24 11:09:06  danchr
prettify the way stream format is handled - this just *might* fix a bug

Revision 1.58  2004/03/24 11:00:40  danchr
silence a few warnings and fix a few mem. leaks
make it possible to disable stripping (needed for profiling and debugging)

Revision 1.57  2004/03/17 13:32:13  danchr
- New signal handler. Disabled on Windows, although it *should* work.
- Separated handling of stream format and output format.
- Bitrate + file format displayed on stderr.
- knik and myself added to the copyright header.

Revision 1.56  2004/03/15 20:15:48  knik
improved MP4 support by Dan Christiansen

Revision 1.55  2004/03/03 15:54:50  knik
libmp4v2 autoconf detection and mp4 metadata support by Dan Christiansen

Revision 1.54  2004/02/14 10:31:23  knik
Print help and exit when unknown option is specified.

Revision 1.53  2003/12/20 04:32:48  stux
i've added sms00's OSX patch to faac

Revision 1.52  2003/12/14 12:25:44  ca5e
Gapless MP4 handling method changed again...

Revision 1.51  2003/12/13 21:58:35  ca5e
Improved gapless encoding

Revision 1.50  2003/11/24 18:11:14  knik
using new version info interface

Revision 1.49  2003/11/13 18:30:19  knik
raw input bugfix

Revision 1.48  2003/10/17 17:11:18  knik
fixed raw input

Revision 1.47  2003/10/12 14:30:29  knik
more accurate average bitrate control

Revision 1.46  2003/09/24 16:30:34  knik
Added option to enforce block type.

Revision 1.45  2003/09/08 16:28:21  knik
conditional libmp4v2 compilation

Revision 1.44  2003/09/07 17:44:36  ca5e
length calculations/silence padding changed to match current libfaac behavior
changed tabs to spaces, fixes to indentation

Revision 1.43  2003/08/17 19:38:15  menno
fixes to MP4 files by Case

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.

Revision 1.40  2003/08/07 11:28:06  knik
fixed win32 crash with long filenames

Revision 1.39  2003/07/21 16:33:49  knik
Fixed LFE channel mapping.

Revision 1.38  2003/07/13 08:34:43  knik
Fixed -o, -m and -I option.
Print object type setting.

Revision 1.37  2003/07/10 19:19:32  knik
Input channel remapping and 24-bit support.

Revision 1.36  2003/06/26 19:40:53  knik
TNS disabled by default.
Copyright info moved to library.
Print help to standard output.

Revision 1.35  2003/06/21 08:59:31  knik
raw input support moved to input.c

Revision 1.34  2003/05/10 09:40:35  knik
added approximate ABR option

Revision 1.33  2003/04/13 08:39:28  knik
removed psymodel setting

Revision 1.32  2003/03/27 17:11:06  knik
updated library interface
-b bitrate option replaced with -q quality option
TNS enabled by default

Revision 1.31  2002/12/23 19:02:43  knik
added some headers

Revision 1.30  2002/12/15 15:16:55  menno
Some portability changes

Revision 1.29  2002/11/23 17:34:59  knik
replaced libsndfile with input.c
improved bandwidth/bitrate calculation formula

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

*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -