Pythonで、モールス符号の復号(2)

$ ~/anaconda3/bin/python test4.py ~/40wpm.wav 0 -1
 
<BT> 
NOW 
40 
WPM 
<BT> 
TEXT 
IS 
FROM 
JANUARY 
2014 
QST 
PAGE 
46
<BT> 
SETTING 
THE 
VFO. 
WITH 
THE 
TRANSMITTER 
OUTPUT 
CONNECTED 
TO 
A 
DUMMY 
LOAD, 
SET 
THE 
VFO 
TO 
THE 
CORRECT 
FREQUENCY 
FOR 
THE 
BAND 
OF 
INTEREST.
import sys
import numpy as np
import matplotlib.pyplot as plt
import soundfile as sf
from scipy.signal import hilbert

morse ={
	"" : "",
	"A" : ".-",
	"B" : "-...",
	"C" : "-.-.",
	"D" : "-..",
	"E" : ".",
	"F" : "..-.",
	"G" : "--.",
	"H" : "....",
	"I" : "..",
	"J" : ".---",
	"K" : "-.-",
	"L" : ".-..",
	"M" : "--",
	"N" : "-.",
	"O" : "---",
	"P" : ".--.",
	"Q" : "--.-",
	"R" : ".-.",
	"S" : "...",
	"T" : "-",
	"U" : "..-",
	"V" : "...-",
	"W" : ".--",
	"X" : "-..-",
	"Y" : "-.--",
	"Z" : "--..",
	"1" : ".----",
	"2" : "..---",
	"3" : "...--",
	"4" : "....-",
	"5" : ".....",
	"6" : "-....",
	"7" : "--...",
	"8" : "---..",
	"9" : "----.",
	"0" : "-----",
	"." : ".-.-.-",
	"," : "--..--",
	":" : "---...",
	"?" : "..--..",
	"'" : ".----.",
	"-" : "-....-",
	"/" : "-..-.",
	"@" : ".--.-.",
	"<BT>" : "-...-"
}

morse_inv = dict((v,k) for (k,v) in morse.items())

filename = sys.argv[1]
nstart   = int(sys.argv[2])
nframes  = int(sys.argv[3])

wav, fs  = sf.read(filename,start=nstart,frames=nframes)
analytic_signal = hilbert(wav)
env = np.abs(analytic_signal)

th = 0.5*max(env)
env[env<th] = 0
env[env!=0] = 1

t_up = 0
t_down = 0
up = []
down = []
string = ''
t_ws = 5000
t_ls = 2500
t_dd = 2500

for t in range(1, len(env-1)):
	if env[t-1] == 0 and env[t] == 1:
		t_up = t
		t_down_duration = t - t_down
		down.append(t_down_duration)
		if t_down_duration > t_ls:
			print(morse_inv[string], end='')
			string = ''
		if t_down_duration > t_ws:
			print(' ')
	if env[t-1] == 1 and env[t] == 0:
		t_down = t
		t_up_duration = t - t_up
		up.append(t_up_duration)
		if t_up_duration < t_dd:
			string = string + '.'
		else:
			string = string + '-'

print('')

Pythonで、モールス符号の復号

$ ~/anaconda3/bin/python test4.py ~/40wpm.wav 0 500000

-...-
-. --- .--
....- -----
.-- .--. --
-...-
- . -..- -
.. ...
..-. .-. --- --
.--- .- -. ..- .- .-. -.--

$

import sys
import numpy as np
import matplotlib.pyplot as plt
import soundfile as sf
from scipy.signal import hilbert

filename = sys.argv[1]
nstart   = int(sys.argv[2])
nframes  = int(sys.argv[3])

wav, fs  = sf.read(filename,start=nstart,frames=nframes)
analytic_signal = hilbert(wav)
env = np.abs(analytic_signal)

th = 0.5*max(env)
env[env<th] = 0
env[env!=0] = 1

t_up = 0
t_down = 0
up = []
down = []
string = ''
t_ws = 5000
t_ls = 2500
t_dd = 2500

for t in range(1, len(env-1)):
	if env[t-1] == 0 and env[t] == 1:
		t_up = t
		t_down_duration = t - t_down
		down.append(t_down_duration)
		if t_down_duration > t_ws:
			print(string)
			string = ''
		elif t_down_duration > t_ls:
			string = string + ' '
	if env[t-1] == 1 and env[t] == 0:
		t_down = t
		t_up_duration = t - t_up
		up.append(t_up_duration)
		if t_up_duration < t_dd:
			string = string + '.'
		else:
			string = string + '-'

print('')

PythonとSciPy(2)

包絡線さえ得てしまえば、短点/長点の継続時間のヒストグラムを描くことは容易です。

import sys
import numpy as np
import matplotlib.pyplot as plt
import soundfile as sf
from scipy.signal import hilbert

filename = sys.argv[1]
nstart   = int(sys.argv[2])
nframes  = int(sys.argv[3])

wav, fs  = sf.read(filename,start=nstart,frames=nframes)
analytic_signal = hilbert(wav)
env = np.abs(analytic_signal)

th = 0.5*max(env)
env[env<th] = 0
env[env!=0] = 1

t_up = 0
t_down = 0
up = []
down = []

for t in range(1, len(env-1)):
	if env[t-1] == 0 and env[t] == 1:
		t_up = t
		t_down_duration = t - t_down
		down.append(t_down_duration)
	if env[t-1] == 1 and env[t] == 0:
		t_down = t
		t_up_duration = t - t_up
		up.append(t_up_duration)

plt.figure(1)

plt.subplot(221)
plt.plot(wav, color='green')
plt.title("input signal")

plt.subplot(222)
plt.plot(env, color='red')
plt.title("binary signal")


plt.subplot(223)
plt.hist(up, bins=50, color="orange")
plt.title("Dot/Dash Histogram")
plt.grid(True)

plt.subplot(224)
plt.hist(down, bins=50, color="blue")
plt.title("Spaces Histogram")
plt.grid(True)

plt.subplots_adjust(hspace=0.5, wspace=0.35)
plt.show()

PythonとSciPy

信号の包絡線は、解析信号の振幅より得ることができます。

import sys
import numpy as np
import matplotlib.pyplot as plt
import soundfile as sf
from scipy.signal import hilbert

filename = sys.argv[1]
nstart   = int(sys.argv[2])
nframes  = int(sys.argv[3])

wav, fs  = sf.read(filename,start=nstart,frames=nframes)
analytic_signal = hilbert(wav)
env = np.abs(analytic_signal)

plt.plot(wav, color='green')
plt.plot(env, color='red')
plt.title("input signal")
plt.xlabel("time")
plt.ylabel("amplitude")

plt.show()

私の以前の記事、Analytic Signals (2)では、同じことをC言語を用いて行っていました。

PythonとPySoundFile

サウンドファイルから波形を表示する短いPythonプログラムです。

import sys
import numpy as np
import matplotlib.pyplot as plt
import soundfile as sf

filename = sys.argv[1]
nsbegin  = int(sys.argv[2])
nsend    = int(sys.argv[3])

wav, fs  = sf.read(filename)

plt.plot(wav[nsbegin:nsend], color='green')
plt.title("input signal")
plt.xlabel("time")
plt.ylabel("amplitude")

plt.show()

Anacondaディストリビューション

$ which python
/opt/local/bin/python

$ python --version
Python 2.7.14

$ which curl
/opt/local/bin/curl

$ curl --version
curl 7.57.0 (x86_64-apple-darwin17.3.0) libcurl/7.57.0 OpenSSL/1.0.2n zlib/1.2.11 libidn2/2.0.4 libpsl/0.19.1 (+libidn2/2.0.4)
Release-Date: 2017-11-29

$ ./anaconda3/bin/python
Python 3.6.4 |Anaconda, Inc.| (default, Jan 16 2018, 12:04:33) 
[GCC 4.2.1 Compatible Clang 4.0.1 (tags/RELEASE_401/final)] on darwin

$ ./anaconda3/bin/curl --version
curl 7.58.0 (x86_64-apple-darwin13.4.0) libcurl/7.58.0 OpenSSL/1.0.2n zlib/1.2.11
Release-Date: 2018-01-24

KiCadとWebGL

あなたは、ボードをマウスで動かすことができます。

私が本当に表示させたいのは、パーツを搭載したボードです。

STLファイルと、 WebGL

あなたは、物体をあなたのマウスで動かすことができます。

画像の中を左クリックして、押し下げたまま、マウスを動かして下さい。他の制御も可能です。

<script src="/js/three.js-dev/build/three.js"></script>
<script src="/js/three.js-dev/examples/js/loaders/STLLoader.js"></script>

<script>
        var loader = new THREE.STLLoader();
        loader.load( 'SMA.stl', function ( geometry ) {
                var material = new THREE.MeshLambertMaterial( { ambient: 0xff5533, color: 0x8f55f3} );
                mesh = new THREE.Mesh( geometry, material );
                APP.scene.add( mesh );
                APP.controls = new THREE.TrackballControls( APP.camera );
                APP.animate();
        });

KiCadと3次元モデル(6)

// dimensions in 0.1mm
l=63;
r1=23/2;
r2=6/2;
h2h=8*(50/1000)*25.4*10; echo(h2h);
ll=(h2h-l)/2; echo(ll);

module pin() {
translate([0,0,-r1]) rotate([0,0,0]) cylinder(r=r2,h=r1*3-5, $fn=16); // vertical
translate([0,-5,r1*2]) rotate([90,0,0]) cylinder(r=r2,h=ll-5, $fn=16); // horizozntal
translate([0,-5,r1*2-5]) rotate([0,-90,0]) 
rotate_extrude(angle=90, convexity=10) translate([5, 0]) circle(r2, $fn=16);
}

translate([0,l/2,r1*2]) rotate([90,0,0]) cylinder(r=r1,h=l, $fn=16); // body
translate([0,  h2h/2, 0]) pin();
translate([0, -h2h/2, 0]) rotate([0,0,180]) pin();