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

mewkiz / flac / 16222310284

11 Jul 2025 02:20PM UTC coverage: 62.333% (+0.2%) from 62.179%
16222310284

push

github

mewmew
go fmt

2 of 2 new or added lines in 1 file covered. (100.0%)

8 existing lines in 1 file now uncovered.

1774 of 2846 relevant lines covered (62.33%)

3774476.96 hits per line

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

45.9
/encode.go
1
package flac
2

3
import (
4
        "crypto/md5"
5
        "hash"
6
        "io"
7

8
        "github.com/icza/bitio"
9
        "github.com/mewkiz/flac/meta"
10
        "github.com/mewkiz/pkg/errutil"
11
)
12

13
// An Encoder represents a FLAC encoder.
14
type Encoder struct {
15
        // FLAC stream of encoder.
16
        *Stream
17
        // Underlying io.Writer or io.WriteCloser to the output stream.
18
        w io.Writer
19
        // Minimum and maximum block size (in samples) of frames written by encoder.
20
        blockSizeMin, blockSizeMax uint16
21
        // Minimum and maximum frame size (in bytes) of frames written by encoder.
22
        frameSizeMin, frameSizeMax uint32
23
        // MD5 running hash of unencoded audio samples.
24
        md5sum hash.Hash
25
        // Total number of samples (per channel) written by encoder.
26
        nsamples uint64
27
        // Current frame number if block size is fixed, and the first sample number
28
        // of the current frame otherwise.
29
        curNum uint64
30
        // AnalysisEnabled indicates whether analysis is enabled for the encoder.
31
        AnalysisEnabled bool
32
}
33

34
// NewEncoder returns a new FLAC encoder for the given metadata StreamInfo block
35
// and optional metadata blocks.
36
//
37
// By default prediction analysis is enabled. For more information, see
38
// Encoder.EnablePredictionAnalysis.
39
func NewEncoder(w io.Writer, info *meta.StreamInfo, blocks ...*meta.Block) (*Encoder, error) {
82✔
40
        // Store FLAC signature.
82✔
41
        enc := &Encoder{
82✔
42
                Stream: &Stream{
82✔
43
                        Info:   info,
82✔
44
                        Blocks: blocks,
82✔
45
                },
82✔
46
                w:               w,
82✔
47
                md5sum:          md5.New(),
82✔
48
                AnalysisEnabled: true, // enable prediction analysis by default.
82✔
49
        }
82✔
50

82✔
51
        bw := bitio.NewWriter(w)
82✔
52
        if _, err := bw.Write(flacSignature); err != nil {
82✔
UNCOV
53
                return nil, errutil.Err(err)
×
54
        }
×
55
        // Encode metadata blocks.
56
        // TODO: consider using bufio.NewWriter.
57
        if err := encodeStreamInfo(bw, info, len(blocks) == 0); err != nil {
82✔
58
                return nil, errutil.Err(err)
×
59
        }
×
60
        for i, block := range blocks {
274✔
61
                if err := encodeBlock(bw, block, i == len(blocks)-1); err != nil {
192✔
UNCOV
62
                        return nil, errutil.Err(err)
×
63
                }
×
64
        }
65
        // Flush pending writes of metadata blocks.
66
        if _, err := bw.Align(); err != nil {
82✔
UNCOV
67
                return nil, errutil.Err(err)
×
UNCOV
68
        }
×
69
        // Return encoder to be used for encoding audio samples.
70
        return enc, nil
82✔
71
}
72

73
// Close closes the underlying io.Writer of the encoder and flushes any pending
74
// writes. If the io.Writer implements io.Seeker, the encoder will update the
75
// StreamInfo metadata block with the MD5 checksum of the unencoded audio
76
// samples, the number of samples, and the minimum and maximum frame size and
77
// block size.
78
func (enc *Encoder) Close() error {
82✔
79
        // TODO: check if bit writer should be flushed before seeking on enc.w.
82✔
80
        // Update StreamInfo metadata block.
82✔
81
        if ws, ok := enc.w.(io.WriteSeeker); ok {
82✔
82
                if _, err := ws.Seek(int64(len(flacSignature)), io.SeekStart); err != nil {
×
83
                        return errutil.Err(err)
×
84
                }
×
85
                // Update minimum and maximum block size (in samples) of FLAC stream.
86
                enc.Info.BlockSizeMin = enc.blockSizeMin
×
87
                enc.Info.BlockSizeMax = enc.blockSizeMax
×
88
                // Update minimum and maximum frame size (in bytes) of FLAC stream.
×
89
                enc.Info.FrameSizeMin = enc.frameSizeMin
×
90
                enc.Info.FrameSizeMax = enc.frameSizeMax
×
91
                // Update total number of samples (per channel) of FLAC stream.
×
92
                enc.Info.NSamples = enc.nsamples
×
93
                // Update MD5 checksum of the unencoded audio samples.
×
94
                sum := enc.md5sum.Sum(nil)
×
95
                for i := range sum {
×
96
                        enc.Info.MD5sum[i] = sum[i]
×
97
                }
×
98
                bw := bitio.NewWriter(ws)
×
99
                // Write updated StreamInfo metadata block to output stream.
×
100
                if err := encodeStreamInfo(bw, enc.Info, len(enc.Blocks) == 0); err != nil {
×
101
                        return errutil.Err(err)
×
UNCOV
102
                }
×
UNCOV
103
                if _, err := bw.Align(); err != nil {
×
104
                        return errutil.Err(err)
×
105
                }
×
106
        }
107
        if closer, ok := enc.w.(io.Closer); ok {
82✔
UNCOV
108
                return closer.Close()
×
UNCOV
109
        }
×
110
        return nil
82✔
111
}
112

113
// EnablePredictionAnalysis specifies whether to enable analysis for the
114
// encoder. When analysis is enabled, subframes that are currently marked as
115
// PredVerbatim will be analyzed to use the best prediction method
116
// (constant, fixed or verbatim) based on size.
117
func (enc *Encoder) EnablePredictionAnalysis(enable bool) {
81✔
118
        enc.AnalysisEnabled = enable
81✔
119
}
81✔
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

© 2026 Coveralls, Inc