/dummymri/DummyMriMain.PAS
Pascal | 434 lines | 334 code | 55 blank | 45 comment | 17 complexity | 7d7c278059b37ae453316a043fa240c4 MD5 | raw file
- unit DummyMriMain;
- //
- // DummyMRI
- //
- // The Dummy MRI application allows playback of a wav sound file associated with
- // one single TR of an accociated sequence at the MRI Avanto or Trio.
- // No actual MRI sequence parameters can be adjusted (the wav soundfile should just
- // generate the proper sound for each TR.
- //
- // Only TR and measurements can be set to allow emulation of the measurement time
- // and number of scanned volumes
- //
- // For each volume a scan trigger pulse is generated via the attached BITSI box
- // For each volume a wav sound file is played, emulating the scanner noise in the pace
- // of TR.
- //
- // Note: If the playback time of the sound file is longer than the TR, the soundfile
- // is stopped, rewinded and replayed at the beginning of the next TR. This results
- // in an uninterrupted playback of the sound file. In such case the subject would
- // only hear the first TR-time segments of the complete sound file.
- //
- // Version history:
- //
- // Created version 1.1: May 10, 2010, Erik van den Boogert
- // Debugged version 1.2: May 11, 2010, Erik van den Boogert
- //
-
- interface
-
- uses Windows, Classes, Graphics, Forms, Controls, Menus,
- Dialogs, StdCtrls, Buttons, ExtCtrls, ComCtrls, ImgList, StdActns,
- ActnList, ToolWin, OoMisc, AdPort, MPlayer, Spin, SysUtils, IniFiles;
-
- type
- TSDIAppForm = class(TForm)
- OpenDialog: TOpenDialog;
- SaveDialog: TSaveDialog;
- ToolBar1: TToolBar;
- ToolButton1: TToolButton;
- ToolButton2: TToolButton;
- ActionList1: TActionList;
- FileNew1: TAction;
- FileOpen1: TAction;
- FileSave1: TAction;
- FileSaveAs1: TAction;
- FileExit1: TAction;
- EditCut1: TEditCut;
- EditCopy1: TEditCopy;
- EditPaste1: TEditPaste;
- HelpAbout1: TAction;
- StatusBar: TStatusBar;
- ImageList1: TImageList;
- MainMenu1: TMainMenu;
- File1: TMenuItem;
- FileOpenItem: TMenuItem;
- FileSaveItem: TMenuItem;
- FileSaveAsItem: TMenuItem;
- N1: TMenuItem;
- FileExitItem: TMenuItem;
- Help1: TMenuItem;
- HelpAboutItem: TMenuItem;
- comBITSI: TApdComPort;
- TimerRunMRI: TTimer;
- mpSound: TMediaPlayer;
- btnStartStop: TButton;
- lblTS: TLabel;
- lblTA: TLabel;
- panRoutine: TPanel;
- lblSoundFile: TLabel;
- lblComNumber: TLabel;
- edtComNumber: TSpinEdit;
- lblTR: TLabel;
- edtTR: TSpinEdit;
- lblMeasurements: TLabel;
- edtMeasurements: TSpinEdit;
- shpLineLeft1: TShape;
- shpLineRight: TShape;
- lblTRUnits: TLabel;
- shpLineLeft2: TShape;
- Shape4: TShape;
- TimerDisplay: TTimer;
- edtSoundFile: TEdit;
- chkPlaySoundFile: TCheckBox;
- OpenDialogSoundFile: TOpenDialog;
- btnBrowse: TButton;
- lblSoundFilePath: TLabel;
- procedure FileOpen1Execute(Sender: TObject);
- procedure FileSave1Execute(Sender: TObject);
- procedure FileExit1Execute(Sender: TObject);
- procedure HelpAbout1Execute(Sender: TObject);
- procedure TimerRunMRITimer(Sender: TObject);
- procedure edtSlicesChange(Sender: TObject);
- procedure edtTRChange(Sender: TObject);
- procedure edtMeasurementsChange(Sender: TObject);
- procedure edtConcatenationsChange(Sender: TObject);
- procedure btnStartStopClick(Sender: TObject);
- procedure TimerDisplayTimer(Sender: TObject);
- procedure FormCreate(Sender: TObject);
- procedure btnBrowseClick(Sender: TObject);
- private
- { Private declarations }
- TAms : longint;
- TSms : longint;
- Time32Started: LongWord;
- MeasurementsCount: longint;
- DragInProgress : boolean;
- procedure UpdateTA;
- procedure UpdateTS;
- procedure OnChangeProtocolParam;
- procedure EnableEditing;
- procedure DisableEditing;
- procedure SendBITSITrigger;
- procedure PlayMRISound;
- procedure CloseComBITSI;
- procedure OpenComBITSI;
- procedure SaveInifile(IniFileName: string);
- procedure LoadInifile(IniFileName: string);
- public
- { Public declarations }
- end;
-
- var
- SDIAppForm: TSDIAppForm;
-
- implementation
-
- uses about;
-
- {$R *.dfm}
-
-
- //--- Time format methods ------------------------------------------------------
-
- Function RelTimeToStr(RelTime:Real): String;
- const
- RErr = 0.00003;
- var
- DPara,
- Min, Sec,
- RelTmInt : Integer;
- MinStr, SecStr : string[3];
- FullTmStr : string[11];
- begin
- Str((RelTime + 10000 + RErr):5:2, FullTmStr);
- Val(Copy(FullTmStr,2,4), RelTmInt, DPara);
- Min := (RelTmInt div 60) + 100; Str(Min:3, MinStr);
- Sec := (RelTmInt mod 60) + 100; Str(Sec:3, SecStr);
- Result := Copy(MinStr,2,2)+':'+Copy(SecStr,2,2); //+Copy(FullTmStr,6,3);
- end;
-
- Function GetPCTime32:LongWord;
- begin
- Result := DateTimeToTimeStamp(Time).Time;
- end;
-
- Function ExtractFileName(FileName: string): string;
- begin
- Result := FileName;
- While (Pos('\',Result) > 0) do
- Result := Copy(Result,Pos('\',Result)+1,255);
- end;
-
-
- //--- Load & Save inifiles -----------------------------------------------------
-
- procedure TSDIAppForm.SaveInifile(IniFileName: string);
- var
- IniFile: TIniFile;
- begin
- try
- IniFile := TIniFile.Create(IniFileName);
- IniFile.WriteString('DummyMRI','SoundFile', edtSoundFile.Text);
- IniFile.WriteString('DummyMRI','SoundFilePath', lblSoundFilePath.Caption);
- IniFile.WriteInteger('DummyMRI','TR', edtTR.Value);
- IniFile.WriteInteger('DummyMRI','Measurements', edtMeasurements.Value);
- IniFile.WriteBool('DummyMRI','PlaySoundFile', chkPlaySoundFile.checked);
- IniFile.WriteInteger('DummyMRI','BITSIComPort', edtComNumber.Value);
- IniFile.Free;
- except
- IniFile.Free;
- ShowMessage('Error: Saving settings failed.')
- end;
- end;
-
- procedure TSDIAppForm.LoadInifile(IniFileName: string);
- var
- IniFile: TIniFile;
- begin
- try
- IniFile := TIniFile.Create(IniFileName);
- edtSoundFile.text := IniFile.ReadString('DummyMRI','SoundFile', 'myMRISound.wav');
- lblSoundFilePath.caption := IniFile.ReadString('DummyMRI','SoundFilePath', 'myMRISound.wav');
- edtTR.Value := IniFile.ReadInteger('DummyMRI','TR', 2000);
- edtMeasurements.Value := IniFile.ReadInteger('DummyMRI','Measurements', 100);
- chkPlaySoundFile.checked := IniFile.ReadBool('DummyMRI','PlaySoundFile', false);
- edtComNumber.Value := IniFile.ReadInteger('DummyMRI','BITSIComPort', 1);
- IniFile.Free;
- if NOT FileExists(lblSoundFilePath.Caption) then
- begin
- chkPlaySoundFile.checked := false;
- ShowMessage('Warning: Sound file not found, sound playback disabled.');
- end;
- except
- IniFile.Free;
- ShowMessage('Error: Loading settings failed.');
- end;
- end;
-
- procedure TSDIAppForm.FileOpen1Execute(Sender: TObject);
- begin
- if edtTR.Enabled then
- begin
- if OpenDialog.Execute then LoadIniFile(OpenDialog.FileName);
- end;
- end;
-
- procedure TSDIAppForm.FileSave1Execute(Sender: TObject);
- begin
- if edtTR.Enabled then
- begin
- if SaveDialog.Execute then SaveIniFile(SaveDialog.FileName);
- end;
- end;
-
-
- //--- Create, Close en About methods -------------------------------------------
-
- procedure TSDIAppForm.FormCreate(Sender: TObject);
- begin
- OpenComBITSI;
- SendBITSITrigger;
- end;
-
- procedure TSDIAppForm.FileExit1Execute(Sender: TObject);
- begin
- Close;
- end;
-
- procedure TSDIAppForm.HelpAbout1Execute(Sender: TObject);
- begin
- AboutBox.ShowModal;
- end;
-
-
- //--- BITSI ComPort methods ----------------------------------------------------
-
- procedure TSDIAppForm.btnBrowseClick(Sender: TObject);
- begin
- if OpenDialogSoundFile.execute then
- begin
- lblSoundFilePath.Caption := OpenDialogSoundFile.FileName;
- edtSoundFile.Text := ExtractFileName(lblSoundFilePath.Caption);
- end;
- end;
-
-
- procedure TSDIAppForm.CloseComBITSI;
- begin
- try comBITSI.Open := false; except end;
- end;
-
- procedure TSDIAppForm.OpenComBITSI;
- begin
- comBITSI.ComNumber := edtComNumber.Value;
- try
- comBITSI.Open := true;
- except
- ShowMessage('Error: BITSI Com-Port '+ IntToStr(edtComNumber.Value) +' could not be opened');
- end;
- end;
-
- procedure TSDIAppForm.SendBITSITrigger;
- begin
- try
- comBITSI.PutChar(Chr(1));
- except end;
- end;
-
-
- //--- mpSound methods ----------------------------------------------------------
-
- procedure TSDIAppForm.PlayMRISound;
- begin
- try
- mpSound.Stop;
- mpSound.Rewind;
- mpSound.Play;
- except end;
- end;
-
-
- //--- Update TA & TA labels ----------------------------------------------------
-
- procedure TSDIAppForm.UpdateTA;
- begin
- TAms := edtMeasurements.value * edtTR.value;
- lblTA.Caption := 'TA: ' + RelTimeToStr(TAms/1000);
- end;
-
- procedure TSDIAppForm.UpdateTS;
- begin
- //--- initialize TS = TA
- TSms := TAms;
- //--- only when running count down residual time using GetPCTime32
- if btnStartStop.Caption = 'Stop' then TSms := TAms - (GetPCTime32 - Time32Started);
- //--- ensure TS doesn't underrun 0 s.
- if (TSms < 0) then TSms := 0;
- lblTS.Caption := 'Scanning: ' + RelTimeToStr(TSms/1000);
- end;
-
- procedure TSDIAppForm.OnChangeProtocolParam;
- begin
- UpdateTA;
- end;
-
- procedure TSDIAppForm.TimerDisplayTimer(Sender: TObject);
- begin
- UpdateTA;
- UpdateTS;
- end;
-
- procedure TSDIAppForm.edtMeasurementsChange(Sender: TObject);
- begin
- OnChangeProtocolParam;
- end;
-
- procedure TSDIAppForm.edtConcatenationsChange(Sender: TObject);
- begin
- OnChangeProtocolParam;
- end;
-
- procedure TSDIAppForm.edtSlicesChange(Sender: TObject);
- begin
- OnChangeProtocolParam;
- end;
-
- procedure TSDIAppForm.edtTRChange(Sender: TObject);
- begin
- OnChangeProtocolParam;
- end;
-
-
- //--- Prepare, Start & Stop methods --------------------------------------------
-
- procedure TSDIAppForm.DisableEditing;
- begin
- edtMeasurements.Enabled := false;
- edtTR.Enabled := false;
- edtComNumber.Enabled := false;
- chkPlaySoundFile.Enabled := false;
- end;
-
- procedure TSDIAppForm.EnableEditing;
- begin
- edtMeasurements.Enabled := true;
- edtTR.Enabled := true;
- edtComNumber.Enabled := true;
- chkPlaySoundFile.Enabled := true;
- end;
-
- procedure TSDIAppForm.btnStartStopClick(Sender: TObject);
- begin
- //--- Case Prepare
- if btnStartStop.Caption = 'Prepare' then
- begin
- if comBITSI.ComNumber <> edtComNumber.Value then
- begin
- CloseComBITSI;
- OpenComBITSI;
- end;
- //
- if NOT FileExists(lblSoundFilePath.Caption) then
- begin
- chkPlaySoundFile.checked := false;
- ShowMessage('Warning: Sound File does not exist, sound playback disabled');
- end;
- //
- if (chkPlaySoundFile.checked) then
- begin
- mpSound.Close;
- mpSound.FileName := lblSoundFilePath.Caption;
- try mpSound.Open;
- except
- chkPlaySoundFile.checked := false;
- ShowMessage('Error: Sound File could not be loaded, sound playback disabled.');
- end;
- end;
- //
- if comBITSI.Open then
- begin
- DisableEditing;
- btnStartStop.Caption := 'Start';
- end;
- end else
- //--- Case Start
- if btnStartStop.Caption = 'Start' then
- begin
- Time32Started := GetPCTime32;
- MeasurementsCount := edtMeasurements.Value;
- DisableEditing;
- timerRunMRI.Interval := edtTR.Value;
- timerRunMRI.Enabled := true;
- SendBITSITrigger;
- if chkPlaySoundFile.checked then PlayMRISound;
- btnStartStop.Caption := 'Stop';
- end else
- //--- Case Stop
- begin
- EnableEditing;
- timerRunMRI.Enabled := false;
- btnStartStop.Caption := 'Prepare';
- end;
- end;
-
-
- //--- Timer loop running the MRI sequence --------------------------------------
-
- procedure TSDIAppForm.TimerRunMRITimer(Sender: TObject);
- begin
- Dec(MeasurementsCount);
- if (MeasurementsCount <= 0) then
- begin
- btnStartStopClick(Sender);
- end else
- begin
- SendBITSITrigger;
- if chkPlaySoundFile.checked then PlayMRISound;
- end;
- end;
-
- end.
-
-
-