Class: TorchCodec::Decoders::AudioDecoder

Inherits:
Object
  • Object
show all
Defined in:
lib/torchcodec/decoders/audio_decoder.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source, stream_index: nil, sample_rate: nil, num_channels: nil) ⇒ AudioDecoder

Returns a new instance of AudioDecoder.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/torchcodec/decoders/audio_decoder.rb', line 6

def initialize(
  source,
  stream_index: nil,
  sample_rate: nil,
  num_channels: nil
)
  @decoder = Decoders.create_decoder(source, "approximate")

   = Core.(@decoder)
  @stream_index =
    stream_index.nil? ? [:best_audio_stream_index] : stream_index
  if @stream_index.nil?
    raise ArgumentError, "The best audio stream is unknown and there is no specified stream."
  end
  if @stream_index >= [:streams].length
    raise ArgumentError, "The stream at index #{@stream_index} is not a valid stream."
  end

  @metadata = [:streams][@stream_index]
  if !@metadata.key?(:sample_rate)
    raise ArgumentError, "The stream at index #{@stream_index} is not an audio stream."
  end

  @desired_sample_rate =
    !sample_rate.nil? ? sample_rate : @metadata[:sample_rate]

  Core.add_audio_stream(
    @decoder,
    stream_index,
    sample_rate,
    num_channels
  )
end

Instance Attribute Details

#metadataObject (readonly)

Returns the value of attribute metadata.



4
5
6
# File 'lib/torchcodec/decoders/audio_decoder.rb', line 4

def 
  @metadata
end

Instance Method Details

#get_all_samplesObject



40
41
42
# File 'lib/torchcodec/decoders/audio_decoder.rb', line 40

def get_all_samples
  get_samples_played_in_range
end

#get_samples_played_in_range(start_seconds: 0.0, stop_seconds: nil) ⇒ Object



44
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
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/torchcodec/decoders/audio_decoder.rb', line 44

def get_samples_played_in_range(start_seconds: 0.0, stop_seconds: nil)
  if !stop_seconds.nil? && !(start_seconds <= stop_seconds)
    raise ArgumentError, "Invalid start seconds: #{start_seconds}. It must be less than or equal to stop seconds (#{stop_seconds})."
  end
  frames, first_pts = Core.get_frames_by_pts_in_range_audio(
    @decoder,
    start_seconds,
    stop_seconds
  )
  first_pts = first_pts.item

  sample_rate = @desired_sample_rate
  # TODO: metadata's sample_rate should probably not be Optional
  raise if sample_rate.nil?

  if first_pts < start_seconds
    offset_beginning = ((start_seconds - first_pts) * sample_rate).round
    output_pts_seconds = start_seconds
  else
    # In normal cases we'll have first_pts <= start_pts, but in some
    # edge cases it's possible to have first_pts > start_seconds,
    # typically if the stream's first frame's pts isn't exactly 0.
    offset_beginning = 0
    output_pts_seconds = first_pts
  end

  num_samples = frames.shape[1]
  last_pts = first_pts + num_samples / sample_rate
  if !stop_seconds.nil? && stop_seconds < last_pts
    offset_end = num_samples - ((last_pts - stop_seconds) * sample_rate).round
  else
    offset_end = num_samples
  end

  data = frames[0.., offset_beginning...offset_end]
  {
    data: data,
    pts_seconds: output_pts_seconds,
    duration_seconds: data.shape[1] / sample_rate.to_f,
    sample_rate: sample_rate
  }
end