Skip to content

Commit d11b7bb

Browse files
committed
realtime voice communication demo added
1 parent 906d77d commit d11b7bb

21 files changed

+1122
-134
lines changed

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -174,3 +174,8 @@ $RECYCLE.BIN/
174174

175175
# next.js build output
176176
.next
177+
ssl/server.cert
178+
ssl/server.key
179+
test.wav
180+
recorder/ChromeSetup.exe
181+
test.wav

.vscode/settings.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
{
22
"editor.trimAutoWhitespace": false,
33
"eslint.alwaysShowStatus": true,
4-
"eslint.options": {"parserOptions.ecmaVersion":6}
4+
"eslint.options": {
5+
"parserOptions.ecmaVersion": 6
6+
},
7+
"cSpell.language": "en"
58
}

SIPSERVRMQTT.js

+24-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,23 @@
11
'use strict';
22
// https://devpost.com/software/mosca
33
var mosca = require('mosca');
4-
var http = require('http'),
5-
httpServer = http.createServer()
4+
var fs = require('fs');
5+
var Chalk = require('./chalk');
6+
var http = require('http');
7+
var https = require('https');
8+
var privateKey = fs.readFileSync('ssl/server.key', 'utf8');
9+
var certificate = fs.readFileSync('ssl/server.cert', 'utf8');
10+
11+
// setting credentials object
12+
var credentials = {
13+
key: privateKey,
14+
cert: certificate
15+
};
16+
// creating chalk instance
17+
var myChalk = new Chalk();
18+
19+
var httpServer = http.createServer();
20+
var httpsServer = https.createServer(credentials);
621

722
var ascoltatore = {
823
//using ascoltatore
@@ -32,18 +47,20 @@ MQTTserver.on('clientConnected', function (client) {
3247
});
3348

3449
// fired when a message is received
50+
3551
MQTTserver.on('published', function (packet, client) {
36-
console.log('[Published]', packet.topic, packet.retain);
37-
});
52+
console.log(myChalk.info('[Published]' + packet.topic + 'Packet len = ' + packet.length));
53+
})
3854

3955
MQTTserver.on('ready', setup);
4056

4157
// fired when the mqtt server is ready
4258
function setup() {
4359
console.log('[ready] Mosca server is up and running');
44-
60+
4561
}
4662

4763
MQTTserver.attachHttpServer(httpServer);
48-
49-
httpServer.listen(1800);
64+
MQTTserver.attachHttpServer(httpsServer);
65+
httpServer.listen(1800);
66+
httpsServer.listen(2000);

doc.html

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="UTF-8">
6+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
7+
<meta http-equiv="X-UA-Compatible" content="ie=edge">
8+
<link rel="stylesheet" href="https://cdn.rawgit.com/toopay/bootstrap-markdown/master/css/bootstrap-markdown.min.css" />
9+
<script src="https://rawgit.com/jeresig/jquery.hotkeys/master/jquery.hotkeys.js"></script>
10+
11+
<link data-require="bootstrap-css@3.1.1" data-semver="3.1.1" rel="stylesheet" href="//netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" />
12+
<link data-require="fontawesome@4.1.0" data-semver="4.1.0" rel="stylesheet" href="//netdna.bootstrapcdn.com/font-awesome/4.1.0/css/font-awesome.min.css" />
13+
<link rel="stylesheet" href="https://cdn.rawgit.com/toopay/bootstrap-markdown/master/css/bootstrap-markdown.min.css" />
14+
<link rel="stylesheet" href="style.css" />
15+
<script src="script.js"></script>
16+
<title>Document</title>
17+
</head>
18+
19+
<body>
20+
<h1 id="ics-for-smartdoorbell">ICs for SmartDoorBell</h1>
21+
<p>1. <code>I2S DAC</code> * <a href="https://www.aliexpress.com/store/product/Free-Shipping-AT29LV020-10TU-AT29LV020-10-TSOP32-new-and-Original-in-stock/1665444_32294995142.html?spm=2114.search0204.3.8.12b47844KCpffg&amp;ws_ab_test=searchweb0_0,searchweb201602_3_10065_10068_10546_10059_10884_10548_10887_10696_100031_10084_10083_10103_10618_10307_449,searchweb201603_60,ppcSwitch_0_ppcChannel&amp;algo_expid=834f15a2-3c9a-4af7-b18f-1f0dafd11be0-1&amp;algo_pvid=834f15a2-3c9a-4af7-b18f-1f0dafd11be0&amp;priceBeautifyAB=0">PCM5100A
22+
100dB Audio Stereo DAC with 32-bit, 384kHz PCM Interface</a> * &gt;<a href="https://www.aliexpress.com/store/product/Free-shipping-20PCS-TDA1543-TDA1543A-Dual-16-bit-DAC-DIP-8-NEW-GOOD-QUALITY/3632102_32854590140.html?spm=2114.search0204.3.158.423f48e8bSP6Wn&amp;ws_ab_test=searchweb0_0,searchweb201602_3_10065_10068_10546_10059_10884_10548_10887_10696_100031_10084_10083_10103_10618_10307_449,searchweb201603_60,ppcSwitch_0_ppcChannel&amp;algo_expid=5f78b67a-9a90-49eb-88fd-177f5d7b7084-24&amp;algo_pvid=5f78b67a-9a90-49eb-88fd-177f5d7b7084&amp;priceBeautifyAB=0">TDA1543A
23+
Dual 16-bit DAC I2S input format</a></p>
24+
<h2 id="i2s-mems-mic">2. <code>I2S mems MIC</code></h2>
25+
<ul>
26+
<li>
27+
<blockquote>
28+
<p><a href="https://www.alibaba.com/product-detail/MIC-MEMS-DIGITAL-I2S-26DB-SPH0645LM4H_60760425284.html">MIC
29+
MEMS DIGITAL I2S 26DB SPH0645LM4H-B SPH0645</a></p>
30+
</blockquote>
31+
</li>
32+
</ul>
33+
</body>
34+
35+
</html>

exec.sh

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
nohup nodemon SIPSERVRMQTT.js </dev/null &
2+
nohup nodemon index.js </dev/null &

include/script.js

+201-32
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,201 @@
1-
// Create a client instance
2-
var client = new Paho.MQTT.Client(location.hostname, Number(location.port), "clientId");
3-
4-
// set callback handlers
5-
client.onConnectionLost = onConnectionLost;
6-
client.onMessageArrived = onMessageArrived;
7-
8-
// connect the client
9-
client.connect({onSuccess:onConnect});
10-
11-
12-
// called when the client connects
13-
function onConnect() {
14-
// Once a connection has been made, make a subscription and send a message.
15-
console.log("onConnect");
16-
client.subscribe("World");
17-
message = new Paho.MQTT.Message("Hello");
18-
message.destinationName = "World";
19-
client.send(message);
20-
}
21-
22-
// called when the client loses its connection
23-
function onConnectionLost(responseObject) {
24-
if (responseObject.errorCode !== 0) {
25-
console.log("onConnectionLost:"+responseObject.errorMessage);
26-
}
27-
}
28-
29-
// called when a message arrives
30-
function onMessageArrived(message) {
31-
console.log("onMessageArrived:"+message.payloadString);
32-
}
1+
$(document).ready(function () {
2+
// var mqtt = require('mqtt');
3+
var connected = false;
4+
var source = null;
5+
$("#connectionSt").addClass("offline");
6+
$("#main").hide();
7+
console.log("from script.js");
8+
window.addEventListener("bufferFull", () => {
9+
console.log("buffer full");
10+
11+
});
12+
var buffull = new CustomEvent("bufferFull");
13+
// Create a client instance
14+
var client = mqtt.connect('wss://206.189.131.144:2000');
15+
// var client = mqtt.connect('mqtt://localhost:1800')
16+
function createProfile() {
17+
window.localStorage.setItem()
18+
};
19+
20+
////////////////////// canvas draw
21+
var canvas = document.getElementById("myCanvas");
22+
var canvasCtx = canvas.getContext("2d");
23+
24+
var WIDTH = canvas.width;
25+
var HEIGHT = canvas.height;
26+
canvasCtx.clearRect(0, 0, WIDTH, HEIGHT);
27+
28+
function draw(data) {
29+
drawVisual = requestAnimationFrame(draw);
30+
canvasCtx.clearRect(0, 0, WIDTH, HEIGHT);
31+
32+
33+
canvasCtx.fillStyle = 'rgb(200, 200, 200)';
34+
canvasCtx.fillRect(0, 0, WIDTH, HEIGHT);
35+
36+
canvasCtx.lineWidth = 2;
37+
canvasCtx.strokeStyle = 'rgb(0, 0, 0)';
38+
canvasCtx.beginPath();
39+
40+
var sliceWidth = WIDTH * 1.0 / data.length;
41+
// console.log("sliceWidth:\t: " + canvas.height);
42+
var x = 0;
43+
for (var i = 0; i < data.length; i++) {
44+
45+
var v = data[i] * 100;
46+
//console.log(array_time_domain[i]);
47+
var y = v + HEIGHT / 2;
48+
49+
if (i === 0) {
50+
canvasCtx.moveTo(x, y);
51+
} else {
52+
canvasCtx.lineTo(x, y);
53+
}
54+
55+
x += sliceWidth;
56+
}
57+
//console.log(array_time_domain[1]);
58+
canvasCtx.lineTo(canvas.width, canvas.height / 2);
59+
canvasCtx.stroke();
60+
61+
};
62+
/////////////////////////////////
63+
client.on('connect', function () {
64+
console.log("connected");
65+
$("#connectionSt").removeClass("offline").addClass("online");
66+
client.subscribe('/new/user/', function (err) {
67+
if (!err) {
68+
console.log("subscribed");
69+
}
70+
})
71+
// client.subscribe('jkhaiwue8r23u923y9r9wuf89y93wyr89aur/client1', function (err) {
72+
// if (!err) {
73+
// console.log("subscribed");
74+
// }
75+
// })
76+
client.subscribe('jkhaiwue8r23u923y9r9wuf89y93wyr89aur/client2', function (err) {
77+
if (!err) {
78+
console.log("subscribed\t: jkhaiwue8r23u923y9r9wuf89y93wyr89aur/client2");
79+
}
80+
})
81+
});
82+
client.on("offline", function () {
83+
$("#connectionSt").removeClass("online").addClass("offline");
84+
85+
});
86+
var AudioContext = window.AudioContext || window.webkitAudioContext;
87+
const bufferSize = 10240 * 10;
88+
var tempbuffer = [];
89+
var audioCtx = new AudioContext({
90+
latencyHint: 'interactive',
91+
sampleRate: 44100
92+
});
93+
// var audioCtx = new AudioContext({
94+
// latencyHint: 'interactive',
95+
// sampleRate: 44100,
96+
// });
97+
var myArrayBuffer = audioCtx.createBuffer(2, bufferSize, 44100);
98+
var buffoffset = 0;
99+
// Get an AudioBufferSourceNode.
100+
// This is the AudioNode to use when we want to play an AudioBuffer
101+
var resume = false;
102+
103+
client.on('message', function (topic, message) {
104+
// message is Buffer
105+
console.log(message.length);
106+
// console.log(JSON.parse(message));
107+
108+
//console.log(message);
109+
// console.log(message.offset);
110+
var uintbuf = new Uint8Array(message).buffer
111+
var float32array = new Float32Array(uintbuf, 0, message.length / 4);
112+
//console.log(float32array)
113+
draw(float32array);
114+
for (var channel = 0; channel < myArrayBuffer.numberOfChannels; channel++) {
115+
// This gives us the actual array that contains the data
116+
nowBuffering = myArrayBuffer.getChannelData(channel);
117+
118+
if (buffoffset >= bufferSize) {
119+
window.dispatchEvent(buffull);
120+
// Get an AudioBufferSourceNode.
121+
// This is the AudioNode to use when we want to play an AudioBuffer
122+
source = audioCtx.createBufferSource();
123+
// set the buffer in the AudioBufferSourceNode
124+
tempbuffer.forEach((el, index) => {
125+
126+
nowBuffering[index] = el;
127+
});
128+
source.buffer = myArrayBuffer;
129+
// connect the AudioBufferSourceNode to the
130+
// destination so we can hear the sound
131+
source.connect(audioCtx.destination);
132+
133+
// start the source playing
134+
source.start();
135+
// buffoffset = 0;
136+
buffoffset = 0;
137+
138+
}
139+
// filling the buffer with PCM data at channel nunber "value of channel"
140+
// filling the buffer with PCM data at channel nunber "value of channel"
141+
float32array.forEach((el, index) => {
142+
tempbuffer[index + buffoffset] = el;
143+
});
144+
///console.log(nowBuffering.valueOf());
145+
146+
}
147+
// incrementing the offset
148+
buffoffset += 1024;
149+
150+
151+
152+
// var uint8buffer = new Uint8Array(message).buffer;
153+
// var uint32array = new Int32Array(uint8buffer);
154+
// var float32array = Float32Array.from(uint32array, X => X / 2147483648);
155+
156+
// // Fill the buffer with white noise;
157+
// // just random values between -1.0 and 1.0
158+
// for (var channel = 0; channel < myArrayBuffer.numberOfChannels; channel++) {
159+
// // This gives us the actual array that contains the data
160+
// var nowBuffering = myArrayBuffer.getChannelData(channel);
161+
162+
163+
164+
// // filling the buffer with PCM data at channel nunber "value of channel"
165+
// float32array.forEach((el, index) => {
166+
// tempbuffer[index + buffoffset] = el;
167+
// });
168+
// if (buffoffset >= bufferSize) {
169+
// window.dispatchEvent(buffull);
170+
// // Get an AudioBufferSourceNode.
171+
// // This is the AudioNode to use when we want to play an AudioBuffer
172+
// source = audioCtx.createBufferSource();
173+
// // set the buffer in the AudioBufferSourceNode
174+
// tempbuffer.forEach((el, index) => {
175+
176+
// nowBuffering[index] = el;
177+
// });
178+
// source.buffer = myArrayBuffer;
179+
// // connect the AudioBufferSourceNode to the
180+
// // destination so we can hear the sound
181+
// source.connect(audioCtx.destination);
182+
183+
// // start the source playing
184+
// source.start();
185+
// // buffoffset = 0;
186+
// buffoffset = 0;
187+
// }
188+
// if (!resume) {
189+
190+
// resume = true;
191+
192+
// }
193+
// ///console.log(nowBuffering.valueOf());
194+
195+
// }
196+
// // incrementing the offset
197+
// buffoffset += 1024;
198+
})
199+
200+
201+
});

include/style.css

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
.online {
2+
height: 15px;
3+
width: 15px;
4+
background-color: #28a796;
5+
border-radius: 50%;
6+
display: inline-block;
7+
position: relative;
8+
left: 1px;
9+
top: -17px;
10+
border: 2px solid white;
11+
}
12+
13+
.offline {
14+
height: 15px;
15+
width: 15px;
16+
background-color: #bbb;
17+
border-radius: 50%;
18+
display: inline-block;
19+
position: relative;
20+
left: 1px;
21+
top: -17px;
22+
border: 2px solid white
23+
}

0 commit comments

Comments
 (0)