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

Custom Piano Labels #6162

Open
anytizer opened this issue Sep 16, 2021 · 11 comments
Open

Custom Piano Labels #6162

anytizer opened this issue Sep 16, 2021 · 11 comments

Comments

@anytizer
Copy link
Contributor

anytizer commented Sep 16, 2021

static std::array<QString, 12> s_noteStrings {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"};

Representation↓ Keys → C C# D D# E F F# G G# A A# B Notes
English C C# D D# E F F# G G# A A# B Currently in use
SARGAM short form S r R g G m M P d D n N Use case 1
Classical सरगम सा .रे रे .ग म' .ध ऩि नि Use case 2 (needs to rewrite the symbols)

Notations for classical in the example above are not fully correct.
Notations in other systems to be addressed as well.

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


Related articles:

Usages of the symbols:

@Veratil
Copy link
Contributor

Veratil commented Sep 16, 2021

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

@anytizer
Copy link
Contributor Author

anytizer commented Sep 16, 2021

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.

@he29-net
Copy link
Contributor

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.

@Spekular
Copy link
Member

Spekular commented Sep 16, 2021

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.

@anytizer
Copy link
Contributor Author

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?

@Veratil
Copy link
Contributor

Veratil commented Sep 16, 2021

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

No, the save format is XML.

@anytizer
Copy link
Contributor Author

anytizer commented Sep 16, 2021

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.

@Monospace-V
Copy link
Contributor

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

@PhysSong
Copy link
Member

PhysSong commented Jan 3, 2022

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

Related: #5357

@anytizer
Copy link
Contributor Author

anytizer commented Aug 3, 2023

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
Copy link
Contributor Author

anytizer commented Sep 16, 2023

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants