# Programming

## Introduction

The Voicetronix cards are programmed via the VPB Application Programmer Interface (VPBAPI, or just API). This is a set of C callable functions. The following sections describe the VPBAPI in detail, and also include examples of the API functions in action. It is recommended that the user browse the header file vpbapi.h to gain an overview of the API.

## Compiling with the VPBAPI

### Linux and FreeBSD

Simply link `libvpb.a` with your application:

    $  gcc test.cpp -o test -Wall -g -lvpb -pthread -lm

### Windows

1. Create a new project (e.g. Win32 Console Application) and insert your source files.

2. Project-Settings-C/C++:

   - set "Category" to "Code Generation"

   - set "Use run-time library:" to "Debug Multithreaded"

3. Project-Settings-Link:

   - To the "Object/library modules" add `../debug/libvpb.lib` (you might need to change the path to `libvpb.lib`, depending on where you create your project).

4. Build your project.

5. Make sure `libvpb.dll` and `plxapi.dll` are in your path before running. One way is to set the Project-Settings-Debug-Working Directory to a directory containing the DLL, or place the DLL in a directory in your path (e.g. `c:\winnt\system32`)

6. Set the path for the firmware. The firmware is called `vpbmain_pci.out`, and is in `vpb-driver/firmware/`. There are two ways to set the path:

   - Modify `vpbreg.cpp`, change the `#define FIRMWARE_FILE_PCI` to your path and recompile `libvpb.dll` (see `Readme.Win32.txt` for information on how to recompile the driver).

   - Set an environment variable `VPB_FIRMWARE` to the path to the firmware file. Under NT go to control panel-system-environment. After setting the env. variable, you will need to restart MSVC before running so that the new env. variable is available to MSVC.

7. You should now be able to run your program from MSVC.

## Initialization and Shutdown

This section describes the "housekeeping" functions used to initialize and shutdown a Voicetronix card. The initialization function `vpb_open()` must be called before any other API functions will work:

## Initialization and Shutdown

    void main() {
            handle = vpb_open(1, 2);
            vpb_close(handle);
    }

This program demonstrates initialization and shutdown of a single channel, (number 2), on the first board in the system. Each channel (or port) of the card has an associated number. On the OpenLine4 card, channel 1 is the port furthest from the motherboard. Port 4 is closest to the motherboard.

The `vpb_open()` function returns a handle to the open channel. This handle then provides a reference to all other operations with this channel. A call to `vpb_open()` is required for each channel that is to be used. If a channel is not opened, then no operations can be performed with that channel.

## Error Handling

Under certain conditions the API functions will be unable to successfully execute. In this case an error condition will occur that requires handling by code outside of the API. The API provides three modes of error handling:

- Exceptions

- Error codes

- Debug

The current error mode is set using the `vpb_seterrormode()` function. The default error mode is `Debug`.

## Debug

If an error occurs in this mode, the program stops execution immediately and prints an error message. This is useful during debugging as it brings any problems to the programmer's immediate attention. However, such behavior is obviously not desirable in release versions of the software. Note that this mode is only suitable for console mode programs, it will cause the program to hang when used with a windows program.

## Error Codes

In this case the function returns an integer corresponding to the nature of the error. The convention used by the API is that positive numbers and zero indicate successful function completion, and negative numbers represent an error condition. The error codes for the API functions are listed in `vpberr.h`. There are other, undocumented error codes that lower levels of the API software may return, but these are not defined in `vpberr.h`. These errors should not occur during normal operation.

## Exceptions

Exceptions are a form of error handling supported by C++. When an error occurs, an exception is "thrown". In the case of the VPBAPI , the exception is a class `VpbException` that contains information describing the error. The code member of the class corresponds to an error number defined exactly the same way as in the error code error handling method. The other members contain strings describing the API function that generated the error and a brief translation of the error code. The user must provide code to catch the exception at some level in their program. The advantage of exceptions is that it is not necessary to trap errors at every API call, which can become tedious from a programming point of view, especially for API calls deep within nested function calls. Consider the following code fragments, first using error codes:

### Error Handling Using Error Codes

    vpb_seterrormode(VPB_ERROR_CODE);

    // Attempt to open channel 1

    if ((handle1 = vpb_open(1,1)) != VPB_OK) {
            printf("Error, code = %d\n",handle1);
            exit(0);
    }

    // Attempt to open channel 2

    if ((handle2 = vpb_open(1,2)) != VPB_OK) {
            printf("Error, code = %d\n",handle2);
            exit(0);
    }

And now using exceptions:

### Error Handling Using Exceptions

    try {
            vpb_seterrormode(VPB_EXCEPTION);
            handle1 = vpb_open(1,1);
            handle2 = vpb_open(1,2);
    }

    catch (VpbException v) {
            printf("Error, code = %d, s = %s, api func = %s\n", v.code,
                   v.s, v.api_function);
            exit(0);
    }

Using exceptions enables the programmer to send all run time errors to a single point in the code, removing the need for handling errors after every API call. If the current function does not have try/catch exception handling, then the compiler aborts the current function, climbing up the "call stack" until an exception handler is found in a calling function. If no exception handler is found in the calling functions, the program aborts. For more information on exceptions, see a C++ text, or your C++ compiler on-line documentation.