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

Added capability of overriding wav MIDIPitchFraction with the Pipe999MIDIPitchFraction key https://github.com/GrandOrgue/grandorgue/issues/1378 #1396

Merged
merged 7 commits into from
Feb 25, 2023
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
- Added capability of overriding wav MIDIPitchFraction with the Pipe999MIDIPitchFraction key https://github.com/GrandOrgue/grandorgue/issues/1378
# 3.10.1 (2022-02-24)
- Fixed crash on loading an incorrect organ
# 3.10.0 (2022-02-17)
Expand Down
58 changes: 36 additions & 22 deletions help/grandorgue.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9896,30 +9896,44 @@ rank size), eg. 2 2/3 => 64 / (2 2/3) = 24.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Pipe999MIDIKeyNumber</term>
<listitem>
<para>
<varlistentry>
<term>Pipe999MIDIKeyNumber</term>
<listitem>
<para>
(integer -1 - 127, default: -1) If -1, use pitch information from the
Pipe999 sample, else override the information in the sample with this
MIDI note number (Pipe999PitchCorrection is used for specifying the
fraction). Specifying the MIDI note number also reset the pitch
fraction in the sample to 0.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Pipe999PitchCorrection</term>
<listitem>
<para>
(float -1800 - 1800, default: 0) Correction factor in cent for the
pitch specified in the sample in addition to PitchCorrection of
the whole organ, of the windchest and of the rank. This setting is
used for retuning to other temperaments.
</para>
</listitem>
</varlistentry>
<varlistentry>
MIDI note number (Pipe999MIDIPitchFraction is used for specifying the
fraction). Specifying the MIDI note number also resets the pitch
fraction in the sample to 0 unless Pipe999MIDIPitchFraction is also specified.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Pipe999MIDIPitchFraction</term>
<listitem>
<para>
(float 0 - 100, default: -1) If -1, use pitch information from the
Pipe999 sample, else override the information in the sample with this
value. Describes the actual existing pitch fraction in cent over the
normal (440hz equal) tone of the midi key specified in the sample or in
the Pipe999MIDIKeyNumber. This setting (together with
Pipe999MIDIKeyNumber) is used when retuning to other temperaments.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Pipe999PitchCorrection</term>
<listitem>
<para>
(float -1800 - 1800, default: 0) Correction factor in cent for the
pitch specified in the sample in addition to PitchCorrection of
the whole organ, of the windchest and of the rank. This setting is used
to adjust tuning while in other temperaments (than original). A positive
value raise the pitch, a negative value lowers the pitch.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term>Pipe999AcceptsRetuning</term>
<listitem>
<para>
Expand Down
110 changes: 62 additions & 48 deletions src/grandorgue/model/GOSoundingPipe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,10 @@ GOSoundingPipe::GOSoundingPipe(
m_ReleaseCrossfadeLength(0),
m_MinVolume(min_volume),
m_MaxVolume(max_volume),
m_SampleMidiKeyNumber(-1),
larspalo marked this conversation as resolved.
Show resolved Hide resolved
m_OdfMidiKeyNumber(-1),
m_OdfMidiPitchFraction(-1.0),
m_SampleMidiKeyNumber(0),
m_SampleMidiPitchFraction(0.0),
m_RetunePipe(retune),
m_IsTemperamentOriginalBased(true),
m_PipeConfigNode(
Expand Down Expand Up @@ -135,7 +138,8 @@ void GOSoundingPipe::Init(
m_OrganController->RegisterCacheObject(this);
m_Filename = filename;
m_PipeConfigNode.Init(cfg, group, prefix);
m_SampleMidiKeyNumber = -1;
m_OdfMidiKeyNumber = -1;
m_OdfMidiPitchFraction = -1.0;
m_LoopCrossfadeLength = 0;
m_ReleaseCrossfadeLength = 0;
UpdateAmplitude();
Expand Down Expand Up @@ -182,8 +186,16 @@ void GOSoundingPipe::Load(
m_SamplerGroupID);
m_Percussive = cfg.ReadBoolean(
ODFSetting, group, prefix + wxT("Percussive"), false, m_Percussive);
m_SampleMidiKeyNumber = cfg.ReadInteger(
m_OdfMidiKeyNumber = cfg.ReadInteger(
ODFSetting, group, prefix + wxT("MIDIKeyNumber"), -1, 127, false, -1);
m_OdfMidiPitchFraction = cfg.ReadFloat(
ODFSetting,
group,
prefix + wxT("MIDIPitchFraction"),
0,
100.0,
false,
-1.0);
m_LoopCrossfadeLength = cfg.ReadInteger(
ODFSetting, group, prefix + wxT("LoopCrossfadeLength"), 0, 120, false, 0);
m_ReleaseCrossfadeLength = cfg.ReadInteger(
Expand Down Expand Up @@ -254,7 +266,6 @@ void GOSoundingPipe::LoadData(
(loop_load_type)m_PipeConfigNode.GetEffectiveLoopLoad(),
m_PipeConfigNode.GetEffectiveAttackLoad(),
m_PipeConfigNode.GetEffectiveReleaseLoad(),
m_SampleMidiKeyNumber,
m_LoopCrossfadeLength,
m_ReleaseCrossfadeLength);
Validate();
Expand Down Expand Up @@ -301,7 +312,7 @@ void GOSoundingPipe::UpdateHash(GOHash &hash) {
hash.Update(m_PipeConfigNode.GetEffectiveLoopLoad());
hash.Update(m_PipeConfigNode.GetEffectiveAttackLoad());
hash.Update(m_PipeConfigNode.GetEffectiveReleaseLoad());
hash.Update(m_SampleMidiKeyNumber);
hash.Update(m_OdfMidiKeyNumber);
hash.Update(m_LoopCrossfadeLength);
hash.Update(m_ReleaseCrossfadeLength);

Expand Down Expand Up @@ -336,7 +347,40 @@ void GOSoundingPipe::Initialize() {}

const wxString &GOSoundingPipe::GetLoadTitle() { return m_Filename; }

float GOSoundingPipe::GetManualTuningPitchOffset() const {
return m_PipeConfigNode.GetEffectivePitchTuning()
+ m_PipeConfigNode.GetEffectiveManualTuning();
}

float GOSoundingPipe::GetAutoTuningPitchOffset() const {
float pitchAdjustment = 0.0;

// For any other temperament than original. Calculate pitchAdjustment by
// converting from the original temperament to the equal one before using
// temperament offset. Take PitchCorrection into account. Also GUI tuning
// adjustments are added and ODF adjustments removed leaving difference.
if (!m_PipeConfigNode.GetEffectiveIgnorePitch() && m_SampleMidiKeyNumber) {
pitchAdjustment
= log(m_HarmonicNumber / 8.0) / log(2) * 1200 // harmonic correction
+ ((int)m_MidiKeyNumber - m_SampleMidiKeyNumber) * 100 // note correction
- m_SampleMidiPitchFraction; // fraction correction
}
return pitchAdjustment + m_PipeConfigNode.GetEffectivePitchCorrection()
+ m_PipeConfigNode.GetEffectiveAutoTuningCorection(); // final correction
}

void GOSoundingPipe::Validate() {
// make effective values
m_SampleMidiKeyNumber = m_OdfMidiKeyNumber >= 0
? m_OdfMidiKeyNumber
: m_SoundProvider.GetMidiKeyNumber();
m_SampleMidiPitchFraction = m_OdfMidiPitchFraction >= 0.0
? m_OdfMidiPitchFraction
: m_OdfMidiKeyNumber < 0
? m_SoundProvider.GetMidiPitchFract()
: 0.0; // if MidiKeyNumber is provided in the ODF then we ignore
// the PitchFraction from the sample

if (!m_OrganController->GetConfig().ODFCheck())
return;

Expand Down Expand Up @@ -372,35 +416,26 @@ void GOSoundingPipe::Validate() {
}

if (
m_RetunePipe && m_SoundProvider.GetMidiKeyNumber() == 0
&& m_SoundProvider.GetMidiPitchFract() == 0
&& m_SampleMidiKeyNumber == -1) {
m_RetunePipe && m_SampleMidiKeyNumber <= 0
&& m_SampleMidiPitchFraction <= 0.0) {
wxLogWarning(
_("rank %s pipe %s: no pitch information provided"),
m_Rank->GetName().c_str(),
GetLoadTitle().c_str());
return;
}
double offset;
if (!m_RetunePipe)
offset = 0;
else
offset = m_SoundProvider.GetMidiKeyNumber()
+ log(8.0 / m_HarmonicNumber) * (12.0 / log(2))
- (m_SoundProvider.GetMidiPitchFract()
- m_PipeConfigNode.GetEffectivePitchTuning()
+ m_PipeConfigNode.GetEffectivePitchCorrection())
/ 100.0
- m_MidiKeyNumber;
if (offset < -18 || offset > 18) {
float offset = m_RetunePipe ? GetAutoTuningPitchOffset() : 0.0;

if (offset < -1800 || offset > 1800) {
wxLogError(
_("rank %s pipe %s: temperament would retune pipe by more than "
_("rank %s pipe %s: temperament would retune pipe by %f - more than "
"1800 cent"),
m_Rank->GetName().c_str(),
GetLoadTitle().c_str());
m_Rank->GetName(),
GetLoadTitle(),
offset);
return;
}
if (offset < -6 || offset > 6) {
if (offset < -600 || offset > 600) {
wxLogWarning(
_("rank %s pipe %s: temperament would retune pipe by more "
"than 600 cent"),
Expand Down Expand Up @@ -468,31 +503,10 @@ void GOSoundingPipe::UpdateAmplitude() {
}

void GOSoundingPipe::UpdateTuning() {
float pitchAdjustment = 0;
float pitchAdjustment = m_IsTemperamentOriginalBased
? GetManualTuningPitchOffset()
: GetAutoTuningPitchOffset();

if (m_IsTemperamentOriginalBased) {
// For original temperament. Set pitchAdjustment from GetEffectiveTuning
pitchAdjustment = m_PipeConfigNode.GetEffectivePitchTuning()
+ m_PipeConfigNode.GetEffectiveManualTuning();
} else {
// For any other temperament than original. Calculate pitchAdjustment by
// converting from the original temperament to the equal one before using
// temperament offset. Take PitchCorrection into account. Also GUI tuning
// adjustments are added and ODF adjustments removed leaving difference.
double concert_pitch_correction = 0;

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.GetEffectivePitchCorrection()
+ m_PipeConfigNode.GetEffectiveAutoTuningCorection()
- concert_pitch_correction;
}
m_SoundProvider.SetTuning(pitchAdjustment + m_TemperamentOffset);
}

Expand Down
15 changes: 15 additions & 0 deletions src/grandorgue/model/GOSoundingPipe.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,10 @@ class GOSoundingPipe : public GOPipe,
unsigned m_ReleaseCrossfadeLength;
float m_MinVolume;
float m_MaxVolume;
int m_OdfMidiKeyNumber;
float m_OdfMidiPitchFraction;
int m_SampleMidiKeyNumber;
float m_SampleMidiPitchFraction;
bool m_RetunePipe;
bool m_IsTemperamentOriginalBased;
GOSoundProviderWave m_SoundProvider;
Expand All @@ -54,6 +57,18 @@ class GOSoundingPipe : public GOPipe,
void SetOff();
void Change(unsigned velocity, unsigned old_velocity);
GOSoundProvider *GetSoundProvider();

/**
* Calculate a pitch offset for manual tuning
* @return pitch offset in cents
*/
float GetManualTuningPitchOffset() const;
/**
* Calculates a pitch offset for retuning from the sample pitch
* to the equal temperament
* @return pitch offset in cents
*/
float GetAutoTuningPitchOffset() const;
void Validate();

void LoadAttack(GOConfigReader &cfg, wxString group, wxString prefix);
Expand Down
5 changes: 0 additions & 5 deletions src/grandorgue/sound/GOSoundProviderWave.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,6 @@ void GOSoundProviderWave::LoadFromFile(
loop_load_type loop_mode,
unsigned attack_load,
unsigned release_load,
int midi_key_number,
unsigned loop_crossfade_length,
unsigned release_crossfase_length) {
ClearData();
Expand Down Expand Up @@ -424,10 +423,6 @@ void GOSoundProviderWave::LoadFromFile(
}

ComputeReleaseAlignmentInfo();
if (midi_key_number != -1) {
m_MidiKeyNumber = midi_key_number;
m_MidiPitchFract = 0;
}
if (release_crossfase_length)
m_ReleaseCrossfadeLength = release_crossfase_length;
else
Expand Down
1 change: 0 additions & 1 deletion src/grandorgue/sound/GOSoundProviderWave.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ class GOSoundProviderWave : public GOSoundProvider {
loop_load_type loop_mode,
unsigned attack_load,
unsigned release_load,
int midi_key_number,
unsigned loop_crossfade_length,
unsigned release_crossfase_length);
void SetAmplitude(float fixed_amplitude, float gain);
Expand Down
1 change: 0 additions & 1 deletion src/tools/GOPerfTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@ void GOPerfTestApp::RunTest(
LOOP_LOAD_ALL,
1,
1,
-1,
0,
0);
pipes.push_back(w);
Expand Down