unit MalcPrc0501; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, StdCtrls, ExtCtrls, HyperStr, SadEDL0601, Output0501, MakFlx0501, MalcCons0501, FinDlg0501, MakODB0501, MakALE0501, Spin; type TProcForm = class(TForm) Panel1: TPanel; Label1: TLabel; Panel2: TPanel; Label2: TLabel; BtnSrceSelect: TButton; ChkSrceMultiple: TCheckBox; Label3: TLabel; LBoxSrceFiles: TListBox; DlgProcOpenFile: TOpenDialog; LblNumSrceFiles: TLabel; Panel3: TPanel; Label4: TLabel; BtnSyncSelect: TButton; ChkSyncMultiple: TCheckBox; Label5: TLabel; LBoxSyncFiles: TListBox; LblNumSyncFiles: TLabel; Panel4: TPanel; LblTKFlex: TLabel; BtnFlexSelect: TButton; ChkFlexMultiple: TCheckBox; LblTKCheckBox: TLabel; LBoxFlexFiles: TListBox; LblNumFlexFiles: TLabel; BtnProcess: TButton; Panel5: TPanel; SpinReelNum: TSpinEdit; Label6: TLabel; procedure BtnSrceSelectClick(Sender: TObject); procedure BtnSyncSelectClick(Sender: TObject); procedure BtnFlexSelectClick(Sender: TObject); procedure FormShow(Sender: TObject); procedure BtnProcessClick(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); private FlexFile : Boolean; FlexTypeList : TList; SrceEDLList : TStringList; SyncEDLList : TStringList; FlexFLXList : TStringList; function CheckFiles : Boolean; function CreateSrceObject : Boolean; function CreateSyncObject : Boolean; function CreateFlexObject : Boolean; procedure ProcessData; procedure AdjustToFrame( var StartSample, Break1Sample : LongInt; const SampleDiv : LongInt); procedure AdjustToA1Frame( var StartSample, BreakSample : LongInt; const SampleDiv, FrameRate, FlexIndex : Integer; OpType : TOpParams); function ConvertToFrames( SampleValue : LongInt; SampleDiv : Integer) : LongInt; function MultiplyByRatio( StartSample : LongInt; OpType : TOpParams) : Longint; function MakeKeyCode( FlexIndex, StartFramesOffset : Integer; OpType : TOpParams) : String; function Make3PKeyCode( FlexIndex, StartFramesOffset : Integer; OpType : TOpParams) : String; procedure DestroyFlexTypeList; public end; var ProcForm: TProcForm; implementation {$R *.DFM} uses MalcMain0501, Flex0501; //----------------------------------------------------------------------------- procedure TProcForm.BtnSrceSelectClick(Sender: TObject); var SingleFile, MultiFile : TOpenOptions; n : Integer; Temp : String; begin // Set up style strings for File Open Dialog SingleFile := [ofreadOnly, ofPathMustExist, ofFilemustExist]; MultiFile := [ofreadOnly, ofPathMustExist, ofFilemustExist, ofAllowMultiSelect]; // Create string list for full pathnames if assigned(SrceEDLList) then begin SrceEDLList.Clear; // Clear existing strings LBoxSrceFiles.Clear; // and empty listbox strings LblNumSrceFiles.Caption := 'No Files Selected'; end else SrceEDLList := TStringList.Create; DlgProcOpenFile.Title := 'Open SADiE source EDL(s)'; DlgProcOpenFile.Filter := 'SADiE EDL|*.edl|All Files|*.*'; if ChkSrceMultiple.Checked then begin DlgProcOpenFile.Options := MultiFile; if DlgProcOpenFile.Execute then begin SrceEDLList.AddStrings(DlgProcOpenFile.Files); for n := 0 to DlgProcOpenFile.Files.Count - 1 do begin Temp := DlgProcOpenFile.Files[n]; TruncPath(Temp, 30); LBoxSrceFiles.Items.Add(Temp); end; LblNumSrceFiles.Caption := IntToStr(DlgProcOpenFile.Files.Count) + ' files selected.'; end; end else begin DlgProcOpenFile.Options := SingleFile; if DlgProcOpenFile.Execute then begin SrceEDLList.AddStrings(DlgProcOpenFile.Files); Temp := DlgProcOpenFile.Files[0]; TruncPath(Temp, 30); LBoxSrceFiles.Items.Add(Temp); LblNumSrceFiles.Caption := '1 file selected'; end; end; end; //----------------------------------------------------------------------------- procedure TProcForm.BtnSyncSelectClick(Sender: TObject); var SingleFile, MultiFile : TOpenOptions; n : Integer; Temp : String; begin // Create style sets for File Open Dialog SingleFile := [ofreadOnly, ofPathMustExist, ofFilemustExist]; MultiFile := [ofreadOnly, ofPathMustExist, ofFilemustExist, ofAllowMultiSelect]; // Create list for full pathnames if assigned(SyncEDLList) then begin SyncEDLList.Clear; // Clear existing strings LBoxSyncFiles.Clear; // and empty listbox strings LblNumSyncFiles.Caption := 'No Files Selected'; end else SyncEDLList := TStringList.Create; DlgProcOpenFile.Title := 'Open SADiE source EDL(s)'; DlgProcOpenFile.Filter := 'SADiE EDL|*.edl|All Files|*.*'; if ChkSrceMultiple.Checked then begin DlgProcOpenFile.Options := MultiFile; if DlgProcOpenFile.Execute then begin SyncEDLList.AddStrings(DlgProcOpenFile.Files); for n := 0 to DlgProcOpenFile.Files.Count - 1 do begin Temp := DlgProcOpenFile.Files[n]; TruncPath(Temp, 30); LBoxSyncFiles.Items.Add(Temp); end; LblNumSyncFiles.Caption := IntToStr(DlgProcOpenFile.Files.Count) + ' files selected.'; end; end else begin DlgProcOpenFile.Options := SingleFile; if DlgProcOpenFile.Execute then begin SyncEDLList.AddStrings(DlgProcOpenFile.Files); Temp := DlgProcOpenFile.Files[0]; TruncPath(Temp, 30); LBoxSyncFiles.Items.Add(Temp); LblNumSyncFiles.Caption := '1 file selected'; end; end; end; //----------------------------------------------------------------------------- procedure TProcForm.BtnFlexSelectClick(Sender: TObject); var SingleFile, MultiFile : TOpenOptions; n : Integer; Temp : String; begin // Create style sets for File Open Dialog SingleFile := [ofreadOnly, ofPathMustExist, ofFilemustExist]; MultiFile := [ofreadOnly, ofPathMustExist, ofFilemustExist, ofAllowMultiSelect]; // Create list for full pathnames if assigned(FlexFLXList) then begin FlexFLXList.Clear; // Clear existing strings LBoxFlexFiles.Clear; // and empty listbox strings LblNumFlexFiles.Caption := 'No Files Selected'; end else FlexFLXList := TStringList.Create; DlgProcOpenFile.Title := 'Open Telecine Flex files'; DlgProcOpenFile.Filter := 'Flex file|*.flx|All Files|*.*'; if ChkFlexMultiple.Checked then begin DlgProcOpenFile.Options := MultiFile; if DlgProcOpenFile.Execute then begin FlexFLXList.AddStrings(DlgProcOpenFile.Files); for n := 0 to DlgProcOpenFile.Files.Count - 1 do begin Temp := DlgProcOpenFile.Files[n]; TruncPath(Temp, 30); LBoxFlexFiles.Items.Add(Temp); end; LblNumFlexFiles.Caption := IntToStr(DlgProcOpenFile.Files.Count) + ' files selected.'; end; end else begin DlgProcOpenFile.Options := SingleFile; if DlgProcOpenFile.Execute then begin FlexFLXList.AddStrings(DlgProcOpenFile.Files); Temp := DlgProcOpenFile.Files[0]; TruncPath(Temp, 30); LBoxFlexFiles.Items.Add(Temp); LblNumFlexFiles.Caption := '1 file selected'; end; end; end; //----------------------------------------------------------------------------- procedure TProcForm.FormShow(Sender: TObject); { This function reads the requirement for the inclusion of flex file data from the main form and disables the Flexfile controls if there is no requirement. The FlexFile value in ProcForm is also set accordingly. } begin if not FormOpening.FlexFileRequired then begin LBoxFlexFiles.Items.Add('No Flex File Required'); LblTKFlex.Enabled := False; BtnFlexSelect.Enabled := False; LBoxFlexFiles.Enabled := False; ChkFlexMultiple.Enabled := False; LblTKCheckBox.Enabled := False; LblNumFlexFiles.Enabled := False; end; FlexFile := FormOpening.FlexFileRequired; end; //----------------------------------------------------------------------------- procedure TProcForm.BtnProcessClick(Sender: TObject); begin if not CheckFiles then Exit; if not CreateSrceObject then Exit; if not CreateSyncObject then Exit; if FlexFile then begin if not CreateFlexObject then Exit; end; // Flex object test here //FlexData.TestListStart; ProcessData; if FormOpening.ChkFlex.Checked then begin MakeFlex := TMakeFlex.Create; MakeFlex.MakeNewFlexFile; end; if FormOpening.ChkLWorks.Checked then begin MakeODB := TMakeODB.Create; MakeODB.MakeNewODBFile; end; if FormOpening.ChkAvid.Checked then begin MakeALE := TMakeALE.Create; MakeALE.MakeNewALEFile; end; if FormOpening.ChkFlex.Checked then FinDlg0501.ShowFlexFinishDlg; end; //----------------------------------------------------------------------------- function TProcForm.CheckFiles : Boolean; var n, FlexType : Integer; FileName : TFileName; FlexTypePtr : ^Integer; begin // Check Source files first if SrceEDLList.Count > 0 then begin for n := 1 to SrceEDLList.Count do begin Filename := SrceEDLList[n-1]; if not SadEDL0501.CheckSadieEDL(FileName) then begin Result := False; Exit; end; end; end else begin MessageDlg('No SADiE source files selected!', mtError, [mbOK], 0); Result := False; Exit; end; // Then check Sync files if SyncEDLList.Count > 0 then begin for n := 1 to SyncEDLList.Count do begin Filename := SyncEDLList[n-1]; if not SadEDL0501.CheckSadieEDL(FileName) then begin Result := False; Exit; end; end; end else begin MessageDlg('No SADiE sync files selected!', mtError, [mbOK], 0); Result := False; Exit; end; // Then check Flex files if necessary if FlexFile then begin if FlexFLXList.Count > 0 then begin // Create list for type of file FlexTypeList := TList.Create; for n := 1 to FlexFLXList.Count do begin Filename := FlexFLXList[n-1]; FlexType := Flex0501.CheckFile(Filename); if FlexType > 0 then begin New(FlexTypePtr); FlexTypeList.Add(FlexTypePtr); FlexTypePtr^ := FlexType; end else begin Result := False; Exit; end; end; end else begin MessageDlg('No Flex files selected!', mtError, [mbOK], 0); Result := False; Exit; end; end; //Check ODB and ALE Reel Number and store if required if (FormOpening.ChkLWorks.Checked or FormOpening.ChkAvid.Checked) and (SpinReelNum.Value = 0) then begin MessageDlg( 'No valid reel number for ODB or ALE file entered!', mtError, [mbOK], 0); Result := False; Exit; end; Result := True; end; //----------------------------------------------------------------------------- function TProcForm.CreateSrceObject : Boolean; var FileName : TFileName; n : Integer; begin // Create SrceData object SrceData := TSadiedata.Create; // Load first/only source file FileName := SrceEDLList.Strings[0]; if SrceData.NewHeaderData(FileName) then begin if SrceData.NewEDLData(FileName) then begin if SrceEDLList.Count > 1 then begin for n := 1 to SrceEDLList.Count - 1 do begin FileName := SrceEDLList.Strings[n]; if SrceData.CompareHeaderData(FileName) then begin if not SrceData.AddEDLData(FileName) then begin Result := False; Exit; end; end else begin Result := False; Exit // Compare Data alternate end; end; end; end else begin Result := False; Exit; // Load EDL data alternative end; end else begin Result := False; Exit; // Load Header data alternative end; Result := True end; //----------------------------------------------------------------------------- function TProcForm.CreateSyncObject : Boolean; var FileName : TFileName; n : Integer; begin // Create SyncData object SyncData := TSadiedata.Create; // Load first/only source file FileName := SyncEDLList.Strings[0]; if SyncData.NewHeaderData(FileName) then begin if SyncData.NewEDLData(FileName) then begin if SyncEDLList.Count > 1 then begin for n := 1 to SyncEDLList.Count - 1 do begin FileName := SyncEDLList.Strings[n]; if SyncData.CompareHeaderData(FileName) then begin if not SyncData.AddEDLData(FileName) then begin Result := False; Exit; end; end else begin Result := False; Exit; // Compare Data alternate end; end; end; end else begin Result := False; Exit; // Load EDL data alternative end; end else begin Result := False; Exit; // Load Header data alternative end; Result := True; end; //----------------------------------------------------------------------------- function TProcForm.CreateFlexObject : Boolean; var FileName : TFileName; n : Integer; FlexTypePtr : ^Integer; OpType : TOpParams; CheckPtr : PtrFlexData; TempBuff : String; begin // Create SrceData object FlexData := TFlexData.Create; // Load first/only source file FileName := FlexFLXList.Strings[0]; FlexTypePtr := FlexTypeList.Items[0]; if FlexData.LoadFlexData(FileName, FlexTypePtr^) then begin FlexData.TestListStart; // Check for more than one file name if FlexFLXList.Count > 1 then begin // if so set up loop to process for n := 1 to FlexFLXList.Count - 1 do begin // Get filename FileName := FlexFLXList.Strings[n]; // and file type FlexTypePtr := FlexTypeList.Items[n]; if FlexData.CompareHeaderData(FileName, FlexTypePtr^) then begin if not FlexData.AddFlexData(FileName, FlexTypePtr^) then begin Result := False; Exit; end; end else begin Result := False; Exit // Compare Data alternate end; end; end; end else begin Result := False; Exit; // Load Header data alternative end; OpType := FormOpening.GetOperationType; Flexdata.TestListStart; FlexData.SortByStartTime(OpType); FlexData.TestListStart; Result := True end; //----------------------------------------------------------------------------- procedure TProcForm.ProcessData; var SyncIndex, SrceIndex, SyncEventCount, SyncFrameRate : Integer; FlexIndex : Integer; SyncSampleDiv : LongInt; SyncStartSample, SyncStartFrames, SrceStartSample, EventLength : LongInt; SyncBreak1Offset, SrceBreak1Offset, SyncBreak4Offset, Variance : Longint; SyncEndSample, SrceBreak4Offset : LongInt; SyncTrackName, SyncClipName, SrceTrackName, NewKeyCode : String; OpType : TOpParams; FlexVariance : Integer; TestCount : Integer; begin // Get type of processing operation OpType := FormOpening.GetOperationType; // Create result data object Output := TOutput.Create; // Create list in Result object using count of sync events SyncEventCount := SyncData.GetListCount; Output.CreateDataList(SyncEventCount); SyncFrameRate := SyncData.GetFrameRate; SyncSampleDiv := SyncData.GetSampleDiv; // Start main processing loop for SyncIndex := 0 to SyncEventCount - 1 do begin // Get start time and break1 offset of sync event SyncStartSample := SyncData.GetStartSample(SyncIndex); SyncBreak1Offset := SyncData.GetBreakSample1(SyncIndex); // Adjust to next highest whole frame AdjustToFrame( SyncStartSample, SyncBreak1Offset, SyncSampleDiv); // Convert sync start sample value to frames SyncStartFrames := ConvertToFrames( SyncStartSample, SyncSampleDiv); // Check if Flex File loaded FlexIndex := -1; if FlexFile then begin // Find matching flex event FlexIndex := FlexData.MatchFlexEvent(SyncStartFrames, SyncIndex, OpType); // Adjust to sync start time to A1 frame if match found if FlexIndex >= 0 then AdjustToA1Frame( SyncStartSample, SyncBreak1Offset, SyncSampleDiv, SyncFrameRate, FlexIndex, OpType); end; // Now find matching event and time in source EDL // First get track name of sync event SyncTrackName := SyncData.GetTrackName(SyncIndex); // Get duration of sync event in samples SyncBreak4Offset := SyncData.GetBreakSample4(SyncIndex); EventLength := SubUSI(SyncBreak4Offset, SyncBreak1Offset); // Then check if speed processing of tracks has been necessary if (TK25 in OpType) and (Film24 in OpType) or (TK24 in OpType) and (Film25 in OpType) then begin // and multiply break offset by appropriate ratio SrceBreak1Offset := MultiplyByRatio(SyncBreak1Offset, OpType); // and multiply end break offset by appropriate value SrceBreak4Offset := MultiplyByRatio(SyncBreak4Offset, OpType); // Get matching source event index or -1 if no match SrceIndex := SrceData.MatchProcSyncEvent( SyncTrackName, SrceBreak1Offset, SrceBreak4Offset, OpType); if SrceIndex >= 0 then begin SrceStartSample := AddUSI(SrceData.GetStartSample(SrceIndex), SrceBreak1Offset); SrceTrackName := LStr(SrceData.GetTrackName(SrceIndex), 3) end else begin // or set source parameters if no match found SrceStartSample := 0; SrceTrackName := 'No Match'; end; end else begin // Get matching non-processed source track or -1 if no match SrceIndex := SrceData.MatchSyncEvent( SyncTrackName, SyncBreak1Offset, SyncBreak4Offset); SrceBreak1Offset := SyncBreak1Offset; // Now get information for Result object // Get source start time if SrceIndex >= 0 then begin { Calculate offset into Original Clip } if CmpUSI( SrceBreak1Offset, SrceData.GetBreakSample1(SrceIndex)) >= 0 then begin Variance := SrceBreak1Offset - SrceData.GetBreakSample1(SrceIndex); { Calculate equivalent Origin start time using offset } SrceStartSample := AddUSI( SrceData.GetStartSample(SrceIndex), Variance); end else begin // This necessary in case srce offset less than // matching clip's Break1 point - possible if sync clip has been // extended earlier than its original clip time with the // Trim window in SADiE - shouldn't happen but it does on occasion!! Variance := SrceData.GetBreakSample1(SrceIndex) - SrceBreak1Offset; { Calculate equivalent Origin start time using offset } SrceStartSample := SubUSI( SrceData.GetStartSample(SrceIndex), Variance); end; SrceTrackName := LStr(SrceData.GetTrackName(SrceIndex), 3); end else begin // or set source parameters if no match found SrceStartSample := 0; SrceTrackName := 'No Match'; end; end; // Get sync event end time SyncEndSample := AddUSI(SyncStartSample, EventLength); SyncClipName := SyncData.GetClipName(SyncIndex); // Now deal with flex detail if required. if FlexFile then begin if FlexIndex >= 0 then begin FlexVariance := FlexData.GetFlexStartFrames(FlexIndex, SyncFrameRate) - ConvertToFrames(SyncStartSample, SyncSampleDiv); NewKeyCode := MakeKeyCode( FlexIndex, FlexVariance, OpType); end else NewKeyCode := '0'; end; // Now store data in Record list Output.CreateResultRecord( SyncStartSample, SyncEndSample, SrceStartSample, SyncClipName, SrceTrackname, NewKeyCode, FlexIndex) end; end; //----------------------------------------------------------------------------- procedure TProcForm.AdjustToFrame( var StartSample, Break1Sample : LongInt; const SampleDiv : LongInt); { Adjusts the time to a whole frame and sets that frame on the next higher frame value } var Remainder, Offset : LongInt; begin Remainder := ModUSI(StartSample, SampleDiv); if Remainder > 0 then Offset := SubUSI(SampleDiv, Remainder) else Offset := 0; StartSample := AddUSI(StartSample, Offset); Break1Sample := AddUSI(Break1Sample, Offset); end; //----------------------------------------------------------------------------- procedure TProcForm.AdjustToA1Frame( var StartSample, BreakSample : LongInt; const SampleDiv, FrameRate, FlexIndex : Integer; OpType : TOpParams); { Sets the frame to the next higher A1 frame. In the case of 24+1 transfers in PAL, will read the A1 frame offset from the flex file and adjust the sync start time to the same offset. } var FrameValue, FlexFrameOffset, SyncFrameOffset, Difference : Integer; FlexStartInFrames : LongInt; FlexFrameIdent : String; begin // Get Flex start time in frames FlexStartInFrames := FlexData.GetFlexStartFrames(FlexIndex, FrameRate); // Get frame ident as string FlexFrameIdent := FlexData.GetFieldIdent(FlexIndex); if FlexFrameIdent = 'A1' then begin // Get the A1 frame offset FlexFrameOffset := FlexStartInFrames mod FrameRate; // Get the sync event frame offset SyncFrameOffset := ModUSI(DivUSI(StartSample, SampleDiv), FrameRate); // Initialise Difference to zero Difference := 0; // Check if 24 frame PAL transfer and set sync event offset to A1 frame if (TK24 in OpType) and (Film24 in OpType) and (PAL in OpType) then begin if FlexFrameOffset > SyncFrameOffset then // If the Flex offset is greater than the sync offset // get the difference in frames Difference := FlexFrameOffset - SyncFrameOffset; if FlexFrameOffset < SyncFrameOffset then // If Flex offset is less than sync event offset then adjust // sync offset to next highest value to match Difference := FrameRate - SyncFrameOffset + FlexframeOffset; end // Or process for other standards to multiples of 5 frames depending on // A1 frame start of telecine else begin FlexFrameOffset := FlexFrameOffset mod 5; SyncFrameOffset := SyncFrameOffset mod 5; if FlexFrameOffset > SyncFrameOffset then Difference := FlexFrameOffset - SyncFrameOffset; if FlexFrameOffset < SyncFrameOffset then Difference := 5 -SyncFrameOffset + FlexFrameOffset; end; // Adjust the start sample and break sample StartSample := AddUSI(StartSample, SampleDiv * Difference); BreakSample := AddUSI(BreakSample, SampleDiv * Difference); end; end; //----------------------------------------------------------------------------- function TProcForm.ConvertToFrames( SampleValue : Longint; SampleDiv : Integer) : LongInt; begin Result := DivUSI(SampleValue, SampleDiv); end; //----------------------------------------------------------------------------- function TProcForm.MultiplyByRatio( StartSample : LongInt; OpType : TOpParams) : Longint; var Remainder : Single; Store1, Store2, Store3, Store4 : String; begin // Check for 25 frame film run at 24 fps if Film25 in OpType then begin Remainder := ModUSI(StartSample, 25); Result := MulUSI(DivUSI(StartSample, 25), 24); if Remainder > 0 then Result := AddUSI(Result, Trunc(Remainder*24/25)); end else // Process for 24 fps film at 25fps in telecine begin // Check for V3 processing if V3 in OpType then begin Store1 := USIToStr(StartSample); Store2 := StrMul(Store1, '1041508246'); // was 1041448499 Store3 := StrRnd(Store2, 9); Store4 := LStr(Store3, Length(Store3)- 9); Result := StrToUSI(Store4); end else // Otherwise do standard V2 processing begin Remainder := ModUSI(StartSample, 24); Result := MulUSI(DivUSI(StartSample, 24), 25); if Remainder > 0 then Result := AddUSI(Result, Trunc(Remainder*25/24)); end; end; end; //----------------------------------------------------------------------------- function TProcForm.MakeKeyCode( FlexIndex, StartFramesOffset : Integer; OpType : TOpParams) : String; var StartCodeOffset, CodeNumber, CodeBase, Pos : Integer; KeyCodeBase, DotPos : String; KeyCodeNumber, KeyCodeOffset, NewNumber, NewOffset : Integer; NewKeyCodenumber, NewKeyCodeOffset, Temp : String; BaseNumber, BaseVariance : Integer; begin StartCodeOffset := 0; if StartFramesOffset <> 0 then // Check for NTSC 3:2 Pulldown if (NTSC in OpType) and (TK24 in OpType) then // and adjust frame offset for 3:2 pulldown StartCodeOffset := (StartFramesOffset * 4) div 5 else StartCodeOffset := StartFramesOffset; // Select KeyCode base for 16mm or 35mm film // 16mm = 20 frames per number, 35mm = 16 frames per number CodeBase := 16; if (G16 in OpType) then CodeBase := 20; // Get selected flex entry keycode FlexData.GetFlexKeyCode( KeyCodeBase, KeyCodeNumber, KeyCodeOffset, FlexIndex); if (FlexData.GetFilmGauge(FlexIndex) = '3P') then // Do 3P code calculations begin // Get Dot position information DotPos := FlexData.GetDotPos(FlexIndex); // and convert to integer Pos := StrToInt(Copy(Dotpos, 2, 1)); case Pos of 1: begin BaseNumber := KeyCodeNumber div 3; BaseVariance := KeyCodeNumber mod 3; end; 2: begin Dec(KeyCodeNumber); BaseNumber := KeyCodeNumber div 3; BaseVariance := KeyCodeNumber mod 3; KeyCodeOffset := KeyCodeOffset + 21; end; 3: begin Dec(KeyCodeNumber, 2); BaseNumber := KeyCodeNumber div 3; BaseVariance := KeyCodeNumber mod 3; KeyCodeOffset := KeyCodeOffset + 42; end; end; // Convert base and offset into frames CodeNumber := BaseNumber * 64 + KeyCodeOffset; // and calculate new position CodeNumber := Codenumber - StartCodeOffset; // and generate new keycode number NewNumber := ((Codenumber div 64) * 3) + BaseVariance; NewOffset := CodeNumber mod 64; if (NewOffset > 20) and (NewOffset < 42) then begin Inc(NewNumber); Newoffset := NewOffset - 21; end; if (NewOffset > 41) and (NewOffset < 64) then begin Inc(NewNumber, 2); NewOffset := NewOffset - 42; end; NewKeyCodeNumber := IntToStr(NewNumber); LPad(NewKeyCodeNumber, '0', 4); NewKeyCodeOffset := IntToStr(NewOffset); LPad(NewKeyCodeOffset, '0', 2); Result := KeyCodeBase + NewKeyCodeNumber + '+' + NewKeyCodeOffset end else // Do standard code calculation begin // Get keycode number as integer CodeNumber := KeyCodeNumber; // convert to frames and add frames offset CodeNumber := CodeNumber * CodeBase + KeyCodeOffset; // then calculate new keycode value in frames using offset CodeNumber := Codenumber - StartCodeOffset; // and generate new keycode number NewKeyCodeNumber := IntToStr(CodeNumber div Codebase); // and pad to 4 places with leading zeros LPad(NewKeyCodeNumber, '0', 4); // Get new keycode offset NewKeyCodeOffset := IntToStr(CodeNumber mod CodeBase); // and pad to 2 places with leading zeros LPad(NewKeyCodeOffset, '0', 2); // then construct complete new keycode number and offset as a string Result := KeyCodeBase + NewKeyCodeNumber + '+' + NewKeyCodeOffset end; end; //----------------------------------------------------------------------------- function TProcForm.Make3PKeyCode( FlexIndex, StartFramesOffset : Integer; OpType : TOpParams) : String; var StartCodeOffset, CodeNumber, CodeBase : Integer; KeyCodeBase : String; KeyCodeNumber, KeyCodeOffset : Integer; NewKeyCodenumber, NewKeyCodeOffset : String; begin StartCodeOffset := 0; if StartFramesOffset <> 0 then // Check for NTSC 3:2 Pulldown if (NTSC in OpType) and (TK24 in OpType) then // and adjust frame offset for 3:2 pulldown StartCodeOffset := (StartFramesOffset * 4) div 5 else StartCodeOffset := StartFramesOffset; // Select KeyCode base for 16mm or 35mm film // 16mm = 20 frames per number, 35mm = 16 frames per number CodeBase := 16; if (G16 in OpType) then CodeBase := 20; // Get selected flex entry keycode FlexData.GetFlexKeyCode( KeyCodeBase, KeyCodeNumber, KeyCodeOffset, FlexIndex); // Get keycode number as integer CodeNumber := KeyCodeNumber; // convert to frames and add frames offset CodeNumber := CodeNumber * CodeBase + KeyCodeOffset; // then calculate new keycode value in frames using offset CodeNumber := Codenumber - StartCodeOffset; // and generate new keycode number NewKeyCodeNumber := IntToStr(CodeNumber div Codebase); // and pad to 4 places with leading zeros LPad(NewKeyCodeNumber, '0', 4); // Get new keycode offset NewKeyCodeOffset := IntToStr(CodeNumber mod CodeBase); // and pad to 2 places with leading zeros LPad(NewKeyCodeOffset, '0', 2); // then construct complete new keycode number and offset as a string Result := KeyCodeBase + NewKeyCodeNumber + '+' + NewKeyCodeOffset; end; //----------------------------------------------------------------------------- procedure TProcForm.DestroyFlexTypeList; var n : Integer; FlexTypePtr : ^Integer; begin if assigned(FlexTypeList) then begin for n := 0 to FlexTypeList.Count - 1 do begin FlexTypePtr := FlexTypeList.Items[n]; Dispose(FlexTypePtr); end; FlexTypeList.Free; FlexTypeList := nil; end; end; //----------------------------------------------------------------------------- procedure TProcForm.FormClose(Sender: TObject; var Action: TCloseAction); begin // On Process form close, clear down all list and object memory // First clear lists in EDL and Flex objects if assigned(SrceData) then begin SrceData.FreeEventListMemory; SrceData.Free; Srcedata := nil; end; if assigned(SyncData) then begin SyncData.FreeEventListMemory; SyncData.Free; Syncdata := nil; end; if assigned(Flexdata) then begin FlexData.FreeEventListMemory; FlexData.Free; FlexData := nil; end; if assigned(OutPut) then begin OutPut.FreeEventListMemory; OutPut.Free; OutPut := nil; end; DestroyFlexTypeList; // Clean up string lists SrceEDLList.Free; SrceEDLList := nil; SyncEDLList.Free; SyncEDLList := nil; FlexFLXList.Free; FlexFLXList := nil; end; end.