Made a tool (attached, should compile fine for windows) to dump some stats about a flac bitstream. Probably not going to develop it much further and the code is nothing to write home about. Works on my PC but YMMV, here's some example output:
STREAMINFO{
blocksize min 4096 max 4096
framesize min 14 max 13664
samplerate 44100
channels 2 bits_per_sample 16 total samples 6791829
Blocking strategy: Fixed
}
Metadata bit stats (% including bitstream):
304 (0.000184%) STREAMINFO
Frame header stats (% excluding metadata):
23226 (0.014046%) bits spent on sync codes
3318 (0.002007%) bits spent on frame reservations to maintain syncability
1659 (0.001003%) bits spent on block strategy bit
6652 (0.004023%) bits spent encoding blocksize
6636 (0.004013%) bits spent encoding samplerate
6636 (0.004013%) bits spent encoding channel assignment
4977 (0.003010%) bits spent encoding sample size
25520 (0.015433%) bits spent encoding current frame/sample index with UTF8
13272 (0.008026%) bits spent encoding frame header crc8
Subframe header stats (% excluding metadata)
3318 (0.002007%) bits spent on subframe reservations to maintain syncability
19908 (0.012039%) bits spent encoding model type
3318 (0.002007%) bits spent on wasted bits flag
Modelling stats (bit % excluding metadata) (excluding residual bits)
18 (0.542495%) subframes used constant modelling
0 (0.000000%) subframes used verbatim modelling
6 (0.180832%) subframes used fixed modelling
3294 (99.276673%) subframes used lpc modelling
288 (0.000174%) bits spent on constant
0 (0.000000%) bits spent on verbatim
48 (0.000029%) bits spent on fixed
927478 (0.560881%) bits spent on LPC
Residual stats (% excluding metadata):
3300 (0.001996%) bits spent on residual reservations to maintain syncability
3300 (0.001996%) bits spent on residual type (4 or 5 bit rice parameter)
164275633 (99.343672%) bits spent on residual encoding
Frame footer stats (% excluding metadata):
26544 (0.016052%) bits spent encoding frame footer crc16
5913 (0.003576%) bits spent on frame padding for byte alignment
Combined stats (% excluding metadata)
927814 (0.561084%) total bits spent on modelling
164282233 (99.347663%) total bits spent on residual
150897 (0.091253%) total bits spent on overhead (frame_header+subframe_header+footer
Miscellaneous stats:
27432 (100.000000%) of residual partitions stored rice-encoded
0 (0.000000%) of residual partitions stored verbatim
9936 (0.006009%) total bits spent on pure reservations to maintain syncability (not including the many reserved values in used elements or end-of-frame padding)
Used it to see how the structure of the bitstream changes as different compression settings are used. Tested with the album version of this song without the talking intro: https://www.youtube.com/watch?v=MODhTJwebz8
Percentages are just for the bitstream, no metadata blocks are included in the 100% not even streaminfo
Filesize Frames Overhead Modelling Residual Settings
22131570 1659 0.085% 0.067% 99.848% fixed -0b4096
20941266 1659 0.090% 0.324% 99.586% fixed -3b4096
20705886 1659 0.091% 0.418% 99.491% fixed -6b4096
20681000 1659 0.091% 0.579% 99.330% fixed -8b4096
20670160 1659 0.091% 0.561% 99.348% fixed -8pb4096
20649171 1721 0.120% 0.565% 99.315% peakset all -8p, blocksizes 1152,2304,3456,4608 no merge no tweak
20641291 1721 0.126% 0.566% 99.308% peakset all -8p, blocksizes 1152,2304,3456,4608, no merge with tweak set to maximum iterations
20614856 904 0.070% 0.305% 99.625% peakset all -8p, blocksizes 1152,2304,3456,4608, non-subset with merge and tweak set to maximum iterations
20614731 958 0.074% 0.318% 99.608% peakset all -8p, blocksizes 576,1152,1728,2304,2880,3456,4032,4608, non-subset with merge and tweak set to maximum iterations
20613363 921 0.071% 0.312% 99.616% peakset all -8p, blocksizes 1152,2304,3456,4608,5760,6912,8064,9216, non-subset with merge and tweak set to maximum iterations
- No surprise that as compression effort increases for fixed runs that the overhead and model proportions increase, stronger settings search for heavier models which take more space to define
- The overhead of the weakest peakset jumping relative to fixed is mostly because variable frame indexing is by sample instead of frame number, adding approx 2 bytes per header
- By adding tweak in the next run overhead increased slightly thanks to having to encode a few blocksizes with a literal instead of one of the dozen or so predefined common values
- This track apparently prefers blocksizes well above 4k on average so lax allows a lot of overhead to be saved by reducing the number of frames. Less frames also means less models to store. Merge did a good job of clawing upwards in blocksize despite the max blocksize used in analysis being below what it probably should be for this input
- Adding intermediate blocksizes without increasing the max blocksize used during analysis didn't help much, the analysis stage performed better but it ate some of tweak/merges lunch to do so
- Finally changing the blocksize list to something better-fitting the input was beneficial, but there wasn't much to gain