diff --git a/rootex/framework/components/audio/audio_bus.cpp b/rootex/framework/components/audio/audio_bus.cpp new file mode 100644 index 000000000..32bb84cdb --- /dev/null +++ b/rootex/framework/components/audio/audio_bus.cpp @@ -0,0 +1,488 @@ +#include "audio_bus.h" +#include "audio_listener_component.h" +#include "audio_component.h" +#include "core/audio/audio_source.h" +#include "music_component.h" + +Vector AudioBusCollection::all_buses = { "Speakers" }; +Vector AudioBusCollection::all_buses_parent = { "Master" }; +Vector AudioBusCollection::all_buses_volume = { 100.0 }; + +AudioBusCollection::AudioBusCollection(Entity& owner, const JSON::json& data) + : Component(owner) +{ + //all_buses_parent.push_back("Speakers"); + //all_buses.push_back("Master"); + //all_buses_volume.push_back(100.0); + count = 1; +} + +void AudioBusCollection::to_json(JSON::json& j, const AudioBusCollection& a) +{ + //write the code + j["audioBusName"] = JSON::json::array(); + for (auto bus : a.all_buses) + { + j["audioBusName"].push_back(bus); + } + j["parentAudioBusName"] = JSON::json::array(); + for (auto bus : a.all_buses_parent) + { + j["parentAudioBusName"].push_back(bus); + } + j["audioBusVolume"] = JSON::json::array(); + for (auto vol : a.all_buses_volume) + { + j["audioBusVolume"].push_back(vol); + } +} + +void AudioBusCollection::from_json(const JSON::json& j, AudioBusCollection& a) +{ + //for (auto& index : j.value("pixelShaderTexturesMapping", Vector())) + //{ + // s.pixelShaderTexturesMapping.push_back(index); + //} + for (auto& bus : j.value("audioBusName", Vector())) + { + a.all_buses.push_back(bus); + } + for (auto& parent : j.value("parentAudioBusName", Vector())) + { + a.all_buses_parent.push_back(parent); + } + for (auto& volume : j.value("audioBusVolume", Vector())) + { + a.all_buses_volume.push_back(volume); + } +} + +void AudioBusCollection::volumeChange(String name, float volume) +{ + int j = getIndexByName(name); + float val = all_buses_volume[j]; + all_buses_volume[j] = volume; + float ratio = volume/val; + float temp; + String parent = all_buses_parent[j]; + int y = all_buses_parent.size(); + ALfloat finvol; + auto itr = MusicComponent::music_comp_audio_bus.begin(); + auto itr2 = MusicComponent::music_comp_volume.begin(); + while (itr != MusicComponent::music_comp_audio_bus.end()) + { + if (itr->second == name) + { + finvol = itr2->second; + itr2->second = finvol * ratio; + AL_CHECK(alSourcef(itr->first, AL_GAIN, finvol * ratio)); + } + itr++; + itr2++; + } + for ( int i = 0; i < all_buses_parent.size(); i++) + { + if( all_buses_parent[i] == name ) + { + temp = ratio*(all_buses_volume[i]); + volumeChange(all_buses[i],temp); + } + } +} + +void AudioBusCollection::removeAudioBus(String name) +{ + int j = getIndexByName(name); + String parent = all_buses_parent[j]; //can't remove without setting the parent + for ( int i = 0; i < all_buses_parent.size(); i++) + { + if(all_buses_parent[i]==name) + { + all_buses_parent[i] = parent; + } + } + int t = j; + auto it = all_buses.begin(); + while(t--) + it++; + all_buses.erase(it); + it = all_buses_parent.begin(); + t = j; + while (t--) + it++; + all_buses_parent.erase(it); + auto it2 = all_buses_volume.begin(); + t = j; + while (t--) + it2++; + all_buses_volume.erase(it2); + auto itr = MusicComponent::music_comp_audio_bus.begin(); + while (itr != MusicComponent::music_comp_audio_bus.end()) + { + if (itr->second == name) + { + itr->second = parent; + } + itr++; + } +} + +void AudioBusCollection::setAudioBusName(int ind, String name) +{ + if(ind=all_buses.size()) bl2=false; + if (bl2) + { + name = all_buses[i]; + volume = all_buses_volume[i]; + par = all_buses_parent[i]; + par_id = getIndexByName(par); + } + setAudioBusName(i, name); + setAudioParentBusName(i, par); + if (!bl2) + all_buses_volume.push_back(volume); + if (ImGui::InputTextWithHint(s1.c_str(), "Name of audio bus",&name, ImGuiInputTextFlags_EnterReturnsTrue)) + { + setAudioBusName(i, name); + } + //only for debugging + if (ImGui::ListBoxHeader("Set Parent of Audio Bus")) + { + for (int j = 0; j < all_buses.size(); j++) + { + if (i == j) + continue; + if (ImGui::RadioButton(all_buses[j].c_str(), bl)) + { + { + setAudioParentBusName(i, all_buses[j]); + } + } + } + ImGui::ListBoxFooter(); + } + /*if (ImGui::InputTextWithHint(s2.c_str(), "Set Parent of Audio Bus", &par, ImGuiInputTextFlags_EnterReturnsTrue)) + //{ + //bl3 = true; + //for (int j = 0; j < count; j++) + { + if (i == j) + continue; + if (ImGui::RadioButton(all_buses[j].c_str(), bl)) + { + { + setAudioParentBusName(i, all_buses[j]); + } + } + } + }*/ + //while (bl3) + //{ + //bl3 = !bl; + //} + if (ImGui::DragFloat("Volume", &volume, 0.01f, 0.001f, FLT_MAX)) + { + if (bl2) + volumeChange(name, volume); + else + setAudioBusVolume(i, volume); + //all_buses_volume.push_back(volume); + } + if (ImGui::Button("Remove Audio Bus")) + { + removeAudioBus(name); + count--; + } + ImGui::PopID(); + } + + if (ImGui::Button("Add Audio Bus")) + { + count++; + } +} + +float AudioSourceChild::getDuration() const +{ + // + return 1.0; +} + +/* +#include "audio_bus.h" +#include "audio_listener_component.h" + +static int count = 0; + +void AudioBusCollection::to_json(JSON::json& j, const AudioBusCollection& a) +{ + //write the code + j["audioBusName"] = JSON::json::array(); + for (auto& bus : a.all_buses) + { + j["audioBusName"].push_back(bus); + } + j["parentAudioBusName"] = JSON::json::array(); + for (auto& bus : a.all_buses_parent) + { + j["parentAudioBusName"].push_back(bus); + } + j["audioBusVolume"] = JSON::json::array(); + for (auto& vol : a.all_buses_volume) + { + j["audioBusVolume"].push_back(vol); + } +} + +void AudioBusCollection::from_json(JSON::json& j, const AudioBusCollection& a) +{ + //write the code + + for (auto& index : j.value("pixelShaderTexturesMapping", Vector())) + { + s.pixelShaderTexturesMapping.push_back(index); + } +} + +/* +void to_json(JSON::json& j, const CustomMaterialData& s) +{ + j["pixelShader"] = s.pixelShaderPath; + j["pixelShaderCount"] = s.pixelShaderCount; + j["vertexShader"] = s.vertexShaderPath; + j["vertexShaderTextures"] = JSON::json::array(); + for (auto& texture : s.vertexShaderTextures) + { + j["vertexShaderTextures"].push_back(texture->getPath().generic_string()); + } + j["pixelShaderTextures"] = JSON::json::array(); + j["pixelShaderTexturesMapping"] = JSON::json::array(); + for (auto& texture : s.pixelShaderTextures) + { + j["pixelShaderTextures"].push_back(texture->getPath().generic_string()); + } + for (auto& index : s.pixelShaderTexturesMapping) + { + j["pixelShaderTexturesMapping"].push_back(index); + } + for (auto& customConstantBuffers : s.customConstantBuffers) + { + j["customConstantBuffers"].push_back(customConstantBuffers); + } + for (auto& typeOfCustomConstantBuffers : s.typeOfCustomConstantBuffers) + { + j["typeOfCustomConstantBuffers"].push_back(typeOfCustomConstantBuffers); + } + j["vertexShaderPath"] = s.dummyVertexShaderPath; +} + +void from_json(const JSON::json& j, CustomMaterialData& s) +{ + s.vertexShaderPath = j.value("vertexShader", CustomMaterialResourceFile::s_DefaultCustomVSPath); + s.pixelShaderPath = j.value("pixelShader", CustomMaterialResourceFile::s_DefaultCustomPSPath); + s.pixelShaderCount = j.value("pixelShaderCount", 1); + s.dummyVertexShaderPath = j.value("vertexShaderPath", CustomMaterialResourceFile::s_DefaultCustomVSPath); + for (auto& texturePath : j.value("vertexShaderTextures", Vector())) + { + if (Ref texture = ResourceLoader::CreateImageResourceFile(texturePath)) + { + s.vertexShaderTextures.push_back(texture); + } + } + for (auto& texturePath : j.value("pixelShaderTextures", Vector({ "rootex/assets/rootex.png" }))) + { + if (Ref texture = ResourceLoader::CreateImageResourceFile(texturePath)) + { + s.pixelShaderTextures.push_back(texture); + } + } + for (auto& index : j.value("pixelShaderTexturesMapping", Vector())) + { + s.pixelShaderTexturesMapping.push_back(index); + } + for (auto& customConstantBuffers : j.value("customConstantBuffers", Vector())) + { + s.customConstantBuffers.push_back(customConstantBuffers); + } + for (auto& typeOfCustomConstantBuffers : j.value("typeOfCustomConstantBuffers", Vector())) + { + s.typeOfCustomConstantBuffers.push_back(typeOfCustomConstantBuffers); + } +} + +AudioBus* AudioBusCollection::getAudioBusByName(String name, AudioBus* master) +{ + AudioBus* ans = nullptr; + for (auto& child : master->children) + { + if (child->name == name) + return child; + else + ans = (getAudioBusByName(name, child) == nullptr) ? ans : getAudioBusByName(name, child); + } + return ans; +} + +int AudioBusCollection::getIndexByName(String name) +{ + + for ( int i = 0; i < all_buses.size(); i++) + { + if(all_buses[i]==bus.name) break; + } + return i; +} + +AudioBus* AudioBusCollection::addAudioBus(String name, bool isMaster, float volume, AudioBus* parentBus) +{ + AudioBus* newBus; + newBus->isMaster = isMaster; + newBus->volume = volume; + all_buses_volume.push_back(volume); + newBus->parent = parentBus; + newBus->name = name; + parentBus->children.push_back(newBus); + all_buses.push_back(name); + all_buses_parent.push_back(parentBus.name); + return newBus; +} + +void AudioBusCollection::volumeChange(AudioBus* bus, float val) +{ + if (val > 100) + { + // error + } + else + { + int i = getIndexByName(bus.name); + float t = val / (bus->volume); + bus->volume = val; + all_buses_volume[i] = val; + float temp; + for (auto& child : bus->children) + { + temp = t * (child->volume); + volumeChange(child, temp); + } + } +} + +void AudioBusCollection::setParentOfAudioBus(AudioBus* bus, AudioBus* parentBus) +{ + bus->parent = parentBus; + int i = getIndexByName(bus); + all_buses_parent[i] = parentBus.name; +} + +void AudioBusCollection::removeAudioBus(AudioBus* bus) +{ + for (auto& child : bus->children) + { + child->parent = bus->parent; + } + bus->parent = nullptr; +} + +void AudioBusCollection::draw() +{ + // master bus + AudioBus master; + master.name = "Master"; + master.isMaster = true; + master.volume = 50.0; + // master.parent = "Speakers"; + all_buses.push_back("Master"); + for (int i = 0; i < count; i++) + { + AudioBus *currentBus, *parentBus; + AudioBus* bus; + String name, *parentname; + float volume = 100; + bool bl = false; + if (ImGui::DragFloat("Volume", &volume, 0.01f, 0.001f, FLT_MAX)) + { + ; + } + if (ImGui::InputTextWithHint("Name", "Name of audio bus", &name, ImGuiInputTextFlags_EnterReturnsTrue)) + { + for (int j = 0; j <= count; j++) + { + if (i == j) + continue; + // if (ImGui::RadioButton()) + parentname = &all_buses[j]; + if (ImGui::RadioButton("", bl)) + { + { + parentBus = getAudioBusByName(all_buses[j], &master); + bus = addAudioBus(name, false, volume, parentBus); + } + } + } + } + currentBus = getAudioBusByName(name, &master); + volumeChange(currentBus, volume); + setParentOfAudioBus(currentBus, parentBus); + if (ImGui::Button("Remove Audio Bus")) + { + removeAudioBus(currentBus); + count--; + } + } + + if (ImGui::Button("Add Audio Bus")) + { + count++; + } +} + +*/ diff --git a/rootex/framework/components/audio/audio_bus.h b/rootex/framework/components/audio/audio_bus.h new file mode 100644 index 000000000..0a69a2eb5 --- /dev/null +++ b/rootex/framework/components/audio/audio_bus.h @@ -0,0 +1,57 @@ +#pragma once +#include +#include +#include "audio_listener_component.h" +#include "entity.h" +#include "imgui.h" +#include "systems/audio_system.h" +#include "core/audio/audio_source.h" +#include "component.h" + + +struct AudioBus +{ + std::string name; + bool isMaster; + float volume; + std::vector children; + AudioBus* parent; +}; + +class AudioSourceChild : public AudioSource +{ +public: + ALuint m_SourceID = AudioSource::m_SourceID; + virtual float getDuration() const override; + void setVolume(int volume) + { + AudioSource::setVolume(volume); + } +}; + +class AudioBusCollection : public Component +{ + COMPONENT(AudioBusCollection, Category::Audio); + int m_temp; + + public: + AudioBusCollection(Entity& owner, const JSON::json& data); + ~AudioBusCollection() = default; + static Vector all_buses; + static Vector all_buses_parent; + static Vector all_buses_volume; + int count = 0; + void to_json(JSON::json& j, const AudioBusCollection& a); + void from_json(const JSON::json& j, AudioBusCollection& a); + void setAudioBusName(int ind, String name); + void setAudioParentBusName(int ind, String name); + void setAudioBusVolume(int ind, float volume); + //AudioBus *getAudioBusByName(String name, AudioBus *master); + //AudioBus *addAudioBus(String name,bool isMaster,float volume,AudioBus *parentBus); + void volumeChange(String name, float val); + //void setParentOfAudioBus(AudioBus *bus, AudioBus *parentBus); + void removeAudioBus(String name); + int getIndexByName(String name); + void draw(); +}; +DECLARE_COMPONENT(AudioBusCollection); diff --git a/rootex/framework/components/audio/audio_component.cpp b/rootex/framework/components/audio/audio_component.cpp index e5457fe26..fc87cf2e3 100644 --- a/rootex/framework/components/audio/audio_component.cpp +++ b/rootex/framework/components/audio/audio_component.cpp @@ -1,6 +1,8 @@ #include "audio_component.h" +#include "al.h" #include "systems/render_system.h" +#include "systems/audio_system.h" #include "components/physics/box_collider_component.h" #include "components/physics/sphere_collider_component.h" #include "components/physics/capsule_collider_component.h" @@ -175,5 +177,8 @@ void AudioComponent::draw() ImGui::DragFloat("Reference Distance", &m_ReferenceDistance, 1.0f, 0.0f, 100.0f); ImGui::DragFloat("Rolloff Factor", &m_RolloffFactor, 1.0f, 0.0f, 100.0f); ImGui::DragFloat("Max Distance", &m_MaxDistance, 1.0f, 0.0f, 100.0f); - ImGui::DragFloat("Volume", &m_Volume, 0.01f, 0.0f, 100.0f); + if(ImGui::DragFloat("Volume", &m_Volume, 0.01f, 0.0f, 100.0f)) + { + AL_CHECK(alSourcef(1, AL_GAIN, m_Volume)); + } } diff --git a/rootex/framework/components/audio/audio_component.h b/rootex/framework/components/audio/audio_component.h index 1a470c5f9..ca33a9dec 100644 --- a/rootex/framework/components/audio/audio_component.h +++ b/rootex/framework/components/audio/audio_component.h @@ -53,6 +53,7 @@ class AudioComponent : public Component void setPlaying(bool enabled); void play(); void stop(); + // void getVolume(float ratio) { m_Volume=ratio*m_Volume; } void setLooping(bool enabled); bool isLooping(); diff --git a/rootex/framework/components/audio/audio_listener_component.cpp b/rootex/framework/components/audio/audio_listener_component.cpp index 77c8d7be8..c7398bd0c 100644 --- a/rootex/framework/components/audio/audio_listener_component.cpp +++ b/rootex/framework/components/audio/audio_listener_component.cpp @@ -1,5 +1,5 @@ #include "audio_listener_component.h" - +#include "audio_bus.h" #include "entity.h" #include "systems/audio_system.h" @@ -90,5 +90,10 @@ RigidBodyComponent* AudioListenerComponent::getCollider() void AudioListenerComponent::draw() { + //AudioBusCollection obj; + //JSON::json j; + //obj.from_json(j,obj); + //obj.draw(); + //obj.to_json(j,obj); ImGui::DragFloat("Volume", &m_Volume, 0.01f, 0.001f, FLT_MAX); } diff --git a/rootex/framework/components/audio/music_component.cpp b/rootex/framework/components/audio/music_component.cpp index 118cda0a9..273e19937 100644 --- a/rootex/framework/components/audio/music_component.cpp +++ b/rootex/framework/components/audio/music_component.cpp @@ -1,4 +1,9 @@ #include "music_component.h" +#include "audio_bus.h" +#include + +Map MusicComponent::music_comp_audio_bus = Map(); +Map MusicComponent::music_comp_volume = Map(); DEFINE_COMPONENT(MusicComponent); @@ -15,6 +20,7 @@ MusicComponent::MusicComponent(Entity& owner, const JSON::json& data) (ALfloat)data.value("maxDistance", 100.0f)) , m_AudioFile(ResourceLoader::CreateAudioResourceFile(data.value("audio", "rootex/assets/ball.wav"))) { + volume_comp = data.value("volume", 1.0f); } MusicComponent::~MusicComponent() @@ -33,6 +39,54 @@ bool MusicComponent::setupData() return AudioComponent::setupData(); } +void MusicComponent::to_json(JSON::json& j, const MusicComponent& a) +{ + // write the code + j["audioBusName"] = JSON::json::array(); + auto itr = music_comp_audio_bus.begin(); + while (itr != music_comp_audio_bus.end()) + { + j["audioBusName"].push_back(itr->second); + itr++; + } + j["ComponentPointer"] = JSON::json::array(); + itr = music_comp_audio_bus.begin(); + while (itr != music_comp_audio_bus.end()) + { + auto val = itr->first; + j["ComponentPointer"].emplace_back(itr->first); + itr++; + } + j["ComponentVolume"] = JSON::json::array(); + auto itr2 = music_comp_volume.begin(); + while (itr2 != music_comp_volume.end()) + { + j["ComponentPointer"].push_back(itr2->second); + itr2++; + } +} + +void MusicComponent::from_json(const JSON::json& j, MusicComponent& a) +{ + Vector temp; + Vector temp2; + for (auto& name : j.value("audioBusName", Vector())) + { + temp.push_back(name); + } + for (auto& vol : j.value("ComponentVolume", Vector())) + { + temp2.push_back(vol); + } + int i = 0; + for (auto& bus : j.value("ComponentPointer", Vector())) + { + MusicComponent::music_comp_audio_bus.insert({ bus, temp[i] }); + MusicComponent::music_comp_volume.insert({ bus, temp2[i] }); + i++; + } +} + JSON::json MusicComponent::getJSON() const { JSON::json& j = AudioComponent::getJSON(); @@ -49,8 +103,14 @@ void MusicComponent::setAudioFile(Ref audioFile) setupData(); } +// void MusicComponent::updateVolume(float ratio) +// { +// getVolume(ratio); +// } + void MusicComponent::draw() { + AudioComponent::getAudioSource()->setVolume(volume_comp); ImGui::BeginGroup(); ImGui::Text("%s", m_AudioFile->getPath().generic_string().c_str()); ImGui::SameLine(); @@ -75,5 +135,19 @@ void MusicComponent::draw() setAudioFile(ResourceLoader::CreateAudioResourceFile(path)); } } + if (ImGui::ListBoxHeader("Choose an audio bus")) + { + bool bl = false; + auto component_pointer = m_StreamingAudioSource.get()->getSourceID(); + for (int j = 0; j < AudioBusCollection::all_buses.size(); j++) + { + if (ImGui::RadioButton(AudioBusCollection::all_buses[j].c_str(), bl)) + { + music_comp_audio_bus.insert({component_pointer, AudioBusCollection::all_buses[j]}); + music_comp_volume.insert({ component_pointer, volume_comp }); + } + } + ImGui::ListBoxFooter(); + } AudioComponent::draw(); } diff --git a/rootex/framework/components/audio/music_component.h b/rootex/framework/components/audio/music_component.h index 74ead27cf..a69ef311f 100644 --- a/rootex/framework/components/audio/music_component.h +++ b/rootex/framework/components/audio/music_component.h @@ -11,6 +11,7 @@ class MusicComponent : public AudioComponent { COMPONENT(MusicComponent, Category::Audio); + ALfloat volume_comp; Ref m_StreamingAudioSource; Ref m_StreamingAudioBuffer; Ref m_AudioFile; @@ -18,9 +19,13 @@ class MusicComponent : public AudioComponent public: MusicComponent(Entity& owner, const JSON::json& data); ~MusicComponent(); - + static Map music_comp_audio_bus; + static Map music_comp_volume; AudioResourceFile* getAudioFile() const { return m_AudioFile.get(); } + void to_json(JSON::json& j, const MusicComponent& a); + void from_json(const JSON::json& j, MusicComponent& a); void setAudioFile(Ref audioFile); + // void updateVolume(float ratio); bool setupData() override; JSON::json getJSON() const override; diff --git a/rootex/framework/components/component_ids.h b/rootex/framework/components/component_ids.h index e8853e9f1..a47664e2a 100644 --- a/rootex/framework/components/component_ids.h +++ b/rootex/framework/components/component_ids.h @@ -1,4 +1,4 @@ -#pragma once + #pragma once enum class ComponentIDs : unsigned int { @@ -24,6 +24,7 @@ enum class ComponentIDs : unsigned int MusicComponent, ShortMusicComponent, AudioListenerComponent, + AudioBusCollection, TransformAnimationComponent, SkyComponent, FogComponent, diff --git a/rootex/framework/ecs_factory.cpp b/rootex/framework/ecs_factory.cpp index 252c279f8..7a77d9614 100644 --- a/rootex/framework/ecs_factory.cpp +++ b/rootex/framework/ecs_factory.cpp @@ -4,6 +4,7 @@ #include "scene.h" #include "components/audio/audio_listener_component.h" +#include "components/audio/audio_bus.h" #include "components/audio/music_component.h" #include "components/physics/box_collider_component.h" #include "components/physics/sphere_collider_component.h" @@ -106,6 +107,7 @@ void ECSFactory::FillRootEntity(Entity& root) root.getComponent()->setVisible(false); ECSFactory::AddDefaultCameraComponent(root); ECSFactory::AddDefaultAudioListenerComponent(root); + //ECSFactory::AddDefaultAudioBusCollection(root); ECSFactory::AddDefaultSkyComponent(root); } @@ -118,6 +120,7 @@ void ECSFactory::Initialize() ASSIGN_COMPONENT_SET(TransformAnimationComponent); ASSIGN_COMPONENT_SET(AudioListenerComponent); + ASSIGN_COMPONENT_SET(AudioBusCollection); ASSIGN_COMPONENT_SET(MusicComponent); ASSIGN_COMPONENT_SET(ShortMusicComponent);