C ++, 15186 bytes
Há um link na parte inferior onde você pode ouvir uma amostra
Apresento uma das maneiras menos práticas de tocar música em sua máquina Linux:
#include <SFML/Audio.hpp>
#include <cmath>
#include <iostream>
#include <fstream>
#include <string>
namespace N{double a = 440.;double as = 466.16;double b = 493.88;double c = 523.25;double cs = 554.37;double d = 587.33;double ds = 622.25;double e = 659.25;double f = 698.46;double fs = 739.99 ;double g = 783.99;double gs = 830.61; const unsigned SAMPLES = 10*44100;const unsigned SAMPLE_RATE = 44100;const unsigned AMPLITUDE = 10000;const double TWO_PI = 6.28318; sf::Int16 a4raw[SAMPLES];sf::Int16 as4raw[SAMPLES];sf::Int16 b4raw[SAMPLES];sf::Int16 c4raw[SAMPLES];sf::Int16 cs4raw[SAMPLES];sf::Int16 d4raw[SAMPLES];sf::Int16 ds4raw[SAMPLES];sf::Int16 e4raw[SAMPLES];sf::Int16 f4raw[SAMPLES];sf::Int16 fs4raw[SAMPLES];sf::Int16 g4raw[SAMPLES];sf::Int16 gs4raw[SAMPLES];sf::Int16 pauseraw[SAMPLES];double inc = a/44100;double x=0;int i=0;void set1(){for(int i=0;i<SAMPLES;i++){a4raw[i]=AMPLITUDE*sin(x*TWO_PI);x+=inc;}inc=as/44100;x=0;for(unsigned i=0;i<SAMPLES;i++){as4raw[i]=AMPLITUDE*sin(x*TWO_PI);x += inc;}inc=b/44100;x=0;for(unsigned i=0;i<SAMPLES;i++){b4raw[i]=AMPLITUDE*sin(x*TWO_PI);x+=inc;}inc=c/44100;x=0;for(unsigned i=0;i<SAMPLES;i++){c4raw[i]=AMPLITUDE * sin(x*TWO_PI);x+=inc;}inc=cs/44100;x=0;for(unsigned i=0;i<SAMPLES;i++){cs4raw[i]=AMPLITUDE*sin(x*TWO_PI);x+=inc;}inc=d/44100;x=0;for(unsigned i=0;i<SAMPLES;i++){d4raw[i]=AMPLITUDE*sin(x*TWO_PI);x+=inc;}inc=ds/44100;x=0;for(unsigned i=0;i<SAMPLES;i++){ds4raw[i]=AMPLITUDE*sin(x*TWO_PI);x+=inc;}inc=e/44100;x=0;for(unsigned i=0;i<SAMPLES;i++){e4raw[i]=AMPLITUDE*sin(x*TWO_PI);x+=inc;}inc=f/44100;x=0;for(unsigned i=0;i<SAMPLES;i++){f4raw[i]=AMPLITUDE*sin(x*TWO_PI);x+=inc;}inc=fs/44100;x=0;for(unsigned i=0;i<SAMPLES;i++){fs4raw[i]=AMPLITUDE*sin(x*TWO_PI);x+=inc;}inc=g/44100;x=0;for(unsigned i=0;i<SAMPLES;i++){g4raw[i]=AMPLITUDE*sin(x*TWO_PI);x+=inc;} inc=gs/44100;x=0;for(unsigned i=0;i<SAMPLES;i++){gs4raw[i]=AMPLITUDE*sin(x*TWO_PI);x+=inc;}}sf::SoundBuffer a3; sf::SoundBuffer a4; sf::SoundBuffer a5; sf::SoundBuffer a6; sf::SoundBuffer a7;sf::SoundBuffer as3; sf::SoundBuffer as4; sf::SoundBuffer as5; sf::SoundBuffer as6; sf::SoundBuffer as7;sf::SoundBuffer b3; sf::SoundBuffer b4; sf::SoundBuffer b5; sf::SoundBuffer b6; sf::SoundBuffer b7;sf::SoundBuffer c3; sf::SoundBuffer c4; sf::SoundBuffer c5; sf::SoundBuffer c6; sf::SoundBuffer c7;sf::SoundBuffer cs3; sf::SoundBuffer cs4; sf::SoundBuffer cs5; sf::SoundBuffer cs6; sf::SoundBuffer cs7;sf::SoundBuffer d3; sf::SoundBuffer d4; sf::SoundBuffer d5; sf::SoundBuffer d6; sf::SoundBuffer d7;sf::SoundBuffer ds3; sf::SoundBuffer ds4; sf::SoundBuffer ds5; sf::SoundBuffer ds6; sf::SoundBuffer ds7;sf::SoundBuffer e3; sf::SoundBuffer e4; sf::SoundBuffer e5; sf::SoundBuffer e6; sf::SoundBuffer e7;sf::SoundBuffer f3; sf::SoundBuffer f4; sf::SoundBuffer f5; sf::SoundBuffer f6; sf::SoundBuffer f7;sf::SoundBuffer fs3; sf::SoundBuffer fs4; sf::SoundBuffer fs5; sf::SoundBuffer fs6; sf::SoundBuffer fs7;sf::SoundBuffer g3; sf::SoundBuffer g4; sf::SoundBuffer g5; sf::SoundBuffer g6; sf::SoundBuffer g7;sf::SoundBuffer gs3; sf::SoundBuffer gs4; sf::SoundBuffer gs5; sf::SoundBuffer gs6; sf::SoundBuffer gs7;sf::SoundBuffer pauseBuffer;void set2(){if (!a3.loadFromSamples(a4raw,SAMPLES,1,SAMPLE_RATE/2)){std::cerr<<"err: load fail";}if(!a4.loadFromSamples(a4raw,SAMPLES,1,SAMPLE_RATE)){std::cerr<<"err: load fail";}if(!a5.loadFromSamples(a4raw, SAMPLES, 1, SAMPLE_RATE*2)){std::cerr<<"err: load fail";}if(!a6.loadFromSamples(a4raw,SAMPLES,1,SAMPLE_RATE*4)){std::cerr<<"err: load fail";}if(!a7.loadFromSamples(a4raw,SAMPLES,1, SAMPLE_RATE*8)){std::cerr<<"err: load fail";} if (!as3.loadFromSamples(as4raw, SAMPLES, 1, SAMPLE_RATE/2)){std::cerr<<"err: load fail";}if (!as4.loadFromSamples(as4raw, SAMPLES, 1, SAMPLE_RATE)){std::cerr<<"err: load fail";}if (!as5.loadFromSamples(as4raw, SAMPLES, 1, SAMPLE_RATE*2)){std::cerr<<"err: load fail";}if (!as6.loadFromSamples(as4raw, SAMPLES, 1, SAMPLE_RATE*4)){std::cerr<<"err: load fail";}if (!as7.loadFromSamples(as4raw, SAMPLES, 1, SAMPLE_RATE*8)){std::cerr<<"err: load fail";}if (!b3.loadFromSamples(b4raw, SAMPLES, 1, SAMPLE_RATE/2)){std::cerr<<"err: load fail";}if (!b4.loadFromSamples(b4raw, SAMPLES, 1, SAMPLE_RATE)){std::cerr<<"err: load fail";}if (!b5.loadFromSamples(b4raw, SAMPLES, 1, SAMPLE_RATE*2)){std::cerr<<"err: load fail";}if (!b6.loadFromSamples(b4raw, SAMPLES, 1, SAMPLE_RATE*4)){std::cerr<<"err: load fail";}if (!b7.loadFromSamples(b4raw, SAMPLES, 1, SAMPLE_RATE*8)){std::cerr<<"err: load fail";}if (!c3.loadFromSamples(c4raw, SAMPLES, 1, SAMPLE_RATE/2)){std::cerr<<"err: load fail";}if (!c4.loadFromSamples(c4raw, SAMPLES, 1, SAMPLE_RATE)){std::cerr<<"err: load fail";}if (!c5.loadFromSamples(c4raw, SAMPLES, 1, SAMPLE_RATE*2)){std::cerr<<"err: load fail";}if (!c6.loadFromSamples(c4raw, SAMPLES, 1, SAMPLE_RATE*4)){std::cerr<<"err: load fail";}if (!c7.loadFromSamples(c4raw, SAMPLES, 1, SAMPLE_RATE*8)){std::cerr<<"err: load fail";}if (!cs3.loadFromSamples(cs4raw, SAMPLES, 1, SAMPLE_RATE/2)){std::cerr<<"err: load fail";}if (!cs4.loadFromSamples(cs4raw, SAMPLES, 1, SAMPLE_RATE)){std::cerr<<"err: load fail";}if (!cs5.loadFromSamples(cs4raw, SAMPLES, 1, SAMPLE_RATE*2)){std::cerr<<"err: load fail";}if (!cs6.loadFromSamples(cs4raw, SAMPLES, 1, SAMPLE_RATE*4)){std::cerr<<"err: load fail";}if (!cs7.loadFromSamples(cs4raw, SAMPLES, 1, SAMPLE_RATE*8)){std::cerr<<"err: load fail";}if (!d3.loadFromSamples(d4raw, SAMPLES, 1, SAMPLE_RATE/2)){std::cerr<<"err: load fail";}if (!d4.loadFromSamples(d4raw, SAMPLES, 1, SAMPLE_RATE)){std::cerr<<"err: load fail";}if (!d5.loadFromSamples(d4raw, SAMPLES, 1, SAMPLE_RATE*2)){std::cerr<<"err: load fail";}if (!d6.loadFromSamples(d4raw, SAMPLES, 1, SAMPLE_RATE*4)){std::cerr<<"err: load fail";}if (!d7.loadFromSamples(d4raw, SAMPLES, 1, SAMPLE_RATE*8)){std::cerr<<"err: load fail";}if (!ds3.loadFromSamples(ds4raw, SAMPLES, 1, SAMPLE_RATE/2)){std::cerr<<"err: load fail";}if (!ds4.loadFromSamples(ds4raw, SAMPLES, 1, SAMPLE_RATE)){std::cerr<<"err: load fail";}if (!ds5.loadFromSamples(ds4raw, SAMPLES, 1, SAMPLE_RATE*2)){std::cerr<<"err: load fail";}if (!ds6.loadFromSamples(ds4raw, SAMPLES, 1, SAMPLE_RATE*4)){std::cerr<<"err: load fail";}if (!ds7.loadFromSamples(ds4raw, SAMPLES, 1, SAMPLE_RATE*8)){std::cerr<<"err: load fail";} if (!e3.loadFromSamples(e4raw, SAMPLES, 1, SAMPLE_RATE/2)){std::cerr<<"err: load fail";}if (!e4.loadFromSamples(e4raw, SAMPLES, 1, SAMPLE_RATE)){std::cerr<<"err: load fail";}if (!e5.loadFromSamples(e4raw, SAMPLES, 1, SAMPLE_RATE*2)){std::cerr<<"err: load fail";}if (!e6.loadFromSamples(e4raw, SAMPLES, 1, SAMPLE_RATE*4)){std::cerr<<"err: load fail";}if (!e7.loadFromSamples(e4raw, SAMPLES, 1, SAMPLE_RATE*8)){std::cerr<<"err: load fail";}if (!f3.loadFromSamples(f4raw, SAMPLES, 1, SAMPLE_RATE/2)){std::cerr<<"err: load fail";}if (!f4.loadFromSamples(f4raw, SAMPLES, 1, SAMPLE_RATE)){std::cerr<<"err: load fail";}if (!f5.loadFromSamples(f4raw, SAMPLES, 1, SAMPLE_RATE*2)){std::cerr<<"err: load fail";}if (!f6.loadFromSamples(f4raw, SAMPLES, 1, SAMPLE_RATE*4)){std::cerr<<"err: load fail";}if (!f7.loadFromSamples(f4raw, SAMPLES, 1, SAMPLE_RATE*8)){std::cerr<<"err: load fail";}if (!fs3.loadFromSamples(fs4raw, SAMPLES, 1, SAMPLE_RATE/2)){std::cerr<<"err: load fail";}if (!fs4.loadFromSamples(fs4raw, SAMPLES, 1, SAMPLE_RATE)){std::cerr<<"err: load fail";}if (!fs5.loadFromSamples(fs4raw, SAMPLES, 1, SAMPLE_RATE*2)){std::cerr<<"err: load fail";}if (!fs6.loadFromSamples(fs4raw, SAMPLES, 1, SAMPLE_RATE*4)){std::cerr<<"err: load fail";}if (!fs7.loadFromSamples(fs4raw, SAMPLES, 1, SAMPLE_RATE*8)){std::cerr<<"err: load fail";}if (!g3.loadFromSamples(g4raw, SAMPLES, 1, SAMPLE_RATE/2)){std::cerr<<"err: load fail";}if (!g4.loadFromSamples(g4raw, SAMPLES, 1, SAMPLE_RATE)){std::cerr<<"err: load fail";}if (!g5.loadFromSamples(g4raw, SAMPLES, 1, SAMPLE_RATE*2)){std::cerr<<"err: load fail";}if (!g6.loadFromSamples(g4raw, SAMPLES, 1, SAMPLE_RATE*4)){std::cerr<<"err: load fail";}if (!g7.loadFromSamples(g4raw, SAMPLES, 1, SAMPLE_RATE*8)){std::cerr<<"err: load fail";}if (!gs3.loadFromSamples(gs4raw, SAMPLES, 1, SAMPLE_RATE/2)){std::cerr<<"err: load fail";}if (!gs4.loadFromSamples(gs4raw, SAMPLES, 1, SAMPLE_RATE)){std::cerr<<"err: load fail";}if (!gs5.loadFromSamples(gs4raw, SAMPLES, 1, SAMPLE_RATE*2)){std::cerr<<"err: load fail";}if (!gs6.loadFromSamples(gs4raw, SAMPLES, 1, SAMPLE_RATE*4)){std::cerr<<"err: load fail";}if (!gs7.loadFromSamples(gs4raw, SAMPLES, 1, SAMPLE_RATE*8)){std::cerr<<"err: load fail";}if(!pauseBuffer.loadFromSamples(pauseraw, SAMPLES, 1, SAMPLE_RATE)){std::cerr<<"err: load fail";}}sf::Sound A3; sf::Sound A4;sf::Sound A5;sf::Sound A6;sf::Sound A7;sf::Sound AS3; sf::Sound AS4;sf::Sound AS5;sf::Sound AS6;sf::Sound AS7;sf::Sound B3; sf::Sound B4;sf::Sound B5;sf::Sound B6;sf::Sound B7;sf::Sound C3; sf::Sound C4;sf::Sound C5;sf::Sound C6;sf::Sound C7;sf::Sound CS3; sf::Sound CS4;sf::Sound CS5;sf::Sound CS6;sf::Sound CS7;sf::Sound D3; sf::Sound D4;sf::Sound D5;sf::Sound D6;sf::Sound D7;sf::Sound DS3; sf::Sound DS4;sf::Sound DS5;sf::Sound DS6;sf::Sound DS7;sf::Sound E3; sf::Sound E4;sf::Sound E5;sf::Sound E6;sf::Sound E7;sf::Sound F3; sf::Sound F4;sf::Sound F5;sf::Sound F6;sf::Sound F7;sf::Sound FS3; sf::Sound FS4;sf::Sound FS5;sf::Sound FS6;sf::Sound FS7;sf::Sound G3; sf::Sound G4;sf::Sound G5;sf::Sound G6;sf::Sound G7;sf::Sound GS3; sf::Sound GS4;sf::Sound GS5;sf::Sound GS6;sf::Sound GS7;sf::Sound pause;void set3(){A3.setBuffer(a3);A3.setLoop(true);A4.setBuffer(a4);A4.setLoop(true);A5.setBuffer(a5);A5.setLoop(true);A6.setBuffer(a6);A6.setLoop(true);A7.setBuffer(a7);A7.setLoop(true);AS3.setBuffer(as3);AS3.setLoop(true);AS4.setBuffer(as4);AS4.setLoop(true);AS5.setBuffer(as5);AS5.setLoop(true);AS6.setBuffer(as6);AS6.setLoop(true);AS7.setBuffer(as7);AS7.setLoop(true);B3.setBuffer(b3);B3.setLoop(true);B4.setBuffer(b4);B4.setLoop(true);B5.setBuffer(b5);B5.setLoop(true);B6.setBuffer(b6);B6.setLoop(true);B7.setBuffer(b7);B7.setLoop(true);C3.setBuffer(c3);C3.setLoop(true);C4.setBuffer(c4);C4.setLoop(true);C5.setBuffer(c5);C5.setLoop(true);C6.setBuffer(c6);C6.setLoop(true);C7.setBuffer(c7);C7.setLoop(true);D3.setBuffer(d3);D3.setLoop(true);D4.setBuffer(d4);D4.setLoop(true);D5.setBuffer(d5);D5.setLoop(true);D6.setBuffer(d6);D6.setLoop(true);D7.setBuffer(d7);D7.setLoop(true);DS3.setBuffer(ds3);DS3.setLoop(true);DS4.setBuffer(ds4);DS4.setLoop(true);DS5.setBuffer(ds5);DS5.setLoop(true);DS6.setBuffer(ds6);DS6.setLoop(true);DS7.setBuffer(ds7);DS7.setLoop(true);E3.setBuffer(e3);E3.setLoop(true);E4.setBuffer(e4);E4.setLoop(true);E5.setBuffer(e5);E5.setLoop(true);E6.setBuffer(e6);E6.setLoop(true);E7.setBuffer(e7);E7.setLoop(true);F3.setBuffer(f3);F3.setLoop(true);F4.setBuffer(f4);F4.setLoop(true);F5.setBuffer(f5);F5.setLoop(true);F6.setBuffer(f6);F6.setLoop(true);F7.setBuffer(f7);F7.setLoop(true);FS3.setBuffer(fs3);FS3.setLoop(true);FS4.setBuffer(fs4);FS4.setLoop(true);FS5.setBuffer(fs5);FS5.setLoop(true);FS6.setBuffer(fs6);FS6.setLoop(true);FS7.setBuffer(fs7);FS7.setLoop(true);G3.setBuffer(g3);G3.setLoop(true);G4.setBuffer(g4);G4.setLoop(true);G5.setBuffer(g5);G5.setLoop(true);G6.setBuffer(g6);G6.setLoop(true);G7.setBuffer(g7);G7.setLoop(true);GS3.setBuffer(gs3);GS3.setLoop(true);GS4.setBuffer(gs4);GS4.setLoop(true);GS5.setBuffer(gs5);GS5.setLoop(true);GS6.setBuffer(gs6);GS6.setLoop(true);GS7.setBuffer(gs7);GS7.setLoop(true);pause.setBuffer(pauseBuffer);pause.setLoop(true);}sf::Sound* naturalNotePtrs[7][5] = {{&A3,&A4,&A5,&A6,&A7}, {&B3,&B4,&B5,&B6,&B7}, {&C3,&C4,&C5,&C6,&C7}, {&D3,&D4,&D5,&D6,&D7}, {&E3,&E4,&E5,&E6,&E7}, {&F3,&F4,&F5,&F6,&F7}, {&G3,&G4,&G5,&G6,&G7}};sf::Sound* sharpNotePtrs[5][5]={ {&AS3,&AS4,&AS5,&AS6,&AS7}, {&CS3,&CS4,&CS5,&CS6,&CS7}, {&DS3,&DS4,&DS5,&DS6,&DS7},{&FS3,&FS4,&FS5,&FS6,&FS7},{&GS3,&GS4,&GS5,&GS6,&GS7}};sf::Sound getNote(char value, int octave, bool sharp){if (value =='p' || value=='P'){return A4;}if(sharp){switch(value){case 'a':return (*sharpNotePtrs[0][octave-3]);break;case 'c':return (*sharpNotePtrs[1][octave-3]);break;case 'd':return *sharpNotePtrs[2][octave-3];break;case 'f':return *sharpNotePtrs[3][octave-3];break;case 'g':return *sharpNotePtrs[4][octave-3];break;default:std::cerr<<"Invalid sharp\n";}}else {return *naturalNotePtrs[value-97][octave-3];}}void playNote(float duration,int bpm, char value, int octave, bool sharp) {sf::Clock clock;sf::Time time;sf::Sound sound;sound = getNote(value, octave,sharp);double beats=4/duration;double bps = bpm/60.;double trueTimeSecs = beats/bps;int sleepTime =trueTimeSecs*1000+1;while(1) {if(value!='p' && value!= 'P') {sound.play();}sf::sleep(sf::milliseconds(sleepTime));time = clock.getElapsedTime();if(time.asSeconds()>trueTimeSecs){sound.stop();clock.restart();break;}}}}char upperToLower(char input) {if(input>='A'&&input<='Z') {return input+32;}else {return input;}}int main(){using namespace std;using namespace N;using namespace sf;set1();set2();set3();bool delFile=false;ifstream test("x.rtttl"); if(test.good()) {cout<<"no input necessary, 'x.rtttl' already exists and will be read, as is.\n";}else {ofstream outf("x.rtttl");string in;cout<<"Please enter your rtttl file manually, in one line:\n";getline(cin,in);outf<<in<<endl;outf.close();delFile=true;}ifstream song("x.rtttl");song.seekg(0,ios::beg);float duration=0.;int octave=4;int bpm=0;float noteDuration =0.;int noteOctave =0;char noteValue='a';bool sharp = false;bool readIntro = false;bool readData = false;char c;std::cout<< "Now Playing: ";while(song){song>>c;if(c==':'&& !readIntro){readIntro=true;}else if (c==':') { readIntro=false; readData=true;}if(!readIntro && !readData){std::cout<<c;}c=upperToLower(c);if(readIntro) {if(c=='d') {song>>c;c=upperToLower(c);song>>c;c=upperToLower(c);duration = c-48;}if(c=='o'){song>>c;c=upperToLower(c);song>>c;c=upperToLower(c);octave = c-48;}if(c=='b') {song>>c;c=upperToLower(c);song>>c;c=upperToLower(c);int steps=0;while(c!=':'&&steps<5) {song>>c;steps++;}song.seekg(-steps-1, ios::cur);song>>c;c=upperToLower(c);if(steps==3) {bpm+=100*(c-48);song>>c;bpm+=10*(c-48);song>>c;bpm+=c-48;}if(steps==2){bpm+=10*(c-48);song>>c;bpm+=(c-48);}}}else if (readData){if(c<='9' && c>='0') {switch(c){case '1': song>>c;if(c=='6'){ noteDuration=16.;}else {noteDuration = 1.;}break;case '2': noteDuration = 2.;break;case '4':noteDuration = 4.;break;case'8':noteDuration =8.; break;case '3':noteDuration = 32.; song>>c; break;default:cerr<<"\nBad Duration:"<<c;return 1;}song>>c;c=upperToLower(c);noteValue = c;song>>c;c=upperToLower(c);if(c=='#'){sharp = true;song>>c;c=upperToLower(c);}else {sharp =false;}if(c<='9' && c>= '0' ) { noteOctave = c-48;song>>c;c=upperToLower(c); }else {noteOctave = octave;}if(c=='.'){noteDuration*=1.5; song>>c;c=upperToLower(c);}playNote(noteDuration,bpm, noteValue, noteOctave,sharp);}else if(c<='z' && c>='a') {noteDuration = duration;noteValue = c;song>>c;c=upperToLower(c);if(c=='#') { sharp = true;song>>c;c=upperToLower(c);}else {sharp =false;}if(c<='9' && c>= '0' ) { noteOctave = c-48;song>>c;c=upperToLower(c); }else {noteOctave = octave;}if(c=='.') { noteDuration*=1.5; song>>c;c=upperToLower(c);}playNote(noteDuration,bpm, noteValue, noteOctave,sharp);}}}if(delFile) {song.close();remove("x.rtttl");}return 0;}
Infelizmente, não posso incluir o código com e sem golfe (restrições de espaço), e o código pode ser alterado ainda mais.
Grande parte do motivo pelo qual o arquivo é tão longo é que ele precisa criar todos os passos (12 notas * 5 oitavas) individualmente usando ondas senoidais.
Compilando Compilei usando o prompt dev cmd do visual studio, mas é muito semelhante ao g ++ no Linux.
cl music.cpp /I SFML\SFML-2.3.1\include /link SFML\SFML-2.3.1\lib\sfml-system.lib SFML\SFML-2.3.1\lib\sfml-audio.lib
Você só precisa vincular as coisas corretamente.
crédito para SFML e este post para a idéia.
Acho que os horários estão corretos, deixe-me saber se não estão.
Ouça
Aqui (Link to DropBox) está uma gravação de tela dele, reproduzindo uma versão rápida do Tema Morrowind que eu criei. Observe que no vídeo ele não solicita entrada porque o arquivo já existe.
MorrowindTheme: d=4,o=4,b=100: 8a, 8b, 2c, 8c, 8d, 2e, 8e, 8g, 2d, 16e, 16d, 8c, 8b, a, p, 8a, 8b, 2c, 8c, 8d, 2e, 8e, 8g, 2a5, g, 8b5, a5, 8a5, 8b5, c5, b5, a5, g, f, e, 2d, c, 8e, 2d, 8c, 8b, 1a