/
BirdLeon
/
ROBLOX2016
Обзор
Документация
Войти
/
BirdLeon
/
ROBLOX2016
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
App/include/util/SoundService.h
290 строк
8 KB
PatoFlamejanteTV
full source code
19 дек 2024, 19:11
19 дек 2024, 19:11
05db15d
Код
Авторство
О чём код?
/* Copyright 2003-2014 ROBLOX Corporation, All Rights Reserved */ #pragma once #include "V8Tree/Service.h" #include "V8datamodel/DataModel.h" #include "V8DataModel/Stats.h" #include "Util/SoundWorld.h" #include "Util/SoundChannel.h" #include "Reflection/Event.h" #include "Util/IHasLocation.h" #include "fmod.h" #include "fmod.hpp" #include "fmod_errors.h" #if FMOD_VERSION != 0x00010702 # error Wrong version of fmod. #endif namespace RBX { typedef enum { FADE_STATUS_NONE = 0, FADE_STATUS_IN, FADE_STATUS_OUT } FadeStatus; namespace Soundscape { class SoundJob; class SoundChannel; class Sound; class SoundId; enum ReverbType { NoReverb = 0, GenericReverb, PaddedCell, Room, Bathroom, LivingRoom, StoneRoom, Auditorium, ConcertHall, Cave, Arena, Hangar, CarpettedHallway, Hallway, StoneCorridor, Alley, Forest, City, Mountains, Quarry, Plain, ParkingLot, SewerPipe, UnderWater }; enum ListenerType { CameraListener = 0, CFrame, ObjectPosition, ObjectCFrame }; struct listenerValues { CoordinateFrame listenCFrame; shared_ptr<IHasLocation> listenObject; }; extern const char* const sSoundService; class SoundService : public DescribedCreatable<SoundService, Instance, sSoundService, Reflection::ClassDescriptor::PERSISTENT_HIDDEN> , public Service { private: typedef DescribedCreatable<SoundService, Instance, sSoundService, Reflection::ClassDescriptor::PERSISTENT_HIDDEN> Super; typedef boost::unordered_set<SoundChannel*> SoundChannels; friend class SoundChannel; shared_ptr<FMOD::System> system; typedef boost::unordered_map<SoundType, shared_ptr<SoundChannel> > StockSounds; StockSounds stockSounds; float dopplerscale; float distancefactor; float rolloffscale; ListenerType currentListenerType; listenerValues currentListenerValues; shared_ptr<Instance> statsItem; ReverbType ambientReverb; SoundChannels soundChannels; FMOD::ChannelGroup *channelMaster; shared_ptr<SoundJob> soundJob; rbx::signals::scoped_connection gameSettingsChangedConnection; Time nextGarbageCollectTime; typedef boost::unordered_map<SoundId, shared_ptr<Sound> > LoadedSounds; LoadedSounds loadedSounds; LoadedSounds loaded3DSounds; float masterChannelFadeTimeMsec; FadeStatus masterChannelFadeStatus; bool initialized; bool muted; void openFmod(); void closeFmod(); void garbageCollectSounds(); static void gcSounds(LoadedSounds& sounds); static void getSoundStats(const LoadedSounds& sounds, unsigned int& numSounds, unsigned int& numUnusedSounds); void updateSoundChannels(const Time::Interval& timeSinceLastStep); void updateMasterChannelGroup(const Time::Interval& timeSinceLastStep); void update3DSettings(); void on3DSettingChanged(const Reflection::PropertyDescriptor&) { update3DSettings(); } void updateAmbientReverb(); protected: /////////////////////////////////////////////////////////////////////////////////////////////// // Instance Overrides ////////////////////////////////////////////////////////////////////////////// /*override*/ void onServiceProvider(ServiceProvider* oldProvider, ServiceProvider* newProvider); public: static bool soundDisabled; // Used to suppress all fmod calls by builds that don't play sound (like web service) shared_ptr<Sound> loadSound(SoundId id, bool is3D); bool enabled() const { return initialized; } SoundService(); ~SoundService(); void playSound(SoundType sound); FMOD::DSP* createDSP(FMOD_DSP_DESCRIPTION &dspdesc); int getSampleRate(); unsigned int getfmod_version() const; void getSoundStats(unsigned int& numSounds, unsigned int& numUnusedSounds) const; void getChannelsPlaying(int& value) const; void muteAllChannels(bool mute); bool isMuted(); void setListener(ListenerType listenerType, shared_ptr<const RBX::Reflection::Tuple> value); shared_ptr<const RBX::Reflection::Tuple> getListener(); CoordinateFrame getListenCFrame(Camera* camera); void setMasterVolume(float value); float getMasterVolume(); void setMasterVolumeFadeOut(float timeToFadeMsec); void setMasterVolumeFadeIn(float timeToFadeMsec); void gameSettingsChanged(const Reflection::PropertyDescriptor* propertyDescriptor); FMOD::ChannelGroup* getMasterChannel() { return channelMaster; } struct CpuStats { float total; float dsp; float stream; float geometry; float update; }; void getCpuStats(CpuStats& stats) const; ReverbType getAmbientReverb() const { return ambientReverb; } void setAmbientReverb(const ReverbType& value); static Reflection::BoundProp<float> prop_dopplerscale; static Reflection::BoundProp<float> prop_distancefactor; static Reflection::BoundProp<float> prop_rolloffscale; static Reflection::EnumPropDescriptor<SoundService, ReverbType> prop_AmbientReverb; void registerSoundChannel(SoundChannel *soundChannel); void unregisterSoundChannel(SoundChannel *soundChannel); void step(const Time::Interval& timeSinceLastStep); static void checkResultNoThrow(FMOD_RESULT result, const char* fmodOperation, const void *rbxFmodParent, const void *fmodObject); static void checkResult(FMOD_RESULT result, const char* fmodOperation, const void *rbxFmodParent, const void *fmodObject); static bool convert(const G3D::Vector3& src, FMOD_VECTOR& dst); }; // Responsible for updating all sound logic class SoundJob : public DataModelJob { private: SoundService* const soundService; const double fps; public: SoundJob(SoundService* soundService) :DataModelJob("Sound", DataModelJob::Write, false, shared_from_dynamic_cast<DataModel>(DataModel::get(soundService)), Time::Interval(0.003)) ,fps(30) ,soundService(soundService) { cyclicExecutive = true; } Time::Interval sleepTime(const Stats& stats) { return computeStandardSleepTime(stats, fps); } virtual Job::Error error(const Stats& stats) { return computeStandardErrorCyclicExecutiveSleeping(stats, fps); } TaskScheduler::StepResult stepDataModelJob(const Stats& stats) { soundService->step(stats.timespanSinceLastStep); return TaskScheduler::Stepped; } }; class SoundServiceStatsItem : public Stats::Item { const SoundService* service; size_t currentalloced; size_t maxalloced; unsigned int numSounds; unsigned int numUnusedSounds; int channelsPlaying; SoundService::CpuStats cpuStats; public: SoundServiceStatsItem(const SoundService* service) :service(service),currentalloced(0),maxalloced(0) { setName("Sound"); } static shared_ptr<SoundServiceStatsItem> create(const SoundService* service) { shared_ptr<SoundServiceStatsItem> result = Creatable<Instance>::create<SoundServiceStatsItem>(service); Stats::Item* cpu = result->createBoundPercentChildItem("CPU", result->cpuStats.total); cpu->createBoundPercentChildItem("Dsp", result->cpuStats.dsp); cpu->createBoundPercentChildItem("Stream", result->cpuStats.stream); cpu->createBoundPercentChildItem("Geometry", result->cpuStats.geometry); cpu->createBoundPercentChildItem("Update", result->cpuStats.update); result->createBoundChildItem("ChannelsPlaying", result->channelsPlaying); result->createBoundMemChildItem("Current", result->currentalloced); result->createBoundMemChildItem("Max", result->maxalloced); result->createBoundChildItem("# Sounds", result->numSounds); result->createBoundChildItem("# Unused", result->numUnusedSounds); return result; } /*override*/ void update() { if (service->enabled()) { this->formatValue(service->getfmod_version(), "fmod %08x", service->getfmod_version()); int a, b; if (FMOD::Memory_GetStats(&a, &b)==FMOD_OK) { currentalloced = (size_t) a; maxalloced = (size_t) b; } service->getSoundStats(numSounds, numUnusedSounds); service->getChannelsPlaying(channelsPlaying); service->getCpuStats(cpuStats); } else { this->setValue(0, "-disabled-"); } } }; } // namespace Soundscape } // namespace RBX