cw 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/Gemfile +11 -0
- data/LICENSE +21 -0
- data/README.md +21 -0
- data/Rakefile +1 -0
- data/audio/audio_output.wav +0 -0
- data/audio/audio_output.wav0000.mp3 +0 -0
- data/audio/dash.wav +0 -0
- data/audio/dot.wav +0 -0
- data/audio/e_space.wav +0 -0
- data/audio/space.wav +0 -0
- data/cw.gemspec +18 -0
- data/daily.rb +182 -0
- data/data/text/abbreviations.txt +1 -0
- data/data/text/common_words.txt +90 -0
- data/data/text/cw_conversation.txt +1 -0
- data/data/text/most_common_words.txt +1 -0
- data/data/text/progress.txt +1 -0
- data/data/text/q_codes.txt +1 -0
- data/data/text/tom_sawyer.txt +6477 -0
- data/example.rb +139 -0
- data/lib/cw.rb +111 -0
- data/lib/cw/alphabet.rb +29 -0
- data/lib/cw/audio_player.rb +63 -0
- data/lib/cw/book.rb +239 -0
- data/lib/cw/book_details.rb +47 -0
- data/lib/cw/cl.rb +112 -0
- data/lib/cw/cw_dsl.rb +211 -0
- data/lib/cw/cw_encoding.rb +56 -0
- data/lib/cw/cw_params.rb +29 -0
- data/lib/cw/cw_threads.rb +36 -0
- data/lib/cw/file_details.rb +13 -0
- data/lib/cw/key_input.rb +53 -0
- data/lib/cw/monitor.rb +36 -0
- data/lib/cw/monitor_keys.rb +37 -0
- data/lib/cw/numbers.rb +29 -0
- data/lib/cw/print.rb +137 -0
- data/lib/cw/process.rb +11 -0
- data/lib/cw/progress.rb +27 -0
- data/lib/cw/randomize.rb +73 -0
- data/lib/cw/repeat_word.rb +91 -0
- data/lib/cw/rss.rb +71 -0
- data/lib/cw/sentence.rb +78 -0
- data/lib/cw/speak.rb +11 -0
- data/lib/cw/spoken.rb +11 -0
- data/lib/cw/str.rb +67 -0
- data/lib/cw/stream.rb +161 -0
- data/lib/cw/test_letters.rb +52 -0
- data/lib/cw/test_words.rb +59 -0
- data/lib/cw/tester.rb +221 -0
- data/lib/cw/timing.rb +92 -0
- data/lib/cw/tone_generator.rb +225 -0
- data/lib/cw/voice.rb +16 -0
- data/lib/cw/words.rb +182 -0
- data/read_book.rb +33 -0
- data/test/run_tests_continuously.rb +4 -0
- data/test/test_cw.rb +527 -0
- data/test/test_stream.rb +401 -0
- metadata +102 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class BookDetails
|
4
|
+
|
5
|
+
attr_reader :args
|
6
|
+
|
7
|
+
HERE = File.dirname(__FILE__) + '/'
|
8
|
+
BOOK_DIRECTORY = HERE + '../../data/text/'
|
9
|
+
BOOK_NAME = 'tom_sawyer.txt'
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@book_name = BOOK_NAME
|
13
|
+
@book_directory = BOOK_DIRECTORY
|
14
|
+
end
|
15
|
+
|
16
|
+
def book_location
|
17
|
+
@book_directory + @book_name
|
18
|
+
end
|
19
|
+
|
20
|
+
def arguments args
|
21
|
+
@args = args
|
22
|
+
@args[:output] = :letter unless @args[:output]
|
23
|
+
if @args[:duration]
|
24
|
+
@timeout = Time.now + @args[:duration] * 60.0
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def session_finished? source
|
29
|
+
sentences_complete?(source) || book_timeout?
|
30
|
+
end
|
31
|
+
|
32
|
+
def sentences_complete? source
|
33
|
+
if @args.has_key?(:sentences) && @args[:sentences].is_a?(Fixnum)
|
34
|
+
if @sentence_count_source
|
35
|
+
@sentence_count_source = nil
|
36
|
+
else
|
37
|
+
@args[:sentences] -= 1
|
38
|
+
@sentence_count_source = true
|
39
|
+
end
|
40
|
+
true if(@args[:sentences] < 0)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
def book_timeout?
|
45
|
+
@timeout && (Time.now > @timeout)
|
46
|
+
end
|
47
|
+
end
|
data/lib/cw/cl.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
#class Cl performs command-line processing
|
4
|
+
|
5
|
+
class Cl
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@tone = {
|
9
|
+
sinewave: 0,
|
10
|
+
sawtooth: 1,
|
11
|
+
squarewave: 2
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
def cl_wpm
|
16
|
+
wpm = Params.wpm
|
17
|
+
wpm ? "-w #{wpm} " : ''
|
18
|
+
end
|
19
|
+
|
20
|
+
def cl_effective_wpm
|
21
|
+
ewpm = Params.effective_wpm
|
22
|
+
ewpm ? "-e #{ewpm} " : ''
|
23
|
+
end
|
24
|
+
|
25
|
+
def cl_word_spacing
|
26
|
+
ws = Params.word_spacing
|
27
|
+
ws ? "-W #{ws} " : ''
|
28
|
+
end
|
29
|
+
|
30
|
+
def cl_frequency
|
31
|
+
freq = Params.frequency
|
32
|
+
freq ? "-f #{freq} " : ''
|
33
|
+
end
|
34
|
+
|
35
|
+
def cl_squarewave
|
36
|
+
sqr = Params.tone == :squarewave
|
37
|
+
sqr ? "-T #{@tone[:squarewave]} " : ''
|
38
|
+
end
|
39
|
+
|
40
|
+
def cl_sawtooth
|
41
|
+
st = Params.tone == :sawtooth
|
42
|
+
st ? "-T #{@tone[:sawtooth]} " : ''
|
43
|
+
end
|
44
|
+
|
45
|
+
def cl_sinewave
|
46
|
+
sin = Params.tone == :sinewave
|
47
|
+
sin ? "-T #{@tone[:sinewave]} " : ''
|
48
|
+
end
|
49
|
+
|
50
|
+
def cl_author
|
51
|
+
author = Params.author
|
52
|
+
author ? "-a \"#{author}\" " : ''
|
53
|
+
end
|
54
|
+
|
55
|
+
def cl_title
|
56
|
+
title = Params.title
|
57
|
+
title ? "-t \"#{title}\" " : ''
|
58
|
+
end
|
59
|
+
|
60
|
+
def cl_noise
|
61
|
+
noise = Params.noise
|
62
|
+
noise ? "-N 5 -B 1000 " : ''
|
63
|
+
end
|
64
|
+
|
65
|
+
def cl_audio_filename
|
66
|
+
"-o \"#{Params.audio_dir}/#{Params.audio_filename}\" "
|
67
|
+
end
|
68
|
+
|
69
|
+
def coarse_quality(quality)
|
70
|
+
{
|
71
|
+
:high => "-q 1 ",
|
72
|
+
:medium => "-q 5 ",
|
73
|
+
:low => "-q 9 "
|
74
|
+
}[quality]
|
75
|
+
end
|
76
|
+
|
77
|
+
def cl_quality
|
78
|
+
quality = Params.quality
|
79
|
+
if quality && quality.class == Fixnum
|
80
|
+
"-q #{quality} "
|
81
|
+
else
|
82
|
+
coarse_quality quality
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def cl_command_line
|
87
|
+
cl = Params.command_line
|
88
|
+
cl ? "#{cl}" : ''
|
89
|
+
end
|
90
|
+
|
91
|
+
def build_command_line
|
92
|
+
[ cl_wpm,
|
93
|
+
cl_effective_wpm,
|
94
|
+
cl_word_spacing,
|
95
|
+
cl_frequency,
|
96
|
+
cl_squarewave,
|
97
|
+
cl_sawtooth,
|
98
|
+
cl_sinewave,
|
99
|
+
cl_author,
|
100
|
+
cl_title,
|
101
|
+
cl_noise,
|
102
|
+
cl_audio_filename,
|
103
|
+
cl_quality,
|
104
|
+
cl_command_line
|
105
|
+
].collect{|param| param}.join
|
106
|
+
end
|
107
|
+
|
108
|
+
def cl_echo words
|
109
|
+
"echo #{words} | ebook2cw #{build_command_line}"
|
110
|
+
end
|
111
|
+
|
112
|
+
end
|
data/lib/cw/cw_dsl.rb
ADDED
@@ -0,0 +1,211 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# class Cw_dsl provides CW's commands
|
4
|
+
|
5
|
+
class CwDsl
|
6
|
+
|
7
|
+
HERE = File.dirname(__FILE__) + '/'
|
8
|
+
TEXT = HERE + '../../data/text/'
|
9
|
+
COMMON_WORDS = TEXT + 'common_words.txt'
|
10
|
+
MOST_COMMON_WORDS = TEXT + 'most_common_words.txt'
|
11
|
+
ABBREVIATIONS = TEXT + 'abbreviations.txt'
|
12
|
+
Q_CODES = TEXT + 'q_codes.txt'
|
13
|
+
|
14
|
+
def initialize
|
15
|
+
@words, @cl, @str =
|
16
|
+
Words.new, Cl.new, Str.new
|
17
|
+
init_config
|
18
|
+
end
|
19
|
+
|
20
|
+
[:name, :wpm,
|
21
|
+
:effective_wpm, :word_spacing,
|
22
|
+
:command_line, :frequency,
|
23
|
+
:author, :title,
|
24
|
+
:quality, :audio_filename,
|
25
|
+
:pause, :noise,
|
26
|
+
:shuffle, :mark_words,
|
27
|
+
:double_words, :single_words,
|
28
|
+
:audio_dir, :def_word_count
|
29
|
+
].each do |method|
|
30
|
+
define_method method do |arg = nil|
|
31
|
+
arg ? Params.send("#{method}=", arg) : Params.send("#{method}")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
[[:pause, :pause, true],
|
36
|
+
[:un_pause, :pause, nil],
|
37
|
+
[:print_letters, :print_letters, true],
|
38
|
+
[:mark_words, :print_letters, nil],
|
39
|
+
[:noise, :noise, true],
|
40
|
+
[:no_noise, :noise, nil],
|
41
|
+
[:shuffle, :shuffle, true],
|
42
|
+
[:no_shuffle, :shuffle, nil],
|
43
|
+
[:double_words, :double_words, true],
|
44
|
+
[:single_words, :double_words, nil],
|
45
|
+
[:use_ebook2cw, :use_ebook2cw, true],
|
46
|
+
[:use_ruby_tone, :use_ebook2cw, nil],
|
47
|
+
].each do |bool|
|
48
|
+
define_method bool[0] do
|
49
|
+
Params.send("#{bool[1]}=", bool[2])
|
50
|
+
@words.shuffle if((bool[1] == :shuffle) && (bool[2]))
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def init_config
|
55
|
+
Params.config do
|
56
|
+
param :name, :wpm,
|
57
|
+
:dictionary, :command_line, :audio_filename, :tone, :pause,
|
58
|
+
:print_letters, :double_words,
|
59
|
+
:word_filename, :author, :title, :quality, :frequency, :shuffle, :effective_wpm,
|
60
|
+
:max, :min, :word_spacing, :noise, :begin, :end, :word_count, :including,
|
61
|
+
:word_size, :size, :beginning_with, :ending_with, :mark_words, :audio_dir,
|
62
|
+
:use_ebook2cw, :def_word_count
|
63
|
+
end
|
64
|
+
|
65
|
+
config_defaults
|
66
|
+
config_files
|
67
|
+
end
|
68
|
+
|
69
|
+
def config_defaults
|
70
|
+
Params.config {
|
71
|
+
name 'unnamed'
|
72
|
+
wpm 25
|
73
|
+
frequency 500
|
74
|
+
dictionary COMMON_WORDS
|
75
|
+
# def_word_count 100
|
76
|
+
}
|
77
|
+
end
|
78
|
+
|
79
|
+
def config_files
|
80
|
+
Params.config {
|
81
|
+
audio_dir 'audio'
|
82
|
+
audio_filename 'audio_output.wav'
|
83
|
+
word_filename 'words.txt'
|
84
|
+
}
|
85
|
+
end
|
86
|
+
|
87
|
+
def words
|
88
|
+
@words.all
|
89
|
+
end
|
90
|
+
|
91
|
+
def words= words
|
92
|
+
@words.add words
|
93
|
+
end
|
94
|
+
|
95
|
+
def word_size(size = nil)
|
96
|
+
if size
|
97
|
+
Params.size = size
|
98
|
+
@words.word_size size
|
99
|
+
end
|
100
|
+
Params.size
|
101
|
+
end
|
102
|
+
|
103
|
+
def beginning_with(* letters)
|
104
|
+
@words.beginning_with letters
|
105
|
+
Params.begin = letters
|
106
|
+
end
|
107
|
+
|
108
|
+
def ending_with(* letters)
|
109
|
+
@words.ending_with letters
|
110
|
+
Params.end = letters
|
111
|
+
end
|
112
|
+
|
113
|
+
def word_count(wordcount)
|
114
|
+
Params.word_count = wordcount
|
115
|
+
@words.count wordcount
|
116
|
+
end
|
117
|
+
|
118
|
+
def including(* letters)
|
119
|
+
Params.including = letters
|
120
|
+
@words.including letters
|
121
|
+
end
|
122
|
+
|
123
|
+
def no_longer_than(max)
|
124
|
+
Params.max = max
|
125
|
+
@words.no_longer_than max
|
126
|
+
end
|
127
|
+
|
128
|
+
def no_shorter_than(min)
|
129
|
+
Params.min = min
|
130
|
+
@words.no_shorter_than min
|
131
|
+
end
|
132
|
+
|
133
|
+
def reverse
|
134
|
+
@words.reverse
|
135
|
+
end
|
136
|
+
|
137
|
+
def letters_numbers
|
138
|
+
@words.letters_numbers
|
139
|
+
end
|
140
|
+
|
141
|
+
def random_letters_numbers(options = {})
|
142
|
+
options.merge!(letters_numbers: true)
|
143
|
+
@words.random_letters_numbers options
|
144
|
+
end
|
145
|
+
|
146
|
+
def random_letters(options = {})
|
147
|
+
@words.random_letters(options)
|
148
|
+
end
|
149
|
+
|
150
|
+
def random_numbers(options = {})
|
151
|
+
@words.random_numbers(options)
|
152
|
+
end
|
153
|
+
|
154
|
+
def alphabet(options = {reverse: nil})
|
155
|
+
@words.alphabet(options)
|
156
|
+
end
|
157
|
+
|
158
|
+
def numbers(options = {reverse: nil})
|
159
|
+
@words.numbers(options)
|
160
|
+
end
|
161
|
+
|
162
|
+
def numbers_spoken()
|
163
|
+
end
|
164
|
+
|
165
|
+
# def add_noise
|
166
|
+
# Params.noise = true
|
167
|
+
# end
|
168
|
+
|
169
|
+
def reload
|
170
|
+
load_words(Params.dictionary)
|
171
|
+
end
|
172
|
+
|
173
|
+
def load_common_words
|
174
|
+
load_words
|
175
|
+
end
|
176
|
+
|
177
|
+
def load_most_common_words
|
178
|
+
load_words MOST_COMMON_WORDS
|
179
|
+
end
|
180
|
+
|
181
|
+
def load_abbreviations
|
182
|
+
load_words ABBREVIATIONS
|
183
|
+
end
|
184
|
+
|
185
|
+
def load_q_codes
|
186
|
+
load_words Q_CODES
|
187
|
+
end
|
188
|
+
|
189
|
+
#todo refactor
|
190
|
+
|
191
|
+
def load_alphabet
|
192
|
+
@words.assign '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 '
|
193
|
+
end
|
194
|
+
|
195
|
+
def load_numbers
|
196
|
+
@words.assign '1 2 3 4 5 6 7 8 9 0 '
|
197
|
+
end
|
198
|
+
|
199
|
+
def load_words(filename = COMMON_WORDS)
|
200
|
+
Params.dictionary = filename
|
201
|
+
@words.load filename
|
202
|
+
end
|
203
|
+
|
204
|
+
def set_tone_type(type)
|
205
|
+
case type
|
206
|
+
when :squarewave, :sawtooth, :sinewave
|
207
|
+
Params.tone = type
|
208
|
+
end
|
209
|
+
end
|
210
|
+
|
211
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
class CwEncoding
|
4
|
+
|
5
|
+
def fetch char
|
6
|
+
encode[char]
|
7
|
+
end
|
8
|
+
|
9
|
+
def encode
|
10
|
+
{
|
11
|
+
'a' => [:dot, :dash],
|
12
|
+
'b' => [:dash, :dot, :dot, :dot],
|
13
|
+
'c' => [:dash, :dot, :dash, :dot],
|
14
|
+
'd' => [:dash, :dot, :dot],
|
15
|
+
'e' => [:dot],
|
16
|
+
'f' => [:dot, :dot, :dash, :dot],
|
17
|
+
'g' => [:dash, :dash, :dot],
|
18
|
+
'h' => [:dot, :dot, :dot, :dot],
|
19
|
+
'i' => [:dot, :dot],
|
20
|
+
'j' => [:dot, :dash, :dash, :dash],
|
21
|
+
'k' => [:dash, :dot, :dash],
|
22
|
+
'l' => [:dot, :dash, :dot, :dot],
|
23
|
+
'm' => [:dash, :dash],
|
24
|
+
'n' => [:dash, :dot],
|
25
|
+
'o' => [:dash, :dash, :dash],
|
26
|
+
'p' => [:dot, :dash, :dash, :dot],
|
27
|
+
'q' => [:dash, :dash, :dot, :dash],
|
28
|
+
'r' => [:dot, :dash, :dot],
|
29
|
+
's' => [:dot, :dot, :dot],
|
30
|
+
't' => [:dash],
|
31
|
+
'u' => [:dot, :dot, :dash],
|
32
|
+
'v' => [:dot, :dot, :dot, :dash],
|
33
|
+
'w' => [:dot, :dash, :dash],
|
34
|
+
'x' => [:dash, :dot, :dot, :dash],
|
35
|
+
'y' => [:dash, :dot, :dash, :dash],
|
36
|
+
'z' => [:dash, :dash, :dot, :dot],
|
37
|
+
'1' => [:dot, :dash, :dash, :dash, :dash],
|
38
|
+
'2' => [:dot, :dot, :dash, :dash, :dash],
|
39
|
+
'3' => [:dot, :dot, :dot, :dash, :dash],
|
40
|
+
'4' => [:dot, :dot, :dot, :dot, :dash],
|
41
|
+
'5' => [:dot, :dot, :dot, :dot, :dot],
|
42
|
+
'6' => [:dash, :dot, :dot, :dot, :dot],
|
43
|
+
'7' => [:dash, :dash, :dot, :dot, :dot],
|
44
|
+
'8' => [:dash, :dash, :dash, :dot, :dot],
|
45
|
+
'9' => [:dash, :dash, :dash, :dash, :dot],
|
46
|
+
'0' => [:dash, :dash, :dash, :dash, :dash],
|
47
|
+
'.' => [:dot, :dash, :dot, :dash, :dot, :dash],
|
48
|
+
',' => [:dash, :dash, :dot, :dot, :dash, :dash],
|
49
|
+
'=' => [:dash, :dot, :dot,:dot, :dash],
|
50
|
+
'!' => [:dot, :dot, :dash, :dash, :dot],
|
51
|
+
'/' => [:dash, :dot, :dot, :dash, :dot],
|
52
|
+
'?' => [:dot, :dot, :dash, :dash, :dot, :dot],
|
53
|
+
' ' => []
|
54
|
+
}
|
55
|
+
end
|
56
|
+
end
|
data/lib/cw/cw_params.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
module Params
|
4
|
+
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def param_method values, name
|
8
|
+
value = values.first
|
9
|
+
value ? self.send("#{name}=", value) : instance_variable_get("@#{name}")
|
10
|
+
end
|
11
|
+
|
12
|
+
def param_internal name
|
13
|
+
attr_accessor name
|
14
|
+
instance_variable_set("@#{name}", nil)
|
15
|
+
define_method name do | * values|
|
16
|
+
param_method values, name
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def param( * names)
|
21
|
+
names.each do |name|
|
22
|
+
param_internal name
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def config( & block)
|
27
|
+
instance_eval( & block)
|
28
|
+
end
|
29
|
+
end
|