我如何产生不同频率的连续音调



我想生成并播放具有随时间变化的特定频率和振幅的连续声音。我不想声音之间有延迟。我如何用Delphi或c++ Builder做到这一点?

这个非常简单的例子应该可以让你开始。

program Project1;
{$APPTYPE CONSOLE}
uses
  SysUtils, Windows, MMSystem;
type
  TWaveformSample = integer; // signed 32-bit; -2147483648..2147483647
  TWaveformSamples = packed array of TWaveformSample; // one channel
var
  Samples: TWaveformSamples;
  fmt: TWaveFormatEx;
procedure InitAudioSys;
begin
  with fmt do
  begin
    wFormatTag := WAVE_FORMAT_PCM;
    nChannels := 1;
    nSamplesPerSec := 44100;
    wBitsPerSample := 32;
    nAvgBytesPerSec := nChannels * nSamplesPerSec * wBitsPerSample div 8;
    nBlockAlign := nChannels * wBitsPerSample div 8;
    cbSize := 0;
  end;
end;
                                          // Hz                     // msec
procedure CreatePureSineTone(const AFreq: integer; const ADuration: integer;
  const AVolume: double { in [0, 1] });
var
  i: Integer;
  omega,
  dt, t: double;
  vol: double;
begin
  omega := 2*Pi*AFreq;
  dt := 1/fmt.nSamplesPerSec;
  t := 0;
  vol := MaxInt * AVolume;
  SetLength(Samples, Round((ADuration / 1000) * fmt.nSamplesPerSec));
  for i := 0 to high(Samples) do
  begin
    Samples[i] := round(vol*sin(omega*t));
    t := t + dt;
  end;
end;
procedure PlaySound;
var
  wo: integer;
  hdr: TWaveHdr;
begin
  if Length(samples) = 0 then
  begin
    Writeln('Error: No audio has been created yet.');
    Exit;
  end;
  if waveOutOpen(@wo, WAVE_MAPPER, @fmt, 0, 0, CALLBACK_NULL) = MMSYSERR_NOERROR then
    try
      ZeroMemory(@hdr, sizeof(hdr));
      with hdr do
      begin
        lpData := @samples[0];
        dwBufferLength := fmt.nChannels * Length(Samples) * sizeof(TWaveformSample);
        dwFlags := 0;
      end;
      waveOutPrepareHeader(wo, @hdr, sizeof(hdr));
      waveOutWrite(wo, @hdr, sizeof(hdr));
      sleep(500);
      while waveOutUnprepareHeader(wo, @hdr, sizeof(hdr)) = WAVERR_STILLPLAYING do
        sleep(100);
    finally
      waveOutClose(wo);
    end;

end;

begin
  try
    InitAudioSys;
    CreatePureSineTone(400, 1000, 0.7);
    PlaySound;
  except
    on E: Exception do
    begin
      Writeln(E.Classname, ': ', E.Message);
      Readln;
    end;
  end;
end.

特别注意你得到的简洁界面:

    InitAudioSys;
    CreatePureSineTone(400, 1000, 0.7);
    PlaySound;

使用WaveAudio库可以生成连续的鼻窦波

我本来要发布一些代码,但是我不知道怎么做才好,所以我就不发了。

但是你所需要做的就是使用TLiveAudioPlayer,然后重写OnData事件。

如果没有消息泵,也将Async设置为true。

  • 更新于2021年12月,我只是偶然发现了我的答案…所以我想更新它,我在2009年使用了这个ASIO库,我想后来,下面的库很棒:*

我推荐Delphi的ASIO库!

https://sourceforge.net/projects/delphiasiovst/

使用这个非常简单,不是所有的文件都必须包含在内,从主文件开始,然后从那里添加其余的文件,也可以参见示例。

最终它就像OnSomeEvent/OnSomeBuffer一样简单

,然后简单地用浮点值填充数组。

不记得OnEvent的确切名称,但你会在例子中很容易找到它。

另一件要做的事情是将某些组件设置为active/true,然后瞧。

ASIO的优点是延迟非常低,甚至可以将延迟降低到50微秒甚至更低。

声音芯片需要ASIO驱动

ASIO =音频流输入输出

音频工程师设计的API

可能没有比这更好的了!div;)

最新更新