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

📄 main.c

📁 功能非常完善的MP3编译码器,输入文件WAV或AIFF,能够方便的嵌入到你自己的系统当中.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
			(c) Copyright 1998, 1999 - Tord Jansson
			=======================================

		This file is part of the BladeEnc MP3 Encoder, based on
		ISO's reference code for MPEG Layer 3 compression.

		This file doesn't contain any of the ISO reference code and
		is copyright Tord Jansson (tord.jansson@swipnet.se).

	BladeEnc is free software; you can redistribute this file
	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.

*/

#include		<stdio.h>
#include    <stdlib.h>
#include    <string.h>
#include    <time.h>
#include    "system.h"
#include		"codec.h"
#include    "samplein.h"
#include		"bladesys.h"

#define MAX_NAMELEN 256

#ifdef OS2
	#define INCL_DOSFILEMGR
	#define INCL_DOSERRORS
	#define INCL_DOSPROCESS
	#include <os2.h>
	#include "os2key.h"
#endif

extern	char *mystrupr(char * strng);


/*____ Structure Definitions __________________________________________________*/

typedef struct  JobDef  Job;

struct JobDef
{
        CodecInitIn		sCodec;
        SplIn         sInput;
        Job         * psNext;
        int           fDeleteSource;
        char          outputFilename[MAX_NAMELEN];
        char          sourceFilename[MAX_NAMELEN];
};


/*____ Function Prototypes ____________________________________________________*/

int     printUsage( void );
int			validateJobs( Job * psJob );
int			readGlobalSwitches( int argc, char * argv[] );
int			readLocalSwitches( int argc, char * argv[], Job * psJob );
int			addCommandlineJob( int argc, char * argv[] );
int     addFileToBatch( char * pFilename, char * pOutputFilename );
int     clearJobQueue( void );
int     removeJobQueueEntry( Job * psJob );

int     readL3EncCommandline( int argc, char * argv[] );

void		updateProgressIndicator( time_t startBatch, double batchLen, double batchDone,
                                 time_t startFile, unsigned int fileLen, unsigned int fileDone );
void    quit( int returnValue );




/*____ Static Data ____________________________________________________________*/



/* Parameters set through the commandline. */

int				wantedBitrate = -1;             /* -1 = Unspecified. */
int				wantedCRC = FALSE;
int				wantedPrivate = FALSE;
int				wantedCopyright = FALSE;
int				wantedOriginal = TRUE;
int				wantedChannelSwap = FALSE;
SampleType	wantedInputType = STEREO;

int     wantedDeleteSource = FALSE;

#ifdef	WAIT_KEY
	int     wantedQuit = FALSE;
#else
	int			wantedQuit = TRUE;
#endif
int			wantedQuiet = FALSE;
int			wantedSTDOUT = FALSE;
int			fPreparedSTDIN = FALSE;

char		prioString[256];
char	* pPrioString = NULL;

Job		* psJobQueue = NULL;

char		outputDir[MAX_NAMELEN];

FILE	* textout;

/*____ main() _________________________________________________________________*/

int main( int argc, char* argv[] )
{
	int           samplesPerFrame;
	int           nSamples;

  short         readBuffer[2304];
  int           x;

  char          mystring[2] = { 13, 0 };
  char          input;
  Job         * psTemp;

  time_t        startTimeBatch, startTimeFile, currTime;
  double        batchSamplesTotal = 0.0, batchSamplesRead = 0.0;

  CodecInitOut *pCodecInfo;
  char        * pBuffer;
  uint          encodedChunkSize;
  FILE        * fp;

	int						cmdOfs;
	char					temp[256];
#ifdef	WILDCARDS
	void				* pWildcardLink;
#endif

	/* First things first... */

 	textout = stdout;	
	outputDir[0] = 0;

#ifdef	WILDCARDS
	pWildcardLink = expandWildcards( &argc, &argv );
#endif

	cmdOfs = readGlobalSwitches( argc-1, argv+1 ) +1;

	/* Check for STDOUT */

	for( x = 1 ; x < argc ; x++ )
	{
		strcpy( temp, argv[x] );
		mystrupr( temp );
		if( strcmp( temp, "STDOUT" ) == 0 )
		{
			prepStdout();
			textout = stderr;
			break;
		}
	}

  /* Print Text */

	if( !wantedQuiet )
	{
		fprintf( textout, "\n" );
		fprintf( textout, "BladeEnc 0.82    (c) Tord Jansson       Homepage: http://www.bladeenc.cjb.net\n" );
		fprintf( textout, "===============================================================================\n" );
		fprintf( textout, "BladeEnc is free software, distributed under the Lesser General Public License.\n" );
		fprintf( textout, "See the file COPYING, BladeEnc's homepage or www.fsf.org for more details.\n" );
    fprintf( textout, "\n" );
	}

	/* Initialise batch */

	while( cmdOfs < argc )
	{
		x = addCommandlineJob( argc - cmdOfs, &argv[cmdOfs] );
		if( x == 0 )
		{
#ifdef	WILDCARDS	
			freeExpandWildcardMem( pWildcardLink );
#endif
			quit( -1 );
		}
		cmdOfs += x;
	}

#ifdef	WILDCARDS
	freeExpandWildcardMem( pWildcardLink );
#endif
	

	/* Validate job settings */

	x = validateJobs( psJobQueue );
  if( x == FALSE )
    quit( -2 );


  /* Set priority */

	if( setPriority( pPrioString ) == FALSE )
	{
		fprintf( textout, "Error: '%s' is not a valid priority setting!\n", pPrioString );
		quit(	-1 );
	};

	/* Procedure if no files found */

  if( psJobQueue == NULL )
  {
    printUsage();                                                           /* No files on the commandline */
    quit( -1 );
  }


  /* Print files to encode */

  for( x = 0, psTemp = psJobQueue ; psTemp != NULL ; x++, psTemp = psTemp->psNext );
	if( !wantedQuiet )
	  fprintf( textout, "Files to encode: %d\n\n", x );


  /* Encode */

  startTimeBatch = time( NULL );

  for( psTemp = psJobQueue ; psTemp != NULL ; batchSamplesTotal += psTemp->sInput.length, psTemp = psTemp->psNext );


  while( psJobQueue != NULL )
  {
    /* Print information */

		if( !wantedQuiet )
		{
			fprintf( textout, "Encoding:  %s\n", psJobQueue->sourceFilename );
			fprintf( textout, "Input:     %.1f kHz, %d bit, ", psJobQueue->sInput.freq/1000.f, psJobQueue->sInput.bits );
			if( psJobQueue->sInput.fReadStereo == TRUE )
				fprintf( textout, "stereo.\n" );
			else
				fprintf( textout, "mono.\n" );
			fprintf( textout, "Output:    %d kBit, ", psJobQueue->sCodec.bitrate );
			if( psJobQueue->sCodec.mode == 0 )
				fprintf( textout, "stereo.\n\n" );
			else
				fprintf( textout, "mono.\n\n" );
		}

    /* Init a new job */

    startTimeFile = time( NULL );
    pCodecInfo = codecInit( &psJobQueue->sCodec );
    samplesPerFrame = pCodecInfo->nSamples;
    pBuffer = (char *) malloc( pCodecInfo->bufferSize );
		if( strcmp( psJobQueue->outputFilename, "STDOUT" ) == 0 )
			fp = stdout;
		else
		{
			fp = fopen( psJobQueue->outputFilename, "wb" );
			if( fp == NULL )
			{
		/*  codecExit(); */
				closeInput( &psJobQueue->sInput );
				fprintf( textout, "ERROR: Couldn't create '%s'!\n", psJobQueue->outputFilename );
				quit( -1 );
			}
		}

    /* Encoding loop */

    while ( (nSamples = readSamples( &psJobQueue->sInput, samplesPerFrame, readBuffer)) > 0 )
    {
      encodedChunkSize = codecEncodeChunk( nSamples, readBuffer, pBuffer );
      if( fwrite( pBuffer, 1, encodedChunkSize, fp ) != encodedChunkSize )
      {
        fprintf( textout, "ERROR: Couldn't write '%s'! Disc probably full.\n", psJobQueue->outputFilename );
        quit( -1 );
      }

      batchSamplesRead += nSamples;

			if( !wantedQuiet )
				updateProgressIndicator( startTimeBatch, batchSamplesTotal, batchSamplesRead,
					                       startTimeFile, psJobQueue->sInput.length,
						                     psJobQueue->sInput.length - psJobQueue->sInput.samplesLeft );
			if( be_kbhit() != 0 )
			{
				input = be_getch();
				if( input == 27 )
        {
          fprintf( textout, "%s                                                                             %s", mystring, mystring );
          fprintf( textout, "Quit, are you sure? (y/n)" );
					fflush( textout );
          input = be_getch();
          if( input == 'y' || input == 'Y' )
          {
            encodedChunkSize = codecExit( pBuffer );
            if( encodedChunkSize != 0 )
              if( fwrite( pBuffer, encodedChunkSize, 1, fp ) != 1 )
              {
                fprintf( textout, "ERROR: Couldn't write '%s'! Disc probably full.\n", psJobQueue->outputFilename );
                quit( -1 );
              }
            free( pBuffer );
            closeInput( &psJobQueue->sInput );
						if( fp != stdout )
							fclose( fp );
            return  0;
          }
          else
            fprintf( textout, "%s                                                                             %s", mystring, mystring );
        }
      }
    }

    /* File done */


    encodedChunkSize = codecExit( pBuffer );
    if( encodedChunkSize != 0 )
      if( fwrite( pBuffer, encodedChunkSize, 1, fp ) != 1 )
      {
        fprintf( textout, "ERROR: Couldn't write '%s'! Disc probably full.\n", psJobQueue->outputFilename );
        quit( -1 );
      }
    if( fp != stdout )
			fclose( fp );
    free( pBuffer );
    if( psJobQueue->fDeleteSource == TRUE )
      remove( psJobQueue->sourceFilename );
    x = time( NULL ) - startTimeFile;
		if( !wantedQuiet )
		{
			fprintf( textout, "%s                                                                             %s", mystring, mystring );
			fprintf( textout, "Completed. Encoding time: %02d:%02d:%02d (%.2fX)\n\n",
               x/3600, (x/60)%60, x%60, ((float)psJobQueue->sInput.length) /
               ((psJobQueue->sInput.fReadStereo+1)*psJobQueue->sInput.freq*x) );
		}
    removeJobQueueEntry( psJobQueue );
  }

  /* Batch done */

  if( !wantedQuiet )
  {
    currTime = time( NULL ) - startTimeBatch;
    fprintf( textout, "All operations completed. Total encoding time: %02d:%02d:%02d\n",
             (int) currTime/3600, (int)(currTime/60)%60, (int) currTime%60 );

    if( !wantedQuit )
		{
			fprintf( textout, "Press ENTER to exit..." );
			be_getch();
		  fprintf( textout, "\n" );
		}
  }

  return 0;
}



/*____ quit() _________________________________________________________________*/

void    quit( int returnValue )
{
	if( !wantedQuit )
	{
		fprintf( textout, "Press ENTER to exit..." );
		be_getch();
	  fprintf( textout, "\n" );
	}
  exit( returnValue );
}



/*____ updateProgressIndicator() ______________________________________________*/

void    updateProgressIndicator( time_t startBatch, double batchLen, double batchDone,
                                 time_t startFile, unsigned int fileLen, unsigned int fileDone )
{
  time_t  currTime;
  float   percentageFile, percentageBatch;
  int     fileEta, batchEta;

  char    mystring[2] = { 13, 0 };                        /* CR without LF. */


  currTime = time( NULL );

  percentageFile = ((float)fileDone) / fileLen * 100;
  if( percentageFile < 100 )
  {
    fileEta = (int) (((float)(currTime - startFile)) / fileDone * (fileLen - fileDone) );

    percentageBatch = (float)(batchDone / batchLen * 100);
    batchEta = (int) (((float)(currTime - startBatch)) / batchDone * (batchLen - batchDone));
    fprintf( textout, "Status:   %4.1f%% done, ETA %02d:%02d:%02d          BATCH: %4.1f%% done, ETA %02d:%02d:%02d%s",
	           percentageFile, fileEta/3600, (fileEta/60)%60, fileEta%60,
           	 percentageBatch, batchEta/3600, (batchEta/60)%60, batchEta%60,
             mystring );
		fflush( textout );
  }
}

/*____ setOutputDir() _______________________________________________________*/

void	setOutputDir( char * pPath )
{
	int		i;

	strcpy( outputDir, pPath );
	i = strlen( outputDir ) -1;
	if( outputDir[i] != '\\' && outputDir[i] != '/' )
	{
		outputDir[i+1] = DIRECTORY_SEPARATOR;
		outputDir[i+2] = 0;
	}
}

/*____ readGlobalSwitches() ___________________________________________________*/

int			readGlobalSwitches( int argc, char * argv[] )
{
	int			ofs;
	char		arg[256];
	int			x, y;
	
	for( ofs = 0 ; ofs < argc ; ofs++ )
	{
		strcpy( arg, argv[ofs] );
		mystrupr( arg );
		if( arg[0] != '-' )
			return	ofs;
		if( !strcmp( arg+1, "MONO" ) || !strcmp( arg+1, "DM" ) )
			wantedInputType = DOWNMIX_MONO;
    else if( !strcmp( arg+1, "CRC" ) )
      wantedCRC = TRUE;
    else if( !strcmp( arg+1, "PRIVATE" ) || !strcmp( arg+1, "P" ) )
      wantedPrivate = TRUE;
    else if( !strcmp( arg+1, "COPYRIGHT" ) || !strcmp( arg+1, "C" ) )
      wantedCopyright = TRUE;
    else if( !strcmp( arg+1, "ORIGINAL" ) )
      wantedOriginal = TRUE;
    else if( !strcmp( arg+1, "COPY" ) )
      wantedOriginal = FALSE;
    else if( !strcmp( arg+1, "DELETE" ) || !strcmp( arg+1, "DEL" ) )
      wantedDeleteSource = TRUE;
    else if( !strcmp( arg+1, "QUIT" ) || !strcmp( arg+1, "Q" ))
      wantedQuit = TRUE;
		else if( !strcmp( arg+1, "SWAP" ) )
			wantedInputType = INVERSE_STEREO;
		else if( !strcmp( arg+1, "LEFTMONO" ) || !strcmp( arg+1, "LM" ))
			wantedInputType = LEFT_CHANNEL_MONO;
		else if( !strcmp( arg+1, "RIGHTMONO" ) || !strcmp( arg+1, "RM" ))
			wantedInputType = RIGHT_CHANNEL_MONO;
		else if( !strcmp( arg+1, "QUIET" ) )
			wantedQuiet = TRUE;
		else if( strstr( arg+1, "OUTDIR=" ) == arg+1 )
			setOutputDir( &argv[ofs][8] );

⌨️ 快捷键说明

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