GrandOrgue / grandorgue

GrandOrgue software
Other
168 stars 41 forks source link

Capability of preserving the original pitch and deviations when switching the temperaments #1351

Closed oleg68 closed 1 year ago

oleg68 commented 1 year ago

Now GrandOrgue allows a user to choose a temperament. One of them is the Original temperament , others are a lot of predefined user-defined temperaments.

There are some issues releated to the current temperament implementations:

  1. When a non-original temperament selected, the organ is automatically tuned and pitched to 440hz (mentioned in https://github.com/GrandOrgue/grandorgue/discussions/1162#discussion-4330176).
  2. Any user-tuning settings made with GUI can be appropriate for either the original temperament or non-original temperaments, but not for both #1333.

I propose to do several enchancements.

  1. To introduce the Temperament key in the ODF with the name of original temperament.
  2. To implement a separate feature AutoTuning. It would allow to tune the organ using the embeded pitch information regardless the temperament used. To introduce a special menu entry Auto Tuning,
  3. To allow the 'PitchCorrection' ODF key at the organ, windchest, and rank level. It would allow to specify the original pitch other than 440hz and use it with auto tuning.
  4. If the original temperament is specified in the ODF, switching to a non-original temperament may be done with or without the automatic tuning. In the second case the difference between the temperament offsets of the original and the target temperament is used.
  5. To remove the Tuning field from the Organ Settings and to introduce two another user-tunable fields: ManualTuning and AutoTuningCorrection.

@larspalo @rousseldenis do you agree with this approach?

larspalo commented 1 year ago

@oleg68 For your suggested improvements I'd say that:

  1. temperament key is not desired as temperament alone does not cover for instance targeted pitch. The recorded samples contain everything that's original! ;-)
  2. Depends... Might be useful as a way to quickly fill the tuning (actually both manual and TemperamentTuning)
  3. Absolutely!
  4. I think you should abandon the idea of specifying temperament in odf and thus this point is invalid.
  5. Yes, but OriginalTuning and TemperamentTuning might be better wordings.
oleg68 commented 1 year ago
  1. The recorded samples contain everything that's original! ;-)

I call Original Temperament what was intended by the organ builder. The real pipes always have some deviations from the original temperament.

Now when the user chooses any non-original temperament, GO tunes all the pipes and discards the recorded deviations. It makes the sound "atrificial".

I'd like to separate the auto-tuning feature (discarding all deviations) from switching the temperaments. If the original intended organ temperament was known, GrandOrgue would be capable to recalculate temperament offsets with preserving the original pitch and deviations.

I think you should abandon the idea of specifying temperament in odf and thus this point is invalid.

But capability of preserving the original pitch and deviations when switching the temperaments looks as attractive.

rousseldenis commented 1 year ago

think you should abandon the idea of specifying temperament in odf and thus this point is invalid.

I agree on that point (as we suppose the sampler person has done the job to 'just fix' inherent errors due to real recording conditions - and not a full temperament change) and agree too on @oleg68 idea to keep the (I call it 'sample set original temperament' - which sounds better to me) temperament as a base for further temperament changes, which is a good idea compared to 'reset' the adjustments made by the sampler.

larspalo commented 1 year ago

The general idea of using equal temperament with a1=440 Hz as base is because that's the generally accepted standard. The fact that it almoast isn't used anymore in real life is another thing completely (most orchestras and opera houses uses another pitch...). It's still a point of reference (actually the point of reference).

larspalo commented 1 year ago

Now when the user chooses any non-original temperament, GO tunes all the pipes and discards the recorded deviations. It makes the sound "atrificial".

The only thing artificial (except the digital resampling that happens) is that the tuning usually gets extremely precise, and that in itself is seldom the case in real life...

oleg68 commented 1 year ago

@larspalo

3. Absolutely!

I am very frustrated with PitchCorrection: I found that now it works in a very strange way: Pipe999PitchCorrection is not added to the rank-level PitchCorrection, but overrides it. The windchest-level and Organ-Level PitchCorrection do not exist.

It looks like a bug, but I'm afraid to fix it because some existing ODFs may be pledged to this behavior. Should we change it?

My intention was to set Pipe999PitchCorrection only fo correcting wav-pitches, Rank::PitchCorrection for a celeste stop only and Organ::PitchCorrection for setting the pitch of the whole organ.

larspalo commented 1 year ago

@oleg68 The only usage for the PitchCorrection was with a temperament (other than Original). It could either override the PitchFraction value from the wav file (when used for a pipe), or apply to a whole rank for instance when you have a Voix Celeste that's indeed supposed to be tuned somewhat sharp (and the temperament would otherwise tune it perfect like any other stop).

So, I think you're on the right track! Pipe999PitchCorrection override the .wav pitch data. [Organ] [Windchest] and [Rank] (including stop usage) cumulative.

oleg68 commented 1 year ago

@larspalo I'm talking about possible behavior changes.

Current behavior:

Intended behavior:

So if an ODF contains both Rank.PitchCorrection and Pipe999PitchCorrection, currently only Pipe999PitchCorrection is used, but I'm going to use Rank.PitchCorrection + Pipe999PitchCorrection instead. So the ODF will be played differently with non-original temperament, and this change will impact all that ODFs. But I don't know, whether that ODFs exist.

oleg68 commented 1 year ago

@larspalo @rousseldenis, is the proposed change acceptable or not?

larspalo commented 1 year ago

@oleg68 This is maybe not quite as simple as it might seem, or we have some slight misunderstandings in the communication.

If pitch info is present in .wav file samples it should always be used unless Pipe999PitchCorrection is specified or IgnorePitchInfo is selected. In such cases it's replaced (or simply overridden).

All levels of pitchCorrection should work cumulatively, I think. But, for temperament tunings only the .wav info or Pipe999PitchCorrection (and Pipe999MIDIKeyNumber) are used for actual first stage temperament retuning (adjusted according to standard pitch equal temperament). Then the other layers from [Organ] to [Rank] should be applied "on top" without changing individual relations or be tuned back to standard pitch. (The very point of the other layers is to be able to deviate from standard pitch even in temperaments)

The PiteaMHS sampleset have a VoixCeleste with rank level pitch correction applied to get the approximately correct de-tuning of the rank. I'm not aware of any sample set that intentionally adjust both Pipe999PitchCorrection and Rank level, but it certainly should be possible to do - and they should be done for quite different purposes, I think.

For a sample set where lot of re-tuning was needed you can explore the Norrfjärden Sample Set I recently released. That sampleset would indeed profit from the possibility to specify an organ level pitch correction so that the "hoher chorton" pitch could be preserved if that's desired even in temperaments.

If you think I'm misunderstanding something, feel free to explain that in detail!

oleg68 commented 1 year ago

If you think I'm misunderstanding something, feel free to explain that in detail!

You do not answer my main question.

Now coalesce(Pipe999PitchCorrection, PitchCorrection) is used. I want to replace it with Pipe999PitchCorrection+PitchCorrection. Is it acceptable or not?

oleg68 commented 1 year ago

you can explore the Norrfjärden Sample Set

@larspalo I could not find any Download button at http://familjenpalo.se/vpo/about-my-samplesets/norrfjarden-church/

May be I missed something?

larspalo commented 1 year ago

It's on the download page http://familjenpalo.se/vpo/download/. I really should add the download options from each description page too...

larspalo commented 1 year ago

Is it acceptable or not?

I'd still say that it depends on the context (specific temperament re-tuning, or overall pitch adjustment).

But GrandOrgue can not know the context. It can either add two numbers or use only one of them.

Martin's point was that a sample set producer can calculate all final Pipe999PitchCorrection values by himself, so he/she need neither Organ/Windchest-level correction, nor addition of the rank level correction. The only case when he/she needs a rank PitchCorrection is when all embeded wav pitches are correct and he/she wants to adjust the overall pitch of the rank. And there is no need a capability of adjusting pitch of the whole organ because he/she is free to do it on each rank with the same value. It is a 'macos-like' approach. But I cann't see any cases when both Pipe999PitchCorrection and PitchCorrection should be specified in this approach.

I prefer a linux-like approach: there is a quite simple universal data model, that allows to implement lots of useful usecases, but it does not protect against implementing useless ones. So I suggest to add all PitchCorrections from all levels.

The only thing in doubt is the transition from the first approach to the second one. Some old ODFs may stop working correctly.

larspalo commented 1 year ago

So I suggest to add all PitchCorrections from all levels

On this I agree.

The real question though is if we need to separate the overriding function of the Pipe999PitchCorrection of the .wav file pitch data? Presently, if Pipe999PitchCorrection is specified it will override it and not be used cumulatively. One possibility would be to change that behavior so that the PitchFraction instead would be used to override/supply pitch info and PitchCorrection will only adjust. This is of course a change of behavior that will affect existing odfs.

oleg68 commented 1 year ago

On this I agree.

Excellent!

Should we increase the major version number 3.10.0 -> 4.0.0 due the possible incompatibility with old ODFs? Or leave 3.10.0 because the probability of this affect is very low?

larspalo commented 1 year ago

@oleg68 I think we could stay on 3.10 because as you say it's unlikely that it will be a real problem for older odfs (most of the time they don't use pitch correction anyway). We just need to make sure that this improvement won't have unintended side effects.

oleg68 commented 1 year ago

Presently, if Pipe999PitchCorrection is specified it will override it and not be used cumulatively.

It is not true.

    if (
      !m_PipeConfigNode.GetEffectiveIgnorePitch()
      && m_SoundProvider.GetMidiKeyNumber()) {
      concert_pitch_correction
        = (100.0 * m_SoundProvider.GetMidiKeyNumber() - 100.0 * m_MidiKeyNumber
           + log(8.0 / m_HarmonicNumber) / log(2) * 1200)
        + m_SoundProvider.GetMidiPitchFract();
    }
    pitchAdjustment = m_PipeConfigNode.GetEffectiveTuning() + m_PitchCorrection
      - m_PipeConfigNode.GetDefaultTuning() - concert_pitch_correction;

So now PitchCorrection is added to MidiPitchFract unless IgnorePitch is set.

Martin wrote:

PitchCorrection does not override wav pitch, but added to it.

so this behavior was intended by Martin and it is not a bug.

I'd leave this behavior unchanged. Moreover, the word Correction means "a small modification" rather than "replacement".

The real question though is if we need to separate the overriding function of the Pipe999PitchCorrection of the .wav file pitch data

It is a completely another question.

Presently IgnorePitch allows to separate this function. There is a case when ignoring a pitch is preferable: when wav-files contain a true garbage and the sample set producer has prohibitted modification of them due the license restriction (for example, when creating an ODF for existing HW sample set). It is a reason for allowing to specify IgnorePitch in ODF, not only in CMB, but, I know, you disagree.

One possibility would be to change that behavior so that the PitchFraction

Of cause, PitchFraction is another way to do it. But if MidiPitchFract is a garbage in the wav, MidiKeyNumber is most likely too. And adding a new entity instead of using a combination of already existing ones contradicts the Occam principle.

Another possible way is to specify Pipe999MidiKeyNumber=0. But this way is more for hackers rather for ODF creators.

larspalo commented 1 year ago

I'd leave this behavior unchanged. Moreover, the word Correction means "a small modification" rather than "replacement".

Sure. It might indeed be instead that if Pipe999MIDIKeyNumber is specified then the .wav pitch fraction is also reset and specified by the Pipe999PitchCorrection. This can anyway already be exploited to correct faulty or non existant .wav pitch info.

Ignore pitch is one global option to use from within GO (expects the .wav files to already be permanently tuned to standard pitch), in odf it's possible to specify AcceptsRetuning to get around things - but this is only supposed to be used on noise effects that should not change pitch at all.

I think the overall goal is most important - allowing the user to effectively adjust pitch both in the original temperament and in a selected temperament, which requires different (separate) tuning information to be able to work. And this needs to be possible on individual pipe level as well as on higher levels.

oleg68 commented 1 year ago

@larspalo #1366 allows to keep the original organ pitch when switching temperaments.

But I'd like to implement recalculating between different temperaments without autotuning.

You don't like my idea to specify the initial temperament in ODF. Unfortunaly, I don't have any alternative idea for implementing this feature.

So if you still opose ODF.OriginalTemperament, I'll close this issue without resolving.

larspalo commented 1 year ago

I'll close this issue without resolving.

Do that for now, I think. The calculation to get what PitchCorrection at [Organ] level would keep the overall pitch of say reference tone a1 should not be that hard to do. That would of course require the pitch info from one (or more, for an average) such pipe (which describe the existing pitch and what's used when the temperament re-tuning happen) and compare what offset would be needed to not retune that to a1=440.

oleg68 commented 1 year ago
  1. Capability of preserving the original pitch was added with #1366
  2. Splitting Tuning into ManualTuning and AutoTuningCorrection will be done with #1370 in the scope of #1333
  3. Capability of preserving the deviation won't be implemented due lack of approval from @larspalo
000masa000 commented 1 year ago

Hello, new to this project, interested in implementation of dynamic retuning for microtonal music (MTS / MIDI tuning standard), as supported by fluidsynth and some other projects. Also might be used for dynamic retuning while playing (as is possible in Hauptwerk). Is there anyone conversant with the relevant issues code to help guide me getting started. I just finished developing a fork of the isomorphic onscreen keyboard (plainsound.org/hex) adding MTS support which works nicely with fluidsynth, would however like a more sophisticated digital organ than soundfont format can provide. Thanks in advance .... Marc

larspalo commented 1 year ago

@000masa000 Welcome! For general discussions, please post in https://github.com/GrandOrgue/grandorgue/discussions instead. GrandOrgue has since a long time ago had the capability of microtonal adjustments, temperament changes and custom temperaments, feel free to explore it.