lmms icon indicating copy to clipboard operation
lmms copied to clipboard

Custom Piano Labels

Open anytizer opened this issue 4 years ago • 11 comments

Representation↓ Keys → C C# D D# E F F# G G# A A# B
English C C# D D# E F F# G G# A A# B
Best Alternative Sa Sa' Re Re' Ga Ma Ma' Pa Pa' Dha Dha' Ni
Roman Short Form S S' R R' G M M' P P' D D' N
North Indian सा सा' रे रे' म' प' ध' नि
South Indian सा सा' री री' गा म' प' ध' नि
German C C' D D' E F F# G G# A A# H
Western Do Do' Re Re' Mi Fa Fa' So So' La La' Ti

It would be fantastic if one can change the piano labels to custom labels as used in many other practices. The table above shows some basic replacements (what to replace with). The table may not be exact at the moment.

image

Many authors (tutors in particular) use their notes/labels for comfort. But while it comes to data-entry the existing notes in LMMS; it is confusing to see English Labels only. It would help a beginner do the data entry so easily, if the custom labels were possible.

Spreadsheet File attached: custom-labels.ods

Edit: Found a detailed Wikipedia Article: Key signature names and translations

anytizer avatar Sep 16 '21 15:09 anytizer

A couple followup questions: What about sharps and flats? Would the octave number need to be changed as well? I'm assuming yes.

Veratil avatar Sep 16 '21 17:09 Veratil

Sharp, Flats and Octave numbers representation should remain unchanged for now (which is still fine).

In some cases:

  • C4 to B4 can be written without numbers. eg. D

  • C5 - B5 can have a dot on the top side ( * ) eg: D*

  • C3 - B3 can have an underscore or a lower dot in the front, if possible ( . ) eg, .D Hence, .D, D, D* will represent keys from three different octaves:

  • mandhra saptak: lower octave ( . )

  • madhya saptak: mid octave ( )

  • taar saptak.: higher octave ( * )

When necessary to use note from another octave, a double symbol may be used.

  • eg. D** for D6.
  • eg. ..D for D2.

An example of notations is in the description of this video.

Update: Adding a dot (.) in the front of the name would be difficult. So, appending a dot would do the same thing. Eg. D.. instead of ..D.

anytizer avatar Sep 16 '21 19:09 anytizer

Just as an idea for implementation, this could (should?) be integrated to the new tuning system. Simply save an identifier for each scale degree along with its ratio / interval. Just as getFrequency(key) returns the pitch based on given scale degree, getLabel(key) could return whatever string the user set for the scale degree (probably combined with the octave number). Changing the set of labels would be then as simple as switching between scales (or overwriting the default scale). Not to mention that if the user needs Indian labels for example, there is a good chance they may want to use an Indian scale / tuning system. So this should be a natural fit for such functionality.

One problem is that the Scala tuning format does not support this. To work around it, I would suggest adding another "LMMS extension" to the format, similar to the one that is used in our keymap files. I think I used a double comment character (;;) to identify a line that contains name of the keymap (since name is not present in the original Scala keymap format). Scala and other software would see it as an ordinary comment, so the format stays 100 % compatible with the original.

Similarly, a "special comment" added after a cent or fraction value in the .scl file could define a label for that scale degree. Unfortunately, ZynAddSubFX (and possibly other SW) is broken in that regard: the Scala specification says that everything that appears on the line after a cent or fraction value (i.e. comments) should be ignored, but Zyn will fail to correctly load a file with such comments. Alternatively, the optional "special comment" could be expected on the next line, after the scale degree. That would be not as nice, but probably more compatible with broken software.

he29-net avatar Sep 16 '21 19:09 he29-net

I definitely agree that this should be mappable if added. My honest opinion is that adding alternative note labels is a bit like putting training wheels on training wheels, but if we're doing it then it shouldn't be hard coded.

Also, if we're bundling the labels proposed above then Do Re Mi Fa So La Ti Do and CDEFGAH should be included as well.

Spekular avatar Sep 16 '21 21:09 Spekular

That's true about mapping, so that we could add any kind of notation practice. (PS: @Spekular I updated 2 columns in the primary comment for reference).

Currently, there should be very little change to the code (not wanting to introduce any new bugs due to this change). So, we should pick an easiest and minimal way for mapping.

Also, does LMMS use .sqlite somewhere to read/write configs?

anytizer avatar Sep 16 '21 21:09 anytizer

Also, does LMMS use .sqlite somewhere to read/write configs?

No, the save format is XML.

Veratil avatar Sep 16 '21 22:09 Veratil

Not sure if the below xml helps. Also, it needs to work with the Unicode characters as well.

<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
<scales>
	<scale name="Indian Classical - Romanized">
		<label name="C" notation="Sa">
		<label name="D" notation="Re">
		<label name="E" notation="Ga">
		<label name="F" notation="Ma">
		<label name="G" notation="Pa">
		<label name="A" notation="Dha">
		<label name="B" notation="Ni">
	</scale>
	<scale name="Indian Classical - Unicode">
		<label name="C" notation="सा">
		<label name="D" notation="रे">
		<label name="E" notation="ग">
		<label name="F" notation="म">
		<label name="G" notation="प">
		<label name="A" notation="ध">
		<label name="B" notation="नि">
	</scale>
	<scale name="Solfège - Western">
		<label name="C" notation="Do">
		<label name="D" notation="Re">
		<label name="E" notation="Mi">
		<label name="F" notation="Fa">
		<label name="G" notation="So">
		<label name="A" notation="La">
		<label name="B" notation="Ti">
	</scale>
	<scale name="German">
		<label name="C" notation="C">
		<label name="D" notation="D">
		<label name="E" notation="E">
		<label name="F" notation="F">
		<label name="G" notation="G">
		<label name="A" notation="A">
		<label name="B" notation="H">
	</scale>
	<scale name="English">
		<label name="C" notation="C">
		<label name="D" notation="D">
		<label name="E" notation="E">
		<label name="F" notation="F">
		<label name="G" notation="G">
		<label name="A" notation="A">
		<label name="B" notation="B">
	</scale>
</scales>

There are 2 ways to deal with:

  • Put the xml in /configs/scales/*.xml
  • Or, make a single file appending <scale> block for each config.

It should be ok to repeat <label name="..." in each xml, because this is what can be used to return the new name.

anytizer avatar Sep 16 '21 22:09 anytizer

I believe there is something called drum-mapping, which some DAWs support. This enhancement request could help map drums too.

Monospace-V avatar Sep 17 '21 05:09 Monospace-V

I believe there is something called drum-mapping, which some DAWs support. This enhancement request could help map drums too.

Related: #5357

PhysSong avatar Jan 03 '22 08:01 PhysSong

External solution: I created a temporary solution: swar-converter application that can generate .xpt XML files. These files can later be imported in LMMS piano editor. It actually converts SARGAM Notes into English Scales and meanwhile, produces an .xpt file.

But it is still NOT the solution to custom labels. It rather works in a reverse way - by importing the xpt files, and skipping the need for the names of the piano keys.

Notes: Source code is in C# using Visual Studio. Compilation of the software gives you a Windows Binary file. Rest of the details are in the application itself. Just linked in here, if it helps.

anytizer avatar Feb 07 '22 02:02 anytizer

One of the well formatted notations for reference is here that uses few higher and lower octave notes. Also, English scales are available in the same folder.

anytizer avatar Aug 05 '22 19:08 anytizer

Basic process is a 3 step change in PianoRoll.cpp file.

Step 1:

Obtain your own key/note names somewhere around line 130.

static std::array<QString, 12> s_noteStrings {"S", "r", "R", "g", "G", "m", "M", "P", "d", "D", "n", "N"};

These values may be read from translation or config files.

Step 2:

Add a parameter to control the prefix and suffixes for octave number. Replace the function as:

static QString getNoteString(int key, bool showfixes=false)
{
	QString prefix = "";
	QString suffix = "";
	
	int octave = static_cast<int>(FirstOctave + key / KeysPerOctave);
	
	if(showfixes==true)
	{
		if(octave<4) {for(int l=3; l>=octave; --l){prefix += "."; }}
		if(octave>4) {for(int h=5; h<=octave; ++h){suffix += "*"; }}
	}
	return prefix + s_noteStrings[key % 12] + suffix;
}

Step 3:

Line near by 1070: // show octave notice in actual tone (green marker)
QString noteKeyString = getNoteString(n->key(), true);

Line near by 3262: // hide octave notice in the piano key (while kyes)
QString noteString = getNoteString(key, false);

anytizer avatar Aug 03 '23 05:08 anytizer

List of some related changes: #6865 - Added flats to array of keys #6873 - Changed sharps to music sharps unicode #6876 - Use UTF-8 for MSVC source and execution charset

anytizer avatar Sep 16 '23 15:09 anytizer