Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Программирование и базы данных (http://forum.oszone.net/forumdisplay.php?f=21)
-   -   Как в Delphi заставить звуковую карту генерировать звук определенной частоты? (http://forum.oszone.net/showthread.php?t=48754)

Alexander_Grig 29-04-2005 19:39 320408

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

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

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

hasherfrog 30-04-2005 15:44 320648

Звуковую карту или динамик-beeper?
Про системный динамик я знаю :]

Alexander_Grig 30-04-2005 21:35 320704

Написано
Цитата:

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

pva 04-05-2005 13:31 321552

Предположим, вы умеете воспроизводить звук, т.е. знакомы с функциями 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 321555

В предыдущем постере заменить знак > на <;
Заметил слово "делфи"; исправляю:

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 321567

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

pva 04-05-2005 14:08 321573

Sorry... "smallint" Совсем уже забыл паскаль

aESThete 04-05-2005 14:28 321578

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

Savant 04-05-2005 14:32 321585

aESThete
Цитата:

phase := phase - int(phase/pi2)*pi2
угу, очепятка.

Alexander_Grig 08-05-2005 16:38 322663

Благодарю, буду пробовать

pva 12-05-2005 12:38 323502

Цитата:

можно тип "byte" попробовать
smallint и short - это 16-битные знаковые целые

aESThete 12-05-2005 15:08 323531

прошлый пост писал по памяти (давно паскалем не занимался), а сейчас проверил:
Цитата:

Цитата Turbo Pascal 7.0 Help
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 324915

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


Время: 18:30.

Время: 18:30.
© OSzone.net 2001-