Есть ли формула пересчёта высоты тона из команды 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 она ничего не делает.

