Esempio n. 1
0
UINT CMP3ToWavDlg::ConvertFunc(PVOID pParams)
{
	CUString		strLang;
	int			nPeakValue	= 0;
	DWORD		dwIndex		= 0;
	CDEX_ERR	bErr		= CDEX_OK;
	PBYTE		pStream		= NULL;
 	DWORD       dwTotalTime = 0;

	ENTRY_TRACE( _T( "ConvertFunc" ) );

	CMP3ToWavDlg* pDlg = (CMP3ToWavDlg*)pParams;

	pDlg->m_wCurrentTrack = 0;
	pDlg->m_bAbortThread = FALSE;


	CUString strOutDir(g_config.GetCnvOutputDir());

	while(	pDlg->m_wCurrentTrack < pDlg->m_nTotalFiles && 
			!pDlg->m_bAbortThread )
	{
		BOOL bNoToAll = FALSE;

		nPeakValue	= 0;

		POSITION nFileListPos = pDlg->m_Pos;

		pDlg->m_strMP3FileName = pDlg->m_pFileDlg->GetNextPathName( pDlg->m_Pos );
		pDlg->m_strWavFileName = pDlg->m_pFileDlg->GetFileName( nFileListPos );

		CUString strSubPath = pDlg->m_pFileDlg->GetSubPath( nFileListPos );

		int nPos = pDlg->m_strWavFileName.ReverseFind('.');

		if (nPos > 0 )
		{
			pDlg->m_strWavFileName= pDlg->m_strWavFileName.Left( nPos );
		}

		strOutDir = g_config.GetCnvOutputDir() + strSubPath;

		// Prepend output directory
		pDlg->m_strWavFileName= strOutDir + CUString( pDlg->m_strWavFileName );

		// Create Ouput directory
		if ( CDEX_OK != DoesDirExist( strOutDir, FALSE )  )
		{
			LTRACE( _T( "ConvertFunc::Error creating output dir %s" ), strOutDir );

			strLang = g_language.GetString( IDS_CANNOT_CREATE_OUTDIR );
			CDexMessageBox( strLang + strOutDir );
			bErr = CDEX_ERROR;
		}

		// Clear error flag
		bErr = CDEX_OK;

		LTRACE( _T( "Converting track %d" ), pDlg->m_wCurrentTrack );

		// Reset estimate timer
		//pDlg->m_TimeTrack.ReInit();

		pDlg->m_nPercentCompleted=0;

		// create proper input stream
		pDlg->m_pInStream = ICreateStream( CUString( pDlg->m_strMP3FileName ) );

		if ( FALSE == CheckNoFileOverwrite(	pDlg,
										CUString( pDlg->m_strWavFileName ) + _W( ".wav" ), 
										TRUE,
										pDlg->m_bYesToAll,
										bNoToAll ) )
		{
			// Open the input stream if available
			if (	pDlg->m_pInStream && 
					pDlg->m_pInStream->OpenStream( CUString( pDlg->m_strMP3FileName ) ) )
			{
				DWORD	dwBufferSize = pDlg->m_pInStream->GetBufferSize();

				// Reset estimate timer
 				dwTotalTime = pDlg->m_pInStream->GetTotalTime();
 				pDlg->m_TimeTrack.ReInit( dwTotalTime );

				// Create a play stream object
				OSndStreamWAV wavStream;

				wavStream.CopyStreamInfo( *pDlg->m_pInStream );

				// Initialize output WAV stream object
				wavStream.OpenStream( CUString( pDlg->m_strWavFileName ) );

				// Allocate stream input buffer
				pStream = new BYTE[ dwBufferSize ];

				int nMPEGBytes = 0;

				double dSampleRatio = 1.0;

				BOOL bFinished = FALSE;

				while( ( FALSE == bFinished ) && !pDlg->m_bAbortThread )
				{
					nMPEGBytes = pDlg->m_pInStream->Read( pStream, dwBufferSize );
	
					if ( nMPEGBytes > 0 )
					{

						for ( dwIndex=0; dwIndex< (DWORD)nMPEGBytes / 2; dwIndex++ )
						{
							if ( abs( ((SHORT*)pStream)[dwIndex]) > nPeakValue )
								nPeakValue=abs( ((SHORT*)pStream )[ dwIndex ] );
						}

						if ( nMPEGBytes > 0 )
						{
							wavStream.Write( pStream, nMPEGBytes );
						}

						int nTotalTime = pDlg->m_pInStream->GetTotalTime();
						int nCurrentTime = pDlg->m_pInStream->GetCurrentTime();

						if ( nTotalTime )
						{
							pDlg->m_nPercentCompleted = nCurrentTime * 100 / nTotalTime;
						}
						else
						{
							pDlg->m_nPercentCompleted = 0;
						}
					}
					else
					{
						bFinished = TRUE;
					}

				}

				delete [] pStream; pStream= NULL;

				// Close input stream
				pDlg->m_pInStream->CloseStream();

				// Close the WAV stream
				wavStream.CloseStream();

				// close the Input stream

				// Check if we have to normalize the file
				if (	pDlg->m_pFileDlg->m_bNormalize && 
						FALSE == pDlg->m_bAbortThread )
				{
					double dNormFactor=1.0;

					// Reset estimate timer
					pDlg->m_TimeTrack.ReInit(dwTotalTime);

					// Set percentage completed to zero
					pDlg->m_nPercentCompleted=0;

					// Determine normalization factor
					dNormFactor=((nPeakValue-1.0)/327.68);

					// DO we have to normalize this file
					if (dNormFactor<(double)g_config.GetLowNormLevel() || dNormFactor>(double)g_config.GetHighNormLevel())
					{
						if (dNormFactor<(double)g_config.GetLowNormLevel())
						{
							// Normalize to for desired level
							dNormFactor=(double)g_config.GetLNormFactor()/dNormFactor;
						}
						else
						{
							// Normalize to for desired level
							dNormFactor=(double)g_config.GetHNormFactor()/dNormFactor;
						}

						// Little fine tuning to avoid overflows due to round off errors
						dNormFactor*=0.9999;

						LTRACE( _T( "CMP3ToWavDlg::Normalizing Track/File %s with factor %f" ), pDlg->m_strWavFileName, dNormFactor );

						CWAV myWav;

						// Step 1: Open the input WAV file
						if ( myWav.StartNormalizeAudioFile( CUString( pDlg->m_strWavFileName ) )!=0)
						{
							// Step 2: Loop through data and normalize chunk
							while ( myWav.NormalizeAudioFileChunk( dNormFactor, pDlg->m_nPercentCompleted ) == FALSE && 
									!pDlg->m_bAbortThread )
							{
								::Sleep(0);
							}
					
							// Step 3: Close the input WAV file, and replace original
							myWav.CloseNormalizeAudioFile( CUString( pDlg->m_strWavFileName ) , pDlg->m_bAbortThread, TRUE );
						}
					}
				}

				// Check if thread has been aborted, if so, remove original file
				if ( TRUE == pDlg->m_bAbortThread )
				{
					LTRACE( _T( "Deleting file ( due to abort ) %s.wav" ), pDlg->m_strWavFileName );
					DeleteFile( pDlg->m_strWavFileName + _T( ".wav" ) );
				}

				// Check if we have to delete the file
				if ( pDlg->m_pFileDlg->m_bDeleteOriginal && ( FALSE == pDlg->m_bAbortThread )  )
				{
					LTRACE( _T( "Deleting file ( user request ) %s" ), pDlg->m_strMP3FileName );
					DeleteFile( pDlg->m_strMP3FileName );
				}
			}
		}
		else
		{
			if ( TRUE == bNoToAll )
			{
				pDlg->m_bAbortThread = TRUE;
			}
		}

		// delete input stream object
		delete pDlg->m_pInStream;pDlg->m_pInStream=NULL;

		// Jump to the next track
		pDlg->m_wCurrentTrack++;
	}

	pDlg->m_eThreadFinished.SetEvent();

	// OK close the stuff
	pDlg->PostMessage( WM_COMMAND, IDCANCEL,0);

	EXIT_TRACE( _T( "RipFunc" ) );
	return 0;
}
Esempio n. 2
0
UINT CPlayerView::PlayThreadFunc(PVOID pParams)
{
	BYTE*			pStream		 = NULL;
	CDEX_ERR		bErr		 = CDEX_OK;
	CPlayerView*	pDlg		 = NULL;
	int				nCurrentFile = -1;
	CString			strFileName;

	ENTRY_TRACE( _T( "CPlayerView::PlayFunc" ) );

	nCurrentFile	= 0;

	pDlg=(CPlayerView*)pParams;

	pDlg->m_bAbortThread	= FALSE;
	pDlg->m_nTotalTime = 0;
	pDlg->m_nCurrentTime = 0;

	nCurrentFile = 	pDlg->m_PlayList.GetCurSel( );

	if ( pDlg->GetPlayRandom() )
	{
		srand( (unsigned)time( NULL ) );
		nCurrentFile = rand() % pDlg->m_vFileNames.size();
	}

	if ( nCurrentFile < 0 )
	{
		nCurrentFile = 0;
	}

	while(	( nCurrentFile >= 0 ) &&
			( nCurrentFile < (int)pDlg->m_vFileNames.size() ) && 
			( FALSE == pDlg->m_bAbortThread ) )
	{
		DWORD	dwStreamIndex=0;

		strFileName = pDlg->m_vFileNames[ nCurrentFile ];

#ifdef _DEBUG
//		strFileName = "http://urn.nottingham.ac.uk/urnlive.pls";
//		strFileName = "http://reclib.su.nottingham.ac.uk:8080";
#endif

		pDlg->m_PlayList.SetCurSel( nCurrentFile );

		LTRACE( _T( "Playing track %s (file %d)" ), strFileName, nCurrentFile );

		pDlg->SetThreadCommand( THREAD_PLAY_NEXT_TRACK );

		// Delete the old stream if it does exist
		if ( pDlg->m_pInStream )
		{
			delete pDlg->m_pInStream; pDlg->m_pInStream = NULL;
		}


		// create proper input stream
		pDlg->m_pInStream = ICreateStream( CUString( strFileName ) ); 

		pDlg->m_dwSeekOffset = 0;

		// Open the MPEG stream
		if (pDlg->m_pInStream->OpenStream( CUString( strFileName ) ) )
		{
			DWORD	dwInBufferSize = pDlg->m_pInStream->GetBufferSize();
			int		nMPEGBytes=0;

			// Create a play stream object
			pDlg->m_pPlayStream=new PlayWavStream;

			pDlg->m_pPlayStream->CopyStreamInfo( *pDlg->m_pInStream );

			// Initialize play stream object
			if ( FALSE == pDlg->m_pPlayStream->OpenStream( _W( "" ) ) )
			{
				pDlg->m_bAbortThread = TRUE;
			}

			// Allocate stream input buffer
			auto_ptr<BYTE> pStream( new BYTE[ dwInBufferSize  + STREAMBUFFERSIZE ] );
	
			pDlg->m_bAbortCurrent = FALSE;

			// Set status
			pDlg->m_nStatus = PLAYING;

			while ( ( !pDlg->m_bAbortThread ) && 
					( FALSE == pDlg->m_bAbortCurrent ) )
			{

				if ( PLAYING != pDlg->m_nStatus )
				{
					WaitForSingleObject( pDlg->m_ePaused, INFINITE );
					dwStreamIndex = 0;
					pDlg->m_pInStream->Seek( pDlg->m_dwSeekOffset, SEEK_TIME );

				}

				if ( pDlg->m_bAbortThread )
				{
					break;
				}

				if ( (nMPEGBytes = pDlg->m_pInStream->Read( (BYTE*)( pStream.get() ) + dwStreamIndex,dwInBufferSize ) ) >0 )
				{
					// increase current stream index position
					dwStreamIndex += nMPEGBytes ;

					// play the stuff when there is STREAMBUFFERSIZE samples are present
					while ( ( dwStreamIndex >= STREAMBUFFERSIZE ) && 
							( FALSE == pDlg->m_bAbortThread )  &&
							( FALSE == pDlg->m_bAbortCurrent ) )
					{
						if ( PLAYING != pDlg->m_nStatus )
						{
							break;
						}

						pDlg->m_pPlayStream->Write( pStream.get(), STREAMBUFFERSIZE );
						dwStreamIndex-= STREAMBUFFERSIZE;
						memmove( pStream.get() , (BYTE*)pStream.get() + STREAMBUFFERSIZE, dwStreamIndex );
					}

					pDlg->m_dwBitRate=pDlg->m_pInStream->GetBitRate();
					pDlg->m_nTotalTime=pDlg->m_pInStream->GetTotalTime();
				}
				else
				{
					while ( dwStreamIndex )
					{
						DWORD dwBytes = min( STREAMBUFFERSIZE, dwStreamIndex );

						if ( pDlg->m_bAbortThread )
						{
							break;
						}

						if ( dwBytes < STREAMBUFFERSIZE )
						{
							memset( (BYTE*)pStream.get() + dwBytes, 0, STREAMBUFFERSIZE - dwBytes );
						}

						pDlg->m_pPlayStream->Write( pStream.get(), STREAMBUFFERSIZE );

						dwStreamIndex-= dwBytes;

						if ( dwStreamIndex )
						{
							memmove( pStream.get() , (BYTE*)pStream.get() + dwBytes, dwStreamIndex );
						}
					}

					pDlg->m_bAbortCurrent = TRUE;
				}
			}
		}
		else
		{
			pDlg->MessageBox( _T( "Problem opening the file" ) );
		}

		// Close the mpeg stream
		if (pDlg->m_pInStream)
		{
			pDlg->m_pInStream->CloseStream();

			// Don't delete it, since we want to able to get 
			// the file details
		}

		// Close the play stream
		if (pDlg->m_pPlayStream)
		{
			LTRACE( _T( "Closing the output stream !!!!" ) );
			pDlg->m_pPlayStream->CloseStream();
		}


		delete pDlg->m_pPlayStream; pDlg->m_pPlayStream = NULL;

		switch ( pDlg->GetThreadCommand() )
		{
			case THREAD_PLAY_NEXT_TRACK:
				if ( pDlg->GetPlayRandom() )
				{
					int nNewFile = nCurrentFile;

					// randomize until we got a different track
					while ( pDlg->m_vFileNames.size() > 1 &&
							nCurrentFile == nNewFile )
					{
						srand( (unsigned)time( NULL ) );
						nNewFile = rand() % pDlg->m_vFileNames.size();
					}
					nCurrentFile = nNewFile;
				}
				else
				{
					nCurrentFile++;
				}
			break;
			case THREAD_PLAY_PREV_TRACK:
				if ( nCurrentFile > 0 )
				{
					nCurrentFile--;
				}
			break;
			case THREAD_PLAY_FINISH:
				pDlg->m_bAbortThread = TRUE;
			break;
			case THREAD_PLAY_TRACK:
				nCurrentFile = 	pDlg->m_PlayList.GetCurSel( );
			break;
		}
	}

	pDlg->m_nStatus = IDLE;

	pDlg->m_pThread = NULL;

	pDlg->m_eThreadFinished.SetEvent();

	EXIT_TRACE( _T( "CPlayerView::PlayThreadFunc" ) );

	return 0;
}