aboutsummaryrefslogtreecommitdiffstats
path: root/tests/codec
diff options
context:
space:
mode:
Diffstat (limited to 'tests/codec')
-rw-r--r--tests/codec/codec_ecu_fr_test.c6
-rw-r--r--tests/codec/codec_ecu_fr_test.ok84
-rw-r--r--tests/codec/codec_efr_sid_test.c97
-rw-r--r--tests/codec/codec_efr_sid_test.in183
-rw-r--r--tests/codec/codec_efr_sid_test.ok175
-rw-r--r--tests/codec/codec_fr_sid_test.c97
-rw-r--r--tests/codec/codec_fr_sid_test.in184
-rw-r--r--tests/codec/codec_fr_sid_test.ok175
-rw-r--r--tests/codec/codec_hr_sid_test.c144
-rw-r--r--tests/codec/codec_hr_sid_test.in61
-rw-r--r--tests/codec/codec_hr_sid_test.ok40
11 files changed, 1201 insertions, 45 deletions
diff --git a/tests/codec/codec_ecu_fr_test.c b/tests/codec/codec_ecu_fr_test.c
index 4040ce94..4e5b71d7 100644
--- a/tests/codec/codec_ecu_fr_test.c
+++ b/tests/codec/codec_ecu_fr_test.c
@@ -151,7 +151,7 @@ void test_fr_concealment_core(void)
int i, rc;
int j = 0;
- printf("=> Testing FR concealment (simple, consecutive bad frames)\n");
+ printf("=> Testing FR concealment (simple, using ECU abstraction)\n");
while (sample_frame_hex[j] != NULL) {
/* Parse frame from string to hex */
@@ -183,7 +183,7 @@ void test_fr_concealment_core(void)
}
/* Simulate a real life situation: voice frames with a few dropouts */
-void test_fr_concealment_realistic()
+void test_fr_concealment_realistic(void)
{
struct osmo_ecu_fr_state state;
uint8_t frame[GSM_FR_BYTES];
@@ -219,7 +219,7 @@ void test_fr_concealment_realistic()
}
/* Simulate a real life situation: voice frames with a few dropouts, using generic core */
-void test_fr_concealment_realistic_core()
+void test_fr_concealment_realistic_core(void)
{
struct osmo_ecu_state *state = osmo_ecu_init(NULL, OSMO_ECU_CODEC_FR);
uint8_t frame[GSM_FR_BYTES];
diff --git a/tests/codec/codec_ecu_fr_test.ok b/tests/codec/codec_ecu_fr_test.ok
index d925e285..ed5eb9d8 100644
--- a/tests/codec/codec_ecu_fr_test.ok
+++ b/tests/codec/codec_ecu_fr_test.ok
@@ -41,49 +41,49 @@ conceal: 16, result: d0000000000000000000000000000000000000000000000000000000000
conceal: 17, result: d00000000000000000000000000000000000000000000000000000000000000000 XMAXC: [0, 0, 0, 0]
conceal: 18, result: d00000000000000000000000000000000000000000000000000000000000000000 XMAXC: [0, 0, 0, 0]
conceal: 19, result: d00000000000000000000000000000000000000000000000000000000000000000 XMAXC: [0, 0, 0, 0]
-=> Testing FR concealment (simple, consecutive bad frames)
+=> Testing FR concealment (simple, using ECU abstraction)
Start with: d9ec9be212901f802335598c501f805bad3d4ba01f809b69df5a501f809cd1b4da, XMAXC: [3f, 3f, 3f, 3f]
conceal: 00, result: d9ec9be212901f802335598c501f805bad3d4ba01f809b69df5a501f809cd1b4da XMAXC: [3f, 3f, 3f, 3f]
-conceal: 01, result: d9ec9be212901d802335598c501d805bad3d4ba01d809b69df5a501d809cd1b4da XMAXC: [3b, 3b, 3b, 3b]
-conceal: 02, result: d9ec9be212901b802335598c501b805bad3d4ba01b809b69df5a501b809cd1b4da XMAXC: [37, 37, 37, 37]
+conceal: 01, result: d9ec9be212905d802335598c501d805bad3d4ba01d809b69df5a501d809cd1b4da XMAXC: [3b, 3b, 3b, 3b]
+conceal: 02, result: d9ec9be212901b802335598c501b805bad3d4ba01b809b69df5a507b809cd1b4da XMAXC: [37, 37, 37, 37]
conceal: 03, result: d9ec9be2129019802335598c5019805bad3d4ba019809b69df5a5019809cd1b4da XMAXC: [33, 33, 33, 33]
-conceal: 04, result: d9ec9be2129017802335598c5017805bad3d4ba017809b69df5a5017809cd1b4da XMAXC: [2f, 2f, 2f, 2f]
+conceal: 04, result: d9ec9be2129017802335598c5017805bad3d4ba057809b69df5a5057809cd1b4da XMAXC: [2f, 2f, 2f, 2f]
conceal: 05, result: d9ec9be2129015802335598c5015805bad3d4ba015809b69df5a5015809cd1b4da XMAXC: [2b, 2b, 2b, 2b]
-conceal: 06, result: d9ec9be2129013802335598c5013805bad3d4ba013809b69df5a5013809cd1b4da XMAXC: [27, 27, 27, 27]
+conceal: 06, result: d9ec9be2129013802335598c5073805bad3d4ba073809b69df5a5013809cd1b4da XMAXC: [27, 27, 27, 27]
conceal: 07, result: d9ec9be2129011802335598c5011805bad3d4ba011809b69df5a5011809cd1b4da XMAXC: [23, 23, 23, 23]
-conceal: 08, result: d9ec9be212900f802335598c500f805bad3d4ba00f809b69df5a500f809cd1b4da XMAXC: [1f, 1f, 1f, 1f]
-conceal: 09, result: d9ec9be212900d802335598c500d805bad3d4ba00d809b69df5a500d809cd1b4da XMAXC: [1b, 1b, 1b, 1b]
-conceal: 10, result: d9ec9be212900b802335598c500b805bad3d4ba00b809b69df5a500b809cd1b4da XMAXC: [17, 17, 17, 17]
-conceal: 11, result: d9ec9be2129009802335598c5009805bad3d4ba009809b69df5a5009809cd1b4da XMAXC: [13, 13, 13, 13]
-conceal: 12, result: d9ec9be2129007802335598c5007805bad3d4ba007809b69df5a5007809cd1b4da XMAXC: [f, f, f, f]
-conceal: 13, result: d9ec9be2129005802335598c5005805bad3d4ba005809b69df5a5005809cd1b4da XMAXC: [b, b, b, b]
-conceal: 14, result: d9ec9be2129003802335598c5003805bad3d4ba003809b69df5a5003809cd1b4da XMAXC: [7, 7, 7, 7]
-conceal: 15, result: d9ec9be2129001802335598c5001805bad3d4ba001809b69df5a5001809cd1b4da XMAXC: [3, 3, 3, 3]
-conceal: 16, result: d00000000000000000000000000000000000000000000000000000000000000000 XMAXC: [0, 0, 0, 0]
-conceal: 17, result: d00000000000000000000000000000000000000000000000000000000000000000 XMAXC: [0, 0, 0, 0]
-conceal: 18, result: d00000000000000000000000000000000000000000000000000000000000000000 XMAXC: [0, 0, 0, 0]
-conceal: 19, result: d00000000000000000000000000000000000000000000000000000000000000000 XMAXC: [0, 0, 0, 0]
+conceal: 08, result: d9ec9be212904f802335598c500f805bad3d4ba04f809b69df5a500f809cd1b4da XMAXC: [1f, 1f, 1f, 1f]
+conceal: 09, result: d9ec9be212900d802335598c500d805bad3d4ba00d809b69df5a506d809cd1b4da XMAXC: [1b, 1b, 1b, 1b]
+conceal: 10, result: d9ec9be212900b802335598c506b805bad3d4ba00b809b69df5a500b809cd1b4da XMAXC: [17, 17, 17, 17]
+conceal: 11, result: d9ec9be2129009802335598c5009805bad3d4ba049809b69df5a5049809cd1b4da XMAXC: [13, 13, 13, 13]
+conceal: 12, result: d9ec9be2129047802335598c5047805bad3d4ba007809b69df5a5007809cd1b4da XMAXC: [f, f, f, f]
+conceal: 13, result: d9ec9be2129005802335598c5065805bad3d4ba065809b69df5a5065809cd1b4da XMAXC: [b, b, b, b]
+conceal: 14, result: d9ec9be2129063802335598c5003805bad3d4ba003809b69df5a5003809cd1b4da XMAXC: [7, 7, 7, 7]
+conceal: 15, result: d9ec9be2129041802335598c5001805bad3d4ba001809b69df5a5001809cd1b4da XMAXC: [3, 3, 3, 3]
+conceal: 16, result: d9ec9be2129040002335598c5000005bad3d4ba000009b69df5a5060009cd1b4da XMAXC: [0, 0, 0, 0]
+conceal: 17, result: daa7aaa51a502038e46db91b502038e46db91b502038e46db91b502038e46db91b XMAXC: [0, 0, 0, 0]
+conceal: 18, result: daa7aaa51a502038e46db91b502038e46db91b502038e46db91b502038e46db91b XMAXC: [0, 0, 0, 0]
+conceal: 19, result: daa7aaa51a502038e46db91b502038e46db91b502038e46db91b502038e46db91b XMAXC: [0, 0, 0, 0]
Start with: d9ec9be212901d802335598c5013805bad3d4ba01f809b69df5a5019809cd1b4da, XMAXC: [3b, 27, 3f, 33]
conceal: 00, result: d9ec9be212901d802335598c5013805bad3d4ba01f809b69df5a5019809cd1b4da XMAXC: [3b, 27, 3f, 33]
-conceal: 01, result: d9ec9be212901b802335598c5011805bad3d4ba01d809b69df5a5017809cd1b4da XMAXC: [37, 23, 3b, 2f]
-conceal: 02, result: d9ec9be2129019802335598c500f805bad3d4ba01b809b69df5a5015809cd1b4da XMAXC: [33, 1f, 37, 2b]
-conceal: 03, result: d9ec9be2129017802335598c500d805bad3d4ba019809b69df5a5013809cd1b4da XMAXC: [2f, 1b, 33, 27]
-conceal: 04, result: d9ec9be2129015802335598c500b805bad3d4ba017809b69df5a5011809cd1b4da XMAXC: [2b, 17, 2f, 23]
-conceal: 05, result: d9ec9be2129013802335598c5009805bad3d4ba015809b69df5a500f809cd1b4da XMAXC: [27, 13, 2b, 1f]
-conceal: 06, result: d9ec9be2129011802335598c5007805bad3d4ba013809b69df5a500d809cd1b4da XMAXC: [23, f, 27, 1b]
-conceal: 07, result: d9ec9be212900f802335598c5005805bad3d4ba011809b69df5a500b809cd1b4da XMAXC: [1f, b, 23, 17]
-conceal: 08, result: d9ec9be212900d802335598c5003805bad3d4ba00f809b69df5a5009809cd1b4da XMAXC: [1b, 7, 1f, 13]
-conceal: 09, result: d9ec9be212900b802335598c5001805bad3d4ba00d809b69df5a5007809cd1b4da XMAXC: [17, 3, 1b, f]
-conceal: 10, result: d9ec9be2129009802335598c5000005bad3d4ba00b809b69df5a5005809cd1b4da XMAXC: [13, 0, 17, b]
-conceal: 11, result: d9ec9be2129007802335598c5000005bad3d4ba009809b69df5a5003809cd1b4da XMAXC: [f, 0, 13, 7]
-conceal: 12, result: d9ec9be2129005802335598c5000005bad3d4ba007809b69df5a5001809cd1b4da XMAXC: [b, 0, f, 3]
-conceal: 13, result: d9ec9be2129003802335598c5000005bad3d4ba005809b69df5a5000009cd1b4da XMAXC: [7, 0, b, 0]
-conceal: 14, result: d9ec9be2129001802335598c5000005bad3d4ba003809b69df5a5000009cd1b4da XMAXC: [3, 0, 7, 0]
-conceal: 15, result: d9ec9be2129000002335598c5000005bad3d4ba001809b69df5a5000009cd1b4da XMAXC: [0, 0, 3, 0]
-conceal: 16, result: d00000000000000000000000000000000000000000000000000000000000000000 XMAXC: [0, 0, 0, 0]
-conceal: 17, result: d00000000000000000000000000000000000000000000000000000000000000000 XMAXC: [0, 0, 0, 0]
-conceal: 18, result: d00000000000000000000000000000000000000000000000000000000000000000 XMAXC: [0, 0, 0, 0]
-conceal: 19, result: d00000000000000000000000000000000000000000000000000000000000000000 XMAXC: [0, 0, 0, 0]
+conceal: 01, result: d9ec9be212901b802335598c5011805bad3d4ba01d809b69df5a5077809cd1b4da XMAXC: [37, 23, 3b, 2f]
+conceal: 02, result: d9ec9be2129019802335598c500f805bad3d4ba05b809b69df5a5055809cd1b4da XMAXC: [33, 1f, 37, 2b]
+conceal: 03, result: d9ec9be2129017802335598c500d805bad3d4ba059809b69df5a5053809cd1b4da XMAXC: [2f, 1b, 33, 27]
+conceal: 04, result: d9ec9be2129015802335598c506b805bad3d4ba077809b69df5a5011809cd1b4da XMAXC: [2b, 17, 2f, 23]
+conceal: 05, result: d9ec9be2129013802335598c5069805bad3d4ba075809b69df5a500f809cd1b4da XMAXC: [27, 13, 2b, 1f]
+conceal: 06, result: d9ec9be2129051802335598c5007805bad3d4ba053809b69df5a500d809cd1b4da XMAXC: [23, f, 27, 1b]
+conceal: 07, result: d9ec9be212904f802335598c5005805bad3d4ba051809b69df5a506b809cd1b4da XMAXC: [1f, b, 23, 17]
+conceal: 08, result: d9ec9be212900d802335598c5063805bad3d4ba00f809b69df5a5069809cd1b4da XMAXC: [1b, 7, 1f, 13]
+conceal: 09, result: d9ec9be212900b802335598c5061805bad3d4ba04d809b69df5a5047809cd1b4da XMAXC: [17, 3, 1b, f]
+conceal: 10, result: d9ec9be2129049802335598c5040005bad3d4ba04b809b69df5a5045809cd1b4da XMAXC: [13, 0, 17, b]
+conceal: 11, result: d9ec9be2129047802335598c5020005bad3d4ba069809b69df5a5063809cd1b4da XMAXC: [f, 0, 13, 7]
+conceal: 12, result: d9ec9be2129065802335598c5060005bad3d4ba067809b69df5a5061809cd1b4da XMAXC: [b, 0, f, 3]
+conceal: 13, result: d9ec9be2129023802335598c5000005bad3d4ba005809b69df5a5000009cd1b4da XMAXC: [7, 0, b, 0]
+conceal: 14, result: d9ec9be2129001802335598c5000005bad3d4ba003809b69df5a5060009cd1b4da XMAXC: [3, 0, 7, 0]
+conceal: 15, result: d9ec9be2129040002335598c5000005bad3d4ba001809b69df5a5000009cd1b4da XMAXC: [0, 0, 3, 0]
+conceal: 16, result: d9ec9be2129000002335598c5000005bad3d4ba040009b69df5a5020009cd1b4da XMAXC: [0, 0, 0, 0]
+conceal: 17, result: daa7aaa51a502038e46db91b502038e46db91b502038e46db91b502038e46db91b XMAXC: [0, 0, 0, 0]
+conceal: 18, result: daa7aaa51a502038e46db91b502038e46db91b502038e46db91b502038e46db91b XMAXC: [0, 0, 0, 0]
+conceal: 19, result: daa7aaa51a502038e46db91b502038e46db91b502038e46db91b502038e46db91b XMAXC: [0, 0, 0, 0]
=> Testing FR concealment (realistic, various bad frames)
Frame No. 000:
@@ -318,7 +318,7 @@ Frame No. 018:
* output: d9689ba5e3d260491b516adb5e4027256e27227ee0351c8e549a5c60492471971b
Frame No. 019:
* input: (bad)
- * output: d00000000000000000000000000000000000000000000000000000000000000000
+ * output: d9689ba5e3d240491b516adb5e0027256e27227e80351c8e549a5c00492471971b
Frame No. 020:
* input: d8e6a2e1d3d2605b1376c8d35280392451391cbc80392a71b6db8aa049238dc8ab
* output: d8e6a2e1d3d2605b1376c8d35280392451391cbc80392a71b6db8aa049238dc8ab
@@ -357,19 +357,19 @@ Frame No. 031:
* output: d9a99361a276403b1a6ad6dcd40026e489c8e3bc40371c4dc564e2c036e28eb963
Frame No. 032:
* input: (bad)
- * output: d00000000000000000000000000000000000000000000000000000000000000000
+ * output: d9a99361a276003b1a6ad6dcd40026e489c8e3bc00371c4dc564e2e036e28eb963
Frame No. 033:
* input: (bad)
- * output: d00000000000000000000000000000000000000000000000000000000000000000
+ * output: daa7aaa51a502038e46db91b502038e46db91b502038e46db91b502038e46db91b
Frame No. 034:
* input: (bad)
- * output: d00000000000000000000000000000000000000000000000000000000000000000
+ * output: daa7aaa51a502038e46db91b502038e46db91b502038e46db91b502038e46db91b
Frame No. 035:
* input: (bad)
- * output: d00000000000000000000000000000000000000000000000000000000000000000
+ * output: daa7aaa51a502038e46db91b502038e46db91b502038e46db91b502038e46db91b
Frame No. 036:
* input: (bad)
- * output: d00000000000000000000000000000000000000000000000000000000000000000
+ * output: daa7aaa51a502038e46db91b502038e46db91b502038e46db91b502038e46db91b
Frame No. 037:
* input: d92c8b6d5aee4034ebb22724862047145634a5c0a038e371b8e4a880485c89dd25
* output: d92c8b6d5aee4034ebb22724862047145634a5c0a038e371b8e4a880485c89dd25
diff --git a/tests/codec/codec_efr_sid_test.c b/tests/codec/codec_efr_sid_test.c
new file mode 100644
index 00000000..08cc94b5
--- /dev/null
+++ b/tests/codec/codec_efr_sid_test.c
@@ -0,0 +1,97 @@
+/*
+ * This program is a test for osmo_efr_sid_classify(). It reads a set of
+ * EFR codec frames in hex format (TS 101 318 RTP format represented in hex,
+ * each frame as its own hex line) and feeds each test frame to
+ * osmo_efr_sid_classify(). It then prints the output next to each input.
+ *
+ * Author: Mychaela N. Falconia <falcon@freecalypso.org>, 2024 - however,
+ * Mother Mychaela's contributions are NOT subject to copyright.
+ * No rights reserved, all rights relinquished.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <osmocom/core/utils.h>
+#include <osmocom/codec/codec.h>
+
+static void process_record(const char *hex_str)
+{
+ uint8_t frame_bytes[GSM_EFR_BYTES];
+ enum osmo_gsm631_sid_class sidc;
+
+ osmo_hexparse(hex_str, frame_bytes, GSM_EFR_BYTES);
+ sidc = osmo_efr_sid_classify(frame_bytes);
+ printf("%s ==> %d\n", hex_str, (int) sidc);
+}
+
+static void process_line(char *linebuf, const char *infname, int lineno)
+{
+ char *cp = linebuf, *hex_str;
+ int ndig;
+
+ while (isspace(*cp))
+ cp++;
+ if (*cp == '\0' || *cp == '#')
+ return;
+ /* expect string of 62 hex digits */
+ hex_str = cp;
+ for (ndig = 0; ndig < GSM_EFR_BYTES * 2; ndig++) {
+ if (!isxdigit(*cp))
+ goto inv;
+ cp++;
+ }
+ if (*cp) {
+ if (!isspace(*cp))
+ goto inv;
+ *cp++ = '\0';
+ }
+ /* must be end of non-comment line */
+ while (isspace(*cp))
+ cp++;
+ if (*cp != '\0' && *cp != '#')
+ goto inv;
+
+ process_record(hex_str);
+ return;
+
+inv: fprintf(stderr, "%s line %d: invalid syntax\n", infname, lineno);
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ const char *infname;
+ FILE *inf;
+ char linebuf[128];
+ int lineno;
+
+ if (argc != 2) {
+ fprintf(stderr, "usage: %s input-file\n", argv[0]);
+ exit(1);
+ }
+ infname = argv[1];
+ inf = fopen(infname, "r");
+ if (!inf) {
+ perror(infname);
+ exit(1);
+ }
+ for (lineno = 1; fgets(linebuf, sizeof(linebuf), inf); lineno++)
+ process_line(linebuf, infname, lineno);
+ fclose(inf);
+ exit(0);
+}
diff --git a/tests/codec/codec_efr_sid_test.in b/tests/codec/codec_efr_sid_test.in
new file mode 100644
index 00000000..af95b5b2
--- /dev/null
+++ b/tests/codec/codec_efr_sid_test.in
@@ -0,0 +1,183 @@
+# This file is input for the EFR SID classifier test program.
+# It has been generated here:
+#
+# https://www.freecalypso.org/hg/vband-misc/file/tip/efr-sid
+#
+# Unit-test-desc file in the above directory contains
+# a detailed description.
+
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5802FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5804FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B58067FFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806BFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806DFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806EFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806F7FFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FBFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FDFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FEFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FF7FF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFBFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFDFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFEFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFF7F80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFBF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFDF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFEF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFF780001E3BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFB80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFD80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFE80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF00001E3BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E1BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E2BFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E33FFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E39FFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3AFFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3B7FFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BBFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BDFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BEFFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BF7FFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFBFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFDFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFEFFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFF7FE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFBFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFDFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFEFE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFF7E0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFBE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFDE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFEE0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFF60000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFA0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFC0000800FFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE00008007FFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800BFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800DFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800EFFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800F7FFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FBFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FDFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FEFFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FF7FFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFBFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFDFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFEFFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFF7FF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFBFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFDFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFEFF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFF7F000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFBF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFDF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFEF000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFF7000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFB000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFD000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFE000040FFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF0000407FFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040BFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040DFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040EFFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040F7FCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FBFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FDFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FEFCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FF7CFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFBCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFDCFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFECFFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFF4FFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFF8FFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFC7FC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCBFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCDFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCEFC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCF7C00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFBC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFDC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFEC00010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFF400010
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFF800010
+C286DD29B5802FFFFF80001E3BFFFFE00008007FFFFF000040FFFCFFC00010
+C286DD29B5804FFFFF80001E3BFFFFE0000800BFFFFF000040FFFCFFC00010
+C286DD29B58067FFFF80001E3BFFFFE0000800DFFFFF000040FFFCFFC00010
+C286DD29B5806BFFFF80001E3BFFFFE0000800EFFFFF000040FFFCFFC00010
+C286DD29B5806DFFFF80001E3BFFFFE0000800F7FFFF000040FFFCFFC00010
+C286DD29B5806EFFFF80001E3BFFFFE0000800FBFFFF000040FFFCFFC00010
+C286DD29B5806F7FFF80001E3BFFFFE0000800FDFFFF000040FFFCFFC00010
+C286DD29B5806FBFFF80001E3BFFFFE0000800FEFFFF000040FFFCFFC00010
+C286DD29B5806FDFFF80001E3BFFFFE0000800FF7FFF000040FFFCFFC00010
+C286DD29B5806FEFFF80001E3BFFFFE0000800FFBFFF000040FFFCFFC00010
+C286DD29B5806FF7FF80001E3BFFFFE0000800FFDFFF000040FFFCFFC00010
+C286DD29B5806FFBFF80001E3BFFFFE0000800FFEFFF000040FFFCFFC00010
+C286DD29B5806FFDFF80001E3BFFFFE0000800FFF7FF000040FFFCFFC00010
+C286DD29B5806FFEFF80001E3BFFFFE0000800FFFBFF000040FFFCFFC00010
+C286DD29B5806FFF7F80001E3BFFFFE0000800FFFDFF000040FFFCFFC00010
+C286DD29B5806FFFBF80001E3BFFFFE0000800FFFEFF000040FFFCFFC00010
+C286DD29B5806FFFDF80001E3BFFFFE0000800FFFF7F000040FFFCFFC00010
+C286DD29B5806FFFEF80001E3BFFFFE0000800FFFFBF000040FFFCFFC00010
+C286DD29B5806FFFF780001E3BFFFFE0000800FFFFDF000040FFFCFFC00010
+C286DD29B5806FFFFB80001E3BFFFFE0000800FFFFEF000040FFFCFFC00010
+C286DD29B5806FFFFD80001E3BFFFFE0000800FFFFF7000040FFFCFFC00010
+C286DD29B5806FFFFE80001E3BFFFFE0000800FFFFFB000040FFFCFFC00010
+C286DD29B5806FFFFF00001E3BFFFFE0000800FFFFFD000040FFFCFFC00010
+C286DD29B5806FFFFF80001E1BFFFFE0000800FFFFFE000040FFFCFFC00010
+C286DD29B5806FFFFF80001E2BFFFFE0000800FFFFFF0000407FFCFFC00010
+C286DD29B5806FFFFF80001E33FFFFE0000800FFFFFF000040BFFCFFC00010
+C286DD29B5806FFFFF80001E39FFFFE0000800FFFFFF000040DFFCFFC00010
+C286DD29B5806FFFFF80001E3AFFFFE0000800FFFFFF000040EFFCFFC00010
+C286DD29B5806FFFFF80001E3B7FFFE0000800FFFFFF000040F7FCFFC00010
+C286DD29B5806FFFFF80001E3BBFFFE0000800FFFFFF000040FBFCFFC00010
+C286DD29B5806FFFFF80001E3BDFFFE0000800FFFFFF000040FDFCFFC00010
+C286DD29B5806FFFFF80001E3BEFFFE0000800FFFFFF000040FEFCFFC00010
+C286DD29B5806FFFFF80001E3BF7FFE0000800FFFFFF000040FF7CFFC00010
+C286DD29B5806FFFFF80001E3BFBFFE0000800FFFFFF000040FFBCFFC00010
+C286DD29B5806FFFFF80001E3BFDFFE0000800FFFFFF000040FFDCFFC00010
+C286DD29B5806FFFFF80001E3BFEFFE0000800FFFFFF000040FFECFFC00010
+C286DD29B5806FFFFF80001E3BFF7FE0000800FFFFFF000040FFF4FFC00010
+C286DD29B5806FFFFF80001E3BFFBFE0000800FFFFFF000040FFF8FFC00010
+C286DD29B5806FFFFF80001E3BFFDFE0000800FFFFFF000040FFFC7FC00010
+C286DD29B5806FFFFF80001E3BFFEFE0000800FFFFFF000040FFFCBFC00010
+C286DD29B5806FFFFF80001E3BFFF7E0000800FFFFFF000040FFFCDFC00010
+C286DD29B5806FFFFF80001E3BFFFBE0000800FFFFFF000040FFFCEFC00010
+C286DD29B5806FFFFF80001E3BFFFDE0000800FFFFFF000040FFFCF7C00010
+C286DD29B5806FFFFF80001E3BFFFEE0000800FFFFFF000040FFFCFBC00010
+C286DD29B5806FFFFF80001E3BFFFF60000800FFFFFF000040FFFCFDC00010
+C286DD29B5806FFFFF80001E3BFFFFA0000800FFFFFF000040FFFCFEC00010
+C286DD29B5806FFFFF80001E3BFFFFC0000800FFFFFF000040FFFCFF400010
+C286DD29B5806FFFFF80001E3BFFFFE00008007FFFFF000040FFFCFF800010
+C286DD29B5802F7DF780001E2BDF7DE0000800BEFBEF000040BEF8FFC00010
+C286DD29B5804FBEFB80001E33EFBEE0000800DF7DF7000040DF7C7FC00010
+C286DD29B58067DF7D80001E39F7DF60000800EFBEFB000040EFBCBFC00010
+C286DD29B5806BEFBE80001E3AFBEFA0000800F7DF7D000040F7DCDFC00010
+C286DD29B5806DF7DF00001E3B7DF7C0000800FBEFBE000040FBECEFC00010
+C286DD29B5806EFBEF80001E1BBEFBE00008007DF7DF0000407DF4F7C00010
+C286DD29B5806F7DF780001E2BDF7DE0000800BEFBEF000040BEF8FBC00010
+C286DD29B5806FBEFB80001E33EFBEE0000800DF7DF7000040DF7C7DC00010
+C286DD29B5806FDF7D80001E39F7DF60000800EFBEFB000040EFBCBEC00010
+C286DD29B5806FEFBE80001E3AFBEFA0000800F7DF7D000040F7DCDF400010
+C286DD29B5806FF7DF00001E3B7DF7C0000800FBEFBE000040FBECEF800010
+C286DD29B5802EF7BD80001E33DEF7A0000800EF7BDE000040F7FCFFC00010
+C286DD29B5804F7BDE80001E39EF7BC0000800F7BDEF0000407BFCFFC00010
+C286DD29B58067BDEF00001E3AF7BDE00008007BDEF7000040BDFCFFC00010
+C286DD29B5806BDEF780001E1B7BDEE0000800BDEF7B000040DEFCFFC00010
+C286DD29B5806DEF7B80001E2BBDEF60000800DEF7BD000040EF7CFFC00010
+C286DD29B5806EF7BD80001E33DEF7A0000800EF7BDE000040F7BCFFC00010
+C286DD29B5806F7BDE80001E39EF7BC0000800F7BDEF0000407BDCFFC00010
+C286DD29B5806FBDEF00001E3AF7BDE00008007BDEF7000040BDECFFC00010
+C286DD29B5806FDEF780001E1B7BDEE0000800BDEF7B000040DEF4FFC00010
+C286DD29B5806FEF7B80001E2BBDEF60000800DEF7BD000040EF78FFC00010
+C286DD29B5806FF7BD80001E33DEF7A0000800EF7BDE000040F7BC7FC00010
+C286DD29B5806FFBDE80001E39EF7BC0000800F7BDEF0000407BDCBFC00010
+C286DD29B5806FFDEF00001E3AF7BDE00008007BDEF7000040BDECDFC00010
+C286DD29B5806FFEF780001E1B7BDEE0000800BDEF7B000040DEF4EFC00010
+C286DD29B5806FFF7B80001E2BBDEF60000800DEF7BD000040EF78F7C00010
+C286DD29B5806FFFBD80001E33DEF7A0000800EF7BDE000040F7BC7BC00010
+C286DD29B5806FFFDE80001E39EF7BC0000800F7BDEF0000407BDCBDC00010
+C286DD29B5806FFFEF00001E3AF7BDE00008007BDEF7000040BDECDEC00010
+C286DD29B5806FFFF780001E1B7BDEE0000800BDEF7B000040DEF4EF400010
+C286DD29B5806FFFFB80001E2BBDEF60000800DEF7BD000040EF78F7800010
diff --git a/tests/codec/codec_efr_sid_test.ok b/tests/codec/codec_efr_sid_test.ok
new file mode 100644
index 00000000..6b94cf4e
--- /dev/null
+++ b/tests/codec/codec_efr_sid_test.ok
@@ -0,0 +1,175 @@
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5802FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5804FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B58067FFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806BFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806DFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806EFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806F7FFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FBFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FDFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FEFFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FF7FF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFBFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFDFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFEFF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFF7F80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFBF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFDF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFEF80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFF780001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFB80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFD80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFE80001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF00001E3BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E1BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E2BFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E33FFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E39FFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3AFFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3B7FFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BBFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BDFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BEFFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BF7FFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFBFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFDFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFEFFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFF7FE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFBFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFDFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFEFE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFF7E0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFBE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFDE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFEE0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFF60000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFA0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFC0000800FFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE00008007FFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800BFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800DFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800EFFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800F7FFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FBFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FDFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FEFFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FF7FFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFBFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFDFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFEFFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFF7FF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFBFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFDFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFEFF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFF7F000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFBF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFDF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFEF000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFF7000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFB000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFD000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFE000040FFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF0000407FFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040BFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040DFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040EFFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040F7FCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FBFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FDFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FEFCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FF7CFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFBCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFDCFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFECFFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFF4FFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFF8FFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFC7FC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCBFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCDFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCEFC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCF7C00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFBC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFDC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFEC00010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFF400010 ==> 2
+C286DD29B5806FFFFF80001E3BFFFFE0000800FFFFFF000040FFFCFF800010 ==> 2
+C286DD29B5802FFFFF80001E3BFFFFE00008007FFFFF000040FFFCFFC00010 ==> 1
+C286DD29B5804FFFFF80001E3BFFFFE0000800BFFFFF000040FFFCFFC00010 ==> 1
+C286DD29B58067FFFF80001E3BFFFFE0000800DFFFFF000040FFFCFFC00010 ==> 1
+C286DD29B5806BFFFF80001E3BFFFFE0000800EFFFFF000040FFFCFFC00010 ==> 1
+C286DD29B5806DFFFF80001E3BFFFFE0000800F7FFFF000040FFFCFFC00010 ==> 1
+C286DD29B5806EFFFF80001E3BFFFFE0000800FBFFFF000040FFFCFFC00010 ==> 1
+C286DD29B5806F7FFF80001E3BFFFFE0000800FDFFFF000040FFFCFFC00010 ==> 1
+C286DD29B5806FBFFF80001E3BFFFFE0000800FEFFFF000040FFFCFFC00010 ==> 1
+C286DD29B5806FDFFF80001E3BFFFFE0000800FF7FFF000040FFFCFFC00010 ==> 1
+C286DD29B5806FEFFF80001E3BFFFFE0000800FFBFFF000040FFFCFFC00010 ==> 1
+C286DD29B5806FF7FF80001E3BFFFFE0000800FFDFFF000040FFFCFFC00010 ==> 1
+C286DD29B5806FFBFF80001E3BFFFFE0000800FFEFFF000040FFFCFFC00010 ==> 1
+C286DD29B5806FFDFF80001E3BFFFFE0000800FFF7FF000040FFFCFFC00010 ==> 1
+C286DD29B5806FFEFF80001E3BFFFFE0000800FFFBFF000040FFFCFFC00010 ==> 1
+C286DD29B5806FFF7F80001E3BFFFFE0000800FFFDFF000040FFFCFFC00010 ==> 1
+C286DD29B5806FFFBF80001E3BFFFFE0000800FFFEFF000040FFFCFFC00010 ==> 1
+C286DD29B5806FFFDF80001E3BFFFFE0000800FFFF7F000040FFFCFFC00010 ==> 1
+C286DD29B5806FFFEF80001E3BFFFFE0000800FFFFBF000040FFFCFFC00010 ==> 1
+C286DD29B5806FFFF780001E3BFFFFE0000800FFFFDF000040FFFCFFC00010 ==> 1
+C286DD29B5806FFFFB80001E3BFFFFE0000800FFFFEF000040FFFCFFC00010 ==> 1
+C286DD29B5806FFFFD80001E3BFFFFE0000800FFFFF7000040FFFCFFC00010 ==> 1
+C286DD29B5806FFFFE80001E3BFFFFE0000800FFFFFB000040FFFCFFC00010 ==> 1
+C286DD29B5806FFFFF00001E3BFFFFE0000800FFFFFD000040FFFCFFC00010 ==> 1
+C286DD29B5806FFFFF80001E1BFFFFE0000800FFFFFE000040FFFCFFC00010 ==> 1
+C286DD29B5806FFFFF80001E2BFFFFE0000800FFFFFF0000407FFCFFC00010 ==> 1
+C286DD29B5806FFFFF80001E33FFFFE0000800FFFFFF000040BFFCFFC00010 ==> 1
+C286DD29B5806FFFFF80001E39FFFFE0000800FFFFFF000040DFFCFFC00010 ==> 1
+C286DD29B5806FFFFF80001E3AFFFFE0000800FFFFFF000040EFFCFFC00010 ==> 1
+C286DD29B5806FFFFF80001E3B7FFFE0000800FFFFFF000040F7FCFFC00010 ==> 1
+C286DD29B5806FFFFF80001E3BBFFFE0000800FFFFFF000040FBFCFFC00010 ==> 1
+C286DD29B5806FFFFF80001E3BDFFFE0000800FFFFFF000040FDFCFFC00010 ==> 1
+C286DD29B5806FFFFF80001E3BEFFFE0000800FFFFFF000040FEFCFFC00010 ==> 1
+C286DD29B5806FFFFF80001E3BF7FFE0000800FFFFFF000040FF7CFFC00010 ==> 1
+C286DD29B5806FFFFF80001E3BFBFFE0000800FFFFFF000040FFBCFFC00010 ==> 1
+C286DD29B5806FFFFF80001E3BFDFFE0000800FFFFFF000040FFDCFFC00010 ==> 1
+C286DD29B5806FFFFF80001E3BFEFFE0000800FFFFFF000040FFECFFC00010 ==> 1
+C286DD29B5806FFFFF80001E3BFF7FE0000800FFFFFF000040FFF4FFC00010 ==> 1
+C286DD29B5806FFFFF80001E3BFFBFE0000800FFFFFF000040FFF8FFC00010 ==> 1
+C286DD29B5806FFFFF80001E3BFFDFE0000800FFFFFF000040FFFC7FC00010 ==> 1
+C286DD29B5806FFFFF80001E3BFFEFE0000800FFFFFF000040FFFCBFC00010 ==> 1
+C286DD29B5806FFFFF80001E3BFFF7E0000800FFFFFF000040FFFCDFC00010 ==> 1
+C286DD29B5806FFFFF80001E3BFFFBE0000800FFFFFF000040FFFCEFC00010 ==> 1
+C286DD29B5806FFFFF80001E3BFFFDE0000800FFFFFF000040FFFCF7C00010 ==> 1
+C286DD29B5806FFFFF80001E3BFFFEE0000800FFFFFF000040FFFCFBC00010 ==> 1
+C286DD29B5806FFFFF80001E3BFFFF60000800FFFFFF000040FFFCFDC00010 ==> 1
+C286DD29B5806FFFFF80001E3BFFFFA0000800FFFFFF000040FFFCFEC00010 ==> 1
+C286DD29B5806FFFFF80001E3BFFFFC0000800FFFFFF000040FFFCFF400010 ==> 1
+C286DD29B5806FFFFF80001E3BFFFFE00008007FFFFF000040FFFCFF800010 ==> 1
+C286DD29B5802F7DF780001E2BDF7DE0000800BEFBEF000040BEF8FFC00010 ==> 1
+C286DD29B5804FBEFB80001E33EFBEE0000800DF7DF7000040DF7C7FC00010 ==> 1
+C286DD29B58067DF7D80001E39F7DF60000800EFBEFB000040EFBCBFC00010 ==> 1
+C286DD29B5806BEFBE80001E3AFBEFA0000800F7DF7D000040F7DCDFC00010 ==> 1
+C286DD29B5806DF7DF00001E3B7DF7C0000800FBEFBE000040FBECEFC00010 ==> 1
+C286DD29B5806EFBEF80001E1BBEFBE00008007DF7DF0000407DF4F7C00010 ==> 1
+C286DD29B5806F7DF780001E2BDF7DE0000800BEFBEF000040BEF8FBC00010 ==> 1
+C286DD29B5806FBEFB80001E33EFBEE0000800DF7DF7000040DF7C7DC00010 ==> 1
+C286DD29B5806FDF7D80001E39F7DF60000800EFBEFB000040EFBCBEC00010 ==> 1
+C286DD29B5806FEFBE80001E3AFBEFA0000800F7DF7D000040F7DCDF400010 ==> 1
+C286DD29B5806FF7DF00001E3B7DF7C0000800FBEFBE000040FBECEF800010 ==> 1
+C286DD29B5802EF7BD80001E33DEF7A0000800EF7BDE000040F7FCFFC00010 ==> 0
+C286DD29B5804F7BDE80001E39EF7BC0000800F7BDEF0000407BFCFFC00010 ==> 0
+C286DD29B58067BDEF00001E3AF7BDE00008007BDEF7000040BDFCFFC00010 ==> 0
+C286DD29B5806BDEF780001E1B7BDEE0000800BDEF7B000040DEFCFFC00010 ==> 0
+C286DD29B5806DEF7B80001E2BBDEF60000800DEF7BD000040EF7CFFC00010 ==> 0
+C286DD29B5806EF7BD80001E33DEF7A0000800EF7BDE000040F7BCFFC00010 ==> 0
+C286DD29B5806F7BDE80001E39EF7BC0000800F7BDEF0000407BDCFFC00010 ==> 0
+C286DD29B5806FBDEF00001E3AF7BDE00008007BDEF7000040BDECFFC00010 ==> 0
+C286DD29B5806FDEF780001E1B7BDEE0000800BDEF7B000040DEF4FFC00010 ==> 0
+C286DD29B5806FEF7B80001E2BBDEF60000800DEF7BD000040EF78FFC00010 ==> 0
+C286DD29B5806FF7BD80001E33DEF7A0000800EF7BDE000040F7BC7FC00010 ==> 0
+C286DD29B5806FFBDE80001E39EF7BC0000800F7BDEF0000407BDCBFC00010 ==> 0
+C286DD29B5806FFDEF00001E3AF7BDE00008007BDEF7000040BDECDFC00010 ==> 0
+C286DD29B5806FFEF780001E1B7BDEE0000800BDEF7B000040DEF4EFC00010 ==> 0
+C286DD29B5806FFF7B80001E2BBDEF60000800DEF7BD000040EF78F7C00010 ==> 0
+C286DD29B5806FFFBD80001E33DEF7A0000800EF7BDE000040F7BC7BC00010 ==> 0
+C286DD29B5806FFFDE80001E39EF7BC0000800F7BDEF0000407BDCBDC00010 ==> 0
+C286DD29B5806FFFEF00001E3AF7BDE00008007BDEF7000040BDECDEC00010 ==> 0
+C286DD29B5806FFFF780001E1B7BDEE0000800BDEF7B000040DEF4EF400010 ==> 0
+C286DD29B5806FFFFB80001E2BBDEF60000800DEF7BD000040EF78F7800010 ==> 0
diff --git a/tests/codec/codec_fr_sid_test.c b/tests/codec/codec_fr_sid_test.c
new file mode 100644
index 00000000..25c1b3f3
--- /dev/null
+++ b/tests/codec/codec_fr_sid_test.c
@@ -0,0 +1,97 @@
+/*
+ * This program is a test for osmo_fr_sid_classify(). It reads a set of
+ * FRv1 codec frames in hex format (TS 101 318 RTP format represented in hex,
+ * each frame as its own hex line) and feeds each test frame to
+ * osmo_fr_sid_classify(). It then prints the output next to each input.
+ *
+ * Author: Mychaela N. Falconia <falcon@freecalypso.org>, 2024 - however,
+ * Mother Mychaela's contributions are NOT subject to copyright.
+ * No rights reserved, all rights relinquished.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <osmocom/core/utils.h>
+#include <osmocom/codec/codec.h>
+
+static void process_record(const char *hex_str)
+{
+ uint8_t frame_bytes[GSM_FR_BYTES];
+ enum osmo_gsm631_sid_class sidc;
+
+ osmo_hexparse(hex_str, frame_bytes, GSM_FR_BYTES);
+ sidc = osmo_fr_sid_classify(frame_bytes);
+ printf("%s ==> %d\n", hex_str, (int) sidc);
+}
+
+static void process_line(char *linebuf, const char *infname, int lineno)
+{
+ char *cp = linebuf, *hex_str;
+ int ndig;
+
+ while (isspace(*cp))
+ cp++;
+ if (*cp == '\0' || *cp == '#')
+ return;
+ /* expect string of 66 hex digits */
+ hex_str = cp;
+ for (ndig = 0; ndig < GSM_FR_BYTES * 2; ndig++) {
+ if (!isxdigit(*cp))
+ goto inv;
+ cp++;
+ }
+ if (*cp) {
+ if (!isspace(*cp))
+ goto inv;
+ *cp++ = '\0';
+ }
+ /* must be end of non-comment line */
+ while (isspace(*cp))
+ cp++;
+ if (*cp != '\0' && *cp != '#')
+ goto inv;
+
+ process_record(hex_str);
+ return;
+
+inv: fprintf(stderr, "%s line %d: invalid syntax\n", infname, lineno);
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ const char *infname;
+ FILE *inf;
+ char linebuf[128];
+ int lineno;
+
+ if (argc != 2) {
+ fprintf(stderr, "usage: %s input-file\n", argv[0]);
+ exit(1);
+ }
+ infname = argv[1];
+ inf = fopen(infname, "r");
+ if (!inf) {
+ perror(infname);
+ exit(1);
+ }
+ for (lineno = 1; fgets(linebuf, sizeof(linebuf), inf); lineno++)
+ process_line(linebuf, infname, lineno);
+ fclose(inf);
+ exit(0);
+}
diff --git a/tests/codec/codec_fr_sid_test.in b/tests/codec/codec_fr_sid_test.in
new file mode 100644
index 00000000..d5930e25
--- /dev/null
+++ b/tests/codec/codec_fr_sid_test.in
@@ -0,0 +1,184 @@
+# This file is input for the FRv1 SID classifier test program.
+# It has been generated here:
+#
+# https://www.freecalypso.org/hg/vband-misc/file/tip/fr-sid
+#
+# It is based on the same principle as the EFR version:
+#
+# https://www.freecalypso.org/hg/vband-misc/file/tip/efr-sid/Unit-test-desc
+
+DAE6DB659B00010000000000000100000000000001000000000000010000000000
+DAE6DB659B00014000000000000100000000000001000000000000010000000000
+DAE6DB659B00012000000000000100000000000001000000000000010000000000
+DAE6DB659B00010800000000000100000000000001000000000000010000000000
+DAE6DB659B00010400000000000100000000000001000000000000010000000000
+DAE6DB659B00010100000000000100000000000001000000000000010000000000
+DAE6DB659B00010080000000000100000000000001000000000000010000000000
+DAE6DB659B00010020000000000100000000000001000000000000010000000000
+DAE6DB659B00010010000000000100000000000001000000000000010000000000
+DAE6DB659B00010004000000000100000000000001000000000000010000000000
+DAE6DB659B00010002000000000100000000000001000000000000010000000000
+DAE6DB659B00010000800000000100000000000001000000000000010000000000
+DAE6DB659B00010000400000000100000000000001000000000000010000000000
+DAE6DB659B00010000100000000100000000000001000000000000010000000000
+DAE6DB659B00010000080000000100000000000001000000000000010000000000
+DAE6DB659B00010000020000000100000000000001000000000000010000000000
+DAE6DB659B00010000010000000100000000000001000000000000010000000000
+DAE6DB659B00010000004000000100000000000001000000000000010000000000
+DAE6DB659B00010000002000000100000000000001000000000000010000000000
+DAE6DB659B00010000000800000100000000000001000000000000010000000000
+DAE6DB659B00010000000400000100000000000001000000000000010000000000
+DAE6DB659B00010000000100000100000000000001000000000000010000000000
+DAE6DB659B00010000000080000100000000000001000000000000010000000000
+DAE6DB659B00010000000020000100000000000001000000000000010000000000
+DAE6DB659B00010000000010000100000000000001000000000000010000000000
+DAE6DB659B00010000000004000100000000000001000000000000010000000000
+DAE6DB659B00010000000002000100000000000001000000000000010000000000
+DAE6DB659B00010000000000000140000000000001000000000000010000000000
+DAE6DB659B00010000000000000120000000000001000000000000010000000000
+DAE6DB659B00010000000000000108000000000001000000000000010000000000
+DAE6DB659B00010000000000000104000000000001000000000000010000000000
+DAE6DB659B00010000000000000101000000000001000000000000010000000000
+DAE6DB659B00010000000000000100800000000001000000000000010000000000
+DAE6DB659B00010000000000000100200000000001000000000000010000000000
+DAE6DB659B00010000000000000100100000000001000000000000010000000000
+DAE6DB659B00010000000000000100040000000001000000000000010000000000
+DAE6DB659B00010000000000000100020000000001000000000000010000000000
+DAE6DB659B00010000000000000100008000000001000000000000010000000000
+DAE6DB659B00010000000000000100004000000001000000000000010000000000
+DAE6DB659B00010000000000000100001000000001000000000000010000000000
+DAE6DB659B00010000000000000100000800000001000000000000010000000000
+DAE6DB659B00010000000000000100000200000001000000000000010000000000
+DAE6DB659B00010000000000000100000100000001000000000000010000000000
+DAE6DB659B00010000000000000100000040000001000000000000010000000000
+DAE6DB659B00010000000000000100000020000001000000000000010000000000
+DAE6DB659B00010000000000000100000008000001000000000000010000000000
+DAE6DB659B00010000000000000100000004000001000000000000010000000000
+DAE6DB659B00010000000000000100000001000001000000000000010000000000
+DAE6DB659B00010000000000000100000000800001000000000000010000000000
+DAE6DB659B00010000000000000100000000200001000000000000010000000000
+DAE6DB659B00010000000000000100000000100001000000000000010000000000
+DAE6DB659B00010000000000000100000000040001000000000000010000000000
+DAE6DB659B00010000000000000100000000020001000000000000010000000000
+DAE6DB659B00010000000000000100000000000001400000000000010000000000
+DAE6DB659B00010000000000000100000000000001200000000000010000000000
+DAE6DB659B00010000000000000100000000000001080000000000010000000000
+DAE6DB659B00010000000000000100000000000001040000000000010000000000
+DAE6DB659B00010000000000000100000000000001010000000000010000000000
+DAE6DB659B00010000000000000100000000000001008000000000010000000000
+DAE6DB659B00010000000000000100000000000001002000000000010000000000
+DAE6DB659B00010000000000000100000000000001001000000000010000000000
+DAE6DB659B00010000000000000100000000000001000400000000010000000000
+DAE6DB659B00010000000000000100000000000001000200000000010000000000
+DAE6DB659B00010000000000000100000000000001000080000000010000000000
+DAE6DB659B00010000000000000100000000000001000040000000010000000000
+DAE6DB659B00010000000000000100000000000001000010000000010000000000
+DAE6DB659B00010000000000000100000000000001000008000000010000000000
+DAE6DB659B00010000000000000100000000000001000002000000010000000000
+DAE6DB659B00010000000000000100000000000001000001000000010000000000
+DAE6DB659B00010000000000000100000000000001000000400000010000000000
+DAE6DB659B00010000000000000100000000000001000000200000010000000000
+DAE6DB659B00010000000000000100000000000001000000080000010000000000
+DAE6DB659B00010000000000000100000000000001000000040000010000000000
+DAE6DB659B00010000000000000100000000000001000000010000010000000000
+DAE6DB659B00010000000000000100000000000001000000008000010000000000
+DAE6DB659B00010000000000000100000000000001000000002000010000000000
+DAE6DB659B00010000000000000100000000000001000000001000010000000000
+DAE6DB659B00010000000000000100000000000001000000000400010000000000
+DAE6DB659B00010000000000000100000000000001000000000200010000000000
+DAE6DB659B00010000000000000100000000000001000000000000014000000000
+DAE6DB659B00010000000000000100000000000001000000000000012000000000
+DAE6DB659B00010000000000000100000000000001000000000000010800000000
+DAE6DB659B00010000000000000100000000000001000000000000010400000000
+DAE6DB659B00010000000000000100000000000001000000000000010100000000
+DAE6DB659B00010000000000000100000000000001000000000000010080000000
+DAE6DB659B00010000000000000100000000000001000000000000010020000000
+DAE6DB659B00010000000000000100000000000001000000000000010010000000
+DAE6DB659B00010000000000000100000000000001000000000000010004000000
+DAE6DB659B00010000000000000100000000000001000000000000010000800000
+DAE6DB659B00010000000000000100000000000001000000000000010000100000
+DAE6DB659B00010000000000000100000000000001000000000000010000020000
+DAE6DB659B00010000000000000100000000000001000000000000010000004000
+DAE6DB659B00010000000000000100000000000001000000000000010000000800
+DAE6DB659B00010000000000000100000000000001000000000000010000000100
+DAE6DB659B00010000000000000100000000000001000000000000010000000020
+DAE6DB659B00010000000000000100000000000001000000000000010000000004
+DAE6DB659B00014000000000000100000000800001000000000000010000000000
+DAE6DB659B00012000000000000100000000200001000000000000010000000000
+DAE6DB659B00010800000000000100000000100001000000000000010000000000
+DAE6DB659B00010400000000000100000000040001000000000000010000000000
+DAE6DB659B00010100000000000100000000020001000000000000010000000000
+DAE6DB659B00010080000000000100000000000001400000000000010000000000
+DAE6DB659B00010020000000000100000000000001200000000000010000000000
+DAE6DB659B00010010000000000100000000000001080000000000010000000000
+DAE6DB659B00010004000000000100000000000001040000000000010000000000
+DAE6DB659B00010002000000000100000000000001010000000000010000000000
+DAE6DB659B00010000800000000100000000000001008000000000010000000000
+DAE6DB659B00010000400000000100000000000001002000000000010000000000
+DAE6DB659B00010000100000000100000000000001001000000000010000000000
+DAE6DB659B00010000080000000100000000000001000400000000010000000000
+DAE6DB659B00010000020000000100000000000001000200000000010000000000
+DAE6DB659B00010000010000000100000000000001000080000000010000000000
+DAE6DB659B00010000004000000100000000000001000040000000010000000000
+DAE6DB659B00010000002000000100000000000001000010000000010000000000
+DAE6DB659B00010000000800000100000000000001000008000000010000000000
+DAE6DB659B00010000000400000100000000000001000002000000010000000000
+DAE6DB659B00010000000100000100000000000001000001000000010000000000
+DAE6DB659B00010000000080000100000000000001000000400000010000000000
+DAE6DB659B00010000000020000100000000000001000000200000010000000000
+DAE6DB659B00010000000010000100000000000001000000080000010000000000
+DAE6DB659B00010000000004000100000000000001000000040000010000000000
+DAE6DB659B00010000000002000100000000000001000000010000010000000000
+DAE6DB659B00010000000000000140000000000001000000008000010000000000
+DAE6DB659B00010000000000000120000000000001000000002000010000000000
+DAE6DB659B00010000000000000108000000000001000000001000010000000000
+DAE6DB659B00010000000000000104000000000001000000000400010000000000
+DAE6DB659B00010000000000000101000000000001000000000200010000000000
+DAE6DB659B00010000000000000100800000000001000000000000014000000000
+DAE6DB659B00010000000000000100200000000001000000000000012000000000
+DAE6DB659B00010000000000000100100000000001000000000000010800000000
+DAE6DB659B00010000000000000100040000000001000000000000010400000000
+DAE6DB659B00010000000000000100020000000001000000000000010100000000
+DAE6DB659B00010000000000000100008000000001000000000000010080000000
+DAE6DB659B00010000000000000100004000000001000000000000010020000000
+DAE6DB659B00010000000000000100001000000001000000000000010010000000
+DAE6DB659B00010000000000000100000800000001000000000000010004000000
+DAE6DB659B00010000000000000100000200000001000000000000010000800000
+DAE6DB659B00010000000000000100000100000001000000000000010000100000
+DAE6DB659B00010000000000000100000040000001000000000000010000020000
+DAE6DB659B00010000000000000100000020000001000000000000010000004000
+DAE6DB659B00010000000000000100000008000001000000000000010000000800
+DAE6DB659B00010000000000000100000004000001000000000000010000000100
+DAE6DB659B00010000000000000100000001000001000000000000010000000020
+DAE6DB659B00010000000000000100000000800001000000000000010000000004
+DAE6DB659B00014020100804000101008040200001080402010000014020000000
+DAE6DB659B00012010080402000100804020100001040201008000012010000000
+DAE6DB659B00010804020100000140201008040001010080402000010804000000
+DAE6DB659B00010402010080000120100804020001008040201000010400800000
+DAE6DB659B00010100804020000108040201000001402010080400010100100000
+DAE6DB659B00010080402010000104020100800001201008040200010080020000
+DAE6DB659B00010020100804000101008040200001080402010000014020004000
+DAE6DB659B00010010080402000100804020100001040201008000012010000800
+DAE6DB659B00010004020100000140201008040001010080402000010804000100
+DAE6DB659B00010002010080000120100804020001008040201000010400800020
+DAE6DB659B00010000804020000108040201000001402010080400010100100004
+DAE6DB659B00014080810102000101020204040001040408081000010000000000
+DAE6DB659B00012020404080000140808101020001010202040400010000000000
+DAE6DB659B00010810102020000120204040800001408081010200010000000000
+DAE6DB659B00010404080810000108101020200001202040408000014000000000
+DAE6DB659B00010102020404000104040808100001081010202000012000000000
+DAE6DB659B00010080810102000101020204040001040408081000010800000000
+DAE6DB659B00010020404080000140808101020001010202040400010400000000
+DAE6DB659B00010010102020000120204040800001408081010200010100000000
+DAE6DB659B00010004080810000108101020200001202040408000014080000000
+DAE6DB659B00010002020404000104040808100001081010202000012020000000
+DAE6DB659B00010000810102000101020204040001040408081000010810000000
+DAE6DB659B00010000404080000140808101020001010202040400010404000000
+DAE6DB659B00010000102020000120204040800001408081010200010100800000
+DAE6DB659B00010000080810000108101020200001202040408000014080100000
+DAE6DB659B00010000020404000104040808100001081010202000012020020000
+DAE6DB659B00010000010102000101020204040001040408081000010810004000
+DAE6DB659B00010000004080000140808101020001010202040400010404000800
+DAE6DB659B00010000002020000120204040800001408081010200010100800100
+DAE6DB659B00010000000810000108101020200001202040408000014080100020
+DAE6DB659B00010000000404000104040808100001081010202000012020020004
diff --git a/tests/codec/codec_fr_sid_test.ok b/tests/codec/codec_fr_sid_test.ok
new file mode 100644
index 00000000..8dcaa345
--- /dev/null
+++ b/tests/codec/codec_fr_sid_test.ok
@@ -0,0 +1,175 @@
+DAE6DB659B00010000000000000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00014000000000000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00012000000000000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010800000000000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010400000000000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010100000000000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010080000000000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010020000000000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010010000000000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010004000000000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010002000000000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000800000000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000400000000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000100000000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000080000000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000020000000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000010000000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000004000000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000002000000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000800000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000400000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000100000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000080000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000020000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000010000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000004000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000002000100000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000140000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000120000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000108000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000104000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000101000000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100800000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100200000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100100000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100040000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100020000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100008000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100004000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100001000000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000800000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000200000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000100000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000040000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000020000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000008000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000004000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000001000001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000800001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000200001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000100001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000040001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000020001000000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001400000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001200000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001080000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001040000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001010000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001008000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001002000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001001000000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000400000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000200000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000080000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000040000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000010000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000008000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000002000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000001000000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000000400000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000000200000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000000080000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000000040000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000000010000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000000008000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000000002000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000000001000010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000000000400010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000000000200010000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000000000000014000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000000000000012000000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000000000000010800000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000000000000010400000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000000000000010100000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000000000000010080000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000000000000010020000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000000000000010010000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000000000000010004000000 ==> 2
+DAE6DB659B00010000000000000100000000000001000000000000010000800000 ==> 2
+DAE6DB659B00010000000000000100000000000001000000000000010000100000 ==> 2
+DAE6DB659B00010000000000000100000000000001000000000000010000020000 ==> 2
+DAE6DB659B00010000000000000100000000000001000000000000010000004000 ==> 2
+DAE6DB659B00010000000000000100000000000001000000000000010000000800 ==> 2
+DAE6DB659B00010000000000000100000000000001000000000000010000000100 ==> 2
+DAE6DB659B00010000000000000100000000000001000000000000010000000020 ==> 2
+DAE6DB659B00010000000000000100000000000001000000000000010000000004 ==> 2
+DAE6DB659B00014000000000000100000000800001000000000000010000000000 ==> 1
+DAE6DB659B00012000000000000100000000200001000000000000010000000000 ==> 1
+DAE6DB659B00010800000000000100000000100001000000000000010000000000 ==> 1
+DAE6DB659B00010400000000000100000000040001000000000000010000000000 ==> 1
+DAE6DB659B00010100000000000100000000020001000000000000010000000000 ==> 1
+DAE6DB659B00010080000000000100000000000001400000000000010000000000 ==> 1
+DAE6DB659B00010020000000000100000000000001200000000000010000000000 ==> 1
+DAE6DB659B00010010000000000100000000000001080000000000010000000000 ==> 1
+DAE6DB659B00010004000000000100000000000001040000000000010000000000 ==> 1
+DAE6DB659B00010002000000000100000000000001010000000000010000000000 ==> 1
+DAE6DB659B00010000800000000100000000000001008000000000010000000000 ==> 1
+DAE6DB659B00010000400000000100000000000001002000000000010000000000 ==> 1
+DAE6DB659B00010000100000000100000000000001001000000000010000000000 ==> 1
+DAE6DB659B00010000080000000100000000000001000400000000010000000000 ==> 1
+DAE6DB659B00010000020000000100000000000001000200000000010000000000 ==> 1
+DAE6DB659B00010000010000000100000000000001000080000000010000000000 ==> 1
+DAE6DB659B00010000004000000100000000000001000040000000010000000000 ==> 1
+DAE6DB659B00010000002000000100000000000001000010000000010000000000 ==> 1
+DAE6DB659B00010000000800000100000000000001000008000000010000000000 ==> 1
+DAE6DB659B00010000000400000100000000000001000002000000010000000000 ==> 1
+DAE6DB659B00010000000100000100000000000001000001000000010000000000 ==> 1
+DAE6DB659B00010000000080000100000000000001000000400000010000000000 ==> 1
+DAE6DB659B00010000000020000100000000000001000000200000010000000000 ==> 1
+DAE6DB659B00010000000010000100000000000001000000080000010000000000 ==> 1
+DAE6DB659B00010000000004000100000000000001000000040000010000000000 ==> 1
+DAE6DB659B00010000000002000100000000000001000000010000010000000000 ==> 1
+DAE6DB659B00010000000000000140000000000001000000008000010000000000 ==> 1
+DAE6DB659B00010000000000000120000000000001000000002000010000000000 ==> 1
+DAE6DB659B00010000000000000108000000000001000000001000010000000000 ==> 1
+DAE6DB659B00010000000000000104000000000001000000000400010000000000 ==> 1
+DAE6DB659B00010000000000000101000000000001000000000200010000000000 ==> 1
+DAE6DB659B00010000000000000100800000000001000000000000014000000000 ==> 1
+DAE6DB659B00010000000000000100200000000001000000000000012000000000 ==> 1
+DAE6DB659B00010000000000000100100000000001000000000000010800000000 ==> 1
+DAE6DB659B00010000000000000100040000000001000000000000010400000000 ==> 1
+DAE6DB659B00010000000000000100020000000001000000000000010100000000 ==> 1
+DAE6DB659B00010000000000000100008000000001000000000000010080000000 ==> 1
+DAE6DB659B00010000000000000100004000000001000000000000010020000000 ==> 1
+DAE6DB659B00010000000000000100001000000001000000000000010010000000 ==> 1
+DAE6DB659B00010000000000000100000800000001000000000000010004000000 ==> 1
+DAE6DB659B00010000000000000100000200000001000000000000010000800000 ==> 1
+DAE6DB659B00010000000000000100000100000001000000000000010000100000 ==> 1
+DAE6DB659B00010000000000000100000040000001000000000000010000020000 ==> 1
+DAE6DB659B00010000000000000100000020000001000000000000010000004000 ==> 1
+DAE6DB659B00010000000000000100000008000001000000000000010000000800 ==> 1
+DAE6DB659B00010000000000000100000004000001000000000000010000000100 ==> 1
+DAE6DB659B00010000000000000100000001000001000000000000010000000020 ==> 1
+DAE6DB659B00010000000000000100000000800001000000000000010000000004 ==> 1
+DAE6DB659B00014020100804000101008040200001080402010000014020000000 ==> 1
+DAE6DB659B00012010080402000100804020100001040201008000012010000000 ==> 1
+DAE6DB659B00010804020100000140201008040001010080402000010804000000 ==> 1
+DAE6DB659B00010402010080000120100804020001008040201000010400800000 ==> 1
+DAE6DB659B00010100804020000108040201000001402010080400010100100000 ==> 1
+DAE6DB659B00010080402010000104020100800001201008040200010080020000 ==> 1
+DAE6DB659B00010020100804000101008040200001080402010000014020004000 ==> 1
+DAE6DB659B00010010080402000100804020100001040201008000012010000800 ==> 1
+DAE6DB659B00010004020100000140201008040001010080402000010804000100 ==> 1
+DAE6DB659B00010002010080000120100804020001008040201000010400800020 ==> 1
+DAE6DB659B00010000804020000108040201000001402010080400010100100004 ==> 1
+DAE6DB659B00014080810102000101020204040001040408081000010000000000 ==> 0
+DAE6DB659B00012020404080000140808101020001010202040400010000000000 ==> 0
+DAE6DB659B00010810102020000120204040800001408081010200010000000000 ==> 0
+DAE6DB659B00010404080810000108101020200001202040408000014000000000 ==> 0
+DAE6DB659B00010102020404000104040808100001081010202000012000000000 ==> 0
+DAE6DB659B00010080810102000101020204040001040408081000010800000000 ==> 0
+DAE6DB659B00010020404080000140808101020001010202040400010400000000 ==> 0
+DAE6DB659B00010010102020000120204040800001408081010200010100000000 ==> 0
+DAE6DB659B00010004080810000108101020200001202040408000014080000000 ==> 0
+DAE6DB659B00010002020404000104040808100001081010202000012020000000 ==> 0
+DAE6DB659B00010000810102000101020204040001040408081000010810000000 ==> 0
+DAE6DB659B00010000404080000140808101020001010202040400010404000000 ==> 0
+DAE6DB659B00010000102020000120204040800001408081010200010100800000 ==> 0
+DAE6DB659B00010000080810000108101020200001202040408000014080100000 ==> 0
+DAE6DB659B00010000020404000104040808100001081010202000012020020000 ==> 0
+DAE6DB659B00010000010102000101020204040001040408081000010810004000 ==> 0
+DAE6DB659B00010000004080000140808101020001010202040400010404000800 ==> 0
+DAE6DB659B00010000002020000120204040800001408081010200010100800100 ==> 0
+DAE6DB659B00010000000810000108101020200001202040408000014080100020 ==> 0
+DAE6DB659B00010000000404000104040808100001081010202000012020020004 ==> 0
diff --git a/tests/codec/codec_hr_sid_test.c b/tests/codec/codec_hr_sid_test.c
new file mode 100644
index 00000000..ed4aa9bc
--- /dev/null
+++ b/tests/codec/codec_hr_sid_test.c
@@ -0,0 +1,144 @@
+/*
+ * This program is a test for osmo_hr_sid_classify(). It reads a set of
+ * TCH/HS Rx bit patterns in TI DSP format (originally captured from a
+ * Calypso MS under conditions of induced radio errors), converts each
+ * bit pattern to TS 101 318 format (using same bit reordering function
+ * as libosmocoding gsm0503 implementation), and feeds each test line
+ * to osmo_hr_sid_classify(). It then prints the output next to each input.
+ *
+ * Author: Mychaela N. Falconia <falcon@freecalypso.org>, 2024 - however,
+ * Mother Mychaela's contributions are NOT subject to copyright.
+ * No rights reserved, all rights relinquished.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <ctype.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <osmocom/core/bits.h>
+#include <osmocom/core/utils.h>
+#include <osmocom/codec/codec.h>
+
+#define HR_CODEC_BITS (GSM_HR_BYTES * 8)
+#define HR_BYTES_TIDSP (GSM_HR_BYTES + 1)
+
+/* re-arrange according to TS 05.03 Table 3a (receiver) */
+/* function copied from src/coding/gsm0503_coding.c */
+static void tch_hr_d_to_b(ubit_t *b_bits, const ubit_t *d_bits)
+{
+ int i;
+
+ const uint16_t *map;
+
+ if (!d_bits[93] && !d_bits[94])
+ map = gsm620_unvoiced_bitorder;
+ else
+ map = gsm620_voiced_bitorder;
+
+ for (i = 0; i < 112; i++)
+ b_bits[map[i]] = d_bits[i];
+}
+
+static void process_record(const char *hex_str, bool bci_flag)
+{
+ uint8_t dsp_rx_bytes[HR_BYTES_TIDSP];
+ ubit_t bits_transmission_order[HR_BYTES_TIDSP * 8];
+ ubit_t bits_codec_order[HR_CODEC_BITS];
+ uint8_t hr_bytes_ts101318[GSM_HR_BYTES];
+ bool bfi_flag = false;
+ enum osmo_gsm631_sid_class sidc;
+
+ osmo_hexparse(hex_str, dsp_rx_bytes, HR_BYTES_TIDSP);
+ osmo_pbit2ubit(bits_transmission_order, dsp_rx_bytes,
+ HR_BYTES_TIDSP * 8);
+ /* TI DSP format has a gap of 4 bits between class 1 and class 2
+ * portions - get rid of it. 95 is the number of class 1 bits,
+ * 17 is the number of class 2 bits. */
+ memmove(bits_transmission_order + 95,
+ bits_transmission_order + 95 + 4, 17);
+ tch_hr_d_to_b(bits_codec_order, bits_transmission_order);
+ osmo_ubit2pbit(hr_bytes_ts101318, bits_codec_order, HR_CODEC_BITS);
+
+ sidc = osmo_hr_sid_classify(hr_bytes_ts101318, bci_flag, &bfi_flag);
+ printf("%s %d ==> %d %d\n", hex_str, (int) bci_flag,
+ (int) sidc, (int) bfi_flag);
+}
+
+static void process_line(char *linebuf, const char *infname, int lineno)
+{
+ char *cp = linebuf, *hex_str;
+ int ndig;
+ bool bci_flag;
+
+ while (isspace(*cp))
+ cp++;
+ if (*cp == '\0' || *cp == '#')
+ return;
+ /* expect string of 30 hex digits */
+ hex_str = cp;
+ for (ndig = 0; ndig < HR_BYTES_TIDSP * 2; ndig++) {
+ if (!isxdigit(*cp))
+ goto inv;
+ cp++;
+ }
+ if (!isspace(*cp))
+ goto inv;
+ *cp++ = '\0';
+ while (isspace(*cp))
+ cp++;
+ /* 0 or 1 must follow, giving BCI flag */
+ if (*cp == '0')
+ bci_flag = false;
+ else if (*cp == '1')
+ bci_flag = true;
+ else
+ goto inv;
+ cp++;
+ /* must be end of non-comment line */
+ while (isspace(*cp))
+ cp++;
+ if (*cp != '\0' && *cp != '#')
+ goto inv;
+
+ process_record(hex_str, bci_flag);
+ return;
+
+inv: fprintf(stderr, "%s line %d: invalid syntax\n", infname, lineno);
+ exit(1);
+}
+
+int main(int argc, char **argv)
+{
+ const char *infname;
+ FILE *inf;
+ char linebuf[128];
+ int lineno;
+
+ if (argc != 2) {
+ fprintf(stderr, "usage: %s input-file\n", argv[0]);
+ exit(1);
+ }
+ infname = argv[1];
+ inf = fopen(infname, "r");
+ if (!inf) {
+ perror(infname);
+ exit(1);
+ }
+ for (lineno = 1; fgets(linebuf, sizeof(linebuf), inf); lineno++)
+ process_line(linebuf, infname, lineno);
+ fclose(inf);
+ exit(0);
+}
diff --git a/tests/codec/codec_hr_sid_test.in b/tests/codec/codec_hr_sid_test.in
new file mode 100644
index 00000000..e8ad9662
--- /dev/null
+++ b/tests/codec/codec_hr_sid_test.in
@@ -0,0 +1,61 @@
+# This file is input for the HR SID classifier test program. All TCH/HS
+# Rx bit strings contained in this file have been taken from hr-test1.dl
+# or hr-test2.dl, attached to this wiki page:
+#
+# https://osmocom.org/projects/retro-gsm/wiki/HRv1_error_flags
+#
+# Each Rx bit string (15 hex bytes) is from TI DSP; the 0 or 1 that follows
+# is the BCI flag to be fed to the SID classifier. The original DSP status
+# word is noted in the comments; running the unit test program will show
+# whether or not our SID classification agrees with that produced by
+# TI Calypso DSP.
+
+# perfect, error-free SID: hr-test2.dl line 171, C010
+FFFFFFFFFFFFFFFFFFFFFFFE1FFFF0 0
+
+# mode bits cleared to 0, all other bits still 1s
+FFFFFFFFFFFFFFFFFFFFFFF81FFFF0 0
+
+# selected error lines
+FFFFFFFFFFFFFFFFFFFFFFFE0FFF70 0 # hr-test2.dl line 4226, C010
+FFFFFFFFFFFFFFFFFFFFFFFE13FFF0 1 # hr-test2.dl line 4256, C012
+FFFFFFFFFFFFFFFFFFFFFFFE17FFF0 1 # hr-test2.dl line 4258, C012
+FFFD01FFFFFFFFFFFFFFFFFE0FFFF0 1 # hr-test2.dl line 4598, C00A
+FFFFFFFFFFFCC296452940FE1FFEF0 1 # hr-test2.dl line 5141, C00F
+FFFFFFFFFFFCC296452940FE1FFEF0 0 # same bits without BCI
+FF6E76F40C276FFFFFFFFFFE0FFFF0 1 # hr-test2.dl line 5173, C003
+FF6E76F40C276FFFFFFFFFFE0FFFF0 0 # same bits without BCI
+FFFFFFFFFDFFFFFFFFFFFFFE0FFFF0 1 # hr-test2.dl line 5206, C012
+FFFFFFFFFDFFFFFFFFFFFFFE0FFFF0 0 # same bits without BCI
+FFFFFFFFFFD0DFFFFFFFFFFE07FEF0 1 # hr-test2.dl line 5261, C00A
+FFFFFFFFFFD0DFFFFFFFFFFE07FEF0 0 # same bits without BCI
+FFFFFFFFFFFF41EAC9676FFE1F7DF0 1 # hr-test2.dl line 5738, C00F
+FFFFFFFFFFFF41EAC9676FFE1F7DF0 0 # same bits without BCI
+
+FFFFFFFFFFFF847D5B9DBFFE1937B0 1 # hr-test2.dl line 6175, C00F
+FFFFFFFFFFFF847D5B9DBFFE1937B0 0 # same bits without BCI
+FFFFFFFFFFFFFFFFFFFFFFD01FFEB0 1 # hr-test2.dl line 6188, C017
+FFFFFFFFFFFFFFFFFFFFFFD01FFEB0 0 # same bits without BCI
+FDBD7D552CB25FFFFFFFFFFE1DFBB0 1 # hr-test2.dl line 6191, C002
+FDBD7D552CB25FFFFFFFFFFE1DFBB0 0 # same bits without BCI
+FFD2F0A52B8FFFFFFFFEDE600FFDF0 1 # hr-test2.dl line 6195, C007
+FFD2F0A52B8FFFFFFFFEDE600FFDF0 0 # same bits without BCI
+FFFFFFFFCC7FFFFFFFF4EE601C31D0 1 # hr-test2.dl line 6318, C007
+FFFFFFFFCC7FFFFFFFF4EE601C31D0 0 # same bits without BCI
+FFFFFFFFFFFFFFFFFFFFA5901BEFD0 1 # hr-test2.dl line 6545, C00F
+FFFFFFFFFFFFFFFFFFFFA5901BEFD0 0 # same bits without BCI
+FFFFFFFFEA97FFFFFFE765901FFFB0 1 # hr-test2.dl line 6973, C00F
+FFFFFFFFEA97FFFFFFE765901FFFB0 0 # same bits without BCI
+
+FFFFFFFFF8C8A5E29DA0DFFE07FFF0 1 # hr-test2.dl line 7158, C00F
+FFFFFFFFF8C8A5E29DA0DFFE07FFF0 0 # same bits without BCI
+FFFD01853B7206E63FFFFFFE1FBFD0 1 # hr-test2.dl line 7175, C003
+FFFD01853B7206E63FFFFFFE1FBFD0 0 # same bits without BCI
+E6ACC7FFFF40FFFFFFFFFFFE1FF770 1 # hr-test2.dl line 7195, C00B
+E6ACC7FFFF40FFFFFFFFFFFE1FF770 0 # same bits without BCI
+
+# hr-test1.dl, PRBS without major errors
+55A5404BFAED58A3BE33A978092A40 0 # hr-test1.dl line 1051, C000
+CFE44B516ED5D1F54E4615AA101260 0 # hr-test1.dl line 2710, C000
+D7881D40AA0F68106195DCD41568C0 0 # hr-test1.dl line 4306, C000
+D4CFB4961F8F9F11313454560690E0 1 # hr-test1.dl line 4631, C002
diff --git a/tests/codec/codec_hr_sid_test.ok b/tests/codec/codec_hr_sid_test.ok
new file mode 100644
index 00000000..3ea1fedf
--- /dev/null
+++ b/tests/codec/codec_hr_sid_test.ok
@@ -0,0 +1,40 @@
+FFFFFFFFFFFFFFFFFFFFFFFE1FFFF0 0 ==> 2 0
+FFFFFFFFFFFFFFFFFFFFFFF81FFFF0 0 ==> 1 0
+FFFFFFFFFFFFFFFFFFFFFFFE0FFF70 0 ==> 2 0
+FFFFFFFFFFFFFFFFFFFFFFFE13FFF0 1 ==> 2 0
+FFFFFFFFFFFFFFFFFFFFFFFE17FFF0 1 ==> 2 0
+FFFD01FFFFFFFFFFFFFFFFFE0FFFF0 1 ==> 1 0
+FFFFFFFFFFFCC296452940FE1FFEF0 1 ==> 1 0
+FFFFFFFFFFFCC296452940FE1FFEF0 0 ==> 0 0
+FF6E76F40C276FFFFFFFFFFE0FFFF0 1 ==> 0 1
+FF6E76F40C276FFFFFFFFFFE0FFFF0 0 ==> 0 0
+FFFFFFFFFDFFFFFFFFFFFFFE0FFFF0 1 ==> 2 0
+FFFFFFFFFDFFFFFFFFFFFFFE0FFFF0 0 ==> 2 0
+FFFFFFFFFFD0DFFFFFFFFFFE07FEF0 1 ==> 1 0
+FFFFFFFFFFD0DFFFFFFFFFFE07FEF0 0 ==> 1 0
+FFFFFFFFFFFF41EAC9676FFE1F7DF0 1 ==> 1 0
+FFFFFFFFFFFF41EAC9676FFE1F7DF0 0 ==> 0 0
+FFFFFFFFFFFF847D5B9DBFFE1937B0 1 ==> 1 0
+FFFFFFFFFFFF847D5B9DBFFE1937B0 0 ==> 0 0
+FFFFFFFFFFFFFFFFFFFFFFD01FFEB0 1 ==> 1 0
+FFFFFFFFFFFFFFFFFFFFFFD01FFEB0 0 ==> 1 0
+FDBD7D552CB25FFFFFFFFFFE1DFBB0 1 ==> 0 1
+FDBD7D552CB25FFFFFFFFFFE1DFBB0 0 ==> 0 0
+FFD2F0A52B8FFFFFFFFEDE600FFDF0 1 ==> 0 1
+FFD2F0A52B8FFFFFFFFEDE600FFDF0 0 ==> 0 0
+FFFFFFFFCC7FFFFFFFF4EE601C31D0 1 ==> 0 1
+FFFFFFFFCC7FFFFFFFF4EE601C31D0 0 ==> 0 0
+FFFFFFFFFFFFFFFFFFFFA5901BEFD0 1 ==> 1 0
+FFFFFFFFFFFFFFFFFFFFA5901BEFD0 0 ==> 1 0
+FFFFFFFFEA97FFFFFFE765901FFFB0 1 ==> 1 0
+FFFFFFFFEA97FFFFFFE765901FFFB0 0 ==> 0 0
+FFFFFFFFF8C8A5E29DA0DFFE07FFF0 1 ==> 1 0
+FFFFFFFFF8C8A5E29DA0DFFE07FFF0 0 ==> 0 0
+FFFD01853B7206E63FFFFFFE1FBFD0 1 ==> 0 1
+FFFD01853B7206E63FFFFFFE1FBFD0 0 ==> 0 0
+E6ACC7FFFF40FFFFFFFFFFFE1FF770 1 ==> 1 0
+E6ACC7FFFF40FFFFFFFFFFFE1FF770 0 ==> 0 0
+55A5404BFAED58A3BE33A978092A40 0 ==> 0 0
+CFE44B516ED5D1F54E4615AA101260 0 ==> 0 0
+D7881D40AA0F68106195DCD41568C0 0 ==> 0 0
+D4CFB4961F8F9F11313454560690E0 1 ==> 0 0