/* f31.c */ #include #include #include #include /* ---- PC audio parameters ---- */ #define R_SMPL 44100 /* sampling rate */ #define NBYTE 2 /* 16bit */ // #define BUFLEN (NBYTE * R_SMPL) /* 1sps */ #define BUFLEN (NBYTE * R_SMPL / 10) /* 10sps */ /* ---- FFT related parameters ---- */ #define MAX_NPT 16384 #define NMAX (2 * MAX_NPT) #define NMAXSQRT 256 /* 128? */ extern double a[NMAX + 1]; extern double b[NMAX + 1]; extern double w[NMAX * 5 / 4]; extern int ip[NMAXSQRT + 2]; /* ---- graphic display parameters ---- */ extern int gp_valid; extern int gp_npt; /* gp_npt <= MAX_NPT */ extern RECT gp; /* ---- fft?g functions -------- */ void cdft(int, int, double *, int *, double *); void rdft(int, int, double *, int *, double *); void ddct(int, int, double *, int *, double *); void ddst(int, int, double *, int *, double *); void dfct(int, double *, double *, int *, double *); void dfst(int, double *, double *, int *, double *); /* ---- f3.c functions ---- */ double itp_val(double*); void send_hLb(char*); void send_logf(char*); int printf_hLb(const char*, ...); /* ---- prototypes ---- */ int aio_create(HWND); void aio_destroy(); int aio_istart(HWND); int aio_ostart(HWND); int aio_istop(); int aio_ostop(); int aio_WIM_OPEN(); int aio_WIM_DATA(HWND, LPARAM); int aio_WIM_CLOSE(); int aio_WOM_OPEN(); int aio_WOM_DONE(HWND, LPARAM); int aio_WOM_CLOSE(); /* ---- local static variables ---- */ static WAVEFORMATEX wfe; static HWAVEOUT hWaveOut; static HWAVEIN hWaveIn; static short int *bWave[3]; /* バッファーを 3 つ使います */ static WAVEHDR whdr[3]; static BOOL blReset = FALSE; static int iOStop = 0; static const int n_whdr = sizeof(whdr)/sizeof(whdr[0]); /* ---- ここで入力データを処理します ---- */ static int prc_data(WAVEHDR* p) { int i; int ofst = 0, ums = 0; /* オーバーフローに注意 */ short int *sp, *sp0 = (short int*) p->lpData; sp0 = sp0 + (4410 - 4096); /* 前のほうの余分なデータは捨てます */ sp = sp0; for (i = 0; i < gp_npt; i += 1) { short int tmp = *sp++; ofst += tmp; ums += (tmp >= 0) ? tmp : -tmp; } ofst /= gp_npt; ums /= gp_npt; double scl = 0.0038; /* 振幅係数は当面固定にしてあります */ sp = sp0; double* dp = a; for (i = 0; i < gp_npt; i += 1) { *dp++ = scl * (*sp++ - ofst); *dp++ = 0; } // printf_hLb("ums %d, ofst %d, scl %g", ums, ofst, scl); memcpy(b, a, 2 * sizeof(double) * gp_npt); cdft(2 * gp_npt, 1, b, ip, w); double f = itp_val(b); /* ここで結果が得られます */ printf_hLb(" %5.2f (%5.1f)", f, 44100 * f / gp_npt); return 0; } /* ---- make test data for output ---- */ static void set_wo_data(int ix) { } /* -------- aio_ functions -------- */ int aio_create(HWND hWnd) { wfe.wFormatTag = WAVE_FORMAT_PCM; wfe.nChannels = 1; wfe.nSamplesPerSec = R_SMPL; wfe.nAvgBytesPerSec = NBYTE * R_SMPL; wfe.wBitsPerSample = NBYTE * 8; wfe.nBlockAlign = wfe.nChannels * wfe.wBitsPerSample / 8; wfe.cbSize = 0; int i; for (i = 0; i < n_whdr; i += 1) { bWave[i] = malloc(BUFLEN); if (!bWave[i]) return -1; } return 0; } void aio_destroy() { int i; for (i = 0; i < n_whdr; i += 1) free(bWave[i]); } int aio_istart(HWND hWnd) { int i; for (i = 0; i < n_whdr; i += 1) { whdr[i].lpData = (BYTE*)bWave[i]; whdr[i].dwBufferLength = BUFLEN; whdr[i].dwBytesRecorded = 0; whdr[i].dwFlags = 0; whdr[i].dwLoops = 1; whdr[i].lpNext = NULL; whdr[i].dwUser = 0; whdr[i].reserved = 0; } MMRESULT r = waveInOpen(&hWaveIn, WAVE_MAPPER, &wfe, (DWORD)hWnd, 0, CALLBACK_WINDOW); if (r) return (int) r; for (i = 0; i < n_whdr; i += 1) { r = waveInPrepareHeader(hWaveIn, &whdr[i], sizeof(WAVEHDR)); if (r) return (int) r; } return 0; } int aio_ostart(HWND hWnd) { int i; for (i = 0; i < n_whdr; i += 1) { whdr[i].lpData = (BYTE*)bWave[i]; whdr[i].dwBufferLength = BUFLEN; whdr[i].dwBytesRecorded = 0; whdr[i].dwFlags = 0; whdr[i].dwLoops = 1; whdr[i].lpNext = NULL; whdr[i].dwUser = 0; whdr[i].reserved = 0; set_wo_data(i); } MMRESULT r = waveOutOpen(&hWaveOut, WAVE_MAPPER, &wfe, (DWORD)hWnd, 0, CALLBACK_WINDOW); if (r) return (int) r; for (i = 0; i < n_whdr; i += 1) { r = waveOutPrepareHeader(hWaveOut, &whdr[i], sizeof(WAVEHDR)); if (r) return (int) r; } for (i = 0; i < n_whdr; i += 1) { r = waveOutWrite(hWaveOut, &whdr[i], sizeof(WAVEHDR)); if (r) return (int) r; } return 0; } int aio_istop() { blReset = TRUE; return (int) waveInReset(hWaveIn); } int aio_ostop() { iOStop = 1; return (int) waveOutReset(hWaveOut); } int aio_WIM_OPEN() { MMRESULT r; int i; send_hLb("IM_OPEN"); for (i = 0; i < n_whdr; i += 1) { r = waveInAddBuffer(hWaveIn, &whdr[i], sizeof(WAVEHDR)); if (r) return (int) r; } return (int) waveInStart(hWaveIn); } int aio_WIM_DATA(HWND hWnd, LPARAM lParam) { // clock_t t0 = clock(); if (blReset) { waveInClose(hWaveIn); blReset = FALSE; return 0; } WAVEHDR* p = (WAVEHDR*) lParam; // printf_hLb("IM_DATA %d (0x%x)", (int)p->dwBytesRecorded, (unsigned) p); int i; for (i = 0; i < 1; i += 1) /* 所要時間測定用のループ (無使用) */ prc_data(p); MMRESULT r = waveInAddBuffer(hWaveIn, p, sizeof(WAVEHDR)); InvalidateRect(hWnd, &gp, TRUE); // printf_hLb(" %dms", clock() - t0); return (int) r; } int aio_WIM_CLOSE() { int i; MMRESULT r; send_hLb("IM_CLOSE"); for (i = 0; i < n_whdr; i += 1) { r = waveInUnprepareHeader(hWaveIn, &whdr[i], sizeof(WAVEHDR)); if (r) return (int) r; } return 0; } int aio_WOM_OPEN() { send_hLb("OM_OPEN"); return 0; } int aio_WOM_DONE(HWND hWnd, LPARAM lParam) { if (iOStop == 1) { send_hLb("OM_DONE (iOStop 1)"); waveOutClose(hWaveOut); iOStop = 2; return 0; } else if (iOStop) { printf_hLb("OM_DONE (iOStop %d)", iOStop); return 0; } WAVEHDR* p = (WAVEHDR*) lParam; printf_hLb("OM_DONE %d (0x%x)", (int)p->dwBufferLength, (unsigned) p); return (int) waveOutWrite(hWaveOut, p, sizeof(WAVEHDR)); } int aio_WOM_CLOSE() { int i; MMRESULT r; send_hLb("OM_CLOSE"); iOStop = 0; for (i = 0; i < n_whdr; i += 1) { r = waveOutUnprepareHeader(hWaveOut, &whdr[i], sizeof(WAVEHDR)); if (r) return (int) r; } return 0; }