/
reds
/
OpenDAW
Обзор
Документация
Войти
/
reds
/
OpenDAW
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
develop
src/core/AudioEngine.cpp
171 строка
5 KB
OpenDAW Developer
feat(v0.4.0): Add Audio Device Backend (ALSA)
21 фев 2026, 02:32
21 фев 2026, 02:32
8473a58
Код
Авторство
О чём код?
#include <opendaw/core/AudioEngine.h> #include <opendaw/io/AudioDevice.h> #include <iostream> #include <algorithm> #include <cmath> namespace opendaw { AudioEngine::AudioEngine() = default; AudioEngine::~AudioEngine() { shutdown(); } bool AudioEngine::initialize() { std::cout << "[AudioEngine] Initializing..." << std::endl; std::cout << " Sample rate: " << config_.sampleRate << " Hz" << std::endl; std::cout << " Block size: " << config_.blockSize << " samples" << std::endl; std::cout << " Latency: " << config_.getLatencyMs() << " ms" << std::endl; // Создаём и инициализируем Audio Device audioDevice_ = AudioDevice::createDefault(); if (audioDevice_) { audioDevice_->setAudioCallback([this]( const float** inputs, float** outputs, int numSamples, int numInputChannels, int numOutputChannels ) { processBlock(outputs, inputs, numSamples, numInputChannels, numOutputChannels); }); // Конвертируем AudioEngineConfig в AudioDeviceConfig AudioDeviceConfig deviceConfig; deviceConfig.sampleRate = static_cast<int>(config_.sampleRate); deviceConfig.blockSize = config_.blockSize; deviceConfig.numInputChannels = config_.numInputChannels; deviceConfig.numOutputChannels = config_.numOutputChannels; deviceConfig.numBuffers = config_.numBuffers; audioDevice_->initialize(deviceConfig); } std::cout << "[AudioEngine] Initialized successfully" << std::endl; return true; } void AudioEngine::shutdown() { stop(); std::cout << "[AudioEngine] Shutdown complete" << std::endl; } bool AudioEngine::start() { if (isRunning()) { return true; } std::cout << "[AudioEngine] Starting..." << std::endl; // Запускаем Audio Device if (audioDevice_) { audioDevice_->start(); } status_ = AudioEngineStatus::Playing; isPlaying_ = true; if (statusCallback_) { statusCallback_(status_); } std::cout << "[AudioEngine] Started (Audio Device running)" << std::endl; return true; } void AudioEngine::stop() { if (!isRunning()) { return; } std::cout << "[AudioEngine] Stopping..." << std::endl; // Останавливаем Audio Device if (audioDevice_) { audioDevice_->stop(); } status_ = AudioEngineStatus::Stopped; isPlaying_ = false; isRecording_ = false; if (statusCallback_) { statusCallback_(status_); } std::cout << "[AudioEngine] Stopped" << std::endl; } void AudioEngine::setPlaying(bool playing) { if (playing) { start(); } else { stop(); } } void AudioEngine::setRecording(bool recording) { isRecording_ = recording; if (recording && !isRunning()) { status_ = AudioEngineStatus::Recording; start(); } else if (!recording && status_ == AudioEngineStatus::Recording) { status_ = AudioEngineStatus::Playing; } } void AudioEngine::setPlayheadPosition(double beats) { playheadPosition_ = beats; } void AudioEngine::setTempo(double bpm) { tempo_ = std::clamp(bpm, 20.0, 300.0); } void AudioEngine::processBlock(float** output, const float** input, int numSamples, int numInputChannels, int numOutputChannels) { // В полной реализации здесь будет обработка аудио-графа // Заглушка: генерация тишины или простой сигнал if (output) { for (int ch = 0; ch < numOutputChannels; ++ch) { if (ch < numInputChannels && input && input[ch]) { // Копирование входа на выход std::copy(input[ch], input[ch] + numSamples, output[ch]); } else { // Тишина std::fill(output[ch], output[ch] + numSamples, 0.0f); } } } // Обновление CPU нагрузки updateCpuLoad(); } void AudioEngine::updateCpuLoad() { // Простая эмуляция CPU load static constexpr float alpha = 0.1f; float estimatedLoad = 0.01f; // 1% для заглушки float current = cpuLoad_.load(); float newLoad = current * (1.0f - alpha) + estimatedLoad * alpha; cpuLoad_.store(newLoad < 1.0f ? newLoad : 1.0f); } void AudioEngine::handleError(const std::string& error) { std::cerr << "[AudioEngine] Error: " << error << std::endl; status_ = AudioEngineStatus::Error; if (errorCallback_) { errorCallback_(error); } if (statusCallback_) { statusCallback_(status_); } } } // namespace opendaw