Есть ли формула пересчёта высоты тона из команды BEEP в частоту в герцах? Хочу воспроизводить вот этой процедурой:
Кто может сказать: правильной ли частоты звуки генерирует эта процедура? Мне кажется, она фальшивит. Как точно это проверить в домашних условиях?Код:#include <windows.h> // описание заголовка файла WAV struct WAVHEADER { char sigRIFF[4]; // должно быть равно "RIFF" DWORD sizeRIFFch; // размер чанка RIFF char sigWAVE[4]; // должно быть равно "WAVE" char sigFMT[4]; // должно быть равно "fmt " DWORD sizeFMTch; // размер чанка FMT WORD wFormatTag; // категория формата, для PCM = 1 WORD wChannels; // кол-во каналов: 1-моно 2-стерео DWORD dwSamplesPerSec;// кол-во сэмплов в сек. DWORD dwAvgBytesPerSec;// среднее число байт в сек WORD wBlockAlign; // выравнивание данных в дата-чанке WORD wBitPerSample; // бит в сэмпле char sigDATA[4]; // должно быть равно "data" DWORD sizeDATAch; // размер data-чанка }; void Beep(DWORD dwFrequency, DWORD dwMilliSeconds) { // частота дискретизации = 44100 Гц // кол-во бит на сэмпл = 8 // если требуемая частота > 44100 или равна нулю, то выходим if(!dwFrequency || dwFrequency>44100) return; // длина дорожки в байтах DWORD numSamples = 44100 / dwFrequency; // выделяем память под дорожку DWORD size = sizeof(WAVHEADER) + numSamples; void *buff = new char[size]; if(buff) { // заполняем WAV-header WAVHEADER *head = (WAVHEADER*)buff; strcpy(head->sigRIFF, "RIFF"); strcpy(head->sigWAVE, "WAVE"); head->sizeRIFFch = size - 8; strcpy(head->sigFMT, "fmt "); head->sizeFMTch = 16; head->wFormatTag = 1; head->wChannels = 1; // моно head->dwSamplesPerSec = 44100; head->dwAvgBytesPerSec = 44100; head->wBlockAlign = 1; head->wBitPerSample = 8; strcpy(head->sigDATA, "data"); head->sizeDATAch = size; // заполняем дорожку периодом синуса BYTE *samples = (BYTE*)(head+1); for(DWORD i=0; i<numSamples; i++) samples[i] = BYTE(255*sin(6.28*double(i)/double(numSamples))); // проигрываем звук PlaySound((LPCWSTR)buff, 0, SND_ASYNC|SND_LOOP|SND_MEMORY); // ждём заданное количество миллисекунд Sleep(dwMilliSeconds); // останавливаем звук PlaySound(0, 0, SND_ASYNC); delete buff; } }
P.S. Beep из WinAPI не годится - её поддержка есть не на всех версиях винды: в старых виндах она воспроизводит на бипер, в новых на звуковуху, на 64-битной висте/XP она ничего не делает.




Ответить с цитированием