Blame view
sound/core/pcm_timer.c
3.67 KB
1da177e4c Linux-2.6.12-rc2 |
1 2 |
/* * Digital Audio (PCM) abstract layer |
c1017a4cd [ALSA] Changed Ja... |
3 |
* Copyright (c) by Jaroslav Kysela <perex@perex.cz> |
1da177e4c Linux-2.6.12-rc2 |
4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
* * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * */ |
1da177e4c Linux-2.6.12-rc2 |
21 |
#include <linux/time.h> |
a9605391c ALSA: sound/core/... |
22 |
#include <linux/gcd.h> |
1da177e4c Linux-2.6.12-rc2 |
23 24 25 26 27 28 29 |
#include <sound/core.h> #include <sound/pcm.h> #include <sound/timer.h> /* * Timer functions */ |
877211f5e [ALSA] Remove xxx... |
30 |
void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream) |
1da177e4c Linux-2.6.12-rc2 |
31 32 |
{ unsigned long rate, mult, fsize, l, post; |
877211f5e [ALSA] Remove xxx... |
33 |
struct snd_pcm_runtime *runtime = substream->runtime; |
1da177e4c Linux-2.6.12-rc2 |
34 35 36 |
mult = 1000000000; rate = runtime->rate; |
7eaa943c8 ALSA: Kill snd_as... |
37 38 |
if (snd_BUG_ON(!rate)) return; |
1da177e4c Linux-2.6.12-rc2 |
39 40 41 42 |
l = gcd(mult, rate); mult /= l; rate /= l; fsize = runtime->period_size; |
7eaa943c8 ALSA: Kill snd_as... |
43 44 |
if (snd_BUG_ON(!fsize)) return; |
1da177e4c Linux-2.6.12-rc2 |
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
l = gcd(rate, fsize); rate /= l; fsize /= l; post = 1; while ((mult * fsize) / fsize != mult) { mult /= 2; post *= 2; } if (rate == 0) { snd_printk(KERN_ERR "pcm timer resolution out of range (rate = %u, period_size = %lu) ", runtime->rate, runtime->period_size); runtime->timer_resolution = -1; return; } runtime->timer_resolution = (mult * fsize / rate) * post; } |
877211f5e [ALSA] Remove xxx... |
61 |
static unsigned long snd_pcm_timer_resolution(struct snd_timer * timer) |
1da177e4c Linux-2.6.12-rc2 |
62 |
{ |
877211f5e [ALSA] Remove xxx... |
63 |
struct snd_pcm_substream *substream; |
1da177e4c Linux-2.6.12-rc2 |
64 65 66 67 |
substream = timer->private_data; return substream->runtime ? substream->runtime->timer_resolution : 0; } |
877211f5e [ALSA] Remove xxx... |
68 |
static int snd_pcm_timer_start(struct snd_timer * timer) |
1da177e4c Linux-2.6.12-rc2 |
69 |
{ |
877211f5e [ALSA] Remove xxx... |
70 |
struct snd_pcm_substream *substream; |
1da177e4c Linux-2.6.12-rc2 |
71 72 |
substream = snd_timer_chip(timer); |
1da177e4c Linux-2.6.12-rc2 |
73 |
substream->timer_running = 1; |
1da177e4c Linux-2.6.12-rc2 |
74 75 |
return 0; } |
877211f5e [ALSA] Remove xxx... |
76 |
static int snd_pcm_timer_stop(struct snd_timer * timer) |
1da177e4c Linux-2.6.12-rc2 |
77 |
{ |
877211f5e [ALSA] Remove xxx... |
78 |
struct snd_pcm_substream *substream; |
1da177e4c Linux-2.6.12-rc2 |
79 80 |
substream = snd_timer_chip(timer); |
1da177e4c Linux-2.6.12-rc2 |
81 |
substream->timer_running = 0; |
1da177e4c Linux-2.6.12-rc2 |
82 83 |
return 0; } |
877211f5e [ALSA] Remove xxx... |
84 |
static struct snd_timer_hardware snd_pcm_timer = |
1da177e4c Linux-2.6.12-rc2 |
85 86 87 88 89 90 91 92 93 94 95 96 |
{ .flags = SNDRV_TIMER_HW_AUTO | SNDRV_TIMER_HW_SLAVE, .resolution = 0, .ticks = 1, .c_resolution = snd_pcm_timer_resolution, .start = snd_pcm_timer_start, .stop = snd_pcm_timer_stop, }; /* * Init functions */ |
877211f5e [ALSA] Remove xxx... |
97 |
static void snd_pcm_timer_free(struct snd_timer *timer) |
1da177e4c Linux-2.6.12-rc2 |
98 |
{ |
877211f5e [ALSA] Remove xxx... |
99 |
struct snd_pcm_substream *substream = timer->private_data; |
1da177e4c Linux-2.6.12-rc2 |
100 101 |
substream->timer = NULL; } |
877211f5e [ALSA] Remove xxx... |
102 |
void snd_pcm_timer_init(struct snd_pcm_substream *substream) |
1da177e4c Linux-2.6.12-rc2 |
103 |
{ |
877211f5e [ALSA] Remove xxx... |
104 105 |
struct snd_timer_id tid; struct snd_timer *timer; |
1da177e4c Linux-2.6.12-rc2 |
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
tid.dev_sclass = SNDRV_TIMER_SCLASS_NONE; tid.dev_class = SNDRV_TIMER_CLASS_PCM; tid.card = substream->pcm->card->number; tid.device = substream->pcm->device; tid.subdevice = (substream->number << 1) | (substream->stream & 1); if (snd_timer_new(substream->pcm->card, "PCM", &tid, &timer) < 0) return; sprintf(timer->name, "PCM %s %i-%i-%i", substream->stream == SNDRV_PCM_STREAM_CAPTURE ? "capture" : "playback", tid.card, tid.device, tid.subdevice); timer->hw = snd_pcm_timer; if (snd_device_register(timer->card, timer) < 0) { snd_device_free(timer->card, timer); return; } timer->private_data = substream; timer->private_free = snd_pcm_timer_free; substream->timer = timer; } |
877211f5e [ALSA] Remove xxx... |
127 |
void snd_pcm_timer_done(struct snd_pcm_substream *substream) |
1da177e4c Linux-2.6.12-rc2 |
128 129 130 131 132 133 |
{ if (substream->timer) { snd_device_free(substream->pcm->card, substream->timer); substream->timer = NULL; } } |