📄 main.c
字号:
/*
(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 + -