Branch data Line data Source code
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 : : */ 6 : : #ifndef __SND_SEQ_TIMER_H 7 : : #define __SND_SEQ_TIMER_H 8 : : 9 : : #include <sound/timer.h> 10 : : #include <sound/seq_kernel.h> 11 : : 12 : : struct snd_seq_timer_tick { 13 : : snd_seq_tick_time_t cur_tick; /* current tick */ 14 : : unsigned long resolution; /* time per tick in nsec */ 15 : : unsigned long fraction; /* current time per tick in nsec */ 16 : : }; 17 : : 18 : : struct snd_seq_timer { 19 : : /* ... tempo / offset / running state */ 20 : : 21 : : unsigned int running:1, /* running state of queue */ 22 : : initialized:1; /* timer is initialized */ 23 : : 24 : : unsigned int tempo; /* current tempo, us/tick */ 25 : : int ppq; /* time resolution, ticks/quarter */ 26 : : 27 : : snd_seq_real_time_t cur_time; /* current time */ 28 : : struct snd_seq_timer_tick tick; /* current tick */ 29 : : int tick_updated; 30 : : 31 : : int type; /* timer type */ 32 : : struct snd_timer_id alsa_id; /* ALSA's timer ID */ 33 : : struct snd_timer_instance *timeri; /* timer instance */ 34 : : unsigned int ticks; 35 : : unsigned long preferred_resolution; /* timer resolution, ticks/sec */ 36 : : 37 : : unsigned int skew; 38 : : unsigned int skew_base; 39 : : 40 : : struct timespec64 last_update; /* time of last clock update, used for interpolation */ 41 : : 42 : : spinlock_t lock; 43 : : }; 44 : : 45 : : 46 : : /* create new timer (constructor) */ 47 : : struct snd_seq_timer *snd_seq_timer_new(void); 48 : : 49 : : /* delete timer (destructor) */ 50 : : void snd_seq_timer_delete(struct snd_seq_timer **tmr); 51 : : 52 : : /* */ 53 : 0 : static inline void snd_seq_timer_update_tick(struct snd_seq_timer_tick *tick, 54 : : unsigned long resolution) 55 : : { 56 [ # # # # ]: 0 : if (tick->resolution > 0) { 57 : 0 : tick->fraction += resolution; 58 : 0 : tick->cur_tick += (unsigned int)(tick->fraction / tick->resolution); 59 : 0 : tick->fraction %= tick->resolution; 60 : : } 61 : : } 62 : : 63 : : 64 : : /* compare timestamp between events */ 65 : : /* return 1 if a >= b; otherwise return 0 */ 66 : 0 : static inline int snd_seq_compare_tick_time(snd_seq_tick_time_t *a, snd_seq_tick_time_t *b) 67 : : { 68 : : /* compare ticks */ 69 [ # # # # : 0 : return (*a >= *b); # # # # ] 70 : : } 71 : : 72 : 0 : static inline int snd_seq_compare_real_time(snd_seq_real_time_t *a, snd_seq_real_time_t *b) 73 : : { 74 : : /* compare real time */ 75 [ # # # # : 0 : if (a->tv_sec > b->tv_sec) # # # # ] 76 : : return 1; 77 [ # # # # : 0 : if ((a->tv_sec == b->tv_sec) && (a->tv_nsec >= b->tv_nsec)) # # # # # # # # # # # # ] 78 : : return 1; 79 : : return 0; 80 : : } 81 : : 82 : : 83 : 0 : static inline void snd_seq_sanity_real_time(snd_seq_real_time_t *tm) 84 : : { 85 [ # # # # : 0 : while (tm->tv_nsec >= 1000000000) { # # ] 86 : : /* roll-over */ 87 : 0 : tm->tv_nsec -= 1000000000; 88 : 0 : tm->tv_sec++; 89 : : } 90 : : } 91 : : 92 : : 93 : : /* increment timestamp */ 94 : 0 : static inline void snd_seq_inc_real_time(snd_seq_real_time_t *tm, snd_seq_real_time_t *inc) 95 : : { 96 : 0 : tm->tv_sec += inc->tv_sec; 97 : 0 : tm->tv_nsec += inc->tv_nsec; 98 : 0 : snd_seq_sanity_real_time(tm); 99 : : } 100 : : 101 : 0 : static inline void snd_seq_inc_time_nsec(snd_seq_real_time_t *tm, unsigned long nsec) 102 : : { 103 : 0 : tm->tv_nsec += nsec; 104 : 0 : snd_seq_sanity_real_time(tm); 105 : : } 106 : : 107 : : /* called by timer isr */ 108 : : struct snd_seq_queue; 109 : : int snd_seq_timer_open(struct snd_seq_queue *q); 110 : : int snd_seq_timer_close(struct snd_seq_queue *q); 111 : : int snd_seq_timer_midi_open(struct snd_seq_queue *q); 112 : : int snd_seq_timer_midi_close(struct snd_seq_queue *q); 113 : : void snd_seq_timer_defaults(struct snd_seq_timer *tmr); 114 : : void snd_seq_timer_reset(struct snd_seq_timer *tmr); 115 : : int snd_seq_timer_stop(struct snd_seq_timer *tmr); 116 : : int snd_seq_timer_start(struct snd_seq_timer *tmr); 117 : : int snd_seq_timer_continue(struct snd_seq_timer *tmr); 118 : : int snd_seq_timer_set_tempo(struct snd_seq_timer *tmr, int tempo); 119 : : int snd_seq_timer_set_tempo_ppq(struct snd_seq_timer *tmr, int tempo, int ppq); 120 : : int snd_seq_timer_set_position_tick(struct snd_seq_timer *tmr, snd_seq_tick_time_t position); 121 : : int snd_seq_timer_set_position_time(struct snd_seq_timer *tmr, snd_seq_real_time_t position); 122 : : int snd_seq_timer_set_skew(struct snd_seq_timer *tmr, unsigned int skew, unsigned int base); 123 : : snd_seq_real_time_t snd_seq_timer_get_cur_time(struct snd_seq_timer *tmr, 124 : : bool adjust_ktime); 125 : : snd_seq_tick_time_t snd_seq_timer_get_cur_tick(struct snd_seq_timer *tmr); 126 : : 127 : : extern int seq_default_timer_class; 128 : : extern int seq_default_timer_sclass; 129 : : extern int seq_default_timer_card; 130 : : extern int seq_default_timer_device; 131 : : extern int seq_default_timer_subdevice; 132 : : extern int seq_default_timer_resolution; 133 : : 134 : : #endif