Loading...
Searching...
No Matches
plugins/score-plugin-avnd/Crousti/File.hpp
1#pragma once
2#include <Media/AudioDecoder.hpp>
3
4#include <score/document/DocumentContext.hpp>
5#include <score/tools/File.hpp>
6
7#include <ossia/dataflow/exec_state_facade.hpp>
8#include <ossia/dataflow/nodes/media.hpp>
9#include <ossia/network/value/value.hpp>
10
11#include <QByteArray>
12#include <QFile>
13
14#include <avnd/binding/ossia/soundfiles.hpp>
15#include <libremidi/reader.hpp>
16
17namespace oscr
18{
19
20namespace
21{
22[[nodiscard]] static QString
23filenameFromPort(const ossia::value& value, const score::DocumentContext& ctx)
24{
25 if(auto str = value.target<std::string>())
26 return score::locateFilePath(QString::fromStdString(*str).trimmed(), ctx);
27 return {};
28}
29
30// TODO refactor this into a generic explicit soundfile loaded mechanism
31[[nodiscard]] static auto
32loadSoundfile(const ossia::value& value, const score::DocumentContext& ctx, double rate)
33{
34 // Initialize the control with the current soundfile
35 if(auto str = filenameFromPort(value, ctx); !str.isEmpty())
36 {
37 auto dec = Media::AudioDecoder::decode_synchronous(str, rate);
38
39 if(dec.has_value())
40 {
41 auto hdl = std::make_shared<ossia::audio_data>();
42 hdl->data = std::move(dec->second);
43 hdl->path = str.toStdString();
44 hdl->rate = rate;
45 return hdl;
46 }
47 }
48 return ossia::audio_handle{};
49}
50
51using midifile_handle = std::shared_ptr<oscr::midifile_data>;
52[[nodiscard]] inline midifile_handle
53loadMidifile(const ossia::value& value, const score::DocumentContext& ctx)
54{
55 // Initialize the control with the current soundfile
56 if(auto str = filenameFromPort(value, ctx); !str.isEmpty())
57 {
58 QFile f(str);
59 if(!f.open(QIODevice::ReadOnly))
60 return {};
61 auto ptr = f.map(0, f.size());
62
63 auto hdl = std::make_shared<oscr::midifile_data>();
64 if(auto ret = hdl->reader.parse((uint8_t*)ptr, f.size());
65 ret == libremidi::reader::invalid)
66 return {};
67
68 hdl->filename = str.toStdString();
69 return hdl;
70 }
71 return {};
72}
73
74using raw_file_handle = std::shared_ptr<raw_file_data>;
75[[nodiscard]] inline raw_file_handle loadRawfile(
76 const ossia::value& value, const score::DocumentContext& ctx, bool text, bool mmap)
77{
78 // Initialize the control with the current soundfile
79 if(auto filename = filenameFromPort(value, ctx); !filename.isEmpty())
80 {
81 if(!QFile::exists(filename))
82 return {};
83
84 auto hdl = std::make_shared<oscr::raw_file_data>();
85 hdl->file.setFileName(filename);
86 if(!hdl->file.open(QIODevice::ReadOnly))
87 return {};
88
89 if(mmap)
90 {
91 auto map = (char*)hdl->file.map(0, hdl->file.size());
92 hdl->data = QByteArray::fromRawData(map, hdl->file.size());
93 }
94 else
95 {
96 if(text)
97 hdl->file.setTextModeEnabled(true);
98
99 hdl->data = hdl->file.readAll();
100 }
101 hdl->filename = filename.toStdString();
102 return hdl;
103 }
104 return {};
105}
106
107[[nodiscard]] inline auto loadSoundfile(
108 const ossia::value& value, const score::DocumentContext& ctx,
109 const std::shared_ptr<ossia::execution_state>& st)
110{
111 const double rate = ossia::exec_state_facade{st.get()}.sampleRate();
112 return loadSoundfile(value, ctx, rate);
113}
114
115template <typename Field>
116static auto executePortPreprocess(auto& file)
117{
118 using field_file_type = decltype(Field::file);
119 field_file_type ffile;
120 ffile.bytes = decltype(ffile.bytes)(file.data.constData(), file.file.size());
121 ffile.filename = file.filename;
122 return Field::process(ffile);
123}
124
125}
126
127}
Definition Factories.hpp:19
QString locateFilePath(const QString &filename, const score::DocumentContext &ctx) noexcept
Definition File.cpp:57
Definition DocumentContext.hpp:18