/* Воспроизведение собственного Opus-файла voice_file: worker декодирует PCM, SoundManager проигрывает. * Управление — в GUI-потоке; ready(duration,id) вызывается там же, 0 означает ошибку/busy. * cancelPending подавляет результат, не останавливая worker; уничтожение context также подавляет callback. * decodeOpusFile синхронно возвращает число кадров или -1; это отдельный API для worker. */ #pragma once #include #include #include #include class QObject; class VoicePlayer { public: static void playOpusFile(const QString& filePath, QObject* context, std::function ready); static void cancelPending(); static void stop(); static bool isPlaying(); static uint64_t playbackId(); static bool isPreparing(); static int decodeOpusFile(const QString& filePath, std::vector& outPcm, int& outSampleRate, int& outChannels, float& outDurationSec); };