Click here to Skip to main content
15,897,273 members
Articles / Desktop Programming / MFC

Pitch

Rate me:
Please Sign up or sign in to vote.
3.07/5 (9 votes)
9 Jun 20034 min read 99.9K   2K   40  
A music skill builder
// RelDlg.cpp : implementation file
//
#include "stdafx.h"
#include "Pitch.h"
#include "PitchDlg.h"
#include "RelDlg.h"
#include "scrdlg.h"    
#include "Prompt.h"
#include <mmsystem.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define PLAY_BUFFER_LENGTH 128

extern unsigned int RelativeNoteResults[][15];
extern int LowPianoNote;
extern int HighPianoNote;
extern char NoteDescription[];
extern char NoteTable1[];
extern char MidiReturn[];
extern int HighNoteForSoundBlaster;
extern int RelativeX, RelativeY, RelativeWidth, RelativeHeight;
extern BYTE CurrentChannel;
extern BYTE bStatus;      // Midi status byte
extern BYTE bChannel;	   // Midi channel byte
extern BYTE bData1;       // First midi data byte
extern BYTE bData2;       // Second midi data byte//  Play note and wait until it finishes   
extern int NoteWaitTimeLength;
extern BYTE InstrumentNumber;
extern int IncorrectDialogSwitch;
extern HWND myHWND;
extern int currentDialog;

MSG RelativeMessage;                                                            

static char RelativePlayNoteStatus[7];
static int OnlyResetingSwitch = 0;
//static int WaitTypeSwitch = 1;   // 1 for cutoff notes, 2 for delay between notes
static int BypassSelectionAllRoutine = 0;
static int Random1st;
static int Random2nd;
static int RelativeCorrect = 0;
static int RelativeGuesses = 0;
static char IntervalTable[196] = "Unison         "  "Minor 2nd      "
								 "Major 2nd      "  "Minor 3rd      "
								 "Major 3rd      "  "Perfect 4th    "
								 "Diminished 5th "  "Perfect 5th    "
								 "Minor 6th      "  "Major 6th      "
								 "Minor 7th      "  "Major 7th      "
								 "Perfect 8th    " ; 
static char IntervalDescription[128];
static char FirstNoteDescription[32];
static char SecondNoteDescription[32];
static char MidiReturnX[128];
BYTE SecondChannel;
int SecondNoteValue;
int RelativeTimerKey;
int RelativeWaitLength = 250;    // 250 milliseconds
int RelativeTimerWaitSwitch = 0;
int DebugNote;
char DebugChar[5];
int UpDownSwitch = 2;  // 0 = up, 1 = down and 2 = both
int AllSelectionSwitch = 0;    // 0 = off and 1 = on
char charresultR[4];
char score_workR[24];

BOOL ResUnison;		BOOL ResGuessedUnison;
BOOL ResMinor2nd;	BOOL ResGuessedMinor2nd;
BOOL ResMajor2nd;	BOOL ResGuessedMajor2nd;
BOOL ResMinor3rd;	BOOL ResGuessedMinor3rd;
BOOL ResMajor3rd;	BOOL ResGuessedMajor3rd;
BOOL ResPerfect4th;	BOOL ResGuessedPerfect4th;
BOOL ResDiminished5th;	BOOL ResGuessedDiminished5th;
BOOL ResPerfect5th;	BOOL ResGuessedPerfect5th;
BOOL ResMinor6th;	BOOL ResGuessedMinor6th;
BOOL ResMajor6th;	BOOL ResGuessedMajor6th;
BOOL ResMinor7th;	BOOL ResGuessedMinor7th;
BOOL ResMajor7th;	BOOL ResGuessedMajor7th;
BOOL ResPerfect8th;	BOOL ResGuessedPerfect8th;
BOOL ResSelectedAll;
//////////////////////////////////Prototypes/////////////////////////////////
void ChangeRelativeNoteBoxes(int);
void ChangeRelativeSelectedNoteBoxes(int);
void PlayTwoNotes();
/////////////////////////////////////////////////////////////////////////////
// CRelDlg dialog
CRelDlg::CRelDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CRelDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CRelDlg)
	m_relative_high_note = "";
	m_relative_interval = "";
	m_relative_low_note = "";
	m_up = -1;
	m_relative_Low_Scroll_Position = 25;     // Default low is note C2
	m_relative_High_Scroll_Position= 76;     // Default high is E6
	m_relative_Scroll_Min = 1;
	m_relative_Scroll_Max = 104; 
	m_relative_Speed_Scroll_Position= 10;     // Equal to 1 second 
	m_relative_Speed_Scroll_Min = 0;          // 0 means to play notes at the same time
	m_relative_Speed_Scroll_Max = 100; 
	//}}AFX_DATA_INIT
}

void CRelDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CRelDlg)
	DDX_Control(pDX, IDC_RelativeTitle, m_RelativeTitle);
	DDX_Control(pDX, IDC_RelativePlayNotes, m_RelativePlayNotes);
	DDX_Control(pDX, IDC_RelativeScore, m_RelativeScore);
	DDX_Control(pDX, IDC_RELATIVE_SPEED, m_relative_speed);
	DDX_Control(pDX, IDC_RELATIVE_LOW_RANGE, m_relative_low_range);
	DDX_Control(pDX, IDC_RELATIVE_HIGH_RANGE, m_relative_high_range);
	DDX_Text(pDX, IDC_RELATIVE_HIGH_NOTE, m_relative_high_note);
	DDX_Text(pDX, IDC_RELATIVE_INTERVAL, m_relative_interval);
	DDX_Text(pDX, IDC_RELATIVE_LOW_NOTE, m_relative_low_note);
	DDX_Control(pDX, IDC_RELATIVE_MAJOR_2ND, m_relative_major_2nd);
	DDX_Control(pDX, IDC_RELATIVE_MAJOR_3RD, m_relative_major_3rd);
	DDX_Control(pDX, IDC_RELATIVE_MAJOR_6TH, m_relative_major_6th);
	DDX_Control(pDX, IDC_RELATIVE_MAJOR_7TH, m_relative_major_7th);
	DDX_Control(pDX, IDC_RELATIVE_DIMINISHED_5TH, m_relative_diminished_5th);
	DDX_Control(pDX, IDC_RELATIVE_MINOR_2ND, m_relative_minor_2nd);
	DDX_Control(pDX, IDC_RELATIVE_MINOR_3RD, m_relative_minor_3rd);
	DDX_Control(pDX, IDC_RELATIVE_MINOR_6TH, m_relative_minor_6th);
	DDX_Control(pDX, IDC_RELATIVE_MINOR_7TH, m_relative_minor_7th);
	DDX_Control(pDX, IDC_RELATIVE_PERFECT_4TH, m_relative_perfect_4th);
	DDX_Control(pDX, IDC_RELATIVE_PERFECT_5TH, m_relative_perfect_5th);
	DDX_Control(pDX, IDC_RELATIVE_PERFECT_8TH, m_relative_perfect_8th);
	DDX_Control(pDX, IDC_RELATIVE_UNISON, m_relative_unison);
	DDX_Control(pDX, IDC_RELATIVE_SELECTED_UNISON, m_relative_selected_unison);
	DDX_Control(pDX, IDC_RELATIVE_SELECTED_MINOR_2ND, m_relative_selected_minor_2nd);
	DDX_Control(pDX, IDC_RELATIVE_SELECTED_MAJOR_2ND, m_relative_selected_major_2nd);
	DDX_Control(pDX, IDC_RELATIVE_SELECTED_MINOR_3RD, m_relative_selected_minor_3rd);
	DDX_Control(pDX, IDC_RELATIVE_SELECTED_MAJOR_3RD, m_relative_selected_major_3rd);
	DDX_Control(pDX, IDC_RELATIVE_SELECTED_PERFECT_4TH, m_relative_selected_perfect_4th);
	DDX_Control(pDX, IDC_RELATIVE_SELECTED_DIMINISHED_5TH, m_relative_selected_diminished_5th);
	DDX_Control(pDX, IDC_RELATIVE_SELECTED_PERFECT_5TH, m_relative_selected_perfect_5th);
	DDX_Control(pDX, IDC_RELATIVE_SELECTED_MINOR_6TH, m_relative_selected_minor_6th);
	DDX_Control(pDX, IDC_RELATIVE_SELECTED_MAJOR_6TH, m_relative_selected_major_6th);
	DDX_Control(pDX, IDC_RELATIVE_SELECTED_MINOR_7TH, m_relative_selected_minor_7th);
	DDX_Control(pDX, IDC_RELATIVE_SELECTED_MAJOR_7TH, m_relative_selected_major_7th);
	DDX_Control(pDX, IDC_RELATIVE_SELECTED_PERFECT_8TH, m_relative_selected_perfect_8th);
	DDX_Control(pDX, IDC_RELATIVE_SELECTED_ALL, m_relative_selected_all);
	DDX_Radio(pDX, IDC_UP, m_up);
	DDX_Control(pDX, IDC_GetOutOfRelative, m_GetOutOfRelative);
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CRelDlg, CDialog)
	//{{AFX_MSG_MAP(CRelDlg)
	ON_WM_HSCROLL()
	ON_BN_CLICKED(IDC_RELATIVE_SELECTED_UNISON, OnRelativeSelectedUnison)
	ON_BN_CLICKED(IDC_RELATIVE_SELECTED_MINOR_2ND, OnRelativeSelectedMinor2nd)
	ON_BN_CLICKED(IDC_RELATIVE_SELECTED_MAJOR_2ND, OnRelativeSelectedMajor2nd)
	ON_BN_CLICKED(IDC_RELATIVE_SELECTED_MINOR_3RD, OnRelativeSelectedMinor3rd)
	ON_BN_CLICKED(IDC_RELATIVE_SELECTED_MAJOR_3RD, OnRelativeSelectedMajor3rd)
	ON_BN_CLICKED(IDC_RELATIVE_SELECTED_PERFECT_4TH, OnRelativeSelectedPerfect4th)
	ON_BN_CLICKED(IDC_RELATIVE_SELECTED_DIMINISHED_5TH, OnRelativeSelectedDiminished5th)
	ON_BN_CLICKED(IDC_RELATIVE_SELECTED_PERFECT_5TH, OnRelativeSelectedPerfect5th)
	ON_BN_CLICKED(IDC_RELATIVE_SELECTED_MINOR_6TH, OnRelativeSelectedMinor6th)
	ON_BN_CLICKED(IDC_RELATIVE_SELECTED_MAJOR_6TH, OnRelativeSelectedMajor6th)
	ON_BN_CLICKED(IDC_RELATIVE_SELECTED_MINOR_7TH, OnRelativeSelectedMinor7th)
	ON_BN_CLICKED(IDC_RELATIVE_SELECTED_MAJOR_7TH, OnRelativeSelectedMajor7th)
	ON_BN_CLICKED(IDC_RELATIVE_SELECTED_PERFECT_8TH, OnRelativeSelectedPerfect8th)
	ON_BN_CLICKED(IDC_RELATIVE_SELECTED_ALL, OnRelativeSelectedAll)
	ON_BN_CLICKED(IDC_RELATIVE_UNISON, OnRelativeUnison)
	ON_BN_CLICKED(IDC_RELATIVE_MINOR_2ND, OnRelativeMinor2nd)
	ON_BN_CLICKED(IDC_RELATIVE_MAJOR_2ND, OnRelativeMajor2nd)
	ON_BN_CLICKED(IDC_RELATIVE_MINOR_3RD, OnRelativeMinor3rd)
	ON_BN_CLICKED(IDC_RELATIVE_MAJOR_3RD, OnRelativeMajor3rd)
	ON_BN_CLICKED(IDC_RELATIVE_PERFECT_4TH, OnRelativePerfect4th)
	ON_BN_CLICKED(IDC_RELATIVE_DIMINISHED_5TH, OnRelativeDiminished5th)
	ON_BN_CLICKED(IDC_RELATIVE_PERFECT_5TH, OnRelativePerfect5th)
	ON_BN_CLICKED(IDC_RELATIVE_MINOR_6TH, OnRelativeMinor6th)
	ON_BN_CLICKED(IDC_RELATIVE_MAJOR_6TH, OnRelativeMajor6th)
	ON_BN_CLICKED(IDC_RELATIVE_MINOR_7TH, OnRelativeMinor7th)
	ON_BN_CLICKED(IDC_RELATIVE_MAJOR_7TH, OnRelativeMajor7th)
	ON_BN_CLICKED(IDC_RELATIVE_PERFECT_8TH, OnRelativePerfect8th)
	ON_WM_TIMER()
	ON_WM_RBUTTONDOWN()
	ON_WM_RBUTTONUP()
	ON_BN_CLICKED(IDC_UP, OnUp)
	ON_BN_CLICKED(IDC_DOWN, OnDown)
	ON_BN_CLICKED(IDC_UPDOWN, OnUpdown)
	ON_WM_DESTROY()
	ON_BN_CLICKED(IDC_GetOutOfRelative, OnGetOutOfRelative)
	ON_BN_CLICKED(IDC_RelativeScore, OnRelativeScore)
	ON_BN_CLICKED(IDC_RelativePlayNotes, OnRelativePlayNotes)
	ON_MESSAGE(UWM_RelativeButtonMove, OnRelativeButtonMove)
	ON_MESSAGE(UWM_RelativeButtonLeave, OnRelativeButtonLeave)
	ON_WM_CREATE()
	ON_BN_CLICKED(IDC_RelativeTitle, OnRelativeTitle)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CRelDlg message handlers

BEGIN_EVENTSINK_MAP(CRelDlg, CDialog)
    //{{AFX_EVENTSINK_MAP(CRelDlg)
	//}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()
 BOOL CRelDlg::OnInitDialog()                                            
{
	CDialog::OnInitDialog();
	// Set the Relativet window to where it finished last time
	MoveWindow(RelativeX, RelativeY, RelativeWidth, RelativeHeight, TRUE);

	LowPianoNote = 25; 
	HighPianoNote = HighNoteForSoundBlaster;   // Use SoundBlaster as default
	RelativeWaitLength = 250;  // Set default interval speed to 250 milliseconds

	CScrollBar* pSB_Low  = (CScrollBar*) GetDlgItem(IDC_RELATIVE_LOW_RANGE);
	CScrollBar* pSB_High = (CScrollBar*) GetDlgItem(IDC_RELATIVE_HIGH_RANGE); 
	CScrollBar* pSB_Speed = (CScrollBar*) GetDlgItem(IDC_RELATIVE_SPEED);  
    pSB_Low  ->SetScrollRange(m_relative_Scroll_Min, m_relative_Scroll_Max); 
    pSB_High ->SetScrollRange(m_relative_Scroll_Min, m_relative_Scroll_Max); 
    pSB_Speed ->SetScrollRange(m_relative_Speed_Scroll_Min, m_relative_Speed_Scroll_Max); 

    pSB_Low  ->SetScrollPos(m_relative_Low_Scroll_Position);            
    pSB_High ->SetScrollPos(m_relative_High_Scroll_Position);           
    pSB_Speed  ->SetScrollPos(m_relative_Speed_Scroll_Position);        

	strncpy(NoteDescription,NoteTable1 + (m_relative_Low_Scroll_Position-1)*3, 3); 
    m_relative_low_note = NoteDescription; 
	strncpy(NoteDescription,NoteTable1 + (m_relative_High_Scroll_Position-1)*3, 3); 
    m_relative_high_note = NoteDescription; 
	UpdateData(FALSE);
	strcpy(RelativePlayNoteStatus,"Play");
	GetDlgItem(IDC_RelativePlayNotes) ->EnableWindow(FALSE);             
	KillGuessedCheckBoxes();
    UpDownSwitch = 2;
    m_up = 2;    //  Default to up and down intervals
	m_RelativePlayNotes.SetWindowText(RelativePlayNoteStatus);
	m_RelativePlayNotes.SetShade(SHS_SOFTBUMP,6,30);
	m_RelativePlayNotes.SetTextColor(GreenColour);
	m_RelativePlayNotes.SetFont("Signature",24,20);
	m_GetOutOfRelative.SetShade(SHS_SOFTBUMP,6,30);
	m_GetOutOfRelative.SetTextColor(RedColour);
	m_GetOutOfRelative.SetFont("Signature",24,20);
	m_RelativeScore.SetShade(SHS_SOFTBUMP,6,30);
	m_RelativeScore.SetTextColor(BlueColour);
	m_RelativeScore.SetFont("Signature",24,20);

	m_RelativeScore.SetShade(SHS_DIAGSHADE,8,20,5,RGB(55,255,55));


	m_relative_selected_unison.SetShade(SHS_SOFTBUMP,8,30);
	m_relative_selected_minor_2nd.SetShade(SHS_SOFTBUMP,8,30);
	m_relative_selected_major_2nd.SetShade(SHS_SOFTBUMP,8,30);
	m_relative_selected_minor_3rd.SetShade(SHS_SOFTBUMP,8,30);
	m_relative_selected_major_3rd.SetShade(SHS_SOFTBUMP,8,30);
	m_relative_selected_perfect_4th.SetShade(SHS_SOFTBUMP,8,30);
	m_relative_selected_diminished_5th.SetShade(SHS_SOFTBUMP,8,30);
	m_relative_selected_perfect_5th.SetShade(SHS_SOFTBUMP,8,30);
	m_relative_selected_minor_6th.SetShade(SHS_SOFTBUMP,8,30);
	m_relative_selected_major_6th.SetShade(SHS_SOFTBUMP,8,30);
	m_relative_selected_minor_7th.SetShade(SHS_SOFTBUMP,8,30);
	m_relative_selected_major_7th.SetShade(SHS_SOFTBUMP,8,30);
	m_relative_selected_perfect_8th.SetShade(SHS_SOFTBUMP,8,30);
	m_relative_selected_all.SetShade(SHS_SOFTBUMP,8,30);

	m_relative_selected_unison.SetTextColor(RedColour);
	m_relative_selected_minor_2nd.SetTextColor(RedColour);
	m_relative_selected_major_2nd.SetTextColor(RedColour);
	m_relative_selected_minor_3rd.SetTextColor(RedColour);
	m_relative_selected_major_3rd.SetTextColor(RedColour);
	m_relative_selected_perfect_4th.SetTextColor(RedColour);
	m_relative_selected_diminished_5th.SetTextColor(RedColour);
	m_relative_selected_perfect_5th.SetTextColor(RedColour);
	m_relative_selected_minor_6th.SetTextColor(RedColour);
	m_relative_selected_major_6th.SetTextColor(RedColour);
	m_relative_selected_minor_7th.SetTextColor(RedColour);
	m_relative_selected_major_7th.SetTextColor(RedColour);
	m_relative_selected_perfect_8th.SetTextColor(RedColour);
	m_relative_selected_all.SetTextColor(RedColour);
	//  font name, size, weight italic underline for selection
	m_relative_selected_unison.SetFont("Comic Sans MS",24,20,1);
	m_relative_selected_minor_2nd.SetFont("Comic Sans MS",24,20,1);
	m_relative_selected_major_2nd.SetFont("Comic Sans MS",24,20,1);
	m_relative_selected_minor_3rd.SetFont("Comic Sans MS",24,20,1);
	m_relative_selected_major_3rd.SetFont("Comic Sans MS",24,20,1);
	m_relative_selected_perfect_4th.SetFont("Comic Sans MS",24,20,1);
	m_relative_selected_diminished_5th.SetFont("Comic Sans MS",24,20,1);
	m_relative_selected_perfect_5th.SetFont("Comic Sans MS",24,20,1);
	m_relative_selected_minor_6th.SetFont("Comic Sans MS",24,20,1);
	m_relative_selected_major_6th.SetFont("Comic Sans MS",24,20,1);
	m_relative_selected_minor_7th.SetFont("Comic Sans MS",24,20,1);
	m_relative_selected_major_7th.SetFont("Comic Sans MS",24,20,1);
	m_relative_selected_perfect_8th.SetFont("Comic Sans MS",24,20,1);
	m_relative_selected_all.SetFont("Comic Sans MS",24,20,1);
	//  font name, size, weight for playing
	m_relative_unison.SetFont("Comic Sans MS",24,20,1);
	m_relative_minor_2nd.SetFont("Comic Sans MS",24,20,1);
	m_relative_major_2nd.SetFont("Comic Sans MS",24,20,1);
	m_relative_minor_3rd.SetFont("Comic Sans MS",24,20,1);
	m_relative_major_3rd.SetFont("Comic Sans MS",24,20,1);
	m_relative_perfect_4th.SetFont("Comic Sans MS",24,20,1);
	m_relative_diminished_5th.SetFont("Comic Sans MS",24,20,1);
	m_relative_perfect_5th.SetFont("Comic Sans MS",24,20,1);
	m_relative_minor_6th.SetFont("Comic Sans MS",24,20,1);
	m_relative_major_6th.SetFont("Comic Sans MS",24,20,1);
	m_relative_minor_7th.SetFont("Comic Sans MS",24,20,1);
	m_relative_major_7th.SetFont("Comic Sans MS",24,20,1);
	m_relative_perfect_8th.SetFont("Comic Sans MS",24,20,1);

	m_RelativeTitle.SetShade(SHS_METAL,8,30);
	m_RelativeTitle.SetTextColor(PurpleColour);
	m_RelativeTitle.SetFont("Signature",32,20);
	m_RelativeTitle.SetWindowText("Relative Pitch");


	UpdateData(FALSE);

	currentDialog = RelativeDialog;

	
	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CRelDlg::OnRelativePlayNotes() 
{
long MidiErr = 0;
int RandomNote = 0;
int signed NoteDifference; 

int i, InfiniteLoopCounter1, InfiniteLoopCounter2;
InfiniteLoopCounter1 = 0;
InfiniteLoopCounter2 = 0;
char Alpha[5];
	CFile ResultsFile;
	// Use GetARandomNumber member of CPitchDlg as a friend
	CPitchDlg GetNumb;

if (strcmp(RelativePlayNoteStatus,"Replay"))
	{} else
	{
		RelativeReplayNotes();
		goto PlayNotesExit;
	}

	NoteDifference = HighPianoNote-LowPianoNote;
	if (NoteDifference < 0) {NoteDifference = NoteDifference * -1;};  // Ensure positive
	if (NoteDifference < 12)                                               
		{MessageBox("Range too small for interval testing.");                 
		goto PlayNotesExit;};
	// Disable all selection boxes
	ChangeRelativeSelectedNoteBoxes(FALSE);
	// Enable any guessing boxes that have relative selection boxes enabled
	EnableGuessedCheckBoxes();
	// Set the ticks off in the guessing boxes
	OnlyResetingSwitch = 1;
	m_relative_unison.SetCheck(FALSE);
	m_relative_minor_2nd.SetCheck(FALSE);
	m_relative_major_2nd.SetCheck(FALSE);
	m_relative_minor_3rd.SetCheck(FALSE);
	m_relative_major_3rd.SetCheck(FALSE);
	m_relative_perfect_4th.SetCheck(FALSE);
	m_relative_diminished_5th.SetCheck(FALSE);
	m_relative_perfect_5th.SetCheck(FALSE);
	m_relative_minor_6th.SetCheck(FALSE);
	m_relative_major_6th.SetCheck(FALSE);
	m_relative_minor_7th.SetCheck(FALSE);
	m_relative_major_7th.SetCheck(FALSE);
	m_relative_perfect_8th.SetCheck(FALSE);
   OnlyResetingSwitch = 0;
	m_relative_interval = "";
	UpdateData(FALSE);
TopOfFirstNote:			
	InfiniteLoopCounter1++; InfiniteLoopCounter2 = 0;
	if (InfiniteLoopCounter1 > 200)
		{
		//MessageBox("Can not randomly create an interval in this range");
		itoa(LowPianoNote,Alpha,10);
		MessageBox(Alpha);                                                    
		itoa(HighPianoNote,Alpha,10);
		MessageBox(Alpha);                                                    
		goto PlayNotesExit;
		};  //Finding any interval is impossible, so tell user and get out
	if (LowPianoNote < HighPianoNote)
		{RandomNote = GetNumb.GetARandomNumber(LowPianoNote,HighPianoNote);} 
	else
		{RandomNote = GetNumb.GetARandomNumber(HighPianoNote,LowPianoNote);} ;
    Random1st = RandomNote;
TopOfSecondNote:
	InfiniteLoopCounter2++;
	if (InfiniteLoopCounter2 > 100)
		{goto TopOfFirstNote;};  //Finding second note is impossible, retry the first note

	//  Second note must be within an octave (plus or minus) of 1st note	
	//  Need a random number from 0-24 which we will use as -12 to -1 and 0 to 12
	//  This will then be used to adjust the first note.
	//  If it is not a valid note, another search will be done.
	//  If it is valid, it is used as the 2nd note.
	if (UpDownSwitch == 0) 
		{RandomNote = GetNumb.GetARandomNumber(0,12);   // Up only		 
			Random2nd = (Random1st+RandomNote );};
	if (UpDownSwitch == 1) 
		{RandomNote = GetNumb.GetARandomNumber(0,12);   // Down only	
			Random2nd = (Random1st-RandomNote );};
	if (UpDownSwitch == 2) 
		{RandomNote = GetNumb.GetARandomNumber(0,24);    // Up and Down!  
 		 if (RandomNote > 11)
			{Random2nd = (Random1st+RandomNote -12);}    // 12 to 24 becomes 0 to 12
    	 else
    		{Random2nd = (Random1st-RandomNote-1);};     // 0 to 11 becomes -1 to -12
        };
    DebugNote = RandomNote;

//  Following test is a bit messy as user could have high and low note notes reversed. 
	if ((LowPianoNote < HighPianoNote)
		& ((Random2nd > HighPianoNote) | (Random2nd < LowPianoNote)))
			{goto TopOfSecondNote;};
	if ((LowPianoNote > HighPianoNote)
		& ((Random2nd < HighPianoNote) | (Random2nd > LowPianoNote)))
			{goto TopOfSecondNote;};
//Check to see that both notes create one of the intervals user selected
	NoteDifference = Random1st - Random2nd;
	if (NoteDifference < 0)
	   {NoteDifference = NoteDifference * -1;};  // Ensure positive
    if (ResUnison & (NoteDifference == 0))
	    {goto IntervalIsValid;};
    if (ResMinor2nd & (NoteDifference == 1))
	    {goto IntervalIsValid;};
    if (ResMajor2nd & (NoteDifference == 2))
	    {goto IntervalIsValid;};
    if (ResMinor3rd & (NoteDifference == 3))
	    {goto IntervalIsValid;};
    if (ResMajor3rd & (NoteDifference == 4))
	    {goto IntervalIsValid;};
    if (ResPerfect4th & (NoteDifference == 5))
	    {goto IntervalIsValid;};
    if (ResDiminished5th & (NoteDifference == 6))
	    {goto IntervalIsValid;};
    if (ResPerfect5th & (NoteDifference == 7))
	    {goto IntervalIsValid;};
    if (ResMinor6th & (NoteDifference == 8))
	    {goto IntervalIsValid;};
    if (ResMajor6th & (NoteDifference == 9))
	    {goto IntervalIsValid;};
    if (ResMinor7th & (NoteDifference == 10))
	    {goto IntervalIsValid;};
    if (ResMajor7th & (NoteDifference == 11))
	    {goto IntervalIsValid;};
    if (ResPerfect8th & (NoteDifference == 12))
	    {goto IntervalIsValid;};
    goto TopOfSecondNote;   // Must try for the 2nd note again.
IntervalIsValid:	    
		//    Play the two notes
	PlayTwoNotes();
    UpdateData(FALSE);
// Make the interval box the centrepiece
//    GetDlgItem(IDC_RELATIVE_INTERVAL) ->SetFocus();	
// Recalculate all the check boxes
	for (i = 1;i < 13; i++)
		{A_Selection_Clicked_Routine(i);};

 	//  Do not allow another set of notes until user responds to this set
	strcpy(RelativePlayNoteStatus,"Replay");
	m_RelativePlayNotes.SetWindowText(RelativePlayNoteStatus);
PlayNotesExit:
	NoteDifference = 0;	
}

void CRelDlg::PlayTwoNotes()
{
long MidiErr = 0;
    strncpy(NoteDescription,NoteTable1 + (Random1st-1)*3, 3); 
	strcpy(FirstNoteDescription,NoteDescription);
			    	
    strncpy(NoteDescription,NoteTable1 + (Random2nd-1)*3, 3); 
	strcpy(SecondNoteDescription,NoteDescription);
	SecondNoteValue = 0;
	if (RelativeWaitLength == 0)
	{
		MidiErr = PlayRelativeNote(Random1st, Random2nd); // Play notes together
	}
	else
	{
		MidiErr = PlayRelativeNote(Random1st, SecondNoteValue); // Play 1st note of pair
		// delay between notes  
		DoRelativeWait(RelativeWaitLength); 
		//  Now play the 2nd note of the set	
		MidiErr = PlayRelativeNote(Random2nd, SecondNoteValue); // Play 2nd note of pair              
	}
}
void CRelDlg::RelativeReplayNotes() 
{
long MidiErr = 0;
 	//WaitTypeSwitch = 1;
	if (RelativeWaitLength == 0)
	{		
		MidiErr = PlayRelativeNote(Random1st, Random2nd); // Play 1st note of pair
	}
	else
	{
		MidiErr = PlayRelativeNote(Random1st, SecondNoteValue); // Play 1st note of pair
		DoRelativeWait(RelativeWaitLength);
		//WaitTypeSwitch = 1;
		MidiErr = PlayRelativeNote(Random2nd, SecondNoteValue); // Play 2nd note of pair
    }
}

void CRelDlg::OnRelativeScore() 
{
char score_message[64];
char score_analysis[1681];
char score_work1[280], score_work2[280];
char charwork[12];
char note_work[64] = "", note_compressed[16];
CScRDlg dlg;
	strcpy(score_message, "You have answered ");
	itoa(RelativeCorrect,charresultR,10);
	strcat(score_message,charresultR);
	strcat(score_message," correctly out of ");
	itoa(RelativeGuesses,charresultR,10);
	strcat(score_message,charresultR);
	strcat(score_message," attempts.");	
	dlg.m_relative_score_summary = score_message;

	strcpy(score_analysis,"");
	for (int i = 0; i < 13; i++)
		{
	    if (RelativeNoteResults[i][0] != 0)
	    	{
	    	strcpy(note_work,""); strcpy(charwork,"");
	    	strncpy(note_work,IntervalTable + (i)*15, 14);     
			strcat(score_analysis,note_work);              
			strcat(score_analysis,"(");
			itoa(RelativeNoteResults[i][0],charwork,10);
			strcat(score_analysis,charwork);
			strcat(score_analysis,") ");
		
			strcat(score_analysis,"Correct(");
			itoa(RelativeNoteResults[i][1],charwork,10);
			strcat(score_analysis,charwork);
			strcat(score_analysis,")   ");
			strcpy(score_work1,"");
			for (int j = 2; j < 15; j++) // Go through columns 3-15
				{
			     	if (RelativeNoteResults[i][j] != 0)
			     		{
			     		 	if (i+2 != j)
			     		 	{
			     		 		strcpy(note_work,"");
			     		 		strcpy(charwork,"");
			     		 		strncpy(note_work,IntervalTable + (j-2)*15, 14);
			     		 		CompressString(note_work,note_compressed);
			     		 		strcat(score_work1,note_compressed);
			     		 		strcat(score_work1,"(");
						 		itoa(RelativeNoteResults[i][j],charwork,10);
						 		strcat(score_work1,charwork);
						 		strcat(score_work1,"),");
						 	}
						}
				}
			CompressString(score_work1,score_work2);
			strcat(score_analysis,score_work2);
			strcat(score_analysis,"\n\n");
          }
    }
	dlg.m_relative_score_details = score_analysis;
	UpdateData(FALSE);
	dlg.DoModal();	
}
////////////////////////////////////////////////////////////////////////////////////
/////Compress a string from left to right allowing only one continuous space////////
////////////////////////////////////////////////////////////////////////////////////
void CRelDlg::CompressString(char * InputString, char * OutputString)
{
      
    strcpy(OutputString,"");   // Clear before processing

    while ( *InputString != '\0')
    	{
         if (*InputString == ' ')
         	{
         		*OutputString++ = *InputString++;  // Move first space across
         		while (*InputString == ' ')
         			{InputString++;}               // Bypass remaining spaces
         	}
         else
     	 	{*OutputString++ = *InputString++;};
        }
 // Added special code to ensure we do not end string on a comma or a blank
        *OutputString--;  // Point back to last character output
//        while ((*OutputString == ',') | (**OutputString == ' '))
//        		{*OutputString--;};
        
//        *++OutputString = '\0'; // Indicate end of new string
}

void CRelDlg::OnRelativeSelectedAll(short FAR* Value) 
{
	
bool CheckCondition;	
int i;

	if (BypassSelectionAllRoutine == 1) goto OnClickRelativeSelectionAllExit;
	OnlyResetingSwitch = 1;

//    if (m_relative_selected_all.GetCheck())    // Is currently off?                
    if (AllSelectionSwitch == 0)    // Is currently off?                
    {                               // yes                              
		CheckCondition = TRUE;
    	//ChangeRelativeSelectedNoteBoxes(TRUE);         
		m_relative_selected_unison.SetCheck(TRUE);
		m_relative_selected_minor_2nd.SetCheck(TRUE);
		m_relative_selected_major_2nd.SetCheck(TRUE);
		m_relative_selected_minor_3rd.SetCheck(TRUE);
		m_relative_selected_major_3rd.SetCheck(TRUE);
		m_relative_selected_perfect_4th.SetCheck(TRUE);
		m_relative_selected_diminished_5th.SetCheck(TRUE);
		m_relative_selected_perfect_5th.SetCheck(TRUE);
		m_relative_selected_minor_6th.SetCheck(TRUE);
		m_relative_selected_major_6th.SetCheck(TRUE);
		m_relative_selected_minor_7th.SetCheck(TRUE);
		m_relative_selected_major_7th.SetCheck(TRUE);
		m_relative_selected_perfect_8th.SetCheck(TRUE);
		m_relative_selected_all.SetCheck(TRUE);

		m_relative_selected_unison.SetTextColor(GreenColour);
		m_relative_selected_minor_2nd.SetTextColor(GreenColour);
		m_relative_selected_major_2nd.SetTextColor(GreenColour);
		m_relative_selected_minor_3rd.SetTextColor(GreenColour);
		m_relative_selected_major_3rd.SetTextColor(GreenColour);
		m_relative_selected_perfect_4th.SetTextColor(GreenColour);
		m_relative_selected_diminished_5th.SetTextColor(GreenColour);
		m_relative_selected_perfect_5th.SetTextColor(GreenColour);
		m_relative_selected_minor_6th.SetTextColor(GreenColour);
		m_relative_selected_major_6th.SetTextColor(GreenColour);
		m_relative_selected_minor_7th.SetTextColor(GreenColour);
		m_relative_selected_major_7th.SetTextColor(GreenColour);
		m_relative_selected_perfect_8th.SetTextColor(GreenColour);
		m_relative_selected_all.SetTextColor(GreenColour);
		
		
		AllSelectionSwitch = 1;
		
		
	
	
	}
	else            // no, it is currently on
    {
		CheckCondition = FALSE;
    	//ChangeRelativeSelectedNoteBoxes(FALSE);         
		m_relative_selected_unison.SetCheck(FALSE);
		m_relative_selected_minor_2nd.SetCheck(FALSE);
		m_relative_selected_major_2nd.SetCheck(FALSE);
		m_relative_selected_minor_3rd.SetCheck(FALSE);
		m_relative_selected_major_3rd.SetCheck(FALSE);
		m_relative_selected_perfect_4th.SetCheck(FALSE);
		m_relative_selected_diminished_5th.SetCheck(FALSE);
		m_relative_selected_perfect_5th.SetCheck(FALSE);
		m_relative_selected_minor_6th.SetCheck(FALSE);
		m_relative_selected_major_6th.SetCheck(FALSE);
		m_relative_selected_minor_7th.SetCheck(FALSE);
		m_relative_selected_major_7th.SetCheck(FALSE);
		m_relative_selected_perfect_8th.SetCheck(FALSE);
		m_relative_selected_all.SetCheck(FALSE);

		m_relative_selected_unison.SetTextColor(RedColour);
		m_relative_selected_minor_2nd.SetTextColor(RedColour);
		m_relative_selected_major_2nd.SetTextColor(RedColour);
		m_relative_selected_minor_3rd.SetTextColor(RedColour);
		m_relative_selected_major_3rd.SetTextColor(RedColour);
		m_relative_selected_perfect_4th.SetTextColor(RedColour);
		m_relative_selected_diminished_5th.SetTextColor(RedColour);
		m_relative_selected_perfect_5th.SetTextColor(RedColour);
		m_relative_selected_minor_6th.SetTextColor(RedColour);
		m_relative_selected_major_6th.SetTextColor(RedColour);
		m_relative_selected_minor_7th.SetTextColor(RedColour);
		m_relative_selected_major_7th.SetTextColor(RedColour);
		m_relative_selected_perfect_8th.SetTextColor(RedColour);
		m_relative_selected_all.SetTextColor(RedColour);
		
		AllSelectionSwitch = 0;
		

		TurnOffAllSelected();
	};
OnClickRelativeSelectionAllExit:

	// Recalculate all the check boxes
	for (i = 1;i < 14; i++)
		{A_Selection_Clicked_Routine(i);};

	OnlyResetingSwitch = 0;
	BypassSelectionAllRoutine = 0;	
	GetDlgItem(IDC_RelativePlayNotes) ->EnableWindow(CheckCondition);

	ResSelectedAll = CheckCondition;


}
void CRelDlg::OnRelativeSelectedUnison(short FAR* Value) 
{A_Selection_Clicked_Routine(1);}

void CRelDlg::OnRelativeSelectedMinor2nd(short FAR* Value) 
{A_Selection_Clicked_Routine(2);}

void CRelDlg::OnRelativeSelectedMajor2nd(short FAR* Value) 
{A_Selection_Clicked_Routine(3);}

void CRelDlg::OnRelativeSelectedMinor3rd(short FAR* Value) 
{A_Selection_Clicked_Routine(4);}

void CRelDlg::OnRelativeSelectedMajor3rd(short FAR* Value) 
{A_Selection_Clicked_Routine(5);}

void CRelDlg::OnRelativeSelectedPerfect4th(short FAR* Value) 
{A_Selection_Clicked_Routine(6);}

void CRelDlg::OnRelativeSelectedDiminished5th(short FAR* Value) 
{A_Selection_Clicked_Routine(7);}

void CRelDlg::OnRelativeSelectedPerfect5th(short FAR* Value) 
{A_Selection_Clicked_Routine(8);}

void CRelDlg::OnRelativeSelectedMinor6th(short FAR* Value) 
{A_Selection_Clicked_Routine(9);}

void CRelDlg::OnRelativeSelectedMajor6th(short FAR* Value) 
{A_Selection_Clicked_Routine(10);}

void CRelDlg::OnRelativeSelectedMinor7th(short FAR* Value) 
{A_Selection_Clicked_Routine(11);}

void CRelDlg::OnRelativeSelectedMajor7th(short FAR* Value) 
{A_Selection_Clicked_Routine(12);}

void CRelDlg::OnRelativeSelectedPerfect8th(short FAR* Value) 
{A_Selection_Clicked_Routine(13);}

void CRelDlg::A_Selection_Clicked_Routine(int LocalNoteSwitch)
{
	ResUnison = m_relative_selected_unison.GetCheck();
	ResMinor2nd = m_relative_selected_minor_2nd.GetCheck();
	ResMajor2nd = m_relative_selected_major_2nd.GetCheck();
	ResMinor3rd = m_relative_selected_minor_3rd.GetCheck();
	ResMajor3rd = m_relative_selected_major_3rd.GetCheck();
	ResPerfect4th = m_relative_selected_perfect_4th.GetCheck();
	ResDiminished5th = m_relative_selected_diminished_5th.GetCheck();
	ResPerfect5th = m_relative_selected_perfect_5th.GetCheck();
	ResMinor6th = m_relative_selected_minor_6th.GetCheck();
	ResMajor6th = m_relative_selected_major_6th.GetCheck();
	ResMinor7th = m_relative_selected_minor_7th.GetCheck();
	ResMajor7th = m_relative_selected_major_7th.GetCheck();
	ResPerfect8th = m_relative_selected_perfect_8th.GetCheck();
	ResSelectedAll = m_relative_selected_all.GetCheck();

	
    switch (LocalNoteSwitch)
    	{
    		case 1:
    		if (ResUnison)
					{m_relative_selected_unison.SetTextColor(GreenColour);
					m_relative_unison.SetTextColor(GreenColour);}
			else
			{m_relative_selected_unison.SetTextColor(RedColour);
					m_relative_unison.SetTextColor(RedColour);
					TurnOffAllSelected();};
                break;
    		case 2:
    		if (ResMinor2nd)
				{m_relative_selected_minor_2nd.SetTextColor(GreenColour);
					m_relative_minor_2nd.SetTextColor(GreenColour);}
			else
				{m_relative_selected_minor_2nd.SetTextColor(RedColour);
					m_relative_minor_2nd.SetTextColor(RedColour);
					TurnOffAllSelected();};
                break;
    		case 3:
    		if (ResMajor2nd)
				{m_relative_selected_major_2nd.SetTextColor(GreenColour);
					m_relative_major_2nd.SetTextColor(GreenColour);}
			else
				{m_relative_selected_major_2nd.SetTextColor(RedColour);
					m_relative_major_2nd.SetTextColor(RedColour);
					TurnOffAllSelected();};
                break;
    		case 4:
    		if (ResMinor3rd)
				{m_relative_selected_minor_3rd.SetTextColor(GreenColour);
					m_relative_minor_3rd.SetTextColor(GreenColour);}
			else
				{m_relative_selected_minor_3rd.SetTextColor(RedColour);
					m_relative_minor_3rd.SetTextColor(RedColour);
					TurnOffAllSelected();};
                break;
    		case 5:
    		if (ResMajor3rd)
				{m_relative_selected_major_3rd.SetTextColor(GreenColour);
					m_relative_major_3rd.SetTextColor(GreenColour);}
			else
				{m_relative_selected_major_3rd.SetTextColor(RedColour);
					m_relative_major_3rd.SetTextColor(RedColour);
					TurnOffAllSelected();};
                break;
    		case 6:
    		if (ResPerfect4th)
				{m_relative_selected_perfect_4th.SetTextColor(GreenColour);
					m_relative_perfect_4th.SetTextColor(GreenColour);}
			else
				{m_relative_selected_perfect_4th.SetTextColor(RedColour);
					m_relative_perfect_4th.SetTextColor(RedColour);
					TurnOffAllSelected();};
                break;
    		case 7:
    		if (ResDiminished5th)
				{m_relative_selected_diminished_5th.SetTextColor(GreenColour);
					m_relative_diminished_5th.SetTextColor(GreenColour);}
			else
				{m_relative_selected_diminished_5th.SetTextColor(RedColour);
					m_relative_diminished_5th.SetTextColor(RedColour);
					TurnOffAllSelected();};
                break;
    		case 8:
    		if (ResPerfect5th)
				{m_relative_selected_perfect_5th.SetTextColor(GreenColour);
					m_relative_perfect_5th.SetTextColor(GreenColour);}
			else
				{m_relative_selected_perfect_5th.SetTextColor(RedColour);
					m_relative_perfect_5th.SetTextColor(RedColour);
					TurnOffAllSelected();};
                break;
    		case 9:
    		if (ResMinor6th)
				{m_relative_selected_minor_6th.SetTextColor(GreenColour);
					m_relative_minor_6th.SetTextColor(GreenColour);}
			else
				{m_relative_selected_minor_6th.SetTextColor(RedColour);
					m_relative_minor_6th.SetTextColor(RedColour);
					TurnOffAllSelected();};
                break;
    		case 10:
    		if (ResMajor6th)
				{m_relative_selected_major_6th.SetTextColor(GreenColour);
					m_relative_major_6th.SetTextColor(GreenColour);}
			else
				{m_relative_selected_major_6th.SetTextColor(RedColour);
					m_relative_major_6th.SetTextColor(RedColour);
					TurnOffAllSelected();};
                break;
    		case 11:
    		if (ResMinor7th)
				{m_relative_selected_minor_7th.SetTextColor(GreenColour);
					m_relative_minor_7th.SetTextColor(GreenColour);}
			else
				{m_relative_selected_minor_7th.SetTextColor(RedColour);
					m_relative_minor_7th.SetTextColor(RedColour);
					TurnOffAllSelected();};
                break;
    		case 12:
    		if (ResMajor7th)
				{m_relative_selected_major_7th.SetTextColor(GreenColour);
					m_relative_major_7th.SetTextColor(GreenColour);}
			else
				{m_relative_selected_major_7th.SetTextColor(RedColour);
					m_relative_major_7th.SetTextColor(RedColour);
					TurnOffAllSelected();};
                break;
    		case 13:
    		if (ResPerfect8th)
				{m_relative_selected_perfect_8th.SetTextColor(GreenColour);
					m_relative_perfect_8th.SetTextColor(GreenColour);}
			else
				{m_relative_selected_perfect_8th.SetTextColor(RedColour);
					m_relative_perfect_8th.SetTextColor(RedColour);
					TurnOffAllSelected();};
                break;
		}	// End of switch processing         
	
	
	
	strcpy(RelativePlayNoteStatus,"Play");
	m_RelativePlayNotes.SetWindowText(RelativePlayNoteStatus);
	//  If any interval boxes are true, allow PlayNote button to be pushed
	if (ResUnison     | ResMinor2nd   | ResMajor2nd      | ResMinor3rd | 
		ResMajor3rd   | ResPerfect4th | ResDiminished5th | ResPerfect5th |           
		ResMinor6th   | ResMajor6th   | ResMinor7th      | ResMajor7th |             
		ResPerfect8th)	           
			{GetDlgItem(IDC_RelativePlayNotes) ->EnableWindow(TRUE);}            
	else
			{GetDlgItem(IDC_RelativePlayNotes) ->EnableWindow(FALSE);};

	// If all check boxes are on, set the 'All' box to green, etc.
	if (ResUnison   & ResMinor2nd   & ResMajor2nd      & ResMinor3rd &
		ResMajor3rd & ResPerfect4th & ResDiminished5th & ResPerfect5th &
		ResMinor6th & ResMajor6th   & ResMinor7th      & ResMajor7th &
		ResPerfect8th)	
		{
		BypassSelectionAllRoutine = 1;
		m_relative_selected_all.SetTextColor(GreenColour);
		m_relative_selected_all.SetCheck(TRUE);
		BypassSelectionAllRoutine = 0;
	    AllSelectionSwitch = 1;
    	} 
	else
		{
		BypassSelectionAllRoutine = 0;
		m_relative_selected_all.SetTextColor(RedColour);
		m_relative_selected_all.SetCheck(FALSE);
		BypassSelectionAllRoutine = 1;
	    AllSelectionSwitch = 0;
    	}; 


}

void CRelDlg::OnRelativeUnison(short FAR* Value) 
{A_Guess_Clicked_Routine(0);}

void CRelDlg::OnRelativeMinor2nd(short FAR* Value) 
{A_Guess_Clicked_Routine(1);}

void CRelDlg::OnRelativeMajor2nd(short FAR* Value) 
{A_Guess_Clicked_Routine(2);}

void CRelDlg::OnRelativeMinor3rd(short FAR* Value) 
{A_Guess_Clicked_Routine(3);}

void CRelDlg::OnRelativeMajor3rd(short FAR* Value) 
{A_Guess_Clicked_Routine(4);}

void CRelDlg::OnRelativePerfect4th(short FAR* Value) 
{A_Guess_Clicked_Routine(5);}

void CRelDlg::OnRelativeDiminished5th(short FAR* Value) 
{A_Guess_Clicked_Routine(6);}

void CRelDlg::OnRelativePerfect5th(short FAR* Value) 
{A_Guess_Clicked_Routine(7);}

void CRelDlg::OnRelativeMinor6th(short FAR* Value) 
{A_Guess_Clicked_Routine(8);}

void CRelDlg::OnRelativeMajor6th(short FAR* Value) 
{A_Guess_Clicked_Routine(9);}

void CRelDlg::OnRelativeMinor7th(short FAR* Value) 
{A_Guess_Clicked_Routine(10);}

void CRelDlg::OnRelativeMajor7th(short FAR* Value) 
{A_Guess_Clicked_Routine(11);}

void CRelDlg::OnRelativePerfect8th(short FAR* Value) 
{A_Guess_Clicked_Routine(12);}
//
//   Following function is called when a user presses one of the 
//   enabled 'play' buttons
//
void CRelDlg::A_Guess_Clicked_Routine(int LocalNoteSwitch)
{
int RandomWork= 0;    
//LocalNoteSwitch--;
 	if (OnlyResetingSwitch == 0)
       {
		UpdateData(TRUE);
		// Create a variable for each check box
		RandomWork = Random2nd - Random1st;
    	if (RandomWork < 0)                 //   Only interested in a positive result
    		{RandomWork = RandomWork * -1;};
    	RelativeGuesses++;
        RelativeNoteResults[RandomWork][0]++; //  This increases the total for note played 
   		strcpy(IntervalDescription,"Wrong, interval was ");
    	strncat(IntervalDescription,IntervalTable + (RandomWork)*15, 15); 
    	strcat(IntervalDescription,"\nFirst note was ");
    	strcat(IntervalDescription,FirstNoteDescription);
    	strcat(IntervalDescription,"\nSecond note was ");
    	strcat(IntervalDescription,SecondNoteDescription);
    	if (RandomWork == LocalNoteSwitch)                    	
    		{strcpy(IntervalDescription,"Correct");
    	 	RelativeCorrect++;
    	 	RelativeNoteResults[RandomWork][1]++;
    		};
		RelativeNoteResults[RandomWork][LocalNoteSwitch + 2]++; // Increase total user guessed
		m_relative_interval = IntervalDescription;
    	UpdateData(FALSE);
		GetDlgItem(IDC_RELATIVE_INTERVAL) ->ShowWindow(SW_SHOW);              
    	GetDlgItem(IDC_RelativePlayNotes) ->EnableWindow(TRUE);         
				
		strcpy(RelativePlayNoteStatus,"Play");
		m_RelativePlayNotes.SetWindowText(RelativePlayNoteStatus);
    	// Disable all guess boxes until another note sequence is played                 			
		m_relative_unison.EnableWindow(FALSE);
		m_relative_minor_2nd.EnableWindow(FALSE);
		m_relative_major_2nd.EnableWindow(FALSE);
		m_relative_minor_3rd.EnableWindow(FALSE);
		m_relative_major_3rd.EnableWindow(FALSE);
		m_relative_perfect_4th.EnableWindow(FALSE);
		m_relative_diminished_5th.EnableWindow(FALSE);
		m_relative_perfect_5th.EnableWindow(FALSE);
		m_relative_minor_6th.EnableWindow(FALSE);
		m_relative_major_6th.EnableWindow(FALSE);
		m_relative_minor_7th.EnableWindow(FALSE);
		m_relative_major_7th.EnableWindow(FALSE);
		m_relative_perfect_8th.EnableWindow(FALSE);
	// Make selection boxes available for ticking
		EnableSelectionCheckBoxes();
	}	
}

void CRelDlg::OnGetOutOfRelative() 
{
	CDialog::OnOK();
}

void CRelDlg::ChangeRelativeNoteBoxes(int ChangeType)
{
	GetDlgItem(IDC_RELATIVE_UNISON) ->EnableWindow(ChangeType);            
	GetDlgItem(IDC_RELATIVE_MINOR_2ND) ->EnableWindow(ChangeType);         
	GetDlgItem(IDC_RELATIVE_MAJOR_2ND) ->EnableWindow(ChangeType);         
	GetDlgItem(IDC_RELATIVE_MINOR_3RD) ->EnableWindow(ChangeType);         
	GetDlgItem(IDC_RELATIVE_MAJOR_3RD) ->EnableWindow(ChangeType);         
	GetDlgItem(IDC_RELATIVE_PERFECT_4TH) ->EnableWindow(ChangeType);       
	GetDlgItem(IDC_RELATIVE_DIMINISHED_5TH) ->EnableWindow(ChangeType);    
	GetDlgItem(IDC_RELATIVE_PERFECT_5TH) ->EnableWindow(ChangeType);       
	GetDlgItem(IDC_RELATIVE_MINOR_6TH) ->EnableWindow(ChangeType);         
	GetDlgItem(IDC_RELATIVE_MAJOR_6TH) ->EnableWindow(ChangeType);         
	GetDlgItem(IDC_RELATIVE_MINOR_7TH) ->EnableWindow(ChangeType);         
	GetDlgItem(IDC_RELATIVE_MAJOR_7TH) ->EnableWindow(ChangeType);         
	GetDlgItem(IDC_RELATIVE_PERFECT_8TH) ->EnableWindow(ChangeType);       
	GetDlgItem(IDC_RELATIVE_SELECTED_ALL) ->EnableWindow(ChangeType);       
}

void CRelDlg::ChangeRelativeSelectedNoteBoxes(int ChangeType)
{
	GetDlgItem(IDC_RELATIVE_SELECTED_UNISON) ->EnableWindow(ChangeType);            
	GetDlgItem(IDC_RELATIVE_SELECTED_MINOR_2ND) ->EnableWindow(ChangeType);         
	GetDlgItem(IDC_RELATIVE_SELECTED_MAJOR_2ND) ->EnableWindow(ChangeType);         
	GetDlgItem(IDC_RELATIVE_SELECTED_MINOR_3RD) ->EnableWindow(ChangeType);         
	GetDlgItem(IDC_RELATIVE_SELECTED_MAJOR_3RD) ->EnableWindow(ChangeType);         
	GetDlgItem(IDC_RELATIVE_SELECTED_PERFECT_4TH) ->EnableWindow(ChangeType);       
	GetDlgItem(IDC_RELATIVE_SELECTED_DIMINISHED_5TH) ->EnableWindow(ChangeType);    
	GetDlgItem(IDC_RELATIVE_SELECTED_PERFECT_5TH) ->EnableWindow(ChangeType);       
	GetDlgItem(IDC_RELATIVE_SELECTED_MINOR_6TH) ->EnableWindow(ChangeType);         
	GetDlgItem(IDC_RELATIVE_SELECTED_MAJOR_6TH) ->EnableWindow(ChangeType);         
	GetDlgItem(IDC_RELATIVE_SELECTED_MINOR_7TH) ->EnableWindow(ChangeType);         
	GetDlgItem(IDC_RELATIVE_SELECTED_MAJOR_7TH) ->EnableWindow(ChangeType);         
	GetDlgItem(IDC_RELATIVE_SELECTED_PERFECT_8TH) ->EnableWindow(ChangeType);       
	GetDlgItem(IDC_RELATIVE_SELECTED_ALL) ->EnableWindow(ChangeType);       
}

void CRelDlg::TurnOffAllSelected()
{
//	m_relative_selected_all.SetForeColor(BlackColour);
	OnlyResetingSwitch = 1;
	//  Because the following turning off of the "all" checkbox causes the routine
	//   to be executed, we use a switch to effectively bypass the routine
	BypassSelectionAllRoutine = 1;
	m_relative_selected_all.SetCheck(FALSE);	// Turn tick box off
	BypassSelectionAllRoutine = 0;
	OnlyResetingSwitch = 0;
	AllSelectionSwitch = 0;                      // Indicate "all" is off
}

void CRelDlg::EnableGuessedCheckBoxes()             
{
	if (ResUnison)          
	{m_relative_unison.EnableWindow(TRUE);};            
	if (ResMinor2nd)       
	{m_relative_minor_2nd.EnableWindow(TRUE);};         
	if (ResMajor2nd)       
	{m_relative_major_2nd.EnableWindow(TRUE);};         
	if (ResMinor3rd)       
	{m_relative_minor_3rd.EnableWindow(TRUE);};         
	if (ResMajor3rd)       
	{m_relative_major_3rd.EnableWindow(TRUE);};         
	if (ResPerfect4th)     
	{m_relative_perfect_4th.EnableWindow(TRUE);};       
	if (ResDiminished5th)  
	{m_relative_diminished_5th.EnableWindow(TRUE);};    
	if (ResPerfect5th)     
	{m_relative_perfect_5th.EnableWindow(TRUE);};       
	if (ResMinor6th)       
	{m_relative_minor_6th.EnableWindow(TRUE);};         
	if (ResMajor6th)       
	{m_relative_major_6th.EnableWindow(TRUE);};         
	if (ResMinor7th)       
	{m_relative_minor_7th.EnableWindow(TRUE);};         
	if (ResMajor7th)       
	{m_relative_major_7th.EnableWindow(TRUE);};         
	if (ResPerfect8th)     
	{m_relative_perfect_8th.EnableWindow(TRUE);};       
}

void CRelDlg::EnableSelectionCheckBoxes()             
{
	m_relative_selected_unison.EnableWindow(TRUE);
	m_relative_selected_minor_2nd.EnableWindow(TRUE);
	m_relative_selected_major_2nd.EnableWindow(TRUE);
	m_relative_selected_minor_3rd.EnableWindow(TRUE);
	m_relative_selected_major_3rd.EnableWindow(TRUE);
	m_relative_selected_perfect_4th.EnableWindow(TRUE);
	m_relative_selected_diminished_5th.EnableWindow(TRUE);
	m_relative_selected_perfect_5th.EnableWindow(TRUE);
	m_relative_selected_minor_6th.EnableWindow(TRUE);
	m_relative_selected_major_6th.EnableWindow(TRUE);
	m_relative_selected_minor_7th.EnableWindow(TRUE);
	m_relative_selected_major_7th.EnableWindow(TRUE);
	m_relative_selected_perfect_8th.EnableWindow(TRUE);
	m_relative_selected_all.EnableWindow(TRUE);

	if (ResUnison)          
	{m_relative_selected_unison.SetTextColor(GreenColour);}
	if (ResMinor2nd)       
	{m_relative_selected_minor_2nd.SetTextColor(GreenColour);}
	if (ResMajor2nd)       
	{m_relative_selected_major_2nd.SetTextColor(GreenColour);}
	if (ResMinor3rd)       
	{m_relative_selected_minor_3rd.SetTextColor(GreenColour);}
	if (ResMajor3rd)       
	{m_relative_selected_major_3rd.SetTextColor(GreenColour);}
	if (ResPerfect4th)     
	{m_relative_selected_perfect_4th.SetTextColor(GreenColour);}
	if (ResDiminished5th)  
	{m_relative_selected_diminished_5th.SetTextColor(GreenColour);}
	if (ResPerfect5th)     
	{m_relative_selected_perfect_5th.SetTextColor(GreenColour);}
	if (ResMinor6th)       
	{m_relative_selected_minor_6th.SetTextColor(GreenColour);}
	if (ResMajor6th)       
	{m_relative_selected_major_6th.SetTextColor(GreenColour);}
	if (ResMinor7th)       
	{m_relative_selected_minor_7th.SetTextColor(GreenColour);}
	if (ResMajor7th)       
	{m_relative_selected_major_7th.SetTextColor(GreenColour);}
	if (ResPerfect8th)     
	{m_relative_selected_perfect_8th.SetTextColor(GreenColour);}
	if (ResSelectedAll)     
	{m_relative_selected_all.SetTextColor(GreenColour);}
//	UpdateData(FALSE);


}

void CRelDlg::KillGuessedCheckBoxes()
{
	m_relative_unison.EnableWindow(FALSE);
	m_relative_minor_2nd.EnableWindow(FALSE);
	m_relative_major_2nd.EnableWindow(FALSE);
	m_relative_minor_3rd.EnableWindow(FALSE);
	m_relative_major_3rd.EnableWindow(FALSE);
	m_relative_perfect_4th.EnableWindow(FALSE);
	m_relative_diminished_5th.EnableWindow(FALSE);
	m_relative_perfect_5th.EnableWindow(FALSE);
	m_relative_minor_6th.EnableWindow(FALSE);
	m_relative_major_6th.EnableWindow(FALSE);
	m_relative_minor_7th.EnableWindow(FALSE);
	m_relative_major_7th.EnableWindow(FALSE);
	m_relative_perfect_8th.EnableWindow(FALSE);
}

void CRelDlg::OnTimer(UINT nIDEvent)
{
	RelativeTimerWaitSwitch = 1;
	CDialog::OnTimer(nIDEvent);
}

void CRelDlg::DoRelativeWait(int WaitTimeInMilliseconds)
{
	RelativeTimerWaitSwitch = 0;
	RelativeTimerKey = SetTimer(1, WaitTimeInMilliseconds, NULL);                          
	ASSERT(RelativeTimerKey !=0);
//  Wait until the timer changes RelativeTimerWaitSwitch to non zero. 
//  The PeekMessage will allow the message through
	while (RelativeTimerWaitSwitch == 0)                                                  
		{if(::PeekMessage(&RelativeMessage, NULL, 0, 0, PM_REMOVE))                   
			{                                                                    
			::TranslateMessage(&RelativeMessage);                                        
			::DispatchMessage(&RelativeMessage);                                         
			} 
        };
	KillTimer(RelativeTimerKey); 
	//WaitTypeSwitch = 1;  // Default
}

// The following function is really only for debugging
void CRelDlg::OnRButtonDown(UINT nFlags, CPoint point)
{
	// Display the pop up menu seection on right mouse button down
CRect rect;
CPoint TL; 
	int x; int y;
	GetWindowRect(&rect);
	TL = rect.TopLeft(); 
	RelativeX = TL.x;  RelativeY = TL.y;
	x = point.x + RelativeX + 20; y = point.y + RelativeY + 17;
	CPitchDlg PopupTime; 
	PopupTime.ProcessPopupMenu(x,y);

	CDialog::OnRButtonDown(nFlags, point);
}

void CRelDlg::OnRButtonUp(UINT nFlags, CPoint point)
{
		m_relative_interval = "";
    	UpdateData(FALSE);
	
	CDialog::OnRButtonUp(nFlags, point);
}

void CRelDlg::OnUp()
{
	UpDownSwitch = 0;
    m_up = 0;     
	UpdateData(FALSE);
}

void CRelDlg::OnDown()
{
	UpDownSwitch = 1;
    m_up = 1;     
	UpdateData(FALSE);
}

void CRelDlg::OnUpdown()
{
	UpDownSwitch = 2;	
    m_up = 2;     
	UpdateData(FALSE);
}
 void CRelDlg::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	int iCurrent;
	//  PScrollBar is a pointer to the control being updated
    //  pSB_Low and pSB_High are the pointers to the two range scroll bars

	CScrollBar* pSB_Low  = (CScrollBar*) GetDlgItem(IDC_RELATIVE_LOW_RANGE); 
	CScrollBar* pSB_High = (CScrollBar*) GetDlgItem(IDC_RELATIVE_HIGH_RANGE); 
	CScrollBar* pSB_Speed = (CScrollBar*) GetDlgItem(IDC_RELATIVE_SPEED);  
    // Get the current position
    iCurrent = pScrollBar->GetScrollPos();                              
	if (pScrollBar == (CScrollBar*) pSB_Speed)
	   {goto ProcessSpeedScroll;};
	
	switch (nSBCode)
		{
		case SB_THUMBPOSITION:                                                
		pScrollBar->SetScrollPos (nPos);                                      
		break;
		
        case SB_LINERIGHT:
                // Increase current position by 1 (if possible)
                iCurrent = iCurrent + 1;
                if ( iCurrent >= m_relative_Scroll_Max )
                     iCurrent = m_relative_Scroll_Max;
                // Set scroll bar to its new position.
                pScrollBar->SetScrollPos (  iCurrent );                  
                break;

          case SB_LINELEFT:
                // Decrease current position by 1 (if possible)
                iCurrent = iCurrent - 1;
                if ( iCurrent <= m_relative_Scroll_Min )
                     iCurrent = m_relative_Scroll_Min;
                // Set scroll bar to its new position.
                pScrollBar->SetScrollPos ( iCurrent );                  
                break;

          case SB_PAGERIGHT:
                 // Increase scroll bar by an octave(if possible).
                iCurrent = iCurrent + 12;
                if ( iCurrent >= m_relative_Scroll_Max )
                     iCurrent = m_relative_Scroll_Max;
                // Set scroll bar to its new position.
                pScrollBar->SetScrollPos ( iCurrent );                  
                break;

          case SB_PAGELEFT:
                // Decrease scroll bar by an octave(if possible).
                iCurrent = iCurrent - 12;
                if ( iCurrent <= m_relative_Scroll_Min )
                     iCurrent = m_relative_Scroll_Min;
                // Set scroll bar to its new position.
                pScrollBar->SetScrollPos ( iCurrent );                  
                break;

          case SB_THUMBTRACK:                                           
               // Set scroll bar to its new position.
               pScrollBar->SetScrollPos ( nPos );                       
               break;
          }

    // Update the caption of the label.		  
	if (pScrollBar == (CScrollBar*) pSB_Low)
		  {	strncpy(NoteDescription,NoteTable1 + (iCurrent-1)*3, 3); 
    	  	m_relative_low_note = NoteDescription; 
    	  	LowPianoNote = iCurrent;	}
    else
		  {	strncpy(NoteDescription,NoteTable1 + (iCurrent-1)*3, 3); 
    	  	m_relative_high_note = NoteDescription; 
    	  	HighPianoNote = iCurrent;	} ;
	UpdateData(FALSE);     
	goto OnHScrollExit ;

ProcessSpeedScroll:	
	switch (nSBCode)
		{
		case SB_THUMBPOSITION:                                                
		pScrollBar->SetScrollPos (nPos);                                      
		break;
        case SB_LINERIGHT:
                // Increase current position by 1 (if possible)
                iCurrent = iCurrent + 1;
                if ( iCurrent >= m_relative_Speed_Scroll_Max )
                     iCurrent = m_relative_Speed_Scroll_Max;
                // Set scroll bar to its new position.
                pScrollBar->SetScrollPos ( iCurrent );                  
                break;

          case SB_LINELEFT:
                // Decrease current position by 1 (if possible)
                iCurrent = iCurrent - 1;
                if ( iCurrent <= m_relative_Speed_Scroll_Min )
                     iCurrent = m_relative_Speed_Scroll_Min;
                // Set scroll bar to its new position.
                pScrollBar->SetScrollPos ( iCurrent );                  
                break;

          case SB_PAGERIGHT:
                iCurrent = iCurrent + 10;
                if ( iCurrent >= m_relative_Speed_Scroll_Max )
                     iCurrent = m_relative_Speed_Scroll_Max;
                // Set scroll bar to its new position.
                pScrollBar->SetScrollPos ( iCurrent );                  
                break;

          case SB_PAGELEFT:
                iCurrent = iCurrent - 10;
                if ( iCurrent <= m_relative_Speed_Scroll_Min )
                     iCurrent = m_relative_Speed_Scroll_Min;
                // Set scroll bar to its new position.
                pScrollBar->SetScrollPos ( iCurrent );                  
                break;

          case SB_THUMBTRACK:                                           
               // Set scroll bar to its new position.
               pScrollBar->SetScrollPos ( nPos );                       
               break;
          }
          RelativeWaitLength = iCurrent*50;
OnHScrollExit:	
	CDialog::OnHScroll(nSBCode, nPos, pScrollBar);
}

void CRelDlg::OnDestroy() 
{
	CDialog::OnDestroy();	
	// Grab the screen location at end for the registry
	CRect rect;
	GetWindowRect(&rect);
	CPoint TL, BR;
	TL = rect.TopLeft(); BR = rect.BottomRight();
	RelativeX = TL.x;  RelativeY = TL.y;
	rect.NormalizeRect();
	RelativeWidth = rect.Width(); RelativeHeight = rect.Height();
}

long CRelDlg::PlayRelativeNote(int NoteNumber1, int NoteNumber2)
{
	CPitchDlg abc;
	long NoteError = 0;
	NoteNumber1--; 
	if (NoteNumber2 > 0) {NoteNumber2--;}
	SecondChannel = CurrentChannel+1;
	bStatus   = MIDI_PROGRAM_CHANGE;
	bChannel  = CurrentChannel;
	bData1    = InstrumentNumber;  
	bData2    = '\x00';  // Not used
	abc.SendShortMessage();
	bStatus   = MIDI_NOTE_ON;
	bChannel  = CurrentChannel;
	bData1    = NoteNumber1;  
	bData2    = '\x7f';	 // Volume
	abc.SendShortMessage();
	// If a second not sent, get it off now
	if (NoteNumber2 > 0) 
	{
		bStatus   = MIDI_PROGRAM_CHANGE;
		bChannel  = CurrentChannel;
		bData1    = InstrumentNumber;  
		bData2    = '\x00';  // Not used
		abc.SendShortMessage();
		bStatus   = MIDI_NOTE_ON;
		bChannel  = CurrentChannel;
		bData1    = NoteNumber2;  
		bData2    = '\x7f';	 // Volume
		abc.SendShortMessage();
	}
	// Wait for timeout
	DoRelativeWait(NoteWaitTimeLength);
	bStatus   = MIDI_NOTE_OFF;
	bChannel  = CurrentChannel;
	bData1    = NoteNumber1;  
	bData2    = '\x00';	 // Volume
	abc.SendShortMessage();
	// If a second note we must also stop it.
	if (NoteNumber2 > 0) 
	{
		bStatus   = MIDI_NOTE_OFF;
		bChannel  = CurrentChannel;
		bData1    = NoteNumber2;  
		bData2    = '\x00';	 // Volume
		abc.SendShortMessage();
	}
    return (NoteError);
}
void CRelDlg::OnRelativeButtonMove(UINT nFlags, CPoint point) 
{

	if (myHWND == m_RelativeScore.GetSafeHwnd() )
	{
		itoa(RelativeCorrect,charresultR,10);
		strcpy(score_workR,charresultR);
		strcat(score_workR,"  of ");
		itoa(RelativeGuesses,charresultR,10);
		strcat(score_workR,charresultR);
		m_RelativeScore.SetWindowText(score_workR);
		m_RelativeScore.SetTextColor(PurpleColour);
		UpdateData(FALSE);
	}
	UpdateData(FALSE);
	
  CDialog::OnMouseMove(nFlags, point);
}

void CRelDlg::OnRelativeButtonLeave(WPARAM, LPARAM)
{
	if (myHWND == m_RelativeScore.GetSafeHwnd() )
	{
		m_RelativeScore.SetWindowText("Score");
		UpdateData(FALSE);					
	}
	
}





void CRelDlg::OnRelativeTitle() 
{
	// TODO: Add your control notification handler code here
	
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Australia Australia
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions