• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

mewkiz / flac / 6713408042

31 Oct 2023 11:04PM UTC coverage: 68.265% (+4.9%) from 63.409%
6713408042

push

github

mewmew
internal/bits: minor updates of TestUnary for consistency

Run `goimports -w` to sort imports and change order of
"expected xx, got xx" to match other test cases
(e.g. TestZigZag).

1680 of 2461 relevant lines covered (68.26%)

4364391.81 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

76.87
/frame/subframe.go
1
package frame
2

3
import (
4
        "errors"
5
        "fmt"
6

7
        "github.com/mewkiz/flac/internal/bits"
8
)
9

10
// A Subframe contains the encoded audio samples from one channel of an audio
11
// block (a part of the audio stream).
12
//
13
// ref: https://www.xiph.org/flac/format.html#subframe
14
type Subframe struct {
15
        // Subframe header.
16
        SubHeader
17
        // Unencoded audio samples. Samples is initially nil, and gets populated by a
18
        // call to Frame.Parse.
19
        //
20
        // Samples is used by decodeFixed and decodeFIR to temporarily store
21
        // residuals. Before returning they call decodeLPC which decodes the audio
22
        // samples.
23
        Samples []int32
24
        // Number of audio samples in the subframe.
25
        NSamples int
26
}
27

28
// parseSubframe reads and parses the header, and the audio samples of a
29
// subframe.
30
func (frame *Frame) parseSubframe(br *bits.Reader, bps uint) (subframe *Subframe, err error) {
78,172✔
31
        // Parse subframe header.
78,172✔
32
        subframe = new(Subframe)
78,172✔
33
        if err = subframe.parseHeader(br); err != nil {
78,172✔
34
                return subframe, err
×
35
        }
×
36
        // Adjust bps of subframe for wasted bits-per-sample.
37
        bps -= subframe.Wasted
78,172✔
38

78,172✔
39
        // Decode subframe audio samples.
78,172✔
40
        subframe.NSamples = int(frame.BlockSize)
78,172✔
41
        subframe.Samples = make([]int32, 0, subframe.NSamples)
78,172✔
42
        switch subframe.Pred {
78,172✔
43
        case PredConstant:
2,560✔
44
                err = subframe.decodeConstant(br, bps)
2,560✔
45
        case PredVerbatim:
110✔
46
                err = subframe.decodeVerbatim(br, bps)
110✔
47
        case PredFixed:
39,742✔
48
                err = subframe.decodeFixed(br, bps)
39,742✔
49
        case PredFIR:
35,760✔
50
                err = subframe.decodeFIR(br, bps)
35,760✔
51
        }
52

53
        // Left shift to account for wasted bits-per-sample.
54
        for i, sample := range subframe.Samples {
105,201,771✔
55
                subframe.Samples[i] = sample << subframe.Wasted
105,123,599✔
56
        }
105,123,599✔
57
        return subframe, err
78,172✔
58
}
59

60
// A SubHeader specifies the prediction method and order of a subframe.
61
//
62
// ref: https://www.xiph.org/flac/format.html#subframe_header
63
type SubHeader struct {
64
        // Specifies the prediction method used to encode the audio sample of the
65
        // subframe.
66
        Pred Pred
67
        // Prediction order used by fixed and FIR linear prediction decoding.
68
        Order int
69
        // Wasted bits-per-sample.
70
        Wasted uint
71
        // Residual coding method used by fixed and FIR linear prediction decoding.
72
        ResidualCodingMethod ResidualCodingMethod
73
        // Coefficients' precision in bits used by FIR linear prediction decoding.
74
        CoeffPrec uint
75
        // Predictor coefficient shift needed in bits used by FIR linear prediction
76
        // decoding.
77
        CoeffShift int32
78
        // Predictor coefficients used by FIR linear prediction decoding.
79
        Coeffs []int32
80
        // Rice-coding subframe fields used by residual coding methods rice1 and
81
        // rice2; nil if unused.
82
        RiceSubframe *RiceSubframe
83
}
84

85
// RiceSubframe holds rice-coding subframe fields used by residual coding
86
// methods rice1 and rice2.
87
type RiceSubframe struct {
88
        // Partition order used by fixed and FIR linear prediction decoding
89
        // (for residual coding methods, rice1 and rice2).
90
        PartOrder int // TODO: remove PartOrder and infer from int(math.Log2(float64(len(Partitions))))?
91
        // Rice partitions.
92
        Partitions []RicePartition
93
}
94

95
// RicePartition is a partition containing a subset of the residuals of a
96
// subframe.
97
type RicePartition struct {
98
        // Rice parameter.
99
        Param uint
100
        // Residual sample size in bits-per-sample used by escaped partitions.
101
        EscapedBitsPerSample uint
102
}
103

104
// parseHeader reads and parses the header of a subframe.
105
func (subframe *Subframe) parseHeader(br *bits.Reader) error {
78,172✔
106
        // 1 bit: zero-padding.
78,172✔
107
        x, err := br.Read(1)
78,172✔
108
        if err != nil {
78,172✔
109
                return unexpected(err)
×
110
        }
×
111
        if x != 0 {
78,172✔
112
                return errors.New("frame.Subframe.parseHeader: non-zero padding")
×
113
        }
×
114

115
        // 6 bits: Pred.
116
        x, err = br.Read(6)
78,172✔
117
        if err != nil {
78,172✔
118
                return unexpected(err)
×
119
        }
×
120
        // The 6 bits are used to specify the prediction method and order as follows:
121
        //    000000: Constant prediction method.
122
        //    000001: Verbatim prediction method.
123
        //    00001x: reserved.
124
        //    0001xx: reserved.
125
        //    001xxx:
126
        //       if (xxx <= 4)
127
        //          Fixed prediction method; xxx=order
128
        //       else
129
        //          reserved.
130
        //    01xxxx: reserved.
131
        //    1xxxxx: FIR prediction method; xxxxx=order-1
132
        switch {
78,172✔
133
        case x < 1:
2,560✔
134
                // 000000: Constant prediction method.
2,560✔
135
                subframe.Pred = PredConstant
2,560✔
136
        case x < 2:
110✔
137
                // 000001: Verbatim prediction method.
110✔
138
                subframe.Pred = PredVerbatim
110✔
139
        case x < 8:
×
140
                // 00001x: reserved.
×
141
                // 0001xx: reserved.
×
142
                return fmt.Errorf("frame.Subframe.parseHeader: reserved prediction method bit pattern (%06b)", x)
×
143
        case x < 16:
39,742✔
144
                // 001xxx:
39,742✔
145
                //    if (xxx <= 4)
39,742✔
146
                //       Fixed prediction method; xxx=order
39,742✔
147
                //    else
39,742✔
148
                //       reserved.
39,742✔
149
                order := int(x & 0x07)
39,742✔
150
                if order > 4 {
39,742✔
151
                        return fmt.Errorf("frame.Subframe.parseHeader: reserved prediction method bit pattern (%06b)", x)
×
152
                }
×
153
                subframe.Pred = PredFixed
39,742✔
154
                subframe.Order = order
39,742✔
155
        case x < 32:
×
156
                // 01xxxx: reserved.
×
157
                return fmt.Errorf("frame.Subframe.parseHeader: reserved prediction method bit pattern (%06b)", x)
×
158
        default:
35,760✔
159
                // 1xxxxx: FIR prediction method; xxxxx=order-1
35,760✔
160
                subframe.Pred = PredFIR
35,760✔
161
                subframe.Order = int(x&0x1F) + 1
35,760✔
162
        }
163

164
        // 1 bit: hasWastedBits.
165
        x, err = br.Read(1)
78,172✔
166
        if err != nil {
78,172✔
167
                return unexpected(err)
×
168
        }
×
169
        if x != 0 {
78,952✔
170
                // k wasted bits-per-sample in source subblock, k-1 follows, unary coded;
780✔
171
                // e.g. k=3 => 001 follows, k=7 => 0000001 follows.
780✔
172
                x, err = br.ReadUnary()
780✔
173
                if err != nil {
780✔
174
                        return unexpected(err)
×
175
                }
×
176
                subframe.Wasted = uint(x) + 1
780✔
177
        }
178

179
        return nil
78,172✔
180
}
181

182
// Pred specifies the prediction method used to encode the audio samples of a
183
// subframe.
184
type Pred uint8
185

186
// Prediction methods.
187
const (
188
        // PredConstant specifies that the subframe contains a constant sound. The
189
        // audio samples are encoded using run-length encoding. Since every audio
190
        // sample has the same constant value, a single unencoded audio sample is
191
        // stored in practice. It is replicated a number of times, as specified by
192
        // BlockSize in the frame header.
193
        PredConstant Pred = iota
194
        // PredVerbatim specifies that the subframe contains unencoded audio samples.
195
        // Random sound is often stored verbatim, since no prediction method can
196
        // compress it sufficiently.
197
        PredVerbatim
198
        // PredFixed specifies that the subframe contains linear prediction coded
199
        // audio samples. The coefficients of the prediction polynomial are selected
200
        // from a fixed set, and can represent 0th through fourth-order polynomials.
201
        // The prediction order (0 through 4) is stored within the subframe along
202
        // with the same number of unencoded warm-up samples, which are used to kick
203
        // start the prediction polynomial. The remainder of the subframe stores
204
        // encoded residuals (signal errors) which specify the difference between the
205
        // predicted and the original audio samples.
206
        PredFixed
207
        // PredFIR specifies that the subframe contains linear prediction coded audio
208
        // samples. The coefficients of the prediction polynomial are stored in the
209
        // subframe, and can represent 0th through 32nd-order polynomials. The
210
        // prediction order (0 through 32) is stored within the subframe along with
211
        // the same number of unencoded warm-up samples, which are used to kick start
212
        // the prediction polynomial. The remainder of the subframe stores encoded
213
        // residuals (signal errors) which specify the difference between the
214
        // predicted and the original audio samples.
215
        PredFIR
216
)
217

218
// signExtend interprets x as a signed n-bit integer value and sign extends it
219
// to 32 bits.
220
func signExtend(x uint64, n uint) int32 {
1,081,936✔
221
        // x is signed if its most significant bit is set.
1,081,936✔
222
        if x&(1<<(n-1)) != 0 {
1,581,577✔
223
                // Sign extend x.
499,641✔
224
                return int32(x | ^uint64(0)<<n)
499,641✔
225
        }
499,641✔
226
        return int32(x)
582,295✔
227
}
228

229
// decodeConstant reads an unencoded audio sample of the subframe. Each sample
230
// of the subframe has this constant value. The constant encoding can be thought
231
// of as run-length encoding.
232
//
233
// ref: https://www.xiph.org/flac/format.html#subframe_constant
234
func (subframe *Subframe) decodeConstant(br *bits.Reader, bps uint) error {
2,560✔
235
        // (bits-per-sample) bits: Unencoded constant value of the subblock.
2,560✔
236
        x, err := br.Read(bps)
2,560✔
237
        if err != nil {
2,560✔
238
                return unexpected(err)
×
239
        }
×
240

241
        // Each sample of the subframe has the same constant value.
242
        sample := signExtend(x, bps)
2,560✔
243
        for i := 0; i < subframe.NSamples; i++ {
10,367,616✔
244
                subframe.Samples = append(subframe.Samples, sample)
10,365,056✔
245
        }
10,365,056✔
246

247
        return nil
2,560✔
248
}
249

250
// decodeVerbatim reads the unencoded audio samples of the subframe.
251
//
252
// ref: https://www.xiph.org/flac/format.html#subframe_verbatim
253
func (subframe *Subframe) decodeVerbatim(br *bits.Reader, bps uint) error {
110✔
254
        // Parse the unencoded audio samples of the subframe.
110✔
255
        for i := 0; i < subframe.NSamples; i++ {
440,620✔
256
                // (bits-per-sample) bits: Unencoded constant value of the subblock.
440,510✔
257
                x, err := br.Read(bps)
440,510✔
258
                if err != nil {
440,510✔
259
                        return unexpected(err)
×
260
                }
×
261
                sample := signExtend(x, bps)
440,510✔
262
                subframe.Samples = append(subframe.Samples, sample)
440,510✔
263
        }
264
        return nil
110✔
265
}
266

267
// FixedCoeffs maps from prediction order to the LPC coefficients used in fixed
268
// encoding.
269
//
270
//        x_0[n] = 0
271
//        x_1[n] = x[n-1]
272
//        x_2[n] = 2*x[n-1] - x[n-2]
273
//        x_3[n] = 3*x[n-1] - 3*x[n-2] + x[n-3]
274
//        x_4[n] = 4*x[n-1] - 6*x[n-2] + 4*x[n-3] - x[n-4]
275
var FixedCoeffs = [...][]int32{
276
        // ref: Section 2.2 of http://www.hpl.hp.com/techreports/1999/HPL-1999-144.pdf
277
        1: {1},
278
        2: {2, -1},
279
        3: {3, -3, 1},
280
        // ref: Data Compression: The Complete Reference (7.10.1)
281
        4: {4, -6, 4, -1},
282
}
283

284
// decodeFixed decodes the linear prediction coded samples of the subframe,
285
// using a fixed set of predefined polynomial coefficients.
286
//
287
// ref: https://www.xiph.org/flac/format.html#subframe_fixed
288
func (subframe *Subframe) decodeFixed(br *bits.Reader, bps uint) error {
39,742✔
289
        // Parse unencoded warm-up samples.
39,742✔
290
        for i := 0; i < subframe.Order; i++ {
135,680✔
291
                // (bits-per-sample) bits: Unencoded warm-up sample.
95,938✔
292
                x, err := br.Read(bps)
95,938✔
293
                if err != nil {
95,938✔
294
                        return unexpected(err)
×
295
                }
×
296
                sample := signExtend(x, bps)
95,938✔
297
                subframe.Samples = append(subframe.Samples, sample)
95,938✔
298
        }
299

300
        // Decode subframe residuals.
301
        if err := subframe.decodeResiduals(br); err != nil {
39,742✔
302
                return err
×
303
        }
×
304

305
        // Predict the audio samples of the subframe using a polynomial with
306
        // predefined coefficients of a given order. Correct signal errors using the
307
        // decoded residuals.
308
        const shift = 0
39,742✔
309
        return subframe.decodeLPC(FixedCoeffs[subframe.Order], shift)
39,742✔
310
}
311

312
// decodeFIR decodes the linear prediction coded samples of the subframe, using
313
// polynomial coefficients stored in the stream.
314
//
315
// ref: https://www.xiph.org/flac/format.html#subframe_lpc
316
func (subframe *Subframe) decodeFIR(br *bits.Reader, bps uint) error {
35,760✔
317
        // Parse unencoded warm-up samples.
35,760✔
318
        for i := 0; i < subframe.Order; i++ {
289,344✔
319
                // (bits-per-sample) bits: Unencoded warm-up sample.
253,584✔
320
                x, err := br.Read(bps)
253,584✔
321
                if err != nil {
253,584✔
322
                        return unexpected(err)
×
323
                }
×
324
                sample := signExtend(x, bps)
253,584✔
325
                subframe.Samples = append(subframe.Samples, sample)
253,584✔
326
        }
327

328
        // 4 bits: (coefficients' precision in bits) - 1.
329
        x, err := br.Read(4)
35,760✔
330
        if err != nil {
35,760✔
331
                return unexpected(err)
×
332
        }
×
333
        if x == 0xF {
35,760✔
334
                return errors.New("frame.Subframe.decodeFIR: invalid coefficient precision bit pattern (1111)")
×
335
        }
×
336
        prec := uint(x) + 1
35,760✔
337
        subframe.CoeffPrec = prec
35,760✔
338

35,760✔
339
        // 5 bits: predictor coefficient shift needed in bits.
35,760✔
340
        x, err = br.Read(5)
35,760✔
341
        if err != nil {
35,760✔
342
                return unexpected(err)
×
343
        }
×
344
        shift := signExtend(x, 5)
35,760✔
345
        subframe.CoeffShift = shift
35,760✔
346

35,760✔
347
        // Parse coefficients.
35,760✔
348
        coeffs := make([]int32, subframe.Order)
35,760✔
349
        for i := range coeffs {
289,344✔
350
                // (prec) bits: Predictor coefficient.
253,584✔
351
                x, err = br.Read(prec)
253,584✔
352
                if err != nil {
253,584✔
353
                        return unexpected(err)
×
354
                }
×
355
                coeffs[i] = signExtend(x, prec)
253,584✔
356
        }
357
        subframe.Coeffs = coeffs
35,760✔
358

35,760✔
359
        // Decode subframe residuals.
35,760✔
360
        if err := subframe.decodeResiduals(br); err != nil {
35,760✔
361
                return err
×
362
        }
×
363

364
        // Predict the audio samples of the subframe using a polynomial with
365
        // predefined coefficients of a given order. Correct signal errors using the
366
        // decoded residuals.
367
        return subframe.decodeLPC(coeffs, shift)
35,760✔
368
}
369

370
// ResidualCodingMethod specifies a residual coding method.
371
type ResidualCodingMethod uint8
372

373
// Residual coding methods.
374
const (
375
        // Rice coding with a 4-bit Rice parameter (rice1).
376
        ResidualCodingMethodRice1 ResidualCodingMethod = 0
377
        // Rice coding with a 5-bit Rice parameter (rice2).
378
        ResidualCodingMethodRice2 ResidualCodingMethod = 1
379
)
380

381
// decodeResiduals decodes the encoded residuals (prediction method error
382
// signals) of the subframe.
383
//
384
// ref: https://www.xiph.org/flac/format.html#residual
385
func (subframe *Subframe) decodeResiduals(br *bits.Reader) error {
75,502✔
386
        // 2 bits: Residual coding method.
75,502✔
387
        x, err := br.Read(2)
75,502✔
388
        if err != nil {
75,502✔
389
                return unexpected(err)
×
390
        }
×
391
        residualCodingMethod := ResidualCodingMethod(x)
75,502✔
392
        subframe.ResidualCodingMethod = residualCodingMethod
75,502✔
393
        // The 2 bits are used to specify the residual coding method as follows:
75,502✔
394
        //    00: Rice coding with a 4-bit Rice parameter.
75,502✔
395
        //    01: Rice coding with a 5-bit Rice parameter.
75,502✔
396
        //    10: reserved.
75,502✔
397
        //    11: reserved.
75,502✔
398
        switch residualCodingMethod {
75,502✔
399
        case 0x0:
71,624✔
400
                return subframe.decodeRicePart(br, 4)
71,624✔
401
        case 0x1:
3,878✔
402
                return subframe.decodeRicePart(br, 5)
3,878✔
403
        default:
×
404
                return fmt.Errorf("frame.Subframe.decodeResiduals: reserved residual coding method bit pattern (%02b)", uint8(residualCodingMethod))
×
405
        }
406
}
407

408
// decodeRicePart decodes a Rice partition of encoded residuals from the
409
// subframe, using a Rice parameter of the specified size in bits.
410
//
411
// ref: https://www.xiph.org/flac/format.html#partitioned_rice
412
// ref: https://www.xiph.org/flac/format.html#partitioned_rice2
413
func (subframe *Subframe) decodeRicePart(br *bits.Reader, paramSize uint) error {
75,502✔
414
        // 4 bits: Partition order.
75,502✔
415
        x, err := br.Read(4)
75,502✔
416
        if err != nil {
75,502✔
417
                return unexpected(err)
×
418
        }
×
419
        partOrder := int(x)
75,502✔
420
        riceSubframe := &RiceSubframe{
75,502✔
421
                PartOrder: partOrder,
75,502✔
422
        }
75,502✔
423
        subframe.RiceSubframe = riceSubframe
75,502✔
424

75,502✔
425
        // Parse Rice partitions; in total 2^partOrder partitions.
75,502✔
426
        //
75,502✔
427
        // ref: https://www.xiph.org/flac/format.html#rice_partition
75,502✔
428
        // ref: https://www.xiph.org/flac/format.html#rice2_partition
75,502✔
429
        nparts := 1 << partOrder
75,502✔
430
        partitions := make([]RicePartition, nparts)
75,502✔
431
        riceSubframe.Partitions = partitions
75,502✔
432
        for i := 0; i < nparts; i++ {
401,453✔
433
                partition := &partitions[i]
325,951✔
434
                // (4 or 5) bits: Rice parameter.
325,951✔
435
                x, err = br.Read(paramSize)
325,951✔
436
                if err != nil {
325,951✔
437
                        return unexpected(err)
×
438
                }
×
439
                param := uint(x)
325,951✔
440
                partition.Param = param
325,951✔
441

325,951✔
442
                // Determine the number of Rice encoded samples in the partition.
325,951✔
443
                var nsamples int
325,951✔
444
                if partOrder == 0 {
389,838✔
445
                        nsamples = subframe.NSamples - subframe.Order
63,887✔
446
                } else if i != 0 {
576,400✔
447
                        nsamples = subframe.NSamples / nparts
250,449✔
448
                } else {
262,064✔
449
                        nsamples = subframe.NSamples/nparts - subframe.Order
11,615✔
450
                }
11,615✔
451

452
                if paramSize == 4 && param == 0xF || paramSize == 5 && param == 0x1F {
328,656✔
453
                        // 1111 or 11111: Escape code, meaning the partition is in unencoded
2,705✔
454
                        // binary form using n bits per sample; n follows as a 5-bit number.
2,705✔
455
                        x, err := br.Read(5)
2,705✔
456
                        if err != nil {
2,705✔
457
                                return unexpected(err)
×
458
                        }
×
459
                        n := uint(x)
2,705✔
460
                        partition.EscapedBitsPerSample = n
2,705✔
461
                        for j := 0; j < nsamples; j++ {
56,693✔
462
                                sample, err := br.Read(n)
53,988✔
463
                                if err != nil {
53,988✔
464
                                        return unexpected(err)
×
465
                                }
×
466
                                // ref: https://datatracker.ietf.org/doc/draft-ietf-cellar-flac/
467
                                //
468
                                // From section 9.2.7.1.  Escaped partition:
469
                                //
470
                                // The residual samples themselves are stored signed two's
471
                                // complement.  For example, when a partition is escaped and each
472
                                // residual sample is stored with 3 bits, the number -1 is
473
                                // represented as 0b111.
474
                                subframe.Samples = append(subframe.Samples, int32(bits.IntN(sample, n)))
53,988✔
475
                        }
476
                        continue
2,705✔
477
                }
478

479
                // Decode the Rice encoded residuals of the partition.
480
                for j := 0; j < nsamples; j++ {
94,237,769✔
481
                        residual, err := subframe.decodeRiceResidual(br, param)
93,914,523✔
482
                        if err != nil {
93,914,523✔
483
                                return err
×
484
                        }
×
485
                        subframe.Samples = append(subframe.Samples, residual)
93,914,523✔
486
                }
487
        }
488

489
        return nil
75,502✔
490
}
491

492
// decodeRiceResidual decodes and returns a Rice encoded residual (error
493
// signal).
494
func (subframe *Subframe) decodeRiceResidual(br *bits.Reader, k uint) (int32, error) {
93,914,523✔
495
        // Read unary encoded most significant bits.
93,914,523✔
496
        high, err := br.ReadUnary()
93,914,523✔
497
        if err != nil {
93,914,523✔
498
                return 0, unexpected(err)
×
499
        }
×
500

501
        // Read binary encoded least significant bits.
502
        low, err := br.Read(k)
93,914,523✔
503
        if err != nil {
93,914,523✔
504
                return 0, unexpected(err)
×
505
        }
×
506
        folded := uint32(high<<k | low)
93,914,523✔
507

93,914,523✔
508
        // ZigZag decode.
93,914,523✔
509
        residual := bits.DecodeZigZag(folded)
93,914,523✔
510
        return residual, nil
93,914,523✔
511
}
512

513
// decodeLPC decodes linear prediction coded audio samples, using the
514
// coefficients of a given polynomial, a couple of unencoded warm-up samples,
515
// and the signal errors of the prediction as specified by the residuals.
516
func (subframe *Subframe) decodeLPC(coeffs []int32, shift int32) error {
75,502✔
517
        if len(coeffs) != subframe.Order {
75,502✔
518
                return fmt.Errorf("frame.Subframe.decodeLPC: prediction order (%d) differs from number of coefficients (%d)", subframe.Order, len(coeffs))
×
519
        }
×
520
        if shift < 0 {
75,502✔
521
                return fmt.Errorf("frame.Subframe.decodeLPC: invalid negative shift")
×
522
        }
×
523
        if subframe.NSamples != len(subframe.Samples) {
75,502✔
524
                return fmt.Errorf("frame.Subframe.decodeLPC: subframe sample count mismatch; expected %d, got %d", subframe.NSamples, len(subframe.Samples))
×
525
        }
×
526
        for i := subframe.Order; i < subframe.NSamples; i++ {
94,044,013✔
527
                var sample int64
93,968,511✔
528
                for j, c := range coeffs {
1,512,646,263✔
529
                        sample += int64(c) * int64(subframe.Samples[i-j-1])
1,418,677,752✔
530
                }
1,418,677,752✔
531
                subframe.Samples[i] += int32(sample >> uint(shift))
93,968,511✔
532
        }
533
        return nil
75,502✔
534
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc