radio 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,39 @@
1
+ # Copyright 2012 The ham21/radio Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ class Radio
17
+
18
+ PI = Math::PI.freeze
19
+ PI2 = (8.0 * Math.atan(1.0)).freeze
20
+
21
+ module Utils
22
+
23
+ def kaiser_estimate options
24
+ ripple = options[:passband].to_f * options[:stopband]
25
+ numer = -20.0 * Math.log10(ripple) - 13
26
+ denum = 14.6 * options[:transition]
27
+ taps = (numer/denum).round
28
+ type = options[:type] || :odd
29
+ if type == :even
30
+ taps +=1 if taps.odd?
31
+ else
32
+ taps +=1 if taps.even?
33
+ end
34
+ taps
35
+ end
36
+ module_function :kaiser_estimate
37
+
38
+ end
39
+ end
@@ -0,0 +1,37 @@
1
+ # Copyright 2012 The ham21/radio Authors
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+
16
+ class Radio
17
+
18
+ module Utils
19
+
20
+ def hamming_window! array, width = nil
21
+ n = -1
22
+ width ||= array.size
23
+ w = width - 1
24
+ array.collect! do |v|
25
+ n += 1
26
+ 0.54 - 0.46 * Math.cos((PI2 * n) / w)
27
+ end
28
+ end
29
+ module_function :hamming_window!
30
+
31
+ def hamming_window array, w = nil
32
+ hamming_window! array.dup
33
+ end
34
+ module_function :hamming_window
35
+
36
+ end
37
+ end
@@ -1,3 +1,3 @@
1
1
  class Radio
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
@@ -1,29 +1,98 @@
1
- <% if !$rig; response.redirect 'setup/input'; else
1
+ <% if !$rig; response.redirect 'setup/rx'; else
2
2
  -%><!DOCTYPE html>
3
3
  <html>
4
4
  <head>
5
5
  <style type="text/css" media="screen">
6
- body{font:13px/1.231 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}
6
+ body{font:13px/1.231 arial,helvetica,clean,sans-serif;
7
+ *font-size:small;*font:x-small;background:#fff}
7
8
  select,input,button,textarea,button{font:99% arial,helvetica,clean,sans-serif;}
8
9
  img{display:block}
9
- #waterfall{height: 75px; width: 95%; overflow-x:scroll; overflow-y: hidden; background:#000}
10
+ #waterfallxx{height: 75px; width: 95%; overflow-x:scroll; overflow-y: hidden; background:#000}
11
+ #main{
12
+ background:#D36B01;
13
+ color:#fff;
14
+ width:940px;
15
+ margin:auto;
16
+ -moz-border-radius: 10px;
17
+ border-radius: 10px;
18
+ padding: 3px 10px 10px 10px;
19
+ }
20
+ #title {
21
+ font-size:36px;
22
+ font-weight:bold;
23
+ text-align:center;
24
+ }
25
+ #main a:link, #title a:visited, #title a:link, #title a:link {
26
+ text-decoration:none; color:#fff
27
+ }
28
+ #waterfall{
29
+ }
30
+ #output{
31
+ background:#fcfcfc;
32
+ color:#000;
33
+ height:400px;
34
+ overflow-x: hidden;
35
+ overflow-y: scroll;
36
+ }
37
+ #marker{
38
+ position:absolute;
39
+ left:-10px;
40
+ top:20px;
41
+ z-index:5;
42
+ background:#13D205;
43
+ width:10px;
44
+ height:10px;
45
+ -moz-border-radius: 10px;
46
+ border-radius: 10px;
47
+ }
48
+ #wrap{
49
+ position:relative;
50
+ height: 100px;
51
+ width: 940px;
52
+ overflow-x: scroll;
53
+ overflow-y: hidden;
54
+ background:#000
55
+ }
10
56
  </style>
11
57
  <script src='jquery-1.7.js'></script>
12
58
  </head>
13
59
  <body>
60
+ <div id="main">
61
+ <div id="title">
62
+ <a href="https://www.github.com/ham21/radio" target="_blank">
63
+ The Twenty-First Century Amateur Radio Project
64
+ </a>
65
+ </div>
66
+
67
+ <div id="wrap">
68
+ <div id="marker"></div>
69
+ <div id="waterfall"></div>
70
+ </div>
71
+
72
+ <div style="float:right;">
73
+ <%= render 'ssb' %>
74
+ </div>
75
+ <%= render 'lo' %>
76
+
77
+ <div id="output">
78
+ </div>
14
79
 
15
- <h2>
16
- <a href="https://github.com/ham21/radio">Ham21</a>
17
- - The Twenty-First Century Amateur Radio Project
18
- </h2>
19
- <p>SETUP: <a href="setup/input">Input</a> | <a href="setup/lo">LO</a></p>
20
-
21
- <%= render 'lo' %>
22
-
23
- <div id="waterfall">
24
80
  </div>
81
+
82
+ <p style="text-align:center">
83
+ SETUP: <a href="setup/rx">RX</a> | <a href="setup/af">AF</a> | <a href="setup/lo">LO</a>
84
+ </p>
85
+
25
86
 
26
87
  <script type="text/javascript" charset="utf-8">
88
+ $("#waterfall").mousedown(function(event) {
89
+ console.log(event);
90
+ pos = event.offsetX / $("#waterfall").children()[1].width
91
+ $.post( 'tune', { pos: pos });
92
+ $("#marker")[0].style.left = '' + (event.offsetX - 5) + 'px';
93
+ });
94
+
95
+
27
96
  var waterfallSeqNo = 0;
28
97
  function nextWaterfall() {
29
98
  $('#waterfall').prepend('<img src="waterfall?' + waterfallSeqNo + '" alt="" onload="nextWaterfall()"></img>');
data/www/lo.erb CHANGED
@@ -4,7 +4,7 @@
4
4
  @response.headers['Content-Type'] = 'text/plain'
5
5
  end -%>
6
6
  <form action="lo" id="freqForm">
7
- <input type="text" name="freq" value="<%= $rig.lo %>" %>
7
+ <input type="text" name="freq" value="<%= $rig.lo %>" %> MHz
8
8
  </form>
9
9
  <script type="text/javascript">
10
10
  $("#freqForm").submit(function(event) {
@@ -17,5 +17,5 @@ end -%>
17
17
  $form.find( 'input[name="freq"]' ).val(data)
18
18
  }
19
19
  );
20
- });
20
+ });
21
21
  </script>
@@ -0,0 +1,72 @@
1
+ <%
2
+ if params['doit']
3
+ if params['type'] == 'none'
4
+ $rig.af = nil
5
+ else
6
+ $rig.af = Radio::Signal.new type:params['type'], id:params['id'], rate:params['rate'].to_i, output:true
7
+ end
8
+ response.redirect '/'
9
+ elsif params['type']
10
+ %>
11
+ <!DOCTYPE html>
12
+ <html>
13
+ <head>
14
+ <meta http-equiv="refresh" content="0; <%=h '?doit=1&' + query_string %>">
15
+ </head>
16
+ <body>
17
+ <p><strong>Stand by, generating coefficients and compiling filter.</strong></p>
18
+ This may take many minutes.<br />
19
+ Results are cached in: <%=h Radio::Utils::FIRPM_CACHE_FILENAME %>
20
+ </body>
21
+ </html>
22
+ <% else -%>
23
+ <!DOCTYPE html>
24
+ <html>
25
+ <head>
26
+ <style type="text/css" media="screen">
27
+ body{font:13px/1.231 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small;}
28
+ select,input,button,textarea,button{font:99% arial,helvetica,clean,sans-serif;}
29
+ </style>
30
+ </head>
31
+ <body>
32
+
33
+ <h2>Audio Output Sources</h2>
34
+ <% if (input_sources = Radio::Signal.devices.delete_if{|k,v|v[:output]==0}).empty? -%>
35
+ No input sources found.
36
+ <% else -%>
37
+ <dl>
38
+ <form action='?' method="get">
39
+ <dt>
40
+ <input type="submit" value="Select"%>
41
+ <input type="hidden" name="type" value="none" %>
42
+ No output: stop processing audio
43
+ </dt>
44
+ </form>
45
+ <% input_sources.each do |k, opts| -%>
46
+ <form action='?' method="get">
47
+ <% input_type, input_id = k -%>
48
+ <dt>
49
+ <input type="submit" value="Select"%>
50
+ <input type="hidden" name="type" value="<%=h input_type %>" %>
51
+ <input type="hidden" name="id" value="<%=h input_id %>" %>
52
+ <%=h input_type %>: <%=h opts[:name] %>
53
+ </dt>
54
+ <dd>
55
+ <% opts[:rates].reverse.each_with_index do |rate, index| %>
56
+ <input type="radio" name="rate" value="<%=h rate %>" <%= "checked=checked" if index==0 %> /><%=h rate %>
57
+ <% end -%>
58
+ </dd>
59
+ </form>
60
+ <br />
61
+ <% end -%>
62
+ </dl>
63
+ <% end -%>
64
+
65
+ <h2>Driver Status</h2>
66
+ <% Radio::Signal.status.each do |k, v| -%>
67
+ <%=h k %>: <%=h v %> <br />
68
+ <% end -%>
69
+
70
+ </body>
71
+ </html>
72
+ <% end -%>
@@ -2,6 +2,13 @@
2
2
  if post?
3
3
  $rig.lo = case params['type']
4
4
  when 'softrock' then Radio::Controls::Si570AVR.new
5
+ when 'civ'
6
+ Radio::Controls::CIV.new({
7
+ port:params['port'],
8
+ baud:params['baud'],
9
+ host:params['host'],
10
+ device:params['device'],
11
+ })
5
12
  else Radio::Controls::Null.new
6
13
  end
7
14
  response.redirect '/'
@@ -30,6 +37,30 @@ unless response.redirection? -%>
30
37
  SoftRock Si570 (DG8SAQ/PE0FKO)
31
38
  </form>
32
39
  <br />
40
+ <form action='?' method="post">
41
+ <input type="submit" value="Select"%>
42
+ <input type="hidden" name="type" value="civ" %>
43
+ Icom CI-V (supports CT-17 and RS-422 multi-drop)
44
+ <br/>
45
+ Port:
46
+ <select name="port">
47
+ <% 0.upto(7) do |num| -%>
48
+ <option value="<%=h num %>"><%=h num %></option>
49
+ <% end -%>
50
+ </select>
51
+ Baud:
52
+ <select name="baud">
53
+ <% [300,1200,9600,19200].each do |num| -%>
54
+ <option value="<%=h num %>" <%= 'selected="selected"' if num==1200 %>><%=h num %></option>
55
+ <% end -%>
56
+ </select>
57
+ Host:
58
+ <input type="text" name="host" value="224"%>
59
+ Device:
60
+ <input type="text" name="device" value="80" %>
61
+
62
+ </form>
63
+ <br />
33
64
 
34
65
  </body>
35
66
  </html>
@@ -1,12 +1,13 @@
1
1
  <%
2
2
  if post?
3
3
  $rig ||= Radio::Rig.new
4
- channel_i, channel_q = case params['channel']
4
+ device = case params['channel']
5
5
  when 'iq' then [0,1]
6
6
  when 'qi' then [1,0]
7
- else [0,nil]
7
+ else 0
8
8
  end
9
- $rig.rx = Radio::Input.new params['type'], params['id'], params['rate'].to_i, channel_i, channel_q
9
+ $rig.af = nil
10
+ $rig.rx = Radio::Signal.new type:params['type'], id:params['id'], rate:params['rate'].to_i, input:device
10
11
  response.redirect '/'
11
12
  end
12
13
  unless response.redirection? -%>
@@ -20,8 +21,8 @@ unless response.redirection? -%>
20
21
  </head>
21
22
  <body>
22
23
 
23
- <h2>Input Sources</h2>
24
- <% if (input_sources = Radio::Input.sources).empty? -%>
24
+ <h2>Radio Input Sources</h2>
25
+ <% if (input_sources = Radio::Signal.devices.delete_if{|k,v|v[:input]==0}).empty? -%>
25
26
  No input sources found.
26
27
  <% else -%>
27
28
  <dl>
@@ -40,12 +41,12 @@ unless response.redirection? -%>
40
41
  <% end -%>
41
42
  </dd>
42
43
  <dd>
43
- <% if opts[:channels] == 1 or input_type != :File %>
44
+ <% if opts[:input] == 1 or input_type != :File %>
44
45
  <input type="radio" name="channel" value="i" checked="checked" />LPCM
45
46
  <% end -%>
46
- <% if opts[:channels] == 2 %>
47
- <input type="radio" name="channel" value="iq" />I/Q
48
- <input type="radio" name="channel" value="qi" checked="checked" />Q/I
47
+ <% if opts[:input] == 2 %>
48
+ <input type="radio" name="channel" value="iq" checked="checked" />I/Q
49
+ <input type="radio" name="channel" value="qi" />Q/I
49
50
  <% end -%>
50
51
  </dd>
51
52
  </form>
@@ -55,7 +56,7 @@ unless response.redirection? -%>
55
56
  <% end -%>
56
57
 
57
58
  <h2>Driver Status</h2>
58
- <% Radio::Input.status.each do |k, v| -%>
59
+ <% Radio::Signal.status.each do |k, v| -%>
59
60
  <%=h k %>: <%=h v %> <br />
60
61
  <% end -%>
61
62
 
@@ -0,0 +1,20 @@
1
+ <% if xhr?
2
+ if params['ssb'] == 'lsb'
3
+ $rig.set_lsb
4
+ else
5
+ $rig.set_usb
6
+ end
7
+ end -%>
8
+ <form action="ssb" id="ssbForm">
9
+ <input type="radio" name="ssb" value="lsb" %> LSB
10
+ <input type="radio" name="ssb" value="usb" %> USB
11
+ </form>
12
+ <script type="text/javascript">
13
+ $("#ssbForm input").change(function(event) {
14
+ event.preventDefault();
15
+ var $form = $( this ),
16
+ term = $form.val(),
17
+ url = $form.attr( 'action' );
18
+ $.post( url, { ssb: term });
19
+ });
20
+ </script>
@@ -0,0 +1,5 @@
1
+ <%
2
+ i = params['pos'].to_f
3
+ i -= 0.5 if $rig.iq?
4
+ $rig.tune = -i * $rig.rate
5
+ %>
@@ -14,7 +14,7 @@ when $rig.rate <= 48000 then $rig.spectrum 2048, 2.0
14
14
  when $rig.rate <= 96000 then $rig.spectrum 2048, 4.0
15
15
  else $rig.spectrum 2048, 8.0
16
16
  end
17
- @response.body = [Radio::Gif.waterfall($waterfall_gradient, [spectrum])]
17
+ @response.body = [Radio::Gif.waterfall($waterfall_gradient, spectrum.reshape(spectrum.size,1))]
18
18
  @response.headers['Content-Type'] = 'image/gif'
19
19
  @response.headers["Cache-Control"] = 'max-age=0, private, must-revalidate'
20
20
  %>
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: radio
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-02-14 00:00:00.000000000Z
12
+ date: 2012-05-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: fftw3
16
- requirement: &2198866920 !ruby/object:Gem::Requirement
16
+ requirement: &70250569804720 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *2198866920
24
+ version_requirements: *70250569804720
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: thin
27
- requirement: &2198866220 !ruby/object:Gem::Requirement
27
+ requirement: &70250569803780 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :runtime
34
34
  prerelease: false
35
- version_requirements: *2198866220
35
+ version_requirements: *70250569803780
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: libusb
38
- requirement: &2198865360 !ruby/object:Gem::Requirement
38
+ requirement: &70250569802740 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,7 +43,18 @@ dependencies:
43
43
  version: '0'
44
44
  type: :runtime
45
45
  prerelease: false
46
- version_requirements: *2198865360
46
+ version_requirements: *70250569802740
47
+ - !ruby/object:Gem::Dependency
48
+ name: serialport
49
+ requirement: &70250569801620 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :runtime
56
+ prerelease: false
57
+ version_requirements: *70250569801620
47
58
  description:
48
59
  email:
49
60
  - dturnbull@gmail.com
@@ -53,43 +64,49 @@ extensions: []
53
64
  extra_rdoc_files: []
54
65
  files:
55
66
  - bin/radio-server
67
+ - lib/radio/controls/civ.rb
56
68
  - lib/radio/controls/null.rb
57
69
  - lib/radio/controls/si570avr.rb
58
70
  - lib/radio/filter.rb
71
+ - lib/radio/filters/agc.rb
59
72
  - lib/radio/filters/fir.rb
73
+ - lib/radio/filters/iq.rb
60
74
  - lib/radio/gif.rb
61
75
  - lib/radio/http/file.rb
62
76
  - lib/radio/http/script.rb
63
77
  - lib/radio/http/server.rb
64
78
  - lib/radio/http/session.rb
65
- - lib/radio/input.rb
66
- - lib/radio/inputs/alsa.rb
67
- - lib/radio/inputs/coreaudio.rb
68
- - lib/radio/inputs/file.rb
69
- - lib/radio/inputs/wav.rb
70
79
  - lib/radio/psk31/bit_detect.rb
71
80
  - lib/radio/psk31/decoder.rb
72
- - lib/radio/psk31/fir_coef.rb
73
81
  - lib/radio/psk31/rx.rb
74
82
  - lib/radio/psk31/varicode.rb
75
83
  - lib/radio/rig/lo.rb
76
84
  - lib/radio/rig/rx.rb
77
85
  - lib/radio/rig/spectrum.rb
86
+ - lib/radio/rig/ssb.rb
87
+ - lib/radio/rig/ssb.rb_
78
88
  - lib/radio/rig.rb
89
+ - lib/radio/signal.rb
90
+ - lib/radio/signals/alsa.rb
91
+ - lib/radio/signals/coreaudio.rb
92
+ - lib/radio/signals/file.rb
93
+ - lib/radio/signals/wav.rb
94
+ - lib/radio/utils/firpm.rb
95
+ - lib/radio/utils/misc.rb
96
+ - lib/radio/utils/window.rb
79
97
  - lib/radio/version.rb
80
98
  - lib/radio.rb
81
99
  - www/index.erb
82
100
  - www/jquery-1.7.js
83
101
  - www/lo.erb
84
- - www/setup/input.erb
102
+ - www/setup/af.erb
85
103
  - www/setup/lo.erb
104
+ - www/setup/rx.erb
105
+ - www/ssb.erb
106
+ - www/tune.erb
86
107
  - www/waterfall.erb
87
108
  - README.md
88
109
  - LICENSE
89
- - test/test.rb
90
- - test/wav/bpsk8k.wav
91
- - test/wav/qpsk8k.wav
92
- - test/wav/ssb.wav
93
110
  homepage: https://github.com/ham21/radio
94
111
  licenses: []
95
112
  post_install_message:
@@ -110,13 +127,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
110
127
  version: '0'
111
128
  requirements: []
112
129
  rubyforge_project:
113
- rubygems_version: 1.8.10
130
+ rubygems_version: 1.8.15
114
131
  signing_key:
115
132
  specification_version: 3
116
133
  summary: The Twenty-First Century Amateur Radio Project
117
- test_files:
118
- - test/test.rb
119
- - test/wav/bpsk8k.wav
120
- - test/wav/qpsk8k.wav
121
- - test/wav/ssb.wav
122
- has_rdoc:
134
+ test_files: []