Class: Vizcore::Audio::PortAudioFFI::Stream

Inherits:
Object
  • Object
show all
Defined in:
lib/vizcore/audio/portaudio_ffi.rb

Overview

Runtime wrapper for an opened PortAudio input stream.

Constant Summary collapse

PA_INPUT_OVERFLOWED =
-9981

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(mod:, pointer:, channels:) ⇒ Stream

Returns a new instance of Stream.

Parameters:

  • mod (Module)

    ffi-bound PortAudio module

  • pointer (FFI::Pointer)

    native stream pointer

  • channels (Integer)

    input channel count



14
15
16
17
18
19
20
# File 'lib/vizcore/audio/portaudio_ffi.rb', line 14

def initialize(mod:, pointer:, channels:)
  @mod = mod
  @pointer = pointer
  @channels = channels
  @started = false
  @closed = false
end

Class Method Details

.ffi_moduleModule

Returns loaded ffi module.

Returns:

  • (Module)

    loaded ffi module



98
99
100
101
# File 'lib/vizcore/audio/portaudio_ffi.rb', line 98

def ffi_module
  require "ffi"
  FFI
end

.pa_input_overflowedObject

PortAudio returns this when input data was dropped before this read, but the current read buffer can still contain usable samples.



110
111
112
# File 'lib/vizcore/audio/portaudio_ffi.rb', line 110

def pa_input_overflowed
  PA_INPUT_OVERFLOWED
end

.pa_no_errorInteger

Returns:

  • (Integer)


104
105
106
# File 'lib/vizcore/audio/portaudio_ffi.rb', line 104

def pa_no_error
  0
end

Instance Method Details

#closevoid

This method returns an undefined value.



64
65
66
67
68
69
70
71
72
# File 'lib/vizcore/audio/portaudio_ffi.rb', line 64

def close
  return if @closed

  stop
  @mod.Pa_CloseStream(@pointer) unless @pointer.nil? || @pointer.null?
  @closed = true
rescue StandardError
  @closed = true
end

#read(frame_size) ⇒ Array<Float>

Returns mono samples or silence on failure.

Parameters:

  • frame_size (Integer)

Returns:

  • (Array<Float>)

    mono samples or silence on failure



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/vizcore/audio/portaudio_ffi.rb', line 36

def read(frame_size)
  frames = Integer(frame_size)
  return Array.new(frames, 0.0) unless @started

  buffer = ffi_module::MemoryPointer.new(:float, frames * @channels)
  result = @mod.Pa_ReadStream(@pointer, buffer, frames)
  return Array.new(frames, 0.0) unless readable_result?(result)

  samples = buffer.read_array_of_float(frames * @channels)
  return samples if @channels == 1

  downmix(samples, frames)
rescue StandardError
  Array.new(frames, 0.0)
end

#startBoolean

Returns true when stream start succeeded.

Returns:

  • (Boolean)

    true when stream start succeeded



23
24
25
26
27
28
29
30
31
32
# File 'lib/vizcore/audio/portaudio_ffi.rb', line 23

def start
  return true if @started
  return false if @closed

  result = @mod.Pa_StartStream(@pointer)
  return false unless ok?(result)

  @started = true
  true
end

#stopBoolean

Returns true when stop call succeeded.

Returns:

  • (Boolean)

    true when stop call succeeded



53
54
55
56
57
58
59
60
61
# File 'lib/vizcore/audio/portaudio_ffi.rb', line 53

def stop
  return true if @closed || !@started

  result = @mod.Pa_StopStream(@pointer)
  @started = false if ok?(result)
  ok?(result)
rescue StandardError
  false
end