347 lines
8.9 KiB
C++
347 lines
8.9 KiB
C++
#include <music/chord.hpp>
|
|
#include <music/progression.hpp>
|
|
#include <music/scales.hpp>
|
|
#include <midiseq/midiout.hpp>
|
|
#include <common/array.hpp>
|
|
#include <common/stringbuffer.hpp>
|
|
#include <common/pointer.hpp>
|
|
|
|
#include <music/scansymbols.hpp>
|
|
#include <music/emitter.hpp>
|
|
#include <music/scanner.hpp>
|
|
#include <music/parser.hpp>
|
|
#include <music/ChordCompiler.hpp>
|
|
#include <music/Random.hpp>
|
|
|
|
|
|
// *********************************************
|
|
// "D-7","G7","C^","Eb-7","Ab7","B-7","E7","Bb-7","Bb7","Db^","C7#9","D7alt","C^#4","Gb^#4","G7#11","F7#11",
|
|
// "Gsus","Ebsus","Dsusb9","F#susb9","Ebsusb9","Ab/Eb","G-",""
|
|
|
|
/*
|
|
ABCDEFG
|
|
#b
|
|
-
|
|
^
|
|
|
|
Note (A-G)
|
|
Degree(^,7,9,None)
|
|
Inflection(Sharp,Flat,None)
|
|
Verb(sus,aug,alt,None)
|
|
Inflection(Sharp,Flat,None)
|
|
Degree(^,4,7,9,11,None)
|
|
|
|
(note1,value)
|
|
(degree1,value)
|
|
(inflection1,value)
|
|
(verb1,value)
|
|
*/
|
|
|
|
void testCompiler();
|
|
Notes getNotes(Scale &scale,int noteCount);
|
|
Notes getNotes(Music::Chord &chord,int noteCount);
|
|
int getCount(void);
|
|
int getDelay(int cNotes);
|
|
|
|
using namespace Music;
|
|
void main()
|
|
{
|
|
// testCompiler();
|
|
MIDIOutputDevice midiOut;
|
|
|
|
Block<Music::Chord> chords;
|
|
Notes notes;
|
|
Music::Chord chord;
|
|
Note root;
|
|
Note third;
|
|
Note fifth;
|
|
Note seventh;
|
|
|
|
DiminishedHalfScale diminishedScale(Note::E);
|
|
|
|
root=diminishedScale.getDegree(Degree::I);
|
|
third=diminishedScale.getDegree(Degree::III);
|
|
fifth=diminishedScale.getDegree(Degree::V);
|
|
|
|
chord.create(root,Chord::ChordType::DominantSeventh);
|
|
::OutputDebugString(chord.toString()+String("\n"));
|
|
chords.insert(&chord);
|
|
chord.create(third,Chord::ChordType::DominantSeventh);
|
|
::OutputDebugString(chord.toString()+String("\n"));
|
|
chords.insert(&chord);
|
|
chord.create(fifth,Chord::ChordType::DominantSeventh);
|
|
::OutputDebugString(chord.toString()+String("\n"));
|
|
chords.insert(&chord);
|
|
chord.create(seventh,Chord::ChordType::DominantSeventh);
|
|
::OutputDebugString(chord.toString()+String("\n"));
|
|
chords.insert(&chord);
|
|
|
|
int octave=3;
|
|
|
|
while(true)
|
|
{
|
|
DiminishedHalfScale diminishedScale(Note(Note::E,octave));
|
|
|
|
for(int index=0;index<chord.size();index++)
|
|
{
|
|
chords[index].play(midiOut,false);
|
|
::OutputDebugString("***************************************\n");
|
|
::OutputDebugString(String("Chord=")+chords[index].toString()+String("\n"));
|
|
::Sleep(250);
|
|
// notes=getNotes(chords[index],getCount()); // get scalar notes (ie) I,III,V,VII
|
|
notes=getNotes(diminishedScale,getCount()+3); // get scalar notes (ie) I,III,V,VII
|
|
notes+=getNotes(chords[index],getCount()); // get chordal notes (ie) 1,3,5,7
|
|
for(int noteIndex=0;noteIndex<notes.size();noteIndex++)
|
|
{
|
|
notes[noteIndex].noteOn(midiOut);
|
|
::Sleep(getDelay(notes.size()));
|
|
notes[noteIndex].noteOff(midiOut);
|
|
}
|
|
chords[index].off(midiOut);
|
|
}
|
|
}
|
|
::MessageBox(0,"Compile",chord.toString(),MB_OK);
|
|
}
|
|
|
|
// All notes should play in 130
|
|
|
|
int getDelay(int notes)
|
|
{
|
|
return 1250/notes;
|
|
}
|
|
|
|
int getCount()
|
|
{
|
|
Random random(5);
|
|
int count=0;
|
|
while(count<3)count=random.random()+1;
|
|
return count;
|
|
}
|
|
|
|
Notes getNotes(Scale &scale,int noteCount)
|
|
{
|
|
Notes notes;
|
|
Random random(scale.size());
|
|
for(int count=0;count<noteCount;count++)
|
|
{
|
|
int index=random.random();
|
|
Note note(scale.getDegree(Degree((Degree::Interval)index)));
|
|
notes.insert(¬e);
|
|
OutputDebugString(note.toString());
|
|
}
|
|
OutputDebugString(String("\n"));
|
|
return notes;
|
|
}
|
|
|
|
Notes getNotes(Music::Chord &chord,int noteCount)
|
|
{
|
|
Notes notes;
|
|
Note note;
|
|
Random random(4);
|
|
for(int count=0;count<noteCount;count++)
|
|
{
|
|
int index=random.random();
|
|
note=Note(chord[index]);
|
|
notes.insert(¬e);
|
|
OutputDebugString(note.toString());
|
|
}
|
|
OutputDebugString(String("\n"));
|
|
return notes;
|
|
}
|
|
|
|
|
|
void testCompiler()
|
|
{
|
|
Block<String> chords;
|
|
|
|
IonianScale ionianScale;
|
|
Note note(Note::GSh);
|
|
Degree degree;
|
|
|
|
degree=ionianScale.getDegree(note);
|
|
if(degree==Degree::None)::OutputDebugString("No degree.");
|
|
else ::OutputDebugString("Found degree.");
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// chords.insert(&String("C^"));
|
|
// chords.insert(&String("Db^"));
|
|
// chords.insert(&String("C^#4"));
|
|
// chords.insert(&String("D7"));
|
|
// chords.insert(&String("D-7"));
|
|
// chords.insert(&String("Cb7#9"));
|
|
// chords.insert(&String("D-7"));
|
|
// chords.insert(&String("G7"));
|
|
// chords.insert(&String("Eb-7"));
|
|
// chords.insert(&String("G-"));
|
|
// chords.insert(&String("Ab7"));
|
|
// chords.insert(&String("B-7"));
|
|
// chords.insert(&String("F#7"));
|
|
// chords.insert(&String("E7"));
|
|
// chords.insert(&String("Bb-7"));
|
|
// chords.insert(&String("Bb7"));
|
|
// chords.insert(&String("C7#9"));
|
|
// chords.insert(&String("Gb^#4"));
|
|
// chords.insert(&String("G7#11"));
|
|
// chords.insert(&String("F7#11"));
|
|
// chords.insert(&String("Ebsus"));
|
|
// chords.insert(&String("Gsus"));
|
|
// chords.insert(&String("E#sus"));
|
|
// chords.insert(&String("Dsusb9"));
|
|
// chords.insert(&String("F#susb9"));
|
|
// chords.insert(&String("Ebsusb9"));
|
|
// chords.insert(&String("A-"));
|
|
// chords.insert(&String("A-b6"));
|
|
// chords.insert(&String("Ah")); for lack of a better system, this is half-diminished, can also do "A-7b5"
|
|
// chords.insert(&String("Ao")); diminished
|
|
|
|
|
|
// chords.insert(&String("C-^")); // C MinorMajor
|
|
|
|
// chords.insert(&String("C-#7")); // C Minor - Sharp 7 a.k.a C Minor Major
|
|
|
|
// chords.insert(&String("C7b9")); // C Minor - Sharp 7 a.k.a C Minor Major
|
|
|
|
|
|
// chords.insert(&String("D7alt")); // this is based on melodic minor scale
|
|
// chords.insert(&String("Ab/Eb"));
|
|
// chords.insert(&String(""));
|
|
|
|
|
|
// chords.insert(&String("Aalt"));
|
|
// chords.insert(&String("A7alt"));
|
|
|
|
// Scanner scanner;
|
|
// Parser parser;
|
|
// scanner.scan(chords[0]);
|
|
// Music::Chord chord;
|
|
// ::OutputDebugString(scanner.toString());
|
|
// parser.parse(scanner,chord);
|
|
|
|
// chords.insert(&String("Esusb9"));
|
|
|
|
// chords.insert(&String("E6"));
|
|
|
|
|
|
|
|
|
|
|
|
ChordCompiler chordCompiler;
|
|
Music::Chord chord;
|
|
|
|
chords.insert(&String("Am7"));
|
|
|
|
|
|
// chords.insert(&String("A-6")); // A minor 6
|
|
// chords.insert(&String("A-7b5")); // A-half diminished a.k.a "B-7b5"
|
|
|
|
// chords.insert(&String("Ah")); // A-half diminished a.k.a "B-7b5"
|
|
// chords.insert(&String("A-7b5")); // A-half diminished a.k.a "B-7b5"
|
|
|
|
|
|
|
|
for(int index=0;index<chords.size();index++)
|
|
{
|
|
if(!chordCompiler.compile(chords[index],chord))::MessageBox(0,"Error Parsing Chord",chords[index].str(),MB_OK);
|
|
::OutputDebugString(chords[index]+String(" = ")+chord.toString()+String("\n"));
|
|
}
|
|
|
|
// MIDIOutputDevice midiOut;
|
|
//chord.play(midiOut);
|
|
|
|
/*
|
|
for(int index=0;index<chords.size();index++)
|
|
{
|
|
if(!scanner.scan(chords[index]))
|
|
::OutputDebugString(String(String("Scan failed for '")+chords[index]+String("'\n")).str());
|
|
break;
|
|
}
|
|
*/
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
/*
|
|
Music::Progression progression;
|
|
|
|
MIDIOutputDevice midiOut;
|
|
Music::Chord chord;
|
|
|
|
Note key(Note::A);
|
|
progression.createProgression(Progression::PIII_VI_II_V,key);
|
|
progression.play(midiOut);
|
|
progression.createProgression(Progression::PV_V,key);
|
|
progression.play(midiOut);
|
|
|
|
|
|
Music::ProgressionManager::createProgression(ProgressionManager::PV_V,progression,key);
|
|
key=key.getParentSecond();
|
|
Music::ProgressionManager::createProgression(ProgressionManager::PV_V,progression2,key);
|
|
progression+=progression2;
|
|
key=key.getParentSecond();
|
|
Music::ProgressionManager::createProgression(ProgressionManager::PV_V,progression2,key);
|
|
progression+=progression2;
|
|
// AeolianScale aeolianScale;
|
|
// aeolianScale.play(midiOut);
|
|
// aeolianScale.playBack(midiOut);
|
|
|
|
/*
|
|
MelodicMinorScale melodicMinorScale;
|
|
Music::Chord melodicMinorChord=melodicMinorScale.getI7Chord();
|
|
melodicMinorChord.play(midiOut);
|
|
::Sleep(750);
|
|
melodicMinorScale.play(midiOut);
|
|
melodicMinorScale.playBack(midiOut);
|
|
::Sleep(750);
|
|
melodicMinorChord.play(midiOut);
|
|
::Sleep(500);
|
|
::OutputDebugString(melodicMinorScale.toString());
|
|
*/
|
|
|
|
// SusFlat9Scale susFlat9Scale(Note::D);
|
|
// susFlat9Scale.play(midiOut);
|
|
// susFlat9Scale.playBack(midiOut);
|
|
// ::OutputDebugString(susFlat9Scale.toString());
|
|
|
|
// LydianAugmentedScale lydianAugmentedScale(Note::DSh);
|
|
// lydianAugmentedScale.play(midiOut);
|
|
// lydianAugmentedScale.playBack(midiOut);
|
|
// ::OutputDebugString(lydianAugmentedScale.toString()+String("\n"));
|
|
|
|
// LydianDominantScale lydianDominantScale;
|
|
// lydianDominantScale.play(midiOut);
|
|
// lydianDominantScale.playBack(midiOut);
|
|
// ::OutputDebugString(lydianDominantScale.toString()+String("\n"));
|
|
|
|
/*
|
|
Locrian2Scale locrian2Scale;
|
|
Music::Chord locrian2Chord=locrian2Scale.getI7Chord();
|
|
::OutputDebugString(locrian2Chord.toString()+String("\n"));
|
|
locrian2Chord.play(midiOut);
|
|
::Sleep(750);
|
|
locrian2Scale.play(midiOut);
|
|
locrian2Scale.playBack(midiOut);
|
|
::Sleep(500);
|
|
locrian2Chord.play(midiOut);
|
|
::Sleep(750);
|
|
::OutputDebugString(locrian2Scale.toString()+String("\n"));
|
|
|
|
AlteredScale alteredScale;
|
|
Music::Chord alteredChord=alteredScale.getI7Chord();
|
|
::OutputDebugString(alteredChord.toString()+String("\n"));
|
|
alteredChord.play(midiOut);
|
|
::Sleep(750);
|
|
alteredScale.play(midiOut);
|
|
alteredScale.playBack(midiOut);
|
|
::OutputDebugString(alteredScale.toString()+String("\n"));
|
|
::Sleep(500);
|
|
alteredChord.play(midiOut);
|
|
::Sleep(750);
|
|
*/
|
|
|