
рдкреНрд░рд╕реНрддрд╛рд╡рд┐рдд рдЦрд┐рд▓рд╛рдбрд╝реА рдХреЛ рдореЗрдореЛрд░реА рдХрд╛рд░реНрдб рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рдирд╣реАрдВ рд╣реЛрддреА рд╣реИ, рдпрд╣ ATTiny85 рдорд╛рдЗрдХреНрд░реЛрдХрдВрдЯреНрд░реЛрд▓рд░ (рд╕реАрдзреЗ
рдЗрд╕ рдХреНрд▓рд╛рд╕рд┐рдХ рдбрд┐рдЬрд╝рд╛рдЗрди рдХреЗ рд╡рд┐рдкрд░реАрдд, рдЬреЛ WAV рдлрд╝рд╛рдЗрд▓реЛрдВ рдХреЛ рдЦреЗрд▓рддрд╛ рд╣реИ, рдЗрд╕реЗ рд╕реНрд╡рд╛рднрд╛рд╡рд┐рдХ рд░реВрдк рд╕реЗ рдореЗрдореЛрд░реА рдХрд╛рд░реНрдб рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ) рдХреЗ рд╡рд┐рдкрд░реАрдд рд▓рдВрдмрд╛рдИ рдореЗрдВ 6,000 рдмрд╛рдЗрдЯреНрд╕ рддрдХ рдХреА MIDI рдлрд╝рд╛рдЗрд▓ рд╕рдВрдЧреНрд░рд╣реАрдд рдХрд░рддрд╛ рд╣реИред рдкреАрдбрдмреНрд▓реВрдПрдо рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП рдХреНрд╖реАрдгрди рдХреЗ рд╕рд╛рде рдЪрд╛рд░-рддрд░рдлрд╛ рдкреНрд▓реЗрдмреИрдХ рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рдореЗрдВ рд▓рд╛рдЧреВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдзреНрд╡рдирд┐ рдХрд╛ рдПрдХ рдЙрджрд╛рд╣рд░рдг
рдпрд╣рд╛рдБ рд╣реИ ред
рдЙрдкрдХрд░рдг рдпреЛрдЬрдирд╛ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдмрдирд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ:

рдорд╛рдЗрдХреНрд░реЛрдХрдВрдЯреНрд░реЛрд▓рд░ рдФрд░ рдЧрддрд┐рд╢реАрд▓ рд╕рд┐рд░ рдХреЗ рдмреАрдЪ рдЗрд▓реЗрдХреНрдЯреНрд░реЛрд▓рд╛рдЗрдЯрд┐рдХ рд╕рдВрдзрд╛рд░рд┐рддреНрд░ рдирд┐рд░рдВрддрд░ рдШрдЯрдХ рдХреЛ рдпрд╛рдж рдирд╣реАрдВ рдХрд░реЗрдЧрд╛ рдпрджрд┐ рдПрдХ рд╕реЙрдлреНрдЯрд╡реЗрдпрд░ рд╡рд┐рдлрд▓рддрд╛ рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк рдкреАрдмреА 4 рдХреЗ рдЖрдЙрдЯрдкреБрдЯ рдкрд░ рдПрдХ рддрд╛рд░реНрдХрд┐рдХ рдЗрдХрд╛рдИ рджрд┐рдЦрд╛рдИ рджреЗрддреА рд╣реИред рд╕рд┐рд░ рдХреА рдЕрдирд┐рдЪреНрдЫрд╛ рдкреАрдбрдмреНрд▓реВрдПрдо рдЖрд╡реГрддреНрддрд┐ рдХреЛ рдкрд╛рд░рд┐рдд рдирд╣реАрдВ рдХрд░рддреА рд╣реИред рдпрджрд┐ рдЖрдк рдПрдореНрдкрд▓реАрдлрд╛рдпрд░ рд╕реЗ рдбрд┐рд╡рд╛рдЗрд╕ рдХреЛ рдХрдиреЗрдХреНрдЯ рдХрд░рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓реЗрддреЗ рд╣реИрдВ, рддреЛ рдкреАрдбрдмреНрд▓реВрдПрдо рд╕рд┐рдЧреНрдирд▓ рдХреЗ рд╕рд╛рде рдЙрддреНрддрд░рд╛рд░реНрджреНрдз рдХреЛ рдУрд╡рд░рд▓реЛрдб рдХрд░рдиреЗ рд╕реЗ рдмрдЪрдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдпрд╣рд╛рдВ рдХрдо-рдкрд╛рд╕ рдлрд┐рд▓реНрдЯрд░ рдЬреЛрдбрд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛
рд╣реИ ред
рдорд┐рдбреА рдлрд╝рд╛рдЗрд▓ рдХреЛ рдкреНрд░рдкрддреНрд░ рдХреЗ рдПрдХ рд╕рд░рдгреА рдХреЗ рд░реВрдк рдореЗрдВ рдлрд░реНрдорд╡реЗрдпрд░ рд╕реНрд░реЛрдд рдореЗрдВ рд░рдЦрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП:
const uint8_t Tune[] PROGMEM = { 0x4d, 0x54, 0x68, 0x64, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x01, 0x03, 0xc0, 0x4d, 0x54, 0x72, 0x6b, 0x00, 0x00, 0x0a, 0x7e, 0x00, 0xff, ... 0x50, 0xb0, 0x5b, 0x00, 0x00, 0xff, 0x2f, 0x00 };
рдлрд╝рд╛рдЗрд▓ рдХреЛ рдЗрд╕ рдкреНрд░рд╛рд░реВрдк рдореЗрдВ UNIX- рдЬреИрд╕реЗ OS - xxd рдЙрдкрдпреЛрдЧрд┐рддрд╛ рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рддреИрдпрд╛рд░ рд╕рдорд╛рдзрд╛рди рд╣реИред рд╣рдо рдорд┐рдбреА рдлрд╝рд╛рдЗрд▓ рд▓реЗрддреЗ рд╣реИрдВ рдФрд░ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдЗрд╕ рдЙрдкрдпреЛрдЧрд┐рддрд╛ рд╕реЗ рдЧреБрдЬрд░рддреЗ рд╣реИрдВ:
xxd -i musicbox.mid
рдХрдВрд╕реЛрд▓ рдХреБрдЫ рдЗрд╕ рддрд░рд╣ рдкреНрд░рджрд░реНрд╢рд┐рдд рд╣реЛрдЧрд╛:
unsigned char musicbox_mid[] = { 0x4d, 0x54, 0x68, 0x64, 0x00, 0x00, 0x00, 0x06, 0x00, 0x01, 0x00, 0x01, 0x03, 0xc0, 0x4d, 0x54, 0x72, 0x6b, 0x00, 0x00, 0x0a, 0x7e, 0x00, 0xff, ... 0x50, 0xb0, 0x5b, 0x00, 0x00, 0xff, 0x2f, 0x00 }; unsigned int musicbox_mid_len = 2708;
2708 рдмрд╛рдЗрдЯреНрд╕ рдореЗрдВ рд▓рдВрдмрд╛рдИ рд╣реИред рдпрд╣ 6000 рд╕реЗ рдХрдо рдирд┐рдХрд▓рд╛ - рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рдпрд╣ рдлрд┐рдЯ рдмреИрдарддрд╛ рд╣реИред рдХреНрд▓рд┐рдкрдмреЛрд░реНрдб рдХреЗ рдорд╛рдзреНрдпрдо рд╕реЗ рд╣реЗрдХреНрд╕рд╛рдбреЗрд╕рд┐рдорд▓ рд╕рдВрдЦреНрдпрд╛рдУрдВ рдХреЗ рдЕрдиреБрдХреНрд░рдо рдХреЛ рд╕реНрдХреЗрдЪ рдкрд░ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ (рдмрд╕ рдпрд╛рдж рд░рдЦреЗрдВ:
рдХрдВрд╕реЛрд▓ рдореЗрдВ - рдХреЛрдИ Ctrl + C ) рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╕рд░рдгреА рдХреЗ рдмрдЬрд╛рдпред рдпрд╛ рдЕрдЧрд░ рд╣рдо рдЗрд╕реЗ рдЫреЛрдбрд╝рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рддреЛ рдпрд╣ рд╕рдм рди рдХрд░реЗрдВред
рдЯрд╛рдЗрдорд░ рдХрд╛рдЙрдВрдЯрд░ 1 PLL рд╕реЗ 64 рдореЗрдЧрд╛рд╣рд░реНрдЯреНрдЬ рдХреА рдЖрд╡реГрддреНрддрд┐ рдкрд░ рдХрд╛рдо рдХрд░реЗрдЧрд╛:
PLLCSR = 1<<PCKE | 1<<PLLE;
рд╣рдо DAC рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЗрд╕ рдЯрд╛рдЗрдорд░ рдХреЛ PWM рдореЛрдб рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддреЗ рд╣реИрдВ; рдХрд░реНрддрд╡реНрдп рдЪрдХреНрд░ OCR1B рдХреЗ рдорд╛рди рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░реЗрдЧрд╛:
TIMSK = 0; // Timer interrupts OFF TCCR1 = 1<<CS10; // 1:1 prescale GTCCR = 1<<PWM1B | 2<<COM1B0; // PWM B, clear on match OCR1B = 128; DDRB = 1<<DDB4; // Enable PWM output on pin 4
рдЖрдпрддрд╛рдХрд╛рд░ рджрд╛рд▓реЛрдВ рдХреА рдЖрд╡реГрддреНрддрд┐ OCR1C рдХреЗ рдореВрд▓реНрдп рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░рддреА рд╣реИ, рд╣рдо рдЗрд╕реЗ 255 (рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ) рдХреЗ рдмрд░рд╛рдмрд░ рдЫреЛрдбрд╝ рджреЗрддреЗ рд╣реИрдВ, рдлрд┐рд░ 64 рдореЗрдЧрд╛рд╣рд░реНрдЯреНрдЬ рдХреА рдЖрд╡реГрддреНрддрд┐ рдХреЛ 256 рд╕реЗ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рд╣рдореЗрдВ 250 kHz рдорд┐рд▓рддрд╛ рд╣реИред
рдЯрд╛рдЗрдорд░ рдХрд╛рдЙрдВрдЯрд░ 0 рдЕрд╡рд░реЛрдз рдЙрддреНрдкрдиреНрди рдХрд░реЗрдЧрд╛:
TCCR0A = 3<<WGM00; // Fast PWM TCCR0B = 1<<WGM02 | 2<<CS00; // 1/8 prescale OCR0A = 19; // Divide by 20 TIMSK = 1<<OCIE0A; // Enable compare match, disable overflow
16 рдореЗрдЧрд╛рд╣рд░реНрдЯреНрдЬ рдХреА рдПрдХ рдШрдбрд╝реА рдЖрд╡реГрддреНрддрд┐ рдХреЛ рд╡рд┐рднрдХреНрдд рджреНрд╡рд╛рд░рд╛ 8 рд╕реЗ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рдФрд░ рдлрд┐рд░ 19 + 1 рдХреЗ OCR0A рдорд╛рди рд╕реЗ, рдФрд░ 100 kHz рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЦрд┐рд▓рд╛рдбрд╝реА рдЪрд╛рд░ рдЖрд╡рд╛рдЬ рд╡рд╛рд▓рд╛ рд╣реЛрддрд╛ рд╣реИ, рдкреНрд░рддреНрдпреЗрдХ рдЖрд╡рд╛рдЬ рдХреЗ рд▓рд┐рдП 25 kHz рдкреНрд░рд╛рдкреНрдд рд╣реЛрддрд╛ рд╣реИред рд░реБрдХрд╛рд╡рдЯ рд╣реЛрдиреЗ рдкрд░, рдПрдХ ISR рдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рд░реВрдЯреАрди рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИ (TIMER0_COMPA_vect), рдЬреЛ рдзреНрд╡рдирд┐рдпреЛрдВ рдХреА рдЧрдгрдирд╛ рдФрд░ рдЖрдЙрдЯрдкреБрдЯ рдХрд░рддрд╛ рд╣реИред
рд╡реЙрдЪрдбреЙрдЧ рдЯрд╛рдЗрдорд░ рдХреЛ рд╣рд░ 16 рдПрдордПрд╕ рдореЗрдВ рдПрдХ рдмрд╛рдзрд╛ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рдиреЛрдЯ рдЖрд╡реГрддреНрддрд┐рдпреЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реИ:
WDTCR = 1<<WDIE | 0<<WDP0; // Interrupt every 16ms
рдХрд┐рд╕реА рджрд┐рдП рдЧрдП рдЖрдХрд╛рд░ рдХреЗ рджреЛрд▓рдиреЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдкреНрд░рддреНрдпрдХреНрд╖ рдбрд┐рдЬрд┐рдЯрд▓ рд╕рдВрд╢реНрд▓реЗрд╖рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред ATtiny85 рдореЗрдВ рдХреЛрдИ рд╣рд╛рд░реНрдбрд╡реЗрдпрд░ рдЧреБрдгрди рдирд╣реАрдВ рд╣реИ, рдЗрд╕рд▓рд┐рдП рд╣рдо рдЖрдпрддрд╛рдХрд╛рд░ рджрд╛рд▓реЛрдВ рдХреЛ рд▓реЗрддреЗ рд╣реИрдВ рдФрд░ рд▓рд┐рдлрд╛рдлреЗ рдХреЗ рдЖрдпрд╛рдо рдХреЛ 1 рдпрд╛ -1 рд╕реЗ рдЧреБрдгрд╛ рдХрд░рддреЗ рд╣реИрдВред рдЖрдпрд╛рдо рд░реИрдЦрд┐рдХ рд░реВрдк рд╕реЗ рдШрдЯрддрд╛ рд╣реИ, рдФрд░ рд╕рдордп рдореЗрдВ рдЗрд╕реЗ рдПрдХ рдирд┐рд╢реНрдЪрд┐рдд рд╕рдордп рдкрд░ рдЧрдгрдирд╛ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдпрд╣ рдореАрдЯрд░ рд░реАрдбрд┐рдВрдЧ рдХреЛ рд░реИрдЦрд┐рдХ рд░реВрдк рд╕реЗ рдХрдо рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдкрд░реНрдпрд╛рдкреНрдд рд╣реИред
рдкреНрд░рддреНрдпреЗрдХ рдЪреИрдирд▓ рдХреЗ рд▓рд┐рдП рддреАрди рдЪрд░ рдкреНрд░рджрд╛рди рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ: Freq [] - рдЖрд╡реГрддреНрддрд┐, Acc [] - рдЪрд░рдг рдмреИрдЯрд░реА, Amp [], рд▓рд┐рдлрд╛рдлрд╛ рдкреНрд░рд╡рд░реНрдзрд┐рдд рдореВрд▓реНрдпред Freq [] рдФрд░ Acc [] рдХреЗ рдореВрд▓реНрдп рд╕рдВрдХреНрд╖реЗрдк рд╣реИрдВред рдЖрдпрддрд╛рдХрд╛рд░ рджрд╛рд▓реЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЙрдЪреНрдЪ-рдХреНрд░рдо рдмрд┐рдЯ Acc [] рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЕрдзрд┐рдХ Freq [], рдЙрдЪреНрдЪ рдЖрд╡реГрддреНрддрд┐ред рддреИрдпрд╛рд░ рддрд░рдВрдЧ рд▓рд┐рдлрд╛рдлреЗ Amp [] рджреНрд╡рд╛рд░рд╛ рдЧреБрдгрд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рд╕рднреА рдЪрд╛рд░ рдЪреИрдирд▓ рдорд▓реНрдЯреАрдкреНрд▓реЗрдХреНрд╕ рд╣реИрдВ рдФрд░ рдПрдирд╛рд▓реЙрдЧ рдЖрдЙрдЯрдкреБрдЯ рдХреЛ рдЦрд┐рд▓рд╛рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдХрд╛рд░реНрдпрдХреНрд░рдо рдХрд╛ рдПрдХ рдорд╣рддреНрд╡рдкреВрд░реНрдг рд╣рд┐рд╕реНрд╕рд╛ рдЯрд╛рдЗрдорд░-рдХрд╛рдЙрдВрдЯрд░ 0 рд╕реЗ рд░реБрдХрд╛рд╡рдЯ рдХреЛ рд╕рдВрд╕рд╛рдзрд┐рдд рдХрд░рдиреЗ рдХреА рдкреНрд░рдХреНрд░рд┐рдпрд╛ рд╣реИ, рдЬреЛ рдПрдирд╛рд▓реЙрдЧ рдЙрддреНрдкрд╛рджрди рдХреЗ рд▓рд┐рдП рджреЛрд▓рдиреЛрдВ рдХреЛ рдЖрдЙрдЯрдкреБрдЯ рдХрд░рддрд╛ рд╣реИред рдЗрд╕ рдкреНрд░рдХреНрд░рд┐рдпрд╛ рдХреЛ рд▓рдЧрднрдЧ 95 kHz рдХреА рдЖрд╡реГрддреНрддрд┐ рдкрд░ рдХрд╣рд╛ рдЬрд╛рддрд╛ рд╣реИред рд╡рд░реНрддрдорд╛рди рдЪреИрдирд▓ c рдХреЗ рд▓рд┐рдП, рдпрд╣ Acc [c] рдФрд░ Amp [c] рдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреЛ рдЕрджреНрдпрддрди рдХрд░рддрд╛ рд╣реИ, рдФрд░ рд╡рд░реНрддрдорд╛рди рдиреЛрдЯ рдХреЗ рдореВрд▓реНрдп рдХреА рдЧрдгрдирд╛ рднреА рдХрд░рддрд╛ рд╣реИред рдкрд░рд┐рдгрд╛рдо OCR1B рдЯрд╛рдЗрдорд░-рдХрд╛рдЙрдВрдЯрд░ рдХреЗ OCR1B рддреБрд▓рдирд╛ рд░рдЬрд┐рд╕реНрдЯрд░ рдХреЛ рдкрд┐рди 4 рдкрд░ рдПрдХ рдПрдирд╛рд▓реЙрдЧ рд╕рд┐рдЧреНрдирд▓ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рднреЗрдЬрд╛ рдЬрд╛рддрд╛ рд╣реИ:
ISR(TIMER0_COMPA_vect) { static uint8_t c; signed char Temp, Mask, Env, Note; Acc[c] = Acc[c] + Freq[c]; Amp[c] = Amp[c] - (Amp[c] != 0); Temp = Acc[c] >> 8; Temp = Temp & Temp<<1; Mask = Temp >> 7; Env = Amp[c] >> Volume; Note = (Env ^ Mask) + (Mask & 1); OCR1B = Note + 128; c = (c + 1) & 3; }
рдкрдВрдХреНрддрд┐
Acc[c] = Acc[c] + Freq[c];
рдмреИрдЯрд░реА Acc [c] рдореЗрдВ рдлреНрд░реАрдХреНрд╡реЗрдВрд╕реА freq [c] рдЬреЛрдбрд╝рддрд╛ рд╣реИред рдЕрдзрд┐рдХ рд╕реЗ рдЕрдзрд┐рдХ Freq [c], рддреЗрдЬреА рд╕реЗ Acc [c] рдорд╛рди рдмрджрд▓ рдЬрд╛рдПрдЧрд╛ред рдлрд┐рд░ рд▓рд╛рдЗрди
Amp[c] = Amp[c] - (Amp[c] != 0);
рдХрд┐рд╕реА рджрд┐рдП рдЧрдП рдЪреИрдирд▓ рдХреЗ рд▓рд┐рдП рдЖрдпрд╛рдо рдорд╛рди рдХреЛ рдШрдЯрд╛рддрд╛ рд╣реИред рдЯреБрдХрдбрд╝рд╛ (Amp [c]! = 0) рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рддрд╛рдХрд┐ рдЖрдпрд╛рдо рд╢реВрдиреНрдп рддрдХ рдкрд╣реБрдВрдЪрдиреЗ рдХреЗ рдмрд╛рдж рдпрд╣ рдФрд░ рдХрдо рди рд╣реЛред рдЕрдм рд░реЗрдЦрд╛
Temp = Acc[c] >> 8;
Acc [c] рдХреЗ рдЙрдЪреНрдЪ 9 рдмрд┐рдЯреНрд╕ рдХреЛ Temp рдореЗрдВ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддрд╛ рд╣реИред рдФрд░ рд░реЗрдЦрд╛
Temp = Temp & Temp<<1;
рдЗрд╕ рдЪрд░ рдХреЗ рдЙрдЪреНрдЪ-рдХреНрд░рдо рдмрд┐рдЯ рдХреЛ рдПрдХ рдХреЗ рдмрд░рд╛рдмрд░ рдЫреЛрдбрд╝рддрд╛ рд╣реИ рдпрджрд┐ рджреЛ рдЙрдЪреНрдЪ-рдХреНрд░рдо рдмрд┐рдЯ рдПрдХ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИрдВ, рдФрд░ рдЙрдЪреНрдЪ-рдХреНрд░рдо рдмрд┐рдЯ рдХреЛ рд╢реВрдиреНрдп рдкрд░ рд╕реЗрдЯ рдХрд░рддрд╛ рд╣реИ рдпрджрд┐ рдпрд╣ рдирд╣реАрдВ рд╣реИред рдкрд░рд┐рдгрд╛рдо рдЖрдпрддрд╛рдХрд╛рд░ рджрд╛рд▓реЛрдВ рдХреЗ рд╕рд╛рде 25/75 рдХреЗ рдСрди / рдСрдл рдЕрдиреБрдкрд╛рдд рд╣реИред рдкрд┐рдЫрд▓реЗ рдирд┐рд░реНрдорд╛рдгреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдореЗрдВ, рд▓реЗрдЦрдХ рдиреЗ рдПрдХ рдореЗрдиреНрдбрдВрдбрд░ рд▓рдЧрд╛рдпрд╛, рдЬрдмрдХрд┐ рдирдИ рд╡рд┐рдзрд┐ рдХреЗ рд╕рд╛рде, рд╣рд╛рд░реНрдореЛрдирд┐рдХреНрд╕ рдереЛрдбрд╝рд╛ рдЕрдзрд┐рдХ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдкрдВрдХреНрддрд┐
Mask = Temp >> 7;
рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдЗрдЯ рдХреЗ рд╢реЗрд╖ рдмрд┐рдЯреНрд╕ рдХреЗ рдореВрд▓реНрдпреЛрдВ рдХреЛ рд╕реНрдерд╛рдирд╛рдВрддрд░рд┐рдд рдХрд░рддрд╛ рд╣реИ, рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдпрджрд┐ рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд┐рдЯ 0 рдерд╛, рддреЛ 0x00 рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рдПрдЧрд╛, рдФрд░ рдпрджрд┐ 1 - рддреЛ 0xFFред рдкрдВрдХреНрддрд┐
Env = Amp[c] >> Volume;
рд╡реЙрд▓реНрдпреВрдо рдХреЗ рдорд╛рди рд╕реЗ Enp [c] рдмрд┐рдЯ рдХреЛ Env рдореЗрдВ рдЯреНрд░рд╛рдВрд╕рдлрд░ рдХрд░рддрд╛ рд╣реИ, рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рд╕реАрдирд┐рдпрд░ рджреНрд╡рд╛рд░рд╛, рд╡реЙрд▓реНрдпреВрдо = 8. рд╕реНрдЯреНрд░рд┐рдВрдЧ рдХреЗ рдмрд╛рдж рд╕реЗ
Note = (Env ^ Mask) + (Mask & 1);
рдпрд╣ рд╕рдм рдПрдХрдЬреБрдЯ рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдорд╛рд╕реНрдХ = 0x00 рд╣реИ, рддреЛ рдиреЛрдЯ рдХреЛ Env рдорд╛рди рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдпрджрд┐ рдорд╛рд╕реНрдХ = 0xFF, рддреЛ рдиреЛрдЯ рдХреЛ Env + 1 рдХреЗ рд▓рд┐рдП рдЕрддрд┐рд░рд┐рдХреНрдд рдорд╛рди рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рдЕрд░реНрдерд╛рдд, рдПрдХ рдЛрдг рдЪрд┐рд╣реНрди рдХреЗ рд╕рд╛рде Envред рдиреЛрдЯ рдореЗрдВ рд╡рд░реНрддрдорд╛рди рддрд░рдВрдЧ рд╣реИ, рдЬреЛ рд╡рд░реНрддрдорд╛рди рдЖрдпрд╛рдо рдХреЗ рд╕рдХрд╛рд░рд╛рддреНрдордХ рд╕реЗ рдирдХрд╛рд░рд╛рддреНрдордХ рдорд╛рдиреЛрдВ рдореЗрдВ рдмрджрд▓ рд░рд╣реА рд╣реИред рдкрдВрдХреНрддрд┐
OCR1B = Note + 128;
рдиреЛрдЯ рдореЗрдВ 128 рдЬреЛрдбрд╝рддрд╛ рд╣реИ рдФрд░ OCR1B рдкрд░ рдкрд░рд┐рдгрд╛рдо рд▓рд┐рдЦрддрд╛ рд╣реИред рдкрдВрдХреНрддрд┐
c = (c + 1) & 3;
рдЗрд╕реА рдЕрдВрддрд░рд╛рд▓ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЪрд╛рд░ рдЪреИрдирд▓ рдЖрдЙрдЯрдкреБрдЯ рдХрд░рддрд╛ рд╣реИ, рдЖрдЙрдЯрдкреБрдЯ рдкрд░ рдЖрд╡рд╛рдЬрд╝реЛрдВ рдХреЛ рдЧреБрдгрд╛ рдХрд░рддрд╛ рд╣реИред
рдмрд╛рд░рд╣ рдиреЛрдЯ рдЖрд╡реГрддреНрддрд┐рдпреЛрдВ рд╕рд░рдгреА рдореЗрдВ рджрд┐рдП рдЧрдП рд╣реИрдВ:
unsigned int Scale[] = { 10973, 11626, 12317, 13050, 13826, 14648, 15519, 16442, 17419, 18455, 19552, 20715};
рдЕрдиреНрдп рд╕рдкреНрддрдХ рдХреЗ рдиреЛрдЯ рдЖрд╡реГрддреНрддрд┐рдпреЛрдВ рдХреЛ 2
n рд╕реЗ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рдХреЗ рдкреНрд░рд╛рдкреНрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдо 10973 рдХреЛ 2
4 рд╕реЗ рд╡рд┐рднрд╛рдЬрд┐рдд рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рд╣рдореЗрдВ 686 рдорд┐рд▓рддреЗ рд╣реИрдВред рдКрдкрд░реА рдмрд┐рдЯ Acc [c] 25000 / (65536/685) = 261.7 рд╣рд░реНрдЯреНрдЬ рдХреА рдЖрд╡реГрддреНрддрд┐ рдХреЗ рд╕рд╛рде рд╕реНрд╡рд┐рдЪ рдХрд░реЗрдЧрд╛ред
рджреЛ рдЪрд░ рдзреНрд╡рдирд┐ рдХреЛ рдкреНрд░рднрд╛рд╡рд┐рдд рдХрд░рддреЗ рд╣реИрдВ: рдЖрдпрддрди - рдЖрдпрддрди, 7 рд╕реЗ 9 рдФрд░ рдХреНрд╖рдп - рдХреНрд╖реАрдгрди, 12 рд╕реЗ 14. рддрдХ рдЙрдЪреНрдЪрддрд░ рдХреНрд╖рдп рдорд╛рди, рдХреНрд╖реАрдгрди рдзреАрдорд╛ред
рд╕рд░рд▓рддрдо рдорд┐рдбреА рджреБрднрд╛рд╖рд┐рдпрд╛ рдХреЗрд╡рд▓ рдиреЛрдЯ, рдЯреЗрдореНрдкреЛ рдФрд░ рдбрд┐рд╡реАрдЬрди рдЧреБрдгрд╛рдВрдХ рдХреЗ рдореВрд▓реНрдпреЛрдВ рдкрд░ рдзреНрдпрд╛рди рджреЗрддрд╛ рд╣реИ, рдФрд░ рдЕрдиреНрдп рдбреЗрдЯрд╛ рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░рддрд╛ рд╣реИред ReadIgnore () рд░реВрдЯреАрди рдлрд╝рд╛рдЗрд▓ рд╕реЗ рдкреНрд░рд╛рдкреНрдд рд╕рд░рдгреА рдореЗрдВ рдмрд╛рдЗрдЯреНрд╕ рдХреА рдирд┐рд░реНрджрд┐рд╖реНрдЯ рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдЫреЛрдбрд╝ рджреЗрддрд╛ рд╣реИ:
void readIgnore (int n) { Ptr = Ptr + n; }
ReadNumber () рджрд┐рдирдЪрд░реНрдпрд╛ рджреА рдЧрдИ рдмрд╛рдЗрдЯреНрд╕ рдХреА рд╕рдВрдЦреНрдпрд╛ рд╕реЗ 4 рдХреА рд╕рдЯреАрдХрддрд╛ рдХреЗ рд╕рд╛рде рдПрдХ рд╕рдВрдЦреНрдпрд╛ рдкрдврд╝рддреА рд╣реИ:
unsigned long readNumber (int n) { long result = 0; for (int i=0; i<n; i++) result = (result<<8) + pgm_read_byte(&Tune[Ptr++]); return result; }
ReadVariable () рджрд┐рдирдЪрд░реНрдпрд╛ MIDI рдЪрд░ рдкрд░рд┐рд╢реБрджреНрдзрддрд╛ рдХреЗ рд╕рд╛рде рдПрдХ рд╕рдВрдЦреНрдпрд╛ рдкрдврд╝рддрд╛ рд╣реИред рдЗрд╕ рдорд╛рдорд▓реЗ рдореЗрдВ рдмрд╛рдЗрдЯреНрд╕ рдХреА рд╕рдВрдЦреНрдпрд╛ рдПрдХ рд╕реЗ рдЪрд╛рд░ рд╣реЛ рд╕рдХрддреА рд╣реИ:
unsigned long readVariable () { long result = 0; uint8_t b; do { b = pgm_read_byte(&Tune[Ptr++]); result = (result<<7) + (b & 0x7F); } while (b & 0x80); return result; }
рдкреНрд░рддреНрдпреЗрдХ рдмрд╛рдЗрдЯ рд╕реЗ рд╕рд╛рдд рдмрд┐рдЯреНрд╕ рд▓рд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдФрд░ рдЖрдард╡реЗрдВ рдПрдХ рдХреЗ рдмрд░рд╛рдмрд░ рд╣реИ рдпрджрд┐ рдЖрдкрдХреЛ рдХрд┐рд╕реА рдЕрдиреНрдп рдмрд╛рдЗрдЯ рдХреЛ рдЖрдЧреЗ рдкрдврд╝рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ, рдпрд╛ рд╢реВрдиреНрдп рдирд╣реАрдВ рддреЛред
рджреБрднрд╛рд╖рд┐рдпрд╛ рдиреЛрдЯрдСрди () рд░реВрдЯреАрди рдХреЛ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЙрдкрд▓рдмреНрдз рдЪреИрдирд▓ рдореЗрдВ рдиреЛрдЯ рдЪрд▓рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╣рддрд╛ рд╣реИ:
void noteOn (uint8_t number) { uint8_t octave = number/12; uint8_t note = number%12; unsigned int freq = Scale[note]; uint8_t shift = 9-octave; Freq[Chan] = freq>>shift; Amp[Chan] = 1<<Decay; Chan = (Chan + 1) & 3; }
Ptr рдЪрд░ рдкрдврд╝рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдЧрд▓реЗ рдмрд╛рдЗрдЯ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ:
void playMidiData () { Ptr = 0; // Begin at start of file
MIDI рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдкрд╣рд▓рд╛ рдмреНрд▓реЙрдХ рдПрдХ рд╣реЗрдбрд░ рд╣реИ рдЬреЛ рдкрдЯрд░рд┐рдпреЛрдВ, рдЯреЗрдореНрдкреЛ рдФрд░ рдбрд┐рд╡реАрдЬрди рдЕрдиреБрдкрд╛рдд рдХреА рд╕рдВрдЦреНрдпрд╛ рдХреЛ рдЗрдВрдЧрд┐рдд рдХрд░рддрд╛ рд╣реИ:
// Read header chunk unsigned long type = readNumber(4); if (type != MThd) error(1); unsigned long len = readNumber(4); unsigned int format = readNumber(2); unsigned int tracks = readNumber(2); unsigned int division = readNumber(2); // Ticks per beat TempoDivisor = (long)division*16000/Tempo;
рд╡рд┐рднрд╛рдЬрди рдЧреБрдгрд╛рдВрдХ рдЖрдорддреМрд░ рдкрд░ 960 рдХреЗ рдмрд░рд╛рдмрд░ рд╣реЛрддрд╛ рд╣реИред рдЕрдм рд╣рдо рджрд┐рдП рдЧрдП рдмреНрд▓реЙрдХреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдкрдврд╝рддреЗ рд╣реИрдВ:
// Read track chunks for (int t=0; t<tracks; t++) { type = readNumber(4); if (type != MTrk) error(2); len = readNumber(4); EndBlock = Ptr + len;
рдмреНрд▓реЙрдХ рдХреЗ рдЕрдВрдд рддрдХ рдЕрдиреБрдХреНрд░рдорд┐рдХ рдШрдЯрдирд╛рдУрдВ рдХреЛ рдкрдврд╝реЗрдВ:
// Parse track while (Ptr < EndBlock) { unsigned long delta = readVariable(); uint8_t event = readNumber(1); uint8_t eventType = event & 0xF0; if (delta > 0) Delay(delta/TempoDivisor);
рдкреНрд░рддреНрдпреЗрдХ рдШрдЯрдирд╛ рдореЗрдВ, рдбреЗрд▓реНрдЯрд╛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ - рд╡рд┐рднрд╛рдЬрди рдЧреБрдгрд╛рдВрдХ рджреНрд╡рд╛рд░рд╛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рд╕рдордп рдХреА рдЗрдХрд╛рдЗрдпреЛрдВ рдореЗрдВ рджреЗрд░реА, рдЬреЛ рдЗрд╕ рдШрдЯрдирд╛ рд╕реЗ рдкрд╣рд▓реЗ рд╣реЛрдиреА рдЪрд╛рд╣рд┐рдПред рдпрд╣рд╛рдВ рд╣реЛрдиреЗ рд╡рд╛рд▓реА рдШрдЯрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП, рдбреЗрд▓реНрдЯрд╛ рд╢реВрдиреНрдп рд╣реИред
рдореЗрдЯрд╛-рдЗрд╡реЗрдВрдЯреНрд╕ рдкреНрд░рдХрд╛рд░ рдХреА рдШрдЯрдирд╛рдПрдБ рд╣реИрдВ 0xFF:
// Meta event if (event == 0xFF) { uint8_t mtype = readNumber(1); uint8_t mlen = readNumber(1); // Tempo if (mtype == 0x51) { Tempo = readNumber(mlen); TempoDivisor = (long)division*16000/Tempo; // Ignore other meta events } else readIgnore(mlen);
рдПрдХрдорд╛рддреНрд░ рдкреНрд░рдХрд╛рд░ рдХреА рдореЗрдЯрд╛-рдШрдЯрдирд╛ рдЬреЛ рд╣рдореЗрдВ рд░реБрдЪрддреА рд╣реИ, рдЯреЗрдВрдкреЛ рд╣реИ, рдорд╛рдЗрдХреНрд░реЛрд╕реЗрдХрдВрдб рдореЗрдВ рдЯреЗрдореНрдкреЛ рдХрд╛ рдореВрд▓реНрдпред рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ, рдпрд╣ 500,000 рд╣реИ, рдпрд╛рдиреА рдЖрдзрд╛ рд╕реЗрдХрдВрдб, рдЬреЛ рдкреНрд░рддрд┐ рдорд┐рдирдЯ 120 рдмреАрдЯреНрд╕ рд╕реЗ рдореЗрд▓ рдЦрд╛рддреА рд╣реИред
рд╢реЗрд╖ рдШрдЯрдирд╛рдПрдВ рдорд┐рдбреА рдХреА рдШрдЯрдирд╛рдУрдВ рдХреЛ рдЙрдирдХреЗ рдкреНрд░рдХрд╛рд░ рдХреЗ рдкрд╣рд▓реЗ рд╣реЗрдХреНрд╕рд╛рдбреЗрд╕рд┐рдорд▓ рдЕрдВрдХ рджреНрд╡рд╛рд░рд╛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рд╣рдо рдХреЗрд╡рд▓ 0x90 рдореЗрдВ рд░реБрдЪрд┐ рд░рдЦрддреЗ рд╣реИрдВ - рдиреЛрдЯ рдкрд░, рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЙрдкрд▓рдмреНрдз рдЪреИрдирд▓ рдкрд░ рдиреЛрдЯреНрд╕ рдЦреЗрд▓ рд░рд╣реЗ рд╣реИрдВ:
// Note off - ignored } else if (eventType == 0x80) { uint8_t number = readNumber(1); uint8_t velocity = readNumber(1); // Note on } else if (eventType == 0x90) { uint8_t number = readNumber(1); uint8_t velocity = readNumber(1); noteOn(number); // Polyphonic key pressure } else if (eventType == 0xA0) readIgnore(2); // Controller change else if (eventType == 0xB0) readIgnore(2); // Program change else if (eventType == 0xC0) readIgnore(1); // Channel key pressure else if (eventType == 0xD0) readIgnore(1); // Pitch bend else if (eventType == 0xD0) readIgnore(2); else error(3); } } }
рд╣рдо рд╡реЗрдЧ рдорд╛рди рдХреЛ рдЕрдирджреЗрдЦрд╛ рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдпрджрд┐ рдЖрдк рдЪрд╛рд╣реЗрдВ, рддреЛ рдЖрдк рдЗрд╕ рдкрд░ рдиреЛрдЯ рдХрд╛ рдкреНрд░рд╛рд░рдВрднрд┐рдХ рдЖрдпрд╛рдо рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рд╣рдо рдмрд╛рдХреА рдШрдЯрдирд╛рдУрдВ рдХреЛ рдЫреЛрдбрд╝ рджреЗрддреЗ рд╣реИрдВ, рдЙрдирдХреА рд▓рдВрдмрд╛рдИ рдЕрд▓рдЧ рд╣реЛ рд╕рдХрддреА рд╣реИред рдпрджрд┐ рдорд┐рдбреА рдлрд╝рд╛рдЗрд▓ рдореЗрдВ рдХреЛрдИ рддреНрд░реБрдЯрд┐ рд╣реЛрддреА рд╣реИ, рддреЛ рдПрд▓рдИрдбреА рдЪрд╛рд▓реВ рд╣реЛрддрд╛ рд╣реИред
рдорд╛рдЗрдХреНрд░реЛрдХрдВрдЯреНрд░реЛрд▓рд░ 16 рдореЗрдЧрд╛рд╣рд░реНрдЯреНрдЬ рдХреА рдЖрд╡реГрддреНрддрд┐ рдкрд░ рд╕рдВрдЪрд╛рд▓рд┐рдд рд╣реЛрддрд╛ рд╣реИ, рддрд╛рдХрд┐ рдХреНрд╡рд╛рд░реНрдЯреНрдЬ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рди рд╣реЛ, рдЖрдкрдХреЛ рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд PLL рдХреЛ рдареАрдХ рд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд░рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИред Arduino- рд╕рдВрдЧрдд рдмрдирдиреЗ рдХреЗ рд▓рд┐рдП рдорд╛рдЗрдХреНрд░реЛрдХрдВрдЯреНрд░реЛрд▓рд░ рдХреЗ рд▓рд┐рдП, рд╕реНрдкреЗрдВрд╕ рдХреЛрдВрдбреЗ рдХрд╛
рдпрд╣ рдЕрдиреБрднрд╡ рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИред рдмреЛрд░реНрдб рдореЗрдиреВ рдореЗрдВ, ATtinyCore рд╕рдмрдореЗрдиреВ рдХрд╛ рдЪрдпрди рдХрд░реЗрдВ, рдФрд░ рд╡рд╣рд╛рдВ - ATtiny25 / 45/85ред рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдореЗрдиреВ рдореЗрдВ, рдЪрдпрди рдХрд░реЗрдВ: рдЯрд╛рдЗрдорд░ 1 рдХреНрд▓реЙрдХ: рд╕реАрдкреАрдпреВ, рдмреАрдУрдбреА рдбрд┐рд╕реЗрдмрд▓, рдПрдЯреАрдЯрд┐рдиреА 85, 16 рдореЗрдЧрд╛рд╣рд░реНрдЯреНрдЬ (рдкреАрдПрд▓рдПрд▓)ред рдлрд┐рд░ рдмрд░реНрди рдмреВрдЯрд▓реЛрдбрд░ рдЪреБрдиреЗрдВ, рдлрд┐рд░ рдкреНрд░реЛрдЧреНрд░рд╛рдо рдореЗрдВ рднрд░реЗрдВред рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдХрд╛ рдЙрдкрдпреЛрдЧ SpinyFun рдХреЗ рдЯрд┐рдиреА AVR рдкреНрд░реЛрдЧреНрд░рд╛рдорд░ рдмреЛрд░реНрдб рдХреА рддрд░рд╣ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
CC-BY 4.0 рдХреЗ рд▓рд┐рдП рдлрд░реНрдорд╡реЗрдпрд░, рдЬрд┐рд╕рдореЗрдВ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рдбреА рдорд╛рдЗрдирд░ рдореЗрдВ рдПрдХ рдмреИрдЪ рдлрд╝рдЧреНрдпреВ рд╣реИ,
рдпрд╣рд╛рдВ рдореВрд▓ рдУрдбреАрдЖрдИ рдлрд╝рд╛рдЗрд▓ рд▓реА рдЧрдИ
рд╣реИ ред