Skip to content

Commit

Permalink
Feature: Add DeepFilterCommandBuilder to MediaProcessor (omeryusufyag…
Browse files Browse the repository at this point in the history
…ci#42)

Initial implementation of DeepFilterCommandBuilder

---------

Co-authored-by: George Olson <[email protected]>
Co-authored-by: omeryusufyagci <[email protected]>
  • Loading branch information
3 people authored Oct 22, 2024
1 parent c3d0caf commit 80827ea
Show file tree
Hide file tree
Showing 8 changed files with 144 additions and 14 deletions.
1 change: 0 additions & 1 deletion MediaProcessor/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ option(BUILD_TESTING "Test Build" OFF)
# Set include directories
include(CTest)
include_directories(${CMAKE_SOURCE_DIR}/include)
include_directories(${CMAKE_SOURCE_DIR}/third_party/nlohmann)

# Threads is required
set(THREADS_PREFER_PTHREAD_FLAG ON)
Expand Down
1 change: 1 addition & 0 deletions MediaProcessor/cmake/src.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ add_executable(MediaProcessor
${CMAKE_SOURCE_DIR}/src/CommandBuilder.cpp
${CMAKE_SOURCE_DIR}/src/HardwareUtils.cpp
${CMAKE_SOURCE_DIR}/src/FFmpegSettingsManager.cpp
${CMAKE_SOURCE_DIR}/src/DeepFilterCommandBuilder.cpp
)

target_link_libraries(MediaProcessor PRIVATE Threads::Threads)
Expand Down
1 change: 1 addition & 0 deletions MediaProcessor/src/AudioProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ bool AudioProcessor::invokeDeepFilter(fs::path chunkPath) {
const fs::path deepFilterPath = configManager.getDeepFilterPath();
const fs::path deepFilterTarballPath = configManager.getDeepFilterTarballPath();

// TODO: implement with DeepFilterCommandBuilder once base class is updated (#51)
// `--compensate-delay` ensures the audio remains in sync after filtering
CommandBuilder cmd;
cmd.addArgument(deepFilterPath.string());
Expand Down
4 changes: 2 additions & 2 deletions MediaProcessor/src/ConfigManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ unsigned int ConfigManager::getNumThreadsValue() {

unsigned int ConfigManager::determineNumThreads(unsigned int configNumThreads,
unsigned int hardwareNumThreads) {
return Utils::isWithinRange(configNumThreads, 1, hardwareNumThreads) ? configNumThreads
: hardwareNumThreads;
return Utils::isWithinRange(configNumThreads, 1u, hardwareNumThreads) ? configNumThreads
: hardwareNumThreads;
}
} // namespace MediaProcessor
58 changes: 58 additions & 0 deletions MediaProcessor/src/DeepFilterCommandBuilder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#include "DeepFilterCommandBuilder.h"

#include <sstream>
#include <stdexcept>

#include "Utils.h"

namespace MediaProcessor {

DeepFilterCommandBuilder& DeepFilterCommandBuilder::setInputFile(
const std::string& inputAudioPath) {
/**
* FIXME: Find a solution to ensure flexibility in calling `setInputFile()`.
* See the header for more details on the problem.
*/

m_inputAudioPath = inputAudioPath;
addArgument(inputAudioPath);

return *this;
}

DeepFilterCommandBuilder& DeepFilterCommandBuilder::setOutputFile(
const std::string& outputAudioPath) {
m_outputAudioPath = outputAudioPath;
addFlag("--output-dir", outputAudioPath);

return *this;
}

DeepFilterCommandBuilder& DeepFilterCommandBuilder::setNoiseReductionLevel(double level) {
if (!Utils::isWithinRange(level, 0.0, 1.0)) {
throw std::invalid_argument("Noise reduction level must be between 0.0 and 1.0");
}
m_noiseReductionLevel = level;
addFlag("--noise-reduction", std::to_string(level));

return *this;
}

DeepFilterCommandBuilder& DeepFilterCommandBuilder::enableDelayCompensation() {
addFlag("--compensate-delay");

return *this;
}

std::string DeepFilterCommandBuilder::build() const {
if (m_inputAudioPath.empty()) {
throw std::runtime_error("Input audio path must be specified.");
}
if (m_outputAudioPath.empty()) {
throw std::runtime_error("Output audio path must be specified.");
}

return CommandBuilder::build();
}

} // namespace MediaProcessor
72 changes: 72 additions & 0 deletions MediaProcessor/src/DeepFilterCommandBuilder.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#ifndef DEEPFILTERCOMMANDBUILDER_H
#define DEEPFILTERCOMMANDBUILDER_H

#include "CommandBuilder.h"

namespace MediaProcessor {

/**
* @brief A builder class for constructing DeepFilter commands.
*/
class DeepFilterCommandBuilder : public CommandBuilder {
public:
/**
* @brief Sets the input audio file for the DeepFilter command.
*
* @note
* To ensure the correct behavior, please call `setInputFile()` as the first
* method when configuring this builder. This guarantees that the input file
* is added in the proper order before other optional parameters.
*
* DeepFilter not providing an input file flag poses challenges to implement
* this without breaking the builder pattern or sacrificing const-correctness.
* We'll try to find a good solution for this ASAP.
*
* @return A reference to the updated object for method chaining.
*/
DeepFilterCommandBuilder& setInputFile(const std::string& inputAudioPath);

/**
* @brief Sets the output audio file for the DeepFilter command.
*
* @return A reference to the updated object for method chaining.
*/
DeepFilterCommandBuilder& setOutputFile(const std::string& outputAudioPath);

/**
* @brief Sets the noise reduction level for the DeepFilter command.
*
* @param level The noise reduction level: from 0.0 (no reduction) to 1.0 (max reduction).
* @return A reference to the updated DeepFilterCommandBuilder instance.
*
* @throws std::invalid_argument if the level is not within the range [0.0, 1.0].
*/
DeepFilterCommandBuilder& setNoiseReductionLevel(double level);

/**
* @brief Enabled filtering delay compensation for the DeepFilter command.
*
* @return A reference to the updated DeepFilterCommandBuilder instance.
*/
DeepFilterCommandBuilder& enableDelayCompensation();

/**
* @brief Builds the final DeepFilter command string.
*
* Constructs the command string using the provided parameters and options.
*
* @return The constructed command string.
*
* @throws std::runtime_error if required parameters (input or output file) are missing.
*/
std::string build() const override;

private:
std::string m_inputAudioPath;
std::string m_outputAudioPath;
double m_noiseReductionLevel = 0.5;
};

} // namespace MediaProcessor

#endif
4 changes: 0 additions & 4 deletions MediaProcessor/src/Utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,10 +69,6 @@ bool containsWhitespace(const std::string &str) {
return str.find(' ') != std::string::npos;
}

bool isWithinRange(unsigned int value, unsigned int lowerBound, unsigned int upperBound) {
return value >= lowerBound && value <= upperBound;
}

std::string trimTrailingSpace(const std::string &str) {
if (str.empty() || str.back() != ' ') {
return str;
Expand Down
17 changes: 10 additions & 7 deletions MediaProcessor/src/Utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,13 +37,6 @@ bool removeFileIfExists(const fs::path &filePath);
*/
bool containsWhitespace(const std::string &str);

/**
* @brief Checks if a value is within a specified range (inclusive).
*
* @return true if the value is within the range, false otherwise.
*/
bool isWithinRange(unsigned int value, unsigned int lowerBound, unsigned int upperBound);

/**
* @brief Prepares the output paths for audio and video processing.
*
Expand All @@ -65,6 +58,16 @@ std::string trimTrailingSpace(const std::string &str);
*/
double getMediaDuration(const fs::path &mediaPath);

/**
* @brief Checks if a value is within a specified range (inclusive).
*
* @return true if the value is within the range, false otherwise.
*/
template <typename T>
bool isWithinRange(T value, T lowerBound, T upperBound) {
return value >= lowerBound && value <= upperBound;
}

} // namespace MediaProcessor::Utils

#endif // UTILS_H

0 comments on commit 80827ea

Please sign in to comment.