📄 mpegaudioinfodlg.cpp
字号:
DWORD dwFileSize = m_pMPAFile->GetFileSize();
m_strFileInfo.Format(_T("File Size (without Tags): %d Byte (%d KB)\nEstimated Length: %.2d:%.2d"), dwFileSize,
dwFileSize / 1024, dwLengthSec / 60, dwLengthSec % 60);
// current frame is first frame (need new instance)
OnBnClickedFirstframe();
}
catch(CMPAException& Exc)
{
Exc.ShowError();
m_CtrlPrevFrame.EnableWindow(false);
m_CtrlNextFrame.EnableWindow(false);
m_CtrlFirstFrame.EnableWindow(false);
m_CtrlLastFrame.EnableWindow(false);
m_CtrlCheckFile.EnableWindow(false);
}
UpdateData(false);
}
CString CMPEGAudioInfoDlg::IsVarTrue(bool bVar)
{
return bVar?_T("Yes"):_T("No");
}
void CMPEGAudioInfoDlg::OnBnClickedNextframe()
{
CMPAFrame* pFrame;
if ((pFrame = m_pMPAFile->GetFrame(CMPAFile::Next, m_pFrame)) != NULL)
{
m_pFrame = pFrame;
if (m_dwFrameNo > 0)
m_dwFrameNo++;
GetFrameInfo(m_pFrame, m_dwFrameNo);
}
}
void CMPEGAudioInfoDlg::OnBnClickedPrevframe()
{
CMPAFrame* pFrame;
if ((pFrame = m_pMPAFile->GetFrame(CMPAFile::Prev, m_pFrame)) != NULL)
{
m_pFrame = pFrame;
if (m_dwFrameNo > 1)
m_dwFrameNo--;
GetFrameInfo(m_pFrame, m_dwFrameNo);
}
}
void CMPEGAudioInfoDlg::OnBnClickedFirstframe()
{
if ((m_pFrame = m_pMPAFile->GetFrame(CMPAFile::First, m_pFrame)) != NULL)
{
m_dwFrameNo = 1;
GetFrameInfo(m_pFrame, m_dwFrameNo);
}
}
void CMPEGAudioInfoDlg::OnBnClickedLastframe()
{
if ((m_pFrame = m_pMPAFile->GetFrame(CMPAFile::Last, m_pFrame)) != NULL)
{
m_dwFrameNo = 0;
GetFrameInfo(m_pFrame, m_dwFrameNo);
}
}
void CMPEGAudioInfoDlg::OnBnClickedCheckfile()
{
m_strOutput = _T("");
// go through every frame of the file and look if the next frame is at the computed offset and valid
CMPAFrame* pCurMPAFrame;
CMPAFrame* pPrevMPAFrame;
pCurMPAFrame = m_pMPAFile->GetFrame(CMPAFile::First);
pPrevMPAFrame = m_pMPAFile->GetFrame(CMPAFile::First);
if (!pCurMPAFrame || !pPrevMPAFrame)
{
m_strOutput = _T("Couldn't find first frame. This is probably no MPEG audio file!");
return;
}
DWORD dwPadded = 0, dwUnpadded = 0;
DWORD dwFrameNo = 0;
DWORD dwAverBitrate = pCurMPAFrame->m_pHeader->m_dwBitrate;
bool bVBR = false;
CString strHelp;
do
{
dwFrameNo++;
// check CRC
if (pCurMPAFrame->m_pHeader->m_bCRC)
{
if (!pCurMPAFrame->CheckCRC())
{
strHelp.Format(_T("Wrong CRC checksum in frame %d\r\n"), dwFrameNo);
m_strOutput += strHelp;
};
}
// is it VBR?
if (pCurMPAFrame->m_pHeader->m_dwBitrate != dwAverBitrate)
{
// aver. bitrate += (new bitrate - aver. bitrate / #frames)
// convert to int (some values can be negative)
dwAverBitrate += (int)((int)pCurMPAFrame->m_pHeader->m_dwBitrate - (int)dwAverBitrate) / (int)dwFrameNo;
bVBR = true;
}
// even in VBR files these values must not change
if (pCurMPAFrame->m_pHeader->m_dwSamplesPerSec != pPrevMPAFrame->m_pHeader->m_dwSamplesPerSec)
{
CString strNewSamplingRate, strOldSamplingRate;
strOldSamplingRate.Format(_T("%d Hz"), pPrevMPAFrame->m_pHeader->m_dwSamplesPerSec);
// new sampling rate
strNewSamplingRate.Format(_T("%d Hz"), pCurMPAFrame->m_pHeader->m_dwSamplesPerSec);
InvalidChange( _T("Sampling rate"), dwFrameNo, strOldSamplingRate, strNewSamplingRate);
}
if (pCurMPAFrame->m_pHeader->m_Layer != pPrevMPAFrame->m_pHeader->m_Layer)
{
InvalidChange( _T("Layer"), dwFrameNo, CMPAHeader::m_szLayers[pPrevMPAFrame->m_pHeader->m_Layer], CMPAHeader::m_szLayers[pCurMPAFrame->m_pHeader->m_Layer] );
}
if (pCurMPAFrame->m_pHeader->m_Version != pPrevMPAFrame->m_pHeader->m_Version)
{
InvalidChange( _T("Version"), dwFrameNo, CMPAHeader::m_szMPEGVersions[pPrevMPAFrame->m_pHeader->m_Version], CMPAHeader::m_szMPEGVersions[pCurMPAFrame->m_pHeader->m_Version] );
}
if (dwFrameNo > 1 && pCurMPAFrame->m_dwOffset != pPrevMPAFrame->GetSubsequentHeaderOffset())
{
strHelp.Format( _T("Frame %d header expected at byte %d, but found at byte %d.\r\n")
_T("Frame %d (bytes %d-%d) was %d bytes long (expected %d bytes).\r\n\r\n"),
dwFrameNo,
pPrevMPAFrame->GetSubsequentHeaderOffset(),
pCurMPAFrame->m_dwOffset,
dwFrameNo-1,
pPrevMPAFrame->m_dwOffset,
pCurMPAFrame->m_dwOffset,
pCurMPAFrame->m_dwOffset - pPrevMPAFrame->m_dwOffset,
pPrevMPAFrame->m_dwFrameSize );
m_strOutput += strHelp;
}
if (pCurMPAFrame->m_pHeader->m_dwPaddingSize > 0)
dwPadded++;
else
dwUnpadded++;
delete pPrevMPAFrame;
pPrevMPAFrame = pCurMPAFrame;
}while ((pCurMPAFrame = m_pMPAFile->GetFrame(CMPAFile::Next, pCurMPAFrame, false)) != NULL);
if (pPrevMPAFrame->GetSubsequentHeaderOffset() > m_pMPAFile->GetEnd())
{
strHelp.Format(_T("Last frame truncated.\r\nFrame %d (bytes %d-%d) was %d bytes long (expected %d bytes)\r\n\r\n"),
dwFrameNo, pPrevMPAFrame->m_dwOffset, m_pMPAFile->GetEnd(), m_pMPAFile->GetEnd() - pPrevMPAFrame->m_dwOffset, pPrevMPAFrame->m_dwFrameSize);
m_strOutput += strHelp;
}
else if (pPrevMPAFrame->GetSubsequentHeaderOffset() < m_pMPAFile->GetEnd())
{
strHelp.Format(_T("Free space or unrecognized Tag after last frame %d (bytes %d-%d).\r\n\r\n"),
dwFrameNo, pPrevMPAFrame->m_dwOffset, m_pMPAFile->GetEnd());
m_strOutput += strHelp;
}
if (m_strOutput.IsEmpty())
{
m_strOutput += (_T("No errors found in file.\r\n\r\n"));
}
m_strOutput += (_T("\r\nSummary:\r\n===============\r\n"));
strHelp.Format(_T("Total number of frames: %d, unpadded: %d, padded: %d\r\n"), dwFrameNo, dwUnpadded, dwPadded);
m_strOutput += strHelp;
DWORD dwLengthSec = pPrevMPAFrame->m_pHeader->GetLengthSecond(dwFrameNo);
if (bVBR)
strHelp.Format( _T("File is VBR. Average bitrate is %d kbps.\r\n"), dwAverBitrate/1000);
else
strHelp.Format(_T("File is CBR. Bitrate of each frame is %d kbps.\r\n"), dwAverBitrate/1000);
m_strOutput += strHelp;
strHelp.Format(_T("Exact length: %.2d:%.2d\r\n"), dwLengthSec / 60, dwLengthSec % 60);
m_strOutput += strHelp;
delete pPrevMPAFrame;
UpdateData(false);
}
void CMPEGAudioInfoDlg::InvalidChange(LPCTSTR szWhat, DWORD dwFrame, LPCTSTR szOldValue, LPCTSTR szNewValue)
{
CString strHelp;
strHelp.Format(_T("%s changed in frame %d from %s to %s\r\n"), szWhat, dwFrame, szOldValue, szNewValue);
m_strOutput += strHelp;
}
void CMPEGAudioInfoDlg::OnBnClickedAbout()
{
CAboutDlg dlg;
dlg.DoModal();
}
// this source is not yet used, will be added later to check whole directories instead of single files
/*
#include <shlobj.h>
void CMPEGAudioInfoDlg::OnBnClickedOpendir()
{
LPMALLOC pMalloc;
SHGetMalloc(&pMalloc);
TCHAR szPath[MAX_PATH];
BROWSEINFO BrowseInfo;
LPITEMIDLIST pIDList;
memset(&BrowseInfo, NULL, sizeof(BrowseInfo));
BrowseInfo.hwndOwner = m_hWnd;
BrowseInfo.lpszTitle = _T("Select Folder...");
BrowseInfo.ulFlags = BIF_NEWDIALOGSTYLE|BIF_RETURNFSANCESTORS|BIF_RETURNONLYFSDIRS;
BrowseInfo.lpfn = NULL;
pIDList = SHBrowseForFolder(&BrowseInfo);
SHGetPathFromIDList(pIDList, szPath);
RecurseFindFile(szPath);
pMalloc->Free(pIDList);
pMalloc->Release();
}
#include "apetag.h"
void CMPEGAudioInfoDlg::RecurseFindFile(LPCTSTR szPath)
{
CFileFind Finder;
CString strSearch;
strSearch.Format(_T("%s\\*.*"), szPath);
BOOL bWorking = Finder.FindFile(strSearch);
while (bWorking)
{
bWorking = Finder.FindNextFile();
if (Finder.IsDots())
continue;
// if it's a directory, recursively search it
if (Finder.IsDirectory())
{
RecurseFindFile(Finder.GetFilePath());
}
else
{
try
{
CMPAFile File(Finder.GetFilePath());
CXINGHeader* pXINGHeader;
// we need runtime type information for the dynamic_cast -> compile this with /GR switch
// is it a XING header?
if ((pXINGHeader = dynamic_cast<CXINGHeader*>(File.m_pVBRHeader)) != NULL)
{
if (pXINGHeader->m_pLAMETag)
{
CString strMsg;
strMsg.Format(_T("Found LAME Extension in %s"), Finder.GetFilePath());
AfxMessageBox(strMsg);
}
}
}
catch(...)
{
}
}
}
}*/
void CMPEGAudioInfoDlg::OnDropFiles(HDROP hDropInfo)
{
// get information about dropped files
// get size of filename of first file
UINT nBufferSize = ::DragQueryFile(hDropInfo, 0, NULL, 0);
nBufferSize++;
LPTSTR szFilename = new TCHAR[nBufferSize];
// get filename of first file
::DragQueryFile(hDropInfo, 0, szFilename, nBufferSize);
LoadMPEGFile(szFilename);
delete[] szFilename;
::DragFinish(hDropInfo);
CDialog::OnDropFiles(hDropInfo);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -