開発環境 Microsoft Visual C++ 2010 Express (SP1)
実行環境 Microsoft Windows XP Home Edition (SP3)
プロジェクトの種類 Win32 プロジェクト
プロジェクト名 TestMP3
アプリケーションの種類 Windows アプリケーション
追加のオプション 空のプロジェクト

参考

TestMP3.cpp
// TestMP3_2 MP3ファイルの概要
 
#pragma comment(lib, "winmm")
 
#include <Windows.h>
#include <MMReg.h>
#include <stdio.h>
#include <string>
#include "resource.h"
 
using namespace std;
 
typedef struct {
	BYTE id[3];
	BYTE version[2];
	BYTE flag;
	BYTE size[4];
} ID3V2HEADER, *LPID3V2HEADER;
 
// 関数プロトタイプ宣言
INT_PTR CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
void OnDropFiles(HWND hDlg, WPARAM wParam);
void Trace(LPCTSTR format, ...);
BOOL LoadMP3(LPTSTR lpszFile);
BOOL GetMP3Format(LPBYTE lpData);
 
// 外部変数
wstring str;
 
//==============================================================================
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR, int)
{
	DialogBox(hInstance, MAKEINTRESOURCE(IDD_DIALOG), NULL, DlgProc);
	return 0;
}
 
INT_PTR CALLBACK DlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	INT_PTR result = TRUE;
 
	switch (uMsg) {
	case WM_COMMAND:
		switch (LOWORD(wParam)) {
		case IDCANCEL:
			EndDialog(hDlg, IDCANCEL);
			break;
		}
		break;
	case WM_DROPFILES:
		OnDropFiles(hDlg, wParam);
		DragFinish((HDROP)wParam);
		break;
	case WM_CLOSE:
		EndDialog(hDlg, 0);
		break;
	default:
		result = FALSE;
	}
	return result;
}
 
void OnDropFiles(HWND hDlg, WPARAM wParam)
{
	HDROP hDrop = (HDROP)wParam;
	TCHAR szFile[MAX_PATH];
	DragQueryFile(hDrop, 0, szFile, _countof(szFile));
 
	TCHAR title[256];
	swprintf_s(title, TEXT("%s - %s"), TEXT("TestMP3"), szFile);
	SetWindowText(hDlg, title);
 
	str.clear();
	if (!LoadMP3(szFile)) {
		return;
	}
 
	SetWindowText(GetDlgItem(hDlg, IDC_EDIT), str.c_str());
}
 
void Trace(LPCTSTR format, ...)
{
	va_list arg_ptr;
	va_start(arg_ptr, format);
	TCHAR buffer[256];
	int size = _vsnwprintf_s(buffer, _TRUNCATE, format, arg_ptr);
	va_end(arg_ptr);
	str += buffer;
	str += TEXT("\r\n");
}
 
BOOL LoadMP3(LPTSTR lpszFileName)
{
	// MP3ファイル部
	HMMIO hmmio = mmioOpen(lpszFileName, NULL, MMIO_READ);
	if (hmmio == NULL) {
		MessageBox(NULL, TEXT("ファイルのオープンに失敗しました。"), NULL, MB_ICONWARNING);
		return FALSE;
	}
	DWORD dwFile = mmioSeek(hmmio, 0, SEEK_END);
	LPBYTE lpFile = new BYTE[dwFile];
	mmioSeek(hmmio, 0, SEEK_SET);
	mmioRead(hmmio, (HPSTR)lpFile, dwFile);
	mmioClose(hmmio, 0);
 
	// MP3データ部
	DWORD dwData = dwFile;
	LPBYTE lpData = lpFile;
 
	// ID3v1
	if (128 <= dwFile && memcmp(lpFile + dwFile - 128, "TAG", 3) == 0) {
		dwData -= 128;
		Trace(TEXT("ID3v1: o"));
	} else {
		Trace(TEXT("ID3v1: x"));
	}
 
	// ID3v2
	if (10 <= dwData && memcmp(lpFile, "ID3", 3) == 0) {
		LPID3V2HEADER lpHeader = (LPID3V2HEADER)lpFile;
		LPBYTE size = lpHeader->size;
		DWORD dwTagSize = ((size[0]<<21)|(size[1]<<14)|(size[2]<<7)|size[3]) + 10;
		dwData -= dwTagSize;
		lpData = lpFile + dwTagSize;
		Trace(TEXT("ID3v2: o"));
		Trace(TEXT("Version: %u"), lpHeader->version[0]);
		Trace(TEXT("Size: %u %#x"), dwTagSize, dwTagSize);
	} else {
		Trace(TEXT("ID3v2:x"));
	}
 
	GetMP3Format(lpData);
 
	delete[] lpFile;
	return TRUE;
}
 
BOOL GetMP3Format(LPBYTE lpData)
{
	static const DWORD dwBitTableLayer3[][16] = {
		{0, 32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 0},
		{0, 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160, 0}
	};
	static const DWORD dwSampleTable[][3] = {
		{44100, 48000, 32000},
		{22050, 24000, 16000}
	};
 
	// 同期ヘッダ
	if (lpData[0] != 0xff || lpData[1] >> 5 != 0x07) {
		return FALSE;
	}
 
	// バージョン
	BYTE version;
	switch (lpData[1] >> 3 & 0x03) {
	case 3:	// 11=MPEG1
		version = 1;
		break;
	case 2:	// 10=MPEG2
		version = 2;
		break;
	default:
		return FALSE;
	}
 
	// レイヤー
	if ((lpData[1] >> 1 & 0x03) != 1) {	// 01=Leyer3
		return FALSE;
	}
 
	// ビットレート
	BYTE index = lpData[2] >> 4;
	DWORD dwBitRate = dwBitTableLayer3[version - 1][index];
 
	// サンプリングレート
	index = lpData[2] >> 2 & 0x03;
	DWORD dwSampleRate = dwSampleTable[version - 1][index];
 
	// パディング
	BYTE padding = lpData[2] >> 1 & 0x01;
 
	// チャンネルモード
	BYTE channel = (lpData[3] >> 6) == 3 ? 1 : 2;	// 11=シングルチャネル
 
	Trace(TEXT("----"));
	Trace(TEXT("Version: MPEG%u"), version);
	Trace(TEXT("Layer: 3"));
	Trace(TEXT("Bit Rate: %u kbps"), dwBitRate);
	Trace(TEXT("Sampling Rate: %u Hz"), dwSampleRate);
	Trace(TEXT("Channels: %u"), channel);
 
	return TRUE;
}
 

resource.h
#define IDD_DIALOG	100
 
#define IDC_EDIT	1000
 

TestMP3.rc
// resource script
 
#include <Windows.h>
#include "resource.h"
 
IDD_DIALOG DIALOGEX 100, 100, 320, 200
STYLE WS_POPUPWINDOW | WS_MINIMIZEBOX
EXSTYLE WS_EX_APPWINDOW | WS_EX_ACCEPTFILES
CAPTION "TestMP3"
FONT 9, "MS Pゴシック"
BEGIN
	EDITTEXT	IDC_EDIT,10,10,300,150,ES_MULTILINE
END
 
最終更新:2013年03月07日 17:44