A scale based on a particular tonic.

For our purposes, a scale is defined by a tonic and then the pattern that it uses to ascend up to the next tonic and then descend back to the original tonic. The tonic is described with a NoteFamily because it is not specific to any one octave. The ascending/descending pattern is provided by the Pattern nested class.

This class comes with a collection of predefined patterns, such as Scale.Major and Scale.HarmonicMinor.

示例#1
0
        /// <summary>
        /// Just generate a cloud of points within the given sphere
        /// </summary>
        /// <param name="engine"></param>
        public static void GenerateAFuckTonneOfCubes(Engine.Engine engine, ChannelAndInstrument ci, Note scaleNote, int numberOfCubes, Point3D point, double radius, double cubeRadius) {
            Scale scale = new Scale(scaleNote, Scale.Major);
            Random random = new Random();
            OutputDevice device = OutputDevice.InstalledDevices[0];
            Channel channel = ci.Channel;
            Instrument instrument = ci.Instrument;
            int rootOctave = 3;

            int thisOctave = rootOctave;
            for (int i = 0; i < numberOfCubes; i++) {

                double x = point.X + (random.NextDouble() - 0.5) * radius;
                double y = point.Y + (random.NextDouble() - 0.5) * radius;
                double z = point.Z + (random.NextDouble() - 0.5) * radius;
                Point3D cubePoint = new Point3D(x * radius, y * radius, z * radius);
                Pitch thisPitch;
                
                // limit it to 3 octaves
                if (i % 21 == 0)
                    thisOctave = rootOctave;

                thisPitch = scale.NoteSequence[i % 7].PitchInOctave(thisOctave);

                // increment the octave if we have run out of notes
                if (i % 7 == 0)
                    thisOctave++;

                SingleNoteCube a = new Cubes.SingleNoteCube(cubePoint, cubeRadius, thisPitch, instrument, App.OutputDevice, channel);

                engine.AddCube(a);
            }
        }
示例#2
0
 /// <summary>
 /// Returns a comma-separated string with the note names of c's NoteSequence.
 /// </summary>
 private static string SequenceString(Scale s)
 {
     string result = "";
     for (int i = 0; i < s.NoteSequence.Length; ++i)
     {
         if (i > 0)
         {
             result += ", ";
         }
         result += s.NoteSequence[i].ToString();
     }
     return result;
 }
示例#3
0
        public void Contains()
        {
            Scale cmajor = new Scale(new Note("C"), Scale.Major);
            Pitch[] cmajorPitches = new Pitch[] {
                Pitch.C2, Pitch.D2, Pitch.E2, Pitch.F2, Pitch.G2, Pitch.A2, Pitch.B2 };
            Pitch[] cmajorNotPitches = new Pitch[] {
                Pitch.CSharp2, Pitch.DSharp2, Pitch.FSharp2, Pitch.GSharp2, Pitch.ASharp2 };
            foreach (Pitch p in cmajorPitches)
            {
                Assert.True(cmajor.Contains(p));
            }
            foreach (Pitch p in cmajorNotPitches)
            {
                Assert.False(cmajor.Contains(p));
            }

            Scale bbhminor = new Scale(new Note("Bb"), Scale.HarmonicMinor);
            Pitch[] bbhminorPitches = new Pitch[] {
                Pitch.ASharp2, Pitch.C3, Pitch.CSharp3, Pitch.DSharp3, Pitch.F3, Pitch.FSharp3,
                Pitch.A3 };
            Pitch[] bbhminorNotPitches = new Pitch[] {
                Pitch.B2, Pitch.D3, Pitch.E3, Pitch.G3, Pitch.GSharp3  };
            foreach (Pitch p in bbhminorPitches)
            {
                Assert.True(bbhminor.Contains(p));
            }
            foreach (Pitch p in bbhminorNotPitches)
            {
                Assert.False(bbhminor.Contains(p));
            }
        }
示例#4
0
 public void NoteOn(NoteOnMessage msg)
 {
     lock (this)
     {
         List<Pitch> pitches = new List<Pitch>();
         if (playingChords)
         {
             Chord chord = new Chord(msg.Pitch.NotePreferringSharps(),
                 Chord.Patterns[currentChordPattern], 0);
             Pitch p = msg.Pitch;
             for (int i = 0; i < chord.NoteSequence.Length; ++i)
             {
                 p = chord.NoteSequence[i].PitchAtOrAbove(p);
                 pitches.Add(p);
             }
         }
         else
         {
             Scale scale = new Scale(msg.Pitch.NotePreferringSharps(),
                 Scale.Patterns[currentScalePattern]);
             Pitch p = msg.Pitch;
             for (int i = 0; i < scale.NoteSequence.Length; ++i)
             {
                 p = scale.NoteSequence[i].PitchAtOrAbove(p);
                 pitches.Add(p);
             }
             pitches.Add(msg.Pitch + 12);
         }
         lastSequenceForPitch[msg.Pitch] = pitches;
         for (int i = 1; i < pitches.Count; ++i)
         {
             clock.Schedule(new NoteOnMessage(outputDevice, msg.Channel,
                 pitches[i], msg.Velocity, msg.Time + i));
         }
     }
 }
示例#5
0
 public void NoteOn(NoteOnMessage msg)
 {
     Scale scale = new Scale(msg.Note.Family(), Scale.Patterns[scaleToUse]);
     List<Note> scaleNotes = scale.Traverse(msg.Note, msg.Note+12);
     float delay = msg.BeatTime+1;
     for (int i = 1; i < scaleNotes.Count; ++i, delay++)
     {
         clock.Schedule(new NoteOnOffMessage(outputDevice, msg.Channel, scaleNotes[i],
         msg.Velocity, delay, 0.99f));
     }
     scaleNotes = scale.Traverse(msg.Note+12, msg.Note);
     for (int i = 1; i < scaleNotes.Count; ++i, delay++)
     {
         clock.Schedule(new NoteOnOffMessage(outputDevice, msg.Channel, scaleNotes[i],
         msg.Velocity, delay, 0.99f));
     }
 }
        private void btnCreate_Click(object sender, RoutedEventArgs e) {
            // scale mode?
            if (!(bool)chkScaleMode.IsChecked)
                currentScaleNoteIndex = 0;

            // otherwise, create a cube that matches the specifications we just set
            Cube cube = new NullCube(Engine.Engine.Origin, 0);

            // yank values from comboboxes n shit
            Note note = new Note((string)((ComboBoxItem)cmbNote.SelectedItem).Content);
            int octave = int.Parse((string)((ComboBoxItem)cmbOctave.SelectedItem).Content);
            
            ChordPattern chordPattern = Chord.Major;
            ScalePattern scalePattern = Scale.Major;

            switch ((string)((ComboBoxItem)cmbScale.SelectedItem).Content) {
                case "Major": scalePattern = Scale.Major; break;
                case "HarmonicMinor": scalePattern = Scale.HarmonicMinor; break;
                case "MelodicMinorAscending": scalePattern = Scale.MelodicMinorAscending; break;
                case "MelodicMinorDescending": scalePattern = Scale.MelodicMinorDescending; break;
                case "NaturalMinor": scalePattern = Scale.NaturalMinor; break;
            }
            
            switch ((string)((ComboBoxItem)cmbChordType.SelectedItem).Content) {
                case "Major": chordPattern = Chord.Major; break;
                case "Minor": chordPattern = Chord.Minor; break;
                case "Seventh": chordPattern = Chord.Seventh; break;
                case "Augmented": chordPattern = Chord.Augmented; break;
                case "Diminished": chordPattern = Chord.Diminished; break;
            }
            Scale scale = new Scale(note, scalePattern);

            // scalemode translation
            note = scale.NoteSequence[currentScaleNoteIndex++ % 7];

            Pitch pitch = note.PitchInOctave(octave);

            int chordInversion = int.Parse((string)((ComboBoxItem)cmbInversion.SelectedItem).Content);
            Chord chord = new Chord(note, chordPattern, chordInversion);

            // single note cube
            if ((bool)Note.IsChecked) {
                cube = new SingleNoteCube(Engine.Engine.Origin, _Constants.CreateHandDistance / 2.0, pitch, CurrentInstrument, App.OutputDevice, CurrentChannel);
            }

            if ((bool)Chord2.IsChecked) {
                cube = new ChordCube(Engine.Engine.Origin, _Constants.CreateHandDistance / 2.0, chord, octave, CurrentInstrument, App.OutputDevice, CurrentChannel);
            }

            
            // give the cube a random colour
            Random randomGen = new Random();
            KnownColor[] names = (KnownColor[])Enum.GetValues(typeof(KnownColor));
            KnownColor randomColorName = names[randomGen.Next(names.Length)];
            System.Drawing.Color tempColor = System.Drawing.Color.FromKnownColor(randomColorName);
            System.Windows.Media.Color randomColor = System.Windows.Media.Color.FromArgb(tempColor.A, tempColor.R, tempColor.G, tempColor.B);
            cube.SolidColorBrush.Color = randomColor;

            // now set the engine to create mode, and assign this as the cube to be created
            App.Engine.SetCreateCube(cube);
        }