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

📄 riptracks.c

📁 读取音乐光盘磁道为磁盘文件的DLL源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	  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 + -