aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/tinyalsa/asoundlib.h4
-rw-r--r--pcm.c16
-rw-r--r--tinycap.c53
-rw-r--r--tinymix.c16
-rw-r--r--tinyplay.c49
5 files changed, 96 insertions, 42 deletions
diff --git a/include/tinyalsa/asoundlib.h b/include/tinyalsa/asoundlib.h
index 92a004c..655fe76 100644
--- a/include/tinyalsa/asoundlib.h
+++ b/include/tinyalsa/asoundlib.h
@@ -139,13 +139,13 @@ int pcm_get_htimestamp(struct pcm *pcm, unsigned int *avail,
139 * Will start playback on the first write or on a write that 139 * Will start playback on the first write or on a write that
140 * occurs after a fifo underrun. 140 * occurs after a fifo underrun.
141 */ 141 */
142int pcm_write(struct pcm *pcm, void *data, unsigned int count); 142int pcm_write(struct pcm *pcm, const void *data, unsigned int count);
143int pcm_read(struct pcm *pcm, void *data, unsigned int count); 143int pcm_read(struct pcm *pcm, void *data, unsigned int count);
144 144
145/* 145/*
146 * mmap() support. 146 * mmap() support.
147 */ 147 */
148int pcm_mmap_write(struct pcm *pcm, void *data, unsigned int count); 148int pcm_mmap_write(struct pcm *pcm, const void *data, unsigned int count);
149int pcm_mmap_begin(struct pcm *pcm, void **areas, unsigned int *offset, 149int pcm_mmap_begin(struct pcm *pcm, void **areas, unsigned int *offset,
150 unsigned int *frames); 150 unsigned int *frames);
151int pcm_mmap_commit(struct pcm *pcm, unsigned int offset, unsigned int frames); 151int pcm_mmap_commit(struct pcm *pcm, unsigned int offset, unsigned int frames);
diff --git a/pcm.c b/pcm.c
index 9324f38..f0dbcc5 100644
--- a/pcm.c
+++ b/pcm.c
@@ -303,7 +303,7 @@ static int pcm_areas_copy(struct pcm *pcm, unsigned int pcm_offset,
303 return 0; 303 return 0;
304} 304}
305 305
306static int pcm_mmap_write_areas(struct pcm *pcm, char *src, 306static int pcm_mmap_write_areas(struct pcm *pcm, const char *src,
307 unsigned int offset, unsigned int size) 307 unsigned int offset, unsigned int size)
308{ 308{
309 void *pcm_areas; 309 void *pcm_areas;
@@ -365,14 +365,14 @@ int pcm_get_htimestamp(struct pcm *pcm, unsigned int *avail,
365 return 0; 365 return 0;
366} 366}
367 367
368int pcm_write(struct pcm *pcm, void *data, unsigned int count) 368int pcm_write(struct pcm *pcm, const void *data, unsigned int count)
369{ 369{
370 struct snd_xferi x; 370 struct snd_xferi x;
371 371
372 if (pcm->flags & PCM_IN) 372 if (pcm->flags & PCM_IN)
373 return -EINVAL; 373 return -EINVAL;
374 374
375 x.buf = data; 375 x.buf = (void*)data;
376 x.frames = count / (pcm->config.channels * 376 x.frames = count / (pcm->config.channels *
377 pcm_format_to_bits(pcm->config.format) / 8); 377 pcm_format_to_bits(pcm->config.format) / 8);
378 378
@@ -411,11 +411,7 @@ int pcm_read(struct pcm *pcm, void *data, unsigned int count)
411 411
412 for (;;) { 412 for (;;) {
413 if (!pcm->running) { 413 if (!pcm->running) {
414 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_PREPARE)) 414 pcm_start(pcm);
415 return oops(pcm, errno, "cannot prepare channel");
416 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_START))
417 return oops(pcm, errno, "cannot start channel");
418 pcm->running = 1;
419 } 415 }
420 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_READI_FRAMES, &x)) { 416 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_READI_FRAMES, &x)) {
421 pcm->running = 0; 417 pcm->running = 0;
@@ -575,7 +571,7 @@ struct pcm *pcm_open(unsigned int card, unsigned int device,
575 sparams.silence_threshold = config->silence_threshold; 571 sparams.silence_threshold = config->silence_threshold;
576 pcm->boundary = sparams.boundary = pcm->buffer_size; 572 pcm->boundary = sparams.boundary = pcm->buffer_size;
577 573
578 while (pcm->boundary * 2 <= LONG_MAX - pcm->buffer_size) 574 while (pcm->boundary * 2 <= INT_MAX - pcm->buffer_size)
579 pcm->boundary *= 2; 575 pcm->boundary *= 2;
580 576
581 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_SW_PARAMS, &sparams)) { 577 if (ioctl(pcm->fd, SNDRV_PCM_IOCTL_SW_PARAMS, &sparams)) {
@@ -774,7 +770,7 @@ int pcm_wait(struct pcm *pcm, int timeout)
774 return 1; 770 return 1;
775} 771}
776 772
777int pcm_mmap_write(struct pcm *pcm, void *buffer, unsigned int bytes) 773int pcm_mmap_write(struct pcm *pcm, const void *buffer, unsigned int bytes)
778{ 774{
779 int err = 0, frames, avail; 775 int err = 0, frames, avail;
780 unsigned int offset = 0, count; 776 unsigned int offset = 0, count;
diff --git a/tinycap.c b/tinycap.c
index 3eb5c60..a50c417 100644
--- a/tinycap.c
+++ b/tinycap.c
@@ -57,9 +57,10 @@ struct wav_header {
57 57
58int capturing = 1; 58int capturing = 1;
59 59
60unsigned int capture_sample(FILE *file, unsigned int device, 60unsigned int capture_sample(FILE *file, unsigned int card, unsigned int device,
61 unsigned int channels, unsigned int rate, 61 unsigned int channels, unsigned int rate,
62 unsigned int bits); 62 unsigned int bits, unsigned int period_size,
63 unsigned int period_count);
63 64
64void sigint_handler(int sig) 65void sigint_handler(int sig)
65{ 66{
@@ -70,14 +71,17 @@ int main(int argc, char **argv)
70{ 71{
71 FILE *file; 72 FILE *file;
72 struct wav_header header; 73 struct wav_header header;
74 unsigned int card = 0;
73 unsigned int device = 0; 75 unsigned int device = 0;
74 unsigned int channels = 2; 76 unsigned int channels = 2;
75 unsigned int rate = 44100; 77 unsigned int rate = 44100;
76 unsigned int bits = 16; 78 unsigned int bits = 16;
77 unsigned int frames; 79 unsigned int frames;
80 unsigned int period_size = 1024;
81 unsigned int period_count = 4;
78 82
79 if (argc < 2) { 83 if (argc < 2) {
80 fprintf(stderr, "Usage: %s file.wav [-d device] [-c channels] " 84 fprintf(stderr, "Usage: %s file.wav [-D card] [-d device] [-c channels] "
81 "[-r rate] [-b bits]\n", argv[0]); 85 "[-r rate] [-b bits]\n", argv[0]);
82 return 1; 86 return 1;
83 } 87 }
@@ -93,18 +97,35 @@ int main(int argc, char **argv)
93 while (*argv) { 97 while (*argv) {
94 if (strcmp(*argv, "-d") == 0) { 98 if (strcmp(*argv, "-d") == 0) {
95 argv++; 99 argv++;
96 device = atoi(*argv); 100 if (*argv)
101 device = atoi(*argv);
97 } else if (strcmp(*argv, "-c") == 0) { 102 } else if (strcmp(*argv, "-c") == 0) {
98 argv++; 103 argv++;
99 channels = atoi(*argv); 104 if (*argv)
105 channels = atoi(*argv);
100 } else if (strcmp(*argv, "-r") == 0) { 106 } else if (strcmp(*argv, "-r") == 0) {
101 argv++; 107 argv++;
102 rate = atoi(*argv); 108 if (*argv)
109 rate = atoi(*argv);
103 } else if (strcmp(*argv, "-b") == 0) { 110 } else if (strcmp(*argv, "-b") == 0) {
104 argv++; 111 argv++;
105 bits = atoi(*argv); 112 if (*argv)
113 bits = atoi(*argv);
114 } else if (strcmp(*argv, "-D") == 0) {
115 argv++;
116 if (*argv)
117 card = atoi(*argv);
118 } else if (strcmp(*argv, "-p") == 0) {
119 argv++;
120 if (*argv)
121 period_size = atoi(*argv);
122 } else if (strcmp(*argv, "-n") == 0) {
123 argv++;
124 if (*argv)
125 period_count = atoi(*argv);
106 } 126 }
107 argv++; 127 if (*argv)
128 argv++;
108 } 129 }
109 130
110 header.riff_id = ID_RIFF; 131 header.riff_id = ID_RIFF;
@@ -125,8 +146,9 @@ int main(int argc, char **argv)
125 146
126 /* install signal handler and begin capturing */ 147 /* install signal handler and begin capturing */
127 signal(SIGINT, sigint_handler); 148 signal(SIGINT, sigint_handler);
128 frames = capture_sample(file, device, header.num_channels, 149 frames = capture_sample(file, card, device, header.num_channels,
129 header.sample_rate, header.bits_per_sample); 150 header.sample_rate, header.bits_per_sample,
151 period_size, period_count);
130 printf("Captured %d frames\n", frames); 152 printf("Captured %d frames\n", frames);
131 153
132 /* write header now all information is known */ 154 /* write header now all information is known */
@@ -139,9 +161,10 @@ int main(int argc, char **argv)
139 return 0; 161 return 0;
140} 162}
141 163
142unsigned int capture_sample(FILE *file, unsigned int device, 164unsigned int capture_sample(FILE *file, unsigned int card, unsigned int device,
143 unsigned int channels, unsigned int rate, 165 unsigned int channels, unsigned int rate,
144 unsigned int bits) 166 unsigned int bits, unsigned int period_size,
167 unsigned int period_count)
145{ 168{
146 struct pcm_config config; 169 struct pcm_config config;
147 struct pcm *pcm; 170 struct pcm *pcm;
@@ -151,8 +174,8 @@ unsigned int capture_sample(FILE *file, unsigned int device,
151 174
152 config.channels = channels; 175 config.channels = channels;
153 config.rate = rate; 176 config.rate = rate;
154 config.period_size = 1024; 177 config.period_size = period_size;
155 config.period_count = 4; 178 config.period_count = period_count;
156 if (bits == 32) 179 if (bits == 32)
157 config.format = PCM_FORMAT_S32_LE; 180 config.format = PCM_FORMAT_S32_LE;
158 else if (bits == 16) 181 else if (bits == 16)
@@ -161,7 +184,7 @@ unsigned int capture_sample(FILE *file, unsigned int device,
161 config.stop_threshold = 0; 184 config.stop_threshold = 0;
162 config.silence_threshold = 0; 185 config.silence_threshold = 0;
163 186
164 pcm = pcm_open(0, device, PCM_IN, &config); 187 pcm = pcm_open(card, device, PCM_IN, &config);
165 if (!pcm || !pcm_is_ready(pcm)) { 188 if (!pcm || !pcm_is_ready(pcm)) {
166 fprintf(stderr, "Unable to open PCM device (%s)\n", 189 fprintf(stderr, "Unable to open PCM device (%s)\n",
167 pcm_get_error(pcm)); 190 pcm_get_error(pcm));
diff --git a/tinymix.c b/tinymix.c
index b9c71a4..e7bd276 100644
--- a/tinymix.c
+++ b/tinymix.c
@@ -41,8 +41,20 @@ static void tinymix_print_enum(struct mixer_ctl *ctl, int print_all);
41int main(int argc, char **argv) 41int main(int argc, char **argv)
42{ 42{
43 struct mixer *mixer; 43 struct mixer *mixer;
44 int card = 0;
45
46 if ((argc > 2) && (strcmp(argv[1], "-D") == 0)) {
47 argv++;
48 if (argv[1]) {
49 card = atoi(argv[1]);
50 argv++;
51 argc -= 2;
52 } else {
53 argc -= 1;
54 }
55 }
44 56
45 mixer = mixer_open(0); 57 mixer = mixer_open(card);
46 if (!mixer) { 58 if (!mixer) {
47 fprintf(stderr, "Failed to open mixer\n"); 59 fprintf(stderr, "Failed to open mixer\n");
48 return EXIT_FAILURE; 60 return EXIT_FAILURE;
@@ -55,7 +67,7 @@ int main(int argc, char **argv)
55 else if (argc == 3) 67 else if (argc == 3)
56 tinymix_set_value(mixer, atoi(argv[1]), argv[2]); 68 tinymix_set_value(mixer, atoi(argv[1]), argv[2]);
57 else 69 else
58 printf("Usage: tinymix [control id] [value to set]\n"); 70 printf("Usage: tinymix [-D card] [control id] [value to set]\n");
59 71
60 mixer_close(mixer); 72 mixer_close(mixer);
61 73
diff --git a/tinyplay.c b/tinyplay.c
index 915a1ea..4d257e7 100644
--- a/tinyplay.c
+++ b/tinyplay.c
@@ -54,17 +54,22 @@ struct wav_header {
54 uint32_t data_sz; 54 uint32_t data_sz;
55}; 55};
56 56
57void play_sample(FILE *file, unsigned int device, unsigned int channels, 57void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int channels,
58 unsigned int rate, unsigned int bits); 58 unsigned int rate, unsigned int bits, unsigned int period_size,
59 unsigned int period_count);
59 60
60int main(int argc, char **argv) 61int main(int argc, char **argv)
61{ 62{
62 FILE *file; 63 FILE *file;
63 struct wav_header header; 64 struct wav_header header;
64 unsigned int device = 0; 65 unsigned int device = 0;
66 unsigned int card = 0;
67 unsigned int period_size = 1024;
68 unsigned int period_count = 4;
65 69
66 if (argc < 2) { 70 if (argc < 2) {
67 fprintf(stderr, "Usage: %s file.wav [-d device]\n", argv[0]); 71 fprintf(stderr, "Usage: %s file.wav [-D card] [-d device] [-p period_size]"
72 " [-n n_periods] \n", argv[0]);
68 return 1; 73 return 1;
69 } 74 }
70 75
@@ -79,9 +84,26 @@ int main(int argc, char **argv)
79 while (*argv) { 84 while (*argv) {
80 if (strcmp(*argv, "-d") == 0) { 85 if (strcmp(*argv, "-d") == 0) {
81 argv++; 86 argv++;
82 device = atoi(*argv); 87 if (*argv)
88 device = atoi(*argv);
83 } 89 }
84 argv++; 90 if (strcmp(*argv, "-p") == 0) {
91 argv++;
92 if (*argv)
93 period_size = atoi(*argv);
94 }
95 if (strcmp(*argv, "-n") == 0) {
96 argv++;
97 if (*argv)
98 period_count = atoi(*argv);
99 }
100 if (strcmp(*argv, "-D") == 0) {
101 argv++;
102 if (*argv)
103 card = atoi(*argv);
104 }
105 if (*argv)
106 argv++;
85 } 107 }
86 108
87 fread(&header, sizeof(struct wav_header), 1, file); 109 fread(&header, sizeof(struct wav_header), 1, file);
@@ -96,16 +118,17 @@ int main(int argc, char **argv)
96 return 1; 118 return 1;
97 } 119 }
98 120
99 play_sample(file, device, header.num_channels, header.sample_rate, 121 play_sample(file, card, device, header.num_channels, header.sample_rate,
100 header.bits_per_sample); 122 header.bits_per_sample, period_size, period_count);
101 123
102 fclose(file); 124 fclose(file);
103 125
104 return 0; 126 return 0;
105} 127}
106 128
107void play_sample(FILE *file, unsigned int device, unsigned int channels, 129void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int channels,
108 unsigned int rate, unsigned int bits) 130 unsigned int rate, unsigned int bits, unsigned int period_size,
131 unsigned int period_count)
109{ 132{
110 struct pcm_config config; 133 struct pcm_config config;
111 struct pcm *pcm; 134 struct pcm *pcm;
@@ -115,8 +138,8 @@ void play_sample(FILE *file, unsigned int device, unsigned int channels,
115 138
116 config.channels = channels; 139 config.channels = channels;
117 config.rate = rate; 140 config.rate = rate;
118 config.period_size = 1024; 141 config.period_size = period_size;
119 config.period_count = 4; 142 config.period_count = period_count;
120 if (bits == 32) 143 if (bits == 32)
121 config.format = PCM_FORMAT_S32_LE; 144 config.format = PCM_FORMAT_S32_LE;
122 else if (bits == 16) 145 else if (bits == 16)
@@ -125,14 +148,14 @@ void play_sample(FILE *file, unsigned int device, unsigned int channels,
125 config.stop_threshold = 0; 148 config.stop_threshold = 0;
126 config.silence_threshold = 0; 149 config.silence_threshold = 0;
127 150
128 pcm = pcm_open(0, device, PCM_OUT, &config); 151 pcm = pcm_open(card, device, PCM_OUT, &config);
129 if (!pcm || !pcm_is_ready(pcm)) { 152 if (!pcm || !pcm_is_ready(pcm)) {
130 fprintf(stderr, "Unable to open PCM device %u (%s)\n", 153 fprintf(stderr, "Unable to open PCM device %u (%s)\n",
131 device, pcm_get_error(pcm)); 154 device, pcm_get_error(pcm));
132 return; 155 return;
133 } 156 }
134 157
135 size = pcm_get_buffer_size(pcm); 158 size = pcm_frames_to_bytes(pcm, pcm_get_buffer_size(pcm));
136 buffer = malloc(size); 159 buffer = malloc(size);
137 if (!buffer) { 160 if (!buffer) {
138 fprintf(stderr, "Unable to allocate %d bytes\n", size); 161 fprintf(stderr, "Unable to allocate %d bytes\n", size);