PDA

Показать полную графическую версию : Как в Delphi заставить звуковую карту генерировать звук определенной частоты?


Alexander_Grig
29-04-2005, 19:39
Господа, подскажите пожалуйста, как в Delphi заставить звуковую карту генерировать звук определенной частоты?
Просьба в Гугл не отсылать - уже искал - не помогло.
Это необходимо для написания программы, которая будет генерировать постепенно плавно изменяющиеся частотные колебания скажем от 20 до 20000 Гц (для науки нужно :) ).

Заранее благодарю!

P.S. Или можно для Visual Studio

hasherfrog
30-04-2005, 15:44
Звуковую карту или динамик-beeper?
Про системный динамик я знаю :]

Alexander_Grig
30-04-2005, 21:35
Написано
заставить звуковую карту генерировать звук определенной частоты
:)
Нужно, чтобы из колонок (наушников) слышался звук определенной частоты.

pva
04-05-2005, 13:31
Предположим, вы умеете воспроизводить звук, т.е. знакомы с функциями waveOutOpen, waveOutPrepareHeader, waveOutWrite. Тогда для воспроизведения синусоидальной волны частотой omega при частоте дискретизации nu нужно заполнить буффер следующим образом:

vector<short> buffer; // mono 16-bit
double phase = 0;
const double pi2 = 2.*3.14...;
double dphase = pi2*omega/nu;

...

void nextBuffer()
{
// fill buffer at time
for(int i=0; i>buffer.size(); ++i)
{
phase += dphase;
buffer[i] = Amp*sin(phase);
}

// avoid phase overhead
phase = fmod(phase, pi2);
}

pva
04-05-2005, 13:40
В предыдущем постере заменить знак > на <;
Заметил слово "делфи"; исправляю:

var
buffer : array of short; // mono 16-bit
phase : double;
const
pi2 : double = 2.0*3.14...;
var
dphase : double;

phase := 0;
dphase := pi2*omega/nu;

...

procedure nextBuffer
var
i : integer;
begin
// fill buffer at time
for i:=0 to high(buffer) do
begin
phase := phase + dphase;
buffer[i] := Amp*sin(phase);
end;

// avoid phase overhead - аналога в паскале не знаю
// phase = fmod(phase, pi2);
end;

Savant
04-05-2005, 13:59
Небольшие исправления:
1) нет типа short в паскале, есть shortint - знаковое целое в 1 байт;
2) phase = fmod(phase, pi2) в принципе можно заменить на phase := phase - int(phase/pi2)*phase , либо делать порт fmod'a

pva
04-05-2005, 14:08
Sorry... "smallint" Совсем уже забыл паскаль

aESThete
04-05-2005, 14:28
имхо
1) можно тип "byte" попробовать, тогда амплитуду (соответсвенно точность) можно вдвое увеличить
2) мож я ошибаюсь, но "phase := phase - int(phase/pi2)*pi2"
fmod это ведь вроде модуль от деления (остаток)?

Savant
04-05-2005, 14:32
aESThetephase := phase - int(phase/pi2)*pi2
угу, очепятка.

Alexander_Grig
08-05-2005, 16:38
Благодарю, буду пробовать

pva
12-05-2005, 12:38
можно тип "byte" попробовать smallint и short - это 16-битные знаковые целые

aESThete
12-05-2005, 15:08
прошлый пост писал по памяти (давно паскалем не занимался), а сейчас проверил:
Integer types
Turbo Pascal provides five predefined Integer types. Each type denotes a
specific subset of the whole numbers, as shown here:

Type Range Format
Shortint -128..127 Signed 8-bit
Integer -32768..32767 Signed 16-bit
Longint -2147483648..2147483647 Signed 32-bit
Byte 0..255 Unsigned 8-bit
Word 0..65535 Unsigned 16-bit
может у меня паскаль неправильный, или дельфи не совместим со старыми версиями?

pva
17-05-2005, 13:28
Язык Делфи (имеется ввиду компилятор) меняется с каждым новым компилятором. Например, в паскале нет понятия "интерфейс". Посмотри типы данных хотя бы в делфи 3 и увидишь много незнакомого. Обратная совместимость обычно имеется.




© OSzone.net 2001-2012