flbuf.cpp 2.85 KB
Newer Older
thomas's avatar
thomas committed
1
2
3
4
5
6
7
8
9
10
11
12
13
/* 

max-pd - C++ compatibility layer for Max/MSP and pd (pure data) externals

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.  

*/

#include <_cppext.h>

#ifdef PD
thomas's avatar
thomas committed
14
#define DIRTY_INTERVAL 0   // buffer dirty check in msec
thomas's avatar
thomas committed
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#endif

buffer::buffer(t_symbol *bn):
	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

	if(bn) Set(bn);
}

buffer::~buffer()
{
#ifdef PD
    clock_free(tick);
#endif
}

thomas's avatar
thomas committed
38
I buffer::Set(t_symbol *s)
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
51
52
	if(s && *s->s_name)	sym = s;

	if(sym) {
#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
60
		{
    		if (*sym->s_name)
    			error("%s: no such array '%s'",thisName(), 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
66
67
68
		{
    		error("%s: bad template '%s'", thisName(),sym->s_name);
    		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
82
			chns = 1;
		}
#elif defined(MAXMSP)
		if(sym->s_thing) {
			const _buffer *p = (const _buffer *)sym->s_thing;
			
			if(NOGOOD(p)) {
				post("%s: buffer object '%s' no good",thisName(),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 buflen:%i",thisName(),bufname->s_name,p->b_valid,p->b_frames,p->b_nchans,p->b_size);
thomas's avatar
thomas committed
88
#endif
thomas's avatar
thomas committed
89
90
91
				if(data != p->b_samples) { data = p->b_samples; ret = 1; }
				if(chns != p->b_nchans) { chns = p->b_nchans; ret = 1; }
				if(frames != p->b_size) { frames = p->b_size; ret = 1; }
thomas's avatar
thomas committed
92
93
94
95
			}
		}
		else {
    		error("%s: symbol '%s' not defined",thisName(), 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 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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
			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)) {
				post("%s: buffer object '%s' no good",thisName(),sym->s_name);
			}
			else {
				p->b_modtime = gettime();
			}
		}
		else {
    		error("%s: symbol '%s' not defined",thisName(),sym->s_name);
		}
#endif 
	}
}

#ifdef PD
V buffer::cb_tick(buffer *b)
{
	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