diff options
-rw-r--r-- | debian/changelog | 14 | ||||
-rw-r--r-- | doxygen/Doxyfile | 2 | ||||
-rw-r--r-- | include/tinyalsa/mixer.h | 30 | ||||
-rw-r--r-- | include/tinyalsa/pcm.h | 42 | ||||
-rw-r--r-- | include/tinyalsa/version.h | 8 | ||||
-rw-r--r-- | src/Makefile | 19 | ||||
-rw-r--r-- | src/mixer.c | 70 | ||||
-rw-r--r-- | src/pcm.c | 152 | ||||
-rw-r--r-- | utils/tinycap.c | 2 | ||||
-rw-r--r-- | utils/tinypcminfo.c | 2 | ||||
-rw-r--r-- | utils/tinyplay.c | 2 |
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; @@ -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(¶ms, SNDRV_PCM_HW_PARAM_PERIOD_SIZE); - config->period_count = param_get_int(¶ms, SNDRV_PCM_HW_PARAM_PERIODS); + pcm->config.period_size = param_get_int(¶ms, SNDRV_PCM_HW_PARAM_PERIOD_SIZE); + pcm->config.period_count = param_get_int(¶ms, 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; } |