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