quite a lot of stuff, can't list them all here (approaching 1.9)

This commit is contained in:
2026-04-25 18:13:09 +02:00
parent d79c238924
commit 4b904bc720
20 changed files with 639 additions and 628 deletions
+230 -237
View File
@@ -2,245 +2,239 @@ import unicodedata
# This script prepares the RDS charset conversion function # This script prepares the RDS charset conversion function
# RDS code to UCS-2 # RDS code to UCS-2
charset = {}
# The data comes directly from the rdscharset.pdf, which comes from the R22_039_1 standard # The data comes directly from the rdscharset.pdf, which comes from the R22_039_1 standard
charset = {
data = """33 0x21 ! 0x0021 EXCLAMATION MARK 0x0A: 0x0A,
34 0x22 " 0x0022 QUOTATION MARK 0x0D: 0x0D,
35 0x23 # 0x0023 NUMBER SIGN 0x1F: 0x1F,
36 0x24 ¤ 0x00A4 CURRENCY SIGN 0x20: 0x20,
37 0x25 % 0x0025 PERCENT SIGN 0x21: 0x21,
38 0x26 & 0x0026 AMPERSAND 0x22: 0x22,
39 0x27 ' 0x0027 APOSTROPHE 0x23: 0x23,
40 0x28 ( 0x0028 LEFT PARENTHESIS 0x24: 0xA4,
41 0x29 ) 0x0029 RIGHT PARENTHESIS 0x25: 0x25,
42 0x2A * 0x002A ASTERISK 0x26: 0x26,
43 0x2B + 0x002B PLUS SIGN 0x27: 0x27,
44 0x2C , 0x002C COMMA 0x28: 0x28,
45 0x2D - 0x002D HYPHEN-MINUS 0x29: 0x29,
46 0x2E . 0x002E FULL STOP 0x2A: 0x2A,
47 0x2F / 0x002F SOLIDUS 0x2B: 0x2B,
48 0x30 0 0x0030 DIGIT ZERO 0x2C: 0x2C,
49 0x31 1 0x0031 DIGIT ONE 0x2D: 0x2D,
50 0x32 2 0x0032 DIGIT TWO 0x2E: 0x2E,
51 0x33 3 0x0033 DIGIT THREE 0x2F: 0x2F,
52 0x34 4 0x0034 DIGIT FOUR 0x30: 0x30,
53 0x35 5 0x0035 DIGIT FIVE 0x31: 0x31,
54 0x36 6 0x0036 DIGIT SIX 0x32: 0x32,
55 0x37 7 0x0037 DIGIT SEVEN 0x33: 0x33,
56 0x38 8 0x0038 DIGIT EIGHT 0x34: 0x34,
57 0x39 9 0x0039 DIGIT NINE 0x35: 0x35,
58 0x3A : 0x003A COLON 0x36: 0x36,
59 0x3B ; 0x003B SEMICOLON 0x37: 0x37,
60 0x3C < 0x003C LESS-THAN SIGN 0x38: 0x38,
61 0x3D = 0x003D EQUALS SIGN 0x39: 0x39,
62 0x3E > 0x003E GREATER-THAN SIGN 0x3A: 0x3A,
63 0x3F ? 0x003F QUESTION MARK 0x3B: 0x3B,
64 0x40 @ 0x0040 COMMERCIAL AT 0x3C: 0x3C,
65 0x41 A 0x0041 LATIN CAPITAL LETTER A 0x3D: 0x3D,
66 0x42 B 0x0042 LATIN CAPITAL LETTER B 0x3E: 0x3E,
67 0x43 C 0x0043 LATIN CAPITAL LETTER C 0x3F: 0x3F,
68 0x44 D 0x0044 LATIN CAPITAL LETTER D 0x40: 0x40,
69 0x45 E 0x0045 LATIN CAPITAL LETTER E 0x41: 0x41,
70 0x46 F 0x0046 LATIN CAPITAL LETTER F 0x42: 0x42,
71 0x47 G 0x0047 LATIN CAPITAL LETTER G 0x43: 0x43,
72 0x48 H 0x0048 LATIN CAPITAL LETTER H 0x44: 0x44,
73 0x49 I 0x0049 LATIN CAPITAL LETTER I 0x45: 0x45,
74 0x4A J 0x004A LATIN CAPITAL LETTER J 0x46: 0x46,
75 0x4B K 0x004B LATIN CAPITAL LETTER K 0x47: 0x47,
76 0x4C L 0x004C LATIN CAPITAL LETTER L 0x48: 0x48,
77 0x4D M 0x004D LATIN CAPITAL LETTER M 0x49: 0x49,
78 0x4E N 0x004E LATIN CAPITAL LETTER N 0x4A: 0x4A,
79 0x4F O 0x004F LATIN CAPITAL LETTER O 0x4B: 0x4B,
80 0x50 P 0x0050 LATIN CAPITAL LETTER P 0x4C: 0x4C,
81 0x51 Q 0x0051 LATIN CAPITAL LETTER Q 0x4D: 0x4D,
82 0x52 R 0x0052 LATIN CAPITAL LETTER R 0x4E: 0x4E,
83 0x53 S 0x0053 LATIN CAPITAL LETTER S 0x4F: 0x4F,
84 0x54 T 0x0054 LATIN CAPITAL LETTER T 0x50: 0x50,
85 0x55 U 0x0055 LATIN CAPITAL LETTER U 0x51: 0x51,
86 0x56 V 0x0056 LATIN CAPITAL LETTER V 0x52: 0x52,
87 0x57 W 0x0057 LATIN CAPITAL LETTER W 0x53: 0x53,
88 0x58 X 0x0058 LATIN CAPITAL LETTER X 0x54: 0x54,
89 0x59 Y 0x0059 LATIN CAPITAL LETTER Y 0x55: 0x55,
90 0x5A Z 0x005A LATIN CAPITAL LETTER Z 0x56: 0x56,
91 0x5B [ 0x005B LEFT SQUARE BRACKET 0x57: 0x57,
92 0x5C \\ 0x005C REVERSE SOLIDUS 0x58: 0x58,
93 0x5D ] 0x005D RIGHT SQUARE BRACKET 0x59: 0x59,
94 0x5E ― 0x2015 HORIZONTAL BAR 0x5A: 0x5A,
95 0x5F _ 0x005F LOW LINE 0x5B: 0x5B,
96 0x60 ║ 0x2016 DOUBLE VERTICAL LINE 0x5C: 0x5C,
97 0x61 a 0x0061 LATIN SMALL LETTER A 0x5D: 0x5D,
98 0x62 b 0x0062 LATIN SMALL LETTER B 0x5E: 0x2015,
99 0x63 c 0x0063 LATIN SMALL LETTER C 0x5F: 0x005F,
100 0x64 d 0x0064 LATIN SMALL LETTER D 0x60: 0x2016,
101 0x65 e 0x0065 LATIN SMALL LETTER E 0x61: 0x61,
102 0x66 f 0x0066 LATIN SMALL LETTER F 0x62: 0x62,
103 0x67 g 0x0067 LATIN SMALL LETTER G 0x63: 0x63,
104 0x68 h 0x0068 LATIN SMALL LETTER H 0x64: 0x64,
105 0x69 i 0x0069 LATIN SMALL LETTER I 0x65: 0x65,
106 0x6A j 0x006A LATIN SMALL LETTER J 0x66: 0x66,
107 0x6B k 0x006B LATIN SMALL LETTER K 0x67: 0x67,
108 0x6C l 0x006C LATIN SMALL LETTER L 0x68: 0x68,
109 0x6D m 0x006D LATIN SMALL LETTER M 0x69: 0x69,
110 0x6E n 0x006E LATIN SMALL LETTER N 0x6A: 0x6A,
111 0x6F o 0x006F LATIN SMALL LETTER O 0x6B: 0x6B,
112 0x70 p 0x0070 LATIN SMALL LETTER P 0x6C: 0x6C,
113 0x71 q 0x0071 LATIN SMALL LETTER Q 0x6D: 0x6D,
114 0x72 r 0x0072 LATIN SMALL LETTER R 0x6E: 0x6E,
115 0x73 s 0x0073 LATIN SMALL LETTER S 0x6F: 0x6F,
116 0x74 t 0x0074 LATIN SMALL LETTER T 0x70: 0x70,
117 0x75 u 0x0075 LATIN SMALL LETTER U 0x71: 0x71,
118 0x76 v 0x0076 LATIN SMALL LETTER V 0x72: 0x72,
119 0x77 w 0x0077 LATIN SMALL LETTER W 0x73: 0x73,
120 0x78 x 0x0078 LATIN SMALL LETTER X 0x74: 0x74,
121 0x79 y 0x0079 LATIN SMALL LETTER Y 0x75: 0x75,
122 0x7A z 0x007A LATIN SMALL LETTER Z 0x76: 0x76,
123 0x7B { 0x007B LEFT CURLY BRACKET 0x77: 0x77,
124 0x7C | 0x007C VERTICAL LINE 0x78: 0x78,
125 0x7D } 0x007D RIGHT CURLY BRACKET 0x79: 0x79,
126 0x7E ¯ 0x203E OVERLINE 0x7A: 0x7A,
128 0x80 á 0x00E1 LATIN SMALL LETTER A WITH ACUTE 0x7B: 0x7B,
129 0x81 à 0x00E0 LATIN SMALL LETTER A WITH GRAVE 0x7C: 0x7C,
130 0x82 é 0x00E9 LATIN SMALL LETTER E WITH ACUTE 0x7D: 0x7D,
131 0x83 è 0x00E8 LATIN SMALL LETTER E WITH GRAVE 0x7E: 0x203E,
132 0x84 í 0x00ED LATIN SMALL LETTER I WITH ACUTE 0x80: 0xE1,
133 0x85 ì 0x00EC LATIN SMALL LETTER I WITH GRAVE 0x81: 0xE0,
134 0x86 ó 0x00F3 LATIN SMALL LETTER O WITH ACUTE 0x82: 0xE9,
135 0x87 ò 0x00F2 LATIN SMALL LETTER O WITH GRAVE 0x83: 0xE8,
136 0x88 ú 0x00FA LATIN SMALL LETTER U WITH ACUTE 0x84: 0xED,
137 0x89 ù 0x00F9 LATIN SMALL LETTER U WITH GRAVE 0x85: 0xEC,
138 0x8A Ñ 0x00D1 LATIN CAPITAL LETTER N WITH TILDE 0x86: 0xF3,
139 0x8B Ç 0x00C7 LATIN CAPITAL LETTER C WITH CEDILLA 0x87: 0xF2,
140 0x8C Ş 0x015E LATIN CAPITAL LETTER S WITH CEDILLA 0x88: 0xFA,
141 0x8D ß 0x00DF LATIN SMALL LETTER SHARP S (German) 0x89: 0xF9,
142 0x8E ¡ 0x00A1 INVERTED EXCLAMATION MARK 0x8A: 0xD1,
143 0x8F IJ 0x0132 LATIN CAPITAL LIGATURE IJ 0x8B: 0xC7,
144 0x90 â 0x00E2 LATIN SMALL LETTER A WITH CIRCUMFLEX 0x8C: 0x15E,
145 0x91 ä 0x00E4 LATIN SMALL LETTER A WITH DIAERESIS 0x8D: 0xDF,
146 0x92 ê 0x00EA LATIN SMALL LETTER E WITH CIRCUMFLEX 0x8E: 0xA1,
147 0x93 ë 0x00EB LATIN SMALL LETTER E WITH DIAERESIS 0x8F: 0x132,
148 0x94 î 0x00EE LATIN SMALL LETTER I WITH CIRCUMFLEX 0x90: 0xE2,
149 0x95 ï 0x00EF LATIN SMALL LETTER I WITH DIAERESIS 0x91: 0xE4,
150 0x96 ô 0x00F4 LATIN SMALL LETTER O WITH CIRCUMFLEX 0x92: 0xEA,
151 0x97 ö 0x00F6 LATIN SMALL LETTER O WITH DIAERESIS 0x93: 0xEB,
152 0x98 û 0x00FB LATIN SMALL LETTER U WITH CIRCUMFLEX 0x94: 0xEE,
153 0x99 ü 0x00FC LATIN SMALL LETTER U WITH DIAERESIS 0x95: 0xEF,
154 0x9A ñ 0x00F1 LATIN SMALL LETTER N WITH TILDE 0x96: 0xF4,
155 0x9B ç 0x00E7 LATIN SMALL LETTER C WITH CEDILLA 0x97: 0xF6,
156 0x9C ş 0x015F LATIN SMALL LETTER S WITH CEDILLA 0x98: 0xFB,
157 0x9D ğ 0x011F LATIN SMALL LETTER G WITH BREVE 0x99: 0xFC,
158 0x9E ı 0x0131 LATIN SMALL LETTER DOTLESS I 0x9A: 0xF1,
159 0x9F ij 0x0133 LATIN SMALL LIGATURE IJ 0x9B: 0xE7,
160 0xA0 ª 0x00AA FEMININE ORDINAL INDICATOR 0x9C: 0x15F,
161 0xA1 α 0x03B1 GREEK SMALL LETTER ALPHA 0x9D: 0x11F,
162 0xA2 © 0x00A9 COPYRIGHT SIGN 0x9E: 0x131,
163 0xA3 ‰ 0x2030 PER THOUSAND SIGN 0x9F: 0x133,
164 0xA4 Ğ 0x011E LATIN CAPITAL LETTER G WITH BREVE 0xA0: 0xAA,
165 0xA5 ĕ 0x011B LATIN SMALL LETTER WITH CARON 0xA1: 0x3B1,
166 0xA6 ň 0x0148 LATIN SMALL LETTER N WITH CARON 0xA2: 0xA9,
167 0xA7 ő 0x0151 LATIN SMALL LETTER O WITH DOUBLE ACUTE 0xA3: 0x2030,
168 0xA8 π 0x03C0 GREEK SMALL LETTER PI 0xA4: 0x11E,
169 0xA9 € 0x20AC EURO SIGN 0xA5: 0x11B,
170 0xAA ₤ 0x00A3 POUND SIGN 0xA6: 0x148,
171 0xAB $ 0x0024 DOLLAR SIGN 0xA7: 0x151,
172 0xAC ← 0x2190 LEFTWARDS ARROW 0xA8: 0x3C0,
173 0xAD ↑ 0x2191 UPWARDS ARROW 0xA9: 0x20AC,
174 0xAE → 0x2192 RIGHTWARDS ARROW 0xAA: 0xA3,
175 0xAF ↓ 0x2193 DOWNWARDS ARROW 0xAB: 0x24,
176 0xB0 º 0x00BA MASCULIN ORDINAL INDICATOR 0xAC: 0x2190,
177 0xB1 ¹ 0x00B9 SUPERSCRIPT ONE 0xAD: 0x2191,
178 0xB2 ² 0x00B2 SUPERSCRIPT TWO 0xAE: 0x2192,
179 0xB3 ³ 0x00B3 SUPERSCRIPT THREE 0xAF: 0x2193,
180 0xB4 ± 0x00B1 PLUS-MINUS SIGN 0xB0: 0xBA,
181 0xB5 İ 0x0130 LATIN CAPITAL LETTER I WITH DOT ABOVE 0xB1: 0xB9,
182 0xB6 ń 0x0144 LATIN SMALL LETTER N WITH ACUTE 0xB2: 0xB2,
183 0xB7 ű 0x0171 LATIN SMALL LETTER U WITH DOUBLE ACUTE 0xB3: 0xB3,
184 0xB8 µ 0x00B5 MIKRO SIGN 0xB4: 0xB1,
185 0xB9 ¿ 0x00BF INVERTED QUESTION MARK 0xB5: 0x130,
186 0xBA ÷ 0x00F7 DIVISION SIGN 0xB6: 0x144,
187 0xBB º 0x00B0 DEGREE SIGN 0xB7: 0x171,
188 0xBC ¼ 0x00BC VULGAR FRACTION ONE QUARTER 0xB8: 0xB5,
189 0xBD ½ 0x00BD VULGAR FRACTION ONE HALF 0xB9: 0xBF,
190 0xBE ¾ 0x00BE VULGAR FRACTION THREE QUARTERS 0xBA: 0xF7,
191 0xBF § 0x00A7 SECTION SIGN 0xBB: 0xB0,
192 0xC0 Á 0x00C1 LATIN CAPITAL LETTER A WITH ACUTE 0xBC: 0xBC,
193 0xC1 À 0x00C0 LATIN CAPITAL LETTER A WITH GRAVE 0xBD: 0xBD,
194 0xC2 É 0x00C9 LATIN CAPITAL LETTER E WITH ACUTE 0xBE: 0xBE,
195 0xC3 È 0x00C8 LATIN CAPITAL LETTER E WITH GRAVE 0xBF: 0xA7,
196 0xC4 Í 0x00CD LATIN CAPITAL LETTER I WITH ACUTE 0xC0: 0xC1,
197 0xC5 Ì 0x00CC LATIN CAPITAL LETTER I WITH GRAVE 0xC1: 0xC0,
198 0xC6 Ó 0x00D3 LATIN CAPITAL LETTER O WITH ACUTE 0xC2: 0xC9,
199 0xC7 Ò 0x00D2 LATIN CAPITAL LETTER O WITH GRAVE 0xC3: 0xC8,
200 0xC8 Ú 0x00DA LATIN CAPITAL LETTER U WITH ACUTE 0xC4: 0xCD,
201 0xC9 Ù 0x00D9 LATIN CAPITAL LETTER U WITH GRAVE 0xC5: 0xCC,
202 0xCA Ř 0x0158 LATIN CAPITAL LETTER R WITH CARON 0xC6: 0xD3,
203 0xCB Č 0x010C LATIN CAPITAL LETTER C WITH CARON 0xC7: 0xD2,
204 0xCC Š 0x0160 LATIN CAPITAL LETTER S WITH CARON 0xC8: 0xDA,
205 0xCD Ž 0x017D LATIN CAPITAL LETTER Z WITH CARON 0xC9: 0xD9,
206 0xCE Ð 0x00D0 LATIN CAPITAL LETTER ETH 0xCA: 0x158,
207 0xCF Ŀ 0x013F LATIN CAPITAL LETTER L WITH MIDDLE DOT 0xCB: 0x10C,
208 0xD0 Â 0x00C2 LATIN CAPITAL LETTER A WITH CIRCUMFLEX 0xCC: 0x160,
209 0xD1 Ä 0x00C4 LATIN CAPITAL LETTER A WITH DIAERESIS 0xCD: 0x17D,
210 0xD2 Ê 0x00CA LATIN CAPITAL LETTER E WITH CIRCUMFLEX 0xCE: 0xD0,
211 0xD3 Ë 0x00CB LATIN CAPITAL LETTER A WITH DIAERESIS 0xCF: 0x13F,
212 0xD4 Î 0x00CE LATIN CAPITAL LETTER I WITH CIRCUMFLEX 0xD0: 0xC2,
213 0xD5 Ï 0x00CF LATIN CAPITAL LETTER I WITH DIAERESIS 0xD1: 0xC4,
214 0xD6 Ô 0x00D4 0xD2: 0xCA,
215 0xD7 Ö 0x00D6 0xD3: 0xCB,
216 0xD8 Û 0x00DB 0xD4: 0xCE,
217 0xD9 Ü 0x00DC 0xD5: 0xCF,
218 0xDA ř 0x0159 0xD6: 0xD4,
219 0xDB č 0x010D 0xD7: 0xD6,
220 0xDC š 0x0161 0xD8: 0xDB,
221 0xDD ž 0x017E 0xD9: 0xDC,
222 0xDE đ 0x0111 0xDA: 0x159,
223 0xDF ŀ 0x0140 0xDB: 0x10D,
224 0xE0 Ã 0x00C3 0xDC: 0x161,
225 0xE1 Å 0x00C5 0xDD: 0x17E,
226 0xE2 Æ 0x00C6 0xDE: 0x111,
227 0xE3 Œ 0x0152 0xDF: 0x140,
228 0xE4 ŷ 0x0177 0xE0: 0xC3,
229 0xE5 Ý 0x00DD 0xE1: 0xC5,
230 0xE6 Õ 0x00D5 0xE2: 0xC6,
231 0xE7 Ø 0x00D8 0xE3: 0x152,
232 0xE8 Þ 0x00DE 0xE4: 0x177,
233 0xE9 Ŋ 0x014A 0xE5: 0xDD,
234 0xEA Ŕ 0x0154 0xE6: 0xD5,
235 0xEB Ć 0x0106 0xE7: 0xD8,
236 0xEC Ś 0x015A 0xE8: 0xDE,
237 0xED Ź 0x0179 0xE9: 0x14A,
238 0xEE Ŧ 0x0166 0xEA: 0x154,
239 0xEF ð 0x00F0 0xEB: 0x106,
240 0xF0 ã 0x00E3 0xEC: 0x15A,
241 0xF1 å 0x00E5 0xED: 0x179,
242 0xF2 æ 0x00E6 0xEE: 0x166,
243 0xF3 œ 0x0153 0xEF: 0xF0,
244 0xF4 ŵ 0x0175 0xF0: 0xE3,
245 0xF5 ý 0x00FD 0xF1: 0xE5,
246 0xF6 õ 0x00F5 0xF2: 0xE6,
247 0xF7 ø 0x00F8 0xF3: 0x153,
248 0xF8 þ 0x00FE 0xF4: 0x175,
249 0xF9 ŋ 0x014B 0xF5: 0xFD,
250 0xFA ŕ 0x0155 0xF6: 0xF5,
251 0xFB ć 0x0107 0xF7: 0xF8,
252 0xFC ś 0x015B 0xF8: 0x0FE,
253 0xFD ź 0x017A 0xF9: 0x14B,
254 0xFE ŧ 0x0167 0xFA: 0x155,
""" 0xFB: 0x107,
0xFC: 0x15B,
for line in data.splitlines(): 0xFD: 0x17A,
parts = line.split() 0xFE: 0x167}
num, rds_code, symbol, ucs2, *_ = parts
code = int(rds_code, 16)
ucs = int(ucs2, 16)
if code != ucs: charset[code] = ucs
table = {} table = {}
import struct import struct
for rds_code, ucs2 in charset.items(): for rds_code, ucs2 in charset.items():
utf8 = struct.pack("!H", ucs2).decode("utf-16-be").encode() utf8 = struct.pack("!H", ucs2).decode("utf-16-be").encode("utf-8")
node = table node = table
for i, byte in enumerate(utf8): for i, byte in enumerate(utf8):
@@ -263,10 +257,9 @@ def generate_switch(node, indent=0, level=0):
code_lines.extend(generate_switch(child, indent + 2, level + 1)) code_lines.extend(generate_switch(child, indent + 2, level + 1))
code_lines.append(f"{ind}\t\tbreak;") code_lines.append(f"{ind}\t\tbreak;")
else: else:
comment = unicodedata.name(struct.pack("!H", charset[child]).decode("utf-16-be")) comment = unicodedata.name(struct.pack("!H", charset[child]).decode("utf-16-be"), "N/A")
code_lines.append(f"{ind}\tcase (char)0x{byte:02x}: new_str[i] = (char)0x{child:02x}; break; // {comment}") code_lines.append(f"{ind}\tcase (char)0x{byte:02x}: output[i] = (char)0x{child:02x}; break; // {comment}")
if level == 0: code_lines.append(f"{ind}\tdefault: new_str[i] = *str; break;") code_lines.append(f"{ind}\tdefault: output[i] = (char)0x3f; break; // {unicodedata.name("?")}") # Question mark
else: code_lines.append(f"{ind}\tdefault: new_str[i] = (char)0x3f; break; // {unicodedata.name("?")}") # Question mark
code_lines.append(f"{ind}}}") code_lines.append(f"{ind}}}")
return code_lines return code_lines
+48 -20
View File
@@ -1,10 +1,10 @@
---@meta ---@meta
---@type string
core_version = ""
dp = {} dp = {}
---@type string
dp.core_version = ""
---@type integer ---@type integer
dp.max_programs = 0 dp.max_programs = 0
@@ -17,7 +17,7 @@ function dp.crc16(data) end
---@return nil ---@return nil
function dp.set_program_defaults() end function dp.set_program_defaults() end
---Saves, loads and resets the state of the data, you might as well restart the whole program ---Saves, loads and resets the state of the data, you might as well restart the whole program. this does NOT cause data loss other than the current internal state
---@return nil ---@return nil
function dp.reset_rds() end function dp.reset_rds() end
@@ -37,40 +37,62 @@ function dp.set_writing_program(program_idx) end
---@return integer ---@return integer
function dp.get_writing_program() end function dp.get_writing_program() end
---Encodes the given UTF-8 string into the unnamed RDS character set
---@param data string
---@return string
function dp.encode_charset(data) end
hooks = {} hooks = {}
---This function is called by the C core after we reset data, or have no data in general ---This function is called by the C core after we reset data, or have no data in general
---It should be defined by the user in the script. ---It should be defined by the user in the script.
---This is a table of functions. Each will be called ---This is a table of functions. Each will be called
---@type function[]
hooks.on_init = {} hooks.on_init = {}
---This function is called by the C core after we initialize the encoder (always, every start) ---This function is called by the C core after we initialize the encoder (always, every start)
---It should be defined by the user in the script. ---It should be defined by the user in the script.
---This is a table of functions. Each will be called ---This is a table of functions. Each will be called
---@type function[]
hooks.on_start = {} hooks.on_start = {}
---This function is called every time when the state resets, register your odas here ---This function is called every time when the state resets, register your odas here
---It should be defined by the user in the script. ---It should be defined by the user in the script.
---This is a table of functions. Each will be called ---This is a table of functions. Each will be called
---@type function[]
hooks.on_state = {} hooks.on_state = {}
---This function is called every second ---This function is called every second
---It should be defined by the user in the script. ---It should be defined by the user in the script.
---This is a table of functions. Each will be called ---This is a table of functions. Each will be called
---@type function[]
hooks.tick = {} hooks.tick = {}
---This function is calld every time a RT transmits start to end - Useful for UECP's RT buffer shenanigans ---This function is called every minute
---It should be defined by the user in the script. ---It should be defined by the user in the script.
---This is a table of functions. Each will be called ---This is a table of functions. Each will be called
---@type function[]
hooks.minute_tick = {}
---This function is called every time a RT transmits start to end - Useful for UECP's RT buffer shenanigans
---It should be defined by the user in the script.
---This is a table of functions. Each will be called
---@type function[]
hooks.rt_transmission = {} hooks.rt_transmission = {}
---This function is calld every time a PS transmits start to end
---It should be defined by the user in the script.
---This is a table of functions. Each will be called
---@type function[]
hooks.ps_transmission = {}
-- Every function with with the s suffixed table means that other versions of that function can be in that list-table, and each one will be called -- Every function with with the s suffixed table means that other versions of that function can be in that list-table, and each one will be called
---This function is called in order to handle UDP data ---This function is called in order to handle UDP data. The string returned is sent back to the UDP peer as a response
---It should be defined by the user in the script. ---It should be defined by the user in the script.
---@param data string ---@param data string
---@return string ---@return string
function data_handle(data) end function hooks.data_handle(data) end
---This function is called when the group "L" is in the sequence ---This function is called when the group "L" is in the sequence
---Please remember that the core always fills in PTY and TP and PI in C if this is an B group ---Please remember that the core always fills in PTY and TP and PI in C if this is an B group
@@ -80,7 +102,7 @@ function data_handle(data) end
---@return integer b ---@return integer b
---@return integer c ---@return integer c
---@return integer d ---@return integer d
function group(group) end function hooks.group(group) end
---This function is called when an RDS2 group is to be generated on mode 3 ---This function is called when an RDS2 group is to be generated on mode 3
---If a was returned 0, PTY and TP will be filled in, along with the PI code in C if needed ---If a was returned 0, PTY and TP will be filled in, along with the PI code in C if needed
@@ -91,7 +113,7 @@ function group(group) end
---@return integer b ---@return integer b
---@return integer c ---@return integer c
---@return integer d ---@return integer d
function rds2_group(stream) end function hooks.rds2_group(stream) end
rds = {} rds = {}
@@ -166,15 +188,26 @@ function rds.set_link(linkage) end
---@return boolean ---@return boolean
function rds.get_link() end function rds.get_link() end
-- String Setters (Charset converted) -- String Setters
---@param ptyn string Program Type Name (max 8 chars) ---@param ptyn string Program Type Name (max 8 chars)
function rds.set_ptyn(ptyn) end function rds.set_ptyn(ptyn) end
---@param ptyn string Program Type Name (max 8 chars) which is expected to be already encoded in the RDS charset
function rds.set_ptyn_raw(ptyn) end
---@param ps string Program Service (8 chars) ---@param ps string Program Service (8 chars)
function rds.set_ps(ps) end function rds.set_ps(ps) end
---@param ps string Program Service (8 chars) which is expected to be already encoded in the RDS charset
function rds.set_ps_raw(ps) end
---@param tps string Traffic PS ---@param tps string Traffic PS
function rds.set_tps(tps) end function rds.set_tps(tps) end
---@param tps string Traffic PS which is expected to be already encoded in the RDS charset
function rds.set_tps_raw(tps) end
---@param rt string Radio Text (max 64 chars) ---@param rt string Radio Text (max 64 chars)
function rds.set_rt(rt) end function rds.set_rt(rt) end
---@param rt string Radio Text (max 64 chars) which is expected to be already encoded in the RDS charset
function rds.set_rt_raw(rt) end
---@return nil ---@return nil
function rds.toggle_rt_ab() end function rds.toggle_rt_ab() end
@@ -231,15 +264,6 @@ function rds.set_eon(eon, data) end
---@return EON_Data ---@return EON_Data
function rds.get_eon(eon) end function rds.get_eon(eon) end
---Sets the X/Y of the UDG
---@param xy boolean
---@param groups table Table of tables, this should be up to 8 tables containing 3 integers
function rds.set_udg(xy, groups) end
---Sets the X/Y of the UDG for RDS2
---@param xy boolean
---@param groups table Table of tables, this should be up to 8 tables containing 4 integers
function rds.set_udg2(xy, groups) end
userdata = {} userdata = {}
---@type integer ---@type integer
@@ -263,7 +287,7 @@ function userdata.get() end
---@return string ---@return string
function userdata.get_offset(offset, size) end function userdata.get_offset(offset, size) end
--#endregion --- Extensions start here - The following is made in Lua and can be used as an standard library
ext = {} ext = {}
rds.ext = {} rds.ext = {}
@@ -359,3 +383,7 @@ function ext.unregister_oda_rds2(oda_id) end
function rds.ext.set_ert(ert) end function rds.ext.set_ert(ert) end
---@return string ---@return string
function rds.ext.get_ert() end function rds.ext.get_ert() end
---@param designator string
---@param handler function
function rds.ext.register_group(designator, handler) end
+1 -5
View File
@@ -29,11 +29,7 @@ RDS95 is the only (as far as i can tell) encoder to transmit the 9-bit AF codes
## Lua engine ## Lua engine
Yet another unique feature, the Lua engine allows you to parse the messages from UDP, and more! Yet another unique feature, the Lua engine allows you to control the encoder, almost entirely.
You wanna make an ODA? Sure go for it, look in the scripts folder to see `0-ert.lua`, that is how ERT is implemmented in this encoder
Wanna do scrolling PS without C stuff and no external scripts? Just do it with the `tick` function!
Don't wanna run a bash script to send your station's data to the encoder when defaults take over? I'll welcome you to the `on_init` function
### RFT ### RFT
+22
View File
@@ -0,0 +1,22 @@
hooks.registered_groups = {}
function hooks.group(group)
if hooks.registered_groups[group] then
local ok, generated, b, c, d = pcall(hooks.registered_groups[group], group)
if ok then return generated, b, c, d
else
print(generated)
return false, 0, 0, 0
end
end
return false, 0, 0, 0
end
---@param designator string
---@param handler function
function rds.ext.register_group(designator, handler)
for i = 1, #designator do
local char = designator:sub(i, i)
hooks.registered_groups[char] = handler
end
end
+1 -1
View File
@@ -51,7 +51,7 @@ function ext.set_oda_handler_rds2(oda_id, func)
_RDS2_ODAs[oda_id].handler = func _RDS2_ODAs[oda_id].handler = func
end end
function rds2_group(stream) function hooks.rds2_group(stream)
if #_RDS2_ODAs == 0 then return false, 0, 0, 0, 0 end if #_RDS2_ODAs == 0 then return false, 0, 0, 0, 0 end
if _RDS2_ODA_pointer > #_RDS2_ODAs then _RDS2_ODA_pointer = 1 end if _RDS2_ODA_pointer > #_RDS2_ODAs then _RDS2_ODA_pointer = 1 end
+2 -4
View File
@@ -112,16 +112,14 @@ local function get_data()
return false, 0, 0, 0 return false, 0, 0, 0
end end
function group(group_type) local function group_handler(group_type)
if group_type == "O" or group_type == "K" then
if #_RDS_ODAs == 0 then return false, 0, 0, 0 end if #_RDS_ODAs == 0 then return false, 0, 0, 0 end
if _RDS_ODA_pointer > #_RDS_ODAs or _RDS_ODA_pointer < 1 then _RDS_ODA_pointer = 1 end if _RDS_ODA_pointer > #_RDS_ODAs or _RDS_ODA_pointer < 1 then _RDS_ODA_pointer = 1 end
if group_type == "O" then return get_aid() if group_type == "O" then return get_aid()
elseif group_type == "K" then return get_data() end elseif group_type == "K" then return get_data() end
end
return false, 0, 0, 0
end end
rds.ext.register_group("OK", group_handler)
table.insert(hooks.on_state, function () table.insert(hooks.on_state, function ()
_RDS_ODAs = {} _RDS_ODAs = {}
+12 -4
View File
@@ -19,7 +19,7 @@ hooks.rt_transmission[#hooks.rt_transmission + 1] = function ()
local entry = uecp.rt_buffer[uecp.rt_buffer_index] local entry = uecp.rt_buffer[uecp.rt_buffer_index]
uecp.rt_tx_remaining = entry.number_tx uecp.rt_tx_remaining = entry.number_tx
rds.set_rt(entry.text) rds.set_rt_raw(entry.text)
if entry.toggle_ab then rds.toggle_rt_ab() end if entry.toggle_ab then rds.toggle_rt_ab() end
end end
@@ -167,7 +167,7 @@ mec_handlers[0x0A] = function(data)
uecp.rt_tx_remaining = number_tx uecp.rt_tx_remaining = number_tx
-- Seed the encoder immediately with the first entry -- Seed the encoder immediately with the first entry
dsn_helper(dsn, function () dsn_helper(dsn, function ()
rds.set_rt(rt_text) rds.set_rt_raw(rt_text)
if toggle_ab then rds.toggle_rt_ab() end if toggle_ab then rds.toggle_rt_ab() end
rds.set_rt_enabled(true) rds.set_rt_enabled(true)
end) end)
@@ -222,7 +222,15 @@ mec_handlers[0x2E] = function (data)
end end
mec_handlers[0x24] = function (data) mec_handlers[0x24] = function (data)
-- Free-format data in type A or B group -- Free-format data in type A or B group
-- TODO: figure out the docs local group = string.byte(data, 2)
local bufferdata = string.byte(data, 3)
local buffer = (bufferdata >> 5) & 3 -- No clue
local blockb = bufferdata & 31
local blockc_msb = string.byte(data, 4)
local blockc_lsb = string.byte(data, 5)
local blockd_msb = string.byte(data, 6)
local blockd_lsb = string.byte(data, 7)
rds.put_custom_group((group << 11) | blockb, (blockc_msb << 8) | blockc_lsb, (blockd_msb << 8) | blockd_lsb)
return 7 return 7
end end
-- Fuck you mean, i have to implement some fucking "spinning wHELLs"? may the lord have mercy -- Fuck you mean, i have to implement some fucking "spinning wHELLs"? may the lord have mercy
@@ -274,7 +282,7 @@ mec_handlers[0x2D] = function (data)
local designation = string.sub(data, 3, 4) local designation = string.sub(data, 3, 4)
if string.byte(designation, 1) == 0x39 and string.byte(designation, 2) == 0x35 and mel > 2 then if string.byte(designation, 1) == 0x39 and string.byte(designation, 2) == 0x35 and mel > 2 then
local data = string.sub(data, 5, 4+mel) local data = string.sub(data, 5, 4+mel)
pcall(data_handle, data) pcall(hooks.data_handle, data)
end end
return 2+mel return 2+mel
end end
+3 -34
View File
@@ -1,5 +1,5 @@
---@param data string ---@param data string
function data_handle(data) function hooks.data_handle(data)
-- UECP -- UECP
if uecp.parse_uecp and string.byte(data, 1) == 0xfe then return uecp.parse_uecp(data) end if uecp.parse_uecp and string.byte(data, 1) == 0xfe then return uecp.parse_uecp(data) end
@@ -42,7 +42,7 @@ function data_handle(data)
end end
if cmd == nil then if cmd == nil then
data = data:lower() data = data:lower()
if data == "ver" then return string.format("rds95 core v. %s - (C) 2025 radio95 - lua parser\r\n", core_version) if data == "ver" then return string.format("rds95 core v. %s - (C) 2025 radio95 - lua parser\r\n", dp.core_version)
elseif data == "init" then elseif data == "init" then
dp.set_program_defaults() dp.set_program_defaults()
return "+\r\n" return "+\r\n"
@@ -165,37 +165,6 @@ function data_handle(data)
else return "?\r\n" end else return "?\r\n" end
end end
local udg_num = cmd:match("^udg([12])$")
local udg2_num = cmd:match("^2udg([12])$")
if udg_num then
local xy = (udg_num == "1")
local groups = {}
for segment in value:gmatch("([^,]+)") do
local b, c, d = segment:match("^(%x%x%x%x)(%x%x%x%x)(%x%x%x%x)$")
if not (b and c and d) then return "-\r\n" end
table.insert(groups, {tonumber(b, 16), tonumber(c, 16), tonumber(d, 16)})
end
if #groups > 8 or #groups == 0 then return "-\r\n" end
rds.set_udg(xy, groups)
return "+\r\n"
end
if udg2_num then
local xy = (udg2_num == "1")
local groups = {}
for segment in value:gmatch("([^,]+)") do
local a, b, c, d = segment:match("^(%x%x%x%x)(%x%x%x%x)(%x%x%x%x)(%x%x%x%x)$")
if not (a and b and c and d) then return "-" end
table.insert(groups, {tonumber(a, 16), tonumber(b, 16), tonumber(c, 16), tonumber(d, 16)})
end
if #groups > 8 or #groups == 0 then return "-" end
rds.set_udg2(xy, groups)
return "+\r\n"
end
if cmd == "pi" then if cmd == "pi" then
local pi = tonumber(value, 16) local pi = tonumber(value, 16)
if not pi then return "-\r\n" end if not pi then return "-\r\n" end
@@ -264,7 +233,7 @@ function data_handle(data)
elseif cmd == "rt1" or cmd == "text" then elseif cmd == "rt1" or cmd == "text" then
uecp.rt_buffer = {} uecp.rt_buffer = {}
uecp.rt_buffer_index = 1 uecp.rt_buffer_index = 1
uecp.rt_buffer[1] = { text = value, number_tx = 0, toggle_ab = true } uecp.rt_buffer[1] = { text = dp.encode_charset(value), number_tx = 0, toggle_ab = true }
uecp.rt_tx_remaining = 0 uecp.rt_tx_remaining = 0
rds.set_rt_enabled(true) rds.set_rt_enabled(true)
rds.set_rt(value) rds.set_rt(value)
+240 -143
View File
@@ -76,201 +76,299 @@ uint8_t add_rds_af(RDSAFs *af_list, float freq) {
return 0; return 0;
} }
char *convert_to_rdscharset(const char *str) { void convert_to_rdscharset(const char *str, char *output, size_t buffer_size) {
static char new_str[255]; size_t i = 0;
uint8_t i = 0;
while (*str != 0 && i < 255) { while (*str != 0 && i < buffer_size) {
// The following line is neccesary for the charset.py to work properly // The following line is neccesary for the charset.py to work properly
// CHARSET START // CHARSET START
switch(*str) { switch(*str) {
case (char)0x0a: output[i] = (char)0x0a; break; // N/A
case (char)0x0d: output[i] = (char)0x0d; break; // N/A
case (char)0x1f: output[i] = (char)0x1f; break; // N/A
case (char)0x20: output[i] = (char)0x20; break; // SPACE
case (char)0x21: output[i] = (char)0x21; break; // EXCLAMATION MARK
case (char)0x22: output[i] = (char)0x22; break; // QUOTATION MARK
case (char)0x23: output[i] = (char)0x23; break; // NUMBER SIGN
case (char)0xc2: case (char)0xc2:
str++; str++;
switch(*str) { switch(*str) {
case (char)0xa4: new_str[i] = (char)0x24; break; // CURRENCY SIGN case (char)0xa4: output[i] = (char)0x24; break; // CURRENCY SIGN
case (char)0xa1: new_str[i] = (char)0x8e; break; // INVERTED EXCLAMATION MARK case (char)0xa1: output[i] = (char)0x8e; break; // INVERTED EXCLAMATION MARK
case (char)0xaa: new_str[i] = (char)0xa0; break; // FEMININE ORDINAL INDICATOR case (char)0xaa: output[i] = (char)0xa0; break; // FEMININE ORDINAL INDICATOR
case (char)0xa9: new_str[i] = (char)0xa2; break; // COPYRIGHT SIGN case (char)0xa9: output[i] = (char)0xa2; break; // COPYRIGHT SIGN
case (char)0xa3: new_str[i] = (char)0xaa; break; // POUND SIGN case (char)0xa3: output[i] = (char)0xaa; break; // POUND SIGN
case (char)0xba: new_str[i] = (char)0xb0; break; // MASCULINE ORDINAL INDICATOR case (char)0xba: output[i] = (char)0xb0; break; // MASCULINE ORDINAL INDICATOR
case (char)0xb9: new_str[i] = (char)0xb1; break; // SUPERSCRIPT ONE case (char)0xb9: output[i] = (char)0xb1; break; // SUPERSCRIPT ONE
case (char)0xb1: new_str[i] = (char)0xb4; break; // PLUS-MINUS SIGN case (char)0xb2: output[i] = (char)0xb2; break; // SUPERSCRIPT TWO
case (char)0xb5: new_str[i] = (char)0xb8; break; // MICRO SIGN case (char)0xb3: output[i] = (char)0xb3; break; // SUPERSCRIPT THREE
case (char)0xbf: new_str[i] = (char)0xb9; break; // INVERTED QUESTION MARK case (char)0xb1: output[i] = (char)0xb4; break; // PLUS-MINUS SIGN
case (char)0xb0: new_str[i] = (char)0xbb; break; // DEGREE SIGN case (char)0xb5: output[i] = (char)0xb8; break; // MICRO SIGN
case (char)0xa7: new_str[i] = (char)0xbf; break; // SECTION SIGN case (char)0xbf: output[i] = (char)0xb9; break; // INVERTED QUESTION MARK
default: new_str[i] = (char)0x3f; break; // QUESTION MARK case (char)0xb0: output[i] = (char)0xbb; break; // DEGREE SIGN
case (char)0xbc: output[i] = (char)0xbc; break; // VULGAR FRACTION ONE QUARTER
case (char)0xbd: output[i] = (char)0xbd; break; // VULGAR FRACTION ONE HALF
case (char)0xbe: output[i] = (char)0xbe; break; // VULGAR FRACTION THREE QUARTERS
case (char)0xa7: output[i] = (char)0xbf; break; // SECTION SIGN
default: output[i] = (char)0x3f; break; // QUESTION MARK
} }
break; break;
case (char)0x25: output[i] = (char)0x25; break; // PERCENT SIGN
case (char)0x26: output[i] = (char)0x26; break; // AMPERSAND
case (char)0x27: output[i] = (char)0x27; break; // APOSTROPHE
case (char)0x28: output[i] = (char)0x28; break; // LEFT PARENTHESIS
case (char)0x29: output[i] = (char)0x29; break; // RIGHT PARENTHESIS
case (char)0x2a: output[i] = (char)0x2a; break; // ASTERISK
case (char)0x2b: output[i] = (char)0x2b; break; // PLUS SIGN
case (char)0x2c: output[i] = (char)0x2c; break; // COMMA
case (char)0x2d: output[i] = (char)0x2d; break; // HYPHEN-MINUS
case (char)0x2e: output[i] = (char)0x2e; break; // FULL STOP
case (char)0x2f: output[i] = (char)0x2f; break; // SOLIDUS
case (char)0x30: output[i] = (char)0x30; break; // DIGIT ZERO
case (char)0x31: output[i] = (char)0x31; break; // DIGIT ONE
case (char)0x32: output[i] = (char)0x32; break; // DIGIT TWO
case (char)0x33: output[i] = (char)0x33; break; // DIGIT THREE
case (char)0x34: output[i] = (char)0x34; break; // DIGIT FOUR
case (char)0x35: output[i] = (char)0x35; break; // DIGIT FIVE
case (char)0x36: output[i] = (char)0x36; break; // DIGIT SIX
case (char)0x37: output[i] = (char)0x37; break; // DIGIT SEVEN
case (char)0x38: output[i] = (char)0x38; break; // DIGIT EIGHT
case (char)0x39: output[i] = (char)0x39; break; // DIGIT NINE
case (char)0x3a: output[i] = (char)0x3a; break; // COLON
case (char)0x3b: output[i] = (char)0x3b; break; // SEMICOLON
case (char)0x3c: output[i] = (char)0x3c; break; // LESS-THAN SIGN
case (char)0x3d: output[i] = (char)0x3d; break; // EQUALS SIGN
case (char)0x3e: output[i] = (char)0x3e; break; // GREATER-THAN SIGN
case (char)0x3f: output[i] = (char)0x3f; break; // QUESTION MARK
case (char)0x40: output[i] = (char)0x40; break; // COMMERCIAL AT
case (char)0x41: output[i] = (char)0x41; break; // LATIN CAPITAL LETTER A
case (char)0x42: output[i] = (char)0x42; break; // LATIN CAPITAL LETTER B
case (char)0x43: output[i] = (char)0x43; break; // LATIN CAPITAL LETTER C
case (char)0x44: output[i] = (char)0x44; break; // LATIN CAPITAL LETTER D
case (char)0x45: output[i] = (char)0x45; break; // LATIN CAPITAL LETTER E
case (char)0x46: output[i] = (char)0x46; break; // LATIN CAPITAL LETTER F
case (char)0x47: output[i] = (char)0x47; break; // LATIN CAPITAL LETTER G
case (char)0x48: output[i] = (char)0x48; break; // LATIN CAPITAL LETTER H
case (char)0x49: output[i] = (char)0x49; break; // LATIN CAPITAL LETTER I
case (char)0x4a: output[i] = (char)0x4a; break; // LATIN CAPITAL LETTER J
case (char)0x4b: output[i] = (char)0x4b; break; // LATIN CAPITAL LETTER K
case (char)0x4c: output[i] = (char)0x4c; break; // LATIN CAPITAL LETTER L
case (char)0x4d: output[i] = (char)0x4d; break; // LATIN CAPITAL LETTER M
case (char)0x4e: output[i] = (char)0x4e; break; // LATIN CAPITAL LETTER N
case (char)0x4f: output[i] = (char)0x4f; break; // LATIN CAPITAL LETTER O
case (char)0x50: output[i] = (char)0x50; break; // LATIN CAPITAL LETTER P
case (char)0x51: output[i] = (char)0x51; break; // LATIN CAPITAL LETTER Q
case (char)0x52: output[i] = (char)0x52; break; // LATIN CAPITAL LETTER R
case (char)0x53: output[i] = (char)0x53; break; // LATIN CAPITAL LETTER S
case (char)0x54: output[i] = (char)0x54; break; // LATIN CAPITAL LETTER T
case (char)0x55: output[i] = (char)0x55; break; // LATIN CAPITAL LETTER U
case (char)0x56: output[i] = (char)0x56; break; // LATIN CAPITAL LETTER V
case (char)0x57: output[i] = (char)0x57; break; // LATIN CAPITAL LETTER W
case (char)0x58: output[i] = (char)0x58; break; // LATIN CAPITAL LETTER X
case (char)0x59: output[i] = (char)0x59; break; // LATIN CAPITAL LETTER Y
case (char)0x5a: output[i] = (char)0x5a; break; // LATIN CAPITAL LETTER Z
case (char)0x5b: output[i] = (char)0x5b; break; // LEFT SQUARE BRACKET
case (char)0x5c: output[i] = (char)0x5c; break; // REVERSE SOLIDUS
case (char)0x5d: output[i] = (char)0x5d; break; // RIGHT SQUARE BRACKET
case (char)0xe2: case (char)0xe2:
str++; str++;
switch(*str) { switch(*str) {
case (char)0x80: case (char)0x80:
str++; str++;
switch(*str) { switch(*str) {
case (char)0x95: new_str[i] = (char)0x5e; break; // HORIZONTAL BAR case (char)0x95: output[i] = (char)0x5e; break; // HORIZONTAL BAR
case (char)0x96: new_str[i] = (char)0x60; break; // DOUBLE VERTICAL LINE case (char)0x96: output[i] = (char)0x60; break; // DOUBLE VERTICAL LINE
case (char)0xbe: new_str[i] = (char)0x7e; break; // OVERLINE case (char)0xbe: output[i] = (char)0x7e; break; // OVERLINE
case (char)0xb0: new_str[i] = (char)0xa3; break; // PER MILLE SIGN case (char)0xb0: output[i] = (char)0xa3; break; // PER MILLE SIGN
default: new_str[i] = (char)0x3f; break; // QUESTION MARK default: output[i] = (char)0x3f; break; // QUESTION MARK
} }
break; break;
case (char)0x82: case (char)0x82:
str++; str++;
switch(*str) { switch(*str) {
case (char)0xac: new_str[i] = (char)0xa9; break; // EURO SIGN case (char)0xac: output[i] = (char)0xa9; break; // EURO SIGN
default: new_str[i] = (char)0x3f; break; // QUESTION MARK default: output[i] = (char)0x3f; break; // QUESTION MARK
} }
break; break;
case (char)0x86: case (char)0x86:
str++; str++;
switch(*str) { switch(*str) {
case (char)0x90: new_str[i] = (char)0xac; break; // LEFTWARDS ARROW case (char)0x90: output[i] = (char)0xac; break; // LEFTWARDS ARROW
case (char)0x91: new_str[i] = (char)0xad; break; // UPWARDS ARROW case (char)0x91: output[i] = (char)0xad; break; // UPWARDS ARROW
case (char)0x92: new_str[i] = (char)0xae; break; // RIGHTWARDS ARROW case (char)0x92: output[i] = (char)0xae; break; // RIGHTWARDS ARROW
case (char)0x93: new_str[i] = (char)0xaf; break; // DOWNWARDS ARROW case (char)0x93: output[i] = (char)0xaf; break; // DOWNWARDS ARROW
default: new_str[i] = (char)0x3f; break; // QUESTION MARK default: output[i] = (char)0x3f; break; // QUESTION MARK
} }
break; break;
default: new_str[i] = (char)0x3f; break; // QUESTION MARK default: output[i] = (char)0x3f; break; // QUESTION MARK
} }
break; break;
case (char)0x5f: output[i] = (char)0x5f; break; // LOW LINE
case (char)0x61: output[i] = (char)0x61; break; // LATIN SMALL LETTER A
case (char)0x62: output[i] = (char)0x62; break; // LATIN SMALL LETTER B
case (char)0x63: output[i] = (char)0x63; break; // LATIN SMALL LETTER C
case (char)0x64: output[i] = (char)0x64; break; // LATIN SMALL LETTER D
case (char)0x65: output[i] = (char)0x65; break; // LATIN SMALL LETTER E
case (char)0x66: output[i] = (char)0x66; break; // LATIN SMALL LETTER F
case (char)0x67: output[i] = (char)0x67; break; // LATIN SMALL LETTER G
case (char)0x68: output[i] = (char)0x68; break; // LATIN SMALL LETTER H
case (char)0x69: output[i] = (char)0x69; break; // LATIN SMALL LETTER I
case (char)0x6a: output[i] = (char)0x6a; break; // LATIN SMALL LETTER J
case (char)0x6b: output[i] = (char)0x6b; break; // LATIN SMALL LETTER K
case (char)0x6c: output[i] = (char)0x6c; break; // LATIN SMALL LETTER L
case (char)0x6d: output[i] = (char)0x6d; break; // LATIN SMALL LETTER M
case (char)0x6e: output[i] = (char)0x6e; break; // LATIN SMALL LETTER N
case (char)0x6f: output[i] = (char)0x6f; break; // LATIN SMALL LETTER O
case (char)0x70: output[i] = (char)0x70; break; // LATIN SMALL LETTER P
case (char)0x71: output[i] = (char)0x71; break; // LATIN SMALL LETTER Q
case (char)0x72: output[i] = (char)0x72; break; // LATIN SMALL LETTER R
case (char)0x73: output[i] = (char)0x73; break; // LATIN SMALL LETTER S
case (char)0x74: output[i] = (char)0x74; break; // LATIN SMALL LETTER T
case (char)0x75: output[i] = (char)0x75; break; // LATIN SMALL LETTER U
case (char)0x76: output[i] = (char)0x76; break; // LATIN SMALL LETTER V
case (char)0x77: output[i] = (char)0x77; break; // LATIN SMALL LETTER W
case (char)0x78: output[i] = (char)0x78; break; // LATIN SMALL LETTER X
case (char)0x79: output[i] = (char)0x79; break; // LATIN SMALL LETTER Y
case (char)0x7a: output[i] = (char)0x7a; break; // LATIN SMALL LETTER Z
case (char)0x7b: output[i] = (char)0x7b; break; // LEFT CURLY BRACKET
case (char)0x7c: output[i] = (char)0x7c; break; // VERTICAL LINE
case (char)0x7d: output[i] = (char)0x7d; break; // RIGHT CURLY BRACKET
case (char)0xc3: case (char)0xc3:
str++; str++;
switch(*str) { switch(*str) {
case (char)0xa1: new_str[i] = (char)0x80; break; // LATIN SMALL LETTER A WITH ACUTE case (char)0xa1: output[i] = (char)0x80; break; // LATIN SMALL LETTER A WITH ACUTE
case (char)0xa0: new_str[i] = (char)0x81; break; // LATIN SMALL LETTER A WITH GRAVE case (char)0xa0: output[i] = (char)0x81; break; // LATIN SMALL LETTER A WITH GRAVE
case (char)0xa9: new_str[i] = (char)0x82; break; // LATIN SMALL LETTER E WITH ACUTE case (char)0xa9: output[i] = (char)0x82; break; // LATIN SMALL LETTER E WITH ACUTE
case (char)0xa8: new_str[i] = (char)0x83; break; // LATIN SMALL LETTER E WITH GRAVE case (char)0xa8: output[i] = (char)0x83; break; // LATIN SMALL LETTER E WITH GRAVE
case (char)0xad: new_str[i] = (char)0x84; break; // LATIN SMALL LETTER I WITH ACUTE case (char)0xad: output[i] = (char)0x84; break; // LATIN SMALL LETTER I WITH ACUTE
case (char)0xac: new_str[i] = (char)0x85; break; // LATIN SMALL LETTER I WITH GRAVE case (char)0xac: output[i] = (char)0x85; break; // LATIN SMALL LETTER I WITH GRAVE
case (char)0xb3: new_str[i] = (char)0x86; break; // LATIN SMALL LETTER O WITH ACUTE case (char)0xb3: output[i] = (char)0x86; break; // LATIN SMALL LETTER O WITH ACUTE
case (char)0xb2: new_str[i] = (char)0x87; break; // LATIN SMALL LETTER O WITH GRAVE case (char)0xb2: output[i] = (char)0x87; break; // LATIN SMALL LETTER O WITH GRAVE
case (char)0xba: new_str[i] = (char)0x88; break; // LATIN SMALL LETTER U WITH ACUTE case (char)0xba: output[i] = (char)0x88; break; // LATIN SMALL LETTER U WITH ACUTE
case (char)0xb9: new_str[i] = (char)0x89; break; // LATIN SMALL LETTER U WITH GRAVE case (char)0xb9: output[i] = (char)0x89; break; // LATIN SMALL LETTER U WITH GRAVE
case (char)0x91: new_str[i] = (char)0x8a; break; // LATIN CAPITAL LETTER N WITH TILDE case (char)0x91: output[i] = (char)0x8a; break; // LATIN CAPITAL LETTER N WITH TILDE
case (char)0x87: new_str[i] = (char)0x8b; break; // LATIN CAPITAL LETTER C WITH CEDILLA case (char)0x87: output[i] = (char)0x8b; break; // LATIN CAPITAL LETTER C WITH CEDILLA
case (char)0x9f: new_str[i] = (char)0x8d; break; // LATIN SMALL LETTER SHARP S case (char)0x9f: output[i] = (char)0x8d; break; // LATIN SMALL LETTER SHARP S
case (char)0xa2: new_str[i] = (char)0x90; break; // LATIN SMALL LETTER A WITH CIRCUMFLEX case (char)0xa2: output[i] = (char)0x90; break; // LATIN SMALL LETTER A WITH CIRCUMFLEX
case (char)0xa4: new_str[i] = (char)0x91; break; // LATIN SMALL LETTER A WITH DIAERESIS case (char)0xa4: output[i] = (char)0x91; break; // LATIN SMALL LETTER A WITH DIAERESIS
case (char)0xaa: new_str[i] = (char)0x92; break; // LATIN SMALL LETTER E WITH CIRCUMFLEX case (char)0xaa: output[i] = (char)0x92; break; // LATIN SMALL LETTER E WITH CIRCUMFLEX
case (char)0xab: new_str[i] = (char)0x93; break; // LATIN SMALL LETTER E WITH DIAERESIS case (char)0xab: output[i] = (char)0x93; break; // LATIN SMALL LETTER E WITH DIAERESIS
case (char)0xae: new_str[i] = (char)0x94; break; // LATIN SMALL LETTER I WITH CIRCUMFLEX case (char)0xae: output[i] = (char)0x94; break; // LATIN SMALL LETTER I WITH CIRCUMFLEX
case (char)0xaf: new_str[i] = (char)0x95; break; // LATIN SMALL LETTER I WITH DIAERESIS case (char)0xaf: output[i] = (char)0x95; break; // LATIN SMALL LETTER I WITH DIAERESIS
case (char)0xb4: new_str[i] = (char)0x96; break; // LATIN SMALL LETTER O WITH CIRCUMFLEX case (char)0xb4: output[i] = (char)0x96; break; // LATIN SMALL LETTER O WITH CIRCUMFLEX
case (char)0xb6: new_str[i] = (char)0x97; break; // LATIN SMALL LETTER O WITH DIAERESIS case (char)0xb6: output[i] = (char)0x97; break; // LATIN SMALL LETTER O WITH DIAERESIS
case (char)0xbb: new_str[i] = (char)0x98; break; // LATIN SMALL LETTER U WITH CIRCUMFLEX case (char)0xbb: output[i] = (char)0x98; break; // LATIN SMALL LETTER U WITH CIRCUMFLEX
case (char)0xbc: new_str[i] = (char)0x99; break; // LATIN SMALL LETTER U WITH DIAERESIS case (char)0xbc: output[i] = (char)0x99; break; // LATIN SMALL LETTER U WITH DIAERESIS
case (char)0xb1: new_str[i] = (char)0x9a; break; // LATIN SMALL LETTER N WITH TILDE case (char)0xb1: output[i] = (char)0x9a; break; // LATIN SMALL LETTER N WITH TILDE
case (char)0xa7: new_str[i] = (char)0x9b; break; // LATIN SMALL LETTER C WITH CEDILLA case (char)0xa7: output[i] = (char)0x9b; break; // LATIN SMALL LETTER C WITH CEDILLA
case (char)0xb7: new_str[i] = (char)0xba; break; // DIVISION SIGN case (char)0xb7: output[i] = (char)0xba; break; // DIVISION SIGN
case (char)0x81: new_str[i] = (char)0xc0; break; // LATIN CAPITAL LETTER A WITH ACUTE case (char)0x81: output[i] = (char)0xc0; break; // LATIN CAPITAL LETTER A WITH ACUTE
case (char)0x80: new_str[i] = (char)0xc1; break; // LATIN CAPITAL LETTER A WITH GRAVE case (char)0x80: output[i] = (char)0xc1; break; // LATIN CAPITAL LETTER A WITH GRAVE
case (char)0x89: new_str[i] = (char)0xc2; break; // LATIN CAPITAL LETTER E WITH ACUTE case (char)0x89: output[i] = (char)0xc2; break; // LATIN CAPITAL LETTER E WITH ACUTE
case (char)0x88: new_str[i] = (char)0xc3; break; // LATIN CAPITAL LETTER E WITH GRAVE case (char)0x88: output[i] = (char)0xc3; break; // LATIN CAPITAL LETTER E WITH GRAVE
case (char)0x8d: new_str[i] = (char)0xc4; break; // LATIN CAPITAL LETTER I WITH ACUTE case (char)0x8d: output[i] = (char)0xc4; break; // LATIN CAPITAL LETTER I WITH ACUTE
case (char)0x8c: new_str[i] = (char)0xc5; break; // LATIN CAPITAL LETTER I WITH GRAVE case (char)0x8c: output[i] = (char)0xc5; break; // LATIN CAPITAL LETTER I WITH GRAVE
case (char)0x93: new_str[i] = (char)0xc6; break; // LATIN CAPITAL LETTER O WITH ACUTE case (char)0x93: output[i] = (char)0xc6; break; // LATIN CAPITAL LETTER O WITH ACUTE
case (char)0x92: new_str[i] = (char)0xc7; break; // LATIN CAPITAL LETTER O WITH GRAVE case (char)0x92: output[i] = (char)0xc7; break; // LATIN CAPITAL LETTER O WITH GRAVE
case (char)0x9a: new_str[i] = (char)0xc8; break; // LATIN CAPITAL LETTER U WITH ACUTE case (char)0x9a: output[i] = (char)0xc8; break; // LATIN CAPITAL LETTER U WITH ACUTE
case (char)0x99: new_str[i] = (char)0xc9; break; // LATIN CAPITAL LETTER U WITH GRAVE case (char)0x99: output[i] = (char)0xc9; break; // LATIN CAPITAL LETTER U WITH GRAVE
case (char)0x90: new_str[i] = (char)0xce; break; // LATIN CAPITAL LETTER ETH case (char)0x90: output[i] = (char)0xce; break; // LATIN CAPITAL LETTER ETH
case (char)0x82: new_str[i] = (char)0xd0; break; // LATIN CAPITAL LETTER A WITH CIRCUMFLEX case (char)0x82: output[i] = (char)0xd0; break; // LATIN CAPITAL LETTER A WITH CIRCUMFLEX
case (char)0x84: new_str[i] = (char)0xd1; break; // LATIN CAPITAL LETTER A WITH DIAERESIS case (char)0x84: output[i] = (char)0xd1; break; // LATIN CAPITAL LETTER A WITH DIAERESIS
case (char)0x8a: new_str[i] = (char)0xd2; break; // LATIN CAPITAL LETTER E WITH CIRCUMFLEX case (char)0x8a: output[i] = (char)0xd2; break; // LATIN CAPITAL LETTER E WITH CIRCUMFLEX
case (char)0x8b: new_str[i] = (char)0xd3; break; // LATIN CAPITAL LETTER E WITH DIAERESIS case (char)0x8b: output[i] = (char)0xd3; break; // LATIN CAPITAL LETTER E WITH DIAERESIS
case (char)0x8e: new_str[i] = (char)0xd4; break; // LATIN CAPITAL LETTER I WITH CIRCUMFLEX case (char)0x8e: output[i] = (char)0xd4; break; // LATIN CAPITAL LETTER I WITH CIRCUMFLEX
case (char)0x8f: new_str[i] = (char)0xd5; break; // LATIN CAPITAL LETTER I WITH DIAERESIS case (char)0x8f: output[i] = (char)0xd5; break; // LATIN CAPITAL LETTER I WITH DIAERESIS
case (char)0x94: new_str[i] = (char)0xd6; break; // LATIN CAPITAL LETTER O WITH CIRCUMFLEX case (char)0x94: output[i] = (char)0xd6; break; // LATIN CAPITAL LETTER O WITH CIRCUMFLEX
case (char)0x96: new_str[i] = (char)0xd7; break; // LATIN CAPITAL LETTER O WITH DIAERESIS case (char)0x96: output[i] = (char)0xd7; break; // LATIN CAPITAL LETTER O WITH DIAERESIS
case (char)0x9b: new_str[i] = (char)0xd8; break; // LATIN CAPITAL LETTER U WITH CIRCUMFLEX case (char)0x9b: output[i] = (char)0xd8; break; // LATIN CAPITAL LETTER U WITH CIRCUMFLEX
case (char)0x9c: new_str[i] = (char)0xd9; break; // LATIN CAPITAL LETTER U WITH DIAERESIS case (char)0x9c: output[i] = (char)0xd9; break; // LATIN CAPITAL LETTER U WITH DIAERESIS
case (char)0x83: new_str[i] = (char)0xe0; break; // LATIN CAPITAL LETTER A WITH TILDE case (char)0x83: output[i] = (char)0xe0; break; // LATIN CAPITAL LETTER A WITH TILDE
case (char)0x85: new_str[i] = (char)0xe1; break; // LATIN CAPITAL LETTER A WITH RING ABOVE case (char)0x85: output[i] = (char)0xe1; break; // LATIN CAPITAL LETTER A WITH RING ABOVE
case (char)0x86: new_str[i] = (char)0xe2; break; // LATIN CAPITAL LETTER AE case (char)0x86: output[i] = (char)0xe2; break; // LATIN CAPITAL LETTER AE
case (char)0x9d: new_str[i] = (char)0xe5; break; // LATIN CAPITAL LETTER Y WITH ACUTE case (char)0x9d: output[i] = (char)0xe5; break; // LATIN CAPITAL LETTER Y WITH ACUTE
case (char)0x95: new_str[i] = (char)0xe6; break; // LATIN CAPITAL LETTER O WITH TILDE case (char)0x95: output[i] = (char)0xe6; break; // LATIN CAPITAL LETTER O WITH TILDE
case (char)0x98: new_str[i] = (char)0xe7; break; // LATIN CAPITAL LETTER O WITH STROKE case (char)0x98: output[i] = (char)0xe7; break; // LATIN CAPITAL LETTER O WITH STROKE
case (char)0x9e: new_str[i] = (char)0xe8; break; // LATIN CAPITAL LETTER THORN case (char)0x9e: output[i] = (char)0xe8; break; // LATIN CAPITAL LETTER THORN
case (char)0xb0: new_str[i] = (char)0xef; break; // LATIN SMALL LETTER ETH case (char)0xb0: output[i] = (char)0xef; break; // LATIN SMALL LETTER ETH
case (char)0xa3: new_str[i] = (char)0xf0; break; // LATIN SMALL LETTER A WITH TILDE case (char)0xa3: output[i] = (char)0xf0; break; // LATIN SMALL LETTER A WITH TILDE
case (char)0xa5: new_str[i] = (char)0xf1; break; // LATIN SMALL LETTER A WITH RING ABOVE case (char)0xa5: output[i] = (char)0xf1; break; // LATIN SMALL LETTER A WITH RING ABOVE
case (char)0xa6: new_str[i] = (char)0xf2; break; // LATIN SMALL LETTER AE case (char)0xa6: output[i] = (char)0xf2; break; // LATIN SMALL LETTER AE
case (char)0xbd: new_str[i] = (char)0xf5; break; // LATIN SMALL LETTER Y WITH ACUTE case (char)0xbd: output[i] = (char)0xf5; break; // LATIN SMALL LETTER Y WITH ACUTE
case (char)0xb5: new_str[i] = (char)0xf6; break; // LATIN SMALL LETTER O WITH TILDE case (char)0xb5: output[i] = (char)0xf6; break; // LATIN SMALL LETTER O WITH TILDE
case (char)0xb8: new_str[i] = (char)0xf7; break; // LATIN SMALL LETTER O WITH STROKE case (char)0xb8: output[i] = (char)0xf7; break; // LATIN SMALL LETTER O WITH STROKE
case (char)0xbe: new_str[i] = (char)0xf8; break; // LATIN SMALL LETTER THORN case (char)0xbe: output[i] = (char)0xf8; break; // LATIN SMALL LETTER THORN
default: new_str[i] = (char)0x3f; break; // QUESTION MARK default: output[i] = (char)0x3f; break; // QUESTION MARK
} }
break; break;
case (char)0xc5: case (char)0xc5:
str++; str++;
switch(*str) { switch(*str) {
case (char)0x9e: new_str[i] = (char)0x8c; break; // LATIN CAPITAL LETTER S WITH CEDILLA case (char)0x9e: output[i] = (char)0x8c; break; // LATIN CAPITAL LETTER S WITH CEDILLA
case (char)0x9f: new_str[i] = (char)0x9c; break; // LATIN SMALL LETTER S WITH CEDILLA case (char)0x9f: output[i] = (char)0x9c; break; // LATIN SMALL LETTER S WITH CEDILLA
case (char)0x88: new_str[i] = (char)0xa6; break; // LATIN SMALL LETTER N WITH CARON case (char)0x88: output[i] = (char)0xa6; break; // LATIN SMALL LETTER N WITH CARON
case (char)0x91: new_str[i] = (char)0xa7; break; // LATIN SMALL LETTER O WITH DOUBLE ACUTE case (char)0x91: output[i] = (char)0xa7; break; // LATIN SMALL LETTER O WITH DOUBLE ACUTE
case (char)0x84: new_str[i] = (char)0xb6; break; // LATIN SMALL LETTER N WITH ACUTE case (char)0x84: output[i] = (char)0xb6; break; // LATIN SMALL LETTER N WITH ACUTE
case (char)0xb1: new_str[i] = (char)0xb7; break; // LATIN SMALL LETTER U WITH DOUBLE ACUTE case (char)0xb1: output[i] = (char)0xb7; break; // LATIN SMALL LETTER U WITH DOUBLE ACUTE
case (char)0x98: new_str[i] = (char)0xca; break; // LATIN CAPITAL LETTER R WITH CARON case (char)0x98: output[i] = (char)0xca; break; // LATIN CAPITAL LETTER R WITH CARON
case (char)0xa0: new_str[i] = (char)0xcc; break; // LATIN CAPITAL LETTER S WITH CARON case (char)0xa0: output[i] = (char)0xcc; break; // LATIN CAPITAL LETTER S WITH CARON
case (char)0xbd: new_str[i] = (char)0xcd; break; // LATIN CAPITAL LETTER Z WITH CARON case (char)0xbd: output[i] = (char)0xcd; break; // LATIN CAPITAL LETTER Z WITH CARON
case (char)0x99: new_str[i] = (char)0xda; break; // LATIN SMALL LETTER R WITH CARON case (char)0x99: output[i] = (char)0xda; break; // LATIN SMALL LETTER R WITH CARON
case (char)0xa1: new_str[i] = (char)0xdc; break; // LATIN SMALL LETTER S WITH CARON case (char)0xa1: output[i] = (char)0xdc; break; // LATIN SMALL LETTER S WITH CARON
case (char)0xbe: new_str[i] = (char)0xdd; break; // LATIN SMALL LETTER Z WITH CARON case (char)0xbe: output[i] = (char)0xdd; break; // LATIN SMALL LETTER Z WITH CARON
case (char)0x80: new_str[i] = (char)0xdf; break; // LATIN SMALL LETTER L WITH MIDDLE DOT case (char)0x80: output[i] = (char)0xdf; break; // LATIN SMALL LETTER L WITH MIDDLE DOT
case (char)0x92: new_str[i] = (char)0xe3; break; // LATIN CAPITAL LIGATURE OE case (char)0x92: output[i] = (char)0xe3; break; // LATIN CAPITAL LIGATURE OE
case (char)0xb7: new_str[i] = (char)0xe4; break; // LATIN SMALL LETTER Y WITH CIRCUMFLEX case (char)0xb7: output[i] = (char)0xe4; break; // LATIN SMALL LETTER Y WITH CIRCUMFLEX
case (char)0x8a: new_str[i] = (char)0xe9; break; // LATIN CAPITAL LETTER ENG case (char)0x8a: output[i] = (char)0xe9; break; // LATIN CAPITAL LETTER ENG
case (char)0x94: new_str[i] = (char)0xea; break; // LATIN CAPITAL LETTER R WITH ACUTE case (char)0x94: output[i] = (char)0xea; break; // LATIN CAPITAL LETTER R WITH ACUTE
case (char)0x9a: new_str[i] = (char)0xec; break; // LATIN CAPITAL LETTER S WITH ACUTE case (char)0x9a: output[i] = (char)0xec; break; // LATIN CAPITAL LETTER S WITH ACUTE
case (char)0xb9: new_str[i] = (char)0xed; break; // LATIN CAPITAL LETTER Z WITH ACUTE case (char)0xb9: output[i] = (char)0xed; break; // LATIN CAPITAL LETTER Z WITH ACUTE
case (char)0xa6: new_str[i] = (char)0xee; break; // LATIN CAPITAL LETTER T WITH STROKE case (char)0xa6: output[i] = (char)0xee; break; // LATIN CAPITAL LETTER T WITH STROKE
case (char)0x93: new_str[i] = (char)0xf3; break; // LATIN SMALL LIGATURE OE case (char)0x93: output[i] = (char)0xf3; break; // LATIN SMALL LIGATURE OE
case (char)0xb5: new_str[i] = (char)0xf4; break; // LATIN SMALL LETTER W WITH CIRCUMFLEX case (char)0xb5: output[i] = (char)0xf4; break; // LATIN SMALL LETTER W WITH CIRCUMFLEX
case (char)0x8b: new_str[i] = (char)0xf9; break; // LATIN SMALL LETTER ENG case (char)0x8b: output[i] = (char)0xf9; break; // LATIN SMALL LETTER ENG
case (char)0x95: new_str[i] = (char)0xfa; break; // LATIN SMALL LETTER R WITH ACUTE case (char)0x95: output[i] = (char)0xfa; break; // LATIN SMALL LETTER R WITH ACUTE
case (char)0x9b: new_str[i] = (char)0xfc; break; // LATIN SMALL LETTER S WITH ACUTE case (char)0x9b: output[i] = (char)0xfc; break; // LATIN SMALL LETTER S WITH ACUTE
case (char)0xba: new_str[i] = (char)0xfd; break; // LATIN SMALL LETTER Z WITH ACUTE case (char)0xba: output[i] = (char)0xfd; break; // LATIN SMALL LETTER Z WITH ACUTE
case (char)0xa7: new_str[i] = (char)0xfe; break; // LATIN SMALL LETTER T WITH STROKE case (char)0xa7: output[i] = (char)0xfe; break; // LATIN SMALL LETTER T WITH STROKE
default: new_str[i] = (char)0x3f; break; // QUESTION MARK default: output[i] = (char)0x3f; break; // QUESTION MARK
} }
break; break;
case (char)0xc4: case (char)0xc4:
str++; str++;
switch(*str) { switch(*str) {
case (char)0xb2: new_str[i] = (char)0x8f; break; // LATIN CAPITAL LIGATURE IJ case (char)0xb2: output[i] = (char)0x8f; break; // LATIN CAPITAL LIGATURE IJ
case (char)0x9f: new_str[i] = (char)0x9d; break; // LATIN SMALL LETTER G WITH BREVE case (char)0x9f: output[i] = (char)0x9d; break; // LATIN SMALL LETTER G WITH BREVE
case (char)0xb1: new_str[i] = (char)0x9e; break; // LATIN SMALL LETTER DOTLESS I case (char)0xb1: output[i] = (char)0x9e; break; // LATIN SMALL LETTER DOTLESS I
case (char)0xb3: new_str[i] = (char)0x9f; break; // LATIN SMALL LIGATURE IJ case (char)0xb3: output[i] = (char)0x9f; break; // LATIN SMALL LIGATURE IJ
case (char)0x9e: new_str[i] = (char)0xa4; break; // LATIN CAPITAL LETTER G WITH BREVE case (char)0x9e: output[i] = (char)0xa4; break; // LATIN CAPITAL LETTER G WITH BREVE
case (char)0x9b: new_str[i] = (char)0xa5; break; // LATIN SMALL LETTER E WITH CARON case (char)0x9b: output[i] = (char)0xa5; break; // LATIN SMALL LETTER E WITH CARON
case (char)0xb0: new_str[i] = (char)0xb5; break; // LATIN CAPITAL LETTER I WITH DOT ABOVE case (char)0xb0: output[i] = (char)0xb5; break; // LATIN CAPITAL LETTER I WITH DOT ABOVE
case (char)0x8c: new_str[i] = (char)0xcb; break; // LATIN CAPITAL LETTER C WITH CARON case (char)0x8c: output[i] = (char)0xcb; break; // LATIN CAPITAL LETTER C WITH CARON
case (char)0xbf: new_str[i] = (char)0xcf; break; // LATIN CAPITAL LETTER L WITH MIDDLE DOT case (char)0xbf: output[i] = (char)0xcf; break; // LATIN CAPITAL LETTER L WITH MIDDLE DOT
case (char)0x8d: new_str[i] = (char)0xdb; break; // LATIN SMALL LETTER C WITH CARON case (char)0x8d: output[i] = (char)0xdb; break; // LATIN SMALL LETTER C WITH CARON
case (char)0x91: new_str[i] = (char)0xde; break; // LATIN SMALL LETTER D WITH STROKE case (char)0x91: output[i] = (char)0xde; break; // LATIN SMALL LETTER D WITH STROKE
case (char)0x86: new_str[i] = (char)0xeb; break; // LATIN CAPITAL LETTER C WITH ACUTE case (char)0x86: output[i] = (char)0xeb; break; // LATIN CAPITAL LETTER C WITH ACUTE
case (char)0x87: new_str[i] = (char)0xfb; break; // LATIN SMALL LETTER C WITH ACUTE case (char)0x87: output[i] = (char)0xfb; break; // LATIN SMALL LETTER C WITH ACUTE
default: new_str[i] = (char)0x3f; break; // QUESTION MARK default: output[i] = (char)0x3f; break; // QUESTION MARK
} }
break; break;
case (char)0xce: case (char)0xce:
str++; str++;
switch(*str) { switch(*str) {
case (char)0xb1: new_str[i] = (char)0xa1; break; // GREEK SMALL LETTER ALPHA case (char)0xb1: output[i] = (char)0xa1; break; // GREEK SMALL LETTER ALPHA
default: new_str[i] = (char)0x3f; break; // QUESTION MARK default: output[i] = (char)0x3f; break; // QUESTION MARK
} }
break; break;
case (char)0xcf: case (char)0xcf:
str++; str++;
switch(*str) { switch(*str) {
case (char)0x80: new_str[i] = (char)0xa8; break; // GREEK SMALL LETTER PI case (char)0x80: output[i] = (char)0xa8; break; // GREEK SMALL LETTER PI
default: new_str[i] = (char)0x3f; break; // QUESTION MARK default: output[i] = (char)0x3f; break; // QUESTION MARK
} }
break; break;
case (char)0x24: new_str[i] = (char)0xab; break; // DOLLAR SIGN case (char)0x24: output[i] = (char)0xab; break; // DOLLAR SIGN
default: new_str[i] = *str; break; default: output[i] = (char)0x3f; break; // QUESTION MARK
} }
// CHARSET END // CHARSET END
@@ -278,6 +376,5 @@ char *convert_to_rdscharset(const char *str) {
str++; str++;
} }
new_str[i] = 0; output[i] = 0;
return new_str;
} }
+1 -1
View File
@@ -13,4 +13,4 @@ uint16_t crc16_ccitt(const char *data, uint16_t len);
uint16_t get_block_from_group(RDSGroup *group, uint8_t block); uint16_t get_block_from_group(RDSGroup *group, uint8_t block);
uint8_t add_rds_af(RDSAFs *af_list, float freq); uint8_t add_rds_af(RDSAFs *af_list, float freq);
char *convert_to_rdscharset(const char *str); void convert_to_rdscharset(const char *str, char *output, size_t buffer_size);
+24 -78
View File
@@ -81,10 +81,12 @@ int lua_set_rds_##name(lua_State *localL) { \
enc->data[writing_program].name = luaL_checkinteger(localL, 1); \ enc->data[writing_program].name = luaL_checkinteger(localL, 1); \
return 0; \ return 0; \
} }
#define STR_SETTER(name, function) \ #define STR_SETTER(name, function, buffer_size) \
int lua_set_rds_##name(lua_State *localL) { \ int lua_set_rds_##name(lua_State *localL) { \
const char* str = luaL_checklstring(localL, 1, NULL); \ const char* str = luaL_checklstring(localL, 1, NULL); \
function(enc, convert_to_rdscharset(str), writing_program); \ char converted[buffer_size+1]; \
convert_to_rdscharset(str, converted, buffer_size+1); \
function(enc, converted, writing_program); \
return 0; \ return 0; \
} }
#define STR_RAW_SETTER(name, function) \ #define STR_RAW_SETTER(name, function) \
@@ -244,10 +246,15 @@ int lua_put_rds2_custom_group(lua_State *localL) {
return 0; return 0;
} }
STR_SETTER(ptyn, set_rds_ptyn) STR_SETTER(ptyn, set_rds_ptyn, PTYN_LENGTH)
STR_SETTER(ps, set_rds_ps) STR_SETTER(ps, set_rds_ps, PS_LENGTH)
STR_SETTER(tps, set_rds_tps) STR_SETTER(tps, set_rds_tps, PS_LENGTH)
STR_SETTER(rt, set_rds_rt) STR_SETTER(rt, set_rds_rt, RT_LENGTH)
STR_RAW_SETTER(ptyn_raw, set_rds_ptyn)
STR_RAW_SETTER(ps_raw, set_rds_ps)
STR_RAW_SETTER(tps_raw, set_rds_tps)
STR_RAW_SETTER(rt_raw, set_rds_rt)
STR_RAW_SETTER(lps, set_rds_lps) STR_RAW_SETTER(lps, set_rds_lps)
STR_RAW_GETTER(lps, LPS_LENGTH) STR_RAW_GETTER(lps, LPS_LENGTH)
@@ -374,81 +381,20 @@ int lua_get_rds_eon(lua_State *localL) {
return 1; return 1;
} }
int lua_set_rds_udg(lua_State *localL) {
if (!lua_isboolean(localL, 1)) return luaL_error(localL, "boolean expected, got %s", luaL_typename(localL, 1));
int xy = lua_toboolean(localL, 1);
luaL_checktype(localL, 2, LUA_TTABLE);
int n = lua_rawlen(localL, 2);
if(n > 8) return luaL_error(localL, "table length over 8");
uint16_t blocks[8][3] = {0};
for (int i = 1; i <= n; i++) {
lua_rawgeti(localL, 2, i);
if(lua_istable(localL, -1)) {
int n2 = lua_rawlen(localL, -1);
if(n2 > 3) return luaL_error(localL, "table length over 3");
for(int j = 1; j <= n2; j++) {
lua_rawgeti(localL, -1, j);
if (lua_isinteger(localL, -1)) blocks[i-1][j-1] = lua_tointeger(localL, -1);
else return luaL_error(localL, "integer expected, got %s", luaL_typename(localL, -1));
lua_pop(localL, 1);
}
}
else return luaL_error(localL, "table expected, got %s", luaL_typename(localL, -1));
lua_pop(localL, 1);
}
if(xy) {
memcpy(&(enc->data[writing_program].udg2), blocks, n * sizeof(uint16_t[3]));
enc->data[writing_program].udg2_len = n;
} else {
memcpy(&(enc->data[writing_program].udg1), blocks, n * sizeof(uint16_t[3]));
enc->data[writing_program].udg1_len = n;
}
return 0;
}
int lua_set_rds_udg2(lua_State *localL) {
if (!lua_isboolean(localL, 1)) return luaL_error(localL, "boolean expected, got %s", luaL_typename(localL, 1));
int xy = lua_toboolean(localL, 1);
luaL_checktype(localL, 2, LUA_TTABLE);
int n = lua_rawlen(localL, 2);
if(n > 8) return luaL_error(localL, "table length over 8");
uint16_t blocks[8][4] = {0};
for (int i = 1; i <= n; i++) {
lua_rawgeti(localL, 2, i);
if(lua_istable(localL, -1)) {
int n2 = lua_rawlen(localL, -1);
if(n2 > 4) return luaL_error(localL, "table length over 4");
for(int j = 1; j <= n2; j++) {
lua_rawgeti(localL, -1, j);
if (lua_isinteger(localL, -1)) blocks[i-1][j-1] = lua_tointeger(localL, -1);
else return luaL_error(localL, "integer expected, got %s", luaL_typename(localL, -1));
lua_pop(localL, 1);
}
}
else return luaL_error(localL, "table expected, got %s", luaL_typename(localL, -1));
lua_pop(localL, 1);
}
if(xy) {
memcpy(&(enc->data[writing_program].udg2_rds2), blocks, n * sizeof(uint16_t[4]));
enc->data[writing_program].udg2_len_rds2 = n;
} else {
memcpy(&(enc->data[writing_program].udg1_rds2), blocks, n * sizeof(uint16_t[4]));
enc->data[writing_program].udg1_len_rds2 = n;
}
return 0;
}
int lua_crc16(lua_State *localL) { int lua_crc16(lua_State *localL) {
size_t len; size_t len;
const char* data = luaL_checklstring(localL, 1, &len); const char* data = luaL_checklstring(localL, 1, &len);
lua_pushinteger(localL, crc16_ccitt(data, len)); lua_pushinteger(localL, crc16_ccitt(data, len));
return 1; return 1;
} }
int lua_convert_to_rdscharset(lua_State *localL) {
size_t len;
const char *input = luaL_checklstring(localL, 1, &len);
char output[len + 1];
convert_to_rdscharset(input, output, len + 1);
lua_pushstring(localL, output);
return 1;
}
+6 -2
View File
@@ -72,16 +72,20 @@ int lua_set_rds_lps(lua_State *localL);
int lua_get_rds_lps(lua_State *localL); int lua_get_rds_lps(lua_State *localL);
int lua_set_rds_af_group0(lua_State *localL); int lua_set_rds_af_group0(lua_State *localL);
int lua_set_rds_rt(lua_State *localL); int lua_set_rds_rt(lua_State *localL);
int lua_set_rds_rt_raw(lua_State *localL);
int lua_set_rds_tps(lua_State *localL); int lua_set_rds_tps(lua_State *localL);
int lua_set_rds_tps_raw(lua_State *localL);
int lua_set_rds_ps(lua_State *localL); int lua_set_rds_ps(lua_State *localL);
int lua_set_rds_ps_raw(lua_State *localL);
int lua_set_rds_ptyn(lua_State *localL); int lua_set_rds_ptyn(lua_State *localL);
int lua_set_rds_ptyn_raw(lua_State *localL);
int lua_set_rds_grp_sqc(lua_State *localL); int lua_set_rds_grp_sqc(lua_State *localL);
int lua_toggle_rt_ab(lua_State *localL); int lua_toggle_rt_ab(lua_State *localL);
int lua_set_rds_eon(lua_State *localL); int lua_set_rds_eon(lua_State *localL);
int lua_get_rds_eon(lua_State *localL); int lua_get_rds_eon(lua_State *localL);
int lua_set_rds_udg(lua_State *localL);
int lua_set_rds_udg2(lua_State *localL);
int lua_crc16(lua_State *localL); int lua_crc16(lua_State *localL);
int lua_convert_to_rdscharset(lua_State *localL);
+30 -22
View File
@@ -22,9 +22,6 @@ void init_lua(RDSEncoder* _enc) {
luaL_requiref(L, LUA_IOLIBNAME, luaopen_io, 1); luaL_requiref(L, LUA_IOLIBNAME, luaopen_io, 1);
lua_pop(L, 6); lua_pop(L, 6);
lua_pushstring(L, VERSION);
lua_setglobal(L, "core_version");
lua_newtable(L); lua_newtable(L);
lua_setglobal(L, "ext"); lua_setglobal(L, "ext");
@@ -53,10 +50,13 @@ void init_lua(RDSEncoder* _enc) {
lua_registertotable(L, "set_program_defaults", lua_set_rds_program_defaults); lua_registertotable(L, "set_program_defaults", lua_set_rds_program_defaults);
lua_pushinteger(L, PROGRAMS); lua_pushinteger(L, PROGRAMS);
lua_setfield(L, -2, "max_programs"); lua_setfield(L, -2, "max_programs");
lua_pushstring(L, VERSION);
lua_setfield(L, -2, "core_version");
lua_registertotable(L, "set_output_program", lua_set_rds_program); lua_registertotable(L, "set_output_program", lua_set_rds_program);
lua_registertotable(L, "get_output_program", lua_get_rds_program); lua_registertotable(L, "get_output_program", lua_get_rds_program);
lua_registertotable(L, "set_writing_program", lua_set_rds_writing_program); lua_registertotable(L, "set_writing_program", lua_set_rds_writing_program);
lua_registertotable(L, "get_writing_program", lua_get_rds_writing_program); lua_registertotable(L, "get_writing_program", lua_get_rds_writing_program);
lua_registertotable(L, "encode_charset", lua_convert_to_rdscharset);
lua_setglobal(L, "dp"); lua_setglobal(L, "dp");
lua_newtable(L); lua_newtable(L);
@@ -69,7 +69,11 @@ void init_lua(RDSEncoder* _enc) {
lua_newtable(L); lua_newtable(L);
lua_setfield(L, -2, "tick"); lua_setfield(L, -2, "tick");
lua_newtable(L); lua_newtable(L);
lua_setfield(L, -2, "minute_tick");
lua_newtable(L);
lua_setfield(L, -2, "rt_transmission"); lua_setfield(L, -2, "rt_transmission");
lua_newtable(L);
lua_setfield(L, -2, "ps_transmission");
lua_setglobal(L, "hooks"); lua_setglobal(L, "hooks");
lua_newtable(L); lua_newtable(L);
@@ -117,9 +121,13 @@ void init_lua(RDSEncoder* _enc) {
lua_registertotable(L, "get_link", lua_get_rds_link); lua_registertotable(L, "get_link", lua_get_rds_link);
lua_registertotable(L, "set_ptyn", lua_set_rds_ptyn); lua_registertotable(L, "set_ptyn", lua_set_rds_ptyn);
lua_registertotable(L, "set_ptyn_raw", lua_set_rds_ptyn_raw);
lua_registertotable(L, "set_ps", lua_set_rds_ps); lua_registertotable(L, "set_ps", lua_set_rds_ps);
lua_registertotable(L, "set_ps_raw", lua_set_rds_ps_raw);
lua_registertotable(L, "set_tps", lua_set_rds_tps); lua_registertotable(L, "set_tps", lua_set_rds_tps);
lua_registertotable(L, "set_tps_raw", lua_set_rds_tps_raw);
lua_registertotable(L, "set_rt", lua_set_rds_rt); lua_registertotable(L, "set_rt", lua_set_rds_rt);
lua_registertotable(L, "set_rt_raw", lua_set_rds_rt_raw);
lua_registertotable(L, "toggle_rt_ab", lua_toggle_rt_ab); lua_registertotable(L, "toggle_rt_ab", lua_toggle_rt_ab);
lua_registertotable(L, "set_lps", lua_set_rds_lps); lua_registertotable(L, "set_lps", lua_set_rds_lps);
@@ -139,9 +147,6 @@ void init_lua(RDSEncoder* _enc) {
lua_registertotable(L, "set_eon", lua_set_rds_eon); lua_registertotable(L, "set_eon", lua_set_rds_eon);
lua_registertotable(L, "get_eon", lua_get_rds_eon); lua_registertotable(L, "get_eon", lua_get_rds_eon);
lua_registertotable(L, "set_udg", lua_set_rds_udg);
lua_registertotable(L, "set_udg2", lua_set_rds_udg2);
lua_registertotable(L, "set_streams", lua_set_rds_streams); lua_registertotable(L, "set_streams", lua_set_rds_streams);
lua_registertotable(L, "get_streams", lua_get_rds_streams); lua_registertotable(L, "get_streams", lua_get_rds_streams);
@@ -166,7 +171,8 @@ void init_lua(RDSEncoder* _enc) {
void run_lua(char *str, size_t str_len, char *cmd_output, size_t *out_len) { void run_lua(char *str, size_t str_len, char *cmd_output, size_t *out_len) {
pthread_mutex_lock(&lua_mutex); pthread_mutex_lock(&lua_mutex);
lua_getglobal(L, "data_handle"); lua_getglobal(L, "hooks");
lua_getfield(L, -1, "data_handle");
if (lua_isfunction(L, -1)) { if (lua_isfunction(L, -1)) {
lua_pushlstring(L, str, str_len); lua_pushlstring(L, str, str_len);
@@ -180,16 +186,17 @@ void run_lua(char *str, size_t str_len, char *cmd_output, size_t *out_len) {
} else fprintf(stderr, "Lua error: %s at 'data_handle'\n", lua_tostring(L, -1)); } else fprintf(stderr, "Lua error: %s at 'data_handle'\n", lua_tostring(L, -1));
} else fprintf(stderr, "'data_handle' is not a function\n"); } else fprintf(stderr, "'data_handle' is not a function\n");
lua_pop(L, 1); lua_pop(L, 2);
pthread_mutex_unlock(&lua_mutex); pthread_mutex_unlock(&lua_mutex);
} }
int lua_group(RDSGroup* group, const char grp) { int lua_group(RDSGroup* group, const char grp) {
pthread_mutex_lock(&lua_mutex); pthread_mutex_lock(&lua_mutex);
lua_getglobal(L, "group"); lua_getglobal(L, "hooks");
lua_getfield(L, -1, "group");
if (!lua_isfunction(L, -1)) { if (!lua_isfunction(L, -1)) {
lua_pop(L, 1); lua_pop(L, 2);
pthread_mutex_unlock(&lua_mutex); pthread_mutex_unlock(&lua_mutex);
return 0; return 0;
} }
@@ -198,7 +205,7 @@ int lua_group(RDSGroup* group, const char grp) {
if (lua_pcall(L, 1, 4, 0) != LUA_OK) { if (lua_pcall(L, 1, 4, 0) != LUA_OK) {
fprintf(stderr, "Lua error: %s\n", lua_tostring(L, -1)); fprintf(stderr, "Lua error: %s\n", lua_tostring(L, -1));
lua_pop(L, 1); lua_pop(L, 2);
pthread_mutex_unlock(&lua_mutex); pthread_mutex_unlock(&lua_mutex);
return 0; return 0;
} }
@@ -213,46 +220,47 @@ int lua_group(RDSGroup* group, const char grp) {
success = 1; success = 1;
} }
lua_pop(L, 4); lua_pop(L, 5);
pthread_mutex_unlock(&lua_mutex); pthread_mutex_unlock(&lua_mutex);
return success; return success;
} }
int lua_rds2_group(RDSGroup* group, int stream) { int lua_rds2_group(RDSGroup* group, int stream) {
pthread_mutex_lock(&lua_mutex); pthread_mutex_lock(&lua_mutex);
lua_getglobal(L, "rds2_group"); lua_getglobal(L, "hooks");
lua_getfield(L, -1, "rds2_group");
if (lua_isfunction(L, -1)) { if (lua_isfunction(L, -1)) {
lua_pushinteger(L, stream); lua_pushinteger(L, stream);
if (lua_pcall(L, 1, 5, 0) == LUA_OK) { if (lua_pcall(L, 1, 5, 0) == LUA_OK) {
if (!lua_isboolean(L, -5)) { if (!lua_isboolean(L, -5)) {
lua_pop(L, 5); lua_pop(L, 6);
pthread_mutex_unlock(&lua_mutex); pthread_mutex_unlock(&lua_mutex);
return 0; return 0;
} }
if (!lua_isinteger(L, -4)) { if (!lua_isinteger(L, -4)) {
lua_pop(L, 5); lua_pop(L, 6);
pthread_mutex_unlock(&lua_mutex); pthread_mutex_unlock(&lua_mutex);
return 0; return 0;
} }
if (!lua_isinteger(L, -3)) { if (!lua_isinteger(L, -3)) {
lua_pop(L, 5); lua_pop(L, 6);
pthread_mutex_unlock(&lua_mutex); pthread_mutex_unlock(&lua_mutex);
return 0; return 0;
} }
if (!lua_isinteger(L, -2)) { if (!lua_isinteger(L, -2)) {
lua_pop(L, 5); lua_pop(L, 6);
pthread_mutex_unlock(&lua_mutex); pthread_mutex_unlock(&lua_mutex);
return 0; return 0;
} }
if (!lua_isinteger(L, -1)) { if (!lua_isinteger(L, -1)) {
lua_pop(L, 5); lua_pop(L, 6);
pthread_mutex_unlock(&lua_mutex); pthread_mutex_unlock(&lua_mutex);
return 0; return 0;
} }
if(lua_toboolean(L, -5) == 0) { if(lua_toboolean(L, -5) == 0) {
lua_pop(L, 5); lua_pop(L, 6);
pthread_mutex_unlock(&lua_mutex); pthread_mutex_unlock(&lua_mutex);
return 0; return 0;
} }
@@ -261,12 +269,12 @@ int lua_rds2_group(RDSGroup* group, int stream) {
group->b = lua_tointeger(L, -3); group->b = lua_tointeger(L, -3);
group->c = lua_tointeger(L, -2); group->c = lua_tointeger(L, -2);
group->d = lua_tointeger(L, -1); group->d = lua_tointeger(L, -1);
lua_pop(L, 5); lua_pop(L, 6);
} else { } else {
fprintf(stderr, "Lua error: %s at 'rds2_group'\n", lua_tostring(L, -1)); fprintf(stderr, "Lua error: %s at 'rds2_group'\n", lua_tostring(L, -1));
lua_pop(L, 1); lua_pop(L, 2);
} }
} else lua_pop(L, 1); } else lua_pop(L, 2);
pthread_mutex_unlock(&lua_mutex); pthread_mutex_unlock(&lua_mutex);
return 1; return 1;
+1 -1
View File
@@ -41,7 +41,7 @@ float get_rds_sample(RDSModulator* rdsMod, uint8_t stream) {
rdsMod->data[stream].cur_bit = rdsMod->data[stream].bit_buffer[rdsMod->data[stream].bit_pos++]; rdsMod->data[stream].cur_bit = rdsMod->data[stream].bit_buffer[rdsMod->data[stream].bit_pos++];
rdsMod->data[stream].prev_output = rdsMod->data[stream].cur_output; rdsMod->data[stream].prev_output = rdsMod->data[stream].cur_output;
rdsMod->data[stream].cur_output = rdsMod->data[stream].prev_output ^ rdsMod->data[stream].cur_bit; rdsMod->data[stream].cur_output = rdsMod->data[stream].prev_output ^ rdsMod->data[stream].cur_bit; // Something with differential encoding? Instead of encoding the data, encode if the bit of data changes
} }
float sample = sinf(M_2PI * rdsMod->data[stream].phase + rdsMod->data[stream].symbol_shift); float sample = sinf(M_2PI * rdsMod->data[stream].phase + rdsMod->data[stream].symbol_shift);
+5 -50
View File
@@ -21,32 +21,7 @@ uint8_t get_rds_custom_groups(RDSEncoder* enc, RDSGroup *group);
uint8_t get_rds_custom_groups2(RDSEncoder* enc, RDSGroup *group); uint8_t get_rds_custom_groups2(RDSEncoder* enc, RDSGroup *group);
int get_rdsp_lua_group(RDSGroup *group, const char grp); int get_rdsp_lua_group(RDSGroup *group, const char grp);
#define HANDLE_UDG_STREAM(chan_idx, udg_prefix) \
do { \
if (stream != 0) { \
udg_idx = enc->state[enc->program].udg_idxs_rds2[chan_idx]; \
group->a = enc->data[enc->program].udg_prefix##_rds2[udg_idx][0]; \
group->b = enc->data[enc->program].udg_prefix##_rds2[udg_idx][1]; \
group->c = enc->data[enc->program].udg_prefix##_rds2[udg_idx][2]; \
group->d = enc->data[enc->program].udg_prefix##_rds2[udg_idx][3]; \
enc->state[enc->program].udg_idxs_rds2[chan_idx]++; \
if (enc->state[enc->program].udg_idxs_rds2[chan_idx] == enc->data[enc->program].udg_prefix##_len_rds2) \
enc->state[enc->program].udg_idxs_rds2[chan_idx] = 0; \
group->is_type_b = (group->a == 0 && IS_TYPE_B(group->b)); \
} else { \
udg_idx = enc->state[enc->program].udg_idxs[chan_idx]; \
group->b = enc->data[enc->program].udg_prefix[udg_idx][0]; \
group->c = enc->data[enc->program].udg_prefix[udg_idx][1]; \
group->d = enc->data[enc->program].udg_prefix[udg_idx][2]; \
enc->state[enc->program].udg_idxs[chan_idx]++; \
if (enc->state[enc->program].udg_idxs[chan_idx] == enc->data[enc->program].udg_prefix##_len) \
enc->state[enc->program].udg_idxs[chan_idx] = 0; \
group->is_type_b = (IS_TYPE_B(group->b) != 0); \
} \
} while(0)
static void get_rds_sequence_group(RDSEncoder* enc, RDSGroup *group, char* grp, uint8_t stream) { static void get_rds_sequence_group(RDSEncoder* enc, RDSGroup *group, char* grp, uint8_t stream) {
uint8_t udg_idx;
uint8_t ps_seq_idx = (stream == 0) ? 1 : 3; uint8_t ps_seq_idx = (stream == 0) ? 1 : 3;
uint8_t grp_seq_idx = (stream == 0) ? 0 : 2; uint8_t grp_seq_idx = (stream == 0) ? 0 : 2;
switch (*grp) switch (*grp)
@@ -73,12 +48,6 @@ static void get_rds_sequence_group(RDSEncoder* enc, RDSGroup *group, char* grp,
case 'E': case 'E':
get_rds_eon_group(enc, group); get_rds_eon_group(enc, group);
break; break;
case 'X':
HANDLE_UDG_STREAM(0, udg1);
break;
case 'Y':
HANDLE_UDG_STREAM(1, udg2);
break;
case 'F': case 'F':
get_rds_lps_group(enc, group); get_rds_lps_group(enc, group);
break; break;
@@ -92,6 +61,8 @@ static void get_rds_sequence_group(RDSEncoder* enc, RDSGroup *group, char* grp,
case 'O': case 'O':
case 'K': case 'K':
case 'U': case 'U':
case 'X':
case 'Y':
if(get_rdsp_lua_group(group, *grp) == 0) get_rds_ps_group(enc, group); if(get_rdsp_lua_group(group, *grp) == 0) get_rds_ps_group(enc, group);
break; break;
} }
@@ -111,11 +82,9 @@ static uint8_t check_rds_good_group(RDSEncoder* enc, char* grp) {
} }
} }
} }
if(*grp == 'X' && enc->data[enc->program].udg1_len != 0) good_group = 1;
if(*grp == 'Y' && enc->data[enc->program].udg2_len != 0) good_group = 1;
if(*grp == 'F' && enc->data[enc->program].lps[0] != '\0') good_group = 1; if(*grp == 'F' && enc->data[enc->program].lps[0] != '\0') good_group = 1;
if(*grp == 'T') good_group = 1; if(*grp == 'T') good_group = 1;
if(*grp == 'L' || *grp == 'R' || *grp == 'P' || *grp == 'S' || *grp == 'O' || *grp == 'K' || *grp == 'U') good_group = 1; if(*grp == 'L' || *grp == 'R' || *grp == 'P' || *grp == 'S' || *grp == 'O' || *grp == 'K' || *grp == 'U' || *grp == 'X' || *grp == 'Y') good_group = 1;
return good_group; return good_group;
} }
@@ -138,21 +107,7 @@ void get_rds_group(RDSEncoder* enc, RDSGroup *group, uint8_t stream) {
if (utc->tm_min != enc->state[enc->program].last_minute) { if (utc->tm_min != enc->state[enc->program].last_minute) {
enc->state[enc->program].last_minute = utc->tm_min; enc->state[enc->program].last_minute = utc->tm_min;
lua_call_tfunction("minute_tick");
uint8_t eon_has_ta = 0;
for (int i = 0; i < EONs; i++) {
if (enc->data[enc->program].eon[i].enabled && enc->data[enc->program].eon[i].ta) {
eon_has_ta = 1;
break;
}
}
if(enc->data[enc->program].tp && enc->data[enc->program].ta && enc->state[enc->program].ta_timeout && !eon_has_ta) {
enc->state[enc->program].ta_timeout--;
if(enc->state[enc->program].ta_timeout == 0) {
enc->data[enc->program].ta = 0;
enc->state[enc->program].ta_timeout_state = enc->state[enc->program].ta_timeout;
};
}
if(enc->data[enc->program].ct && stream == 0) { if(enc->data[enc->program].ct && stream == 0) {
get_rdsp_ct_group(group, now); get_rdsp_ct_group(group, now);
@@ -228,7 +183,7 @@ void get_rds_group(RDSEncoder* enc, RDSGroup *group, uint8_t stream) {
if(!good_group) cant_find_group++; if(!good_group) cant_find_group++;
else cant_find_group = 0; else cant_find_group = 0;
if(!good_group && cant_find_group == 23) { if(!good_group && cant_find_group >= 23) {
cant_find_group = 0; cant_find_group = 0;
break; break;
} }
-17
View File
@@ -72,17 +72,6 @@ typedef struct {
char grp_sqc[32]; char grp_sqc[32];
char grp_sqc_rds2[32]; char grp_sqc_rds2[32];
uint8_t udg1_len : 4;
uint8_t udg2_len : 4;
uint8_t udg1_len_rds2 : 4;
uint8_t udg2_len_rds2 : 4;
uint16_t udg1[8][3];
uint16_t udg2[8][3];
uint16_t udg1_rds2[8][4];
uint16_t udg2_rds2[8][4];
RDSEON eon[EONs]; RDSEON eon[EONs];
uint8_t lua_data[LUA_USER_DATA]; uint8_t lua_data[LUA_USER_DATA];
@@ -119,17 +108,12 @@ typedef struct {
uint8_t data_ecc : 1; uint8_t data_ecc : 1;
uint8_t grp_seq_idx[4]; uint8_t grp_seq_idx[4];
uint8_t udg_idxs[2];
uint8_t udg_idxs_rds2[2];
uint8_t fasttuning_state : 3; uint8_t fasttuning_state : 3;
uint8_t last_minute : 6; uint8_t last_minute : 6;
uint8_t last_second : 6; uint8_t last_second : 6;
uint8_t ta_timeout : 7;
uint8_t ta_timeout_state : 7;
uint8_t eon_index : 3; uint8_t eon_index : 3;
uint8_t eon_state : 4; uint8_t eon_state : 4;
RDSEONState eon_states[4]; RDSEONState eon_states[4];
@@ -144,7 +128,6 @@ typedef struct {
typedef struct { typedef struct {
uint8_t rds2_mode : 2; uint8_t rds2_mode : 2;
// uint8_t rds2_buffer[16384];
} RDSEncoderData; } RDSEncoderData;
typedef struct { typedef struct {
RDSEncoderData encoder_data; RDSEncoderData encoder_data;
+6 -2
View File
@@ -61,7 +61,8 @@ void get_rds_ps_group(RDSEncoder* enc, RDSGroup *group) {
if(enc->data[enc->program].af.num_afs) group->c = get_next_af(enc); if(enc->data[enc->program].af.num_afs) group->c = get_next_af(enc);
else { else {
group->b |= 1 << 11; // set to b // Set type to B, just makes it easier for a receiver to catch the PI
group->b |= 1 << 11;
group->is_type_b = 1; group->is_type_b = 1;
} }
@@ -69,7 +70,10 @@ void get_rds_ps_group(RDSEncoder* enc, RDSGroup *group) {
else group->d = enc->state[enc->program].ps_text[enc->state[enc->program].ps_csegment * 2] << 8 | enc->state[enc->program].ps_text[enc->state[enc->program].ps_csegment * 2 + 1]; else group->d = enc->state[enc->program].ps_text[enc->state[enc->program].ps_csegment * 2] << 8 | enc->state[enc->program].ps_text[enc->state[enc->program].ps_csegment * 2 + 1];
enc->state[enc->program].ps_csegment++; enc->state[enc->program].ps_csegment++;
if (enc->state[enc->program].ps_csegment == 4) enc->state[enc->program].ps_csegment = 0; if (enc->state[enc->program].ps_csegment == 4) {
lua_call_tfunction("ps_transmission");
enc->state[enc->program].ps_csegment = 0;
}
} }
void get_rds_fasttuning_group(RDSEncoder* enc, RDSGroup *group) { void get_rds_fasttuning_group(RDSEncoder* enc, RDSGroup *group) {