second commit

This commit is contained in:
2025-07-01 13:52:40 +02:00
parent ee767d952b
commit 7a8e4db550
6 changed files with 2220 additions and 5 deletions

9
.gitignore vendored Normal file
View File

@@ -0,0 +1,9 @@
# Xmake cache
.xmake/
build/
# MacOS Cache
.DS_Store
.vscode

View File

@@ -7,13 +7,28 @@
<title>Document</title>
<script
src="https://cdn.jsdelivr.net/combine/npm/tone@14.7.58,npm/@magenta/music@1.23.1/es6/core.js,npm/focus-visible@5,npm/html-midi-player@1.5.0"></script>
</head>
</head>
<body>
<midi-player src="indie.mid" sound-font
<body>
<midi-player src="indie.mid" sound-font
visualizer="#myVisualizer">
</midi-player>
<midi-visualizer type="piano-roll" id="myVisualizer"></midi-visualizer>
</body>
</html>
<!--
Prendre un fichier midi :
- Sélectionner un passage
- Sélectionner les instruments
- Générer les fichiers midi
-->

48
src/main.cpp Normal file
View File

@@ -0,0 +1,48 @@
#include "stx-execpipe.h"
#include <iostream>
#include <vector>
#include <string>
static const std::vector<std::string> links = {
"2gQ--SCEfmI"};
static const std::string YTDLP_BINARY = "/usr/bin/yt-dlp";
void DownloadFile()
{
stx::ExecPipe ep;
std::string link = "https://music.youtube.com/watch?v=" + links.front();
std::vector<std::string> args = {YTDLP_BINARY, link.c_str(), "--extract-audio", "--audio-format", "vorbis", "-o", "%(id)s.%(ext)s"};
ep.add_exec(&args);
ep.run();
}
float GetDuration()
{
stx::ExecPipe ep;
std::string fileName = links.front() + ".ogg";
std::vector<std::string> args = {"/usr/bin/ffprobe", "-v", "error", "-show_entries", "format=duration", "-of", "default=noprint_wrappers=1:nokey=1", fileName};
ep.add_exec(&args);
std::string output;
ep.set_output_string(&output);
ep.run();
return std::stof(output);
}
int main(int argc, char **argv)
{
float duration = GetDuration();
std::cout << "Durée : " << duration << std::endl;
return 0;
}

1698
src/stx-execpipe.cpp Normal file

File diff suppressed because it is too large Load Diff

367
src/stx-execpipe.h Normal file
View File

@@ -0,0 +1,367 @@
// -*- mode: c++; fill-column: 79 -*-
/*
* STX Execution Pipe Library v0.7.0
* Copyright (C) 2010 Timo Bingmann
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by the
* Free Software Foundation; either version 2.1 of the License, or (at your
* option) any later version.
*
* This library 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 Lesser General Public License
* for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _STX_EXECPIPE_H_
#define _STX_EXECPIPE_H_
#include <string>
#include <vector>
/// STX - Some Template Extensions namespace
namespace stx {
/**
* Abstract class used as an input stream source for an ExecPipe.
*
* Derived classes can be used in an ExecPipe to generate an input stream
* source. Data generated by this class is written to the first stage of the
* pipe.
*
* When data is needed by the pipe the function poll() is called. This pure
* virtual function must generate data and push it into a buffer using the
* write() function. The input stream is terminated when poll() returns false.
*/
class PipeSource
{
private:
/// pointer to associated pipe. filled by ExecPipe::add_input_source()
class ExecPipeImpl* m_impl;
/// association to the pipe implementation for write access to m_impl.
friend class ExecPipeImpl;
public:
/// Constructor which clears m_impl.
PipeSource();
/// Poll the input source for new data. The input stream is closed when
/// this function returns false, otherwise it will be polled again.
virtual bool poll() = 0;
/// Write input data to the first stage via a buffer.
void write(const void* data, unsigned int datalen);
};
/**
* Abstract class used as an output stream source for an ExecPipe.
*
* Derived classes can be attached to the end of an execution pipe. It will
* receive all data outputted by the final pipe stage.
*
* Data read from the final or preceding stage is passed to the class via
* process(). When the final stage closes the pipe, the function eof() is
* called.
*/
class PipeSink
{
public:
/// Pure virtual function which receives the output stream as read from the
/// final or preceding pipe stage.
virtual void process(const void* data, unsigned int datalen) = 0;
/// Pure virtual function called when the final or preceding pipe stage
/// finishes.
virtual void eof() = 0;
};
/**
* Abstract class used as an intermediate pipe stage between executed
* processes.
*
* Derived classes can be inserted into an execution pipe between two
* externally executed processes. It will receive all data from the preceding
* pipe stage and after processing it may forward output to the next pipe
* stage.
*
* The class is derived from PipeSink and receives data from the preceding
* stage via the inherited functions process() and also the eof()
* signal. Usually process() will perform some action on the data and then
* forward the resulting data block to the next pipe stage via write().
*/
class PipeFunction : public PipeSink
{
private:
/// pointer to associated pipe filled by ExecPipe::add_function()
class ExecPipeImpl* m_impl;
/// pipe stage identifier
unsigned int m_stageid;
/// association to the pipe implementation for write access to m_impl.
friend class ExecPipeImpl;
public:
/// Constructor which clears m_impl and m_stageid.
PipeFunction();
/// Write input data to the next pipe stage via a buffer.
void write(const void* data, unsigned int datalen);
};
/**
* \brief Main library interface (reference counted pointer)
*
* The ExecPipe class is the main interface to the library. It is a reference
* counted pointer implementation, so you can easily copy and pass around
* without duplicating the inside object. See the \ref index "main page" for
* detailed information and examples.
*/
class ExecPipe
{
protected:
/// reference-counted pointer implementation
class ExecPipeImpl* m_impl;
public:
/// Construct a new uninitialize execution pipe.
ExecPipe();
/// Release reference to execution pipe.
~ExecPipe();
/// Copy-constructor creates a new reference to the _same_ pipe.
ExecPipe(const ExecPipe& ep);
/// Assignment operator creates a new reference to the right pipe.
ExecPipe& operator=(const ExecPipe& ep);
// *** Debugging Output ***
/// Enumeration for ascending debug levels.
enum DebugLevel
{
DL_ERROR=0, ///< error reporting is always active. shows failed syscalls.
DL_INFO=1, ///< info reports at important points during pipe run.
DL_DEBUG=2, ///< debug shows information about select() calls.
DL_TRACE=3 ///< trace lists lots of info about read() and write() calls.
};
/// Change the current debug level. The default is DL_ERROR.
void set_debug_level(enum DebugLevel dl);
/// Change output function for debug messages. If set to NULL (the default)
/// the debug lines are printed to stdout.
void set_debug_output(void (*output)(const char *line));
// *** Input Selectors ***
///@{ \name Input Selectors
/**
* Assign an already opened file descriptor as input stream for the first
* exec stage.
*/
void set_input_fd(int fd);
/**
* Assign a file as input stream source. This file will be opened read-only
* and read by the first exec stage.
*/
void set_input_file(const char* path);
/**
* Assign a std::string as input stream source. The contents of the string
* will be written to the first exec stage. The string object is not copied
* and must still exist when run() is called.
*/
void set_input_string(const std::string* input);
/**
* Assign a PipeSource as input stream source. The object will be queried
* via the read() function for data which is then written to the first exec
* stage.
*/
void set_input_source(PipeSource* source);
///@}
// *** Output Selectors ***
///@{ \name Output Selectors
/**
* Assign an already opened file descriptor as output stream for the last
* exec stage.
*/
void set_output_fd(int fd);
/**
* Assign a file as output stream destination. This file will be created or
* truncated write-only and written by the last exec stage.
*/
void set_output_file(const char* path, int mode = 0666);
/**
* Assign a std::string as output stream destination. The output of the
* last exec stage will be stored as the contents of the string. The string
* object is not copied and must still exist when run() is called.
*/
void set_output_string(std::string* output);
/**
* Assign a PipeSink as output stream destination. The object will receive
* data via the process() function and is informed via eof()
*/
void set_output_sink(PipeSink* sink);
///@}
// *** Pipe Stages ***
///@{ \name Add Pipe Stages
/**
* Return the number of pipe stages added.
*/
unsigned int size() const;
/**
* Add an exec() stage to the pipe with given arguments. Note that argv[0]
* is set to prog.
*/
void add_exec(const char* prog);
/**
* Add an exec() stage to the pipe with given arguments. Note that argv[0]
* is set to prog.
*/
void add_exec(const char* prog, const char* arg1);
/**
* Add an exec() stage to the pipe with given arguments. Note that argv[0]
* is set to prog.
*/
void add_exec(const char* prog, const char* arg1, const char* arg2);
/**
* Add an exec() stage to the pipe with given arguments. Note that argv[0]
* is set to prog.
*/
void add_exec(const char* prog, const char* arg1, const char* arg2, const char* arg3);
/**
* Add an exec() stage to the pipe with given arguments. The vector of
* arguments is not copied, so it must still exist when run() is
* called. Note that the program called is args[0].
*/
void add_exec(const std::vector<std::string>* args);
/**
* Add an execp() stage to the pipe with given arguments. The PATH variable
* is search for programs not containing a slash / character. Note that
* argv[0] is set to prog.
*/
void add_execp(const char* prog);
/**
* Add an execp() stage to the pipe with given arguments. The PATH variable
* is search for programs not containing a slash / character. Note that
* argv[0] is set to prog.
*/
void add_execp(const char* prog, const char* arg1);
/**
* Add an execp() stage to the pipe with given arguments. The PATH variable
* is search for programs not containing a slash / character. Note that
* argv[0] is set to prog.
*/
void add_execp(const char* prog, const char* arg1, const char* arg2);
/**
* Add an execp() stage to the pipe with given arguments. The PATH variable
* is search for programs not containing a slash / character. Note that
* argv[0] is set to prog.
*/
void add_execp(const char* prog, const char* arg1, const char* arg2, const char* arg3);
/**
* Add an execp() stage to the pipe with given arguments. The PATH variable
* is search for programs not containing a slash / character. The vector of
* arguments is not copied, so it must still exist when run() is
* called. Note that the program called is args[0].
*/
void add_execp(const std::vector<std::string>* args);
/**
* Add an exece() stage to the pipe with the given arguments and
* environments. This is the most flexible exec() call. The vector of
* arguments and environment variables is not copied, so it must still
* exist when run() is called. The args[0] is _not_ override with path, so
* you can fake program name calls.
*/
void add_exece(const char* path,
const std::vector<std::string>* args,
const std::vector<std::string>* env);
/**
* Add a function stage to the pipe. This function object will be called in
* the parent process with data passing through the stage. See PipeFunction
* for more information.
*/
void add_function(PipeFunction* func);
///@}
// *** Run Pipe ***
/**
* Run the configured pipe sequence and wait for all children processes to
* complete. Returns a reference to *this for chaining.
*
* This function call should be wrapped into a try-catch block as it will
* throw() if a system call fails.
*/
ExecPipe& run();
// *** Inspection After Pipe Execution ***
///@{ \name Inspect Return Codes
/**
* Get the return status of exec() stage's program run after pipe execution
* as indicated by wait().
*/
int get_return_status(unsigned int stageid) const;
/**
* Get the return code of exec() stage's program run after pipe execution,
* or -1 if the program terminated abnormally.
*/
int get_return_code(unsigned int stageid) const;
/**
* Get the signal of the abnormally terminated exec() stage's program run
* after pipe execution, or -1 if the program terminated normally.
*/
int get_return_signal(unsigned int stageid) const;
/**
* Return true if the return code of all exec() stages were zero.
*/
bool all_return_codes_zero() const;
///@}
};
} // namespace stx
#endif // _STX_EXECPIPE_H_

78
xmake.lua Normal file
View File

@@ -0,0 +1,78 @@
add_rules("mode.debug", "mode.release")
set_languages("c++11")
target("Songdle")
set_kind("binary")
add_files("src/*.cpp")
set_rundir(".")
--
-- If you want to known more usage about xmake, please see https://xmake.io
--
-- ## FAQ
--
-- You can enter the project directory firstly before building project.
--
-- $ cd projectdir
--
-- 1. How to build project?
--
-- $ xmake
--
-- 2. How to configure project?
--
-- $ xmake f -p [macosx|linux|iphoneos ..] -a [x86_64|i386|arm64 ..] -m [debug|release]
--
-- 3. Where is the build output directory?
--
-- The default output directory is `./build` and you can configure the output directory.
--
-- $ xmake f -o outputdir
-- $ xmake
--
-- 4. How to run and debug target after building project?
--
-- $ xmake run [targetname]
-- $ xmake run -d [targetname]
--
-- 5. How to install target to the system directory or other output directory?
--
-- $ xmake install
-- $ xmake install -o installdir
--
-- 6. Add some frequently-used compilation flags in xmake.lua
--
-- @code
-- -- add debug and release modes
-- add_rules("mode.debug", "mode.release")
--
-- -- add macro definition
-- add_defines("NDEBUG", "_GNU_SOURCE=1")
--
-- -- set warning all as error
-- set_warnings("all", "error")
--
-- -- set language: c99, c++11
-- set_languages("c99", "c++11")
--
-- -- set optimization: none, faster, fastest, smallest
-- set_optimize("fastest")
--
-- -- add include search directories
-- add_includedirs("/usr/include", "/usr/local/include")
--
-- -- add link libraries and search directories
-- add_links("tbox")
-- add_linkdirs("/usr/local/lib", "/usr/lib")
--
-- -- add system link libraries
-- add_syslinks("z", "pthread")
--
-- -- add compilation and link flags
-- add_cxflags("-stdnolib", "-fno-strict-aliasing")
-- add_ldflags("-L/usr/local/lib", "-lpthread", {force = true})
--
-- @endcode
--