summaryrefslogtreecommitdiffstats
path: root/src/yaml_log.h
blob: c5c0b852cbfd846e36014bde457e91c0bf1e1418 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*
 * This file is part of AtracDEnc.
 *
 * AtracDEnc is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * AtracDEnc is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with AtracDEnc; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

#pragma once
// YAML debug logging for the ATRAC3 gain control pipeline.
//
// Inspired by edge264's YAML logging approach (FOSDEM 2026):
//   - Every gain control decision is logged as a YAML stream (one document
//     per frame) so each frame's state is self-contained and grep-able.
//   - Field names match C++ variable names to make code↔log navigation easy.
//   - Comments explain enum values and computed context (e.g. # prev_E/cur_E).
//   - The output can be post-processed with Python for analysis or used to
//     craft custom gain curves for stress testing.
//
// Enable with --yaml-log <file> on the command line.
// Each YAML document covers one frame; bands/channels nest under it.
//
// Example output:
//   ---
//   frame: 42
//   time: 0.952  # seconds
//   channels:
//     - channel: 0
//       bands:
//         - band: 0
//           high_freq_ratio: 0.8721
//           overlap_ratio: 1.2340  # prev_E/cur_E; >1 means prev frame louder
//           dynamic_min_score: 2.2134
//           gain: [0.1200, 0.1500, 0.8900, ...]  # 32 subframe RMS values
//           next_level: 1.0800
//           curve_raw:
//             - {level: 2, loc: 8}
//           rms_cur: 0.023000
//           rms_next_mod: 0.019000
//           point0_level: 4
//           crossover: 12
//           curve_final:
//             - {level: 4, loc: 0}
//             - {level: 3, loc: 12}
//           max_gain: 5.1000
//       gain_energy_scale:
//         - {band: 0, prev_half: 1.000000, cur_half: 16.000000, frame: 8.500000, next_overlap: 1.100000}

#include <ostream>
#include <iomanip>
#include <vector>

namespace NAtracDEnc {

// Restore ostream float format on scope exit.
struct TYamlFmtGuard {
    std::ostream& os;
    std::ios_base::fmtflags flags;
    std::streamsize prec;
    TYamlFmtGuard(std::ostream& o, int precision)
        : os(o), flags(o.flags()), prec(o.precision()) {
        o << std::fixed << std::setprecision(precision);
    }
    ~TYamlFmtGuard() { os.flags(flags); os.precision(prec); }
};

// Write a float array as a compact YAML inline sequence.
inline void YamlWriteFloatSeq(std::ostream& out, const float* v, size_t n, int precision = 4) {
    TYamlFmtGuard fmt(out, precision);
    out << "[";
    for (size_t i = 0; i < n; ++i) {
        if (i) out << ", ";
        out << v[i];
    }
    out << "]";
}

// Write a float vector as a compact YAML inline sequence.
inline void YamlWriteFloatSeq(std::ostream& out, const std::vector<float>& v, int precision = 4) {
    YamlWriteFloatSeq(out, v.data(), v.size(), precision);
}

} // namespace NAtracDEnc