aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTaylor Holberton <taylorcholberton@gmail.com>2016-12-01 21:39:53 -0800
committerTaylor Holberton <taylorcholberton@gmail.com>2016-12-01 21:39:53 -0800
commit053a009cab9ad0e440e511a1546e9cba415565d7 (patch)
tree8c9ee73c50c8eaba24c87389e0eb7d1754f492c8
parentf42051ce4de1a3b2655c2cab778338fe66ee9580 (diff)
parent6860acb720fcc5d67639b72aa349b16e1fc6acc6 (diff)
Merge branch 'develop'
This merges all the changes for the 1.1.0 release to the master branch.
-rw-r--r--debian/changelog14
-rw-r--r--doxygen/Doxyfile2
-rw-r--r--include/tinyalsa/mixer.h30
-rw-r--r--include/tinyalsa/pcm.h42
-rw-r--r--include/tinyalsa/version.h8
-rw-r--r--src/Makefile19
-rw-r--r--src/mixer.c70
-rw-r--r--src/pcm.c152
-rw-r--r--utils/tinycap.c2
-rw-r--r--utils/tinypcminfo.c2
-rw-r--r--utils/tinyplay.c2
11 files changed, 252 insertions, 91 deletions
diff --git a/debian/changelog b/debian/changelog
index 851ac70..8a47e9a 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,17 @@
+tinyalsa (1.1.0) xenial; urgency=medium
+
+ * Finished most of the PCM and mixer API documentation
+ * Added const specifiers where necessary
+ * Added pcm_readi() and pcm_writei()
+ * Deprecated pcm_read() and pcm_write()
+ * Added mixer_get_num_ctls_by_name()
+ * Added pcm_get_channels(), pcm_get_rate() and pcm_get_format()
+ * Made libtinyalsa.so.x a symbol link, using libtinyalsa.so.x.y.z as library name
+ * Added long option names in tinyplay
+ * Using amixer-style interface for tinymix
+
+ -- Taylor Holberton <taylorcholberton@gmail.com> Thu, 01 Dec 2016 21:38:12 -0800
+
tinyalsa (1.0.2) xenial; urgency=medium
* Removed install of libtinyalsa.so in package libtinyalsa
diff --git a/doxygen/Doxyfile b/doxygen/Doxyfile
index 6a3a2d2..1c18b30 100644
--- a/doxygen/Doxyfile
+++ b/doxygen/Doxyfile
@@ -38,7 +38,7 @@ PROJECT_NAME = "TinyALSA"
# could be handy for archiving the generated documentation or if some version
# control system is used.
-PROJECT_NUMBER = 1.0.0
+PROJECT_NUMBER = 1.1.0
# Using the PROJECT_BRIEF tag one can provide an optional one line description
# for a project that appears at the top of each page and should give viewer a
diff --git a/include/tinyalsa/mixer.h b/include/tinyalsa/mixer.h
index 4de6133..f743f6e 100644
--- a/include/tinyalsa/mixer.h
+++ b/include/tinyalsa/mixer.h
@@ -69,9 +69,13 @@ struct mixer *mixer_open(unsigned int card);
void mixer_close(struct mixer *mixer);
-const char *mixer_get_name(struct mixer *mixer);
+const char *mixer_get_name(const struct mixer *mixer);
-unsigned int mixer_get_num_ctls(struct mixer *mixer);
+unsigned int mixer_get_num_ctls(const struct mixer *mixer);
+
+unsigned int mixer_get_num_ctls_by_name(const struct mixer *mixer, const char *name);
+
+const struct mixer_ctl *mixer_get_ctl_const(const struct mixer *mixer, unsigned int id);
struct mixer_ctl *mixer_get_ctl(struct mixer *mixer, unsigned int id);
@@ -81,17 +85,17 @@ struct mixer_ctl *mixer_get_ctl_by_name_and_index(struct mixer *mixer,
const char *name,
unsigned int index);
-unsigned int mixer_ctl_get_id(struct mixer_ctl *ctl);
+unsigned int mixer_ctl_get_id(const struct mixer_ctl *ctl);
-const char *mixer_ctl_get_name(struct mixer_ctl *ctl);
+const char *mixer_ctl_get_name(const struct mixer_ctl *ctl);
-enum mixer_ctl_type mixer_ctl_get_type(struct mixer_ctl *ctl);
+enum mixer_ctl_type mixer_ctl_get_type(const struct mixer_ctl *ctl);
-const char *mixer_ctl_get_type_string(struct mixer_ctl *ctl);
+const char *mixer_ctl_get_type_string(const struct mixer_ctl *ctl);
-unsigned int mixer_ctl_get_num_values(struct mixer_ctl *ctl);
+unsigned int mixer_ctl_get_num_values(const struct mixer_ctl *ctl);
-unsigned int mixer_ctl_get_num_enums(struct mixer_ctl *ctl);
+unsigned int mixer_ctl_get_num_enums(const struct mixer_ctl *ctl);
const char *mixer_ctl_get_enum_string(struct mixer_ctl *ctl, unsigned int enum_id);
@@ -102,13 +106,13 @@ const char *mixer_ctl_get_enum_string(struct mixer_ctl *ctl, unsigned int enum_i
void mixer_ctl_update(struct mixer_ctl *ctl);
/* Set and get mixer controls */
-int mixer_ctl_get_percent(struct mixer_ctl *ctl, unsigned int id);
+int mixer_ctl_get_percent(const 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_value(const struct mixer_ctl *ctl, unsigned int id);
-int mixer_ctl_get_array(struct mixer_ctl *ctl, void *array, size_t count);
+int mixer_ctl_get_array(const struct mixer_ctl *ctl, void *array, size_t count);
int mixer_ctl_set_value(struct mixer_ctl *ctl, unsigned int id, int value);
@@ -117,9 +121,9 @@ int mixer_ctl_set_array(struct mixer_ctl *ctl, const void *array, size_t count);
int mixer_ctl_set_enum_by_string(struct mixer_ctl *ctl, const char *string);
/* Determe range of integer mixer controls */
-int mixer_ctl_get_range_min(struct mixer_ctl *ctl);
+int mixer_ctl_get_range_min(const struct mixer_ctl *ctl);
-int mixer_ctl_get_range_max(struct mixer_ctl *ctl);
+int mixer_ctl_get_range_max(const struct mixer_ctl *ctl);
#if defined(__cplusplus)
} /* extern "C" */
diff --git a/include/tinyalsa/pcm.h b/include/tinyalsa/pcm.h
index 3d9dfaa..1d84eed 100644
--- a/include/tinyalsa/pcm.h
+++ b/include/tinyalsa/pcm.h
@@ -223,43 +223,63 @@ struct pcm_params *pcm_params_get(unsigned int card, unsigned int device,
void pcm_params_free(struct pcm_params *pcm_params);
-struct pcm_mask *pcm_params_get_mask(struct pcm_params *pcm_params, enum pcm_param param);
+const struct pcm_mask *pcm_params_get_mask(const struct pcm_params *pcm_params, enum pcm_param param);
-unsigned int pcm_params_get_min(struct pcm_params *pcm_params, enum pcm_param param);
+unsigned int pcm_params_get_min(const struct pcm_params *pcm_params, enum pcm_param param);
-unsigned int pcm_params_get_max(struct pcm_params *pcm_params, enum pcm_param param);
+unsigned int pcm_params_get_max(const struct pcm_params *pcm_params, enum pcm_param param);
struct pcm;
struct pcm *pcm_open(unsigned int card,
unsigned int device,
unsigned int flags,
- struct pcm_config *config);
+ const struct pcm_config *config);
int pcm_close(struct pcm *pcm);
-int pcm_is_ready(struct pcm *pcm);
+int pcm_is_ready(const struct pcm *pcm);
-int pcm_get_file_descriptor(struct pcm *pcm);
+unsigned int pcm_get_channels(const struct pcm *pcm);
-const char *pcm_get_error(struct pcm *pcm);
+unsigned int pcm_get_rate(const struct pcm *pcm);
+
+enum pcm_format pcm_get_format(const struct pcm *pcm);
+
+int pcm_get_file_descriptor(const struct pcm *pcm);
+
+const char *pcm_get_error(const struct pcm *pcm);
unsigned int pcm_format_to_bits(enum pcm_format format);
-unsigned int pcm_get_buffer_size(struct pcm *pcm);
+unsigned int pcm_get_buffer_size(const struct pcm *pcm);
-unsigned int pcm_frames_to_bytes(struct pcm *pcm, unsigned int frames);
+unsigned int pcm_frames_to_bytes(const struct pcm *pcm, unsigned int frames);
-unsigned int pcm_bytes_to_frames(struct pcm *pcm, unsigned int bytes);
+unsigned int pcm_bytes_to_frames(const struct pcm *pcm, unsigned int bytes);
int pcm_get_htimestamp(struct pcm *pcm, unsigned int *avail, struct timespec *tstamp);
-unsigned int pcm_get_subdevice(struct pcm *pcm);
+unsigned int pcm_get_subdevice(const struct pcm *pcm);
+
+int pcm_writei(struct pcm *pcm, const void *data, unsigned int frame_count);
+
+int pcm_readi(struct pcm *pcm, void *data, unsigned int frame_count);
+
+#ifdef __GNUC__
+
+int pcm_write(struct pcm *pcm, const void *data, unsigned int count) __attribute((deprecated));
+
+int pcm_read(struct pcm *pcm, void *data, unsigned int count) __attribute((deprecated));
+
+#else
int pcm_write(struct pcm *pcm, const void *data, unsigned int count);
int pcm_read(struct pcm *pcm, void *data, unsigned int count);
+#endif
+
int pcm_mmap_write(struct pcm *pcm, const void *data, unsigned int count);
int pcm_mmap_read(struct pcm *pcm, void *data, unsigned int count);
diff --git a/include/tinyalsa/version.h b/include/tinyalsa/version.h
index b92e030..5d71840 100644
--- a/include/tinyalsa/version.h
+++ b/include/tinyalsa/version.h
@@ -31,13 +31,13 @@
#define TINYALSA_VERSION_MAJOR 1
-#define TINYALSA_VERSION_MINOR 0
+#define TINYALSA_VERSION_MINOR 1
-#define TINYALSA_VERSION_PATCH 3
+#define TINYALSA_VERSION_PATCH 0
-#define TINYALSA_VERSION 0x010003UL
+#define TINYALSA_VERSION 0x010100UL
-#define TINYALSA_VERSION_STRING "1.0.3"
+#define TINYALSA_VERSION_STRING "1.1.0"
#endif /* TINYALSA_VERSION_H */
diff --git a/src/Makefile b/src/Makefile
index da19c54..cde8267 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -19,7 +19,7 @@ VPATH = ../include/tinyalsa
OBJECTS = mixer.o pcm.o
.PHONY: all
-all: libtinyalsa.a libtinyalsa.so.1
+all: libtinyalsa.a libtinyalsa.so
pcm.o: pcm.c pcm.h
@@ -28,19 +28,28 @@ mixer.o: mixer.c mixer.h
libtinyalsa.a: $(OBJECTS)
$(AR) $(ARFLAGS) $@ $^
-libtinyalsa.so.1: $(OBJECTS)
- $(LD) $(LDFLAGS) -shared $^ -o $@
+libtinyalsa.so: libtinyalsa.so.1
+ ln -sf $< $@
+
+libtinyalsa.so.1: libtinyalsa.so.1.1.0
+ ln -sf $< $@
+
+libtinyalsa.so.1.1.0: $(OBJECTS)
+ $(LD) $(LDFLAGS) -shared -Wl,-soname,libtinyalsa.so.1 $^ -o $@
.PHONY: clean
clean:
rm -f libtinyalsa.a
+ rm -f libtinyalsa.so
rm -f libtinyalsa.so.1
+ rm -f libtinyalsa.so.1.1.0
rm -f $(OBJECTS)
.PHONY: install
install: libtinyalsa.a libtinyalsa.so.1
install -d $(DESTDIR)$(LIBDIR)/
- ln -sf libtinyalsa.so.1 $(DESTDIR)$(LIBDIR)/libtinyalsa.so
install libtinyalsa.a $(DESTDIR)$(LIBDIR)/
- install libtinyalsa.so.1 $(DESTDIR)$(LIBDIR)/
+ install libtinyalsa.so.1.1.0 $(DESTDIR)$(LIBDIR)/
+ ln -sf libtinyalsa.so.1.1.0 $(DESTDIR)$(LIBDIR)/libtinyalsa.so.1
+ ln -sf libtinyalsa.so.1 $(DESTDIR)$(LIBDIR)/libtinyalsa.so
diff --git a/src/mixer.c b/src/mixer.c
index 0fe9c99..9e661c5 100644
--- a/src/mixer.c
+++ b/src/mixer.c
@@ -176,7 +176,7 @@ fail:
* @returns The name of the mixer's card.
* @ingroup libtinyalsa-mixer
*/
-const char *mixer_get_name(struct mixer *mixer)
+const char *mixer_get_name(const struct mixer *mixer)
{
return (const char *)mixer->card_info.name;
}
@@ -186,7 +186,7 @@ const char *mixer_get_name(struct mixer *mixer)
* @returns The number of mixer controls for the given mixer.
* @ingroup libtinyalsa-mixer
*/
-unsigned int mixer_get_num_ctls(struct mixer *mixer)
+unsigned int mixer_get_num_ctls(const struct mixer *mixer)
{
if (!mixer)
return 0;
@@ -194,7 +194,47 @@ unsigned int mixer_get_num_ctls(struct mixer *mixer)
return mixer->count;
}
+/** Gets the number of mixer controls, that go by a specified name, for a given mixer.
+ * @param mixer An initialized mixer handle.
+ * @param name The name of the mixer control
+ * @returns The number of mixer controls, specified by @p name, for the given mixer.
+ * @ingroup libtinyalsa-mixer
+ */
+unsigned int mixer_get_num_ctls_by_name(const struct mixer *mixer, const char *name)
+{
+ unsigned int n;
+ unsigned int count = 0;
+ struct mixer_ctl *ctl;
+
+ if (!mixer)
+ return 0;
+
+ ctl = mixer->ctl;
+
+ for (n = 0; n < mixer->count; n++)
+ if (!strcmp(name, (char*) ctl[n].info.id.name))
+ count++;
+
+ return count;
+}
+
+/** Gets a mixer control handle, by the mixer control's id.
+ * For non-const access, see @ref mixer_get_ctl
+ * @param mixer An initialized mixer handle.
+ * @param id The control's id in the given mixer.
+ * @returns A handle to the mixer control.
+ * @ingroup libtinyalsa-mixer
+ */
+const struct mixer_ctl *mixer_get_ctl_const(const struct mixer *mixer, unsigned int id)
+{
+ if (mixer && (id < mixer->count))
+ return mixer->ctl + id;
+
+ return NULL;
+}
+
/** Gets a mixer control handle, by the mixer control's id.
+ * For const access, see @ref mixer_get_ctl_const
* @param mixer An initialized mixer handle.
* @param id The control's id in the given mixer.
* @returns A handle to the mixer control.
@@ -263,7 +303,7 @@ void mixer_ctl_update(struct mixer_ctl *ctl)
* On error, UINT_MAX is returned instead.
* @ingroup libtinyalsa-mixer
*/
-unsigned int mixer_ctl_get_id(struct mixer_ctl *ctl)
+unsigned int mixer_ctl_get_id(const struct mixer_ctl *ctl)
{
if (!ctl)
return UINT_MAX;
@@ -280,7 +320,7 @@ unsigned int mixer_ctl_get_id(struct mixer_ctl *ctl)
* On error, NULL.
* @ingroup libtinyalsa-mixer
*/
-const char *mixer_ctl_get_name(struct mixer_ctl *ctl)
+const char *mixer_ctl_get_name(const struct mixer_ctl *ctl)
{
if (!ctl)
return NULL;
@@ -294,7 +334,7 @@ const char *mixer_ctl_get_name(struct mixer_ctl *ctl)
* On failure, it returns @ref MIXER_CTL_TYPE_UNKNOWN
* @ingroup libtinyalsa-mixer
*/
-enum mixer_ctl_type mixer_ctl_get_type(struct mixer_ctl *ctl)
+enum mixer_ctl_type mixer_ctl_get_type(const struct mixer_ctl *ctl)
{
if (!ctl)
return MIXER_CTL_TYPE_UNKNOWN;
@@ -315,7 +355,7 @@ enum mixer_ctl_type mixer_ctl_get_type(struct mixer_ctl *ctl)
* @returns On success, a string describing type of mixer control.
* @ingroup libtinyalsa-mixer
*/
-const char *mixer_ctl_get_type_string(struct mixer_ctl *ctl)
+const char *mixer_ctl_get_type_string(const struct mixer_ctl *ctl)
{
if (!ctl)
return "";
@@ -336,7 +376,7 @@ const char *mixer_ctl_get_type_string(struct mixer_ctl *ctl)
* @returns The number of values in the mixer control
* @ingroup libtinyalsa-mixer
*/
-unsigned int mixer_ctl_get_num_values(struct mixer_ctl *ctl)
+unsigned int mixer_ctl_get_num_values(const struct mixer_ctl *ctl)
{
if (!ctl)
return 0;
@@ -344,7 +384,7 @@ unsigned int mixer_ctl_get_num_values(struct mixer_ctl *ctl)
return ctl->info.count;
}
-static int percent_to_int(struct snd_ctl_elem_info *ei, int percent)
+static int percent_to_int(const struct snd_ctl_elem_info *ei, int percent)
{
if ((percent > 100) || (percent < 0)) {
return -EINVAL;
@@ -355,7 +395,7 @@ static int percent_to_int(struct snd_ctl_elem_info *ei, int percent)
return ei->value.integer.min + (range * percent) / 100;
}
-static int int_to_percent(struct snd_ctl_elem_info *ei, int value)
+static int int_to_percent(const struct snd_ctl_elem_info *ei, int value)
{
int range = (ei->value.integer.max - ei->value.integer.min);
@@ -372,7 +412,7 @@ static int int_to_percent(struct snd_ctl_elem_info *ei, int value)
* On failure, -EINVAL is returned.
* @ingroup libtinyalsa-mixer
*/
-int mixer_ctl_get_percent(struct mixer_ctl *ctl, unsigned int id)
+int mixer_ctl_get_percent(const struct mixer_ctl *ctl, unsigned int id)
{
if (!ctl || (ctl->info.type != SNDRV_CTL_ELEM_TYPE_INTEGER))
return -EINVAL;
@@ -403,7 +443,7 @@ int mixer_ctl_set_percent(struct mixer_ctl *ctl, unsigned int id, int percent)
* On failure, -EINVAL is returned.
* @ingroup libtinyalsa-mixer
*/
-int mixer_ctl_get_value(struct mixer_ctl *ctl, unsigned int id)
+int mixer_ctl_get_value(const struct mixer_ctl *ctl, unsigned int id)
{
struct snd_ctl_elem_value ev;
int ret;
@@ -449,7 +489,7 @@ int mixer_ctl_get_value(struct mixer_ctl *ctl, unsigned int id)
* On failure, non-zero.
* @ingroup libtinyalsa-mixer
*/
-int mixer_ctl_get_array(struct mixer_ctl *ctl, void *array, size_t count)
+int mixer_ctl_get_array(const struct mixer_ctl *ctl, void *array, size_t count)
{
struct snd_ctl_elem_value ev;
int ret = 0;
@@ -634,7 +674,7 @@ int mixer_ctl_set_array(struct mixer_ctl *ctl, const void *array, size_t count)
* On failure, -EINVAL.
* @ingroup libtinyalsa-mixer
*/
-int mixer_ctl_get_range_min(struct mixer_ctl *ctl)
+int mixer_ctl_get_range_min(const struct mixer_ctl *ctl)
{
if (!ctl || (ctl->info.type != SNDRV_CTL_ELEM_TYPE_INTEGER))
return -EINVAL;
@@ -650,7 +690,7 @@ int mixer_ctl_get_range_min(struct mixer_ctl *ctl)
* On failure, -EINVAL.
* @ingroup libtinyalsa-mixer
*/
-int mixer_ctl_get_range_max(struct mixer_ctl *ctl)
+int mixer_ctl_get_range_max(const struct mixer_ctl *ctl)
{
if (!ctl || (ctl->info.type != SNDRV_CTL_ELEM_TYPE_INTEGER))
return -EINVAL;
@@ -663,7 +703,7 @@ int mixer_ctl_get_range_max(struct mixer_ctl *ctl)
* @returns The number of enumerated items in the control.
* @ingroup libtinyalsa-mixer
*/
-unsigned int mixer_ctl_get_num_enums(struct mixer_ctl *ctl)
+unsigned int mixer_ctl_get_num_enums(const struct mixer_ctl *ctl)
{
if (!ctl)
return 0;
diff --git a/src/pcm.c b/src/pcm.c
index 1ce1a54..f879fe7 100644
--- a/src/pcm.c
+++ b/src/pcm.c
@@ -64,6 +64,11 @@ static inline int param_is_interval(int p)
(p <= SNDRV_PCM_HW_PARAM_LAST_INTERVAL);
}
+static inline const struct snd_interval *param_get_interval(const struct snd_pcm_hw_params *p, int n)
+{
+ return &(p->intervals[n - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL]);
+}
+
static inline struct snd_interval *param_to_interval(struct snd_pcm_hw_params *p, int n)
{
return &(p->intervals[n - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL]);
@@ -94,19 +99,19 @@ static void param_set_min(struct snd_pcm_hw_params *p, int n, unsigned int val)
}
}
-static unsigned int param_get_min(struct snd_pcm_hw_params *p, int n)
+static unsigned int param_get_min(const struct snd_pcm_hw_params *p, int n)
{
if (param_is_interval(n)) {
- struct snd_interval *i = param_to_interval(p, n);
+ const struct snd_interval *i = param_get_interval(p, n);
return i->min;
}
return 0;
}
-static unsigned int param_get_max(struct snd_pcm_hw_params *p, int n)
+static unsigned int param_get_max(const struct snd_pcm_hw_params *p, int n)
{
if (param_is_interval(n)) {
- struct snd_interval *i = param_to_interval(p, n);
+ const struct snd_interval *i = param_get_interval(p, n);
return i->max;
}
return 0;
@@ -194,18 +199,49 @@ struct pcm {
* @return The buffer size of the PCM.
* @ingroup libtinyalsa-pcm
*/
-unsigned int pcm_get_buffer_size(struct pcm *pcm)
+unsigned int pcm_get_buffer_size(const struct pcm *pcm)
{
return pcm->buffer_size;
}
+/** Gets the channel count of the PCM.
+ * @param pcm A PCM handle.
+ * @return The channel count of the PCM.
+ * @ingroup libtinyalsa-pcm
+ */
+unsigned int pcm_get_channels(const struct pcm *pcm)
+{
+ return pcm->config.channels;
+}
+
+/** Gets the rate of the PCM.
+ * The rate is given in frames per second.
+ * @param pcm A PCM handle.
+ * @return The rate of the PCM.
+ * @ingroup libtinyalsa-pcm
+ */
+unsigned int pcm_get_rate(const struct pcm *pcm)
+{
+ return pcm->config.rate;
+}
+
+/** Gets the format of the PCM.
+ * @param pcm A PCM handle.
+ * @return The format of the PCM.
+ * @ingroup libtinyalsa-pcm
+ */
+enum pcm_format pcm_get_format(const struct pcm *pcm)
+{
+ return pcm->config.format;
+}
+
/** Gets the file descriptor of the PCM.
* Useful for extending functionality of the PCM when needed.
* @param pcm A PCM handle.
* @return The file descriptor of the PCM.
* @ingroup libtinyalsa-pcm
*/
-int pcm_get_file_descriptor(struct pcm *pcm)
+int pcm_get_file_descriptor(const struct pcm *pcm)
{
return pcm->fd;
}
@@ -216,7 +252,7 @@ int pcm_get_file_descriptor(struct pcm *pcm)
* @return The error message of the last error that occured.
* @ingroup libtinyalsa-pcm
*/
-const char* pcm_get_error(struct pcm *pcm)
+const char* pcm_get_error(const struct pcm *pcm)
{
return pcm->error;
}
@@ -224,7 +260,7 @@ const char* pcm_get_error(struct pcm *pcm)
/** Gets the subdevice on which the pcm has been opened.
* @param pcm A PCM handle.
* @return The subdevice on which the pcm has been opened */
-unsigned int pcm_get_subdevice(struct pcm *pcm)
+unsigned int pcm_get_subdevice(const struct pcm *pcm)
{
return pcm->subdevice;
}
@@ -306,7 +342,7 @@ unsigned int pcm_format_to_bits(enum pcm_format format)
* @return The number of frames that may fit into @p bytes
* @ingroup libtinyalsa-pcm
*/
-unsigned int pcm_bytes_to_frames(struct pcm *pcm, unsigned int bytes)
+unsigned int pcm_bytes_to_frames(const struct pcm *pcm, unsigned int bytes)
{
return bytes / (pcm->config.channels *
(pcm_format_to_bits(pcm->config.format) >> 3));
@@ -318,7 +354,7 @@ unsigned int pcm_bytes_to_frames(struct pcm *pcm, unsigned int bytes)
* @return The bytes occupied by @p frames.
* @ingroup libtinyalsa-pcm
*/
-unsigned int pcm_frames_to_bytes(struct pcm *pcm, unsigned int frames)
+unsigned int pcm_frames_to_bytes(const struct pcm *pcm, unsigned int frames)
{
return frames * pcm->config.channels *
(pcm_format_to_bits(pcm->config.format) >> 3);
@@ -486,11 +522,11 @@ int pcm_get_htimestamp(struct pcm *pcm, unsigned int *avail,
* This function is not valid for PCMs opened with the @ref PCM_MMAP flag.
* @param pcm A PCM handle.
* @param data The audio sample array
- * @param count The number of bytes occupied by the sample array.
- * @return On success, this function returns zero; otherwise, a negative number.
+ * @param frame_count The number of frames occupied by the sample array.
+ * @return On success, this function returns the number of frames written; otherwise, a negative number.
* @ingroup libtinyalsa-pcm
*/
-int pcm_write(struct pcm *pcm, const void *data, unsigned int count)
+int pcm_writei(struct pcm *pcm, const void *data, unsigned int frame_count)
{
struct snd_xferi x;
@@ -498,8 +534,7 @@ int pcm_write(struct pcm *pcm, const void *data, unsigned int count)
return -EINVAL;
x.buf = (void*)data;
- x.frames = count / (pcm->config.channels *
- pcm_format_to_bits(pcm->config.format) / 8);
+ x.frames = frame_count;
x.result = 0;
for (;;) {
if (!pcm->running) {
@@ -525,7 +560,7 @@ int pcm_write(struct pcm *pcm, const void *data, unsigned int count)
}
return oops(pcm, errno, "cannot write stream data");
}
- return 0;
+ return x.result;
}
}
@@ -535,11 +570,11 @@ int pcm_write(struct pcm *pcm, const void *data, unsigned int count)
* This function is not valid for PCMs opened with the @ref PCM_MMAP flag.
* @param pcm A PCM handle.
* @param data The audio sample array
- * @param count The number of bytes occupied by the sample array.
- * @return On success, this function returns zero; otherwise, a negative number.
+ * @param frame_count The number of frames occupied by the sample array.
+ * @return On success, this function returns the number of frames written; otherwise, a negative number.
* @ingroup libtinyalsa-pcm
*/
-int pcm_read(struct pcm *pcm, void *data, unsigned int count)
+int pcm_readi(struct pcm *pcm, void *data, unsigned int frame_count)
{
struct snd_xferi x;
@@ -547,8 +582,7 @@ int pcm_read(struct pcm *pcm, void *data, unsigned int count)
return -EINVAL;
x.buf = data;
- x.frames = count / (pcm->config.channels *
- pcm_format_to_bits(pcm->config.format) / 8);
+ x.frames = frame_count;
x.result = 0;
for (;;) {
if (!pcm->running) {
@@ -567,8 +601,48 @@ int pcm_read(struct pcm *pcm, void *data, unsigned int count)
}
return oops(pcm, errno, "cannot read stream data");
}
- return 0;
+ return x.result;
+ }
+}
+
+/** Writes audio samples to PCM.
+ * If the PCM has not been started, it is started in this function.
+ * This function is only valid for PCMs opened with the @ref PCM_OUT flag.
+ * This function is not valid for PCMs opened with the @ref PCM_MMAP flag.
+ * @param pcm A PCM handle.
+ * @param data The audio sample array
+ * @param count The number of bytes occupied by the sample array.
+ * @return On success, this function returns zero; otherwise, a negative number.
+ * @deprecated
+ * @ingroup libtinyalsa-pcm
+ */
+int pcm_write(struct pcm *pcm, const void *data, unsigned int count)
+{
+ int ret = pcm_writei(pcm, data, pcm_bytes_to_frames(pcm, count));
+ if (ret < 0){
+ return ret;
}
+ return 0;
+}
+
+/** Reads audio samples from PCM.
+ * If the PCM has not been started, it is started in this function.
+ * This function is only valid for PCMs opened with the @ref PCM_IN flag.
+ * This function is not valid for PCMs opened with the @ref PCM_MMAP flag.
+ * @param pcm A PCM handle.
+ * @param data The audio sample array
+ * @param count The number of bytes occupied by the sample array.
+ * @return On success, this function returns zero; otherwise, a negative number.
+ * @deprecated
+ * @ingroup libtinyalsa-pcm
+ */
+int pcm_read(struct pcm *pcm, void *data, unsigned int count)
+{
+ int ret = pcm_readi(pcm, data, pcm_bytes_to_frames(pcm, count));
+ if (ret < 0) {
+ return ret;
+ }
+ return 0;
}
static struct pcm bad_pcm = {
@@ -696,7 +770,7 @@ static int pcm_param_to_alsa(enum pcm_param param)
* Otherwise, the mask associated with @p param is returned.
* @ingroup libtinyalsa-pcm
*/
-struct pcm_mask *pcm_params_get_mask(struct pcm_params *pcm_params,
+const struct pcm_mask *pcm_params_get_mask(const struct pcm_params *pcm_params,
enum pcm_param param)
{
int p;
@@ -710,7 +784,7 @@ struct pcm_mask *pcm_params_get_mask(struct pcm_params *pcm_params,
return NULL;
}
- return (struct pcm_mask *)param_to_mask(params, p);
+ return (const struct pcm_mask *)param_to_mask(params, p);
}
/** Get the minimum of a specified PCM parameter.
@@ -719,7 +793,7 @@ struct pcm_mask *pcm_params_get_mask(struct pcm_params *pcm_params,
* @returns On success, the parameter minimum.
* On failure, zero.
*/
-unsigned int pcm_params_get_min(struct pcm_params *pcm_params,
+unsigned int pcm_params_get_min(const struct pcm_params *pcm_params,
enum pcm_param param)
{
struct snd_pcm_hw_params *params = (struct snd_pcm_hw_params *)pcm_params;
@@ -741,10 +815,10 @@ unsigned int pcm_params_get_min(struct pcm_params *pcm_params,
* @returns On success, the parameter maximum.
* On failure, zero.
*/
-unsigned int pcm_params_get_max(struct pcm_params *pcm_params,
+unsigned int pcm_params_get_max(const struct pcm_params *pcm_params,
enum pcm_param param)
{
- struct snd_pcm_hw_params *params = (struct snd_pcm_hw_params *)pcm_params;
+ const struct snd_pcm_hw_params *params = (const struct snd_pcm_hw_params *)pcm_params;
int p;
if (!params)
@@ -803,7 +877,7 @@ int pcm_close(struct pcm *pcm)
* @ingroup libtinyalsa-pcm
*/
struct pcm *pcm_open(unsigned int card, unsigned int device,
- unsigned int flags, struct pcm_config *config)
+ unsigned int flags, const struct pcm_config *config)
{
struct pcm *pcm;
struct snd_pcm_info info;
@@ -818,14 +892,14 @@ struct pcm *pcm_open(unsigned int card, unsigned int device,
if (config == NULL) {
config = &pcm->config;
- config->channels = 2;
- config->rate = 48000;
- config->period_size = 1024;
- config->period_count = 4;
- config->format = PCM_FORMAT_S16_LE;
- config->start_threshold = config->period_count * config->period_size;
- config->stop_threshold = config->period_count * config->period_size;
- config->silence_threshold = 0;
+ pcm->config.channels = 2;
+ pcm->config.rate = 48000;
+ pcm->config.period_size = 1024;
+ pcm->config.period_count = 4;
+ pcm->config.format = PCM_FORMAT_S16_LE;
+ pcm->config.start_threshold = config->period_count * config->period_size;
+ pcm->config.stop_threshold = config->period_count * config->period_size;
+ pcm->config.silence_threshold = 0;
} else {
pcm->config = *config;
}
@@ -885,8 +959,8 @@ struct pcm *pcm_open(unsigned int card, unsigned int device,
}
/* get our refined hw_params */
- config->period_size = param_get_int(&params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
- config->period_count = param_get_int(&params, SNDRV_PCM_HW_PARAM_PERIODS);
+ pcm->config.period_size = param_get_int(&params, SNDRV_PCM_HW_PARAM_PERIOD_SIZE);
+ pcm->config.period_count = param_get_int(&params, SNDRV_PCM_HW_PARAM_PERIODS);
pcm->buffer_size = config->period_count * config->period_size;
if (flags & PCM_MMAP) {
@@ -974,7 +1048,7 @@ fail_close:
* Otherwise, the function returns one.
* @ingroup libtinyalsa-pcm
*/
-int pcm_is_ready(struct pcm *pcm)
+int pcm_is_ready(const struct pcm *pcm)
{
return pcm->fd >= 0;
}
diff --git a/utils/tinycap.c b/utils/tinycap.c
index 503b118..05c7180 100644
--- a/utils/tinycap.c
+++ b/utils/tinycap.c
@@ -244,7 +244,7 @@ unsigned int capture_sample(FILE *file, unsigned int card, unsigned int device,
pcm_format_to_bits(format));
}
- while (capturing && !pcm_read(pcm, buffer, size)) {
+ while (capturing && (pcm_readi(pcm, buffer, size) < 0)) {
if (capture_time > 0 &&
((bytes_read + size) > pcm_frames_to_bytes(pcm, capture_time * rate))) {
size = pcm_frames_to_bytes(pcm, capture_time * rate) - bytes_read;
diff --git a/utils/tinypcminfo.c b/utils/tinypcminfo.c
index 5b8db1f..0dd381d 100644
--- a/utils/tinypcminfo.c
+++ b/utils/tinypcminfo.c
@@ -129,7 +129,7 @@ int main(int argc, char **argv)
for (i = 0; i < 2; i++) {
struct pcm_params *params;
- struct pcm_mask *m;
+ const struct pcm_mask *m;
unsigned int min;
unsigned int max;
diff --git a/utils/tinyplay.c b/utils/tinyplay.c
index db1b611..d0c1e36 100644
--- a/utils/tinyplay.c
+++ b/utils/tinyplay.c
@@ -409,7 +409,7 @@ int play_sample(struct ctx *ctx)
do {
num_read = fread(buffer, 1, size, ctx->file);
if (num_read > 0) {
- if (pcm_write(ctx->pcm, buffer, num_read)) {
+ if (pcm_writei(ctx->pcm, buffer, num_read) < 0) {
fprintf(stderr, "error playing sample\n");
break;
}