Class: AlsaBackup::Recorder

Inherits:
Object
  • Object
show all
Defined in:
lib/alsa_backup/recorder.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file = "record.wav") ⇒ Recorder

Returns a new instance of Recorder.



6
7
8
9
10
11
12
13
14
15
# File 'lib/alsa_backup/recorder.rb', line 6

def initialize(file = "record.wav")
  @file = File.basename(file)
  @directory = File.dirname(file)

  @device = "hw:0"
  @sample_rate = 44100
  @channels = 2

  @error_handler = Proc.new { |e| true }
end

Instance Attribute Details

#buffer_timeObject

Returns the value of attribute buffer_time.



18
19
20
# File 'lib/alsa_backup/recorder.rb', line 18

def buffer_time
  @buffer_time
end

#channelsObject

Returns the value of attribute channels.



18
19
20
# File 'lib/alsa_backup/recorder.rb', line 18

def channels
  @channels
end

#deviceObject

Returns the value of attribute device.



18
19
20
# File 'lib/alsa_backup/recorder.rb', line 18

def device
  @device
end

#directoryObject

Returns the value of attribute directory.



17
18
19
# File 'lib/alsa_backup/recorder.rb', line 17

def directory
  @directory
end

#error_handlerObject

Returns the value of attribute error_handler.



17
18
19
# File 'lib/alsa_backup/recorder.rb', line 17

def error_handler
  @error_handler
end

#fileObject

Returns the value of attribute file.



17
18
19
# File 'lib/alsa_backup/recorder.rb', line 17

def file
  @file
end

#period_timeObject

Returns the value of attribute period_time.



18
19
20
# File 'lib/alsa_backup/recorder.rb', line 18

def period_time
  @period_time
end

#sample_rateObject

Returns the value of attribute sample_rate.



18
19
20
# File 'lib/alsa_backup/recorder.rb', line 18

def sample_rate
  @sample_rate
end

Instance Method Details

#alsa_optionsObject



45
46
47
48
49
50
# File 'lib/alsa_backup/recorder.rb', line 45

def alsa_options
  format(:sample_format => :s16_le).tap do |alsa_options|
    alsa_options[:buffer_time] = buffer_time if buffer_time
    alsa_options[:period_time] = period_time if period_time
  end
end

#continue_on_error?(e) ⇒ Boolean

Returns:

  • (Boolean)


68
69
70
71
72
73
74
75
76
77
78
# File 'lib/alsa_backup/recorder.rb', line 68

def continue_on_error?(e)
  error_handler_response = @error_handler.call(e) if @error_handler

  if error_handler_response
    sleep_time = Numeric === error_handler_response ? error_handler_response : 5
    AlsaBackup.logger.warn("sleep #{sleep_time}s before retrying")
    sleep sleep_time
  end

  error_handler_response
end

#format(additional_parameters = {}) ⇒ Object



80
81
82
# File 'lib/alsa_backup/recorder.rb', line 80

def format(additional_parameters = {})
  {:sample_rate => sample_rate, :channels => channels}.merge(additional_parameters)
end

#handle_error(e, try_to_continue = true) ⇒ Object



52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/alsa_backup/recorder.rb', line 52

def handle_error(e, try_to_continue = true)
  if Interrupt === e or SignalException === e
    AlsaBackup.logger.debug('recorder interrupted')      
    return false 
  end

  AlsaBackup.logger.error(e)
  AlsaBackup.logger.debug { e.backtrace.join("\n") }

  if try_to_continue and continue_on_error?(e)
    return true
  else
    raise e
  end
end

#length_controller(seconds_to_record) ⇒ Object



84
85
86
87
88
89
90
# File 'lib/alsa_backup/recorder.rb', line 84

def length_controller(seconds_to_record)
  if seconds_to_record
    AlsaBackup::LengthController::FrameCount.new format[:sample_rate] * seconds_to_record 
  else
    AlsaBackup::LengthController::Loop.new
  end
end

#on_close(&block) ⇒ Object



92
93
94
# File 'lib/alsa_backup/recorder.rb', line 92

def on_close(&block)
  @on_close = block
end

#open_capture(&block) ⇒ Object



41
42
43
# File 'lib/alsa_backup/recorder.rb', line 41

def open_capture(&block)
  ALSA::PCM::Capture.open(device, alsa_options, &block)      
end

#open_writer(&block) ⇒ Object



35
36
37
38
39
# File 'lib/alsa_backup/recorder.rb', line 35

def open_writer(&block)
  writer_options = { :directory => directory, :file => file, :format => format(:format => "wav pcm_16") }
  writer_options[:on_close] = @on_close if @on_close
  Writer.open(writer_options, &block)
end

#start(seconds_to_record = nil) ⇒ Object



20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/alsa_backup/recorder.rb', line 20

def start(seconds_to_record = nil)
  length_controller = self.length_controller(seconds_to_record)

  open_writer do |writer|
    open_capture do |capture|
      capture.read do |buffer, frame_count|
        writer.write buffer, frame_count*format[:channels]
        length_controller.continue_after? frame_count
      end
    end
  end
rescue Exception => e
  retry if handle_error(e, seconds_to_record.nil?)
end