WaveIO2
Visual C++ 2005 Express Edition
Windows Server 2003 SP1 Platform SDK
コンソール アプリケーション / 空のプロジェクト
サウンド処理のプログラミング
sample.c
#include "WaveIO.h" #include
#include
#include
#include
#include
#include
typedef unsigned char u_char; // プロトタイプ宣言 int Convert200(WaveIO *pwioDst, const WaveIO *pwioSrc); int Convert150(WaveIO *pwioDst, const WaveIO *pwioSrc); int main() { WaveIO wioSrc; WaveIO wioDst; DWORD dwAvgBytesPerSec; int iMSec; int iRet; int i; iRet = WioRead(&wioSrc, "sample.wav"); if (iRet) { fprintf(stderr, "WioRead\n"); return 1; } iRet = Convert200(&wioDst, &wioSrc); if (iRet) { fprintf(stderr, "Convert\n"); return 1; } iRet = WioPlay(&wioDst); if (iRet) { fprintf(stderr, "WioPlay\n"); return 1; } dwAvgBytesPerSec = (wioDst.wBitsPerSample / 8) * wioDst.wChannels * wioDst.dwSamplesPerSec; iMSec = (int)(1000.0 * wioDst.dwSampleLength / dwAvgBytesPerSec); for (i = 0; i < iMSec; i += 1000) { if (_kbhit()) { break; } Sleep(1000); } iRet = WioStop(&wioDst); if (iRet) { fprintf(stderr, "WioStop\n"); return 1; } iRet = WioWrite(&wioDst, "sample2.wav"); if (iRet) { fprintf(stderr, "WioWrite\n"); return 1; } free(wioSrc.psWaveformData); free(wioDst.psWaveformData); return 0; } int Convert200(WaveIO *pwioDst, const WaveIO *pwioSrc) { short *psDataSrc; // 変換元データ short *psDataDst; int iWavLenMin; // 最小波長 int iWavLenMax; // 最大波長 int iWavLen; // 波長 int iWavLenNum; // 波長数 int *piWavLen; // 波長配列 int iSrcLen; // 変換元データ長 int iDstMax; // 変換先データ長 int iOffsetSrc; int iOffsetDst; int iOffSrc0; int iOffSrc1; int iOffDst; int iIndex; int iLen; int i; double dTop; double dSum; // 変換元データ iSrcLen = pwioSrc->dwSampleLength / 2; psDataSrc = pwioSrc->psWaveformData; // 波長 iWavLenMin = pwioSrc->dwSamplesPerSec / 320; // 8KHzの場合320Hz->25 iWavLenMax = pwioSrc->dwSamplesPerSec / 80; // 8KHzの場合80Hz->100 if (iSrcLen < iWavLenMax * 2) { return -1; } iWavLenNum = 1 + (iSrcLen - iWavLenMax * 2) / iWavLenMin; piWavLen = malloc(iWavLenNum * sizeof(int)); if (piWavLen == NULL) { return -2; } // 変換先データ iDstMax = iSrcLen * 2; psDataDst = malloc(iDstMax * sizeof(short)); if (psDataDst == NULL) { return -3; } // 自己相関により波長を求める iWavLenNum = 0; iOffsetSrc = 0; while (iOffsetSrc + iWavLenMax * 2 <= iSrcLen) { iWavLen = 0; for (iLen = iWavLenMin; iLen <= iWavLenMax; iLen++) { dSum = 0.0; for (i = 0; i < iLen; i++) { dSum += psDataSrc[iOffsetSrc + i] * psDataSrc[iOffsetSrc + iLen + i]; } dSum /= iLen; if (iWavLen == 0 || dTop < dSum) { iWavLen = iLen; dTop = dSum; } } printf("%.3lf %d %d %.1lf\n", (double)iOffsetSrc / pwioSrc->dwSamplesPerSec, iOffsetSrc, iWavLen, dTop); piWavLen[iWavLenNum++] = iWavLen; iOffsetSrc += iWavLen * 2; } // 波形データの合成 iOffsetSrc = 0; iOffsetDst = 0; for (iIndex = 0; iIndex < iWavLenNum; iIndex++) { iWavLen = piWavLen[iIndex]; iOffSrc0 = iOffsetSrc; iOffSrc1 = iOffsetSrc + iWavLen; // 区間(−1)←波形データ(0)前 if (0 < iIndex) { iOffDst = iOffsetDst - piWavLen[iIndex - 1]; iLen = (piWavLen[iIndex - 1] < iWavLen) ? piWavLen[iIndex - 1] : iWavLen; for (i = 0; i < iLen; i++) { psDataDst[iOffDst + i] += psDataSrc[iOffSrc0 + i] * (iLen - i) / (iLen + 1); } } // 区間(0)←波形データ(0) iOffDst = iOffsetDst; memcpy(psDataDst + iOffDst, psDataSrc + iOffSrc0, iWavLen * sizeof(short)); // 区間(1)←波形データ(0)後+波形データ(1)前 iOffDst = iOffsetDst + iWavLen; for (i = 0; i < iWavLen; i++) { psDataDst[iOffDst + i] = psDataSrc[iOffSrc0 + i] * (i + 1) / (iWavLen + 1) + psDataSrc[iOffSrc1 + i] * (iWavLen - i) / (iWavLen + 1); } // 区間(2)←波形データ(1) iOffDst = iOffsetDst + iWavLen * 2; memcpy(psDataDst + iOffDst, psDataSrc + iOffSrc1, iWavLen * sizeof(short)); // 区間(3)←波形データ(1)後 if (iIndex < iWavLenNum - 1) { iOffDst = iOffsetDst + iWavLen * 3; for (i = 0; i < iWavLen; i++) { psDataDst[iOffDst + i] = psDataSrc[iOffSrc1 + i] * (i + 1) / (iWavLen + 1); } } // オフセット加算 iOffsetSrc += iWavLen * 2; iOffsetDst += iWavLen * 4; } free(piWavLen); pwioDst->wBitsPerSample = pwioSrc->wBitsPerSample; pwioDst->wChannels = pwioSrc->wChannels; pwioDst->dwSamplesPerSec = pwioSrc->dwSamplesPerSec * 2; pwioDst->dwSampleLength = (iOffsetDst - iWavLen) * sizeof(short); pwioDst->psWaveformData = psDataDst; return 0; } int Convert150(WaveIO *pwioDst, const WaveIO *pwioSrc) { short *psDataSrc; short *psDataDst; int iWavLenMin; // 最小波長 int iWavLenMax; // 最大波長 int iWavLen; // 波長 int iOffsetSrc; int iOffsetDst; int iData; int iLen; int i; double dSum; double dTop; pwioDst->wBitsPerSample = pwioSrc->wBitsPerSample; pwioDst->wChannels = pwioSrc->wChannels; pwioDst->dwSamplesPerSec = pwioSrc->dwSamplesPerSec * 3 / 2; psDataDst = malloc(pwioSrc->dwSampleLength * 3 / 2); if (psDataDst == NULL) { return -1; } psDataSrc = pwioSrc->psWaveformData; iWavLenMin = pwioSrc->dwSamplesPerSec / 320; // 8KHzの場合320Hz->25 iWavLenMax = pwioSrc->dwSamplesPerSec / 80; // 8KHzの場合80Hz->100 iOffsetSrc = 0; iOffsetDst = 0; while (iOffsetSrc + iWavLenMax * 2 < (int)pwioSrc->dwSampleLength / 2) { // 自己相関により波長を求める iWavLen = 0; for (iLen = iWavLenMin; iLen <= iWavLenMax; iLen++) { dSum = 0.0; for (i = 0; i < iLen; i++) { dSum += psDataSrc[iOffsetSrc + i] * psDataSrc[iOffsetSrc + iLen + i]; } dSum /= iLen; if (iWavLen == 0 || dTop < dSum) { iWavLen = iLen; dTop = dSum; } } printf("%.3lf %d %d %.1lf\n", (double)iOffsetSrc / pwioSrc->dwSamplesPerSec, iOffsetSrc, iWavLen, dTop); // 波形データの合成 memcpy(psDataDst + iOffsetDst, psDataSrc + iOffsetSrc, iWavLen * 2); for (i = 0; i < iWavLen; i++) { iData = psDataSrc[iOffsetSrc + i] * (i + 1) + psDataSrc[iOffsetSrc + iWavLen + i] * (iWavLen - i); psDataDst[iOffsetDst + iWavLen + i] = iData / (iWavLen + 1); } memcpy(psDataDst + iOffsetDst + iWavLen * 2, psDataSrc + iOffsetSrc + iWavLen, iWavLen * 2); // オフセット加算 iOffsetSrc += iWavLen * 2; iOffsetDst += iWavLen * 3; } pwioDst->dwSampleLength = iOffsetDst * 2; pwioDst->psWaveformData = psDataDst; return 0; }