riptracks.c
资源名称:xtractor.zip [点击查看]
上传用户:xmgzy123
上传日期:2007-01-07
资源大小:373k
文件大小:26k
源码类别:
SCSI/ASPI
开发平台:
WINDOWS
- /*
- * riptracks.c - Copyright (C) 1999,2000 Jay A. Key
- *
- * Contains the RipTrack() function. The rip dialog proc, plus the
- * read and encode threads are all contained in this file. The read
- * thread is also responsible for jitter correction. A good example of
- * how to rip a track from a CD via AKRip32.dll
- *
- **********************************************************************
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
- *
- */
- #include <windows.h>
- #include <stdio.h>
- #include <time.h>
- #include <malloc.h>
- #include "akrip/akrip32.h"
- #include "resources.h"
- #include "globals.h"
- #include "riptracks.h"
- #include "trackwnd.h"
- #include "bladedll.h"
- #include "gauge.h"
- #include "id3.h"
- #define _USE_LAME 0
- DWORD RipThread( LPENCODETHREAD pet );
- DWORD EncodeThread( LPENCODETHREAD pet );
- LPTRACKBUF newTrackBuf( DWORD numFrames );
- void RipTrack( HWND hDlg, int idx, LPADDTRACK lpAddTrack );
- int writeAndFlush( FILE *fp, BYTE *buf, int len );
- void writeWavHeader( FILE *fp, DWORD len );
- BOOL loadBladeEnc( void );
- void setRipTrackStatus( LPENCODETHREAD e );
- BOOL LoadEncoderFunctions( ENCODER nEncoder );
- void UpdateTime (long numWritten);
- BOOL isOldLameEnc( void );
- static ENCODETHREAD e;
- static ADDTRACK rtAddTrack;
- //static BOOL bSecond = FALSE;
- /*
- * 1. initializes the common data structure
- * 2. starts the threads
- *
- *
- */
- void RipTrack( HWND hDlg, int idx, LPADDTRACK lpAddTrack )
- {
- DWORD dwRipThreadID, dwEncThreadID;
- static DWORD numBufFrames = 8;
- static char outputName[MAX_PATH+1];
- int iDirLen; // iNameLen, iTotal;
- char *p;
- ZeroMemory( &e, sizeof(e) );
- e.idx = idx;
- time( &e.tstart );
- e.hDlg = hDlg;
- wsprintf( outputName, "%s.%s", lpAddTrack->name, bMP3?"mp3":"wav" );
- SetDlgItemText( hDlg, IDT_TRACKNAME, outputName );
- // we really need to check filename lengths here, but I'm just too damn
- // tired right now
- iDirLen = lstrlen( szMP3OutputDir );
- //iNameLen = lstrlen( lpAddTrack->name );
- //iTotal = iDirLen + iNameLen + 5;
- if ( bMP3 )
- lstrcpy( outputName, szMP3OutputDir );
- else
- lstrcpy( outputName, szWavOutputDir );
- iDirLen = lstrlen( outputName );
- if ( !iDirLen )
- lstrcpy( outputName, ".\" );
- if ( iDirLen && outputName[iDirLen-1] != '\' )
- lstrcat( outputName, "\" );
- // add the track name, and then replace illegal characters with a '_'
- p = outputName + lstrlen( outputName );
- lstrcat( outputName, lpAddTrack->name );
- while( *p )
- {
- if ( !validFnameChar[(unsigned char)*p] )
- *p = '_';
- p++;
- }
- // add the proper extension
- p = outputName + lstrlen( outputName );
- lstrcat( outputName, bMP3?".mp3":".wav" );
- e.fpOut = fopen( outputName, "w+b" );
- if ( !bMP3 )
- writeWavHeader( e.fpOut, 0 );
- if ( bMP3 && bWavMirror )
- {
- // change the extension to WAV (p was set to the terminating NULL)
- lstrcpy( p, ".wav" );
- e.fpWavMirror = fopen( outputName, "wb" );
- writeWavHeader( e.fpWavMirror, 0 );
- }
- else
- e.fpWavMirror = NULL;
- if ( bMP3 )
- {
- switch( iEncoder )
- {
- case BLADE_ENC_DLL:
- wsprintf( outputName, "%d kbps MP3 via BladeEnc DLL", wBitrate );
- break;
- case LAME_ENC_DLL:
- if ( isOldLameEnc() )
- {
- e.bOldLame = TRUE;
- }
- wsprintf( outputName, "%d kbps MP3 via Lame_Enc DLL", wBitrate );
- if ( bVBR && !e.bOldLame )
- wsprintf( outputName+lstrlen(outputName),
- ", VBR max bitrate %d, VBR quality %d", wMaxBitrate,
- nVBRQuality );
- break;
- }
- }
- else
- wsprintf( outputName, "WAV file" );
- SetDlgItemText( hDlg, IDT_OUTPUTOPTTEXT, outputName );
- ModifyCDParms( hCD, CDP_OVERLAP, numOverlap );
- ModifyCDParms( hCD, CDP_JITTER, jitterCheck );
- ModifyCDParms( hCD, CDP_READMODE, readMode );
- e.startFrame = lpAddTrack->start;
- e.trackLen = lpAddTrack->len;
- e.endFrame = e.startFrame + e.trackLen;
- InitializeCriticalSection( &e.cs );
- e.hRipCancel = CreateEvent( NULL, FALSE, FALSE, NULL );
- SendDlgItemMessage( hDlg, IDG_RIPPROG, GM_SETRANGE,
- (WPARAM)((UINT)e.trackLen * 2352),
- 0L );
- SendDlgItemMessage( hDlg, IDG_RIPPROG, GM_SETPOS, 0, 0L );
- wrqInitQueue( &e.q, maxRip * 2352 * numBufFrames );
- SendDlgItemMessage( hDlg, IDG_READBUF, GM_DISPPCT, (WPARAM)FALSE, 0L );
- SendDlgItemMessage( hDlg, IDG_READBUF, GM_SETRANGE,
- (WPARAM)wrqFreeSpace( &e.q ), 0L );
- // Set ID3 info for track. Album title and artist are set elsewhere
- asSetID3Info( ID3_TITLE, lpAddTrack->name, 0 );
- asSetID3Info( ID3_LEVEL, NULL, 1 );
- #if 0
- asSetID3Info( ID3_YEAR, "1997", 0 );
- asSetID3Info( ID3_GENRE, NULL, 17 );
- #endif
- e.aHandles[0] = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)RipThread,
- (LPVOID)&e, 0, &dwRipThreadID );
- e.aHandles[1] = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)EncodeThread,
- (LPVOID)&e, 0, &dwEncThreadID );
- }
- BOOL RipTrackDlgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- WORD wID;
- //static BOOL bDone = FALSE;
- static HWND hTrckWnd = NULL;
- int idx = -1;
- switch( uMsg )
- {
- case WM_DESTROY:
- bRippingTracks = FALSE;
- EndDialog( hWnd, 0 );
- break;
- case WM_TRACKDONE:
- //bSecond = TRUE;
- DeleteCriticalSection( &e.cs );
- //CloseHandle( &e.hRipCancel );
- wrqDeinitQueue( &e.q );
- // set the status text for the last track ripped
- setRipTrackStatus( &e );
- // if more tracks to rip and the last one finished successfully,
- // call RipTrack again
- idx = SendMessage( hTrckWnd,WM_FINDNEXTTRACK,0,(LPARAM)&rtAddTrack);
- if ( (idx != -1) && (e.status == EST_SUCCESS) )
- RipTrack( hWnd, idx, &rtAddTrack );
- else
- {
- bRippingTracks = FALSE;
- EndDialog( hWnd, 0 );
- }
- break;
- case WM_INITDIALOG:
- //bDone = FALSE;
- //bSecond = FALSE;
- hTrckWnd = (HWND)lParam;
- bRippingTracks = TRUE;
- idx = SendMessage(hTrckWnd,WM_FINDFIRSTTRACK,0,
- (LPARAM)&rtAddTrack);
- if ( idx != -1 )
- {
- RipTrack( hWnd, idx, &rtAddTrack );
- }
- else
- {
- MessageBox( GetParent(hTrckWnd), "No tracks selected", "Warning!",
- MB_ICONEXCLAMATION | MB_OK );
- bRippingTracks = FALSE;
- EndDialog( hWnd, 0 );
- }
- break;
- case WM_COMMAND:
- wID = LOWORD( wParam );
- if ( wID == IDBN_CANCELRIP || wID == 2 )
- {
- if ( /* bDone || */ (MessageBox( hWnd, "Really stop?", "Abort?", MB_APPLMODAL | MB_YESNO | MB_ICONEXCLAMATION ) == IDYES) )
- {
- e.bForceRipExit = TRUE;
- e.status = EST_ABORTED;
- SetEvent( e.hRipCancel );
- EnableWindow( GetDlgItem( hWnd, IDBN_CANCELRIP ),FALSE );
- }
- }
- return TRUE;
- }
- return FALSE;
- }
- BOOL RipTrackSegmentDlgProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
- {
- WORD wID;
- switch( uMsg )
- {
- case WM_DESTROY:
- bRippingTracks = FALSE;
- EndDialog( hWnd, 0 );
- break;
- case WM_TRACKDONE:
- DeleteCriticalSection( &e.cs );
- wrqDeinitQueue( &e.q );
- if ( e.status != EST_SUCCESS )
- {
- }
- bRippingTracks = FALSE;
- EndDialog( hWnd, 0 );
- break;
- case WM_INITDIALOG:
- bRippingTracks = TRUE;
- RipTrack( hWnd, -1, (LPADDTRACK)lParam );
- break;
- case WM_COMMAND:
- wID = LOWORD( wParam );
- if ( wID == IDBN_CANCELRIP || wID == 2 )
- {
- if ( MessageBox( hWnd, "Really stop?", "Abort?", MB_APPLMODAL | MB_YESNO | MB_ICONEXCLAMATION ) == IDYES )
- {
- e.bForceRipExit = TRUE;
- e.status = EST_ABORTED;
- SetEvent( e.hRipCancel );
- EnableWindow( GetDlgItem( hWnd, IDBN_CANCELRIP ),FALSE );
- }
- }
- return TRUE;
- }
- return FALSE;
- }
- LPTRACKBUF newTrackBuf( DWORD numFrames )
- {
- LPTRACKBUF t;
- int numAlloc;
- numAlloc = (((int)numFrames)*2352) + TRACKBUFEXTRA;
- t = (LPTRACKBUF)malloc( numAlloc );
- if ( !t )
- return NULL;
- t->startFrame = 0;
- t->numFrames = 0;
- t->maxLen = numFrames * 2352;
- t->len = 0;
- t->status = 0;
- t->startOffset = 0;
- return t;
- }
- //#define _ALWAYS_READ_MAX
- /*
- * Thread responsible for reading the data from the CD and placing it in
- * a queue for the encode thread.
- *
- * trying a new strategy -- always read the full maxRip frames, and truncate
- * if it's too many, but after the read. Some of the SCSI read modes were
- * crapping out on the last read when I suddenly requested a different number
- * of frames. To switch back to the old method, undefine _ALWAYS_READ_MAX
- *
- * CDRM_JITTERONERR uses two full-size TRACKBUFs on a rotating basis. On the
- * read it uses t1, and then on the next read switches to t2. If an error
- * is returned from the read function, then the buffer from the previous read
- * is used to jitter correct the current one.
- */
- DWORD RipThread( LPENCODETHREAD pet )
- {
- LPTRACKBUF tbuf, t1, t2, tover, tTmp;
- DWORD num2rip, dwStatus;
- HANDLE hWait[2];
- int retries;
- BOOL useT1 = FALSE;
- HWND hReadGauge;
- BOOL bWaited;
- //char buf[81];
- hWait[0] = CreateEvent( NULL, FALSE, FALSE, NULL );
- hWait[1] = pet->hRipCancel;
- // initialize all buffers
- tbuf = t1 = t2 = tover = tTmp = NULL;
- tbuf = t1 = newTrackBuf( maxRip );
- switch ( readMode )
- {
- case CDRM_JITTER:
- tover = newTrackBuf( numOverlap );
- break;
- case CDRM_JITTERONERR:
- t2 = newTrackBuf( maxRip );
- break;
- default:
- case CDRM_NOJITTER:
- readMode = CDRM_NOJITTER;
- break;
- }
- num2rip = maxRip;
- hReadGauge = GetDlgItem( e.hDlg, IDG_READBUF );
- while( TRUE )
- {
- bWaited = FALSE;
- if ( e.startFrame >= e.endFrame )
- break;
- if ( e.bForceRipExit )
- {
- e.bForceEncExit = TRUE;
- goto asRipExit;
- }
- EnterCriticalSection( &e.cs );
- if ( e.endFrame - e.startFrame < maxRip )
- num2rip = e.endFrame - e.startFrame;
- LeaveCriticalSection( &e.cs );
- while( wrqFreeSpace( &e.q ) < 2352 * num2rip )
- {
- bWaited = TRUE;
- if ( e.bForceRipExit )
- {
- e.bForceEncExit = TRUE;
- goto asRipExit;
- }
- ResetEvent( hWait[0] );
- wrqSetWait( &e.q, hWait[0], 2352 * maxRip * 6 );
- //WaitForSingleObject( hWait, 20000 );
- WaitForMultipleObjects( 2, hWait, FALSE, 60000 );
- if ( e.bForceRipExit )
- {
- e.bForceEncExit = TRUE;
- goto asRipExit;
- }
- }
- switch( readMode )
- {
- case CDRM_JITTER:
- 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;
- //retries = 3;
- //dwStatus = SS_ERR;
- for( dwStatus = SS_ERR, retries = 3; dwStatus != SS_COMP && retries; retries-- )
- {
- dwStatus = ReadCDAudioLBAEx( hCD, tbuf, tover );
- }
- break;
- case CDRM_JITTERONERR:
- if ( useT1 )
- {
- tbuf = t1;
- tTmp = t2;
- }
- else
- {
- tbuf = t2;
- tTmp = t1;
- }
- 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;
- // try to force jitter correction after a wait
- if ( !bWaited )
- dwStatus = ReadCDAudioLBA( hCD, tbuf );
- else
- dwStatus = SS_ERR;
- // after an error or a wait, dwStatus will be SS_ERR
- if ( dwStatus == SS_ERR )
- {
- if ( tTmp->len )
- {
- tTmp->startOffset += ((tTmp->numFrames - jitterCheck)*2352);
- tTmp->startFrame += ( tTmp->numFrames - jitterCheck );
- tTmp->numFrames = jitterCheck;
- tTmp->len = jitterCheck * 2352;
- }
- else
- tTmp->len = tTmp->startOffset = tTmp->numFrames;
- for( retries = 3; (dwStatus != SS_COMP) && retries; retries-- )
- {
- dwStatus = ReadCDAudioLBAEx( hCD, tbuf, tTmp );
- }
- }
- useT1 = !useT1;
- 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;
- }