Added audio player componenet
This commit is contained in:
parent
4bdae7213d
commit
31d9176b0d
46
imgui.ini
46
imgui.ini
@ -14,10 +14,10 @@ Size=1280,701
|
|||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
[Window][Inspector]
|
[Window][Inspector]
|
||||||
Pos=774,19
|
Pos=831,19
|
||||||
Size=506,701
|
Size=449,439
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000006,0
|
DockId=0x0000000D,0
|
||||||
|
|
||||||
[Window][Scene Tree]
|
[Window][Scene Tree]
|
||||||
Pos=0,19
|
Pos=0,19
|
||||||
@ -27,7 +27,7 @@ DockId=0x00000003,0
|
|||||||
|
|
||||||
[Window][Viewport]
|
[Window][Viewport]
|
||||||
Pos=344,19
|
Pos=344,19
|
||||||
Size=428,390
|
Size=485,390
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000007,0
|
DockId=0x00000007,0
|
||||||
|
|
||||||
@ -37,13 +37,13 @@ Collapsed=0
|
|||||||
|
|
||||||
[Window][Performance Info]
|
[Window][Performance Info]
|
||||||
Pos=344,411
|
Pos=344,411
|
||||||
Size=428,309
|
Size=485,309
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000008,2
|
DockId=0x00000008,2
|
||||||
|
|
||||||
[Window][Console]
|
[Window][Console]
|
||||||
Pos=344,411
|
Pos=344,411
|
||||||
Size=428,309
|
Size=485,309
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000008,0
|
DockId=0x00000008,0
|
||||||
|
|
||||||
@ -55,7 +55,7 @@ DockId=0x00000007,1
|
|||||||
|
|
||||||
[Window][Profiler]
|
[Window][Profiler]
|
||||||
Pos=344,411
|
Pos=344,411
|
||||||
Size=428,309
|
Size=485,309
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000008,3
|
DockId=0x00000008,3
|
||||||
|
|
||||||
@ -79,7 +79,7 @@ DockId=0x00000008,1
|
|||||||
|
|
||||||
[Window][Color Correction]
|
[Window][Color Correction]
|
||||||
Pos=344,411
|
Pos=344,411
|
||||||
Size=428,309
|
Size=485,309
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
DockId=0x00000008,1
|
DockId=0x00000008,1
|
||||||
|
|
||||||
@ -94,14 +94,38 @@ Pos=797,551
|
|||||||
Size=325,75
|
Size=325,75
|
||||||
Collapsed=0
|
Collapsed=0
|
||||||
|
|
||||||
|
[Window][Audio VU]
|
||||||
|
Pos=831,509
|
||||||
|
Size=449,211
|
||||||
|
Collapsed=0
|
||||||
|
DockId=0x0000000A,0
|
||||||
|
|
||||||
|
[Window][Audio Mixer]
|
||||||
|
Pos=831,577
|
||||||
|
Size=449,143
|
||||||
|
Collapsed=0
|
||||||
|
DockId=0x0000000C,0
|
||||||
|
|
||||||
|
[Window][Playing Audio]
|
||||||
|
Pos=831,460
|
||||||
|
Size=449,260
|
||||||
|
Collapsed=0
|
||||||
|
DockId=0x0000000E,0
|
||||||
|
|
||||||
[Docking][Data]
|
[Docking][Data]
|
||||||
DockSpace ID=0x11111111 Window=0x1BBC0F80 Pos=0,19 Size=1280,701 Split=X
|
DockSpace ID=0x11111111 Window=0x1BBC0F80 Pos=0,19 Size=1280,701 Split=X
|
||||||
DockNode ID=0x00000005 Parent=0x11111111 SizeRef=772,1158 Split=X
|
DockNode ID=0x00000005 Parent=0x11111111 SizeRef=829,1158 Split=X
|
||||||
DockNode ID=0x00000001 Parent=0x00000005 SizeRef=342,701 Split=Y Selected=0x12EF0F59
|
DockNode ID=0x00000001 Parent=0x00000005 SizeRef=342,701 Split=Y Selected=0x12EF0F59
|
||||||
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=342,575 HiddenTabBar=1 Selected=0x12EF0F59
|
DockNode ID=0x00000003 Parent=0x00000001 SizeRef=342,575 HiddenTabBar=1 Selected=0x12EF0F59
|
||||||
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=342,581 HiddenTabBar=1 Selected=0x36AF052B
|
DockNode ID=0x00000004 Parent=0x00000001 SizeRef=342,581 HiddenTabBar=1 Selected=0x36AF052B
|
||||||
DockNode ID=0x00000002 Parent=0x00000005 SizeRef=428,701 Split=Y Selected=0xC450F867
|
DockNode ID=0x00000002 Parent=0x00000005 SizeRef=485,701 Split=Y Selected=0xC450F867
|
||||||
DockNode ID=0x00000007 Parent=0x00000002 SizeRef=606,847 CentralNode=1 HiddenTabBar=1 Selected=0xC450F867
|
DockNode ID=0x00000007 Parent=0x00000002 SizeRef=606,847 CentralNode=1 HiddenTabBar=1 Selected=0xC450F867
|
||||||
DockNode ID=0x00000008 Parent=0x00000002 SizeRef=606,309 Selected=0x9B5D3198
|
DockNode ID=0x00000008 Parent=0x00000002 SizeRef=606,309 Selected=0x9B5D3198
|
||||||
DockNode ID=0x00000006 Parent=0x11111111 SizeRef=506,1158 HiddenTabBar=1 Selected=0x36DC96AB
|
DockNode ID=0x00000006 Parent=0x11111111 SizeRef=449,1158 Split=Y Selected=0x36DC96AB
|
||||||
|
DockNode ID=0x00000009 Parent=0x00000006 SizeRef=449,488 Split=Y Selected=0x36DC96AB
|
||||||
|
DockNode ID=0x0000000B Parent=0x00000009 SizeRef=449,556 Split=Y Selected=0x36DC96AB
|
||||||
|
DockNode ID=0x0000000D Parent=0x0000000B SizeRef=449,439 HiddenTabBar=1 Selected=0x36DC96AB
|
||||||
|
DockNode ID=0x0000000E Parent=0x0000000B SizeRef=449,260 HiddenTabBar=1 Selected=0x9D7E7171
|
||||||
|
DockNode ID=0x0000000C Parent=0x00000009 SizeRef=449,143 HiddenTabBar=1 Selected=0xB6C74292
|
||||||
|
DockNode ID=0x0000000A Parent=0x00000006 SizeRef=449,211 HiddenTabBar=1 Selected=0xD83E5DD3
|
||||||
|
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
[LINK] g++ src\build\Engine.o src\build\main.o src\build\Renderer.o src\build\Components\AnimationComponent.o src\build\Components\CameraComponent.o src\build\Components\LightComponent.o src\build\Components\ParticleComponent.o src\build\Components\PhysicsComponent.o src\build\Components\ScriptComponent.o src\build\Components\SpriteComponent.o src\build\Components\TextComonent.o src\build\Components\TilemapComponent.o src\build\core\audio\AudioEngine.o src\build\core\utils\AssetManager.o src\build\core\utils\EngineConfig.o src\build\core\utils\ExceptionHandler.o src\build\core\utils\FileDialog.o src\build\core\utils\input.o src\build\core\utils\LoadingWindow.o src\build\core\utils\Logging.o src\build\core\utils\Profiler.o src\build\core\utils\Texture.o src\build\core\utils\utils.o src\build\editor\windows\AssetBrowser.o src\build\editor\windows\Inspector.o src\build\Entitys\Object.o src\build\utils\GameObjectsList.o src\build\utils\Shader.o src\build\utils\UID.o src\build\lapi.o src\build\lauxlib.o src\build\lbaselib.o src\build\lcode.o src\build\lcorolib.o src\build\lctype.o src\build\ldblib.o src\build\ldebug.o src\build\ldo.o src\build\ldump.o src\build\lfunc.o src\build\lgc.o src\build\linit.o src\build\liolib.o src\build\llex.o src\build\lmathlib.o src\build\lmem.o src\build\loadlib.o src\build\lobject.o src\build\lopcodes.o src\build\loslib.o src\build\lparser.o src\build\lstate.o src\build\lstring.o src\build\lstrlib.o src\build\ltable.o src\build\ltablib.o src\build\ltm.o src\build\lua.o src\build\luac.o src\build\lundump.o src\build\lutf8lib.o src\build\lvm.o src\build\lzio.o src\build\imgui.o src\build\imgui_demo.o src\build\imgui_draw.o src\build\imgui_impl_glfw.o src\build\imgui_impl_opengl3.o src\build\imgui_tables.o src\build\imgui_widgets.o src\build\aabb.o src\build\arena_allocator.o src\build\array.o src\build\bitset.o src\build\body.o src\build\broad_phase.o src\build\constraint_graph.o src\build\contact.o src\build\contact_solver.o src\build\core.o src\build\distance.o src\build\distance_joint.o src\build\dynamic_tree.o src\build\geometry.o src\build\hull.o src\build\id_pool.o src\build\island.o src\build\joint.o src\build\manifold.o src\build\math_functions.o src\build\motor_joint.o src\build\mouse_joint.o src\build\mover.o src\build\prismatic_joint.o src\build\revolute_joint.o src\build\sensor.o src\build\shape.o src\build\solver.o src\build\solver_set.o src\build\table.o src\build\timer.o src\build\types.o src\build\weld_joint.o src\build\wheel_joint.o src\build\world.o src\build\xxhash.o -o src\build\app.exe -LC:\msys64\mingw64\lib -lglfw3 -lglew32 -lopengl32 -lgdi32 -lyaml-cpp -lcomdlg32 -lssl -lcrypto
|
|
||||||
[RUN] Executed app.exe successfully.
|
|
60
src/assets/scenes/audio_test.cene
Normal file
60
src/assets/scenes/audio_test.cene
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
engine_version: 0.1.0
|
||||||
|
scene_name: audio_test
|
||||||
|
scene_hash: 2f3968cbbb1905084ea57585a1e25851d20881c0027323ccc1f8b56bc53c90c0
|
||||||
|
format_version: 1
|
||||||
|
objects:
|
||||||
|
- name: Hello, Create
|
||||||
|
uid: 4afb134ba5a84d3d837374e314ca9adb
|
||||||
|
id: 0
|
||||||
|
position: [0, 0]
|
||||||
|
rotation: 0
|
||||||
|
layer: 0
|
||||||
|
visable: true
|
||||||
|
components:
|
||||||
|
- type: AudioPlayerComponent
|
||||||
|
uaid: 1
|
||||||
|
volume: 1
|
||||||
|
loop: false
|
||||||
|
children: []
|
||||||
|
color_correction:
|
||||||
|
brightness: 1
|
||||||
|
saturation: 1
|
||||||
|
gamma: 1
|
||||||
|
bloom: true
|
||||||
|
intensity: 1.20000005
|
||||||
|
threshold: 1
|
||||||
|
Assets:
|
||||||
|
- uaid: 4
|
||||||
|
path: C:\Users\spenc\OneDrive\Pictures\textures\ganges_river_pebbles_nor_gl_1k.png
|
||||||
|
filename: ganges_river_pebbles_nor_gl_1k.png
|
||||||
|
filetype: png
|
||||||
|
type: 0
|
||||||
|
hash: 6711b00700d4c94a
|
||||||
|
lastModified: 1744565594
|
||||||
|
size: [1024, 1024]
|
||||||
|
channels: 4
|
||||||
|
format: GL_RGBA
|
||||||
|
- uaid: 3
|
||||||
|
path: C:\Users\spenc\OneDrive\Pictures\textures\ganges_river_pebbles_diff_1k.png
|
||||||
|
filename: ganges_river_pebbles_diff_1k.png
|
||||||
|
filetype: png
|
||||||
|
type: 0
|
||||||
|
hash: 0349580fcbf62155
|
||||||
|
lastModified: 1744565606
|
||||||
|
size: [1024, 1024]
|
||||||
|
channels: 4
|
||||||
|
format: GL_RGBA
|
||||||
|
- uaid: 2
|
||||||
|
path: C:\Users\spenc\Music\simple-notification-152054.mp3
|
||||||
|
filename: simple-notification-152054.mp3
|
||||||
|
filetype: mp3
|
||||||
|
type: 1
|
||||||
|
hash: 3e57c2530f08c1ab
|
||||||
|
lastModified: 1745951639
|
||||||
|
- uaid: 1
|
||||||
|
path: C:\Users\spenc\Music\simple-notification-152054.wav
|
||||||
|
filename: simple-notification-152054.wav
|
||||||
|
filetype: wav
|
||||||
|
type: 1
|
||||||
|
hash: 0f5adca8b95e7494
|
||||||
|
lastModified: 1745953000
|
100
src/src/Components/AudioPlayerComponent.cpp
Normal file
100
src/src/Components/AudioPlayerComponent.cpp
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
#include "AudioPlayerComponent.h"
|
||||||
|
#include "../core/utils/Logging.h"
|
||||||
|
|
||||||
|
AudioPlayerComponent::AudioPlayerComponent(Object* owner)
|
||||||
|
: Component(owner) {}
|
||||||
|
|
||||||
|
AudioPlayerComponent::~AudioPlayerComponent()
|
||||||
|
{
|
||||||
|
if (m_OwnsSound && m_Sound)
|
||||||
|
{
|
||||||
|
ma_sound_uninit(m_Sound);
|
||||||
|
delete m_Sound;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioPlayerComponent::SetAudio(uint64_t uaid)
|
||||||
|
{
|
||||||
|
Stop();
|
||||||
|
m_UAID = uaid;
|
||||||
|
|
||||||
|
const auto* asset = dynamic_cast<const AudioAssetInfo*>(AssetManager::GetAssetByID(uaid));
|
||||||
|
if (!asset || !asset->loaded)
|
||||||
|
{
|
||||||
|
Logger::LogWarning("AudioPlayerComponent: Asset not found or not loaded (UAID: %llu)", uaid);
|
||||||
|
m_Sound = nullptr;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_Sound = asset->sound;
|
||||||
|
m_OwnsSound = false;
|
||||||
|
|
||||||
|
ma_sound_set_volume(m_Sound, volume);
|
||||||
|
ma_sound_set_looping(m_Sound, loop ? MA_TRUE : MA_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioPlayerComponent::Play()
|
||||||
|
{
|
||||||
|
if (m_Sound) ma_sound_start(m_Sound);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioPlayerComponent::Pause()
|
||||||
|
{
|
||||||
|
if (m_Sound) ma_sound_stop(m_Sound);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioPlayerComponent::Stop()
|
||||||
|
{
|
||||||
|
if (m_Sound)
|
||||||
|
{
|
||||||
|
ma_sound_stop(m_Sound);
|
||||||
|
ma_sound_seek_to_pcm_frame(m_Sound, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioPlayerComponent::SetLooping(bool value)
|
||||||
|
{
|
||||||
|
loop = value;
|
||||||
|
if (m_Sound) ma_sound_set_looping(m_Sound, value ? MA_TRUE : MA_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioPlayerComponent::SetVolume(float vol)
|
||||||
|
{
|
||||||
|
volume = vol;
|
||||||
|
if (m_Sound) ma_sound_set_volume(m_Sound, vol);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool AudioPlayerComponent::IsPlaying() const
|
||||||
|
{
|
||||||
|
return m_Sound && ma_sound_is_playing(m_Sound);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string AudioPlayerComponent::GetName() const
|
||||||
|
{
|
||||||
|
return "AudioPlayerComponent";
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioPlayerComponent::Save(YAML::Emitter& out) const
|
||||||
|
{
|
||||||
|
|
||||||
|
out << YAML::BeginMap;
|
||||||
|
out << YAML::Key << "type" << YAML::Value << GetName();
|
||||||
|
out << YAML::Key << "uaid" << YAML::Value << m_UAID;
|
||||||
|
out << YAML::Key << "volume" << YAML::Value << volume;
|
||||||
|
out << YAML::Key << "loop" << YAML::Value << loop;
|
||||||
|
out << YAML::EndMap;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioPlayerComponent::Load(const YAML::Node& node)
|
||||||
|
{
|
||||||
|
if (node["uaid"])
|
||||||
|
{
|
||||||
|
m_UAID = node["uaid"].as<uint64_t>();
|
||||||
|
SetAudio(m_UAID);
|
||||||
|
}
|
||||||
|
if (node["volume"])
|
||||||
|
SetVolume(node["volume"].as<float>());
|
||||||
|
if (node["loop"])
|
||||||
|
SetLooping(node["loop"].as<bool>());
|
||||||
|
}
|
37
src/src/Components/AudioPlayerComponent.h
Normal file
37
src/src/Components/AudioPlayerComponent.h
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#pragma once
|
||||||
|
#include "Component.h"
|
||||||
|
#include "../core/audio/AudioEngine.h"
|
||||||
|
#include "../core/utils/AssetManager.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
class AudioPlayerComponent : public Component
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
AudioPlayerComponent(Object* owner);
|
||||||
|
~AudioPlayerComponent();
|
||||||
|
|
||||||
|
void SetAudio(uint64_t uaid);
|
||||||
|
void Play();
|
||||||
|
void Pause();
|
||||||
|
void Stop();
|
||||||
|
|
||||||
|
void SetLooping(bool loop);
|
||||||
|
void SetVolume(float vol);
|
||||||
|
|
||||||
|
bool IsPlaying() const;
|
||||||
|
|
||||||
|
// Serialization
|
||||||
|
std::string GetName() const override;
|
||||||
|
void Save(YAML::Emitter& out) const override;
|
||||||
|
void Load(const YAML::Node& node) override;
|
||||||
|
|
||||||
|
uint64_t GetUAID() const { return m_UAID; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
ma_sound* m_Sound = nullptr;
|
||||||
|
uint64_t m_UAID = 0;
|
||||||
|
bool m_OwnsSound = false;
|
||||||
|
|
||||||
|
float volume = 1.0f;
|
||||||
|
bool loop = false;
|
||||||
|
};
|
@ -15,7 +15,6 @@
|
|||||||
|
|
||||||
#include "core/audio/AudioEngine.h"
|
#include "core/audio/AudioEngine.h"
|
||||||
|
|
||||||
|
|
||||||
#include "core/utils/EngineConfig.h"
|
#include "core/utils/EngineConfig.h"
|
||||||
#include "utils/GameObjectsList.h"
|
#include "utils/GameObjectsList.h"
|
||||||
#include "core/utils/Profiler.h"
|
#include "core/utils/Profiler.h"
|
||||||
@ -517,8 +516,6 @@ void Engine::Init()
|
|||||||
|
|
||||||
AudioEngine::Init();
|
AudioEngine::Init();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Logger::LogVerbose("Resverving Objects");
|
Logger::LogVerbose("Resverving Objects");
|
||||||
|
|
||||||
// These values were AI Generated.
|
// These values were AI Generated.
|
||||||
@ -540,6 +537,44 @@ core::types::Vec2 ScreenToWorld(const core::types::Vec2 &screenPos, const core::
|
|||||||
return world;
|
return world;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void DrawAudioPlayingList()
|
||||||
|
{
|
||||||
|
ImGui::Begin("Playing Audio");
|
||||||
|
|
||||||
|
std::vector<uint64_t> toStop;
|
||||||
|
|
||||||
|
for (const auto& [uaid, psound] : AudioEngine::GetPlayingSounds())
|
||||||
|
{
|
||||||
|
ImGui::Text("%s", psound.name.c_str());
|
||||||
|
|
||||||
|
if (psound.totalTime > 0.0)
|
||||||
|
{
|
||||||
|
float progress = static_cast<float>(psound.currentTime / psound.totalTime);
|
||||||
|
ImGui::ProgressBar(progress, ImVec2(-1.0f, 6.0f));
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Text("Time: %.2f / %.2f sec", psound.currentTime, psound.totalTime);
|
||||||
|
|
||||||
|
if (ImGui::Button(("Stop##" + std::to_string(uaid)).c_str()))
|
||||||
|
{
|
||||||
|
toStop.push_back(uaid);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::Separator();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui::End();
|
||||||
|
|
||||||
|
for (uint64_t id : toStop)
|
||||||
|
AudioEngine::Stop(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Engine::collectObjects(bool playing, const glm::vec2 &camPos, float camZoom)
|
void Engine::collectObjects(bool playing, const glm::vec2 &camPos, float camZoom)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -743,7 +778,7 @@ void Engine::Run()
|
|||||||
ShowColorCorrectionWindow();
|
ShowColorCorrectionWindow();
|
||||||
|
|
||||||
ShowAssetBrowser();
|
ShowAssetBrowser();
|
||||||
|
DrawAudioPlayingList();
|
||||||
{
|
{
|
||||||
PROFILE_ENGINE_SCOPE("Engine::DrawSceneTree");
|
PROFILE_ENGINE_SCOPE("Engine::DrawSceneTree");
|
||||||
|
|
||||||
@ -947,6 +982,8 @@ void Engine::Run()
|
|||||||
|
|
||||||
profiler.EndSection();
|
profiler.EndSection();
|
||||||
|
|
||||||
|
AudioEngine::Update();
|
||||||
|
|
||||||
profiler.BeginSection("Render");
|
profiler.BeginSection("Render");
|
||||||
for (auto *obj : m_toDraw)
|
for (auto *obj : m_toDraw)
|
||||||
{
|
{
|
||||||
@ -1563,6 +1600,5 @@ void Engine::Shutdown()
|
|||||||
|
|
||||||
AudioEngine::Shutdown();
|
AudioEngine::Shutdown();
|
||||||
|
|
||||||
|
|
||||||
std::filesystem::remove(tempScenePath);
|
std::filesystem::remove(tempScenePath);
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,8 @@
|
|||||||
#include "../Components/ScriptComponent.h"
|
#include "../Components/ScriptComponent.h"
|
||||||
#include "../Components/ParticleComponent.h"
|
#include "../Components/ParticleComponent.h"
|
||||||
#include "../Components/AnimationComponent.h"
|
#include "../Components/AnimationComponent.h"
|
||||||
|
#include "../Components/AudioPlayerComponent.h"
|
||||||
|
|
||||||
|
|
||||||
#include "../core/utils/Logging.h"
|
#include "../core/utils/Logging.h"
|
||||||
#include "../utils/UID.h"
|
#include "../utils/UID.h"
|
||||||
@ -165,6 +167,8 @@ void Object::Load(const YAML::Node &node)
|
|||||||
AddComponent<ParticleComponent>()->Load(compNode);
|
AddComponent<ParticleComponent>()->Load(compNode);
|
||||||
else if (type == "AnimationComponent")
|
else if (type == "AnimationComponent")
|
||||||
AddComponent<AnimationComponent>()->Load(compNode);
|
AddComponent<AnimationComponent>()->Load(compNode);
|
||||||
|
else if (type == "AudioPlayerComponent")
|
||||||
|
AddComponent<AudioPlayerComponent>()->Load(compNode);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Logger::LogError("Invalid Componenet type '%s' found in component '%s'(%d)", type.c_str(), name.c_str(), uid.id);
|
Logger::LogError("Invalid Componenet type '%s' found in component '%s'(%d)", type.c_str(), name.c_str(), uid.id);
|
||||||
|
@ -2,80 +2,95 @@
|
|||||||
#define MA_ENABLE_WAV
|
#define MA_ENABLE_WAV
|
||||||
#define MA_ENABLE_FLAC
|
#define MA_ENABLE_FLAC
|
||||||
#define MA_ENABLE_VORBIS
|
#define MA_ENABLE_VORBIS
|
||||||
|
#define MA_IMPLEMENTATION
|
||||||
#include "AudioEngine.h"
|
#include "AudioEngine.h"
|
||||||
#include "../utils/AssetManager.h"
|
#include "../utils/AssetManager.h"
|
||||||
#include "../utils/Logging.h"
|
#include "../utils/Logging.h"
|
||||||
|
|
||||||
ma_engine AudioEngine::s_Engine{};
|
ma_engine AudioEngine::s_Engine{};
|
||||||
std::unordered_map<uint64_t, ma_sound> AudioEngine::s_SoundMap;
|
std::unordered_map<uint64_t, PlayingSound> AudioEngine::s_PlayingSounds;
|
||||||
|
|
||||||
bool AudioEngine::Init()
|
bool AudioEngine::Init() {
|
||||||
{
|
if (ma_engine_init(nullptr, &s_Engine) != MA_SUCCESS) {
|
||||||
ma_result result = ma_engine_init(nullptr, &s_Engine);
|
Logger::LogError("Failed to start AudioCore");
|
||||||
if (result != MA_SUCCESS)
|
|
||||||
{
|
|
||||||
Logger::LogError("Failed to start AudioCore: %s", MiniaudioResultToString(result));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::LogVerbose("AudioCore initialized successfully.");
|
Logger::LogVerbose("AudioCore initialized successfully.");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudioEngine::Shutdown() {
|
||||||
void AudioEngine::Shutdown()
|
for (auto& [_, s] : s_PlayingSounds)
|
||||||
{
|
s.Stop();
|
||||||
for (auto& [_, sound] : s_SoundMap)
|
s_PlayingSounds.clear();
|
||||||
ma_sound_uninit(&sound);
|
|
||||||
s_SoundMap.clear();
|
|
||||||
ma_engine_uninit(&s_Engine);
|
ma_engine_uninit(&s_Engine);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioEngine::Play(uint64_t uaid, bool loop)
|
void AudioEngine::Play(uint64_t uaid, bool loop) {
|
||||||
{
|
if (s_PlayingSounds.find(uaid) == s_PlayingSounds.end()) {
|
||||||
if (s_SoundMap.find(uaid) == s_SoundMap.end())
|
|
||||||
{
|
|
||||||
const auto* asset = AssetManager::GetAssetByID(uaid);
|
const auto* asset = AssetManager::GetAssetByID(uaid);
|
||||||
if (!asset || !asset->loaded || asset->type != AssetType::Audio)
|
if (!asset || !asset->loaded || asset->type != AssetType::Audio) {
|
||||||
{
|
|
||||||
Logger::LogError("[AudioEngine] Invalid or unloaded audio asset: %llu", uaid);
|
Logger::LogError("[AudioEngine] Invalid or unloaded audio asset: %llu", uaid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ma_sound sound;
|
ma_sound sound;
|
||||||
if (ma_sound_init_from_file(&s_Engine, asset->path.c_str(), 0, NULL, NULL, &sound) != MA_SUCCESS)
|
if (ma_sound_init_from_file(&s_Engine, asset->path.c_str(), 0, nullptr, nullptr, &sound) != MA_SUCCESS) {
|
||||||
{
|
Logger::LogError("[AudioEngine] Failed to load sound: %s", asset->path.c_str());
|
||||||
Logger::LogError("[AudioEngine] Failed to initialize sound from: %s", asset->path.c_str());
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
s_SoundMap[uaid] = sound;
|
|
||||||
}
|
|
||||||
|
|
||||||
auto& sound = s_SoundMap[uaid];
|
|
||||||
ma_sound_set_looping(&sound, loop);
|
ma_sound_set_looping(&sound, loop);
|
||||||
ma_sound_start(&sound);
|
|
||||||
|
ma_uint64 totalFrames = 0;
|
||||||
|
ma_sound_get_length_in_pcm_frames(&sound, &totalFrames);
|
||||||
|
ma_uint32 sampleRate = ma_engine_get_sample_rate(&s_Engine);
|
||||||
|
double totalSeconds = sampleRate > 0 ? double(totalFrames) / sampleRate : 0.0;
|
||||||
|
|
||||||
|
PlayingSound ps{ uaid, asset->filename, sound, 0.0, totalSeconds };
|
||||||
|
s_PlayingSounds[uaid] = ps;
|
||||||
|
|
||||||
|
ma_sound_start(&s_PlayingSounds[uaid].sound);
|
||||||
|
} else {
|
||||||
|
auto& s = s_PlayingSounds[uaid];
|
||||||
|
ma_sound_set_looping(&s.sound, loop);
|
||||||
|
ma_sound_start(&s.sound);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioEngine::Stop(uint64_t uaid)
|
void AudioEngine::Stop(uint64_t uaid) {
|
||||||
{
|
auto it = s_PlayingSounds.find(uaid);
|
||||||
auto it = s_SoundMap.find(uaid);
|
if (it != s_PlayingSounds.end()) {
|
||||||
if (it != s_SoundMap.end())
|
it->second.Stop();
|
||||||
ma_sound_stop(&it->second);
|
s_PlayingSounds.erase(it);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioEngine::StopAll()
|
void AudioEngine::StopAll() {
|
||||||
{
|
for (auto& [_, s] : s_PlayingSounds)
|
||||||
for (auto& [_, sound] : s_SoundMap)
|
s.Stop();
|
||||||
ma_sound_stop(&sound);
|
s_PlayingSounds.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AudioEngine::Unload(uint64_t uaid)
|
void AudioEngine::Unload(uint64_t uaid) {
|
||||||
{
|
Stop(uaid);
|
||||||
auto it = s_SoundMap.find(uaid);
|
}
|
||||||
if (it != s_SoundMap.end())
|
|
||||||
{
|
void AudioEngine::Update() {
|
||||||
ma_sound_uninit(&it->second);
|
for (auto it = s_PlayingSounds.begin(); it != s_PlayingSounds.end();) {
|
||||||
s_SoundMap.erase(it);
|
if (!ma_sound_is_playing(&it->second.sound)) {
|
||||||
|
it->second.Stop();
|
||||||
|
it = s_PlayingSounds.erase(it);
|
||||||
|
} else {
|
||||||
|
ma_uint64 cursorFrames = 0;
|
||||||
|
ma_sound_get_cursor_in_pcm_frames(&it->second.sound, &cursorFrames);
|
||||||
|
ma_uint32 sampleRate = ma_engine_get_sample_rate(&s_Engine);
|
||||||
|
it->second.currentTime = sampleRate > 0 ? static_cast<double>(cursorFrames) / sampleRate : 0.0;
|
||||||
|
++it;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::unordered_map<uint64_t, PlayingSound>& AudioEngine::GetPlayingSounds() {
|
||||||
|
return s_PlayingSounds;
|
||||||
|
}
|
||||||
|
@ -4,8 +4,20 @@
|
|||||||
#include "miniaudio.h"
|
#include "miniaudio.h"
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
class AudioEngine
|
struct PlayingSound {
|
||||||
{
|
uint64_t uaid;
|
||||||
|
std::string name;
|
||||||
|
ma_sound sound;
|
||||||
|
double currentTime = 0.0;
|
||||||
|
double totalTime = 0.0;
|
||||||
|
|
||||||
|
void Stop() {
|
||||||
|
ma_sound_stop(&sound);
|
||||||
|
ma_sound_uninit(&sound);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class AudioEngine {
|
||||||
public:
|
public:
|
||||||
static bool Init();
|
static bool Init();
|
||||||
static void Shutdown();
|
static void Shutdown();
|
||||||
@ -14,10 +26,12 @@ public:
|
|||||||
static void Stop(uint64_t uaid);
|
static void Stop(uint64_t uaid);
|
||||||
static void StopAll();
|
static void StopAll();
|
||||||
static void Unload(uint64_t uaid);
|
static void Unload(uint64_t uaid);
|
||||||
|
static void Update();
|
||||||
|
|
||||||
static ma_engine* GetEngine() { return &s_Engine; }
|
static ma_engine* GetEngine() { return &s_Engine; }
|
||||||
|
static const std::unordered_map<uint64_t, PlayingSound>& GetPlayingSounds();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static ma_engine s_Engine;
|
static ma_engine s_Engine;
|
||||||
static std::unordered_map<uint64_t, ma_sound> s_SoundMap;
|
static std::unordered_map<uint64_t, PlayingSound> s_PlayingSounds;
|
||||||
};
|
};
|
||||||
|
BIN
src/src/core/data/icons/lightbulb-on-20.png
Normal file
BIN
src/src/core/data/icons/lightbulb-on-20.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.2 KiB |
0
src/src/core/data/icons/sound.h
Normal file
0
src/src/core/data/icons/sound.h
Normal file
BIN
src/src/core/data/icons/video.png
Normal file
BIN
src/src/core/data/icons/video.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.7 KiB |
BIN
src/src/core/data/icons/volume-high.png
Normal file
BIN
src/src/core/data/icons/volume-high.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 7.1 KiB |
@ -6,103 +6,169 @@
|
|||||||
#define STB_IMAGE_IMPLEMENTATION
|
#define STB_IMAGE_IMPLEMENTATION
|
||||||
#include <stb_image.h>
|
#include <stb_image.h>
|
||||||
|
|
||||||
#define MINIAUDIO_IMPLEMENTATION
|
|
||||||
#define MA_ENABLE_MP3
|
|
||||||
#define MA_ENABLE_WAV
|
|
||||||
#define MA_ENABLE_FLAC
|
|
||||||
#define MA_ENABLE_VORBIS
|
|
||||||
#include "miniaudio.h"
|
|
||||||
|
|
||||||
std::unordered_map<uint64_t, std::shared_ptr<AssetInfo>> AssetManager::s_Assets;
|
std::unordered_map<uint64_t, std::shared_ptr<AssetInfo>> AssetManager::s_Assets;
|
||||||
std::unordered_map<std::string, uint64_t> AssetManager::s_PathToUAID;
|
std::unordered_map<std::string, uint64_t> AssetManager::s_PathToUAID;
|
||||||
uint64_t AssetManager::s_NextUAID = 1;
|
uint64_t AssetManager::s_NextUAID = 1;
|
||||||
|
|
||||||
|
|
||||||
const char *MiniaudioResultToString(ma_result result)
|
const char *MiniaudioResultToString(ma_result result)
|
||||||
{
|
{
|
||||||
switch (result)
|
switch (result)
|
||||||
{
|
{
|
||||||
case MA_SUCCESS: return "Success";
|
case MA_SUCCESS:
|
||||||
case MA_ERROR: return "Generic error";
|
return "Success";
|
||||||
case MA_INVALID_ARGS: return "Invalid arguments";
|
case MA_ERROR:
|
||||||
case MA_INVALID_OPERATION: return "Invalid operation";
|
return "Generic error";
|
||||||
case MA_OUT_OF_MEMORY: return "Out of memory";
|
case MA_INVALID_ARGS:
|
||||||
case MA_OUT_OF_RANGE: return "Out of range";
|
return "Invalid arguments";
|
||||||
case MA_ACCESS_DENIED: return "Access denied";
|
case MA_INVALID_OPERATION:
|
||||||
case MA_DOES_NOT_EXIST: return "File does not exist";
|
return "Invalid operation";
|
||||||
case MA_ALREADY_EXISTS: return "File already exists";
|
case MA_OUT_OF_MEMORY:
|
||||||
case MA_TOO_MANY_OPEN_FILES: return "Too many open files";
|
return "Out of memory";
|
||||||
case MA_INVALID_FILE: return "Invalid or corrupted file";
|
case MA_OUT_OF_RANGE:
|
||||||
case MA_TOO_BIG: return "File too big";
|
return "Out of range";
|
||||||
case MA_PATH_TOO_LONG: return "Path too long";
|
case MA_ACCESS_DENIED:
|
||||||
case MA_NAME_TOO_LONG: return "Name too long";
|
return "Access denied";
|
||||||
case MA_NOT_DIRECTORY: return "Not a directory";
|
case MA_DOES_NOT_EXIST:
|
||||||
case MA_IS_DIRECTORY: return "Is a directory";
|
return "File does not exist";
|
||||||
case MA_DIRECTORY_NOT_EMPTY: return "Directory not empty";
|
case MA_ALREADY_EXISTS:
|
||||||
case MA_AT_END: return "End of file or stream";
|
return "File already exists";
|
||||||
case MA_NO_SPACE: return "No space left on device";
|
case MA_TOO_MANY_OPEN_FILES:
|
||||||
case MA_BUSY: return "Resource busy";
|
return "Too many open files";
|
||||||
case MA_IO_ERROR: return "I/O error";
|
case MA_INVALID_FILE:
|
||||||
case MA_INTERRUPT: return "Operation interrupted";
|
return "Invalid or corrupted file";
|
||||||
case MA_UNAVAILABLE: return "Resource unavailable";
|
case MA_TOO_BIG:
|
||||||
case MA_ALREADY_IN_USE: return "Already in use";
|
return "File too big";
|
||||||
case MA_BAD_ADDRESS: return "Bad memory address";
|
case MA_PATH_TOO_LONG:
|
||||||
case MA_BAD_SEEK: return "Bad seek operation";
|
return "Path too long";
|
||||||
case MA_BAD_PIPE: return "Bad pipe";
|
case MA_NAME_TOO_LONG:
|
||||||
case MA_DEADLOCK: return "Deadlock detected";
|
return "Name too long";
|
||||||
case MA_TOO_MANY_LINKS: return "Too many symbolic links";
|
case MA_NOT_DIRECTORY:
|
||||||
case MA_NOT_IMPLEMENTED: return "Not implemented";
|
return "Not a directory";
|
||||||
case MA_NO_MESSAGE: return "No message available";
|
case MA_IS_DIRECTORY:
|
||||||
case MA_BAD_MESSAGE: return "Bad message format";
|
return "Is a directory";
|
||||||
case MA_NO_DATA_AVAILABLE: return "No data available";
|
case MA_DIRECTORY_NOT_EMPTY:
|
||||||
case MA_INVALID_DATA: return "Invalid data";
|
return "Directory not empty";
|
||||||
case MA_TIMEOUT: return "Operation timed out";
|
case MA_AT_END:
|
||||||
case MA_NO_NETWORK: return "Network unavailable";
|
return "End of file or stream";
|
||||||
case MA_NOT_UNIQUE: return "Not unique";
|
case MA_NO_SPACE:
|
||||||
case MA_NOT_SOCKET: return "Not a socket";
|
return "No space left on device";
|
||||||
case MA_NO_ADDRESS: return "No address available";
|
case MA_BUSY:
|
||||||
case MA_BAD_PROTOCOL: return "Bad protocol";
|
return "Resource busy";
|
||||||
case MA_PROTOCOL_UNAVAILABLE: return "Protocol unavailable";
|
case MA_IO_ERROR:
|
||||||
case MA_PROTOCOL_NOT_SUPPORTED: return "Protocol not supported";
|
return "I/O error";
|
||||||
case MA_PROTOCOL_FAMILY_NOT_SUPPORTED: return "Protocol family not supported";
|
case MA_INTERRUPT:
|
||||||
case MA_ADDRESS_FAMILY_NOT_SUPPORTED: return "Address family not supported";
|
return "Operation interrupted";
|
||||||
case MA_SOCKET_NOT_SUPPORTED: return "Socket not supported";
|
case MA_UNAVAILABLE:
|
||||||
case MA_CONNECTION_RESET: return "Connection reset";
|
return "Resource unavailable";
|
||||||
case MA_ALREADY_CONNECTED: return "Already connected";
|
case MA_ALREADY_IN_USE:
|
||||||
case MA_NOT_CONNECTED: return "Not connected";
|
return "Already in use";
|
||||||
case MA_CONNECTION_REFUSED: return "Connection refused";
|
case MA_BAD_ADDRESS:
|
||||||
case MA_NO_HOST: return "Host not found";
|
return "Bad memory address";
|
||||||
case MA_IN_PROGRESS: return "Operation in progress";
|
case MA_BAD_SEEK:
|
||||||
case MA_CANCELLED: return "Operation cancelled";
|
return "Bad seek operation";
|
||||||
case MA_MEMORY_ALREADY_MAPPED: return "Memory already mapped";
|
case MA_BAD_PIPE:
|
||||||
|
return "Bad pipe";
|
||||||
|
case MA_DEADLOCK:
|
||||||
|
return "Deadlock detected";
|
||||||
|
case MA_TOO_MANY_LINKS:
|
||||||
|
return "Too many symbolic links";
|
||||||
|
case MA_NOT_IMPLEMENTED:
|
||||||
|
return "Not implemented";
|
||||||
|
case MA_NO_MESSAGE:
|
||||||
|
return "No message available";
|
||||||
|
case MA_BAD_MESSAGE:
|
||||||
|
return "Bad message format";
|
||||||
|
case MA_NO_DATA_AVAILABLE:
|
||||||
|
return "No data available";
|
||||||
|
case MA_INVALID_DATA:
|
||||||
|
return "Invalid data";
|
||||||
|
case MA_TIMEOUT:
|
||||||
|
return "Operation timed out";
|
||||||
|
case MA_NO_NETWORK:
|
||||||
|
return "Network unavailable";
|
||||||
|
case MA_NOT_UNIQUE:
|
||||||
|
return "Not unique";
|
||||||
|
case MA_NOT_SOCKET:
|
||||||
|
return "Not a socket";
|
||||||
|
case MA_NO_ADDRESS:
|
||||||
|
return "No address available";
|
||||||
|
case MA_BAD_PROTOCOL:
|
||||||
|
return "Bad protocol";
|
||||||
|
case MA_PROTOCOL_UNAVAILABLE:
|
||||||
|
return "Protocol unavailable";
|
||||||
|
case MA_PROTOCOL_NOT_SUPPORTED:
|
||||||
|
return "Protocol not supported";
|
||||||
|
case MA_PROTOCOL_FAMILY_NOT_SUPPORTED:
|
||||||
|
return "Protocol family not supported";
|
||||||
|
case MA_ADDRESS_FAMILY_NOT_SUPPORTED:
|
||||||
|
return "Address family not supported";
|
||||||
|
case MA_SOCKET_NOT_SUPPORTED:
|
||||||
|
return "Socket not supported";
|
||||||
|
case MA_CONNECTION_RESET:
|
||||||
|
return "Connection reset";
|
||||||
|
case MA_ALREADY_CONNECTED:
|
||||||
|
return "Already connected";
|
||||||
|
case MA_NOT_CONNECTED:
|
||||||
|
return "Not connected";
|
||||||
|
case MA_CONNECTION_REFUSED:
|
||||||
|
return "Connection refused";
|
||||||
|
case MA_NO_HOST:
|
||||||
|
return "Host not found";
|
||||||
|
case MA_IN_PROGRESS:
|
||||||
|
return "Operation in progress";
|
||||||
|
case MA_CANCELLED:
|
||||||
|
return "Operation cancelled";
|
||||||
|
case MA_MEMORY_ALREADY_MAPPED:
|
||||||
|
return "Memory already mapped";
|
||||||
|
|
||||||
case MA_CRC_MISMATCH: return "CRC mismatch";
|
case MA_CRC_MISMATCH:
|
||||||
|
return "CRC mismatch";
|
||||||
|
|
||||||
case MA_FORMAT_NOT_SUPPORTED: return "Audio format not supported";
|
case MA_FORMAT_NOT_SUPPORTED:
|
||||||
case MA_DEVICE_TYPE_NOT_SUPPORTED: return "Device type not supported";
|
return "Audio format not supported";
|
||||||
case MA_SHARE_MODE_NOT_SUPPORTED: return "Share mode not supported";
|
case MA_DEVICE_TYPE_NOT_SUPPORTED:
|
||||||
case MA_NO_BACKEND: return "No backend available";
|
return "Device type not supported";
|
||||||
case MA_NO_DEVICE: return "No device available";
|
case MA_SHARE_MODE_NOT_SUPPORTED:
|
||||||
case MA_API_NOT_FOUND: return "API not found";
|
return "Share mode not supported";
|
||||||
case MA_INVALID_DEVICE_CONFIG: return "Invalid device configuration";
|
case MA_NO_BACKEND:
|
||||||
case MA_LOOP: return "Loop detected";
|
return "No backend available";
|
||||||
case MA_BACKEND_NOT_ENABLED: return "Backend not enabled";
|
case MA_NO_DEVICE:
|
||||||
|
return "No device available";
|
||||||
|
case MA_API_NOT_FOUND:
|
||||||
|
return "API not found";
|
||||||
|
case MA_INVALID_DEVICE_CONFIG:
|
||||||
|
return "Invalid device configuration";
|
||||||
|
case MA_LOOP:
|
||||||
|
return "Loop detected";
|
||||||
|
case MA_BACKEND_NOT_ENABLED:
|
||||||
|
return "Backend not enabled";
|
||||||
|
|
||||||
case MA_DEVICE_NOT_INITIALIZED: return "Device not initialized";
|
case MA_DEVICE_NOT_INITIALIZED:
|
||||||
case MA_DEVICE_ALREADY_INITIALIZED: return "Device already initialized";
|
return "Device not initialized";
|
||||||
case MA_DEVICE_NOT_STARTED: return "Device not started";
|
case MA_DEVICE_ALREADY_INITIALIZED:
|
||||||
case MA_DEVICE_NOT_STOPPED: return "Device not stopped";
|
return "Device already initialized";
|
||||||
|
case MA_DEVICE_NOT_STARTED:
|
||||||
|
return "Device not started";
|
||||||
|
case MA_DEVICE_NOT_STOPPED:
|
||||||
|
return "Device not stopped";
|
||||||
|
case MA_FAILED_TO_INIT_BACKEND:
|
||||||
|
return "Failed to initialize backend";
|
||||||
|
case MA_FAILED_TO_OPEN_BACKEND_DEVICE:
|
||||||
|
return "Failed to open backend device";
|
||||||
|
case MA_FAILED_TO_START_BACKEND_DEVICE:
|
||||||
|
return "Failed to start backend device";
|
||||||
|
case MA_FAILED_TO_STOP_BACKEND_DEVICE:
|
||||||
|
return "Failed to stop backend device";
|
||||||
|
|
||||||
case MA_FAILED_TO_INIT_BACKEND: return "Failed to initialize backend";
|
default:
|
||||||
case MA_FAILED_TO_OPEN_BACKEND_DEVICE: return "Failed to open backend device";
|
return "Unknown error code";
|
||||||
case MA_FAILED_TO_START_BACKEND_DEVICE: return "Failed to start backend device";
|
|
||||||
case MA_FAILED_TO_STOP_BACKEND_DEVICE: return "Failed to stop backend device";
|
|
||||||
|
|
||||||
default: return "Unknown error code";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void AssetManager::Init()
|
void AssetManager::Init()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@ -233,9 +299,6 @@ void AssetManager::LoadAudioInternal(const std::string& path, uint64_t uaid)
|
|||||||
Logger::LogVerbose("[AssetManager] Loaded audio: %s", path.c_str());
|
Logger::LogVerbose("[AssetManager] Loaded audio: %s", path.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const AssetInfo *AssetManager::GetAssetByID(uint64_t uaid)
|
const AssetInfo *AssetManager::GetAssetByID(uint64_t uaid)
|
||||||
{
|
{
|
||||||
auto it = s_Assets.find(uaid);
|
auto it = s_Assets.find(uaid);
|
||||||
@ -332,9 +395,13 @@ void AssetManager::Load(const YAML::Node& node)
|
|||||||
|
|
||||||
if (uaid >= s_NextUAID)
|
if (uaid >= s_NextUAID)
|
||||||
s_NextUAID = uaid + 1;
|
s_NextUAID = uaid + 1;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (type == AssetType::Image)
|
||||||
|
LoadImageInternal(path, uaid);
|
||||||
|
else if (type == AssetType::Audio)
|
||||||
|
LoadAudioInternal(path, uaid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ImageAssetInfo::Save(YAML::Emitter &out) const
|
void ImageAssetInfo::Save(YAML::Emitter &out) const
|
||||||
{
|
{
|
||||||
@ -356,4 +423,3 @@ void ImageAssetInfo::Load(const YAML::Node& node)
|
|||||||
|
|
||||||
void AudioAssetInfo::Save(YAML::Emitter &out) const {}
|
void AudioAssetInfo::Save(YAML::Emitter &out) const {}
|
||||||
void AudioAssetInfo::Load(const YAML::Node &node) {}
|
void AudioAssetInfo::Load(const YAML::Node &node) {}
|
||||||
|
|
||||||
|
@ -9,14 +9,18 @@
|
|||||||
#include "../../components/PhysicsComponent.h"
|
#include "../../components/PhysicsComponent.h"
|
||||||
#include "../../components/ParticleComponent.h"
|
#include "../../components/ParticleComponent.h"
|
||||||
#include "../../components/AnimationComponent.h"
|
#include "../../components/AnimationComponent.h"
|
||||||
|
#include "../../components/AudioPlayerComponent.h"
|
||||||
|
|
||||||
#include "imgui.h"
|
#include "imgui.h"
|
||||||
#include "imgui_internal.h"
|
#include "imgui_internal.h"
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void DrawInspectorUI(std::shared_ptr<Object> selected)
|
void DrawInspectorUI(std::shared_ptr<Object> selected)
|
||||||
{
|
{
|
||||||
|
|
||||||
PROFILE_ENGINE_SCOPE("Engine::DrawInspectorUI");
|
PROFILE_ENGINE_SCOPE("Engine::DrawInspectorUI");
|
||||||
ImGui::Begin("Inspector", nullptr, ImGuiWindowFlags_NoScrollbar);
|
ImGui::Begin("Inspector", nullptr, ImGuiWindowFlags_NoScrollbar);
|
||||||
|
|
||||||
@ -79,7 +83,8 @@ void DrawInspectorUI(std::shared_ptr<Object> selected)
|
|||||||
"Script",
|
"Script",
|
||||||
"Tilemap",
|
"Tilemap",
|
||||||
"Particle",
|
"Particle",
|
||||||
"Animation"};
|
"Animation",
|
||||||
|
"Audio Player"};
|
||||||
|
|
||||||
static int selectedIndex = -1;
|
static int selectedIndex = -1;
|
||||||
|
|
||||||
@ -115,6 +120,9 @@ void DrawInspectorUI(std::shared_ptr<Object> selected)
|
|||||||
selected->AddComponent<ParticleComponent>();
|
selected->AddComponent<ParticleComponent>();
|
||||||
else if (type == "Animation" && !selected->GetComponent<AnimationComponent>())
|
else if (type == "Animation" && !selected->GetComponent<AnimationComponent>())
|
||||||
selected->AddComponent<AnimationComponent>();
|
selected->AddComponent<AnimationComponent>();
|
||||||
|
else if (type == "Audio Player" && !selected->GetComponent<AudioPlayerComponent>())
|
||||||
|
selected->AddComponent<AudioPlayerComponent>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto sprite = selected->GetComponent<SpriteComponent>())
|
if (auto sprite = selected->GetComponent<SpriteComponent>())
|
||||||
@ -696,5 +704,50 @@ void DrawInspectorUI(std::shared_ptr<Object> selected)
|
|||||||
ImGui::Spacing();
|
ImGui::Spacing();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (auto audio = selected->GetComponent<AudioPlayerComponent>())
|
||||||
|
{
|
||||||
|
ImGui::SeparatorText("Audio Player");
|
||||||
|
|
||||||
|
uint64_t currentUaid = audio->GetUAID();
|
||||||
|
const AssetInfo *asset = AssetManager::GetAssetByID(currentUaid);
|
||||||
|
|
||||||
|
std::string filename = asset ? asset->filename : "(None)";
|
||||||
|
ImGui::Text("%s", filename.c_str());
|
||||||
|
|
||||||
|
// Drag & Drop from Asset Browser
|
||||||
|
if (ImGui::BeginDragDropTarget())
|
||||||
|
{
|
||||||
|
if (const ImGuiPayload *payload = ImGui::AcceptDragDropPayload("ASSET_AUDIO"))
|
||||||
|
{
|
||||||
|
if (payload->DataSize == sizeof(uint64_t))
|
||||||
|
{
|
||||||
|
uint64_t newUaid = *(const uint64_t *)payload->Data;
|
||||||
|
audio->SetAudio(newUaid);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui::EndDragDropTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Play/Pause/Stop buttons
|
||||||
|
if (ImGui::Button("Play"))
|
||||||
|
audio->Play();
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Pause"))
|
||||||
|
audio->Pause();
|
||||||
|
ImGui::SameLine();
|
||||||
|
if (ImGui::Button("Stop"))
|
||||||
|
audio->Stop();
|
||||||
|
|
||||||
|
// Looping
|
||||||
|
static bool loop = false;
|
||||||
|
loop = ImGui::Checkbox("Loop", &loop);
|
||||||
|
audio->SetLooping(loop);
|
||||||
|
|
||||||
|
// Volume
|
||||||
|
static float volume = 1.0f;
|
||||||
|
if (ImGui::SliderFloat("Volume", &volume, 0.0f, 1.0f))
|
||||||
|
audio->SetVolume(volume);
|
||||||
|
}
|
||||||
|
|
||||||
ImGui::End();
|
ImGui::End();
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user