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