This source file includes following definitions.
- tmr2ticks
- poll_def_tmr
- tmr_reset
- def_tmr_open
- def_tmr_close
- def_tmr_event
- def_tmr_get_time
- def_tmr_ioctl
- def_tmr_arm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 #define SEQUENCER_C
32 #include "sound_config.h"
33
34 #ifdef CONFIGURE_SOUNDCARD
35
36 #ifndef EXCLUDE_SEQUENCER
37
38 static volatile int opened = 0, tmr_running = 0;
39 static volatile time_t tmr_offs, tmr_ctr;
40 static volatile unsigned long ticks_offs;
41 static volatile int curr_tempo, curr_timebase;
42 static volatile unsigned long curr_ticks;
43 static volatile unsigned long next_event_time;
44 static unsigned long prev_event_time;
45
46 static void poll_def_tmr (unsigned long dummy);
47
48 DEFINE_TIMER (def_tmr, poll_def_tmr);
49
50 static unsigned long
51 tmr2ticks (int tmr_value)
52 {
53
54
55
56
57 unsigned long tmp;
58 unsigned long scale;
59
60 tmp = (tmr_value * 1000) / HZ;
61
62 if (curr_tempo == 0 || curr_timebase == 0)
63 scale = 1;
64 else
65 scale = (60 * 1000) / (curr_tempo * curr_timebase);
66
67 if (scale == 0)
68 scale = 1;
69
70 return (tmp + (scale >> 1)) / scale;
71 }
72
73 static void
74 poll_def_tmr (unsigned long dummy)
75 {
76
77 if (opened)
78 {
79 ACTIVATE_TIMER (def_tmr, poll_def_tmr, 1);
80
81 if (tmr_running)
82 {
83 tmr_ctr++;
84 curr_ticks = ticks_offs + tmr2ticks (tmr_ctr);
85
86 if (curr_ticks >= next_event_time)
87 {
88 next_event_time = 0xffffffff;
89 sequencer_timer ();
90 }
91 }
92 }
93 }
94
95 static void
96 tmr_reset (void)
97 {
98 unsigned long flags;
99
100 DISABLE_INTR (flags);
101 tmr_offs = 0;
102 ticks_offs = 0;
103 tmr_ctr = 0;
104 next_event_time = 0xffffffff;
105 prev_event_time = 0;
106 curr_ticks = 0;
107 RESTORE_INTR (flags);
108 }
109
110 static int
111 def_tmr_open (int dev, int mode)
112 {
113 if (opened)
114 return RET_ERROR (EBUSY);
115
116 tmr_reset ();
117 curr_tempo = 60;
118 curr_timebase = HZ;
119 opened = 1;
120
121 ACTIVATE_TIMER (def_tmr, poll_def_tmr, 1);
122
123 return 0;
124 }
125
126 static void
127 def_tmr_close (int dev)
128 {
129 opened = tmr_running = 0;
130 }
131
132 static int
133 def_tmr_event (int dev, unsigned char *event)
134 {
135 unsigned char cmd = event[1];
136 unsigned long parm = *(int *) &event[4];
137
138 switch (cmd)
139 {
140 case TMR_WAIT_REL:
141 parm += prev_event_time;
142 case TMR_WAIT_ABS:
143 if (parm > 0)
144 {
145 long time;
146
147 if (parm <= curr_ticks)
148 return TIMER_NOT_ARMED;
149
150 time = parm;
151 next_event_time = prev_event_time = time;
152
153 return TIMER_ARMED;
154 }
155 break;
156
157 case TMR_START:
158 tmr_reset ();
159 tmr_running = 1;
160 break;
161
162 case TMR_STOP:
163 tmr_running = 0;
164 break;
165
166 case TMR_CONTINUE:
167 tmr_running = 1;
168 break;
169
170 case TMR_TEMPO:
171 if (parm)
172 {
173 if (parm < 8)
174 parm = 8;
175 if (parm > 250)
176 parm = 250;
177 tmr_offs = tmr_ctr;
178 ticks_offs += tmr2ticks (tmr_ctr);
179 tmr_ctr = 0;
180 curr_tempo = parm;
181 }
182 break;
183
184 case TMR_ECHO:
185 seq_copy_to_input (event, 8);
186 break;
187
188 default:;
189 }
190
191 return TIMER_NOT_ARMED;
192 }
193
194 static unsigned long
195 def_tmr_get_time (int dev)
196 {
197 if (!opened)
198 return 0;
199
200 return curr_ticks;
201 }
202
203 static int
204 def_tmr_ioctl (int dev,
205 unsigned int cmd, unsigned int arg)
206 {
207 switch (cmd)
208 {
209 case SNDCTL_TMR_SOURCE:
210 return IOCTL_OUT (arg, TMR_INTERNAL);
211 break;
212
213 case SNDCTL_TMR_START:
214 tmr_reset ();
215 tmr_running = 1;
216 return 0;
217 break;
218
219 case SNDCTL_TMR_STOP:
220 tmr_running = 0;
221 return 0;
222 break;
223
224 case SNDCTL_TMR_CONTINUE:
225 tmr_running = 1;
226 return 0;
227 break;
228
229 case SNDCTL_TMR_TIMEBASE:
230 {
231 int val = IOCTL_IN (arg);
232
233 if (val)
234 {
235 if (val < 1)
236 val = 1;
237 if (val > 1000)
238 val = 1000;
239 curr_timebase = val;
240 }
241
242 return IOCTL_OUT (arg, curr_timebase);
243 }
244 break;
245
246 case SNDCTL_TMR_TEMPO:
247 {
248 int val = IOCTL_IN (arg);
249
250 if (val)
251 {
252 if (val < 8)
253 val = 8;
254 if (val > 250)
255 val = 250;
256 tmr_offs = tmr_ctr;
257 ticks_offs += tmr2ticks (tmr_ctr);
258 tmr_ctr = 0;
259 curr_tempo = val;
260 }
261
262 return IOCTL_OUT (arg, curr_tempo);
263 }
264 break;
265
266 case SNDCTL_SEQ_CTRLRATE:
267 if (IOCTL_IN (arg) != 0)
268 return RET_ERROR (EINVAL);
269
270 return IOCTL_OUT (arg, ((curr_tempo * curr_timebase) + 30) / 60);
271 break;
272
273 case SNDCTL_TMR_METRONOME:
274
275 break;
276
277 default:;
278 }
279
280 return RET_ERROR (EINVAL);
281 }
282
283 static void
284 def_tmr_arm (int dev, long time)
285 {
286 if (time < 0)
287 time = curr_ticks + 1;
288 else if (time <= curr_ticks)
289 return;
290
291 next_event_time = prev_event_time = time;
292
293 return;
294 }
295
296 struct sound_timer_operations default_sound_timer =
297 {
298 {"System Timer", 0},
299 0,
300 0,
301 def_tmr_open,
302 def_tmr_close,
303 def_tmr_event,
304 def_tmr_get_time,
305 def_tmr_ioctl,
306 def_tmr_arm
307 };
308
309 #endif
310 #endif