есть у кого соображения как сделать чтоб с выделенными жирным и подчеркнутым строчками работал данный код...
Код:
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;
Так работает.