class CW::ToneGenerator

Constants

MUTE

Attributes

code[R]

Public Class Methods

new() click to toggle source
# File lib/cw/tone_generator.rb, line 38
def initialize
  @sample_rate = 2400
  @max_amplitude = (Cfg.config["volume"].to_f > 1.0 ?
                      1.0 : Cfg.config["volume"].to_f)
  @wpm = Cfg.config["wpm"].to_f
  @frequency = Cfg.config["frequency"].to_i
  @effective_wpm = Cfg.config["effective_wpm"] ?
                     Cfg.config["effective_wpm"].to_f : @wpm
  @print = Print.new
end

Public Instance Methods

char_space() click to toggle source
# File lib/cw/tone_generator.rb, line 166
def char_space
  Array.new(2, word_space)
end
compile_fundamentals() click to toggle source
# File lib/cw/tone_generator.rb, line 111
def compile_fundamentals
  elements.each do |ele|
    audio_samples = generate_samples ele
    buffer = generate_buffer(audio_samples, ele)
    write_element_audio_file ele, buffer
  end
end
cw_encoding() click to toggle source
# File lib/cw/tone_generator.rb, line 63
def cw_encoding
  @encoding ||= Encoding.new
end
elements() click to toggle source
# File lib/cw/tone_generator.rb, line 102
def elements
  [:dot, :dash, :space, :e_space]
end
ewpm?() click to toggle source
# File lib/cw/tone_generator.rb, line 119
def ewpm?
  @effective_wpm != @wpm
end
filter_maybe(size, count) click to toggle source
# File lib/cw/tone_generator.rb, line 71
def filter_maybe(size, count)
  ramp = 0.05
  ramp_point =  @max_amplitude / ramp
  ampl = (count < ramp_point) ? (ramp * count) : @max_amplitude
  (count > (size - ramp_point)) ? (ramp * (size - count)) : ampl
end
format() click to toggle source
# File lib/cw/tone_generator.rb, line 178
def format
  WaveFile::Format.new(:mono, :pcm_16, @sample_rate)
end
generate(wrds) click to toggle source
# File lib/cw/tone_generator.rb, line 53
def generate wrds
  word_parts(wrds)
  compile_fundamentals
  write_word_parts
end
generate_buffer(audio_samples, ele) click to toggle source
# File lib/cw/tone_generator.rb, line 90
def generate_buffer audio_samples, ele
  WaveFile::Buffer.new(audio_samples,
                       WaveFile::Format.new(:mono, :float, code.spb(ele)))
end
generate_samples(ele) click to toggle source
# File lib/cw/tone_generator.rb, line 106
def generate_samples ele
  return generate_space(code.spb(ele)) if space_sample? ele
  generate_tone(code.spb(ele))     unless space_sample? ele
end
generate_tone(number_of_samples) click to toggle source
# File lib/cw/tone_generator.rb, line 78
def generate_tone(number_of_samples)
  audio_samples = [].fill(0.0, 0, number_of_samples)
  number_of_samples.times do |sample_number|
    amplitude = filter_maybe(number_of_samples, sample_number)
    #      amplitude = 1.0 # @max_amplitude
    #      amplitude = 0.01 if MUTE
    sine_radians = ((@frequency * TWO_PI) / @sample_rate) * sample_number
    audio_samples[sample_number] = amplitude * Math.sin(sine_radians)
  end
  audio_samples
end
play_filename() click to toggle source
# File lib/cw/tone_generator.rb, line 59
def play_filename
  @play_filename ||= File.join(audio_dir, audio_filename)
end
prepare_buffers() click to toggle source
# File lib/cw/tone_generator.rb, line 150
def prepare_buffers
  @buffers = {}
  elements.each do |ele|
    @buffers[ele] = []
    WaveFile::Reader.new(code.filename(ele))
                    .each_buffer(code.spb(ele)) do |buffer|
      @buffers[ele] = buffer
    end
  end
end
progress() click to toggle source
# File lib/cw/tone_generator.rb, line 67
def progress
  @progress ||= Progress.new('Compiling')
end
push_enc(chr) click to toggle source
# File lib/cw/tone_generator.rb, line 127
def push_enc chr
  arry = []
  chr.each_with_index do |c,idx|
    arry << c
    arry << (last_element?(idx, chr) ? space_or_espace : { name: :space })
  end
  arry += char_space
end
reset() click to toggle source
# File lib/cw/tone_generator.rb, line 199
def reset
  @word_parts = @progress = nil
end
send_char(c) click to toggle source
# File lib/cw/tone_generator.rb, line 136
def send_char(c)
  enc = c == ' ' ? [word_space] : cw_encoding.fetch(c).map { |e|
    { :name => e }
  }
  push_enc enc
end
space_or_espace() click to toggle source
# File lib/cw/tone_generator.rb, line 123
def space_or_espace
  { name: (ewpm? ? :e_space : :space) }
end
word_composite(word) click to toggle source
# File lib/cw/tone_generator.rb, line 174
def word_composite(word)
  send_char word.downcase
end
word_parts(str = nil) click to toggle source
# File lib/cw/tone_generator.rb, line 143
def word_parts(str = nil)
  return @word_parts if @word_parts
  @word_parts = []
  str.split('').each { |part| @word_parts << part }
  @word_parts
end
word_space() click to toggle source
# File lib/cw/tone_generator.rb, line 170
def word_space
  { name: (ewpm? ? :e_space : :space) }
end
write_audio() { || ... } click to toggle source
# File lib/cw/tone_generator.rb, line 186
def write_audio
  WaveFile::Writer.new(play_filename, format) do |writer|
    yield.map { |ch| ch.map { |fta| write_buffer(writer, fta) } }
  end
end
write_audio_file() click to toggle source
# File lib/cw/tone_generator.rb, line 192
def write_audio_file
  write_audio do
    @word_parts.collect { |part| word_composite(part) }
  end
  reset
end
write_buffer(writer, fta) click to toggle source
# File lib/cw/tone_generator.rb, line 182
def write_buffer(writer, fta)
  writer.write(@buffers[fta[:name]])
end
write_element_audio_file(ele, buffer) click to toggle source
# File lib/cw/tone_generator.rb, line 95
def write_element_audio_file ele, buffer
  WaveFile::Writer.new(code.filename(ele),
                       WaveFile::Format.new(:mono, :pcm_16, @sample_rate)) do |writer|
    writer.write(buffer)
  end
end
write_word_parts() click to toggle source
# File lib/cw/tone_generator.rb, line 161
def write_word_parts
  prepare_buffers
  write_audio_file
end