есть у кого соображения как сделать чтоб с выделенными жирным и подчеркнутым строчками работал данный код...
Код:
unit Unit1;
interface
uses
Windows, Forms, MMSystem, Classes, Controls, StdCtrls;
type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
const
sps = 8000; // samples per second
freq1 = 1000; // signal frequency (Hz)
freq2 = 1000; // signal frequency (Hz)
freq3 = 1000; // signal frequency (Hz)
time1 = 1000; // time of signal (ms)
time2 = 1000; // time of signal (ms)
time3 = 1000; // time of signal (ms)
Volume1 = 32767;
Volume2 = 32767;
Volume3 = 32767;
type
int16 = smallint;
var
Form1: TForm1;
hdr: array[0..2] of WAVEHDR;
//second: array[0..2, 0..sps-1] of int16; // full second
second: array of array of int16; // full second
implementation
{$R *.dfm}
procedure prepareSine();
var
i, nSamples: Integer;
angle, delta: double;
begin
nSamples := sps * time1 div 1000; // signal length in samples
//
angle := 0;
delta := (freq1 / sps) * 2 * Pi; // how much in one sample
//
for i := 0 to nSamples - 1 do begin
//
second[0, i] := random(Volume1*2-Volume1);//round(sin(angle) * Volume1);
angle := angle + delta;
end;
nSamples := sps * time2 div 1000; // signal length in samples
//
angle := 0;
delta := (freq2 / sps) * 2 * Pi; // how much in one sample
//
for i := 0 to nSamples - 1 do begin
//
second[1, i] := round(sin(angle) * Volume2);
angle := angle + delta;
end;
nSamples := sps * time3 div 1000; // signal length in samples
//
angle := 0;
delta := (freq3 / sps) * 2 * Pi; // how much in one sample
//
for i := 0 to nSamples - 1 do begin
//
second[2, i] := round(sin(angle) * Volume3);
angle := angle + delta;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
i: integer;
wout: hWaveOut;
fmt: tWAVEFORMATEX;
begin
SetLength(second, 3, sps);
prepareSine();
//
With fmt do
Begin
wFormatTag := WAVE_FORMAT_PCM;
nChannels := 1;
nSamplesPerSec := SPS;
wBitsPerSample := 16;
nBlockAlign := nChannels*wBitsPerSample div 8;
nAvgBytesPerSec := nSamplesPerSec*nBlockAlign;
cbSize := 0;
End;
//
WaveOutOpen(@wout, cardinal(-1), @fmt, 0, 0, 0);
if (0 <> wout) then
begin
//
for i := 0 to 2 do
begin
//
fillChar(hdr[i], sizeof(hdr[i]), #0);
hdr[i].lpData := @second[i];
hdr[i].dwBufferLength := sizeof(second[i]);
//
waveOutPrepareHeader(wout, @hdr[i], sizeof(hdr[i]));
WaveOutWrite(wout, @hdr[i], sizeof(hdr[i]));
end;
//
//Sleep(3100); // sleep for 3 seconds
//
waveOutUnprepareHeader(wout, @hdr, sizeof(TWAVEHDR));
WaveOutClose(wout);
end;
end;
end.Решение:
Указателем на элемент динамического массива должен быть первый элемент и функция SizeOf не применима к вложенным в массив последовательностям. Ее надо тоже заменить. Например, как ниже показано.
Код:
var
hdr: WAVEHDR;
procedure TForm1.Button1Click(Sender: TObject);
var
I, J: integer;
wout: hWaveOut;
fmt: tWAVEFORMATEX;
begin
SetLength(second, 3, sps);
prepareSine();
with fmt do Begin
wFormatTag := WAVE_FORMAT_PCM;
nChannels := 1;
nSamplesPerSec := SPS;
wBitsPerSample := 16;
nBlockAlign := nChannels*wBitsPerSample div 8;
nAvgBytesPerSec := nSamplesPerSec*nBlockAlign;
cbSize := 0;
end;
WaveOutOpen(@wout, cardinal(-1), @fmt, 0, 0, 0);
if (0 <> wout) then begin
for I := 0 to 2 do begin
hdr.lpData := @second[i][0];
hdr.dwBufferLength := sps;
waveOutPrepareHeader(wout, @hdr, sizeof(hdr));
WaveOutWrite(wout, @hdr, sizeof(hdr));
Sleep(2100);
end;
waveOutUnprepareHeader(wout, @hdr, sizeof(TWAVEHDR));
VirtualFree(@second,0,MEM_RELEASE);
WaveOutClose(wout);
end;
second := nil;
end;Так работает.