<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="pl-pl">
<link rel="self" type="application/atom+xml" href="https://forum.atnel.pl/feed.php?f=23&amp;t=8633&amp;mode" />

<title>ATNEL tech-forum</title>
<link href="https://forum.atnel.pl/index.php" />
<updated>2017-06-29T06:11:30+01:00</updated>

<author><name><![CDATA[ATNEL tech-forum]]></name></author>
<id>https://forum.atnel.pl/feed.php?f=23&amp;t=8633&amp;mode</id>
<entry>
<author><name><![CDATA[tiko98]]></name></author>
<updated>2017-06-29T06:11:30+01:00</updated>
<published>2017-06-29T06:11:30+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=191436#p191436</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=191436#p191436"/>
<title type="html"><![CDATA[Re: Odtwarzanie MIDI AVR hxMidiPlayer]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=191436#p191436"><![CDATA[
Chętnie skorzystał bym z przeróbki na Atmega8. Ale minęło już trochę czasu, to nie wiem czy się doczekam.<br />Pozdrawiam.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=12369">tiko98</a> — 29 cze 2017, o 06:11</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[ryba84]]></name></author>
<updated>2015-05-09T19:28:20+01:00</updated>
<published>2015-05-09T19:28:20+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=128678#p128678</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=128678#p128678"/>
<title type="html"><![CDATA[Re: Odtwarzanie MIDI AVR hxMidiPlayer]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=128678#p128678"><![CDATA[
W Protelu.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=3170">ryba84</a> — 9 maja 2015, o 19:28</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[pitat1]]></name></author>
<updated>2015-05-03T19:21:11+01:00</updated>
<published>2015-05-03T19:21:11+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=128146#p128146</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=128146#p128146"/>
<title type="html"><![CDATA[Re: Odtwarzanie MIDI AVR hxMidiPlayer]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=128146#p128146"><![CDATA[
Wiecie może w jakim programie są zrobione te projekty płytek ze strony autora?<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=9416">pitat1</a> — 3 maja 2015, o 19:21</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[ryba84]]></name></author>
<updated>2014-10-08T00:39:18+01:00</updated>
<published>2014-10-08T00:39:18+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=98039#p98039</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=98039#p98039"/>
<title type="html"><![CDATA[Re: Odtwarzanie MIDI AVR hxMidiPlayer]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=98039#p98039"><![CDATA[
<div class="quotetitle">mirekk36 napisał(a):</div><div class="quotecontent"><br />fajny projekt <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" /> ... tylko skąd ci ludzie biorą te muzyczki midi ? Tak z ciekawości pytam bo dla mnie tego typu audio projekty to nie jest chleb powszedni.<br /></div><br />Midi można pełno znaleźć w necie. W archiwum projektu ze strony autora jest kilkadziesiąt melodii (z gier, muzyki poważnej, filmów itp..). Dodatkowo na chomiku pełno plików od karaoke a to też midi tylko z innym rozszerzeniem <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" /> No i dzwonki do telefonów. Kiedyś midi to był dość popularny format. A trafiłem na tą stronę szukając jakiegoś sposobu na puszczanie melodyjek z AVR bez dodatkowego osprzętu (karty SD, zewnętrznego RAM itd..). Wiem, że łatwiej odtwarzać WAV, ale ile to wymaga pamięci (jakiejkolwiek) stąd pomysł na midi. Jeszcze tylko poprawię komentarze w kodzie i może przerobię to na Atmegę8 co by więcej ludzi mogło wypróbować. Dźwięk jest przyzwoitej jakości (dużo zależy od wybranej opcji podłączenia ze strony autora, u mnie np. nie sprawdza się ostatni schemat, ale to może być wina tego, że za głośnik służy mi słuchawka, którą wyszabrowałem od zestawu z jakiegoś starego telefonu).<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=3170">ryba84</a> — 8 paź 2014, o 00:39</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[SylwekK]]></name></author>
<updated>2014-10-08T00:00:20+01:00</updated>
<published>2014-10-08T00:00:20+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=98036#p98036</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=98036#p98036"/>
<title type="html"><![CDATA[Re: Odtwarzanie MIDI AVR hxMidiPlayer]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=98036#p98036"><![CDATA[
Ta muzyczka &quot;River flows in You&quot; mnie rozwala <img src="https://forum.atnel.pl/images/smilies/icon_e_smile.gif" alt=":)" title="Szczęśliwy" /> a sie miło słucha... (a na drugim kompie właśnie wesele próbuję montować  <img src="https://forum.atnel.pl/images/smilies/icon_lol.gif" alt=":lol:" title="Śmieje się" /> )<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=1922">SylwekK</a> — 8 paź 2014, o 00:00</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[mirekk36]]></name></author>
<updated>2014-10-07T23:09:42+01:00</updated>
<published>2014-10-07T23:09:42+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=98035#p98035</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=98035#p98035"/>
<title type="html"><![CDATA[Re: Odtwarzanie MIDI AVR hxMidiPlayer]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=98035#p98035"><![CDATA[
fajny projekt <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" /> ... tylko skąd ci ludzie biorą te muzyczki midi ? Tak z ciekawości pytam bo dla mnie tego typu audio projekty to nie jest chleb powszedni.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=54">mirekk36</a> — 7 paź 2014, o 23:09</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[ryba84]]></name></author>
<updated>2014-10-07T22:57:38+01:00</updated>
<published>2014-10-07T22:57:38+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=98034#p98034</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=98034#p98034"/>
<title type="html"><![CDATA[Re: Odtwarzanie MIDI AVR hxMidiPlayer]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=98034#p98034"><![CDATA[
Kolejna aktualizacja:<br />Struktura TMelody znajduje się również we flash (okazało się to łatwiejsze niż myślałem) <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" /><p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=3170">ryba84</a> — 7 paź 2014, o 22:57</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[ryba84]]></name></author>
<updated>2014-10-07T12:24:00+01:00</updated>
<published>2014-10-07T12:24:00+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=97911#p97911</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=97911#p97911"/>
<title type="html"><![CDATA[Re: Odtwarzanie MIDI AVR hxMidiPlayer]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=97911#p97911"><![CDATA[
Nie ma to jak sobie samemu odpowiedzieć. W pierwszym poście poprawione źródełka z samplami przetrzymywanymi w pamięci flash. Teraz ten kod pójdzie nawet na Atmega8 (po zmianach w main.c). Jedyne do czego jeszcze nie doszedłem to jak umieścić strukturę TMelody we flash (zawsze kilka bajtów mniej zużytego RAM-u).<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=3170">ryba84</a> — 7 paź 2014, o 12:24</p><hr />
]]></content>
</entry>
<entry>
<author><name><![CDATA[ryba84]]></name></author>
<updated>2014-10-07T22:55:29+01:00</updated>
<published>2014-09-25T16:44:16+01:00</published>
<id>https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=96676#p96676</id>
<link href="https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=96676#p96676"/>
<title type="html"><![CDATA[Odtwarzanie MIDI AVR hxMidiPlayer]]></title>

<content type="html" xml:base="https://forum.atnel.pl/viewtopic.php?t=8633&amp;p=96676#p96676"><![CDATA[
Witam.<br /><br />Projekt odtwarzacza plików MIDI opiera się na kodzie ze strony: <a href="http://www.deep-shadows.com/hax/wordpress/?page_id=1111"  class="postlink">http://www.deep-shadows.com/hax/wordpress/?page_id=1111</a>. Kod pierwotnie był przystosowany do kompilacji pod CodeVision AVR. Ja tylko przystosowałem kod biblioteki, aby kompilował się z AVR-GCC. Poniżej main.c dla Atmega2560, ale można łatwo przystosować do innej Atmegi z min. 4kB flash i jednym kanałem PWM pracującym w trybie Fast PWM. Na stronie autora znajdują się pliki projektu, oraz program do generowania melody.c i hxMidiPlayer_Config.h z wybranego pliku midi.<br /><br />Jak konwertować swoje pliki midi do odtwarzania przez AVR? Uruchamiamy program MidiToC pobrany ze strony widocznej na górze postu. Ustawiamy &quot;Sampling rate&quot; na taką częstotliwość z jaką będzie pracował timer obsługujący odtwarzanie. Wybieramy ilość kanałów (proponuję zacząć od 4), wybieramy obwiednię, zaznaczamy lub nie syntetyzer perkusji (Drums syntezer) i wczytujemy plik midi za pomocą &quot;Load midi&quot;. Program zacznie odtwarzać dźwięk mniej więcej jak nasz AVR. Po skorygowaniu ustawień tak by odpowiadały naszym upodobaniom możemy przejść do generowania plików. Klikamy &quot;Create player config&quot; i wklejamy ze schowka kod do pliku hxMidiPlayer_Config.h. Klikamy &quot;Create melody code&quot; i wklejamy do pliku melody.c.<br />Aby program działał pod AVR-GCC należy nanieść małe zmiany w plikach przed chwilą wygenerowanych:<br />- W pliku hxMidiPlayer_Config.h:<br /><ol style="list-style-type: decimal">należy usunąć wszystkie wystąpienia dyrektywy flash</ol><ol style="list-style-type: decimal">w tablicach s_noteFreqEx, s_sineTable, s_envelope i s_sample należy dodać atrybut PROGMEM</ol><ol style="list-style-type: decimal">ew. co by nam kompilator nie pluł warningami należy zakomentować na samym końcu HXMIDIPLAYER_CONFIG_INCLUDED</ol>- W pliku melody.c:<br /><ol style="list-style-type: decimal">należy usunąć wszystkie wystąpienia dyrektywy flash</ol><ol style="list-style-type: decimal">w tablicach s_melody_stream1 i s_melody_stream2 oraz strukturze s_melody należy dodać atrybut PROGMEM</ol><br />Po kompilacji możemy wrzucić program do AVR z podłączonym głośnikiem do wybranego pinu PWM. Na stronie autora jest kilka możliwych schematów łącznie ze schematem prostego wzmacniacza klasy D <img src="https://forum.atnel.pl/images/smilies/icon_e_wink.gif" alt=";)" title="Puszcza oko" />.<br /><br />Tak to działa (film autora):<br /><div style="width: 583px; height: 471px; margin: 0 auto; padding-left: 26px; padding-top: 48px; background: url('https://www.atnel.pl/download/atnel_tv.png') no-repeat;"> <strong>iframe</strong> </div><div style="width: 583px; height: 471px; margin: 0 auto; padding-left: 26px; padding-top: 48px; background: url('https://www.atnel.pl/download/atnel_tv.png') no-repeat;"> <strong>iframe</strong> </div><br /><br />Poniżej kod:<br />main.c<br />[syntax=c]#include &lt;avr/io.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &quot;melody.h&quot;<br />#include &quot;hxMidiPlayer.h&quot;<br /><br />//====================================================================<br />//====================================================================<br />// Timer0 output compare A interrupt service routine<br />ISR(TIMER1_COMPB_vect) {<br />Player_TimerFunc();<br />}<br /><br />//====================================================================<br />//====================================================================<br />//Note: in SQUARE Waveform mode, min value is 0 and max is HXMIDIPLAYER_CHANNELS_COUNT<br />//In all other modes, min is 0 and max is 255, while zero level is 128.<br />void Player_Output(uint8_t sample) {<br />#ifdef HXMIDIPLAYER_WAVEFORM_SQUARE<br />OCR1B = sample * (1023 / HXMIDIPLAYER_CHANNELS_COUNT);<br />#else<br />OCR1B = sample * 4;<br />#endif    <br />}<br /><br />//====================================================================<br />//====================================================================<br />void Player_Started() {<br />}<br /><br />//====================================================================<br />//====================================================================<br />void Player_Finished() {<br />Player_StartMelody(&amp;s_melody, 255);<br />}<br /><br />int main(void) {<br />// Declare your local variables here<br /><br />// Port initialization<br />// Func7=In Func6=In Func5=In Func4=In Func3=Out Func2=In Func1=In Func0=In <br />// State7=T State6=T State5=T State4=T State3=0 State2=T State1=T State0=T <br />//PORTB = 0x00;<br />//DDRB |= 0xff;<br />DDRB |= (1 &lt;&lt; PB6);<br /><br />// Timer/Counter 0 initialization<br />// Clock source: System Clock<br />// Clock value: 16000,000 kHz<br />// Mode: Fast PWM top=0xFF<br />// OC0A output: Non-Inverted PWM<br />// OC0B output: Disconnected<br />TCCR1A |= (1 &lt;&lt; COM1B1) | (1 &lt;&lt; WGM11) | (1 &lt;&lt; WGM10);<br />TCCR1B |= (1&lt;&lt;WGM12) | (1 &lt;&lt; CS10);<br />TIMSK1 |= (1 &lt;&lt; OCIE1B);<br /><br />// Global enable interrupts<br />sei();<br /><br />Player_StartMelody(&amp;s_melody, 0);<br /><br />while (1) {<br />// Place your code here<br /><br />}<br />}[/syntax]<br />hxMidiPlayer.c<br />[syntax=c]#include &lt;string.h&gt;<br />#include &lt;avr/interrupt.h&gt;<br />#include &lt;avr/pgmspace.h&gt;<br />#include &quot;hxMidiPlayer.h&quot;<br /><br />///=====================================================<br />// ChannelState<br />///=====================================================<br />///Single syntezer channel state  <br />typedef struct {<br />#ifdef HXMIDIPLAYER_WAVEFORM_SAMPLE<br />//can be 24 bit uint<br />uint32_t m_counter;//sample index counter<br />#else<br />uint16_t m_counter;      //square wave, sine or waveform generator counter<br />#endif<br />uint16_t m_counterAdd;   //0 - off, 1 - drum, &gt;0 - add value for counter<br /><br />#ifdef HXMIDIPLAYER_WAVEFORM_SINE_ENVELOPE<br />uint8_t m_envelopeCounter;<br />#endif    <br /><br />} TChannelState;<br /><br />#ifdef HXMIDIPLAYER_ENABLE_DRUMS_SYNTEZER<br />///=====================================================<br />// WhiteNoiseGeneratorState<br />///=====================================================<br />typedef struct {<br />uint8_t m_nze;<br />uint8_t m_t1;<br />uint8_t m_t2;<br />uint8_t m_t3;<br />}WhiteNoiseGeneratorState;<br />#endif<br /><br />#ifdef HXMIDIPLAYER_USE_COMPRESSION<br />///=====================================================<br />/// TCompressedStreamState<br />///=====================================================<br />typedef struct {<br />const uint8_t* m_pData;<br /><br />//number of bits still used in byte m_pData points to<br />uint8_t m_bitsUsed;<br />} TCompressedStreamState;<br />#endif<br /><br />///=====================================================<br />/// TPlayerState<br />///=====================================================<br />typedef struct {<br />#ifdef HXMIDIPLAYER_USE_COMPRESSION<br />//noteNumber stream, 11 bits<br />TCompressedStreamState m_stream1;<br />//pause stream, 13 bits<br />TCompressedStreamState m_stream2;<br /><br />const uint8_t* m_stream1_start;<br />const uint8_t* m_stream2_start;<br />#else<br />///pointer to next event in melody<br />const TPlayerStateChange* m_pMelody;<br />#endif<br /><br />#ifdef HXMIDIPLAYER_ENABLE_DRUMS_SYNTEZER<br />WhiteNoiseGeneratorState m_wngState;<br />#endif<br /><br />///This value is decreased on every timer event.<br />///Initially is writeln from m_delta value of StateChangeEvent.<br />///When it reaches 0, it's time to process state change events.<br />uint16_t m_eventCounter;<br /><br />//255Hz counter<br />//initally writeln ENVELOPE_SKIP_MAX<br />//decreased every tick<br />//when reaches 0, envelope index on all channels should increase<br />uint8_t m_envelopeSkipCounter;<br /><br />///Syntezer channels states<br />TChannelState m_channelState&#91;HXMIDIPLAYER_CHANNELS_COUNT&#93;;<br />} TPlayerState;<br /><br />///=====================================================<br />///=====================================================<br />///Player state<br />static TPlayerState s_playerState = {<br />#ifdef HXMIDIPLAYER_USE_COMPRESSION<br />{ NULL, 0 }, { NULL, 0 },<br />NULL,<br />NULL,<br />#else<br />NULL,<br />#endif    <br />#ifdef HXMIDIPLAYER_ENABLE_DRUMS_SYNTEZER<br />{0, 45, 34, 53}<br />#endif<br />};<br /><br />#ifdef HXMIDIPLAYER_ENABLE_DRUMS_SYNTEZER<br />///=====================================================<br />///=====================================================<br />static inline uint8_t Player_GetWhiteNoise() {<br />uint8_t b;<br />uint8_t b1;<br /><br />s_playerState.m_wngState.m_t1 = s_playerState.m_wngState.m_nze;<br />s_playerState.m_wngState.m_t1 &amp;= 66;<br /><br />if ((s_playerState.m_wngState.m_t1 != 0)<br />&amp;&amp; (s_playerState.m_wngState.m_t1 &lt; 66)) {<br />b = 1;<br />} else {<br />b = 0;<br />}<br /><br />b1 = s_playerState.m_wngState.m_t2 &gt;&gt; 7;<br />s_playerState.m_wngState.m_t2 &lt;&lt;= 1;<br />s_playerState.m_wngState.m_t2 |= b;<br />b = s_playerState.m_wngState.m_t3 &gt;&gt; 7;<br />s_playerState.m_wngState.m_t3 &lt;&lt;= 1;<br />s_playerState.m_wngState.m_t3 |= b1;<br />s_playerState.m_wngState.m_nze &lt;&lt;= 1;<br />s_playerState.m_wngState.m_nze |= b;<br /><br />return s_playerState.m_wngState.m_nze;<br />}<br />#endif<br /><br />///=====================================================<br />///=====================================================<br />static inline uint16_t Player_GetNoteFreqAdd(uint8_t _noteNumber) {<br />uint8_t noteIndex;<br />uint8_t noteDiv;<br /><br />noteIndex = 132 - 1 - _noteNumber;<br />noteDiv = noteIndex / 12;  //how many octaves down<br />noteIndex = noteIndex - 12 * noteDiv;<br />return pgm_read_word(&amp;s_noteFreqEx&#91;noteIndex&#93;) &gt;&gt; noteDiv;<br />}<br /><br />#ifdef HXMIDIPLAYER_USE_COMPRESSION<br /><br />///=====================================================<br />///=====================================================<br />//advance stream by number of bits<br />static inline void Player_Advance(TCompressedStreamState* _state,<br />uint16_t _bitsCount) {<br />uint16_t s;<br />s = _state-&gt;m_bitsUsed + _bitsCount;<br /><br />_state-&gt;m_pData += s &gt;&gt; 3;<br />_state-&gt;m_bitsUsed = s &amp; 0x7;<br />}<br /><br />///=====================================================<br />///=====================================================<br />static uint16_t Player_ReadBits(TCompressedStreamState* _state,<br />uint8_t _bitsCount, uint16_t _mask) {<br />//this procedure is optimized for _bitsCount 1..16<br />//(value can be spread at most by 3 bytes)<br /><br />uint32_t r;<br />int8_t s;<br /><br />r = pgm_read_byte(&amp;_state-&gt;m_pData&#91;0&#93;);<br /><br />r &lt;&lt;= 8;<br />r |= pgm_read_byte(&amp;_state-&gt;m_pData&#91;1&#93;);<br /><br />r &lt;&lt;= 8;<br />r |= pgm_read_byte(&amp;_state-&gt;m_pData&#91;2&#93;);<br /><br />s = 24 - _bitsCount - _state-&gt;m_bitsUsed;<br /><br />r &gt;&gt;= s;<br /><br />Player_Advance(_state, _bitsCount);<br /><br />return r &amp; _mask;<br />}<br /><br />///=====================================================<br />///=====================================================<br />//advance stream to actual data<br />void Player_StartStream(TCompressedStreamState* _state, uint8_t _numberOfBits) {<br />uint16_t s;<br /><br />s = Player_ReadBits(_state, 5, 0x1f);<br />Player_Advance(_state, 16 + s * _numberOfBits);<br />}<br /><br />///=====================================================<br />///=====================================================<br />static uint16_t Player_Decompress(TCompressedStreamState* _state,<br />const uint8_t* _streamBase, uint8_t _bitsCount, uint16_t _mask) {<br />uint8_t code;<br />TCompressedStreamState state;<br /><br />code = Player_ReadBits(_state, 3, 0x7);<br /><br />switch (code) {<br />case 0:<br />case 1:<br />case 2:<br />//use code as immediate value<br />break;<br /><br />case 3:<br />code = 3 + Player_ReadBits(_state, 1, 1);<br />break;<br /><br />case 4:<br />code = 5 + Player_ReadBits(_state, 2, 3);<br />break;<br /><br />case 5:<br />code = 9 + Player_ReadBits(_state, 3, 7);<br />break;<br /><br />case 6:<br />code = 17 + Player_ReadBits(_state, 3, 7);<br />break;<br /><br />case 7:<br />return Player_ReadBits(_state, _bitsCount, _mask);<br />}<br /><br />state.m_pData = _streamBase;<br />state.m_bitsUsed = 0;<br />Player_Advance(&amp;state, 5 + 16 + ((uint16_t) code) * _bitsCount);<br />return Player_ReadBits(&amp;state, _bitsCount, _mask); //review: doen't need advance<br />}<br />#endif<br /><br />///=====================================================<br />///=====================================================<br />static inline void Player_ProcessEvents() {<br />uint8_t channelIndex;<br />uint8_t noteNumber;<br />uint16_t delta;<br />uint16_t cadd;<br /><br />s_playerState.m_eventCounter = 0xffff;<br />sei();<br /><br />#ifdef HXMIDIPLAYER_USE_COMPRESSION<br />delta = Player_Decompress(&amp;s_playerState.m_stream1,<br />s_playerState.m_stream1_start, 11, 0x7ff);<br />noteNumber = delta &amp; 0x7f;<br />channelIndex = delta &gt;&gt; 7;<br /><br />delta = Player_Decompress(&amp;s_playerState.m_stream2,<br />s_playerState.m_stream2_start, 13, 0x1fff);<br /><br />if (delta == 0) {<br />cli();<br />s_playerState.m_stream1.m_pData = NULL;<br />Player_Finished();<br />return;<br />}<br /><br />#else    <br />delta = s_playerState.m_pMelody-&gt;m_delta;<br />noteNumber = s_playerState.m_pMelody-&gt;m_noteNumber;<br /><br />channelIndex = delta &amp; 0x7;<br />delta &gt;&gt;= 3;<br /><br />if ( delta == 0 )<br />{<br />cli();<br />s_playerState.m_pMelody = NULL;<br />Player_Finished();<br />return;<br />}<br /><br />channelIndex |= ( noteNumber &gt;&gt; (7 - 3 ) ) &amp; 8;<br /><br />noteNumber &amp;= 0x7f;<br />#endif<br /><br />if (noteNumber == 0) {<br />cadd = 0;<br />} else if (noteNumber == 1) {<br />cadd = 1;<br />} else {<br />cadd = Player_GetNoteFreqAdd(noteNumber);<br />}<br /><br />#ifndef HXMIDIPLAYER_USE_COMPRESSION            <br />s_playerState.m_pMelody++;<br />#endif    <br /><br />//mid delta is 1:<br />//do not hold interrupt for a long time:<br />//process next event on next tick event it should be processed immediatelly<br />//it wan't be noticable<br /><br />cli();<br /><br />s_playerState.m_channelState&#91;channelIndex&#93;.m_counter = 0;<br />s_playerState.m_channelState&#91;channelIndex&#93;.m_counterAdd = cadd;<br /><br />#ifdef HXMIDIPLAYER_WAVEFORM_SINE_ENVELOPE<br />s_playerState.m_channelState&#91;channelIndex&#93;.m_envelopeCounter = 0;<br />#endif    <br /><br />s_playerState.m_eventCounter = delta;<br />}<br /><br />///=====================================================<br />///=====================================================<br />void Player_TimerFunc() {<br />uint8_t sample;<br />uint8_t i;<br />TChannelState* pState;<br /><br />#ifdef HXMIDIPLAYER_USE_COMPRESSION<br />if (s_playerState.m_stream1.m_pData == NULL) {<br />return;<br />}<br />#else<br />if ( s_playerState.m_pMelody == NULL )<br />{<br />return;<br />}<br />#endif    <br /><br />//advance envelopeCounter<br />if (s_playerState.m_envelopeSkipCounter == 0) {<br />s_playerState.m_envelopeSkipCounter = ENVELOPE_SKIP_MAX;<br /><br />#ifdef HXMIDIPLAYER_WAVEFORM_SINE_ENVELOPE<br />for (i = 0; i &lt; HXMIDIPLAYER_CHANNELS_COUNT; i++) {<br />if (s_playerState.m_channelState&#91;i&#93;.m_envelopeCounter &lt; 255) {<br />s_playerState.m_channelState&#91;i&#93;.m_envelopeCounter++;<br />}<br />}<br />#endif    <br />s_playerState.m_eventCounter--;<br />if (s_playerState.m_eventCounter == 0) {<br />Player_ProcessEvents();<br />}<br />}<br />s_playerState.m_envelopeSkipCounter--;<br /><br />//create sample<br /><br />#ifdef HXMIDIPLAYER_WAVEFORM_SQUARE    <br />sample = 0;<br />#else<br />sample = 0x80;<br />#endif<br /><br />pState = &amp;s_playerState.m_channelState&#91;0&#93;;<br /><br />for (i = 0; i &lt; HXMIDIPLAYER_CHANNELS_COUNT; i++) {<br />#ifdef HXMIDIPLAYER_ENABLE_DRUMS_SYNTEZER    <br />if (pState-&gt;m_counterAdd == 1) {<br /><br />#ifdef HXMIDIPLAYER_WAVEFORM_SQUARE    <br />sample += Player_GetWhiteNoise() &amp; 1;<br />#else<br />if ( ( Player_GetWhiteNoise() &amp; 1 ) != 0 )<br />{<br />sample += 511 / HXMIDIPLAYER_CHANNELS_COUNT / 4;<br />}<br />#endif<br /><br />} else<br />#endif //drums syntezer        <br />{<br /><br />#ifdef HXMIDIPLAYER_WAVEFORM_SQUARE<br />pState-&gt;m_counter += pState-&gt;m_counterAdd;<br />sample += (pState-&gt;m_counter &gt;&gt; PLAYER_FREQ_SHR) &amp; 1;<br />#endif /*HXMIDIPLAYER_WAVEFORM_SQUARE*/<br /><br />#ifdef HXMIDIPLAYER_WAVEFORM_SINE<br />pState-&gt;m_counter += pState-&gt;m_counterAdd;<br />sample += pgm_read_byte(&amp;s_sineTable&#91; ( pState-&gt;m_counter &gt;&gt; (PLAYER_FREQ_SHR - 5 ) ) &amp; 63 &#93;);<br />#endif /*HXMIDIPLAYER_WAVEFORM_SINE*/<br /><br />#ifdef HXMIDIPLAYER_WAVEFORM_SINE_ENVELOPE<br />{<br />uint8_t sineVal;<br />uint8_t envelopeVal;<br />pState-&gt;m_counter += pState-&gt;m_counterAdd;<br />//sineVal is unsigned value, biased by 0x80 ( 0 -&gt; 0x80 )<br />sineVal =<br />pgm_read_byte(<br />&amp;s_sineTable&#91; ( pState-&gt;m_counter &gt;&gt; (PLAYER_FREQ_SHR - 5 ) ) &amp; 63 &#93;);<br />//envelopeVal is volume value 0..255<br />envelopeVal = pgm_read_byte(<br />&amp;s_envelope&#91;pState-&gt;m_envelopeCounter &gt;&gt; 1&#93;);<br />//scale sineVal as unsigned value using simple mul/shift. We divide by 256, not 255 for simplicity.<br />sineVal = (uint8_t) ((((uint16_t) sineVal) * envelopeVal) &gt;&gt; 8);<br />//after scaling, 0x80 (biased zero ) became m_envelopeVal / 2<br />//create unsigned value by biasing back<br />sineVal -= envelopeVal &gt;&gt; 1;<br />sample += sineVal;<br />}<br />#endif /*HXMIDIPLAYER_WAVEFORM_SINE_ENVELOPE*/<br /><br />#ifdef HXMIDIPLAYER_WAVEFORM_SAMPLE<br />if ( pState-&gt;m_counter &lt; PLAYER_COUNTER_MAX_VAL )<br />{<br />pState-&gt;m_counter += pState-&gt;m_counterAdd;<br />}<br />sample += s_sample&#91; pState-&gt;m_counter &gt;&gt; (PLAYER_FREQ_SHR - 3 ) &#93;;<br />#endif /*HXMIDIPLAYER_WAVEFORM_SAMPLE*/<br /><br />}<br />pState++;<br />}<br /><br />Player_Output(sample);<br />}<br /><br />///=====================================================<br />///=====================================================<br />void Player_StartMelody(const TMelody* _pMelody, uint16_t _delay) {<br />Player_Stop();<br /><br />Player_Started();<br /><br />memset(s_playerState.m_channelState, 0,<br />sizeof(TChannelState) * HXMIDIPLAYER_CHANNELS_COUNT);<br /><br />s_playerState.m_eventCounter = 1 + _delay;<br />s_playerState.m_envelopeSkipCounter = 0;<br /><br />cli();<br /><br />#ifdef HXMIDIPLAYER_USE_COMPRESSION<br />s_playerState.m_stream1.m_pData = (uint8_t *)pgm_read_word(&amp;_pMelody-&gt;m_pStream1);<br />s_playerState.m_stream2.m_pData = (uint8_t *)pgm_read_word(&amp;_pMelody-&gt;m_pStream2);<br />s_playerState.m_stream1.m_bitsUsed = 0;<br />s_playerState.m_stream2.m_bitsUsed = 0;<br /><br />s_playerState.m_stream1_start = (uint8_t *)pgm_read_word(&amp;_pMelody-&gt;m_pStream1);<br />s_playerState.m_stream2_start = (uint8_t *)pgm_read_word(&amp;_pMelody-&gt;m_pStream2);<br /><br />Player_StartStream(&amp;s_playerState.m_stream1, 11);<br />Player_StartStream(&amp;s_playerState.m_stream2, 13);<br />#else<br />s_playerState.m_pMelody = _pMelody-&gt;m_pEvents;<br />#endif<br /><br />sei();<br /><br />///Set initial values for white noise generator<br />//s_playerState.m_wngState.m_nze = 0;<br />//s_playerState.m_wngState.m_t1 = 45;<br />//s_playerState.m_wngState.m_t2 = 34;<br />//s_playerState.m_wngState.m_t3 = 53;<br />}<br /><br />///=====================================================<br />///=====================================================<br />bool Player_IsPlaying() {<br />#ifdef HXMIDIPLAYER_USE_COMPRESSION<br />return s_playerState.m_stream1.m_pData != NULL;<br />#else<br />return s_playerState.m_pMelody != NULL;<br />#endif    <br />}<br /><br />///=====================================================<br />///=====================================================<br />//Wait untill player finishes playing<br />void Player_WaitFinish() {<br />while (Player_IsPlaying() == true)<br />;<br />}<br /><br />///=====================================================<br />///=====================================================<br />void Player_Stop() {<br />if (Player_IsPlaying()) {<br />cli();<br /><br />#ifdef HXMIDIPLAYER_USE_COMPRESSION<br />s_playerState.m_stream1.m_pData = NULL;<br />#else          <br />s_playerState.m_pMelody = NULL;<br />#endif        <br /><br />sei();<br /><br />Player_Finished();<br />}<br />}[/syntax]<br />hxMidiPlayer.h<br />[syntax=c]#ifndef HXMIDIPLAYER_H_<br />#define HXMIDIPLAYER_H_<br /><br />#include &lt;stdint.h&gt;<br />#include &lt;stdbool.h&gt;<br />#include &lt;avr/pgmspace.h&gt;<br />#include &quot;hxMidiPlayer_Config.h&quot;<br /><br />#ifdef HXMIDIPLAYER_USE_COMPRESSION<br /><br />///=====================================================<br />///=====================================================<br />typedef struct {<br />const uint8_t* m_pStream1;<br />const uint8_t* m_pStream2;<br />} TMelody;<br /><br />#else<br /><br />///=====================================================<br />///=====================================================<br />typedef struct {<br />//highest bit is highest for channel index<br />uint8_t m_noteNumber;<br /><br />///15-3 bits - Delta value, 2,1,0 bits - channel index<br />uint16_t m_delta;<br />} TPlayerStateChange;<br /><br />///=====================================================<br />///=====================================================<br />typedef struct {<br />const TPlayerStateChange* m_pEvents;<br />} TMelody;<br /><br />#endif<br /><br />//======== Timer function ===========<br /><br />///Timer event function, should be called by user with fixed frequency HXMIDIPLAYER_SAMPLING_RATE<br />extern void Player_TimerFunc();<br /><br />//======== Callbacks ===========<br /><br />///Called by player to output data to DAC/pwm<br />extern void Player_Output(uint8_t sample);<br /><br />///Called by player when player starts to play<br />///( from Player_StartMelody() )<br />///Can be used to configure timer/pwm<br />extern void Player_Started();<br /><br />///Called by player when melody is finished<br />///( from Player_TimerFunc(), interrupts disabled )<br />///Can be used to configure timer/pwm<br />extern void Player_Finished();<br /><br />// ======== Control functions ===========<br /><br />///Start playing melody<br />//Previously played melody is stoped, Player_Finished callback is called.<br />//Player_Started() callback is called on start.<br />//_delay - start delay in 255Hz ticks, max is 65534<br />extern void Player_StartMelody(const TMelody* _pMelody, uint16_t _delay);<br /><br />/// ======== Misc functions ===========<br /><br />///Is player currently playing ?<br />extern bool Player_IsPlaying();<br /><br />///Wait untill player finish playing<br />//If not playing currently, returns immediatelly.<br />extern void Player_WaitFinish();<br /><br />//Stop currently played melody.<br />//Player_Finished() callback is called if was playing.<br />//If melody is not playing - call is ignored completely.<br />void Player_Stop();<br /><br />#endif /*HXMIDIPLAYER_H_*/[/syntax]<br />wygenerowany hxMidiPlayer_Config.h po poprawkach<br />[syntax=c]#ifndef HXMIDIPLAYER_CONFIG_INCLUDED<br />#define HXMIDIPLAYER_CONFIG_INCLUDED<br /><br />#include &lt;stdint.h&gt;<br /><br />//=====================================================<br />//=====================================================<br />//Player settings:<br />//Channels count: 8<br />//Frequency: 15625<br />//Pitch: 0<br />//Waveform: EWK_SQUARE<br /><br />//uncomment to place note frequency table in eeprom<br />//#define NOTES_TO_EEPROM<br /><br />//=====================================================<br />//=====================================================<br />#define HXMIDIPLAYER_SAMPLING_RATE          15625<br />#define HXMIDIPLAYER_CHANNELS_COUNT         8<br />#define HXMIDIPLAYER_WAVEFORM_SQUARE<br />#define HXMIDIPLAYER_ENABLE_DRUMS_SYNTEZER<br />#define HXMIDIPLAYER_USE_COMPRESSION<br />#define ENVELOPE_SKIP_MAX      61<br /><br />//Player frequency = 15625<br />//Pitch = 0<br />#define PLAYER_FREQ_SHR               14<br />#define PLAYER_COUNTER_MAX_VAL        0<br />static const<br />#ifdef NOTES_TO_EEPROM<br />//eeprom<br />#else<br />//flash<br />#endif<br />uint16_t PROGMEM s_noteFreqEx&#91; 12 &#93; PROGMEM = {0x8178, 0x7A34, 0x7357, 0x6CDF, 0x66C2, 0x60FE, 0x5B8C, 0x5668, 0x518F, 0x4CFB, 0x48A9, 0x4495};<br /><br />#endif /*HXMIDIPLAYER_CONFIG_INCLUDED*/[/syntax]<br />wygenerowane melody.c po porawkach<br />[syntax=c]#include &quot;melody.h&quot;<br /><br />//Player frequency=15625<br />//Player minimum channels count =8<br />const uint8_t s_melody_stream1&#91;2008&#93; PROGMEM = { 200, 82, 240, 128, 16, 36, 0, 192, 0,<br />3, 2, 18, 9, 184, 76, 38, 4, 240, 37, 4, 241, 144, 64, 70, 41, 52, 8,<br />99, 16, 35, 140, 18, 148, 21, 2, 136, 1, 159, 24, 92, 153, 65, 166, 121,<br />66, 230, 200, 58, 105, 241, 133, 201, 148, 25, 194, 143, 24, 92, 153,<br />65, 166, 121, 66, 230, 200, 58, 106, 248, 199, 229, 6, 12, 225, 17, 198,<br />28, 145, 4, 17, 30, 48, 37, 6, 112, 136, 195, 139, 203, 224, 206, 136,<br />225, 3, 139, 122, 32, 206, 136, 35, 132, 94, 47, 57, 53, 116, 70, 92,<br />95, 74, 12, 232, 142, 17, 184, 189, 228, 219, 132, 83, 79, 54, 161, 211,<br />17, 30, 48, 239, 131, 79, 140, 58, 96, 213, 217, 202, 4, 27, 99, 202,<br />71, 56, 33, 211, 112, 155, 119, 39, 208, 106, 207, 41, 28, 224, 7, 76,<br />68, 248, 195, 165, 209, 17, 227, 3, 147, 152, 53, 71, 148, 62, 110, 198,<br />77, 197, 244, 157, 16, 68, 120, 192, 148, 25, 194, 35, 14, 47, 47, 131,<br />58, 35, 132, 14, 45, 232, 131, 58, 32, 142, 17, 120, 188, 228, 213, 209,<br />25, 113, 125, 40, 51, 162, 56, 70, 226, 247, 147, 110, 17, 77, 60, 218,<br />135, 76, 68, 120, 195, 190, 13, 62, 48, 233, 131, 87, 103, 40, 16, 109,<br />143, 41, 28, 224, 135, 77, 194, 109, 220, 159, 65, 171, 60, 163, 243,<br />128, 29, 49, 19, 227, 14, 151, 68, 71, 140, 14, 78, 96, 213, 30, 80,<br />121, 187, 25, 55, 23, 210, 116, 65, 20, 16, 171, 227, 50, 213, 194, 116,<br />143, 57, 99, 132, 214, 58, 14, 18, 215, 24, 239, 65, 19, 178, 212, 252,<br />154, 145, 85, 201, 200, 141, 212, 193, 157, 17, 194, 46, 113, 228, 212,<br />243, 138, 42, 68, 59, 80, 66, 175, 140, 203, 87, 9, 215, 158, 114, 199,<br />9, 172, 116, 28, 37, 174, 49, 222, 68, 78, 202, 96, 206, 136, 215, 140,<br />222, 83, 221, 17, 175, 25, 188, 167, 193, 181, 60, 166, 243, 158, 29,<br />55, 37, 100, 34, 40, 33, 87, 198, 101, 171, 132, 233, 30, 114, 199, 9,<br />172, 116, 28, 37, 174, 49, 222, 130, 39, 101, 169, 249, 53, 34, 171,<br />147, 145, 27, 169, 131, 58, 35, 132, 92, 227, 201, 169, 231, 20, 84,<br />136, 118, 35, 132, 187, 57, 56, 131, 58, 32, 138, 179, 228, 233, 209, 4,<br />71, 140, 10, 96, 206, 17, 18, 34, 68, 42, 8, 68, 80, 66, 175, 140, 203,<br />87, 9, 210, 60, 229, 142, 19, 88, 232, 56, 75, 92, 99, 189, 4, 78, 203,<br />83, 242, 106, 69, 87, 39, 34, 55, 83, 6, 116, 71, 8, 185, 199, 147, 83,<br />206, 40, 169, 16, 237, 65, 10, 190, 51, 45, 92, 39, 94, 121, 203, 28,<br />38, 177, 208, 112, 150, 184, 199, 121, 17, 59, 41, 131, 58, 35, 94, 51,<br />121, 79, 116, 70, 188, 102, 242, 159, 6, 212, 242, 155, 206, 120, 116,<br />220, 149, 144, 136, 160, 133, 95, 25, 150, 174, 19, 164, 121, 203, 28,<br />38, 177, 208, 112, 150, 184, 199, 122, 8, 157, 150, 167, 228, 212, 138,<br />174, 78, 68, 110, 166, 12, 232, 142, 17, 115, 143, 38, 167, 156, 81, 82,<br />33, 216, 142, 18, 236, 228, 226, 12, 232, 130, 42, 207, 147, 167, 68,<br />17, 30, 48, 41, 131, 56, 68, 72, 137, 16, 168, 33, 17, 28, 121, 44, 137,<br />229, 16, 58, 34, 56, 242, 103, 6, 116, 68, 113, 181, 85, 201, 193, 231,<br />24, 59, 34, 39, 100, 160, 219, 242, 134, 232, 142, 17, 120, 192, 162,<br />13, 129, 229, 0, 58, 35, 146, 178, 17, 17, 199, 146, 200, 158, 81, 3,<br />162, 35, 143, 38, 112, 103, 68, 71, 27, 85, 92, 156, 30, 113, 132, 216,<br />242, 134, 30, 68, 34, 8, 160, 132, 65, 28, 149, 144, 136, 142, 60, 150,<br />68, 242, 136, 29, 17, 28, 121, 51, 131, 58, 34, 56, 218, 170, 228, 224,<br />243, 140, 29, 145, 19, 178, 80, 109, 249, 67, 116, 71, 8, 188, 96, 81,<br />6, 192, 242, 128, 29, 17, 201, 89, 8, 137, 241, 133, 201, 148, 26, 103,<br />148, 46, 108, 131, 166, 159, 24, 92, 153, 65, 156, 40, 241, 133, 201,<br />148, 26, 103, 148, 46, 108, 131, 166, 175, 140, 126, 80, 96, 206, 17,<br />28, 97, 201, 16, 65, 17, 227, 2, 80, 103, 8, 140, 56, 188, 190, 12, 232,<br />142, 16, 56, 183, 162, 12, 232, 130, 56, 69, 226, 243, 147, 87, 68, 101,<br />197, 244, 160, 206, 136, 225, 27, 139, 222, 77, 184, 69, 52, 243, 106,<br />29, 49, 17, 227, 14, 248, 52, 248, 195, 166, 13, 93, 156, 160, 65, 182,<br />60, 164, 115, 130, 29, 55, 9, 183, 114, 125, 6, 172, 242, 145, 206, 0,<br />116, 196, 79, 140, 58, 93, 17, 30, 48, 57, 57, 131, 84, 121, 67, 230,<br />236, 100, 220, 95, 73, 209, 4, 71, 140, 9, 65, 156, 34, 48, 226, 242,<br />248, 51, 162, 56, 64, 226, 222, 136, 51, 162, 8, 225, 23, 139, 206, 77,<br />93, 17, 151, 23, 210, 131, 58, 35, 132, 110, 47, 121, 54, 225, 20, 211,<br />205, 168, 116, 196, 71, 140, 59, 224, 211, 227, 14, 152, 53, 118, 114,<br />129, 6, 216, 242, 145, 206, 8, 116, 220, 38, 221, 201, 244, 26, 179,<br />202, 63, 56, 1, 211, 17, 62, 48, 233, 116, 68, 120, 192, 228, 230, 13,<br />81, 229, 7, 155, 177, 147, 113, 125, 39, 68, 17, 65, 10, 190, 51, 45,<br />92, 39, 72, 243, 150, 56, 77, 99, 160, 225, 45, 113, 142, 244, 17, 59,<br />45, 79, 201, 169, 21, 92, 156, 136, 221, 76, 25, 209, 28, 34, 231, 30,<br />77, 79, 56, 162, 164, 67, 181, 4, 42, 248, 204, 181, 112, 157, 121, 231,<br />44, 112, 154, 199, 65, 194, 90, 227, 29, 228, 68, 236, 166, 12, 232,<br />141, 120, 205, 229, 61, 209, 26, 241, 155, 202, 124, 27, 83, 202, 111,<br />57, 225, 211, 114, 86, 66, 34, 130, 21, 124, 102, 90, 184, 78, 145, 231,<br />44, 112, 154, 199, 65, 194, 90, 227, 29, 232, 34, 118, 90, 159, 147, 82,<br />42, 185, 57, 17, 186, 152, 51, 162, 56, 69, 206, 60, 154, 158, 113, 69,<br />72, 135, 98, 56, 75, 179, 147, 136, 51, 162, 8, 171, 62, 78, 157, 16,<br />68, 120, 192, 166, 12, 225, 17, 34, 36, 66, 160, 132, 69, 4, 42, 248,<br />204, 181, 112, 157, 35, 206, 88, 225, 53, 142, 131, 132, 181, 198, 59,<br />208, 68, 236, 181, 63, 38, 164, 85, 114, 114, 35, 117, 48, 103, 68, 112,<br />139, 156, 121, 53, 60, 226, 138, 145, 14, 212, 16, 171, 227, 50, 213,<br />194, 117, 231, 156, 177, 194, 107, 29, 7, 9, 107, 140, 119, 145, 19,<br />178, 152, 51, 162, 53, 227, 55, 148, 247, 68, 107, 198, 111, 41, 240,<br />109, 79, 41, 188, 231, 135, 77, 201, 89, 8, 138, 8, 85, 241, 153, 106,<br />225, 58, 71, 156, 177, 194, 107, 29, 7, 9, 107, 140, 119, 160, 137, 217,<br />106, 126, 77, 72, 170, 228, 228, 70, 234, 96, 206, 136, 225, 23, 56,<br />242, 106, 121, 197, 21, 34, 29, 136, 225, 46, 206, 78, 32, 206, 136, 34,<br />172, 249, 58, 116, 65, 17, 227, 2, 152, 51, 132, 68, 136, 145, 10, 130,<br />17, 17, 199, 146, 200, 158, 81, 3, 162, 35, 143, 38, 112, 103, 68, 71,<br />27, 85, 92, 156, 30, 113, 131, 178, 34, 118, 74, 13, 191, 40, 110, 136,<br />225, 23, 140, 10, 32, 216, 30, 80, 3, 162, 57, 43, 33, 17, 28, 121, 44,<br />137, 229, 16, 58, 34, 56, 242, 103, 6, 116, 68, 113, 181, 85, 201, 193,<br />231, 24, 77, 143, 40, 97, 228, 66, 32, 138, 8, 68, 17, 201, 89, 8, 136,<br />227, 201, 100, 79, 40, 129, 209, 17, 199, 147, 56, 51, 162, 35, 141,<br />170, 174, 78, 15, 56, 193, 217, 17, 59, 37, 6, 223, 148, 55, 68, 112,<br />139, 198, 5, 16, 108, 15, 40, 1, 209, 28, 149, 144, 136, 159, 24, 92,<br />153, 65, 166, 121, 66, 230, 200, 58, 105, 241, 133, 201, 148, 25, 194,<br />143, 24, 92, 153, 65, 166, 121, 66, 230, 200, 58, 106, 248, 199, 229, 6,<br />12, 225, 17, 198, 28, 145, 4, 17, 30, 48, 37, 6, 112, 136, 195, 139,<br />203, 224, 206, 136, 225, 3, 139, 122, 32, 206, 136, 35, 132, 94, 47, 57,<br />53, 116, 70, 92, 95, 74, 12, 232, 142, 17, 184, 189, 228, 219, 132, 83,<br />79, 54, 161, 211, 17, 30, 48, 239, 131, 79, 140, 58, 96, 213, 217, 202,<br />4, 27, 99, 202, 71, 56, 33, 211, 112, 155, 119, 39, 208, 106, 207, 41,<br />28, 224, 7, 76, 68, 248, 195, 165, 209, 17, 227, 3, 147, 152, 53, 71,<br />148, 62, 110, 198, 77, 197, 244, 157, 16, 68, 120, 192, 148, 25, 194,<br />35, 14, 47, 47, 131, 58, 35, 132, 14, 45, 232, 131, 58, 32, 142, 17,<br />120, 188, 228, 213, 209, 25, 113, 125, 40, 51, 162, 56, 70, 226, 247,<br />147, 110, 17, 77, 60, 218, 135, 76, 68, 120, 195, 190, 13, 62, 48, 233,<br />131, 87, 103, 40, 16, 109, 143, 41, 28, 224, 135, 77, 194, 109, 220,<br />159, 65, 171, 60, 163, 243, 128, 29, 49, 19, 227, 14, 151, 68, 71, 140,<br />14, 78, 96, 213, 30, 80, 121, 187, 25, 55, 23, 210, 116, 65, 19, 178,<br />136, 50, 193, 200, 195, 140, 9, 65, 157, 17, 194, 39, 24, 20, 65, 157,<br />17, 194, 46, 124, 154, 193, 184, 77, 87, 57, 28, 38, 221, 76, 27, 126,<br />80, 92, 44, 249, 53, 221, 214, 239, 148, 143, 56, 99, 102, 92, 102, 218,<br />182, 151, 25, 176, 109, 143, 41, 188, 219, 138, 219, 140, 206, 78, 96,<br />220, 38, 241, 149, 201, 220, 24, 207, 148, 142, 111, 3, 183, 24, 114,<br />35, 132, 94, 48, 45, 88, 80, 121, 192, 14, 200, 130, 39, 101, 16, 101,<br />131, 145, 135, 24, 18, 131, 58, 35, 132, 78, 48, 40, 131, 58, 35, 132,<br />92, 249, 53, 131, 112, 154, 174, 114, 56, 77, 186, 152, 54, 252, 160,<br />184, 89, 242, 107, 187, 173, 223, 9, 17, 194, 111, 25, 74, 213, 194,<br />108, 184, 202, 131, 112, 154, 116, 230, 220, 77, 172, 228, 230, 13, 87,<br />24, 252, 157, 193, 140, 105, 24, 39, 145, 28, 32, 16, 184, 60, 160, 135,<br />68, 17, 30, 48, 37, 6, 112, 136, 195, 139, 203, 224, 206, 136, 225, 3,<br />139, 122, 32, 206, 136, 35, 132, 94, 47, 57, 53, 116, 70, 92, 95, 74,<br />12, 232, 142, 17, 184, 189, 228, 219, 132, 83, 79, 54, 161, 211, 17, 30,<br />48, 239, 131, 79, 140, 58, 96, 213, 217, 202, 4, 27, 99, 202, 71, 56,<br />33, 211, 112, 155, 119, 39, 208, 106, 207, 41, 28, 224, 7, 76, 68, 248,<br />195, 165, 209, 17, 227, 3, 147, 152, 53, 71, 148, 62, 110, 198, 77, 197,<br />244, 157, 16, 68, 120, 192, 148, 25, 194, 35, 14, 47, 47, 131, 58, 35,<br />132, 14, 45, 232, 131, 58, 32, 142, 17, 120, 188, 228, 213, 209, 25,<br />113, 125, 40, 51, 162, 56, 70, 226, 247, 147, 110, 17, 77, 60, 218, 135,<br />76, 68, 120, 195, 190, 13, 62, 48, 233, 131, 87, 103, 40, 16, 109, 143,<br />41, 28, 224, 135, 77, 194, 109, 220, 159, 65, 171, 60, 163, 243, 128,<br />29, 49, 19, 227, 14, 151, 68, 71, 140, 14, 78, 96, 213, 30, 80, 121,<br />187, 25, 55, 23, 210, 116, 65, 112 };<br /><br />const uint8_t s_melody_stream2&#91;1142&#93; PROGMEM = { 104, 82, 240, 0, 64, 6, 2, 224, 1, 0,<br />88, 3, 32, 34, 1, 40, 18, 0, 42, 0, 192, 38, 0, 0, 0, 98, 0, 49, 2, 64,<br />3, 16, 36, 0, 49, 0, 24, 129, 192, 76, 0, 49, 2, 163, 17, 32, 98, 98,<br />98, 0, 40, 8, 20, 0, 103, 0, 204, 0, 80, 12, 229, 1, 0, 10, 0, 51, 128,<br />80, 16, 0, 20, 0, 103, 0, 20, 4, 13, 0, 65, 156, 0, 80, 16, 0, 20, 0,<br />103, 0, 20, 4, 0, 40, 0, 206, 0, 40, 1, 0, 10, 103, 0, 20, 4, 10, 0, 51,<br />128, 102, 0, 40, 6, 114, 128, 128, 5, 0, 25, 192, 40, 8, 0, 10, 0, 51,<br />128, 10, 2, 6, 128, 32, 206, 0, 40, 8, 0, 10, 0, 51, 128, 10, 2, 0, 20,<br />0, 103, 0, 20, 0, 128, 5, 51, 130, 160, 1, 64, 6, 112, 1, 64, 64, 2,<br />128, 103, 0, 160, 32, 10, 0, 51, 128, 80, 128, 0, 160, 25, 192, 5, 64,<br />2, 128, 12, 224, 2, 128, 128, 5, 0, 25, 192, 40, 8, 0, 80, 1, 156, 0,<br />80, 16, 5, 6, 112, 84, 0, 40, 0, 206, 0, 40, 8, 0, 80, 12, 224, 20, 4,<br />1, 64, 6, 112, 10, 16, 0, 20, 3, 56, 6, 96, 2, 128, 103, 40, 8, 0, 83,<br />56, 0, 160, 32, 80, 103, 5, 64, 20, 25, 193, 80, 0, 160, 3, 56, 0, 160,<br />32, 1, 64, 51, 128, 80, 16, 5, 0, 25, 192, 40, 64, 0, 80, 12, 224, 2,<br />160, 1, 64, 6, 112, 1, 64, 64, 2, 128, 12, 224, 20, 4, 0, 40, 0, 206, 0,<br />40, 8, 2, 131, 56, 42, 0, 20, 0, 103, 0, 20, 4, 0, 40, 6, 112, 10, 2, 0,<br />160, 3, 56, 5, 8, 0, 10, 1, 156, 3, 48, 1, 64, 51, 148, 4, 0, 41, 156,<br />0, 80, 16, 40, 51, 130, 160, 10, 12, 224, 72, 3, 16, 12, 64, 6, 32, 24,<br />128, 98, 0, 49, 0, 24, 128, 12, 65, 136, 49, 0, 24, 128, 98, 1, 136, 49,<br />6, 32, 72, 3, 16, 12, 64, 6, 32, 24, 128, 98, 0, 49, 0, 24, 128, 98, 12,<br />76, 65, 136, 49, 49, 6, 32, 196, 9, 0, 98, 1, 136, 0, 196, 3, 16, 12,<br />64, 6, 32, 3, 16, 1, 136, 49, 6, 32, 3, 16, 12, 64, 49, 6, 32, 196, 0,<br />98, 0, 49, 2, 64, 3, 16, 36, 0, 49, 0, 24, 129, 192, 76, 0, 49, 2, 163,<br />17, 32, 98, 98, 98, 0, 40, 8, 20, 0, 103, 0, 204, 0, 80, 12, 229, 1, 0,<br />10, 0, 51, 128, 80, 16, 0, 20, 0, 103, 0, 20, 4, 13, 0, 65, 156, 0, 80,<br />16, 0, 20, 0, 103, 0, 20, 4, 0, 40, 0, 206, 0, 40, 1, 0, 10, 103, 0, 20,<br />4, 10, 0, 51, 128, 102, 0, 40, 6, 114, 128, 128, 5, 0, 25, 192, 40, 8,<br />0, 10, 0, 51, 128, 10, 2, 6, 128, 32, 206, 0, 40, 8, 0, 10, 0, 51, 128,<br />10, 2, 0, 20, 0, 103, 0, 20, 0, 128, 5, 51, 130, 160, 1, 64, 6, 112, 1,<br />64, 64, 2, 128, 103, 0, 160, 32, 10, 0, 51, 128, 80, 128, 0, 160, 25,<br />192, 5, 64, 2, 128, 12, 224, 2, 128, 128, 5, 0, 25, 192, 40, 8, 0, 80,<br />1, 156, 0, 80, 16, 5, 6, 112, 84, 0, 40, 0, 206, 0, 40, 8, 0, 80, 12,<br />224, 20, 4, 1, 64, 6, 112, 10, 16, 0, 20, 3, 56, 6, 96, 2, 128, 103, 40,<br />8, 0, 83, 56, 0, 160, 32, 80, 103, 5, 64, 20, 25, 193, 80, 0, 160, 3,<br />56, 0, 160, 32, 1, 64, 51, 128, 80, 16, 5, 0, 25, 192, 40, 64, 0, 80,<br />12, 224, 2, 160, 1, 64, 6, 112, 1, 64, 64, 2, 128, 12, 224, 20, 4, 0,<br />40, 0, 206, 0, 40, 8, 2, 131, 56, 42, 0, 20, 0, 103, 0, 20, 4, 0, 40, 6,<br />112, 10, 2, 0, 160, 3, 56, 5, 8, 0, 10, 1, 156, 3, 48, 1, 64, 51, 148,<br />4, 0, 41, 156, 0, 80, 16, 40, 51, 130, 160, 10, 12, 224, 72, 3, 16, 12,<br />64, 6, 32, 24, 128, 98, 0, 49, 0, 24, 128, 12, 65, 136, 49, 0, 24, 128,<br />98, 1, 136, 49, 6, 32, 72, 3, 16, 12, 64, 6, 32, 24, 128, 98, 0, 49, 0,<br />24, 128, 98, 12, 76, 65, 136, 49, 49, 6, 32, 196, 9, 0, 98, 1, 136, 0,<br />196, 3, 16, 12, 64, 6, 32, 3, 16, 1, 136, 49, 6, 32, 3, 16, 12, 64, 49,<br />6, 32, 196, 0, 98, 0, 49, 2, 64, 3, 16, 36, 0, 49, 0, 24, 129, 192, 76,<br />0, 49, 2, 163, 17, 32, 98, 98, 98, 0, 40, 8, 20, 0, 103, 0, 204, 0, 80,<br />12, 229, 1, 0, 10, 0, 51, 128, 80, 16, 0, 20, 0, 103, 0, 20, 4, 13, 0,<br />65, 156, 0, 80, 16, 0, 20, 0, 103, 0, 20, 4, 0, 40, 0, 206, 0, 40, 1, 0,<br />10, 103, 0, 20, 4, 10, 0, 51, 128, 102, 0, 40, 6, 114, 128, 128, 5, 0,<br />25, 192, 40, 8, 0, 10, 0, 51, 128, 10, 2, 6, 128, 32, 206, 0, 40, 8, 0,<br />10, 0, 51, 128, 10, 2, 0, 20, 0, 103, 0, 20, 0, 128, 5, 51, 128, 10, 16,<br />5, 0, 25, 192, 51, 0, 20, 3, 56, 0, 160, 32, 10, 0, 51, 130, 132, 0, 40,<br />51, 128, 10, 0, 64, 208, 4, 25, 192, 5, 0, 32, 104, 2, 12, 224, 2, 128,<br />128, 40, 6, 112, 1, 64, 64, 166, 112, 1, 66, 0, 160, 3, 56, 6, 96, 2,<br />128, 103, 0, 20, 4, 1, 64, 6, 112, 80, 128, 5, 6, 112, 10, 2, 6, 128,<br />32, 206, 0, 40, 1, 3, 64, 16, 103, 0, 170, 105, 0, 160, 220, 1, 84, 128,<br />85, 52, 148, 206, 0, 40, 8, 20, 0, 103, 0, 204, 0, 80, 12, 229, 1, 0,<br />10, 0, 51, 128, 80, 16, 0, 20, 0, 103, 0, 20, 4, 13, 0, 65, 156, 0, 80,<br />16, 0, 20, 0, 103, 0, 20, 4, 0, 40, 0, 206, 0, 40, 1, 0, 10, 103, 0, 20,<br />4, 10, 0, 51, 128, 102, 0, 40, 6, 114, 128, 128, 5, 0, 25, 192, 40, 8,<br />0, 10, 0, 51, 128, 10, 2, 6, 128, 32, 206, 0, 40, 8, 0, 10, 0, 51, 128,<br />10, 2, 0, 20, 0, 103, 0, 20, 0, 128, 5, 10, 192 };<br /><br />const TMelody s_melody PROGMEM = { s_melody_stream1, s_melody_stream2 };[/syntax]<br />melody.h<br />[syntax=c]#ifndef MELODY_H_<br />#define MELODY_H_<br /><br />#include &quot;hxMidiPlayer.h&quot;<br /><br />extern const TMelody s_melody;<br /><br />#endif /*MELODY_H_*/[/syntax]<br /><br />Powyższy kod jest uruchomiony na 16 bitowym timerze. W przypadku uruchamiania na 8 bitowym timerze funkcja Player_Output powinna wyglądać tak:[syntax=c]void Player_Output(uint8_t sample) {<br />#ifdef HXMIDIPLAYER_WAVEFORM_SQUARE<br />OCR1B = sample * (255 / HXMIDIPLAYER_CHANNELS_COUNT);<br />#else<br />OCR1B = sample;<br />#endif    <br />}[/syntax]<br />Jak ktoś jest oblatany w Deplhi mógłby pomóc zmienić kod MidiToC tak by generował gotowe pliki pod AVR-GCC. Źródełka programu znajdują się na stronie autora. Uwaga synteza dźwięku nie jest lekkim zadaniem dla małych AVR-ków, więc polecam zegar min. 16MHz (nie próbowałem na niższym). Zegar będzie głównym ogranicznikiem ilości kanałów i częstotliwości próbkowania z jaką będziemy mogli odtwarzać melodie. Więcej na ten temat na stronie autora.<p>Statystyki: Napisane przez <a href="https://forum.atnel.pl/memberlist.php?mode=viewprofile&amp;u=3170">ryba84</a> — 25 wrz 2014, o 16:44</p><hr />
]]></content>
</entry>
</feed>