annotate alsa_pcm_api.c @ 9:4e34698c666b

Remove the embedded udivdi3 implementation.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Mon, 08 Sep 2014 17:28:09 +0200
parents c55ea9478c80
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
1 #include <stdint.h>
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
2 #include <stdlib.h>
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
3 #include <string.h>
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
4 #include <fcntl.h>
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
5 #include <unistd.h>
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
6 #include <errno.h>
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
7 #include "alsa_pcm_api.h"
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
8 int snd_pcm_hw_params_any(int snd_fd, snd_pcm_hw_params_t *params);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
9 int snd_pcm_hw_params_set_access(int snd_fd, snd_pcm_hw_params_t *params, snd_pcm_access_t access);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
10 int snd_pcm_hw_params_set_format(int snd_fd, snd_pcm_hw_params_t *params, snd_pcm_format_t format);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
11 int snd_pcm_hw_params_set_channels(int snd_fd, snd_pcm_hw_params_t *params, unsigned int val);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
12 int snd_pcm_hw_params_set_rate(int snd_fd, snd_pcm_hw_params_t *params, unsigned int val, int dir);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
13 int snd_pcm_hw_params_set_buffer_size(int snd_fd, snd_pcm_hw_params_t *params, snd_pcm_uframes_t val);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
14 #define MASK_SIZE (SND_MASK_MAX / 32)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
15 #define MASK_OFS(i) ((i) >> 5)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
16 #define MASK_BIT(i) (1U << ((i) & 31))
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
17
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
18 static inline
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
19 snd_interval_t *hw_param_interval(snd_pcm_hw_params_t *params, int var)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
20 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
21 return &params->intervals[var - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL];
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
22 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
23
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
24 static inline
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
25 const snd_interval_t *hw_param_interval_c(const snd_pcm_hw_params_t *params, int var)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
26 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
27 return (const snd_interval_t *)hw_param_interval((snd_pcm_hw_params_t*) params, var);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
28 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
29
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
30 size_t snd_pcm_hw_params_sizeof(void)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
31 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
32 return sizeof(snd_pcm_hw_params_t);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
33 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
34
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
35 static void snd_interval_any(snd_interval_t *i)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
36 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
37 i->min = 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
38 i->openmin = 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
39 i->max = -1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
40 i->openmax = 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
41 i->integer = 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
42 i->empty = 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
43 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
44
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
45 static inline int snd_interval_empty(const snd_interval_t *i)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
46 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
47 return i->empty;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
48 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
49
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
50 static inline int snd_interval_checkempty(const snd_interval_t *i)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
51 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
52 return (i->min > i->max ||
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
53 (i->min == i->max && (i->openmin || i->openmax)));
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
54 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
55
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
56 /* Return the minimum value for field PAR. */
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
57 int _snd_pcm_hw_param_get_min(const snd_pcm_hw_params_t *params,
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
58 int var, unsigned int *val, int *dir)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
59 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
60 const snd_interval_t *i = hw_param_interval_c(params, var);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
61 if (dir)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
62 *dir = i->openmin;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
63 if (val)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
64 *val = i->min;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
65 return 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
66 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
67
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
68 /* Return the maximum value for field PAR. */
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
69 int _snd_pcm_hw_param_get_max(const snd_pcm_hw_params_t *params,
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
70 int var, unsigned int *val, int *dir)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
71 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
72 const snd_interval_t *i = hw_param_interval_c(params, var);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
73 if (dir)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
74 *dir = - (int) i->openmax;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
75 if (val)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
76 *val = i->max;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
77 return 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
78 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
79
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
80 static void _snd_pcm_hw_param_any(snd_pcm_hw_params_t *params, int var)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
81 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
82 snd_interval_any(hw_param_interval(params, var));
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
83 params->cmask |= 1 << var;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
84 params->rmask |= 1 << var;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
85 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
86
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
87 int snd_pcm_hw_params_any(int snd_fd, snd_pcm_hw_params_t *params)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
88 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
89 unsigned int k;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
90 memset(params, 0, sizeof(*params));
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
91 for (k = SNDRV_PCM_HW_PARAM_FIRST_MASK;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
92 k <= SNDRV_PCM_HW_PARAM_LAST_MASK; k++) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
93 snd_mask_t *mask = &params->masks[k - SNDRV_PCM_HW_PARAM_FIRST_MASK];
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
94 memset(mask, 0xff, sizeof(*mask));
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
95 params->cmask |= 1 << k;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
96 params->rmask |= 1 << k;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
97 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
98 for (k = SNDRV_PCM_HW_PARAM_FIRST_INTERVAL;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
99 k <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL; k++)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
100 _snd_pcm_hw_param_any(params, k);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
101 params->rmask = ~0U;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
102 params->cmask = 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
103 params->info = ~0U;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
104 return(ioctl(snd_fd, SNDRV_PCM_IOCTL_HW_REFINE, params));
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
105 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
106
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
107 int snd_pcm_hw_params_store(int snd_fd, snd_pcm_hw_params_t *params)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
108 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
109 ioctl(snd_fd, SNDRV_PCM_IOCTL_HW_REFINE, params);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
110 if (ioctl(snd_fd, SNDRV_PCM_IOCTL_HW_PARAMS, params) < 0)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
111 return -1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
112 if (ioctl(snd_fd, SNDRV_PCM_IOCTL_PREPARE) < 0)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
113 return -1; //-errno;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
114 return 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
115 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
116
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
117 snd_pcm_sframes_t snd_pcm_writei(int snd_fd, const void *buffer, snd_pcm_uframes_t size)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
118 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
119 struct snd_xferi xferi;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
120 xferi.result = 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
121 xferi.buf = (char*) buffer;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
122 xferi.frames = size;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
123 if (ioctl(snd_fd, SNDRV_PCM_IOCTL_WRITEI_FRAMES, &xferi) < 0)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
124 return -1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
125 return xferi.result;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
126 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
127
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
128 snd_pcm_sframes_t snd_pcm_writen(int snd_fd, void **bufs, snd_pcm_uframes_t size)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
129 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
130 struct snd_xfern xfern;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
131 xfern.result = 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
132 xfern.bufs = bufs;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
133 xfern.frames = size;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
134 if (ioctl(snd_fd, SNDRV_PCM_IOCTL_WRITEN_FRAMES, &xfern) < 0)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
135 return -1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
136 return xfern.result;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
137 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
138
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
139 int snd_pcm_prepare(int snd_fd)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
140 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
141 return ioctl(snd_fd, SNDRV_PCM_IOCTL_PREPARE);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
142 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
143
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
144 int snd_pcm_recover(int snd_fd, int err, int silent)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
145 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
146 if (err > 0)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
147 err = -err;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
148 switch (err) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
149 case -EINTR:
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
150 return 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
151 case -EPIPE:
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
152 if (ioctl(snd_fd, SNDRV_PCM_IOCTL_PREPARE) < 0)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
153 return -1; //-errno;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
154 return 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
155 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
156 return err;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
157 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
158
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
159 int snd_pcm_status(int snd_fd, snd_pcm_status_t *status)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
160 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
161 if (ioctl(snd_fd, SNDRV_PCM_IOCTL_STATUS, status) < 0)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
162 return -1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
163 return 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
164 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
165
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
166 static int hw_param_update_var(int snd_fd, snd_pcm_hw_params_t *params,
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
167 int var, int changed)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
168 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
169 if (changed < 0)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
170 return changed;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
171 if (changed) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
172 params->cmask |= 1 << var;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
173 params->rmask |= 1 << var;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
174 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
175 if (params->rmask) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
176 changed = ioctl(snd_fd, SNDRV_PCM_IOCTL_HW_REFINE, params);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
177 if (changed < 0)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
178 return changed;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
179 if (snd_interval_empty(hw_param_interval_c(params, var)))
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
180 return -ENOENT;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
181 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
182 return 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
183 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
184
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
185 static int snd_interval_refine(snd_interval_t *i, const snd_interval_t *v)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
186 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
187 int changed = 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
188 if (snd_interval_empty(i))
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
189 return -ENOENT;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
190 if (i->min < v->min) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
191 i->min = v->min;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
192 i->openmin = v->openmin;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
193 changed = 1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
194 } else if (i->min == v->min && !i->openmin && v->openmin) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
195 i->openmin = 1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
196 changed = 1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
197 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
198 if (i->max > v->max) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
199 i->max = v->max;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
200 i->openmax = v->openmax;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
201 changed = 1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
202 } else if (i->max == v->max && !i->openmax && v->openmax) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
203 i->openmax = 1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
204 changed = 1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
205 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
206 if (!i->integer && v->integer) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
207 i->integer = 1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
208 changed = 1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
209 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
210 if (i->integer) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
211 if (i->openmin) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
212 i->min++;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
213 i->openmin = 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
214 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
215 if (i->openmax) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
216 i->max--;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
217 i->openmax = 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
218 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
219 } else if (!i->openmin && !i->openmax && i->min == i->max)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
220 i->integer = 1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
221 if (snd_interval_checkempty(i)) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
222 i->empty = 1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
223 return -EINVAL;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
224 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
225 return changed;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
226 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
227
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
228 int _snd_pcm_hw_param_get(const snd_pcm_hw_params_t *params,
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
229 int var, unsigned int *val, int *dir)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
230 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
231 const snd_interval_t *i = hw_param_interval_c(params, var);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
232 if (snd_interval_empty(i) || !(i->min == i->max || ((i->min + 1 == i->max) && i->openmax)))
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
233 return -EINVAL;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
234 if (dir)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
235 *dir = i->openmin;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
236 if (val)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
237 *val = i->min;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
238 return 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
239 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
240
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
241 int _snd_pcm_hw_param_set(int snd_fd, snd_pcm_hw_params_t *params, int var,
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
242 unsigned int val, int dir)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
243 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
244 int err = 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
245 snd_pcm_hw_params_t save = *params;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
246 snd_interval_t *i = hw_param_interval(params, var);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
247 snd_interval_t t;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
248 t.empty = 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
249 t.min = t.max = var;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
250 t.openmin = t.openmax = 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
251 t.integer = 1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
252 err = snd_interval_refine(i, &t);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
253 err = hw_param_update_var(snd_fd, params, var, err);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
254 if (err)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
255 *params = save;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
256 return err;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
257 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
258
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
259 static inline int _snd_pcm_hw_param_get64(const snd_pcm_hw_params_t *params, int type, unsigned long *val, int *dir)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
260 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
261 unsigned int _val;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
262 int err = _snd_pcm_hw_param_get(params, type, &_val, dir);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
263 *val = _val;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
264 return err;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
265 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
266
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
267 #if 0
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
268 int snd_pcm_hw_params_get_channels(const snd_pcm_hw_params_t *params, unsigned int *val)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
269 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
270 return _snd_pcm_hw_param_get(params, SNDRV_PCM_HW_PARAM_CHANNELS, val, NULL);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
271 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
272
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
273 int snd_pcm_hw_params_set_channels(int snd_fd, snd_pcm_hw_params_t *params, unsigned int val)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
274 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
275 return _snd_pcm_hw_param_set(snd_fd, params, SNDRV_PCM_HW_PARAM_CHANNELS, val, 0);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
276 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
277
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
278 int snd_pcm_hw_params_get_rate(const snd_pcm_hw_params_t *params, unsigned int *val, int *dir)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
279 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
280 return _snd_pcm_hw_param_get(params, SNDRV_PCM_HW_PARAM_RATE, val, dir);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
281 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
282
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
283 int snd_pcm_hw_params_set_rate(int snd_fd, snd_pcm_hw_params_t *params, unsigned int val, int dir)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
284 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
285 return _snd_pcm_hw_param_set(snd_fd, params, SNDRV_PCM_HW_PARAM_RATE, val, dir);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
286 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
287
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
288 int snd_pcm_hw_params_get_period_time(const snd_pcm_hw_params_t *params,
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
289 unsigned int *val, int *dir)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
290 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
291 return _snd_pcm_hw_param_get(params, SNDRV_PCM_HW_PARAM_PERIOD_TIME, val, dir);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
292 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
293
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
294 int snd_pcm_hw_params_get_period_size(const snd_pcm_hw_params_t *params,
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
295 snd_pcm_uframes_t *val, int *dir)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
296 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
297 return _snd_pcm_hw_param_get64(params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, val, dir);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
298 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
299
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
300 int snd_pcm_hw_params_get_buffer_size(const snd_pcm_hw_params_t *params,
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
301 snd_pcm_uframes_t *val)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
302 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
303 return _snd_pcm_hw_param_get64(params, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, val, NULL);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
304 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
305
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
306 int snd_pcm_hw_params_set_buffer_size(int snd_fd, snd_pcm_hw_params_t *params,
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
307 snd_pcm_uframes_t val)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
308 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
309 return _snd_pcm_hw_param_set(snd_fd, params, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, val, 0);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
310 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
311 #endif
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
312
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
313 static inline unsigned int popcount32(uint32_t mask)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
314 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
315 register unsigned int y;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
316 y = (mask >> 1) &033333333333;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
317 y = mask - y - ((y >>1) & 033333333333);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
318 return (((y + (y >> 3)) & 030707070707) % 077);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
319 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
320
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
321 int snd_pcm_hw_params_set_access(int pcm_fd, snd_pcm_hw_params_t *params,
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
322 snd_pcm_access_t access)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
323 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
324 snd_pcm_hw_params_t save = *params;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
325 snd_mask_t *param = (snd_mask_t*)&params->masks[SNDRV_PCM_HW_PARAM_ACCESS - SNDRV_PCM_HW_PARAM_FIRST_MASK];
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
326 uint32_t i, v = 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
327 int err = 0, changed;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
328 for (i = 0; i < MASK_SIZE; i++) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
329 v += popcount32(param->bits[i]);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
330 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
331 changed = (v != 1);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
332 v = param->bits[MASK_OFS(access)] & MASK_BIT(access);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
333 memset(param, 0, sizeof(*param));
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
334 param->bits[MASK_OFS(access)] = v;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
335 if (changed) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
336 params->cmask |= 1 << SNDRV_PCM_HW_PARAM_ACCESS;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
337 params->rmask |= 1 << SNDRV_PCM_HW_PARAM_ACCESS;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
338 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
339 if (params->rmask) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
340 err = ioctl(pcm_fd, SNDRV_PCM_IOCTL_HW_REFINE, params);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
341 if (err)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
342 *params = save;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
343 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
344 return err;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
345 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
346
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
347 int snd_pcm_hw_params_set_format(int pcm_fd, snd_pcm_hw_params_t *params,
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
348 snd_pcm_format_t format)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
349 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
350 snd_pcm_hw_params_t save = *params;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
351 snd_mask_t *param = (snd_mask_t*)&params->masks[SNDRV_PCM_HW_PARAM_FORMAT - SNDRV_PCM_HW_PARAM_FIRST_MASK];
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
352 uint32_t i, v = 0;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
353 int err = 0, changed;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
354 for (i = 0; i < MASK_SIZE; i++) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
355 v += popcount32(param->bits[i]);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
356 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
357 changed = (v != 1);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
358 v = param->bits[MASK_OFS(format)] & MASK_BIT(format);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
359 memset(param, 0, sizeof(*param));
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
360 param->bits[MASK_OFS(format)] = v;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
361 if (changed) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
362 params->cmask |= 1 << SNDRV_PCM_HW_PARAM_ACCESS;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
363 params->rmask |= 1 << SNDRV_PCM_HW_PARAM_ACCESS;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
364 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
365 if (params->rmask) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
366 err = ioctl(pcm_fd, SNDRV_PCM_IOCTL_HW_REFINE, params);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
367 if (err)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
368 *params = save;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
369 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
370 return err;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
371 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
372
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
373 int alsa_audio_close(int snd_fd)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
374 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
375 ioctl(snd_fd, SNDRV_PCM_IOCTL_HW_FREE);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
376 return close(snd_fd);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
377 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
378
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
379 int alsa_audio_open(uint32_t *rate, uint8_t channels, uint32_t *_ver, int mode)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
380 {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
381 uint32_t actual_channels;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
382 snd_pcm_hw_params_t *hwparams;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
383 *&hwparams = (snd_pcm_hw_params_t *) alloca(snd_pcm_hw_params_sizeof());
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
384 int ver, snd_fd = open("/dev/snd/pcmC0D0p", O_WRONLY|mode);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
385 if (snd_fd < 0)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
386 return -1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
387
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
388 if (ioctl(snd_fd, SNDRV_PCM_IOCTL_PVERSION, &ver) < 0) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
389 if (snd_fd >= 0)
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
390 close(snd_fd);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
391 return -1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
392 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
393 if(_ver) *_ver = ver;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
394
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
395 // Initialize hwparams structure.
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
396 snd_pcm_hw_params_any(snd_fd, hwparams);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
397
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
398 // this *must* be set, or else the writei (actually an ioctl(), wtf?) below will fail with -EBADF
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
399 snd_pcm_hw_params_set_access(snd_fd, hwparams, SND_PCM_ACCESS_RW_INTERLEAVED);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
400 snd_pcm_hw_params_set_format(snd_fd, hwparams, SND_PCM_FORMAT_S16_LE);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
401
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
402 _snd_pcm_hw_param_set(snd_fd, hwparams, SNDRV_PCM_HW_PARAM_CHANNELS, channels, 0);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
403 _snd_pcm_hw_param_get(hwparams, SNDRV_PCM_HW_PARAM_CHANNELS, &actual_channels, NULL);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
404 if ((channels == 1) && (actual_channels == 2)) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
405 // This is an offensively dumb hack that works around the fact that the ALSA devs erroneously believe that HDAudio chipsets cannot playback mono.
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
406 // On any other chipset, it's a terrible idea. In general, it's awful. I'm just lazy. That, and I don't use ALSA myself. :P
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
407 *rate >>= 1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
408 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
409 _snd_pcm_hw_param_set(snd_fd, hwparams, SNDRV_PCM_HW_PARAM_RATE, *rate, 0);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
410 snd_pcm_hw_params_store(snd_fd, hwparams);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
411 _snd_pcm_hw_param_get(hwparams, SNDRV_PCM_HW_PARAM_RATE, rate, NULL);
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
412 if ((channels == 1) && (actual_channels == 2)) {
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
413 *rate <<= 1;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
414 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
415 return snd_fd;
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
416 }
c55ea9478c80 Hello Gensokyo!
Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
parents:
diff changeset
417