// Copyright (c) 2012-2017 VideoStitch SAS // Copyright (c) 2018 stitchEm #pragma once #include "audio/resampler.hpp" #include "libvideostitch/ambisonic.hpp" #include "libvideostitch/audio.hpp" #include "libvideostitch/audioBlock.hpp" #include "libvideostitch/audioWav.hpp" #include "libvideostitch/matrix.hpp" #include "libvideostitch/panoDef.hpp" #include "libvideostitch/audioPipeDef.hpp" #include "libvideostitch/output.hpp" #include "libvideostitch/quaternion.hpp" #include "libvideostitch/status.hpp" #include "libvideostitch/stitchOutput.hpp" #include namespace VideoStitch { namespace Audio { typedef std::map audioBlockReaderMap_t; typedef std::map audioBlockGroupMap_t; static const std::string kAudioPipeTag{"audiopipeline"}; class AudioPipeline { public: AudioPipeline(const BlockSize blockSize, const SamplingRate samplingRate, const Core::AudioPipeDefinition& audioPipeDef, const Core::PanoDefinition& pano); ~AudioPipeline(); bool addOutput(std::shared_ptr); Status applyProcessorParam(const Core::AudioPipeDefinition& def); void applyRotation(double yaw, double pitch, double roll); PotentialValue getAudioProcessor(const std::string& inputName, const std::string& procName) const; bool hasVuMeter(const std::string& inputName) const; PotentialValue> getPeakValues(const std::string& inputName) const; PotentialValue> getRMSValues(const std::string& inputName) const; Vector3 getRotation() const; bool hasAudio() const; Status process(audioBlockGroupMap_t& samples); bool removeOutput(const std::string& id); Status resetPano(const Core::PanoDefinition& newPano); void resetRotation(); Status setDecodingCoefficients(const AmbisonicDecoderDef& def); Status setDelay(double delay); void setInput(const std::string& inputName); private: friend class AudioPipeFactory; class AudioOutputResampler { public: AudioOutputResampler(std::shared_ptr o, SamplingRate internalSamplingRate, size_t internalBlockSize, const ambCoefTable_t& decodeCoef) : output(o), ambDec(o->getChannelLayout(), decodeCoef), ambEnc(AmbisonicOrder::FIRST_ORDER, AmbisonicNorm::SN3D) { rsp = AudioResampler::create(internalSamplingRate, SamplingDepth::DBL_P, o->getSamplingRate(), o->getSamplingDepth(), o->getChannelLayout(), internalBlockSize); } ~AudioOutputResampler() { delete rsp; } void pushAudio(AudioBlock& b) { Samples s; AudioBlock c; if (b.getLayout() == AMBISONICS_WXYZ && output->getChannelLayout() != AMBISONICS_WXYZ) { ambDec.step(c, b); } if (b.getLayout() != AMBISONICS_WXYZ && output->getChannelLayout() == AMBISONICS_WXYZ) { ambEnc.step(c, b); } if (c.empty()) { rsp->resample(b, s); } else { rsp->resample(c, s); } if (s.getNbOfSamples() > 0) { output->pushAudio(s); } } private: std::shared_ptr output; AudioResampler* rsp; AmbDecoder ambDec; AmbEncoder ambEnc; }; Status addProcessor(const Core::AudioProcessorDef& procDef); Status createAudioProcessors(const Core::AudioPipeDefinition& def); AudioBlock& getBlockFromInputName(const std::string& inputName); AudioBlock& getBlockFromMixName(const std::string& mixName); BlockSize getBlockSize() const; std::string getInputNameFromId(audioreaderid_t i) const; PotentialValue getInputIdFromName(const std::string& inputName) const; SamplingRate getSamplingRate() const; bool isInputEmpty(const std::string& inputName) const; bool isMixEmpty(const std::string& mixName) const; Status makeAudioInputs(audioBlockGroupMap_t& audioPerGroup); Status makeAudioMixes(); void pushAudio(); void recordDebugFile(std::string name, AudioBlock& input); void setDebugFolder(const std::string& s); typedef std::map>> inputPath_t; const BlockSize blockSize; const SamplingRate samplingRate; std::unique_ptr audioPipeDef; std::unique_ptr pano; std::map recorder; std::string debugFolder = ""; std::map inputs; /// audio data defined in the audio_inputs of the audio_pipe definition std::map mixes; /// audio data defined in the audio_mixes of the audio_pipe definition std::string selectedInput; mutable std::mutex inputPathsLock; inputPath_t inputPaths; // input paths are the audio processing chain mutable std::mutex paramsLock; std::map outputs; mtime_t lastTimestamp; mtime_t lastTimestampMaster; std::string inputMaster; Vector3 stabOrientation; // yaw/pitch/roll ambCoefTable_t ambDecodingCoef; }; } // namespace Audio } // namespace VideoStitch