/* obs-websocket Copyright (C) 2016-2021 Stephane Lepin Copyright (C) 2020-2021 Kyle Manning This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see */ #pragma once #include #include #include #include #include #include #include #include "Obs.h" #include "Json.h" namespace Utils { namespace Obs { namespace VolumeMeter { // Some code copied from https://github.com/obsproject/obs-studio/blob/master/libobs/obs-audio-controls.c // Keeps a running tally of the current audio levels, for a specific input class Meter { public: Meter(obs_source_t *input); ~Meter(); bool InputValid(); obs_weak_source_t *GetWeakInput() { return _input; } json GetMeterData(); std::atomic PeakMeterType; private: OBSWeakSourceAutoRelease _input; // All values in mul std::mutex _mutex; bool _muted; int _channels; float _magnitude[MAX_AUDIO_CHANNELS]; float _peak[MAX_AUDIO_CHANNELS]; float _previousSamples[MAX_AUDIO_CHANNELS][4]; std::atomic _lastUpdate; std::atomic _volume; void ResetAudioLevels(); void ProcessAudioChannels(const struct audio_data *data); void ProcessPeak(const struct audio_data *data); void ProcessMagnitude(const struct audio_data *data); static void InputAudioCaptureCallback(void *priv_data, obs_source_t *source, const struct audio_data *data, bool muted); static void InputVolumeCallback(void *priv_data, calldata_t *cd); }; // Maintains an array of active inputs class Handler { typedef std::function)> UpdateCallback; typedef std::unique_ptr MeterPtr; public: Handler(UpdateCallback cb, uint64_t updatePeriod = 50); ~Handler(); private: UpdateCallback _updateCallback; std::mutex _meterMutex; std::vector _meters; uint64_t _updatePeriod; std::mutex _mutex; std::condition_variable _cond; std::atomic _running; std::thread _updateThread; void UpdateThread(); static void InputActivateCallback(void *priv_data, calldata_t *cd); static void InputDeactivateCallback(void *priv_data, calldata_t *cd); }; } } }