/// <summary> /// Makes scale data /// </summary> /// <param name="_composition"></param> /// <returns></returns> public ScaleNote GenerateScale(Composition _composition) { // scale data ScaleNote _scaleNote = new ScaleNote(); // 1.1. make scale _scaleNote.MakeScale(_composition.Setting.Scale, _composition.Setting.ScaleNote, _composition.Setting.ChordHeight); return(_scaleNote); }
List <List <Note> > GetMellToneList(MellTone _mellTone, Form _form, ScaleNote _scale) { // avoid notes List <List <Note> > _avoid = new List <List <Note> >(); // tension notes List <List <Note> > _tension = new List <List <Note> >(); // chord tone notes List <List <Note> > _tone = new List <List <Note> >(); int _lastNoteBuffer; int _thirdNoteBuffer; // 1. prepare usable note list for (int _count = 0; _count < _form.Chord.FullChord.Count; _count++) { _avoid.Add(new List <Note>()); _tension.Add(new List <Note>()); _tone.Add(new List <Note>()); } // copy chord as pure List <List <Note> > _chordBuffer = new List <List <Note> >(); List <Note> _subBuffer = new List <Note>(); foreach (List <Note> _iterChord in _form.Chord.FullChord) { foreach (Note _iterNote in _iterChord) { _subBuffer.Add(GetPureNote(_iterNote)); } _chordBuffer.Add(CopyNoteList(_subBuffer)); _subBuffer.Clear(); } // 2. make avoid, tension and chord tone note list for (int _iterChord = 0; _iterChord < _chordBuffer.Count; _iterChord++) { for (int _iterNote = 0; _iterNote < _chordBuffer[_iterChord].Count; _iterNote++) { // chord tone _tone[_iterChord].Add(GetPureNote(_chordBuffer[_iterChord][_iterNote])); // check if there is 3 avoid or tension notes if (_tone[_iterChord].Count == _chordBuffer[_iterChord].Count) { break; } // last note in the chord _lastNoteBuffer = ((int)_chordBuffer[_iterChord][_chordBuffer[_iterChord].Count - 1] % 12); // 해당 코드에서 n번째 3도 위 음의 인덱스(스케일에서의 인덱스) _thirdNoteBuffer = (_scale.Notes.IndexOf((Note)_lastNoteBuffer) + (3 * (_iterNote + 1))) % 7; // avoid if ((int)_scale.Notes[_thirdNoteBuffer] - _lastNoteBuffer == 1) { _avoid[_iterChord].Add(_scale.Notes[_thirdNoteBuffer]); } // tension else { _tension[_iterChord].Add(_scale.Notes[_thirdNoteBuffer]); } } } switch (_mellTone) { case (MellTone.Tone): return(_tone); case (MellTone.Tension): return(_tension); case (MellTone.Avoid): return(_avoid); } return(_tone); }
/// <summary> /// Extends mellodies, rhythm in the form /// </summary> /// <param name="_origin"></param> /// <param name="_scale"></param> /// <returns></returns> Form VariateExtend(Form _origin, ScaleNote _scale, int _baseOctave) { Form _result = new Form(); // avoid notes List <List <Note> > _avoid; // tension notes List <List <Note> > _tension; // chord tone notes List <List <Note> > _tone; // deep copy the form _result.Copy(_origin); // 1. make mellody tone list _avoid = GetMellToneList(MellTone.Avoid, _origin, _scale); _tension = GetMellToneList(MellTone.Tension, _origin, _scale); _tone = GetMellToneList(MellTone.Tone, _origin, _scale); int _octaveBuffer = 0; // 2.1. specific tension list making for (int _iter = 0; _iter < _tension.Count; _iter++) { _octaveBuffer = 0; for (int _itt = 0; _itt < _tension[_iter].Count; _itt++) { if (_itt != _tension[_iter].Count - 1 && _tension[_iter][_itt] > _tension[_iter][_itt + 1]) { _tension[_iter][_itt] = GetOctaveNote(_tension[_iter][_itt], _baseOctave + _octaveBuffer); _octaveBuffer++; continue; } _tension[_iter][_itt] = GetOctaveNote(_tension[_iter][_itt], _baseOctave + _octaveBuffer); } } // 2.2. specific tone list making for (int _iter = 0; _iter < _tone.Count; _iter++) { _octaveBuffer = 0; for (int _itt = 0; _itt < _tone[_iter].Count; _itt++) { if (_itt != _tone[_iter].Count - 1 && _tone[_iter][_itt] > _tone[_iter][_itt + 1]) { _tone[_iter][_itt] = GetOctaveNote(_tone[_iter][_itt], _baseOctave + _octaveBuffer); _octaveBuffer++; continue; } _tone[_iter][_itt] = GetOctaveNote(_tone[_iter][_itt], _baseOctave + _octaveBuffer); } } // count buffer int _countBuffer = 0; // random buffer int _ranBuffer; // 2. variate for (int _iter = 0; _iter < _origin.Rhythm.NoteTime.Count; _iter++) { // check the item index if (_origin.Rhythm.NoteTime[_iter] != 1) { _ranBuffer = random.Next() % 10; _result.Rhythm.NoteTime[_iter] /= 2; _result.Rhythm.NoteTime.Insert(_iter, _origin.Rhythm.NoteTime[_iter] / 2); // tension : 30 % if (_ranBuffer <= 2) { _result.Mellody.FullMellody.Insert(_iter, _tension[_countBuffer / 8][random.Next() % _tension[_countBuffer / 8].Count]); } // chord tone : 70% else { _result.Mellody.FullMellody.Insert(_iter, _tone[_countBuffer / 8][random.Next() % _tone[_countBuffer / 8].Count]); } } _countBuffer += _origin.Rhythm.NoteTime[_iter]; } return(_result); }
/// <summary> /// Variate tail randomly /// </summary> /// <param name="_origin"></param> /// <param name="_scale"></param> /// <returns></returns> Form VariateTail(Form _origin, ScaleNote _scale, int _baseOctave) { Form _result = new Form(); // avoid notes List <List <Note> > _avoid; // tension notes List <List <Note> > _tension; // chord tone notes List <List <Note> > _tone; // deep copy the form _result.Copy(_origin); // 1. make mellody tone list _avoid = GetMellToneList(MellTone.Avoid, _origin, _scale); _tension = GetMellToneList(MellTone.Tension, _origin, _scale); _tone = GetMellToneList(MellTone.Tone, _origin, _scale); int _octaveBuffer = 0; // 2.1. specific tension list making for (int _iter = 0; _iter < _tension.Count; _iter++) { _octaveBuffer = 0; for (int _itt = 0; _itt < _tension[_iter].Count; _itt++) { if (_itt != _tension[_iter].Count - 1 && _tension[_iter][_itt] > _tension[_iter][_itt + 1]) { _tension[_iter][_itt] = GetOctaveNote(_tension[_iter][_itt], _baseOctave + _octaveBuffer); _octaveBuffer++; continue; } _tension[_iter][_itt] = GetOctaveNote(_tension[_iter][_itt], _baseOctave + _octaveBuffer); } } // 2.2. specific tone list making for (int _iter = 0; _iter < _tone.Count; _iter++) { _octaveBuffer = 0; for (int _itt = 0; _itt < _tone[_iter].Count; _itt++) { if (_itt != _tone[_iter].Count - 1 && _tone[_iter][_itt] > _tone[_iter][_itt + 1]) { _tone[_iter][_itt] = GetOctaveNote(_tone[_iter][_itt], _baseOctave + _octaveBuffer); _octaveBuffer++; continue; } _tone[_iter][_itt] = GetOctaveNote(_tone[_iter][_itt], _baseOctave + _octaveBuffer); } } // count buffer int _countBuffer = 0; // random buffer int _ranBuffer; // tail buffer int _tailBuffer = 0; // index buffer int _indexBuffer = 0; // 1. calculate full time foreach (int _iter in _origin.Rhythm.NoteTime) { _tailBuffer += _iter; } // 75% of value _tailBuffer = _tailBuffer - (_tailBuffer / 4); // 2. variate for (int _iter = 0; _iter < _origin.Rhythm.NoteTime.Count; _iter++) { // check the item time value if (_countBuffer > _tailBuffer) { _indexBuffer = _iter; break; } _countBuffer += _origin.Rhythm.NoteTime[_iter]; } // reset mellodies _result.Mellody.FullMellody.Clear(); // refresh count buffer _countBuffer = 0; // 3. make new mellody notes for (int _iter = 0; _iter < _origin.Rhythm.NoteTime.Count; _iter++) { // check index : first 75% notes to be same / last 25% notes to be new if (_iter < _indexBuffer) { _result.Mellody.FullMellody.Add(_origin.Mellody.FullMellody[_iter]); } else { _ranBuffer = random.Next() % 10; // tension : 20 % if (_ranBuffer < 0) { _result.Mellody.FullMellody.Add(_tension[_countBuffer / 8][random.Next() % _tension[_countBuffer / 8].Count]); } // chord tone : 70% else { _result.Mellody.FullMellody.Add(_tone[_countBuffer / 8][random.Next() % _tone[_countBuffer / 8].Count]); } } _countBuffer += _origin.Rhythm.NoteTime[_iter]; } return(_result); }