概要
受信プログラムは、直交復調のアルゴリズム。
R、puredata、pythonで実験した。
実際には、javascriptで書いて、jsdoに置いた。
直交復調
信号に、sin波とcos波を乗算して、ローパスフィルターを通して、自乗の和の平方根をとる。
写真
実験
R
R
puredata
puredata
python
python
サンプルコード
sin波、cos波は、5000hz。
ローパスフィルターは、1500hz。
サンプリング周波数は、48000。
ゲインは、5
DC補正は、-1.0
var ws = new WebSocket('ws://ohijs0.paas.jp-e1.cloudn-service.com/sdr');
var ac = new (window.AudioContext || window.webkitAudioContext);
function lpf(input, samplerate, freq) {
var q = 1.0;
var omega = 2.0 * 3.14159265 * freq / samplerate;
var alpha = Math.sin(omega) / (2.0 * q);
var a0 = 1.0 + alpha;
var a1 = -2.0 * Math.cos(omega);
var a2 = 1.0 - alpha;
var b0 = (1.0 - Math.cos(omega)) / 2.0;
var b1 = 1.0 - Math.cos(omega);
var b2 = (1.0 - Math.cos(omega)) / 2.0;
var size = input.length;
var output = new Float32Array(size);
var in1 = 0;
var in2 = 0;
var out1 = 0;
var out2 = 0;
for (var i = 0; i < size; i++)
{
output[i] = b0 / a0 * input[i] + b1 / a0 * in1 + b2 / a0 * in2 - a1 / a0 * out1 - a2 / a0 * out2;
in2 = in1;
in1 = input[i];
out2 = out1;
out1 = output[i];
}
return output;
}
var initial_delay_sec = 0;
var scheduled_time = 0;
function playAudioStream(vam) {
var audio_buf = ac.createBuffer(1, vam.length, ac.sampleRate);
var audio_src = ac.createBufferSource();
var current_time = ac.currentTime;
var t;
var I = new Float32Array(vam.length);
var Q = new Float32Array(vam.length);
var I2;
var Q2;
var o = new Float32Array(vam.length);
for (t = 0; t < vam.length; t++)
{
I[t] = vam[t] * Math.cos(t / 48000 * 2 * Math.PI * 5000);
Q[t] = vam[t] * Math.sin(t / 48000 * 2 * Math.PI * 5000);
}
I2 = lpf(I, 48000, 1500);
Q2 = lpf(Q, 48000, 1500);
for (t = 0; t < vam.length; t++)
{
o[t] = Math.sqrt(I2[t] * I2[t] + Q2[t] * Q2[t]) * 5 - 1.0;
}
audio_buf.getChannelData(0).set(o);
audio_src.buffer = audio_buf;
audio_src.connect(ac.destination);
if (current_time < scheduled_time)
{
audio_src.start(scheduled_time);
scheduled_time += audio_buf.duration;
}
else
{
audio_src.start(current_time);
scheduled_time = current_time + audio_buf.duration + initial_delay_sec;
}
}
ws.binaryType = 'arraybuffer';
ws.onopen = function() {
};
ws.onerror = function(e) {
alert(String(e));
};
ws.onmessage = function(evt) {
if (evt.data.constructor !== ArrayBuffer) throw 'expecting ArrayBuffer';
playAudioStream(new Float32Array(evt.data));
};