cw 0.3.1 → 0.3.2

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6f9afa759907fb0e7b21040a2ded39c2f63afa1c
4
- data.tar.gz: 80e9d68f993ec46c96c4ca791f8a9330b24ce110
3
+ metadata.gz: bb7266c839627f6135e9adf8e83b3e59f5112177
4
+ data.tar.gz: b0da0ee8068f18450a1fedfee2e0b0df2d3b4053
5
5
  SHA512:
6
- metadata.gz: 7a46e8ee242b6b3d6e1c1dd603dd7afae2e945debdc32cd3eb9e9c5256ab4260c7690fbcbe34bd582f269444eed110977c2dc210521574fc5b3f55e1e1e0e5b4
7
- data.tar.gz: f4adad501d5e1a397eceeb966a2339af495bc49c5a60565d11da97e40924c99c195336ed050d84ced79c1ae6385100f1a22c2ac60e89a69321fa289b2d0a9e53
6
+ metadata.gz: edadbf29105e8f07f58d899b9446bcd7e23dd0d70e9c9f455b4b93182ed21418a0dda8a813651f2461e493a2e9b4ac55240e20710de157de1582778761de16a3
7
+ data.tar.gz: f1ec5443a2fd3a574460318171438d77511a4450f273f44d03b8f9674c26b38b01b30dfed56dff53c84dc7a06d4cb3dc7cdfebeccfc089885727e17f6901309c
data/.cw_config CHANGED
@@ -4,6 +4,9 @@ volume = 1
4
4
  success_colour = green
5
5
  fail_colour = red
6
6
  list_colour = default
7
+ tx_colour = red
8
+ rx_colour = blue
9
+ menu_colour = default
7
10
  ebook2cw_path = /usr/bin/ebook2cw
8
11
  run_default = test_letters
9
- word_count = 16
12
+ word_count = 9999
data/.gitignore CHANGED
@@ -42,3 +42,5 @@ audio/audio_output.wav
42
42
  /.yardoc/
43
43
  /.yardoc/
44
44
  /.cw/
45
+ /dev/
46
+ /.ruby-version
data/Gemfile CHANGED
@@ -1,4 +1,10 @@
1
1
  # CW Gemfile
2
2
 
3
3
  source "https://rubygems.org"
4
+
5
+ require 'rbconfig'
6
+
7
+ if RbConfig::CONFIG['target_os'].include?('darwin')
8
+ gem 'coreaudio', '~> 0.0.11'
9
+ end
4
10
  gemspec
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.1
1
+ 0.3.2
data/cw.gemspec CHANGED
@@ -19,22 +19,22 @@ Gem::Specification.new do |spec|
19
19
  spec.require_paths = ["lib", "audio", "data/text", "test"]
20
20
 
21
21
  spec.required_ruby_version = '>= 2.0.0'
22
- spec.add_runtime_dependency 'feedjira', '>= 2.0.0'
22
+ spec.add_runtime_dependency 'oga', '~>2.7'
23
+ spec.add_runtime_dependency 'httpclient'
23
24
  spec.add_runtime_dependency 'htmlentities', '>= 4.3.4'
24
25
  spec.add_runtime_dependency 'paint', '>= 1.0.1'
25
26
  spec.add_runtime_dependency 'rake', '>= 11.2.2'
26
27
  spec.add_runtime_dependency 'ruby-progressbar', '>= 1.8.1'
27
- spec.add_runtime_dependency 'sanitize', '~> 4.2.0'
28
+ spec.add_runtime_dependency 'sanitize', '~> 4.4.0'
28
29
  spec.add_runtime_dependency 'wavefile', '>= 0.7.0'
29
30
  spec.add_runtime_dependency 'parseconfig', '~> 1.0.8'
31
+ spec.add_runtime_dependency 'rubyserial', '~> 0.4.0'
30
32
  spec.add_dependency 'os', '~> 0.9.6'
31
33
 
32
- # remove dependency for live version (used for reading on OSX) spec.add_runtime_dependency 'coreaudio', '~> 0.0.11'
33
-
34
34
  spec.add_development_dependency 'version', '>= 1.0.0'
35
- spec.add_development_dependency 'minitest', '>= 5.8.4'
35
+ spec.add_development_dependency 'minitest', '>= 5.10.1'
36
36
  spec.add_development_dependency 'simplecov', '>= 0.12.0'
37
37
  spec.add_development_dependency 'yard', '~> 0.9.5'
38
- spec.add_development_dependency 'sequel', '~> 4.38.0'
38
+ spec.add_development_dependency 'sequel', '~> 4.42.0'
39
39
  spec.add_development_dependency 'sqlite3', '~> 1.3.11'
40
40
  end
data/lib/cw.rb CHANGED
@@ -32,14 +32,20 @@ require_relative 'cw/test_letters'
32
32
  require_relative 'cw/repeat_word'
33
33
  require_relative 'cw/reveal'
34
34
  require_relative 'cw/book'
35
- #require_relative 'cw/tx'
36
35
  require_relative 'cw/tone_generator'
37
36
  require_relative 'cw/progress'
38
37
  require_relative 'cw/common_words'
39
38
  require_relative 'cw/callsign'
40
-
41
39
  #require_relative 'cw/read.rb'
42
40
 
41
+ require 'rbconfig'
42
+
43
+ if RbConfig::CONFIG['target_os'].include?('darwin')
44
+ require_relative 'cw/coreaudio'
45
+ require_relative 'cw/tx'
46
+ require_relative 'cw/winkey'
47
+ end
48
+
43
49
  def cw &block
44
50
  CW.new do
45
51
  instance_eval(&block)
@@ -74,7 +74,10 @@ module CWG
74
74
  def play
75
75
  cmd = play_command + ' ' + play_filename
76
76
  @pid = ! @dry_run ? Process.spawn(cmd) : cmd
77
- Process.waitpid(@pid)
77
+ begin
78
+ Process.waitpid(@pid) if @pid.is_a?(Fixnum)
79
+ rescue Errno::ECHILD
80
+ end
78
81
  end
79
82
 
80
83
  def stop
@@ -11,9 +11,9 @@ module CWG
11
11
  :book_name,:book_dir,:play_command,:size,:run_default,:word_spacing,
12
12
  :command_line,:author,:title,:quality,:ebook2cw_path,:noise,:tone,
13
13
  :word_count,:volume,:list_colour,:success_colour,:fail_colour,
14
- :no_run,:run,:print_letters,:no_print,:use_ebook2cw,
15
- :dictionary,:containing,:begin,:end,:including,:word_filename,:max,:min,
16
- :exit, :quit
14
+ :tx_colour,:rx_colour,:menu_colour,:no_run,:run,:print_letters,:no_print,
15
+ :use_ebook2cw,:dictionary,:containing,:begin,:end,:including,
16
+ :word_filename,:max,:min,:exit, :quit
17
17
  ]
18
18
 
19
19
  def self.config
@@ -0,0 +1,144 @@
1
+ require 'coreaudio'
2
+
3
+ module CWG
4
+
5
+ class Coreaudio
6
+
7
+ include ToneHelpers
8
+
9
+ def initialize
10
+ dev = CoreAudio.default_output_device
11
+ @buf = dev.output_buffer(8192)
12
+ end
13
+
14
+ def ramp_filter(size, count)
15
+ @max_amplitude = 1
16
+ ramp = 0.03
17
+ ramp_point = @max_amplitude / ramp
18
+ ampl = (count < ramp_point) ? (ramp * count) : @max_amplitude
19
+ (count > (size - ramp_point)) ? (ramp * (size - count)) : ampl
20
+ end
21
+
22
+ def generate_tone(number_of_samples)
23
+ @sample_rate = 44100
24
+ @frequency = 1000
25
+ @w = (@frequency * TWO_PI) / @sample_rate
26
+ ary = []
27
+ number_of_samples.round.times do |sample_number|
28
+ amplitude = ramp_filter(number_of_samples, sample_number)
29
+ sine_radians = @w * sample_number
30
+ temp = (amplitude * Math.sin(sine_radians) * 0x7FFF).round
31
+ ary << temp
32
+ end
33
+ @buf << ary
34
+ end
35
+
36
+ def generate_silence(number_of_samples)
37
+ ary = []
38
+ number_of_samples.round.times do |sample_number|
39
+ ary << 0.0
40
+ end
41
+ @buf << ary
42
+ end
43
+
44
+ def start
45
+ @buf.start
46
+ end
47
+
48
+ def stop
49
+ @buf.stop
50
+ end
51
+
52
+ # def play_tone(wpm)
53
+ # # phase = Math::PI * 2.0 * 440.0 / dev.nominal_rate
54
+ # th = Thread.start do
55
+ # # i = 0
56
+ # # loop do
57
+ # # wav = NArray.sint(1024)
58
+ ## p @buf
59
+ # 1.times do
60
+ # generate_tone(1024 * wpm)
61
+ # generate_silence(1024 * wpm)
62
+ # generate_tone(1024 * wpm)
63
+ # generate_silence(1024 * wpm)
64
+ # generate_tone(1024 * wpm)
65
+ # generate_silence(1024 * wpm)
66
+ # generate_tone(1024 * wpm * 3)
67
+ # generate_silence(1024 * wpm * 3)
68
+ #
69
+ # generate_tone(1024 * wpm)
70
+ # generate_silence(1024 * wpm)
71
+ # generate_tone(1024 * wpm)
72
+ # generate_silence(1024 * wpm)
73
+ # generate_tone(1024 * wpm)
74
+ # generate_silence(1024 * wpm)
75
+ # generate_tone(1024 * wpm * 3)
76
+ # generate_silence(1024 * wpm * 3)
77
+ #
78
+ # generate_tone(1024 * wpm)
79
+ # generate_silence(1024 * wpm)
80
+ # generate_tone(1024 * wpm)
81
+ # generate_silence(1024 * wpm)
82
+ # generate_tone(1024 * wpm)
83
+ # generate_silence(1024 * wpm)
84
+ # generate_tone(1024 * wpm * 3)
85
+ # generate_silence(1024 * wpm * 3)
86
+ #
87
+ # generate_tone(1024 * wpm)
88
+ # generate_silence(1024 * wpm)
89
+ # generate_tone(1024 * wpm)
90
+ # generate_silence(1024 * wpm)
91
+ # generate_tone(1024 * wpm * 3)
92
+ # generate_silence(1024 * wpm)
93
+ # generate_tone(1024 * wpm)
94
+ # generate_silence(1024 * wpm * 3)
95
+ #
96
+ # generate_tone(1024 * wpm)
97
+ # generate_silence(1024 * wpm)
98
+ # generate_tone(1024 * wpm)
99
+ # generate_silence(1024 * wpm)
100
+ # generate_tone(1024 * wpm * 3)
101
+ # generate_silence(1024 * wpm)
102
+ # generate_tone(1024 * wpm)
103
+ # generate_silence(1024 * wpm * 3)
104
+ #
105
+ # generate_tone(1024 * wpm)
106
+ # generate_silence(1024 * wpm)
107
+ # generate_tone(1024 * wpm * 3)
108
+ # generate_silence(1024 * wpm)
109
+ # generate_tone(1024 * wpm)
110
+ # generate_silence(1024 * wpm)
111
+ # generate_tone(1024 * wpm)
112
+ # generate_silence(1024 * wpm * 3)
113
+ # generate_tone(1024 * wpm)
114
+ # generate_silence(1024 * wpm)
115
+ # generate_tone(1024 * wpm * 3)
116
+ # generate_silence(1024 * wpm)
117
+ # generate_tone(1024 * wpm)
118
+ # generate_silence(1024 * wpm)
119
+ # generate_tone(1024 * wpm)
120
+ # generate_silence(1024 * wpm * 3)
121
+ # generate_silence(1024 * wpm * 3)
122
+ # end
123
+ # end
124
+ # @buf.start
125
+ # th.join
126
+ # @buf.stop
127
+ # puts "#{@buf.dropped_frame} frame dropped."
128
+ # th.kill.join
129
+ #
130
+ # # def listen words
131
+ # # play_tone
132
+ # # # @words = words
133
+ # # # p @words
134
+ # # # @cw_threads = CWThreads.new(self, thread_processes)
135
+ # # # @cw_threads.run
136
+ # # # reset_stdin
137
+ # # # print.newline
138
+ # # end
139
+ # #
140
+ # # end
141
+ #
142
+ # end
143
+ end
144
+ end
@@ -51,13 +51,10 @@ module CWG
51
51
  test_letters.run @words
52
52
  end
53
53
 
54
- #todo
55
- # def tx
56
- # @words.add ["abc"]
57
- # Cfg.config.params["no_run"] = true
58
- # tx = Tx.new
59
- # tx.listen @words
60
- # end
54
+ def tx str
55
+ Cfg.config.params["no_run"] = true
56
+ Tx.new.tx(str)
57
+ end
61
58
 
62
59
  # Test user against complete words rather than letters.
63
60
  #
@@ -126,7 +123,6 @@ module CWG
126
123
 
127
124
  def read_rss(source, article_count = 3)
128
125
  rss, = Rss.new
129
-
130
126
  # don't go online if CW_ENV == test
131
127
  if(ENV["CW_ENV"] == "test")
132
128
  @words.assign ['test', 'rss', 'stub']
@@ -136,6 +132,9 @@ module CWG
136
132
  loop do
137
133
  article = rss.next_article
138
134
  return unless article
135
+ Cfg.config.params["no_run"] = false
136
+ Cfg.config.params["exit"] = false
137
+ Cfg.config.params["quit"] = false
139
138
  @words.assign article
140
139
  run
141
140
  end
@@ -290,12 +289,12 @@ module CWG
290
289
  def letters_numbers ; @words.letters_numbers ; end
291
290
  def load_codes ; load_text Q_CODES ; end
292
291
  def alpha ; 'a'.upto('z').collect{|ch| ch} ; end
293
- def vowels ; ['a','e','i','o','u'] ; end
294
- def dot_letters ; ['e','i','s','h'] ; end
295
- def dash_letters ; ['t','m','o'] ; end
292
+ def vowels ; %w(a e i o u) ; end
293
+ def dot_letters ; %w(e i s h) ; end
294
+ def dash_letters ; %w(t m o) ; end
296
295
  def load_vowels ; @words.assign vowels ; end
297
296
  def load_consonants ; @words.assign alpha - vowels ; end
298
- def numbers ; '0'.upto('9').collect{|ch| ch} ; end
297
+ def numbers ; '0'.upto('9').collect ; end
299
298
  def load_numbers ; @words.assign numbers ; end
300
299
  def load_dots ; load_letters(dot_letters) ; end
301
300
  def load_dashes ; load_letters(dash_letters) ; end
@@ -304,6 +303,7 @@ module CWG
304
303
 
305
304
  alias_method :ewpm, :effective_wpm
306
305
  alias_method :comment, :name
306
+ alias_method :read_feed, :read_rss
307
307
  alias_method :word_length, :word_size
308
308
  alias_method :load_letters, :load_alphabet
309
309
  alias_method :word_shuffle, :shuffle
@@ -7,45 +7,74 @@ module CWG
7
7
  attr_reader :threads
8
8
 
9
9
  def initialize context, processes
10
+ Thread.abort_on_exception = true
10
11
  @context = context
11
12
  @processes = processes
13
+ @threads = []
12
14
  end
13
15
 
14
16
  def start_threads
15
- @threads = @processes.collect do |th|
16
- {:thread =>
17
- Thread.new do
18
- @context.send th
19
- end,
20
- :name => th
21
- }
17
+ @processes.collect do |th|
18
+ @threads << start_thread(@context, th)
19
+ end
20
+ end
21
+
22
+ def start_thread context, th
23
+ {
24
+ :thread => Thread.new do
25
+ context.send th
26
+ end,
27
+ :name => th
28
+ }
29
+ end
30
+
31
+ def kill_thread thread
32
+ thread[:thread].kill
33
+ end
34
+
35
+ def kill_thread_x x
36
+ @threads.each_with_index do |th,idx|
37
+ if th[:name] == x
38
+ kill_thread th
39
+ @threads.delete_at idx
40
+ end
22
41
  end
23
42
  end
24
43
 
44
+ def join x
45
+ @threads.each do |th|
46
+ if th[:name] == x
47
+ th[:thread].join
48
+ end
49
+ end
50
+ end
51
+
52
+ def add context, th
53
+ @threads << start_thread(context, th)
54
+ end
55
+
25
56
  def monitor_threads
26
57
  exiting = false
27
58
  loop do
28
59
  sleep 0.5
29
- @threads.each do |th|
30
- if thread_false_or_nil?(th)
31
- exiting = true
32
- unless Cfg.config["exit"]
33
- # puts "** #{th[:name].to_s.gsub('_',' ')} quit unexpectedly!**"
34
- if th[:thread].backtrace
35
- STDERR.puts th[:thread].backtrace.join("\n \\_ ")
36
- end
37
- end
38
- end
39
- end
60
+ # @threads.each do |th|
61
+ # if thread_false_or_nil?(th)
62
+ ##todo exiting = true
63
+ # unless Cfg.config["exit"]
64
+ ## puts "** #{th[:name].to_s.gsub('_',' ')} quit unexpectedly!**"
65
+ # if th[:thread].backtrace
66
+ # STDERR.puts th[:thread].backtrace.join("\n \\_ ")
67
+ # end
68
+ # end
69
+ # end
40
70
  # print_threads_status
41
71
  exiting = true if(Cfg.config["exit"])
42
72
  break if exiting
43
73
  end
44
- close_threads if exiting
45
- end
46
-
47
- def kill_thread thread
48
- thread[:thread].kill
74
+ @threads.each do |th|
75
+ th[:thread].kill.join
76
+ end
77
+ #close_threads if exiting
49
78
  end
50
79
 
51
80
  def kill_open_threads
@@ -91,7 +120,7 @@ module CWG
91
120
  @threads.each do |thread|
92
121
  puts "\r"
93
122
  print "#{thread[:name]} = "
94
- p thread[:thread].status
123
+ # p thread[:thread].status
95
124
  end
96
125
  end
97
126
 
@@ -139,6 +168,7 @@ module CWG
139
168
  start_threads
140
169
  monitor_threads
141
170
  system("stty -raw echo")
171
+ puts "\r"
142
172
  end
143
173
 
144
174
  end
@@ -17,25 +17,32 @@ module CWG
17
17
  begin
18
18
  system("stty raw -echo")
19
19
  @chr = STDIN.getc
20
+ # @chr = @chr.downcase unless(@chr.include? 'Q')
21
+ # puts "@chr = #{@chr}"
22
+ @chr
20
23
  ensure
21
24
  system("stty raw -echo")
22
25
  end
23
26
  end
24
27
 
25
- def is_letter?
26
- @chr >= 'a' && @chr <= 'z'
28
+ def is_letter? char = nil
29
+ char = char ? char : @chr
30
+ char >= 'a' && char <= 'z'
27
31
  end
28
32
 
29
- def is_number?
30
- @chr >= '0' && @chr <= '9'
33
+ def is_number? char = nil
34
+ char = char ? char : @chr
35
+ char >= '0' && char <= '9'
31
36
  end
32
37
 
33
- def is_punctuation?
34
- [' ', ',', '.', '=', '?'].detect{|letr| letr == @chr}
38
+ def is_punctuation? char = nil
39
+ char = char ? char : @chr
40
+ [' ', ',', '.', '=', '?','/','+'].detect{|letr| letr == char}
35
41
  end
36
42
 
37
- def is_relevant_char?
38
- is_letter? || is_number? || is_punctuation? ? true : false
43
+ def is_relevant_char? char = nil
44
+ char = char ? char : @chr
45
+ is_letter?(char) || is_number?(char) || is_punctuation?(char) ? true : false
39
46
  end
40
47
 
41
48
  def reset_stdin