aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/seq/seq_timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'sound/core/seq/seq_timer.c')
-rw-r--r--sound/core/seq/seq_timer.c29
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;
34extern int seq_default_timer_subdevice; 34extern int seq_default_timer_subdevice;
35extern int seq_default_timer_resolution; 35extern 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
39static void snd_seq_timer_set_tick_resolution(seq_timer_tick_t *tick, 44static 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)
326static int initialize_timer(seq_timer_t *tmr) 330static 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 }