Module: Cohere::Transcribe::Output::Timing
- Defined in:
- lib/cohere/transcribe/output/timing.rb
Class Method Summary collapse
- .proportional_counts(token_count, spans) ⇒ Object
- .spans_within(speech_spans, start_time, end_time) ⇒ Object
- .uniform_words(text, start_time, end_time, segment_index, timing_source = "uniform_segment") ⇒ Object
- .uniform_words_across_spans(text, spans, segment_index, timing_source = "uniform_speech_spans") ⇒ Object
Class Method Details
.proportional_counts(token_count, spans) ⇒ Object
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 |
# File 'lib/cohere/transcribe/output/timing.rb', line 57 def proportional_counts(token_count, spans) raise ArgumentError, "token_count must be non-negative" if token_count.negative? durations = spans.map { |start_time, end_time| [0.0, end_time - start_time].max } total = durations.sum return Array.new(spans.length, 0).freeze if token_count.zero? || total <= 0 exact = durations.map { |duration| token_count * duration.fdiv(total) } counts = exact.map(&:floor) remaining = token_count - counts.sum order = spans.each_index.sort_by do |index| [-(exact[index] - counts[index]), -durations[index], index] end order.first(remaining).each { |index| counts[index] += 1 } counts.freeze end |
.spans_within(speech_spans, start_time, end_time) ⇒ Object
74 75 76 77 78 79 80 81 82 |
# File 'lib/cohere/transcribe/output/timing.rb', line 74 def spans_within(speech_spans, start_time, end_time) speech_spans.filter_map do |speech_start, speech_end| next unless speech_end > start_time && speech_start < end_time clipped_start = [start_time, speech_start].max clipped_end = [end_time, speech_end].min [clipped_start, clipped_end] if clipped_end > clipped_start end.freeze end |
.uniform_words(text, start_time, end_time, segment_index, timing_source = "uniform_segment") ⇒ Object
12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/cohere/transcribe/output/timing.rb', line 12 def uniform_words(text, start_time, end_time, segment_index, timing_source = "uniform_segment") tokens = PythonText.split(text.to_s) return [] if tokens.empty? token_duration = [0.0, end_time - start_time].max.fdiv(tokens.length) tokens.each_with_index.map do |token, index| TranscriptionWord.new( start: start_time + (index * token_duration), end: start_time + ((index + 1) * token_duration), text: token, segment_index: segment_index, segment_word_index: index, timing_source: timing_source ) end.freeze end |
.uniform_words_across_spans(text, spans, segment_index, timing_source = "uniform_speech_spans") ⇒ Object
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
# File 'lib/cohere/transcribe/output/timing.rb', line 29 def uniform_words_across_spans(text, spans, segment_index, timing_source = "uniform_speech_spans") tokens = PythonText.split(text.to_s) valid_spans = spans.select { |start_time, end_time| end_time > start_time } return [] if tokens.empty? || valid_spans.empty? counts = proportional_counts(tokens.length, valid_spans) token_offset = 0 words = valid_spans.zip(counts).flat_map do |(start_time, end_time), count| next [] unless count.positive? duration = (end_time - start_time).fdiv(count) Array.new(count) do |local_index| token_index = token_offset + local_index TranscriptionWord.new( start: start_time + (local_index * duration), end: start_time + ((local_index + 1) * duration), text: tokens.fetch(token_index), segment_index: segment_index, segment_word_index: token_index, timing_source: timing_source ) end.tap { token_offset += count } end raise "Speech-span token allocation did not preserve every token" unless token_offset == tokens.length words.freeze end |