Skip to content

Commit

Permalink
Add note2root() and note2octave()
Browse files Browse the repository at this point in the history
  • Loading branch information
xaviliz committed May 27, 2024
1 parent 3340cc9 commit c10dc6b
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/essentia/essentiamath.h
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,15 @@ inline std::string midi2note(int midiNoteNumber) {
return closest_note;
}

inline std::string note2root(std::string note) {
return note.substr(0, note.size()-1);
}

inline int note2octave(std::string note) {
char octaveChar = note.back();
return octaveChar - '0';
}

inline Real midi2hz(int midiNoteNumber, Real tuningFrequency) {
return tuningFrequency * powf(2, (midiNoteNumber - 69) / 12.0);
}
Expand Down
7 changes: 7 additions & 0 deletions src/python/essentia/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,12 @@ def hz2cents(arg1, arg2):
def midi2note(arg):
return _essentia.midi2note( _c.convertData(arg, _c.Edt.INTEGER) )

def note2root(arg):
return _essentia.note2root( _c.convertData(arg, _c.Edt.STRING) )

def note2octave(arg):
return _essentia.note2octave( _c.convertData(arg, _c.Edt.STRING) )

def equivalentKey(arg):
return _essentia.equivalentKey( _c.convertData(arg, _c.Edt.STRING) )

Expand All @@ -107,6 +113,7 @@ def derivative(array):
'mel2hz', 'hz2mel',
'midi2hz', 'hz2midi',
'cents2hz', 'hz2cents',
'note2root', 'note2octave',
'midi2note',
'postProcessTicks',
'normalize', 'derivative',
Expand Down
27 changes: 27 additions & 0 deletions src/python/globalfuncs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -457,6 +457,31 @@ midiToNote(PyObject* notUsed, PyObject* arg) {
return PyString_FromString( c_note );
}

static PyObject*
noteToRoot(PyObject* notUsed, PyObject* arg) {

if (!PyString_Check(arg)) {
PyErr_SetString(PyExc_TypeError, (char*)"expecting arguments (string note)");
return NULL;
}

std::string root = note2root( PyString_AS_STRING(arg) );
const char *c_root = root.c_str();
return PyString_FromString( c_root );
}

static PyObject*
noteToOctave(PyObject* notUsed, PyObject* arg) {

if (!PyString_Check(arg)) {
PyErr_SetString(PyExc_TypeError, (char*)"expecting arguments (string note)");
return NULL;
}

int octave = note2octave( PyString_AS_STRING(arg) );
return PyLong_FromLong( int(octave) );
}

static PyObject*
getEquivalentKey(PyObject* notUsed, PyObject* arg) {
if (!PyString_Check(arg)) {
Expand Down Expand Up @@ -1073,6 +1098,8 @@ static PyMethodDef Essentia__Methods[] = {
{ "hz2cents", hzToCents, METH_VARARGS, "Returns the cents distance between two frequencies in Hz" },
{ "cents2hz", centsToHz, METH_VARARGS, "Returns the frequency from a frequency in Hz and cents distance" },
{ "midi2note", midiToNote, METH_O, "Converts a midi note number to note applying the international pitch standard (A4=440Hz)" },
{ "note2root", noteToRoot, METH_O, "Returns the root of a note" },
{ "note2octave", noteToOctave, METH_O, "Returns the octave of a note" },
{ "lin2db", linToDb, METH_O, "Converts a linear measure of power to a measure in dB" },
{ "db2lin", dbToLin, METH_O, "Converts a dB measure of power to a linear measure" },
{ "db2pow", dbToPow, METH_O, "Converts a dB measure of power to a linear measure" },
Expand Down
10 changes: 10 additions & 0 deletions test/src/unittests/base/test_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,16 @@ def testMidiToNote(self):
expected_note = "A4"
self.assertEqual(expected_note, midi2note(midi))

def testNoteToRoot(self):
note = "A4"
expected_root = note[0]
self.assertEqual(expected_root, note2root(note))

def testNoteToOctave(self):
note = "A4"
expected_octave = int(note[1])
self.assertEqual(expected_octave, note2octave(note))


suite = allTests(TestUtils)

Expand Down

0 comments on commit c10dc6b

Please sign in to comment.