blob: 1dbc61d28816a52727a8d21eced9dc9266a1f67f [file] [log] [blame]
Sylvain Munaut6c96cc22010-10-29 11:46:05 +02001/* Racal 6103E TCH recordings format */
2
3/*
4 * This file is part of gapk (GSM Audio Pocket Knife).
5 *
6 * gapk is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * gapk is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with gapk. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <stdint.h>
Harald Welte59128482017-05-28 10:20:54 +020021#include <assert.h>
Sylvain Munaut6c96cc22010-10-29 11:46:05 +020022
23#include <osmocom/codec/codec.h>
24
25#include <gapk/codecs.h>
26#include <gapk/formats.h>
27#include <gapk/utils.h>
28
Harald Welte59128482017-05-28 10:20:54 +020029#define RACAL_HR_LEN 14
30#define RACAL_FR_LEN 33
31#define RACAL_EFR_LEN 31
Sylvain Munaut6c96cc22010-10-29 11:46:05 +020032
33static int
Harald Welte59128482017-05-28 10:20:54 +020034racal_hr_from_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len)
Sylvain Munaut6c96cc22010-10-29 11:46:05 +020035{
36 int i, voiced;
37 const uint16_t *bit_mapping;
38
Harald Welte59128482017-05-28 10:20:54 +020039 assert(src_len == HR_CANON_LEN);
40
Sylvain Munaut6c96cc22010-10-29 11:46:05 +020041 voiced = (msb_get_bit(src, 34) << 1) | msb_get_bit(src, 35);
42
43 bit_mapping = voiced ?
44 &gsm620_voiced_bitorder[0] :
45 &gsm620_unvoiced_bitorder[0] ;
46
47 for (i=0; i<112; i++) {
48 int si = bit_mapping[i];
49 int di = i;
50 lsb_put_bit(dst, di, msb_get_bit(src, si));
51 }
52
Harald Welte59128482017-05-28 10:20:54 +020053 return RACAL_HR_LEN;
Sylvain Munaut6c96cc22010-10-29 11:46:05 +020054}
55
56static int
Harald Welte59128482017-05-28 10:20:54 +020057racal_hr_to_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len)
Sylvain Munaut6c96cc22010-10-29 11:46:05 +020058{
59 int i, voiced;
60 const uint16_t *bit_mapping;
61
Harald Welte59128482017-05-28 10:20:54 +020062 assert(src_len == HR_CANON_LEN);
63
Sylvain Munaut6c96cc22010-10-29 11:46:05 +020064 voiced = (lsb_get_bit(src, 94) << 1) | lsb_get_bit(src, 93);
65
66 bit_mapping = voiced ?
67 &gsm620_voiced_bitorder[0] :
68 &gsm620_unvoiced_bitorder[0] ;
69
70 for (i=0; i<112; i++) {
71 int si = i;
72 int di = bit_mapping[i];
73 msb_put_bit(dst, di, lsb_get_bit(src, si));
74 }
75
Harald Welte59128482017-05-28 10:20:54 +020076 return RACAL_HR_LEN;
Sylvain Munaut6c96cc22010-10-29 11:46:05 +020077}
78
79const struct format_desc fmt_racal_hr = {
80 .type = FMT_RACAL_HR,
81 .codec_type = CODEC_HR,
82 .name = "racal-hr",
83 .description = "Racal HR TCH/H recording",
84
Harald Welte59128482017-05-28 10:20:54 +020085 .frame_len = RACAL_HR_LEN,
Sylvain Munaut6c96cc22010-10-29 11:46:05 +020086 .conv_from_canon = racal_hr_from_canon,
87 .conv_to_canon = racal_hr_to_canon,
88};
89
90
91static int
Harald Welte59128482017-05-28 10:20:54 +020092racal_fr_from_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len)
Sylvain Munaut6c96cc22010-10-29 11:46:05 +020093{
94 int i;
95
Harald Welte59128482017-05-28 10:20:54 +020096 assert(src_len == FR_CANON_LEN);
97
Sylvain Munaut6c96cc22010-10-29 11:46:05 +020098 dst[32] = 0x00; /* last nibble won't written, pre-clear it */
99
100 for (i=0; i<260; i++) {
101 int si = gsm610_bitorder[i];
102 int di = i;
103 lsb_put_bit(dst, di, msb_get_bit(src, si));
104 }
105
Harald Welte59128482017-05-28 10:20:54 +0200106 return RACAL_FR_LEN;
Sylvain Munaut6c96cc22010-10-29 11:46:05 +0200107}
108
109static int
Harald Welte59128482017-05-28 10:20:54 +0200110racal_fr_to_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len)
Sylvain Munaut6c96cc22010-10-29 11:46:05 +0200111{
112 int i;
113
Harald Welte59128482017-05-28 10:20:54 +0200114 assert(src_len == RACAL_FR_LEN);
115
Sylvain Munaut6c96cc22010-10-29 11:46:05 +0200116 dst[32] = 0x00; /* last nibble won't written, pre-clear it */
117
118 for (i=0; i<260; i++) {
119 int si = i;
120 int di = gsm610_bitorder[i];
121 msb_put_bit(dst, di, lsb_get_bit(src, si));
122 }
123
Harald Welte59128482017-05-28 10:20:54 +0200124 return FR_CANON_LEN;
Sylvain Munaut6c96cc22010-10-29 11:46:05 +0200125}
126
127const struct format_desc fmt_racal_fr = {
128 .type = FMT_RACAL_FR,
129 .codec_type = CODEC_FR,
130 .name = "racal-fr",
131 .description = "Racal FR TCH/F recording",
132
Harald Welte59128482017-05-28 10:20:54 +0200133 .frame_len = RACAL_FR_LEN,
Sylvain Munaut6c96cc22010-10-29 11:46:05 +0200134 .conv_from_canon = racal_fr_from_canon,
135 .conv_to_canon = racal_fr_to_canon,
136};
137
138
139static int
Harald Welte59128482017-05-28 10:20:54 +0200140racal_efr_from_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len)
Sylvain Munaut6c96cc22010-10-29 11:46:05 +0200141{
142 int i;
143
Harald Welte59128482017-05-28 10:20:54 +0200144 assert(src_len == EFR_CANON_LEN);
145
Sylvain Munaut6c96cc22010-10-29 11:46:05 +0200146 dst[30] = 0x00; /* last nibble won't written, pre-clear it */
147
148 for (i=0; i<244; i++)
149 lsb_put_bit(dst, i, msb_get_bit(src, i));
150
Harald Welte59128482017-05-28 10:20:54 +0200151 return RACAL_EFR_LEN;
Sylvain Munaut6c96cc22010-10-29 11:46:05 +0200152}
153
154static int
Harald Welte59128482017-05-28 10:20:54 +0200155racal_efr_to_canon(uint8_t *dst, const uint8_t *src, unsigned int src_len)
Sylvain Munaut6c96cc22010-10-29 11:46:05 +0200156{
157 int i;
158
Harald Welte59128482017-05-28 10:20:54 +0200159 assert(src_len == RACAL_EFR_LEN);
160
Sylvain Munaut6c96cc22010-10-29 11:46:05 +0200161 dst[30] = 0x00; /* last nibble won't written, pre-clear it */
162
163 for (i=0; i<244; i++)
164 msb_put_bit(dst, i, lsb_get_bit(src, i));
165
Harald Welte59128482017-05-28 10:20:54 +0200166 return EFR_CANON_LEN;
Sylvain Munaut6c96cc22010-10-29 11:46:05 +0200167}
168
169const struct format_desc fmt_racal_efr = {
170 .type = FMT_RACAL_EFR,
171 .codec_type = CODEC_EFR,
172 .name = "racal-efr",
173 .description = "Racal EFR TCH/F recording",
174
Harald Welte59128482017-05-28 10:20:54 +0200175 .frame_len = RACAL_EFR_LEN,
Sylvain Munaut6c96cc22010-10-29 11:46:05 +0200176 .conv_from_canon = racal_efr_from_canon,
177 .conv_to_canon = racal_efr_to_canon,
178};