delphi - 如何生成不同频率的连续音调?

标签 delphi winapi audio c++builder

我想生成并播放具有随时间变化的特定频率和幅度的连续声音。我不想声音之间有延迟。我如何使用 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;

关于delphi - 如何生成不同频率的连续音调?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7742377/

相关文章:

delphi - StrToFloat 无法报告 Delphi 64 位中的无效 float

c++ - 如何解决有关使用 FARPROC 调用 GetProcAddress 的 C4191 警告?

ios - 获取XCODE以将运行脚本转换后的文件复制到iOS资源包中?

windows-phone-7 - 播放WP7中的声音循环

delphi - Dwscript 网络服务器

delphi - Lazarus 中的内存泄漏,如何使用 Heaptrcon 调试它们?

delphi - 如何在 ProfileResourceReceived 事件中从 ARemoteResource 获取 TTetheringProfileInfo?

c - 打印时如何取消/重置 StartPage/EndPage 之间的页面?

Cmd提示windows编译

python - 我怎样才能在 python 中发出声音?