Class: Wavify::Codecs::Flac::BitWriter

Inherits:
Object
  • Object
show all
Defined in:
lib/wavify/codecs/flac.rb

Overview

Internal bit writer used by the FLAC encoder.

Instance Method Summary collapse

Constructor Details

#initializeBitWriter

:nodoc:



120
121
122
123
124
# File 'lib/wavify/codecs/flac.rb', line 120

def initialize
  @bytes = +"".b
  @buffer = 0
  @bits_used = 0
end

Instance Method Details

#align_to_byteObject

:nodoc:



180
181
182
183
184
185
186
187
# File 'lib/wavify/codecs/flac.rb', line 180

def align_to_byte # :nodoc:
  return if @bits_used.zero?

  @buffer <<= (8 - @bits_used)
  @bytes << @buffer
  @buffer = 0
  @bits_used = 0
end

#to_sObject

:nodoc:



189
190
191
192
# File 'lib/wavify/codecs/flac.rb', line 189

def to_s # :nodoc:
  align_to_byte
  @bytes.dup
end

#write_bits(value, count) ⇒ Object



126
127
128
129
130
131
132
133
134
135
136
137
138
139
# File 'lib/wavify/codecs/flac.rb', line 126

def write_bits(value, count)
  raise InvalidParameterError, "bit count must be a non-negative Integer" unless count.is_a?(Integer) && count >= 0
  return if count.zero?

  remaining = count
  while remaining.positive?
    take = [8 - @bits_used, remaining].min
    shift = remaining - take
    @buffer = (@buffer << take) | ((value >> shift) & ((1 << take) - 1))
    @bits_used += take
    remaining -= take
    flush_byte_if_needed
  end
end

#write_rice_signed(value, parameter) ⇒ Object

:nodoc:



171
172
173
174
175
176
177
178
# File 'lib/wavify/codecs/flac.rb', line 171

def write_rice_signed(value, parameter) # :nodoc:
  unsigned = value >= 0 ? (value << 1) : ((-value << 1) - 1)
  quotient = unsigned >> parameter
  remainder = parameter.zero? ? 0 : (unsigned & ((1 << parameter) - 1))

  write_unary_zeros_then_one(quotient)
  write_bits(remainder, parameter) if parameter.positive?
end

#write_signed_bits(value, count) ⇒ Object

:nodoc:



141
142
143
144
# File 'lib/wavify/codecs/flac.rb', line 141

def write_signed_bits(value, count) # :nodoc:
  mask = (1 << count) - 1
  write_bits(value & mask, count)
end

#write_unary_zeros_then_one(zero_count) ⇒ Object

:nodoc:



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/wavify/codecs/flac.rb', line 146

def write_unary_zeros_then_one(zero_count) # :nodoc:
  unless zero_count.is_a?(Integer) && zero_count.between?(0, MAX_UNARY_ZERO_RUN)
    raise InvalidParameterError, "FLAC unary zero run exceeds resource limit"
  end

  if @bits_used.positive?
    fill = [8 - @bits_used, zero_count].min
    @buffer <<= fill
    @bits_used += fill
    zero_count -= fill
    flush_byte_if_needed
  end

  if @bits_used.zero? && zero_count >= 8
    whole_bytes, zero_count = zero_count.divmod(8)
    @bytes << ("\x00".b * whole_bytes)
  end

  if zero_count.positive?
    @buffer <<= zero_count
    @bits_used += zero_count
  end
  write_bits(1, 1)
end