Skip to content

Add audio phase meter application #314

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jan 27, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# C++ apps
add_subdirectory(avAudioPhaseMeter)
add_subdirectory(avInfo)
add_subdirectory(avMeta)
add_subdirectory(avPlayer)
Expand Down
24 changes: 24 additions & 0 deletions app/avAudioPhaseMeter/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
### cpp/avProcessor

# Load custom cmake utilities
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
include(AvTranscoderMacros)

# Build app
add_executable(avaudiophasemeter avAudioPhaseMeter.cpp)
set_target_properties(avaudiophasemeter PROPERTIES VERSION ${AVTRANSCODER_VERSION})
target_link_libraries(avaudiophasemeter avtranscoder-shared)

# Install app
if(WIN32)
set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avaudiophasemeter.exe")
else()
set(BINARY_FILES "${CMAKE_CURRENT_BINARY_DIR}/avaudiophasemeter" "${CMAKE_CURRENT_BINARY_DIR}/avaudiophasemeter-${AVTRANSCODER_VERSION}")
endif()

install(
FILES ${BINARY_FILES}
PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ WORLD_READ WORLD_EXECUTE
DESTINATION "bin/"
OPTIONAL
)
148 changes: 148 additions & 0 deletions app/avAudioPhaseMeter/avAudioPhaseMeter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
#include <AvTranscoder/transcoder/Transcoder.hpp>
#include <AvTranscoder/file/OutputFile.hpp>
#include <AvTranscoder/progress/ConsoleProgress.hpp>

#include <iostream>
#include <iomanip>
#include <vector>
#include <fstream>
#include <sstream>
#include <cstdlib>

std::vector<avtranscoder::InputStreamDesc> parseConfigFile(const std::string& configFilename)
{
std::vector<avtranscoder::InputStreamDesc> result;

std::ifstream configFile(configFilename.c_str(), std::ifstream::in);

std::string line;
size_t countLines = 0;
while(std::getline(configFile, line))
{
if(++countLines > 2)
{
throw std::runtime_error("Audio phase analysis can only be done on a stereo pair, i.e. two channels (see usage).");
}

std::istringstream is_line(line);
std::string filename;
if(std::getline(is_line, filename, '='))
{
std::string stream;
std::getline(is_line, stream);

std::stringstream ss(stream);
size_t streamIndex = 0;
char separator;
int channelIndex = -1;
ss >> streamIndex;
ss >> separator;
if(separator == '.')
{
ss >> channelIndex;
}

bool newInputDescAdded = false;
// if we already have an input description with the same filename/streamIndex, add only the new channelIndex
for(std::vector<avtranscoder::InputStreamDesc>::iterator it = result.begin(); it != result.end(); ++it)
{
if(it->_filename == filename && it->_streamIndex == streamIndex)
{
it->_channelIndexArray.push_back(channelIndex);
newInputDescAdded = true;
break;
}
}
if(!newInputDescAdded)
{
result.push_back(avtranscoder::InputStreamDesc(filename, streamIndex, channelIndex));
}
}
}

configFile.close();

return result;
}

void displayUsage(const std::string& program)
{
std::cout << "Usage: " << program << " CONFIG OUTPUT [OPTIONS]" << std::endl << std::endl;
std::cout << "\tCONFIG: input configuration file" << std::endl;
std::cout << "\t\tEach line represents one audio stream analysed." << std::endl;
std::cout << "\t\tPattern of each line is:" << std::endl;
std::cout << "\t\t[inputFile]=STREAM_INDEX.CHANNEL_INDEX" << std::endl;
std::cout << "\t\tWARNING: audio phase analyser only support stereo layout, i.e. two lines in this configuration." << std::endl << std::endl;
std::cout << "\tOUTPUT: metadata output file" << std::endl;
std::cout << "\t\tPattern for each frame is:" << std::endl;
std::cout << "\t\t `frame:[FRAME_ID] pts:[PTS] pts_time:[PTS_TIME]" << std::endl;
std::cout << "\t\t lavfi.aphasemeter.phase=[PHASE_VALUE]`" << std::endl << std::endl;
std::cout << "\tOPTIONS:" << std::endl;
std::cout << "\t\t--info set log level to AV_LOG_INFO" << std::endl;
std::cout << "\t\t--debug set log level to AV_LOG_DEBUG" << std::endl;
std::cout << "\t\t--help display this help" << std::endl << std::endl;
}

int main(int argc, char** argv)
{
// Preload FFmpeg context
avtranscoder::preloadCodecsAndFormats();
avtranscoder::Logger::setLogLevel(AV_LOG_QUIET);

if(argc < 3)
{
displayUsage(argv[0]);
}

// List command line arguments
std::vector<std::string> arguments;
for(int argument = 1; argument < argc; ++argument)
{
arguments.push_back(argv[argument]);
}
for(size_t argument = 0; argument < arguments.size(); ++argument)
{
if(arguments.at(argument) == "--help")
{
displayUsage(argv[0]);
return 0;
}
else if(arguments.at(argument) == "--debug")
{
avtranscoder::Logger::setLogLevel(AV_LOG_DEBUG);
}
else if(arguments.at(argument) == "--info")
{
avtranscoder::Logger::setLogLevel(AV_LOG_INFO);
}
}

try
{
std::string configFilePath(arguments.at(0));
std::string outputFilePath(arguments.at(1));
std::vector<avtranscoder::InputStreamDesc> inputStreamsToAnalyse = parseConfigFile(configFilePath);

avtranscoder::OutputFile outputFile(outputFilePath, "null"); // the output file will be overwritten by the extracted metadata

avtranscoder::Transcoder transcoder(outputFile);
transcoder.setProcessMethod(avtranscoder::eProcessMethodBasedOnStream, 0);
transcoder.addStream(inputStreamsToAnalyse);

avtranscoder::StreamTranscoder& streamTranscoder = transcoder.getStreamTranscoder(0);
avtranscoder::FilterGraph* filterGraph = streamTranscoder.getFilterGraph();
filterGraph->addFilter("aphasemeter", "video=0");
filterGraph->addFilter("ametadata", "mode=print:file=" + outputFilePath);

avtranscoder::ConsoleProgress progress;
transcoder.process(progress);
}
catch(std::exception& e)
{
std::cerr << "ERROR: during process, an error occured: " << e.what() << std::endl;
}
catch(...)
{
std::cerr << "ERROR: during process, an unknown error occured" << std::endl;
}
}
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy