main.c
上传用户:bjsgzm
上传日期:2007-01-08
资源大小:256k
文件大小:35k
- /*
- (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 "arglink.h"
- #include "bladesys.h"
- #ifdef OS2
- # define INCL_DOSFILEMGR
- # define INCL_DOSERRORS
- # define INCL_DOSPROCESS
- # include <os2.h>
- # include "os2key.h"
- #endif
- #if SYSTEM == MAC_OS
- # include <SIOUX.h>
- # include <Events.h>
- void DoEvent(EventRecord *i);
- extern int gFriendliness;
- #endif
- extern char *mystrupr(char * strng);
- enum
- {
- PROG_OFF,
- PROG_BOTH_PERC_ETA,
- PROG_FILE_GRAPH,
- PROG_BATCH_GRAPH,
- PROG_BOTH_GRAPH,
- PROG_BOTH_SAMPLES,
- PROG_BOTH_ETA,
- PROG_FILE_RLEN,
- PROG_FILE_NORETURN,
- };
- /*____ 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 );
- argLink * readGlobalSwitches( argLink * pArgLink );
- argLink * readLocalSwitches( argLink * pArgLink, Job * psJob );
- int addCommandlineJob( argLink ** pArgLink );
- 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, double fileLen, double fileDone,
- int progType, Job * psJob );
- void quit( int returnValue );
- void timerCalibrate( void );
- time_t timerStart( void );
- float timerStop( time_t startTime );
- /*____ Static Data ____________________________________________________________*/
- /* Parameters set through the commandline. */
- int wantedBitrate = -1; /* -1 = Unspecified. */
- int wantedCRC = FALSE;
- int wantedPrivate = FALSE;
- int wantedCopyright = FALSE;
- int wantedOriginal = TRUE;
- SampleType wantedInputType = STEREO;
- int wantedProgressBarRate = 2;
- int wantedChannelSwap = FALSE;
- int wantedDeleteSource = FALSE;
- #ifdef WAIT_KEY
- int wantedQuit = FALSE;
- int defWantedQuit = FALSE;
- #else
- int wantedQuit = TRUE;
- int defWantedQuit = 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;
- int timerCalibrationValue; /* Only used if PRECISE_TIMER is defined. */
- int progType = PROG_BOTH_PERC_ETA; /* Style of the progress bar */
- int rawFrequency = 44100;
- int rawChannels = 2;
- int rawBits = 16;
- int rawSigned = TRUE;
- int rawByteorder = BYTEORDER;
- /*____ main() _________________________________________________________________*/
- #if SYSTEM == MAC_OS
- int main_( int argc, char* argv[] ) /* Because the real main is somewhere else */
- #else
- int main( int argc, char* argv[] )
- #endif
- {
- int samplesPerFrame;
- int nSamples;
- short readBuffer[2304];
- int x;
- char input;
- Job * psTemp;
- time_t startTimeBatch, startTimeFile;
- float seconds;
- double batchSamplesTotal = 0.0, batchSamplesRead = 0.0;
- double fileSamplesRead;
- int showProgressCnt = 0;
- CodecInitOut *pCodecInfo;
- char * pBuffer;
- uint encodedChunkSize;
- FILE * fp;
- char temp[256];
- argLink * pArgLink, * pNextArg;
- #if SYSTEM == MAC_OS
- long macTickStart = TickCount();
- #endif
- /* Setting default parameters. Might seem useless since most of them
- allready are predefined, but the MAC OS port uses main() as a subroutine
- which can be called multiple times. */
- wantedBitrate = -1; /* -1 = Unspecified. */
- wantedCRC = FALSE;
- wantedPrivate = FALSE;
- wantedCopyright = FALSE;
- wantedOriginal = TRUE;
- wantedInputType = STEREO;
- wantedProgressBarRate = 2;
- wantedChannelSwap = FALSE;
- wantedDeleteSource = FALSE;
- wantedQuit = defWantedQuit;
- wantedQuiet = FALSE;
- wantedSTDOUT = FALSE;
- fPreparedSTDIN = FALSE;
- pPrioString = NULL;
- psJobQueue = NULL;
- progType = PROG_BOTH_PERC_ETA; /* Style of the progress bar */
- rawFrequency = 44100;
- rawChannels = 2;
- rawBits = 16;
- rawSigned = TRUE;
- rawByteorder = BYTEORDER;
- textout = stdout;
- outputDir[0] = 0;
- /* Fix ArgLink */
- pArgLink = argv2ArgLink( argc-1, argv+1 );
- if( findStrInArgLink( pArgLink, "-NOCFG" ) == NULL )
- if( findConfigFile( argv[0], temp ) == TRUE )
- addFileContentToArgLink( &pArgLink, temp );
- #ifdef WILDCARDS
- expandWildcards( &pArgLink );
- #endif
- pNextArg = readGlobalSwitches( pArgLink );
- /* Check for STDOUT */
- if( findStrInArgLink( pArgLink, "stdout" ) != NULL )
- {
- prepStdout();
- textout = stderr;
- }
- /* Print Text */
- if( !wantedQuiet )
- {
- fprintf( textout, "n" );
- fprintf( textout, "BladeEnc 0.90 (c) Tord Jansson Homepage: http://bladeenc.mp3.non" );
- 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( pNextArg != NULL )
- {
- x = addCommandlineJob( &pNextArg );
- if( x == FALSE )
- {
- deleteArgLink( pArgLink );
- quit( -1 );
- }
- }
- deleteArgLink( pArgLink );
- /* Validate job settings */
- x = validateJobs( psJobQueue );
- if( x == FALSE )
- quit( -2 );
- /* Make sure we don't have certain progress indicators if RAW file in batch */
- x = 0;
- for( psTemp = psJobQueue ; psTemp != NULL ; psTemp = psTemp->psNext )
- {
- if( psTemp->sInput.filetype == RAW )
- x++;
- }
- if( x != 0 && progType != PROG_OFF && progType != PROG_FILE_RLEN )
- progType = PROG_FILE_RLEN;
- /* 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: %dnn", x );
- /* Encode */
- #ifdef PRECISE_TIMER
- timerCalibrate();
- #endif
- startTimeBatch = timerStart();
- for( psTemp = psJobQueue ; psTemp != NULL ; psTemp = psTemp->psNext )
- if( psTemp->sInput.length == 0xFFFFFFFF )
- {
- batchSamplesTotal = 0xFFFFFFFF;
- break;
- }
- else
- batchSamplesTotal += psTemp->sInput.length;
- while( psJobQueue != NULL )
- {
- /* Print information */
- if( !wantedQuiet )
- {
- fprintf( textout, "Encoding: %sn", 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.nn" );
- else
- fprintf( textout, "mono.nn" );
- }
- /* Init a new job */
- startTimeFile = timerStart();
- fileSamplesRead = 0;
- 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 )
- {
- #if SYSTEM == MAC_OS /* Stuff needed for Petteri Kamppuri's Mac OS port */
- if(macTickStart + gFriendliness < TickCount())
- {
- macTickStart = TickCount();
-
- Boolean gotEvent;
- EventRecord event;
-
- gotEvent = GetNextEvent(everyEvent, &event);
- if(gotEvent)
- {
- SIOUXHandleOneEvent(&event);
- DoEvent(&event);
- }
- }
- #endif
- 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;
- fileSamplesRead += nSamples;
- if( !wantedQuiet )
- {
- showProgressCnt = (showProgressCnt+1) % wantedProgressBarRate;
- if( showProgressCnt == 0 )
- updateProgressIndicator( startTimeBatch, batchSamplesTotal, batchSamplesRead,
- startTimeFile, psJobQueue->sInput.length, fileSamplesRead,
- progType, psJobQueue );
- }
- if( be_kbhit() != 0 )
- {
- input = be_getch();
- if( input == 27 )
- {
- fprintf( textout, "r r" );
- 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, "r r" );
- }
- }
- }
- /* 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 );
- seconds = timerStop( startTimeFile );
- x = (int) seconds;
- if( !wantedQuiet )
- {
- fprintf( textout, "r r" );
- fprintf( textout, "Completed. Encoding time: %02d:%02d:%02d (%.2fX)nn",
- x/3600, (x/60)%60, x%60, ((float)fileSamplesRead) /
- ((psJobQueue->sInput.fReadStereo+1)*psJobQueue->sInput.freq*seconds) );
- }
- removeJobQueueEntry( psJobQueue );
- }
- /* Batch done */
- if( !wantedQuiet )
- {
- seconds = timerStop( startTimeBatch );
- fprintf( textout, "All operations completed. Total encoding time: %02d:%02d:%02dn",
- (int) seconds/3600, (int)(seconds/60)%60, (int) seconds%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" );
- }
- #if SYSTEM == MAC_OS
- throw returnValue;
- #else
- exit( returnValue );
- #endif
- }
- /*____ timerCalibrate() _______________________________________________________*/
- void timerCalibrate( void )
- {
- time_t x, y;
- int i;
- x = y = time( NULL );
- while( y == x )
- y = time( NULL );
- for( i = 0 ; y == time( NULL ) ; i++ );
- timerCalibrationValue = i;
- printf( "Timer Calibration Value: %dn", timerCalibrationValue );
- }
- /*____ timerStart() ___________________________________________________________*/
- time_t timerStart( void )
- {
- time_t x, y;
- x = y = time( NULL );
- #ifdef PRECISE_TIMER
- while( y == x )
- y = time( NULL );
- #endif
- return y;
- }
- /*____ timerStop() ____________________________________________________________*/
- float timerStop( time_t startTime )
- {
- float seconds;
- time_t stopTime = time( NULL );
- #ifdef PRECISE_TIMER
- int i;
- for( i = 0 ; stopTime == time( NULL ) ; i++ );
- #endif
- seconds = (float) (stopTime - startTime);
- #ifdef PRECISE_TIMER
- seconds += ((float)(timerCalibrationValue - i))/timerCalibrationValue;
- printf( "Exact seconds: %.5fn", seconds );
- #endif
- return seconds;
- }
- /*____ updateProgressIndicator() ______________________________________________*/
- void updateProgressIndicator( time_t startBatch, double batchLen, double batchDone,
- time_t startFile, double fileLen, double fileDone,
- int progType, Job * psJob )
- {
- time_t currTime;
- float percentageFile, percentageBatch;
- int fileEta, batchEta;
- char temp[82];
- int x, i;
- static char wheel[4] = { '|' , '/' , '-' , '\' };
- static int wheelindex = 0;
- static int prevFileDone = -1;
- currTime = time( NULL );
- switch( progType )
- {
- case PROG_BOTH_PERC_ETA:
- percentageFile = (float) (fileDone / fileLen * 100);
- if( percentageFile >= 100.f )
- percentageFile = (float) 99.9;
- 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:%02dr",
- percentageFile, fileEta/3600, (fileEta/60)%60, fileEta%60,
- percentageBatch, batchEta/3600, (batchEta/60)%60, batchEta%60 );
- fflush( textout );
- break;
- case PROG_FILE_GRAPH:
- strcpy( temp, "File progress: [..................................................]r" );
- x = (int) (fileDone*50/fileLen);
- memset( temp + 16, '*', x );
- if( x < 50 )
- {
- temp[16+x] = wheel[wheelindex];
- wheelindex = (wheelindex + 1) % 4;
- }
- fprintf( textout, temp );
- break;
- case PROG_BATCH_GRAPH:
- strcpy( temp, "Batch progress: [..................................................]r" );
- x = (int) (batchDone*50/batchLen);
- memset( temp + 16, '*', x );
- if( x < 50 )
- {
- temp[16+x] = wheel[wheelindex];
- wheelindex = (wheelindex + 1) % 4;
- }
- fprintf( textout, temp );
- break;
- case PROG_BOTH_GRAPH:
- strcpy( temp, "File: [.........................] Batch: [.........................]r" );
- x = (int) (fileDone*25/fileLen);
- memset( temp + 7, '*', x );
- x = (int) (batchDone*25/batchLen);
- memset( temp + 44, '*', x );
- if( x < 25 )
- {
- temp[7+x] = temp[44+x] = wheel[wheelindex];
- wheelindex = (wheelindex + 1) % 4;
- }
- fprintf( textout, temp );
- break;
- case PROG_BOTH_SAMPLES:
-
- fprintf( textout, "Samples encoded:%10d / %d BATCH:%10d / %dr",
- (int) fileDone, (int) fileLen, (int) batchDone, (int) batchLen );
- break;
- case PROG_BOTH_ETA:
- fileEta = (int) (((float)(currTime - startFile)) / fileDone * (fileLen - fileDone) );
- batchEta = (int) (((float)(currTime - startBatch)) / batchDone * (batchLen - batchDone));
- fprintf( textout, " >>> %02d:%02d:%02d <<< >>> %02d:%02d:%02d <<<r",
- fileEta/3600, (fileEta/60)%60, fileEta%60,
- batchEta/3600, (batchEta/60)%60, batchEta%60 );
- fflush( textout );
- break;
- case PROG_FILE_RLEN:
- x = (int) (fileDone / psJob->sCodec.frequency);
- if( psJob->sCodec.mode != 3 )
- x /= 2;
- fprintf( textout, "Encoded runlength (current file): %02d:%02d:%02dr",
- x/3600, (x/60)%60, x%60 );
- break;
- case PROG_FILE_NORETURN:
- x = (int) (fileDone*70/fileLen);
- if( prevFileDone > x || prevFileDone == -1 )
- {
- prevFileDone = 0;
- fprintf( textout, " |----------------------------------------------------------------------|n |" );
- fflush( textout );
- }
- for( i = prevFileDone ; i < x ; i++ )
- {
- fprintf( textout, "#" );
- fflush( textout );
- }
- if( x == 70 )
- fprintf( textout, "|nn" );
- prevFileDone = x;
- break;
- }
- }
- /*____ setOutputDir() _______________________________________________________*/
- void setOutputDir( char * pPath )
- {
- int i;
- strcpy( outputDir, pPath );
- i = strlen( outputDir ) -1;
- if( outputDir[i] != DIRECTORY_SEPARATOR )
- {
- outputDir[i+1] = DIRECTORY_SEPARATOR;
- outputDir[i+2] = 0;
- }
- }
- /*____ readGlobalSwitches() ___________________________________________________*/
- argLink * readGlobalSwitches( argLink * pArgLink )
- {
- char arg[256];
- int x, y;
- for( ; pArgLink != NULL ; pArgLink = pArgLink->psNext )
- {
- strcpy( arg, pArgLink->pString );
- mystrupr( arg );
- if( arg[0] != '-' )
- return pArgLink;
- 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( !strcmp( arg+1, "NOCFG" ) )
- ; /* simply do nothing... */
- else if( strstr( arg+1, "PROGRESS=" ) == arg+1 )
- progType = atoi( arg+10 );
- else if( strstr( arg+1, "OUTDIR=" ) == arg+1 )
- setOutputDir( pArgLink->pString + 8 );
- else if( strstr( arg+1, "REFRESH=" ) == arg+1 )
- {
- wantedProgressBarRate = atoi( arg+9 );
- if( wantedProgressBarRate < 1 )
- wantedProgressBarRate = 1;
- }
- #ifdef PRIO
- else if( strstr( arg+1, "PRIO=" ) == arg+1 )
- {
- strcpy( prioString, arg+6 );
- pPrioString = prioString;
- }
- #endif
- else if( !strcmp( arg+1, "RAWMONO" ) )
- rawChannels = 1;
- else if( !strcmp( arg+1, "RAWSTEREO" ) )
- rawChannels = 2;
- else if( !strcmp( arg+1, "RAWSIGNED" ) )
- rawSigned = TRUE;
- else if( !strcmp( arg+1, "RAWUNSIGNED" ) )
- rawSigned = FALSE;
- else if( strstr( arg+1, "RAWBITS=" ) == arg+1 )
- {
- rawBits = atoi( arg+9 );
- if( rawBits != 8 && rawBits != 16 )
- rawBits = 16;
- }
- else if( strstr( arg+1, "RAWFREQ=" ) == arg+1 )
- {
- rawFrequency = atoi( arg+9 );
- }
- else if( strstr( arg+1, "RAWBYTEORDER=" ) == arg+1 )
- {
- if( strstr( arg+14, "LITTLE" ) == arg+14 )
- rawByteorder = LITTLE_ENDIAN;
- if( strstr( arg+14, "BIG" ) == arg+14 )
- rawByteorder = BIG_ENDIAN;
- if( strstr( arg+14, "DEFAULT" ) == arg+14 )
- rawByteorder = BYTEORDER;
- }
- else if( strstr( arg+1, "RAWCHANNELS=" ) == arg+1 )
- {
- rawChannels = atoi( arg+13 );
- if( rawChannels != 1 && rawChannels != 2 )
- rawChannels = 2;
- }
- else if( !strcmp( arg+1, "BR" ) )
- {
- pArgLink = pArgLink->psNext;
- if( pArgLink == NULL )
- return NULL;
- wantedBitrate = atoi( pArgLink->pString );
- if( wantedBitrate > 1000 )
- wantedBitrate /= 1000;
- }
- else
- {
- y = 0;
- for( x = 1 ; arg[x] >= '0' && arg[x] <= '9' ; x++ )
- y = y * 10 + (arg[x] - '0');
- if( arg[x] == 0 )
- {
- wantedBitrate = y;
- if( wantedBitrate > 1000 )
- wantedBitrate /= 1000;
- }
- else
- return pArgLink;
- }
- }
- return pArgLink;
- }
- /*____ readLocalSwitches() ___________________________________________________*/
- argLink * readLocalSwitches( argLink * pArgLink, Job * psJob )
- {
- char arg[256];
- int x, y;
- for( ; pArgLink != NULL ; pArgLink = pArgLink->psNext )
- {
- strcpy( arg, pArgLink->pString );
- mystrupr( arg );
- if( arg[0] != '-' )
- return pArgLink;
- if( !strcmp( arg+1, "MONO" ) || !strcmp( arg+1, "DM" ) )
- {
- psJob->sInput.outputType = DOWNMIX_MONO;
- psJob->sCodec.mode = 3;
- }
- else if( !strcmp( arg+1, "CRC" ) )
- psJob->sCodec.fCRC = TRUE;
- else if( !strcmp( arg+1, "PRIVATE" ) || !strcmp( arg+1, "P" ) )
- psJob->sCodec.fPrivate = TRUE;
- else if( !strcmp( arg+1, "COPYRIGHT" ) || !strcmp( arg+1, "C" ) )
- psJob->sCodec.fCopyright = TRUE;
- else if( !strcmp( arg+1, "ORIGINAL" ) )
- psJob->sCodec.fOriginal = TRUE;
- else if( !strcmp( arg+1, "COPY" ) )
- psJob->sCodec.fOriginal = FALSE;
- else if( !strcmp( arg+1, "DELETE" ) || !strcmp( arg+1, "DEL" ) )
- psJob->fDeleteSource = TRUE;
- else if( !strcmp( arg+1, "SWAP" ) )
- {
- if( psJob->sInput.fReadStereo == TRUE )
- {
- psJob->sInput.outputType = INVERSE_STEREO;
- psJob->sCodec.mode = 3;
- }
- }
- else if( !strcmp( arg+1, "LEFTMONO" ) || !strcmp( arg+1, "LM" ))
- {
- if( psJob->sInput.fReadStereo == TRUE )
- {
- psJob->sInput.outputType = LEFT_CHANNEL_MONO;
- psJob->sCodec.mode = 3;
- }
- }
- else if( !strcmp( arg+1, "RIGHTMONO" ) || !strcmp( arg+1, "RM" ))
- {
- if( psJob->sInput.fReadStereo == TRUE )
- {
- psJob->sInput.outputType = RIGHT_CHANNEL_MONO;
- psJob->sCodec.mode = 3;
- }
- }
- else if( !strcmp( arg+1, "RAWMONO" ) )
- {
- if( psJob->sInput.filetype == RAW )
- psJob->sInput.fReadStereo = FALSE;
- }
- else if( !strcmp( arg+1, "RAWSTEREO" ) )
- {
- if( psJob->sInput.filetype == RAW )
- psJob->sInput.fReadStereo = TRUE;
- }
- else if( !strcmp( arg+1, "RAWSIGNED" ) )
- {
- if( psJob->sInput.filetype == RAW )
- psJob->sInput.fSign = TRUE;
- }
- else if( !strcmp( arg+1, "RAWUNSIGNED" ) )
- {
- if( psJob->sInput.filetype == RAW )
- psJob->sInput.fSign = FALSE;
- }
- else if( strstr( arg+1, "RAWBITS=" ) == arg+1 )
- {
- if( psJob->sInput.filetype == RAW )
- {
- psJob->sInput.bits = atoi( arg+9 );
- if( psJob->sInput.bits != 8 && psJob->sInput.bits != 16 )
- psJob->sInput.bits = 16;
- }
- }
- else if( strstr( arg+1, "RAWFREQ=" ) == arg+1 )
- {
- if( psJob->sInput.filetype == RAW )
- psJob->sInput.freq = atoi( arg+9 );
- }
- else if( strstr( arg+1, "RAWBYTEORDER=" ) == arg+1 )
- {
- if( psJob->sInput.filetype == RAW )
- {
- if( strstr( arg+14, "LITTLE" ) == arg+14 )
- psJob->sInput.byteorder = LITTLE_ENDIAN;
- if( strstr( arg+14, "BIG" ) == arg+14 )
- psJob->sInput.byteorder = BIG_ENDIAN;
- if( strstr( arg+14, "DEFAULT" ) == arg+14 )
- psJob->sInput.byteorder = BYTEORDER;
- }
- }
- else if( strstr( arg+1, "RAWCHANNELS=" ) == arg+1 )
- {
- if( psJob->sInput.filetype == RAW )
- {
- psJob->sInput.fReadStereo = atoi( arg+13 )-1;
- if( psJob->sInput.fReadStereo != FALSE && psJob->sInput.fReadStereo != TRUE )
- psJob->sInput.fReadStereo = TRUE;
- }
- }
- else if( !strcmp( arg+1, "BR" ) )
- {
- pArgLink = pArgLink->psNext;
- if( pArgLink == NULL )
- return pArgLink;
- psJob->sCodec.bitrate = atoi( pArgLink->pString );
- if( psJob->sCodec.bitrate > 1000 )
- {
- psJob->sCodec.bitrate /= 1000;
- wantedQuit = TRUE;
- }
- }
- else if( !strcmp( arg+1, "HQ" ) )
- {
- wantedQuit = TRUE; /* Dummy for l3enc support */
- }
- else
- {
- y = 0;
- for( x = 1 ; arg[x] >= '0' && arg[x] <= '9' ; x++ )
- y = y * 10 + (arg[x] - '0');
- if( arg[x] == 0 )
- {
- psJob->sCodec.bitrate = y;
- if( psJob->sCodec.bitrate > 1000 )
- psJob->sCodec.bitrate /= 1000;
- }
- else
- return pArgLink;
- }
- }
- return pArgLink;
- }
- /*____ validateJobs() _________________________________________________________*/
- int validateJobs( Job * psJob )
- {
- static int aValidBitrates[14] = { 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320 };
- int i;
- int fOk = TRUE;
- while( psJob != NULL && fOk )
- {
- fOk = FALSE;
- for( i = 0 ; i < 14 ; i++ )
- if( wantedBitrate == aValidBitrates[i] )
- fOk = TRUE;
- psJob = psJob->psNext;
- }
- if( fOk )
- return TRUE;
- fprintf( textout, "ERROR: %d is not a valid bitrate!nn", wantedBitrate );
- fprintf( textout, "Valid bitrates are:nn" );
- for( i = 0 ; i < 13 ; i++ )
- fprintf( textout, "%d, ", aValidBitrates[i] );
- fprintf( textout, "and %d kBit.n", aValidBitrates[13] );
- return FALSE;
- }
- /*____ printUsage() ___________________________________________________________*/
- int printUsage( void )
- {
- fprintf( textout, "Usage: bladeenc [global switches] input1 [output1 [switches]] input2 ...n" );
- fprintf( textout, "n" );
- fprintf( textout, "General switches:n" );
- fprintf( textout, " -[kbit], -br [kbit] Set MP3 bitrate. Default is 128 (64 for mono output).n" );
- fprintf( textout, " -crc Include checksum data in MP3 file.n" );
- fprintf( textout, " -delete, -del Delete sample after successful encoding.n" );
- fprintf( textout, " -private, -p Set the private-flag in the output file.n" );
- fprintf( textout, " -copyright, -c Set the copyright-flag in the output file.n" );
- fprintf( textout, " -copy Clears the original-flag in the output file.n" );
- fprintf( textout, " -mono, -dm Produce mono MP3 files by combining stereo channels.n" );
- fprintf( textout, " -leftmono, -lm Produce mono MP3 files from left stereo channel only.n" );
- fprintf( textout, " -rightmono, -rm Produce mono MP3 files from right stereo channel only.n" );
- fprintf( textout, " -swap Swap left and right stereo channels.n" );
- fprintf( textout, " -rawfreq=[freq] Specify frequency for RAW samples. Default is 44100.n" );
- fprintf( textout, " -rawbits=[bits] Specify bits per channel for RAW samples. Default is 16.n" );
- fprintf( textout, " -rawmono Specifies that RAW samples are in mono, not stereo.n" );
- fprintf( textout, " -rawstereo Specifies that RAW samples are in stereo (default).n" );
- fprintf( textout, " -rawsigned Specifies that RAW samples are signed (default).n" );
- fprintf( textout, " -rawunsigned Specifies that RAW samples are unsigned.n" );
- #ifdef PAUSE_25_LINES
- fprintf( textout, "Press ENTER to continue..." );
- fflush( textout );
- be_getch();
- fprintf( textout, "n" );
- #endif
- fprintf( textout, " -rawbyteorder=[order]Specifies byteorder for RAW samples, LITTLE or BIG.n" );
- fprintf( textout, " -rawchannels=[1/2] Specifies number of channels for RAW samples. Doesn" );
- fprintf( textout, " the same as -rawmono and -rawstereo respectively.n" );
- fprintf( textout, "n" );
- fprintf( textout, "Global only switches:n" );
- fprintf( textout, " -quit, -q Quit without waiting for keypress when finished.n" );
- fprintf( textout, " -outdir=[dir] Save MP3 files in specified directory.n" );
- fprintf( textout, " -quiet Disable screen output.n" );
- fprintf( textout, " -nocfg Don't take settings from the config-file.n" );
- #ifdef PRIO
- fprintf( textout, " -prio=[prio] Sets the task priority for BladeEnc. Valid settings aren" );
- fprintf( textout, " HIGHEST, HIGHER, NORMAL, LOWER, LOWEST(default) and IDLEn" );
- #endif
- fprintf( textout, " -refresh=[rate] Refresh rate for progress indicator. 1=fastest, 2=def.n" );
- fprintf( textout, " -progress=[0-8] Which progress indicator to use. 0=Off, 1=Default.n" );
- fprintf( textout, "n" );
- fprintf( textout, "Input/output files can be replaced with STDIN and STDOUT respectively.n" );
- #ifdef DRAG_DROP
- fprintf( textout, "To make a normal 128kBit MP3, just drag-n-drop your WAV onto the BladeEnc icon.n" );
- #endif
- fprintf( textout, "n" );
- return TRUE;
- }
- /*____ addCommandlineJob() ____________________________________________________*/
- int addCommandlineJob( argLink ** ppArgLink )
- {
- char temp[256];
- Job * psOp, * psTemp;
- int x;
- argLink * pArgLink;
- pArgLink = * ppArgLink;
-
- psOp = (Job *) malloc( sizeof( Job ) );
- psOp->psNext = NULL;
- /* Open Input File */
- strcpy( temp, pArgLink->pString );
- mystrupr( temp );
- if( strcmp( temp, "STDIN" ) == 0 )
- {
- if( !fPreparedSTDIN )
- {
- prepStdin();
- fPreparedSTDIN = TRUE;
- }
- strcpy( psOp->sourceFilename, "Standard input stream" );
- x = openInput( &psOp->sInput, NULL );
- }
- else
- {
- strcpy( psOp->sourceFilename, pArgLink->pString );
- x = openInput( &psOp->sInput, pArgLink->pString );
- }
- if( x != TRUE )
- {
- switch( psOp->sInput.errcode )
- {
- case -1:
- fprintf( textout, "ERROR: '%s' is not a WAV or AIFF file!n", psOp->sourceFilename );
- break;
- case -2:
- fprintf( textout, "ERROR: Couldn't open '%s'!n", psOp->sourceFilename );
- break;
- case -3:
- fprintf( textout, "ERROR: Unexpected end of file '%s'!n", psOp->sourceFilename );
- break;
- case -5:
- fprintf( textout, "ERROR: Necessary chunk missing in '%s'!n", psOp->sourceFilename );
- break;
- case -6:
- fprintf( textout, "ERROR: Sample '%s' is of an unknown subtype!n", psOp->sourceFilename );
- break;
- default:
- fprintf( textout, "ERROR: Unknown error while opening '%s'!n", psOp->sourceFilename );
- }
- free( psOp );
- return FALSE;
- }
- /* If RAW, set default values */
- if( psOp->sInput.filetype == RAW )
- {
- psOp->sInput.freq = rawFrequency;
- psOp->sInput.outputFreq = rawFrequency;
- psOp->sInput.fReadStereo = rawChannels-1;
- psOp->sInput.bits = rawBits;
- psOp->sInput.fSign = rawSigned;
- psOp->sInput.byteorder = rawByteorder;
- }
- /* */
- if( !psOp->sInput.fReadStereo && (wantedInputType == STEREO || wantedInputType == INVERSE_STEREO) )
- psOp->sInput.outputType = DOWNMIX_MONO;
- else
- psOp->sInput.outputType = wantedInputType;
- /* Set sCodec.mode (MONO or STEREO) */
- if( psOp->sInput.outputType == DOWNMIX_MONO || psOp->sInput.outputType == LEFT_CHANNEL_MONO
- || psOp->sInput.outputType == RIGHT_CHANNEL_MONO )
- psOp->sCodec.mode = 3; /* Force to mono... */
- else
- {
- psOp->sCodec.mode = 0;
- }
- /* Set frequency */
- if( psOp->sInput.freq != 44100 && psOp->sInput.freq != 48000
- && psOp->sInput.freq != 32000 )
- {
- fprintf( textout, "ERROR: Sample '%s' is not in 32, 44.1 or 48 kHz!n", psOp->sourceFilename );
- closeInput( &(psOp->sInput) );
- free( psOp );
- return FALSE;
- }
- psOp->sCodec.frequency = psOp->sInput.freq;
- /* Set bitrate */
- if( wantedBitrate == -1 )
- {
- if( psOp->sCodec.mode == 3 )
- wantedBitrate = 64;
- else
- wantedBitrate = 128;
- }
- else
- psOp->sCodec.bitrate = wantedBitrate;
- /* Set other parameters */
- psOp->sCodec.bitrate = wantedBitrate;
- psOp->sCodec.fPrivate = wantedPrivate;
- psOp->sCodec.fCRC = wantedCRC;
- psOp->sCodec.fCopyright = wantedCopyright;
- psOp->sCodec.fOriginal = wantedOriginal;
- psOp->fDeleteSource = wantedDeleteSource;
- /* Set unsupported parameters */
- psOp->sCodec.emphasis = 0;
- pArgLink = pArgLink->psNext;
- /* Check for output specification and set output name */
- psOp->outputFilename[0] = 0;
- if( pArgLink != NULL )
- {
- strcpy( temp, pArgLink->pString );
- mystrupr( temp );
- if( !strcmp( temp, "STDOUT" ) )
- {
- wantedSTDOUT = TRUE;
- strcpy( psOp->outputFilename, "STDOUT" );
- pArgLink = pArgLink->psNext;
- }
- else if( strlen( temp ) >= 4 && !strcmp( temp+strlen(temp)-4, ".MP3" ) )
- {
- strcpy( psOp->outputFilename, pArgLink->pString );
- pArgLink = pArgLink->psNext;
- }
- }
- /* Generate output name if not allready set */
- if( psOp->outputFilename[0] == 0 )
- {
- if( outputDir[0] != 0 )
- {
- strcpy( psOp->outputFilename, outputDir );
- strcpy( temp, psOp->sourceFilename );
- x = strlen( temp );
- while( temp[x] != '.' && x >=0 && temp[x] != DIRECTORY_SEPARATOR )
- x--;
- if( temp[x] == DIRECTORY_SEPARATOR )
- x = strlen(temp);
- if( x >= 0 )
- strcpy( temp + x, ".mp3" );
- else
- {
- x = strlen( temp );
- strcat( temp, ".mp3" );
- }
- while( x >= 0 && temp[x] != '\' && temp[x] != '/' && temp[x] != ':' )
- x--;
- x++;
- strcat( psOp->outputFilename, temp + x );
- }
- else
- {
- strcpy( temp, psOp->sourceFilename );
- x = strlen( temp );
- while( temp[x] != '.' && x >=0 && temp[x] != DIRECTORY_SEPARATOR )
- x--;
- if( temp[x] == DIRECTORY_SEPARATOR )
- x = strlen(temp);
- if( x >= 0 )
- strcpy( temp + x, ".mp3" );
- else
- strcat( temp, ".mp3" );
- strcpy( psOp->outputFilename, temp );
- }
- }
- /* Read local switches */
- pArgLink = readLocalSwitches( pArgLink, psOp );
- /* Put this Job in the batch */
- if( psJobQueue == NULL )
- psJobQueue = psOp;
- else
- {
- psTemp = psJobQueue;
- while( psTemp->psNext != NULL )
- psTemp = psTemp->psNext;
- psTemp->psNext = psOp;
- }
- * ppArgLink = pArgLink;
- return TRUE;
- }
- /*____ clearJobQueue() ________________________________________________________*/
- int clearJobQueue( void )
- {
- while( psJobQueue != NULL )
- removeJobQueueEntry( psJobQueue );
- return TRUE;
- }
- /*____ removeQueueEntry() _____________________________________________________*/
- int removeJobQueueEntry( Job * psJob )
- {
- Job * psPrev;
- /* Unlink specified entry */
- if( psJob == psJobQueue )
- psJobQueue = psJob->psNext;
- else
- {
- psPrev = psJobQueue;
- while( psPrev->psNext != psJobQueue && psPrev->psNext != NULL )
- psPrev = psPrev->psNext;
- if( psPrev->psNext == NULL )
- return FALSE;
- psPrev->psNext = psJob->psNext;
- }
- /* Close open file, free the entry and return. */
- closeInput( &psJob->sInput );
- free( psJob );
- return TRUE;
- }