Module: Vizcore::Audio::PortAudioFFI
Overview
PortAudio FFI bridge for microphone stream access and device discovery.
Defined Under Namespace
Classes: Stream
Constant Summary collapse
- DEFAULT_CHANNELS =
Default mono channel count.
1- PA_NO_ERROR =
PortAudio no-error status code.
0- PA_FLOAT_32 =
PortAudio float sample format code.
0x0000_0001- PA_NO_FLAGS =
PortAudio stream flags.
0
Instance Method Summary collapse
-
#available? ⇒ Boolean
True when PortAudio native library can be loaded.
- #close_stream(stream) ⇒ nil
-
#input_devices ⇒ Array<Hash>
Available input device descriptors.
- #open_default_input_stream(sample_rate:, channels: DEFAULT_CHANNELS, frames_per_buffer: 1024) ⇒ Vizcore::Audio::PortAudioFFI::Stream?
- #open_input_stream(device:, sample_rate:, channels: DEFAULT_CHANNELS, frames_per_buffer: 1024) ⇒ Vizcore::Audio::PortAudioFFI::Stream?
Instance Method Details
#available? ⇒ Boolean
Returns true when PortAudio native library can be loaded.
128 129 130 |
# File 'lib/vizcore/audio/portaudio_ffi.rb', line 128 def available? !ffi_module.nil? end |
#close_stream(stream) ⇒ nil
237 238 239 240 241 242 |
# File 'lib/vizcore/audio/portaudio_ffi.rb', line 237 def close_stream(stream) stream&.close ffi_module&.Pa_Terminate rescue StandardError nil end |
#input_devices ⇒ Array<Hash>
Returns available input device descriptors.
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 |
# File 'lib/vizcore/audio/portaudio_ffi.rb', line 133 def input_devices mod = ffi_module return [] unless mod return [] unless ok?(mod.Pa_Initialize) count = mod.Pa_GetDeviceCount return [] if count <= 0 count.times.filter_map do |index| pointer = mod.Pa_GetDeviceInfo(index) next if pointer.null? info = mod::DeviceInfo.new(pointer) next unless info[:maxInputChannels].positive? { index: index, name: info[:name].read_string, max_input_channels: info[:maxInputChannels], default_sample_rate: info[:defaultSampleRate].to_f } end ensure mod&.Pa_Terminate end |
#open_default_input_stream(sample_rate:, channels: DEFAULT_CHANNELS, frames_per_buffer: 1024) ⇒ Vizcore::Audio::PortAudioFFI::Stream?
163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 |
# File 'lib/vizcore/audio/portaudio_ffi.rb', line 163 def open_default_input_stream(sample_rate:, channels: DEFAULT_CHANNELS, frames_per_buffer: 1024) mod = ffi_module return nil unless mod return nil unless ok?(mod.Pa_Initialize) stream_ptr_ptr = ffi::MemoryPointer.new(:pointer) result = mod.Pa_OpenDefaultStream( stream_ptr_ptr, Integer(channels), 0, PA_FLOAT_32, Float(sample_rate), Integer(frames_per_buffer), nil, nil ) return terminate_with_nil(mod) unless ok?(result) stream_pointer = stream_ptr_ptr.read_pointer return terminate_with_nil(mod) if stream_pointer.null? Stream.new(mod: mod, pointer: stream_pointer, channels: Integer(channels)) rescue StandardError mod&.Pa_Terminate nil end |
#open_input_stream(device:, sample_rate:, channels: DEFAULT_CHANNELS, frames_per_buffer: 1024) ⇒ Vizcore::Audio::PortAudioFFI::Stream?
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 |
# File 'lib/vizcore/audio/portaudio_ffi.rb', line 196 def open_input_stream(device:, sample_rate:, channels: DEFAULT_CHANNELS, frames_per_buffer: 1024) mod = ffi_module return nil unless mod return nil unless ok?(mod.Pa_Initialize) device_info = resolve_input_device(mod, device) return terminate_with_nil(mod) unless device_info device_index, info = device_info actual_channels = [Integer(channels), info[:maxInputChannels]].min input_params = mod::StreamParameters.new input_params[:device] = device_index input_params[:channelCount] = actual_channels input_params[:sampleFormat] = PA_FLOAT_32 input_params[:suggestedLatency] = info[:defaultLowInputLatency].to_f input_params[:hostApiSpecificStreamInfo] = nil stream_ptr_ptr = ffi::MemoryPointer.new(:pointer) result = mod.Pa_OpenStream( stream_ptr_ptr, input_params.to_ptr, nil, Float(sample_rate), Integer(frames_per_buffer), PA_NO_FLAGS, nil, nil ) return terminate_with_nil(mod) unless ok?(result) stream_pointer = stream_ptr_ptr.read_pointer return terminate_with_nil(mod) if stream_pointer.null? Stream.new(mod: mod, pointer: stream_pointer, channels: actual_channels) rescue StandardError mod&.Pa_Terminate nil end |