Loading...
Searching...
No Matches
ClipMetadata.hpp
1#pragma once
2#include <halp/custom_widgets.hpp>
3
4#include <string>
5#include <string_view>
6#include <vector>
7
8namespace Process
9{
19inline constexpr std::string_view clip_metadata_mime = "application/x-ossia-take";
20
22{
23 std::string path;
24 halp::clip_stretch stretch{halp::clip_stretch::automatic};
27 bool loop{};
28};
29
30inline constexpr std::string_view clip_stretch_names[]{
31 "automatic", "none", "repitch", "repitch_fast",
32 "timestretch", "timestretch_percussive"};
33
34inline std::string_view to_string(halp::clip_stretch s) noexcept
35{
36 const auto i = std::size_t(s);
37 return i < std::size(clip_stretch_names) ? clip_stretch_names[i] : clip_stretch_names[0];
38}
39
40inline halp::clip_stretch clip_stretch_from_string(std::string_view s) noexcept
41{
42 for(std::size_t i = 0; i < std::size(clip_stretch_names); i++)
43 if(clip_stretch_names[i] == s)
44 return halp::clip_stretch(i);
45 return halp::clip_stretch::automatic;
46}
47
49inline std::string encode_clip_metadata(
50 const std::vector<std::string>& files, halp::clip_stretch stretch, bool loop = false)
51{
52 std::string res;
53 if(stretch == halp::clip_stretch::automatic && !loop)
54 return res;
55 for(const auto& f : files)
56 {
57 res += f;
58 if(stretch != halp::clip_stretch::automatic)
59 {
60 res += "\tstretch=";
61 res += to_string(stretch);
62 }
63 if(loop)
64 res += "\tloop=1";
65 res += '\n';
66 }
67 return res;
68}
69
70inline std::vector<clip_file_metadata> decode_clip_metadata(std::string_view data)
71{
72 std::vector<clip_file_metadata> res;
73 while(!data.empty())
74 {
75 auto eol = data.find('\n');
76 std::string_view line = data.substr(0, eol);
77 data = eol == std::string_view::npos ? std::string_view{} : data.substr(eol + 1);
78 if(!line.empty() && line.back() == '\r')
79 line.remove_suffix(1);
80
81 auto tab = line.find('\t');
82 clip_file_metadata m;
83 m.path = std::string{line.substr(0, tab)};
84 if(m.path.empty())
85 continue;
86 while(tab != std::string_view::npos)
87 {
88 line.remove_prefix(tab + 1);
89 tab = line.find('\t');
90 const auto field = line.substr(0, tab);
91 const auto eq = field.find('=');
92 if(eq == std::string_view::npos)
93 continue;
94 const auto key = field.substr(0, eq);
95 const auto value = field.substr(eq + 1);
96 if(key == "stretch")
97 m.stretch = clip_stretch_from_string(value);
98 else if(key == "loop")
99 m.loop = value == "1";
100 }
101 res.push_back(std::move(m));
102 }
103 return res;
104}
105
108inline const clip_file_metadata*
109find_clip_metadata(const std::vector<clip_file_metadata>& meta, std::string_view path)
110{
111 for(const auto& m : meta)
112 if(m.path == path)
113 return &m;
114 auto name = [](std::string_view p) {
115 const auto sep = p.find_last_of("/\\");
116 return sep == std::string_view::npos ? p : p.substr(sep + 1);
117 };
118 const auto file = name(path);
119 for(const auto& m : meta)
120 if(name(m.path) == file)
121 return &m;
122 return nullptr;
123}
124}
Base classes and tools to implement processes and layers.
Definition JSONVisitor.hpp:1115
constexpr std::string_view clip_metadata_mime
Definition ClipMetadata.hpp:19
const clip_file_metadata * find_clip_metadata(const std::vector< clip_file_metadata > &meta, std::string_view path)
Definition ClipMetadata.hpp:109
std::string encode_clip_metadata(const std::vector< std::string > &files, halp::clip_stretch stretch, bool loop=false)
Empty when there is nothing to say: every file is left to the host.
Definition ClipMetadata.hpp:49
Definition ClipMetadata.hpp:22
bool loop
Definition ClipMetadata.hpp:27