cw 0.2.4 → 0.3.0

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.
Files changed (68) hide show
  1. checksums.yaml +4 -4
  2. data/.cw_config +18 -0
  3. data/.gitignore +10 -1
  4. data/LICENSE +2 -1
  5. data/README.md +212 -96
  6. data/Rakefile +15 -2
  7. data/VERSION +1 -1
  8. data/Vagrantfile +45 -0
  9. data/cw.gemspec +6 -1
  10. data/data/text/book_to_read.txt +4 -0
  11. data/data/text/english.txt +10000 -0
  12. data/example.rb +172 -106
  13. data/lib/cw.rb +10 -126
  14. data/lib/cw/alphabet.rb +53 -46
  15. data/lib/cw/audio_player.rb +83 -72
  16. data/lib/cw/book.rb +160 -185
  17. data/lib/cw/book_details.rb +38 -49
  18. data/lib/cw/cl.rb +101 -95
  19. data/lib/cw/common_words.rb +76 -0
  20. data/lib/cw/config.rb +50 -0
  21. data/lib/cw/current_word.rb +23 -24
  22. data/lib/cw/cw_dsl.rb +264 -131
  23. data/lib/cw/cw_encoding.rb +63 -69
  24. data/lib/cw/cw_stream.rb +86 -82
  25. data/lib/cw/cw_threads.rb +132 -22
  26. data/lib/cw/element.rb +60 -54
  27. data/lib/cw/file_details.rb +26 -11
  28. data/lib/cw/key_input.rb +53 -35
  29. data/lib/cw/numbers.rb +26 -19
  30. data/lib/cw/os.rb +13 -0
  31. data/lib/cw/play.rb +92 -0
  32. data/lib/cw/print.rb +102 -100
  33. data/lib/cw/process.rb +3 -0
  34. data/lib/cw/progress.rb +20 -17
  35. data/lib/cw/randomize.rb +56 -52
  36. data/lib/cw/repeat_word.rb +59 -66
  37. data/lib/cw/reveal.rb +32 -31
  38. data/lib/cw/rss.rb +52 -48
  39. data/lib/cw/sentence.rb +83 -76
  40. data/lib/cw/speak.rb +8 -4
  41. data/lib/cw/spoken.rb +8 -4
  42. data/lib/cw/str.rb +62 -30
  43. data/lib/cw/test_letters.rb +20 -28
  44. data/lib/cw/test_words.rb +25 -31
  45. data/lib/cw/tester.rb +219 -226
  46. data/lib/cw/text_helpers.rb +19 -15
  47. data/lib/cw/timing.rb +63 -67
  48. data/lib/cw/tone_generator.rb +176 -153
  49. data/lib/cw/tone_helpers.rb +15 -23
  50. data/lib/cw/voice.rb +12 -8
  51. data/lib/cw/words.rb +136 -106
  52. data/run_script_tests.rb +165 -0
  53. data/test/my_words.txt +1 -0
  54. data/test/test_common_words.rb +71 -0
  55. data/test/test_config.rb +98 -0
  56. data/test/test_current_word.rb +62 -0
  57. data/test/test_cw.rb +87 -120
  58. data/test/test_cw_threads.rb +123 -0
  59. data/test/test_filtering.rb +439 -0
  60. data/test/test_params.rb +28 -0
  61. data/test/test_play.rb +51 -0
  62. data/test/test_stream.rb +83 -83
  63. data/test/test_tester.rb +9 -27
  64. data/test/test_timing.rb +212 -0
  65. metadata +94 -12
  66. data/lib/cw/config_file.rb +0 -69
  67. data/lib/cw/monitor_keys.rb +0 -37
  68. data/lib/cw/params.rb +0 -104
@@ -1,66 +1,73 @@
1
1
  # encoding: utf-8
2
2
 
3
- #class Alphabet provides alphabet generation functionality
3
+ module CWG
4
4
 
5
- class Alphabet
5
+ #class Alphabet provides alphabet generation functionality
6
6
 
7
- # initialize class Alphabet
8
- # == Parameters:
9
- # options::
10
- # An optional hash containg options:
11
- # :reverse - reverse alphabet
12
- # :shuffle - shuffle alphabet
13
- # :include - include only these letters of the alphabet
14
- # :exclude - exclude these letters from the alphabet
7
+ class Alphabet
15
8
 
16
- def initialize(options = {})
17
- @options = options
18
- end
9
+ # initialize class Alphabet
10
+ # == Parameters:
11
+ # options::
12
+ # An optional hash containg options:
13
+ # :reverse - reverse alphabet
14
+ # :shuffle - shuffle alphabet
15
+ # :include - include only these letters of the alphabet
16
+ # :exclude - exclude these letters from the alphabet
19
17
 
20
- # return string containing alphabet
18
+ def initialize(options = {})
19
+ @options = options
20
+ end
21
21
 
22
- def alphabet
23
- 'abcdefghijklmnopqrstuvwxyz'
24
- end
22
+ # return string containing alphabet
25
23
 
26
- # reverse alphabet if :reverse option defined
24
+ def alphabet
25
+ 'abcdefghijklmnopqrstuvwxyz'
26
+ end
27
27
 
28
- def reverse_alphabet_maybe
29
- @letters.reverse! if @options[:reverse]
30
- end
28
+ # reverse alphabet if :reverse option defined
31
29
 
32
- # shuffle alphabet if :shuffle option defined
30
+ def reverse_alphabet_maybe
31
+ @letters.reverse! if @options[:reverse]
32
+ end
33
33
 
34
- def shuffle_alphabet_maybe
35
- @letters = @letters.split('').shuffle.join if @options[:shuffle]
36
- end
34
+ # shuffle alphabet if :shuffle option defined
37
35
 
38
- # include letters passed in as string if :include defined
36
+ def shuffle_alphabet_maybe
37
+ unless(ENV["CW_ENV"] == "test")
38
+ @letters = @letters.split('').shuffle.join if @options[:shuffle]
39
+ end
40
+ end
41
+
42
+ # include letters passed in as string if :include defined
39
43
 
40
- def include_letters
41
- if @options[:include]
42
- @letters = @options[:include]
44
+ def include_letters
45
+ if @options[:include]
46
+ @letters = @options[:include]
47
+ end
43
48
  end
44
- end
45
49
 
46
- # exclude letters passed in as string if :exclude defined
50
+ # exclude letters passed in as string if :exclude defined
47
51
 
48
- def exclude_letters
49
- if @options[:exclude]
50
- @letters.tr!(@options[:exclude],'')
52
+ def exclude_letters
53
+ if @options[:exclude]
54
+ @letters.tr!(@options[:exclude],'')
55
+ end
56
+ end
57
+
58
+ # generate alphabet with options acted upon
59
+ # == Returns:
60
+ # alphabet or filtered alphabet
61
+
62
+ def generate
63
+ @letters = alphabet
64
+ include_letters
65
+ exclude_letters
66
+ shuffle_alphabet_maybe
67
+ reverse_alphabet_maybe
68
+ @letters.split('').join(' ')
51
69
  end
52
- end
53
70
 
54
- # generate alphabet with options acted upon
55
- # == Returns:
56
- # alphabet or filtered alphabet
57
-
58
- def generate
59
- @letters = alphabet
60
- include_letters
61
- exclude_letters
62
- shuffle_alphabet_maybe
63
- reverse_alphabet_maybe
64
- @letters.split('').join(' ')
65
71
  end
72
+
66
73
  end
@@ -1,95 +1,106 @@
1
1
  # encoding: utf-8
2
2
 
3
- class AudioPlayer
3
+ require 'timeout'
4
+ require 'os'
4
5
 
5
- AFPLAY = '/usr/bin/afplay'
6
+ module CWG
6
7
 
7
- #todo def initialize
8
- #todo if Params.play_command
9
- #todo @play_command = Params.play_command
10
- #todo end
11
- #todo end
8
+ class AudioPlayer
12
9
 
13
- def tone
14
- @tone ||= ToneGenerator.new
15
- end
10
+ include CWG::OStest
16
11
 
17
- def play_command
18
- @play_command ||= AFPLAY
19
- end
12
+ def tone
13
+ @tone ||= ToneGenerator.new
14
+ end
20
15
 
21
- def play_filename_for_ebook2cw
22
- @play_filename ||= File.expand_path(Params.audio_filename, audio_dir)
23
- end
16
+ def os_play_command
17
+ if is_mac?
18
+ 'afplay'
19
+ elsif is_posix?
20
+ 'ossplay'
21
+ else
22
+ puts 'Error - play_command required in .cw_config'
23
+ exit 1
24
+ end
25
+ end
24
26
 
25
- def audio_dir
26
- Params.audio_dir ||= './audio'
27
- end
27
+ def play_command
28
+ if Cfg.config["play_command"].nil?
29
+ Cfg.config.params["play_command"] =
30
+ os_play_command
31
+ end
32
+ Cfg.config["play_command"]
33
+ end
28
34
 
29
- def temp_filename_for_ebook2cw
30
- File.expand_path("tempxxxx.txt", audio_dir)
31
- end
35
+ def play_filename_for_ebook2cw
36
+ @play_filename ||= File.expand_path(Cfg.config["audio_filename"], audio_dir)
37
+ end
32
38
 
33
- def convert_book words
34
- words = words.delete("\n")
35
- File.open(temp_filename_for_ebook2cw, 'w') do |file|
36
- file.print words
39
+ def audio_dir
40
+ Cfg.config["audio_dir"]
37
41
  end
38
- cl = Cl.new.cl_full(temp_filename_for_ebook2cw)
39
- ! @dry_run ? `#{cl}` : cl
40
- File.delete(temp_filename_for_ebook2cw)
41
- File.rename(play_filename_for_ebook2cw + '0000.mp3', play_filename_for_ebook2cw)
42
- end
43
42
 
44
- #FIXME dry_run
45
- def convert_words_with_ebook2cw words
46
- words = words.delete("\n")
47
- cl = Cl.new.cl_echo(words)
48
- ! @dry_run ? `#{cl}` : cl
49
- File.rename(play_filename + '0000.mp3', play_filename)
50
- end
43
+ def temp_filename_for_ebook2cw
44
+ File.expand_path("tempxxxx.txt", audio_dir)
45
+ end
51
46
 
52
- def convert_words words
53
- tone.generate words unless Params.use_ebook2cw
54
- convert_words_with_ebook2cw words if Params.use_ebook2cw
55
- end
47
+ def convert_book words
48
+ words = words.delete("\n")
49
+ File.open(temp_filename_for_ebook2cw, 'w') do |file|
50
+ file.print words
51
+ end
52
+ cl = Cl.new.cl_full(temp_filename_for_ebook2cw)
53
+ ! @dry_run ? `#{cl}` : cl
54
+ File.delete(temp_filename_for_ebook2cw)
55
+ File.rename(play_filename_for_ebook2cw + '0000.mp3', play_filename_for_ebook2cw)
56
+ end
56
57
 
57
- def play_filename
58
- return play_filename_for_ebook2cw if Params.use_ebook2cw
59
- tone.play_filename
60
- end
58
+ #FIXME dry_run
59
+ def convert_words_with_ebook2cw words
60
+ words = words.delete("\n")
61
+ cl = Cl.new.cl_echo(words)
62
+ ! @dry_run ? `#{cl}` : cl
63
+ File.rename(play_filename + '0000.mp3', play_filename)
64
+ end
61
65
 
62
- #FIXME dry_run
63
- def play
64
- cmd = play_command + ' ' + play_filename
65
- @pid = ! @dry_run ? Process.spawn(cmd) : cmd
66
- end
66
+ def convert_words words
67
+ tone.generate words unless Cfg.config["use_ebook2cw"]
68
+ convert_words_with_ebook2cw words if Cfg.config["use_ebook2cw"]
69
+ end
67
70
 
68
- def stop
69
- begin
70
- Process.kill(:TERM, @pid)
71
- Process.wait(@pid)
72
- rescue
73
- # puts 'Error: Failed to kill pid ' + @pid.to_s
74
- exit 1
71
+ def play_filename
72
+ return play_filename_for_ebook2cw if Cfg.config["use_ebook2cw"]
73
+ tone.play_filename
75
74
  end
76
- end
77
75
 
78
- def play_tone tone
79
- `#{play_command + ' ' + tone}`
80
- end
76
+ #FIXME dry_run
77
+ def play
78
+ cmd = play_command + ' ' + play_filename
79
+ @pid = ! @dry_run ? Process.spawn(cmd) : cmd
80
+ Process.waitpid(@pid)
81
+ end
81
82
 
82
- def play_cmd_for_ps
83
- '[' << play_command[0] << ']' << play_command[1..-1]
84
- end
83
+ def stop
84
+ begin
85
+ Process.kill(:TERM, @pid)
86
+ Process.wait(@pid)
87
+ rescue
88
+ end
89
+ end
85
90
 
86
- def still_playing?
87
- ps = `ps -ewwo pid,args | grep #{play_cmd_for_ps}`
88
- return ps.include? "#{play_filename_for_ebook2cw}" if Params.use_ebook2cw
89
- return ps.include? tone.play_filename unless Params.use_ebook2cw
90
- end
91
+ def play_tone tone
92
+ `#{play_command + ' ' + tone}`
93
+ end
91
94
 
92
- def startup_delay
93
- 0.2
95
+ def play_cmd_for_ps
96
+ '[' << play_command[0] << ']' << play_command[1..-1]
97
+ end
98
+
99
+ def still_playing?
100
+ cl = "ps -eo pid,args | grep #{play_cmd_for_ps}"
101
+ ps = `#{cl}`
102
+ return ps.include?("#{play_filename_for_ebook2cw}") if Cfg.config["use_ebook2cw"]
103
+ return ps.include?(tone.play_filename) unless Cfg.config["use_ebook2cw"]
104
+ end
94
105
  end
95
106
  end
@@ -1,227 +1,202 @@
1
1
  # encoding: utf-8
2
2
 
3
- class Book < FileDetails
4
-
5
- include Tester
6
-
7
- def initialize book_details
8
- # prn.print_advice('Test Words')
9
- @book_details = book_details
10
- @print_letters = Params.print_letters
11
- super()
12
- read_book book_location
13
- find_sentences
14
- # print_book_advice
15
- end
3
+ module CWG
16
4
 
17
- def sentence ; @sentence ||= Sentence.new ; end
18
- def find_sentences ; sentence.find_all ; end
19
- def raw_text ; sentence.text ; end
20
- def read_book(book) ; sentence.read_book(book) ; end
21
- def next_sentence ; sentence.next ; end
22
- def change_sentence ; sentence.change ; end
23
- def change_sentence? ; sentence.change? ; end
24
- def repeat_sentence? ; sentence.repeat? ; end
25
- def current_sentence ; sentence.current ; end
26
- def current_sentence_ary ; sentence.current_to_array ; end
27
- def sentence_index ; sentence.index ; end
28
- def play_repeat_tone ; audio_play_tone @repeat_tone ; end
29
- def audio_play_tone t ; audio.play_tone(t) ; end
30
- def play_r_tone ; audio_play_tone @r_tone ; end
31
- def complete_word? ; get_word_last_char == space ; end
32
- def audio_stop ; audio.stop if audio_still_playing?; end
33
- def book_location ; @book_details.book_location ; end
34
- def print_letters? ; @print_letters && ! quit? ; end
35
- def reset_sentence_flags ; sentence.reset_flags ; end
36
- def audio_play_sentence ; audio.play ; end
37
- def print_book_advice ; print.print_advice('Play Book') ; end
38
-
39
- def convert
40
- book = @sentence.all.join
41
- audio.convert_book(book)
42
- end
5
+ class Book < Tester
43
6
 
44
- def change_or_repeat_sentence?
45
- sentence.change_or_repeat?
46
- end
7
+ include FileDetails
47
8
 
48
- def change_repeat_or_quit?
49
- if(change_or_repeat_sentence? || quit?)
50
- sentence.index += 1
51
- write_book_progress
52
- return true
9
+ def initialize book_details
10
+ init_filenames
11
+ @book_details = book_details
12
+ read_book book_location
13
+ find_sentences
53
14
  end
54
- false
55
- end
56
15
 
57
- def check_sentence_navigation chr
58
- sentence.check_sentence_navigation chr
59
- end
16
+ def sentence ; @sentence ||= Sentence.new ; end
17
+ def find_sentences ; sentence.find_all ; end
18
+ def read_book(book) ; sentence.read_book(book) ; end
19
+ def play_repeat_tone ; play.audio.play_tone @repeat_tone ; end
20
+ def complete_word? ; get_word_last_char == ' ' ; end
21
+ def book_location ; @book_details.book_location ; end
22
+ def print_book_advice ; print.print_advice('Play Book') ; end
23
+
24
+ def convert
25
+ book = @sentence.all.join
26
+ play.audio.convert_book(book)
27
+ end
60
28
 
61
- def progress_file
62
- File.expand_path(@progress_file, @text_folder)
63
- end
29
+ def change_or_repeat_sentence?
30
+ sentence.change_or_repeat?
31
+ end
64
32
 
65
- def get_book_progress
66
- sentence.read_progress progress_file
67
- @current_sentence_index = sentence_index
68
- end
33
+ def change_repeat_or_quit?
34
+ if(change_or_repeat_sentence? || quit?)
35
+ sentence.index += 1
36
+ write_book_progress
37
+ return true
38
+ end
39
+ false
40
+ end
69
41
 
70
- def write_book_progress
71
- sentence.write_progress progress_file
72
- end
42
+ def check_sentence_navigation chr
43
+ sentence.check_sentence_navigation chr
44
+ end
73
45
 
74
- def audio_play_repeat_tone_maybe
75
- play_repeat_tone if repeat_sentence?
76
- end
46
+ def progress_file
47
+ File.expand_path(@progress_file, @text_folder)
48
+ end
77
49
 
78
- def monitor_keys
79
- loop do
80
- get_key_input
81
- check_quit_key_input
82
- break if quit?
83
- check_sentence_navigation key_chr
84
- build_word_maybe
50
+ def get_book_progress
51
+ sentence.read_progress progress_file
52
+ @current_sentence_index = sentence.index
85
53
  end
86
- end
87
54
 
88
- def process_input_word_maybe
89
- if @word_to_process
90
- if @book_details.args[:output] == :letter
91
- stream.match_first_active_element @process_input_word # .strip #todo
92
- else
93
- stream.match_last_active_element @process_input_word.strip #todo
94
- end
95
- @process_input_word = @word_to_process = nil
55
+ def write_book_progress
56
+ sentence.write_progress progress_file
96
57
  end
97
- end
98
58
 
99
- def build_word_maybe
100
- @input_word ||= empty_string
101
- @input_word << key_chr if is_relevant_char?
102
- if @book_details.args[:output] == :letter
103
- move_word_to_process if is_relevant_char? #todo
104
- else
105
- move_word_to_process if complete_word?
59
+ def audio_play_repeat_tone_maybe
60
+ play_repeat_tone if sentence.repeat?
106
61
  end
107
- end
108
62
 
109
- def add_space sentence
110
- sentence + space
111
- end
63
+ def process_input_word_maybe
64
+ if @word_to_process
65
+ if @book_details.args[:output] == :letter
66
+ stream.match_first_active_element @process_input_word # .strip #todo
67
+ else
68
+ stream.match_last_active_element @process_input_word.strip #todo
69
+ end
70
+ @process_input_word = @word_to_process = nil
71
+ end
72
+ end
112
73
 
113
- def compile_sentence
114
- audio.convert_words(add_space(current_sentence))
115
- end
74
+ def build_word_maybe
75
+ @input_word ||= ''
76
+ @input_word << key_chr if is_relevant_char?
77
+ if @book_details.args[:output] == :letter
78
+ move_word_to_process if is_relevant_char? #todo
79
+ else
80
+ move_word_to_process if complete_word?
81
+ end
82
+ end
116
83
 
117
- def compile_and_play
118
- compile_sentence
119
- audio_play_sentence
120
- start_sync
121
- end
84
+ def compile_sentence
85
+ play.audio.convert_words(sentence.current + ' ')
86
+ end
122
87
 
123
- def change_and_kill_audio
124
- change_sentence
125
- audio_stop
126
- end
88
+ def compile_and_play
89
+ compile_sentence
90
+ play.start_sync()
91
+ play.audio.play
92
+ end
127
93
 
128
- def next_sentence_or_quit?
129
- playing = audio_still_playing?
130
- sleep 0.01 if playing
131
- next_sentence unless playing
132
- if change_repeat_or_quit?
133
- change_and_kill_audio
134
- #todo prn.newline unless quit?
135
- return true
94
+ # def change_and_kill_audio
95
+ # sentence.change
96
+ # play.stop
97
+ # end
98
+
99
+ def next_sentence_or_quit?
100
+ sleep 0.01 if play.still_playing?
101
+ sentence.next unless play.still_playing?
102
+ if change_repeat_or_quit?
103
+ play.stop
104
+ # quit #todo
105
+ sentence.change unless quit?
106
+ # change_and_kill_audio
107
+ #todo prn.newline unless quit?
108
+ return true
109
+ end
136
110
  end
137
- end
138
111
 
139
- def await_next_sentence_or_quit
140
- loop do
141
- break if next_sentence_or_quit?
112
+ def await_next_sentence_or_quit
113
+ loop do
114
+ break if next_sentence_or_quit?
115
+ sleep 0.01
116
+ end
142
117
  end
143
- end
144
118
 
145
- def quit_or_process_input?
146
- quit? || @word_to_process
147
- end
119
+ def quit_or_process_input?
120
+ quit? || @word_to_process
121
+ end
148
122
 
149
- def process_letter letr
150
- current_word.process_letter letr
151
- sleep_char_delay letr
152
- end
123
+ def process_letter letr
124
+ current_word.process_letter letr
125
+ sleep_char_delay letr
126
+ end
153
127
 
154
- def print_marked_maybe
155
- @popped = stream.pop_next_marked
156
- if @book_details.args[:output] == :letter
157
- print.char_result(@popped) if(@popped && ! print_letters?) #todo
158
- else
159
- print.results(@popped) if(@popped && ! print_letters?)
128
+ def print_marked_maybe
129
+ @popped = stream.pop_next_marked
130
+ if @book_details.args[:output] == :letter
131
+ print.char_result(@popped) if(@popped && ! print_letters?) #todo
132
+ else
133
+ print.results(@popped) if(@popped && ! print_letters?)
134
+ end
160
135
  end
161
- end
162
136
 
163
- def print_words_for_current_sentence
164
- print_words current_sentence
165
- end
137
+ def print_words_for_current_sentence
138
+ print_words(sentence.current)
139
+ end
166
140
 
167
- def make_sentence_index_current
168
- @current_sentence_index = sentence_index
169
- end
141
+ def make_sentence_index_current
142
+ @current_sentence_index = sentence.index
143
+ end
170
144
 
171
- def sentence_index_current?
172
- @current_sentence_index && (@current_sentence_index == sentence_index)
173
- end
145
+ def sentence_index_current?
146
+ @current_sentence_index && (@current_sentence_index == sentence.index)
147
+ end
174
148
 
175
- def play_sentences_until_quit
176
- get_book_progress
177
- loop do
178
- check_sentence_count
179
- sync_with_print
180
- audio_play_repeat_tone_maybe
181
- reset_sentence_flags
182
- compile_and_play
183
- await_next_sentence_or_quit
184
- break if quit?
185
- end
186
- print_words_exit unless @print_letters
187
- end
149
+ def play_sentences_until_quit
150
+ get_book_progress
151
+
152
+ loop do
153
+ check_sentence_count
154
+ sync_with_print
155
+ audio_play_repeat_tone_maybe
156
+ sentence.reset_flags
157
+ compile_and_play
158
+ await_next_sentence_or_quit
159
+ break if quit?
160
+ end
161
+ print_words_exit
162
+ end
188
163
 
189
- def check_sentence_count
190
- if @book_details.session_finished?
191
- audio_stop
192
- quit
193
- reset_stdin
194
- kill_threads
164
+ def check_sentence_count
165
+ if @book_details.session_finished?
166
+ play.stop
167
+ quit
168
+ # reset_stdin
169
+ # kill_threads
170
+ end
195
171
  end
196
- end
197
172
 
198
- def print_sentences_until_quit
199
- loop do
200
- check_sentence_count
201
- sync_with_play
202
- break if quit?
203
- sync_with_audio_player
204
- print_words_for_current_sentence
205
- print.reset
173
+ def print_sentences_until_quit
174
+ loop do
175
+ check_sentence_count
176
+ sync_with_play
177
+ break if quit?
178
+ sync_with_audio_player
179
+ print_words_for_current_sentence
180
+ end
206
181
  end
207
- end
208
182
 
209
- def play_sentences_thread
210
- play_sentences_until_quit
211
- # kill_threads
212
- print "\n\rplay has quit " if @debug
213
- end
183
+ def play_sentences_thread
184
+ play_sentences_until_quit
185
+ print "\n\rplay has quit " if @debug
186
+ exit!
187
+ end
214
188
 
215
- def print_sentences_thread
216
- print_sentences_until_quit
217
- kill_threads
218
- print "\n\rprint has quit " if @debug
219
- end
189
+ def print_sentences_thread
190
+ print_sentences_until_quit
191
+ print "\n\rprint has quit " if @debug
192
+ exit!
193
+ end
220
194
 
221
- def thread_processes
222
- [:monitor_keys_thread,
223
- :play_sentences_thread,
224
- :print_sentences_thread]
195
+ def thread_processes
196
+ [:monitor_keys_thread,
197
+ :play_sentences_thread,
198
+ :print_sentences_thread
199
+ ]
200
+ end
225
201
  end
226
-
227
202
  end