ãããããç¾ä»£éæ³1話ã®å§åç¾éã®ä½¿ã£ãããã°ã©ã ã½ã¼ã¹
ä¸é¨åæè£å®ãã¦ä½ã£ã¦ã¿ãã
ãã®ã½ã¼ã¹ã®åºå ¸ã ãã©ãu8ã¨ãs16ã¨ãã®ååãããLinuxã«ã¼ãã«ãã¨æã£ããã©ã«ã¼ãã«ã«C++使ããªãã®ã§é¢ä¿ãªãã¦ãä»ã«ããããååãæ¢å®ã§å®ç¾©ããã¦ããã®ã¯GBA/NDSããã°ã©ãã³ã°ã£ã½ãã®ã§ããã£ã¡ã¾ããã®ãµã³ãã«ã½ã¼ã¹ã¨ã調ã¹ã¦ã¿ããã ãã©è¦ã¤ãããªãã£ãã
ãã¨Kodersã¨ãDebian Source Searchã§ã調ã¹ããã©å¼ã£ããããªãã£ãã®ã§ãèªä½ã§ããå¯è½æ§ãé«ãããã
é³å£°é¢é£ã®ã½ã¼ã¹ã§ããã¨ãããã¨ããèæ ®ãã¦ããGBA/NDSããã°ã©ãã³ã°ã§èªä½ããã¨ããå¯è½æ§ãé«ãã®ã§ã¯ãªããã¨æãã
ãªããã¢ãã¡ä¸ã§forã«ã¼ãå ã®ã¤ã³ãã³ããå´©ãã¦ãã件ã«ã¤ãã¦ã¯ãã¿ãã¹ããã8ãã¤ã³ãã³ã2ã§ä¿åããããã®ãã¿ãã¹ããã2ã§èªã¿ã ããããã4ã¤ã³ãã³ãããã¦ãforã®ä¸èº«ãä¸ãã£ã¦ãã¾ã£ãã¨èããã®ãé©åã ã¨æãããããããã¨ãããããã¿ãã¯ã¡ããã¨ã¹ãã¼ã¹ã«å±éããªãããããªããã§ããã
template <int NUMSAMPLES, class DECODER> class Voice { protected: DECODER* dec; public: typedef DECODER Decoder; enum { SAMPLES = NUMSAMPLES, }; Voice() : dec(&DECODER::null) {} DECODER* decoder() const {return dec;} DECODER* decoder(Decoder* newdec) {return dec=newdec;} void ready() {} class Monoral : public Voice { s16 ce[SAMPLES]; public: void ready() { for (int i = dec->decodeTo(ce, SAMPLES); i < SAMPLES; i++) { ce[i] = 0; } } s16 center(u16 i) const { return ce[i]; } s16 left(u16 i) const { return ce[i]; } u16 right(u16 i) const { return ce[i]; } }; class Stereo : public Voice { s16 le[SAMPLES]; s16 ri[SAMPLES]; public: void ready() { for (int i = dec->decodeTo(le, ri, SAMPLES); i < SAMPLES; i++) { le[i] = ri[i] = 0; } } s16 center(u16 i) const { return ((s32)le[i] + (s32)ri[i])/2; } s16 left(u16 i) const { return le[i]; } s16 right(u16 i) const { return ri[i]; } }; }; template <int NUMVOICES, class VOICE> class Mixer { protected: VOICE vocs[NUMVOICES]: static inline u8 s16_u8(int v) { return u8(v/256+128); } public: typedef VOICE Voice; typedef typename Voice::Decoder Decoder; enum{ VOICES = NUMVOICES, SAMPLES = Voice::SAMPLES, }; Decoder* decoder(u16 i) const { return i<VOICES ? vocs[i].decoder() : &Decoder::null; } Decoder* decoder(u16 i, Decoder* dec) { return i<VOICES ? vocs[i].decoder(dec) : &Decoder::null; } void mix() {} class Monoral : public Mixer { u8 ce[SAMPLES]; public: void mix() { for (int i = 0; i < VOICES; i++) { vocs[i].ready(); } for (int i = 0; i < SAMPLES; i++) { int v = 0; if (VOICES >= 1) { v += vocs[0].center(i); } if (VOICES >= 2) { v += vocs[1].center(i); } if (VOICES >= 3) { v += vocs[2].center(i); } if (VOICES >= 4) { v += vocs[3].center(i); } if (VOICES >= 5) { v += vocs[4].center(i); } if (VOICES >= 6) { v += vocs[5].center(i); } if (VOICES >= 7) { v += vocs[6].center(i); } if (VOICES >= 8) { v += vocs[7].center(i); } ce[i] = s16_u8(v/VOICES); } } const u8* center() const { return ce; } const u8* left() const { return ce; } const u8* right() const { return ce; } }; class Stereo : public Mixer { u8 le[SAMPLES]; u8 ri[SAMPLES]; public: void mix() { for (int i = 0; i < VOICES; i++) { vocs[i].ready(); } for (int i = 0; i < SAMPLES; i++) { s16 v = 0; if (VOICES >= 1) { v += vocs[0].left(i); } if (VOICES >= 2) { v += vocs[1].left(i); } if (VOICES >= 3) { v += vocs[2].left(i); } if (VOICES >= 4) { v += vocs[3].left(i); } if (VOICES >= 5) { v += vocs[4].left(i); } if (VOICES >= 6) { v += vocs[5].left(i); } if (VOICES >= 7) { v += vocs[6].left(i); } if (VOICES >= 8) { v += vocs[7].left(i); } le[i] = s16_u8(v/VOICES); v = 0; if (VOICES >= 1) { v += vocs[0].right(i); } if (VOICES >= 2) { v += vocs[1].right(i); } if (VOICES >= 3) { v += vocs[2].right(i); } if (VOICES >= 4) { v += vocs[3].right(i); } if (VOICES >= 5) { v += vocs[4].right(i); } if (VOICES >= 6) { v += vocs[5].right(i); } if (VOICES >= 7) { v += vocs[6].right(i); } if (VOICES >= 8) { v += vocs[7].right(i); } ri[i] = s16_u8(v/VOICES); } } s16 center(u16 i) const { return ((s32)le[i] + (s32)ri[i])/2; } const u8* left() const { return le; } const u8* right() const { return ri; } } };