Kazeia-engine/dist/jni/kazeia_mel.h

64 lines
2.7 KiB
C++

// Mel spectrogram extractor unifié Kazeia-Engine.
// Couvre Whisper (16kHz, 80 mel, log10 + Whisper norm) et Qwen3-TTS speaker encoder
// (24kHz, 128 mel, log naturel + clip 1e-5).
//
// Bit-correct vs librosa/torch reference pour les deux profils.
//
// Layout sortie : [N_MELS, T] = data[mel * T + frame] (PyTorch [B, C, T] / ggml
// ne[0]=T fastest). Compatible directement avec speaker_encoder_encode_waveform()
// et Whisper encoder ONNX (qui veut [1, n_mels, n_frames] fp16).
#pragma once
#include <string>
#include <vector>
#include <cstdint>
namespace kazeia_mel {
enum class WindowKind {
HANN_SYMMETRIC, // torch.hann_window(N) = 0.5*(1-cos(2*pi*n/(N-1))) (TTS)
HANN_PERIODIC, // numpy/HF whisper = 0.5*(1-cos(2*pi*n/N)) (STT)
};
enum class Compression {
LOG_NATURAL, // log(max(mel, eps)) (TTS Qwen3-TTS)
LOG10, // log10(max(mel, eps)) (STT Whisper)
};
enum class PostNorm {
NONE, // pas de post-process (TTS)
WHISPER, // clamp à max-8, puis (x+4)/4 (STT Whisper)
};
struct MelConfig {
int sample_rate = 16000;
int n_fft = 400;
int hop_size = 160;
int win_size = 400;
int n_mels = 80;
int pad_amount = -1; // -1 -> auto : whisper n_fft/2, tts (n_fft-hop)/2
int fixed_n_frames = 0; // 0 -> variable ; >0 -> pad audio à T fixe (whisper=3000=30s)
float clip_eps = 1e-5f; // valeur min avant log
WindowKind window = WindowKind::HANN_SYMMETRIC;
Compression comp = Compression::LOG_NATURAL;
PostNorm post = PostNorm::NONE;
};
// Configs pré-faites — utiliser comme défauts puis customiser au besoin.
MelConfig config_qwen3_tts_speaker(); // SR=24000, N_FFT=1024, hop=256, n_mels=128, log naturel
MelConfig config_whisper(); // SR=16000, N_FFT=400, hop=160, n_mels=80, log10 + WhisperNorm
// Charge mel_basis [n_mels, n_fft/2+1] depuis un fichier binaire f32 (librosa pré-calculé
// ou mel_filters.json converti). Le caller fournit le path et la lib vérifie la taille
// attendue n_mels * (n_fft/2+1).
bool load_mel_basis(const char * path, const MelConfig & cfg, std::vector<float> & out);
// Compute mel spectrogram. wav = mono f32 [-1..1] @ cfg.sample_rate. mel_basis attendu
// dans le layout librosa [n_mels, n_fft/2+1]. Retourne mel [n_mels, T] dans le layout
// data[mel * T + frame]. out_T renvoie le nombre de frames calculés.
std::vector<float> compute(const std::vector<float> & wav,
const std::vector<float> & mel_basis,
const MelConfig & cfg,
int & out_T);
} // namespace kazeia_mel