웨이브 파일의 PCM 데이터를 읽어서 그대로 바이너리 파일로 저장하도록
작성하였으므로 웨이브 파일이 PCM포맷일 때만 바이너리 PCM 파일로 저장할 수
있습니다. (아닌 경우는 변환 불가 메시지박스가 뜹니다.)
PCM포맷이 아닌 경우는 ACM 라이브러리를 사용해서 디코딩해야 하나 여기서는
생략하였습니다.
Win32 윈도우 애플리케이션으로 만들었지만 메인 윈도우는 만들지 않았습니다.
명령프롬프트(혹은 MS-DOS)창에서 변환하고자 하는 파일 이름을 같이 입력하면
확장자가 .pcm이 되는 파일로 변환이 됩니다. 만일 변환 대상 파일 이름을 같이 입력
하지 않으면 파일 열기 다이얼로그박스가 열리므로 거기서 선택하면 됩니다.
이 프로그램은 winmm.lib와 같이 링크되어야 합니다.
// Wav2PCM.cpp : Wave to PCM Converter
// winmm.lib are required when linking
#include <windows.h>
#include <mmsystem.h>
#define IO_SAMPLES 2048
BOOL GetWaveFileName(LPSTR lpFileName, int cbFileName, LPSTR lpCmdLine);
void SetDefExtension(LPSTR lpFileName, LPCSTR lpDefExt, BOOL bForce);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
char szWaveName[_MAX_PATH], szPcmName[_MAX_PATH];
if(!GetWaveFileName(szWaveName, sizeof(szWaveName), lpCmdLine))
return 0;
strcpy(szPcmName, szWaveName);
SetDefExtension(szPcmName, ".pcm", TRUE);
HMMIO hmmio;
MMCKINFO mmckRiff, mmck;
LPWAVEFORMATEX lpwfx;
LONG cbwfx;
LONG nTotalSamples;
hmmio = mmioOpen((LPTSTR)szWaveName, NULL, MMIO_READ | MMIO_ALLOCBUF);
if(hmmio == NULL) {
MessageBox(NULL, "파일을 열 수 없습니다.", "Wav2PCM", MB_OK | MB_ICONSTOP);
return 0;
}
mmckRiff.fccType = mmioStringToFOURCC("WAVE", 0);
if(mmioDescend(hmmio, &mmckRiff, NULL, MMIO_FINDRIFF)) {
mmioClose(hmmio, 0);
MessageBox(NULL, "웨이브 파일이 아닙니다.", "Wav2PCM", MB_OK | MB_ICONSTOP);
return 0;
}
mmck.ckid = mmioStringToFOURCC("fmt ", 0);
if(mmioDescend(hmmio, &mmck, &mmckRiff, MMIO_FINDCHUNK)) {
mmioClose(hmmio, 0);
MessageBox(NULL, "웨이브 포맷을 찾을 수 없습니다.", "Wav2PCM", MB_OK | MB_ICONSTOP);
return 0;
}
cbwfx = mmck.cksize;
lpwfx = (LPWAVEFORMATEX)new BYTE[cbwfx];
if(mmioRead(hmmio, (HPSTR)lpwfx, cbwfx) < 0) {
delete [] lpwfx;
mmioClose(hmmio, 0);
MessageBox(NULL, "웨이브 포맷을 읽을 수 없습니다.", "Wav2PCM", MB_OK | MB_ICONSTOP);
return 0;
}
mmioAscend(hmmio, &mmck, 0);
if((lpwfx->wFormatTag != WAVE_FORMAT_PCM)) {
delete [] lpwfx;
mmioClose(hmmio, 0);
MessageBox(NULL, "PCM 포맷이 아닙니다.", "Wav2PCM", MB_OK | MB_ICONSTOP);
return 0;
}
nTotalSamples = 0;
mmck.ckid = mmioStringToFOURCC("fact", 0);
if(mmioDescend(hmmio, &mmck, &mmckRiff, MMIO_FINDCHUNK) == MMSYSERR_NOERROR) {
mmioRead(hmmio, (LPSTR)&nTotalSamples, mmck.cksize);
mmioAscend(hmmio, &mmck, 0);
}
else {
mmioSeek(hmmio, 0, SEEK_SET);
mmckRiff.fccType = mmioStringToFOURCC("WAVE", 0);
mmioDescend(hmmio, &mmckRiff, NULL, MMIO_FINDRIFF);
}
mmck.ckid = mmioStringToFOURCC("data", 0);
if(mmioDescend(hmmio, &mmck, &mmckRiff, MMIO_FINDCHUNK)) {
delete [] lpwfx;
mmioClose(hmmio, 0);
MessageBox(NULL, "웨이브 데이터를 찾을 수 없습니다.", "Wav2PCM", MB_OK | MB_ICONSTOP);
return 0;
}
if(nTotalSamples == 0)
nTotalSamples = MulDiv(mmck.cksize, lpwfx->nSamplesPerSec, lpwfx->nAvgBytesPerSec);
HANDLE hFile = CreateFile(szPcmName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile == INVALID_HANDLE_VALUE) {
delete [] lpwfx;
mmioClose(hmmio, 0);
MessageBox(NULL, "출력 파일을 만들 수 없습니다.", "Error", MB_OK | MB_ICONSTOP);
return 0;
}
LONG cbBuffer = lpwfx->nBlockAlign * IO_SAMPLES;
LPBYTE lpBuffer = new BYTE[cbBuffer];
while(TRUE) {
LONG lReadBytes = mmioRead(hmmio, (HPSTR)lpBuffer, cbBuffer);
if(lReadBytes <= 0) break;
DWORD dwWritten;
WriteFile(hFile, lpBuffer, lReadBytes, &dwWritten, NULL);
}
delete [] lpBuffer;
CloseHandle(hFile);
delete [] lpwfx;
mmioClose(hmmio, 0);
MessageBox(NULL, "변환을 완료하였습니다.", "Wav2PCM", MB_OK | MB_ICONINFORMATION);
return 0;
}
BOOL GetWaveFileName(LPSTR lpFileName, int cbFileName, LPSTR lpCmdLine)
{
if(lpCmdLine[0] == '\0') {
lpFileName[0] = '\0';
OPENFILENAME ofn;
ZeroMemory(&ofn, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.lpstrFilter = "Wave Files (*.wav)\0*.wav\0All Files (*.*)\0*.*\0\0";
ofn.lpstrFile = lpFileName;
ofn.nMaxFile = cbFileName;
ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;
if(!GetOpenFileName(&ofn)) return FALSE;
}
else if(lpCmdLine[0] == '\"') {
char *sp = strchr(lpCmdLine + 1, '\"');
if(sp != NULL) *sp = '\0';
strcpy(lpFileName, lpCmdLine + 1);
}
else {
char *sp = strchr(lpCmdLine, ' ');
if(sp != NULL) *sp = '\0';
strcpy(lpFileName, lpCmdLine);
}
return TRUE;
}
void SetDefExtension(LPSTR lpFileName, LPCSTR lpDefExt, BOOL bForce)
{
char szDrv[_MAX_DRIVE], szDir[_MAX_DIR], szFname[_MAX_FNAME], szExt[_MAX_EXT];
_splitpath(lpFileName, szDrv, szDir, szFname, szExt);
if(bForce || szExt[0] == 0) strcpy(szExt, lpDefExt);
_makepath(lpFileName, szDrv, szDir, szFname, szExt);
}
작성하였으므로 웨이브 파일이 PCM포맷일 때만 바이너리 PCM 파일로 저장할 수
있습니다. (아닌 경우는 변환 불가 메시지박스가 뜹니다.)
PCM포맷이 아닌 경우는 ACM 라이브러리를 사용해서 디코딩해야 하나 여기서는
생략하였습니다.
Win32 윈도우 애플리케이션으로 만들었지만 메인 윈도우는 만들지 않았습니다.
명령프롬프트(혹은 MS-DOS)창에서 변환하고자 하는 파일 이름을 같이 입력하면
확장자가 .pcm이 되는 파일로 변환이 됩니다. 만일 변환 대상 파일 이름을 같이 입력
하지 않으면 파일 열기 다이얼로그박스가 열리므로 거기서 선택하면 됩니다.
이 프로그램은 winmm.lib와 같이 링크되어야 합니다.
// Wav2PCM.cpp : Wave to PCM Converter
// winmm.lib are required when linking
#include <windows.h>
#include <mmsystem.h>
#define IO_SAMPLES 2048
BOOL GetWaveFileName(LPSTR lpFileName, int cbFileName, LPSTR lpCmdLine);
void SetDefExtension(LPSTR lpFileName, LPCSTR lpDefExt, BOOL bForce);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
char szWaveName[_MAX_PATH], szPcmName[_MAX_PATH];
if(!GetWaveFileName(szWaveName, sizeof(szWaveName), lpCmdLine))
return 0;
strcpy(szPcmName, szWaveName);
SetDefExtension(szPcmName, ".pcm", TRUE);
HMMIO hmmio;
MMCKINFO mmckRiff, mmck;
LPWAVEFORMATEX lpwfx;
LONG cbwfx;
LONG nTotalSamples;
hmmio = mmioOpen((LPTSTR)szWaveName, NULL, MMIO_READ | MMIO_ALLOCBUF);
if(hmmio == NULL) {
MessageBox(NULL, "파일을 열 수 없습니다.", "Wav2PCM", MB_OK | MB_ICONSTOP);
return 0;
}
mmckRiff.fccType = mmioStringToFOURCC("WAVE", 0);
if(mmioDescend(hmmio, &mmckRiff, NULL, MMIO_FINDRIFF)) {
mmioClose(hmmio, 0);
MessageBox(NULL, "웨이브 파일이 아닙니다.", "Wav2PCM", MB_OK | MB_ICONSTOP);
return 0;
}
mmck.ckid = mmioStringToFOURCC("fmt ", 0);
if(mmioDescend(hmmio, &mmck, &mmckRiff, MMIO_FINDCHUNK)) {
mmioClose(hmmio, 0);
MessageBox(NULL, "웨이브 포맷을 찾을 수 없습니다.", "Wav2PCM", MB_OK | MB_ICONSTOP);
return 0;
}
cbwfx = mmck.cksize;
lpwfx = (LPWAVEFORMATEX)new BYTE[cbwfx];
if(mmioRead(hmmio, (HPSTR)lpwfx, cbwfx) < 0) {
delete [] lpwfx;
mmioClose(hmmio, 0);
MessageBox(NULL, "웨이브 포맷을 읽을 수 없습니다.", "Wav2PCM", MB_OK | MB_ICONSTOP);
return 0;
}
mmioAscend(hmmio, &mmck, 0);
if((lpwfx->wFormatTag != WAVE_FORMAT_PCM)) {
delete [] lpwfx;
mmioClose(hmmio, 0);
MessageBox(NULL, "PCM 포맷이 아닙니다.", "Wav2PCM", MB_OK | MB_ICONSTOP);
return 0;
}
nTotalSamples = 0;
mmck.ckid = mmioStringToFOURCC("fact", 0);
if(mmioDescend(hmmio, &mmck, &mmckRiff, MMIO_FINDCHUNK) == MMSYSERR_NOERROR) {
mmioRead(hmmio, (LPSTR)&nTotalSamples, mmck.cksize);
mmioAscend(hmmio, &mmck, 0);
}
else {
mmioSeek(hmmio, 0, SEEK_SET);
mmckRiff.fccType = mmioStringToFOURCC("WAVE", 0);
mmioDescend(hmmio, &mmckRiff, NULL, MMIO_FINDRIFF);
}
mmck.ckid = mmioStringToFOURCC("data", 0);
if(mmioDescend(hmmio, &mmck, &mmckRiff, MMIO_FINDCHUNK)) {
delete [] lpwfx;
mmioClose(hmmio, 0);
MessageBox(NULL, "웨이브 데이터를 찾을 수 없습니다.", "Wav2PCM", MB_OK | MB_ICONSTOP);
return 0;
}
if(nTotalSamples == 0)
nTotalSamples = MulDiv(mmck.cksize, lpwfx->nSamplesPerSec, lpwfx->nAvgBytesPerSec);
HANDLE hFile = CreateFile(szPcmName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
if(hFile == INVALID_HANDLE_VALUE) {
delete [] lpwfx;
mmioClose(hmmio, 0);
MessageBox(NULL, "출력 파일을 만들 수 없습니다.", "Error", MB_OK | MB_ICONSTOP);
return 0;
}
LONG cbBuffer = lpwfx->nBlockAlign * IO_SAMPLES;
LPBYTE lpBuffer = new BYTE[cbBuffer];
while(TRUE) {
LONG lReadBytes = mmioRead(hmmio, (HPSTR)lpBuffer, cbBuffer);
if(lReadBytes <= 0) break;
DWORD dwWritten;
WriteFile(hFile, lpBuffer, lReadBytes, &dwWritten, NULL);
}
delete [] lpBuffer;
CloseHandle(hFile);
delete [] lpwfx;
mmioClose(hmmio, 0);
MessageBox(NULL, "변환을 완료하였습니다.", "Wav2PCM", MB_OK | MB_ICONINFORMATION);
return 0;
}
BOOL GetWaveFileName(LPSTR lpFileName, int cbFileName, LPSTR lpCmdLine)
{
if(lpCmdLine[0] == '\0') {
lpFileName[0] = '\0';
OPENFILENAME ofn;
ZeroMemory(&ofn, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.lpstrFilter = "Wave Files (*.wav)\0*.wav\0All Files (*.*)\0*.*\0\0";
ofn.lpstrFile = lpFileName;
ofn.nMaxFile = cbFileName;
ofn.Flags = OFN_HIDEREADONLY | OFN_FILEMUSTEXIST;
if(!GetOpenFileName(&ofn)) return FALSE;
}
else if(lpCmdLine[0] == '\"') {
char *sp = strchr(lpCmdLine + 1, '\"');
if(sp != NULL) *sp = '\0';
strcpy(lpFileName, lpCmdLine + 1);
}
else {
char *sp = strchr(lpCmdLine, ' ');
if(sp != NULL) *sp = '\0';
strcpy(lpFileName, lpCmdLine);
}
return TRUE;
}
void SetDefExtension(LPSTR lpFileName, LPCSTR lpDefExt, BOOL bForce)
{
char szDrv[_MAX_DRIVE], szDir[_MAX_DIR], szFname[_MAX_FNAME], szExt[_MAX_EXT];
_splitpath(lpFileName, szDrv, szDir, szFname, szExt);
if(bForce || szExt[0] == 0) strcpy(szExt, lpDefExt);
_makepath(lpFileName, szDrv, szDir, szFname, szExt);
}
다음검색