1 //enum mclass { mc_f, mc_i, mc_t };
2
3 #define mclass FIT_IDX
4
5 /*
6 * More comments should eventually come here. These markers are attached
7 * to units, in an unlimited number. At present, they carry prosodic
8 * information (only intensity and pitch, not duration) relating either
9 * to the unit, or to a specified point within it.
10 *
11 * This was added between 2.4 and 2.5.
12 */
13
14 class marker
15 {
16 friend class unit;
17
18 mclass quant;
19 bool extent;
20 int par;
21 float pos;
22 marker *next;
23
24 public:
25 marker();
26 ~marker();
marker(mclass mc,bool e,int p,marker * m,float po)27 marker(mclass mc, bool e, int p, marker *m, float po) { quant = mc; extent = e; par = p; next = m; pos = po; };
28 marker *derived();
29 void merge(marker *&into);
30 inline bool listed(marker *ma);
31 bool disjoint(marker *ma);
32
33 bool operator < (marker &ma);
34
35 int write_ssif(char *whither);
36
37 void *operator new(size_t size);
38 void operator delete(void *ptr);
39 };
40
marker()41 marker::marker()
42 {
43 next = NULL;
44 }
45
~marker()46 marker::~marker()
47 {
48 if (next) delete next;
49 next = NULL;
50 }
51
derived()52 marker *marker::derived()
53 {
54 if (!this) return NULL;
55 marker *nm = new marker;
56 nm->next = next->derived();
57 nm->quant = quant;
58 nm->extent = extent;
59 nm->par = par;
60 nm->pos = pos;
61 return nm;
62 }
63
64 void
merge(marker * & into)65 marker::merge(marker *&into)
66 {
67 if (!disjoint(into)) shriek(861, "Cannot merge non-disjoints");
68 if (!this)
69 return;
70 if (!into) {
71 into = this;
72 return;
73 }
74 if (*into < *this) {
75 if (!into->next) into->next = this;
76 else merge(into->next);
77 } else {
78 if (quant == into->quant && pos == into->pos && extent && into->extent) {
79 into->par += par; // merge compatible extent markers
80 marker *nm = next;
81 next = NULL;
82 delete this;
83 nm->merge(into);
84 } else {
85 marker *other = into;
86 into = this;
87 other->merge(next);
88 }
89 }
90 }
91
92 inline bool
listed(marker * ma)93 marker::listed(marker *ma)
94 {
95 if (!ma) return false;
96 return this == ma || listed(ma->next);
97 }
98
99 bool
disjoint(marker * ma)100 marker::disjoint(marker *ma)
101 {
102 if (!this || !ma) return true;
103 if (this == ma) return false;
104 return !listed(ma->next) && next->disjoint(ma);
105 }
106
107 bool
operator <(marker & ma)108 marker::operator < (marker &ma)
109 {
110 if (extent == ma.extent) return pos < ma.pos;
111 else return !extent;
112 }
113
114
115 int
write_ssif(char * whither)116 marker::write_ssif(char *whither)
117 {
118 if (quant == Q_FREQ) return sprintf(whither, "(%d,%d) ", (int)(pos * 100),
119 this_voice->init_f + par /*, extent?"yes":"no" */ );
120 else return 0;
121 }
122