The Control-L Developer's ToolKit for Windows provides tools to assist Windows programmers in developing Control-L applications. All ToolKit features are contained in a single Dynamic Link Library ( LANC32.DLL), which provides functions to easily control and receive Information from multiple Video sources.
The control of video equipment using the Sony Control-L (LANC) protocol requires some very accurate timing to synchronise the PC's messages with that of the video source. This functionality is hidden away in the hardware cable, giving the user straight forward and logical control over the video source, whilst also freeing the PC's work load.
To use the ToolKit, you will require Microsoft Windows (95,96,ME,NT or 2000), a compiler with DLL function call support and other support tools normally used in software development. The ToolKit assumes the programmer is skilled in writing Windows applications.
The Control-L Developer's ToolKit for Windows provides tool to assist programmers in developing Control-L applications for the Microsoft Windows operating environment.
The ToolKit consists of this manual, cable incorporating hardware controller, along with the LANC32 Dynamic Link Library, header files and .LIB file for the linking to applications, Visual Basic OCX and .BAS file and two (very basic) sample applications showing the basics how to use the application with source code. No source code for the Dynamic Link Library or the OCX file is given.
Using the ToolKit couldn't be simpler. Firstly the Lanc Device must be opened and then Commands can be sent and Status and Frame information received. Finally the Device must be closed when it is no longer needed.
The Status information can either be received via a Windows Message sent on each Video Field, a Callback Function or can be Polled.
OpenLancDevice is used to open a LANC device when a Windows Message is required for receiving the Status and Frame information. (If a Callback function, a Registered Windows Message or Polling is required for the Application use OpenLancDeviceEx).
1a. Windows Message using OpenLancDevice: (Note 1c. is the preferred method to ensure unique Message ID)
|
HANDLE MyLancDevice;
case WM_CREATE: MyLancDevice = OpenLancDevice(hWnd, "COM2"); if (MyLancDevice == 0) MessageBox(hWnd, "Could not open Lanc Device", "Error", MB_OK);
// Application Code break; |
1b. Windows Message using OpenLancDeviceEx (Note 1c. is the preferred method to ensure unique Message ID)
|
HANDLE MyLancDevice; UINT rv;
case WM_CREATE:
rv =
OpenLancDeviceEx(&MyLancDevice,
"COM2",
hWnd, LANCCALLBACK_WINDOW); MessageBox(hWnd, "Could not open Lanc Device", "Error", MB_OK);
// Application
Code |
1c. Windows Registered Message using OpenLancDeviceEx
|
HANDLE MyLancDevice; UINT rv; UINT LancRegisteredMessage;
case WM_CREATE:
rv =
OpenLancDeviceEx(&MyLancDevice,
"COM2",
hWnd, LANCCALLBACK_REGISTERED_MESSAGE); MessageBox(hWnd, "Could not open Lanc Device", "Error", MB_OK); else
LancRegisteredMessage = GetRegisteredLancMessage(MyLancDevice);
// Application
Code |
2. Callback Function:
|
//Function Prototype LRESULT CALLBACK MyLancCallback(UINT iMsg, WPARAM wParam, LPARAM lParam); HANDLE MyLancDevice;
case WM_CREATE: // Open the Lanc Device with a Callback Function rv = OpenLancDeviceEx(&MyLancDevice, "COM2", MyLancCallback, LANCCALLBACK_FUNCTION); if (rv) MessageBox(hWnd, "Could not open Lanc Device", "Error", MB_OK);
// Application Code break;
LRESULT
CALLBACK MyLancCallback(UINT
iMsg, WPARAM
wParam, LPARAM
lParam) // Process the LANC Data Here
} |
3. Polling:
|
HANDLE MyLancDevice;
case WM_CREATE: // Open the Lanc Device with no automatic LANC infomation reporting OpenLancDeviceEx(&MyLancDevice, "COM2", NULL, LANCCALLBACK_NULL);
// Application Code break; |
LANC information is passed from the DLL to the application in the FRAMEDATA structure. This structure contains all the raw data as well as decoded Status and Frame data. The application is sent a MM_LANC_MESSAGE or the Callback function executed on every video field (50 fields/Sec Pal, 60 fields/Sec NTSC).
Windows Message:
|
static BYTE gStatus; //static or global variable LPFRAMEDATA lpFrameData; char StatusName[128]; BYTE Hours, Minutes, Seconds, Frames;
// Window Message Callback function switch (iMsg) { case MM_LANC_MESSAGE:
//wParam contains the device handle (used to
identify LancDevice = (HANDLE) wParam;
//lParam contains the device data lpFrameData = (LPFRAMEDATA)lParam; StatusName = GetStatusString(lpFrameData->Status); gStatus = lpFrameData->Status; Hours = lpFrameData->Hours; Minutes = lpFrameData->Minutes; Seconds = lpFrameData->Seconds; Frames = lpFrameData->Frames;
// Application Code break; |
Windows Registered Message:
|
static BYTE gStatus; //static or global variable LPFRAMEDATA lpFrameData; char StatusName[128]; BYTE Hours, Minutes, Seconds, Frames;
// Window Message Callback function switch (iMsg) { case WM_xxx:
break; default:
if (iMessage == LancRegisteredMessage)
//wParam contains the
device handle (used to identify LancDevice = (HANDLE) wParam;
//lParam contains the device data lpFrameData = (LPFRAMEDATA)lParam; StatusName = GetStatusString(lpFrameData->Status); gStatus = lpFrameData->Status; Hours = lpFrameData->Hours; Minutes = lpFrameData->Minutes; Seconds = lpFrameData->Seconds; Frames = lpFrameData->Frames;
// Application Code } } |
Callback Function:
|
LRESULT
CALLBACK MyLancCallback(UINT iMsg,
WPARAM wParam, LPARAM lParam) LPFRAMEDATA lpFrameData; char StatusName[128]; BYTE gStatus; //static or global variable BYTE Hours, Minutes, Seconds, Frames;
//wParam contains the device handle
(used to identify LancDevice = (HANDLE) wParam;
//lParam contains the device data lpFrameData = (LPFRAMEDATA)lParam; StatusName = GetStatusString(lpFrameData->Status); gStatus = lpFrameData->Status; Hours = lpFrameData->Hours; Minutes = lpFrameData->Minutes; Seconds = lpFrameData->Seconds; Frames = lpFrameData->Frames;
// Application Code } |
Polling:
|
FRAMEDATA MyFrameData;
char StatusName[128]; BYTE gStatus; //static or global variable BYTE Hours, Minutes, Seconds, Frames;
rv = GetLancStatusTimeCode(MyLancDevice, &MyFrameData); if (rv == FALSE) { MessageBox(hWnd, "Could not read data", "Error", MB_OK); } else { StatusName = GetStatusString(MyFrameData.Status); gStatus = MyFrameData.Status; Hours = MyFrameData.Hours; Minutes = MyFrameData.Minutes; Seconds = MyFrameData.Seconds; Frames = MyFrameData.Frames;
// Application Code } |
Time/date information is returned by the GetLancDateTime() function. The time and date information are stored in the TIMEDATA structure.
|
TIMEDATA MyTimeData; BYTE Year, Month, Day, Hours, Minutes, Seconds;
rv = GetLancTimeDate(MyLancDevice, &MyTimeData); if (rv == FALSE) { MessageBox(hWnd, "Could not read data", "Error", MB_OK); } else { Year = MyTimeData.Year; Month = MyTimeData.Month; Day = MyTimeData.Day; Hours = MyTimeData.Hours; Minutes = MyTimeData.Minutes; Seconds = MyTimeData.Seconds;
// Application Code } |
Single Commands are sent to the video equipment with the SendLancCommand() function. eg.
|
rv = SendLancCommand(MyLancDevice, COMMANDTYPE_VCR, COMMAND_REWIND); if (rv == FALSE) { MessageBox(hWnd, "LANC Device Not Responding", "Error", MB_OK); } |
Two Marcos are defined in the SDK for VCR and CAMERA Command Types. The above code can be written as:
|
rv = SendLancVideoCommand(MyLancDevice, COMMAND_REWIND); if (rv == FALSE) { MessageBox(hWnd, "LANC Device Not Responding", "Error", MB_OK); } |
Some Commands are dependant on the current status of the VCR for example the application may want the VCR to 'cue' rather than 'ff' if the 'ff' button is pressed when the current status of the VCR is 'play'. eg.
|
if (gStatus == MODE_PLAY) { SendLancVideoCommand(MyLancDevice, COMMAND_FORWARD); SendLancVideoCommand(MyLancDevice, COMMAND_HIGH_SPEED); } else { SendLancVideoCommand(MyLancDevice, COMMAND_FF); } |
Some commands need to send continuously. These commands include CUE, REVIEW, ZOOM IN/OUT etc. Continuous Commands are send until the next Single Command. A Single Command with Command_Type set to zero also cancels the continuous commands.
Continuous Commands are sent to the video equipment with the SendLancContinousCommand() function. eg.
|
// REWIND BUTTON DOWN SendLancContinuousCommand(MyLancDevice, COMMANDTYPE_VCR, COMMAND_REWIND, NULL);
// REWIND BUTTON UP SendLancCommand(MyLancDevice, 0, 0, NULL); |
To close the Driver use the CloseLancDevice() command eg.
|
case WM_DESTROY: CloseLancDeive(MyLancDevice); PostQuitMessage(0); break; |
This function opens and configures the Communications Port (Serial Port) used for the Control-L device.
Syntax
HANDLE OpenLancDevice(HWND hWnd,
LPSTR ComPort);
Parameters
HWND hWnd
Specifies the handle to the application window that is to receive any messages from the Driver.
LPSTR ComPort
Specifies which Serial Port the Control-L equipment is connected to
"COM1" Serial Port 1
"COM2" Serial Port 2 etc......
Return Value
Returns a handle to the opened device or zero if unsuccessful.
This function opens and configures the Communications Port (Serial Port) used for the Control-L device.
Syntax
HANDLE OpenLancDeviceEX(LPHANDLE lphLancDevice,
LPSTR ComPort,
DWORD dwCallback,
DWORD dwFlags);
Parameters
LPHANDLE lphLancDevice
Specifies a pointer to a handle for the opened device.
LPSTR ComPort
Specifies which Serial Port the Control-L equipment is connected to
"COM1" Serial Port 1
"COM2" Serial Port 2 etc......DWORD dwCallback
Specifies the function or window handle for the LANC information depending on the state of dwFlags.
DWORD dwFlags
Specifies how the LANC information is reported:
LANCCALLBACK_WINDOW
The LANC information is reported to the application window, dwCallback should contain the window handle (hWnd).
LANCCALLBACK_REGISTERED_MESSAGE
The LANC information is reported to the application window using a Registered Message, dwCallback should contain the window handle (hWnd).
LANCCALLBACK_FUNCTION
The LANC information is reported to a callback function. dwCallback should contain the callback function address. The callback function should have the following format:
LRESULT CALLBACK MyLancCallback(UINT iMsg,
WPARAM wParam,
LPARAM lParam)LANCCALLBACK_NULL
No LANC information is automatically reported. dwCallback should be NULL.
LANC information can be read using GetLancStatusTimeCode.
Return Value
Returns a handle to the opened device or zero if unsuccessful.
This function returns the Windows Message ID for Registered Windows Messages. The use of Registered Windows Message IDs ensured that the Windows Message ID is unique.
Syntax
UNIT GetRegisteredLancMessage(HANDLE LancDevice);
Parameters
HANDLE LancDevice
A Handle to the LANC device returned from OpenLancDeviceEx with the dwFlags parameter set to LANCCALLBACK_REGISTERED_MESSAGE.
Return Value
Returns the Registered Windows Message ID.
This function returns the latest LANC information from the specified device.
Syntax
BOOL GetLancStatusTimeCode(HANDLE LancDevice,
LPFRAMEDATA lpFrameData);
Parameters
HANDLE LancDevice
A Handle to the LANC device returned from OpenLancDevice or OpenLancDeviceEx.
LPTIMEDATA lpFrameData
A pointer to the FRAMEDATA structure for the Time Date information. If the returned elements are 0xFF then information is not available at that point of the tape.
Return Value
Returns TRUE is successful.
This function returns the tape time and date stamp from the specified device.
Syntax
BOOL GetLancTimeDateStamp(HANDLE LancDevice,
LPTIMEDATA lpTimeData);
Parameters
HANDLE LancDevice
A Handle to the LANC device returned from OpenLancDevice or OpenLancDeviceEx.
LPTIMEDATA lpTimeData
A pointer to the TIMEDATA structure for the Time Date information. If the returned elements are 0xFF then information is not available at that point of the tape.
Return Value
Returns TRUE is successful, else if time/date information is no transmit from the lanc device returns FALSE
This function sends a command to the specified device.
Syntax
BOOL SendLancCommand(HANDLE LancDevice,
BYTE MessageType,
BYTE Message);
Parameters
HANDLE LancDevice
A Handle to the lanc device returned from OpenLancDevice or OpenLancDeviceEx.
BYTE MessageType
Specifies the Type of Lanc Message such as Camera, Recorder. These values are defined in lanc.h COMMANDTYPE_commandtype
BYTE Message
Specifies the COMMAND Message. These values are defined in lanc.h COMMAND_command
Return Value
Returns TRUE is successful
This function sends a continuous command to the specified device.
Syntax
BOOL SendLancContinuousCommand(HANDLE LancDevice,
BYTE MessageType,
BYTE Message,
UINT Number);
Parameters
HANDLE LancDevice
A Handle to the lanc device returned from OpenLancDevice or OpenLancDeviceEx.
BYTE MessageType
Specifies the Type of Lanc Message such as Camera, Recorder. These values are defined in lanc.h COMMANDTYPE_commandtype
BYTE Message
Specifies the COMMAND Message. These values are defined in lanc.h COMMAND_command
UINT Number
Not used in this version of the DLL, must be NULL.
Return Value
Returns TRUE is successful
This function returns a string containing the status of the specified device.
Syntax
LPSTR GetStatusString(BYTE index);
Parameters
BYTE index
Specifies the Video Status.
Return Value
Returns a far pointer to a string which contains the Status of the Video.
This function closes the specified device.
Syntax
BOOL CloseLancDevice(HANDLE LancDevice);
Parameters
HANDLE LancDevice
A Handle to the lanc device returned from OpenLancDevice or OpenLancDeviceEx.
Return Value
Returns TRUE is successful.
This message is send to the application on receiving of a video Field.
Parameters
WPARAM wParam
The Handle to the LancDevice. Used to identify the origin of the message.
LPARAM lParam
Specifies a long pointer to a FRAMEDATA structure.
The FRAMEDATA structure holds complete Frame data. A LPRAMEDATA is a long pointer to the event.
typedef struct {
BYTE Status;
BYTE Hours;
BYTE Minutes;
BYTE Seconds;
BYTE Frames;
BYTE MinusSign;
BYTE Raw[8];
TIMEDATA DateTime;
} FRAMEDATA, FAR* LPFRAMEDATA;
Fields:
BYTE status
Specifies the status of the Video.
BYTE Hours
Specifies the Hours of the Frame.
BYTE Minutes
Specifies the Minutes of the Frame.
BYTE Seconds
Specifies the Seconds of the Frame.
BYTE Frames
Specifies the Frames of the Frame.
BYTE MinusSign
Specifies the sign of the frame number. 0 +ve, 1 -ve.
BYTE Raw[8]
Specifies the sign of the frame number. 0 +ve, 1 -ve.
TIMEDATA DateTime
The Date and Time Stamp information, synchronised to the current frame.
See TIMEDATA Structure.
The TIMEDATA structure holds the time and date stamp of the current tape position. A LPTIMEDATA is a long pointer to the event.
typedef struct {
BYTE Year;
BYTE Month;
BYTE Day;
BYTE Hours;
BYTE Minutes;
BYTE Seconds;
} TIMEDATA, FAR* LPTIMEDATA;
Fields:
BYTE Year
Specifies the Year of the tape TimeStamp.
BYTE Month
Specifies the Month of the tape TimeStamp.
BYTE Day
Specifies the Day of the tape TimeStamp.
BYTE Hours
Specifies the Hours of the tape TimeStamp.
BYTE Minutes
Specifies the Minutes of the tape TimeStamp.
BYTE Seconds
Specifies the Seconds of the tape TimeStamp.
If you use any part of the ToolKit you are required to provide the copyright acknowledgement by including the statement "Control-L Developer's ToolKit for Windows Copyright (c) 1997 - 2002, by AVIT Research ltd" in a manner visible to the user of your software, and included along with your copyright notice if you provide one.
The Control-L Developer's ToolKit and sample applications are provided on an "as is" basis. The author takes no responsibility for undesired events occurring from the use or misuse of the software.
The version here is release 2.4 and is available for fellow developers. The software will be continually under development and your requirements/feedback will be greatly received. If the software does not meet your application's needs then please don't hesitate to contact me as I may be able to help.
The software was all developed using the PAL standard (25fps) and has been adapted for the NTSC standard (30 fps).
Sincerely,
Adrian Verity