#ifndef Generator_c
#define Generator_c


#define Td_ton (65535-(F_OSC/(8*f_ton)))  // nastaveni přetečení podle frekvence tonu
#define delka_cela 20000/(16000000/F_OSC) // nastaveni delky cele noty

// cela cast frekvence tonu + kalibrace
#define nota_C	66	// 0x1
#define nota_Cs	70	// 0x2
#define nota_D	74	// 0x3
#define nota_Ds	79	// 0x4
#define nota_E	84	// 0x5
#define nota_F	89	// 0x6
#define nota_Fs	95	// 0x7
#define nota_G	102	// 0x8
#define nota_Gs	107	// 0x9
#define nota_A	114	// 0xA
#define nota_As	118	// 0xB
#define nota_H	128	// 0xC
//#define pomlka  0xFFFF

// desetinna cast frekvence tonu
#define notaz_C		41
#define notaz_Cs 	29
#define notaz_D		42
#define notaz_Ds	78
#define notaz_E		40
#define notaz_F		00
#define notaz_Fs	00
#define notaz_G		00
#define notaz_Gs	83
#define notaz_A		00
#define notaz_As	54
#define notaz_H		47

unsigned char *ukazatel;
unsigned char temp=0xFF;
unsigned char oktava,nota,okt,stop,stop1,delkapom;
unsigned char stopcount = 0;
unsigned char exit = 0;

unsigned int  f_ton = 4000;
unsigned int  delka, delkatim;

void Prehraj(unsigned char *melodie) {

	PortReproDir 	|= (1<<PinRepro);	// nastavení výstupu na reproduktor
	TCCR0	|= (1<<CS01);				// nastavení časovače 0 - délka tónu	
	TCCR1B	|= (1<<CS11);				// nastaveni časovače 1 - generátor tónu
	TIMSK	|= (1<<TOIE1)|(1<<TOIE0);	// povolení přerušení při přetečení časovačů
	sei();								// povolení přerušení
	stopcount=0;
	exit = 0;
	temp=0xFF;
	while (!stopcount) {
		if(temp==0xFF)					// test prvniho startu a konce
		{
			stop = 1;
			ukazatel=melodie;			
			temp=*melodie;
			stop = 0;
			if(exit) 
			{
				stopcount=1;
				TIMSK	^= (1<<TOIE1)|(1<<TOIE0);
				stop=1;
			}
			exit = 1;	

		
		} 
		else
		{
			temp=*ukazatel;				// není konec - nacti notu
			oktava=((0xF0&temp)>>4);	// horní nibble je číslo oktávy
			okt = (1<<oktava);
			nota=(0x0F&temp);			// dolní nibble číslo tónu
			delka=*(++ukazatel);		// druhý byte délka noty
			ukazatel++;		

			switch (nota)				// výběr tónu
			{	
				case 0x01: f_ton = nota_C*okt+notaz_C*okt/100; 		break;
				case 0x02: f_ton = nota_Cs*okt+notaz_Cs*okt/100; 	break;
				case 0x03: f_ton = nota_D*okt+notaz_D*okt/100; 		break;
				case 0x04: f_ton = nota_Ds*okt+notaz_Ds*okt/100; 	break;
				case 0x05: f_ton = nota_E*okt+notaz_E*okt/100; 		break;
				case 0x06: f_ton = nota_F*okt+notaz_F*okt/100; 		break;
				case 0x07: f_ton = nota_Fs*okt+notaz_Fs*okt/100; 	break;
				case 0x08: f_ton = nota_G*okt+notaz_G*okt/100;	 	break;
				case 0x09: f_ton = nota_Gs*okt+notaz_Gs*okt/100; 	break;
				case 0x0A: f_ton = nota_A*okt+notaz_A*okt/100; 		break;
				case 0x0B: f_ton = nota_As*okt+notaz_As*okt/100; 	break;
				case 0x0C: f_ton = nota_H*okt+notaz_H*okt/100; 		break;
												
												// rychlost přehrávání
				case 0x0F: { delkapom=oktava; nota=0;}				break; 
				
				default  :						// pomlka - zastavení generátoru
				{ 									
					stop=1;
					f_ton = 0;
					delkatim=delka_cela/delka/delkapom;
					stop1=1;
					while(stop1==1);			// čekání na konec pomlky
					TCNT1=0;
					stop=0;
				}
				break;
			}// switch

			TCNT1=Td_ton;						//změna výšky tónu
			if(nota!=0)
			{
			 	delkatim=delka_cela/delka/delkapom;		// změna délky tónu
				stop1=1;
				while(stop1==1);				// čekání na konec tónu
			}
		}// else
	}// while			
}// Prehraj

ISR(TIMER1_OVF_vect)							// obsulha přerušení TC1 - výška tónu
{
	if(stop==0)
	{
		TCNT1=Td_ton;
		PortRepro ^= (1<<PinRepro);				// negace pinu reproduktoru
	}
}

ISR(TIMER0_OVF_vect)							// obsulha přerušení TC0 - délka tónu
{
	delkatim--;									// rozšíření časovače na 24b (8 + 16)
	if(delkatim==0) stop1=0;
	else stop1=1;                           	
}


#endif //Generator_c
