mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
Better names for ALSA API. Added min_fragments, max_fragments.
This commit is contained in:
parent
4bb0a08bf9
commit
1a7f88d10e
26 changed files with 1938 additions and 1938 deletions
|
|
@ -44,8 +44,8 @@ int snd_ctl_switch_read(snd_ctl_t *handle, snd_switch_t * sw);
|
||||||
int snd_ctl_switch_write(snd_ctl_t *handle, snd_switch_t * sw);
|
int snd_ctl_switch_write(snd_ctl_t *handle, snd_switch_t * sw);
|
||||||
int snd_ctl_hwdep_info(snd_ctl_t *handle, int dev, snd_hwdep_info_t * info);
|
int snd_ctl_hwdep_info(snd_ctl_t *handle, int dev, snd_hwdep_info_t * info);
|
||||||
int snd_ctl_pcm_info(snd_ctl_t *handle, int dev, snd_pcm_info_t * info);
|
int snd_ctl_pcm_info(snd_ctl_t *handle, int dev, snd_pcm_info_t * info);
|
||||||
int snd_ctl_pcm_channel_info(snd_ctl_t *handle, int dev, int channel, int subdev, snd_pcm_channel_info_t * info);
|
int snd_ctl_pcm_stream_info(snd_ctl_t *handle, int dev, int channel, int subdev, snd_pcm_stream_info_t * info);
|
||||||
int snd_ctl_pcm_channel_prefer_subdevice(snd_ctl_t *handle, int dev, int channel, int subdev);
|
int snd_ctl_pcm_stream_prefer_subdevice(snd_ctl_t *handle, int dev, int channel, int subdev);
|
||||||
int snd_ctl_mixer_info(snd_ctl_t *handle, int dev, snd_mixer_info_t * info);
|
int snd_ctl_mixer_info(snd_ctl_t *handle, int dev, snd_mixer_info_t * info);
|
||||||
int snd_ctl_rawmidi_info(snd_ctl_t *handle, int dev, snd_rawmidi_info_t * info);
|
int snd_ctl_rawmidi_info(snd_ctl_t *handle, int dev, snd_rawmidi_info_t * info);
|
||||||
int snd_ctl_read(snd_ctl_t *handle, snd_ctl_callbacks_t * callbacks);
|
int snd_ctl_read(snd_ctl_t *handle, snd_ctl_callbacks_t * callbacks);
|
||||||
|
|
|
||||||
146
include/pcm.h
146
include/pcm.h
|
|
@ -89,31 +89,31 @@ int snd_pcm_open_subdevice(snd_pcm_t **handle, int card, int device, int subdevi
|
||||||
|
|
||||||
snd_pcm_type_t snd_pcm_type(snd_pcm_t *handle);
|
snd_pcm_type_t snd_pcm_type(snd_pcm_t *handle);
|
||||||
int snd_pcm_close(snd_pcm_t *handle);
|
int snd_pcm_close(snd_pcm_t *handle);
|
||||||
int snd_pcm_channel_close(snd_pcm_t *handle, int channel);
|
int snd_pcm_stream_close(snd_pcm_t *handle, int stream);
|
||||||
int snd_pcm_file_descriptor(snd_pcm_t *handle, int channel);
|
int snd_pcm_file_descriptor(snd_pcm_t *handle, int stream);
|
||||||
int snd_pcm_channel_nonblock(snd_pcm_t *handle, int channel, int nonblock);
|
int snd_pcm_stream_nonblock(snd_pcm_t *handle, int stream, int nonblock);
|
||||||
int snd_pcm_info(snd_pcm_t *handle, snd_pcm_info_t *info);
|
int snd_pcm_info(snd_pcm_t *handle, snd_pcm_info_t *info);
|
||||||
int snd_pcm_channel_info(snd_pcm_t *handle, snd_pcm_channel_info_t *info);
|
int snd_pcm_stream_info(snd_pcm_t *handle, snd_pcm_stream_info_t *info);
|
||||||
int snd_pcm_channel_params(snd_pcm_t *handle, snd_pcm_channel_params_t *params);
|
int snd_pcm_stream_params(snd_pcm_t *handle, snd_pcm_stream_params_t *params);
|
||||||
int snd_pcm_channel_setup(snd_pcm_t *handle, snd_pcm_channel_setup_t *setup);
|
int snd_pcm_stream_setup(snd_pcm_t *handle, snd_pcm_stream_setup_t *setup);
|
||||||
int snd_pcm_voice_setup(snd_pcm_t *handle, int channel, snd_pcm_voice_setup_t *setup);
|
int snd_pcm_channel_setup(snd_pcm_t *handle, int stream, snd_pcm_channel_setup_t *setup);
|
||||||
int snd_pcm_channel_status(snd_pcm_t *handle, snd_pcm_channel_status_t *status);
|
int snd_pcm_stream_status(snd_pcm_t *handle, snd_pcm_stream_status_t *status);
|
||||||
int snd_pcm_channel_update(snd_pcm_t *handle, int channel);
|
int snd_pcm_stream_update(snd_pcm_t *handle, int stream);
|
||||||
int snd_pcm_playback_prepare(snd_pcm_t *handle);
|
int snd_pcm_playback_prepare(snd_pcm_t *handle);
|
||||||
int snd_pcm_capture_prepare(snd_pcm_t *handle);
|
int snd_pcm_capture_prepare(snd_pcm_t *handle);
|
||||||
int snd_pcm_channel_prepare(snd_pcm_t *handle, int channel);
|
int snd_pcm_stream_prepare(snd_pcm_t *handle, int stream);
|
||||||
int snd_pcm_playback_go(snd_pcm_t *handle);
|
int snd_pcm_playback_go(snd_pcm_t *handle);
|
||||||
int snd_pcm_capture_go(snd_pcm_t *handle);
|
int snd_pcm_capture_go(snd_pcm_t *handle);
|
||||||
int snd_pcm_channel_go(snd_pcm_t *handle, int channel);
|
int snd_pcm_stream_go(snd_pcm_t *handle, int stream);
|
||||||
int snd_pcm_sync_go(snd_pcm_t *handle, snd_pcm_sync_t *sync);
|
int snd_pcm_sync_go(snd_pcm_t *handle, snd_pcm_sync_t *sync);
|
||||||
int snd_pcm_playback_drain(snd_pcm_t *handle);
|
int snd_pcm_playback_drain(snd_pcm_t *handle);
|
||||||
int snd_pcm_channel_drain(snd_pcm_t *handle, int channel);
|
int snd_pcm_stream_drain(snd_pcm_t *handle, int stream);
|
||||||
int snd_pcm_playback_flush(snd_pcm_t *handle);
|
int snd_pcm_playback_flush(snd_pcm_t *handle);
|
||||||
int snd_pcm_capture_flush(snd_pcm_t *handle);
|
int snd_pcm_capture_flush(snd_pcm_t *handle);
|
||||||
int snd_pcm_channel_flush(snd_pcm_t *handle, int channel);
|
int snd_pcm_stream_flush(snd_pcm_t *handle, int stream);
|
||||||
int snd_pcm_playback_pause(snd_pcm_t *handle, int enable);
|
int snd_pcm_playback_pause(snd_pcm_t *handle, int enable);
|
||||||
int snd_pcm_channel_pause(snd_pcm_t *handle, int channel, int enable);
|
int snd_pcm_stream_pause(snd_pcm_t *handle, int stream, int enable);
|
||||||
ssize_t snd_pcm_transfer_size(snd_pcm_t *handle, int channel);
|
ssize_t snd_pcm_transfer_size(snd_pcm_t *handle, int stream);
|
||||||
ssize_t snd_pcm_write(snd_pcm_t *handle, const void *buffer, size_t size);
|
ssize_t snd_pcm_write(snd_pcm_t *handle, const void *buffer, size_t size);
|
||||||
ssize_t snd_pcm_read(snd_pcm_t *handle, void *buffer, size_t size);
|
ssize_t snd_pcm_read(snd_pcm_t *handle, void *buffer, size_t size);
|
||||||
ssize_t snd_pcm_writev(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count);
|
ssize_t snd_pcm_writev(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count);
|
||||||
|
|
@ -121,42 +121,42 @@ ssize_t snd_pcm_readv(snd_pcm_t *pcm, const struct iovec *vector, unsigned long
|
||||||
const char *snd_pcm_get_format_name(int format);
|
const char *snd_pcm_get_format_name(int format);
|
||||||
const char *snd_pcm_get_format_description(int format);
|
const char *snd_pcm_get_format_description(int format);
|
||||||
int snd_pcm_get_format_value(const char* name);
|
int snd_pcm_get_format_value(const char* name);
|
||||||
int snd_pcm_dump_setup(snd_pcm_t *pcm, int channel, FILE *fp);
|
int snd_pcm_dump_setup(snd_pcm_t *pcm, int stream, FILE *fp);
|
||||||
|
|
||||||
int snd_pcm_mmap(snd_pcm_t *handle, int channel, snd_pcm_mmap_control_t **control, void **buffer);
|
int snd_pcm_mmap(snd_pcm_t *handle, int stream, snd_pcm_mmap_control_t **control, void **buffer);
|
||||||
int snd_pcm_munmap(snd_pcm_t *handle, int channel);
|
int snd_pcm_munmap(snd_pcm_t *handle, int stream);
|
||||||
int snd_pcm_mmap_control(snd_pcm_t *handle, int channel, snd_pcm_mmap_control_t **control);
|
int snd_pcm_mmap_control(snd_pcm_t *handle, int stream, snd_pcm_mmap_control_t **control);
|
||||||
int snd_pcm_mmap_data(snd_pcm_t *handle, int channel, void **buffer);
|
int snd_pcm_mmap_data(snd_pcm_t *handle, int stream, void **buffer);
|
||||||
int snd_pcm_munmap_control(snd_pcm_t *handle, int channel);
|
int snd_pcm_munmap_control(snd_pcm_t *handle, int stream);
|
||||||
int snd_pcm_munmap_data(snd_pcm_t *handle, int channel);
|
int snd_pcm_munmap_data(snd_pcm_t *handle, int stream);
|
||||||
int snd_pcm_voices_mask(snd_pcm_t *pcm, int channel, bitset_t *client_vmask);
|
int snd_pcm_channels_mask(snd_pcm_t *pcm, int stream, bitset_t *client_vmask);
|
||||||
int snd_pcm_mmap_ready(snd_pcm_t *pcm, int channel);
|
int snd_pcm_mmap_ready(snd_pcm_t *pcm, int stream);
|
||||||
ssize_t snd_pcm_mmap_write(snd_pcm_t *handle, const void *buffer, size_t size);
|
ssize_t snd_pcm_mmap_write(snd_pcm_t *handle, const void *buffer, size_t size);
|
||||||
ssize_t snd_pcm_mmap_read(snd_pcm_t *handle, void *buffer, size_t size);
|
ssize_t snd_pcm_mmap_read(snd_pcm_t *handle, void *buffer, size_t size);
|
||||||
ssize_t snd_pcm_mmap_writev(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count);
|
ssize_t snd_pcm_mmap_writev(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count);
|
||||||
ssize_t snd_pcm_mmap_readv(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count);
|
ssize_t snd_pcm_mmap_readv(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count);
|
||||||
int snd_pcm_mmap_frames_used(snd_pcm_t *pcm, int channel, ssize_t *frames);
|
int snd_pcm_mmap_frames_used(snd_pcm_t *pcm, int stream, ssize_t *frames);
|
||||||
int snd_pcm_mmap_frames_free(snd_pcm_t *pcm, int channel, ssize_t *frames);
|
int snd_pcm_mmap_frames_free(snd_pcm_t *pcm, int stream, ssize_t *frames);
|
||||||
ssize_t snd_pcm_mmap_frames_xfer(snd_pcm_t *pcm, int channel, size_t frames);
|
ssize_t snd_pcm_mmap_frames_xfer(snd_pcm_t *pcm, int stream, size_t frames);
|
||||||
ssize_t snd_pcm_mmap_frames_offset(snd_pcm_t *pcm, int channel);
|
ssize_t snd_pcm_mmap_frames_offset(snd_pcm_t *pcm, int stream);
|
||||||
int snd_pcm_mmap_commit_frames(snd_pcm_t *pcm, int channel, int frames);
|
int snd_pcm_mmap_commit_frames(snd_pcm_t *pcm, int stream, int frames);
|
||||||
ssize_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm, snd_pcm_voice_area_t *voices, size_t frames);
|
ssize_t snd_pcm_mmap_write_areas(snd_pcm_t *pcm, snd_pcm_channel_area_t *channels, size_t frames);
|
||||||
ssize_t snd_pcm_mmap_write_frames(snd_pcm_t *pcm, const void *buffer, size_t frames);
|
ssize_t snd_pcm_mmap_write_frames(snd_pcm_t *pcm, const void *buffer, size_t frames);
|
||||||
ssize_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm, snd_pcm_voice_area_t *voices, size_t frames);
|
ssize_t snd_pcm_mmap_read_areas(snd_pcm_t *pcm, snd_pcm_channel_area_t *channels, size_t frames);
|
||||||
ssize_t snd_pcm_mmap_read_frames(snd_pcm_t *pcm, const void *buffer, size_t frames);
|
ssize_t snd_pcm_mmap_read_frames(snd_pcm_t *pcm, const void *buffer, size_t frames);
|
||||||
int snd_pcm_mmap_get_areas(snd_pcm_t *pcm, int channel, snd_pcm_voice_area_t *areas);
|
int snd_pcm_mmap_get_areas(snd_pcm_t *pcm, int stream, snd_pcm_channel_area_t *areas);
|
||||||
|
|
||||||
ssize_t snd_pcm_bytes_per_second(snd_pcm_t *pcm, int channel);
|
ssize_t snd_pcm_bytes_per_second(snd_pcm_t *pcm, int stream);
|
||||||
|
|
||||||
int snd_pcm_area_silence(const snd_pcm_voice_area_t *dst_voice, size_t dst_offset,
|
int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_channel, size_t dst_offset,
|
||||||
size_t samples, int format);
|
size_t samples, int format);
|
||||||
int snd_pcm_areas_silence(const snd_pcm_voice_area_t *dst_voices, size_t dst_offset,
|
int snd_pcm_areas_silence(const snd_pcm_channel_area_t *dst_channels, size_t dst_offset,
|
||||||
size_t vcount, size_t frames, int format);
|
size_t vcount, size_t frames, int format);
|
||||||
int snd_pcm_area_copy(const snd_pcm_voice_area_t *src_voice, size_t src_offset,
|
int snd_pcm_area_copy(const snd_pcm_channel_area_t *src_channel, size_t src_offset,
|
||||||
const snd_pcm_voice_area_t *dst_voice, size_t dst_offset,
|
const snd_pcm_channel_area_t *dst_channel, size_t dst_offset,
|
||||||
size_t samples, int format);
|
size_t samples, int format);
|
||||||
int snd_pcm_areas_copy(const snd_pcm_voice_area_t *src_voices, size_t src_offset,
|
int snd_pcm_areas_copy(const snd_pcm_channel_area_t *src_channels, size_t src_offset,
|
||||||
const snd_pcm_voice_area_t *dst_voices, size_t dst_offset,
|
const snd_pcm_channel_area_t *dst_channels, size_t dst_offset,
|
||||||
size_t vcount, size_t frames, int format);
|
size_t vcount, size_t frames, int format);
|
||||||
|
|
||||||
/* misc */
|
/* misc */
|
||||||
|
|
@ -200,34 +200,34 @@ typedef enum {
|
||||||
PAUSE = 4,
|
PAUSE = 4,
|
||||||
} snd_pcm_plugin_action_t;
|
} snd_pcm_plugin_action_t;
|
||||||
|
|
||||||
typedef struct snd_stru_pcm_plugin_voice {
|
typedef struct snd_stru_pcm_plugin_channel {
|
||||||
void *aptr; /* pointer to the allocated area */
|
void *aptr; /* pointer to the allocated area */
|
||||||
snd_pcm_voice_area_t area;
|
snd_pcm_channel_area_t area;
|
||||||
unsigned int enabled:1; /* voice need to be processed */
|
unsigned int enabled:1; /* channel need to be processed */
|
||||||
unsigned int wanted:1; /* voice is wanted */
|
unsigned int wanted:1; /* channel is wanted */
|
||||||
} snd_pcm_plugin_voice_t;
|
} snd_pcm_plugin_channel_t;
|
||||||
|
|
||||||
struct snd_stru_pcm_plugin {
|
struct snd_stru_pcm_plugin {
|
||||||
char *name; /* plug-in name */
|
char *name; /* plug-in name */
|
||||||
int channel;
|
int stream;
|
||||||
snd_pcm_format_t src_format; /* source format */
|
snd_pcm_format_t src_format; /* source format */
|
||||||
snd_pcm_format_t dst_format; /* destination format */
|
snd_pcm_format_t dst_format; /* destination format */
|
||||||
int src_width; /* sample width in bits */
|
int src_width; /* sample width in bits */
|
||||||
int dst_width; /* sample width in bits */
|
int dst_width; /* sample width in bits */
|
||||||
ssize_t (*src_frames)(snd_pcm_plugin_t *plugin, size_t dst_frames);
|
ssize_t (*src_frames)(snd_pcm_plugin_t *plugin, size_t dst_frames);
|
||||||
ssize_t (*dst_frames)(snd_pcm_plugin_t *plugin, size_t src_frames);
|
ssize_t (*dst_frames)(snd_pcm_plugin_t *plugin, size_t src_frames);
|
||||||
ssize_t (*client_voices)(snd_pcm_plugin_t *plugin,
|
ssize_t (*client_channels)(snd_pcm_plugin_t *plugin,
|
||||||
size_t frames,
|
size_t frames,
|
||||||
snd_pcm_plugin_voice_t **voices);
|
snd_pcm_plugin_channel_t **channels);
|
||||||
int (*src_voices_mask)(snd_pcm_plugin_t *plugin,
|
int (*src_channels_mask)(snd_pcm_plugin_t *plugin,
|
||||||
bitset_t *dst_vmask,
|
bitset_t *dst_vmask,
|
||||||
bitset_t **src_vmask);
|
bitset_t **src_vmask);
|
||||||
int (*dst_voices_mask)(snd_pcm_plugin_t *plugin,
|
int (*dst_channels_mask)(snd_pcm_plugin_t *plugin,
|
||||||
bitset_t *src_vmask,
|
bitset_t *src_vmask,
|
||||||
bitset_t **dst_vmask);
|
bitset_t **dst_vmask);
|
||||||
ssize_t (*transfer)(snd_pcm_plugin_t *plugin,
|
ssize_t (*transfer)(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voices,
|
snd_pcm_plugin_channel_t *dst_channels,
|
||||||
size_t frames);
|
size_t frames);
|
||||||
int (*action)(snd_pcm_plugin_t *plugin,
|
int (*action)(snd_pcm_plugin_t *plugin,
|
||||||
snd_pcm_plugin_action_t action,
|
snd_pcm_plugin_action_t action,
|
||||||
|
|
@ -243,8 +243,8 @@ struct snd_stru_pcm_plugin {
|
||||||
snd_pcm_plugin_handle_t *handle;
|
snd_pcm_plugin_handle_t *handle;
|
||||||
void *private_data;
|
void *private_data;
|
||||||
void (*private_free)(snd_pcm_plugin_t *plugin, void *private_data);
|
void (*private_free)(snd_pcm_plugin_t *plugin, void *private_data);
|
||||||
snd_pcm_plugin_voice_t *src_voices;
|
snd_pcm_plugin_channel_t *src_channels;
|
||||||
snd_pcm_plugin_voice_t *dst_voices;
|
snd_pcm_plugin_channel_t *dst_channels;
|
||||||
bitset_t *src_vmask;
|
bitset_t *src_vmask;
|
||||||
bitset_t *dst_vmask;
|
bitset_t *dst_vmask;
|
||||||
char extra_data[0];
|
char extra_data[0];
|
||||||
|
|
@ -255,20 +255,20 @@ int snd_pcm_plug_open_subdevice(snd_pcm_t **handle, int card, int device, int su
|
||||||
int snd_pcm_plug_open(snd_pcm_t **handle, int card, int device, int mode);
|
int snd_pcm_plug_open(snd_pcm_t **handle, int card, int device, int mode);
|
||||||
|
|
||||||
int snd_pcm_plugin_free(snd_pcm_plugin_t *plugin);
|
int snd_pcm_plugin_free(snd_pcm_plugin_t *plugin);
|
||||||
int snd_pcm_plug_clear(snd_pcm_t *handle, int channel);
|
int snd_pcm_plug_clear(snd_pcm_t *handle, int stream);
|
||||||
int snd_pcm_plugin_insert(snd_pcm_plugin_t *plugin);
|
int snd_pcm_plugin_insert(snd_pcm_plugin_t *plugin);
|
||||||
int snd_pcm_plugin_append(snd_pcm_plugin_t *plugin);
|
int snd_pcm_plugin_append(snd_pcm_plugin_t *plugin);
|
||||||
#if 0
|
#if 0
|
||||||
int snd_pcm_plugin_remove_to(snd_pcm_plugin_t *plugin);
|
int snd_pcm_plugin_remove_to(snd_pcm_plugin_t *plugin);
|
||||||
int snd_pcm_plug_remove_first(snd_pcm_t *handle, int channel);
|
int snd_pcm_plug_remove_first(snd_pcm_t *handle, int stream);
|
||||||
#endif
|
#endif
|
||||||
snd_pcm_plugin_t *snd_pcm_plug_first(snd_pcm_t *handle, int channel);
|
snd_pcm_plugin_t *snd_pcm_plug_first(snd_pcm_t *handle, int stream);
|
||||||
snd_pcm_plugin_t *snd_pcm_plug_last(snd_pcm_t *handle, int channel);
|
snd_pcm_plugin_t *snd_pcm_plug_last(snd_pcm_t *handle, int stream);
|
||||||
int snd_pcm_plug_direct(snd_pcm_t *pcm, int channel);
|
int snd_pcm_plug_direct(snd_pcm_t *pcm, int stream);
|
||||||
ssize_t snd_pcm_plug_client_frames(snd_pcm_t *handle, int channel, size_t drv_frames);
|
ssize_t snd_pcm_plug_client_frames(snd_pcm_t *handle, int stream, size_t drv_frames);
|
||||||
ssize_t snd_pcm_plug_slave_frames(snd_pcm_t *handle, int channel, size_t clt_frames);
|
ssize_t snd_pcm_plug_slave_frames(snd_pcm_t *handle, int stream, size_t clt_frames);
|
||||||
ssize_t snd_pcm_plug_client_size(snd_pcm_t *handle, int channel, size_t drv_size);
|
ssize_t snd_pcm_plug_client_size(snd_pcm_t *handle, int stream, size_t drv_size);
|
||||||
ssize_t snd_pcm_plug_slave_size(snd_pcm_t *handle, int channel, size_t clt_size);
|
ssize_t snd_pcm_plug_slave_size(snd_pcm_t *handle, int stream, size_t clt_size);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Plug-In helpers
|
* Plug-In helpers
|
||||||
|
|
@ -284,7 +284,7 @@ ssize_t snd_pcm_plugin_dst_size_to_frames(snd_pcm_plugin_t *plugin, size_t size)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int snd_pcm_plugin_build(snd_pcm_plugin_handle_t *handle,
|
int snd_pcm_plugin_build(snd_pcm_plugin_handle_t *handle,
|
||||||
int channel,
|
int stream,
|
||||||
const char *name,
|
const char *name,
|
||||||
snd_pcm_format_t *src_format,
|
snd_pcm_format_t *src_format,
|
||||||
snd_pcm_format_t *dst_format,
|
snd_pcm_format_t *dst_format,
|
||||||
|
|
@ -292,12 +292,12 @@ int snd_pcm_plugin_build(snd_pcm_plugin_handle_t *handle,
|
||||||
snd_pcm_plugin_t **ret);
|
snd_pcm_plugin_t **ret);
|
||||||
/* basic I/O */
|
/* basic I/O */
|
||||||
int snd_pcm_plugin_build_io(snd_pcm_plugin_handle_t *handle,
|
int snd_pcm_plugin_build_io(snd_pcm_plugin_handle_t *handle,
|
||||||
int channel,
|
int stream,
|
||||||
snd_pcm_t *slave,
|
snd_pcm_t *slave,
|
||||||
snd_pcm_format_t *format,
|
snd_pcm_format_t *format,
|
||||||
snd_pcm_plugin_t **r_plugin);
|
snd_pcm_plugin_t **r_plugin);
|
||||||
int snd_pcm_plugin_build_mmap(snd_pcm_plugin_handle_t *handle,
|
int snd_pcm_plugin_build_mmap(snd_pcm_plugin_handle_t *handle,
|
||||||
int channel,
|
int stream,
|
||||||
snd_pcm_t *slave,
|
snd_pcm_t *slave,
|
||||||
snd_pcm_format_t *format,
|
snd_pcm_format_t *format,
|
||||||
snd_pcm_plugin_t **r_plugin);
|
snd_pcm_plugin_t **r_plugin);
|
||||||
|
|
@ -315,43 +315,43 @@ typedef int route_ttable_entry_t;
|
||||||
|
|
||||||
/* conversion plugins */
|
/* conversion plugins */
|
||||||
int snd_pcm_plugin_build_interleave(snd_pcm_plugin_handle_t *handle,
|
int snd_pcm_plugin_build_interleave(snd_pcm_plugin_handle_t *handle,
|
||||||
int channel,
|
int stream,
|
||||||
snd_pcm_format_t *src_format,
|
snd_pcm_format_t *src_format,
|
||||||
snd_pcm_format_t *dst_format,
|
snd_pcm_format_t *dst_format,
|
||||||
snd_pcm_plugin_t **r_plugin);
|
snd_pcm_plugin_t **r_plugin);
|
||||||
int snd_pcm_plugin_build_linear(snd_pcm_plugin_handle_t *handle,
|
int snd_pcm_plugin_build_linear(snd_pcm_plugin_handle_t *handle,
|
||||||
int channel,
|
int stream,
|
||||||
snd_pcm_format_t *src_format,
|
snd_pcm_format_t *src_format,
|
||||||
snd_pcm_format_t *dst_format,
|
snd_pcm_format_t *dst_format,
|
||||||
snd_pcm_plugin_t **r_plugin);
|
snd_pcm_plugin_t **r_plugin);
|
||||||
int snd_pcm_plugin_build_mulaw(snd_pcm_plugin_handle_t *handle,
|
int snd_pcm_plugin_build_mulaw(snd_pcm_plugin_handle_t *handle,
|
||||||
int channel,
|
int stream,
|
||||||
snd_pcm_format_t *src_format,
|
snd_pcm_format_t *src_format,
|
||||||
snd_pcm_format_t *dst_format,
|
snd_pcm_format_t *dst_format,
|
||||||
snd_pcm_plugin_t **r_plugin);
|
snd_pcm_plugin_t **r_plugin);
|
||||||
int snd_pcm_plugin_build_alaw(snd_pcm_plugin_handle_t *handle,
|
int snd_pcm_plugin_build_alaw(snd_pcm_plugin_handle_t *handle,
|
||||||
int channel,
|
int stream,
|
||||||
snd_pcm_format_t *src_format,
|
snd_pcm_format_t *src_format,
|
||||||
snd_pcm_format_t *dst_format,
|
snd_pcm_format_t *dst_format,
|
||||||
snd_pcm_plugin_t **r_plugin);
|
snd_pcm_plugin_t **r_plugin);
|
||||||
int snd_pcm_plugin_build_adpcm(snd_pcm_plugin_handle_t *handle,
|
int snd_pcm_plugin_build_adpcm(snd_pcm_plugin_handle_t *handle,
|
||||||
int channel,
|
int stream,
|
||||||
snd_pcm_format_t *src_format,
|
snd_pcm_format_t *src_format,
|
||||||
snd_pcm_format_t *dst_format,
|
snd_pcm_format_t *dst_format,
|
||||||
snd_pcm_plugin_t **r_plugin);
|
snd_pcm_plugin_t **r_plugin);
|
||||||
int snd_pcm_plugin_build_rate(snd_pcm_plugin_handle_t *handle,
|
int snd_pcm_plugin_build_rate(snd_pcm_plugin_handle_t *handle,
|
||||||
int channel,
|
int stream,
|
||||||
snd_pcm_format_t *src_format,
|
snd_pcm_format_t *src_format,
|
||||||
snd_pcm_format_t *dst_format,
|
snd_pcm_format_t *dst_format,
|
||||||
snd_pcm_plugin_t **r_plugin);
|
snd_pcm_plugin_t **r_plugin);
|
||||||
int snd_pcm_plugin_build_route(snd_pcm_plugin_handle_t *handle,
|
int snd_pcm_plugin_build_route(snd_pcm_plugin_handle_t *handle,
|
||||||
int channel,
|
int stream,
|
||||||
snd_pcm_format_t *src_format,
|
snd_pcm_format_t *src_format,
|
||||||
snd_pcm_format_t *dst_format,
|
snd_pcm_format_t *dst_format,
|
||||||
route_ttable_entry_t *ttable,
|
route_ttable_entry_t *ttable,
|
||||||
snd_pcm_plugin_t **r_plugin);
|
snd_pcm_plugin_t **r_plugin);
|
||||||
int snd_pcm_plugin_build_copy(snd_pcm_plugin_handle_t *handle,
|
int snd_pcm_plugin_build_copy(snd_pcm_plugin_handle_t *handle,
|
||||||
int channel,
|
int stream,
|
||||||
snd_pcm_format_t *src_format,
|
snd_pcm_format_t *src_format,
|
||||||
snd_pcm_format_t *dst_format,
|
snd_pcm_format_t *dst_format,
|
||||||
snd_pcm_plugin_t **r_plugin);
|
snd_pcm_plugin_t **r_plugin);
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,13 @@ int snd_rawmidi_close(snd_rawmidi_t *handle);
|
||||||
int snd_rawmidi_file_descriptor(snd_rawmidi_t *handle);
|
int snd_rawmidi_file_descriptor(snd_rawmidi_t *handle);
|
||||||
int snd_rawmidi_block_mode(snd_rawmidi_t *handle, int enable);
|
int snd_rawmidi_block_mode(snd_rawmidi_t *handle, int enable);
|
||||||
int snd_rawmidi_info(snd_rawmidi_t *handle, snd_rawmidi_info_t * info);
|
int snd_rawmidi_info(snd_rawmidi_t *handle, snd_rawmidi_info_t * info);
|
||||||
int snd_rawmidi_channel_params(snd_rawmidi_t *handle, snd_rawmidi_params_t * params);
|
int snd_rawmidi_stream_params(snd_rawmidi_t *handle, snd_rawmidi_params_t * params);
|
||||||
int snd_rawmidi_channel_setup(snd_rawmidi_t *handle, snd_rawmidi_setup_t * setup);
|
int snd_rawmidi_stream_setup(snd_rawmidi_t *handle, snd_rawmidi_setup_t * setup);
|
||||||
int snd_rawmidi_channel_status(snd_rawmidi_t *handle, snd_rawmidi_status_t * status);
|
int snd_rawmidi_stream_status(snd_rawmidi_t *handle, snd_rawmidi_status_t * status);
|
||||||
int snd_rawmidi_output_drain(snd_rawmidi_t *handle);
|
int snd_rawmidi_output_drain(snd_rawmidi_t *handle);
|
||||||
int snd_rawmidi_output_flush(snd_rawmidi_t *handle);
|
int snd_rawmidi_output_flush(snd_rawmidi_t *handle);
|
||||||
int snd_rawmidi_input_flush(snd_rawmidi_t *handle);
|
int snd_rawmidi_input_flush(snd_rawmidi_t *handle);
|
||||||
int snd_rawmidi_channel_flush(snd_rawmidi_t *handle, int channel);
|
int snd_rawmidi_stream_flush(snd_rawmidi_t *handle, int channel);
|
||||||
ssize_t snd_rawmidi_write(snd_rawmidi_t *handle, const void *buffer, size_t size);
|
ssize_t snd_rawmidi_write(snd_rawmidi_t *handle, const void *buffer, size_t size);
|
||||||
ssize_t snd_rawmidi_read(snd_rawmidi_t *handle, void *buffer, size_t size);
|
ssize_t snd_rawmidi_read(snd_rawmidi_t *handle, void *buffer, size_t size);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -171,34 +171,34 @@ int snd_ctl_pcm_info(snd_ctl_t *handle, int dev, snd_pcm_info_t * info)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_ctl_pcm_channel_info(snd_ctl_t *handle, int dev, int chn, int subdev, snd_pcm_channel_info_t * info)
|
int snd_ctl_pcm_stream_info(snd_ctl_t *handle, int dev, int str, int subdev, snd_pcm_stream_info_t * info)
|
||||||
{
|
{
|
||||||
snd_ctl_t *ctl;
|
snd_ctl_t *ctl;
|
||||||
|
|
||||||
ctl = handle;
|
ctl = handle;
|
||||||
if (!ctl || !info || dev < 0 || chn < 0 || chn > 1 || subdev < 0)
|
if (!ctl || !info || dev < 0 || str < 0 || str > 1 || subdev < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_DEVICE, &dev) < 0)
|
if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_DEVICE, &dev) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_CHANNEL, &chn) < 0)
|
if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_STREAM, &str) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_SUBDEVICE, &subdev) < 0)
|
if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_SUBDEVICE, &subdev) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_CHANNEL_INFO, info) < 0)
|
if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_STREAM_INFO, info) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_ctl_pcm_channel_prefer_subdevice(snd_ctl_t *handle, int dev, int chn, int subdev)
|
int snd_ctl_pcm_stream_prefer_subdevice(snd_ctl_t *handle, int dev, int str, int subdev)
|
||||||
{
|
{
|
||||||
snd_ctl_t *ctl;
|
snd_ctl_t *ctl;
|
||||||
|
|
||||||
ctl = handle;
|
ctl = handle;
|
||||||
if (!ctl || dev < 0 || chn < 0 || chn > 1)
|
if (!ctl || dev < 0 || str < 0 || str > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_DEVICE, &dev) < 0)
|
if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_DEVICE, &dev) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_CHANNEL, &chn) < 0)
|
if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_STREAM, &str) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_PREFER_SUBDEVICE, &subdev) < 0)
|
if (ioctl(ctl->fd, SND_CTL_IOCTL_PCM_PREFER_SUBDEVICE, &subdev) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
@ -261,7 +261,7 @@ int snd_ctl_read(snd_ctl_t *handle, snd_ctl_callbacks_t * callbacks)
|
||||||
callbacks->xswitch(callbacks->private_data,
|
callbacks->xswitch(callbacks->private_data,
|
||||||
r.cmd, r.data.sw.iface,
|
r.cmd, r.data.sw.iface,
|
||||||
r.data.sw.device,
|
r.data.sw.device,
|
||||||
r.data.sw.channel,
|
r.data.sw.stream,
|
||||||
&r.data.sw.switem);
|
&r.data.sw.switem);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -73,10 +73,10 @@ int snd_mixer_element_info_build(snd_mixer_t *handle, snd_mixer_element_info_t *
|
||||||
switch (element->eid.type) {
|
switch (element->eid.type) {
|
||||||
case SND_MIXER_ETYPE_INPUT:
|
case SND_MIXER_ETYPE_INPUT:
|
||||||
case SND_MIXER_ETYPE_OUTPUT:
|
case SND_MIXER_ETYPE_OUTPUT:
|
||||||
element->data.io.voices_size = element->data.io.voices_over;
|
element->data.io.channels_size = element->data.io.channels_over;
|
||||||
element->data.io.voices = element->data.io.voices_over = 0;
|
element->data.io.channels = element->data.io.channels_over = 0;
|
||||||
element->data.io.pvoices = (snd_mixer_voice_t *)malloc(element->data.io.voices_size * sizeof(snd_mixer_voice_t));
|
element->data.io.pchannels = (snd_mixer_channel_t *)malloc(element->data.io.channels_size * sizeof(snd_mixer_channel_t));
|
||||||
if (!element->data.io.pvoices)
|
if (!element->data.io.pchannels)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
if ((err = snd_mixer_element_info(handle, element)) < 0)
|
if ((err = snd_mixer_element_info(handle, element)) < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
@ -101,16 +101,16 @@ int snd_mixer_element_info_build(snd_mixer_t *handle, snd_mixer_element_info_t *
|
||||||
return err;
|
return err;
|
||||||
break;
|
break;
|
||||||
case SND_MIXER_ETYPE_VOLUME2:
|
case SND_MIXER_ETYPE_VOLUME2:
|
||||||
element->data.volume2.svoices_size = element->data.volume2.svoices_over;
|
element->data.volume2.schannels_size = element->data.volume2.schannels_over;
|
||||||
element->data.volume2.svoices = element->data.volume2.svoices_over = 0;
|
element->data.volume2.schannels = element->data.volume2.schannels_over = 0;
|
||||||
element->data.volume2.psvoices = (snd_mixer_voice_t *)malloc(element->data.volume2.svoices_size * sizeof(snd_mixer_voice_t));
|
element->data.volume2.pschannels = (snd_mixer_channel_t *)malloc(element->data.volume2.schannels_size * sizeof(snd_mixer_channel_t));
|
||||||
if (!element->data.volume2.psvoices)
|
if (!element->data.volume2.pschannels)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
element->data.volume2.range_size = element->data.volume2.range_over;
|
element->data.volume2.range_size = element->data.volume2.range_over;
|
||||||
element->data.volume2.range = element->data.volume2.range_over = 0;
|
element->data.volume2.range = element->data.volume2.range_over = 0;
|
||||||
element->data.volume2.prange = (struct snd_mixer_element_volume2_range *)malloc(element->data.volume2.range_size * sizeof(struct snd_mixer_element_volume2_range));
|
element->data.volume2.prange = (struct snd_mixer_element_volume2_range *)malloc(element->data.volume2.range_size * sizeof(struct snd_mixer_element_volume2_range));
|
||||||
if (!element->data.volume1.prange) {
|
if (!element->data.volume1.prange) {
|
||||||
safe_free((void **)&element->data.volume2.psvoices);
|
safe_free((void **)&element->data.volume2.pschannels);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
if ((err = snd_mixer_element_info(handle, element)) < 0)
|
if ((err = snd_mixer_element_info(handle, element)) < 0)
|
||||||
|
|
@ -161,7 +161,7 @@ int snd_mixer_element_info_free(snd_mixer_element_info_t *element)
|
||||||
switch (element->eid.type) {
|
switch (element->eid.type) {
|
||||||
case SND_MIXER_ETYPE_INPUT:
|
case SND_MIXER_ETYPE_INPUT:
|
||||||
case SND_MIXER_ETYPE_OUTPUT:
|
case SND_MIXER_ETYPE_OUTPUT:
|
||||||
safe_free((void **)&element->data.io.pvoices);
|
safe_free((void **)&element->data.io.pchannels);
|
||||||
break;
|
break;
|
||||||
case SND_MIXER_ETYPE_CAPTURE1:
|
case SND_MIXER_ETYPE_CAPTURE1:
|
||||||
case SND_MIXER_ETYPE_PLAYBACK1:
|
case SND_MIXER_ETYPE_PLAYBACK1:
|
||||||
|
|
@ -171,7 +171,7 @@ int snd_mixer_element_info_free(snd_mixer_element_info_t *element)
|
||||||
safe_free((void **)&element->data.volume1.prange);
|
safe_free((void **)&element->data.volume1.prange);
|
||||||
break;
|
break;
|
||||||
case SND_MIXER_ETYPE_VOLUME2:
|
case SND_MIXER_ETYPE_VOLUME2:
|
||||||
safe_free((void **)&element->data.volume2.psvoices);
|
safe_free((void **)&element->data.volume2.pschannels);
|
||||||
safe_free((void **)&element->data.volume1.prange);
|
safe_free((void **)&element->data.volume1.prange);
|
||||||
break;
|
break;
|
||||||
case SND_MIXER_ETYPE_ACCU3:
|
case SND_MIXER_ETYPE_ACCU3:
|
||||||
|
|
@ -238,28 +238,28 @@ int snd_mixer_element_build(snd_mixer_t *handle, snd_mixer_element_t *element)
|
||||||
return err;
|
return err;
|
||||||
break;
|
break;
|
||||||
case SND_MIXER_ETYPE_VOLUME1:
|
case SND_MIXER_ETYPE_VOLUME1:
|
||||||
element->data.volume1.voices_size = element->data.volume1.voices_over;
|
element->data.volume1.channels_size = element->data.volume1.channels_over;
|
||||||
element->data.volume1.voices = element->data.volume1.voices_over = 0;
|
element->data.volume1.channels = element->data.volume1.channels_over = 0;
|
||||||
element->data.volume1.pvoices = (int *)malloc(element->data.volume1.voices_size * sizeof(int));
|
element->data.volume1.pchannels = (int *)malloc(element->data.volume1.channels_size * sizeof(int));
|
||||||
if (!element->data.volume1.pvoices)
|
if (!element->data.volume1.pchannels)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
if ((err = snd_mixer_element_read(handle, element)) < 0)
|
if ((err = snd_mixer_element_read(handle, element)) < 0)
|
||||||
return err;
|
return err;
|
||||||
break;
|
break;
|
||||||
case SND_MIXER_ETYPE_VOLUME2:
|
case SND_MIXER_ETYPE_VOLUME2:
|
||||||
element->data.volume2.avoices_size = element->data.volume2.avoices_over;
|
element->data.volume2.achannels_size = element->data.volume2.achannels_over;
|
||||||
element->data.volume2.avoices = element->data.volume2.avoices_over = 0;
|
element->data.volume2.achannels = element->data.volume2.achannels_over = 0;
|
||||||
element->data.volume2.pavoices = (int *)malloc(element->data.volume2.avoices_size * sizeof(int));
|
element->data.volume2.pachannels = (int *)malloc(element->data.volume2.achannels_size * sizeof(int));
|
||||||
if (!element->data.volume2.pavoices)
|
if (!element->data.volume2.pachannels)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
if ((err = snd_mixer_element_read(handle, element)) < 0)
|
if ((err = snd_mixer_element_read(handle, element)) < 0)
|
||||||
return err;
|
return err;
|
||||||
break;
|
break;
|
||||||
case SND_MIXER_ETYPE_ACCU3:
|
case SND_MIXER_ETYPE_ACCU3:
|
||||||
element->data.accu3.voices_size = element->data.accu3.voices_over;
|
element->data.accu3.channels_size = element->data.accu3.channels_over;
|
||||||
element->data.accu3.voices = element->data.accu3.voices_over = 0;
|
element->data.accu3.channels = element->data.accu3.channels_over = 0;
|
||||||
element->data.accu3.pvoices = (int *)malloc(element->data.accu3.voices_size * sizeof(int));
|
element->data.accu3.pchannels = (int *)malloc(element->data.accu3.channels_size * sizeof(int));
|
||||||
if (!element->data.accu3.pvoices)
|
if (!element->data.accu3.pchannels)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
if ((err = snd_mixer_element_read(handle, element)) < 0)
|
if ((err = snd_mixer_element_read(handle, element)) < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
@ -309,13 +309,13 @@ int snd_mixer_element_free(snd_mixer_element_t *element)
|
||||||
safe_free((void **)&element->data.switch3.prsw);
|
safe_free((void **)&element->data.switch3.prsw);
|
||||||
break;
|
break;
|
||||||
case SND_MIXER_ETYPE_VOLUME1:
|
case SND_MIXER_ETYPE_VOLUME1:
|
||||||
safe_free((void **)&element->data.volume1.pvoices);
|
safe_free((void **)&element->data.volume1.pchannels);
|
||||||
break;
|
break;
|
||||||
case SND_MIXER_ETYPE_VOLUME2:
|
case SND_MIXER_ETYPE_VOLUME2:
|
||||||
safe_free((void **)&element->data.volume2.pavoices);
|
safe_free((void **)&element->data.volume2.pachannels);
|
||||||
break;
|
break;
|
||||||
case SND_MIXER_ETYPE_ACCU3:
|
case SND_MIXER_ETYPE_ACCU3:
|
||||||
safe_free((void **)&element->data.accu3.pvoices);
|
safe_free((void **)&element->data.accu3.pchannels);
|
||||||
break;
|
break;
|
||||||
case SND_MIXER_ETYPE_MUX1:
|
case SND_MIXER_ETYPE_MUX1:
|
||||||
safe_free((void **)&element->data.mux1.psel);
|
safe_free((void **)&element->data.mux1.psel);
|
||||||
|
|
|
||||||
342
src/pcm/pcm.c
342
src/pcm/pcm.c
|
|
@ -40,14 +40,14 @@ int snd_pcm_abstract_open(snd_pcm_t **handle, int mode,
|
||||||
if (pcm == NULL)
|
if (pcm == NULL)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
if (mode & SND_PCM_OPEN_PLAYBACK) {
|
if (mode & SND_PCM_OPEN_PLAYBACK) {
|
||||||
struct snd_pcm_chan *chan = &pcm->chan[SND_PCM_CHANNEL_PLAYBACK];
|
struct snd_pcm_stream *str = &pcm->stream[SND_PCM_STREAM_PLAYBACK];
|
||||||
chan->open = 1;
|
str->open = 1;
|
||||||
chan->mode = (mode & SND_PCM_NONBLOCK_PLAYBACK) ? SND_PCM_NONBLOCK : 0;
|
str->mode = (mode & SND_PCM_NONBLOCK_PLAYBACK) ? SND_PCM_NONBLOCK : 0;
|
||||||
}
|
}
|
||||||
if (mode & SND_PCM_OPEN_CAPTURE) {
|
if (mode & SND_PCM_OPEN_CAPTURE) {
|
||||||
struct snd_pcm_chan *chan = &pcm->chan[SND_PCM_CHANNEL_CAPTURE];
|
struct snd_pcm_stream *str = &pcm->stream[SND_PCM_STREAM_CAPTURE];
|
||||||
chan->open = 1;
|
str->open = 1;
|
||||||
chan->mode = (mode & SND_PCM_NONBLOCK_CAPTURE) ? SND_PCM_NONBLOCK : 0;
|
str->mode = (mode & SND_PCM_NONBLOCK_CAPTURE) ? SND_PCM_NONBLOCK : 0;
|
||||||
}
|
}
|
||||||
pcm->type = type;
|
pcm->type = type;
|
||||||
pcm->mode = mode & SND_PCM_OPEN_DUPLEX;
|
pcm->mode = mode & SND_PCM_OPEN_DUPLEX;
|
||||||
|
|
@ -60,43 +60,43 @@ snd_pcm_type_t snd_pcm_type(snd_pcm_t *handle)
|
||||||
return handle->type;
|
return handle->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_channel_close(snd_pcm_t *pcm, int channel)
|
int snd_pcm_stream_close(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int err;
|
int err;
|
||||||
struct snd_pcm_chan *chan;
|
struct snd_pcm_stream *str;
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (channel < 0 || channel > 1)
|
if (stream < 0 || stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
chan = &pcm->chan[channel];
|
str = &pcm->stream[stream];
|
||||||
if (!chan->open)
|
if (!str->open)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
if (chan->mmap_control) {
|
if (str->mmap_control) {
|
||||||
if ((err = snd_pcm_munmap_control(pcm, channel)) < 0)
|
if ((err = snd_pcm_munmap_control(pcm, stream)) < 0)
|
||||||
ret = err;
|
ret = err;
|
||||||
}
|
}
|
||||||
if (chan->mmap_data) {
|
if (str->mmap_data) {
|
||||||
if ((err = snd_pcm_munmap_data(pcm, channel)) < 0)
|
if ((err = snd_pcm_munmap_data(pcm, stream)) < 0)
|
||||||
ret = err;
|
ret = err;
|
||||||
}
|
}
|
||||||
if ((err = pcm->ops->channel_close(pcm, channel)) < 0)
|
if ((err = pcm->ops->stream_close(pcm, stream)) < 0)
|
||||||
ret = err;
|
ret = err;
|
||||||
chan->open = 0;
|
str->open = 0;
|
||||||
chan->valid_setup = 0;
|
str->valid_setup = 0;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_close(snd_pcm_t *pcm)
|
int snd_pcm_close(snd_pcm_t *pcm)
|
||||||
{
|
{
|
||||||
int err, ret = 0;
|
int err, ret = 0;
|
||||||
int channel;
|
int stream;
|
||||||
|
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
for (channel = 0; channel < 2; ++channel) {
|
for (stream = 0; stream < 2; ++stream) {
|
||||||
if (pcm->chan[channel].open) {
|
if (pcm->stream[stream].open) {
|
||||||
if ((err = snd_pcm_channel_close(pcm, channel)) < 0)
|
if ((err = snd_pcm_stream_close(pcm, stream)) < 0)
|
||||||
ret = err;
|
ret = err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -104,21 +104,21 @@ int snd_pcm_close(snd_pcm_t *pcm)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_channel_nonblock(snd_pcm_t *pcm, int channel, int nonblock)
|
int snd_pcm_stream_nonblock(snd_pcm_t *pcm, int stream, int nonblock)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (channel < 0 || channel > 1)
|
if (stream < 0 || stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!pcm->chan[channel].open)
|
if (!pcm->stream[stream].open)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
if ((err = pcm->ops->channel_nonblock(pcm, channel, nonblock)) < 0)
|
if ((err = pcm->ops->stream_nonblock(pcm, stream, nonblock)) < 0)
|
||||||
return err;
|
return err;
|
||||||
if (nonblock)
|
if (nonblock)
|
||||||
pcm->chan[channel].mode |= SND_PCM_NONBLOCK;
|
pcm->stream[stream].mode |= SND_PCM_NONBLOCK;
|
||||||
else
|
else
|
||||||
pcm->chan[channel].mode &= ~SND_PCM_NONBLOCK;
|
pcm->stream[stream].mode &= ~SND_PCM_NONBLOCK;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -129,190 +129,190 @@ int snd_pcm_info(snd_pcm_t *pcm, snd_pcm_info_t *info)
|
||||||
return pcm->ops->info(pcm, info);
|
return pcm->ops->info(pcm, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *info)
|
int snd_pcm_stream_info(snd_pcm_t *pcm, snd_pcm_stream_info_t *info)
|
||||||
{
|
{
|
||||||
if (!pcm || !info)
|
if (!pcm || !info)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (info->channel < 0 || info->channel > 1)
|
if (info->stream < 0 || info->stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!pcm->chan[info->channel].open)
|
if (!pcm->stream[info->stream].open)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
return pcm->ops->channel_info(pcm, info);
|
return pcm->ops->stream_info(pcm, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_channel_params(snd_pcm_t *pcm, snd_pcm_channel_params_t *params)
|
int snd_pcm_stream_params(snd_pcm_t *pcm, snd_pcm_stream_params_t *params)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
snd_pcm_channel_setup_t setup;
|
snd_pcm_stream_setup_t setup;
|
||||||
struct snd_pcm_chan *chan;
|
struct snd_pcm_stream *str;
|
||||||
if (!pcm || !params)
|
if (!pcm || !params)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (params->channel < 0 || params->channel > 1)
|
if (params->stream < 0 || params->stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
chan = &pcm->chan[params->channel];
|
str = &pcm->stream[params->stream];
|
||||||
if (!chan->open)
|
if (!str->open)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
if (chan->mmap_control)
|
if (str->mmap_control)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
if ((err = pcm->ops->channel_params(pcm, params)) < 0)
|
if ((err = pcm->ops->stream_params(pcm, params)) < 0)
|
||||||
return err;
|
return err;
|
||||||
chan->valid_setup = 0;
|
str->valid_setup = 0;
|
||||||
setup.channel = params->channel;
|
setup.stream = params->stream;
|
||||||
return snd_pcm_channel_setup(pcm, &setup);
|
return snd_pcm_stream_setup(pcm, &setup);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_channel_setup(snd_pcm_t *pcm, snd_pcm_channel_setup_t *setup)
|
int snd_pcm_stream_setup(snd_pcm_t *pcm, snd_pcm_stream_setup_t *setup)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
struct snd_pcm_chan *chan;
|
struct snd_pcm_stream *str;
|
||||||
if (!pcm || !setup)
|
if (!pcm || !setup)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (setup->channel < 0 || setup->channel > 1)
|
if (setup->stream < 0 || setup->stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
chan = &pcm->chan[setup->channel];
|
str = &pcm->stream[setup->stream];
|
||||||
if (!chan->open)
|
if (!str->open)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
if (chan->valid_setup) {
|
if (str->valid_setup) {
|
||||||
memcpy(setup, &chan->setup, sizeof(*setup));
|
memcpy(setup, &str->setup, sizeof(*setup));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if ((err = pcm->ops->channel_setup(pcm, setup)) < 0)
|
if ((err = pcm->ops->stream_setup(pcm, setup)) < 0)
|
||||||
return err;
|
return err;
|
||||||
memcpy(&chan->setup, setup, sizeof(*setup));
|
memcpy(&str->setup, setup, sizeof(*setup));
|
||||||
chan->sample_width = snd_pcm_format_physical_width(setup->format.format);
|
str->sample_width = snd_pcm_format_physical_width(setup->format.format);
|
||||||
chan->bits_per_frame = chan->sample_width * setup->format.voices;
|
str->bits_per_frame = str->sample_width * setup->format.channels;
|
||||||
chan->frames_per_frag = setup->frag_size * 8 / chan->bits_per_frame;
|
str->frames_per_frag = setup->frag_size * 8 / str->bits_per_frame;
|
||||||
chan->valid_setup = 1;
|
str->valid_setup = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
const snd_pcm_channel_setup_t* snd_pcm_channel_cached_setup(snd_pcm_t *pcm, int channel)
|
const snd_pcm_stream_setup_t* snd_pcm_stream_cached_setup(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
struct snd_pcm_chan *chan;
|
struct snd_pcm_stream *str;
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return 0;
|
return 0;
|
||||||
if (channel < 0 || channel > 1)
|
if (stream < 0 || stream > 1)
|
||||||
return 0;
|
return 0;
|
||||||
chan = &pcm->chan[channel];
|
str = &pcm->stream[stream];
|
||||||
if (!chan->open || !chan->valid_setup)
|
if (!str->open || !str->valid_setup)
|
||||||
return 0;
|
return 0;
|
||||||
return &chan->setup;
|
return &str->setup;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_voice_setup(snd_pcm_t *pcm, int channel, snd_pcm_voice_setup_t *setup)
|
int snd_pcm_channel_setup(snd_pcm_t *pcm, int stream, snd_pcm_channel_setup_t *setup)
|
||||||
{
|
{
|
||||||
struct snd_pcm_chan *chan;
|
struct snd_pcm_stream *str;
|
||||||
if (!pcm || !setup)
|
if (!pcm || !setup)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (channel < 0 || channel > 1)
|
if (stream < 0 || stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
chan = &pcm->chan[channel];
|
str = &pcm->stream[stream];
|
||||||
if (!chan->open || !chan->valid_setup)
|
if (!str->open || !str->valid_setup)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
return pcm->ops->voice_setup(pcm, channel, setup);
|
return pcm->ops->channel_setup(pcm, stream, setup);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_channel_status(snd_pcm_t *pcm, snd_pcm_channel_status_t *status)
|
int snd_pcm_stream_status(snd_pcm_t *pcm, snd_pcm_stream_status_t *status)
|
||||||
{
|
{
|
||||||
if (!pcm || !status)
|
if (!pcm || !status)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (status->channel < 0 || status->channel > 1)
|
if (status->stream < 0 || status->stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!pcm->chan[status->channel].open)
|
if (!pcm->stream[status->stream].open)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
return pcm->ops->channel_status(pcm, status);
|
return pcm->ops->stream_status(pcm, status);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_channel_update(snd_pcm_t *pcm, int channel)
|
int snd_pcm_stream_update(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (channel < 0 || channel > 1)
|
if (stream < 0 || stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!pcm->chan[channel].open)
|
if (!pcm->stream[stream].open)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
err = pcm->ops->channel_update(pcm, channel);
|
err = pcm->ops->stream_update(pcm, stream);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
snd_pcm_mmap_status_change(pcm, channel, -1);
|
snd_pcm_mmap_status_streamge(pcm, stream, -1);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_channel_prepare(snd_pcm_t *pcm, int channel)
|
int snd_pcm_stream_prepare(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (channel < 0 || channel > 1)
|
if (stream < 0 || stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!pcm->chan[channel].open)
|
if (!pcm->stream[stream].open)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
err = pcm->ops->channel_prepare(pcm, channel);
|
err = pcm->ops->stream_prepare(pcm, stream);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
snd_pcm_mmap_status_change(pcm, channel, SND_PCM_STATUS_PREPARED);
|
snd_pcm_mmap_status_streamge(pcm, stream, SND_PCM_STATUS_PREPARED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_playback_prepare(snd_pcm_t *pcm)
|
int snd_pcm_playback_prepare(snd_pcm_t *pcm)
|
||||||
{
|
{
|
||||||
return snd_pcm_channel_prepare(pcm, SND_PCM_CHANNEL_PLAYBACK);
|
return snd_pcm_stream_prepare(pcm, SND_PCM_STREAM_PLAYBACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_capture_prepare(snd_pcm_t *pcm)
|
int snd_pcm_capture_prepare(snd_pcm_t *pcm)
|
||||||
{
|
{
|
||||||
return snd_pcm_channel_prepare(pcm, SND_PCM_CHANNEL_CAPTURE);
|
return snd_pcm_stream_prepare(pcm, SND_PCM_STREAM_CAPTURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int mmap_playback_go(snd_pcm_t *pcm, int channel)
|
static int mmap_playback_go(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
struct snd_pcm_chan *chan = &pcm->chan[channel];
|
struct snd_pcm_stream *str = &pcm->stream[stream];
|
||||||
if (chan->mmap_control->status != SND_PCM_STATUS_PREPARED)
|
if (str->mmap_control->status != SND_PCM_STATUS_PREPARED)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
if (chan->mmap_control->byte_data == 0)
|
if (str->mmap_control->byte_data == 0)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
chan->mmap_control->status = SND_PCM_STATUS_RUNNING;
|
str->mmap_control->status = SND_PCM_STATUS_RUNNING;
|
||||||
pthread_mutex_lock(&chan->mutex);
|
pthread_mutex_lock(&str->mutex);
|
||||||
pthread_cond_signal(&chan->status_cond);
|
pthread_cond_signal(&str->status_cond);
|
||||||
pthread_cond_wait(&chan->ready_cond, &chan->mutex);
|
pthread_cond_wait(&str->ready_cond, &str->mutex);
|
||||||
pthread_mutex_unlock(&chan->mutex);
|
pthread_mutex_unlock(&str->mutex);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_channel_go(snd_pcm_t *pcm, int channel)
|
int snd_pcm_stream_go(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
struct snd_pcm_chan *chan;
|
struct snd_pcm_stream *str;
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (channel < 0 || channel > 1)
|
if (stream < 0 || stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
chan = &pcm->chan[channel];
|
str = &pcm->stream[stream];
|
||||||
if (!chan->open)
|
if (!str->open)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
if (channel == SND_PCM_CHANNEL_PLAYBACK &&
|
if (stream == SND_PCM_STREAM_PLAYBACK &&
|
||||||
chan->mmap_data_emulation) {
|
str->mmap_data_emulation) {
|
||||||
err = mmap_playback_go(pcm, channel);
|
err = mmap_playback_go(pcm, stream);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
err = pcm->ops->channel_go(pcm, channel);
|
err = pcm->ops->stream_go(pcm, stream);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
if (channel == SND_PCM_CHANNEL_CAPTURE)
|
if (stream == SND_PCM_STREAM_CAPTURE)
|
||||||
snd_pcm_mmap_status_change(pcm, channel, SND_PCM_STATUS_RUNNING);
|
snd_pcm_mmap_status_streamge(pcm, stream, SND_PCM_STATUS_RUNNING);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_playback_go(snd_pcm_t *pcm)
|
int snd_pcm_playback_go(snd_pcm_t *pcm)
|
||||||
{
|
{
|
||||||
return snd_pcm_channel_go(pcm, SND_PCM_CHANNEL_PLAYBACK);
|
return snd_pcm_stream_go(pcm, SND_PCM_STREAM_PLAYBACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_capture_go(snd_pcm_t *pcm)
|
int snd_pcm_capture_go(snd_pcm_t *pcm)
|
||||||
{
|
{
|
||||||
return snd_pcm_channel_go(pcm, SND_PCM_CHANNEL_CAPTURE);
|
return snd_pcm_stream_go(pcm, SND_PCM_STREAM_CAPTURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_sync_go(snd_pcm_t *pcm, snd_pcm_sync_t *sync)
|
int snd_pcm_sync_go(snd_pcm_t *pcm, snd_pcm_sync_t *sync)
|
||||||
|
|
@ -320,8 +320,8 @@ int snd_pcm_sync_go(snd_pcm_t *pcm, snd_pcm_sync_t *sync)
|
||||||
int err;
|
int err;
|
||||||
if (!pcm || !sync)
|
if (!pcm || !sync)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (!pcm->chan[SND_PCM_CHANNEL_PLAYBACK].open &&
|
if (!pcm->stream[SND_PCM_STREAM_PLAYBACK].open &&
|
||||||
!pcm->chan[SND_PCM_CHANNEL_CAPTURE].open)
|
!pcm->stream[SND_PCM_STREAM_CAPTURE].open)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
err = pcm->ops->sync_go(pcm, sync);
|
err = pcm->ops->sync_go(pcm, sync);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
|
@ -330,101 +330,101 @@ int snd_pcm_sync_go(snd_pcm_t *pcm, snd_pcm_sync_t *sync)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_channel_drain(snd_pcm_t *pcm, int channel)
|
int snd_pcm_stream_drain(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (channel < 0 || channel > 1)
|
if (stream < 0 || stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!pcm->chan[channel].open)
|
if (!pcm->stream[stream].open)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
if (channel != SND_PCM_CHANNEL_PLAYBACK)
|
if (stream != SND_PCM_STREAM_PLAYBACK)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
err = pcm->ops->channel_drain(pcm, channel);
|
err = pcm->ops->stream_drain(pcm, stream);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
snd_pcm_mmap_status_change(pcm, channel, SND_PCM_STATUS_READY);
|
snd_pcm_mmap_status_streamge(pcm, stream, SND_PCM_STATUS_READY);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_playback_drain(snd_pcm_t *pcm)
|
int snd_pcm_playback_drain(snd_pcm_t *pcm)
|
||||||
{
|
{
|
||||||
return snd_pcm_channel_drain(pcm, SND_PCM_CHANNEL_PLAYBACK);
|
return snd_pcm_stream_drain(pcm, SND_PCM_STREAM_PLAYBACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_channel_flush(snd_pcm_t *pcm, int channel)
|
int snd_pcm_stream_flush(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (channel < 0 || channel > 1)
|
if (stream < 0 || stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!pcm->chan[channel].open)
|
if (!pcm->stream[stream].open)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
err = pcm->ops->channel_flush(pcm, channel);
|
err = pcm->ops->stream_flush(pcm, stream);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
snd_pcm_mmap_status_change(pcm, channel, SND_PCM_STATUS_READY);
|
snd_pcm_mmap_status_streamge(pcm, stream, SND_PCM_STATUS_READY);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_playback_flush(snd_pcm_t *pcm)
|
int snd_pcm_playback_flush(snd_pcm_t *pcm)
|
||||||
{
|
{
|
||||||
return snd_pcm_channel_flush(pcm, SND_PCM_CHANNEL_PLAYBACK);
|
return snd_pcm_stream_flush(pcm, SND_PCM_STREAM_PLAYBACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_capture_flush(snd_pcm_t *pcm)
|
int snd_pcm_capture_flush(snd_pcm_t *pcm)
|
||||||
{
|
{
|
||||||
return snd_pcm_channel_flush(pcm, SND_PCM_CHANNEL_CAPTURE);
|
return snd_pcm_stream_flush(pcm, SND_PCM_STREAM_CAPTURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_channel_pause(snd_pcm_t *pcm, int channel, int enable)
|
int snd_pcm_stream_pause(snd_pcm_t *pcm, int stream, int enable)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (channel < 0 || channel > 1)
|
if (stream < 0 || stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!pcm->chan[channel].open)
|
if (!pcm->stream[stream].open)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
if (channel != SND_PCM_CHANNEL_PLAYBACK)
|
if (stream != SND_PCM_STREAM_PLAYBACK)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
err = pcm->ops->channel_pause(pcm, channel, enable);
|
err = pcm->ops->stream_pause(pcm, stream, enable);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
snd_pcm_mmap_status_change(pcm, channel, SND_PCM_STATUS_PAUSED);
|
snd_pcm_mmap_status_streamge(pcm, stream, SND_PCM_STATUS_PAUSED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_playback_pause(snd_pcm_t *pcm, int enable)
|
int snd_pcm_playback_pause(snd_pcm_t *pcm, int enable)
|
||||||
{
|
{
|
||||||
return snd_pcm_channel_pause(pcm, SND_PCM_CHANNEL_PLAYBACK, enable);
|
return snd_pcm_stream_pause(pcm, SND_PCM_STREAM_PLAYBACK, enable);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t snd_pcm_transfer_size(snd_pcm_t *pcm, int channel)
|
ssize_t snd_pcm_transfer_size(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
struct snd_pcm_chan *chan;
|
struct snd_pcm_stream *str;
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (channel < 0 || channel > 1)
|
if (stream < 0 || stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
chan = &pcm->chan[channel];
|
str = &pcm->stream[stream];
|
||||||
if (!chan->open)
|
if (!str->open)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
if (!chan->valid_setup)
|
if (!str->valid_setup)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
if (chan->setup.mode != SND_PCM_MODE_BLOCK)
|
if (str->setup.mode != SND_PCM_MODE_FRAGMENT)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
return chan->setup.frag_size;
|
return str->setup.frag_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t snd_pcm_write(snd_pcm_t *pcm, const void *buffer, size_t size)
|
ssize_t snd_pcm_write(snd_pcm_t *pcm, const void *buffer, size_t size)
|
||||||
{
|
{
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (!pcm->chan[SND_PCM_CHANNEL_PLAYBACK].open ||
|
if (!pcm->stream[SND_PCM_STREAM_PLAYBACK].open ||
|
||||||
!pcm->chan[SND_PCM_CHANNEL_PLAYBACK].valid_setup)
|
!pcm->stream[SND_PCM_STREAM_PLAYBACK].valid_setup)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
if (size > 0 && !buffer)
|
if (size > 0 && !buffer)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
@ -435,8 +435,8 @@ ssize_t snd_pcm_writev(snd_pcm_t *pcm, const struct iovec *vector, unsigned long
|
||||||
{
|
{
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (!pcm->chan[SND_PCM_CHANNEL_PLAYBACK].open ||
|
if (!pcm->stream[SND_PCM_STREAM_PLAYBACK].open ||
|
||||||
!pcm->chan[SND_PCM_CHANNEL_PLAYBACK].valid_setup)
|
!pcm->stream[SND_PCM_STREAM_PLAYBACK].valid_setup)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
if (count > 0 && !vector)
|
if (count > 0 && !vector)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
@ -447,8 +447,8 @@ ssize_t snd_pcm_read(snd_pcm_t *pcm, void *buffer, size_t size)
|
||||||
{
|
{
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (!pcm->chan[SND_PCM_CHANNEL_CAPTURE].open ||
|
if (!pcm->stream[SND_PCM_STREAM_CAPTURE].open ||
|
||||||
!pcm->chan[SND_PCM_CHANNEL_CAPTURE].valid_setup)
|
!pcm->stream[SND_PCM_STREAM_CAPTURE].valid_setup)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
if (size > 0 && !buffer)
|
if (size > 0 && !buffer)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
@ -459,47 +459,47 @@ ssize_t snd_pcm_readv(snd_pcm_t *pcm, const struct iovec *vector, unsigned long
|
||||||
{
|
{
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (!pcm->chan[SND_PCM_CHANNEL_CAPTURE].open ||
|
if (!pcm->stream[SND_PCM_STREAM_CAPTURE].open ||
|
||||||
!pcm->chan[SND_PCM_CHANNEL_CAPTURE].valid_setup)
|
!pcm->stream[SND_PCM_STREAM_CAPTURE].valid_setup)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
if (count > 0 && !vector)
|
if (count > 0 && !vector)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
return pcm->ops->readv(pcm, vector, count);
|
return pcm->ops->readv(pcm, vector, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_file_descriptor(snd_pcm_t* pcm, int channel)
|
int snd_pcm_file_descriptor(snd_pcm_t* pcm, int stream)
|
||||||
{
|
{
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (channel < 0 || channel > 1)
|
if (stream < 0 || stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!pcm->chan[channel].open)
|
if (!pcm->stream[stream].open)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
return pcm->ops->file_descriptor(pcm, channel);
|
return pcm->ops->file_descriptor(pcm, stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_voices_mask(snd_pcm_t *pcm, int channel, bitset_t *client_vmask)
|
int snd_pcm_channels_mask(snd_pcm_t *pcm, int stream, bitset_t *client_vmask)
|
||||||
{
|
{
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (channel < 0 || channel > 1)
|
if (stream < 0 || stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!pcm->chan[channel].open)
|
if (!pcm->stream[stream].open)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
return pcm->ops->voices_mask(pcm, channel, client_vmask);
|
return pcm->ops->channels_mask(pcm, stream, client_vmask);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t snd_pcm_bytes_per_second(snd_pcm_t *pcm, int channel)
|
ssize_t snd_pcm_bytes_per_second(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
struct snd_pcm_chan *chan;
|
struct snd_pcm_stream *str;
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (channel < 0 || channel > 1)
|
if (stream < 0 || stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
chan = &pcm->chan[channel];
|
str = &pcm->stream[stream];
|
||||||
if (!chan->open || !chan->valid_setup)
|
if (!str->open || !str->valid_setup)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
return snd_pcm_format_bytes_per_second(&chan->setup.format);
|
return snd_pcm_format_bytes_per_second(&str->setup.format);
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -537,7 +537,7 @@ static const char *assoc(int value, assoc_t *alist)
|
||||||
return "UNKNOWN";
|
return "UNKNOWN";
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CHN(v) { SND_PCM_CHANNEL_##v, #v, #v }
|
#define STREAM(v) { SND_PCM_STREAM_##v, #v, #v }
|
||||||
#define MODE(v) { SND_PCM_MODE_##v, #v, #v }
|
#define MODE(v) { SND_PCM_MODE_##v, #v, #v }
|
||||||
#define FMT(v, d) { SND_PCM_SFMT_##v, #v, d }
|
#define FMT(v, d) { SND_PCM_SFMT_##v, #v, d }
|
||||||
#define XRUN(v) { SND_PCM_XRUN_##v, #v, #v }
|
#define XRUN(v) { SND_PCM_XRUN_##v, #v, #v }
|
||||||
|
|
@ -545,8 +545,8 @@ static const char *assoc(int value, assoc_t *alist)
|
||||||
#define FILL(v) { SND_PCM_FILL_##v, #v, #v }
|
#define FILL(v) { SND_PCM_FILL_##v, #v, #v }
|
||||||
#define END { 0, NULL, NULL }
|
#define END { 0, NULL, NULL }
|
||||||
|
|
||||||
static assoc_t chns[] = { CHN(PLAYBACK), CHN(CAPTURE), END };
|
static assoc_t streams[] = { STREAM(PLAYBACK), STREAM(CAPTURE), END };
|
||||||
static assoc_t modes[] = { MODE(STREAM), MODE(BLOCK), END };
|
static assoc_t modes[] = { MODE(FRAME), MODE(FRAGMENT), END };
|
||||||
static assoc_t fmts[] = {
|
static assoc_t fmts[] = {
|
||||||
FMT(S8, "Signed 8-bit"),
|
FMT(S8, "Signed 8-bit"),
|
||||||
FMT(U8, "Unsigned 8-bit"),
|
FMT(U8, "Unsigned 8-bit"),
|
||||||
|
|
@ -582,22 +582,22 @@ static assoc_t xruns[] = { XRUN(FLUSH), XRUN(DRAIN), END };
|
||||||
static assoc_t fills[] = { FILL(NONE), FILL(SILENCE_WHOLE), FILL(SILENCE), END };
|
static assoc_t fills[] = { FILL(NONE), FILL(SILENCE_WHOLE), FILL(SILENCE), END };
|
||||||
static assoc_t onoff[] = { {0, "OFF", NULL}, {1, "ON", NULL}, {-1, "ON", NULL}, END };
|
static assoc_t onoff[] = { {0, "OFF", NULL}, {1, "ON", NULL}, {-1, "ON", NULL}, END };
|
||||||
|
|
||||||
int snd_pcm_dump_setup(snd_pcm_t *pcm, int channel, FILE *fp)
|
int snd_pcm_dump_setup(snd_pcm_t *pcm, int stream, FILE *fp)
|
||||||
{
|
{
|
||||||
struct snd_pcm_chan *chan;
|
struct snd_pcm_stream *str;
|
||||||
snd_pcm_channel_setup_t *setup;
|
snd_pcm_stream_setup_t *setup;
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (channel < 0 || channel > 1)
|
if (stream < 0 || stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
chan = &pcm->chan[channel];
|
str = &pcm->stream[stream];
|
||||||
if (!chan->open || !chan->valid_setup)
|
if (!str->open || !str->valid_setup)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
setup = &chan->setup;
|
setup = &str->setup;
|
||||||
fprintf(fp, "channel: %s\n", assoc(setup->channel, chns));
|
fprintf(fp, "stream: %s\n", assoc(setup->stream, streams));
|
||||||
fprintf(fp, "mode: %s\n", assoc(setup->mode, modes));
|
fprintf(fp, "mode: %s\n", assoc(setup->mode, modes));
|
||||||
fprintf(fp, "format: %s\n", assoc(setup->format.format, fmts));
|
fprintf(fp, "format: %s\n", assoc(setup->format.format, fmts));
|
||||||
fprintf(fp, "voices: %d\n", setup->format.voices);
|
fprintf(fp, "channels: %d\n", setup->format.channels);
|
||||||
fprintf(fp, "rate: %d\n", setup->format.rate);
|
fprintf(fp, "rate: %d\n", setup->format.rate);
|
||||||
// digital
|
// digital
|
||||||
fprintf(fp, "start_mode: %s\n", assoc(setup->start_mode, starts));
|
fprintf(fp, "start_mode: %s\n", assoc(setup->start_mode, starts));
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
182
src/pcm/pcm_hw.c
182
src/pcm/pcm_hw.c
|
|
@ -33,32 +33,32 @@
|
||||||
#define SND_FILE_PCM_CAPTURE "/dev/snd/pcmC%iD%ic"
|
#define SND_FILE_PCM_CAPTURE "/dev/snd/pcmC%iD%ic"
|
||||||
#define SND_PCM_VERSION_MAX SND_PROTOCOL_VERSION(2, 0, 0)
|
#define SND_PCM_VERSION_MAX SND_PROTOCOL_VERSION(2, 0, 0)
|
||||||
|
|
||||||
static int snd_pcm_hw_channel_close(snd_pcm_t *pcm, int channel)
|
static int snd_pcm_hw_stream_close(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
||||||
if (hw->chan[channel].fd >= 0)
|
if (hw->stream[stream].fd >= 0)
|
||||||
if (close(hw->chan[channel].fd))
|
if (close(hw->stream[stream].fd))
|
||||||
return -errno;
|
return -errno;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_hw_channel_fd(snd_pcm_t *pcm, int channel)
|
int snd_pcm_hw_stream_fd(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
snd_pcm_hw_t *hw;
|
snd_pcm_hw_t *hw;
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (channel < 0 || channel > 1)
|
if (stream < 0 || stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
hw = (snd_pcm_hw_t*) &pcm->private;
|
hw = (snd_pcm_hw_t*) &pcm->private;
|
||||||
return hw->chan[channel].fd;
|
return hw->stream[stream].fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_hw_channel_nonblock(snd_pcm_t *pcm, int channel, int nonblock)
|
static int snd_pcm_hw_stream_nonblock(snd_pcm_t *pcm, int stream, int nonblock)
|
||||||
{
|
{
|
||||||
long flags;
|
long flags;
|
||||||
int fd;
|
int fd;
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
||||||
fd = hw->chan[channel].fd;
|
fd = hw->stream[stream].fd;
|
||||||
|
|
||||||
if ((flags = fcntl(fd, F_GETFL)) < 0)
|
if ((flags = fcntl(fd, F_GETFL)) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
@ -73,10 +73,10 @@ static int snd_pcm_hw_channel_nonblock(snd_pcm_t *pcm, int channel, int nonblock
|
||||||
|
|
||||||
static int snd_pcm_hw_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
|
static int snd_pcm_hw_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
|
||||||
{
|
{
|
||||||
int fd, channel;
|
int fd, stream;
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
||||||
for (channel = 0; channel < 2; ++channel) {
|
for (stream = 0; stream < 2; ++stream) {
|
||||||
fd = hw->chan[channel].fd;
|
fd = hw->stream[stream].fd;
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -87,84 +87,84 @@ static int snd_pcm_hw_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_hw_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t * info)
|
static int snd_pcm_hw_stream_info(snd_pcm_t *pcm, snd_pcm_stream_info_t * info)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
||||||
fd = hw->chan[info->channel].fd;
|
fd = hw->stream[info->stream].fd;
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_INFO, info) < 0)
|
if (ioctl(fd, SND_PCM_IOCTL_STREAM_INFO, info) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_hw_channel_params(snd_pcm_t *pcm, snd_pcm_channel_params_t * params)
|
static int snd_pcm_hw_stream_params(snd_pcm_t *pcm, snd_pcm_stream_params_t * params)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
||||||
fd = hw->chan[params->channel].fd;
|
fd = hw->stream[params->stream].fd;
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_PARAMS, params) < 0)
|
if (ioctl(fd, SND_PCM_IOCTL_STREAM_PARAMS, params) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_hw_channel_setup(snd_pcm_t *pcm, snd_pcm_channel_setup_t * setup)
|
static int snd_pcm_hw_stream_setup(snd_pcm_t *pcm, snd_pcm_stream_setup_t * setup)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
||||||
fd = hw->chan[setup->channel].fd;
|
fd = hw->stream[setup->stream].fd;
|
||||||
|
if (ioctl(fd, SND_PCM_IOCTL_STREAM_SETUP, setup) < 0)
|
||||||
|
return -errno;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int snd_pcm_hw_channel_setup(snd_pcm_t *pcm, int stream, snd_pcm_channel_setup_t * setup)
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
||||||
|
fd = hw->stream[stream].fd;
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_SETUP, setup) < 0)
|
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_SETUP, setup) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_hw_voice_setup(snd_pcm_t *pcm, int channel, snd_pcm_voice_setup_t * setup)
|
static int snd_pcm_hw_stream_status(snd_pcm_t *pcm, snd_pcm_stream_status_t * status)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
||||||
fd = hw->chan[channel].fd;
|
fd = hw->stream[status->stream].fd;
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_VOICE_SETUP, setup) < 0)
|
if (ioctl(fd, SND_PCM_IOCTL_STREAM_STATUS, status) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_hw_channel_status(snd_pcm_t *pcm, snd_pcm_channel_status_t * status)
|
static int snd_pcm_hw_stream_update(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
||||||
fd = hw->chan[status->channel].fd;
|
fd = hw->stream[stream].fd;
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_STATUS, status) < 0)
|
if (ioctl(fd, SND_PCM_IOCTL_STREAM_UPDATE) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_hw_channel_update(snd_pcm_t *pcm, int channel)
|
static int snd_pcm_hw_stream_prepare(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
||||||
fd = hw->chan[channel].fd;
|
fd = hw->stream[stream].fd;
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_UPDATE) < 0)
|
if (ioctl(fd, SND_PCM_IOCTL_STREAM_PREPARE) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_hw_channel_prepare(snd_pcm_t *pcm, int channel)
|
static int snd_pcm_hw_stream_go(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
||||||
fd = hw->chan[channel].fd;
|
fd = hw->stream[stream].fd;
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_PREPARE) < 0)
|
if (ioctl(fd, SND_PCM_IOCTL_STREAM_GO) < 0)
|
||||||
return -errno;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int snd_pcm_hw_channel_go(snd_pcm_t *pcm, int channel)
|
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
|
||||||
fd = hw->chan[channel].fd;
|
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_GO) < 0)
|
|
||||||
return -errno;
|
return -errno;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -173,41 +173,41 @@ static int snd_pcm_hw_sync_go(snd_pcm_t *pcm, snd_pcm_sync_t *sync)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
||||||
if (pcm->chan[SND_PCM_CHANNEL_PLAYBACK].open)
|
if (pcm->stream[SND_PCM_STREAM_PLAYBACK].open)
|
||||||
fd = hw->chan[SND_PCM_CHANNEL_PLAYBACK].fd;
|
fd = hw->stream[SND_PCM_STREAM_PLAYBACK].fd;
|
||||||
else
|
else
|
||||||
fd = hw->chan[SND_PCM_CHANNEL_CAPTURE].fd;
|
fd = hw->stream[SND_PCM_STREAM_CAPTURE].fd;
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_SYNC_GO, sync) < 0)
|
if (ioctl(fd, SND_PCM_IOCTL_SYNC_GO, sync) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_hw_channel_drain(snd_pcm_t *pcm, int channel)
|
static int snd_pcm_hw_stream_drain(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
||||||
fd = hw->chan[channel].fd;
|
fd = hw->stream[stream].fd;
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_DRAIN) < 0)
|
if (ioctl(fd, SND_PCM_IOCTL_STREAM_DRAIN) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_hw_channel_flush(snd_pcm_t *pcm, int channel)
|
static int snd_pcm_hw_stream_flush(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
||||||
fd = hw->chan[channel].fd;
|
fd = hw->stream[stream].fd;
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_FLUSH) < 0)
|
if (ioctl(fd, SND_PCM_IOCTL_STREAM_FLUSH) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_hw_channel_pause(snd_pcm_t *pcm, int channel, int enable)
|
static int snd_pcm_hw_stream_pause(snd_pcm_t *pcm, int stream, int enable)
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
||||||
fd = hw->chan[channel].fd;
|
fd = hw->stream[stream].fd;
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_PAUSE, &enable) < 0)
|
if (ioctl(fd, SND_PCM_IOCTL_STREAM_PAUSE, &enable) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -217,7 +217,7 @@ static ssize_t snd_pcm_hw_write(snd_pcm_t *pcm, const void *buffer, size_t size)
|
||||||
ssize_t result;
|
ssize_t result;
|
||||||
int fd;
|
int fd;
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
||||||
fd = hw->chan[SND_PCM_CHANNEL_PLAYBACK].fd;
|
fd = hw->stream[SND_PCM_STREAM_PLAYBACK].fd;
|
||||||
result = write(fd, buffer, size);
|
result = write(fd, buffer, size);
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
@ -229,7 +229,7 @@ static ssize_t snd_pcm_hw_writev(snd_pcm_t *pcm, const struct iovec *vector, uns
|
||||||
ssize_t result;
|
ssize_t result;
|
||||||
int fd;
|
int fd;
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
||||||
fd = hw->chan[SND_PCM_CHANNEL_PLAYBACK].fd;
|
fd = hw->stream[SND_PCM_STREAM_PLAYBACK].fd;
|
||||||
#if 0
|
#if 0
|
||||||
result = writev(fd, vector, count);
|
result = writev(fd, vector, count);
|
||||||
#else
|
#else
|
||||||
|
|
@ -250,7 +250,7 @@ static ssize_t snd_pcm_hw_read(snd_pcm_t *pcm, void *buffer, size_t size)
|
||||||
ssize_t result;
|
ssize_t result;
|
||||||
int fd;
|
int fd;
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
||||||
fd = hw->chan[SND_PCM_CHANNEL_CAPTURE].fd;
|
fd = hw->stream[SND_PCM_STREAM_CAPTURE].fd;
|
||||||
result = read(fd, buffer, size);
|
result = read(fd, buffer, size);
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
@ -262,7 +262,7 @@ ssize_t snd_pcm_hw_readv(snd_pcm_t *pcm, const struct iovec *vector, unsigned lo
|
||||||
ssize_t result;
|
ssize_t result;
|
||||||
int fd;
|
int fd;
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
||||||
fd = hw->chan[SND_PCM_CHANNEL_CAPTURE].fd;
|
fd = hw->stream[SND_PCM_STREAM_CAPTURE].fd;
|
||||||
#if 0
|
#if 0
|
||||||
result = readv(fd, vector, count);
|
result = readv(fd, vector, count);
|
||||||
#else
|
#else
|
||||||
|
|
@ -278,74 +278,74 @@ ssize_t snd_pcm_hw_readv(snd_pcm_t *pcm, const struct iovec *vector, unsigned lo
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_hw_mmap_control(snd_pcm_t *pcm, int channel, snd_pcm_mmap_control_t **control, size_t csize)
|
static int snd_pcm_hw_mmap_control(snd_pcm_t *pcm, int stream, snd_pcm_mmap_control_t **control, size_t csize)
|
||||||
{
|
{
|
||||||
void *caddr;
|
void *caddr;
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
||||||
caddr = mmap(NULL, csize, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED,
|
caddr = mmap(NULL, csize, PROT_READ|PROT_WRITE, MAP_FILE|MAP_SHARED,
|
||||||
hw->chan[channel].fd, SND_PCM_MMAP_OFFSET_CONTROL);
|
hw->stream[stream].fd, SND_PCM_MMAP_OFFSET_CONTROL);
|
||||||
if (caddr == MAP_FAILED || caddr == NULL)
|
if (caddr == MAP_FAILED || caddr == NULL)
|
||||||
return -errno;
|
return -errno;
|
||||||
*control = caddr;
|
*control = caddr;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_hw_mmap_data(snd_pcm_t *pcm, int channel, void **buffer, size_t bsize)
|
static int snd_pcm_hw_mmap_data(snd_pcm_t *pcm, int stream, void **buffer, size_t bsize)
|
||||||
{
|
{
|
||||||
int prot;
|
int prot;
|
||||||
void *daddr;
|
void *daddr;
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
||||||
prot = channel == SND_PCM_CHANNEL_PLAYBACK ? PROT_WRITE : PROT_READ;
|
prot = stream == SND_PCM_STREAM_PLAYBACK ? PROT_WRITE : PROT_READ;
|
||||||
daddr = mmap(NULL, bsize, prot, MAP_FILE|MAP_SHARED,
|
daddr = mmap(NULL, bsize, prot, MAP_FILE|MAP_SHARED,
|
||||||
hw->chan[channel].fd, SND_PCM_MMAP_OFFSET_DATA);
|
hw->stream[stream].fd, SND_PCM_MMAP_OFFSET_DATA);
|
||||||
if (daddr == MAP_FAILED || daddr == NULL)
|
if (daddr == MAP_FAILED || daddr == NULL)
|
||||||
return -errno;
|
return -errno;
|
||||||
*buffer = daddr;
|
*buffer = daddr;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_hw_munmap_control(snd_pcm_t *pcm UNUSED, int channel UNUSED, snd_pcm_mmap_control_t *control, size_t csize)
|
static int snd_pcm_hw_munmap_control(snd_pcm_t *pcm UNUSED, int stream UNUSED, snd_pcm_mmap_control_t *control, size_t csize)
|
||||||
{
|
{
|
||||||
if (munmap(control, csize) < 0)
|
if (munmap(control, csize) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_hw_munmap_data(snd_pcm_t *pcm UNUSED, int channel UNUSED, void *buffer, size_t bsize)
|
static int snd_pcm_hw_munmap_data(snd_pcm_t *pcm UNUSED, int stream UNUSED, void *buffer, size_t bsize)
|
||||||
{
|
{
|
||||||
if (munmap(buffer, bsize) < 0)
|
if (munmap(buffer, bsize) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_hw_file_descriptor(snd_pcm_t *pcm, int channel)
|
static int snd_pcm_hw_file_descriptor(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
snd_pcm_hw_t *hw = (snd_pcm_hw_t*) &pcm->private;
|
||||||
return hw->chan[channel].fd;
|
return hw->stream[stream].fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_hw_voices_mask(snd_pcm_t *pcm UNUSED, int channel UNUSED,
|
static int snd_pcm_hw_channels_mask(snd_pcm_t *pcm UNUSED, int stream UNUSED,
|
||||||
bitset_t *client_vmask UNUSED)
|
bitset_t *client_vmask UNUSED)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct snd_pcm_ops snd_pcm_hw_ops = {
|
struct snd_pcm_ops snd_pcm_hw_ops = {
|
||||||
channel_close: snd_pcm_hw_channel_close,
|
stream_close: snd_pcm_hw_stream_close,
|
||||||
channel_nonblock: snd_pcm_hw_channel_nonblock,
|
stream_nonblock: snd_pcm_hw_stream_nonblock,
|
||||||
info: snd_pcm_hw_info,
|
info: snd_pcm_hw_info,
|
||||||
channel_info: snd_pcm_hw_channel_info,
|
stream_info: snd_pcm_hw_stream_info,
|
||||||
channel_params: snd_pcm_hw_channel_params,
|
stream_params: snd_pcm_hw_stream_params,
|
||||||
|
stream_setup: snd_pcm_hw_stream_setup,
|
||||||
channel_setup: snd_pcm_hw_channel_setup,
|
channel_setup: snd_pcm_hw_channel_setup,
|
||||||
voice_setup: snd_pcm_hw_voice_setup,
|
stream_status: snd_pcm_hw_stream_status,
|
||||||
channel_status: snd_pcm_hw_channel_status,
|
stream_update: snd_pcm_hw_stream_update,
|
||||||
channel_update: snd_pcm_hw_channel_update,
|
stream_prepare: snd_pcm_hw_stream_prepare,
|
||||||
channel_prepare: snd_pcm_hw_channel_prepare,
|
stream_go: snd_pcm_hw_stream_go,
|
||||||
channel_go: snd_pcm_hw_channel_go,
|
|
||||||
sync_go: snd_pcm_hw_sync_go,
|
sync_go: snd_pcm_hw_sync_go,
|
||||||
channel_drain: snd_pcm_hw_channel_drain,
|
stream_drain: snd_pcm_hw_stream_drain,
|
||||||
channel_flush: snd_pcm_hw_channel_flush,
|
stream_flush: snd_pcm_hw_stream_flush,
|
||||||
channel_pause: snd_pcm_hw_channel_pause,
|
stream_pause: snd_pcm_hw_stream_pause,
|
||||||
write: snd_pcm_hw_write,
|
write: snd_pcm_hw_write,
|
||||||
writev: snd_pcm_hw_writev,
|
writev: snd_pcm_hw_writev,
|
||||||
read: snd_pcm_hw_read,
|
read: snd_pcm_hw_read,
|
||||||
|
|
@ -355,27 +355,27 @@ struct snd_pcm_ops snd_pcm_hw_ops = {
|
||||||
munmap_control: snd_pcm_hw_munmap_control,
|
munmap_control: snd_pcm_hw_munmap_control,
|
||||||
munmap_data: snd_pcm_hw_munmap_data,
|
munmap_data: snd_pcm_hw_munmap_data,
|
||||||
file_descriptor: snd_pcm_hw_file_descriptor,
|
file_descriptor: snd_pcm_hw_file_descriptor,
|
||||||
voices_mask: snd_pcm_hw_voices_mask,
|
channels_mask: snd_pcm_hw_channels_mask,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int snd_pcm_hw_open_channel(int card, int device, int channel, int subdevice, int fmode, snd_ctl_t *ctl, int *ver)
|
static int snd_pcm_hw_open_stream(int card, int device, int stream, int subdevice, int fmode, snd_ctl_t *ctl, int *ver)
|
||||||
{
|
{
|
||||||
char filename[32];
|
char filename[32];
|
||||||
char *filefmt;
|
char *filefmt;
|
||||||
int err, fd;
|
int err, fd;
|
||||||
int attempt = 0;
|
int attempt = 0;
|
||||||
snd_pcm_channel_info_t info;
|
snd_pcm_stream_info_t info;
|
||||||
switch (channel) {
|
switch (stream) {
|
||||||
case SND_PCM_CHANNEL_PLAYBACK:
|
case SND_PCM_STREAM_PLAYBACK:
|
||||||
filefmt = SND_FILE_PCM_PLAYBACK;
|
filefmt = SND_FILE_PCM_PLAYBACK;
|
||||||
break;
|
break;
|
||||||
case SND_PCM_CHANNEL_CAPTURE:
|
case SND_PCM_STREAM_CAPTURE:
|
||||||
filefmt = SND_FILE_PCM_CAPTURE;
|
filefmt = SND_FILE_PCM_CAPTURE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
if ((err = snd_ctl_pcm_channel_prefer_subdevice(ctl, device, channel, subdevice)) < 0)
|
if ((err = snd_ctl_pcm_stream_prefer_subdevice(ctl, device, stream, subdevice)) < 0)
|
||||||
return err;
|
return err;
|
||||||
sprintf(filename, filefmt, card, device);
|
sprintf(filename, filefmt, card, device);
|
||||||
|
|
||||||
|
|
@ -399,7 +399,7 @@ static int snd_pcm_hw_open_channel(int card, int device, int channel, int subdev
|
||||||
}
|
}
|
||||||
if (subdevice >= 0) {
|
if (subdevice >= 0) {
|
||||||
memset(&info, 0, sizeof(info));
|
memset(&info, 0, sizeof(info));
|
||||||
if (ioctl(fd, SND_PCM_IOCTL_CHANNEL_INFO, &info) < 0) {
|
if (ioctl(fd, SND_PCM_IOCTL_STREAM_INFO, &info) < 0) {
|
||||||
err = -errno;
|
err = -errno;
|
||||||
close(fd);
|
close(fd);
|
||||||
return err;
|
return err;
|
||||||
|
|
@ -432,7 +432,7 @@ int snd_pcm_open_subdevice(snd_pcm_t **handle, int card, int device, int subdevi
|
||||||
fmode = O_RDWR;
|
fmode = O_RDWR;
|
||||||
if (mode & SND_PCM_NONBLOCK_PLAYBACK)
|
if (mode & SND_PCM_NONBLOCK_PLAYBACK)
|
||||||
fmode |= O_NONBLOCK;
|
fmode |= O_NONBLOCK;
|
||||||
pfd = snd_pcm_hw_open_channel(card, device, SND_PCM_CHANNEL_PLAYBACK,
|
pfd = snd_pcm_hw_open_stream(card, device, SND_PCM_STREAM_PLAYBACK,
|
||||||
subdevice, fmode, ctl, &ver);
|
subdevice, fmode, ctl, &ver);
|
||||||
if (pfd < 0) {
|
if (pfd < 0) {
|
||||||
snd_ctl_close(ctl);
|
snd_ctl_close(ctl);
|
||||||
|
|
@ -443,7 +443,7 @@ int snd_pcm_open_subdevice(snd_pcm_t **handle, int card, int device, int subdevi
|
||||||
fmode = O_RDWR;
|
fmode = O_RDWR;
|
||||||
if (mode & SND_PCM_NONBLOCK_CAPTURE)
|
if (mode & SND_PCM_NONBLOCK_CAPTURE)
|
||||||
fmode |= O_NONBLOCK;
|
fmode |= O_NONBLOCK;
|
||||||
cfd = snd_pcm_hw_open_channel(card, device, SND_PCM_CHANNEL_CAPTURE,
|
cfd = snd_pcm_hw_open_stream(card, device, SND_PCM_STREAM_CAPTURE,
|
||||||
subdevice, fmode, ctl, &ver);
|
subdevice, fmode, ctl, &ver);
|
||||||
if (cfd < 0) {
|
if (cfd < 0) {
|
||||||
if (pfd >= 0)
|
if (pfd >= 0)
|
||||||
|
|
@ -470,8 +470,8 @@ int snd_pcm_open_subdevice(snd_pcm_t **handle, int card, int device, int subdevi
|
||||||
hw->card = card;
|
hw->card = card;
|
||||||
hw->device = device;
|
hw->device = device;
|
||||||
hw->ver = ver;
|
hw->ver = ver;
|
||||||
hw->chan[SND_PCM_CHANNEL_PLAYBACK].fd = pfd;
|
hw->stream[SND_PCM_STREAM_PLAYBACK].fd = pfd;
|
||||||
hw->chan[SND_PCM_CHANNEL_CAPTURE].fd = cfd;
|
hw->stream[SND_PCM_STREAM_CAPTURE].fd = cfd;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,35 +24,35 @@
|
||||||
|
|
||||||
|
|
||||||
struct snd_pcm_ops {
|
struct snd_pcm_ops {
|
||||||
int (*channel_close)(snd_pcm_t *pcm, int channel);
|
int (*stream_close)(snd_pcm_t *pcm, int stream);
|
||||||
int (*channel_nonblock)(snd_pcm_t *pcm, int channel, int nonblock);
|
int (*stream_nonblock)(snd_pcm_t *pcm, int stream, int nonblock);
|
||||||
int (*info)(snd_pcm_t *pcm, snd_pcm_info_t *info);
|
int (*info)(snd_pcm_t *pcm, snd_pcm_info_t *info);
|
||||||
int (*channel_info)(snd_pcm_t *pcm, snd_pcm_channel_info_t *info);
|
int (*stream_info)(snd_pcm_t *pcm, snd_pcm_stream_info_t *info);
|
||||||
int (*channel_params)(snd_pcm_t *pcm, snd_pcm_channel_params_t *params);
|
int (*stream_params)(snd_pcm_t *pcm, snd_pcm_stream_params_t *params);
|
||||||
int (*channel_setup)(snd_pcm_t *pcm, snd_pcm_channel_setup_t *setup);
|
int (*stream_setup)(snd_pcm_t *pcm, snd_pcm_stream_setup_t *setup);
|
||||||
int (*voice_setup)(snd_pcm_t *pcm, int channel, snd_pcm_voice_setup_t *setup);
|
int (*channel_setup)(snd_pcm_t *pcm, int stream, snd_pcm_channel_setup_t *setup);
|
||||||
int (*channel_status)(snd_pcm_t *pcm, snd_pcm_channel_status_t *status);
|
int (*stream_status)(snd_pcm_t *pcm, snd_pcm_stream_status_t *status);
|
||||||
int (*channel_prepare)(snd_pcm_t *pcm, int channel);
|
int (*stream_prepare)(snd_pcm_t *pcm, int stream);
|
||||||
int (*channel_update)(snd_pcm_t *pcm, int channel);
|
int (*stream_update)(snd_pcm_t *pcm, int stream);
|
||||||
int (*channel_go)(snd_pcm_t *pcm, int channel);
|
int (*stream_go)(snd_pcm_t *pcm, int stream);
|
||||||
int (*sync_go)(snd_pcm_t *pcm, snd_pcm_sync_t *sync);
|
int (*sync_go)(snd_pcm_t *pcm, snd_pcm_sync_t *sync);
|
||||||
int (*channel_drain)(snd_pcm_t *pcm, int channel);
|
int (*stream_drain)(snd_pcm_t *pcm, int stream);
|
||||||
int (*channel_flush)(snd_pcm_t *pcm, int channel);
|
int (*stream_flush)(snd_pcm_t *pcm, int stream);
|
||||||
int (*channel_pause)(snd_pcm_t *pcm, int channel, int enable);
|
int (*stream_pause)(snd_pcm_t *pcm, int stream, int enable);
|
||||||
ssize_t (*write)(snd_pcm_t *pcm, const void *buffer, size_t size);
|
ssize_t (*write)(snd_pcm_t *pcm, const void *buffer, size_t size);
|
||||||
ssize_t (*writev)(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count);
|
ssize_t (*writev)(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count);
|
||||||
ssize_t (*read)(snd_pcm_t *pcm, void *buffer, size_t size);
|
ssize_t (*read)(snd_pcm_t *pcm, void *buffer, size_t size);
|
||||||
ssize_t (*readv)(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count);
|
ssize_t (*readv)(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count);
|
||||||
int (*mmap_control)(snd_pcm_t *pcm, int channel, snd_pcm_mmap_control_t **control, size_t csize);
|
int (*mmap_control)(snd_pcm_t *pcm, int stream, snd_pcm_mmap_control_t **control, size_t csize);
|
||||||
int (*mmap_data)(snd_pcm_t *pcm, int channel, void **buffer, size_t bsize);
|
int (*mmap_data)(snd_pcm_t *pcm, int stream, void **buffer, size_t bsize);
|
||||||
int (*munmap_control)(snd_pcm_t *pcm, int channel, snd_pcm_mmap_control_t *control, size_t csize);
|
int (*munmap_control)(snd_pcm_t *pcm, int stream, snd_pcm_mmap_control_t *control, size_t csize);
|
||||||
int (*munmap_data)(snd_pcm_t *pcm, int channel, void *buffer, size_t bsize);
|
int (*munmap_data)(snd_pcm_t *pcm, int stream, void *buffer, size_t bsize);
|
||||||
int (*file_descriptor)(snd_pcm_t* pcm, int channel);
|
int (*file_descriptor)(snd_pcm_t* pcm, int stream);
|
||||||
int (*voices_mask)(snd_pcm_t *pcm, int channel, bitset_t *client_vmask);
|
int (*channels_mask)(snd_pcm_t *pcm, int stream, bitset_t *client_vmask);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct snd_pcm_plug_chan {
|
struct snd_pcm_plug_stream {
|
||||||
snd_pcm_plugin_t *first;
|
snd_pcm_plugin_t *first;
|
||||||
snd_pcm_plugin_t *last;
|
snd_pcm_plugin_t *last;
|
||||||
void *alloc_ptr[2];
|
void *alloc_ptr[2];
|
||||||
|
|
@ -63,10 +63,10 @@ struct snd_pcm_plug_chan {
|
||||||
typedef struct snd_pcm_plug {
|
typedef struct snd_pcm_plug {
|
||||||
int close_slave;
|
int close_slave;
|
||||||
snd_pcm_t *slave;
|
snd_pcm_t *slave;
|
||||||
struct snd_pcm_plug_chan chan[2];
|
struct snd_pcm_plug_stream stream[2];
|
||||||
} snd_pcm_plug_t;
|
} snd_pcm_plug_t;
|
||||||
|
|
||||||
struct snd_pcm_hw_chan {
|
struct snd_pcm_hw_stream {
|
||||||
int fd;
|
int fd;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -74,15 +74,15 @@ typedef struct snd_pcm_hw {
|
||||||
int card;
|
int card;
|
||||||
int device;
|
int device;
|
||||||
int ver;
|
int ver;
|
||||||
struct snd_pcm_hw_chan chan[2];
|
struct snd_pcm_hw_stream stream[2];
|
||||||
} snd_pcm_hw_t;
|
} snd_pcm_hw_t;
|
||||||
|
|
||||||
struct snd_pcm_chan {
|
struct snd_pcm_stream {
|
||||||
int open;
|
int open;
|
||||||
int mode;
|
int mode;
|
||||||
int valid_setup;
|
int valid_setup;
|
||||||
snd_pcm_channel_setup_t setup;
|
snd_pcm_stream_setup_t setup;
|
||||||
snd_pcm_voice_area_t *voices;
|
snd_pcm_channel_area_t *channels;
|
||||||
size_t sample_width;
|
size_t sample_width;
|
||||||
size_t bits_per_frame;
|
size_t bits_per_frame;
|
||||||
size_t frames_per_frag;
|
size_t frames_per_frag;
|
||||||
|
|
@ -103,42 +103,42 @@ struct snd_pcm {
|
||||||
snd_pcm_type_t type;
|
snd_pcm_type_t type;
|
||||||
int mode;
|
int mode;
|
||||||
struct snd_pcm_ops *ops;
|
struct snd_pcm_ops *ops;
|
||||||
struct snd_pcm_chan chan[2];
|
struct snd_pcm_stream stream[2];
|
||||||
int private[0];
|
int private[0];
|
||||||
};
|
};
|
||||||
|
|
||||||
void snd_pcm_mmap_status_change(snd_pcm_t *pcm, int channel, int newstatus);
|
void snd_pcm_mmap_status_streamge(snd_pcm_t *pcm, int stream, int newstatus);
|
||||||
|
|
||||||
int snd_pcm_abstract_open(snd_pcm_t **handle, int mode, snd_pcm_type_t type, size_t extra);
|
int snd_pcm_abstract_open(snd_pcm_t **handle, int mode, snd_pcm_type_t type, size_t extra);
|
||||||
|
|
||||||
|
|
||||||
unsigned int snd_pcm_plug_formats(unsigned int formats);
|
unsigned int snd_pcm_plug_formats(unsigned int formats);
|
||||||
int snd_pcm_plug_slave_params(snd_pcm_channel_params_t *params,
|
int snd_pcm_plug_slave_params(snd_pcm_stream_params_t *params,
|
||||||
snd_pcm_channel_info_t *slave_info,
|
snd_pcm_stream_info_t *slave_info,
|
||||||
snd_pcm_channel_params_t *slave_params);
|
snd_pcm_stream_params_t *slave_params);
|
||||||
int snd_pcm_plug_format(snd_pcm_plugin_handle_t *pcm,
|
int snd_pcm_plug_format(snd_pcm_plugin_handle_t *pcm,
|
||||||
snd_pcm_channel_params_t *params,
|
snd_pcm_stream_params_t *params,
|
||||||
snd_pcm_channel_params_t *slave_params);
|
snd_pcm_stream_params_t *slave_params);
|
||||||
|
|
||||||
ssize_t snd_pcm_plug_write_transfer(snd_pcm_plugin_handle_t *handle, snd_pcm_plugin_voice_t *src_voices, size_t size);
|
ssize_t snd_pcm_plug_write_transfer(snd_pcm_plugin_handle_t *handle, snd_pcm_plugin_channel_t *src_channels, size_t size);
|
||||||
ssize_t snd_pcm_plug_read_transfer(snd_pcm_plugin_handle_t *handle, snd_pcm_plugin_voice_t *dst_voices_final, size_t size);
|
ssize_t snd_pcm_plug_read_transfer(snd_pcm_plugin_handle_t *handle, snd_pcm_plugin_channel_t *dst_channels_final, size_t size);
|
||||||
ssize_t snd_pcm_plug_client_voices_iovec(snd_pcm_plugin_handle_t *handle, int channel,
|
ssize_t snd_pcm_plug_client_channels_iovec(snd_pcm_plugin_handle_t *handle, int stream,
|
||||||
const struct iovec *vector, unsigned long count,
|
const struct iovec *vector, unsigned long count,
|
||||||
snd_pcm_plugin_voice_t **voices);
|
snd_pcm_plugin_channel_t **channels);
|
||||||
ssize_t snd_pcm_plug_client_voices_buf(snd_pcm_plugin_handle_t *handle, int channel,
|
ssize_t snd_pcm_plug_client_channels_buf(snd_pcm_plugin_handle_t *handle, int stream,
|
||||||
char *buf, size_t count,
|
char *buf, size_t count,
|
||||||
snd_pcm_plugin_voice_t **voices);
|
snd_pcm_plugin_channel_t **channels);
|
||||||
|
|
||||||
int snd_pcm_plug_playback_voices_mask(snd_pcm_plugin_handle_t *handle,
|
int snd_pcm_plug_playback_channels_mask(snd_pcm_plugin_handle_t *handle,
|
||||||
bitset_t *client_vmask);
|
bitset_t *client_vmask);
|
||||||
int snd_pcm_plug_capture_voices_mask(snd_pcm_plugin_handle_t *handle,
|
int snd_pcm_plug_capture_channels_mask(snd_pcm_plugin_handle_t *handle,
|
||||||
bitset_t *client_vmask);
|
bitset_t *client_vmask);
|
||||||
int snd_pcm_plugin_client_voices(snd_pcm_plugin_t *plugin,
|
int snd_pcm_plugin_client_channels(snd_pcm_plugin_t *plugin,
|
||||||
size_t frames,
|
size_t frames,
|
||||||
snd_pcm_plugin_voice_t **voices);
|
snd_pcm_plugin_channel_t **channels);
|
||||||
|
|
||||||
void *snd_pcm_plug_buf_alloc(snd_pcm_t *pcm, int channel, size_t size);
|
void *snd_pcm_plug_buf_alloc(snd_pcm_t *pcm, int stream, size_t size);
|
||||||
void snd_pcm_plug_buf_unlock(snd_pcm_t *pcm, int channel, void *ptr);
|
void snd_pcm_plug_buf_unlock(snd_pcm_t *pcm, int stream, void *ptr);
|
||||||
|
|
||||||
#define ROUTE_PLUGIN_RESOLUTION 16
|
#define ROUTE_PLUGIN_RESOLUTION 16
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -230,7 +230,7 @@ ssize_t snd_pcm_format_size(int format, size_t samples)
|
||||||
|
|
||||||
ssize_t snd_pcm_format_bytes_per_second(snd_pcm_format_t *format)
|
ssize_t snd_pcm_format_bytes_per_second(snd_pcm_format_t *format)
|
||||||
{
|
{
|
||||||
return snd_pcm_format_size(format->format, format->voices * format->rate);
|
return snd_pcm_format_size(format->format, format->channels * format->rate);
|
||||||
}
|
}
|
||||||
|
|
||||||
u_int64_t snd_pcm_format_silence_64(int format)
|
u_int64_t snd_pcm_format_silence_64(int format)
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -30,50 +30,50 @@
|
||||||
|
|
||||||
/* snd_pcm_plug helpers */
|
/* snd_pcm_plug helpers */
|
||||||
|
|
||||||
void *snd_pcm_plug_buf_alloc(snd_pcm_t *pcm, int channel, size_t size)
|
void *snd_pcm_plug_buf_alloc(snd_pcm_t *pcm, int stream, size_t size)
|
||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
struct snd_pcm_plug_chan *plugchan = &plug->chan[channel];
|
struct snd_pcm_plug_stream *plugstr = &plug->stream[stream];
|
||||||
|
|
||||||
for (idx = 0; idx < 2; idx++) {
|
for (idx = 0; idx < 2; idx++) {
|
||||||
if (plugchan->alloc_lock[idx])
|
if (plugstr->alloc_lock[idx])
|
||||||
continue;
|
continue;
|
||||||
if (plugchan->alloc_size[idx] >= size) {
|
if (plugstr->alloc_size[idx] >= size) {
|
||||||
plugchan->alloc_lock[idx] = 1;
|
plugstr->alloc_lock[idx] = 1;
|
||||||
return plugchan->alloc_ptr[idx];
|
return plugstr->alloc_ptr[idx];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (idx = 0; idx < 2; idx++) {
|
for (idx = 0; idx < 2; idx++) {
|
||||||
if (plugchan->alloc_lock[idx])
|
if (plugstr->alloc_lock[idx])
|
||||||
continue;
|
continue;
|
||||||
if (plugchan->alloc_ptr[idx] != NULL)
|
if (plugstr->alloc_ptr[idx] != NULL)
|
||||||
free(plugchan->alloc_ptr[idx]);
|
free(plugstr->alloc_ptr[idx]);
|
||||||
plugchan->alloc_ptr[idx] = malloc(size);
|
plugstr->alloc_ptr[idx] = malloc(size);
|
||||||
if (plugchan->alloc_ptr[idx] == NULL)
|
if (plugstr->alloc_ptr[idx] == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
plugchan->alloc_size[idx] = size;
|
plugstr->alloc_size[idx] = size;
|
||||||
plugchan->alloc_lock[idx] = 1;
|
plugstr->alloc_lock[idx] = 1;
|
||||||
return plugchan->alloc_ptr[idx];
|
return plugstr->alloc_ptr[idx];
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void snd_pcm_plug_buf_unlock(snd_pcm_t *pcm, int channel, void *ptr)
|
void snd_pcm_plug_buf_unlock(snd_pcm_t *pcm, int stream, void *ptr)
|
||||||
{
|
{
|
||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
snd_pcm_plug_t *plug;
|
snd_pcm_plug_t *plug;
|
||||||
struct snd_pcm_plug_chan *plugchan;
|
struct snd_pcm_plug_stream *plugstr;
|
||||||
|
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
return;
|
return;
|
||||||
plug = (snd_pcm_plug_t*) &pcm->private;
|
plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
plugchan = &plug->chan[channel];
|
plugstr = &plug->stream[stream];
|
||||||
|
|
||||||
for (idx = 0; idx < 2; idx++) {
|
for (idx = 0; idx < 2; idx++) {
|
||||||
if (plugchan->alloc_ptr[idx] == ptr) {
|
if (plugstr->alloc_ptr[idx] == ptr) {
|
||||||
plugchan->alloc_lock[idx] = 0;
|
plugstr->alloc_lock[idx] = 0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -84,21 +84,21 @@ void snd_pcm_plug_buf_unlock(snd_pcm_t *pcm, int channel, void *ptr)
|
||||||
int snd_pcm_plugin_insert(snd_pcm_plugin_t *plugin)
|
int snd_pcm_plugin_insert(snd_pcm_plugin_t *plugin)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug;
|
snd_pcm_plug_t *plug;
|
||||||
struct snd_pcm_plug_chan *plugchan;
|
struct snd_pcm_plug_stream *plugstr;
|
||||||
snd_pcm_t *pcm;
|
snd_pcm_t *pcm;
|
||||||
if (!plugin)
|
if (!plugin)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
pcm = plugin->handle;
|
pcm = plugin->handle;
|
||||||
plug = (snd_pcm_plug_t*) &pcm->private;
|
plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
plugchan = &plug->chan[plugin->channel];
|
plugstr = &plug->stream[plugin->stream];
|
||||||
plugin->next = plugchan->first;
|
plugin->next = plugstr->first;
|
||||||
plugin->prev = NULL;
|
plugin->prev = NULL;
|
||||||
if (plugchan->first) {
|
if (plugstr->first) {
|
||||||
plugchan->first->prev = plugin;
|
plugstr->first->prev = plugin;
|
||||||
plugchan->first = plugin;
|
plugstr->first = plugin;
|
||||||
} else {
|
} else {
|
||||||
plugchan->last =
|
plugstr->last =
|
||||||
plugchan->first = plugin;
|
plugstr->first = plugin;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -106,22 +106,22 @@ int snd_pcm_plugin_insert(snd_pcm_plugin_t *plugin)
|
||||||
int snd_pcm_plugin_append(snd_pcm_plugin_t *plugin)
|
int snd_pcm_plugin_append(snd_pcm_plugin_t *plugin)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug;
|
snd_pcm_plug_t *plug;
|
||||||
struct snd_pcm_plug_chan *plugchan;
|
struct snd_pcm_plug_stream *plugstr;
|
||||||
snd_pcm_t *pcm;
|
snd_pcm_t *pcm;
|
||||||
if (!plugin)
|
if (!plugin)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
pcm = plugin->handle;
|
pcm = plugin->handle;
|
||||||
plug = (snd_pcm_plug_t*) &pcm->private;
|
plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
plugchan = &plug->chan[plugin->channel];
|
plugstr = &plug->stream[plugin->stream];
|
||||||
|
|
||||||
plugin->next = NULL;
|
plugin->next = NULL;
|
||||||
plugin->prev = plugchan->last;
|
plugin->prev = plugstr->last;
|
||||||
if (plugchan->last) {
|
if (plugstr->last) {
|
||||||
plugchan->last->next = plugin;
|
plugstr->last->next = plugin;
|
||||||
plugchan->last = plugin;
|
plugstr->last = plugin;
|
||||||
} else {
|
} else {
|
||||||
plugchan->last =
|
plugstr->last =
|
||||||
plugchan->first = plugin;
|
plugstr->first = plugin;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -132,20 +132,20 @@ int snd_pcm_plugin_remove_to(snd_pcm_plugin_t *plugin)
|
||||||
snd_pcm_plugin_t *plugin1, *plugin1_prev;
|
snd_pcm_plugin_t *plugin1, *plugin1_prev;
|
||||||
snd_pcm_plug_t *plug;
|
snd_pcm_plug_t *plug;
|
||||||
snd_pcm_t *pcm;
|
snd_pcm_t *pcm;
|
||||||
struct snd_pcm_plug_chan *plugchan;
|
struct snd_pcm_plug_stream *plugstr;
|
||||||
if (!plugin)
|
if (!plugin)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
pcm = plugin->handle;
|
pcm = plugin->handle;
|
||||||
|
|
||||||
plug = (snd_pcm_plug_t*) &pcm->private;
|
plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
plugchan = &plug->chan[plugin->channel];
|
plugstr = &plug->stream[plugin->stream];
|
||||||
|
|
||||||
plugin1 = plugin;
|
plugin1 = plugin;
|
||||||
while (plugin1->prev)
|
while (plugin1->prev)
|
||||||
plugin1 = plugin1->prev;
|
plugin1 = plugin1->prev;
|
||||||
if (plugchan->first != plugin1)
|
if (plugstr->first != plugin1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
plugchan->first = plugin;
|
plugstr->first = plugin;
|
||||||
plugin1 = plugin->prev;
|
plugin1 = plugin->prev;
|
||||||
plugin->prev = NULL;
|
plugin->prev = NULL;
|
||||||
while (plugin1) {
|
while (plugin1) {
|
||||||
|
|
@ -156,26 +156,26 @@ int snd_pcm_plugin_remove_to(snd_pcm_plugin_t *plugin)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_plug_remove_first(snd_pcm_t *pcm, int channel)
|
int snd_pcm_plug_remove_first(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
snd_pcm_plugin_t *plugin;
|
snd_pcm_plugin_t *plugin;
|
||||||
snd_pcm_plug_t *plug;
|
snd_pcm_plug_t *plug;
|
||||||
struct snd_pcm_plug_chan *plugchan;
|
struct snd_pcm_plug_stream *plugstr;
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (channel < 0 || channel > 1)
|
if (stream < 0 || stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!pcm->chan[channel].open)
|
if (!pcm->stream[stream].open)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
|
|
||||||
plug = (snd_pcm_plug_t*) &pcm->private;
|
plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
plugchan = &plug->chan[channel];
|
plugstr = &plug->stream[stream];
|
||||||
|
|
||||||
plugin = plugchan->first;
|
plugin = plugstr->first;
|
||||||
if (plugin->next) {
|
if (plugin->next) {
|
||||||
plugin = plugin->next;
|
plugin = plugin->next;
|
||||||
} else {
|
} else {
|
||||||
return snd_pcm_plug_clear(pcm, channel);
|
return snd_pcm_plug_clear(pcm, stream);
|
||||||
}
|
}
|
||||||
return snd_pcm_plugin_remove_to(plugin);
|
return snd_pcm_plugin_remove_to(plugin);
|
||||||
}
|
}
|
||||||
|
|
@ -183,108 +183,108 @@ int snd_pcm_plug_remove_first(snd_pcm_t *pcm, int channel)
|
||||||
|
|
||||||
/* snd_pcm_plug externs */
|
/* snd_pcm_plug externs */
|
||||||
|
|
||||||
int snd_pcm_plug_clear(snd_pcm_t *pcm, int channel)
|
int snd_pcm_plug_clear(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
snd_pcm_plugin_t *plugin, *plugin_next;
|
snd_pcm_plugin_t *plugin, *plugin_next;
|
||||||
snd_pcm_plug_t *plug;
|
snd_pcm_plug_t *plug;
|
||||||
struct snd_pcm_plug_chan *plugchan;
|
struct snd_pcm_plug_stream *plugstr;
|
||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (channel < 0 || channel > 1)
|
if (stream < 0 || stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!pcm->chan[channel].open)
|
if (!pcm->stream[stream].open)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
|
|
||||||
plug = (snd_pcm_plug_t*) &pcm->private;
|
plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
plugchan = &plug->chan[channel];
|
plugstr = &plug->stream[stream];
|
||||||
plugin = plugchan->first;
|
plugin = plugstr->first;
|
||||||
plugchan->first = NULL;
|
plugstr->first = NULL;
|
||||||
plugchan->last = NULL;
|
plugstr->last = NULL;
|
||||||
while (plugin) {
|
while (plugin) {
|
||||||
plugin_next = plugin->next;
|
plugin_next = plugin->next;
|
||||||
snd_pcm_plugin_free(plugin);
|
snd_pcm_plugin_free(plugin);
|
||||||
plugin = plugin_next;
|
plugin = plugin_next;
|
||||||
}
|
}
|
||||||
for (idx = 0; idx < 2; idx++) {
|
for (idx = 0; idx < 2; idx++) {
|
||||||
if (plugchan->alloc_ptr[idx]) {
|
if (plugstr->alloc_ptr[idx]) {
|
||||||
free(plugchan->alloc_ptr[idx]);
|
free(plugstr->alloc_ptr[idx]);
|
||||||
plugchan->alloc_ptr[idx] = 0;
|
plugstr->alloc_ptr[idx] = 0;
|
||||||
}
|
}
|
||||||
plugchan->alloc_size[idx] = 0;
|
plugstr->alloc_size[idx] = 0;
|
||||||
plugchan->alloc_lock[idx] = 0;
|
plugstr->alloc_lock[idx] = 0;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
snd_pcm_plugin_t *snd_pcm_plug_first(snd_pcm_t *pcm, int channel)
|
snd_pcm_plugin_t *snd_pcm_plug_first(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug;
|
snd_pcm_plug_t *plug;
|
||||||
struct snd_pcm_plug_chan *plugchan;
|
struct snd_pcm_plug_stream *plugstr;
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (channel < 0 || channel > 1)
|
if (stream < 0 || stream > 1)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!pcm->chan[channel].open)
|
if (!pcm->stream[stream].open)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
plug = (snd_pcm_plug_t*) &pcm->private;
|
plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
plugchan = &plug->chan[channel];
|
plugstr = &plug->stream[stream];
|
||||||
|
|
||||||
return plugchan->first;
|
return plugstr->first;
|
||||||
}
|
}
|
||||||
|
|
||||||
snd_pcm_plugin_t *snd_pcm_plug_last(snd_pcm_t *pcm, int channel)
|
snd_pcm_plugin_t *snd_pcm_plug_last(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug;
|
snd_pcm_plug_t *plug;
|
||||||
struct snd_pcm_plug_chan *plugchan;
|
struct snd_pcm_plug_stream *plugstr;
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (channel < 0 || channel > 1)
|
if (stream < 0 || stream > 1)
|
||||||
return NULL;
|
return NULL;
|
||||||
if (!pcm->chan[channel].open)
|
if (!pcm->stream[stream].open)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
plug = (snd_pcm_plug_t*) &pcm->private;
|
plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
plugchan = &plug->chan[channel];
|
plugstr = &plug->stream[stream];
|
||||||
|
|
||||||
return plugchan->last;
|
return plugstr->last;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_plug_direct(snd_pcm_t *pcm, int channel)
|
int snd_pcm_plug_direct(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
return snd_pcm_plug_first(pcm, channel) == NULL;
|
return snd_pcm_plug_first(pcm, stream) == NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
double snd_pcm_plug_client_ratio(snd_pcm_t *pcm, int channel)
|
double snd_pcm_plug_client_ratio(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
ssize_t client;
|
ssize_t client;
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (channel < 0 || channel > 1)
|
if (stream < 0 || stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!pcm->chan[channel].open)
|
if (!pcm->stream[stream].open)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
|
|
||||||
client = snd_pcm_plug_client_size(pcm, channel, 1000000);
|
client = snd_pcm_plug_client_size(pcm, stream, 1000000);
|
||||||
if (client < 0)
|
if (client < 0)
|
||||||
return 0;
|
return 0;
|
||||||
return (double)client / (double)1000000;
|
return (double)client / (double)1000000;
|
||||||
}
|
}
|
||||||
|
|
||||||
double snd_pcm_plug_slave_ratio(snd_pcm_t *pcm, int channel)
|
double snd_pcm_plug_slave_ratio(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
ssize_t slave;
|
ssize_t slave;
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (channel < 0 || channel > 1)
|
if (stream < 0 || stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!pcm->chan[channel].open)
|
if (!pcm->stream[stream].open)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
|
|
||||||
slave = snd_pcm_plug_slave_size(pcm, channel, 1000000);
|
slave = snd_pcm_plug_slave_size(pcm, stream, 1000000);
|
||||||
if (slave < 0)
|
if (slave < 0)
|
||||||
return 0;
|
return 0;
|
||||||
return (double)slave / (double)1000000;
|
return (double)slave / (double)1000000;
|
||||||
|
|
@ -295,19 +295,19 @@ double snd_pcm_plug_slave_ratio(snd_pcm_t *pcm, int channel)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static int snd_pcm_plug_channel_close(snd_pcm_t *pcm, int channel)
|
static int snd_pcm_plug_stream_close(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
snd_pcm_plug_clear(pcm, channel);
|
snd_pcm_plug_clear(pcm, stream);
|
||||||
if (plug->close_slave)
|
if (plug->close_slave)
|
||||||
return snd_pcm_channel_close(plug->slave, channel);
|
return snd_pcm_stream_close(plug->slave, stream);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_plug_channel_nonblock(snd_pcm_t *pcm, int channel, int nonblock)
|
static int snd_pcm_plug_stream_nonblock(snd_pcm_t *pcm, int stream, int nonblock)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
return snd_pcm_channel_nonblock(plug->slave, channel, nonblock);
|
return snd_pcm_stream_nonblock(plug->slave, stream, nonblock);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_plug_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
|
static int snd_pcm_plug_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
|
||||||
|
|
@ -316,51 +316,51 @@ static int snd_pcm_plug_info(snd_pcm_t *pcm, snd_pcm_info_t * info)
|
||||||
return snd_pcm_info(plug->slave, info);
|
return snd_pcm_info(plug->slave, info);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_plug_channel_info(snd_pcm_t *pcm, snd_pcm_channel_info_t *info)
|
static int snd_pcm_plug_stream_info(snd_pcm_t *pcm, snd_pcm_stream_info_t *info)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
struct snd_pcm_chan *chan;
|
struct snd_pcm_stream *str;
|
||||||
|
|
||||||
if ((err = snd_pcm_channel_info(plug->slave, info)) < 0)
|
if ((err = snd_pcm_stream_info(plug->slave, info)) < 0)
|
||||||
return err;
|
return err;
|
||||||
info->formats = snd_pcm_plug_formats(info->formats);
|
info->formats = snd_pcm_plug_formats(info->formats);
|
||||||
info->min_rate = 4000;
|
info->min_rate = 4000;
|
||||||
info->max_rate = 192000;
|
info->max_rate = 192000;
|
||||||
info->min_voices = 1;
|
info->min_channels = 1;
|
||||||
info->max_voices = 32;
|
info->max_channels = 32;
|
||||||
info->rates = SND_PCM_RATE_CONTINUOUS | SND_PCM_RATE_8000_192000;
|
info->rates = SND_PCM_RATE_CONTINUOUS | SND_PCM_RATE_8000_192000;
|
||||||
info->flags |= SND_PCM_CHNINFO_INTERLEAVE | SND_PCM_CHNINFO_NONINTERLEAVE;
|
info->flags |= SND_PCM_STREAM_INFO_INTERLEAVE | SND_PCM_STREAM_INFO_NONINTERLEAVE;
|
||||||
|
|
||||||
chan = &pcm->chan[info->channel];
|
str = &pcm->stream[info->stream];
|
||||||
if (pcm->chan[info->channel].valid_setup) {
|
if (pcm->stream[info->stream].valid_setup) {
|
||||||
info->buffer_size = snd_pcm_plug_client_size(pcm, info->channel, info->buffer_size);
|
info->buffer_size = snd_pcm_plug_client_size(pcm, info->stream, info->buffer_size);
|
||||||
info->min_fragment_size = snd_pcm_plug_client_size(pcm, info->channel, info->min_fragment_size);
|
info->min_fragment_size = snd_pcm_plug_client_size(pcm, info->stream, info->min_fragment_size);
|
||||||
info->max_fragment_size = snd_pcm_plug_client_size(pcm, info->channel, info->max_fragment_size);
|
info->max_fragment_size = snd_pcm_plug_client_size(pcm, info->stream, info->max_fragment_size);
|
||||||
info->fragment_align = snd_pcm_plug_client_size(pcm, info->channel, info->fragment_align);
|
info->fragment_align = snd_pcm_plug_client_size(pcm, info->stream, info->fragment_align);
|
||||||
info->fifo_size = snd_pcm_plug_client_size(pcm, info->channel, info->fifo_size);
|
info->fifo_size = snd_pcm_plug_client_size(pcm, info->stream, info->fifo_size);
|
||||||
info->transfer_block_size = snd_pcm_plug_client_size(pcm, info->channel, info->transfer_block_size);
|
info->transfer_block_size = snd_pcm_plug_client_size(pcm, info->stream, info->transfer_block_size);
|
||||||
if (chan->setup.mode == SND_PCM_MODE_BLOCK)
|
if (str->setup.mode == SND_PCM_MODE_FRAGMENT)
|
||||||
info->mmap_size = chan->setup.buffer_size;
|
info->mmap_size = str->setup.buffer_size;
|
||||||
else
|
else
|
||||||
info->mmap_size = snd_pcm_plug_client_size(pcm, info->channel, info->mmap_size);
|
info->mmap_size = snd_pcm_plug_client_size(pcm, info->stream, info->mmap_size);
|
||||||
}
|
}
|
||||||
if (!snd_pcm_plug_direct(pcm, info->channel))
|
if (!snd_pcm_plug_direct(pcm, info->stream))
|
||||||
info->flags &= ~(SND_PCM_CHNINFO_MMAP | SND_PCM_CHNINFO_MMAP_VALID);
|
info->flags &= ~(SND_PCM_STREAM_INFO_MMAP | SND_PCM_STREAM_INFO_MMAP_VALID);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_plug_action(snd_pcm_t *pcm, int channel, int action,
|
static int snd_pcm_plug_action(snd_pcm_t *pcm, int stream, int action,
|
||||||
unsigned long data)
|
unsigned long data)
|
||||||
{
|
{
|
||||||
snd_pcm_plugin_t *plugin;
|
snd_pcm_plugin_t *plugin;
|
||||||
int err;
|
int err;
|
||||||
snd_pcm_plug_t *plug;
|
snd_pcm_plug_t *plug;
|
||||||
struct snd_pcm_plug_chan *plugchan;
|
struct snd_pcm_plug_stream *plugstr;
|
||||||
plug = (snd_pcm_plug_t*) &pcm->private;
|
plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
plugchan = &plug->chan[channel];
|
plugstr = &plug->stream[stream];
|
||||||
|
|
||||||
plugin = plugchan->first;
|
plugin = plugstr->first;
|
||||||
while (plugin) {
|
while (plugin) {
|
||||||
if (plugin->action) {
|
if (plugin->action) {
|
||||||
if ((err = plugin->action(plugin, action, data))<0)
|
if ((err = plugin->action(plugin, action, data))<0)
|
||||||
|
|
@ -371,14 +371,14 @@ static int snd_pcm_plug_action(snd_pcm_t *pcm, int channel, int action,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_plug_channel_params(snd_pcm_t *pcm, snd_pcm_channel_params_t *params)
|
static int snd_pcm_plug_stream_params(snd_pcm_t *pcm, snd_pcm_stream_params_t *params)
|
||||||
{
|
{
|
||||||
snd_pcm_channel_params_t slave_params, params1;
|
snd_pcm_stream_params_t slave_params, params1;
|
||||||
snd_pcm_channel_info_t slave_info;
|
snd_pcm_stream_info_t slave_info;
|
||||||
snd_pcm_plugin_t *plugin;
|
snd_pcm_plugin_t *plugin;
|
||||||
snd_pcm_plug_t *plug;
|
snd_pcm_plug_t *plug;
|
||||||
int err;
|
int err;
|
||||||
int channel = params->channel;
|
int stream = params->stream;
|
||||||
|
|
||||||
plug = (snd_pcm_plug_t*) &pcm->private;
|
plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
|
|
||||||
|
|
@ -387,9 +387,9 @@ static int snd_pcm_plug_channel_params(snd_pcm_t *pcm, snd_pcm_channel_params_t
|
||||||
*/
|
*/
|
||||||
|
|
||||||
memset(&slave_info, 0, sizeof(slave_info));
|
memset(&slave_info, 0, sizeof(slave_info));
|
||||||
slave_info.channel = channel;
|
slave_info.stream = stream;
|
||||||
if ((err = snd_pcm_channel_info(plug->slave, &slave_info)) < 0) {
|
if ((err = snd_pcm_stream_info(plug->slave, &slave_info)) < 0) {
|
||||||
snd_pcm_plug_clear(pcm, channel);
|
snd_pcm_plug_clear(pcm, stream);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -397,30 +397,30 @@ static int snd_pcm_plug_channel_params(snd_pcm_t *pcm, snd_pcm_channel_params_t
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
|
|
||||||
snd_pcm_plug_clear(pcm, channel);
|
snd_pcm_plug_clear(pcm, stream);
|
||||||
|
|
||||||
/* add necessary plugins */
|
/* add necessary plugins */
|
||||||
memcpy(¶ms1, params, sizeof(*params));
|
memcpy(¶ms1, params, sizeof(*params));
|
||||||
if ((err = snd_pcm_plug_format(pcm, ¶ms1, &slave_params)) < 0)
|
if ((err = snd_pcm_plug_format(pcm, ¶ms1, &slave_params)) < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
if (snd_pcm_plug_direct(pcm, channel))
|
if (snd_pcm_plug_direct(pcm, stream))
|
||||||
return snd_pcm_channel_params(plug->slave, params);
|
return snd_pcm_stream_params(plug->slave, params);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* I/O plugins
|
* I/O plugins
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if (slave_info.flags & SND_PCM_CHNINFO_MMAP) {
|
if (slave_info.flags & SND_PCM_STREAM_INFO_MMAP) {
|
||||||
pdprintf("params mmap plugin\n");
|
pdprintf("params mmap plugin\n");
|
||||||
err = snd_pcm_plugin_build_mmap(pcm, channel, plug->slave, &slave_params.format, &plugin);
|
err = snd_pcm_plugin_build_mmap(pcm, stream, plug->slave, &slave_params.format, &plugin);
|
||||||
} else {
|
} else {
|
||||||
pdprintf("params I/O plugin\n");
|
pdprintf("params I/O plugin\n");
|
||||||
err = snd_pcm_plugin_build_io(pcm, channel, plug->slave, &slave_params.format, &plugin);
|
err = snd_pcm_plugin_build_io(pcm, stream, plug->slave, &slave_params.format, &plugin);
|
||||||
}
|
}
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
if (channel == SND_PCM_CHANNEL_PLAYBACK) {
|
if (stream == SND_PCM_STREAM_PLAYBACK) {
|
||||||
err = snd_pcm_plugin_append(plugin);
|
err = snd_pcm_plugin_append(plugin);
|
||||||
} else {
|
} else {
|
||||||
err = snd_pcm_plugin_insert(plugin);
|
err = snd_pcm_plugin_insert(plugin);
|
||||||
|
|
@ -431,105 +431,105 @@ static int snd_pcm_plug_channel_params(snd_pcm_t *pcm, snd_pcm_channel_params_t
|
||||||
}
|
}
|
||||||
|
|
||||||
/* compute right sizes */
|
/* compute right sizes */
|
||||||
slave_params.buffer_size = snd_pcm_plug_slave_size(pcm, channel, slave_params.buffer_size);
|
slave_params.buffer_size = snd_pcm_plug_slave_size(pcm, stream, slave_params.buffer_size);
|
||||||
slave_params.frag_size = snd_pcm_plug_slave_size(pcm, channel, slave_params.frag_size);
|
slave_params.frag_size = snd_pcm_plug_slave_size(pcm, stream, slave_params.frag_size);
|
||||||
slave_params.bytes_fill_max = snd_pcm_plug_slave_size(pcm, channel, slave_params.bytes_fill_max);
|
slave_params.bytes_fill_max = snd_pcm_plug_slave_size(pcm, stream, slave_params.bytes_fill_max);
|
||||||
slave_params.bytes_min = snd_pcm_plug_slave_size(pcm, channel, slave_params.bytes_min);
|
slave_params.bytes_min = snd_pcm_plug_slave_size(pcm, stream, slave_params.bytes_min);
|
||||||
slave_params.bytes_xrun_max = snd_pcm_plug_slave_size(pcm, channel, slave_params.bytes_xrun_max);
|
slave_params.bytes_xrun_max = snd_pcm_plug_slave_size(pcm, stream, slave_params.bytes_xrun_max);
|
||||||
slave_params.bytes_align = snd_pcm_plug_slave_size(pcm, channel, slave_params.bytes_align);
|
slave_params.bytes_align = snd_pcm_plug_slave_size(pcm, stream, slave_params.bytes_align);
|
||||||
|
|
||||||
pdprintf("params requested params: format = %i, rate = %i, voices = %i\n", slave_params.format.format, slave_params.format.rate, slave_params.format.voices);
|
pdprintf("params requested params: format = %i, rate = %i, channels = %i\n", slave_params.format.format, slave_params.format.rate, slave_params.format.channels);
|
||||||
err = snd_pcm_channel_params(plug->slave, &slave_params);
|
err = snd_pcm_stream_params(plug->slave, &slave_params);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = snd_pcm_plug_action(pcm, channel, INIT, 0);
|
err = snd_pcm_plug_action(pcm, stream, INIT, 0);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_plug_channel_setup(snd_pcm_t *pcm, snd_pcm_channel_setup_t *setup)
|
static int snd_pcm_plug_stream_setup(snd_pcm_t *pcm, snd_pcm_stream_setup_t *setup)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
struct snd_pcm_plug_chan *plugchan;
|
struct snd_pcm_plug_stream *plugstr;
|
||||||
|
|
||||||
err = snd_pcm_channel_setup(plug->slave, setup);
|
err = snd_pcm_stream_setup(plug->slave, setup);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
if (snd_pcm_plug_direct(pcm, setup->channel))
|
if (snd_pcm_plug_direct(pcm, setup->stream))
|
||||||
return 0;
|
return 0;
|
||||||
setup->byte_boundary /= setup->frag_size;
|
setup->byte_boundary /= setup->frag_size;
|
||||||
setup->frag_size = snd_pcm_plug_client_size(pcm, setup->channel, setup->frag_size);
|
setup->frag_size = snd_pcm_plug_client_size(pcm, setup->stream, setup->frag_size);
|
||||||
setup->byte_boundary *= setup->frag_size;
|
setup->byte_boundary *= setup->frag_size;
|
||||||
setup->buffer_size = setup->frags * setup->frag_size;
|
setup->buffer_size = setup->frags * setup->frag_size;
|
||||||
setup->bytes_min = snd_pcm_plug_client_size(pcm, setup->channel, setup->bytes_min);
|
setup->bytes_min = snd_pcm_plug_client_size(pcm, setup->stream, setup->bytes_min);
|
||||||
setup->bytes_align = snd_pcm_plug_client_size(pcm, setup->channel, setup->bytes_align);
|
setup->bytes_align = snd_pcm_plug_client_size(pcm, setup->stream, setup->bytes_align);
|
||||||
setup->bytes_xrun_max = snd_pcm_plug_client_size(pcm, setup->channel, setup->bytes_xrun_max);
|
setup->bytes_xrun_max = snd_pcm_plug_client_size(pcm, setup->stream, setup->bytes_xrun_max);
|
||||||
setup->bytes_fill_max = snd_pcm_plug_client_size(pcm, setup->channel, setup->bytes_fill_max);
|
setup->bytes_fill_max = snd_pcm_plug_client_size(pcm, setup->stream, setup->bytes_fill_max);
|
||||||
|
|
||||||
plugchan = &plug->chan[setup->channel];
|
plugstr = &plug->stream[setup->stream];
|
||||||
if (setup->channel == SND_PCM_CHANNEL_PLAYBACK)
|
if (setup->stream == SND_PCM_STREAM_PLAYBACK)
|
||||||
setup->format = plugchan->first->src_format;
|
setup->format = plugstr->first->src_format;
|
||||||
else
|
else
|
||||||
setup->format = plugchan->last->dst_format;
|
setup->format = plugstr->last->dst_format;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_plug_channel_status(snd_pcm_t *pcm, snd_pcm_channel_status_t *status)
|
static int snd_pcm_plug_stream_status(snd_pcm_t *pcm, snd_pcm_stream_status_t *status)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
|
|
||||||
err = snd_pcm_channel_status(plug->slave, status);
|
err = snd_pcm_stream_status(plug->slave, status);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
if (snd_pcm_plug_direct(pcm, status->channel))
|
if (snd_pcm_plug_direct(pcm, status->stream))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* FIXME: may overflow */
|
/* FIXME: may overflow */
|
||||||
status->byte_io = snd_pcm_plug_client_size(pcm, status->channel, status->byte_io);
|
status->byte_io = snd_pcm_plug_client_size(pcm, status->stream, status->byte_io);
|
||||||
status->byte_data = snd_pcm_plug_client_size(pcm, status->channel, status->byte_data);
|
status->byte_data = snd_pcm_plug_client_size(pcm, status->stream, status->byte_data);
|
||||||
status->bytes_used = snd_pcm_plug_client_size(pcm, status->channel, status->bytes_used);
|
status->bytes_used = snd_pcm_plug_client_size(pcm, status->stream, status->bytes_used);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_plug_channel_update(snd_pcm_t *pcm, int channel)
|
static int snd_pcm_plug_stream_update(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
int err;
|
int err;
|
||||||
err = snd_pcm_channel_update(plug->slave, channel);
|
err = snd_pcm_stream_update(plug->slave, stream);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
if (snd_pcm_plug_direct(pcm, channel))
|
if (snd_pcm_plug_direct(pcm, stream))
|
||||||
return 0;
|
return 0;
|
||||||
#if 0
|
#if 0
|
||||||
/* To think more about that */
|
/* To think more about that */
|
||||||
if ((err = snd_pcm_plug_action(pcm, channel, UPDATE, 0))<0)
|
if ((err = snd_pcm_plug_action(pcm, stream, UPDATE, 0))<0)
|
||||||
return err;
|
return err;
|
||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_plug_channel_prepare(snd_pcm_t *pcm, int channel)
|
static int snd_pcm_plug_stream_prepare(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
int err;
|
int err;
|
||||||
err = snd_pcm_channel_prepare(plug->slave, channel);
|
err = snd_pcm_stream_prepare(plug->slave, stream);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
if (snd_pcm_plug_direct(pcm, channel))
|
if (snd_pcm_plug_direct(pcm, stream))
|
||||||
return 0;
|
return 0;
|
||||||
if ((err = snd_pcm_plug_action(pcm, channel, PREPARE, 0))<0)
|
if ((err = snd_pcm_plug_action(pcm, stream, PREPARE, 0))<0)
|
||||||
return err;
|
return err;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_plug_channel_go(snd_pcm_t *pcm, int channel)
|
static int snd_pcm_plug_stream_go(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
return snd_pcm_channel_go(plug->slave, channel);
|
return snd_pcm_stream_go(plug->slave, stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_plug_sync_go(snd_pcm_t *pcm, snd_pcm_sync_t *sync)
|
static int snd_pcm_plug_sync_go(snd_pcm_t *pcm, snd_pcm_sync_t *sync)
|
||||||
|
|
@ -538,76 +538,76 @@ static int snd_pcm_plug_sync_go(snd_pcm_t *pcm, snd_pcm_sync_t *sync)
|
||||||
return snd_pcm_sync_go(plug->slave, sync);
|
return snd_pcm_sync_go(plug->slave, sync);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_plug_channel_drain(snd_pcm_t *pcm, int channel)
|
static int snd_pcm_plug_stream_drain(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if ((err = snd_pcm_channel_drain(plug->slave, channel)) < 0)
|
if ((err = snd_pcm_stream_drain(plug->slave, stream)) < 0)
|
||||||
return err;
|
return err;
|
||||||
if (snd_pcm_plug_direct(pcm, channel))
|
if (snd_pcm_plug_direct(pcm, stream))
|
||||||
return 0;
|
return 0;
|
||||||
if ((err = snd_pcm_plug_action(pcm, channel, DRAIN, 0))<0)
|
if ((err = snd_pcm_plug_action(pcm, stream, DRAIN, 0))<0)
|
||||||
return err;
|
return err;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_plug_channel_flush(snd_pcm_t *pcm, int channel)
|
static int snd_pcm_plug_stream_flush(snd_pcm_t *pcm, int stream)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if ((err = snd_pcm_channel_flush(plug->slave, channel)) < 0)
|
if ((err = snd_pcm_stream_flush(plug->slave, stream)) < 0)
|
||||||
return err;
|
return err;
|
||||||
if (snd_pcm_plug_direct(pcm, channel))
|
if (snd_pcm_plug_direct(pcm, stream))
|
||||||
return 0;
|
return 0;
|
||||||
if ((err = snd_pcm_plug_action(pcm, channel, FLUSH, 0))<0)
|
if ((err = snd_pcm_plug_action(pcm, stream, FLUSH, 0))<0)
|
||||||
return err;
|
return err;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_plug_channel_pause(snd_pcm_t *pcm, int channel, int enable)
|
static int snd_pcm_plug_stream_pause(snd_pcm_t *pcm, int stream, int enable)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if ((err = snd_pcm_channel_pause(plug->slave, channel, enable)) < 0)
|
if ((err = snd_pcm_stream_pause(plug->slave, stream, enable)) < 0)
|
||||||
return err;
|
return err;
|
||||||
if ((err = snd_pcm_plug_action(pcm, channel, PAUSE, 0))<0)
|
if ((err = snd_pcm_plug_action(pcm, stream, PAUSE, 0))<0)
|
||||||
return err;
|
return err;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_plug_voice_setup(snd_pcm_t *pcm, int channel, snd_pcm_voice_setup_t *setup)
|
static int snd_pcm_plug_channel_setup(snd_pcm_t *pcm, int stream, snd_pcm_channel_setup_t *setup)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
struct snd_pcm_chan *chan;
|
struct snd_pcm_stream *str;
|
||||||
unsigned int voice;
|
unsigned int channel;
|
||||||
int width;
|
int width;
|
||||||
|
|
||||||
if (snd_pcm_plug_direct(pcm, channel))
|
if (snd_pcm_plug_direct(pcm, stream))
|
||||||
return snd_pcm_voice_setup(plug->slave, channel, setup);
|
return snd_pcm_channel_setup(plug->slave, stream, setup);
|
||||||
|
|
||||||
voice = setup->voice;
|
channel = setup->channel;
|
||||||
memset(setup, 0, sizeof(*setup));
|
memset(setup, 0, sizeof(*setup));
|
||||||
setup->voice = voice;
|
setup->channel = channel;
|
||||||
chan = &pcm->chan[channel];
|
str = &pcm->stream[stream];
|
||||||
if (!chan->mmap_data) {
|
if (!str->mmap_data) {
|
||||||
setup->area.addr = 0;
|
setup->area.addr = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (voice >= chan->setup.format.voices)
|
if (channel >= str->setup.format.channels)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (chan->setup.format.interleave) {
|
if (str->setup.format.interleave) {
|
||||||
setup->area.addr = chan->mmap_data;
|
setup->area.addr = str->mmap_data;
|
||||||
setup->area.first = setup->voice * chan->sample_width;
|
setup->area.first = setup->channel * str->sample_width;
|
||||||
setup->area.step = chan->bits_per_frame;
|
setup->area.step = str->bits_per_frame;
|
||||||
} else {
|
} else {
|
||||||
size_t size = chan->mmap_data_size / chan->setup.format.voices;
|
size_t size = str->mmap_data_size / str->setup.format.channels;
|
||||||
setup->area.addr = chan->mmap_data + setup->voice * size;
|
setup->area.addr = str->mmap_data + setup->channel * size;
|
||||||
setup->area.first = 0;
|
setup->area.first = 0;
|
||||||
setup->area.step = chan->sample_width;
|
setup->area.step = str->sample_width;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -615,26 +615,26 @@ static int snd_pcm_plug_voice_setup(snd_pcm_t *pcm, int channel, snd_pcm_voice_s
|
||||||
ssize_t snd_pcm_plug_writev(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count)
|
ssize_t snd_pcm_plug_writev(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
struct snd_pcm_chan *chan = &pcm->chan[SND_PCM_CHANNEL_PLAYBACK];
|
struct snd_pcm_stream *str = &pcm->stream[SND_PCM_STREAM_PLAYBACK];
|
||||||
unsigned int k, step, voices;
|
unsigned int k, step, channels;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
if (snd_pcm_plug_direct(pcm, SND_PCM_CHANNEL_PLAYBACK))
|
if (snd_pcm_plug_direct(pcm, SND_PCM_STREAM_PLAYBACK))
|
||||||
return snd_pcm_writev(plug->slave, vector, count);
|
return snd_pcm_writev(plug->slave, vector, count);
|
||||||
voices = chan->setup.format.voices;
|
channels = str->setup.format.channels;
|
||||||
if (chan->setup.format.interleave)
|
if (str->setup.format.interleave)
|
||||||
step = 1;
|
step = 1;
|
||||||
else {
|
else {
|
||||||
step = voices;
|
step = channels;
|
||||||
if (count % voices != 0)
|
if (count % channels != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
for (k = 0; k < count; k += step, vector += step) {
|
for (k = 0; k < count; k += step, vector += step) {
|
||||||
snd_pcm_plugin_voice_t *voices;
|
snd_pcm_plugin_channel_t *channels;
|
||||||
int expected, ret;
|
int expected, ret;
|
||||||
expected = snd_pcm_plug_client_voices_iovec(pcm, SND_PCM_CHANNEL_PLAYBACK, vector, count, &voices);
|
expected = snd_pcm_plug_client_channels_iovec(pcm, SND_PCM_STREAM_PLAYBACK, vector, count, &channels);
|
||||||
if (expected < 0)
|
if (expected < 0)
|
||||||
return expected;
|
return expected;
|
||||||
ret = snd_pcm_plug_write_transfer(pcm, voices, expected);
|
ret = snd_pcm_plug_write_transfer(pcm, channels, expected);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (size > 0)
|
if (size > 0)
|
||||||
return size;
|
return size;
|
||||||
|
|
@ -650,26 +650,26 @@ ssize_t snd_pcm_plug_writev(snd_pcm_t *pcm, const struct iovec *vector, unsigned
|
||||||
ssize_t snd_pcm_plug_readv(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count)
|
ssize_t snd_pcm_plug_readv(snd_pcm_t *pcm, const struct iovec *vector, unsigned long count)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
struct snd_pcm_chan *chan = &pcm->chan[SND_PCM_CHANNEL_CAPTURE];
|
struct snd_pcm_stream *str = &pcm->stream[SND_PCM_STREAM_CAPTURE];
|
||||||
unsigned int k, step, voices;
|
unsigned int k, step, channels;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
if (snd_pcm_plug_direct(pcm, SND_PCM_CHANNEL_CAPTURE))
|
if (snd_pcm_plug_direct(pcm, SND_PCM_STREAM_CAPTURE))
|
||||||
return snd_pcm_readv(plug->slave, vector, count);
|
return snd_pcm_readv(plug->slave, vector, count);
|
||||||
voices = chan->setup.format.voices;
|
channels = str->setup.format.channels;
|
||||||
if (chan->setup.format.interleave)
|
if (str->setup.format.interleave)
|
||||||
step = 1;
|
step = 1;
|
||||||
else {
|
else {
|
||||||
step = voices;
|
step = channels;
|
||||||
if (count % voices != 0)
|
if (count % channels != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
for (k = 0; k < count; k += step) {
|
for (k = 0; k < count; k += step) {
|
||||||
snd_pcm_plugin_voice_t *voices;
|
snd_pcm_plugin_channel_t *channels;
|
||||||
int expected, ret;
|
int expected, ret;
|
||||||
expected = snd_pcm_plug_client_voices_iovec(pcm, SND_PCM_CHANNEL_CAPTURE, vector, count, &voices);
|
expected = snd_pcm_plug_client_channels_iovec(pcm, SND_PCM_STREAM_CAPTURE, vector, count, &channels);
|
||||||
if (expected < 0)
|
if (expected < 0)
|
||||||
return expected;
|
return expected;
|
||||||
ret = snd_pcm_plug_read_transfer(pcm, voices, expected);
|
ret = snd_pcm_plug_read_transfer(pcm, channels, expected);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
if (size > 0)
|
if (size > 0)
|
||||||
return size;
|
return size;
|
||||||
|
|
@ -686,96 +686,96 @@ ssize_t snd_pcm_plug_write(snd_pcm_t *pcm, const void *buf, size_t count)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
int expected;
|
int expected;
|
||||||
snd_pcm_plugin_voice_t *voices;
|
snd_pcm_plugin_channel_t *channels;
|
||||||
|
|
||||||
if (snd_pcm_plug_direct(pcm, SND_PCM_CHANNEL_PLAYBACK))
|
if (snd_pcm_plug_direct(pcm, SND_PCM_STREAM_PLAYBACK))
|
||||||
return snd_pcm_write(plug->slave, buf, count);
|
return snd_pcm_write(plug->slave, buf, count);
|
||||||
expected = snd_pcm_plug_client_voices_buf(pcm, SND_PCM_CHANNEL_PLAYBACK, (char *)buf, count, &voices);
|
expected = snd_pcm_plug_client_channels_buf(pcm, SND_PCM_STREAM_PLAYBACK, (char *)buf, count, &channels);
|
||||||
if (expected < 0)
|
if (expected < 0)
|
||||||
return expected;
|
return expected;
|
||||||
return snd_pcm_plug_write_transfer(pcm, voices, expected);
|
return snd_pcm_plug_write_transfer(pcm, channels, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t snd_pcm_plug_read(snd_pcm_t *pcm, void *buf, size_t count)
|
ssize_t snd_pcm_plug_read(snd_pcm_t *pcm, void *buf, size_t count)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
int expected;
|
int expected;
|
||||||
snd_pcm_plugin_voice_t *voices;
|
snd_pcm_plugin_channel_t *channels;
|
||||||
|
|
||||||
if (snd_pcm_plug_direct(pcm, SND_PCM_CHANNEL_CAPTURE))
|
if (snd_pcm_plug_direct(pcm, SND_PCM_STREAM_CAPTURE))
|
||||||
return snd_pcm_read(plug->slave, buf, count);
|
return snd_pcm_read(plug->slave, buf, count);
|
||||||
expected = snd_pcm_plug_client_voices_buf(pcm, SND_PCM_CHANNEL_CAPTURE, buf, count, &voices);
|
expected = snd_pcm_plug_client_channels_buf(pcm, SND_PCM_STREAM_CAPTURE, buf, count, &channels);
|
||||||
if (expected < 0)
|
if (expected < 0)
|
||||||
return expected;
|
return expected;
|
||||||
return snd_pcm_plug_read_transfer(pcm, voices, expected);
|
return snd_pcm_plug_read_transfer(pcm, channels, expected);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_plug_mmap_control(snd_pcm_t *pcm, int channel, snd_pcm_mmap_control_t **control, size_t csize UNUSED)
|
static int snd_pcm_plug_mmap_control(snd_pcm_t *pcm, int stream, snd_pcm_mmap_control_t **control, size_t csize UNUSED)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
if (snd_pcm_plug_direct(pcm, channel))
|
if (snd_pcm_plug_direct(pcm, stream))
|
||||||
return snd_pcm_mmap_control(plug->slave, channel, control);
|
return snd_pcm_mmap_control(plug->slave, stream, control);
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_plug_mmap_data(snd_pcm_t *pcm, int channel, void **buffer, size_t bsize UNUSED)
|
static int snd_pcm_plug_mmap_data(snd_pcm_t *pcm, int stream, void **buffer, size_t bsize UNUSED)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
if (snd_pcm_plug_direct(pcm, channel))
|
if (snd_pcm_plug_direct(pcm, stream))
|
||||||
return snd_pcm_mmap_data(plug->slave, channel, buffer);
|
return snd_pcm_mmap_data(plug->slave, stream, buffer);
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_plug_munmap_control(snd_pcm_t *pcm, int channel, snd_pcm_mmap_control_t *control UNUSED, size_t csize UNUSED)
|
static int snd_pcm_plug_munmap_control(snd_pcm_t *pcm, int stream, snd_pcm_mmap_control_t *control UNUSED, size_t csize UNUSED)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
if (snd_pcm_plug_direct(pcm, channel))
|
if (snd_pcm_plug_direct(pcm, stream))
|
||||||
return snd_pcm_munmap_control(plug->slave, channel);
|
return snd_pcm_munmap_control(plug->slave, stream);
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_plug_munmap_data(snd_pcm_t *pcm, int channel, void *buffer UNUSED, size_t size UNUSED)
|
static int snd_pcm_plug_munmap_data(snd_pcm_t *pcm, int stream, void *buffer UNUSED, size_t size UNUSED)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
if (snd_pcm_plug_direct(pcm, channel))
|
if (snd_pcm_plug_direct(pcm, stream))
|
||||||
return snd_pcm_munmap_data(plug->slave, channel);
|
return snd_pcm_munmap_data(plug->slave, stream);
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int snd_pcm_plug_voices_mask(snd_pcm_t *pcm, int channel,
|
static int snd_pcm_plug_channels_mask(snd_pcm_t *pcm, int stream,
|
||||||
bitset_t *client_vmask)
|
bitset_t *client_vmask)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
if (snd_pcm_plug_direct(pcm, channel))
|
if (snd_pcm_plug_direct(pcm, stream))
|
||||||
return snd_pcm_voices_mask(plug->slave, channel, client_vmask);
|
return snd_pcm_channels_mask(plug->slave, stream, client_vmask);
|
||||||
if (channel == SND_PCM_CHANNEL_PLAYBACK)
|
if (stream == SND_PCM_STREAM_PLAYBACK)
|
||||||
return snd_pcm_plug_playback_voices_mask(pcm, client_vmask);
|
return snd_pcm_plug_playback_channels_mask(pcm, client_vmask);
|
||||||
else
|
else
|
||||||
return snd_pcm_plug_capture_voices_mask(pcm, client_vmask);
|
return snd_pcm_plug_capture_channels_mask(pcm, client_vmask);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_plug_file_descriptor(snd_pcm_t* pcm, int channel)
|
int snd_pcm_plug_file_descriptor(snd_pcm_t* pcm, int stream)
|
||||||
{
|
{
|
||||||
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
snd_pcm_plug_t *plug = (snd_pcm_plug_t*) &pcm->private;
|
||||||
return snd_pcm_file_descriptor(plug->slave, channel);
|
return snd_pcm_file_descriptor(plug->slave, stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct snd_pcm_ops snd_pcm_plug_ops = {
|
struct snd_pcm_ops snd_pcm_plug_ops = {
|
||||||
channel_close: snd_pcm_plug_channel_close,
|
stream_close: snd_pcm_plug_stream_close,
|
||||||
channel_nonblock: snd_pcm_plug_channel_nonblock,
|
stream_nonblock: snd_pcm_plug_stream_nonblock,
|
||||||
info: snd_pcm_plug_info,
|
info: snd_pcm_plug_info,
|
||||||
channel_info: snd_pcm_plug_channel_info,
|
stream_info: snd_pcm_plug_stream_info,
|
||||||
channel_params: snd_pcm_plug_channel_params,
|
stream_params: snd_pcm_plug_stream_params,
|
||||||
|
stream_setup: snd_pcm_plug_stream_setup,
|
||||||
channel_setup: snd_pcm_plug_channel_setup,
|
channel_setup: snd_pcm_plug_channel_setup,
|
||||||
voice_setup: snd_pcm_plug_voice_setup,
|
stream_status: snd_pcm_plug_stream_status,
|
||||||
channel_status: snd_pcm_plug_channel_status,
|
stream_update: snd_pcm_plug_stream_update,
|
||||||
channel_update: snd_pcm_plug_channel_update,
|
stream_prepare: snd_pcm_plug_stream_prepare,
|
||||||
channel_prepare: snd_pcm_plug_channel_prepare,
|
stream_go: snd_pcm_plug_stream_go,
|
||||||
channel_go: snd_pcm_plug_channel_go,
|
|
||||||
sync_go: snd_pcm_plug_sync_go,
|
sync_go: snd_pcm_plug_sync_go,
|
||||||
channel_drain: snd_pcm_plug_channel_drain,
|
stream_drain: snd_pcm_plug_stream_drain,
|
||||||
channel_flush: snd_pcm_plug_channel_flush,
|
stream_flush: snd_pcm_plug_stream_flush,
|
||||||
channel_pause: snd_pcm_plug_channel_pause,
|
stream_pause: snd_pcm_plug_stream_pause,
|
||||||
write: snd_pcm_plug_write,
|
write: snd_pcm_plug_write,
|
||||||
writev: snd_pcm_plug_writev,
|
writev: snd_pcm_plug_writev,
|
||||||
read: snd_pcm_plug_read,
|
read: snd_pcm_plug_read,
|
||||||
|
|
@ -785,7 +785,7 @@ struct snd_pcm_ops snd_pcm_plug_ops = {
|
||||||
munmap_control: snd_pcm_plug_munmap_control,
|
munmap_control: snd_pcm_plug_munmap_control,
|
||||||
munmap_data: snd_pcm_plug_munmap_data,
|
munmap_data: snd_pcm_plug_munmap_data,
|
||||||
file_descriptor: snd_pcm_plug_file_descriptor,
|
file_descriptor: snd_pcm_plug_file_descriptor,
|
||||||
voices_mask: snd_pcm_plug_voices_mask,
|
channels_mask: snd_pcm_plug_channels_mask,
|
||||||
};
|
};
|
||||||
|
|
||||||
int snd_pcm_plug_connect(snd_pcm_t **handle, snd_pcm_t *slave, int mode, int close_slave)
|
int snd_pcm_plug_connect(snd_pcm_t **handle, snd_pcm_t *slave, int mode, int close_slave)
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,7 @@ and vice versa. The ADPCM code used is the Intel/DVI ADPCM code which
|
||||||
is being recommended by the IMA Digital Audio Technical Working Group.
|
is being recommended by the IMA Digital Audio Technical Working Group.
|
||||||
|
|
||||||
The algorithm for this coder was taken from:
|
The algorithm for this coder was taken from:
|
||||||
Proposal for Standardized Audio Interchange Formats,
|
Proposal for Standardized Audio Interstreamge Formats,
|
||||||
IMA compatability project proceedings, Vol 2, Issue 2, May 1992.
|
IMA compatability project proceedings, Vol 2, Issue 2, May 1992.
|
||||||
|
|
||||||
- No, this is *not* a G.721 coder/decoder. The algorithm used by G.721
|
- No, this is *not* a G.721 coder/decoder. The algorithm used by G.721
|
||||||
|
|
@ -74,32 +74,32 @@ static short StepSize[89] = {
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int pred_val; /* Calculated predicted value */
|
int pred_val; /* Calculated predicted value */
|
||||||
int step_idx; /* Previous StepSize lookup index */
|
int step_idx; /* Previous StepSize lookup index */
|
||||||
} adpcm_voice_t;
|
} adpcm_channel_t;
|
||||||
|
|
||||||
typedef void (*adpcm_f)(snd_pcm_plugin_t *plugin,
|
typedef void (*adpcm_f)(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voices,
|
snd_pcm_plugin_channel_t *dst_channels,
|
||||||
size_t frames);
|
size_t frames);
|
||||||
|
|
||||||
typedef struct adpcm_private_data {
|
typedef struct adpcm_private_data {
|
||||||
adpcm_f func;
|
adpcm_f func;
|
||||||
int conv;
|
int conv;
|
||||||
adpcm_voice_t voices[0];
|
adpcm_channel_t channels[0];
|
||||||
} adpcm_t;
|
} adpcm_t;
|
||||||
|
|
||||||
|
|
||||||
static void adpcm_init(snd_pcm_plugin_t *plugin)
|
static void adpcm_init(snd_pcm_plugin_t *plugin)
|
||||||
{
|
{
|
||||||
unsigned int voice;
|
unsigned int channel;
|
||||||
adpcm_t *data = (adpcm_t *)plugin->extra_data;
|
adpcm_t *data = (adpcm_t *)plugin->extra_data;
|
||||||
for (voice = 0; voice < plugin->src_format.voices; voice++) {
|
for (channel = 0; channel < plugin->src_format.channels; channel++) {
|
||||||
adpcm_voice_t *v = &data->voices[voice];
|
adpcm_channel_t *v = &data->channels[channel];
|
||||||
v->pred_val = 0;
|
v->pred_val = 0;
|
||||||
v->step_idx = 0;
|
v->step_idx = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static char adpcm_encoder(int sl, adpcm_voice_t * state)
|
static char adpcm_encoder(int sl, adpcm_channel_t * state)
|
||||||
{
|
{
|
||||||
short diff; /* Difference between sl and predicted sample */
|
short diff; /* Difference between sl and predicted sample */
|
||||||
short pred_diff; /* Predicted difference to next sample */
|
short pred_diff; /* Predicted difference to next sample */
|
||||||
|
|
@ -160,7 +160,7 @@ static char adpcm_encoder(int sl, adpcm_voice_t * state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int adpcm_decoder(unsigned char code, adpcm_voice_t * state)
|
static int adpcm_decoder(unsigned char code, adpcm_channel_t * state)
|
||||||
{
|
{
|
||||||
short pred_diff; /* Predicted difference to next sample */
|
short pred_diff; /* Predicted difference to next sample */
|
||||||
short step; /* holds previous StepSize value */
|
short step; /* holds previous StepSize value */
|
||||||
|
|
@ -211,8 +211,8 @@ static int adpcm_decoder(unsigned char code, adpcm_voice_t * state)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
static void adpcm_decode(snd_pcm_plugin_t *plugin,
|
static void adpcm_decode(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voices,
|
snd_pcm_plugin_channel_t *dst_channels,
|
||||||
size_t frames)
|
size_t frames)
|
||||||
{
|
{
|
||||||
#define PUT_S16_LABELS
|
#define PUT_S16_LABELS
|
||||||
|
|
@ -220,29 +220,29 @@ static void adpcm_decode(snd_pcm_plugin_t *plugin,
|
||||||
#undef PUT_S16_LABELS
|
#undef PUT_S16_LABELS
|
||||||
adpcm_t *data = (adpcm_t *)plugin->extra_data;
|
adpcm_t *data = (adpcm_t *)plugin->extra_data;
|
||||||
void *put = put_s16_labels[data->conv];
|
void *put = put_s16_labels[data->conv];
|
||||||
int voice;
|
int channel;
|
||||||
int nvoices = plugin->src_format.voices;
|
int nchannels = plugin->src_format.channels;
|
||||||
for (voice = 0; voice < nvoices; ++voice) {
|
for (channel = 0; channel < nchannels; ++channel) {
|
||||||
char *src;
|
char *src;
|
||||||
int srcbit;
|
int srcbit;
|
||||||
char *dst;
|
char *dst;
|
||||||
int src_step, srcbit_step, dst_step;
|
int src_step, srcbit_step, dst_step;
|
||||||
size_t frames1;
|
size_t frames1;
|
||||||
adpcm_voice_t *state;
|
adpcm_channel_t *state;
|
||||||
if (!src_voices[voice].enabled) {
|
if (!src_channels[channel].enabled) {
|
||||||
if (dst_voices[voice].wanted)
|
if (dst_channels[channel].wanted)
|
||||||
snd_pcm_area_silence(&dst_voices[voice].area, 0, frames, plugin->dst_format.format);
|
snd_pcm_area_silence(&dst_channels[channel].area, 0, frames, plugin->dst_format.format);
|
||||||
dst_voices[voice].enabled = 0;
|
dst_channels[channel].enabled = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
dst_voices[voice].enabled = 1;
|
dst_channels[channel].enabled = 1;
|
||||||
src = src_voices[voice].area.addr + src_voices[voice].area.first / 8;
|
src = src_channels[channel].area.addr + src_channels[channel].area.first / 8;
|
||||||
srcbit = src_voices[voice].area.first % 8;
|
srcbit = src_channels[channel].area.first % 8;
|
||||||
dst = dst_voices[voice].area.addr + dst_voices[voice].area.first / 8;
|
dst = dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
|
||||||
src_step = src_voices[voice].area.step / 8;
|
src_step = src_channels[channel].area.step / 8;
|
||||||
srcbit_step = src_voices[voice].area.step % 8;
|
srcbit_step = src_channels[channel].area.step % 8;
|
||||||
dst_step = dst_voices[voice].area.step / 8;
|
dst_step = dst_channels[channel].area.step / 8;
|
||||||
state = &data->voices[voice];
|
state = &data->channels[channel];
|
||||||
frames1 = frames;
|
frames1 = frames;
|
||||||
while (frames1-- > 0) {
|
while (frames1-- > 0) {
|
||||||
signed short sample;
|
signed short sample;
|
||||||
|
|
@ -269,8 +269,8 @@ static void adpcm_decode(snd_pcm_plugin_t *plugin,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void adpcm_encode(snd_pcm_plugin_t *plugin,
|
static void adpcm_encode(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voices,
|
snd_pcm_plugin_channel_t *dst_channels,
|
||||||
size_t frames)
|
size_t frames)
|
||||||
{
|
{
|
||||||
#define GET_S16_LABELS
|
#define GET_S16_LABELS
|
||||||
|
|
@ -278,30 +278,30 @@ static void adpcm_encode(snd_pcm_plugin_t *plugin,
|
||||||
#undef GET_S16_LABELS
|
#undef GET_S16_LABELS
|
||||||
adpcm_t *data = (adpcm_t *)plugin->extra_data;
|
adpcm_t *data = (adpcm_t *)plugin->extra_data;
|
||||||
void *get = get_s16_labels[data->conv];
|
void *get = get_s16_labels[data->conv];
|
||||||
int voice;
|
int channel;
|
||||||
int nvoices = plugin->src_format.voices;
|
int nchannels = plugin->src_format.channels;
|
||||||
signed short sample = 0;
|
signed short sample = 0;
|
||||||
for (voice = 0; voice < nvoices; ++voice) {
|
for (channel = 0; channel < nchannels; ++channel) {
|
||||||
char *src;
|
char *src;
|
||||||
char *dst;
|
char *dst;
|
||||||
int dstbit;
|
int dstbit;
|
||||||
int src_step, dst_step, dstbit_step;
|
int src_step, dst_step, dstbit_step;
|
||||||
size_t frames1;
|
size_t frames1;
|
||||||
adpcm_voice_t *state;
|
adpcm_channel_t *state;
|
||||||
if (!src_voices[voice].enabled) {
|
if (!src_channels[channel].enabled) {
|
||||||
if (dst_voices[voice].wanted)
|
if (dst_channels[channel].wanted)
|
||||||
snd_pcm_area_silence(&dst_voices[voice].area, 0, frames, plugin->dst_format.format);
|
snd_pcm_area_silence(&dst_channels[channel].area, 0, frames, plugin->dst_format.format);
|
||||||
dst_voices[voice].enabled = 0;
|
dst_channels[channel].enabled = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
dst_voices[voice].enabled = 1;
|
dst_channels[channel].enabled = 1;
|
||||||
src = src_voices[voice].area.addr + src_voices[voice].area.first / 8;
|
src = src_channels[channel].area.addr + src_channels[channel].area.first / 8;
|
||||||
dst = dst_voices[voice].area.addr + dst_voices[voice].area.first / 8;
|
dst = dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
|
||||||
dstbit = dst_voices[voice].area.first % 8;
|
dstbit = dst_channels[channel].area.first % 8;
|
||||||
src_step = src_voices[voice].area.step / 8;
|
src_step = src_channels[channel].area.step / 8;
|
||||||
dst_step = dst_voices[voice].area.step / 8;
|
dst_step = dst_channels[channel].area.step / 8;
|
||||||
dstbit_step = dst_voices[voice].area.step % 8;
|
dstbit_step = dst_channels[channel].area.step % 8;
|
||||||
state = &data->voices[voice];
|
state = &data->channels[channel];
|
||||||
frames1 = frames;
|
frames1 = frames;
|
||||||
while (frames1-- > 0) {
|
while (frames1-- > 0) {
|
||||||
int v;
|
int v;
|
||||||
|
|
@ -327,34 +327,34 @@ static void adpcm_encode(snd_pcm_plugin_t *plugin,
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t adpcm_transfer(snd_pcm_plugin_t *plugin,
|
static ssize_t adpcm_transfer(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voices,
|
snd_pcm_plugin_channel_t *dst_channels,
|
||||||
size_t frames)
|
size_t frames)
|
||||||
{
|
{
|
||||||
adpcm_t *data;
|
adpcm_t *data;
|
||||||
unsigned int voice;
|
unsigned int channel;
|
||||||
|
|
||||||
if (plugin == NULL || src_voices == NULL || dst_voices == NULL)
|
if (plugin == NULL || src_channels == NULL || dst_channels == NULL)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (frames == 0)
|
if (frames == 0)
|
||||||
return 0;
|
return 0;
|
||||||
for (voice = 0; voice < plugin->src_format.voices; voice++) {
|
for (channel = 0; channel < plugin->src_format.channels; channel++) {
|
||||||
if (plugin->src_format.format == SND_PCM_SFMT_IMA_ADPCM) {
|
if (plugin->src_format.format == SND_PCM_SFMT_IMA_ADPCM) {
|
||||||
if (src_voices[voice].area.first % 4 != 0 ||
|
if (src_channels[channel].area.first % 4 != 0 ||
|
||||||
src_voices[voice].area.step % 4 != 0 ||
|
src_channels[channel].area.step % 4 != 0 ||
|
||||||
dst_voices[voice].area.first % 8 != 0 ||
|
dst_channels[channel].area.first % 8 != 0 ||
|
||||||
dst_voices[voice].area.step % 8 != 0)
|
dst_channels[channel].area.step % 8 != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
} else {
|
} else {
|
||||||
if (src_voices[voice].area.first % 8 != 0 ||
|
if (src_channels[channel].area.first % 8 != 0 ||
|
||||||
src_voices[voice].area.step % 8 != 0 ||
|
src_channels[channel].area.step % 8 != 0 ||
|
||||||
dst_voices[voice].area.first % 4 != 0 ||
|
dst_channels[channel].area.first % 4 != 0 ||
|
||||||
dst_voices[voice].area.step % 4 != 0)
|
dst_channels[channel].area.step % 4 != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
data = (adpcm_t *)plugin->extra_data;
|
data = (adpcm_t *)plugin->extra_data;
|
||||||
data->func(plugin, src_voices, dst_voices, frames);
|
data->func(plugin, src_channels, dst_channels, frames);
|
||||||
return frames;
|
return frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -378,7 +378,7 @@ static int adpcm_action(snd_pcm_plugin_t * plugin,
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_plugin_build_adpcm(snd_pcm_plugin_handle_t *handle,
|
int snd_pcm_plugin_build_adpcm(snd_pcm_plugin_handle_t *handle,
|
||||||
int channel,
|
int stream,
|
||||||
snd_pcm_format_t *src_format,
|
snd_pcm_format_t *src_format,
|
||||||
snd_pcm_format_t *dst_format,
|
snd_pcm_format_t *dst_format,
|
||||||
snd_pcm_plugin_t **r_plugin)
|
snd_pcm_plugin_t **r_plugin)
|
||||||
|
|
@ -395,7 +395,7 @@ int snd_pcm_plugin_build_adpcm(snd_pcm_plugin_handle_t *handle,
|
||||||
|
|
||||||
if (src_format->rate != dst_format->rate)
|
if (src_format->rate != dst_format->rate)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (src_format->voices != dst_format->voices)
|
if (src_format->channels != dst_format->channels)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (dst_format->format == SND_PCM_SFMT_IMA_ADPCM) {
|
if (dst_format->format == SND_PCM_SFMT_IMA_ADPCM) {
|
||||||
|
|
@ -411,11 +411,11 @@ int snd_pcm_plugin_build_adpcm(snd_pcm_plugin_handle_t *handle,
|
||||||
if (!snd_pcm_format_linear(format->format))
|
if (!snd_pcm_format_linear(format->format))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
err = snd_pcm_plugin_build(handle, channel,
|
err = snd_pcm_plugin_build(handle, stream,
|
||||||
"Ima-ADPCM<->linear conversion",
|
"Ima-ADPCM<->linear conversion",
|
||||||
src_format,
|
src_format,
|
||||||
dst_format,
|
dst_format,
|
||||||
sizeof(adpcm_t) + src_format->voices * sizeof(adpcm_voice_t),
|
sizeof(adpcm_t) + src_format->channels * sizeof(adpcm_channel_t),
|
||||||
&plugin);
|
&plugin);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
|
||||||
|
|
@ -133,8 +133,8 @@ static int alaw2linear(unsigned char a_val)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef void (*alaw_f)(snd_pcm_plugin_t *plugin,
|
typedef void (*alaw_f)(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voices,
|
snd_pcm_plugin_channel_t *dst_channels,
|
||||||
size_t frames);
|
size_t frames);
|
||||||
|
|
||||||
typedef struct alaw_private_data {
|
typedef struct alaw_private_data {
|
||||||
|
|
@ -143,8 +143,8 @@ typedef struct alaw_private_data {
|
||||||
} alaw_t;
|
} alaw_t;
|
||||||
|
|
||||||
static void alaw_decode(snd_pcm_plugin_t *plugin,
|
static void alaw_decode(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voices,
|
snd_pcm_plugin_channel_t *dst_channels,
|
||||||
size_t frames)
|
size_t frames)
|
||||||
{
|
{
|
||||||
#define PUT_S16_LABELS
|
#define PUT_S16_LABELS
|
||||||
|
|
@ -152,24 +152,24 @@ static void alaw_decode(snd_pcm_plugin_t *plugin,
|
||||||
#undef PUT_S16_LABELS
|
#undef PUT_S16_LABELS
|
||||||
alaw_t *data = (alaw_t *)plugin->extra_data;
|
alaw_t *data = (alaw_t *)plugin->extra_data;
|
||||||
void *put = put_s16_labels[data->conv];
|
void *put = put_s16_labels[data->conv];
|
||||||
int voice;
|
int channel;
|
||||||
int nvoices = plugin->src_format.voices;
|
int nchannels = plugin->src_format.channels;
|
||||||
for (voice = 0; voice < nvoices; ++voice) {
|
for (channel = 0; channel < nchannels; ++channel) {
|
||||||
char *src;
|
char *src;
|
||||||
char *dst;
|
char *dst;
|
||||||
int src_step, dst_step;
|
int src_step, dst_step;
|
||||||
size_t frames1;
|
size_t frames1;
|
||||||
if (!src_voices[voice].enabled) {
|
if (!src_channels[channel].enabled) {
|
||||||
if (dst_voices[voice].wanted)
|
if (dst_channels[channel].wanted)
|
||||||
snd_pcm_area_silence(&dst_voices[voice].area, 0, frames, plugin->dst_format.format);
|
snd_pcm_area_silence(&dst_channels[channel].area, 0, frames, plugin->dst_format.format);
|
||||||
dst_voices[voice].enabled = 0;
|
dst_channels[channel].enabled = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
dst_voices[voice].enabled = 1;
|
dst_channels[channel].enabled = 1;
|
||||||
src = src_voices[voice].area.addr + src_voices[voice].area.first / 8;
|
src = src_channels[channel].area.addr + src_channels[channel].area.first / 8;
|
||||||
dst = dst_voices[voice].area.addr + dst_voices[voice].area.first / 8;
|
dst = dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
|
||||||
src_step = src_voices[voice].area.step / 8;
|
src_step = src_channels[channel].area.step / 8;
|
||||||
dst_step = dst_voices[voice].area.step / 8;
|
dst_step = dst_channels[channel].area.step / 8;
|
||||||
frames1 = frames;
|
frames1 = frames;
|
||||||
while (frames1-- > 0) {
|
while (frames1-- > 0) {
|
||||||
signed short sample = alaw2linear(*src);
|
signed short sample = alaw2linear(*src);
|
||||||
|
|
@ -185,8 +185,8 @@ static void alaw_decode(snd_pcm_plugin_t *plugin,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void alaw_encode(snd_pcm_plugin_t *plugin,
|
static void alaw_encode(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voices,
|
snd_pcm_plugin_channel_t *dst_channels,
|
||||||
size_t frames)
|
size_t frames)
|
||||||
{
|
{
|
||||||
#define GET_S16_LABELS
|
#define GET_S16_LABELS
|
||||||
|
|
@ -194,25 +194,25 @@ static void alaw_encode(snd_pcm_plugin_t *plugin,
|
||||||
#undef GET_S16_LABELS
|
#undef GET_S16_LABELS
|
||||||
alaw_t *data = (alaw_t *)plugin->extra_data;
|
alaw_t *data = (alaw_t *)plugin->extra_data;
|
||||||
void *get = get_s16_labels[data->conv];
|
void *get = get_s16_labels[data->conv];
|
||||||
int voice;
|
int channel;
|
||||||
int nvoices = plugin->src_format.voices;
|
int nchannels = plugin->src_format.channels;
|
||||||
signed short sample = 0;
|
signed short sample = 0;
|
||||||
for (voice = 0; voice < nvoices; ++voice) {
|
for (channel = 0; channel < nchannels; ++channel) {
|
||||||
char *src;
|
char *src;
|
||||||
char *dst;
|
char *dst;
|
||||||
int src_step, dst_step;
|
int src_step, dst_step;
|
||||||
size_t frames1;
|
size_t frames1;
|
||||||
if (!src_voices[voice].enabled) {
|
if (!src_channels[channel].enabled) {
|
||||||
if (dst_voices[voice].wanted)
|
if (dst_channels[channel].wanted)
|
||||||
snd_pcm_area_silence(&dst_voices[voice].area, 0, frames, plugin->dst_format.format);
|
snd_pcm_area_silence(&dst_channels[channel].area, 0, frames, plugin->dst_format.format);
|
||||||
dst_voices[voice].enabled = 0;
|
dst_channels[channel].enabled = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
dst_voices[voice].enabled = 1;
|
dst_channels[channel].enabled = 1;
|
||||||
src = src_voices[voice].area.addr + src_voices[voice].area.first / 8;
|
src = src_channels[channel].area.addr + src_channels[channel].area.first / 8;
|
||||||
dst = dst_voices[voice].area.addr + dst_voices[voice].area.first / 8;
|
dst = dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
|
||||||
src_step = src_voices[voice].area.step / 8;
|
src_step = src_channels[channel].area.step / 8;
|
||||||
dst_step = dst_voices[voice].area.step / 8;
|
dst_step = dst_channels[channel].area.step / 8;
|
||||||
frames1 = frames;
|
frames1 = frames;
|
||||||
while (frames1-- > 0) {
|
while (frames1-- > 0) {
|
||||||
goto *get;
|
goto *get;
|
||||||
|
|
@ -228,32 +228,32 @@ static void alaw_encode(snd_pcm_plugin_t *plugin,
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t alaw_transfer(snd_pcm_plugin_t *plugin,
|
static ssize_t alaw_transfer(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voices,
|
snd_pcm_plugin_channel_t *dst_channels,
|
||||||
size_t frames)
|
size_t frames)
|
||||||
{
|
{
|
||||||
alaw_t *data;
|
alaw_t *data;
|
||||||
unsigned int voice;
|
unsigned int channel;
|
||||||
|
|
||||||
if (plugin == NULL || src_voices == NULL || dst_voices == NULL)
|
if (plugin == NULL || src_channels == NULL || dst_channels == NULL)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (frames == 0)
|
if (frames == 0)
|
||||||
return 0;
|
return 0;
|
||||||
for (voice = 0; voice < plugin->src_format.voices; voice++) {
|
for (channel = 0; channel < plugin->src_format.channels; channel++) {
|
||||||
if (src_voices[voice].area.first % 8 != 0 ||
|
if (src_channels[channel].area.first % 8 != 0 ||
|
||||||
src_voices[voice].area.step % 8 != 0)
|
src_channels[channel].area.step % 8 != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (dst_voices[voice].area.first % 8 != 0 ||
|
if (dst_channels[channel].area.first % 8 != 0 ||
|
||||||
dst_voices[voice].area.step % 8 != 0)
|
dst_channels[channel].area.step % 8 != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
data = (alaw_t *)plugin->extra_data;
|
data = (alaw_t *)plugin->extra_data;
|
||||||
data->func(plugin, src_voices, dst_voices, frames);
|
data->func(plugin, src_channels, dst_channels, frames);
|
||||||
return frames;
|
return frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_plugin_build_alaw(snd_pcm_plugin_handle_t *handle,
|
int snd_pcm_plugin_build_alaw(snd_pcm_plugin_handle_t *handle,
|
||||||
int channel,
|
int stream,
|
||||||
snd_pcm_format_t *src_format,
|
snd_pcm_format_t *src_format,
|
||||||
snd_pcm_format_t *dst_format,
|
snd_pcm_format_t *dst_format,
|
||||||
snd_pcm_plugin_t **r_plugin)
|
snd_pcm_plugin_t **r_plugin)
|
||||||
|
|
@ -270,7 +270,7 @@ int snd_pcm_plugin_build_alaw(snd_pcm_plugin_handle_t *handle,
|
||||||
|
|
||||||
if (src_format->rate != dst_format->rate)
|
if (src_format->rate != dst_format->rate)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (src_format->voices != dst_format->voices)
|
if (src_format->channels != dst_format->channels)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (dst_format->format == SND_PCM_SFMT_A_LAW) {
|
if (dst_format->format == SND_PCM_SFMT_A_LAW) {
|
||||||
|
|
@ -286,7 +286,7 @@ int snd_pcm_plugin_build_alaw(snd_pcm_plugin_handle_t *handle,
|
||||||
if (!snd_pcm_format_linear(format->format))
|
if (!snd_pcm_format_linear(format->format))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
err = snd_pcm_plugin_build(handle, channel,
|
err = snd_pcm_plugin_build(handle, stream,
|
||||||
"A-Law<->linear conversion",
|
"A-Law<->linear conversion",
|
||||||
src_format,
|
src_format,
|
||||||
dst_format,
|
dst_format,
|
||||||
|
|
|
||||||
|
|
@ -36,41 +36,41 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static ssize_t copy_transfer(snd_pcm_plugin_t *plugin,
|
static ssize_t copy_transfer(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voices,
|
snd_pcm_plugin_channel_t *dst_channels,
|
||||||
size_t frames)
|
size_t frames)
|
||||||
{
|
{
|
||||||
unsigned int voice;
|
unsigned int channel;
|
||||||
unsigned int nvoices;
|
unsigned int nchannels;
|
||||||
|
|
||||||
if (plugin == NULL || src_voices == NULL || dst_voices == NULL)
|
if (plugin == NULL || src_channels == NULL || dst_channels == NULL)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (frames == 0)
|
if (frames == 0)
|
||||||
return 0;
|
return 0;
|
||||||
nvoices = plugin->src_format.voices;
|
nchannels = plugin->src_format.channels;
|
||||||
for (voice = 0; voice < nvoices; voice++) {
|
for (channel = 0; channel < nchannels; channel++) {
|
||||||
if (src_voices->area.first % 8 != 0 ||
|
if (src_channels->area.first % 8 != 0 ||
|
||||||
src_voices->area.step % 8 != 0)
|
src_channels->area.step % 8 != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (dst_voices->area.first % 8 != 0 ||
|
if (dst_channels->area.first % 8 != 0 ||
|
||||||
dst_voices->area.step % 8 != 0)
|
dst_channels->area.step % 8 != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!src_voices->enabled) {
|
if (!src_channels->enabled) {
|
||||||
if (dst_voices->wanted)
|
if (dst_channels->wanted)
|
||||||
snd_pcm_area_silence(&dst_voices->area, 0, frames, plugin->dst_format.format);
|
snd_pcm_area_silence(&dst_channels->area, 0, frames, plugin->dst_format.format);
|
||||||
dst_voices->enabled = 0;
|
dst_channels->enabled = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
dst_voices->enabled = 1;
|
dst_channels->enabled = 1;
|
||||||
snd_pcm_area_copy(&src_voices->area, 0, &dst_voices->area, 0, frames, plugin->src_format.format);
|
snd_pcm_area_copy(&src_channels->area, 0, &dst_channels->area, 0, frames, plugin->src_format.format);
|
||||||
src_voices++;
|
src_channels++;
|
||||||
dst_voices++;
|
dst_channels++;
|
||||||
}
|
}
|
||||||
return frames;
|
return frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_plugin_build_copy(snd_pcm_plugin_handle_t *handle,
|
int snd_pcm_plugin_build_copy(snd_pcm_plugin_handle_t *handle,
|
||||||
int channel,
|
int stream,
|
||||||
snd_pcm_format_t *src_format,
|
snd_pcm_format_t *src_format,
|
||||||
snd_pcm_format_t *dst_format,
|
snd_pcm_format_t *dst_format,
|
||||||
snd_pcm_plugin_t **r_plugin)
|
snd_pcm_plugin_t **r_plugin)
|
||||||
|
|
@ -87,14 +87,14 @@ int snd_pcm_plugin_build_copy(snd_pcm_plugin_handle_t *handle,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (src_format->rate != dst_format->rate)
|
if (src_format->rate != dst_format->rate)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (src_format->voices != dst_format->voices)
|
if (src_format->channels != dst_format->channels)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
width = snd_pcm_format_physical_width(src_format->format);
|
width = snd_pcm_format_physical_width(src_format->format);
|
||||||
if (width < 0)
|
if (width < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
err = snd_pcm_plugin_build(handle, channel,
|
err = snd_pcm_plugin_build(handle, stream,
|
||||||
"copy",
|
"copy",
|
||||||
src_format,
|
src_format,
|
||||||
dst_format,
|
dst_format,
|
||||||
|
|
|
||||||
|
|
@ -46,14 +46,14 @@ typedef struct io_private_data {
|
||||||
} io_t;
|
} io_t;
|
||||||
|
|
||||||
static ssize_t io_transfer(snd_pcm_plugin_t *plugin,
|
static ssize_t io_transfer(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voices,
|
snd_pcm_plugin_channel_t *dst_channels,
|
||||||
size_t frames)
|
size_t frames)
|
||||||
{
|
{
|
||||||
io_t *data;
|
io_t *data;
|
||||||
ssize_t result;
|
ssize_t result;
|
||||||
struct iovec *vec;
|
struct iovec *vec;
|
||||||
int count, voice;
|
int count, channel;
|
||||||
|
|
||||||
if (plugin == NULL)
|
if (plugin == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
@ -61,48 +61,48 @@ static ssize_t io_transfer(snd_pcm_plugin_t *plugin,
|
||||||
if (data == NULL)
|
if (data == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
vec = (struct iovec *)((char *)data + sizeof(*data));
|
vec = (struct iovec *)((char *)data + sizeof(*data));
|
||||||
if (plugin->channel == SND_PCM_CHANNEL_PLAYBACK) {
|
if (plugin->stream == SND_PCM_STREAM_PLAYBACK) {
|
||||||
if (src_voices == NULL)
|
if (src_channels == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if ((result = snd_pcm_plugin_src_frames_to_size(plugin, frames)) < 0)
|
if ((result = snd_pcm_plugin_src_frames_to_size(plugin, frames)) < 0)
|
||||||
return result;
|
return result;
|
||||||
count = plugin->src_format.voices;
|
count = plugin->src_format.channels;
|
||||||
if (plugin->src_format.interleave) {
|
if (plugin->src_format.interleave) {
|
||||||
result = snd_pcm_write(data->slave, src_voices->area.addr, result);
|
result = snd_pcm_write(data->slave, src_channels->area.addr, result);
|
||||||
} else {
|
} else {
|
||||||
result /= count;
|
result /= count;
|
||||||
for (voice = 0; voice < count; voice++) {
|
for (channel = 0; channel < count; channel++) {
|
||||||
if (src_voices[voice].enabled)
|
if (src_channels[channel].enabled)
|
||||||
vec[voice].iov_base = src_voices[voice].area.addr;
|
vec[channel].iov_base = src_channels[channel].area.addr;
|
||||||
else
|
else
|
||||||
vec[voice].iov_base = 0;
|
vec[channel].iov_base = 0;
|
||||||
vec[voice].iov_len = result;
|
vec[channel].iov_len = result;
|
||||||
}
|
}
|
||||||
result = snd_pcm_writev(data->slave, vec, count);
|
result = snd_pcm_writev(data->slave, vec, count);
|
||||||
}
|
}
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return result;
|
return result;
|
||||||
return snd_pcm_plugin_src_size_to_frames(plugin, result);
|
return snd_pcm_plugin_src_size_to_frames(plugin, result);
|
||||||
} else if (plugin->channel == SND_PCM_CHANNEL_CAPTURE) {
|
} else if (plugin->stream == SND_PCM_STREAM_CAPTURE) {
|
||||||
if (dst_voices == NULL)
|
if (dst_channels == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if ((result = snd_pcm_plugin_dst_frames_to_size(plugin, frames)) < 0)
|
if ((result = snd_pcm_plugin_dst_frames_to_size(plugin, frames)) < 0)
|
||||||
return result;
|
return result;
|
||||||
count = plugin->dst_format.voices;
|
count = plugin->dst_format.channels;
|
||||||
if (plugin->dst_format.interleave) {
|
if (plugin->dst_format.interleave) {
|
||||||
result = snd_pcm_read(data->slave, dst_voices->area.addr, result);
|
result = snd_pcm_read(data->slave, dst_channels->area.addr, result);
|
||||||
for (voice = 0; voice < count; voice++) {
|
for (channel = 0; channel < count; channel++) {
|
||||||
dst_voices[voice].enabled = src_voices[voice].enabled;
|
dst_channels[channel].enabled = src_channels[channel].enabled;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result /= count;
|
result /= count;
|
||||||
for (voice = 0; voice < count; voice++) {
|
for (channel = 0; channel < count; channel++) {
|
||||||
dst_voices[voice].enabled = src_voices[voice].enabled;
|
dst_channels[channel].enabled = src_channels[channel].enabled;
|
||||||
if (dst_voices[voice].enabled)
|
if (dst_channels[channel].enabled)
|
||||||
vec[voice].iov_base = dst_voices[voice].area.addr;
|
vec[channel].iov_base = dst_channels[channel].area.addr;
|
||||||
else
|
else
|
||||||
vec[voice].iov_base = 0;
|
vec[channel].iov_base = 0;
|
||||||
vec[voice].iov_len = result;
|
vec[channel].iov_len = result;
|
||||||
}
|
}
|
||||||
result = snd_pcm_readv(data->slave, vec, count);
|
result = snd_pcm_readv(data->slave, vec, count);
|
||||||
}
|
}
|
||||||
|
|
@ -114,24 +114,24 @@ static ssize_t io_transfer(snd_pcm_plugin_t *plugin,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t io_src_voices(snd_pcm_plugin_t *plugin,
|
static ssize_t io_src_channels(snd_pcm_plugin_t *plugin,
|
||||||
size_t frames,
|
size_t frames,
|
||||||
snd_pcm_plugin_voice_t **voices)
|
snd_pcm_plugin_channel_t **channels)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
unsigned int voice;
|
unsigned int channel;
|
||||||
snd_pcm_plugin_voice_t *v;
|
snd_pcm_plugin_channel_t *v;
|
||||||
err = snd_pcm_plugin_client_voices(plugin, frames, &v);
|
err = snd_pcm_plugin_client_channels(plugin, frames, &v);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
*voices = v;
|
*channels = v;
|
||||||
for (voice = 0; voice < plugin->src_format.voices; ++voice, ++v)
|
for (channel = 0; channel < plugin->src_format.channels; ++channel, ++v)
|
||||||
v->wanted = 1;
|
v->wanted = 1;
|
||||||
return frames;
|
return frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_plugin_build_io(snd_pcm_plugin_handle_t *pcm,
|
int snd_pcm_plugin_build_io(snd_pcm_plugin_handle_t *pcm,
|
||||||
int channel,
|
int stream,
|
||||||
snd_pcm_plugin_handle_t *slave,
|
snd_pcm_plugin_handle_t *slave,
|
||||||
snd_pcm_format_t *format,
|
snd_pcm_format_t *format,
|
||||||
snd_pcm_plugin_t **r_plugin)
|
snd_pcm_plugin_t **r_plugin)
|
||||||
|
|
@ -145,18 +145,18 @@ int snd_pcm_plugin_build_io(snd_pcm_plugin_handle_t *pcm,
|
||||||
*r_plugin = NULL;
|
*r_plugin = NULL;
|
||||||
if (pcm == NULL || format == NULL)
|
if (pcm == NULL || format == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
err = snd_pcm_plugin_build(pcm, channel,
|
err = snd_pcm_plugin_build(pcm, stream,
|
||||||
"I/O io",
|
"I/O io",
|
||||||
format, format,
|
format, format,
|
||||||
sizeof(io_t) + sizeof(struct iovec) * format->voices,
|
sizeof(io_t) + sizeof(struct iovec) * format->channels,
|
||||||
&plugin);
|
&plugin);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
data = (io_t *)plugin->extra_data;
|
data = (io_t *)plugin->extra_data;
|
||||||
data->slave = slave;
|
data->slave = slave;
|
||||||
plugin->transfer = io_transfer;
|
plugin->transfer = io_transfer;
|
||||||
if (format->interleave && channel == SND_PCM_CHANNEL_PLAYBACK)
|
if (format->interleave && stream == SND_PCM_STREAM_PLAYBACK)
|
||||||
plugin->client_voices = io_src_voices;
|
plugin->client_channels = io_src_channels;
|
||||||
*r_plugin = plugin;
|
*r_plugin = plugin;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,8 @@ typedef struct linear_private_data {
|
||||||
} linear_t;
|
} linear_t;
|
||||||
|
|
||||||
static void convert(snd_pcm_plugin_t *plugin,
|
static void convert(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voices,
|
snd_pcm_plugin_channel_t *dst_channels,
|
||||||
size_t frames)
|
size_t frames)
|
||||||
{
|
{
|
||||||
#define CONV_LABELS
|
#define CONV_LABELS
|
||||||
|
|
@ -54,24 +54,24 @@ static void convert(snd_pcm_plugin_t *plugin,
|
||||||
#undef CONV_LABELS
|
#undef CONV_LABELS
|
||||||
linear_t *data = (linear_t *)plugin->extra_data;
|
linear_t *data = (linear_t *)plugin->extra_data;
|
||||||
void *conv = conv_labels[data->conv];
|
void *conv = conv_labels[data->conv];
|
||||||
int voice;
|
int channel;
|
||||||
int nvoices = plugin->src_format.voices;
|
int nchannels = plugin->src_format.channels;
|
||||||
for (voice = 0; voice < nvoices; ++voice) {
|
for (channel = 0; channel < nchannels; ++channel) {
|
||||||
char *src;
|
char *src;
|
||||||
char *dst;
|
char *dst;
|
||||||
int src_step, dst_step;
|
int src_step, dst_step;
|
||||||
size_t frames1;
|
size_t frames1;
|
||||||
if (!src_voices[voice].enabled) {
|
if (!src_channels[channel].enabled) {
|
||||||
if (dst_voices[voice].wanted)
|
if (dst_channels[channel].wanted)
|
||||||
snd_pcm_area_silence(&dst_voices[voice].area, 0, frames, plugin->dst_format.format);
|
snd_pcm_area_silence(&dst_channels[channel].area, 0, frames, plugin->dst_format.format);
|
||||||
dst_voices[voice].enabled = 0;
|
dst_channels[channel].enabled = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
dst_voices[voice].enabled = 1;
|
dst_channels[channel].enabled = 1;
|
||||||
src = src_voices[voice].area.addr + src_voices[voice].area.first / 8;
|
src = src_channels[channel].area.addr + src_channels[channel].area.first / 8;
|
||||||
dst = dst_voices[voice].area.addr + dst_voices[voice].area.first / 8;
|
dst = dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
|
||||||
src_step = src_voices[voice].area.step / 8;
|
src_step = src_channels[channel].area.step / 8;
|
||||||
dst_step = dst_voices[voice].area.step / 8;
|
dst_step = dst_channels[channel].area.step / 8;
|
||||||
frames1 = frames;
|
frames1 = frames;
|
||||||
while (frames1-- > 0) {
|
while (frames1-- > 0) {
|
||||||
goto *conv;
|
goto *conv;
|
||||||
|
|
@ -86,27 +86,27 @@ static void convert(snd_pcm_plugin_t *plugin,
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t linear_transfer(snd_pcm_plugin_t *plugin,
|
static ssize_t linear_transfer(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voices,
|
snd_pcm_plugin_channel_t *dst_channels,
|
||||||
size_t frames)
|
size_t frames)
|
||||||
{
|
{
|
||||||
linear_t *data;
|
linear_t *data;
|
||||||
unsigned int voice;
|
unsigned int channel;
|
||||||
|
|
||||||
if (plugin == NULL || src_voices == NULL || dst_voices == NULL)
|
if (plugin == NULL || src_channels == NULL || dst_channels == NULL)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
data = (linear_t *)plugin->extra_data;
|
data = (linear_t *)plugin->extra_data;
|
||||||
if (frames == 0)
|
if (frames == 0)
|
||||||
return 0;
|
return 0;
|
||||||
for (voice = 0; voice < plugin->src_format.voices; voice++) {
|
for (channel = 0; channel < plugin->src_format.channels; channel++) {
|
||||||
if (src_voices[voice].area.first % 8 != 0 ||
|
if (src_channels[channel].area.first % 8 != 0 ||
|
||||||
src_voices[voice].area.step % 8 != 0)
|
src_channels[channel].area.step % 8 != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (dst_voices[voice].area.first % 8 != 0 ||
|
if (dst_channels[channel].area.first % 8 != 0 ||
|
||||||
dst_voices[voice].area.step % 8 != 0)
|
dst_channels[channel].area.step % 8 != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
convert(plugin, src_voices, dst_voices, frames);
|
convert(plugin, src_channels, dst_channels, frames);
|
||||||
return frames;
|
return frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -138,7 +138,7 @@ int conv_index(int src_format, int dst_format)
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_plugin_build_linear(snd_pcm_plugin_handle_t *handle,
|
int snd_pcm_plugin_build_linear(snd_pcm_plugin_handle_t *handle,
|
||||||
int channel,
|
int stream,
|
||||||
snd_pcm_format_t *src_format,
|
snd_pcm_format_t *src_format,
|
||||||
snd_pcm_format_t *dst_format,
|
snd_pcm_format_t *dst_format,
|
||||||
snd_pcm_plugin_t **r_plugin)
|
snd_pcm_plugin_t **r_plugin)
|
||||||
|
|
@ -153,13 +153,13 @@ int snd_pcm_plugin_build_linear(snd_pcm_plugin_handle_t *handle,
|
||||||
|
|
||||||
if (src_format->rate != dst_format->rate)
|
if (src_format->rate != dst_format->rate)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (src_format->voices != dst_format->voices)
|
if (src_format->channels != dst_format->channels)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (!(snd_pcm_format_linear(src_format->format) &&
|
if (!(snd_pcm_format_linear(src_format->format) &&
|
||||||
snd_pcm_format_linear(dst_format->format)))
|
snd_pcm_format_linear(dst_format->format)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
err = snd_pcm_plugin_build(handle, channel,
|
err = snd_pcm_plugin_build(handle, stream,
|
||||||
"linear format conversion",
|
"linear format conversion",
|
||||||
src_format,
|
src_format,
|
||||||
dst_format,
|
dst_format,
|
||||||
|
|
|
||||||
|
|
@ -43,60 +43,60 @@ typedef struct mmap_private_data {
|
||||||
} mmap_t;
|
} mmap_t;
|
||||||
|
|
||||||
|
|
||||||
static ssize_t mmap_src_voices(snd_pcm_plugin_t *plugin,
|
static ssize_t mmap_src_channels(snd_pcm_plugin_t *plugin,
|
||||||
size_t frames,
|
size_t frames,
|
||||||
snd_pcm_plugin_voice_t **voices)
|
snd_pcm_plugin_channel_t **channels)
|
||||||
{
|
{
|
||||||
mmap_t *data;
|
mmap_t *data;
|
||||||
snd_pcm_plugin_voice_t *sv;
|
snd_pcm_plugin_channel_t *sv;
|
||||||
snd_pcm_voice_area_t *dv;
|
snd_pcm_channel_area_t *dv;
|
||||||
struct snd_pcm_chan *chan;
|
struct snd_pcm_stream *stream;
|
||||||
snd_pcm_channel_setup_t *setup;
|
snd_pcm_stream_setup_t *setup;
|
||||||
snd_pcm_mmap_control_t *ctrl;
|
snd_pcm_mmap_control_t *ctrl;
|
||||||
size_t pos;
|
size_t pos;
|
||||||
int ready;
|
int ready;
|
||||||
unsigned int voice;
|
unsigned int channel;
|
||||||
|
|
||||||
if (plugin == NULL || voices == NULL)
|
if (plugin == NULL || channels == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
data = (mmap_t *)plugin->extra_data;
|
data = (mmap_t *)plugin->extra_data;
|
||||||
ctrl = data->control;
|
ctrl = data->control;
|
||||||
chan = &data->slave->chan[plugin->channel];
|
stream = &data->slave->stream[plugin->stream];
|
||||||
|
|
||||||
setup = &chan->setup;
|
setup = &stream->setup;
|
||||||
if (ctrl->status < SND_PCM_STATUS_PREPARED)
|
if (ctrl->status < SND_PCM_STATUS_PREPARED)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
|
|
||||||
ready = snd_pcm_mmap_ready(data->slave, plugin->channel);
|
ready = snd_pcm_mmap_ready(data->slave, plugin->stream);
|
||||||
if (ready < 0)
|
if (ready < 0)
|
||||||
return ready;
|
return ready;
|
||||||
if (!ready) {
|
if (!ready) {
|
||||||
struct pollfd pfd;
|
struct pollfd pfd;
|
||||||
if (ctrl->status != SND_PCM_STATUS_RUNNING)
|
if (ctrl->status != SND_PCM_STATUS_RUNNING)
|
||||||
return -EPIPE;
|
return -EPIPE;
|
||||||
if (chan->mode & SND_PCM_NONBLOCK)
|
if (stream->mode & SND_PCM_NONBLOCK)
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
pfd.fd = snd_pcm_file_descriptor(data->slave, plugin->channel);
|
pfd.fd = snd_pcm_file_descriptor(data->slave, plugin->stream);
|
||||||
pfd.events = POLLOUT | POLLERR;
|
pfd.events = POLLOUT | POLLERR;
|
||||||
ready = poll(&pfd, 1, 10000);
|
ready = poll(&pfd, 1, 10000);
|
||||||
if (ready < 0)
|
if (ready < 0)
|
||||||
return ready;
|
return ready;
|
||||||
if (ready && pfd.revents & POLLERR)
|
if (ready && pfd.revents & POLLERR)
|
||||||
return -EPIPE;
|
return -EPIPE;
|
||||||
assert(snd_pcm_mmap_ready(data->slave, plugin->channel));
|
assert(snd_pcm_mmap_ready(data->slave, plugin->stream));
|
||||||
}
|
}
|
||||||
pos = ctrl->byte_data % setup->buffer_size;
|
pos = ctrl->byte_data % setup->buffer_size;
|
||||||
if ((pos * 8) % chan->bits_per_frame != 0)
|
if ((pos * 8) % stream->bits_per_frame != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
pos = (pos * 8) / chan->bits_per_frame;
|
pos = (pos * 8) / stream->bits_per_frame;
|
||||||
|
|
||||||
sv = plugin->src_voices;
|
sv = plugin->src_channels;
|
||||||
dv = chan->voices;
|
dv = stream->channels;
|
||||||
*voices = sv;
|
*channels = sv;
|
||||||
for (voice = 0; voice < plugin->src_format.voices; ++voice) {
|
for (channel = 0; channel < plugin->src_format.channels; ++channel) {
|
||||||
sv->enabled = 1;
|
sv->enabled = 1;
|
||||||
#if 0
|
#if 0
|
||||||
sv->wanted = !data->silence[voice * setup->frags + f];
|
sv->wanted = !data->silence[channel * setup->frags + f];
|
||||||
#else
|
#else
|
||||||
sv->wanted = 1;
|
sv->wanted = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -107,66 +107,66 @@ static ssize_t mmap_src_voices(snd_pcm_plugin_t *plugin,
|
||||||
++sv;
|
++sv;
|
||||||
++dv;
|
++dv;
|
||||||
}
|
}
|
||||||
return snd_pcm_mmap_frames_xfer(data->slave, plugin->channel, frames);
|
return snd_pcm_mmap_frames_xfer(data->slave, plugin->stream, frames);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t mmap_dst_voices(snd_pcm_plugin_t *plugin,
|
static ssize_t mmap_dst_channels(snd_pcm_plugin_t *plugin,
|
||||||
size_t frames,
|
size_t frames,
|
||||||
snd_pcm_plugin_voice_t **voices)
|
snd_pcm_plugin_channel_t **channels)
|
||||||
{
|
{
|
||||||
mmap_t *data;
|
mmap_t *data;
|
||||||
int err;
|
int err;
|
||||||
unsigned int voice;
|
unsigned int channel;
|
||||||
snd_pcm_plugin_voice_t *dv;
|
snd_pcm_plugin_channel_t *dv;
|
||||||
snd_pcm_voice_area_t *sv;
|
snd_pcm_channel_area_t *sv;
|
||||||
struct snd_pcm_chan *chan;
|
struct snd_pcm_stream *stream;
|
||||||
snd_pcm_channel_setup_t *setup;
|
snd_pcm_stream_setup_t *setup;
|
||||||
snd_pcm_mmap_control_t *ctrl;
|
snd_pcm_mmap_control_t *ctrl;
|
||||||
size_t pos;
|
size_t pos;
|
||||||
int ready;
|
int ready;
|
||||||
|
|
||||||
if (plugin == NULL || voices == NULL)
|
if (plugin == NULL || channels == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
data = (mmap_t *)plugin->extra_data;
|
data = (mmap_t *)plugin->extra_data;
|
||||||
chan = &data->slave->chan[plugin->channel];
|
stream = &data->slave->stream[plugin->stream];
|
||||||
|
|
||||||
setup = &chan->setup;
|
setup = &stream->setup;
|
||||||
ctrl = data->control;
|
ctrl = data->control;
|
||||||
if (ctrl->status < SND_PCM_STATUS_PREPARED)
|
if (ctrl->status < SND_PCM_STATUS_PREPARED)
|
||||||
return -EBADFD;
|
return -EBADFD;
|
||||||
if (ctrl->status == SND_PCM_STATUS_PREPARED &&
|
if (ctrl->status == SND_PCM_STATUS_PREPARED &&
|
||||||
chan->setup.start_mode == SND_PCM_START_DATA) {
|
stream->setup.start_mode == SND_PCM_START_DATA) {
|
||||||
err = snd_pcm_channel_go(data->slave, plugin->channel);
|
err = snd_pcm_stream_go(data->slave, plugin->stream);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
ready = snd_pcm_mmap_ready(data->slave, plugin->channel);
|
ready = snd_pcm_mmap_ready(data->slave, plugin->stream);
|
||||||
if (ready < 0)
|
if (ready < 0)
|
||||||
return ready;
|
return ready;
|
||||||
if (!ready) {
|
if (!ready) {
|
||||||
struct pollfd pfd;
|
struct pollfd pfd;
|
||||||
if (ctrl->status != SND_PCM_STATUS_RUNNING)
|
if (ctrl->status != SND_PCM_STATUS_RUNNING)
|
||||||
return -EPIPE;
|
return -EPIPE;
|
||||||
if (chan->mode & SND_PCM_NONBLOCK)
|
if (stream->mode & SND_PCM_NONBLOCK)
|
||||||
return -EAGAIN;
|
return -EAGAIN;
|
||||||
pfd.fd = snd_pcm_file_descriptor(data->slave, plugin->channel);
|
pfd.fd = snd_pcm_file_descriptor(data->slave, plugin->stream);
|
||||||
pfd.events = POLLIN | POLLERR;
|
pfd.events = POLLIN | POLLERR;
|
||||||
ready = poll(&pfd, 1, 10000);
|
ready = poll(&pfd, 1, 10000);
|
||||||
if (ready < 0)
|
if (ready < 0)
|
||||||
return ready;
|
return ready;
|
||||||
if (ready && pfd.revents & POLLERR)
|
if (ready && pfd.revents & POLLERR)
|
||||||
return -EPIPE;
|
return -EPIPE;
|
||||||
assert(snd_pcm_mmap_ready(data->slave, plugin->channel));
|
assert(snd_pcm_mmap_ready(data->slave, plugin->stream));
|
||||||
}
|
}
|
||||||
pos = ctrl->byte_data % setup->buffer_size;
|
pos = ctrl->byte_data % setup->buffer_size;
|
||||||
if ((pos * 8) % chan->bits_per_frame != 0)
|
if ((pos * 8) % stream->bits_per_frame != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
pos = (pos * 8) / chan->bits_per_frame;
|
pos = (pos * 8) / stream->bits_per_frame;
|
||||||
|
|
||||||
sv = chan->voices;
|
sv = stream->channels;
|
||||||
dv = plugin->dst_voices;
|
dv = plugin->dst_channels;
|
||||||
*voices = dv;
|
*channels = dv;
|
||||||
for (voice = 0; voice < plugin->dst_format.voices; ++voice) {
|
for (channel = 0; channel < plugin->dst_format.channels; ++channel) {
|
||||||
dv->enabled = 1;
|
dv->enabled = 1;
|
||||||
dv->wanted = 0;
|
dv->wanted = 0;
|
||||||
dv->aptr = 0;
|
dv->aptr = 0;
|
||||||
|
|
@ -176,46 +176,46 @@ static ssize_t mmap_dst_voices(snd_pcm_plugin_t *plugin,
|
||||||
++sv;
|
++sv;
|
||||||
++dv;
|
++dv;
|
||||||
}
|
}
|
||||||
return snd_pcm_mmap_frames_xfer(data->slave, plugin->channel, frames);
|
return snd_pcm_mmap_frames_xfer(data->slave, plugin->stream, frames);
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t mmap_playback_transfer(snd_pcm_plugin_t *plugin,
|
static ssize_t mmap_playback_transfer(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voices UNUSED,
|
snd_pcm_plugin_channel_t *dst_channels UNUSED,
|
||||||
size_t frames)
|
size_t frames)
|
||||||
{
|
{
|
||||||
mmap_t *data;
|
mmap_t *data;
|
||||||
snd_pcm_channel_setup_t *setup;
|
snd_pcm_stream_setup_t *setup;
|
||||||
snd_pcm_mmap_control_t *ctrl;
|
snd_pcm_mmap_control_t *ctrl;
|
||||||
struct snd_pcm_chan *chan;
|
struct snd_pcm_stream *stream;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (plugin == NULL)
|
if (plugin == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
data = (mmap_t *)plugin->extra_data;
|
data = (mmap_t *)plugin->extra_data;
|
||||||
if (src_voices == NULL)
|
if (src_channels == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (plugin->prev == NULL)
|
if (plugin->prev == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
ctrl = data->control;
|
ctrl = data->control;
|
||||||
if (ctrl == NULL)
|
if (ctrl == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
chan = &data->slave->chan[SND_PCM_CHANNEL_PLAYBACK];
|
stream = &data->slave->stream[SND_PCM_STREAM_PLAYBACK];
|
||||||
setup = &chan->setup;
|
setup = &stream->setup;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
for (voice = 0; voice < plugin->src_format.voices; voice++) {
|
for (channel = 0; channel < plugin->src_format.channels; channel++) {
|
||||||
if (src_voices[voice].enabled)
|
if (src_channels[channel].enabled)
|
||||||
data->silence[voice * setup->frags + f] = 0;
|
data->silence[channel * setup->frags + f] = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
snd_pcm_mmap_commit_frames(data->slave, SND_PCM_CHANNEL_PLAYBACK, frames);
|
snd_pcm_mmap_commit_frames(data->slave, SND_PCM_STREAM_PLAYBACK, frames);
|
||||||
if (ctrl->status == SND_PCM_STATUS_PREPARED &&
|
if (ctrl->status == SND_PCM_STATUS_PREPARED &&
|
||||||
(chan->setup.start_mode == SND_PCM_START_DATA ||
|
(stream->setup.start_mode == SND_PCM_START_DATA ||
|
||||||
(chan->setup.start_mode == SND_PCM_START_FULL &&
|
(stream->setup.start_mode == SND_PCM_START_FULL &&
|
||||||
!snd_pcm_mmap_ready(data->slave, plugin->channel)))) {
|
!snd_pcm_mmap_ready(data->slave, plugin->stream)))) {
|
||||||
err = snd_pcm_channel_go(data->slave, plugin->channel);
|
err = snd_pcm_stream_go(data->slave, plugin->stream);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
@ -223,12 +223,12 @@ static ssize_t mmap_playback_transfer(snd_pcm_plugin_t *plugin,
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t mmap_capture_transfer(snd_pcm_plugin_t *plugin,
|
static ssize_t mmap_capture_transfer(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices UNUSED,
|
const snd_pcm_plugin_channel_t *src_channels UNUSED,
|
||||||
snd_pcm_plugin_voice_t *dst_voices UNUSED,
|
snd_pcm_plugin_channel_t *dst_channels UNUSED,
|
||||||
size_t frames)
|
size_t frames)
|
||||||
{
|
{
|
||||||
mmap_t *data;
|
mmap_t *data;
|
||||||
snd_pcm_channel_setup_t *setup;
|
snd_pcm_stream_setup_t *setup;
|
||||||
snd_pcm_mmap_control_t *ctrl;
|
snd_pcm_mmap_control_t *ctrl;
|
||||||
|
|
||||||
if (plugin == NULL)
|
if (plugin == NULL)
|
||||||
|
|
@ -240,10 +240,10 @@ static ssize_t mmap_capture_transfer(snd_pcm_plugin_t *plugin,
|
||||||
ctrl = data->control;
|
ctrl = data->control;
|
||||||
if (ctrl == NULL)
|
if (ctrl == NULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
setup = &data->slave->chan[SND_PCM_CHANNEL_CAPTURE].setup;
|
setup = &data->slave->stream[SND_PCM_STREAM_CAPTURE].setup;
|
||||||
|
|
||||||
/* FIXME: not here the increment */
|
/* FIXME: not here the increment */
|
||||||
snd_pcm_mmap_commit_frames(data->slave, SND_PCM_CHANNEL_CAPTURE, frames);
|
snd_pcm_mmap_commit_frames(data->slave, SND_PCM_STREAM_CAPTURE, frames);
|
||||||
return frames;
|
return frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -257,20 +257,20 @@ static int mmap_action(snd_pcm_plugin_t *plugin,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
data = (mmap_t *)plugin->extra_data;
|
data = (mmap_t *)plugin->extra_data;
|
||||||
if (action == INIT) {
|
if (action == INIT) {
|
||||||
snd_pcm_channel_setup_t *setup;
|
snd_pcm_stream_setup_t *setup;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
if (data->control)
|
if (data->control)
|
||||||
snd_pcm_munmap(data->slave, plugin->channel);
|
snd_pcm_munmap(data->slave, plugin->stream);
|
||||||
result = snd_pcm_mmap(data->slave, plugin->channel, &data->control, (void **)&data->buffer);
|
result = snd_pcm_mmap(data->slave, plugin->stream, &data->control, (void **)&data->buffer);
|
||||||
if (result < 0)
|
if (result < 0)
|
||||||
return result;
|
return result;
|
||||||
setup = &data->slave->chan[plugin->channel].setup;
|
setup = &data->slave->stream[plugin->stream].setup;
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (plugin->channel == SND_PCM_CHANNEL_PLAYBACK) {
|
if (plugin->stream == SND_PCM_STREAM_PLAYBACK) {
|
||||||
data->silence = malloc(setup->frags * setup->format.voices);
|
data->silence = malloc(setup->frags * setup->format.channels);
|
||||||
memset(data->silence, 0, setup->frags * setup->format.voices);
|
memset(data->silence, 0, setup->frags * setup->format.channels);
|
||||||
} else
|
} else
|
||||||
data->silence = 0;
|
data->silence = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -291,11 +291,11 @@ static void mmap_free(snd_pcm_plugin_t *plugin, void *private_data UNUSED)
|
||||||
free(data->silence);
|
free(data->silence);
|
||||||
#endif
|
#endif
|
||||||
if (data->control)
|
if (data->control)
|
||||||
snd_pcm_munmap(data->slave, plugin->channel);
|
snd_pcm_munmap(data->slave, plugin->stream);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_plugin_build_mmap(snd_pcm_plugin_handle_t *pcm,
|
int snd_pcm_plugin_build_mmap(snd_pcm_plugin_handle_t *pcm,
|
||||||
int channel,
|
int stream,
|
||||||
snd_pcm_t *slave,
|
snd_pcm_t *slave,
|
||||||
snd_pcm_format_t *format,
|
snd_pcm_format_t *format,
|
||||||
snd_pcm_plugin_t **r_plugin)
|
snd_pcm_plugin_t **r_plugin)
|
||||||
|
|
@ -309,20 +309,20 @@ int snd_pcm_plugin_build_mmap(snd_pcm_plugin_handle_t *pcm,
|
||||||
*r_plugin = NULL;
|
*r_plugin = NULL;
|
||||||
if (!pcm)
|
if (!pcm)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
err = snd_pcm_plugin_build(pcm, channel,
|
err = snd_pcm_plugin_build(pcm, stream,
|
||||||
"I/O mmap",
|
"I/O mmap",
|
||||||
format, format,
|
format, format,
|
||||||
sizeof(mmap_t) + sizeof(snd_pcm_plugin_voice_t) * format->voices,
|
sizeof(mmap_t) + sizeof(snd_pcm_plugin_channel_t) * format->channels,
|
||||||
&plugin);
|
&plugin);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
data = (mmap_t *)plugin->extra_data;
|
data = (mmap_t *)plugin->extra_data;
|
||||||
data->slave = slave;
|
data->slave = slave;
|
||||||
if (channel == SND_PCM_CHANNEL_PLAYBACK) {
|
if (stream == SND_PCM_STREAM_PLAYBACK) {
|
||||||
plugin->client_voices = mmap_src_voices;
|
plugin->client_channels = mmap_src_channels;
|
||||||
plugin->transfer = mmap_playback_transfer;
|
plugin->transfer = mmap_playback_transfer;
|
||||||
} else {
|
} else {
|
||||||
plugin->client_voices = mmap_dst_voices;
|
plugin->client_channels = mmap_dst_channels;
|
||||||
plugin->transfer = mmap_capture_transfer;
|
plugin->transfer = mmap_capture_transfer;
|
||||||
}
|
}
|
||||||
plugin->action = mmap_action;
|
plugin->action = mmap_action;
|
||||||
|
|
|
||||||
|
|
@ -149,8 +149,8 @@ static int ulaw2linear(unsigned char u_val)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef void (*mulaw_f)(snd_pcm_plugin_t *plugin,
|
typedef void (*mulaw_f)(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voices,
|
snd_pcm_plugin_channel_t *dst_channels,
|
||||||
size_t frames);
|
size_t frames);
|
||||||
|
|
||||||
typedef struct mulaw_private_data {
|
typedef struct mulaw_private_data {
|
||||||
|
|
@ -159,8 +159,8 @@ typedef struct mulaw_private_data {
|
||||||
} mulaw_t;
|
} mulaw_t;
|
||||||
|
|
||||||
static void mulaw_decode(snd_pcm_plugin_t *plugin,
|
static void mulaw_decode(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voices,
|
snd_pcm_plugin_channel_t *dst_channels,
|
||||||
size_t frames)
|
size_t frames)
|
||||||
{
|
{
|
||||||
#define PUT_S16_LABELS
|
#define PUT_S16_LABELS
|
||||||
|
|
@ -168,24 +168,24 @@ static void mulaw_decode(snd_pcm_plugin_t *plugin,
|
||||||
#undef PUT_S16_LABELS
|
#undef PUT_S16_LABELS
|
||||||
mulaw_t *data = (mulaw_t *)plugin->extra_data;
|
mulaw_t *data = (mulaw_t *)plugin->extra_data;
|
||||||
void *put = put_s16_labels[data->conv];
|
void *put = put_s16_labels[data->conv];
|
||||||
int voice;
|
int channel;
|
||||||
int nvoices = plugin->src_format.voices;
|
int nchannels = plugin->src_format.channels;
|
||||||
for (voice = 0; voice < nvoices; ++voice) {
|
for (channel = 0; channel < nchannels; ++channel) {
|
||||||
char *src;
|
char *src;
|
||||||
char *dst;
|
char *dst;
|
||||||
int src_step, dst_step;
|
int src_step, dst_step;
|
||||||
size_t frames1;
|
size_t frames1;
|
||||||
if (!src_voices[voice].enabled) {
|
if (!src_channels[channel].enabled) {
|
||||||
if (dst_voices[voice].wanted)
|
if (dst_channels[channel].wanted)
|
||||||
snd_pcm_area_silence(&dst_voices[voice].area, 0, frames, plugin->dst_format.format);
|
snd_pcm_area_silence(&dst_channels[channel].area, 0, frames, plugin->dst_format.format);
|
||||||
dst_voices[voice].enabled = 0;
|
dst_channels[channel].enabled = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
dst_voices[voice].enabled = 1;
|
dst_channels[channel].enabled = 1;
|
||||||
src = src_voices[voice].area.addr + src_voices[voice].area.first / 8;
|
src = src_channels[channel].area.addr + src_channels[channel].area.first / 8;
|
||||||
dst = dst_voices[voice].area.addr + dst_voices[voice].area.first / 8;
|
dst = dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
|
||||||
src_step = src_voices[voice].area.step / 8;
|
src_step = src_channels[channel].area.step / 8;
|
||||||
dst_step = dst_voices[voice].area.step / 8;
|
dst_step = dst_channels[channel].area.step / 8;
|
||||||
frames1 = frames;
|
frames1 = frames;
|
||||||
while (frames1-- > 0) {
|
while (frames1-- > 0) {
|
||||||
signed short sample = ulaw2linear(*src);
|
signed short sample = ulaw2linear(*src);
|
||||||
|
|
@ -201,8 +201,8 @@ static void mulaw_decode(snd_pcm_plugin_t *plugin,
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mulaw_encode(snd_pcm_plugin_t *plugin,
|
static void mulaw_encode(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voices,
|
snd_pcm_plugin_channel_t *dst_channels,
|
||||||
size_t frames)
|
size_t frames)
|
||||||
{
|
{
|
||||||
#define GET_S16_LABELS
|
#define GET_S16_LABELS
|
||||||
|
|
@ -210,25 +210,25 @@ static void mulaw_encode(snd_pcm_plugin_t *plugin,
|
||||||
#undef GET_S16_LABELS
|
#undef GET_S16_LABELS
|
||||||
mulaw_t *data = (mulaw_t *)plugin->extra_data;
|
mulaw_t *data = (mulaw_t *)plugin->extra_data;
|
||||||
void *get = get_s16_labels[data->conv];
|
void *get = get_s16_labels[data->conv];
|
||||||
int voice;
|
int channel;
|
||||||
int nvoices = plugin->src_format.voices;
|
int nchannels = plugin->src_format.channels;
|
||||||
signed short sample = 0;
|
signed short sample = 0;
|
||||||
for (voice = 0; voice < nvoices; ++voice) {
|
for (channel = 0; channel < nchannels; ++channel) {
|
||||||
char *src;
|
char *src;
|
||||||
char *dst;
|
char *dst;
|
||||||
int src_step, dst_step;
|
int src_step, dst_step;
|
||||||
size_t frames1;
|
size_t frames1;
|
||||||
if (!src_voices[voice].enabled) {
|
if (!src_channels[channel].enabled) {
|
||||||
if (dst_voices[voice].wanted)
|
if (dst_channels[channel].wanted)
|
||||||
snd_pcm_area_silence(&dst_voices[voice].area, 0, frames, plugin->dst_format.format);
|
snd_pcm_area_silence(&dst_channels[channel].area, 0, frames, plugin->dst_format.format);
|
||||||
dst_voices[voice].enabled = 0;
|
dst_channels[channel].enabled = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
dst_voices[voice].enabled = 1;
|
dst_channels[channel].enabled = 1;
|
||||||
src = src_voices[voice].area.addr + src_voices[voice].area.first / 8;
|
src = src_channels[channel].area.addr + src_channels[channel].area.first / 8;
|
||||||
dst = dst_voices[voice].area.addr + dst_voices[voice].area.first / 8;
|
dst = dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
|
||||||
src_step = src_voices[voice].area.step / 8;
|
src_step = src_channels[channel].area.step / 8;
|
||||||
dst_step = dst_voices[voice].area.step / 8;
|
dst_step = dst_channels[channel].area.step / 8;
|
||||||
frames1 = frames;
|
frames1 = frames;
|
||||||
while (frames1-- > 0) {
|
while (frames1-- > 0) {
|
||||||
goto *get;
|
goto *get;
|
||||||
|
|
@ -244,32 +244,32 @@ static void mulaw_encode(snd_pcm_plugin_t *plugin,
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t mulaw_transfer(snd_pcm_plugin_t *plugin,
|
static ssize_t mulaw_transfer(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voices,
|
snd_pcm_plugin_channel_t *dst_channels,
|
||||||
size_t frames)
|
size_t frames)
|
||||||
{
|
{
|
||||||
mulaw_t *data;
|
mulaw_t *data;
|
||||||
unsigned int voice;
|
unsigned int channel;
|
||||||
|
|
||||||
if (plugin == NULL || src_voices == NULL || dst_voices == NULL)
|
if (plugin == NULL || src_channels == NULL || dst_channels == NULL)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (frames == 0)
|
if (frames == 0)
|
||||||
return 0;
|
return 0;
|
||||||
for (voice = 0; voice < plugin->src_format.voices; voice++) {
|
for (channel = 0; channel < plugin->src_format.channels; channel++) {
|
||||||
if (src_voices[voice].area.first % 8 != 0 ||
|
if (src_channels[channel].area.first % 8 != 0 ||
|
||||||
src_voices[voice].area.step % 8 != 0)
|
src_channels[channel].area.step % 8 != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (dst_voices[voice].area.first % 8 != 0 ||
|
if (dst_channels[channel].area.first % 8 != 0 ||
|
||||||
dst_voices[voice].area.step % 8 != 0)
|
dst_channels[channel].area.step % 8 != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
data = (mulaw_t *)plugin->extra_data;
|
data = (mulaw_t *)plugin->extra_data;
|
||||||
data->func(plugin, src_voices, dst_voices, frames);
|
data->func(plugin, src_channels, dst_channels, frames);
|
||||||
return frames;
|
return frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_plugin_build_mulaw(snd_pcm_plugin_handle_t *handle,
|
int snd_pcm_plugin_build_mulaw(snd_pcm_plugin_handle_t *handle,
|
||||||
int channel,
|
int stream,
|
||||||
snd_pcm_format_t *src_format,
|
snd_pcm_format_t *src_format,
|
||||||
snd_pcm_format_t *dst_format,
|
snd_pcm_format_t *dst_format,
|
||||||
snd_pcm_plugin_t **r_plugin)
|
snd_pcm_plugin_t **r_plugin)
|
||||||
|
|
@ -286,7 +286,7 @@ int snd_pcm_plugin_build_mulaw(snd_pcm_plugin_handle_t *handle,
|
||||||
|
|
||||||
if (src_format->rate != dst_format->rate)
|
if (src_format->rate != dst_format->rate)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (src_format->voices != dst_format->voices)
|
if (src_format->channels != dst_format->channels)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
if (dst_format->format == SND_PCM_SFMT_MU_LAW) {
|
if (dst_format->format == SND_PCM_SFMT_MU_LAW) {
|
||||||
|
|
@ -302,7 +302,7 @@ int snd_pcm_plugin_build_mulaw(snd_pcm_plugin_handle_t *handle,
|
||||||
if (!snd_pcm_format_linear(format->format))
|
if (!snd_pcm_format_linear(format->format))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
err = snd_pcm_plugin_build(handle, channel,
|
err = snd_pcm_plugin_build(handle, stream,
|
||||||
"Mu-Law<->linear conversion",
|
"Mu-Law<->linear conversion",
|
||||||
src_format,
|
src_format,
|
||||||
dst_format,
|
dst_format,
|
||||||
|
|
|
||||||
|
|
@ -45,11 +45,11 @@
|
||||||
typedef struct {
|
typedef struct {
|
||||||
signed short last_S1;
|
signed short last_S1;
|
||||||
signed short last_S2;
|
signed short last_S2;
|
||||||
} rate_voice_t;
|
} rate_channel_t;
|
||||||
|
|
||||||
typedef void (*rate_f)(snd_pcm_plugin_t *plugin,
|
typedef void (*rate_f)(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voices,
|
snd_pcm_plugin_channel_t *dst_channels,
|
||||||
int src_frames, int dst_frames);
|
int src_frames, int dst_frames);
|
||||||
|
|
||||||
typedef struct rate_private_data {
|
typedef struct rate_private_data {
|
||||||
|
|
@ -58,34 +58,34 @@ typedef struct rate_private_data {
|
||||||
rate_f func;
|
rate_f func;
|
||||||
int get, put;
|
int get, put;
|
||||||
ssize_t old_src_frames, old_dst_frames;
|
ssize_t old_src_frames, old_dst_frames;
|
||||||
rate_voice_t voices[0];
|
rate_channel_t channels[0];
|
||||||
} rate_t;
|
} rate_t;
|
||||||
|
|
||||||
static void rate_init(snd_pcm_plugin_t *plugin)
|
static void rate_init(snd_pcm_plugin_t *plugin)
|
||||||
{
|
{
|
||||||
unsigned int voice;
|
unsigned int channel;
|
||||||
rate_t *data = (rate_t *)plugin->extra_data;
|
rate_t *data = (rate_t *)plugin->extra_data;
|
||||||
data->pos = 0;
|
data->pos = 0;
|
||||||
for (voice = 0; voice < plugin->src_format.voices; voice++) {
|
for (channel = 0; channel < plugin->src_format.channels; channel++) {
|
||||||
data->voices[voice].last_S1 = 0;
|
data->channels[channel].last_S1 = 0;
|
||||||
data->voices[voice].last_S2 = 0;
|
data->channels[channel].last_S2 = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void resample_expand(snd_pcm_plugin_t *plugin,
|
static void resample_expand(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voices,
|
snd_pcm_plugin_channel_t *dst_channels,
|
||||||
int src_frames, int dst_frames)
|
int src_frames, int dst_frames)
|
||||||
{
|
{
|
||||||
unsigned int pos = 0;
|
unsigned int pos = 0;
|
||||||
signed int val;
|
signed int val;
|
||||||
signed short S1, S2;
|
signed short S1, S2;
|
||||||
char *src, *dst;
|
char *src, *dst;
|
||||||
unsigned int voice;
|
unsigned int channel;
|
||||||
int src_step, dst_step;
|
int src_step, dst_step;
|
||||||
int src_frames1, dst_frames1;
|
int src_frames1, dst_frames1;
|
||||||
rate_t *data = (rate_t *)plugin->extra_data;
|
rate_t *data = (rate_t *)plugin->extra_data;
|
||||||
rate_voice_t *rvoices = data->voices;
|
rate_channel_t *rchannels = data->channels;
|
||||||
|
|
||||||
#define GET_S16_LABELS
|
#define GET_S16_LABELS
|
||||||
#define PUT_S16_LABELS
|
#define PUT_S16_LABELS
|
||||||
|
|
@ -100,21 +100,21 @@ static void resample_expand(snd_pcm_plugin_t *plugin,
|
||||||
#include "plugin_ops.h"
|
#include "plugin_ops.h"
|
||||||
#undef GET_S16_END
|
#undef GET_S16_END
|
||||||
|
|
||||||
for (voice = 0; voice < plugin->src_format.voices; voice++, rvoices++) {
|
for (channel = 0; channel < plugin->src_format.channels; channel++, rchannels++) {
|
||||||
pos = data->pos;
|
pos = data->pos;
|
||||||
S1 = rvoices->last_S1;
|
S1 = rchannels->last_S1;
|
||||||
S2 = rvoices->last_S2;
|
S2 = rchannels->last_S2;
|
||||||
if (!src_voices[voice].enabled) {
|
if (!src_channels[channel].enabled) {
|
||||||
if (dst_voices[voice].wanted)
|
if (dst_channels[channel].wanted)
|
||||||
snd_pcm_area_silence(&dst_voices[voice].area, 0, dst_frames, plugin->dst_format.format);
|
snd_pcm_area_silence(&dst_channels[channel].area, 0, dst_frames, plugin->dst_format.format);
|
||||||
dst_voices[voice].enabled = 0;
|
dst_channels[channel].enabled = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
dst_voices[voice].enabled = 1;
|
dst_channels[channel].enabled = 1;
|
||||||
src = (char *)src_voices[voice].area.addr + src_voices[voice].area.first / 8;
|
src = (char *)src_channels[channel].area.addr + src_channels[channel].area.first / 8;
|
||||||
dst = (char *)dst_voices[voice].area.addr + dst_voices[voice].area.first / 8;
|
dst = (char *)dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
|
||||||
src_step = src_voices[voice].area.step / 8;
|
src_step = src_channels[channel].area.step / 8;
|
||||||
dst_step = dst_voices[voice].area.step / 8;
|
dst_step = dst_channels[channel].area.step / 8;
|
||||||
src_frames1 = src_frames;
|
src_frames1 = src_frames;
|
||||||
dst_frames1 = dst_frames;
|
dst_frames1 = dst_frames;
|
||||||
if (pos & ~MASK) {
|
if (pos & ~MASK) {
|
||||||
|
|
@ -153,27 +153,27 @@ static void resample_expand(snd_pcm_plugin_t *plugin,
|
||||||
dst += dst_step;
|
dst += dst_step;
|
||||||
pos += data->pitch;
|
pos += data->pitch;
|
||||||
}
|
}
|
||||||
rvoices->last_S1 = S1;
|
rchannels->last_S1 = S1;
|
||||||
rvoices->last_S2 = S2;
|
rchannels->last_S2 = S2;
|
||||||
rvoices++;
|
rchannels++;
|
||||||
}
|
}
|
||||||
data->pos = pos;
|
data->pos = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void resample_shrink(snd_pcm_plugin_t *plugin,
|
static void resample_shrink(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voices,
|
snd_pcm_plugin_channel_t *dst_channels,
|
||||||
int src_frames, int dst_frames)
|
int src_frames, int dst_frames)
|
||||||
{
|
{
|
||||||
unsigned int pos = 0;
|
unsigned int pos = 0;
|
||||||
signed int val;
|
signed int val;
|
||||||
signed short S1, S2;
|
signed short S1, S2;
|
||||||
char *src, *dst;
|
char *src, *dst;
|
||||||
unsigned int voice;
|
unsigned int channel;
|
||||||
int src_step, dst_step;
|
int src_step, dst_step;
|
||||||
int src_frames1, dst_frames1;
|
int src_frames1, dst_frames1;
|
||||||
rate_t *data = (rate_t *)plugin->extra_data;
|
rate_t *data = (rate_t *)plugin->extra_data;
|
||||||
rate_voice_t *rvoices = data->voices;
|
rate_channel_t *rchannels = data->channels;
|
||||||
|
|
||||||
#define GET_S16_LABELS
|
#define GET_S16_LABELS
|
||||||
#define PUT_S16_LABELS
|
#define PUT_S16_LABELS
|
||||||
|
|
@ -184,21 +184,21 @@ static void resample_shrink(snd_pcm_plugin_t *plugin,
|
||||||
void *put = put_s16_labels[data->put];
|
void *put = put_s16_labels[data->put];
|
||||||
signed short sample = 0;
|
signed short sample = 0;
|
||||||
|
|
||||||
for (voice = 0; voice < plugin->src_format.voices; ++voice) {
|
for (channel = 0; channel < plugin->src_format.channels; ++channel) {
|
||||||
pos = data->pos;
|
pos = data->pos;
|
||||||
S1 = rvoices->last_S1;
|
S1 = rchannels->last_S1;
|
||||||
S2 = rvoices->last_S2;
|
S2 = rchannels->last_S2;
|
||||||
if (!src_voices[voice].enabled) {
|
if (!src_channels[channel].enabled) {
|
||||||
if (dst_voices[voice].wanted)
|
if (dst_channels[channel].wanted)
|
||||||
snd_pcm_area_silence(&dst_voices[voice].area, 0, dst_frames, plugin->dst_format.format);
|
snd_pcm_area_silence(&dst_channels[channel].area, 0, dst_frames, plugin->dst_format.format);
|
||||||
dst_voices[voice].enabled = 0;
|
dst_channels[channel].enabled = 0;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
dst_voices[voice].enabled = 1;
|
dst_channels[channel].enabled = 1;
|
||||||
src = (char *)src_voices[voice].area.addr + src_voices[voice].area.first / 8;
|
src = (char *)src_channels[channel].area.addr + src_channels[channel].area.first / 8;
|
||||||
dst = (char *)dst_voices[voice].area.addr + dst_voices[voice].area.first / 8;
|
dst = (char *)dst_channels[channel].area.addr + dst_channels[channel].area.first / 8;
|
||||||
src_step = src_voices[voice].area.step / 8;
|
src_step = src_channels[channel].area.step / 8;
|
||||||
dst_step = dst_voices[voice].area.step / 8;
|
dst_step = dst_channels[channel].area.step / 8;
|
||||||
src_frames1 = src_frames;
|
src_frames1 = src_frames;
|
||||||
dst_frames1 = dst_frames;
|
dst_frames1 = dst_frames;
|
||||||
while (dst_frames1 > 0) {
|
while (dst_frames1 > 0) {
|
||||||
|
|
@ -230,9 +230,9 @@ static void resample_shrink(snd_pcm_plugin_t *plugin,
|
||||||
}
|
}
|
||||||
pos += data->pitch;
|
pos += data->pitch;
|
||||||
}
|
}
|
||||||
rvoices->last_S1 = S1;
|
rchannels->last_S1 = S1;
|
||||||
rvoices->last_S2 = S2;
|
rchannels->last_S2 = S2;
|
||||||
rvoices++;
|
rchannels++;
|
||||||
}
|
}
|
||||||
data->pos = pos;
|
data->pos = pos;
|
||||||
}
|
}
|
||||||
|
|
@ -300,30 +300,30 @@ static ssize_t rate_dst_frames(snd_pcm_plugin_t *plugin, size_t frames)
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t rate_transfer(snd_pcm_plugin_t *plugin,
|
static ssize_t rate_transfer(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voices,
|
snd_pcm_plugin_channel_t *dst_channels,
|
||||||
size_t frames)
|
size_t frames)
|
||||||
{
|
{
|
||||||
size_t dst_frames;
|
size_t dst_frames;
|
||||||
unsigned int voice;
|
unsigned int channel;
|
||||||
rate_t *data;
|
rate_t *data;
|
||||||
|
|
||||||
if (plugin == NULL || src_voices == NULL || dst_voices == NULL)
|
if (plugin == NULL || src_channels == NULL || dst_channels == NULL)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (frames == 0)
|
if (frames == 0)
|
||||||
return 0;
|
return 0;
|
||||||
for (voice = 0; voice < plugin->src_format.voices; voice++) {
|
for (channel = 0; channel < plugin->src_format.channels; channel++) {
|
||||||
if (src_voices[voice].area.first % 8 != 0 ||
|
if (src_channels[channel].area.first % 8 != 0 ||
|
||||||
src_voices[voice].area.step % 8 != 0)
|
src_channels[channel].area.step % 8 != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (dst_voices[voice].area.first % 8 != 0 ||
|
if (dst_channels[channel].area.first % 8 != 0 ||
|
||||||
dst_voices[voice].area.step % 8 != 0)
|
dst_channels[channel].area.step % 8 != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dst_frames = rate_dst_frames(plugin, frames);
|
dst_frames = rate_dst_frames(plugin, frames);
|
||||||
data = (rate_t *)plugin->extra_data;
|
data = (rate_t *)plugin->extra_data;
|
||||||
data->func(plugin, src_voices, dst_voices, frames, dst_frames);
|
data->func(plugin, src_channels, dst_channels, frames, dst_frames);
|
||||||
return dst_frames;
|
return dst_frames;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -347,7 +347,7 @@ static int rate_action(snd_pcm_plugin_t *plugin,
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_plugin_build_rate(snd_pcm_plugin_handle_t *handle,
|
int snd_pcm_plugin_build_rate(snd_pcm_plugin_handle_t *handle,
|
||||||
int channel,
|
int stream,
|
||||||
snd_pcm_format_t *src_format,
|
snd_pcm_format_t *src_format,
|
||||||
snd_pcm_format_t *dst_format,
|
snd_pcm_format_t *dst_format,
|
||||||
snd_pcm_plugin_t **r_plugin)
|
snd_pcm_plugin_t **r_plugin)
|
||||||
|
|
@ -360,9 +360,9 @@ int snd_pcm_plugin_build_rate(snd_pcm_plugin_handle_t *handle,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
*r_plugin = NULL;
|
*r_plugin = NULL;
|
||||||
|
|
||||||
if (src_format->voices != dst_format->voices)
|
if (src_format->channels != dst_format->channels)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (src_format->voices < 1)
|
if (src_format->channels < 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (snd_pcm_format_linear(src_format->format) <= 0)
|
if (snd_pcm_format_linear(src_format->format) <= 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
@ -371,11 +371,11 @@ int snd_pcm_plugin_build_rate(snd_pcm_plugin_handle_t *handle,
|
||||||
if (src_format->rate == dst_format->rate)
|
if (src_format->rate == dst_format->rate)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
err = snd_pcm_plugin_build(handle, channel,
|
err = snd_pcm_plugin_build(handle, stream,
|
||||||
"rate conversion",
|
"rate conversion",
|
||||||
src_format,
|
src_format,
|
||||||
dst_format,
|
dst_format,
|
||||||
sizeof(rate_t) + src_format->voices * sizeof(rate_voice_t),
|
sizeof(rate_t) + src_format->channels * sizeof(rate_channel_t),
|
||||||
&plugin);
|
&plugin);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
|
||||||
|
|
@ -47,13 +47,13 @@
|
||||||
typedef struct ttable_dst ttable_dst_t;
|
typedef struct ttable_dst ttable_dst_t;
|
||||||
typedef struct route_private_data route_t;
|
typedef struct route_private_data route_t;
|
||||||
|
|
||||||
typedef void (*route_voice_f)(snd_pcm_plugin_t *plugin,
|
typedef void (*route_channel_f)(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voice,
|
snd_pcm_plugin_channel_t *dst_channel,
|
||||||
ttable_dst_t* ttable, size_t frames);
|
ttable_dst_t* ttable, size_t frames);
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int voice;
|
int channel;
|
||||||
int as_int;
|
int as_int;
|
||||||
#if ROUTE_PLUGIN_USE_FLOAT
|
#if ROUTE_PLUGIN_USE_FLOAT
|
||||||
float as_float;
|
float as_float;
|
||||||
|
|
@ -64,7 +64,7 @@ struct ttable_dst {
|
||||||
int att; /* Attenuated */
|
int att; /* Attenuated */
|
||||||
int nsrcs;
|
int nsrcs;
|
||||||
ttable_src_t* srcs;
|
ttable_src_t* srcs;
|
||||||
route_voice_f func;
|
route_channel_f func;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct route_private_data {
|
struct route_private_data {
|
||||||
|
|
@ -84,19 +84,19 @@ typedef union {
|
||||||
} sum_t;
|
} sum_t;
|
||||||
|
|
||||||
|
|
||||||
static void route_to_voice_from_zero(snd_pcm_plugin_t *plugin,
|
static void route_to_channel_from_zero(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices UNUSED,
|
const snd_pcm_plugin_channel_t *src_channels UNUSED,
|
||||||
snd_pcm_plugin_voice_t *dst_voice,
|
snd_pcm_plugin_channel_t *dst_channel,
|
||||||
ttable_dst_t* ttable UNUSED, size_t frames)
|
ttable_dst_t* ttable UNUSED, size_t frames)
|
||||||
{
|
{
|
||||||
if (dst_voice->wanted)
|
if (dst_channel->wanted)
|
||||||
snd_pcm_area_silence(&dst_voice->area, 0, frames, plugin->dst_format.format);
|
snd_pcm_area_silence(&dst_channel->area, 0, frames, plugin->dst_format.format);
|
||||||
dst_voice->enabled = 0;
|
dst_channel->enabled = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void route_to_voice_from_one(snd_pcm_plugin_t *plugin,
|
static void route_to_channel_from_one(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voice,
|
snd_pcm_plugin_channel_t *dst_channel,
|
||||||
ttable_dst_t* ttable, size_t frames)
|
ttable_dst_t* ttable, size_t frames)
|
||||||
{
|
{
|
||||||
#define CONV_LABELS
|
#define CONV_LABELS
|
||||||
|
|
@ -104,26 +104,26 @@ static void route_to_voice_from_one(snd_pcm_plugin_t *plugin,
|
||||||
#undef CONV_LABELS
|
#undef CONV_LABELS
|
||||||
route_t *data = (route_t *)plugin->extra_data;
|
route_t *data = (route_t *)plugin->extra_data;
|
||||||
void *conv;
|
void *conv;
|
||||||
const snd_pcm_plugin_voice_t *src_voice = 0;
|
const snd_pcm_plugin_channel_t *src_channel = 0;
|
||||||
int srcidx;
|
int srcidx;
|
||||||
char *src, *dst;
|
char *src, *dst;
|
||||||
int src_step, dst_step;
|
int src_step, dst_step;
|
||||||
for (srcidx = 0; srcidx < ttable->nsrcs; ++srcidx) {
|
for (srcidx = 0; srcidx < ttable->nsrcs; ++srcidx) {
|
||||||
src_voice = &src_voices[ttable->srcs[srcidx].voice];
|
src_channel = &src_channels[ttable->srcs[srcidx].channel];
|
||||||
if (src_voice->area.addr != NULL)
|
if (src_channel->area.addr != NULL)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (srcidx == ttable->nsrcs) {
|
if (srcidx == ttable->nsrcs) {
|
||||||
route_to_voice_from_zero(plugin, src_voices, dst_voice, ttable, frames);
|
route_to_channel_from_zero(plugin, src_channels, dst_channel, ttable, frames);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dst_voice->enabled = 1;
|
dst_channel->enabled = 1;
|
||||||
conv = conv_labels[data->conv];
|
conv = conv_labels[data->conv];
|
||||||
src = src_voice->area.addr + src_voice->area.first / 8;
|
src = src_channel->area.addr + src_channel->area.first / 8;
|
||||||
src_step = src_voice->area.step / 8;
|
src_step = src_channel->area.step / 8;
|
||||||
dst = dst_voice->area.addr + dst_voice->area.first / 8;
|
dst = dst_channel->area.addr + dst_channel->area.first / 8;
|
||||||
dst_step = dst_voice->area.step / 8;
|
dst_step = dst_channel->area.step / 8;
|
||||||
while (frames-- > 0) {
|
while (frames-- > 0) {
|
||||||
goto *conv;
|
goto *conv;
|
||||||
#define CONV_END after
|
#define CONV_END after
|
||||||
|
|
@ -135,9 +135,9 @@ static void route_to_voice_from_one(snd_pcm_plugin_t *plugin,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void route_to_voice(snd_pcm_plugin_t *plugin,
|
static void route_to_channel(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voice,
|
snd_pcm_plugin_channel_t *dst_channel,
|
||||||
ttable_dst_t* ttable, size_t frames)
|
ttable_dst_t* ttable, size_t frames)
|
||||||
{
|
{
|
||||||
#define GET_U_LABELS
|
#define GET_U_LABELS
|
||||||
|
|
@ -196,31 +196,31 @@ static void route_to_voice(snd_pcm_plugin_t *plugin,
|
||||||
u_int32_t sample = 0;
|
u_int32_t sample = 0;
|
||||||
int srcidx, srcidx1 = 0;
|
int srcidx, srcidx1 = 0;
|
||||||
for (srcidx = 0; srcidx < nsrcs; ++srcidx) {
|
for (srcidx = 0; srcidx < nsrcs; ++srcidx) {
|
||||||
const snd_pcm_plugin_voice_t *src_voice = &src_voices[ttable->srcs[srcidx].voice];
|
const snd_pcm_plugin_channel_t *src_channel = &src_channels[ttable->srcs[srcidx].channel];
|
||||||
if (!src_voice->enabled)
|
if (!src_channel->enabled)
|
||||||
continue;
|
continue;
|
||||||
srcs[srcidx1] = src_voice->area.addr + src_voices->area.first / 8;
|
srcs[srcidx1] = src_channel->area.addr + src_channels->area.first / 8;
|
||||||
src_steps[srcidx1] = src_voice->area.step / 8;
|
src_steps[srcidx1] = src_channel->area.step / 8;
|
||||||
src_tt[srcidx1] = ttable->srcs[srcidx];
|
src_tt[srcidx1] = ttable->srcs[srcidx];
|
||||||
srcidx1++;
|
srcidx1++;
|
||||||
}
|
}
|
||||||
nsrcs = srcidx1;
|
nsrcs = srcidx1;
|
||||||
if (nsrcs == 0) {
|
if (nsrcs == 0) {
|
||||||
route_to_voice_from_zero(plugin, src_voices, dst_voice, ttable, frames);
|
route_to_channel_from_zero(plugin, src_channels, dst_channel, ttable, frames);
|
||||||
return;
|
return;
|
||||||
} else if (nsrcs == 1 && src_tt[0].as_int == ROUTE_PLUGIN_RESOLUTION) {
|
} else if (nsrcs == 1 && src_tt[0].as_int == ROUTE_PLUGIN_RESOLUTION) {
|
||||||
route_to_voice_from_one(plugin, src_voices, dst_voice, ttable, frames);
|
route_to_channel_from_one(plugin, src_channels, dst_channel, ttable, frames);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
dst_voice->enabled = 1;
|
dst_channel->enabled = 1;
|
||||||
zero = zero_labels[data->sum_type];
|
zero = zero_labels[data->sum_type];
|
||||||
get = get_u_labels[data->get];
|
get = get_u_labels[data->get];
|
||||||
add = add_labels[data->sum_type * 2 + ttable->att];
|
add = add_labels[data->sum_type * 2 + ttable->att];
|
||||||
norm = norm_labels[data->sum_type * 8 + ttable->att * 4 + 4 - data->src_sample_size];
|
norm = norm_labels[data->sum_type * 8 + ttable->att * 4 + 4 - data->src_sample_size];
|
||||||
put_u32 = put_u32_labels[data->put];
|
put_u32 = put_u32_labels[data->put];
|
||||||
dst = dst_voice->area.addr + dst_voice->area.first / 8;
|
dst = dst_channel->area.addr + dst_channel->area.first / 8;
|
||||||
dst_step = dst_voice->area.step / 8;
|
dst_step = dst_channel->area.step / 8;
|
||||||
|
|
||||||
while (frames-- > 0) {
|
while (frames-- > 0) {
|
||||||
ttable_src_t *ttp = src_tt;
|
ttable_src_t *ttp = src_tt;
|
||||||
|
|
@ -361,47 +361,47 @@ static void route_to_voice(snd_pcm_plugin_t *plugin,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int route_src_voices_mask(snd_pcm_plugin_t *plugin,
|
int route_src_channels_mask(snd_pcm_plugin_t *plugin,
|
||||||
bitset_t *dst_vmask,
|
bitset_t *dst_vmask,
|
||||||
bitset_t **src_vmask)
|
bitset_t **src_vmask)
|
||||||
{
|
{
|
||||||
route_t *data = (route_t *)plugin->extra_data;
|
route_t *data = (route_t *)plugin->extra_data;
|
||||||
int svoices = plugin->src_format.voices;
|
int schannels = plugin->src_format.channels;
|
||||||
int dvoices = plugin->dst_format.voices;
|
int dchannels = plugin->dst_format.channels;
|
||||||
bitset_t *vmask = plugin->src_vmask;
|
bitset_t *vmask = plugin->src_vmask;
|
||||||
int voice;
|
int channel;
|
||||||
ttable_dst_t *dp = data->ttable;
|
ttable_dst_t *dp = data->ttable;
|
||||||
bitset_zero(vmask, svoices);
|
bitset_zero(vmask, schannels);
|
||||||
for (voice = 0; voice < dvoices; voice++, dp++) {
|
for (channel = 0; channel < dchannels; channel++, dp++) {
|
||||||
int src;
|
int src;
|
||||||
ttable_src_t *sp;
|
ttable_src_t *sp;
|
||||||
if (!bitset_get(dst_vmask, voice))
|
if (!bitset_get(dst_vmask, channel))
|
||||||
continue;
|
continue;
|
||||||
sp = dp->srcs;
|
sp = dp->srcs;
|
||||||
for (src = 0; src < dp->nsrcs; src++, sp++)
|
for (src = 0; src < dp->nsrcs; src++, sp++)
|
||||||
bitset_set(vmask, sp->voice);
|
bitset_set(vmask, sp->channel);
|
||||||
}
|
}
|
||||||
*src_vmask = vmask;
|
*src_vmask = vmask;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int route_dst_voices_mask(snd_pcm_plugin_t *plugin,
|
int route_dst_channels_mask(snd_pcm_plugin_t *plugin,
|
||||||
bitset_t *src_vmask,
|
bitset_t *src_vmask,
|
||||||
bitset_t **dst_vmask)
|
bitset_t **dst_vmask)
|
||||||
{
|
{
|
||||||
route_t *data = (route_t *)plugin->extra_data;
|
route_t *data = (route_t *)plugin->extra_data;
|
||||||
int dvoices = plugin->dst_format.voices;
|
int dchannels = plugin->dst_format.channels;
|
||||||
bitset_t *vmask = plugin->dst_vmask;
|
bitset_t *vmask = plugin->dst_vmask;
|
||||||
int voice;
|
int channel;
|
||||||
ttable_dst_t *dp = data->ttable;
|
ttable_dst_t *dp = data->ttable;
|
||||||
bitset_zero(vmask, dvoices);
|
bitset_zero(vmask, dchannels);
|
||||||
for (voice = 0; voice < dvoices; voice++, dp++) {
|
for (channel = 0; channel < dchannels; channel++, dp++) {
|
||||||
int src;
|
int src;
|
||||||
ttable_src_t *sp;
|
ttable_src_t *sp;
|
||||||
sp = dp->srcs;
|
sp = dp->srcs;
|
||||||
for (src = 0; src < dp->nsrcs; src++, sp++) {
|
for (src = 0; src < dp->nsrcs; src++, sp++) {
|
||||||
if (bitset_get(src_vmask, sp->voice)) {
|
if (bitset_get(src_vmask, sp->channel)) {
|
||||||
bitset_set(vmask, voice);
|
bitset_set(vmask, channel);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -413,10 +413,10 @@ int route_dst_voices_mask(snd_pcm_plugin_t *plugin,
|
||||||
static void route_free(snd_pcm_plugin_t *plugin, void* private_data UNUSED)
|
static void route_free(snd_pcm_plugin_t *plugin, void* private_data UNUSED)
|
||||||
{
|
{
|
||||||
route_t *data = (route_t *)plugin->extra_data;
|
route_t *data = (route_t *)plugin->extra_data;
|
||||||
unsigned int dst_voice;
|
unsigned int dst_channel;
|
||||||
for (dst_voice = 0; dst_voice < plugin->dst_format.voices; ++dst_voice) {
|
for (dst_channel = 0; dst_channel < plugin->dst_format.channels; ++dst_channel) {
|
||||||
if (data->ttable[dst_voice].srcs != NULL)
|
if (data->ttable[dst_channel].srcs != NULL)
|
||||||
free(data->ttable[dst_voice].srcs);
|
free(data->ttable[dst_channel].srcs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -424,7 +424,7 @@ static int route_load_ttable(snd_pcm_plugin_t *plugin,
|
||||||
const route_ttable_entry_t* src_ttable)
|
const route_ttable_entry_t* src_ttable)
|
||||||
{
|
{
|
||||||
route_t *data;
|
route_t *data;
|
||||||
unsigned int src_voice, dst_voice;
|
unsigned int src_channel, dst_channel;
|
||||||
const route_ttable_entry_t *sptr;
|
const route_ttable_entry_t *sptr;
|
||||||
ttable_dst_t *dptr;
|
ttable_dst_t *dptr;
|
||||||
if (src_ttable == NULL)
|
if (src_ttable == NULL)
|
||||||
|
|
@ -433,16 +433,16 @@ static int route_load_ttable(snd_pcm_plugin_t *plugin,
|
||||||
dptr = data->ttable;
|
dptr = data->ttable;
|
||||||
sptr = src_ttable;
|
sptr = src_ttable;
|
||||||
plugin->private_free = route_free;
|
plugin->private_free = route_free;
|
||||||
for (dst_voice = 0; dst_voice < plugin->dst_format.voices; ++dst_voice) {
|
for (dst_channel = 0; dst_channel < plugin->dst_format.channels; ++dst_channel) {
|
||||||
route_ttable_entry_t t = 0;
|
route_ttable_entry_t t = 0;
|
||||||
int att = 0;
|
int att = 0;
|
||||||
int nsrcs = 0;
|
int nsrcs = 0;
|
||||||
ttable_src_t srcs[plugin->src_format.voices];
|
ttable_src_t srcs[plugin->src_format.channels];
|
||||||
for (src_voice = 0; src_voice < plugin->src_format.voices; ++src_voice) {
|
for (src_channel = 0; src_channel < plugin->src_format.channels; ++src_channel) {
|
||||||
if (*sptr < 0 || *sptr > FULL)
|
if (*sptr < 0 || *sptr > FULL)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (*sptr != 0) {
|
if (*sptr != 0) {
|
||||||
srcs[nsrcs].voice = src_voice;
|
srcs[nsrcs].channel = src_channel;
|
||||||
#if ROUTE_PLUGIN_USE_FLOAT
|
#if ROUTE_PLUGIN_USE_FLOAT
|
||||||
/* Also in user space for non attenuated */
|
/* Also in user space for non attenuated */
|
||||||
srcs[nsrcs].as_int = (*sptr == FULL ? ROUTE_PLUGIN_RESOLUTION : 0);
|
srcs[nsrcs].as_int = (*sptr == FULL ? ROUTE_PLUGIN_RESOLUTION : 0);
|
||||||
|
|
@ -465,13 +465,13 @@ static int route_load_ttable(snd_pcm_plugin_t *plugin,
|
||||||
dptr->nsrcs = nsrcs;
|
dptr->nsrcs = nsrcs;
|
||||||
switch (nsrcs) {
|
switch (nsrcs) {
|
||||||
case 0:
|
case 0:
|
||||||
dptr->func = route_to_voice_from_zero;
|
dptr->func = route_to_channel_from_zero;
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
dptr->func = route_to_voice_from_one;
|
dptr->func = route_to_channel_from_one;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dptr->func = route_to_voice;
|
dptr->func = route_to_channel;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (nsrcs > 0) {
|
if (nsrcs > 0) {
|
||||||
|
|
@ -485,40 +485,40 @@ static int route_load_ttable(snd_pcm_plugin_t *plugin,
|
||||||
}
|
}
|
||||||
|
|
||||||
static ssize_t route_transfer(snd_pcm_plugin_t *plugin,
|
static ssize_t route_transfer(snd_pcm_plugin_t *plugin,
|
||||||
const snd_pcm_plugin_voice_t *src_voices,
|
const snd_pcm_plugin_channel_t *src_channels,
|
||||||
snd_pcm_plugin_voice_t *dst_voices,
|
snd_pcm_plugin_channel_t *dst_channels,
|
||||||
size_t frames)
|
size_t frames)
|
||||||
{
|
{
|
||||||
route_t *data;
|
route_t *data;
|
||||||
int src_nvoices, dst_nvoices;
|
int src_nchannels, dst_nchannels;
|
||||||
int src_voice, dst_voice;
|
int src_channel, dst_channel;
|
||||||
ttable_dst_t *ttp;
|
ttable_dst_t *ttp;
|
||||||
snd_pcm_plugin_voice_t *dvp;
|
snd_pcm_plugin_channel_t *dvp;
|
||||||
|
|
||||||
if (plugin == NULL || src_voices == NULL || dst_voices == NULL)
|
if (plugin == NULL || src_channels == NULL || dst_channels == NULL)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
if (frames == 0)
|
if (frames == 0)
|
||||||
return 0;
|
return 0;
|
||||||
data = (route_t *)plugin->extra_data;
|
data = (route_t *)plugin->extra_data;
|
||||||
|
|
||||||
src_nvoices = plugin->src_format.voices;
|
src_nchannels = plugin->src_format.channels;
|
||||||
for (src_voice = 0; src_voice < src_nvoices; ++src_voice) {
|
for (src_channel = 0; src_channel < src_nchannels; ++src_channel) {
|
||||||
if (src_voices[src_voice].area.first % 8 != 0 ||
|
if (src_channels[src_channel].area.first % 8 != 0 ||
|
||||||
src_voices[src_voice].area.step % 8 != 0)
|
src_channels[src_channel].area.step % 8 != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
dst_nvoices = plugin->dst_format.voices;
|
dst_nchannels = plugin->dst_format.channels;
|
||||||
for (dst_voice = 0; dst_voice < dst_nvoices; ++dst_voice) {
|
for (dst_channel = 0; dst_channel < dst_nchannels; ++dst_channel) {
|
||||||
if (dst_voices[dst_voice].area.first % 8 != 0 ||
|
if (dst_channels[dst_channel].area.first % 8 != 0 ||
|
||||||
dst_voices[dst_voice].area.step % 8 != 0)
|
dst_channels[dst_channel].area.step % 8 != 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ttp = data->ttable;
|
ttp = data->ttable;
|
||||||
dvp = dst_voices;
|
dvp = dst_channels;
|
||||||
for (dst_voice = 0; dst_voice < dst_nvoices; ++dst_voice) {
|
for (dst_channel = 0; dst_channel < dst_nchannels; ++dst_channel) {
|
||||||
ttp->func(plugin, src_voices, dvp, ttp, frames);
|
ttp->func(plugin, src_channels, dvp, ttp, frames);
|
||||||
dvp++;
|
dvp++;
|
||||||
ttp++;
|
ttp++;
|
||||||
}
|
}
|
||||||
|
|
@ -543,7 +543,7 @@ int getput_index(int format)
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_pcm_plugin_build_route(snd_pcm_plugin_handle_t *handle,
|
int snd_pcm_plugin_build_route(snd_pcm_plugin_handle_t *handle,
|
||||||
int channel,
|
int stream,
|
||||||
snd_pcm_format_t *src_format,
|
snd_pcm_format_t *src_format,
|
||||||
snd_pcm_format_t *dst_format,
|
snd_pcm_format_t *dst_format,
|
||||||
route_ttable_entry_t *ttable,
|
route_ttable_entry_t *ttable,
|
||||||
|
|
@ -562,11 +562,11 @@ int snd_pcm_plugin_build_route(snd_pcm_plugin_handle_t *handle,
|
||||||
snd_pcm_format_linear(dst_format->format)))
|
snd_pcm_format_linear(dst_format->format)))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
err = snd_pcm_plugin_build(handle, channel,
|
err = snd_pcm_plugin_build(handle, stream,
|
||||||
"attenuated route conversion",
|
"attenuated route conversion",
|
||||||
src_format,
|
src_format,
|
||||||
dst_format,
|
dst_format,
|
||||||
sizeof(route_t) + sizeof(data->ttable[0]) * dst_format->voices,
|
sizeof(route_t) + sizeof(data->ttable[0]) * dst_format->channels,
|
||||||
&plugin);
|
&plugin);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
|
@ -592,8 +592,8 @@ int snd_pcm_plugin_build_route(snd_pcm_plugin_handle_t *handle,
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
plugin->transfer = route_transfer;
|
plugin->transfer = route_transfer;
|
||||||
plugin->src_voices_mask = route_src_voices_mask;
|
plugin->src_channels_mask = route_src_channels_mask;
|
||||||
plugin->dst_voices_mask = route_dst_voices_mask;
|
plugin->dst_channels_mask = route_dst_channels_mask;
|
||||||
*r_plugin = plugin;
|
*r_plugin = plugin;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -122,68 +122,68 @@ int snd_rawmidi_info(snd_rawmidi_t *rmidi, snd_rawmidi_info_t * info)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_rawmidi_channel_params(snd_rawmidi_t *rmidi, snd_rawmidi_params_t * params)
|
int snd_rawmidi_stream_params(snd_rawmidi_t *rmidi, snd_rawmidi_params_t * params)
|
||||||
{
|
{
|
||||||
if (!rmidi || !params)
|
if (!rmidi || !params)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (params->channel < 0 || params->channel > 1)
|
if (params->stream < 0 || params->stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (ioctl(rmidi->fd, SND_RAWMIDI_IOCTL_CHANNEL_PARAMS, params) < 0)
|
if (ioctl(rmidi->fd, SND_RAWMIDI_IOCTL_STREAM_PARAMS, params) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_rawmidi_channel_setup(snd_rawmidi_t *rmidi, snd_rawmidi_setup_t * setup)
|
int snd_rawmidi_stream_setup(snd_rawmidi_t *rmidi, snd_rawmidi_setup_t * setup)
|
||||||
{
|
{
|
||||||
if (!rmidi || !setup)
|
if (!rmidi || !setup)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (setup->channel < 0 || setup->channel > 1)
|
if (setup->stream < 0 || setup->stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (ioctl(rmidi->fd, SND_RAWMIDI_IOCTL_CHANNEL_SETUP, setup) < 0)
|
if (ioctl(rmidi->fd, SND_RAWMIDI_IOCTL_STREAM_SETUP, setup) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_rawmidi_channel_status(snd_rawmidi_t *rmidi, snd_rawmidi_status_t * status)
|
int snd_rawmidi_stream_status(snd_rawmidi_t *rmidi, snd_rawmidi_status_t * status)
|
||||||
{
|
{
|
||||||
if (!rmidi || !status)
|
if (!rmidi || !status)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (status->channel < 0 || status->channel > 1)
|
if (status->stream < 0 || status->stream > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (ioctl(rmidi->fd, SND_RAWMIDI_IOCTL_CHANNEL_STATUS, status) < 0)
|
if (ioctl(rmidi->fd, SND_RAWMIDI_IOCTL_STREAM_STATUS, status) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_rawmidi_output_drain(snd_rawmidi_t *rmidi)
|
int snd_rawmidi_output_drain(snd_rawmidi_t *rmidi)
|
||||||
{
|
{
|
||||||
int chn = SND_RAWMIDI_CHANNEL_OUTPUT;
|
int str = SND_RAWMIDI_STREAM_OUTPUT;
|
||||||
if (!rmidi)
|
if (!rmidi)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (ioctl(rmidi->fd, SND_RAWMIDI_IOCTL_CHANNEL_DRAIN, &chn) < 0)
|
if (ioctl(rmidi->fd, SND_RAWMIDI_IOCTL_STREAM_DRAIN, &str) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_rawmidi_channel_flush(snd_rawmidi_t *rmidi, int chn)
|
int snd_rawmidi_stream_flush(snd_rawmidi_t *rmidi, int str)
|
||||||
{
|
{
|
||||||
if (!rmidi)
|
if (!rmidi)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (chn < 0 || chn > 1)
|
if (str < 0 || str > 1)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
if (ioctl(rmidi->fd, SND_RAWMIDI_IOCTL_CHANNEL_FLUSH) < 0)
|
if (ioctl(rmidi->fd, SND_RAWMIDI_IOCTL_STREAM_FLUSH) < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_rawmidi_output_flush(snd_rawmidi_t *rmidi)
|
int snd_rawmidi_output_flush(snd_rawmidi_t *rmidi)
|
||||||
{
|
{
|
||||||
return snd_rawmidi_channel_flush(rmidi, SND_RAWMIDI_CHANNEL_OUTPUT);
|
return snd_rawmidi_stream_flush(rmidi, SND_RAWMIDI_STREAM_OUTPUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_rawmidi_input_flush(snd_rawmidi_t *rmidi)
|
int snd_rawmidi_input_flush(snd_rawmidi_t *rmidi)
|
||||||
{
|
{
|
||||||
return snd_rawmidi_channel_flush(rmidi, SND_RAWMIDI_CHANNEL_INPUT);
|
return snd_rawmidi_stream_flush(rmidi, SND_RAWMIDI_STREAM_INPUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t snd_rawmidi_write(snd_rawmidi_t *rmidi, const void *buffer, size_t size)
|
ssize_t snd_rawmidi_write(snd_rawmidi_t *rmidi, const void *buffer, size_t size)
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
#include "../include/asoundlib.h"
|
#include "../include/asoundlib.h"
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#define USE_BLOCK_MODE /* latency is twice more than for stream mode!!! */
|
#define USE_FRAGMENT_MODE /* latency is twice more than for frame mode!!! */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define USED_RATE 48000
|
#define USED_RATE 48000
|
||||||
|
|
@ -28,18 +28,18 @@ static char *xitoa(int aaa)
|
||||||
|
|
||||||
static int syncro(snd_pcm_t *phandle, snd_pcm_t *chandle)
|
static int syncro(snd_pcm_t *phandle, snd_pcm_t *chandle)
|
||||||
{
|
{
|
||||||
snd_pcm_channel_info_t pinfo, cinfo;
|
snd_pcm_stream_info_t pinfo, cinfo;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
bzero(&pinfo, sizeof(pinfo));
|
bzero(&pinfo, sizeof(pinfo));
|
||||||
bzero(&cinfo, sizeof(cinfo));
|
bzero(&cinfo, sizeof(cinfo));
|
||||||
pinfo.channel = SND_PCM_CHANNEL_PLAYBACK;
|
pinfo.stream = SND_PCM_STREAM_PLAYBACK;
|
||||||
cinfo.channel = SND_PCM_CHANNEL_CAPTURE;
|
cinfo.stream = SND_PCM_STREAM_CAPTURE;
|
||||||
if ((err = snd_pcm_channel_info(phandle, &pinfo)) < 0) {
|
if ((err = snd_pcm_stream_info(phandle, &pinfo)) < 0) {
|
||||||
printf("Playback info error: %s\n", snd_strerror(err));
|
printf("Playback info error: %s\n", snd_strerror(err));
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
if ((err = snd_pcm_channel_info(chandle, &cinfo)) < 0) {
|
if ((err = snd_pcm_stream_info(chandle, &cinfo)) < 0) {
|
||||||
printf("Capture info error: %s\n", snd_strerror(err));
|
printf("Capture info error: %s\n", snd_strerror(err));
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
@ -70,19 +70,19 @@ static void syncro_id(snd_pcm_sync_t *sync)
|
||||||
int setparams(snd_pcm_t *phandle, snd_pcm_t *chandle, int sync, int *queue)
|
int setparams(snd_pcm_t *phandle, snd_pcm_t *chandle, int sync, int *queue)
|
||||||
{
|
{
|
||||||
int err, again;
|
int err, again;
|
||||||
snd_pcm_channel_params_t params;
|
snd_pcm_stream_params_t params;
|
||||||
snd_pcm_channel_setup_t psetup, csetup;
|
snd_pcm_stream_setup_t psetup, csetup;
|
||||||
|
|
||||||
bzero(¶ms, sizeof(params));
|
bzero(¶ms, sizeof(params));
|
||||||
params.channel = SND_PCM_CHANNEL_PLAYBACK;
|
params.stream = SND_PCM_STREAM_PLAYBACK;
|
||||||
#ifdef USE_BLOCK_MODE
|
#ifdef USE_BLOCK_MODE
|
||||||
params.mode = SND_PCM_MODE_BLOCK;
|
params.mode = SND_PCM_MODE_FRAGMENT;
|
||||||
#else
|
#else
|
||||||
params.mode = SND_PCM_MODE_STREAM;
|
params.mode = SND_PCM_MODE_FRAME;
|
||||||
#endif
|
#endif
|
||||||
params.format.interleave = 1;
|
params.format.interleave = 1;
|
||||||
params.format.format = SND_PCM_SFMT_S16_LE;
|
params.format.format = SND_PCM_SFMT_S16_LE;
|
||||||
params.format.voices = 2;
|
params.format.channels = 2;
|
||||||
params.format.rate = USED_RATE;
|
params.format.rate = USED_RATE;
|
||||||
params.start_mode = SND_PCM_START_GO;
|
params.start_mode = SND_PCM_START_GO;
|
||||||
params.xrun_mode = SND_PCM_XRUN_DRAIN;
|
params.xrun_mode = SND_PCM_XRUN_DRAIN;
|
||||||
|
|
@ -100,7 +100,7 @@ int setparams(snd_pcm_t *phandle, snd_pcm_t *chandle, int sync, int *queue)
|
||||||
if (*queue > LATENCY_MAX)
|
if (*queue > LATENCY_MAX)
|
||||||
return -1;
|
return -1;
|
||||||
again = 0;
|
again = 0;
|
||||||
params.channel = SND_PCM_CHANNEL_PLAYBACK;
|
params.stream = SND_PCM_STREAM_PLAYBACK;
|
||||||
params.frag_size = *queue;
|
params.frag_size = *queue;
|
||||||
#ifdef USE_BLOCK_MODE
|
#ifdef USE_BLOCK_MODE
|
||||||
params.buffer_size = *queue * 2;
|
params.buffer_size = *queue * 2;
|
||||||
|
|
@ -109,24 +109,24 @@ int setparams(snd_pcm_t *phandle, snd_pcm_t *chandle, int sync, int *queue)
|
||||||
params.buffer_size = *queue;
|
params.buffer_size = *queue;
|
||||||
params.buf.stream.bytes_min = 2;
|
params.buf.stream.bytes_min = 2;
|
||||||
#endif
|
#endif
|
||||||
if ((err = snd_pcm_channel_params(phandle, ¶ms)) < 0) {
|
if ((err = snd_pcm_stream_params(phandle, ¶ms)) < 0) {
|
||||||
printf("Playback params error: %s\n", snd_strerror(err));
|
printf("Playback params error: %s\n", snd_strerror(err));
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
params.channel = SND_PCM_CHANNEL_CAPTURE;
|
params.stream = SND_PCM_STREAM_CAPTURE;
|
||||||
if ((err = snd_pcm_channel_params(chandle, ¶ms)) < 0) {
|
if ((err = snd_pcm_stream_params(chandle, ¶ms)) < 0) {
|
||||||
printf("Capture params error: %s\n", snd_strerror(err));
|
printf("Capture params error: %s\n", snd_strerror(err));
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
bzero(&psetup, sizeof(psetup));
|
bzero(&psetup, sizeof(psetup));
|
||||||
psetup.channel = SND_PCM_CHANNEL_PLAYBACK;
|
psetup.stream = SND_PCM_STREAM_PLAYBACK;
|
||||||
if ((err = snd_pcm_channel_setup(phandle, &psetup)) < 0) {
|
if ((err = snd_pcm_stream_setup(phandle, &psetup)) < 0) {
|
||||||
printf("Playback setup error: %s\n", snd_strerror(err));
|
printf("Playback setup error: %s\n", snd_strerror(err));
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
bzero(&csetup, sizeof(csetup));
|
bzero(&csetup, sizeof(csetup));
|
||||||
csetup.channel = SND_PCM_CHANNEL_CAPTURE;
|
csetup.stream = SND_PCM_STREAM_CAPTURE;
|
||||||
if ((err = snd_pcm_channel_setup(chandle, &csetup)) < 0) {
|
if ((err = snd_pcm_stream_setup(chandle, &csetup)) < 0) {
|
||||||
printf("Capture setup error: %s\n", snd_strerror(err));
|
printf("Capture setup error: %s\n", snd_strerror(err));
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
@ -164,17 +164,17 @@ int setparams(snd_pcm_t *phandle, snd_pcm_t *chandle, int sync, int *queue)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void showstat(snd_pcm_t *handle, int channel, snd_pcm_channel_status_t *rstatus, size_t bytes)
|
void showstat(snd_pcm_t *handle, int stream, snd_pcm_stream_status_t *rstatus, size_t bytes)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
snd_pcm_channel_status_t status;
|
snd_pcm_stream_status_t status;
|
||||||
char *str;
|
char *str;
|
||||||
|
|
||||||
str = channel == SND_PCM_CHANNEL_CAPTURE ? "Capture" : "Playback";
|
str = stream == SND_PCM_STREAM_CAPTURE ? "Capture" : "Playback";
|
||||||
bzero(&status, sizeof(status));
|
bzero(&status, sizeof(status));
|
||||||
status.channel = channel;
|
status.stream = stream;
|
||||||
if ((err = snd_pcm_channel_status(handle, &status)) < 0) {
|
if ((err = snd_pcm_stream_status(handle, &status)) < 0) {
|
||||||
printf("Channel %s status error: %s\n", str, snd_strerror(err));
|
printf("Stream %s status error: %s\n", str, snd_strerror(err));
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
printf("%s:\n", str);
|
printf("%s:\n", str);
|
||||||
|
|
@ -233,7 +233,7 @@ long readbuf(snd_pcm_t *handle, char *buf, long len, size_t *bytes)
|
||||||
if (r > 0)
|
if (r > 0)
|
||||||
*bytes += r;
|
*bytes += r;
|
||||||
// printf("read = %li\n", r);
|
// printf("read = %li\n", r);
|
||||||
// showstat(handle, SND_PCM_CHANNEL_CAPTURE, NULL);
|
// showstat(handle, SND_PCM_STREAM_CAPTURE, NULL);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -250,7 +250,7 @@ long writebuf(snd_pcm_t *handle, char *buf, long len, size_t *bytes)
|
||||||
// printf("write = %li\n", r);
|
// printf("write = %li\n", r);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
// showstat(handle, SND_PCM_CHANNEL_PLAYBACK, NULL);
|
// showstat(handle, SND_PCM_STREAM_PLAYBACK, NULL);
|
||||||
buf += r;
|
buf += r;
|
||||||
len -= r;
|
len -= r;
|
||||||
*bytes += r;
|
*bytes += r;
|
||||||
|
|
@ -268,7 +268,7 @@ int main(void)
|
||||||
int size, ok;
|
int size, ok;
|
||||||
int sync;
|
int sync;
|
||||||
snd_pcm_sync_t ssync;
|
snd_pcm_sync_t ssync;
|
||||||
snd_pcm_channel_status_t pstatus, cstatus;
|
snd_pcm_stream_status_t pstatus, cstatus;
|
||||||
ssize_t r;
|
ssize_t r;
|
||||||
size_t bytes_in, bytes_out;
|
size_t bytes_in, bytes_out;
|
||||||
|
|
||||||
|
|
@ -282,9 +282,9 @@ int main(void)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#ifdef USE_BLOCK_MODE
|
#ifdef USE_BLOCK_MODE
|
||||||
printf("Using block mode...\n");
|
printf("Using fragment mode...\n");
|
||||||
#else
|
#else
|
||||||
printf("Using stream mode...\n");
|
printf("Using frame mode...\n");
|
||||||
#endif
|
#endif
|
||||||
sync = syncro(phandle, chandle);
|
sync = syncro(phandle, chandle);
|
||||||
if (sync)
|
if (sync)
|
||||||
|
|
@ -330,8 +330,8 @@ int main(void)
|
||||||
if (r > 0 && writebuf(phandle, buffer, r, &bytes_out) < 0)
|
if (r > 0 && writebuf(phandle, buffer, r, &bytes_out) < 0)
|
||||||
ok = 0;
|
ok = 0;
|
||||||
}
|
}
|
||||||
showstat(phandle, SND_PCM_CHANNEL_PLAYBACK, &pstatus, bytes_out);
|
showstat(phandle, SND_PCM_STREAM_PLAYBACK, &pstatus, bytes_out);
|
||||||
showstat(chandle, SND_PCM_CHANNEL_CAPTURE, &cstatus, bytes_in);
|
showstat(chandle, SND_PCM_STREAM_CAPTURE, &cstatus, bytes_in);
|
||||||
snd_pcm_capture_flush(chandle);
|
snd_pcm_capture_flush(chandle);
|
||||||
snd_pcm_playback_flush(phandle);
|
snd_pcm_playback_flush(phandle);
|
||||||
if (ok) {
|
if (ok) {
|
||||||
|
|
|
||||||
|
|
@ -180,14 +180,14 @@ int main(int argc, char** argv)
|
||||||
|
|
||||||
bzero(&istat, sizeof(istat));
|
bzero(&istat, sizeof(istat));
|
||||||
bzero(&ostat, sizeof(ostat));
|
bzero(&ostat, sizeof(ostat));
|
||||||
istat.channel = SND_RAWMIDI_CHANNEL_INPUT;
|
istat.stream = SND_RAWMIDI_STREAM_INPUT;
|
||||||
ostat.channel = SND_RAWMIDI_CHANNEL_OUTPUT;
|
ostat.stream = SND_RAWMIDI_STREAM_OUTPUT;
|
||||||
err = snd_rawmidi_channel_status(handle_in, &istat);
|
err = snd_rawmidi_stream_status(handle_in, &istat);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
fprintf(stderr, "input channel status error: %d\n", err);
|
fprintf(stderr, "input stream status error: %d\n", err);
|
||||||
err = snd_rawmidi_channel_status(handle_out, &ostat);
|
err = snd_rawmidi_stream_status(handle_out, &ostat);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
fprintf(stderr, "output channel status error: %d\n", err);
|
fprintf(stderr, "output stream status error: %d\n", err);
|
||||||
printf("input.status.queue = %i\n", istat.queue);
|
printf("input.status.queue = %i\n", istat.queue);
|
||||||
printf("input.status.overrun = %i\n", istat.overrun);
|
printf("input.status.overrun = %i\n", istat.overrun);
|
||||||
printf("output.status.queue = %i\n", ostat.queue);
|
printf("output.status.queue = %i\n", ostat.queue);
|
||||||
|
|
|
||||||
156
test/pcmtest.c
156
test/pcmtest.c
|
|
@ -4,144 +4,144 @@
|
||||||
|
|
||||||
void info_channel(snd_pcm_t *handle, int channel, char *id)
|
void info_channel(snd_pcm_t *handle, int channel, char *id)
|
||||||
{
|
{
|
||||||
snd_pcm_channel_info_t chninfo;
|
snd_pcm_stream_info_t stream_info;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
bzero(&chninfo, sizeof(chninfo));
|
bzero(&stream_info, sizeof(stream_info));
|
||||||
chninfo.channel = channel;
|
stream_info.channel = channel;
|
||||||
if ((err = snd_pcm_channel_info(handle, &chninfo))<0) {
|
if ((err = snd_pcm_stream_info(handle, &stream_info))<0) {
|
||||||
fprintf(stderr, "channel info error: %s\n", snd_strerror(err));
|
fprintf(stderr, "channel info error: %s\n", snd_strerror(err));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
printf("%s INFO:\n", id);
|
printf("%s INFO:\n", id);
|
||||||
printf(" subdevice : %i\n", chninfo.subdevice);
|
printf(" subdevice : %i\n", stream_info.subdevice);
|
||||||
printf(" subname : '%s'\n", chninfo.subname);
|
printf(" subname : '%s'\n", stream_info.subname);
|
||||||
printf(" channel : %i\n", chninfo.channel);
|
printf(" channel : %i\n", stream_info.channel);
|
||||||
printf(" mode : ");
|
printf(" mode : ");
|
||||||
switch (chninfo.mode) {
|
switch (stream_info.mode) {
|
||||||
case SND_PCM_MODE_STREAM:
|
case SND_PCM_MODE_FRAME:
|
||||||
printf("stream\n");
|
printf("frame\n");
|
||||||
break;
|
break;
|
||||||
case SND_PCM_MODE_BLOCK:
|
case SND_PCM_MODE_FRAGMENT:
|
||||||
printf("block\n");
|
printf("fragment\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
printf("unknown\n");
|
printf("unknown\n");
|
||||||
}
|
}
|
||||||
printf(" sync : 0x%x, 0x%x, 0x%x, 0x%x\n",
|
printf(" sync : 0x%x, 0x%x, 0x%x, 0x%x\n",
|
||||||
chninfo.sync.id32[0],
|
stream_info.sync.id32[0],
|
||||||
chninfo.sync.id32[1],
|
stream_info.sync.id32[1],
|
||||||
chninfo.sync.id32[2],
|
stream_info.sync.id32[2],
|
||||||
chninfo.sync.id32[3]);
|
stream_info.sync.id32[3]);
|
||||||
printf(" flags :");
|
printf(" flags :");
|
||||||
if (chninfo.flags & SND_PCM_CHNINFO_MMAP)
|
if (stream_info.flags & SND_PCM_STREAM_INFO_MMAP)
|
||||||
printf(" mmap");
|
printf(" mmap");
|
||||||
if (chninfo.flags & SND_PCM_CHNINFO_STREAM)
|
if (stream_info.flags & SND_PCM_STREAM_INFO_FRAME)
|
||||||
printf(" stream");
|
printf(" frame");
|
||||||
if (chninfo.flags & SND_PCM_CHNINFO_BLOCK)
|
if (stream_info.flags & SND_PCM_STREAM_INFO_FRAGMENT)
|
||||||
printf(" block");
|
printf(" fragment");
|
||||||
if (chninfo.flags & SND_PCM_CHNINFO_BATCH)
|
if (stream_info.flags & SND_PCM_STREAM_INFO_BATCH)
|
||||||
printf(" batch");
|
printf(" batch");
|
||||||
if (chninfo.flags & SND_PCM_CHNINFO_INTERLEAVE)
|
if (stream_info.flags & SND_PCM_STREAM_INFO_INTERLEAVE)
|
||||||
printf(" interleave");
|
printf(" interleave");
|
||||||
if (chninfo.flags & SND_PCM_CHNINFO_NONINTERLEAVE)
|
if (stream_info.flags & SND_PCM_STREAM_INFO_NONINTERLEAVE)
|
||||||
printf(" noninterleave");
|
printf(" noninterleave");
|
||||||
if (chninfo.flags & SND_PCM_CHNINFO_BLOCK_TRANSFER)
|
if (stream_info.flags & SND_PCM_STREAM_INFO_BLOCK_TRANSFER)
|
||||||
printf(" block_transfer");
|
printf(" block_transfer");
|
||||||
if (chninfo.flags & SND_PCM_CHNINFO_OVERRANGE)
|
if (stream_info.flags & SND_PCM_STREAM_INFO_OVERRANGE)
|
||||||
printf(" overrange");
|
printf(" overrange");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf(" formats :");
|
printf(" formats :");
|
||||||
if (chninfo.formats & SND_PCM_FMT_MU_LAW)
|
if (stream_info.formats & SND_PCM_FMT_MU_LAW)
|
||||||
printf(" mu-Law");
|
printf(" mu-Law");
|
||||||
if (chninfo.formats & SND_PCM_FMT_A_LAW)
|
if (stream_info.formats & SND_PCM_FMT_A_LAW)
|
||||||
printf(" a-Law");
|
printf(" a-Law");
|
||||||
if (chninfo.formats & SND_PCM_FMT_IMA_ADPCM)
|
if (stream_info.formats & SND_PCM_FMT_IMA_ADPCM)
|
||||||
printf(" IMA-ADPCM");
|
printf(" IMA-ADPCM");
|
||||||
if (chninfo.formats & SND_PCM_FMT_U8)
|
if (stream_info.formats & SND_PCM_FMT_U8)
|
||||||
printf(" U8");
|
printf(" U8");
|
||||||
if (chninfo.formats & SND_PCM_FMT_S16_LE)
|
if (stream_info.formats & SND_PCM_FMT_S16_LE)
|
||||||
printf(" S16-LE");
|
printf(" S16-LE");
|
||||||
if (chninfo.formats & SND_PCM_FMT_S16_BE)
|
if (stream_info.formats & SND_PCM_FMT_S16_BE)
|
||||||
printf(" S16-BE");
|
printf(" S16-BE");
|
||||||
if (chninfo.formats & SND_PCM_FMT_S8)
|
if (stream_info.formats & SND_PCM_FMT_S8)
|
||||||
printf(" S8");
|
printf(" S8");
|
||||||
if (chninfo.formats & SND_PCM_FMT_U16_LE)
|
if (stream_info.formats & SND_PCM_FMT_U16_LE)
|
||||||
printf(" U16-LE");
|
printf(" U16-LE");
|
||||||
if (chninfo.formats & SND_PCM_FMT_U16_BE)
|
if (stream_info.formats & SND_PCM_FMT_U16_BE)
|
||||||
printf(" U16-BE");
|
printf(" U16-BE");
|
||||||
if (chninfo.formats & SND_PCM_FMT_MPEG)
|
if (stream_info.formats & SND_PCM_FMT_MPEG)
|
||||||
printf(" MPEG");
|
printf(" MPEG");
|
||||||
if (chninfo.formats & SND_PCM_FMT_GSM)
|
if (stream_info.formats & SND_PCM_FMT_GSM)
|
||||||
printf(" GSM");
|
printf(" GSM");
|
||||||
if (chninfo.formats & SND_PCM_FMT_S24_LE)
|
if (stream_info.formats & SND_PCM_FMT_S24_LE)
|
||||||
printf(" S24-LE");
|
printf(" S24-LE");
|
||||||
if (chninfo.formats & SND_PCM_FMT_S24_BE)
|
if (stream_info.formats & SND_PCM_FMT_S24_BE)
|
||||||
printf(" S24-BE");
|
printf(" S24-BE");
|
||||||
if (chninfo.formats & SND_PCM_FMT_U24_LE)
|
if (stream_info.formats & SND_PCM_FMT_U24_LE)
|
||||||
printf(" U24-LE");
|
printf(" U24-LE");
|
||||||
if (chninfo.formats & SND_PCM_FMT_U24_BE)
|
if (stream_info.formats & SND_PCM_FMT_U24_BE)
|
||||||
printf(" U24-BE");
|
printf(" U24-BE");
|
||||||
if (chninfo.formats & SND_PCM_FMT_S32_LE)
|
if (stream_info.formats & SND_PCM_FMT_S32_LE)
|
||||||
printf(" S32-LE");
|
printf(" S32-LE");
|
||||||
if (chninfo.formats & SND_PCM_FMT_S32_BE)
|
if (stream_info.formats & SND_PCM_FMT_S32_BE)
|
||||||
printf(" S32-BE");
|
printf(" S32-BE");
|
||||||
if (chninfo.formats & SND_PCM_FMT_U32_LE)
|
if (stream_info.formats & SND_PCM_FMT_U32_LE)
|
||||||
printf(" U32-LE");
|
printf(" U32-LE");
|
||||||
if (chninfo.formats & SND_PCM_FMT_U32_BE)
|
if (stream_info.formats & SND_PCM_FMT_U32_BE)
|
||||||
printf(" U32-BE");
|
printf(" U32-BE");
|
||||||
if (chninfo.formats & SND_PCM_FMT_FLOAT)
|
if (stream_info.formats & SND_PCM_FMT_FLOAT)
|
||||||
printf(" Float");
|
printf(" Float");
|
||||||
if (chninfo.formats & SND_PCM_FMT_FLOAT64)
|
if (stream_info.formats & SND_PCM_FMT_FLOAT64)
|
||||||
printf(" Float64");
|
printf(" Float64");
|
||||||
if (chninfo.formats & SND_PCM_FMT_IEC958_SUBFRAME_LE)
|
if (stream_info.formats & SND_PCM_FMT_IEC958_SUBFRAME_LE)
|
||||||
printf(" IEC958-LE");
|
printf(" IEC958-LE");
|
||||||
if (chninfo.formats & SND_PCM_FMT_IEC958_SUBFRAME_BE)
|
if (stream_info.formats & SND_PCM_FMT_IEC958_SUBFRAME_BE)
|
||||||
printf(" IEC958-BE");
|
printf(" IEC958-BE");
|
||||||
if (chninfo.formats & SND_PCM_FMT_SPECIAL)
|
if (stream_info.formats & SND_PCM_FMT_SPECIAL)
|
||||||
printf(" Special");
|
printf(" Special");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf(" rates :");
|
printf(" rates :");
|
||||||
if (chninfo.rates & SND_PCM_RATE_CONTINUOUS)
|
if (stream_info.rates & SND_PCM_RATE_CONTINUOUS)
|
||||||
printf(" Continuous");
|
printf(" Continuous");
|
||||||
if (chninfo.rates & SND_PCM_RATE_KNOT)
|
if (stream_info.rates & SND_PCM_RATE_KNOT)
|
||||||
printf(" Knot");
|
printf(" Knot");
|
||||||
if (chninfo.rates & SND_PCM_RATE_8000)
|
if (stream_info.rates & SND_PCM_RATE_8000)
|
||||||
printf(" 8000");
|
printf(" 8000");
|
||||||
if (chninfo.rates & SND_PCM_RATE_11025)
|
if (stream_info.rates & SND_PCM_RATE_11025)
|
||||||
printf(" 11025");
|
printf(" 11025");
|
||||||
if (chninfo.rates & SND_PCM_RATE_16000)
|
if (stream_info.rates & SND_PCM_RATE_16000)
|
||||||
printf(" 16000");
|
printf(" 16000");
|
||||||
if (chninfo.rates & SND_PCM_RATE_22050)
|
if (stream_info.rates & SND_PCM_RATE_22050)
|
||||||
printf(" 22050");
|
printf(" 22050");
|
||||||
if (chninfo.rates & SND_PCM_RATE_32000)
|
if (stream_info.rates & SND_PCM_RATE_32000)
|
||||||
printf(" 32000");
|
printf(" 32000");
|
||||||
if (chninfo.rates & SND_PCM_RATE_44100)
|
if (stream_info.rates & SND_PCM_RATE_44100)
|
||||||
printf(" 44100");
|
printf(" 44100");
|
||||||
if (chninfo.rates & SND_PCM_RATE_48000)
|
if (stream_info.rates & SND_PCM_RATE_48000)
|
||||||
printf(" 48000");
|
printf(" 48000");
|
||||||
if (chninfo.rates & SND_PCM_RATE_88200)
|
if (stream_info.rates & SND_PCM_RATE_88200)
|
||||||
printf(" 88200");
|
printf(" 88200");
|
||||||
if (chninfo.rates & SND_PCM_RATE_96000)
|
if (stream_info.rates & SND_PCM_RATE_96000)
|
||||||
printf(" 96000");
|
printf(" 96000");
|
||||||
if (chninfo.rates & SND_PCM_RATE_176400)
|
if (stream_info.rates & SND_PCM_RATE_176400)
|
||||||
printf(" 176400");
|
printf(" 176400");
|
||||||
if (chninfo.rates & SND_PCM_RATE_192000)
|
if (stream_info.rates & SND_PCM_RATE_192000)
|
||||||
printf(" 192000");
|
printf(" 192000");
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf(" min_rate : %i\n", chninfo.min_rate);
|
printf(" min_rate : %i\n", stream_info.min_rate);
|
||||||
printf(" max_rate : %i\n", chninfo.max_rate);
|
printf(" max_rate : %i\n", stream_info.max_rate);
|
||||||
printf(" min_voices : %i\n", chninfo.min_voices);
|
printf(" min_channels : %i\n", stream_info.min_channels);
|
||||||
printf(" max_voices : %i\n", chninfo.max_voices);
|
printf(" max_channels : %i\n", stream_info.max_channels);
|
||||||
printf(" buffer_size : %i\n", chninfo.buffer_size);
|
printf(" buffer_size : %i\n", stream_info.buffer_size);
|
||||||
printf(" min_frag_size : %i\n", chninfo.min_fragment_size);
|
printf(" min_frag_size : %i\n", stream_info.min_fragment_size);
|
||||||
printf(" max_frag_size : %i\n", chninfo.max_fragment_size);
|
printf(" max_frag_size : %i\n", stream_info.max_fragment_size);
|
||||||
printf(" fragment_align : %i\n", chninfo.fragment_align);
|
printf(" fragment_align : %i\n", stream_info.fragment_align);
|
||||||
printf(" fifo_size : %i\n", chninfo.fifo_size);
|
printf(" fifo_size : %i\n", stream_info.fifo_size);
|
||||||
printf(" TBS : %i\n", chninfo.transfer_block_size);
|
printf(" TBS : %i\n", stream_info.transfer_block_size);
|
||||||
printf(" mmap_size : %li\n", chninfo.mmap_size);
|
printf(" mmap_size : %li\n", stream_info.mmap_size);
|
||||||
printf(" mixer_device : %i\n", chninfo.mixer_device);
|
printf(" mixer_device : %i\n", stream_info.mixer_device);
|
||||||
printf(" mixer_eid : '%s',%i,%i\n", chninfo.mixer_eid.name, chninfo.mixer_eid.index, chninfo.mixer_eid.type);
|
printf(" mixer_eid : '%s',%i,%i\n", stream_info.mixer_eid.name, stream_info.mixer_eid.index, stream_info.mixer_eid.type);
|
||||||
}
|
}
|
||||||
|
|
||||||
void info(void)
|
void info(void)
|
||||||
|
|
@ -166,9 +166,9 @@ void info(void)
|
||||||
printf(" playback : %i\n", info.playback);
|
printf(" playback : %i\n", info.playback);
|
||||||
printf(" capture : %i\n", info.capture);
|
printf(" capture : %i\n", info.capture);
|
||||||
if (info.flags & SND_PCM_INFO_PLAYBACK)
|
if (info.flags & SND_PCM_INFO_PLAYBACK)
|
||||||
info_channel(handle, SND_PCM_CHANNEL_PLAYBACK, "Playback");
|
info_channel(handle, SND_PCM_STREAM_PLAYBACK, "Playback");
|
||||||
if (info.flags & SND_PCM_INFO_CAPTURE)
|
if (info.flags & SND_PCM_INFO_CAPTURE)
|
||||||
info_channel(handle, SND_PCM_CHANNEL_CAPTURE, "Capture");
|
info_channel(handle, SND_PCM_STREAM_CAPTURE, "Capture");
|
||||||
snd_pcm_close(handle);
|
snd_pcm_close(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ void print_switch(snd_ctl_t *ctl_handle, char *space, char *prefix, snd_switch_t
|
||||||
sw1.type = SND_SW_TYPE_LIST_ITEM;
|
sw1.type = SND_SW_TYPE_LIST_ITEM;
|
||||||
sw1.low = sw1.high = low;
|
sw1.low = sw1.high = low;
|
||||||
if ((err = snd_ctl_switch_read(ctl_handle, &sw1)) < 0) {
|
if ((err = snd_ctl_switch_read(ctl_handle, &sw1)) < 0) {
|
||||||
printf("Switch list item read failed for %s interface and device %i channel %i: %s\n", get_interface(sw->iface), sw->device, sw->channel, snd_strerror(err));
|
printf("Switch list item read failed for %s interface and device %i stream %i: %s\n", get_interface(sw->iface), sw->device, sw->stream, snd_strerror(err));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
printf(" %s%s : '%s' [%s] {%s}\n", space, prefix, sw1.name, get_type(sw1.type), sw1.value.item);
|
printf(" %s%s : '%s' [%s] {%s}\n", space, prefix, sw1.name, get_type(sw1.type), sw1.value.item);
|
||||||
|
|
@ -62,7 +62,7 @@ void print_switch(snd_ctl_t *ctl_handle, char *space, char *prefix, snd_switch_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void process(snd_ctl_t *ctl_handle, char *space, char *prefix, int iface, int device, int channel)
|
void process(snd_ctl_t *ctl_handle, char *space, char *prefix, int iface, int device, int stream)
|
||||||
{
|
{
|
||||||
snd_switch_list_t list;
|
snd_switch_list_t list;
|
||||||
snd_switch_t sw;
|
snd_switch_t sw;
|
||||||
|
|
@ -71,7 +71,7 @@ void process(snd_ctl_t *ctl_handle, char *space, char *prefix, int iface, int de
|
||||||
bzero(&list, sizeof(list));
|
bzero(&list, sizeof(list));
|
||||||
list.iface = iface;
|
list.iface = iface;
|
||||||
list.device = device;
|
list.device = device;
|
||||||
list.channel = channel;
|
list.stream = stream;
|
||||||
if ((err = snd_ctl_switch_list(ctl_handle, &list)) < 0) {
|
if ((err = snd_ctl_switch_list(ctl_handle, &list)) < 0) {
|
||||||
printf("Switch listing failed for the %s interface and the device %i: %s\n", get_interface(iface), device, snd_strerror(err));
|
printf("Switch listing failed for the %s interface and the device %i: %s\n", get_interface(iface), device, snd_strerror(err));
|
||||||
return;
|
return;
|
||||||
|
|
@ -93,10 +93,10 @@ void process(snd_ctl_t *ctl_handle, char *space, char *prefix, int iface, int de
|
||||||
bzero(&sw, sizeof(sw));
|
bzero(&sw, sizeof(sw));
|
||||||
sw.iface = iface;
|
sw.iface = iface;
|
||||||
sw.device = device;
|
sw.device = device;
|
||||||
sw.channel = channel;
|
sw.stream = stream;
|
||||||
strncpy(sw.name, list.pswitches[idx].name, sizeof(sw.name));
|
strncpy(sw.name, list.pswitches[idx].name, sizeof(sw.name));
|
||||||
if ((err = snd_ctl_switch_read(ctl_handle, &sw)) < 0) {
|
if ((err = snd_ctl_switch_read(ctl_handle, &sw)) < 0) {
|
||||||
printf("Switch read failed for the %s interface and the device %i channel %i: %s\n", get_interface(iface), device, channel, snd_strerror(err));
|
printf("Switch read failed for the %s interface and the device %i stream %i: %s\n", get_interface(iface), device, stream, snd_strerror(err));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
print_switch(ctl_handle, space, prefix, &sw);
|
print_switch(ctl_handle, space, prefix, &sw);
|
||||||
|
|
@ -131,8 +131,8 @@ int main(void)
|
||||||
for (idx = 0; idx < info.mixerdevs; idx++)
|
for (idx = 0; idx < info.mixerdevs; idx++)
|
||||||
process(ctl_handle, " ", "Mixer", SND_CTL_IFACE_MIXER, idx, 0);
|
process(ctl_handle, " ", "Mixer", SND_CTL_IFACE_MIXER, idx, 0);
|
||||||
for (idx = 0; idx < info.pcmdevs; idx++) {
|
for (idx = 0; idx < info.pcmdevs; idx++) {
|
||||||
process(ctl_handle, " ", "PCM playback", SND_CTL_IFACE_PCM, idx, SND_PCM_CHANNEL_PLAYBACK);
|
process(ctl_handle, " ", "PCM playback", SND_CTL_IFACE_PCM, idx, SND_PCM_STREAM_PLAYBACK);
|
||||||
process(ctl_handle, " ", "PCM capture", SND_CTL_IFACE_PCM, idx, SND_PCM_CHANNEL_CAPTURE);
|
process(ctl_handle, " ", "PCM capture", SND_CTL_IFACE_PCM, idx, SND_PCM_STREAM_CAPTURE);
|
||||||
}
|
}
|
||||||
snd_ctl_close(ctl_handle);
|
snd_ctl_close(ctl_handle);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue