1 /*
2     TiMidity++ -- MIDI to WAVE converter and player
3     Copyright (C) 1999-2002 Masanao Izumo <mo@goice.co.jp>
4     Copyright (C) 1995 Tuukka Toivonen <tt@cgs.fi>
5 
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10 
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15 
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19 
20    bitset.c
21 
22    Author: Masanao Izumo <mo@goice.co.jp>
23    Create: Sun Mar 02 1997
24 */
25 
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif /* HAVE_CONFIG_H */
29 
30 #include <stdio.h>
31 #include <stdlib.h>
32 #ifndef NO_STRING_H
33 #include <string.h>
34 #else
35 #include <strings.h>
36 #endif
37 #include "timidity.h"
38 #include "common.h"
39 #include "bitset.h"
40 
41 #define CUTUP(n)   (((n) + BIT_CHUNK_SIZE - 1) & ~(BIT_CHUNK_SIZE - 1))
42 #define CUTDOWN(n) ((n) & ~(BIT_CHUNK_SIZE - 1))
43 
44 /* ������ n �ӥåȤ� 1 �� */
45 #define RFILLBITS(n) ((1u << (n)) - 1)
46 
47 /* ������ n �ӥåȤ� 1 �� */
48 #define LFILLBITS(n) (RFILLBITS(n) << (BIT_CHUNK_SIZE - (n)))
49 
50 static void print_uibits(unsigned int x)
51 {
52     unsigned int mask;
53     for(mask = (1u << (BIT_CHUNK_SIZE-1)); mask; mask >>= 1)
54 	if(mask & x)
55 	    putchar('1');
56 	else
57 	    putchar('0');
58 }
59 
60 /* bitset �����ɽ�� */
61 void print_bitset(Bitset *bitset)
62 {
63     int i, n;
64     unsigned int mask;
65 
66     n = CUTDOWN(bitset->nbits)/BIT_CHUNK_SIZE;
67     for(i = 0; i < n; i++)
68     {
69 	print_uibits(bitset->bits[i]);
70 #if 0
71 	putchar(',');
72 #endif
73     }
null_wrdt_open(char * wrdt_opts)74 
75     n = bitset->nbits - CUTDOWN(bitset->nbits);
null_wrdt_apply(int cmd,int argc,int args[])76     mask = (1u << (BIT_CHUNK_SIZE-1));
null_wrdt_update_events(void)77     while(n--)
78     {
79 	if(mask & bitset->bits[i])
80 	    putchar('1');
81 	else
82 	    putchar('0');
83 	mask >>= 1;
84     }
85 }
86 
87 /*
88  * Bitset �ν����
89  * ������塢���ƤΥӥåȤ� 0 �˽���������
90  */
91 void init_bitset(Bitset *bitset, int nbits)
92 {
93     bitset->bits = (unsigned int *)
94 	safe_malloc((CUTUP(nbits) / BIT_CHUNK_SIZE)
95 		    * sizeof(unsigned int));
96     bitset->nbits = nbits;
97     memset(bitset->bits, 0, (CUTUP(nbits) / BIT_CHUNK_SIZE) * sizeof(int));
98 }
99 
100 /*
101  * start ���ܤΥӥåȤ��顢nbit ʬ��0 �˥��åȤ��롣
102  */
103 void clear_bitset(Bitset *bitset, int start, int nbits)
104 {
105     int i, j, sbitoff, ebitoff;
106     unsigned int mask;
107 
108     if(nbits == 0 || start < 0 || start >= bitset->nbits)
109 	return;
110 
111     if(start + nbits > bitset->nbits)
112 	nbits = bitset->nbits - start;
113 
114     i = CUTDOWN(start);
115     sbitoff = start - i;	/* ��¦ n �ӥå��ܤ��饹������ */
116     i /= BIT_CHUNK_SIZE;	/* i ���ܤ��� */
117 
118     j = CUTDOWN(start + nbits - 1);
119     ebitoff = start + nbits - j; /* ��¦ n �ӥå��ܤޤ�  */
120     /* ebitoff := [1 ... BIT_CHUNK_SIZE] */
121 
122     j /= BIT_CHUNK_SIZE;	/* j ���ܤޤ� */
123 
124     /* ��¦ sbitoff �ӥåȤޤǤ� 1, ����ʳ��� 0 */
125     mask = LFILLBITS(sbitoff);
126 
127     if(i == j)			/* 1 �Ĥ� Chunk ���������  */
128     {
129 	/* ��¦ ebitoff �ʹߤ� 1 */
130 	mask |= RFILLBITS(BIT_CHUNK_SIZE - ebitoff);
131 	bitset->bits[i] &= mask;
132 	return;
133     }
134 
135     bitset->bits[i] &= mask;
136     for(i++; i < j; i++)
137 	bitset->bits[i] = 0;
138     mask = RFILLBITS(BIT_CHUNK_SIZE - ebitoff);
139     bitset->bits[i] &= mask;
140 }
wrd_init_path(void)141 
142 /*
143  * start �ӥåȤ��顢nbits ʬ��bits �˥��åȤ���
144  */
145 void set_bitset(Bitset *bitset, const unsigned int *bits,
146 		int start, int nbits)
147 {
148     int i, j, lsbitoff, rsbitoff, ebitoff;
149     unsigned int mask;
150 
151     if(nbits == 0 || start < 0 || start >= bitset->nbits)
152 	return;
153 
154     if(start + nbits > bitset->nbits)
155 	nbits = bitset->nbits - start;
156 
157     i = CUTDOWN(start);
158     lsbitoff = start - i;	/* ��¦ n �ӥå��ܤ��饹������ */
159     rsbitoff = BIT_CHUNK_SIZE - lsbitoff; /* ��¦ n �ӥå��ܤ��饹������ */
160     i /= BIT_CHUNK_SIZE;	/* i ���ܤ��� */
161 
162     j = CUTDOWN(start + nbits - 1);
163     ebitoff = start + nbits - j; /* ��¦ n �ӥå��ܤޤ�  */
164     /* ebitoff := [1 ... BIT_CHUNK_SIZE] */
165 
166     j /= BIT_CHUNK_SIZE;	/* j ���ܤޤ� */
167 
168     /* ��¦ lsbitoff �ӥåȤޤǤ� 1, ����ʳ��� 0 */
169     mask = LFILLBITS(lsbitoff);
170 
171     if(i == j)			/* 1 �Ĥ� Chunk ���������  */
172     {
173 	mask |= RFILLBITS(BIT_CHUNK_SIZE - ebitoff);
174 	bitset->bits[i] = ((~mask & (*bits >> lsbitoff))
175 			   | (mask & bitset->bits[i]));
176 	return;
177     }
178 
179     /* |1 2 3 4|1 2 3[...]
180      *  \       \     \
181      *   \       \     \
182      * |1 2 3 4|1 2 3 4|1 2 3 4|...
183      */
184     bitset->bits[i] = ((~mask & (*bits >> lsbitoff))
185 		       | (mask & bitset->bits[i]));
186     i++;
187     bits++;
188     for(; i < j; i++)
189     {
190 	bitset->bits[i] = ((bits[-1] << rsbitoff) | (bits[0] >> lsbitoff));
191 	bits++;
192     }
193     mask = LFILLBITS(ebitoff);
194     bitset->bits[i] = ((bits[-1] << rsbitoff) |
195 		       ((mask & bits[0]) >> lsbitoff) |
196 		       (~mask & bitset->bits[i]));
197 }
198 
199 /*
200  * start �ӥåȤ��顢nbits ʬ������
201  */
202 void get_bitset(const Bitset *bitset, unsigned int *bits,
203 		int start, int nbits)
204 {
205     int i, j, lsbitoff, rsbitoff, ebitoff;
wrd_add_default_path(char * path)206 
207     memset(bits, 0, CUTUP(nbits) / 8);
208 
209     if(nbits == 0 || start < 0 || start >= bitset->nbits)
210 	return;
try_wrd_open_file(char * prefix,char * fn)211 
212     if(start + nbits > bitset->nbits)
213 	nbits = bitset->nbits - start;
214 
215     i = CUTDOWN(start);
216     lsbitoff = start - i;	/* ��¦ n �ӥå��ܤ��饹������ */
217     rsbitoff = BIT_CHUNK_SIZE - lsbitoff; /* ��¦ n �ӥå��ܤ��饹������ */
218     i /= BIT_CHUNK_SIZE;	/* i ���ܤ��� */
219 
220     j = CUTDOWN(start + nbits - 1);
221     ebitoff = start + nbits - j; /* ��¦ n �ӥå��ܤޤ�  */
222     /* ebitoff := [1 ... BIT_CHUNK_SIZE] */
223 
224     j /= BIT_CHUNK_SIZE;	/* j ���ܤޤ� */
225 
226     if(i == j)			/* 1 �Ĥ� Chunk ���������  */
227     {
228 	unsigned int mask;
229 	mask = LFILLBITS(lsbitoff) | RFILLBITS(BIT_CHUNK_SIZE - ebitoff);
230 	*bits = (~mask & bitset->bits[i]) << lsbitoff;
231 	return;
232     }
233 
234     /* |1 2 3 4|1 2 3 4|1 2 3 4|...
235      *     /       /   .   /
wrd_open_file(char * filename)236      *   /       /   .   /
237      * |1 2 3 4|1 2 3[...]
238      */
239 
240     for(; i < j; i++)
241     {
242 	*bits = ((bitset->bits[i]     << lsbitoff) |
243 		 (bitset->bits[i + 1] >> rsbitoff));
244 	bits++;
245     }
246 
247     if(ebitoff < lsbitoff)
248 	bits[-1] &= LFILLBITS(BIT_CHUNK_SIZE + ebitoff - lsbitoff);
249     else
250 	*bits = (bitset->bits[i] << lsbitoff) & LFILLBITS(ebitoff - lsbitoff);
wrd_midi_event(int cmd,int arg)251 }
252 
253 /*
254  * bitset ����� 1 �ӥåȤ�ޤޤ�Ƥ��ʤ���� 0 ���֤���
255  * 1 �ӥåȤǤ�ޤޤ�Ƥ������ 1 ���֤���
256  */
257 unsigned int has_bitset(const Bitset *bitset)
258 {
259     int i, n;
260     const unsigned int *p;
261 
262     n = CUTUP(bitset->nbits) / BIT_CHUNK_SIZE;
263     p = bitset->bits;
264 
265     for(i = 0; i < n; i++)
266 	if(p[i])
267 	    return 1;
268     return 0;
269 }
270 
271 int get_bitset1(Bitset *bitset, int n)
272 {
wrd_sherry_event(int addr)273     int i;
274     if(n < 0 || n >= bitset->nbits)
275 	return 0;
276     i = BIT_CHUNK_SIZE - n - 1;
277     return (bitset->bits[n / BIT_CHUNK_SIZE] & (1u << i)) >> i;
278 }
279 
free_wrd(void)280 void set_bitset1(Bitset *bitset, int n, int bit)
281 {
282     if(n < 0 || n >= bitset->nbits)
283 	return;
284     if(bit)
285 	bitset->bits[n / BIT_CHUNK_SIZE] |=
286 	    (1 << (BIT_CHUNK_SIZE - n - 1));
287     else
288 	bitset->bits[n / BIT_CHUNK_SIZE] &=
289 	   ~(1 << (BIT_CHUNK_SIZE - n - 1));
290 }
291 
292 #if 0
293 void main(void)
294 {
295     int i, j;
296     Bitset b;
297     unsigned int bits[3];
298 
299     init_bitset(&b, 96);
300 
301     b.bits[0] = 0x12345678;
302     b.bits[1] = 0x9abcdef1;
303     b.bits[2] = 0xaaaaaaaa;
304     print_bitset(&b);
305 
306     for(i = 0; i <= 96; i++)
307     {
308 	bits[0] = 0xffffffff;
309 	bits[1] = 0xffffffff;
310 	get_bitset(&b, bits, i, 60);
311 	print_uibits(bits[0]);putchar(',');
312 	print_uibits(bits[1]);
313 	putchar('\n');
314     }
315 }
316 #endif
317