概要
paiza.ioでelixirやってみた。
練習問題やってみた。
練習問題
sin波を、FM変調して、FM復調して、元に戻せ。
ソースは、1000Hzの正弦波。
搬送波は、20000Hz
サンプリングレートは、300000
サンプルコード
defmodule Vd do
use Agent
def start_link() do
Agent.start_link(fn ->
0
end, name: __MODULE__)
end
def get() do
Agent.get(__MODULE__, fn v ->
v
end)
end
def cls() do
Agent.update(__MODULE__, fn v ->
0
end)
end
def set() do
Agent.update(__MODULE__, fn v ->
1
end)
end
end
defmodule Vc do
use Agent
def start_link() do
Agent.start_link(fn ->
0
end, name: __MODULE__)
end
def get() do
Agent.get(__MODULE__, fn v ->
v
end)
end
def cls() do
Agent.update(__MODULE__, fn v ->
0
end)
end
def add(o) do
Agent.update(__MODULE__, fn v ->
v + o
end)
end
end
defmodule Ve do
use Agent
def start_link() do
Agent.start_link(fn ->
0
end, name: __MODULE__)
end
def get() do
Agent.get(__MODULE__, fn v ->
v
end)
end
def cls() do
Agent.update(__MODULE__, fn v ->
0
end)
end
def put(o) do
Agent.update(__MODULE__, fn v ->
o
end)
end
end
defmodule Main do
def vin(v) do
v
|> Enum.with_index()
|> Enum.map(fn {x, t} ->
:math.sin(t / 300000 * 2 * :math.pi * 1000);
end)
end
def vfm(v) do
v
|> Enum.with_index()
|> Enum.map(fn {x, t} ->
:math.sin(t / 300000 * 2 * :math.pi * 20000 + 6 * :math.cos(t / 300000 * 2 * :math.pi * 1000));
end)
end
def main do
Vd.start_link
Vc.start_link
Ve.start_link
IO.puts """
<html><head></head><body>
<canvas id="canvas" width="400" height="400"></canvas>
<script type="text/javascript">
var canvas = document.getElementById("canvas");
var ctx = canvas.getContext("2d");
function draw(data, n) {
var hcenter = n * 100 + 50;
ctx.strokeStyle = "#f0f";
ctx.lineWidth = 2;
ctx.moveTo(0, hcenter);
for (var i = 1; i < canvas.width; i++)
{
ctx.lineTo(i, data[i] * 15 + hcenter);
}
ctx.stroke();
}
var src = [
"""
src = List.duplicate(0, 300)
src = vin(src)
Enum.map(src, fn x ->
IO.write(x)
IO.write(",")
end)
IO.puts """
];
var dst = [
"""
dis = List.duplicate(0, 300)
dis = vfm(dis)
Enum.map(dis, fn x ->
IO.write(x)
IO.write(",")
end)
IO.puts """
];
var dec = [
"""
dc = 0.4
for n <- 0..299 do
cond do
(Enum.at(dis, n) < 0 && Vd.get == 1) ->
Vc.add(dc)
v = Ve.get - dc;
v
(Enum.at(dis, n) > 0 && Vd.get == 1) ->
Vd.cls
v = Vc.get - dc;
Ve.put(Vc.get)
Vc.cls
v
(Enum.at(dis, n) < 0 && Vd.get == 0) ->
Vd.set
v = Vc.get - dc;
Ve.put(Vc.get)
Vc.cls
v
(Enum.at(dis, n) > 0 && Vd.get == 0) ->
Vc.add(dc)
v = Ve.get - dc;
v
end
|> IO.write
IO.write(",")
end
IO.puts """
];
draw(src, 0);
draw(dst, 1);
draw(dec, 2);
</script></body></html>
"""
end
end
Main.main
実行結果
成果物
以上。