aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Wilson2012-11-09 17:16:47 -0600
committerSimon Wilson2012-11-09 17:22:36 -0600
commitda39e0b09eb0a1b559a96e2108160d1d8dccf314 (patch)
tree81e2afcb7d8abcbe0829366d5c46b9d7fdeb2300
parentff2e54293f32b5bb5ff75b4cb25babb00f429ca4 (diff)
downloadplatform-external-tinyalsa-da39e0b09eb0a1b559a96e2108160d1d8dccf314.tar.gz
platform-external-tinyalsa-da39e0b09eb0a1b559a96e2108160d1d8dccf314.tar.xz
platform-external-tinyalsa-da39e0b09eb0a1b559a96e2108160d1d8dccf314.zip
Update to latest tinyalsa
2c3a8e2 Add -Wall to Makefile and fix warnings 4ef9a57 tinyplay: add clean shutdown handler for ctrl-c 9bb8066 Merge pull request #15 from quantumdream/master bad2b79 tinymix: Add support for passing control name f51c05b mixer: Add mixer_ctl_{set,get}_bytes() fcf66ab Merge pull request #16 from PeterMalkin/master 3d62222 Add pcm_wait() to the tinyalsa API. f9678dd tinyplay: Add missing header file <string.h> cde1f6f Fix several 'symbol defined but not used' warnings. 2a274a1 pcm: Add support for S8 and S24LE formats. a5baefd tinymix: support setting of multiple control values Change-Id: I3d5fe076753ce7d1f74dd3ebedc59202d29f4efd
-rw-r--r--include/tinyalsa/asoundlib.h8
-rw-r--r--mixer.c43
-rw-r--r--pcm.c14
-rw-r--r--tinycap.c2
-rw-r--r--tinymix.c80
-rw-r--r--tinyplay.c16
6 files changed, 123 insertions, 40 deletions
diff --git a/include/tinyalsa/asoundlib.h b/include/tinyalsa/asoundlib.h
index a796a66..6148361 100644
--- a/include/tinyalsa/asoundlib.h
+++ b/include/tinyalsa/asoundlib.h
@@ -30,6 +30,7 @@
30#define ASOUNDLIB_H 30#define ASOUNDLIB_H
31 31
32#include <sys/time.h> 32#include <sys/time.h>
33#include <stddef.h>
33 34
34#if defined(__cplusplus) 35#if defined(__cplusplus)
35extern "C" { 36extern "C" {
@@ -70,6 +71,8 @@ struct pcm;
70enum pcm_format { 71enum pcm_format {
71 PCM_FORMAT_S16_LE = 0, 72 PCM_FORMAT_S16_LE = 0,
72 PCM_FORMAT_S32_LE, 73 PCM_FORMAT_S32_LE,
74 PCM_FORMAT_S8,
75 PCM_FORMAT_S24_LE,
73 76
74 PCM_FORMAT_MAX, 77 PCM_FORMAT_MAX,
75}; 78};
@@ -163,6 +166,9 @@ int pcm_mmap_commit(struct pcm *pcm, unsigned int offset, unsigned int frames);
163int pcm_start(struct pcm *pcm); 166int pcm_start(struct pcm *pcm);
164int pcm_stop(struct pcm *pcm); 167int pcm_stop(struct pcm *pcm);
165 168
169/* Interrupt driven API */
170int pcm_wait(struct pcm *pcm, int timeout);
171
166/* Change avail_min after the stream has been opened with no need to stop the stream. 172/* Change avail_min after the stream has been opened with no need to stop the stream.
167 * Only accepted if opened with PCM_MMAP and PCM_NOIRQ flags 173 * Only accepted if opened with PCM_MMAP and PCM_NOIRQ flags
168 */ 174 */
@@ -198,7 +204,9 @@ int mixer_ctl_get_percent(struct mixer_ctl *ctl, unsigned int id);
198int mixer_ctl_set_percent(struct mixer_ctl *ctl, unsigned int id, int percent); 204int mixer_ctl_set_percent(struct mixer_ctl *ctl, unsigned int id, int percent);
199 205
200int mixer_ctl_get_value(struct mixer_ctl *ctl, unsigned int id); 206int mixer_ctl_get_value(struct mixer_ctl *ctl, unsigned int id);
207int mixer_ctl_get_bytes(struct mixer_ctl *ctl, void *data, size_t len);
201int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value); 208int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value);
209int mixer_ctl_set_bytes(struct mixer_ctl *ctl, const void *data, size_t len);
202int mixer_ctl_set_enum_by_string(struct mixer_ctl *ctl, const char *string); 210int mixer_ctl_set_enum_by_string(struct mixer_ctl *ctl, const char *string);
203 211
204/* Determe range of integer mixer controls */ 212/* Determe range of integer mixer controls */
diff --git a/mixer.c b/mixer.c
index 9514528..f52bca9 100644
--- a/mixer.c
+++ b/mixer.c
@@ -317,6 +317,27 @@ int mixer_ctl_get_value(struct mixer_ctl *ctl, unsigned int id)
317 return 0; 317 return 0;
318} 318}
319 319
320int mixer_ctl_get_bytes(struct mixer_ctl *ctl, void *data, size_t len)
321{
322 struct snd_ctl_elem_value ev;
323 int ret;
324
325 if (!ctl || (len > ctl->info->count) || !len || !data ||
326 (ctl->info->type != SNDRV_CTL_ELEM_TYPE_BYTES))
327 return -EINVAL;
328
329 memset(&ev, 0, sizeof(ev));
330 ev.id.numid = ctl->info->id.numid;
331
332 ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev);
333 if (ret < 0)
334 return ret;
335
336 memcpy(data, ev.value.bytes.data, len);
337
338 return 0;
339}
340
320int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value) 341int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value)
321{ 342{
322 struct snd_ctl_elem_value ev; 343 struct snd_ctl_elem_value ev;
@@ -351,10 +372,24 @@ int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value)
351 return ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev); 372 return ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev);
352} 373}
353 374
354int mixer_ctl_get_range_min(struct mixer_ctl *ctl) 375int mixer_ctl_set_bytes(struct mixer_ctl *ctl, const void *data, size_t len)
355{ 376{
356 int ret; 377 struct snd_ctl_elem_value ev;
357 378
379 if (!ctl || (len > ctl->info->count) || !len || !data ||
380 (ctl->info->type != SNDRV_CTL_ELEM_TYPE_BYTES))
381 return -EINVAL;
382
383 memset(&ev, 0, sizeof(ev));
384 ev.id.numid = ctl->info->id.numid;
385
386 memcpy(ev.value.bytes.data, data, len);
387
388 return ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev);
389}
390
391int mixer_ctl_get_range_min(struct mixer_ctl *ctl)
392{
358 if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER)) 393 if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER))
359 return -EINVAL; 394 return -EINVAL;
360 395
@@ -363,8 +398,6 @@ int mixer_ctl_get_range_min(struct mixer_ctl *ctl)
363 398
364int mixer_ctl_get_range_max(struct mixer_ctl *ctl) 399int mixer_ctl_get_range_max(struct mixer_ctl *ctl)
365{ 400{
366 int ret;
367
368 if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER)) 401 if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER))
369 return -EINVAL; 402 return -EINVAL;
370 403
@@ -382,8 +415,6 @@ unsigned int mixer_ctl_get_num_enums(struct mixer_ctl *ctl)
382const char *mixer_ctl_get_enum_string(struct mixer_ctl *ctl, 415const char *mixer_ctl_get_enum_string(struct mixer_ctl *ctl,
383 unsigned int enum_id) 416 unsigned int enum_id)
384{ 417{
385 int ret;
386
387 if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_ENUMERATED) || 418 if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_ENUMERATED) ||
388 (enum_id >= ctl->info->value.enumerated.items)) 419 (enum_id >= ctl->info->value.enumerated.items))
389 return NULL; 420 return NULL;
diff --git a/pcm.c b/pcm.c
index 284a7ac..d841bd9 100644
--- a/pcm.c
+++ b/pcm.c
@@ -93,14 +93,6 @@ static void param_set_min(struct snd_pcm_hw_params *p, int n, unsigned int val)
93 } 93 }
94} 94}
95 95
96static void param_set_max(struct snd_pcm_hw_params *p, int n, unsigned int val)
97{
98 if (param_is_interval(n)) {
99 struct snd_interval *i = param_to_interval(p, n);
100 i->max = val;
101 }
102}
103
104static void param_set_int(struct snd_pcm_hw_params *p, int n, unsigned int val) 96static void param_set_int(struct snd_pcm_hw_params *p, int n, unsigned int val)
105{ 97{
106 if (param_is_interval(n)) { 98 if (param_is_interval(n)) {
@@ -190,6 +182,10 @@ static unsigned int pcm_format_to_alsa(enum pcm_format format)
190 switch (format) { 182 switch (format) {
191 case PCM_FORMAT_S32_LE: 183 case PCM_FORMAT_S32_LE:
192 return SNDRV_PCM_FORMAT_S32_LE; 184 return SNDRV_PCM_FORMAT_S32_LE;
185 case PCM_FORMAT_S8:
186 return SNDRV_PCM_FORMAT_S8;
187 case PCM_FORMAT_S24_LE:
188 return SNDRV_PCM_FORMAT_S24_LE;
193 default: 189 default:
194 case PCM_FORMAT_S16_LE: 190 case PCM_FORMAT_S16_LE:
195 return SNDRV_PCM_FORMAT_S16_LE; 191 return SNDRV_PCM_FORMAT_S16_LE;
@@ -741,7 +737,6 @@ int pcm_set_avail_min(struct pcm *pcm, int avail_min)
741int pcm_wait(struct pcm *pcm, int timeout) 737int pcm_wait(struct pcm *pcm, int timeout)
742{ 738{
743 struct pollfd pfd; 739 struct pollfd pfd;
744 unsigned short revents = 0;
745 int err; 740 int err;
746 741
747 pfd.fd = pcm->fd; 742 pfd.fd = pcm->fd;
@@ -864,6 +859,5 @@ int pcm_mmap_write(struct pcm *pcm, const void *buffer, unsigned int bytes)
864 count -= frames; 859 count -= frames;
865 } 860 }
866 861
867_end:
868 return 0; 862 return 0;
869} 863}
diff --git a/tinycap.c b/tinycap.c
index d563309..8c9fcfb 100644
--- a/tinycap.c
+++ b/tinycap.c
@@ -31,6 +31,7 @@
31#include <stdlib.h> 31#include <stdlib.h>
32#include <stdint.h> 32#include <stdint.h>
33#include <signal.h> 33#include <signal.h>
34#include <string.h>
34 35
35#define ID_RIFF 0x46464952 36#define ID_RIFF 0x46464952
36#define ID_WAVE 0x45564157 37#define ID_WAVE 0x45564157
@@ -153,6 +154,7 @@ int main(int argc, char **argv)
153 154
154 /* write header now all information is known */ 155 /* write header now all information is known */
155 header.data_sz = frames * header.block_align; 156 header.data_sz = frames * header.block_align;
157 header.riff_sz = header.data_sz + sizeof(header) - 8;
156 fseek(file, 0, SEEK_SET); 158 fseek(file, 0, SEEK_SET);
157 fwrite(&header, sizeof(struct wav_header), 1, file); 159 fwrite(&header, sizeof(struct wav_header), 1, file);
158 160
diff --git a/tinymix.c b/tinymix.c
index 6427a02..962450e 100644
--- a/tinymix.c
+++ b/tinymix.c
@@ -30,12 +30,13 @@
30#include <stdio.h> 30#include <stdio.h>
31#include <stdlib.h> 31#include <stdlib.h>
32#include <ctype.h> 32#include <ctype.h>
33#include <string.h>
33 34
34static void tinymix_list_controls(struct mixer *mixer); 35static void tinymix_list_controls(struct mixer *mixer);
35static void tinymix_detail_control(struct mixer *mixer, unsigned int id, 36static void tinymix_detail_control(struct mixer *mixer, const char *control,
36 int print_all); 37 int print_all);
37static void tinymix_set_value(struct mixer *mixer, unsigned int id, 38static void tinymix_set_value(struct mixer *mixer, const char *control,
38 char *value); 39 char **values, unsigned int num_values);
39static void tinymix_print_enum(struct mixer_ctl *ctl, int print_all); 40static void tinymix_print_enum(struct mixer_ctl *ctl, int print_all);
40 41
41int main(int argc, char **argv) 42int main(int argc, char **argv)
@@ -63,9 +64,9 @@ int main(int argc, char **argv)
63 if (argc == 1) 64 if (argc == 1)
64 tinymix_list_controls(mixer); 65 tinymix_list_controls(mixer);
65 else if (argc == 2) 66 else if (argc == 2)
66 tinymix_detail_control(mixer, atoi(argv[1]), 1); 67 tinymix_detail_control(mixer, argv[1], 1);
67 else if (argc == 3) 68 else if (argc >= 3)
68 tinymix_set_value(mixer, atoi(argv[1]), argv[2]); 69 tinymix_set_value(mixer, argv[1], &argv[2], argc - 2);
69 else 70 else
70 printf("Usage: tinymix [-D card] [control id] [value to set]\n"); 71 printf("Usage: tinymix [-D card] [control id] [value to set]\n");
71 72
@@ -93,7 +94,7 @@ static void tinymix_list_controls(struct mixer *mixer)
93 type = mixer_ctl_get_type_string(ctl); 94 type = mixer_ctl_get_type_string(ctl);
94 num_values = mixer_ctl_get_num_values(ctl); 95 num_values = mixer_ctl_get_num_values(ctl);
95 printf("%d\t%s\t%d\t%-40s", i, type, num_values, name); 96 printf("%d\t%s\t%d\t%-40s", i, type, num_values, name);
96 tinymix_detail_control(mixer, i, 0); 97 tinymix_detail_control(mixer, name, 0);
97 } 98 }
98} 99}
99 100
@@ -115,7 +116,7 @@ static void tinymix_print_enum(struct mixer_ctl *ctl, int print_all)
115 } 116 }
116} 117}
117 118
118static void tinymix_detail_control(struct mixer *mixer, unsigned int id, 119static void tinymix_detail_control(struct mixer *mixer, const char *control,
119 int print_all) 120 int print_all)
120{ 121{
121 struct mixer_ctl *ctl; 122 struct mixer_ctl *ctl;
@@ -124,13 +125,16 @@ static void tinymix_detail_control(struct mixer *mixer, unsigned int id,
124 unsigned int i; 125 unsigned int i;
125 int min, max; 126 int min, max;
126 127
127 if (id >= mixer_get_num_ctls(mixer)) { 128 if (isdigit(control[0]))
129 ctl = mixer_get_ctl(mixer, atoi(control));
130 else
131 ctl = mixer_get_ctl_by_name(mixer, control);
132
133 if (!ctl) {
128 fprintf(stderr, "Invalid mixer control\n"); 134 fprintf(stderr, "Invalid mixer control\n");
129 return; 135 return;
130 } 136 }
131 137
132 ctl = mixer_get_ctl(mixer, id);
133
134 type = mixer_ctl_get_type(ctl); 138 type = mixer_ctl_get_type(ctl);
135 num_values = mixer_ctl_get_num_values(ctl); 139 num_values = mixer_ctl_get_num_values(ctl);
136 140
@@ -168,30 +172,60 @@ static void tinymix_detail_control(struct mixer *mixer, unsigned int id,
168 printf("\n"); 172 printf("\n");
169} 173}
170 174
171static void tinymix_set_value(struct mixer *mixer, unsigned int id, 175static void tinymix_set_value(struct mixer *mixer, const char *control,
172 char *string) 176 char **values, unsigned int num_values)
173{ 177{
174 struct mixer_ctl *ctl; 178 struct mixer_ctl *ctl;
175 enum mixer_ctl_type type; 179 enum mixer_ctl_type type;
176 unsigned int num_values; 180 unsigned int num_ctl_values;
177 unsigned int i; 181 unsigned int i;
178 182
179 ctl = mixer_get_ctl(mixer, id); 183 if (isdigit(control[0]))
180 type = mixer_ctl_get_type(ctl); 184 ctl = mixer_get_ctl(mixer, atoi(control));
181 num_values = mixer_ctl_get_num_values(ctl); 185 else
186 ctl = mixer_get_ctl_by_name(mixer, control);
182 187
183 if (isdigit(string[0])) { 188 if (!ctl) {
184 int value = atoi(string); 189 fprintf(stderr, "Invalid mixer control\n");
190 return;
191 }
185 192
186 for (i = 0; i < num_values; i++) { 193 type = mixer_ctl_get_type(ctl);
187 if (mixer_ctl_set_value(ctl, i, value)) { 194 num_ctl_values = mixer_ctl_get_num_values(ctl);
188 fprintf(stderr, "Error: invalid value\n"); 195
196 if (isdigit(values[0][0])) {
197 if (num_values == 1) {
198 /* Set all values the same */
199 int value = atoi(values[0]);
200
201 for (i = 0; i < num_ctl_values; i++) {
202 if (mixer_ctl_set_value(ctl, i, value)) {
203 fprintf(stderr, "Error: invalid value\n");
204 return;
205 }
206 }
207 } else {
208 /* Set multiple values */
209 if (num_values > num_ctl_values) {
210 fprintf(stderr,
211 "Error: %d values given, but control only takes %d\n",
212 num_values, num_ctl_values);
189 return; 213 return;
190 } 214 }
215 for (i = 0; i < num_values; i++) {
216 if (mixer_ctl_set_value(ctl, i, atoi(values[i]))) {
217 fprintf(stderr, "Error: invalid value for index %d\n", i);
218 return;
219 }
220 }
191 } 221 }
192 } else { 222 } else {
193 if (type == MIXER_CTL_TYPE_ENUM) { 223 if (type == MIXER_CTL_TYPE_ENUM) {
194 if (mixer_ctl_set_enum_by_string(ctl, string)) 224 if (num_values != 1) {
225 fprintf(stderr, "Enclose strings in quotes and try again\n");
226 return;
227 }
228 if (mixer_ctl_set_enum_by_string(ctl, values[0]))
195 fprintf(stderr, "Error: invalid enum value\n"); 229 fprintf(stderr, "Error: invalid enum value\n");
196 } else { 230 } else {
197 fprintf(stderr, "Error: only enum types can be set with strings\n"); 231 fprintf(stderr, "Error: only enum types can be set with strings\n");
diff --git a/tinyplay.c b/tinyplay.c
index 3f76cc6..d7e7d46 100644
--- a/tinyplay.c
+++ b/tinyplay.c
@@ -30,6 +30,8 @@
30#include <stdio.h> 30#include <stdio.h>
31#include <stdlib.h> 31#include <stdlib.h>
32#include <stdint.h> 32#include <stdint.h>
33#include <string.h>
34#include <signal.h>
33 35
34#define ID_RIFF 0x46464952 36#define ID_RIFF 0x46464952
35#define ID_WAVE 0x45564157 37#define ID_WAVE 0x45564157
@@ -56,10 +58,19 @@ struct chunk_fmt {
56 uint16_t bits_per_sample; 58 uint16_t bits_per_sample;
57}; 59};
58 60
61static int close = 0;
62
59void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int channels, 63void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int channels,
60 unsigned int rate, unsigned int bits, unsigned int period_size, 64 unsigned int rate, unsigned int bits, unsigned int period_size,
61 unsigned int period_count); 65 unsigned int period_count);
62 66
67void stream_close(int sig)
68{
69 /* allow the stream to be closed gracefully */
70 signal(sig, SIG_IGN);
71 close = 1;
72}
73
63int main(int argc, char **argv) 74int main(int argc, char **argv)
64{ 75{
65 FILE *file; 76 FILE *file;
@@ -189,6 +200,9 @@ void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned in
189 200
190 printf("Playing sample: %u ch, %u hz, %u bit\n", channels, rate, bits); 201 printf("Playing sample: %u ch, %u hz, %u bit\n", channels, rate, bits);
191 202
203 /* catch ctrl-c to shutdown cleanly */
204 signal(SIGINT, stream_close);
205
192 do { 206 do {
193 num_read = fread(buffer, 1, size, file); 207 num_read = fread(buffer, 1, size, file);
194 if (num_read > 0) { 208 if (num_read > 0) {
@@ -197,7 +211,7 @@ void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned in
197 break; 211 break;
198 } 212 }
199 } 213 }
200 } while (num_read > 0); 214 } while (!close && num_read > 0);
201 215
202 free(buffer); 216 free(buffer);
203 pcm_close(pcm); 217 pcm_close(pcm);