Commit d0780166 authored by Matteo's avatar Matteo
Browse files

add formatting config and style guide

parent e075f46c
# EditorConfig is awesome: https://EditorConfig.org
# top-most EditorConfig file
root = true
[*]
indent_style = space
indent_size = 4
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = false
insert_final_newline = false
\ No newline at end of file
UNAME := $(shell uname)
FORMATTER = clang-format
DOCS_GEN = doxygen
FORMAT_OPT = -i -style="{BasedOnStyle: google,IndentWidth: 4,ColumnLimit: 120}"
TARGET = video_analyser
ifeq ($(UNAME), Linux)
OPEN = xdg-open
......@@ -10,7 +14,7 @@ ifeq ($(UNAME), Windows)
OPEN = start
endif
.PHONY: all clean test docs run
.PHONY: all clean test docs run build
build:
cmake -S . -B build
......@@ -25,8 +29,11 @@ clean:
rm -rf docs/html
rm -rf docs/latex
format:
$(FORMATTER) $(FORMAT_OPT) src/*.cpp src/*.h src/lib/*.cpp src/lib/*.h tests/*.cpp
docs:
doxygen docs/Doxyfile && $(OPEN) docs/html/index.html
$(DOCS_GEN) docs/Doxyfile && $(OPEN) docs/html/index.html
run:
./bin/audio_analyser
./bin/video_analyser
......@@ -44,7 +44,7 @@ Run the project from the root directory:
make run
```
## Documentation
## Generate the documentation
Along with the source code, the documentation of the *Video Analyser* is provided in the `docs` folder. The documentation is generated with [Doxygen](https://www.doxygen.nl/index.html) and can be accessed by opening the `index.html` file in the `docs/html` folder with a browser.
To generate the documentation, run the following command from the root folder:
......
# Documentation
[TOC]
> There is no worse software than undocumented software.
## Style guide
![Meme](../img/meme-documentation.jpg)
## Generate the documentation
Along with the source code, the documentation of the *Video Analyser* is provided in the `docs` folder. The documentation is generated with [Doxygen](https://www.doxygen.nl/index.html) and can be accessed by opening the `index.html` file in the `docs/html` folder with a browser.
To generate the documentation, run the following command from the root folder:
```
make docs
```
Note that Doxygen must be installed on your machine.
## Write the documentation
Doxygen is a tool for generating documentation from annotated C++ sources, as well as other popular programming languages like C, Objective-C, C#, PHP, Java, Python, IDL (Corba, Microsoft, and UNO/OpenOffice flavors), Fortran, VHDL, Tcl, and to some extent D.
To access Doxygen superpowers you need to add comments to your code. Doxygen supports two types of comments: single-line and multi-line comments. Single-line comments start with `///` or `//!` and multi-line comments start with `/**` and end with `*/`. The following example shows how to use both types of comments:
```
/// This is a single-line comment.
//! This is also a single-line comment.
/**
* This is a multi-line comment.
*/
```
A sample of Doxygen commented class looks like this:
```
/**
* @class SampleClass
* @brief This is a sample class.
*
* This class is used to show how to comment a class with Doxygen.
*/
class SampleClass {
private:
int field1; /**< This is a sample field. */
public:
/**
* @brief This is a sample constructor.
*
* This constructor is used to show how to comment a constructor with Doxygen.
*/
SampleClass();
/**
* @brief This is a sample destructor.
*
* This destructor is used to show how to comment a destructor with Doxygen.
*/
~SampleClass();
/**
* @brief This is a sample method.
*
* This method is used to show how to comment a method with Doxygen.
*
* @param[in] param1 This is a sample parameter.
* @param[in] param2 This is another sample parameter.
* @return This is a sample return value.
*/
int sampleMethod(int param1, int param2);
};
```
For more information about Doxygen, please refer to the [official documentation](https://www.doxygen.nl/manual/index.html).
# Style guide
The code is written following C++20 standard, to ensure the best readability and maintainability. The code is formatted using [clang-format](https://clang.llvm.org/docs/ClangFormat.html) with the [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html) as a reference.
To format the code, run the following command from the root folder:
```
make format
```
Note that clang-format must be installed on your machine.
In addition to the Google C++ Style Guide, the following rules are applied:
- when returning multiple values, use `std::tuple` or `std::pair`, instead of passing by reference;
- when dealing with nullable values, use `std::optional`;
- avoid to manipulate global variables, if you need to share data between different parts of the code, use dependency injection and pass the data as a parameter;
\ No newline at end of file
......@@ -65,7 +65,7 @@ docker build -t mpai-video-analyzer .
To run the container, run the following command:
```
docker run -it --rm -v /path/to/video/analyser:/app mpai-video-analyzer -v /path/to/your/data:/data /bin/bash
docker run -it --rm -v /path/to/video/analyser:/app -v /path/to/your/data:/data /bin/bash mpai-video-analyzer
```
where `/path/to/video/analyser` is the path to the *Video Analyser* folder.
......@@ -83,7 +83,6 @@ There are four required parameters of interest:
There are also other required parameters which deeply influence the behaviour of the *Video Analyser* and, therefore, ***should not be modified unless with great knowledge of what you are doing***. They are:
1. `TapeThresholdPercentual` that specifies the minimum percentage of different pixels for considering the current frame under the tape ROI as a potential Irregularity;
2. `CapstanThresholdPercentual` that specifies the minimum percentage of different pixels for considering the current frame under the capstan ROI as a potential Irregularity;
3. `MinDist` that specifies the minimum distance between the centers of the detected objects for the detection of the reading head;
4. `AngleThresh` that specifies the angle votes threshold for the detection of the reading head;
5. `ScaleThresh` that specifies the scale votes threshold for the detection of the reading head;
6. `PosThresh` that specifies the position votes threshold for the detection of the reading head;
......
# Software Requirements
The software should be able to, given as input the video of an open reel tape, produce as output two irregularity files where are listed the irregularities found in the video and the irregularities found in the audio.
Irregularity files are JSON files that contain a list of irregularities. Each irregularity is a JSON object that contains structured as follow:
```json
{
"type": "object",
"properties": {
"IrregularityID": {
"type": "string",
"format": "uuid"
},
"Source": {
"enum": ["a", "v", "b"]
},
"TimeLabel": {
"type": "string",
"pattern": "[0-9]{2}:[0-5][0-9]:[0-5][0-9]\\.[0-9]{3}"
},
"IrregularityType": {
"enum": ["sp", "b", "sot", "eot", "da", "di", "m", "s", "wf", "pps", "ssv", "esv", "sb"]
},
"IrregularityProperties": {
"type": "object",
"properties": {
"ReadingSpeedStandard": {
"enum": [0.9375, 1.875, 3.75, 7.5, 15, 30]
},
"ReadingEqualisationStandard": {
"enum": ["IEC", "IEC1", "IEC2"]
},
"WritingSpeedStandard": {
"enum": [0.9375, 1.875, 3.75, 7.5, 15, 30]
},
"WritingEqualisationStandard": {
"enum": ["IEC", "IEC1", "IEC2"]
},
}
},
"ImageURI": {
"type": "string","format": "uri"
},
"AudioFileURI": {
"type": "string",
"format": "uri"
}
}
}
```
\ No newline at end of file
using json = nlohmann::json;
void extractIrregularityImagesForAudio(std::string outputPath, const std::string videoPath, json irregularityFileInput, json &irregularityFileOutput2) {
// Make fromAudioAnalyser folder
int capsDirectory = fs::create_directory(outputPath + "fromAudioAnalyser/");
// Open video
cv::VideoCapture videoCapture(videoPath);
// Compute video length in milliseconds
int frameCount = videoCapture.get(CAP_PROP_FRAME_COUNT);
int fps = videoCapture.get(CAP_PROP_FPS);
int videoLenghtMS = (frameCount / fps) * 1000 + std::round((float)((frameCount % fps) * 1000) / fps);
for (int i = 0; i < irregularityFileInput["Irregularities"].size(); i++) {
// Declare output image frame
cv::Mat frame;
std::string framePath;
// Extract TimeLabel from input JSON
std::string timeLabel = irregularityFileInput["Irregularities"][i]["TimeLabel"];
// Obtain time measures from JSON
int h = stoi(timeLabel.substr(0, 2));
int min = stoi(timeLabel.substr(3, 2));
int sec = stoi(timeLabel.substr(6, 2));
int ms = stoi(timeLabel.substr(9, 3));
std::string safeTimeLabel = timeLabel;
safeTimeLabel[2] = '-';
safeTimeLabel[5] = '-';
safeTimeLabel[8] = '-';
// Compute the Irregularity instant in milliseconds
int irrInstMS = ms + sec*1000 + min*60000 + h*3600000;
// Compute the frame number corresponding to the Irregularity
int irrFrame = std::round((float)(irrInstMS/1000)*fps);
try {
framePath = outputPath + "fromAudioAnalyser/AudioIrregularity_" + safeTimeLabel + ".jpg";
videoCapture.set(CAP_PROP_POS_FRAMES, irrFrame);
videoCapture >> frame;
cv::imwrite(framePath, frame);
// Append Irregularity information to JSON
boost::uuids::uuid uuid = boost::uuids::random_generator()();
irregularityFileOutput2["Irregularities"] += {{
"IrregularityID", irregularityFileInput["Irregularities"][i]["IrregularityID"]
}, {
"Source", "a"
}, {
"TimeLabel", timeLabel
}, {
"ImageURI", framePath
}
};
} catch (cv::Exception e) {
std::cout << "\033[0;31mTimeLabel error for Audio Analyser Irregularity " << i << "." << std::endl;
}
}
void extractIrregularityImagesForAudio(std::string outputPath, const std::string videoPath, json irregularityFileInput,
json &irregularityFileOutput2) {
// Make fromAudioAnalyser folder
int capsDirectory = fs::create_directory(outputPath + "fromAudioAnalyser/");
// Open video
cv::VideoCapture videoCapture(videoPath);
// Compute video length in milliseconds
int frameCount = videoCapture.get(CAP_PROP_FRAME_COUNT);
int fps = videoCapture.get(CAP_PROP_FPS);
int videoLenghtMS = (frameCount / fps) * 1000 + std::round((float)((frameCount % fps) * 1000) / fps);
for (int i = 0; i < irregularityFileInput["Irregularities"].size(); i++) {
// Declare output image frame
cv::Mat frame;
std::string framePath;
// Extract TimeLabel from input JSON
std::string timeLabel = irregularityFileInput["Irregularities"][i]["TimeLabel"];
// Obtain time measures from JSON
int h = stoi(timeLabel.substr(0, 2));
int min = stoi(timeLabel.substr(3, 2));
int sec = stoi(timeLabel.substr(6, 2));
int ms = stoi(timeLabel.substr(9, 3));
std::string safeTimeLabel = timeLabel;
safeTimeLabel[2] = '-';
safeTimeLabel[5] = '-';
safeTimeLabel[8] = '-';
// Compute the Irregularity instant in milliseconds
int irrInstMS = ms + sec * 1000 + min * 60000 + h * 3600000;
// Compute the frame number corresponding to the Irregularity
int irrFrame = std::round((float)(irrInstMS / 1000) * fps);
try {
framePath = outputPath + "fromAudioAnalyser/AudioIrregularity_" + safeTimeLabel + ".jpg";
videoCapture.set(CAP_PROP_POS_FRAMES, irrFrame);
videoCapture >> frame;
cv::imwrite(framePath, frame);
// Append Irregularity information to JSON
boost::uuids::uuid uuid = boost::uuids::random_generator()();
irregularityFileOutput2["Irregularities"] +=
{{"IrregularityID", irregularityFileInput["Irregularities"][i]["IrregularityID"]},
{"Source", "a"},
{"TimeLabel", timeLabel},
{"ImageURI", framePath}};
} catch (cv::Exception e) {
std::cout << "\033[0;31mTimeLabel error for Audio Analyser Irregularity " << i << "." << std::endl;
}
}
}
\ No newline at end of file
#include "Irregularity.h"
#include <boost/lexical_cast.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include "Irregularity.h"
#include <boost/uuid/uuid_io.hpp>
Irregularity::Irregularity(const Irregularity& other)
: id(other.id), source(other.source), time_label(other.time_label), type(other.type) {}
Irregularity::Irregularity(Irregularity&& other) noexcept
: id(std::move(other.id)), source(other.source), time_label(std::move(other.time_label)), type(std::move(other.type)) {}
: id(std::move(other.id)),
source(other.source),
time_label(std::move(other.time_label)),
type(std::move(other.type)) {}
Irregularity::Irregularity(Source source, string time_label) {
this->id = boost::uuids::random_generator()();
......@@ -30,14 +34,11 @@ json Irregularity::to_JSON() const {
j["IrregularityID"] = boost::lexical_cast<string>(this->id);
j["Source"] = sourceToString(this->source);
j["TimeLabel"] = this->time_label;
if (this->type.has_value())
j["IrregularityType"] = irregularityTypeToString(this->type.value());
if (this->type.has_value()) j["IrregularityType"] = irregularityTypeToString(this->type.value());
if (this->image_URI.has_value())
j["ImageURI"] = this->image_URI.value();
if (this->image_URI.has_value()) j["ImageURI"] = this->image_URI.value();
if (this->audio_URI.has_value())
j["AudioURI"] = this->audio_URI.value();
if (this->audio_URI.has_value()) j["AudioURI"] = this->audio_URI.value();
return j;
}
......@@ -50,31 +51,19 @@ Irregularity Irregularity::from_JSON(const json& j) {
return Irregularity(source, time_label, type);
}
Source Irregularity::get_source() const {
return this->source;
}
string Irregularity::get_time_label() const {
return this->time_label;
}
std::optional<IrregularityType> Irregularity::get_type() const {
return this->type;
}
boost::uuids::uuid Irregularity::get_id() const {
return this->id;
}
Source Irregularity::get_source() const { return this->source; }
string Irregularity::get_time_label() const { return this->time_label; }
std::optional<IrregularityType> Irregularity::get_type() const { return this->type; }
boost::uuids::uuid Irregularity::get_id() const { return this->id; }
std::optional<string> Irregularity::get_audio_URI() const {
return this->audio_URI;
}
std::optional<string> Irregularity::get_audio_URI() const { return this->audio_URI; }
Irregularity& Irregularity::set_audio_URI(string audio_URI) {
this->audio_URI = audio_URI;
return *this;
}
std::optional<string> Irregularity::get_image_URI() const {
return this->image_URI;
}
std::optional<string> Irregularity::get_image_URI() const { return this->image_URI; }
Irregularity& Irregularity::set_image_URI(string image_URI) {
this->image_URI = image_URI;
......
......@@ -4,14 +4,15 @@
* @brief Header file containing the Irregularity class
* @version 1.0
* @date 2023-05-14
*
*
* @copyright Copyright (c) 2023
*
*
*/
#ifndef IRREGULARITY_H
#define IRREGULARITY_H
#include <boost/uuid/uuid.hpp>
#include <nlohmann/json.hpp>
#include "enums.h"
using std::string;
......@@ -20,17 +21,18 @@ using json = nlohmann::json;
/**
* @class Irregularity
* @brief an irregularity of the tape detected by the system
*
*
*/
class Irregularity {
private:
private:
boost::uuids::uuid id;
Source source;
string time_label;
std::optional<IrregularityType> type;
std::optional<string> image_URI;
std::optional<string> audio_URI;
public:
public:
Irregularity(const Irregularity& other);
Irregularity(Irregularity&& other) noexcept;
Irregularity(Source source, string time_label);
......@@ -38,67 +40,67 @@ public:
~Irregularity() = default;
/**
* @brief Convert the Irregularity to a JSON object
*
* @return json
*
* @return json
*/
json to_JSON() const;
/**
* @brief Create an Irregularity object from a JSON object
*
*
* @param j the JSON object
* @return Irregularity
* @return Irregularity
*/
static Irregularity from_JSON(const json& j);
/**
* @brief Get the source object
*
* @return Source
*
* @return Source
*/
Source get_source() const;
/**
* @brief Get the time label object
*
* @return string
*
* @return string
*/
string get_time_label() const;
/**
* @brief Get the type object
*
* @return IrregularityType
*
* @return IrregularityType
*/
std::optional<IrregularityType> get_type() const;
/**
* @brief Get the id object
*
* @return boost::uuids::uuid
*
* @return boost::uuids::uuid
*/
boost::uuids::uuid get_id() const;
/**
* @brief Get the audio URI object
*
* @return std::optional<string>
*
* @return std::optional<string>
*/
std::optional<string> get_audio_URI() const;
/**
* @brief Get the image URI object
*
* @return std::optional<string>
*
* @return std::optional<string>
*/
std::optional<string> get_image_URI() const;
/**
* @brief Set the audio URI object
*
* @param audio_URI
* @return Irregularity&
*
* @param audio_URI
* @return Irregularity&
*/
Irregularity& set_audio_URI(string audio_URI);
/**
* @brief Set the image URI object
*
* @param image_URI
* @return Irregularity&
*
* @param image_URI
* @return Irregularity&
*/
Irregularity& set_image_URI(string image_URI);
};
#endif // IRREGULARITY_H
\ No newline at end of file
#endif // IRREGULARITY_H
\ No newline at end of file
#include <exception>
#include "IrregularityFile.h"
#include <algorithm>
#include <exception>
#include <iterator>
#include <memory>
IrregularityFile::IrregularityFile(std::optional<uint16_t> offset) : offset_(offset) {}
IrregularityFile::IrregularityFile(const IrregularityFile &rhs) {
std::transform(rhs.irregularities_.begin(), rhs.irregularities_.end(),
std::back_inserter(irregularities_),
[](const std::unique_ptr<Irregularity> &ptr) {
return std::make_unique<Irregularity>(*ptr);
});
IrregularityFile::IrregularityFile(const IrregularityFile& rhs) {
std::transform(rhs.irregularities_.begin(), rhs.irregularities_.end(), std::back_inserter(irregularities_),
[](const std::unique_ptr<Irregularity>& ptr) { return std::make_unique<Irregularity>(*ptr); });
}
IrregularityFile& IrregularityFile::add(std::unique_ptr<Irregularity> irregularity) {
......@@ -20,9 +18,9 @@ IrregularityFile& IrregularityFile::add(std::unique_ptr<Irregularity> irregulari
}
IrregularityFile& IrregularityFile::remove_by_id(const boost::uuids::uuid id) {
auto it = std::find_if(irregularities_.begin(), irregularities_.end(), [&id](const std::unique_ptr<Irregularity>& irregularity) {
return irregularity->get_id() == id;
});
auto it =
std::find_if(irregularities_.begin(), irregularities_.end(),
[&id](const std::unique_ptr<Irregularity>& irregularity) { return irregularity->get_id() == id; });
if (it != irregularities_.end()) {
irregularities_.erase(it);
}
......@@ -30,23 +28,18 @@ IrregularityFile& IrregularityFile::remove_by_id(const boost::uuids::uuid id) {
}
IrregularityFile& IrregularityFile::sort() {
std::sort(irregularities_.begin(), irregularities_.end(), [](const std::unique_ptr<Irregularity>& a, const std::unique_ptr<Irregularity>& b) {
return a->get_time_label() < b->get_time_label();
});
std::sort(irregularities_.begin(), irregularities_.end(),
[](const std::unique_ptr<Irregularity>& a, const std::unique_ptr<Irregularity>& b) {
return a->get_time_label() < b->get_time_label();
});
return *this;
}
std::optional<uint16_t> IrregularityFile::get_offset() const {
return offset_;
}
std::optional<uint16_t> IrregularityFile::get_offset() const { return offset_; }
std::vector<std::unique_ptr<Irregularity>>::iterator IrregularityFile::begin() {
return irregularities_.begin();
}
std::vector<std::unique_ptr<Irregularity>>::iterator IrregularityFile::begin() { return irregularities_.begin(); }
std::vector<std::unique_ptr<Irregularity>>::iterator IrregularityFile::end() {
return irregularities_.end();
}
std::vector<std::unique_ptr<Irregularity>>::iterator IrregularityFile::end() { return irregularities_.end(); }
json IrregularityFile::toJSON() const {
json j;
......
......@@ -4,90 +4,92 @@
* @brief Header file containing the IrregularityFile class
* @version 1.0
* @date 2023-05-14
*
*
* @copyright Copyright (c) 2023
*
*
*/
#ifndef IRREGULARITY_FILE_H
#define IRREGULARITY_FILE_H
#include <vector>
#include <nlohmann/json.hpp>
#include "Irregularity.h"
#include <optional>
#include <vector>
#include "Irregularity.h"
using json = nlohmann::json;
/**
* @class IrregularityFile
* @brief An IrregularityFile is a collection of Irregularities detected on a tape.
*
* @brief An IrregularityFile is a collection of Irregularities detected on a
* tape.
*
*/
class IrregularityFile {
public:
public:
/**
* @brief Create an IrregularityFile object from a JSON object
*
* @param j
* @return IrregularityFile
*
* @param j
* @return IrregularityFile
*/
static IrregularityFile fromJSON(const json j);
/**
* @brief Convert the IrregularityFile to a JSON object
*
* @return json
*
* @return json
*/
json toJSON() const;
IrregularityFile(std::optional<uint16_t> offset = std::nullopt);
/**
* @brief Copy constructor
*
* @param rhs
*
* @param rhs
*/
IrregularityFile(const IrregularityFile &rhs);
~IrregularityFile() {};
IrregularityFile(const IrregularityFile& rhs);
~IrregularityFile(){};
/**
* @brief Add an Irregularity to the IrregularityFile
*
* @param irregularity
* @return IrregularityFile&
*
* @param irregularity
* @return IrregularityFile&
*/
IrregularityFile& add(std::unique_ptr<Irregularity> irregularity);
/**
* @brief Remove an Irregularity from the IrregularityFile
*
* @param id
* @return IrregularityFile&
*
* @param id
* @return IrregularityFile&
*/
IrregularityFile& remove_by_id(const boost::uuids::uuid id);
/**
* @brief Sort the IrregularityFile by time_label
*
* @return IrregularityFile&
*
* @return IrregularityFile&
*/
IrregularityFile& sort();
/**
* @brief Get the offset object
*
* @return std::optional<uint16_t>
*
* @return std::optional<uint16_t>
*/
std::optional<uint16_t> get_offset() const;
/**
* @brief Get an iterator to the beginning of the IrregularityFile
*
* @return std::vector<std::unique_ptr<Irregularity>>::iterator
*
* @return std::vector<std::unique_ptr<Irregularity>>::iterator
*/
std::vector<std::unique_ptr<Irregularity>>::iterator begin();
/**
* @brief Get an iterator to the end of the IrregularityFile
*
* @return std::vector<std::unique_ptr<Irregularity>>::iterator
*
* @return std::vector<std::unique_ptr<Irregularity>>::iterator
*/
std::vector<std::unique_ptr<Irregularity>>::iterator end();
private:
private:
std::optional<uint16_t> offset_;
std::vector<std::unique_ptr<Irregularity>> irregularities_;
};
#endif // IRREGULARITY_FILE_HPP
#endif // IRREGULARITY_FILE_HPP
#include "TimeLabel.h"
TimeLabel::TimeLabel(/* args */)
{
}
TimeLabel::TimeLabel(/* args */) {}
TimeLabel::~TimeLabel()
{
}
\ No newline at end of file
TimeLabel::~TimeLabel() {}
\ No newline at end of file
#ifndef TIME_LABEL_H
#define TIME_LABEL_H
class TimeLabel
{
private:
/**
* @brief A label that displays the current time in the format hh:mm:ss.mms
* @todo Implement this class:
* - Implement the constructor
* - Implement the destructor
* - Move functions from time.h to here
*/
class TimeLabel {
private:
/* data */
public:
public:
TimeLabel(/* args */);
~TimeLabel();
};
#endif // TIME_LABEL_H
\ No newline at end of file
#endif // TIME_LABEL_H
\ No newline at end of file
/**
* @file colors.h
* @author Matteo Spanio (dev2@audioinnova.com)
* @brief Header file containing a set of ANSI escape codes to print colored text in the terminal.
* @brief Header file containing a set of ANSI escape codes to print colored
* text in the terminal.
*
* When printing text in the terminal, it is possible to use ANSI escape codes
* to change the color of the text. This header file contains a set of
* pre-defined ANSI escape codes to print colored text in the terminal.
*
* @see https://en.wikipedia.org/wiki/ANSI_escape_code
* @version 1.0
* @date 2023-05-13
*
* @copyright Copyright (c) 2023
*
*
*/
#ifndef COLORS_H
#define COLORS_H
#include <stdlib.h>
#include <string>
using std::string;
......@@ -26,4 +33,4 @@ string RED = "\033[91m";
string BOLD = "\033[1m";
string UNDERLINE = "\033[4m";
string END = "\033[0m";
#endif // COLORS_H
\ No newline at end of file
#endif // COLORS_H
\ No newline at end of file
#include <stdexcept>
#include "enums.h"
#include <stdexcept>
std::string sourceToString(Source source) {
switch (source) {
case Audio:
......
......@@ -4,34 +4,38 @@
* @brief A collection of enums and functions to handle them.
* @version 1.0
* @date 2023-05-13
*
*
* @copyright Copyright (c) 2023
*
*
* This file contains a set of enums to define properties of an Irregularity.
* The enums are:
* - Source: the source of the Irregularity (Audio, Video or Both)
* - IrregularityType: the type of Irregularity (Brands on tape, Splice, etc.) that can be present on the tape.
*
* The file also contains functions to convert from enum to string and viceversa (useful when saving the Irregularity to a file).
*
* - IrregularityType: the type of Irregularity (Brands on tape, Splice, etc.)
* that can be present on the tape.
*
* The file also contains functions to convert from enum to string and viceversa
* (useful when saving the Irregularity to a file).
*
*/
#ifndef ENUMS_H
#define ENUMS_H
#include<string>
#include <string>
/**
* @enum Source
* @brief The source of the Irregularity (Audio, Video or Both)
*
* An Irregularity can be detected by the Audio analyser, the Video analyser or both.
*
*
* An Irregularity can be detected by the Audio analyser, the Video analyser or
* both.
*
*/
enum Source { Audio, Video, Both };
/**
* @enum IrregularityType
* @brief The type of Irregularity (Brands on tape, Splice, etc.) that can be present on the tape.
*
* @brief The type of Irregularity (Brands on tape, Splice, etc.) that can be
* present on the tape.
*
* The types of Irregularities are:
* - BRANDS_ON_TAPE: Brands on tape
* - SPLICE: Splice
......@@ -47,10 +51,11 @@ enum Source { Audio, Video, Both };
* - EQUALIZATION: Equalization
* - SPEED_AND_EQUALIZATION: Speed and equalization
* - BACKWARD: Backward
*
* @note Speed, Equalization and Speed and equalization are detected only by the Audio analyser,
* while the other Irregularities are detected only by the Video analyser.
*
*
* @note Speed, Equalization and Speed and equalization are detected only by the
* Audio analyser, while the other Irregularities are detected only by the Video
* analyser.
*
*/
enum IrregularityType {
BRANDS_ON_TAPE,
......@@ -73,4 +78,4 @@ std::string sourceToString(Source source);
Source sourceFromString(std::string source);
std::string irregularityTypeToString(IrregularityType type);
IrregularityType irregularityTypeFromString(std::string type);
#endif // ENUMS_H
\ No newline at end of file
#endif // ENUMS_H
\ No newline at end of file
#include <iostream>
#include "files.h"
#include <iostream>
using std::cout, std::endl, std::cerr, std::ofstream, std::ios;
void files::saveFile(std::filesystem::path fileName, std::string content, bool append) {
ofstream outputFile;
if (append) {
outputFile.open(fileName, ios::app);
} else {
outputFile.open(fileName);
}
outputFile << content << endl;
outputFile.close();
ofstream outputFile;
if (append) {
outputFile.open(fileName, ios::app);
} else {
outputFile.open(fileName);
}
outputFile << content << endl;
outputFile.close();
}
void files::findFileNameFromPath(std::string* path, std::string* fileName, std::string* extension) {
*path = path->substr(path->find_last_of("'") + 1, path->size());
std::string path_without_extension = path->substr(0, path->find_last_of("."));
*fileName = path_without_extension.substr(path_without_extension.find_last_of("/") + 1, path_without_extension.size());
*extension = path->substr(path->find_last_of(".") + 1, path->size());
*path = path->substr(path->find_last_of("'") + 1, path->size());
std::string path_without_extension = path->substr(0, path->find_last_of("."));
*fileName =
path_without_extension.substr(path_without_extension.find_last_of("/") + 1, path_without_extension.size());
*extension = path->substr(path->find_last_of(".") + 1, path->size());
}
int files::findFileName(std::string videoPath, std::string &fileName, std::string &extension) {
int files::findFileName(std::string videoPath, std::string& fileName, std::string& extension) {
files::findFileNameFromPath(&videoPath, &fileName, &extension);
if (extension.compare("avi") != 0 && extension.compare("mp4") != 0 && extension.compare("mov") != 0) {
......@@ -35,4 +36,3 @@ int files::findFileName(std::string videoPath, std::string &fileName, std::strin
}
return 0;
}
......@@ -4,54 +4,59 @@
* @brief A collection of functions to handle files.
* @version 1.0
* @date 2023-05-13
*
*
* @copyright Copyright (c) 2023
*
*
*/
#ifndef FILES_H
#define FILES_H
#include <stdlib.h>
#include <filesystem>
#include <fstream>
#include <string>
#include <iostream>
#include <stdlib.h>
#include <string>
/**
* @namespace files
* @brief A collection of functions to handle files.
*
*
*/
namespace files {
/**
* @fn void saveFile(std::filesystem::path fileName, std::string content, bool append)
* @brief Save content to a file
*
* @param fileName the name of the file
* @param content the content to be saved
* @param append if true, the content will be appended to the file, otherwise the file will be overwritten
*/
void saveFile(std::filesystem::path fileName, std::string content, bool append);
/**
* @fn void saveFile(std::filesystem::path fileName, std::string content, bool
* append)
* @brief Save content to a file
*
* @param fileName the name of the file
* @param content the content to be saved
* @param append if true, the content will be appended to the file, otherwise
* the file will be overwritten
*/
void saveFile(std::filesystem::path fileName, std::string content, bool append);
/**
* @fn void findFileNameFromPath(std::string* path, std::string* fileName, std::string* extension)
* @brief Separates video file name from its extension.
*
* @param[in] path Full video path;
* @param[out] fileName Video file name;
* @param[out] extension Video extension.
*/
void findFileNameFromPath(std::string* path, std::string* fileName, std::string* extension);
/**
* @fn void findFileNameFromPath(std::string* path, std::string* fileName,
* std::string* extension)
* @brief Separates video file name from its extension.
*
* @param[in] path Full video path;
* @param[out] fileName Video file name;
* @param[out] extension Video extension.
*/
void findFileNameFromPath(std::string* path, std::string* fileName, std::string* extension);
/**
* @fn int findFileName(std::string videoPath, std::string &fileName, std::string &extension)
* @brief Check if the specified input video file exists and is supported.
*
* @param[in] videoPath Full video path;
* @param[out] fileName Video file name;
* @param[out] extension Video extension.
* @return int -1 if the format is not supported, 0 otherwise.
*/
int findFileName(std::string videoPath, std::string &fileName, std::string &extension);
}
#endif // FILES_H
\ No newline at end of file
/**
* @fn int findFileName(std::string videoPath, std::string &fileName,
* std::string &extension)
* @brief Check if the specified input video file exists and is supported.
*
* @param[in] videoPath Full video path;
* @param[out] fileName Video file name;
* @param[out] extension Video extension.
* @return int -1 if the format is not supported, 0 otherwise.
*/
int findFileName(std::string videoPath, std::string& fileName, std::string& extension);
} // namespace files
#endif // FILES_H
\ No newline at end of file
#include "time.h"
std::string getTimeLabel(int ms, std::string delim) {
int mil = ms % 1000;
int sec = ms / 1000;
int min = (sec / 60) % 60;
int hours = sec / 3600;
sec = sec % 60;
int mil = ms % 1000;
int sec = ms / 1000;
int min = (sec / 60) % 60;
int hours = sec / 3600;
sec = sec % 60;
std::string hoursStr = std::to_string(hours), minStr = std::to_string(min), secStr = std::to_string(sec), milStr = std::to_string(mil);
if (hours < 10)
hoursStr = "0" + hoursStr;
if (min < 10)
minStr = "0" + minStr;
if (sec < 10)
secStr = "0" + secStr;
if (mil < 100) {
if (mil < 10) {
milStr = "00" + milStr;
} else {
milStr = "0" + milStr;
}
}
std::string hoursStr = std::to_string(hours), minStr = std::to_string(min), secStr = std::to_string(sec),
milStr = std::to_string(mil);
if (hours < 10) hoursStr = "0" + hoursStr;
if (min < 10) minStr = "0" + minStr;
if (sec < 10) secStr = "0" + secStr;
if (mil < 100) {
if (mil < 10) {
milStr = "00" + milStr;
} else {
milStr = "0" + milStr;
}
}
std::string timeLabel = hoursStr + delim + minStr + delim + secStr + delim + milStr;
return timeLabel;
return timeLabel;
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment