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