Control-L Developer's ToolKit for Windows

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.


Introduction

Overview

The Control-L Developer's ToolKit for Windows provides tool to assist programmers in developing Control-L applications for the Microsoft Windows operating environment.

Contents

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

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.

Opening a Lanc Device

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);
    if (rv)

        MessageBox(hWnd, "Could not open Lanc Device", "Error", MB_OK);    

    

    // Application Code
break;

1c. Windows Registered Message using OpenLancDeviceEx

HANDLE       MyLancDevice;

UINT         rv;

UINT         LancRegisteredMessage;

 

case WM_CREATE:

    rv = OpenLancDeviceEx(&MyLancDevice, "COM2", hWnd, LANCCALLBACK_REGISTERED_MESSAGE);
    if (rv)

        MessageBox(hWnd, "Could not open Lanc Device", "Error", MB_OK);    

    else

        LancRegisteredMessage = GetRegisteredLancMessage(MyLancDevice);

    // Application Code
break;

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;

Receiving Frame Information

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 
    //the Device the data belongs to.

    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 
        //the Device the data belongs to.

        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 
    //the Device the data belongs to.

    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

    }

Receiving Time Date Information

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

    }

Send Single Commands

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);

    }

Send Continuous Commands

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);

Closing a Lanc Device

To close the Driver use the CloseLancDevice() command eg.

    case WM_DESTROY:

        CloseLancDeive(MyLancDevice);

        PostQuitMessage(0);

        break;

 


Functions

OpenLancDevice

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.

OpenLancDeviceEx

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.

GetRegisteredLancMessage

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.

GetLancStatusTimeCode

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.

GetLancTimeDateStamp

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

SendLancCommand

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

SendLancContinuousCommand

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

GetStatusString

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.

CloseLancDevice

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.


Messages

MM_LANC_MESSAGE

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.


Structures

FRAMEDATA

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.

TIMEDATA

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.


Software License

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.

Warranty/Disclaimer

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.

Version/Standards

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