Да пожалуйста, что мне одному-то рефлексировать?! Я только
safe_abs() поправил на свой вкус. #pragma once
#include <stdint.h>
#include <stddef.h>
typedef struct {
int32_t dc_value; // Вычисленная постоянная составляющая
int32_t old_amplitude; // Размах до нормализации (max_abs)
int32_t new_amplitude; // Фактический размах после (если amplitude != 0)
} ChannelStats;
/**
* @brief Нормализация сигнала с получением статистики по каналам
* @param ptr Указатель на данные (каналы чередуются: [0][1][2][0][1][2]...)
* @param count Общее количество элементов (должно быть кратно channels)
* @param channels Количество каналов
* @param amplitude Целевая амплитуда (0 = не нормализовать)
* @param dc_remove Удалять ли DC (0/1)
* @param stats Массив структур ChannelStats (размер >= channels)
* @note Если stats == NULL, статистика не собирается
*/
void normalize_signal(
int32_t* ptr,
size_t count,
int channels,
int32_t amplitude,
int dc_remove,
ChannelStats* stats
);
//================================//
#include "signal_utils.h"
#include <stdlib.h>
#include <limits.h>
static int32_t safe_abs( int32_t v)
{
if ( v == INT32_MIN ) {
return INT32_MAX; // Особый случай.
}
return abs( v);
}
void normalize_signal(
int32_t* ptr,
size_t count,
int channels,
int32_t amplitude,
int dc_remove,
ChannelStats* stats
)
{
if (!ptr || count == 0 || channels <= 0 || count % channels != 0) {
return;
}
const size_t samples_per_channel = count / channels;
for (int ch = 0; ch < channels; ch++) {
// --- Вычисление DC ---
int64_t sum = 0;
for (size_t i = ch; i < count; i += channels) {
sum += ptr[i];
}
const int32_t dc = (int32_t)(sum / (int64_t)samples_per_channel);
// --- Поиск старой амплитуды ---
int32_t max_abs = 0;
for (size_t i = ch; i < count; i += channels) {
const int32_t val = dc_remove ? (ptr[i] - dc) : ptr[i];
const int32_t abs_val = safe_abs(val);
if (abs_val > max_abs) max_abs = abs_val;
}
// --- Сохранение статистики ---
if (stats) {
stats[ch] = (ChannelStats){
.dc_value = dc,
.old_amplitude = max_abs,
.new_amplitude = (amplitude != 0 && max_abs != 0) ? amplitude : max_abs
};
}
// --- Применение изменений ---
if (dc_remove) {
for (size_t i = ch; i < count; i += channels) {
ptr[i] -= dc;
}
}
if (amplitude != 0 && max_abs != 0) {
for (size_t i = ch; i < count; i += channels) {
int64_t scaled = (int64_t)ptr[i] * amplitude / max_abs;
ptr[i] = (scaled > INT32_MAX) ? INT32_MAX :
(scaled < INT32_MIN) ? INT32_MIN : (int32_t)scaled;
}
}
}
}