1
+ const udp = require ( 'dgram' ) ;
2
+
3
+ // Use with md380-emulator server https://github.com/rick51231/ambe-server-docker
4
+
5
+ // Convert to wav:
6
+ // ffmpeg -f s16le -ar 8000 -ac 1 -i decoded.pcm -af "volume=5" out.wav
7
+ // sox -r 8000 -e signed-integer -L -b 16 -c 1 -v 5 decoded.pcm out.wav
8
+ class AMBEClient {
9
+ socket ;
10
+ ip ;
11
+ port ;
12
+ timeout ; //ms
13
+ isBusy = false ;
14
+ currentPromise = null ;
15
+ currentTimeout = null ;
16
+
17
+ constructor ( ip , port , timeout = 500 ) {
18
+ this . ip = ip ;
19
+ this . port = port ;
20
+ this . timeout = timeout ;
21
+
22
+ this . socket = udp . createSocket ( 'udp4' ) ;
23
+
24
+ this . socket . on ( 'message' , ( msg ) => {
25
+ this . ready ( msg ) ;
26
+ } ) ;
27
+ }
28
+
29
+ decode ( buffer ) {
30
+ return new Promise ( resolve => {
31
+ if ( buffer . length !== 7 )
32
+ return resolve ( null ) ;
33
+
34
+ this . run ( buffer , resolve ) ;
35
+ } ) ;
36
+ }
37
+
38
+ encode ( buffer ) {
39
+ return new Promise ( resolve => {
40
+ if ( buffer . length !== 320 )
41
+ return resolve ( null ) ;
42
+
43
+ this . run ( buffer , resolve ) ;
44
+ } ) ;
45
+ }
46
+
47
+ run ( buffer , resolve ) {
48
+ if ( this . isBusy )
49
+ return setTimeout ( ( ) => {
50
+ this . run ( buffer , resolve ) ;
51
+ } , 1 ) ;
52
+
53
+ this . isBusy = true ;
54
+ this . currentPromise = resolve ;
55
+
56
+ this . currentTimeout = setTimeout ( ( ) => {
57
+ this . ready ( null ) ;
58
+ } , this . timeout ) ;
59
+
60
+ this . socket . send ( buffer , this . port , this . ip ) ;
61
+ }
62
+
63
+ ready ( result ) {
64
+ if ( this . currentPromise === null )
65
+ return ;
66
+
67
+ this . currentPromise ( result ) ;
68
+ clearTimeout ( this . currentTimeout ) ;
69
+ this . currentTimeout = null ;
70
+ this . currentPromise = null ;
71
+ this . isBusy = false ;
72
+ }
73
+ }
74
+
75
+ module . exports = AMBEClient ;
0 commit comments