podwójne buforowanie i dane i widmo

0

Witam!! Mam problem, mianowicie musze użyć podwójnego buforowania w celu dostarczenia danych do fukcji obliczającej widmo sygnału, z którego pochodzą dane. Funkcją obliczającą jest DFT (dyskretna transformata Fouriera). Proszę o jakiś fragment kodu (C++, Delphi), bo nie za bardzo wiem jak sie za to buforowanie zabrać. Pozdrawiam!!

0

A w czym problem ? :-)
Czy chodzi o STFFT?

0

O STFT raczej, ale bardziej interesuje mnie zadanie wypełnienia podwójnego buforu, nastepnie przesłania cześci danych z niego do funkcji obliczającej i tak na zmiane.

0
krwawy_zniwiarz napisał(a)

...j i tak na zmiane.
na zmianę z czym?
<font size="2">FIFO?</span>

0

mianowicie musze użyć podwójnego buforowania w celu dostarczenia danych do fukcji obliczającej widmo sygnału,

Pytanie zbyt ogólne żeby na nie sensownie odpowiedzieć. Czym jest źródło danych? Chodzi o wielowątkowość...?

Jednym słowem - szczegóły.

0

Jeśli chodzi o ta zmianę to bufor ma się zapełnic do połowy (50%) i ta zapełniona część ma zostać przesłana do funkcji obliczającej, a ta druga połówka w tym samym czasie ma sie zapełniać. Po czym ta druga połówka jest obliczana, a druga zapełniana. Źródłem danych jest karta, tutaj link: http://www.elmark.com.pl/index.php?id=17&idw=133

0

A jak gadasz z kartą? Poprzez porty czy jakiś driver? Odbierasz po próbce czy blokami? Czy w czasie gromadzenia ewentualnego bloku twój program działa czy też czeka na zakończenie? Czy...

Więc jak?

0

Poprzez port PCI i próbkami. Mam też jakiś testowy programik, ale za bardzo nie obczajam jego kodu.
Zapomniałem dodać, ze dopiero zaczynam tworzyć ten programik, a jeżeli chodzi o odbieranie danych to próbki będą bardziej odpowiednie niż bloki (zbiór próbek) do wyświetlenia widma.

OTO TEN KOD:

unit AIUnit;

interface

uses
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
OleCtrls, StdCtrls, DAQAILib_TLB, Buttons, ExtCtrls, Variants;

type
TForm1 = class(TForm)
GroupBox1: TGroupBox;
Label1: TLabel;
Label2: TLabel;
cmdExit: TBitBtn;
GroupBox8: TGroupBox;
lstReading: TListBox;
cmdAcquireStart: TButton;
cmdAcquireStop: TButton;
cmdStatus: TButton;
txtStatus: TEdit;
txtDeviceNum: TEdit;
txtDeviceName: TEdit;
cmdSelectDevice: TButton;
GroupBox10: TGroupBox;
Label5: TLabel;
cmbStartChannel: TComboBox;
Label6: TLabel;
cmbNumChan: TComboBox;
Label3: TLabel;
cmbInputRange: TComboBox;
chkOverAllGain: TCheckBox;
cmdGainList: TButton;
Label4: TLabel;
cmbDataType: TComboBox;
Label12: TLabel;
cmbTransferMode: TComboBox;
Label13: TLabel;
cmbTrigSource: TComboBox;
Label14: TLabel;
cmbClockSource: TComboBox;
Label15: TLabel;
txtSampleRate: TEdit;
Label7: TLabel;
Label8: TLabel;
txtNumOfSample: TEdit;
GroupBox6: TGroupBox;
Label9: TLabel;
chkFIFOEnabled: TCheckBox;
txtFIFOSize: TEdit;
chkEventEnabled: TCheckBox;
chkCyclicMode: TCheckBox;
ScanTimer: TTimer;
cmdAutoGet: TButton;
cmdStopAutoGet: TButton;
GroupBox2: TGroupBox;
Label11: TLabel;
txtErrorCode: TEdit;
txtErrorMessage: TEdit;
Label10: TLabel;
DAQAI1: TDAQAI;
ErrorTimer: TTimer;
procedure chkFIFOEnabledClick(Sender: TObject);
procedure chkOverAllGainClick(Sender: TObject);
procedure cmbDataTypeClick(Sender: TObject);
procedure cmbTransferModeClick(Sender: TObject);
procedure cmdAcquireStartClick(Sender: TObject);
procedure cmdAcquireStopClick(Sender: TObject);
procedure cmdGainListClick(Sender: TObject);
procedure cmdSelectDeviceClick(Sender: TObject);
procedure cmdStatusClick(Sender: TObject);
procedure DAQAI1EventRaw(Sender: TObject; DataCount: Integer;
Data: OleVariant);
procedure DAQAI1EventReal(Sender: TObject; DataCount: Integer;
Data: OleVariant);
procedure DAQAI1Terminated(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure txtDeviceNumChange(Sender: TObject);
procedure txtNumOfSampleChange(Sender: TObject);
procedure txtSampleRateChange(Sender: TObject);
procedure ScanTimerTimer(Sender: TObject);
procedure chkCyclicModeClick(Sender: TObject);
procedure chkEventEnabledClick(Sender: TObject);
procedure cmdAutoGetClick(Sender: TObject);
procedure cmdStopAutoGetClick(Sender: TObject);
procedure cmbClockSourceChange(Sender: TObject);
procedure cmbTrigSourceChange(Sender: TObject);
procedure cmbStartChannelChange(Sender: TObject);
procedure cmbNumChanChange(Sender: TObject);
procedure ErrorTimerTimer(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;
bRet : Boolean;

implementation

uses GainUnit;

{$R *.DFM}

procedure TForm1.chkFIFOEnabledClick(Sender: TObject);
begin
if chkFIFOEnabled.State = cbChecked then
begin
txtFIFOSize.Enabled := True;
DAQAI1.FIFOEnabled := True;
txtFIFOSize.Text := IntToStr(DAQAI1.FIFOSize);
end
else
begin
txtFIFOSize.Enabled := False;
DAQAI1.FIFOEnabled := False;
txtFIFOSize.Text := '0';
end;
end;

procedure TForm1.chkOverAllGainClick(Sender: TObject);
begin
if chkOverAllGain.State = cbChecked then
begin
cmbInputRange.Enabled := True;
cmdGainList.Enabled := False;
DAQAI1.InputRangeMode := adOverallRange;
end
else
begin
cmbInputRange.Enabled := False;
cmdGainList.Enabled := True;
DAQAI1.InputRangeMode := adDifferentRange;
{Set gain code list}
end;
end;

procedure TForm1.cmbDataTypeClick(Sender: TObject);
begin
DAQAI1.DataType := cmbDataType.ItemIndex;
end;

procedure TForm1.cmbTransferModeClick(Sender: TObject);
begin
DAQAI1.TransferMode := cmbTransferMode.ItemIndex;
end;

procedure TForm1.cmdAcquireStartClick(Sender: TObject);
var
i : integer;
begin
lstReading.Clear;

if DAQAI1.OpenDevice then
begin
ShowMessage(DAQAI1.ErrorMessage);
Exit;
end;

if DAQAI1.InputRangeMode = adDifferentRange then
begin
gGainCodeList := VarArrayCreate([0, gNumOfChan -1], varSmallint);
for i := 0 to gNumOfChan -1 do
gGainCodeList[i] := gGainCodeSave[i];
DAQAI1.InputRangeList := gGainCodeList;
end
else
begin
DAQAI1.OverallInputRange := cmbInputRange.ItemIndex;
if DAQAI1.OverallInputRange < 0 then
DAQAI1.OverallInputRange := 0;
end;

{Start getting data}
bRet := DAQAI1.AcquireStart;
if bRet then
begin
ShowMessage(DAQAI1.ErrorMessage);
Exit;
end;

GroupBox10.Enabled := False;

cmdAcquireStart.Enabled := False;
cmdAcquireStop.Enabled := True;
cmdExit.Enabled := False;
cmdSelectDevice.Enabled := False;
cmdAutoGet.Enabled := True;
ErrorTimer.Enabled := True;
end;

procedure TForm1.cmdAcquireStopClick(Sender: TObject);
begin
GroupBox10.Enabled := True;
cmdAcquireStart.Enabled := True;
cmdAcquireStop.Enabled := False;
cmdExit.Enabled := True;
cmdSelectDevice.Enabled := True;
cmdAutoGet.Enabled := False;
ErrorTimer.Enabled := False;

{Stop get data}
bRet := DAQAI1.AcquireStop;
if bRet then
begin
ShowMessage(DAQAI1.ErrorMessage);
Exit;
end;

{Close device}
bRet := DAQAI1.CloseDevice;
if bRet then
begin
ShowMessage(DAQAI1.ErrorMessage);
Exit;
end;
end;

procedure TForm1.cmdGainListClick(Sender: TObject);
begin
frmGainList.Show;
end;

procedure TForm1.cmdSelectDeviceClick(Sender: TObject);
var
i : Integer;
j : Integer;
strGain : WideString;
begin
DAQAI1.SelectDevice;

txtDeviceNum.Text := IntToStr(DAQAI1.DeviceNumber);
txtDeviceName.Text := DAQAI1.DeviceName;

cmbInputRange.Clear;
cmbStartChannel.Clear;
cmbNumChan.Clear;

gNumOfInputRange := 0;
gNumOfChan := 0;

{Open device}
if DAQAI1.OpenDevice then
begin
ShowMessage(DAQAI1.ErrorMessage);
Exit;
end;

{Get input range list}
SetLength(strGain, 30);
bRet := DAQAI1.GetFirstInputRange(strGain);
i := 0;
while bRet = False do
begin
gInputRangeList[i] := strGain;
cmbInputRange.Items.Add(gInputRangeList[i]);
i := i + 1;
bRet := DAQAI1.GetNextInputRange(strGain);
end;

If i <> 0 then
begin
cmbInputRange.ItemIndex := 0;
gNumOfInputRange := i;
end;

{Get Max. channel number}
if DAQAI1.MaxDifferentialChannel > DAQAI1.MaxSingleEndedChannel then
i := DAQAI1.MaxDifferentialChannel
else
i := DAQAI1.MaxSingleEndedChannel;

if i = 0 then
begin
ShowMessage('Function Not Supported');
DAQAI1.CloseDevice;
Exit;
end;

gNumOfChan := i;

for j := 0 to i - 1 do
begin
cmbStartChannel.Items.Add (IntToStr(j));
cmbNumChan.Items.Add (IntToStr(j + 1));
gGainCodeSave[j] := 0;
end;
cmbStartChannel.ItemIndex := 0;
cmbNumChan.ItemIndex := 0;
DAQAI1.StartChannel := 0;
DAQAI1.NumberOfChannels := 1;
DAQAI1.CloseDevice;
end;

procedure TForm1.cmdStatusClick(Sender: TObject);
begin
txtStatus.Text := IntToStr(DAQAI1.AcquireStatus);
end;

procedure TForm1.DAQAI1EventRaw(Sender: TObject; DataCount: Integer;
Data: OleVariant);
var
i : LongInt;
j : LongInt;
begin
lstReading.Clear;

if DataCount > 10 then
j := 10
else
j := DataCount;

for i := 0 to j - 1 do {DataCount - 1}
lstReading.Items.Add (IntToStr(Data[i]));
end;

procedure TForm1.DAQAI1EventReal(Sender: TObject; DataCount: Integer;
Data: OleVariant);
var
i : LongInt;
j : LongInt;
begin
lstReading.Clear;

if DataCount > 10 then
j := 10
else
j := DataCount;

for i := 0 to j - 1 do {DataCount - 1}
lstReading.Items.Add (FormatFloat('0.000000', Data[i]));
end;

procedure TForm1.DAQAI1Terminated(Sender: TObject);
var
UserData : OleVariant;
i : Integer;
begin
ScanTimer.Enabled := False;
ErrorTimer.Enabled := False;
GroupBox10.Enabled := True;
cmdAcquireStart.Enabled := True;
cmdAcquireStop.Enabled := False;
cmdExit.Enabled := True;
cmdAutoGet.Enabled := False;
cmdStopAutoGet.Enabled := False;
cmdSelectDevice.Enabled := True;

lstReading.Clear;

if DAQAI1.DataType = adRaw then
begin
UserData := VarArrayCreate([0, 9], varSmallint);
DAQAI1.GetBufferData(0, 10, UserData);
for i := 0 to 9 do
lstReading.Items.Add (IntToStr(UserData[i]));
end
else
begin
UserData := VarArrayCreate([0, 9], varSingle);
DAQAI1.GetBufferData(0, 10, UserData);
for i := 0 to 9 do
lstReading.Items.Add (FormatFloat('0.000000', UserData[i]));
end;

{Stop get data}
DAQAI1.AcquireStop;
{Close device}
DAQAI1.CloseDevice;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
{Select default device}
cmdSelectDevice.Click();

{Setting initial value}
txtDeviceNum.Text := IntToStr(DAQAI1.DeviceNumber);
txtDeviceName.Text := DAQAI1.DeviceName;
cmbDataType.ItemIndex := DAQAI1.DataType;
cmbStartChannel.ItemIndex := DAQAI1.StartChannel;
cmbNumChan.ItemIndex := DAQAI1.NumberOfChannels - 1;
cmbTransferMode.ItemIndex := DAQAI1.TransferMode;
cmbClockSource.ItemIndex := DAQAI1.ClockSource;
if DAQAI1.ExtTrigger then
cmbTrigSource.ItemIndex := 1
else
cmbTrigSource.ItemIndex := 0;
DAQAI1.SampleRate := 100;
DAQAI1.NumberOfSamples := 100;
lstReading.Clear;
end;

procedure TForm1.txtDeviceNumChange(Sender: TObject);
begin
DAQAI1.DeviceNumber := StrToInt(txtDeviceNum.Text);
txtDeviceName.Text := DAQAI1.DeviceName;
end;

procedure TForm1.txtNumOfSampleChange(Sender: TObject);
begin
DAQAI1.NumberOfSamples := StrToInt(txtNumOfSample.Text);
end;

procedure TForm1.txtSampleRateChange(Sender: TObject);
begin
DAQAI1.SampleRate := StrToInt(txtSampleRate.Text);
end;

procedure TForm1.ScanTimerTimer(Sender: TObject);
var
UserData : OleVariant;
i : Integer;
begin
lstReading.Clear;

if DAQAI1.DataType = adRaw then
begin
UserData := VarArrayCreate([0, 9], varSmallint);
DAQAI1.GetBufferData(0, 10, UserData);
for i := 0 to 9 do
lstReading.Items.Add (IntToStr(UserData[i]));
end
else
begin
UserData := VarArrayCreate([0, 9], varSingle);
DAQAI1.GetBufferData(0, 10, UserData);
for i := 0 to 9 do
lstReading.Items.Add (FormatFloat('0.000000', UserData[i]));
end;
end;

procedure TForm1.chkCyclicModeClick(Sender: TObject);
begin
if chkCyclicMode.State = cbChecked then
DAQAI1.CyclicMode := True
else
DAQAI1.CyclicMode := False;
end;

procedure TForm1.chkEventEnabledClick(Sender: TObject);
begin
if chkEventEnabled.State = cbChecked then
DAQAI1.EventEnabled := True
else
DAQAI1.EventEnabled := False;
end;

procedure TForm1.cmdAutoGetClick(Sender: TObject);
begin
ScanTimer.Enabled := True;
cmdAcquireStop.Enabled := False;
cmdAutoGet.Enabled := False;
cmdStopAutoGet.Enabled := True;
end;

procedure TForm1.cmdStopAutoGetClick(Sender: TObject);
begin
ScanTimer.Enabled := False;
cmdAcquireStop.Enabled := True;
cmdAutoGet.Enabled := True;
cmdStopAutoGet.Enabled := False;
end;

procedure TForm1.cmbClockSourceChange(Sender: TObject);
begin
DAQAI1.ClockSource := cmbClockSource.ItemIndex;
end;

procedure TForm1.cmbTrigSourceChange(Sender: TObject);
begin
if cmbTrigSource.ItemIndex = 1 then
DAQAI1.ExtTrigger := True;
end;

procedure TForm1.cmbStartChannelChange(Sender: TObject);
var
i : integer;
num : integer;
begin
cmbNumChan.Clear;
num := gNumOfChan - cmbStartChannel.ItemIndex;
for i := 1 to num do
cmbNumChan.Items.Add (IntToStr(i));
cmbNumChan.ItemIndex := 0;
DAQAI1.NumberOfChannels := 1;
DAQAI1.StartChannel := cmbStartChannel.ItemIndex;
end;

procedure TForm1.cmbNumChanChange(Sender: TObject);
begin
DAQAI1.NumberOfChannels := cmbNumChan.ItemIndex + 1;
end;

procedure TForm1.ErrorTimerTimer(Sender: TObject);
begin
txtErrorCode.Text := IntToStr(DAQAI1.ErrorCode);
txtErrorMessage.Text := DAQAI1.ErrorMessage;
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
ScanTimer.Enabled := False;
ErrorTimer.Enabled := False;
DAQAI1.AcquireStop;
DAQAI1.CloseDevice;
end;

end.

0

Jak próbkami przecież ta karta ma wbudowane FIFO ? ;) Opisz komunikację z kartą. Windows?

Ogólnie wygląda to tak, że jak karta "wypluje" bufor z danymi kopiujesz go do przygotowanego wcześniej bufora programowego. Nie wiem jakie jest to DFT ale pewnie trzeba będzie w trakcie przekonwertować 16 bitowe sample na float lub double. Rozmiar bufora oczywiście musi pomieścić wszystkie sample z bufora karty.

0

swapuj wskaznik?

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0