/* * private void textBoxWavePartials_TextChanged(object sender, RoutedEventArgs e) { * if (_settingInternally) return; * * Rational[] partials = Rational.ParseRationals(_textBoxWavePartials.Text, ","); * //!!! validate by subgroup matrix ? * _soundSettings.partials = partials; * } */ private void PlayNote(SomeInterval t) { if (_soundSettings.output == SoundSettings.EOutput.None) { return; } // get interval cents float cents = t.IsRational() ? _gridDrawer.Temperament.CalculateMeasuredCents(t.rational) : t.cents; switch (_soundSettings.output) { case SoundSettings.EOutput.Midi: #if USE_MIDI if (_midiPlayer != null && _midiPlayer.IsClockStarted()) { _midiPlayer.NoteOn(0, cents, duration: 8f); // duration in beats } #endif break; case SoundSettings.EOutput.Wave: case SoundSettings.EOutput.WavePartialsTempered: #if USE_WAVE if (_waveEngine != null && _waveEngine.IsPlaying() && _partialProvider != null) { IList <Rational> partials = null; // _soundSettings.partials; // get partials from settings if (partials == null) { // generate default integer partials partials = new List <Rational>(); for (int i = 1; i < 100; ++i) { var r = new Rational(i); if (!_gridDrawer.Subgroup.IsInRange(r)) { continue; // skip if out of subgroup } partials.Add(r); if (partials.Count == _systemSettings.wavePartialCount) { break; } } } // bool temper = _soundSettings.output == SoundSettings.EOutput.WavePartialsTempered; foreach (Rational r in partials) { float c = cents; c += temper ? _gridDrawer.Temperament.CalculateMeasuredCents(r) : (float)r.ToCents(); double hz = Wave.Partials.CentsToHz(c); float h = _gridDrawer.GetRationalHarmonicity(r); Debug.Assert(0 <= h && h <= 1f, "Normalized harmonicity expected"); float level = (float)(0.1 * Math.Pow(h, 4.5)); int duration = (int)(2000 * Math.Pow(h, 1)); Debug.WriteLine("Add partial: {0} {1:0.000} -> {2:0.00}c {3:0.00}hz level {4:0.000}", r, h, c, hz, level); _partialProvider.AddPartial(hz, 10, duration, level, -4f); } _partialProvider.FlushPartials(); } #endif break; } }