RISC-V/V203/gsm/player.cpp

155 lines
3.8 KiB
C++
Raw Normal View History

2024-05-08 12:54:33 +02:00
#include <stdlib.h>
#include "player.h"
/******************************************************************/
static constexpr int dmult (const int n) {
int r = 1;
for (int i=0; i<n; i++) r *= 10;
return r;
}
static constexpr int strip_zeros (const int n) {
if ((n % 10) != 0) return n;
return strip_zeros(n / 10);
}
void TextPlayer::say(const int number) {
if (!number) out(m_t.nula);
else sre (number);
}
void TextPlayer::say(const int number, const int dnum) {
if (dnum <= 0 or dnum > 3) { out(m_t.hafo); return; } // meze 1..3
if (number < 0) {
out (m_t.minus); say (-number, dnum); return;
}
const div_t dt = ::div (number, dmult(dnum));
if (dt.quot) sre(dt.quot);
else out(m_t.nula);
out(m_t.point);
mil(dt.rem, dnum);
}
void TextPlayer::mil(const int number, const int dnum) {
if (number == 0) { out(m_t.nula); return; }
const int max = dmult(dnum - 1);
if (number < max) {
out(m_t.nula);
mil(number * 10, dnum);
return;
}
sre (strip_zeros(number));
}
void TextPlayer::sre(const int number) {
if (number < 0) {
out (m_t.minus);
sre (-number);
return;
}
if (number >= 1000000) {
out(m_t.hafo);
return;
}
if (number == 1000) {
out(m_t.tisic);
return;
}
if (number > 1000) {
const div_t dt = ::div (number, 1000);
sre (dt.quot);
const int ln = dt.quot % 10;
(ln < 2 or ln > 4) ? out(m_t.tisic) : out(m_t.tisice);
sre (dt.rem);
return;
}
if (number == 100) {
out(m_t.sto);
return;
}
if (number > 100) {
const div_t dt = ::div (number, 100);
const int ln = dt.quot % 10;
//printf ("stovky:%d ", ln);
hec (ln);
sre (dt.rem);
return;
}
if (number == 20) {
out(m_t.dvacet);
return;
}
if (number > 20) {
const div_t dt = ::div (number, 10);
const int ln = dt.quot % 10;
//printf ("desitky:%d ", ln);
dek (ln);
sre (dt.rem);
return;
}
if (number == 0) return;
// jednotky 1 .. 19
// printf("jednotky:%d ", number);
one (number);
}
void TextPlayer::hec(const int number) {
switch (number) {
case 1: out (m_t.sto); break;
case 2: out (m_t.dveste); break;
case 3:
case 4: one(number); out (m_t.sta); break;
case 5:
case 6:
case 7:
case 8:
case 9: one(number); out (m_t.set); break;
default: break;
};
}
void TextPlayer::dek(const int number) {
switch (number) {
case 2: out (m_t.dvacet); break;
case 3: out (m_t.tricet); break;
case 4: out (m_t.ctyricet); break;
case 5: out (m_t.padesat); break;
case 6: out (m_t.sedesat); break;
case 7: out (m_t.sedmdesat); break;
case 8: out (m_t.osmdesat); break;
case 9: out (m_t.devadesat); break;
default: break;
};
}
void TextPlayer::one(const int number) {
// 1..19
switch (number) {
case 1: out (m_t.jedna); break;
case 2: out (m_t.dva); break;
case 3: out (m_t.tri); break;
case 4: out (m_t.ctyri); break;
case 5: out (m_t.pet); break;
case 6: out (m_t.sest); break;
case 7: out (m_t.sedm); break;
case 8: out (m_t.osm); break;
case 9: out (m_t.devet); break;
case 10: out (m_t.deset); break;
case 11: out (m_t.jedenact); break;
case 12: out (m_t.dvanact); break;
case 13: out (m_t.trinact); break;
case 14: out (m_t.ctrnact); break;
case 15: out (m_t.patnact); break;
case 16: out (m_t.sestnact); break;
case 17: out (m_t.sedmnact); break;
case 18: out (m_t.osmnact); break;
case 19: out (m_t.devatenact); break;
default: break;
};
}
void TextPlayer::out(const text_p & o) {
led << false; // led svítí, pokud to mluví
const int len = o.no_frames;
for (int n=0; n<len; n++) {
const gsm_byte * f = o.frames[n];
const PText t (f);
while (true) {
if (fifo.Write(t)) break;
}
}
led << true;
}