📄 riptracks.c
字号:
break;
case CDRM_NOJITTER:
EnterCriticalSection( &e.cs );
tbuf->startFrame = e.startFrame;
LeaveCriticalSection( &e.cs );
#ifndef _ALWAYS_READ_MAX
tbuf->numFrames = num2rip;
#else
tbuf->numFrames = maxRip;
#endif
tbuf->startOffset = 0;
tbuf->len = 0;
//dwStatus = SS_ERR;
//retries = 3;
for( retries = 3, dwStatus = SS_ERR; (dwStatus != SS_COMP) && retries; retries -- )
dwStatus = ReadCDAudioLBA( hCD, tbuf );
break;
}
if ( dwStatus != SS_COMP )
{
// display the error here
e.status = EST_ERROR;
e.bForceEncExit = TRUE;
goto asRipExit;
}
#ifdef _ALWAYS_READ_MAX
if ( (maxRip > num2rip) && (tbuf->numFrames > num2rip) )
{
tbuf->numFrames = num2rip;
tbuf->len = tbuf->numFrames * 2352;
}
#endif
wrqEnqueue( &e.q, tbuf->buf + tbuf->startOffset, tbuf->len );
#if 0
SendDlgItemMessage( e.hDlg, IDG_READBUF, GM_SETPOS,
(WPARAM)wrqNumUsed( &e.q ), 0L );
#else
PostMessage( hReadGauge, GM_SETPOS, (WPARAM)wrqNumUsed( &e.q ), 0L );
#endif
EnterCriticalSection( &e.cs );
e.startFrame += tbuf->numFrames;
LeaveCriticalSection( &e.cs );
}
e.bNormalExit = TRUE;
ResetEvent( hWait[0] );
wrqSetWait( &e.q, hWait[0], e.q.dataLen - 500 );
WaitForSingleObject( hWait[0], 5000 );
asRipExit:
if ( WaitForSingleObject( e.aHandles[1], 120000 ) == WAIT_TIMEOUT )
{
e.bForceEncExit = TRUE;
if ( WaitForSingleObject( e.aHandles[1], 30000 ) == WAIT_TIMEOUT )
{
TerminateThread( e.aHandles[1], 0xDEADBEEF );
}
}
free( t1 );
if ( t2 )
free( t2 );
if ( tover )
free( tover );
time( &e.tnow );
CloseHandle( hWait[0] );
CloseHandle( hWait[1] );
#if 0
if ( !e.bForceEncExit && !e.bForceRipExit )
PostMessage( e.hDlg, WM_TRACKDONE, 0, 0L );
else
PostMessage( e.hDlg, WM_DESTROY, 0, 0L );
#else
PostMessage( e.hDlg, WM_TRACKDONE, 0, 0L );
#endif
return 0xDEADBEEF;
}
DWORD EncodeThread( LPENCODETHREAD pet )
{
BE_CONFIG b;
BE_ERR err;
HBE_STREAM hbeStream = 0;
DWORD dwSamples, dwSampleBytes, dwMP3BufferSize;
unsigned char *pInput = NULL, *pOutput = NULL;
DWORD numQueued, numWritten = 0;
DWORD totalWritten = 0;
//HWND hRipGauge, hReadGauge;
BOOL bStreamDirty = FALSE;
UpdateTime( -1 );
//hRipGauge = GetDlgItem( e.hDlg, IDG_RIPPROG );
//hReadGauge = GetDlgItem( e.hDlg, IDG_READBUF );
if ( bMP3 )
{
ZeroMemory( &b, sizeof(b) );
if ( iEncoder == BLADE_ENC_DLL || pet->bOldLame )
{
b.dwConfig = BE_CONFIG_MP3;
b.format.mp3.dwSampleRate = 44100;
b.format.mp3.byMode = BE_MP3_MODE_STEREO;
b.format.mp3.wBitrate = wBitrate;
//b.format.mp3.wBitrate = 128;
b.format.mp3.bCRC = bCRC;
b.format.mp3.bPrivate = bPrivate;
b.format.mp3.bOriginal = bOriginal;
b.format.mp3.bCopyright = bCopyright;
}
else if ( iEncoder == LAME_ENC_DLL )
{
b.dwConfig = BE_CONFIG_LAME;
b.format.LHV1.dwStructVersion = 1;
b.format.LHV1.dwStructSize = sizeof(BE_CONFIG);
b.format.LHV1.dwSampleRate = 44100;
b.format.LHV1.dwReSampleRate = 0;
b.format.LHV1.nMode = BE_MP3_MODE_STEREO;
b.format.LHV1.dwBitrate = (DWORD)wBitrate;
b.format.LHV1.dwMaxBitrate = 320;
b.format.LHV1.nQuality = nQuality;
b.format.LHV1.dwMpegVersion = MPEG1;
b.format.LHV1.bCRC = bCRC;
b.format.LHV1.bPrivate = bPrivate;
b.format.LHV1.bOriginal = bOriginal;
b.format.LHV1.bCopyright = bCopyright;
b.format.LHV1.bWriteVBRHeader = bVBRHeader;
b.format.LHV1.bEnableVBR = bVBR;
b.format.LHV1.nVBRQuality = nVBRQuality;
}
err = beInitStream( &b, &dwSamples, &dwMP3BufferSize, &hbeStream );
dwSampleBytes = 2 * dwSamples;
pInput = (unsigned char *)malloc( dwSampleBytes );
pOutput = (unsigned char *)malloc( dwMP3BufferSize );
}
else
pOutput = (unsigned char *)malloc( 32656 );
while( TRUE )
{
unsigned char *pTmp;
pTmp = pOutput;
if ( pet->bForceEncExit )
break;
numQueued = wrqNumUsed( &pet->q );
if ( !numQueued && pet->bNormalExit )
{
break;
}
if ( !bMP3 )
{
while( wrqNumUsed( &pet->q ) )
{
int numRead;
numRead = wrqDequeue( &pet->q, &pTmp, 32656 );
writeAndFlush( pet->fpOut, pTmp, numRead );
totalWritten += numRead;
UpdateTime( numRead );
}
}
else // encoding to MP3
{
pTmp = pInput;
if ( numQueued >= dwSampleBytes || pet->bNormalExit )
{
DWORD num2dequeue = numQueued;
if ( num2dequeue > dwSampleBytes )
num2dequeue = dwSampleBytes;
num2dequeue = wrqDequeue( &pet->q, &pTmp, num2dequeue );
if ( bWavMirror )
{
writeAndFlush( pet->fpWavMirror, pTmp, num2dequeue );
totalWritten += num2dequeue;
}
beEncodeChunk( hbeStream, num2dequeue/2, (PSHORT)pTmp,
pOutput, &numWritten );
fwrite( pOutput, 1, numWritten, pet->fpOut );
UpdateTime( num2dequeue );
bStreamDirty = TRUE;
}
}
}
if ( pet->fpWavMirror && bWavMirror )
writeWavHeader( pet->fpWavMirror, totalWritten );
if ( !bMP3 )
writeWavHeader( pet->fpOut, totalWritten );
else
{
if ( hbeStream && bStreamDirty )
{
beDeinitStream( hbeStream, pOutput, &numWritten );
if ( numWritten )
{
fwrite( pOutput, 1, numWritten, pet->fpOut );
}
beCloseStream( hbeStream );
}
// write ID3 tag here
if ( bID3 )
writeID3V1Tag( pet->fpOut );
}
if ( pInput )
free( pInput );
if ( pOutput )
free( pOutput );
fclose( pet->fpOut );
if ( pet->fpWavMirror && bWavMirror )
fclose( pet->fpWavMirror );
return 0xDEADBEEF;
}
int writeAndFlush( FILE *fp, BYTE *buf, int len )
{
static int wafNumWritten = 0;
int retVal = 0;
wafNumWritten += len;
retVal = fwrite( buf, 1, len, fp );
if ( wafNumWritten > 20480 )
{
fflush( fp );
wafNumWritten = 0;
}
return retVal;
}
void writeWavHeader( FILE *fp, DWORD len )
{
WAVHDR wav;
if ( !fp )
return;
memcpy( wav.riff, "RIFF", 4 );
wav.len = len + 44 - 8;
memcpy( wav.cWavFmt, "WAVEfmt ", 8 );
wav.dwHdrLen = 16;
wav.wFormat = 1;
wav.wNumChannels = 2;
wav.dwSampleRate = 44100;
wav.dwBytesPerSec = 44100*2*2;
wav.wBlockAlign = 4;
wav.wBitsPerSample = 16;
memcpy( wav.cData, "data", 4 );
wav.dwDataLen = len;
fseek( fp, 0, SEEK_SET );
fwrite( &wav, 1, sizeof(wav), fp );
}
BOOL loadBladeEnc( void )
{
ENCODER i;
if ( hBladeDll && hLameDll )
return TRUE;
if ( !hLameDll )
hLameDll = LoadLibrary( "LAME_ENC.DLL" );
if ( !hBladeDll )
hBladeDll = LoadLibrary( "BLADEENC.DLL" );
// See if we can get addresses for the encoder functions, to determine
// what encoders are present
for( i = BLADE_ENC_DLL; i < MAXENCODER; i++ )
LoadEncoderFunctions( i );
if ( !hBladeDll && !hLameDll )
return FALSE;
if ( (iEncoder == NOENCODER ) || !LoadEncoderFunctions( iEncoder ) )
{
if ( hBladeDll && !hLameDll )
iEncoder = BLADE_ENC_DLL;
else if ( hLameDll && !hBladeDll )
iEncoder = LAME_ENC_DLL;
else
iEncoder = BLADE_ENC_DLL; // default if not read from registry
if ( !LoadEncoderFunctions( iEncoder ) )
{
iEncoder = NOENCODER;
return FALSE;
}
return TRUE;
}
return TRUE;
}
/*
* Calls GetProcAddress for the given encoder to obtain addresses for the
* encoder functions. Returns FALSE if the DLL is not loaded, or if
* one or more function addresses cannot be loaded.
*/
BOOL LoadEncoderFunctions( ENCODER nEncoder )
{
HANDLE hDll;
if ( nEncoder <= NOENCODER || nEncoder > MAXENCODER )
return FALSE;
switch( nEncoder )
{
case BLADE_ENC_DLL:
hDll = hBladeDll;
break;
case LAME_ENC_DLL:
hDll = hLameDll;
break;
case NOENCODER:
default:
return FALSE;
}
if ( !hDll )
return FALSE;
beInitStream = (BEINITSTREAM)GetProcAddress( hDll, "beInitStream" );
beEncodeChunk = (BEENCODECHUNK)GetProcAddress( hDll, "beEncodeChunk" );
beDeinitStream = (BEDEINITSTREAM)GetProcAddress( hDll, "beDeinitStream" );
beCloseStream = (BECLOSESTREAM)GetProcAddress( hDll, "beCloseStream" );
beVersion = (BEVERSION)GetProcAddress( hDll, "beVersion" );
if ( !beInitStream || !beEncodeChunk || !beDeinitStream ||
!beCloseStream || !beVersion )
{
switch( nEncoder )
{
case BLADE_ENC_DLL:
hBladeDll = NULL;
break;
case LAME_ENC_DLL:
hLameDll = NULL;
break;
case NOENCODER:
default:
break;
}
beInitStream = NULL;
beEncodeChunk = NULL;
beDeinitStream = NULL;
beCloseStream = NULL;
beVersion = NULL;
FreeLibrary( hDll );
return FALSE;
}
return TRUE;
}
/***************************************************************************/
/* */
/* UpdateTime */
/* */
/* Update the elapsed/remaining time field on the dialog. If we're */
/* supplied with negative bytes, we assume we're initialising our static */
/* variables. */
/* */
/* Written by B. Thompson, January 27, 2000 */
/* */
/***************************************************************************/
void UpdateTime (long numWritten)
{
static
time_t startTime = 0; /* Start time stamp */
static
DWORD totalWritten = 0; /* Total bytes written */
static
DWORD timeLeft = 0; /* Time remaining */
static
DWORD numToWrite; /* Total number to be written */
static
HWND hRipGauge, hReadGauge; /* Dialog controls */
double timeLeftd; /* Improved calculational ability */
time_t currTime; /* Current time stamp */
long secsElapsed; /* Elapsed seconds since last hour */
long secsLeft; /* Remaining seconds since last hour*/
char estTime[24]; /* Estimated time */
if (numWritten < 0)
{ /* Initialisation*/
time(&startTime);
totalWritten = 0;
numToWrite = e.trackLen * 2352;
hRipGauge = GetDlgItem(e.hDlg, IDG_RIPPROG);
hReadGauge = GetDlgItem(e.hDlg, IDG_READBUF);
return;
} /* End if*/
totalWritten += numWritten;
if (!totalWritten)
return; /* Avoid divide by zero!*/
time(&currTime);
currTime -= startTime; /* Elapsed time (seconds)*/
if (currTime != timeLeft)
{ /* At least one second elapsed*/
timeLeftd = currTime;
timeLeftd *= numToWrite;
timeLeftd /= totalWritten;
timeLeftd -= currTime;
timeLeft = (DWORD)timeLeftd;
secsElapsed = currTime % 3600;
secsLeft = (long)(timeLeft % 3600);
// sprintf(estTime, "%i %i", totalWritten, numToWrite);
sprintf(estTime, "%li:%02li:%02li (%ld:%02ld:%02ld)",
currTime / 3600, secsElapsed / 60, secsElapsed % 60,
timeLeft / 3600, secsLeft / 60, secsLeft % 60);
SetDlgItemText(e.hDlg, IDT_ESTTIME, estTime);
} /* End if*/
timeLeft = currTime; /* For next iteration*/
#if 0
SendDlgItemMessage( e.hDlg, IDG_RIPPROG, GM_SETDELTAPOS,
(WPARAM)((UINT)numWritten), 0L );
SendDlgItemMessage( e.hDlg, IDG_READBUF, GM_SETPOS,
(WPARAM)wrqNumUsed( &e.q ), 0L );
#else
PostMessage( hRipGauge, GM_SETDELTAPOS, (WPARAM)((UINT)numWritten), 0L );
PostMessage( hReadGauge, GM_SETPOS, (WPARAM)wrqNumUsed( &e.q ), 0L );
#endif
} /* End of UpdateTime function*/
/*
* Returns TRUE if Lame_enc.dll is old enough to use the original BladeEnc
* interface. Also returns TRUE if lame_enc isn't available...
*/
BOOL isOldLameEnc( void )
{
BE_VERSION bev;
BEVERSION pfnbeVersion;
DWORD dwEngine, dwDll;
if ( hLameDll )
{
pfnbeVersion = (BEVERSION)GetProcAddress( hLameDll, "beVersion" );
ZeroMemory( &bev, sizeof(bev) );
if ( pfnbeVersion )
pfnbeVersion( &bev );
dwEngine = (((DWORD)bev.byMajorVersion)<<8) + bev.byMinorVersion;
dwDll = (((DWORD)bev.byDLLMajorVersion)<<8) + bev.byDLLMinorVersion;
if ( (dwEngine < 0x0336) || (dwDll < 0x0104) )
return TRUE;
return FALSE;
}
return TRUE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -