diff options
Diffstat (limited to 'sound/core/seq/seq_timer.c')
-rw-r--r-- | sound/core/seq/seq_timer.c | 29 |
1 files changed, 21 insertions, 8 deletions
diff --git a/sound/core/seq/seq_timer.c b/sound/core/seq/seq_timer.c index b57a3c07ff6f..65b64a7c456d 100644 --- a/sound/core/seq/seq_timer.c +++ b/sound/core/seq/seq_timer.c | |||
@@ -34,10 +34,15 @@ extern int seq_default_timer_device; | |||
34 | extern int seq_default_timer_subdevice; | 34 | extern int seq_default_timer_subdevice; |
35 | extern int seq_default_timer_resolution; | 35 | extern int seq_default_timer_resolution; |
36 | 36 | ||
37 | /* allowed sequencer timer frequencies, in Hz */ | ||
38 | #define MIN_FREQUENCY 10 | ||
39 | #define MAX_FREQUENCY 6250 | ||
40 | #define DEFAULT_FREQUENCY 1000 | ||
41 | |||
37 | #define SKEW_BASE 0x10000 /* 16bit shift */ | 42 | #define SKEW_BASE 0x10000 /* 16bit shift */ |
38 | 43 | ||
39 | static void snd_seq_timer_set_tick_resolution(seq_timer_tick_t *tick, | 44 | static void snd_seq_timer_set_tick_resolution(seq_timer_tick_t *tick, |
40 | int tempo, int ppq, int nticks) | 45 | int tempo, int ppq) |
41 | { | 46 | { |
42 | if (tempo < 1000000) | 47 | if (tempo < 1000000) |
43 | tick->resolution = (tempo * 1000) / ppq; | 48 | tick->resolution = (tempo * 1000) / ppq; |
@@ -51,7 +56,6 @@ static void snd_seq_timer_set_tick_resolution(seq_timer_tick_t *tick, | |||
51 | } | 56 | } |
52 | if (tick->resolution <= 0) | 57 | if (tick->resolution <= 0) |
53 | tick->resolution = 1; | 58 | tick->resolution = 1; |
54 | tick->resolution *= nticks; | ||
55 | snd_seq_timer_update_tick(tick, 0); | 59 | snd_seq_timer_update_tick(tick, 0); |
56 | } | 60 | } |
57 | 61 | ||
@@ -100,7 +104,7 @@ void snd_seq_timer_defaults(seq_timer_t * tmr) | |||
100 | /* setup defaults */ | 104 | /* setup defaults */ |
101 | tmr->ppq = 96; /* 96 PPQ */ | 105 | tmr->ppq = 96; /* 96 PPQ */ |
102 | tmr->tempo = 500000; /* 120 BPM */ | 106 | tmr->tempo = 500000; /* 120 BPM */ |
103 | snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq, 1); | 107 | snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq); |
104 | tmr->running = 0; | 108 | tmr->running = 0; |
105 | 109 | ||
106 | tmr->type = SNDRV_SEQ_TIMER_ALSA; | 110 | tmr->type = SNDRV_SEQ_TIMER_ALSA; |
@@ -183,7 +187,7 @@ int snd_seq_timer_set_tempo(seq_timer_t * tmr, int tempo) | |||
183 | spin_lock_irqsave(&tmr->lock, flags); | 187 | spin_lock_irqsave(&tmr->lock, flags); |
184 | if ((unsigned int)tempo != tmr->tempo) { | 188 | if ((unsigned int)tempo != tmr->tempo) { |
185 | tmr->tempo = tempo; | 189 | tmr->tempo = tempo; |
186 | snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq, 1); | 190 | snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq); |
187 | } | 191 | } |
188 | spin_unlock_irqrestore(&tmr->lock, flags); | 192 | spin_unlock_irqrestore(&tmr->lock, flags); |
189 | return 0; | 193 | return 0; |
@@ -207,7 +211,7 @@ int snd_seq_timer_set_ppq(seq_timer_t * tmr, int ppq) | |||
207 | } | 211 | } |
208 | 212 | ||
209 | tmr->ppq = ppq; | 213 | tmr->ppq = ppq; |
210 | snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq, 1); | 214 | snd_seq_timer_set_tick_resolution(&tmr->tick, tmr->tempo, tmr->ppq); |
211 | spin_unlock_irqrestore(&tmr->lock, flags); | 215 | spin_unlock_irqrestore(&tmr->lock, flags); |
212 | return 0; | 216 | return 0; |
213 | } | 217 | } |
@@ -326,17 +330,26 @@ int snd_seq_timer_stop(seq_timer_t * tmr) | |||
326 | static int initialize_timer(seq_timer_t *tmr) | 330 | static int initialize_timer(seq_timer_t *tmr) |
327 | { | 331 | { |
328 | snd_timer_t *t; | 332 | snd_timer_t *t; |
333 | unsigned long freq; | ||
334 | |||
329 | t = tmr->timeri->timer; | 335 | t = tmr->timeri->timer; |
330 | snd_assert(t, return -EINVAL); | 336 | snd_assert(t, return -EINVAL); |
331 | 337 | ||
338 | freq = tmr->preferred_resolution; | ||
339 | if (!freq) | ||
340 | freq = DEFAULT_FREQUENCY; | ||
341 | else if (freq < MIN_FREQUENCY) | ||
342 | freq = MIN_FREQUENCY; | ||
343 | else if (freq > MAX_FREQUENCY) | ||
344 | freq = MAX_FREQUENCY; | ||
345 | |||
332 | tmr->ticks = 1; | 346 | tmr->ticks = 1; |
333 | if (tmr->preferred_resolution && | 347 | if (!(t->hw.flags & SNDRV_TIMER_HW_SLAVE)) { |
334 | ! (t->hw.flags & SNDRV_TIMER_HW_SLAVE)) { | ||
335 | unsigned long r = t->hw.resolution; | 348 | unsigned long r = t->hw.resolution; |
336 | if (! r && t->hw.c_resolution) | 349 | if (! r && t->hw.c_resolution) |
337 | r = t->hw.c_resolution(t); | 350 | r = t->hw.c_resolution(t); |
338 | if (r) { | 351 | if (r) { |
339 | tmr->ticks = (unsigned int)(1000000000uL / (r * tmr->preferred_resolution)); | 352 | tmr->ticks = (unsigned int)(1000000000uL / (r * freq)); |
340 | if (! tmr->ticks) | 353 | if (! tmr->ticks) |
341 | tmr->ticks = 1; | 354 | tmr->ticks = 1; |
342 | } | 355 | } |