mirror of
https://github.com/mudler/LocalAI.git
synced 2026-07-31 18:38:23 -04:00
Both emit float seconds, converted from the runtime's sample-index spans, and both take a counted reference to the loaded model through snapshot() and hold it for the whole call: a Free arriving mid-request drops only the global's reference, so whichever request finishes last destroys the model instead of one of them running on freed weights. An AddressSanitizer build reproduces exactly that heap-use-after-free inside ggml_vec_dot_f32 when the handler keeps a raw pointer instead, which is why the shape is what it is. The inference lane is taken before session_for, not after. session_for reads and writes an unsynchronised session cache and the offline run calls prepare(), which mutates the session, so both belong inside the lane. Diarize routes before it reads the input file, so a family that cannot diarize at all says so rather than complaining about the audio first. Its per-segment text stays empty because audio.cpp's SpeakerTurn carries a span and a speaker label only, and nested or overlapping turns are passed through untouched: a sortformer turn inside another speaker's turn is correct output for overlapped speech, and LocalAI is overlap-tolerant downstream. Duration counts frames rather than floats, so a stereo input does not report twice its length. Verified end to end against upstream's bundled silero_vad, which needs no download, using the bundled 16 kHz speech asset: a synthetic tone returns nothing, correctly, because silero detects speech and a sine is not speech. Assisted-by: Claude:claude-opus-5 [Claude Code] Signed-off-by: Ettore Di Giacinto <mudler@localai.io>
36 lines
1.4 KiB
C++
36 lines
1.4 KiB
C++
#pragma once
|
|
|
|
// Thin wrappers over the framework's public audio IO. Engine-linked, so this
|
|
// unit is built and tested through the CMake target rather than by
|
|
// backend/cpp/run-unit-tests.sh. The pure part of the arithmetic these
|
|
// wrappers feed lives in audio_units, which is stdlib-only and does have a
|
|
// standalone test.
|
|
|
|
#include "engine/framework/runtime/session.h"
|
|
|
|
#include <string>
|
|
#include <vector>
|
|
|
|
namespace audiocpp_backend {
|
|
|
|
// Reads a WAV file at its native sample rate and channel count. Throws
|
|
// ConfigError when the file is missing, is not readable as WAV, or declares a
|
|
// non-positive sample rate: all three are user-fixable input problems rather
|
|
// than backend faults.
|
|
//
|
|
// A declared sample rate of zero is refused rather than passed on, because
|
|
// every downstream conversion in audio_units answers 0 for a non-positive rate.
|
|
// Accepting it would turn a corrupt header into a response full of zero
|
|
// timestamps, which reads as a real answer.
|
|
engine::runtime::AudioBuffer read_audio_file(const std::string &path);
|
|
|
|
// Writes 16-bit PCM WAV, creating parent directories. Throws ConfigError when
|
|
// the destination cannot be written.
|
|
void write_audio_file(const std::string &path,
|
|
const engine::runtime::AudioBuffer &audio);
|
|
|
|
engine::runtime::AudioBuffer buffer_from_mono(std::vector<float> samples,
|
|
int sample_rate);
|
|
|
|
} // namespace audiocpp_backend
|