Class: Deftones::Source::UserMedia::PortAudioCapture

Inherits:
Object
  • Object
show all
Defined in:
lib/deftones/source/user_media.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(sample_rate:, buffer_size:, channels: 1) ⇒ PortAudioCapture

Returns a new instance of PortAudioCapture.



445
446
447
448
449
450
451
452
453
454
455
456
457
# File 'lib/deftones/source/user_media.rb', line 445

def initialize(sample_rate:, buffer_size:, channels: 1)
  @sample_rate = sample_rate
  @buffer_size = buffer_size
  @channels = [channels.to_i, 1].max
  @queue = Queue.new
  @max_frames = buffer_size * 64
  @stream = nil
  @device_id = nil
  @group_id = nil
  @label = nil
  @underflow_count = 0
  @overflow_count = 0
end

Instance Attribute Details

#channelsObject (readonly)

Returns the value of attribute channels.



443
444
445
# File 'lib/deftones/source/user_media.rb', line 443

def channels
  @channels
end

#device_idObject (readonly)

Returns the value of attribute device_id.



443
444
445
# File 'lib/deftones/source/user_media.rb', line 443

def device_id
  @device_id
end

#group_idObject (readonly)

Returns the value of attribute group_id.



443
444
445
# File 'lib/deftones/source/user_media.rb', line 443

def group_id
  @group_id
end

#labelObject (readonly)

Returns the value of attribute label.



443
444
445
# File 'lib/deftones/source/user_media.rb', line 443

def label
  @label
end

#overflow_countObject (readonly)

Returns the value of attribute overflow_count.



443
444
445
# File 'lib/deftones/source/user_media.rb', line 443

def overflow_count
  @overflow_count
end

#underflow_countObject (readonly)

Returns the value of attribute underflow_count.



443
444
445
# File 'lib/deftones/source/user_media.rb', line 443

def underflow_count
  @underflow_count
end

Instance Method Details

#assign_device_metadata(device) ⇒ Object (private)



551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
# File 'lib/deftones/source/user_media.rb', line 551

def (device)
  return unless device

  @device_id ||= if device.respond_to?(:device_id)
    device.device_id
  elsif device.respond_to?(:index)
    device.index
  elsif device.respond_to?(:device_index)
    device.device_index
  end
  @label ||= if device.respond_to?(:label)
    device.label
  elsif device.respond_to?(:name)
    device.name
  end
  @group_id ||= if device.respond_to?(:group_id)
    device.group_id
  elsif device.respond_to?(:host_api)
    device.host_api
  elsif device.respond_to?(:host_api_name)
    device.host_api_name
  end
end

#clear_queueObject (private)



584
585
586
587
588
# File 'lib/deftones/source/user_media.rb', line 584

def clear_queue
  @queue.pop(true) while true
rescue ThreadError
  nil
end

#closeObject



493
494
495
496
497
498
499
500
501
502
503
# File 'lib/deftones/source/user_media.rb', line 493

def close
  return self unless @stream

  stream = @stream
  @stream = nil
  clear_queue
  stream.close
  self
ensure
  Deftones::PortAudioSupport.release
end

#next_frameObject



510
511
512
513
514
515
# File 'lib/deftones/source/user_media.rb', line 510

def next_frame
  @queue.pop(true)
rescue ThreadError
  @underflow_count += 1
  Array.new(@channels, 0.0)
end

#next_sampleObject



505
506
507
508
# File 'lib/deftones/source/user_media.rb', line 505

def next_sample
  frame = next_frame
  frame.sum / [frame.length, 1].max.to_f
end

#open(device_id: nil, group_id: nil, label: nil, channels: nil) ⇒ Object



459
460
461
462
463
464
465
466
# File 'lib/deftones/source/user_media.rb', line 459

def open(device_id: nil, group_id: nil, label: nil, channels: nil)
  @device_id = device_id unless device_id.nil?
  @group_id = group_id unless group_id.nil?
  @label = label unless label.nil?
  @channels = [channels.to_i, 1].max unless channels.nil?
  close if @stream
  self
end

#open_streamObject (private)



519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
# File 'lib/deftones/source/user_media.rb', line 519

def open_stream
  Deftones::PortAudioSupport.acquire!
  input_parameters = Deftones::PortAudioSupport.input_parameters(
    @channels,
    device_id: @device_id,
    label: @label,
    sample_rate: @sample_rate
  )
  (input_parameters[:device])
  @stream = PortAudio::Stream.new(
    input: input_parameters,
    sample_rate: @sample_rate.to_f,
    frames_per_buffer: @buffer_size,
    &method(:process)
  )
rescue StandardError
  Deftones::PortAudioSupport.release
  raise
end

#process(input, _output, frame_count, _time_info, _status_flags, _user_data) ⇒ Object (private)



539
540
541
542
543
544
545
546
547
548
549
# File 'lib/deftones/source/user_media.rb', line 539

def process(input, _output, frame_count, _time_info, _status_flags, _user_data)
  return :continue if input.null?

  input.read_array_of_float(frame_count * @channels).each_slice(@channels) do |frame|
    @queue << frame.map(&:to_f)
  end
  trim_queue!
  :continue
rescue StandardError
  :abort
end

#reset_statsObject



487
488
489
490
491
# File 'lib/deftones/source/user_media.rb', line 487

def reset_stats
  @underflow_count = 0
  @overflow_count = 0
  self
end

#rewindObject



482
483
484
485
# File 'lib/deftones/source/user_media.rb', line 482

def rewind
  clear_queue
  self
end

#startObject



468
469
470
471
472
# File 'lib/deftones/source/user_media.rb', line 468

def start
  open_stream unless @stream
  @stream.start
  self
end

#stopObject



474
475
476
477
478
479
480
# File 'lib/deftones/source/user_media.rb', line 474

def stop
  return self unless @stream
  return self if @stream.stopped?

  @stream.stop
  self
end

#trim_queue!Object (private)



575
576
577
578
579
580
581
582
# File 'lib/deftones/source/user_media.rb', line 575

def trim_queue!
  while @queue.size > @max_frames
    @queue.pop(true)
    @overflow_count += 1
  end
rescue ThreadError
  nil
end