Skip to content
Open
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
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ set(SRCS
src/Options.cpp
src/tool-autobeam.cpp
src/tool-autostem.cpp
src/tool-beat.cpp
src/tool-binroll.cpp
src/tool-chord.cpp
src/tool-cint.cpp
Expand Down Expand Up @@ -144,6 +145,7 @@ set(HDRS
include/pugixml/pugixml.hpp
include/tool-autobeam.h
include/tool-autostem.h
include/tool-beat.h
include/tool-binroll.h
include/tool-chord.h
include/tool-cint.h
Expand Down
13 changes: 11 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1015,6 +1015,15 @@ tool-autostem.o: tool-autostem.cpp tool-autostem.h \
HumHash.h HumParamSet.h HumdrumFileStream.h \
HumRegex.h Convert.h

tool-beat.o: tool-beat.cpp tool-beat.h HumTool.h \
Options.h HumdrumFileSet.h HumdrumFile.h \
HumdrumFileContent.h HumdrumFileStructure.h \
HumdrumFileBase.h HumSignifiers.h \
HumSignifier.h HumdrumLine.h HumdrumToken.h \
HumNum.h HumAddress.h HumHash.h \
HumParamSet.h HumdrumFileStream.h NoteGrid.h \
NoteCell.h Convert.h HumRegex.h

tool-binroll.o: tool-binroll.cpp tool-binroll.h \
HumTool.h Options.h HumdrumFileSet.h \
HumdrumFile.h HumdrumFileContent.h \
Expand Down Expand Up @@ -1172,8 +1181,8 @@ tool-filter.o: tool-filter.cpp tool-filter.h \
HumdrumToken.h HumNum.h HumAddress.h \
HumHash.h HumParamSet.h HumdrumFileStream.h \
tool-addic.h tool-addkey.h tool-addlabels.h \
tool-addtempo.h tool-autoaccid.h \
tool-autobeam.h tool-autostem.h tool-binroll.h \
tool-addtempo.h tool-autoaccid.h tool-autobeam.h \
tool-autostem.h tool-beat.h tool-binroll.h \
tool-chantize.h tool-chooser.h tool-chord.h \
tool-cint.h NoteGrid.h NoteCell.h \
HumRegex.h tool-cmr.h tool-colorgroups.h \
Expand Down
14 changes: 14 additions & 0 deletions cli/beatx.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
//
// Programmer: Wolfgang Drescher <drescher.wolfgang@gmail.com>
// Creation Date: Fri Dez 13 08:08:00 UTC 2024
// Filename: cli/beatx.cpp
// URL: https://github.com/craigsapp/humlib/blob/master/cli/beatx.cpp
// Syntax: C++11
// vim: ts=3 noexpandtab nowrap
//
// Description: Analyzes **kern data and generates a rhythmic analysis
//

#include "humlib.h"

STREAM_INTERFACE(Tool_beat)
58 changes: 58 additions & 0 deletions include/tool-beat.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
//
// Programmer: Wolfgang Drescher <drescher.wolfgang@gmail.com>
// Creation Date: Fri Dez 13 08:08:00 UTC 2024
// Filename: tool-beat.h
// URL: https://github.com/craigsapp/humlib/blob/master/include/tool-beat.h
// Syntax: C++11; humlib
// vim: syntax=cpp ts=3 noexpandtab nowrap
//
// Description: Interface for beat tool
//

#ifndef _TOOL_BEAT_H
#define _TOOL_BEAT_H

#include "HumTool.h"
#include "HumdrumFile.h"

using namespace std;

namespace hum {

// START_MERGE

class Tool_beat : public HumTool {

public:
Tool_beat (void);
~Tool_beat() {};

bool run (HumdrumFileSet& infiles);
bool run (HumdrumFile& infile);
bool run (const string& indata, ostream& out);
bool run (HumdrumFile& infile, ostream& out);

protected:
void initialize (void);
void processFile (HumdrumFile& infile);
vector<string> getTrackData(HumdrumFile& infile, int track);

private:
bool m_floatQ; // used with -f option
int m_digits = 0; // used with -D option
bool m_commaQ; // used with -c option
bool m_durationQ; // used with -d option
bool m_restQ; // used with -r option
bool m_tiedQ; // used with -t option
bool m_fullQ; // used with --full option
string m_beatsize; // used with -u option
string m_spineTracks = ""; // used with -s option
string m_kernTracks = ""; // used with -k option
vector<bool> m_selectedKernSpines; // used with -k and -s option
};

// END_MERGE

} // end namespace hum

#endif /* _TOOL_BEAT_H */
234 changes: 233 additions & 1 deletion min/humlib.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
//
// Programmer: Craig Stuart Sapp <craig@ccrma.stanford.edu>
// Creation Date: Sat Aug 8 12:24:49 PDT 2015
// Last Modified: Fri Nov 22 09:29:17 AM PST 2024
// Last Modified: Di 17 Dez 2024 10:43:30 CET
// Filename: min/humlib.cpp
// URL: https://github.com/craigsapp/humlib/blob/master/min/humlib.cpp
// Syntax: C++11
Expand Down Expand Up @@ -58771,6 +58771,233 @@ void Tool_autostem::countBeamStuff(const string& token, int& start, int& stop,



//////////////////////////////
//
// Tool_beat::Tool_beat -- Set the recognized options for the tool.
//

Tool_beat::Tool_beat(void) {
define("s|spine-tracks|spine|spines|track|tracks=s", "process only the specified spines");
define("k|kern-tracks=s", "process only the specified kern spines");
define("d|duration|dur=b", "display duration for each slice");
define("u|beatsize|rhythm=s:4", "beatsize (recip rhythmic value); default=4");
define("f|float=b", "floating-point beat values instead of rational numbers");
define("D|digits=i:0", "number of digits after decimal point");
define("c|comma=b", "display decimal points as commas");
define("t|tied|ties=b", "show beats of tied notes");
define("r|rest=b", "show beats of rests");
define("full=b", "show numbers on each slice");
}



//////////////////////////////
//
// Tool_beat::run -- Do the main work of the tool.
//

bool Tool_beat::run(HumdrumFileSet &infiles) {
bool status = true;
for (int i = 0; i < infiles.getCount(); i++) {
status &= run(infiles[i]);
}
return status;
}

bool Tool_beat::run(const string &indata, ostream &out) {
HumdrumFile infile(indata);
bool status = run(infile);
if (hasAnyText()) {
getAllText(out);
} else {
out << infile;
}
return status;
}

bool Tool_beat::run(HumdrumFile &infile, ostream &out) {
bool status = run(infile);
if (hasAnyText()) {
getAllText(out);
} else {
out << infile;
}
return status;
}

bool Tool_beat::run(HumdrumFile &infile) {
initialize();
processFile(infile);
infile.createLinesFromTokens();
return true;
}



//////////////////////////////
//
// Tool_beat::initialize --
//

void Tool_beat::initialize(void) {
m_floatQ = getBoolean("float");
m_digits = getInteger("digits");
m_commaQ = getBoolean("comma");
m_durationQ = getBoolean("duration");
m_beatsize = getString("beatsize");
m_restQ = getBoolean("rest");
m_tiedQ = getBoolean("tied");
m_fullQ = getBoolean("full");

if (m_digits < 0) {
m_digits = 0;
}
if (m_digits > 15) {
m_digits = 15;
}

if (m_fullQ) {

}

if (getBoolean("spine-tracks")) {
m_spineTracks = getString("spine-tracks");
} else if (getBoolean("kern-tracks")) {
m_kernTracks = getString("kern-tracks");
}
}



//////////////////////////////
//
// Tool_beat::processFile --
//

void Tool_beat::processFile(HumdrumFile& infile) {

vector<HTp> kernspines = infile.getKernLikeSpineStartList();

int maxTrack = infile.getMaxTrack();

m_selectedKernSpines.resize(maxTrack + 1); // +1 is needed since track=0 is not used

// By default, process all tracks:
fill(m_selectedKernSpines.begin(), m_selectedKernSpines.end(), true);
// Otherwise, select which **kern track, or spine tracks to process selectively:

// Calculate which input spines to process based on -s or -k option:
if (!m_kernTracks.empty()) {
vector<int> ktracks = Convert::extractIntegerList(m_kernTracks, maxTrack);
fill(m_selectedKernSpines.begin(), m_selectedKernSpines.end(), false);
for (int i=0; i<(int)ktracks.size(); i++) {
int index = ktracks[i] - 1;
if ((index < 0) || (index >= (int)kernspines.size())) {
continue;
}
int track = kernspines.at(ktracks[i] - 1)->getTrack();
m_selectedKernSpines.at(track) = true;
}
} else if (!m_spineTracks.empty()) {
infile.makeBooleanTrackList(m_selectedKernSpines, m_spineTracks);
}

string suffix = m_durationQ ? "dur" : "absb";
string exinterp = "**cdata-" + suffix;

for (int i = 0; i < kernspines.size(); i++) {
if (m_selectedKernSpines[i]) {
vector<string> trackData = getTrackData(infile, kernspines[i]->getTrack());
infile.insertDataSpineAfter(kernspines[i]->getTrack(), trackData, ".", exinterp);
}
}

// Enables usage in verovio (`!!!filter: beat`)
m_humdrum_text << infile;
}



//////////////////////////////
//
// Tool_beat::getTrackData -- Create beat spine data
//

vector<string> Tool_beat::getTrackData(HumdrumFile& infile, int track) {
vector<string> trackData;
trackData.resize(infile.getLineCount());

for (int i = 0; i < infile.getLineCount(); i++) {
HumNum num;
HLp line = infile.getLine(i);
if (!line->hasSpines()) continue;
HTp token = nullptr;

// Get token for current track
for (int j = 0; j < infile[i].getFieldCount(); j++) {
if (track == infile.token(i, j)->getTrack()) {
// TODO handle spine splits
token = infile.token(i, j);
break;
}
}

if (token == nullptr) continue;

// If -d isset use token or line duration (depending on --full) as num
if (m_durationQ) {
num = m_fullQ ? line->getDuration() : token->getDurationToNoteEnd();
} else {
// Use duration from start as num
num = token->getDurationFromStart();
}

// Hide output if not useful or not configured in options
if (num == -1) continue;
if (token->isRest() && !m_restQ && !m_fullQ) continue;
if (token->isNull() && !m_fullQ) continue;
if (token->isSustainedNote() && !m_tiedQ && !m_fullQ) continue;

// Use beatsize as basis for calculations
HumNum beatsize = Convert::recipToDuration(m_beatsize);
if (beatsize == 0) continue;
num /= beatsize;

string str = "";
if (m_floatQ) {
// Print floating-point beat values instead of rational numbers
stringstream beatStream;
if (m_digits) {
beatStream << std::setprecision(m_digits + 1) << num.getFloat();
} else {
beatStream << num.getFloat();
}
str = beatStream.str();
if (m_commaQ) {
// Repalce . with , when using -f
HumRegex hre;
hre.replaceDestructive(str, ",", "\\.");
}
} else {
// Print two part HumNum as default option
stringstream beatStream;
num.printTwoPart(beatStream);
str = beatStream.str();
}

if (token->isRest()) {
// Add "r" suffix for rests
str = str + "r";
}

trackData[i] = str;
}

return trackData;
}




/////////////////////////////////
//
Expand Down Expand Up @@ -87388,6 +87615,11 @@ bool Tool_filter::run(HumdrumFileSet& infiles) {

// filters with aliases:

} else if (commands[i].first == "beat") { // humlib version of Humdrum Toolkit beat tool
RUNTOOL(beat, infile, commands[i].second, status);
} else if (commands[i].first == "beatx") { // humlib cli name
RUNTOOL(beat, infile, commands[i].second, status);

} else if (commands[i].first == "colortriads") {
RUNTOOL(colortriads, infile, commands[i].second, status);
} else if (commands[i].first == "colourtriads") {
Expand Down
Loading