#include #include #include #include namespace XCEngine { namespace Audio { AudioSystem& AudioSystem::Get() { static AudioSystem instance; return instance; } void AudioSystem::Initialize(const AudioConfig& config) { if (m_backend) { Shutdown(); } m_backend = std::make_unique(); if (m_backend->Initialize(config)) { m_backend->Start(); std::cout << "AudioSystem initialized successfully" << std::endl; } else { std::cout << "Failed to initialize AudioSystem" << std::endl; m_backend.reset(); } } void AudioSystem::Shutdown() { if (m_backend) { m_backend->Stop(); m_backend->Shutdown(); m_backend.reset(); } m_activeSources.clear(); } void AudioSystem::Update(float deltaTime) { m_deltaTime = deltaTime; if (!m_backend || !m_backend->IsRunning()) { return; } const auto& config = m_backend->GetConfig(); uint32 sampleCount = config.bufferSize * config.channels; std::vector mixBuffer(sampleCount, 0.0f); for (auto* source : m_activeSources) { if (source && source->IsEnabled() && source->IsPlaying()) { ProcessSource(source, mixBuffer.data(), sampleCount, config.channels); } } m_backend->ProcessAudio(mixBuffer.data(), sampleCount, config.channels, config.sampleRate); uint32 activeCount = 0; for (auto* source : m_activeSources) { if (source && source->IsPlaying()) { activeCount++; } } m_stats.activeSources = activeCount; m_stats.totalSources = static_cast(m_activeSources.size()); } void AudioSystem::SetBackend(std::unique_ptr backend) { m_backend = std::move(backend); } std::string AudioSystem::GetCurrentDevice() const { if (m_backend) { return m_backend->GetDeviceName(); } return ""; } void AudioSystem::SetDevice(const std::string& deviceName) { if (m_backend) { m_backend->SetDevice(deviceName); } } void AudioSystem::GetAvailableDevices(std::vector& devices) { if (m_backend) { m_backend->GetAvailableDevices(devices); } } float AudioSystem::GetMasterVolume() const { if (m_backend) { return m_backend->GetMasterVolume(); } return 1.0f; } void AudioSystem::SetMasterVolume(float volume) { if (m_backend) { m_backend->SetMasterVolume(volume); } } bool AudioSystem::IsMuted() const { if (m_backend) { return m_backend->IsMuted(); } return false; } void AudioSystem::SetMuted(bool muted) { if (m_backend) { m_backend->SetMuted(muted); } } void AudioSystem::ProcessAudio(float* buffer, uint32 sampleCount, uint32 channels) { if (m_backend) { m_backend->ProcessAudio(buffer, sampleCount, channels, 48000); } } void AudioSystem::SetListenerTransform(const Math::Vector3& position, const Math::Quaternion& rotation) { m_listenerPosition = position; m_listenerRotation = rotation; } void AudioSystem::SetListenerVelocity(const Math::Vector3& velocity) { m_listenerVelocity = velocity; } void AudioSystem::RegisterSource(Components::AudioSourceComponent* source) { if (source) { m_activeSources.push_back(source); } } void AudioSystem::UnregisterSource(Components::AudioSourceComponent* source) { if (!source) { return; } auto it = std::find(m_activeSources.begin(), m_activeSources.end(), source); if (it != m_activeSources.end()) { m_activeSources.erase(it); } } void AudioSystem::ProcessSource(Components::AudioSourceComponent* source, float* buffer, uint32 sampleCount, uint32 channels) { if (!source || !buffer) { return; } source->ProcessAudio(buffer, sampleCount, channels, m_listenerPosition, m_listenerRotation); } } // namespace Audio } // namespace XCEngine