Audio API
Table of contents
- Overview: Available API Routes
- Upload
- Audio Information
- Download
- Delete
- List Audio IDs
- Prepare
- Inject
- Capture
- Audio Analysis: Match
Overview: Available API Routes
This API allows interaction with device's audio interface for supported devices in the user's device pool. It also performs audio analysis.
Method |
Route |
Notes |
POST |
/v0/audio/upload |
Upload an audio resource. |
GET |
/v0/audio/info |
Returns information about the audio_id . |
GET |
/v0/audio/{audio_id}/download?channels&start&end |
Returns the processed audio resource. |
DELETE |
/v0/audio/delete |
Delete an uploaded audio resource. |
GET |
/v0/audio/list |
Fetches all the audio_id s in the user's organization (with the option to filter by the tag field). |
POST |
/v0/audio/prepare |
Cache audio on a host to prepare it for subsequent inject or live analysis requests. |
POST |
/v0/audio/inject/start |
Starts a worker to inject a 'prepared' audio_id into a device. |
GET |
/v0/audio/inject/status |
Returns the status of an inject worker. |
GET |
/v0/audio/inject/wait |
A blocking request that returns the status of an inject worker once it has run to completion. |
POST |
/v0/audio/inject/stop |
Stops an active inject worker. |
POST |
/v0/audio/capture/start |
Starts a worker to capture audio from a device and upload it to a central storage repo. |
GET |
/v0/audio/capture/status |
Returns the status of a capture worker. |
GET |
/v0/audio/capture/wait |
A blocking request that returns the status of a capture worker once it has run to completion. |
POST |
/v0/audio/capture/stop |
Stops an active capture worker. |
POST |
/v0/audio/analysis/match |
Finds the reference in the test and returns the match metrics. |
Upload
External audio resources can be uploaded with the option to add tags. Successful uploads will return a unique <code class="dcode">audio_id</code>. The API supports only WAV type audio -- the upload will fail if the audio file is incompatible or invalid.
Method |
Route |
POST |
/v0/audio/upload |
Example
curl --request POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/audio/upload?tag=helpful-tag --data-binary "@/path/to/your/audio.wav"
Response
{
"success": true,
"audio_id": "313f6795-df6d-4ffa-ba86-7b98f07b4a8d"
}
Audio Information
For a given <code class="dcode">audio_id</code>, information and metadata (such as the tag, the number of channels, samplerate, duration, etc) can be requested.
Method |
Route |
GET |
/v0/audio/info |
Example
curl -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/audio/313f6795-df6d-4ffa-ba86-7b98f07b4a8d/info
Response
{
"success": true,
"audio_id": "313f6795-df6d-4ffa-ba86-7b98f07b4a8d",
"tag": "helpful-tag",
"ts_created": 1526337362,
"channels": 2,
"samplerate": 48000,
"format": "WAV",
"frames": 960000,
"duration": 20
}
Download
The API allows downloading with optional processing. Without the optional parameters, the format, number of channels, samplerate, and duration of the returned resource will be as detailed by the <code class="dcode">/v0/audio/{audio_id}/info</code> request.
Optional processing allows for channel manipulation and time slicing to extract a single segment.
The <code class="dcode">channels</code> parameter allows down-mixing or masking -- valid options include <code class="dcode">mono</code>, <code class="dcode">left</code>, <code class="dcode">right</code> and <code class="dcode">stereo</code>. If you require a single channel stream, the <code class="dcode">left</code> or <code class="dcode">right</code> value is recommended over <code class="dcode">mono</code>. Generally, down-mixing to mono does not produce the intended result if there is stereo separation in the original signal.
The <code class="dcode">start</code> and <code class="dcode">end</code> parameters allow extraction of a segment. Suppose the sample is long and some subset of the sample is required for post-processing. Then the subset can be extracted by providing a <code class="dcode">start</code> and <code class="dcode">end</code> time in seconds in the request.
Method |
Route |
GET |
/v0/audio/{audio_id}/download?channels&start&end |
You can use the <code class="dcode">-O/--remote-name</code>
option in curl in combination with <code class="dcode">-J/--remote-header-name</code>
to write to a file with the filename provided in the <code class="dcode">Content-Dispositio</code>
response header.
Example 1: Download without any processing
curl --remote-name --remote-header-name -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/audio/313f6795-df6d-4ffa-ba86-7b98f07b4a8d/download
Response 1
Outputs to file <code class="dcode">313f6795-df6d-4ffa-ba86-7b98f07b4a8d.wav.</code>
Example 2: Download after down-mixing to mono
curl --remote-name --remote-header-name -H "Authorization: Bearer <your_api_token>" "https://api-dev.headspin.io/v0/audio/313f6795-df6d-4ffa-ba86-7b98f07b4a8d/download?channels=mono"
Response 2
Outputs to file <code class="dcode">313f6795-df6d-4ffa-ba86-7b98f07b4a8d channels(mono).wav.</code>
Example 3: Download after selecting only the left channel and slicing from 2 seconds to the end
curl --remote-name --remote-header-name -H "Authorization: Bearer <your_api_token>" "https://api-dev.headspin.io/v0/audio/313f6795-df6d-4ffa-ba86-7b98f07b4a8d/download?channels=left&start=2"
Response 3
Outputs to file <code class="dcode">313f6795-df6d-4ffa-ba86-7b98f07b4a8d channels(left) start(2).wav</code>.
Example 4: Download after selecting only the right channel and slicing from 3.14 to 15.456 seconds
curl --remote-name --remote-header-name "https://<your_api_token>@api-dev.headspin.io/v0/audio/313f6795-df6d-4ffa-ba86-7b98f07b4a8d/download?channels=right&start=3.14&end=15.456"
Response 4
Outputs to file <code class="dcode">313f6795-df6d-4ffa-ba86-7b98f07b4a8d channels(right) start(2) end(15.456).wav</code>.
Delete
Delete an uploaded audio resource for a given <code class="dcode">audio_id</code>.
Method |
Route |
DELETE |
/v0/audio/delete |
Example
curl -X DELETE -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/audio/313f6795-df6d-4ffa-ba86-7b98f07b4a8d/delete
Response
List Audio IDs
This API endpoint fetches all the audio_ids that exist in the user's organization. You can optionally filter the results by the values of the tag field. The MySQL LIKE operator is used for filtering, which means the two wildcards (% and _) can be used to search for a specified pattern in the tag field (if you're unfamiliar with the usage of wildcards, click here to see examples).
Method |
Route |
GET |
/v0/audio/list?tag |
Example 1: List audio ids that exactly match "helpful-tag" in the tag field
curl -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/audio/list?tag=helpful-tag
Response 1
{
"audio_ids": [
"9e22786d-f7df-4c4a-b601-384bc2b06ae9",
"5eca0c4c-f54f-49f6-9d03-64db261b7e23"
],
"success": true
}
Example 2: List audio ids that contain "help" in any position in the tag field
curl -X GET -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/audio/list --data-urlencode "tag=%help%"
Response 2
{
"audio_ids": [
"9e22786d-f7df-4c4a-b601-384bc2b06ae9",
"5eca0c4c-f54f-49f6-9d03-64db261b7e23"
],
"success": true
}
Prepare
Audio resources are not stored on a host, but they will need to be cached on the host in order to inject audio into a device on that host. A prepare request will block while attempting to cache audio_ids, and return once caching is complete.
Method |
Route |
POST |
/v0/audio/prepare |
Request Body
The request body must be a JSON object with the <code class="dcode">hostname</code> and <code class="dcode">audio_ids</code> fields, as shown in the following example:
{
"hostname": "host.headspin.io",
"audio_ids": [
"6fd55663-0aa4-416e-a752-cfab81a13701",
"6c63cccb-5914-414c-96f5-fd9234147102",
"375051e0-01e6-4dbb-9e4b-017a411ab7c6"
]
}
Example
curl --request POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/audio/prepare --data '{"hostname": "host.headspin.io", "audio_ids": ["6fd55663-0aa4-416e-a752-cfab81a13701", "6c63cccb-5914-414c-96f5-fd9234147102", "375051e0-01e6-4dbb-9e4b-017a411ab7c6"]}'
Response
{
"success": false,
"audio_ids": {
"6fd55663-0aa4-416e-a752-cfab81a13701": "cached",
"6c63cccb-5914-414c-96f5-fd9234147102": "cached",
"375051e0-01e6-4dbb-9e4b-017a411ab7c6": "error"
}
}
Note that <code class="dcode">success</code> is <code class="dcode">false</code> if any of the <code class="dcode>audio_ids</dcode> failed to cached.
Inject
Only prepared audio resources can be injected into a device via an inject worker running on the host. A successful start request returns a <code class="dcode">worker_id</code> which can be used to poll for status updates or prematurely stop the worker.
Start inject worker
Method |
Route |
POST |
/v0/audio/inject/start |
Request Body
The request body must be a JSON object with the <code class="dcode">device_address</code> and <code class="dcode">audio_id</code> fields, as shown in the following example:
{
"device_address": "my_device@host.headspin.io",
"audio_id": "6fd55663-0aa4-416e-a752-cfab81a13701"
}
- <code class="dcode">device_address</code> has the following structure: <code class="dcode">device_id@hostname</code>.
- <code class="dcode">device_id</code> must be a device on the host which has been configured to support audio, and <code class="dcode">hostname</code> must be in the user's pool.
- <code class="dcode">audio_id</code> must be made available for the worker on the host with a prepare request in advance.
- <code class="dcode">use_hsp</code> if set to true, two calls to /v0/bluetooth/mode are made before and after the audio sample plays, the first to turn on HSP mode and the second to turn it off again. This can be useful on some Android devices where audio injection only works in HSP mode, see the bluetooth API for details. (Using this option instead of the bluetooth API saves the roundtrip time of two separate API calls and can be slightly faster.)
A/V box
When the audio is played back on an A/V box it is advisable to use the A/V box API directly. As a special case in an Appium session /audio/inject/start will work as long as the headspin:audio.device capability is set to either "front" or "back". (See Appium capabilities.)
Example
curl --request POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/audio/inject/start --data '{"device_address": "my_device@host.headspin.io", "audio_id": "6fd55663-0aa4-416e-a752-cfab81a13701"}'
Response
If the request is successful, a <code class="dcode">worker_id</code> is returned in the response.
{
"success": true,
"worker_id": "6c7d6c1b27a147a2af48be263ea9a517"
}
Status of inject worker
The worker can be polled for live status updates. In general, workers can have any number of defined tasks which can have any of the following states: <code class="dcode">waiting</code>, <code class="dcode">working</code>, <code class="dcode">finished</code>, or <code class="dcode">error</code>. The inject worker has only one task, <code class="dcode">inject</code>.
Method |
Route |
GET |
/v0/audio/inject/status |
Example
curl -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/audio/inject/6c7d6c1b27a147a2af48be263ea9a517/status
Response 1: Worker at the <code class="dcode">inject</code> stage in <code class="dcode">working</code> state
{
"success": true,
"finished": false,
"hostname": "host.headspin.io",
"device_id": "my_device",
"audio_id": "6fd55663-0aa4-416e-a752-cfab81a13701",
"start_time": 1524884246,
"end_time": null,
"inject": {
"state": "working"
}
}
Response 2: Worker at the <code class="dcode">inject</code> stage that has finished
{
"success": true,
"finished": true,
"hostname": "host.headspin.io",
"device_id": "my_device",
"audio_id": "6fd55663-0aa4-416e-a752-cfab81a13701",
"start_time": 1524884246,
"end_time": 1524884557,
"inject": {
"state": "finished"
}
}
Wait for inject worker
When starting an inject worker, your test may need to wait for the worker to finish before proceeding. While this can be achieved by polling status, a simpler and more direct approach is to make a <code class="dcode">wait</code> request. A <code class="dcode">wait</code> request will block until the worker has run to completion and will then respond with the status. It is important to configure your client to correctly handle timeouts in the case of long-running workers.
The status of a worker will be cached once it runs to completion, but the cache will expire if the status is not accessed for 7 days. If the worker has already finished and its status is cached, the request will return immediately.
Method |
Route |
GET |
/v0/audio/inject/wait |
Example
curl -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/inject/6c7d6c1b27a147a2af48be263ea9a517/wait
Response
{
"success": true,
"finished": true,
"hostname": "host.headspin.io",
"device_id": "my_device",
"audio_id": "6fd55663-0aa4-416e-a752-cfab81a13701",
"start_time": 1524884246,
"end_time": 1524884557,
"inject": {
"state": "finished"
}
}
Stop inject worker
The worker can only be stopped at the <code class="dcode">inject</code> stage and in the <code class="dcode">working</code> state.
Method |
Route |
POST |
/v0/audio/inject/stop |
Note that this is a <code class="dcode">POST</code> request with no payload.
Example
curl --request POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/audio/inject/6c7d6c1b27a147a2af48be263ea9a517/stop
Response
Capture
This API allows high-quality capture from a device which is then uploaded to a storage system and made available to other users in your organization. A successful start request returns a <code class="dcode">worker_id</code> which can be used to poll for status updates or prematurely stop the worker.
Start capture worker
Method |
Route |
POST |
/v0/audio/capture//start |
Request Body
The request body must be a JSON object with the required device_address and max_duration fields, as shown in the following example:
{
"device_address": "my_device@host.headspin.io",
"max_duration": 300,
"tag": "a helpfully descriptive tag"
}
- <code class="dcode">device_address</code> has the following structure: <code class="dcode">device_id@hostname</code>.
- <code class="dcode">device_id</code> must be a device on the host which has been configured to support audio, and <code class="dcode">hostname</code> must be in the user's pool.
- <code class="dcode">max_duration</code> is defined in seconds and must be within a valid range. The worker will stop capturing after this duration if it has not already been stopped.
- <code class="dcode">tag</code> is optional; it can be used as a non-unique reference to the capture audio resource.
Example
curl --request POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/audio/capture/start --data '{"device_address": "my_device@host.headspin.io", "max_duration": 300, "tag": "a helpfully descriptive tag"}'
Response
{
"success": true,
"worker_id": "139a1bbc22304dda8cbb7c6085c43580"
}
Status of capture worker
The worker can be polled for live status updates. In general, workers can have any number of defined tasks which can have any of the following states: <code class="dcode">waiting</code>, <code class="dcode">working</code>, <code class="dcode">finished</code>, or <code class="dcode">error</code>. The capture worker has two tasks, <code class="dcode">capture</code> and <code class="dcode">upload</code>.
Method |
Route |
GET |
/v0/audio/capture/status |
Example
curl -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/audio/capture/139a1bbc22304dda8cbb7c6085c43580/status
Response 1: Worker at the <code class="dcode">capture</code> stage in <code class="dcode">working</code> state
{
"success": true,
"finished": false,
"hostname": "host.headspin.io",
"device_id": "my_device",
"audio_id": null,
"start_time": 1524884246,
"max_duration": 300,
"end_time": null,
"capture": {
"state": "working"
},
"upload": {
"state": "waiting"
}
}
Response 2: Worker at the <code class="dcode">upload</code> stage in the <code class="dcode">working</code> state
{
"success": true,
"finished": true,
"hostname": "host.headspin.io",
"device_id": "my_device",
"audio_id": "db34e55a-e996-4dd5-85bf-d7682630932d",
"start_time": 1524884246,
"end_time": 1524884546,
"capture": {
"state": "finished"
},
"upload": {
"state": "working"
}
}
Wait for capture worker
When starting a capture worker, your test may need to wait for the worker to finish before proceeding. While this can be achieved by polling status, a simpler and more direct approach is to make a <code class="dcode">wait</code> request. A <code class="dcode">wait</code> request will block until the worker has run to completion and will then respond with the status. It is important to configure your client to correctly handle timeouts in the case of long-running workers.
The status of a worker will be cached once it runs to completion, but the cache will expire if the status is not accessed for 7 days. If the worker has already finished and its status is cached, the request will return immediately.
Method |
Route |
GET |
/v0/audio/capture/wait |
Example
curl -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/audio/capture/139a1bbc22304dda8cbb7c6085c43580/wait
Response
{
"success": true,
"finished": true,
"hostname": "host.headspin.io",
"device_id": "my_device",
"audio_id": "db34e55a-e996-4dd5-85bf-d7682630932d",
"start_time": 1524884246,
"end_time": 1524884546,
"capture": {
"state": "finished"
},
"upload": {
"state": "working"
}
}
Stop capture worker
The worker can only be stopped while at the <code class="dcode">capture</code> stage and in the <code class="dcode">working</code> state.
Method |
Route |
POST |
/v0/audio/capture/stop |
Note that this is a <code class="dcode">POST</code> request with no payload.
Example
curl --request POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/audio/capture/139a1bbc22304dda8cbb7c6085c43580/stop
Response
Audio Analysis: Match
The match API finds the reference in the test and outputs a match score, a prominence ratio, and start and end times of the reference relative to the test. Note that in this API, we define reference as the "ground truth" (original audio resource) and test as the longer, captured audio that contains the reference.
The intended usage of this analysis is to find an exact audio match between two audio files. It can be used to locate the reference in the test and/or compare the quality of the test relative to the reference. The algorithm finds the alignments of the reference in the test by sliding the former across the latter and calculating how similar the audio is between the two at each sliding window.
While the analysis does not do speech detection or word recognition, it is not limited to voice and works for any type of sound.
The current version of the analysis API is optimized for tests shorter than 5 minutes and references shorter than 40 seconds.
If you're looking to run the audio match analysis on sessions that have audio, please refer to Audio Match Analysis in the Session Analysis API.
Method |
Route |
POST |
/v0/audio/analysis/match |
Request Body
The request body must be a JSON object with the following keys:
test_audio_id
: audio_id
of the test.
ref_audio_id
: audio_id
of the reference.
match_status_thresholds
: (optional) A JSON object with the following keys:
full
: Threshold used for determining full
match status.
match_score
: Must be a value between 0 and 1.
prominence_ratio
: Must be a value >= 1. See Response Explained below for more details.
partial
: Thresholds used for determining partial
match status. Must meet both thresholds to be partial
match.
match_score
: Must be a value between 0 and 1 and smaller than the threshold used for full
match.
prominence_ratio
: Must be a value >= 1. See Response Explained below for more details.
If no <code class="dcode">match_status_thresholds</code> is provided, then the the following default thresholds will be used:
{
"full": {"match_score": 0.9, "prominence_ratio": 1.0},
"partial": {"match_score": 0.4, "prominence_ratio": 1.5}
}
An example body with default <code class="dcode">match_status_thresholds</code>:
{
"test_audio_id": "6fd55663-0aa4-416e-a752-cfab81a13701",
"ref_audio_id": "6c63cccb-5914-414c-96f5-fd9234147102"
}
An example body with custom <code class="dcode">match_status_thresholds</code>:
{
"test_audio_id": "6fd55663-0aa4-416e-a752-cfab81a13701",
"ref_audio_id": "6c63cccb-5914-414c-96f5-fd9234147102",
"match_status_thresholds": {
"full": {"match_score": 0.8, "prominence_ratio": 1.0},
"partial": {"match_score": 0.5, "prominence_ratio": 1.3}
}
}
Note that if using custom <code class="dcode">match_status_thresholds</code>, all four thresholds must be provided -- e.g., using <code class="dcode">"match_status_thresholds": {"full": {"match_score": 0.8, "prominence_ratio": 1.1}, "partial": {"match_score": 0.5}}"</code> will result in an error.
Example
curl --request POST -H "Authorization: Bearer <your_api_token>" https://api-dev.headspin.io/v0/audio/analysis/match --data '{"test_audio_id": "6fd55663-0aa4-416e-a752-cfab81a13701", "ref_audio_id": "6c63cccb-5914-414c-96f5-fd9234147102"}'
Response: Non-200 Status Codes
Shown below are example responses from unsuccessful POST requests:
Status Code |
Status |
Recommended Action |
400 |
The 'prominence_ratio' threshold is not defined for 'partial' match. |
Check your custom match_status_thresholds . |
500 |
Request timed out waiting for audio match. |
Retry. |
500 |
Failed to retrieve the audio match result. |
Retry. |
Response: 200 Status Code & <code class="dcode">success</code> is <code class="dcode">false</code>
{
"success": false,
"error_message": "empty test audio",
"test_audio_id": "6fd55663-0aa4-416e-a752-cfab81a13701",
"ref_audio_id": "6c63cccb-5914-414c-96f5-fd9234147102"
}
Response (for <code class="dcode">success</code> is <code class="dcode">false</code>) Explained
Response: 200 Status Code & <code class="dcode">success</code> is <code class="dcode">true</code>
{
"success": true,
"version": "0.1.0",
"test_audio_id": "6fd55663-0aa4-416e-a752-cfab81a13701",
"parameters": {
"sr_at_analysis": 8000,
"nfft": 512,
"match_status_thresholds": {
"full": {"match_score": 0.9, "prominence_ratio": 1.0},
"partial": {"match_score": 0.4, "prominence_ratio": 1.5}
}
},
"result": {
"6c63cccb-5914-414c-96f5-fd9234147102": {
"match_status": "no",
"match_score": 0.139,
"prominence_ratio": 1.013,
"start_time": null,
"end_time": null,
"precision_status": "medium",
"poverlap": 0.625,
"error_msg": null,
"analysis_processing_time": 9.824
}
}
}
Response (for <code class="dcode">success</code> is <code class="dcode">true</code>) Explained
-
success
: Returns true
since the analysis successfully completed on the provided audio ids (regardless of match_status
).
-
parameters
:
sr_at_analysis
: Sampling rate to which reference and test are resampled before analysis. Set at 8000.
nfft
: The number of samples used in each block for Fast Fourier Transform (FFT). Set at 512.
match_status_thresholds
:
full
:
match_score
: Match score threshold for full
match. Defaults to 0.9.
prominence_ratio
: Prominence ratio threshold for full
match. Defaults to the minimum possible value of 1 (full
match status is determined purely from match_score
).
partial
:
match_score
: Match score threshold for partial
match. Defaults to 0.4.*
prominence_ratio
: Prominence ratio threshold for partial
match. Defaults to 1.5.*
*Returns partial
match in match_status
only if conditions are met on both thresholds.
E.g., under the default settings, if match_score
is 0.5 but prominence_ratio
is 1.0, then this is classified as no
match.
-
result
:
-
match_status
| full
, partial
, no
, or error
: Status of match as set by match_score
and the thresholds.
Returns error
if precision_status
is critically low
or if the reference is not contained in the test (start_time
or end_time
is null
).
-
match_score
| 0 <= match_score
<= 1: Quality of match when best aligned (max correlation coefficient).
-
prominence_ratio
| >= 1: Quality of match relative to noise (ratio of the max correlation coefficient to the 2nd max).
This number is ~1 if there is no match, but can also be ~1 if there is a match and the reference is repeated in the test.
Because prominence_ratio
is the ratio of the max correlation coefficient to the second max, the minimum possible value is 1.
-
start_time
| sec or null
: Start time (in seconds) of the reference in terms of the test (at best alignment).
Returns null
if match_status
is no
(when there is no match).
Also returns null
if start_time < 0
(i.e., reference starts before the test & therefore not contained in the test), in which case match_status
is set as error
.
-
end_time
| sec or null
: End time (in seconds) of the reference in terms of the test (at best alignment).
Returns null
if match_status
is no
(when there is no match).
Also returns null
if end_time
exceeds the duration of the test (i.e., reference is not contained in the test), in which case match_status
is set as error
.
-
precision_status
| high
, medium
, low
, or critically low
: Status of precision as set by poverlap
.
Returns critically low
if poverlap
drops below 0.25 which also sets match_status
as error
.
-
poverlap
: 0 <= poverlap
<= 0.9: % of overlap used between FFT blocks.
Based on the size of the reference and the test, this parameter is automatically adjusted to keep the analysis processing time under ~10s.
You can compare to the initial value of 0.9 to see how much precision has dropped.
-
error_msg
: Reason(s) for match_status
returning error
.
Returns reference is out of bounds
if either start_time
or end_time
is null
due to the reference not being contained in the test.
Returns precision is too low
if precision_status
is critically low
.
If both conditions are met, then both error messages are displayed.