Reflector voices work!

This commit is contained in:
Simon 2020-09-17 20:34:50 +01:00
parent 4b5d069763
commit 8b6436db5e
23 changed files with 619 additions and 60 deletions

BIN
Audio/de_DE.ambe Normal file

Binary file not shown.

44
Audio/de_DE.indx Normal file
View File

@ -0,0 +1,44 @@
0 70 24
1 113 24
2 155 25
3 194 28
4 240 30
5 287 27
6 332 32
7 383 32
8 432 25
9 476 32
alpha 525 25
bravo 568 31
charlie 621 26
delta 668 30
A 717 19
B 761 21
C 810 27
D 862 23
E 909 23
F 957 23
G 1006 22
H 1052 24
I 1101 18
J 1143 26
K 1199 26
L 1250 23
M 1297 21
N 1343 25
O 1393 19
P 1438 19
Q 1485 24
R 1535 23
S 1583 21
T 1636 23
U 1685 22
V 1732 19
W 1776 22
X 1823 24
Y 1875 34
Z 1935 25
linkedto 1987 40
notlinked 2080 50
linkingto 2150 44
isbusy 2260 40

BIN
Audio/dk_DK.ambe Normal file

Binary file not shown.

44
Audio/dk_DK.indx Normal file
View File

@ -0,0 +1,44 @@
0 74 21
1 112 15
2 152 19
3 190 22
4 228 35
5 280 24
6 321 31
7 370 27
8 414 27
9 458 24
alpha 498 32
bravo 550 27
charlie 596 38
delta 655 27
A 702 18
B 746 16
C 788 20
D 835 16
E 877 14
F 915 18
G 959 13
H 997 19
I 1041 13
J 1079 23
K 1129 20
L 1172 20
M 1216 19
N 1260 17
O 1302 16
P 1344 15
Q 1387 17
R 1429 18
S 1472 19
T 1517 19
U 1561 18
V 1603 17
W 1647 34
X 1706 20
Y 1751 19
Z 1794 23
linkedto 1844 37
notlinked 1920 50
linkingto 1990 34
isbusy 2063 40

BIN
Audio/en_GB.ambe Normal file

Binary file not shown.

44
Audio/en_GB.indx Normal file
View File

@ -0,0 +1,44 @@
0 77 41
1 136 24
2 178 25
3 221 30
4 270 35
5 323 35
6 376 39
7 433 34
8 486 29
9 533 35
alpha 587 31
bravo 638 33
charlie 692 31
delta 745 30
A 796 24
B 842 33
C 890 23
D 925 33
E 982 34
F 1033 34
G 1085 34
H 1137 40
I 1196 30
J 1245 35
K 1299 33
L 1350 30
M 1398 28
N 1444 30
O 1492 23
P 1533 32
Q 1584 39
R 1640 23
S 1681 33
T 1734 32
U 1783 35
V 1837 33
W 1888 38
X 1945 35
Y 1999 28
Z 2052 37
linked 2116 19
notlinked 2186 44
linking 2250 31
isbusy 2342 33

BIN
Audio/en_US.ambe Normal file

Binary file not shown.

44
Audio/en_US.indx Normal file
View File

@ -0,0 +1,44 @@
0 81 39
1 138 34
2 194 22
3 238 31
4 286 34
5 337 46
6 401 39
7 458 37
8 513 29
9 560 35
alpha 613 26
bravo 661 34
charlie 718 34
delta 773 31
A 825 19
B 862 24
C 930 27
D 1001 24
E 1068 28
F 1140 29
G 1213 24
H 1282 31
I 1355 29
J 1424 33
K 1502 25
L 1570 22
M 1636 28
N 1707 28
O 1777 27
P 1850 24
Q 1919 25
R 1985 26
S 2055 29
T 2131 25
U 2200 25
V 2265 27
W 2336 33
X 2413 24
Y 2481 26
Z 2553 32
linked 2629 20
notlinked 2702 49
linking 2771 25
isbusy 2864 34

BIN
Audio/es_ES.ambe Normal file

Binary file not shown.

44
Audio/es_ES.indx Normal file
View File

@ -0,0 +1,44 @@
0 75 31
1 120 32
2 166 33
3 218 30
4 265 36
5 315 42
6 371 37
7 422 37
8 472 35
9 521 34
alpha 570 34
bravo 620 36
charlie 674 43
delta 734 38
A 790 26
B 828 22
C 873 22
D 915 24
E 959 17
F 996 31
G 1045 26
H 1089 35
I 1142 20
J 1181 34
K 1238 22
L 1279 30
M 1329 30
N 1380 33
O 1431 22
P 1472 21
Q 1516 26
R 1563 32
S 1614 31
T 1667 22
U 1710 23
V 1748 28
W 1796 52
X 1868 28
Y 1917 17
Z 1953 35
linkedto 2009 64
notlinked 2125 68
linkingto 2209 66
isbusy 2356 58

BIN
Audio/fr_FR.ambe Normal file

Binary file not shown.

44
Audio/fr_FR.indx Normal file
View File

@ -0,0 +1,44 @@
0 86 29
1 132 16
2 165 20
3 207 19
4 247 24
5 290 29
6 336 34
7 390 25
8 432 24
9 473 23
alpha 513 29
bravo 560 27
charlie 607 30
delta 658 30
A 706 21
B 745 27
C 788 34
D 840 30
E 887 23
F 928 27
G 974 27
H 1018 30
I 1067 20
J 1105 29
K 1154 22
L 1193 28
M 1240 28
N 1287 28
O 1333 23
P 1378 21
Q 1418 23
R 1458 28
S 1503 31
T 1559 21
U 1598 22
V 1638 30
W 1685 46
X 1748 31
Y 1798 21
Z 1836 14
linkedto 1850 35
notlinked 1933 46
linkingto 2000 38
isbusy 2083 47

BIN
Audio/it_IT.ambe Normal file

Binary file not shown.

44
Audio/it_IT.indx Normal file
View File

@ -0,0 +1,44 @@
0 78 33
1 128 27
2 172 30
3 223 17
4 262 38
5 320 38
6 375 31
7 423 36
8 477 33
9 527 39
alpha 583 34
bravo 636 35
charlie 693 35
delta 749 34
A 802 12
B 832 19
C 875 17
D 915 17
E 957 14
F 993 34
G 1050 20
H 1092 32
I 1147 14
J 1184 43
K 1255 30
L 1308 34
M 1365 30
N 1418 29
O 1469 13
P 1511 15
Q 1551 16
R 1590 28
S 1641 30
T 1691 20
U 1733 12
V 1767 21
W 1811 47
X 1880 25
Y 1928 43
Z 1994 35
linkedto 2056 48
notlinked 2146 65
linkingto 2231 41
isbusy 2313 51

BIN
Audio/no_NO.ambe Normal file

Binary file not shown.

44
Audio/no_NO.indx Normal file
View File

@ -0,0 +1,44 @@
0 59 28
1 94 29
2 129 27
3 162 25
4 191 36
5 230 30
6 264 38
7 306 31
8 341 34
9 378 28
alpha 410 36
bravo 464 30
charlie 511 34
delta 561 34
A 614 23
B 657 24
C 702 24
D 750 21
E 795 28
F 848 24
G 895 32
H 947 31
I 999 18
J 1037 30
K 1092 28
L 1144 19
M 1188 20
N 1233 17
O 1274 27
P 1324 24
Q 1370 24
R 1418 19
S 1462 31
T 1516 24
U 1564 23
V 1608 20
W 1650 40
X 1714 32
Y 1771 24
Z 1815 29
linkedto 1874 40
notlinked 1958 49
linkingto 2026 40
isbusy 2140 38

BIN
Audio/pl_PL.ambe Normal file

Binary file not shown.

44
Audio/pl_PL.indx Normal file
View File

@ -0,0 +1,44 @@
0 91 36
1 155 38
2 221 29
3 282 31
4 343 37
5 412 42
6 482 41
7 551 43
8 622 34
9 684 50
alpha 763 30
bravo 812 32
charlie 865 35
delta 923 34
A 979 17
B 1004 30
C 1062 25
D 1110 27
E 1161 29
F 1213 36
G 1273 30
H 1325 26
I 1375 18
J 1417 32
K 1477 23
L 1524 26
M 1573 26
N 1621 24
O 1668 18
P 1716 23
Q 1765 20
R 1809 23
S 1855 35
T 1918 25
U 1967 22
V 2013 28
W 2062 15
X 2099 31
Y 2153 39
Z 2218 12
linkedto 2255 45
notlinked 2352 51
linkingto 2425 45
isbusy 2551 59

BIN
Audio/se_SE.ambe Normal file

Binary file not shown.

44
Audio/se_SE.indx Normal file
View File

@ -0,0 +1,44 @@
0 75 35
1 130 33
2 180 32
3 232 28
4 278 41
5 337 30
6 385 43
7 443 34
8 497 35
9 547 28
alpha 595 35
bravo 652 35
charlie 708 32
delta 760 48
A 828 30
B 886 28
C 938 33
D 997 22
E 1045 34
F 1107 20
G 1152 36
H 1215 30
I 1272 27
J 1325 35
K 1385 29
L 1445 25
M 1499 26
N 1552 20
O 1599 26
P 1649 28
Q 1706 34
R 1773 23
S 1825 30
T 1882 25
U 1935 23
V 1981 35
W 2042 47
X 2118 27
Y 2170 19
Z 2215 45
linkedto 2290 39
notlinked 2382 51
linkingto 2453 36
isbusy 2569 54

View File

@ -49,7 +49,13 @@ import config
import log
from const import *
from mk_voice import pkt_gen
from voice_lib import words
#from voice_lib import words
#Read voices
from read_ambe import readAMBE
#regex
import re
# Stuff for socket reporting
import pickle
@ -534,77 +540,117 @@ class routerHBP(HBSYSTEM):
logger.info('(%s) Reflector for TG %s does not exist. Creating as User Activated',self._system, _int_dst_id)
make_single_reflector(_dst_id,self._system)
if _int_dst_id > 10 and _int_dst_id != 5000:
for _bridge in BRIDGES:
if _bridge[0:1] != '#':
continue
for _system in BRIDGES[_bridge]:
_dehash_bridge = _bridge[1:]
if _system['SYSTEM'] == self._system:
# TGID matches a rule source, reset its timer
if _slot == _system['TS'] and _dst_id == _system['TGID'] and ((_system['TO_TYPE'] == 'ON' and (_system['ACTIVE'] == True)) or (_system['TO_TYPE'] == 'OFF' and _system['ACTIVE'] == False)):
_system['TIMER'] = pkt_time + _system['TIMEOUT']
logger.info('(%s) Transmission match for Reflector: %s. Reset timeout to %s', self._system, _bridge, _system['TIMER'])
# TGID matches an ACTIVATION trigger
if _int_dst_id == int(_dehash_bridge) and _system['SYSTEM'] == self._system and _slot == _system['TS']:
# Set the matching rule as ACTIVE
if _system['ACTIVE'] == False:
_system['ACTIVE'] = True
_system['TIMER'] = pkt_time + _system['TIMEOUT']
logger.info('(%s) Reflector: %s, connection changed to state: %s', self._system, _bridge, _system['ACTIVE'])
# Cancel the timer if we've enabled an "OFF" type timeout
if _system['TO_TYPE'] == 'OFF':
_system['TIMER'] = pkt_time
logger.info('(%s) Reflector: %s set to "OFF" with an on timer rule: timeout timer cancelled', self._system, _bridge)
# Reset the timer for the rule
if _system['ACTIVE'] == True and _system['TO_TYPE'] == 'ON':
_system['TIMER'] = pkt_time + _system['TIMEOUT']
logger.info('(%s) Reflector: %s, timeout timer reset to: %s', self._system, _bridge, _system['TIMER'] - pkt_time)
# TGID matches an DE-ACTIVATION trigger
#Single TG mode
if (_dst_id in _system['OFF'] or _dst_id in _system['RESET'] or (_int_dst_id != int(_dehash_bridge)) and _system['SYSTEM'] == self._system and _slot == _system['TS']):
# Set the matching rule as ACTIVE
#Single TG mode
if _dst_id in _system['OFF'] or _int_dst_id != int(_dehash_bridge) :
#if _dst_id in _system['OFF']:
if _system['ACTIVE'] == True:
_system['ACTIVE'] = False
logger.info('(%s) Reflector: %s, connection changed to state: %s', self._system, _bridge, _system['ACTIVE'])
# Cancel the timer if we've enabled an "ON" type timeout
if _system['TO_TYPE'] == 'ON':
_system['TIMER'] = pkt_time
logger.info('(%s) Reflector: %s set to ON with and "OFF" timer rule: timeout timer cancelled', self._system, _bridge)
# Reset the timer for the rule
if _system['ACTIVE'] == False and _system['TO_TYPE'] == 'OFF':
_system['TIMER'] = pkt_time + _system['TIMEOUT']
logger.info('(%s) Reflector: %s, timeout timer reset to: %s', self._system, _bridge, _system['TIMER'] - pkt_time)
# Cancel the timer if we've enabled an "ON" type timeout
if _system['ACTIVE'] == True and _system['TO_TYPE'] == 'ON' and _dst_id in _system['OFF']:
_system['TIMER'] = pkt_time
logger.info('(%s) Reflector: %s set to ON with and "OFF" timer rule: timeout timer cancelled', self._system, _bridge)
if (_frame_type == HBPF_DATA_SYNC) and (_dtype_vseq == HBPF_SLT_VTERM) and (self.STATUS[_slot]['RX_TYPE'] != HBPF_SLT_VTERM):
#Speak callsign before message
_say = [words['silence']]
_systemcs = re.sub(r'\W+', '', self._system)
_systemcs.upper()
for character in _systemcs:
_say.append(words[character])
_say.append(words['silence'])
#If disconnection called
if _int_dst_id == 4000:
_say.append(words['notlinked'])
_say.append(words['silence'])
#If status called
elif _int_dst_id == 5000:
for _bridge in BRIDGES:
if _bridge[0:1] != '#':
continue
for _system in BRIDGES[_bridge]:
_dehash_bridge = _bridge[1:]
if _system['SYSTEM'] == self._system:
# TGID matches a rule source, reset its timer
if _slot == _system['TS'] and _dst_id == _system['TGID'] and ((_system['TO_TYPE'] == 'ON' and (_system['ACTIVE'] == True)) or (_system['TO_TYPE'] == 'OFF' and _system['ACTIVE'] == False)):
_system['TIMER'] = pkt_time + _system['TIMEOUT']
logger.info('(%s) Transmission match for Reflector: %s. Reset timeout to %s', self._system, _bridge, _system['TIMER'])
logger.info('a')
_active = False
if _system['ACTIVE'] == True:
logger.info('b')
_say.append(words['silence'])
_say.append(words['linked'])
_say.append(words['silence'])
_say.append(words['2'])
_say.append(words['silence'])
for num in str(_dehash_bridge):
_say.append(words[num])
_active = True
# TGID matches an ACTIVATION trigger
if _int_dst_id == int(_dehash_bridge) and _system['SYSTEM'] == self._system and _slot == _system['TS']:
# Set the matching rule as ACTIVE
if _system['ACTIVE'] == False:
_system['ACTIVE'] = True
_system['TIMER'] = pkt_time + _system['TIMEOUT']
logger.info('(%s) Reflector: %s, connection changed to state: %s', self._system, _bridge, _system['ACTIVE'])
# Cancel the timer if we've enabled an "OFF" type timeout
if _system['TO_TYPE'] == 'OFF':
_system['TIMER'] = pkt_time
logger.info('(%s) Reflector: %s set to "OFF" with an on timer rule: timeout timer cancelled', self._system, _bridge)
# Reset the timer for the rule
if _system['ACTIVE'] == True and _system['TO_TYPE'] == 'ON':
_system['TIMER'] = pkt_time + _system['TIMEOUT']
logger.info('(%s) Reflector: %s, timeout timer reset to: %s', self._system, _bridge, _system['TIMER'] - pkt_time)
if _active == False:
_say.append(words['notlinked'])
#Speak what TG was requested to link
else:
_say.append(words['silence'])
_say.append(words['linked'])
_say.append(words['silence'])
_say.append(words['2'])
_say.append(words['silence'])
for num in str(_int_dst_id):
_say.append(words[num])
speech = pkt_gen(bytes_3(9), bytes_3(9), bytes_4(9), 1, _say)
# TGID matches an DE-ACTIVATION trigger
#Single TG mode
if (_dst_id in _system['OFF'] or _dst_id in _system['RESET'] or (_int_dst_id != int(_dehash_bridge)) and _system['SYSTEM'] == self._system and _slot == _system['TS']):
# Set the matching rule as ACTIVE
#Single TG mode
if _dst_id in _system['OFF'] or _int_dst_id != int(_dehash_bridge) :
#if _dst_id in _system['OFF']:
if _system['ACTIVE'] == True:
_system['ACTIVE'] = False
logger.info('(%s) Reflector: %s, connection changed to state: %s', self._system, _bridge, _system['ACTIVE'])
# Cancel the timer if we've enabled an "ON" type timeout
if _system['TO_TYPE'] == 'ON':
_system['TIMER'] = pkt_time
logger.info('(%s) Reflector: %s set to ON with and "OFF" timer rule: timeout timer cancelled', self._system, _bridge)
# Reset the timer for the rule
if _system['ACTIVE'] == False and _system['TO_TYPE'] == 'OFF':
_system['TIMER'] = pkt_time + _system['TIMEOUT']
logger.info('(%s) Reflector: %s, timeout timer reset to: %s', self._system, _bridge, _system['TIMER'] - pkt_time)
# Cancel the timer if we've enabled an "ON" type timeout
if _system['ACTIVE'] == True and _system['TO_TYPE'] == 'ON' and _dst_id in _system['OFF']:
_system['TIMER'] = pkt_time
logger.info('(%s) Reflector: %s set to ON with and "OFF" timer rule: timeout timer cancelled', self._system, _bridge)
if (_frame_type == HBPF_DATA_SYNC) and (_dtype_vseq == HBPF_SLT_VTERM) and (self.STATUS[_slot]['RX_TYPE'] != HBPF_SLT_VTERM):
speech = pkt_gen(bytes_3(2342690), bytes_3(9), bytes_4(2342690), 1, [words['all_circuits'],words['enabled']])
sleep(1)
while True:
try:
pkt = next(speech)
except StopIteration:
break
sleep(.058)
self.send_system(pkt)
#print(bhex(pkt))
sleep(1)
while True:
try:
pkt = next(speech)
except StopIteration:
break
sleep(.058)
self.send_system(pkt)
#print(bhex(pkt))
# Mark status variables for use later
self.STATUS[_slot]['RX_PEER'] = _peer_id
@ -977,6 +1023,12 @@ if __name__ == '__main__':
else:
report_server = None
logger.info('(REPORT) TCP Socket reporting not configured')
#Read AMBE
AMBEobj = readAMBE('en_GB','./Audio/')
#global words
words = AMBEobj.readfiles()
logger.info('(AMBE) Read %s words into voice dict',len(words) - 1)
# HBlink instance creation
logger.info('(GLOBAL) HBlink \'bridge.py\' -- SYSTEM STARTING...')

View File

@ -56,7 +56,6 @@ def pkt_gen(_rf_src, _dst_id, _peer, _slot, _phrase):
EMBED = []
EMBED.append( BS_VOICE_SYNC )
EMBED.append(EMB['BURST_A'][:8] + EMB_LC[1] + EMB['BURST_A'][-8:])
EMBED.append(EMB['BURST_B'][:8] + EMB_LC[1] + EMB['BURST_B'][-8:])
EMBED.append(EMB['BURST_C'][:8] + EMB_LC[2] + EMB['BURST_C'][-8:])
EMBED.append(EMB['BURST_D'][:8] + EMB_LC[3] + EMB['BURST_D'][-8:])
@ -78,7 +77,6 @@ def pkt_gen(_rf_src, _dst_id, _peer, _slot, _phrase):
# Send each burst, six bursts per Superframe rotating through with the proper EMBED value per burst A-F
for word in _phrase:
for burst in range(0, len(word)):
print(burst)
pkt = b'DMRD' + bytes([SEQ]) + SDP + bytes([_slot << 7 | BURSTBITS[burst % 6]]) + STREAM_ID + (word[burst + 0][0] + EMBED[burst % 6] + word[burst + 0][1]).tobytes() + TAIL
SEQ = (SEQ + 1) % 0x100
yield pkt

69
read_ambe.py Normal file
View File

@ -0,0 +1,69 @@
from bitarray import bitarray
from itertools import islice
class readAMBE:
def __init__(self, lang,path):
self.lang = lang
self.path = path
self.prefix = path+lang
def _make_bursts(self,data):
it = iter(data)
for i in range(0, len(data), 108):
yield bitarray([k for k in islice(it, 108)])
def readfiles(self):
_AMBE_LENGTH = 9
indexDict = {}
try:
with open(self.prefix+'.indx') as index:
for line in index:
(voice,start,length) = line.split()
indexDict[voice] = [int(start) * _AMBE_LENGTH ,int(length) * _AMBE_LENGTH]
index.close()
except IOError:
return False
ambeBytearray = {}
_wordBitarray = bitarray(endian='big')
_wordBADict = {}
try:
with open(self.prefix+'.ambe','rb') as ambe:
for _voice in indexDict:
ambe.seek(indexDict[_voice][0])
_wordBitarray.frombytes(ambe.read(indexDict[_voice][1]))
#108
_wordBADict[_voice] = []
pairs = 1
_lastburst = ''
for _burst in self._make_bursts(_wordBitarray):
#Not sure if we need to pad or not? Seems to make little difference.
if len(_burst) < 108:
pad = (108 - len(_burst))
for i in range(0,pad,1):
_burst.append(False)
if pairs == 2:
_wordBADict[_voice].append([_lastburst,_burst])
_lastburst = ''
pairs = 1
next
else:
pairs = pairs + 1
_lastburst = _burst
_wordBitarray.clear()
ambe.close()
except IOError:
return False
_wordBADict['silence'] = ([
[bitarray('000000001010110000000000000000001010101000000000000000000100000000000000000000000010000000000000000000000'),
bitarray('0000000000000000000000001000100000000000000000001000000000000000000000010000000000000000000000010000000')]
])
return _wordBADict
if __name__ == '__main__':
test = readAMBE('en_GB','./Audio/')
print(test.readfiles())