19 #include <ucommon/ucommon.h>
20 #include <ucommon/export.h>
29 using namespace UCOMMON_NAMESPACE;
32 #define M_PI 3.14159265358979323846
35 #define MAP_HASH_SIZE 197
36 #define MAP_PAGE_COUNT 255
37 #define MAP_PAGE_SIZE (sizeof(void *[MAP_PAGE_COUNT]))
38 #define MAP_PAGE_FIX (MAP_PAGE_SIZE / MAP_PAGE_COUNT)
40 static unsigned char *page = NULL;
44 static unsigned key(
const char *
id)
48 val = (val << 1) ^ (*(
id++) & 0x1f);
53 static void *map(
unsigned len)
71 Tonegen::Tonegen(timeout_t duration, rate_t r)
75 samples = (duration *(long)rate) / 1000;
76 frame =
new sample_t[samples];
84 Tonegen::Tonegen(key_t *k, level_t l, timeout_t duration)
88 samples = (duration *(long)rate) / 1000;
89 frame =
new sample_t[samples];
105 remaining = silent = count = 0;
109 Tonegen::Tonegen(
unsigned freq, level_t l, timeout_t duration, rate_t r)
112 df1 = (freq *
M_PI * 2) / (
long)rate;
113 df2 = (freq *
M_PI * 2) / (
long)rate;
115 samples = (duration * (long)rate) / 1000;
122 frame =
new sample_t[samples];
125 Tonegen::Tonegen(
unsigned f1,
unsigned f2, level_t l1, level_t l2, timeout_t duration, rate_t r)
128 df1 = (f1 *
M_PI * 2) / (
long)r;
129 df2 = (f2 *
M_PI * 2) / (
long)r;
131 samples = (duration * (long)r) / 1000;
138 frame =
new sample_t[samples];
141 unsigned Tonegen::getFrames(linear_t buffer,
unsigned pages)
144 linear_t save = frame;
146 while(count < pages) {
154 if(count && count < pages)
155 memset(buffer, 0, samples * (pages - count) * 2);
161 void Tonegen::silence(
void)
166 void Tonegen::reset(
void)
172 void Tonegen::single(
unsigned freq, level_t l)
174 df1 = (freq *
M_PI * 2) / (
long)rate;
175 df2 = (freq *
M_PI * 2) / (
long)rate;
183 void Tonegen::dual(
unsigned f1,
unsigned f2, level_t l1, level_t l2)
185 df1 = (f1 *
M_PI * 2) / (
long)rate;
186 df2 = (f2 *
M_PI * 2) / (
long)rate;
194 Audio::linear_t Tonegen::getFrame(
void)
196 unsigned count = samples;
197 linear_t data = frame;
203 if(count >= def->count && !remaining && !silent) {
212 if(!remaining && !silent) {
213 if(count && !def->duration)
217 dual(def->f1, def->f2, level, level);
219 single(def->f1, level);
221 remaining = def->duration / framing;
223 silent = (def->duration + def->silence) / framing - remaining;
228 if(!remaining && m1 && silent)
239 if(is_silent() && !p1 && !p2) {
241 memset(frame, 0, samples * 2);
248 if(p1 <= 0 && df1 >= p1) {
253 if(p1 >= 0 && -df1 >= p1) {
258 if(p2 <= 0 && df2 >= p1) {
263 if(p2 >= 0 && -df2 >= p1) {
274 *(data++) = (level_t)(sin(p1) * (double)m1) +
275 (level_t)(sin(p2) * (double)m2);
283 *(data++) = (level_t)(sin(p1) * (double)m1) +
284 (level_t)(sin(p2) * (double)m2);
299 void Tonegen::cleanup(
void)
307 bool Tonegen::is_silent(
void)
315 bool Tonegen::load(
const char *l)
319 char *loclist[128], *cp, *ep, *name;
321 char **field, *freq, *fdur, *fcount;
322 def_t *def, *first, *again, *last, *
final = NULL;
324 unsigned count, i, k;
330 fp = fopen(config(
"tones.conf"),
"r");
334 memset(&hash, 0,
sizeof(hash));
338 if(!fgets(buffer,
sizeof(buffer) - 1, fp) || feof(fp))
347 strcpy(locale, buffer);
350 cp = strtok(cp,
"[]|\r\n");
353 loclist[lcount++] = cp;
354 else if(*cp && !stricmp(cp, l))
356 loclist[lcount++] = cp;
359 cp = strtok(NULL,
"[]|\r\n");
364 if(!isalpha(*cp) || !lcount)
367 ep = strchr(cp,
'=');
371 name = strtok(cp,
" \t");
372 cp = strchr(ep,
';');
375 cp = strchr(ep,
'#');
378 cp = strtok(ep,
",");
385 cp = strtok(NULL,
",");
391 first = last = again = NULL;
393 freq = strtok(*field,
" \t\r\n");
394 fdur = strtok(NULL,
" \t\r\n");
395 fcount = strtok(NULL,
" \t\r\n");
400 freq = strtok(freq,
" \r\r\n");
403 tk = find(freq, loclist[0]);
415 def = (def_t *)map(
sizeof(def_t));
416 memset(def, 0,
sizeof(def_t));
426 if(!fdur || !atol(fdur)) {
430 else if((!fcount || !atoi(fcount)) && !count)
433 cp = strtok(freq,
" \t\r\n");
439 def->f2 = atoi(++ep);
444 fcount = (
char *)
"1";
446 def->count = atoi(fcount);
453 cp = strtok(fdur,
" \t\r\n");
457 def->duration = atol(cp);
459 def->silence = atol(++ep);
471 snprintf(namebuf,
sizeof(namebuf),
"%s.%s",
473 tk = (key_t *)map((
unsigned)
sizeof(key_t) + strlen(namebuf));
474 strcpy(tk->id, namebuf);
490 Tonegen::key_t *Tonegen::find(
const char *
id,
const char *locale)
499 snprintf(namebuf,
sizeof(namebuf),
"%s.%s", locale,
id);
504 if(!stricmp(namebuf, tk->id))
#define BAYONNE_NAMESPACE
GNU Bayonne library namespace.