Class: Radio::Signal::ALSA
- Inherits:
-
Object
- Object
- Radio::Signal::ALSA
- Defined in:
- lib/radio/signals/alsa.rb
Constant Summary collapse
- CP_REGEX =
/:\s*(capture|playback)\s*(\d+)\s*$/
- CD_REGEX =
/^(\d+)-(\d+):\s*/
Class Method Summary collapse
Instance Method Summary collapse
- #in(samples) ⇒ Object
-
#initialize(options) ⇒ ALSA
constructor
A new instance of ALSA.
- #input_channels ⇒ Object
- #output_channels ⇒ Object
- #rate ⇒ Object
- #stop ⇒ Object
Constructor Details
#initialize(options) ⇒ ALSA
Returns a new instance of ALSA.
74 75 76 77 78 79 80 81 |
# File 'lib/radio/signals/alsa.rb', line 74 def initialize @stream = ::ALSA::PCM::Capture.new @stream.open [:id] if input = [:input] @channel_i = input[0] @channel_q = input[1] end end |
Class Method Details
.devices ⇒ Object
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/radio/signals/alsa.rb', line 45 def self.devices return {} unless defined? ::ALSA::PCM # Funky read to get around old Linux bug # http://kerneltrap.org/mailarchive/git-commits-head/2009/4/17/5510664 pcm = ::File.open('/proc/asound/pcm') do |io| io.read_nonblock 32768 end result = {} pcm.each_line do |line| capture = 0 2.times do line.gsub! CP_REGEX, '' capture = $2.to_i if $1 == 'capture' end line.gsub! CD_REGEX, '' device = "hw:#{$1.to_i},#{$2.to_i}" ::ALSA::PCM::Capture.open(device) do |stream| params = stream.hardware_parameters result[device] = { name: line, rates: [params.sample_rate], input: params.channels, output: 0 } end rescue nil end result end |
.status ⇒ Object
27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/radio/signals/alsa.rb', line 27 def self.status if defined? ::ALSA::PCM return "Loaded: %d devices" % devices.count end unless defined? @is_linux @is_linux = (`uname`.strip == 'Linux') rescue false end return "Unsupported: requires Linux" unless @is_linux if defined? ::ALSA 'Unavailable: install ALSA to your OS' else 'Unavailable: gem install ruby-alsa' end end |
Instance Method Details
#in(samples) ⇒ Object
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 |
# File 'lib/radio/signals/alsa.rb', line 96 def in samples out=nil buf_size = @stream.hw_params.buffer_size_for(samples) FFI::MemoryPointer.new(:char, buf_size) do |buffer| @stream.read_buffer buffer, samples out = buffer.read_string(buf_size) NArray.to_na(out, NArray::SINT).to_f.div! 32767 end stream_channels = @stream.hardware_parameters.channels sample_size = buf_size / samples / stream_channels out = case sample_size when 1 then NArray.to_na(out,NArray::BYTE).to_f.collect!{|v|(v-128)/127} when 2 then NArray.to_na(out,NArray::SINT).to_f.div! 32767 # when 3 then NArray.to_na(d,NArray::???).to_f.collect!{|v|(v-8388608)/8388607} else raise "Unsupported sample size: #{@sample_size}" end return out if channels == 1 and stream_channels == 1 out.reshape! stream_channels, out.size/stream_channels if channels == 1 out[@channel_i,true] else c_out = NArray.scomplex out[0,true].size c_out[0..-1] = out[@channel_i,true] c_out.imag = out[@channel_q,true] c_out end end |
#input_channels ⇒ Object
87 88 89 90 |
# File 'lib/radio/signals/alsa.rb', line 87 def input_channels return 2 if @channel_q and @stream.hardware_parameters.channels > 1 1 end |
#output_channels ⇒ Object
92 93 94 |
# File 'lib/radio/signals/alsa.rb', line 92 def output_channels 0 end |
#rate ⇒ Object
83 84 85 |
# File 'lib/radio/signals/alsa.rb', line 83 def rate @stream.hardware_parameters.sample_rate end |
#stop ⇒ Object
125 126 127 |
# File 'lib/radio/signals/alsa.rb', line 125 def stop @stream.close end |