TadaoYamaokaの日記

山岡忠夫 Home で公開しているプログラムの開発ネタを中心に書いていきます。

waveファイルの読み込み

Windows限定だけど、C/C++でwaveファイルを読み込む処理の簡単な実装

#include <windows.h>
#include <stdio.h>

#pragma pack(push, 1)
struct RiffHeader {
	char          id[4];
	unsigned long size;
	char          fmt[4];
};

struct FormatChunk {
	char           chunkID[4];
	long           chunkSize;
	short          wFormatTag;
	unsigned short wChannels;
	unsigned long  dwSamplesPerSec;
	unsigned long  dwAvgBytesPerSec;
	unsigned short wBlockAlign;
	unsigned short wBitsPerSample;
	/* Note: there may be additional fields here, depending upon wFormatTag. */
};

struct DataChunk {
	char           chunkID[4];
	long           chunkSize; 
};
#pragma pack(pop)

int wmain(int argc, wchar_t *argv[])
{
	HANDLE hFile = CreateFile(argv[1], GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
	HANDLE hFileMap = CreateFileMapping(hFile, NULL, PAGE_READONLY, 0, 0, NULL);
	const void* pBuf = MapViewOfFile(hFileMap, FILE_MAP_READ, 0, 0, 0);
	// RIFFヘッダー
	struct RiffHeader *header = (struct RiffHeader*)pBuf;
	if (memcmp(header->id, "RIFF", 4) != 0)
	{
		printf("RIFF check error.\n");
		return 1;
	}
	if (memcmp(header->fmt, "WAVE", 4) != 0)
	{
		printf("WAVE check error.\n");
		return 1;
	}
	struct FormatChunk *fmt = (struct FormatChunk*)((unsigned char*)pBuf + sizeof(struct RiffHeader));
	short *data = (short*)((unsigned char*)pBuf + sizeof(struct RiffHeader) + 8 + fmt->chunkSize + sizeof(struct DataChunk));
}

ポイント
・ファイルマッピングを使って、ファイルをメモリのように扱う。
・構造体のアライメントを0にして、メモリを構造体をして扱えるようにする。