xref: /linux/sound/core/seq/seq_timer.c (revision 45d8b572fac3aa8b49d53c946b3685eaf78a2824)
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  *   ALSA sequencer Timer
4  *   Copyright (c) 1998-1999 by Frank van de Pol <fvdpol@coil.demon.nl>
5  *                              Jaroslav Kysela <perex@perex.cz>
6  */
7 
8 #include <sound/core.h>
9 #include <linux/slab.h>
10 #include "seq_timer.h"
11 #include "seq_queue.h"
12 #include "seq_info.h"
13 
14 /* allowed sequencer timer frequencies, in Hz */
15 #define MIN_FREQUENCY		10
16 #define MAX_FREQUENCY		6250
17 #define DEFAULT_FREQUENCY	1000
18 
19 #define SKEW_BASE	0x10000	/* 16bit shift */
20 
21 static void snd_seq_timer_set_tick_resolution(struct snd_seq_timer *tmr)
22 {
23 	if (tmr->tempo < 1000000)
24 		tmr->tick.resolution = (tmr->tempo * 1000) / tmr->ppq;
25 	else {
26 		/* might overflow.. */
27 		unsigned int s;
28 		s = tmr->tempo % tmr->ppq;
29 		s = (s * 1000) / tmr->ppq;
30 		tmr->tick.resolution = (tmr->tempo / tmr->ppq) * 1000;
31 		tmr->tick.resolution += s;
32 	}
33 	if (tmr->tick.resolution <= 0)
34 		tmr->tick.resolution = 1;
35 	snd_seq_timer_update_tick(&tmr->tick, 0);
36 }
37 
38 /* create new timer (constructor) */
39 struct snd_seq_timer *snd_seq_timer_new(void)
40 {
41 	struct snd_seq_timer *tmr;
42 
43 	tmr = kzalloc(sizeof(*tmr), GFP_KERNEL);
44 	if (!tmr)
45 		return NULL;
46 	spin_lock_init(&tmr->lock);
47 
48 	/* reset setup to defaults */
49 	snd_seq_timer_defaults(tmr);
50 
51 	/* reset time */
52 	snd_seq_timer_reset(tmr);
53 
54 	return tmr;
55 }
56 
57 /* delete timer (destructor) */
58 void snd_seq_timer_delete(struct snd_seq_timer **tmr)
59 {
60 	struct snd_seq_timer *t = *tmr;
61 	*tmr = NULL;
62 
63 	if (t == NULL) {
64 		pr_debug("ALSA: seq: snd_seq_timer_delete() called with NULL timer\n");
65 		return;
66 	}
67 	t->running = 0;
68 
69 	/* reset time */
70 	snd_seq_timer_stop(t);
71 	snd_seq_timer_reset(t);
72 
73 	kfree(t);
74 }
75 
76 void snd_seq_timer_defaults(struct snd_seq_timer * tmr)
77 {
78 	guard(spinlock_irqsave)(&tmr->lock);
79 	/* setup defaults */
80 	tmr->ppq = 96;		/* 96 PPQ */
81 	tmr->tempo = 500000;	/* 120 BPM */
82 	snd_seq_timer_set_tick_resolution(tmr);
83 	tmr->running = 0;
84 
85 	tmr->type = SNDRV_SEQ_TIMER_ALSA;
86 	tmr->alsa_id.dev_class = seq_default_timer_class;
87 	tmr->alsa_id.dev_sclass = seq_default_timer_sclass;
88 	tmr->alsa_id.card = seq_default_timer_card;
89 	tmr->alsa_id.device = seq_default_timer_device;
90 	tmr->alsa_id.subdevice = seq_default_timer_subdevice;
91 	tmr->preferred_resolution = seq_default_timer_resolution;
92 
93 	tmr->skew = tmr->skew_base = SKEW_BASE;
94 }
95 
96 static void seq_timer_reset(struct snd_seq_timer *tmr)
97 {
98 	/* reset time & songposition */
99 	tmr->cur_time.tv_sec = 0;
100 	tmr->cur_time.tv_nsec = 0;
101 
102 	tmr->tick.cur_tick = 0;
103 	tmr->tick.fraction = 0;
104 }
105 
106 void snd_seq_timer_reset(struct snd_seq_timer *tmr)
107 {
108 	guard(spinlock_irqsave)(&tmr->lock);
109 	seq_timer_reset(tmr);
110 }
111 
112 
113 /* called by timer interrupt routine. the period time since previous invocation is passed */
114 static void snd_seq_timer_interrupt(struct snd_timer_instance *timeri,
115 				    unsigned long resolution,
116 				    unsigned long ticks)
117 {
118 	struct snd_seq_queue *q = timeri->callback_data;
119 	struct snd_seq_timer *tmr;
120 
121 	if (q == NULL)
122 		return;
123 	tmr = q->timer;
124 	if (tmr == NULL)
125 		return;
126 
127 	scoped_guard(spinlock_irqsave, &tmr->lock) {
128 		if (!tmr->running)
129 			return;
130 
131 		resolution *= ticks;
132 		if (tmr->skew != tmr->skew_base) {
133 			/* FIXME: assuming skew_base = 0x10000 */
134 			resolution = (resolution >> 16) * tmr->skew +
135 				(((resolution & 0xffff) * tmr->skew) >> 16);
136 		}
137 
138 		/* update timer */
139 		snd_seq_inc_time_nsec(&tmr->cur_time, resolution);
140 
141 		/* calculate current tick */
142 		snd_seq_timer_update_tick(&tmr->tick, resolution);
143 
144 		/* register actual time of this timer update */
145 		ktime_get_ts64(&tmr->last_update);
146 	}
147 
148 	/* check queues and dispatch events */
149 	snd_seq_check_queue(q, 1, 0);
150 }
151 
152 /* set current tempo */
153 int snd_seq_timer_set_tempo(struct snd_seq_timer * tmr, int tempo)
154 {
155 	if (snd_BUG_ON(!tmr))
156 		return -EINVAL;
157 	if (tempo <= 0)
158 		return -EINVAL;
159 	guard(spinlock_irqsave)(&tmr->lock);
160 	if ((unsigned int)tempo != tmr->tempo) {
161 		tmr->tempo = tempo;
162 		snd_seq_timer_set_tick_resolution(tmr);
163 	}
164 	return 0;
165 }
166 
167 /* set current tempo and ppq in a shot */
168 int snd_seq_timer_set_tempo_ppq(struct snd_seq_timer *tmr, int tempo, int ppq)
169 {
170 	int changed;
171 
172 	if (snd_BUG_ON(!tmr))
173 		return -EINVAL;
174 	if (tempo <= 0 || ppq <= 0)
175 		return -EINVAL;
176 	guard(spinlock_irqsave)(&tmr->lock);
177 	if (tmr->running && (ppq != tmr->ppq)) {
178 		/* refuse to change ppq on running timers */
179 		/* because it will upset the song position (ticks) */
180 		pr_debug("ALSA: seq: cannot change ppq of a running timer\n");
181 		return -EBUSY;
182 	}
183 	changed = (tempo != tmr->tempo) || (ppq != tmr->ppq);
184 	tmr->tempo = tempo;
185 	tmr->ppq = ppq;
186 	if (changed)
187 		snd_seq_timer_set_tick_resolution(tmr);
188 	return 0;
189 }
190 
191 /* set current tick position */
192 int snd_seq_timer_set_position_tick(struct snd_seq_timer *tmr,
193 				    snd_seq_tick_time_t position)
194 {
195 	if (snd_BUG_ON(!tmr))
196 		return -EINVAL;
197 
198 	guard(spinlock_irqsave)(&tmr->lock);
199 	tmr->tick.cur_tick = position;
200 	tmr->tick.fraction = 0;
201 	return 0;
202 }
203 
204 /* set current real-time position */
205 int snd_seq_timer_set_position_time(struct snd_seq_timer *tmr,
206 				    snd_seq_real_time_t position)
207 {
208 	if (snd_BUG_ON(!tmr))
209 		return -EINVAL;
210 
211 	snd_seq_sanity_real_time(&position);
212 	guard(spinlock_irqsave)(&tmr->lock);
213 	tmr->cur_time = position;
214 	return 0;
215 }
216 
217 /* set timer skew */
218 int snd_seq_timer_set_skew(struct snd_seq_timer *tmr, unsigned int skew,
219 			   unsigned int base)
220 {
221 	if (snd_BUG_ON(!tmr))
222 		return -EINVAL;
223 
224 	/* FIXME */
225 	if (base != SKEW_BASE) {
226 		pr_debug("ALSA: seq: invalid skew base 0x%x\n", base);
227 		return -EINVAL;
228 	}
229 	guard(spinlock_irqsave)(&tmr->lock);
230 	tmr->skew = skew;
231 	return 0;
232 }
233 
234 int snd_seq_timer_open(struct snd_seq_queue *q)
235 {
236 	struct snd_timer_instance *t;
237 	struct snd_seq_timer *tmr;
238 	char str[32];
239 	int err;
240 
241 	tmr = q->timer;
242 	if (snd_BUG_ON(!tmr))
243 		return -EINVAL;
244 	if (tmr->timeri)
245 		return -EBUSY;
246 	sprintf(str, "sequencer queue %i", q->queue);
247 	if (tmr->type != SNDRV_SEQ_TIMER_ALSA)	/* standard ALSA timer */
248 		return -EINVAL;
249 	if (tmr->alsa_id.dev_class != SNDRV_TIMER_CLASS_SLAVE)
250 		tmr->alsa_id.dev_sclass = SNDRV_TIMER_SCLASS_SEQUENCER;
251 	t = snd_timer_instance_new(str);
252 	if (!t)
253 		return -ENOMEM;
254 	t->callback = snd_seq_timer_interrupt;
255 	t->callback_data = q;
256 	t->flags |= SNDRV_TIMER_IFLG_AUTO;
257 	err = snd_timer_open(t, &tmr->alsa_id, q->queue);
258 	if (err < 0 && tmr->alsa_id.dev_class != SNDRV_TIMER_CLASS_SLAVE) {
259 		if (tmr->alsa_id.dev_class != SNDRV_TIMER_CLASS_GLOBAL ||
260 		    tmr->alsa_id.device != SNDRV_TIMER_GLOBAL_SYSTEM) {
261 			struct snd_timer_id tid;
262 			memset(&tid, 0, sizeof(tid));
263 			tid.dev_class = SNDRV_TIMER_CLASS_GLOBAL;
264 			tid.dev_sclass = SNDRV_TIMER_SCLASS_SEQUENCER;
265 			tid.card = -1;
266 			tid.device = SNDRV_TIMER_GLOBAL_SYSTEM;
267 			err = snd_timer_open(t, &tid, q->queue);
268 		}
269 	}
270 	if (err < 0) {
271 		pr_err("ALSA: seq fatal error: cannot create timer (%i)\n", err);
272 		snd_timer_instance_free(t);
273 		return err;
274 	}
275 	scoped_guard(spinlock_irq, &tmr->lock) {
276 		if (tmr->timeri)
277 			err = -EBUSY;
278 		else
279 			tmr->timeri = t;
280 	}
281 	if (err < 0) {
282 		snd_timer_close(t);
283 		snd_timer_instance_free(t);
284 		return err;
285 	}
286 	return 0;
287 }
288 
289 int snd_seq_timer_close(struct snd_seq_queue *q)
290 {
291 	struct snd_seq_timer *tmr;
292 	struct snd_timer_instance *t;
293 
294 	tmr = q->timer;
295 	if (snd_BUG_ON(!tmr))
296 		return -EINVAL;
297 	scoped_guard(spinlock_irq, &tmr->lock) {
298 		t = tmr->timeri;
299 		tmr->timeri = NULL;
300 	}
301 	if (t) {
302 		snd_timer_close(t);
303 		snd_timer_instance_free(t);
304 	}
305 	return 0;
306 }
307 
308 static int seq_timer_stop(struct snd_seq_timer *tmr)
309 {
310 	if (! tmr->timeri)
311 		return -EINVAL;
312 	if (!tmr->running)
313 		return 0;
314 	tmr->running = 0;
315 	snd_timer_pause(tmr->timeri);
316 	return 0;
317 }
318 
319 int snd_seq_timer_stop(struct snd_seq_timer *tmr)
320 {
321 	guard(spinlock_irqsave)(&tmr->lock);
322 	return seq_timer_stop(tmr);
323 }
324 
325 static int initialize_timer(struct snd_seq_timer *tmr)
326 {
327 	struct snd_timer *t;
328 	unsigned long freq;
329 
330 	t = tmr->timeri->timer;
331 	if (!t)
332 		return -EINVAL;
333 
334 	freq = tmr->preferred_resolution;
335 	if (!freq)
336 		freq = DEFAULT_FREQUENCY;
337 	else if (freq < MIN_FREQUENCY)
338 		freq = MIN_FREQUENCY;
339 	else if (freq > MAX_FREQUENCY)
340 		freq = MAX_FREQUENCY;
341 
342 	tmr->ticks = 1;
343 	if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE)) {
344 		unsigned long r = snd_timer_resolution(tmr->timeri);
345 		if (r) {
346 			tmr->ticks = (unsigned int)(1000000000uL / (r * freq));
347 			if (! tmr->ticks)
348 				tmr->ticks = 1;
349 		}
350 	}
351 	tmr->initialized = 1;
352 	return 0;
353 }
354 
355 static int seq_timer_start(struct snd_seq_timer *tmr)
356 {
357 	if (! tmr->timeri)
358 		return -EINVAL;
359 	if (tmr->running)
360 		seq_timer_stop(tmr);
361 	seq_timer_reset(tmr);
362 	if (initialize_timer(tmr) < 0)
363 		return -EINVAL;
364 	snd_timer_start(tmr->timeri, tmr->ticks);
365 	tmr->running = 1;
366 	ktime_get_ts64(&tmr->last_update);
367 	return 0;
368 }
369 
370 int snd_seq_timer_start(struct snd_seq_timer *tmr)
371 {
372 	guard(spinlock_irqsave)(&tmr->lock);
373 	return seq_timer_start(tmr);
374 }
375 
376 static int seq_timer_continue(struct snd_seq_timer *tmr)
377 {
378 	if (! tmr->timeri)
379 		return -EINVAL;
380 	if (tmr->running)
381 		return -EBUSY;
382 	if (! tmr->initialized) {
383 		seq_timer_reset(tmr);
384 		if (initialize_timer(tmr) < 0)
385 			return -EINVAL;
386 	}
387 	snd_timer_start(tmr->timeri, tmr->ticks);
388 	tmr->running = 1;
389 	ktime_get_ts64(&tmr->last_update);
390 	return 0;
391 }
392 
393 int snd_seq_timer_continue(struct snd_seq_timer *tmr)
394 {
395 	guard(spinlock_irqsave)(&tmr->lock);
396 	return seq_timer_continue(tmr);
397 }
398 
399 /* return current 'real' time. use timeofday() to get better granularity. */
400 snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr,
401 					       bool adjust_ktime)
402 {
403 	snd_seq_real_time_t cur_time;
404 
405 	guard(spinlock_irqsave)(&tmr->lock);
406 	cur_time = tmr->cur_time;
407 	if (adjust_ktime && tmr->running) {
408 		struct timespec64 tm;
409 
410 		ktime_get_ts64(&tm);
411 		tm = timespec64_sub(tm, tmr->last_update);
412 		cur_time.tv_nsec += tm.tv_nsec;
413 		cur_time.tv_sec += tm.tv_sec;
414 		snd_seq_sanity_real_time(&cur_time);
415 	}
416 	return cur_time;
417 }
418 
419 /* TODO: use interpolation on tick queue (will only be useful for very
420  high PPQ values) */
421 snd_seq_tick_time_t snd_seq_timer_get_cur_tick(struct snd_seq_timer *tmr)
422 {
423 	guard(spinlock_irqsave)(&tmr->lock);
424 	return tmr->tick.cur_tick;
425 }
426 
427 
428 #ifdef CONFIG_SND_PROC_FS
429 /* exported to seq_info.c */
430 void snd_seq_info_timer_read(struct snd_info_entry *entry,
431 			     struct snd_info_buffer *buffer)
432 {
433 	int idx;
434 	struct snd_seq_queue *q;
435 	struct snd_seq_timer *tmr;
436 	struct snd_timer_instance *ti;
437 	unsigned long resolution;
438 
439 	for (idx = 0; idx < SNDRV_SEQ_MAX_QUEUES; idx++) {
440 		q = queueptr(idx);
441 		if (q == NULL)
442 			continue;
443 		scoped_guard(mutex, &q->timer_mutex) {
444 			tmr = q->timer;
445 			if (!tmr)
446 				break;
447 			ti = tmr->timeri;
448 			if (!ti)
449 				break;
450 			snd_iprintf(buffer, "Timer for queue %i : %s\n", q->queue, ti->timer->name);
451 			resolution = snd_timer_resolution(ti) * tmr->ticks;
452 			snd_iprintf(buffer, "  Period time : %lu.%09lu\n", resolution / 1000000000, resolution % 1000000000);
453 			snd_iprintf(buffer, "  Skew : %u / %u\n", tmr->skew, tmr->skew_base);
454 		}
455 		queuefree(q);
456  	}
457 }
458 #endif /* CONFIG_SND_PROC_FS */
459 
460