Skip to content

Listening Point Coordinate Constraints and Transmission

This document explains the index coordinate system, minimum distance constraints, and the 40×15 index compression/restoration rules for API transmission required to set BATCAM FX Listening Points (LPoint) through the API or display them on screen. All code that handles LPoint indices must follow the coordinate system rule described in this document (bottom-right origin).

The BF Map of a Beamforming event delivered by BATCAM FX is structured as 40x30 and is transmitted as a 1x1200 array.

Example view of a BF Map visualized over BATCAM FX RTSP video. The green area is a Listening Point set as an example

Illustration assuming a BF Map is visualized over BATCAM FX RTSP video. The green area is a Listening Point assumed to be set as an example.

The BATCAM FX LPoint feature supports up to 3 points. The beamformed audio signal at each specified position is transmitted through the LPointAudio message (ROS topic /fx_{hardware_id}/lpoint_audio, channels lpoint0~lpoint2). For the message structure, see the ROS integration guide.

Index Coordinate System

LPoints represent positions on the 40×30 2D grid as one-dimensional indices (0~1199).

⚠️ Coordinate system warning: In the BATCAM FX BF Map index, the bottom-right is 0 and the top-left is 1199. This is the opposite of the common top-left-origin (0) coordinate system, so the 1199 - n conversion is mandatory when compressing/restoring. Computing n % 40, n / 40 directly without this conversion produces incorrect results.

The index starts at the bottom-right (0) and increases to the left; when one row (40 cells) ends, it moves up one row. In other words, if you compute the grid coordinates as x = n mod 40, y = ⌊n / 40⌋, x increases from right to left and y increases from bottom to top. The four corner indices are as follows.

PositionIndex
Bottom-right0
Bottom-left39
Top-right1160
Top-left1199

Constraints

When setting Listening Points, two points must not be too close to each other.

The current BATCAM FX LPoint configuration enforces the following minimum distance constraints:

  • Horizontal: at least ±2 cells apart

  • Vertical: at least ±2 cells apart

In other words, once a Listening Point is set, no area within 2 cells of it horizontally or vertically can be used for another Listening Point.

For example, suppose the following Listening Points are set (x and y below are grid coordinates computed as x = n mod 40, y = ⌊n / 40⌋ — bottom-right origin):

  • Listening Point A: index 20 (x=20, y=0)

  • Listening Point B: index 580 (x=20, y=14)

Around these two Listening Points, the following restricted areas apply:

  • Around A: 18 ≤ x ≤ 22, 0 ≤ y ≤ 2 (negative y is outside the grid, so the range is clipped at 0)

  • Around B: 18 ≤ x ≤ 22, 12 ≤ y ≤ 16

Within these ranges, do not set additional Listening Points.

LPoint Index Compression and Restoration for API Use

For API requests, you must convert the index to a 40×15 form with the vertical resolution halved (index 0599) before sending. Since firmware v1.0.2d, the allowed lpoint index range of the beamforming setting API has changed from 01199 to 0~599 (see the firmware release notes).

Use the following formulas to perform compression (Downsize) and restoration (Upsize).

💡 Note: Compression halves the vertical resolution, so information can be lost. If you need coordinate precision, keep the original index separately before compressing. For details on the loss/restoration rules, see the Limitations and Boundary Values section below.

Index Compression (Downsize)

Converts a one-dimensional index n (0~1199) to the 40×15 grid.

Invert the coordinate system (1199 - n), then halve the vertical resolution to compress the y coordinate.

Formula:

f(n)=401199n402+((1199n)mod40)f(n) = 40 \cdot \left\lfloor \frac{\left\lfloor \frac{1199 - n}{40} \right\rfloor}{2} \right\rfloor + ((1199 - n) \bmod 40)

Examples:

  • f(120) → 559

  • f(600) → 319

  • f(1160) → 39

Index Restoration (Upsize)

Restores a compressed index to the original 40×30 grid.

Of the two rows merged during compression, restoration uses the upper row (y * 2) as the reference, then inverts the coordinate system again.

Formula:

f1(n)=1199(40(2n40)+(nmod40))f^{-1}(n) = 1199 - \left(40 \cdot (2 \cdot \left\lfloor \frac{n}{40} \right\rfloor) + (n \bmod 40)\right)

Examples:

  • f⁻¹(559) → 120

  • f⁻¹(319) → 600

  • f⁻¹(39) → 1160

Usage Summary

SituationFunctionDescription
Sending coordinates in an API requestDownsize40×30 → 40×15 compression
Displaying coordinates on the user screenUpsize40×15 → 40×30 restoration

The equivalent code in each language is as follows.

Swift

extension Int {
func lPointDownSized() -> Int {
let value = 1199 - self
let x = value % 40
let y = value / 40
let downY = y / 2
return downY * 40 + x
}
func lPointUpSized() -> Int {
let x = self % 40
let y = self / 40
let upY = y * 2
return 1199 - (upY * 40 + x)
}
}

Python

def l_point_down_sized(n: int) -> int:
value = 1199 - n
x = value % 40
y = value // 40
down_y = y // 2
return down_y * 40 + x
def l_point_up_sized(n: int) -> int:
x = n % 40
y = n // 40
up_y = y * 2
return 1199 - (up_y * 40 + x)

C#

public static class LPointExtensions
{
public static int LPointDownSized(this int n)
{
int value = 1199 - n;
int x = value % 40;
int y = value / 40;
int downY = y / 2;
return downY * 40 + x;
}
public static int LPointUpSized(this int n)
{
int x = n % 40;
int y = n / 40;
int upY = y * 2;
return 1199 - (upY * 40 + x);
}
}

C++

int lPointDownSized(int n) {
int value = 1199 - n;
int x = value % 40;
int y = value / 40;
int downY = y / 2;
return downY * 40 + x;
}
int lPointUpSized(int n) {
int x = n % 40;
int y = n / 40;
int upY = y * 2;
return 1199 - (upY * 40 + x);
}

API Transmission

Send the converted LPoint index as the index_l parameter of the beamforming setting API. The BATCAM FX device serves the API directly (base URL http://{device_ip}), and authentication uses Basic auth.

ItemDescription
Get settingsGET /beamforming/setting — Returns the current beamforming settings; the index_l in the response is an array of 3 integers.
Update settingsPATCH /beamforming/settingmultipart/form-data is the required request format.
index_l request formatComma-separated string of 3 L point values (e.g. 20,510,579)
CautionPartial settings are not applied, so you must send the full set of values. First fetch the current settings with GET, then modify only index_l and resend everything.
Error responsePassing an invalid lpoint parameter returns a 400 response (error: 1, message: lpoint parameter error).

On success, the response is returned in an envelope structure:

{
"error": 0,
"result": {
"autogain": true,
"gain": 100,
"x_cal": -0.06,
"y_cal": 0,
"distance": 1,
"high_cut": 45000,
"low_cut": 2000,
"index_l": [20, 510, 579]
}
}

The full request/response schema and live call testing are available in the FX API Playground, under the beamforming group. For the properties of each beamforming setting, including index_l, see the beamforming parameters guide.

Limitations and Boundary Values

Vertical resolution compression is lossy. Because each of the provided compression and restoration functions halves only the vertical direction, two originally different indices can map to the same value. For example, 0 and 40 both become 599 when compressed, and 1159 and 1199 both become 0.

The restoration function always restores based on the upper line. When restoring a compressed index, the restoration function uses the upper (y * 2) row of the two possible original rows as the reference, then inverts the coordinate system again (1199 - result).

As a result, when displaying API responses or results, the position may be slightly offset from what the user perceives. If exact restoration is required, you may need to store the original coordinate information separately before compression.

Boundary Value Handling Summary

In the table below, Perfect restoration indicates whether the original input index comes back unchanged after compression (Downsize) followed by restoration (Upsize). For example, 0 is compressed to 599 and then restored to 40, so it is ❌; 40 is compressed to the same 599 but restores back to 40, so it is ✅.

InputCompressed resultRestored resultPerfect restoration
059940❌ (collision possible)
4059940
115901199❌ (collision possible)
1160391160
119901199

In general, indices on even y rows in the inverted coordinate system (1199 - n) are restored perfectly.