Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
be52d9d
Изменение мета-информации
Jun 15, 2026
e3d7da6
Beta версия
Jun 23, 2026
80cc930
Обновление мета-информации блока. Улучшение качества кодека
Jun 24, 2026
fc72522
Новая версия WHA
Jun 25, 2026
76e03d0
Улучшение работы кодека
Jul 9, 2026
00be34a
Обновление стабильности кодека на спокойном материале
Jul 12, 2026
d0217d0
Обновление качества, скорости и стабильности
Jul 13, 2026
dfa9d62
Обновление качества и производительности
Jul 15, 2026
8504cd3
Первая версия 96 кбит/с
Jul 16, 2026
2855f92
Большое обновление качества
Jul 18, 2026
72e1067
Большое обновление стабильности и качества
Jul 27, 2026
7a0905b
Massive update of quality, SBR-like system
Jul 28, 2026
3a11dbd
Удаление комментариев для рабочей версии
Jul 28, 2026
9a757be
Большое обновление качества и производительности
Jul 29, 2026
dce9b53
Массивное обновление, улучшенная SBR ветка с правильным дизерингом бл…
Jul 31, 2026
e2dba1f
ULTRA-MASSIVE UPDATE
Aug 16, 2026
4b23cc3
Обновление стабильности и качества
Aug 26, 2026
491da19
Обновление 64-96 кбит/с по качеству, исправления недочетов 128 кбит/с
Sep 2, 2026
99c1d98
Massive Update of Quality on all bitrates
Sep 13, 2026
cdb571f
Ускорение райс кодов и постобработки
Sep 20, 2026
bbdf195
Минорное обновление
Sep 20, 2026
5259f29
Обновление качества и стабильности, в особенности тональных сигналов
Sep 22, 2026
59f4693
Merge branch 'main' into version/update
AgushaOS Sep 22, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions coder/bit_alloc.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ inline DualAllocResult allocate_bits_dual(

}

for (auto& x : max_bits_in) {
x = 8;
}

static thread_local std::vector<int> bits0, bits1, max_b, active;
static thread_local std::vector<float> s2_0, s2_1, factor0, factor1, global_score;
Expand Down
26 changes: 18 additions & 8 deletions coder/energy_shape.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,14 +93,24 @@ inline void apply_highfreq_attenuation(std::vector<float>& e0, std::vector<float
int band_count, float target_kbps,
int num_channels, bool has_transient)
{
if (target_kbps / float(num_channels) >= 48.0f) return;
if (target_kbps / float(num_channels) >= 64.0f) return;

int64_t start;
if (!has_transient)
start = 3 * (int64_t)e0.size() / 8;
else
start = 4 * (int64_t)e0.size() / 8;
if (target_kbps / float(num_channels) < 48.0) {
int64_t start;
if (!has_transient && target_kbps / float(num_channels) < 48)
start = 3 * (int64_t)e0.size() / 8;
else
start = 4 * (int64_t)e0.size() / 8;

for (int64_t i = start; i < (int64_t)e0.size(); ++i)
e0[i] *= 0.25f;
}
else {
const size_t half = e0.size() / 2;

for (int64_t i = start; i < (int64_t)e0.size(); ++i)
e0[i] *= 0.25f;
if (!has_transient) {
for (size_t i = half; i < e0.size(); ++i)
e0[i] *= 0.25f;
}
}
}
211 changes: 148 additions & 63 deletions coder/quantize.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,34 @@

inline float percentile85_abs(const std::vector<float>& arr) {
if (arr.empty()) return 0.0f;

std::vector<float> tmp(arr.size());
for (size_t i = 0; i < arr.size(); ++i) tmp[i] = std::abs(arr[i]);
for (size_t i = 0; i < arr.size(); ++i)
tmp[i] = std::abs(arr[i]);

size_t idx = tmp.size() * 83 / 100;
std::nth_element(tmp.begin(), tmp.begin() + idx, tmp.end());
return tmp[idx];
}

inline float compute_powerlaw_deadzone(float step, float rms) {
if (step < 1e-12f) return 0.0f;

if (step < 1e-12f)
return 0.0f;

float energy_ratio = rms / step;

float mult = 0.55f + 0.10f * std::log2f(1.0f + energy_ratio);

mult = std::clamp(mult, 0.50f, 0.70f);

return mult * step;
}

struct TemporalMaskingState {
std::vector<float> prev_effective_rms;
bool initialized = false;

float decay_factor = 0.85f;
};

struct QuantResult {
std::vector<float> scales;
std::vector<std::vector<int32_t>> quantized_per_level;
Expand All @@ -35,124 +44,200 @@ struct QuantResult {
inline QuantResult quantize_levels(
const std::vector<std::vector<std::vector<float>>>& coeffs_channels,
const std::vector<int>& bits_per_level,
float target_kbps)
float target_kbps,
TemporalMaskingState* tm_state = nullptr)
{
const int num_channels = static_cast<int>(coeffs_channels.size());
const int band_count = static_cast<int>(coeffs_channels[0].size());

if (tm_state && !tm_state->initialized) {
tm_state->prev_effective_rms.assign(band_count, 0.0f);
tm_state->initialized = true;
}

std::vector<float> scales(band_count);
std::vector<std::vector<int32_t>> quantized_per_level(band_count);

float deadzone_scale = 1.0f;

if (target_kbps > 192.0f) {
float t = (target_kbps - 192.0f) / (320.0f - 192.0f);
t = std::clamp(t, 0.0f, 1.0f);
deadzone_scale = 1.0f - std::pow(t, 1.5f);
}

deadzone_scale = std::clamp(deadzone_scale, 0.0f, 1.0f);

const int block_size = std::max(4, 256 / band_count);

for (int l = 0; l < band_count; ++l) {
const int bbits = bits_per_level[l];
size_t total_samples = 0;
for (int ch = 0; ch < num_channels; ++ch)
total_samples += coeffs_channels[ch][l].size();

if (total_samples == 0 || bbits <= 0) {
const size_t len = coeffs_channels[0][l].size();
const size_t total_samples = len * static_cast<size_t>(num_channels);

if (len == 0 || bbits <= 0) {
scales[l] = 0.0f;
quantized_per_level[l].assign(total_samples, 0);

if (tm_state)
tm_state->prev_effective_rms[l] = 0.0f;

continue;
}

float max_abs = 0.0f;

const int num_blocks = static_cast<int>(len / block_size);

std::vector<float> block_sum_sq(num_blocks, 0.0f);

if (bbits <= 2) {
std::vector<float> abs_vals;
abs_vals.reserve(total_samples);

for (int ch = 0; ch < num_channels; ++ch) {
const auto& arr = coeffs_channels[ch][l];
for (float v : arr) {
float av = std::abs(v);

for (size_t i = 0; i < len; ++i) {
const float v = arr[i];
const float av = std::abs(v);

abs_vals.push_back(av);
if (av > max_abs) max_abs = av;

if (av > max_abs)
max_abs = av;

const int b = static_cast<int>(i / block_size);

if (b < num_blocks)
block_sum_sq[b] += v * v;
}
}
float p85 = percentile85_abs(abs_vals);
const float THRESH = 3.5f;
max_abs /= 2.0;
// max_abs = (max_abs > THRESH * p85) ? max_abs / 2.0f : p85;
// max_abs /= 2.0f;
} else {

max_abs *= 0.5f;
}
else {
for (int ch = 0; ch < num_channels; ++ch) {
const auto& arr = coeffs_channels[ch][l];
for (float v : arr) {
float av = std::abs(v);
if (av > max_abs) max_abs = av;

for (size_t i = 0; i < len; ++i) {
const float v = arr[i];
const float av = std::abs(v);

if (av > max_abs)
max_abs = av;

const int b = static_cast<int>(i / block_size);

if (b < num_blocks)
block_sum_sq[b] += v * v;
}
}
}
if (max_abs < 1e-12f) max_abs = 1.0f;

if (max_abs < 1e-12f)
max_abs = 1.0f;

int sgn = 1;
if (bbits == 2) {
double sum = 0.0;
for (int ch = 0; ch < num_channels; ++ch)
for (float v : coeffs_channels[ch][l]) sum += v;
sgn = (sum >= 0.0) ? 1 : -1;
}

int max_int = (bbits > 1) ? ((1 << (bbits - 1)) - 1) : 1;
float step = max_abs / static_cast<float>(max_int);
const int max_int =
(bbits > 1) ? ((1 << (bbits - 1)) - 1) : 1;

float sum_sq = 0.0f;
for (int ch = 0; ch < num_channels; ++ch) {
for (float v : coeffs_channels[ch][l]) {
sum_sq += v * v;
const float step =
max_abs / static_cast<float>(max_int);

std::vector<float> block_deadzones(num_blocks);

float current_prev_rms =
tm_state ? tm_state->prev_effective_rms[l] : 0.0f;

for (int b = 0; b < num_blocks; ++b) {
const float block_rms =
std::sqrt(
block_sum_sq[b] /
static_cast<float>(block_size * num_channels)
+ 1e-12f
);

float effective_rms = block_rms;

if (tm_state) {
const float masked_rms =
current_prev_rms * tm_state->decay_factor;

effective_rms = std::max(block_rms, masked_rms);
current_prev_rms = effective_rms;
}

block_deadzones[b] =
compute_powerlaw_deadzone(
step,
effective_rms
) * deadzone_scale;
}
float rms = std::sqrt(sum_sq / static_cast<float>(total_samples) + 1e-12f);

float deadzone = compute_powerlaw_deadzone(step, rms);

if (tm_state)
tm_state->prev_effective_rms[l] = current_prev_rms;

std::vector<int32_t> quantized;
quantized.reserve(total_samples);
quantized.resize(total_samples);

size_t out_pos = 0;

for (int ch = 0; ch < num_channels; ++ch) {
const auto& arr = coeffs_channels[ch][l];
for (float v : arr) {

int b = 0;
size_t next_boundary = block_size;

for (size_t i = 0; i < len; ++i) {
if (i >= next_boundary) {
++b;
next_boundary += block_size;
}

const float v = arr[i];
const float av = std::abs(v);

int32_t q;
float av = std::abs(v);

if (bbits == 1) {
float v_clip = (sgn == 1) ? std::max(0.0f, v) : std::max(0.0f, -v);
q = static_cast<int32_t>(std::round(v_clip / step));
const float v_clip =
(sgn == 1)
? std::max(0.0f, v)
: std::max(0.0f, -v);

q = static_cast<int32_t>(
std::round(v_clip / step)
);

q = std::clamp(q, 0, 1);
} else {
if (av < deadzone * deadzone_scale) {
}
else {
if (av < block_deadzones[b]) {
q = 0;
} else {
float scaled = v / step;
q = static_cast<int32_t>(std::round(scaled));
}
else {
q = static_cast<int32_t>(
std::round(v / step)
);
}
}
quantized.push_back(q);

quantized[out_pos++] = q;
}
}

scales[l] = (bbits == 1) ? ((sgn == 1) ? max_abs : -max_abs) : max_abs;
scales[l] =
(bbits == 1)
? ((sgn == 1) ? max_abs : -max_abs)
: max_abs;

quantized_per_level[l] = std::move(quantized);
}

// for (auto y : quantized_per_level) {
// int64_t k = 0;
// for (auto x : y) {
// k += std::abs(x);
// // std::cout << x << ' ';
// }
// std::cout << k << ' ';
// std::cout << "| ";
// }
// std::cout << '\n';

return { scales, quantized_per_level };
return { std::move(scales), std::move(quantized_per_level) };
}

#endif // QUANTIZE_H
3 changes: 2 additions & 1 deletion decoder/decoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -537,4 +537,5 @@ int main(int argc, char** argv) {
}

return 0;
}
} // DECODER

Loading