Skip to content
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

patternist: add support for accent and slide out #1641

Merged
merged 1 commit into from
Dec 27, 2024
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
24 changes: 22 additions & 2 deletions src/lib/score/graphics/widgets/QGraphicsNoteChooser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,19 @@ QGraphicsNoteChooser::QGraphicsNoteChooser(QGraphicsItem* parent)

void QGraphicsNoteChooser::setValue(int v)
{
m_value = ossia::clamp(v, m_min, m_max);
switch(v)
{
case 255:
m_value = -1;
break;
case 254:
m_value = -2;
break;
default:
m_value = ossia::clamp(v, m_min, m_max);
break;
}

update();
}

Expand Down Expand Up @@ -91,7 +103,15 @@ static QString noteText(int n)
{
static constexpr QStringView lit[12]{u"C", u"C#", u"D", u"D#", u"E", u"F",
u"F#", u"G", u"G#", u"A", u"A#", u"B"};
return QString{"%1%2"}.arg(lit[n % 12]).arg(n / 12 - 1);
switch(n)
{
case -1:
return "AC";
case -2:
return "SL";
default:
return QString{"%1%2"}.arg(lit[n % 12]).arg(n / 12 - 1);
}
}

void QGraphicsNoteChooser::paint(
Expand Down
4 changes: 2 additions & 2 deletions src/lib/score/graphics/widgets/QGraphicsNoteChooser.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class SCORE_LIB_BASE_EXPORT QGraphicsNoteChooser final
W_OBJECT(QGraphicsNoteChooser)
SCORE_GRAPHICS_ITEM_TYPE(120)

static constexpr int m_min = 0;
static constexpr int m_min = -2;
static constexpr int m_max = 127;
static constexpr double m_width = 30;
static constexpr double m_height = 28;
Expand All @@ -28,7 +28,7 @@ class SCORE_LIB_BASE_EXPORT QGraphicsNoteChooser final
bool m_grab{};

public:
QGraphicsNoteChooser(QGraphicsItem* parent);
explicit QGraphicsNoteChooser(QGraphicsItem* parent);

void setValue(int v);
int value() const;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,6 @@ MovePoint::MovePoint(
// another
if(std::abs(m_oldPoint.x() - m_newPoint.x()) < 0.0001)
{
qDebug() << m_oldPoint.x() - m_newPoint.x();
m_newPoint.rx() = m_oldPoint.x();
}

Expand Down
25 changes: 24 additions & 1 deletion src/plugins/score-plugin-midi/Patternist/PatternExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ class pattern_node : public ossia::nonowning_graph_node
{
public:
ossia::midi_outlet out;
ossia::value_outlet accent_out;
ossia::value_outlet slide_out;
Pattern pattern;
ossia::flat_set<uint8_t> in_flight;

Expand All @@ -28,6 +30,8 @@ class pattern_node : public ossia::nonowning_graph_node
{
in_flight.reserve(32);
m_outlets.push_back(&out);
m_outlets.push_back(&accent_out);
m_outlets.push_back(&slide_out);
}

std::string label() const noexcept override { return "pattern_node"; }
Expand Down Expand Up @@ -65,13 +69,32 @@ class pattern_node : public ossia::nonowning_graph_node

for(Lane& lane : pattern.lanes)
{
if(lane.pattern[current])
if(lane.note <= 127 && lane.pattern[current])
{
mess.push_back(libremidi::channel_events::note_on(channel, lane.note, 64));
mess.back().timestamp = date;
in_flight.insert(lane.note);
}
}

for(Lane& lane : pattern.lanes)
{
if(lane.note == 255)
{
if(lane.pattern[current])
accent_out->write_value(1., date);
else
accent_out->write_value(0., date);
}
else if(lane.note == 254)
{
if(lane.pattern[current])
slide_out->write_value(1., date);
else
slide_out->write_value(0., date);
}
}

current = (current + 1) % pattern.length;
}
}
Expand Down
35 changes: 31 additions & 4 deletions src/plugins/score-plugin-midi/Patternist/PatternModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ namespace Patternist
ProcessModel::ProcessModel(
const TimeVal& duration, const Id<Process::ProcessModel>& id, QObject* parent)
: Process::
ProcessModel{duration, id, Metadata<ObjectKey_k, ProcessModel>::get(), parent}
ProcessModel{duration, id, Metadata<ObjectKey_k, ProcessModel>::get(), parent}
, outlet{Process::make_midi_outlet(Id<Process::Port>(0), this)}
, accent{Process::make_value_outlet(Id<Process::Port>(1), this)}
, slide{Process::make_value_outlet(Id<Process::Port>(2), this)}
{
Pattern pattern;
pattern.length = 4;
Expand All @@ -37,7 +39,6 @@ ProcessModel::ProcessModel(
const Id<Process::ProcessModel>& id, QObject* parent)
: Patternist::ProcessModel{duration, id, parent}
{

if(QFile f{customData}; f.open(QIODevice::ReadOnly))
if(auto data = score::mapAsByteArray(f); !data.isEmpty())
if(auto pat = parsePattern(data); pat.lanes.size() > 0)
Expand All @@ -47,6 +48,8 @@ ProcessModel::ProcessModel(
void ProcessModel::init()
{
m_outlets.push_back(outlet.get());
m_outlets.push_back(accent.get());
m_outlets.push_back(slide.get());
}

ProcessModel::~ProcessModel() { }
Expand Down Expand Up @@ -196,7 +199,8 @@ void JSONWriter::write(Patternist::Pattern& proc)
template <>
void DataStreamReader::read(const Patternist::ProcessModel& proc)
{
m_stream << *proc.outlet << proc.m_channel << proc.m_currentPattern << proc.m_patterns;
m_stream << *proc.outlet << *proc.accent << *proc.slide << proc.m_channel
<< proc.m_currentPattern << proc.m_patterns;

insertDelimiter();
}
Expand All @@ -205,7 +209,8 @@ template <>
void DataStreamWriter::write(Patternist::ProcessModel& proc)
{
proc.outlet = Process::load_midi_outlet(*this, &proc);
m_stream >> proc.m_channel >> proc.m_currentPattern >> proc.m_patterns;
m_stream >> proc.m_channel >> *proc.accent >> *proc.slide >> proc.m_currentPattern
>> proc.m_patterns;

checkDelimiter();
}
Expand All @@ -214,6 +219,8 @@ template <>
void JSONReader::read(const Patternist::ProcessModel& proc)
{
obj["Outlet"] = *proc.outlet;
obj["Accent"] = *proc.accent;
obj["Slide"] = *proc.slide;
obj["Channel"] = proc.m_channel;
obj["Pattern"] = proc.m_currentPattern;
obj["Patterns"] = proc.m_patterns;
Expand All @@ -226,6 +233,26 @@ void JSONWriter::write(Patternist::ProcessModel& proc)
JSONWriter writer{obj["Outlet"]};
proc.outlet = Process::load_midi_outlet(writer, &proc);
}

if(auto port = obj.tryGet("Accent"))
{
JSONWriter writer{*port};
proc.accent = Process::load_value_outlet(writer, &proc);
}
else
{
proc.accent = Process::make_value_outlet(Id<Process::Port>(1), &proc);
}

if(auto port = obj.tryGet("Slide"))
{
JSONWriter writer{*port};
proc.slide = Process::load_value_outlet(writer, &proc);
}
else
{
proc.slide = Process::make_value_outlet(Id<Process::Port>(2), &proc);
}
proc.m_channel = obj["Channel"].toInt();
proc.m_currentPattern = obj["Pattern"].toInt();
proc.m_patterns <<= obj["Patterns"];
Expand Down
6 changes: 6 additions & 0 deletions src/plugins/score-plugin-midi/Patternist/PatternModel.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@

#include <verdigris>

namespace Process
{
class ValueOutlet;
}
namespace Patternist
{
struct Lane
Expand Down Expand Up @@ -68,6 +72,8 @@ class SCORE_PLUGIN_MIDI_EXPORT ProcessModel final : public Process::ProcessModel
const std::vector<Pattern>& patterns() const noexcept;

std::unique_ptr<Process::MidiOutlet> outlet;
std::unique_ptr<Process::Outlet> accent;
std::unique_ptr<Process::Outlet> slide;

public:
void channelChanged(int arg_1) W_SIGNAL(channelChanged, arg_1);
Expand Down
11 changes: 11 additions & 0 deletions src/plugins/score-plugin-midi/Patternist/PatternParsing.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,17 @@ Pattern parsePattern(const QByteArray& data) noexcept
Lane lane;
bool ok = false;
lane.note = split[0].toInt(&ok);
if(!ok && split[0] == "AC")
{
lane.note = 255;
ok = true;
}
if(!ok && split[0] == "SL")
{
lane.note = 254;
ok = true;
}

if(ok)
{
p.length = split[1].size();
Expand Down
Loading