diff options
author | Adam Szmigin <smidge@xsco.net> | 2020-08-09 21:49:05 +0100 |
---|---|---|
committer | Adam Szmigin <smidge@xsco.net> | 2020-08-09 21:50:48 +0100 |
commit | 65ebd7b1472db20a890a0d098d82170f2473146b (patch) | |
tree | be7e85e57bb649ba2ad8414fce2953a3da812d55 | |
parent | b0db43da2e3b40c54cd0823fa17305c68389bdb7 (diff) |
Added example Engine Prime application
-rw-r--r-- | README.md | 101 | ||||
-rw-r--r-- | example/README.md | 5 | ||||
-rw-r--r-- | example/engine_prime.cpp | 106 | ||||
-rw-r--r-- | example/meson.build | 5 | ||||
-rw-r--r-- | meson.build | 1 |
5 files changed, 140 insertions, 78 deletions
@@ -1,7 +1,8 @@ Overview ======== -`libdjinterop` is a C++ library that allows access to database formats used to store information about DJ record libraries. +`libdjinterop` is a C++ library that allows access to database formats used to +store information about DJ record libraries. This library currently supports: @@ -10,7 +11,8 @@ This library currently supports: State of Support ================ -The library is currently in an early alpha stage, and not all features are implemented yet. It currently supports only the Engine Library format. +The library is currently in an early beta stage, and not all features are +implemented yet. It currently supports only the Engine Library format. What is supported: @@ -35,73 +37,9 @@ What is not supported (yet): How Do I Use It? ================ -The library is not ready for prime-time yet, but if you are willing to read the source code, you can get an example application up and running using code similar to the following: - -```c++ -#include <djinterop/djinterop.hpp> - -namespace el = djinterop::enginelibrary; - -int main(int argc, char **argv) -{ - auto db = el::make_database("Engine Library"); - - auto tr = db.create_track("../01 - Some Artist - Some Song.mp3"); - - tr.set_track_number(1); - tr.set_bpm(120); - tr.set_year(1970); - tr.set_title("Some Song"s); - tr.set_artist("Some Artist"s); - tr.set_publisher(std::nullopt); // std::nullopt indicates missing metadata - tr.set_key(djinterop::musical_key::a_minor); - tr.set_bitrate(320); - tr.set_average_loudness(0.5); // loudness range (0, 1] - int64_t sample_count = 16140600; - tr.set_sampling({44100, // sample rate - sample_count}); // sample count - std::vector<djinterop::beatgrid_marker> beatgrid{ - {-4, -83316.78}, // 1st marker - {812, 17470734.439}}; // 2nd marker - tr.set_default_beatgrid(beatgrid); // as analyzed - tr.set_adjusted_beatgrid(beatgrid); // manually adjusted - - // The main cue concerns the cue button - tr.set_default_main_cue(2732); // as analyzed - tr.set_adjusted_main_cue(2732); // manually adjusted - - // There are always 8 hot cues, whereby each can optionally be set - std::array<std::optional<djinterop::hot_cue>, 8> cues; - cues[0] = - djinterop::hot_cue{"Cue 1", 1377924.5, // position in number of samples - el::standard_pad_colors::pad_1}; - tr.set_hot_cues(cues); - - // Setting a single hot cue can also be done like this - tr.set_hot_cue_at(3, {"Cue 4", 5508265.96, el::standard_pad_colors::pad_4}); - - // The loop API works like the hot cue API - tr.set_loop_at( - 0, {"Loop 1", 1144.012, 345339.134, el::standard_pad_colors::pad_1}); - - // Set high-resolution waveform - int64_t spe = tr.required_waveform_samples_per_entry(); - int64_t waveform_size = (sample_count + spe - 1) / spe; // Ceiling division - std::vector<djinterop::waveform_entry> waveform; - waveform.reserve(waveform_size); - for (int64_t i = 0; i < waveform_size; ++i) - { - waveform.push_back( // VALUE and OPACITY for each band (low/mid/high) - {{0, 255}, // low - {42, 255}, // mid - {255, 255}}); // high - } - tr.set_waveform(std::move(waveform)); - - auto cr = db.create_crate("My Example Crate"); - cr.add_track(tr); -} -``` +The library is not ready for prime-time yet, but if you are willing to read +source code, an example application can be found in the [example](example) +directory. How Do I Build It? ============================ @@ -110,9 +48,11 @@ How Do I Build It? * [SQLite3](https://sqlite.org) * [zlib](http://zlib.net) -* [Boost](https://boost.org) (only required for unit tests, not the main library) +* [Boost](https://boost.org) (only needed for unit tests, not the main library) -`libdjinterop` uses the [Meson build system](https://mesonbuild.com). Assuming you have the above dependencies in place, and the build tools, you can issue the following commands: +`libdjinterop` uses the [Meson build system](https://mesonbuild.com). Assuming +you have the above dependencies in place, and the build tools, you can issue +the following commands: ``` $ meson build/ @@ -123,27 +63,30 @@ $ ninja -C build/ test (optional, run unit tests) ## With Nix -When [Nix](http://nixos.org/nix) is installed, then you don't need to manually install any -dependencies. -`libdjinterop` can then simply be built with: +When [Nix](http://nixos.org/nix) is installed, then you don't need to manually +install any dependencies. `libdjinterop` can then simply be built with: ``` $ nix build ``` -In order to drop into a development environment with dependencies available, execute: +In order to drop into a development environment with dependencies available, +execute: ``` $ nix-shell ``` You can then build `libdjinterop` by using Meson as described above. -This is advantageous when developing since it only recompiles sources that it needs to. + +This is advantageous when developing since it only recompiles sources that it +needs to. Thanks To ========= -`libdjinterop` makes use of a number of software libraries, and is extremely grateful for: +`libdjinterop` makes use of a number of software libraries, and is extremely +grateful for: * [Boost](https://boost.org) * [ClangFormat](https://clang.llvm.org/docs/ClangFormat.html) @@ -151,4 +94,6 @@ Thanks To * [SQLite Modern C++ Wrapper](https://github.com/SqliteModernCpp/sqlite_modern_cpp) * [zlib](http://zlib.net) -Interfacing with the Engine Library database format was made a lot easier with the help of MixMasterG from ATGR, who is the author of the [Denon Conversion Utility](https://sellfy.com/atgr_production_team). +Interfacing with the Engine Library database format was made a lot easier with +the help of MixMasterG from ATGR, who is the author of the +[Denon Conversion Utility](https://sellfy.com/atgr_production_team). diff --git a/example/README.md b/example/README.md new file mode 100644 index 0000000..fa0908a --- /dev/null +++ b/example/README.md @@ -0,0 +1,5 @@ +Overview +======== + +This directory contains small example applications that illustrate the use +of `libdjinterop`.
\ No newline at end of file diff --git a/example/engine_prime.cpp b/example/engine_prime.cpp new file mode 100644 index 0000000..d7b8520 --- /dev/null +++ b/example/engine_prime.cpp @@ -0,0 +1,106 @@ +/* + This file is part of libdjinterop. + + libdjinterop 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 3 of the License, or + (at your option) any later version. + + libdjinterop 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 libdjinterop. If not, see <http://www.gnu.org/licenses/>. + */ + +#include <iostream> +#include <optional> +#include <string> +#include <vector> + +#include <djinterop/djinterop.hpp> + +namespace el = djinterop::enginelibrary; + +int main(int argc, char** argv) +{ + using namespace std::string_literals; + + auto dir = "Engine Library"s; + bool created; + auto db = el::create_or_load_database(dir, el::version_latest, created); + std::cout << (created ? "Created " : "Loaded ") << "database in directory " + << dir << std::endl; + + for (auto& cr : db.crates()) + { + std::cout << "Removing prior crate " << cr.name() << std::endl; + db.remove_crate(cr); + } + + for (auto& tr : db.tracks()) + { + std::cout << "Removing prior track " << tr.filename() << std::endl; + db.remove_track(tr); + } + + auto tr = db.create_track("../01 - Some Artist - Some Song.mp3"); + std::cout << "Added track " << tr.filename() << std::endl; + + tr.set_track_number(1); + tr.set_bpm(120); + tr.set_year(1970); + tr.set_title("Some Song"s); + tr.set_artist("Some Artist"s); + tr.set_publisher(std::nullopt); // std::nullopt indicates missing metadata + tr.set_key(djinterop::musical_key::a_minor); + tr.set_bitrate(320); + tr.set_average_loudness(0.5); // loudness range (0, 1] + int64_t sample_count = 16140600; + tr.set_sampling( + {44100, // sample rate + sample_count}); // sample count + std::vector<djinterop::beatgrid_marker> beatgrid{ + {-4, -83316.78}, // 1st marker + {812, 17470734.439}}; // 2nd marker + tr.set_default_beatgrid(beatgrid); // as analyzed + tr.set_adjusted_beatgrid(beatgrid); // manually adjusted + + // The main cue concerns the cue button + tr.set_default_main_cue(2732); // as analyzed + tr.set_adjusted_main_cue(2732); // manually adjusted + + // There are always 8 hot cues, whereby each can optionally be set + std::array<std::optional<djinterop::hot_cue>, 8> cues; + cues[0] = djinterop::hot_cue{ + "Cue 1", 1377924.5, // position in number of samples + el::standard_pad_colors::pad_1}; + tr.set_hot_cues(cues); + + // Setting a single hot cue can also be done like this + tr.set_hot_cue_at(3, {"Cue 4", 5508265.96, el::standard_pad_colors::pad_4}); + + // The loop API works like the hot cue API + tr.set_loop_at( + 0, {"Loop 1", 1144.012, 345339.134, el::standard_pad_colors::pad_1}); + + // Set high-resolution waveform + int64_t spe = tr.required_waveform_samples_per_entry(); + int64_t waveform_size = (sample_count + spe - 1) / spe; // Ceiling division + std::vector<djinterop::waveform_entry> waveform; + waveform.reserve(waveform_size); + for (int64_t i = 0; i < waveform_size; ++i) + { + waveform.push_back( // VALUE and OPACITY for each band (low/mid/high) + {{0, 255}, // low + {42, 255}, // mid + {255, 255}}); // high + } + tr.set_waveform(std::move(waveform)); + + auto cr = db.create_root_crate("My Example Crate"); + cr.add_track(tr); + std::cout << "Added track to crate " << cr.name() << std::endl; +} diff --git a/example/meson.build b/example/meson.build new file mode 100644 index 0000000..d2d4faa --- /dev/null +++ b/example/meson.build @@ -0,0 +1,5 @@ +executable( + 'engine_prime', + 'engine_prime.cpp', + include_directories : [inc], + link_with : djinterop_lib) diff --git a/meson.build b/meson.build index 065833f..95cb216 100644 --- a/meson.build +++ b/meson.build @@ -24,6 +24,7 @@ subdir('include') subdir('src') subdir('testdata') subdir('test') +subdir('example') # TODO - add Doxygen support |