flbuf.cpp 2.9 KB
Newer Older
thomas's avatar
thomas committed
1
2
/* 

thomas's avatar
thomas committed
3
flext - C++ layer for Max/MSP and pd (pure data) externals
thomas's avatar
thomas committed
4
5
6
7
8
9
10

Copyright (c) 2001,2002 Thomas Grill (xovo@gmx.net)
For information on usage and redistribution, and for a DISCLAIMER OF ALL
WARRANTIES, see the file, "license.txt," in this distribution.  

*/

thomas's avatar
thomas committed
11
#include <flext.h>
thomas's avatar
thomas committed
12
13

#ifdef PD
thomas's avatar
thomas committed
14
#define DIRTY_INTERVAL 0   // buffer dirty check in msec
thomas's avatar
thomas committed
15
16
#endif

thomas's avatar
thomas committed
17
flext_base::buffer::buffer(t_symbol *bn,BL delayed):
thomas's avatar
thomas committed
18
19
20
21
22
23
24
25
26
27
	sym(NULL),data(NULL),
	chns(0),frames(0)
{
#ifdef PD
	interval = DIRTY_INTERVAL;
	isdirty = false;
	ticking = false;
    tick = clock_new(this,(t_method)cb_tick);
#endif

thomas's avatar
thomas committed
28
	if(bn) Set(bn,delayed);
thomas's avatar
thomas committed
29
30
}

thomas's avatar
thomas committed
31
flext_base::buffer::~buffer()
thomas's avatar
thomas committed
32
33
34
35
36
37
{
#ifdef PD
    clock_free(tick);
#endif
}

thomas's avatar
thomas committed
38
I flext_base::buffer::Set(t_symbol *s,BL nameonly)
thomas's avatar
thomas committed
39
{
thomas's avatar
thomas committed
40
41
	I ret = 0;

thomas's avatar
thomas committed
42
	if(s && sym != s) {
thomas's avatar
thomas committed
43
44
45
46
47
48
		ret = -1;
		data = NULL; 
		frames = 0;
		chns = 0; 
	}

thomas's avatar
thomas committed
49
50
	if(s && *s->s_name)	sym = s;

thomas's avatar
thomas committed
51
	if(sym && !nameonly) {
thomas's avatar
thomas committed
52
#ifdef PD
thomas's avatar
thomas committed
53
54
		I frames1;
		F *data1;
thomas's avatar
thomas committed
55
    
thomas's avatar
thomas committed
56
57
		t_garray *a = (t_garray *)pd_findbyclass(sym, garray_class);
		if(!a)
thomas's avatar
thomas committed
58
59
		{
    		if (*sym->s_name)
thomas's avatar
thomas committed
60
    			error("buffer: no such array '%s'",sym->s_name);
thomas's avatar
thomas committed
61
62
    		sym = NULL;
			ret = -1;
thomas's avatar
thomas committed
63
		}
thomas's avatar
thomas committed
64
		else if (!garray_getfloatarray(a, &frames1, &data1))
thomas's avatar
thomas committed
65
		{
thomas's avatar
thomas committed
66
    		error("buffer: bad template '%s'", sym->s_name);
thomas's avatar
thomas committed
67
68
    		data = NULL;
			frames = 0;
thomas's avatar
thomas committed
69
			ret = -1;
thomas's avatar
thomas committed
70
71
72
		}
		else {
			garray_usedindsp(a);
thomas's avatar
thomas committed
73
74
			if(frames != frames1) { frames = frames1; ret = 1; }
			if(data != data1) { data = data1; ret = 1; }
thomas's avatar
thomas committed
75
76
77
78
79
80
81
			chns = 1;
		}
#elif defined(MAXMSP)
		if(sym->s_thing) {
			const _buffer *p = (const _buffer *)sym->s_thing;
			
			if(NOGOOD(p)) {
thomas's avatar
thomas committed
82
				post("buffer: buffer object '%s' no good",sym->s_name);
thomas's avatar
thomas committed
83
				ret = -1;
thomas's avatar
thomas committed
84
85
86
			}
			else {
#ifdef DEBUG
thomas's avatar
thomas committed
87
				post("%s: buffer object '%s' - valid:%i samples:%i channels:%i frames:%i",thisName(),bufname->s_name,p->b_valid,p->b_frames,p->b_nchans,p->b_frames);
thomas's avatar
thomas committed
88
#endif
thomas's avatar
thomas committed
89
90
				if(data != p->b_samples) { data = p->b_samples; ret = 1; }
				if(chns != p->b_nchans) { chns = p->b_nchans; ret = 1; }
thomas's avatar
thomas committed
91
				if(frames != p->b_frames) { frames = p->b_frames; ret = 1; }
thomas's avatar
thomas committed
92
93
94
			}
		}
		else {
thomas's avatar
thomas committed
95
    		error("buffer: symbol '%s' not defined", sym->s_name);
thomas's avatar
thomas committed
96
			ret = -1;
thomas's avatar
thomas committed
97
98
99
		}
#endif
	}
thomas's avatar
thomas committed
100
	else ret = -1;
thomas's avatar
thomas committed
101

thomas's avatar
thomas committed
102
	return ret;
thomas's avatar
thomas committed
103
104
}

thomas's avatar
thomas committed
105
V flext_base::buffer::Dirty(BL force)
thomas's avatar
thomas committed
106
107
108
{
	if(sym) {
#ifdef PD
thomas's avatar
thomas committed
109
		if((!ticking) && (interval || force)) {
thomas's avatar
thomas committed
110
111
112
113
114
115
116
117
118
119
			ticking = true;
			clock_delay(tick,0);
		}
		else
			isdirty = true;
#elif defined(MAXMSP)
		if(sym->s_thing) {
			_buffer *p = (_buffer *)sym->s_thing;
			
			if(NOGOOD(p)) {
thomas's avatar
thomas committed
120
				post("buffer: buffer object '%s' no good",sym->s_name);
thomas's avatar
thomas committed
121
122
123
124
125
126
			}
			else {
				p->b_modtime = gettime();
			}
		}
		else {
thomas's avatar
thomas committed
127
    		error("buffer: symbol '%s' not defined",sym->s_name);
thomas's avatar
thomas committed
128
129
130
131
132
133
		}
#endif 
	}
}

#ifdef PD
thomas's avatar
thomas committed
134
V flext_base::buffer::cb_tick(buffer *b)
thomas's avatar
thomas committed
135
136
137
138
{
	t_garray *a = (t_garray *)pd_findbyclass(b->sym, garray_class);
	if (a) garray_redraw(a);
//		else bug("tabwrite_tilde_tick");
thomas's avatar
thomas committed
139
140
141
142
	if(b->isdirty && b->interval) {
			b->isdirty = false;
			b->ticking = true;
			clock_delay(b->tick,b->interval);
thomas's avatar
thomas committed
143
144
145
146
147
148
	}
	else 
		b->ticking = false;
}
#endif