2011-10-12 30 views
9

我想要生成並播放具有隨時間變化的特定頻率和幅度的連續聲音。我不想在聲音之間產生延遲。我如何用Delphi或C++ Builder來做到這一點?如何生成不同頻率的連續音調?

+0

請參閱[waveOutXXX函數族](http://msdn.microsoft.com/en-us/library/windows/desktop/dd757715(v = vs.85).aspx) –

+1

由於您沒有接受我的答案,我認爲它沒有幫助你。也許你可以解釋爲什麼它沒有幫助你? –

回答

1

通過使用WaveAudio庫有可能產生一個連續餘弦波。

我要發佈一些代碼,但我不知道如何正確做到這一點,所以我不會。

但是,您只需使用TLiveAudioPlayer,然後重寫OnData事件。

並且如果沒有消息泵,也將異步設置爲真。

17

這個非常簡單的例子應該讓你開始。特別是整齊的接口

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;