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