Skip to content

Instantly share code, notes, and snippets.

@anytizer
Last active December 26, 2025 03:47
Show Gist options
  • Select an option

  • Save anytizer/fe0067958b068091e28f1ff4a111fa3b to your computer and use it in GitHub Desktop.

Select an option

Save anytizer/fe0067958b068091e28f1ff4a111fa3b to your computer and use it in GitHub Desktop.
Various patches for LMMS like randomize() patterns, colors, etc.
// work in progress | help required
void PatternEditor::randomizePatterns()
{
TrackContainer::TrackList tl = model()->tracks();
// @todo Skip counting unsunpported tracks
int tracks = tl.size();
if(tracks>24)
{
QMessageBox warning;
warning.setText("Too many instruments in the track!");
warning.setWindowTitle("Possible slow down!");
warning.setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel);
warning.setDefaultButton(QMessageBox::Cancel);
if(warning.exec() != QMessageBox::Ok)
{
return;
}
}
QApplication::setOverrideCursor(Qt::WaitCursor);
QCoreApplication::processEvents();
QList<Track::Type> allowed = {
Track::Type::Instrument,
Track::Type::Pattern,
};
std::random_device rd;
std::seed_seq ss{rd(), rd(), rd(), rd(), rd(), rd(), rd(), rd()};
std::mt19937 generator(ss);
std::uniform_int_distribution<int> dist1(0, 10);
std::uniform_int_distribution<int> dist2(60, 75);
for(int counter=0; counter<tracks; ++counter)
{
Track* track = tl[counter];
// to skip automations or unsupported tracks
if(!allowed.contains(track->type())) continue;
MidiClip* clip = static_cast<MidiClip*>(track->getClip(m_ps->currentPattern()));
clip->clearNotes();
int steps = (clip->endPosition() - clip->startPosition())/DefaultBeatsPerBar;
//qDebug() << "End Position and Steps: " << clip->endPosition() << steps;
for(int s = 0; s<steps; ++s)
{
int length = DefaultBeatsPerBar;
int pos = s*DefaultBeatsPerBar;
int key = 69; // dist2(generator); // 69: A4?
// 0 - 100; with more of 0% volumes
int volume = dist1(generator)*10;
if(volume>80) volume = 100;
else volume = 0;
if(volume <=0) continue; // empty cell
int panning = 0;
std::shared_ptr<DetuningHelper> detuning = 0;
Note note = Note(length, pos, key, volume, panning, detuning);
note.setType(Note::Type::Step);
clip->addNote(note);
}
}
QApplication::restoreOverrideCursor();
}
// change track color
QColor buffer = ColorChooser::getPalette(ColorChooser::Palette::Track)[rand() % 48];
track->setColor(buffer);
// enumerate pattern editor tracks
void PatternEditor::renumerateTracks()
{
QRegularExpression regex("^#[0-9\\:\\-\\_\\s]*");
TrackContainer::TrackList tl = model()->tracks();
int tracks = tl.size();
for(int i=0; i<tracks; ++i)
{
Track* track = tl[i];
// throw old renumeration signature
QString oldName = QString(track->name()).replace(regex, "");
// apply new renumeration, zero-padded
int width = QString::number(std::abs(tracks)).length();
QString enumeration = QString("%1").arg(i+1, width, 10, QChar('0'));
track->setName(QString("#%1 %2").arg(enumeration).arg(oldName));
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment