Exemplo n.º 1
0
bool ACMStream::open(const AEncodeProperties & the_Properties)
{
	bool bResult = false;

	// Init the MP3 Stream
	// Init the global flags structure
	gfp = lame_init();

	// Set input sample frequency
	lame_set_in_samplerate( gfp, my_SamplesPerSec );

	// Set output sample frequency
	lame_set_out_samplerate( gfp, my_OutBytesPerSec );

	lame_set_num_channels( gfp, my_Channels );
	if (my_Channels == 1)
		lame_set_mode( gfp, MONO );
	else
		lame_set_mode( gfp, (MPEG_mode_e)the_Properties.GetChannelModeValue()) ; /// \todo Get the mode from the default configuration

//	lame_set_VBR( gfp, vbr_off ); /// \note VBR not supported for the moment
	lame_set_VBR( gfp, my_VBRMode ); /// \note VBR not supported for the moment
	
	if (my_VBRMode == vbr_abr)
	{
		lame_set_VBR_q( gfp, 1 );

		lame_set_VBR_mean_bitrate_kbps( gfp, (my_AvgBytesPerSec * 8 + 500) / 1000 );

		if (24000 > lame_get_in_samplerate( gfp ))
		{
			// For MPEG-II
			lame_set_VBR_min_bitrate_kbps( gfp, 8);

			lame_set_VBR_max_bitrate_kbps( gfp, 160);
		}
		else
		{
			// For MPEG-I
			lame_set_VBR_min_bitrate_kbps( gfp, 32);

			lame_set_VBR_max_bitrate_kbps( gfp, 320);
		}
	}

	// Set bitrate
	lame_set_brate( gfp, my_AvgBytesPerSec * 8 / 1000 );

	/// \todo Get the mode from the default configuration
	// Set copyright flag?
	lame_set_copyright( gfp, the_Properties.GetCopyrightMode()?1:0 );
	// Do we have to tag  it as non original 
	lame_set_original( gfp, the_Properties.GetOriginalMode()?1:0 );
	// Add CRC?
	lame_set_error_protection( gfp, the_Properties.GetCRCMode()?1:0 );
	// Set private bit?
	lame_set_extension( gfp, the_Properties.GetPrivateMode()?1:0 );
	// INFO tag support not possible in ACM - it requires rewinding 
        // output stream to the beginning after encoding is finished.   
	lame_set_bWriteVbrTag( gfp, 0 );

	if (0 == lame_init_params( gfp ))
	{
		//LAME encoding call will accept any number of samples.  
		if ( 0 == lame_get_version( gfp ) )
		{
			// For MPEG-II, only 576 samples per frame per channel
			my_SamplesPerBlock = 576 * lame_get_num_channels( gfp );
		}
		else
		{
			// For MPEG-I, 1152 samples per frame per channel
			my_SamplesPerBlock = 1152 * lame_get_num_channels( gfp );
		}
	}

	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "version                =%d",lame_get_version( gfp ) );
	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Layer                  =3");
	switch ( lame_get_mode( gfp ) )
	{
		case STEREO:       my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG,  "mode                   =Stereo" ); break;
		case JOINT_STEREO: my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG,  "mode                   =Joint-Stereo" ); break;
		case DUAL_CHANNEL: my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG,  "mode                   =Forced Stereo" ); break;
		case MONO:         my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG,  "mode                   =Mono" ); break;
		case NOT_SET:      /* FALLTROUGH */
		default:           my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG,  "mode                   =Error (unknown)" ); break;
	}

	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "sampling frequency     =%.1f kHz", lame_get_in_samplerate( gfp ) /1000.0 );
	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "bitrate                =%d kbps", lame_get_brate( gfp ) );
	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Vbr Min bitrate        =%d kbps", lame_get_VBR_min_bitrate_kbps( gfp ) );
	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Vbr Max bitrate        =%d kbps", lame_get_VBR_max_bitrate_kbps( gfp ) );
	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Quality Setting        =%d", lame_get_quality( gfp ) );

	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Low pass frequency     =%d", lame_get_lowpassfreq( gfp ) );
	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Low pass width         =%d", lame_get_lowpasswidth( gfp ) );

	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "High pass frequency    =%d", lame_get_highpassfreq( gfp ) );
	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "High pass width        =%d", lame_get_highpasswidth( gfp ) );

	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "No Short Blocks        =%d", lame_get_no_short_blocks( gfp ) );

	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "de-emphasis            =%d", lame_get_emphasis( gfp ) );
	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "private flag           =%d", lame_get_extension( gfp ) );

	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "copyright flag         =%d", lame_get_copyright( gfp ) );
	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "original flag          =%d",	lame_get_original( gfp ) );
	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "CRC                    =%s", lame_get_error_protection( gfp ) ? "on" : "off" );
	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Fast mode              =%s", ( lame_get_quality( gfp ) )? "enabled" : "disabled" );
	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Force mid/side stereo  =%s", ( lame_get_force_ms( gfp ) )?"enabled":"disabled" );
	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Padding Type           =%d", lame_get_padding_type( gfp ) );
	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Disable Resorvoir      =%d", lame_get_disable_reservoir( gfp ) );
	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "VBR                    =%s, VBR_q =%d, VBR method =",
					( lame_get_VBR( gfp ) !=vbr_off ) ? "enabled": "disabled",
		            lame_get_VBR_q( gfp ) );

	switch ( lame_get_VBR( gfp ) )
	{
		case vbr_off:	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG,  "vbr_off" );	break;
		case vbr_mt :	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG,  "vbr_mt" );	break;
		case vbr_rh :	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG,  "vbr_rh" );	break;
		case vbr_mtrh:	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG,  "vbr_mtrh" );	break;
		case vbr_abr: 
			my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG,  "vbr_abr (average bitrate %d kbps)", lame_get_VBR_mean_bitrate_kbps( gfp ) );
		break;
		default:
			my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "error, unknown VBR setting");
		break;
	}

	my_debug->OutPut(DEBUG_LEVEL_FUNC_DEBUG, "Write VBR Header       =%s\n", ( lame_get_bWriteVbrTag( gfp ) ) ?"Yes":"No");

#ifdef FROM_DLL
beConfig.format.LHV1.dwReSampleRate		= my_OutBytesPerSec;	  // force the user resampling
#endif // FROM_DLL

	bResult = true;

	return bResult;
}
Exemplo n.º 2
0
Mp3OutputStream::Mp3OutputStream() : global_fags(), bytes_per_sample(), bytes_per_second()
#ifdef Mp3OutputStream_Buffering
	m_inBuffer(), m_inBufferLenght(), m_inBufferPos(),
#endif
	,m_outBuffer(), m_outBufferLenght()
{
}

Mp3OutputStream::~Mp3OutputStream()
{
	Close();

#ifdef Mp3OutputStream_Buffering
	delete [] m_inBuffer;
#endif	

	delete [] m_outBuffer;
}
	
bool Mp3OutputStream::Initialize(int samplerate, int numchannels, int bitspersamp)
{
	global_fags = lame_init();
	if(global_fags == nullptr)
		return false;
	
	//lame_set_errorf(global_fags, lame_debugger);
	lame_set_analysis(global_fags, 0);

	lame_set_in_samplerate(global_fags, samplerate);
	lame_set_bWriteVbrTag( global_fags, 0 );
	lame_set_error_protection( global_fags, 0 );
	lame_set_extension( global_fags, 0 );
	lame_set_original( global_fags, 0 );
	lame_set_VBR(global_fags, vbr_off);

	lame_set_num_channels(global_fags, numchannels);
	lame_set_mode( global_fags, STEREO);

	lame_set_out_samplerate(global_fags, 44100);
	// 9 = LQP_LOW_QUALITY
	// 2 = LQP_HIGH_QUALITY:
	// 0 = LQP_VERYHIGH_QUALITY
	//lame_set_quality(global_fags, 0 );
	//lame_set_preset( global_fags, STANDARD_FAST);

	Settings& s = Global::Settings;
	
#ifdef STREAMER_PAYD_VERSION
	lame_set_brate(global_fags, std::min(Mp3OutputStreamConstants::Presets[s.encoder_preset], 320));
#else
	lame_set_brate(global_fags, 64);
#endif
	
	if(lame_init_params(global_fags) != 0)
	{
		OutputDebugString(_T("lame_init_params failed"));
		lame_close(global_fags);
		global_fags = nullptr;
		return false;
	}
	
	bytes_per_second = lame_get_brate(global_fags) / 8;

#ifdef Mp3OutputStream_Buffering
	if ( 0 == lame_get_version( global_fags ) )
	{
		// For MPEG-II, only 576 samples per frame per channel
		m_inBufferLenght = 576 * lame_get_num_channels( global_fags );
	}
	else
	{
		// For MPEG-I, 1152 samples per frame per channel
		m_inBufferLenght = 1152 * lame_get_num_channels( global_fags );
	}


	// delete buffers
	if(m_inBuffer != nullptr)
		delete [] m_inBuffer;
	m_inBuffer = new BYTE[m_inBufferLenght * 2];
#endif

	m_outBufferLenght = static_cast<int>( ( 1.25 * ( samplerate / numchannels ) + 7200 ) * 2.0);
	
	if(m_outBuffer != nullptr)
		delete [] m_outBuffer;
	m_outBuffer = new BYTE[m_outBufferLenght];

	bytes_per_sample = bitspersamp / 8;
	return true;
}
Exemplo n.º 3
0
Arquivo: mcdr.cpp Projeto: msdsgn/mcdr
/* ======================================================================= */
BOOL EncodeTrack(PWINDOWHANDLES H, DWORD Index, PCHAR BasePath, HANDLE CDHandle, PCDTRACK CDTrackData, PDWORD DiscCurrent, PDWORD DiscTotal, PDWORD TrackCount)
{
  Log(LOG_WRITE, "Encoding track %u/%u; Sector %u-%u/%u", Index+1, *TrackCount, CDTrackData[Index].Address, CDTrackData[Index].Address + CDTrackData[Index].Length - 1, CDTrackData[Index].Length);

  CHAR MP3FilePath[MAX_PATH];
  CHAR MP3FilePathFancy[MAX_PATH];

  HANDLE MP3FileHandle = INVALID_HANDLE_VALUE;
  static lame_global_flags *GFP = NULL;

  if(OneTrackOnly == 0)
  {
    _snprintf(MP3FilePath, MAX_PATH, "%s\\Track %u.mp3", BasePath, Index + 1);
    MakeFancyPath(MP3FilePath, MP3FilePathFancy, 35);
    SetLabel(H->WT, "Creating file %s...", MP3FilePath);
    MP3FileHandle = CreateFile(MP3FilePath, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
  }
  else
  {
    _snprintf(MP3FilePath, MAX_PATH, "%s\\Audio.mp3", BasePath, Index + 1);
    MakeFancyPath(MP3FilePath, MP3FilePathFancy, 35);
    switch(OneTrackOnly)
    {
      case 1:
        SetLabel(H->WT, "Creating solid file %s...", MP3FilePath);
        MP3FileHandle = CreateFile(MP3FilePath, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        OneTrackOnly = 2;
        break;
      case 2:
        SetLabel(H->WT, "Re-opening file %s...", MP3FilePath);
        MP3FileHandle = CreateFile(MP3FilePath, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        if(MP3FileHandle != INVALID_HANDLE_VALUE)
          SetFilePointer(MP3FileHandle, 0, NULL, FILE_END);
        break;
    }
  }

  BOOL Success = TRUE;
  INT EncoderReturnCode = 0;

  if(MP3FileHandle != INVALID_HANDLE_VALUE)
  {
    Log(LOG_WRITE, "Created file %s", MP3FilePath);

    DWORD DiscLastCurrent = *DiscCurrent;
    DWORD SectorTotal = CDTrackData[Index].Length/SECTORS_AT_READ;
    DWORD MP3BytesWritten;

    SendMessage(H->PO, PBM_SETRANGE32, 0, SectorTotal);
    SendMessage(H->PO, PBM_SETPOS, 0, 0);
    SendMessage(H->PA, PBM_SETRANGE32, 0, *DiscTotal);

    if(GFP == NULL)
    {
      GFP = lame_init();

      lame_set_preset(GFP, MP3Quality);
      lame_set_copyright(GFP, 1);
      lame_set_original(GFP, 1);
      lame_set_error_protection(GFP, 1);
      lame_set_extension(GFP, 1);
      lame_set_quality(GFP, Quality);

      EncoderReturnCode = lame_init_params(GFP);
    }

    if(EncoderReturnCode == 0)
    {
      DWORD dwWAVBufferSize=(1152 * lame_get_num_channels(GFP));
      DWORD dwMP3BufferSize=(DWORD)(1.25*(dwWAVBufferSize/lame_get_num_channels(GFP))+7200);
      PBYTE MP3Buffer = new BYTE[dwMP3BufferSize];
      PBYTE CDBuffer = new BYTE[SECTORS_AT_READ * RAW_SECTOR_SIZE];
      INT nOutputSamples;
      DWORD CDBytesWritten;
      RAW_READ_INFO Info;
      Info.TrackMode = CDDA;
      Info.SectorCount = SECTORS_AT_READ;
      DWORD SectorCurrent;
      TCHAR NumWritten[30];
      TCHAR NumWrittenKB[30];

      for(SectorCurrent = 0; SectorCurrent < SectorTotal; ++SectorCurrent, ++*DiscCurrent)
      {
        Info.DiskOffset.QuadPart = (CDTrackData[Index].Address + SectorCurrent*SECTORS_AT_READ) * CD_SECTOR_SIZE;
        MP3BytesWritten = SetFilePointer(MP3FileHandle, 0, NULL, FILE_CURRENT);
        Comma(MP3BytesWritten, NumWritten, sizeof(NumWritten));
        Comma(MP3BytesWritten / 1024, NumWrittenKB, sizeof(NumWrittenKB));
        SetLabel(H->WT, "Encoding track %u of %u and sector %u of %u\nTo %s\nWritten %s bytes (%s KB) to file", Index + 1, *TrackCount, SectorCurrent, SectorTotal - 1, MP3FilePathFancy, NumWritten, NumWrittenKB);
        if(DeviceIoControl(CDHandle, IOCTL_CDROM_RAW_READ, &Info, sizeof(Info), CDBuffer, SECTORS_AT_READ*RAW_SECTOR_SIZE, &CDBytesWritten, NULL) != 0)
        {
          if(EncodeAudioBuffer(CDBuffer, CDBytesWritten, dwWAVBufferSize, MP3FileHandle, MP3Buffer, GFP) == FALSE)
          {
            Log(LOG_WRITE, "Encoding of audio buffer failed");
            Success = FALSE;
            break;
          }
        }
        else
        {
          DWORD ErrorCode = GetLastError();
          if(ErrorCode == ERROR_INVALID_FUNCTION)
          {
            Log(LOG_WRITE, "Track %u is not a valid CDDA track", Index + 1);
            Success = FALSE;
            break;
          }
          else if(ErrorCode != ERROR_INVALID_PARAMETER)
          {
            Log(LOG_WRITE, "Error code %u reading track %u!", ErrorCode, Index + 1);
            Success = FALSE;
            break;
          }
        }
        SendMessage(H->PO, PBM_SETPOS, SectorCurrent, 0);
        SendMessage(H->PA, PBM_SETPOS, *DiscCurrent, 0);
        Percentage = (float)((float)*DiscCurrent / (float)*DiscTotal) * 100;
      }

      if(Success == FALSE)
      {
        *DiscTotal -= SectorTotal;
        SectorTotal = 0;
      }
      else if(OneTrackOnly == 0 || Index+1 == *TrackCount)
      {
        nOutputSamples = lame_encode_flush_nogap(GFP, MP3Buffer, LAME_MAXMP3BUFFER);

        if(nOutputSamples > 0)
        {
          if(WriteFile(MP3FileHandle, MP3Buffer, nOutputSamples, &MP3BytesWritten, NULL) == FALSE)
          {
            Log(LOG_WRITE, "Failed to write %u final bytes to file", nOutputSamples);
            Success = FALSE;
          }
          else if(nOutputSamples != (int)MP3BytesWritten)
          {
            Log(LOG_WRITE, "Written %u final bytes instead of %u bytes to file", MP3BytesWritten, nOutputSamples);
            Success = FALSE;
          }
        }
        else if(nOutputSamples < 0)
        {
          Log(LOG_WRITE, "Error code %d flushing encoded audio buffer", nOutputSamples);
          Success = FALSE;
        }
      }

      *DiscCurrent = DiscLastCurrent + SectorTotal;
      SendMessage(H->PO, PBM_SETPOS, *DiscCurrent, 0);
    }
    else
    {
      Log(LOG_WRITE, "Error code %d initialising audio encoder", EncoderReturnCode);
      Success = FALSE;
    }

    MP3BytesWritten = SetFilePointer(MP3FileHandle, 0, NULL, FILE_CURRENT);
    if(CloseHandle(MP3FileHandle) == FALSE)
    {
      Log(LOG_WRITE, "Error code %u closing file handle");
      Success = FALSE;
    }
    if(OneTrackOnly == 0 && (MP3BytesWritten == 0 || Success == FALSE))
    {
      if(DeleteFile(MP3FilePath) == FALSE)
        Log(LOG_WRITE, "Error code %u deleting file");
      else
        Log(LOG_WRITE, "Deleted the file due to error");
    }
    else Log(LOG_WRITE, "Written %u bytes to file", MP3BytesWritten);
  }
  else
  {
    Log(LOG_WRITE, "Error code %u creating %s", GetLastError(), MP3FilePath);
    Success = FALSE;
  }

  if(EncoderReturnCode == 0 && (OneTrackOnly == 0 || Index+1 == *TrackCount))
  {
    lame_close(GFP);
    GFP = NULL;
  }

  return Success;
}