cw 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
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