aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Wilson <simonwilson@google.com>2012-11-09 15:16:47 -0800
committerSimon Wilson <simonwilson@google.com>2012-11-09 15:22:36 -0800
commitda39e0b09eb0a1b559a96e2108160d1d8dccf314 (patch)
tree81e2afcb7d8abcbe0829366d5c46b9d7fdeb2300
parentff2e54293f32b5bb5ff75b4cb25babb00f429ca4 (diff)
downloadandroid_external_tinyalsa-da39e0b09eb0a1b559a96e2108160d1d8dccf314.tar.gz
android_external_tinyalsa-da39e0b09eb0a1b559a96e2108160d1d8dccf314.tar.bz2
android_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 @@
#define ASOUNDLIB_H
#include <sys/time.h>
+#include <stddef.h>
#if defined(__cplusplus)
extern "C" {
@@ -70,6 +71,8 @@ struct pcm;
enum pcm_format {
PCM_FORMAT_S16_LE = 0,
PCM_FORMAT_S32_LE,
+ PCM_FORMAT_S8,
+ PCM_FORMAT_S24_LE,
PCM_FORMAT_MAX,
};
@@ -163,6 +166,9 @@ int pcm_mmap_commit(struct pcm *pcm, unsigned int offset, unsigned int frames);
int pcm_start(struct pcm *pcm);
int pcm_stop(struct pcm *pcm);
+/* Interrupt driven API */
+int pcm_wait(struct pcm *pcm, int timeout);
+
/* Change avail_min after the stream has been opened with no need to stop the stream.
* Only accepted if opened with PCM_MMAP and PCM_NOIRQ flags
*/
@@ -198,7 +204,9 @@ int mixer_ctl_get_percent(struct mixer_ctl *ctl, unsigned int id);
int mixer_ctl_set_percent(struct mixer_ctl *ctl, unsigned int id, int percent);
int mixer_ctl_get_value(struct mixer_ctl *ctl, unsigned int id);
+int mixer_ctl_get_bytes(struct mixer_ctl *ctl, void *data, size_t len);
int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value);
+int mixer_ctl_set_bytes(struct mixer_ctl *ctl, const void *data, size_t len);
int mixer_ctl_set_enum_by_string(struct mixer_ctl *ctl, const char *string);
/* 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)
return 0;
}
+int mixer_ctl_get_bytes(struct mixer_ctl *ctl, void *data, size_t len)
+{
+ struct snd_ctl_elem_value ev;
+ int ret;
+
+ if (!ctl || (len > ctl->info->count) || !len || !data ||
+ (ctl->info->type != SNDRV_CTL_ELEM_TYPE_BYTES))
+ return -EINVAL;
+
+ memset(&ev, 0, sizeof(ev));
+ ev.id.numid = ctl->info->id.numid;
+
+ ret = ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_READ, &ev);
+ if (ret < 0)
+ return ret;
+
+ memcpy(data, ev.value.bytes.data, len);
+
+ return 0;
+}
+
int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value)
{
struct snd_ctl_elem_value ev;
@@ -351,10 +372,24 @@ int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value)
return ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev);
}
-int mixer_ctl_get_range_min(struct mixer_ctl *ctl)
+int mixer_ctl_set_bytes(struct mixer_ctl *ctl, const void *data, size_t len)
{
- int ret;
+ struct snd_ctl_elem_value ev;
+ if (!ctl || (len > ctl->info->count) || !len || !data ||
+ (ctl->info->type != SNDRV_CTL_ELEM_TYPE_BYTES))
+ return -EINVAL;
+
+ memset(&ev, 0, sizeof(ev));
+ ev.id.numid = ctl->info->id.numid;
+
+ memcpy(ev.value.bytes.data, data, len);
+
+ return ioctl(ctl->mixer->fd, SNDRV_CTL_IOCTL_ELEM_WRITE, &ev);
+}
+
+int mixer_ctl_get_range_min(struct mixer_ctl *ctl)
+{
if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER))
return -EINVAL;
@@ -363,8 +398,6 @@ int mixer_ctl_get_range_min(struct mixer_ctl *ctl)
int mixer_ctl_get_range_max(struct mixer_ctl *ctl)
{
- int ret;
-
if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_INTEGER))
return -EINVAL;
@@ -382,8 +415,6 @@ unsigned int mixer_ctl_get_num_enums(struct mixer_ctl *ctl)
const char *mixer_ctl_get_enum_string(struct mixer_ctl *ctl,
unsigned int enum_id)
{
- int ret;
-
if (!ctl || (ctl->info->type != SNDRV_CTL_ELEM_TYPE_ENUMERATED) ||
(enum_id >= ctl->info->value.enumerated.items))
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)
}
}
-static void param_set_max(struct snd_pcm_hw_params *p, int n, unsigned int val)
-{
- if (param_is_interval(n)) {
- struct snd_interval *i = param_to_interval(p, n);
- i->max = val;
- }
-}
-
static void param_set_int(struct snd_pcm_hw_params *p, int n, unsigned int val)
{
if (param_is_interval(n)) {
@@ -190,6 +182,10 @@ static unsigned int pcm_format_to_alsa(enum pcm_format format)
switch (format) {
case PCM_FORMAT_S32_LE:
return SNDRV_PCM_FORMAT_S32_LE;
+ case PCM_FORMAT_S8:
+ return SNDRV_PCM_FORMAT_S8;
+ case PCM_FORMAT_S24_LE:
+ return SNDRV_PCM_FORMAT_S24_LE;
default:
case PCM_FORMAT_S16_LE:
return SNDRV_PCM_FORMAT_S16_LE;
@@ -741,7 +737,6 @@ int pcm_set_avail_min(struct pcm *pcm, int avail_min)
int pcm_wait(struct pcm *pcm, int timeout)
{
struct pollfd pfd;
- unsigned short revents = 0;
int err;
pfd.fd = pcm->fd;
@@ -864,6 +859,5 @@ int pcm_mmap_write(struct pcm *pcm, const void *buffer, unsigned int bytes)
count -= frames;
}
-_end:
return 0;
}
diff --git a/tinycap.c b/tinycap.c
index d563309..8c9fcfb 100644
--- a/tinycap.c
+++ b/tinycap.c
@@ -31,6 +31,7 @@
#include <stdlib.h>
#include <stdint.h>
#include <signal.h>
+#include <string.h>
#define ID_RIFF 0x46464952
#define ID_WAVE 0x45564157
@@ -153,6 +154,7 @@ int main(int argc, char **argv)
/* write header now all information is known */
header.data_sz = frames * header.block_align;
+ header.riff_sz = header.data_sz + sizeof(header) - 8;
fseek(file, 0, SEEK_SET);
fwrite(&header, sizeof(struct wav_header), 1, file);
diff --git a/tinymix.c b/tinymix.c
index 6427a02..962450e 100644
--- a/tinymix.c
+++ b/tinymix.c
@@ -30,12 +30,13 @@
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
+#include <string.h>
static void tinymix_list_controls(struct mixer *mixer);
-static void tinymix_detail_control(struct mixer *mixer, unsigned int id,
+static void tinymix_detail_control(struct mixer *mixer, const char *control,
int print_all);
-static void tinymix_set_value(struct mixer *mixer, unsigned int id,
- char *value);
+static void tinymix_set_value(struct mixer *mixer, const char *control,
+ char **values, unsigned int num_values);
static void tinymix_print_enum(struct mixer_ctl *ctl, int print_all);
int main(int argc, char **argv)
@@ -63,9 +64,9 @@ int main(int argc, char **argv)
if (argc == 1)
tinymix_list_controls(mixer);
else if (argc == 2)
- tinymix_detail_control(mixer, atoi(argv[1]), 1);
- else if (argc == 3)
- tinymix_set_value(mixer, atoi(argv[1]), argv[2]);
+ tinymix_detail_control(mixer, argv[1], 1);
+ else if (argc >= 3)
+ tinymix_set_value(mixer, argv[1], &argv[2], argc - 2);
else
printf("Usage: tinymix [-D card] [control id] [value to set]\n");
@@ -93,7 +94,7 @@ static void tinymix_list_controls(struct mixer *mixer)
type = mixer_ctl_get_type_string(ctl);
num_values = mixer_ctl_get_num_values(ctl);
printf("%d\t%s\t%d\t%-40s", i, type, num_values, name);
- tinymix_detail_control(mixer, i, 0);
+ tinymix_detail_control(mixer, name, 0);
}
}
@@ -115,7 +116,7 @@ static void tinymix_print_enum(struct mixer_ctl *ctl, int print_all)
}
}
-static void tinymix_detail_control(struct mixer *mixer, unsigned int id,
+static void tinymix_detail_control(struct mixer *mixer, const char *control,
int print_all)
{
struct mixer_ctl *ctl;
@@ -124,13 +125,16 @@ static void tinymix_detail_control(struct mixer *mixer, unsigned int id,
unsigned int i;
int min, max;
- if (id >= mixer_get_num_ctls(mixer)) {
+ if (isdigit(control[0]))
+ ctl = mixer_get_ctl(mixer, atoi(control));
+ else
+ ctl = mixer_get_ctl_by_name(mixer, control);
+
+ if (!ctl) {
fprintf(stderr, "Invalid mixer control\n");
return;
}
- ctl = mixer_get_ctl(mixer, id);
-
type = mixer_ctl_get_type(ctl);
num_values = mixer_ctl_get_num_values(ctl);
@@ -168,30 +172,60 @@ static void tinymix_detail_control(struct mixer *mixer, unsigned int id,
printf("\n");
}
-static void tinymix_set_value(struct mixer *mixer, unsigned int id,
- char *string)
+static void tinymix_set_value(struct mixer *mixer, const char *control,
+ char **values, unsigned int num_values)
{
struct mixer_ctl *ctl;
enum mixer_ctl_type type;
- unsigned int num_values;
+ unsigned int num_ctl_values;
unsigned int i;
- ctl = mixer_get_ctl(mixer, id);
- type = mixer_ctl_get_type(ctl);
- num_values = mixer_ctl_get_num_values(ctl);
+ if (isdigit(control[0]))
+ ctl = mixer_get_ctl(mixer, atoi(control));
+ else
+ ctl = mixer_get_ctl_by_name(mixer, control);
- if (isdigit(string[0])) {
- int value = atoi(string);
+ if (!ctl) {
+ fprintf(stderr, "Invalid mixer control\n");
+ return;
+ }
- for (i = 0; i < num_values; i++) {
- if (mixer_ctl_set_value(ctl, i, value)) {
- fprintf(stderr, "Error: invalid value\n");
+ type = mixer_ctl_get_type(ctl);
+ num_ctl_values = mixer_ctl_get_num_values(ctl);
+
+ if (isdigit(values[0][0])) {
+ if (num_values == 1) {
+ /* Set all values the same */
+ int value = atoi(values[0]);
+
+ for (i = 0; i < num_ctl_values; i++) {
+ if (mixer_ctl_set_value(ctl, i, value)) {
+ fprintf(stderr, "Error: invalid value\n");
+ return;
+ }
+ }
+ } else {
+ /* Set multiple values */
+ if (num_values > num_ctl_values) {
+ fprintf(stderr,
+ "Error: %d values given, but control only takes %d\n",
+ num_values, num_ctl_values);
return;
}
+ for (i = 0; i < num_values; i++) {
+ if (mixer_ctl_set_value(ctl, i, atoi(values[i]))) {
+ fprintf(stderr, "Error: invalid value for index %d\n", i);
+ return;
+ }
+ }
}
} else {
if (type == MIXER_CTL_TYPE_ENUM) {
- if (mixer_ctl_set_enum_by_string(ctl, string))
+ if (num_values != 1) {
+ fprintf(stderr, "Enclose strings in quotes and try again\n");
+ return;
+ }
+ if (mixer_ctl_set_enum_by_string(ctl, values[0]))
fprintf(stderr, "Error: invalid enum value\n");
} else {
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 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
+#include <string.h>
+#include <signal.h>
#define ID_RIFF 0x46464952
#define ID_WAVE 0x45564157
@@ -56,10 +58,19 @@ struct chunk_fmt {
uint16_t bits_per_sample;
};
+static int close = 0;
+
void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned int channels,
unsigned int rate, unsigned int bits, unsigned int period_size,
unsigned int period_count);
+void stream_close(int sig)
+{
+ /* allow the stream to be closed gracefully */
+ signal(sig, SIG_IGN);
+ close = 1;
+}
+
int main(int argc, char **argv)
{
FILE *file;
@@ -189,6 +200,9 @@ void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned in
printf("Playing sample: %u ch, %u hz, %u bit\n", channels, rate, bits);
+ /* catch ctrl-c to shutdown cleanly */
+ signal(SIGINT, stream_close);
+
do {
num_read = fread(buffer, 1, size, file);
if (num_read > 0) {
@@ -197,7 +211,7 @@ void play_sample(FILE *file, unsigned int card, unsigned int device, unsigned in
break;
}
}
- } while (num_read > 0);
+ } while (!close && num_read > 0);
free(buffer);
pcm_close(pcm);