wfio
Borland C++ Compiler 5.5
wfio.c
#include
#include
#include
#include
// プロトタイプ宣言 int ReadWaveFile(const char *pcFile); int WriteWaveFile(const char *pcFile); int Tune(void); // グローバル変数 static DWORD g_dwCkSizeFmt; static WAVEFORMATEX *g_pwf = NULL; static DWORD g_dwCkSizeFact; static DWORD g_dwSampleLength; static DWORD g_dwCkSizeData; static void *g_pvWaveformData = NULL; static short *g_psWaveformData = NULL; int main(int argc, char **argv) { if (argc != 3) { fprintf(stderr, "Usage: wfio file-in file-out\n"); return 1; } if (ReadWaveFile(argv[1]) != 0) { return 1; } if (Tune() != 0) { return 1; } WriteWaveFile(argv[2]); if (g_pwf != NULL) { free(g_pwf); } if (g_pvWaveformData != NULL) { free(g_pvWaveformData); } if (g_psWaveformData != NULL) { free(g_psWaveformData); } return 0; } int ReadWaveFile(const char *pcFile) { HMMIO hmmio; MMCKINFO ckParent; MMCKINFO ckSub; MMRESULT result; LONG lRead; LONG lOffset; // Open hmmio = mmioOpen((LPSTR)pcFile, NULL, MMIO_READ); if (hmmio == NULL) { fprintf(stderr, "mmioOpen\n"); return -1; } // RIFFチャンク ckParent.fccType = mmioFOURCC('W', 'A', 'V', 'E'); result = mmioDescend(hmmio, &ckParent, NULL, MMIO_FINDRIFF); if (result != MMSYSERR_NOERROR) { fprintf(stderr, "RIFF\n"); return -1; } // fmtチャンク ckSub.ckid = mmioFOURCC('f', 'm', 't', ' '); result = mmioDescend(hmmio, &ckSub, &ckParent, MMIO_FINDCHUNK); if (result != MMSYSERR_NOERROR) { fprintf(stderr, "fmt mmioDescend\n"); return -1; } g_dwCkSizeFmt = ckSub.cksize; g_pwf = malloc(ckSub.cksize); if (g_pwf == NULL) { fprintf(stderr, "fmt malloc\n"); return -1; } lRead = mmioRead(hmmio, (HPSTR)g_pwf, ckSub.cksize); if (lRead != (LONG)ckSub.cksize) { fprintf(stderr, "fmt mmioRead\n"); return -1; } mmioAscend(hmmio, &ckSub, 0); // factチャンク lOffset = mmioSeek(hmmio, 0, SEEK_CUR); ckSub.ckid = mmioFOURCC('f', 'a', 'c', 't'); result = mmioDescend(hmmio, &ckSub, &ckParent, MMIO_FINDCHUNK); if (result == MMSYSERR_NOERROR) { g_dwCkSizeFact = ckSub.cksize; lRead = mmioRead(hmmio, (HPSTR)&g_dwSampleLength, sizeof(DWORD)); if (lRead != (LONG)sizeof(DWORD)) { fprintf(stderr, "fact mmioRead\n"); return -1; } mmioAscend(hmmio, &ckSub, 0); } else { g_dwCkSizeFact = 0; mmioSeek(hmmio, lOffset, SEEK_SET); } // dataチャンク ckSub.ckid = mmioFOURCC('d', 'a', 't', 'a'); result = mmioDescend(hmmio, &ckSub, &ckParent, MMIO_FINDCHUNK); if (result != MMSYSERR_NOERROR) { fprintf(stderr, "data mmioDescend\n"); return -1; } g_dwCkSizeData = ckSub.cksize; g_pvWaveformData = malloc(ckSub.cksize); if (g_pvWaveformData == NULL) { fprintf(stderr, "data malloc\n"); return -1; } lRead = mmioRead(hmmio, g_pvWaveformData, ckSub.cksize); if (lRead != (LONG)ckSub.cksize) { fprintf(stderr, "data mmioRead\n"); return -1; } mmioAscend(hmmio, &ckSub, 0); // RIFFチャンク mmioAscend(hmmio, &ckParent, 0); // Close mmioClose(hmmio, 0); return 0; } int WriteWaveFile(const char *pcFile) { HMMIO hmmio; MMCKINFO ckParent; MMCKINFO ckSub; // Open hmmio = mmioOpen((LPSTR)pcFile, NULL, MMIO_WRITE | MMIO_CREATE); if (hmmio == NULL) { fprintf(stderr, "mmioOpen\n"); return -1; } // RIFFチャンク ckParent.cksize = 0; // ダミー ckParent.fccType = mmioFOURCC('W', 'A', 'V', 'E'); mmioCreateChunk(hmmio, &ckParent, MMIO_CREATERIFF); // fmtチャンク ckSub.ckid = mmioFOURCC('f', 'm', 't', ' '); ckSub.cksize = g_dwCkSizeFmt; mmioCreateChunk(hmmio, &ckSub, 0); mmioWrite(hmmio, (char *)g_pwf, g_dwCkSizeFmt); mmioAscend(hmmio, &ckSub, 0); // factチャンク if (0 < g_dwCkSizeFact) { ckSub.ckid = mmioFOURCC('f', 'a', 'c', 't'); ckSub.cksize = sizeof(DWORD); mmioCreateChunk(hmmio, &ckSub, 0); mmioWrite(hmmio, (char *)&g_dwSampleLength, sizeof(DWORD)); mmioAscend(hmmio, &ckSub, 0); } // dataチャンク ckSub.ckid = mmioFOURCC('d', 'a', 't', 'a'); ckSub.cksize = 0; // ダミー mmioCreateChunk(hmmio, &ckSub, 0); mmioWrite(hmmio, (char *)g_psWaveformData, g_dwCkSizeData); mmioAscend(hmmio, &ckSub, 0); // RIFFチャンク mmioAscend(hmmio, &ckParent, 0); // Close mmioFlush(hmmio, 0); mmioClose(hmmio, 0); return 0; } int Tune(void) { short *ps; long lData; int iMax; int i; printf("nChannels\t=%u\n", g_pwf->nChannels); printf("nSamplesPerSec\t=%u\n", g_pwf->nSamplesPerSec); printf("nAvgBytesPerSec\t=%u\n", g_pwf->nAvgBytesPerSec); printf("nBlockAlign\t=%u\n", g_pwf->nBlockAlign); printf("wBitsPerSample\t=%u\n", g_pwf->wBitsPerSample); g_dwCkSizeData /= 2; g_psWaveformData = malloc(g_dwCkSizeData); if (g_psWaveformData == NULL) { fprintf(stderr, "malloc g_psWaveformData\n"); return -1; } ps = g_pvWaveformData; iMax = g_dwCkSizeData / 2; for (i = 0; i < iMax; i++) { lData = (long)*ps - (long)*(ps+1); if (SHRT_MAX < lData) { lData = SHRT_MAX; } else if (lData < SHRT_MIN) { lData = SHRT_MIN; } g_psWaveformData[i] = lData; ps += 2; } g_pwf->nChannels = 1; g_pwf->nBlockAlign = 2; g_pwf->nAvgBytesPerSec = g_pwf->nSamplesPerSec * g_pwf->nBlockAlign; printf("Tune:\n"); printf("nChannels\t=%u\n", g_pwf->nChannels); printf("nAvgBytesPerSec\t=%u\n", g_pwf->nAvgBytesPerSec); printf("nBlockAlign\t=%u\n", g_pwf->nBlockAlign); return 0; }