mirror of
				https://github.com/alsa-project/alsa-lib.git
				synced 2025-11-03 09:01:52 -05:00 
			
		
		
		
	Completed linear plugin
This commit is contained in:
		
							parent
							
								
									cde18e13bc
								
							
						
					
					
						commit
						8738da23d8
					
				
					 2 changed files with 265 additions and 306 deletions
				
			
		| 
						 | 
					@ -101,114 +101,98 @@ ssize_t snd_pcm_plugin_hardware_size(PLUGIN_BASE *pb, int channel, size_t trf_si
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned int snd_pcm_plugin_formats(unsigned int formats)
 | 
					unsigned int snd_pcm_plugin_formats(unsigned int formats)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						int linfmts = (SND_PCM_FMT_U8 | SND_PCM_FMT_S8 |
 | 
				
			||||||
 | 
							       SND_PCM_FMT_U16_LE | SND_PCM_FMT_S16_LE |
 | 
				
			||||||
 | 
							       SND_PCM_FMT_U16_BE | SND_PCM_FMT_S16_BE |
 | 
				
			||||||
 | 
							       SND_PCM_FMT_U24_LE | SND_PCM_FMT_S16_LE |
 | 
				
			||||||
 | 
							       SND_PCM_FMT_U24_BE | SND_PCM_FMT_S16_BE |
 | 
				
			||||||
 | 
							       SND_PCM_FMT_U32_LE | SND_PCM_FMT_S32_LE |
 | 
				
			||||||
 | 
							       SND_PCM_FMT_U32_BE | SND_PCM_FMT_S32_BE);
 | 
				
			||||||
	formats |= SND_PCM_FMT_MU_LAW;
 | 
						formats |= SND_PCM_FMT_MU_LAW;
 | 
				
			||||||
#ifndef __KERNEL__
 | 
					#ifndef __KERNEL__
 | 
				
			||||||
	formats |= SND_PCM_FMT_A_LAW | SND_PCM_FMT_IMA_ADPCM;
 | 
						formats |= SND_PCM_FMT_A_LAW | SND_PCM_FMT_IMA_ADPCM;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	if (formats & (SND_PCM_FMT_U8|SND_PCM_FMT_S8|
 | 
						
 | 
				
			||||||
		       SND_PCM_FMT_U16_LE|SND_PCM_FMT_S16_LE))
 | 
						if (formats & linfmts)
 | 
				
			||||||
		formats |= SND_PCM_FMT_U8|SND_PCM_FMT_S8|
 | 
							formats |= linfmts;
 | 
				
			||||||
			   SND_PCM_FMT_U16_LE|SND_PCM_FMT_S16_LE;
 | 
					 | 
				
			||||||
	return formats;
 | 
						return formats;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int preferred_formats[] = {
 | 
				
			||||||
 | 
						SND_PCM_SFMT_S16_LE,
 | 
				
			||||||
 | 
						SND_PCM_SFMT_S16_BE,
 | 
				
			||||||
 | 
						SND_PCM_SFMT_U16_LE,
 | 
				
			||||||
 | 
						SND_PCM_SFMT_U16_BE,
 | 
				
			||||||
 | 
						SND_PCM_SFMT_S24_LE,
 | 
				
			||||||
 | 
						SND_PCM_SFMT_S24_BE,
 | 
				
			||||||
 | 
						SND_PCM_SFMT_U24_LE,
 | 
				
			||||||
 | 
						SND_PCM_SFMT_U24_BE,
 | 
				
			||||||
 | 
						SND_PCM_SFMT_S32_LE,
 | 
				
			||||||
 | 
						SND_PCM_SFMT_S32_BE,
 | 
				
			||||||
 | 
						SND_PCM_SFMT_U32_LE,
 | 
				
			||||||
 | 
						SND_PCM_SFMT_U32_BE,
 | 
				
			||||||
 | 
						SND_PCM_SFMT_S8,
 | 
				
			||||||
 | 
						SND_PCM_SFMT_U8
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int snd_pcm_plugin_hwparams(snd_pcm_channel_params_t *params,
 | 
					int snd_pcm_plugin_hwparams(snd_pcm_channel_params_t *params,
 | 
				
			||||||
			    snd_pcm_channel_info_t *hwinfo,
 | 
								    snd_pcm_channel_info_t *hwinfo,
 | 
				
			||||||
			    snd_pcm_channel_params_t *hwparams)
 | 
								    snd_pcm_channel_params_t *hwparams)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	memcpy(hwparams, params, sizeof(*hwparams));
 | 
						memcpy(hwparams, params, sizeof(*hwparams));
 | 
				
			||||||
	if ((hwinfo->formats & (1 << params->format.format)) == 0) {
 | 
						if ((hwinfo->formats & (1 << params->format.format)) == 0) {
 | 
				
			||||||
		if ((snd_pcm_plugin_formats(hwinfo->formats) & (1 << params->format.format)) == 0)
 | 
							int format = params->format.format;
 | 
				
			||||||
			return -EINVAL;
 | 
							if ((snd_pcm_plugin_formats(hwinfo->formats) & (1 << format)) == 0)
 | 
				
			||||||
		switch (params->format.format) {
 | 
					 | 
				
			||||||
		case SND_PCM_SFMT_U8:
 | 
					 | 
				
			||||||
			if (hwinfo->formats & SND_PCM_FMT_S8) {
 | 
					 | 
				
			||||||
				hwparams->format.format = SND_PCM_SFMT_S8;
 | 
					 | 
				
			||||||
			} else if (hwinfo->formats & SND_PCM_FMT_U16_LE) {
 | 
					 | 
				
			||||||
				hwparams->format.format = SND_PCM_SFMT_U16_LE;
 | 
					 | 
				
			||||||
			} else if (hwinfo->formats & SND_PCM_FMT_S16_LE) {
 | 
					 | 
				
			||||||
				hwparams->format.format = SND_PCM_SFMT_S16_LE;
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
			return -EINVAL;
 | 
								return -EINVAL;
 | 
				
			||||||
 | 
							if (snd_pcm_format_linear(format)) {
 | 
				
			||||||
 | 
								int width = snd_pcm_format_width(format);
 | 
				
			||||||
 | 
								int unsignd = snd_pcm_format_unsigned(format);
 | 
				
			||||||
 | 
								int big = snd_pcm_format_big_endian(format);
 | 
				
			||||||
 | 
								int format1;
 | 
				
			||||||
 | 
								int wid, width1=width;
 | 
				
			||||||
 | 
								for (wid = 0; wid < 4; ++wid) {
 | 
				
			||||||
 | 
									int end, big1 = big;
 | 
				
			||||||
 | 
									for (end = 0; end < 2; ++end) {
 | 
				
			||||||
 | 
										int sgn, unsignd1 = unsignd;
 | 
				
			||||||
 | 
										for (sgn = 0; sgn < 2; ++sgn) {
 | 
				
			||||||
 | 
											format1 = snd_pcm_build_linear_format(width1, unsignd1, big1);
 | 
				
			||||||
 | 
											if (format1 >= 0 &&
 | 
				
			||||||
 | 
											    hwinfo->formats & (1 << format1))
 | 
				
			||||||
 | 
												goto _found;
 | 
				
			||||||
 | 
											unsignd1 = !unsignd1;
 | 
				
			||||||
					}
 | 
										}
 | 
				
			||||||
			break;
 | 
										big1 = !big1;
 | 
				
			||||||
		case SND_PCM_SFMT_S8:
 | 
					 | 
				
			||||||
			if (hwinfo->formats & SND_PCM_FMT_U8) {
 | 
					 | 
				
			||||||
				hwparams->format.format = SND_PCM_SFMT_U8;
 | 
					 | 
				
			||||||
			} else if (hwinfo->formats & SND_PCM_FMT_S16_LE) {
 | 
					 | 
				
			||||||
				hwparams->format.format = SND_PCM_SFMT_S16_LE;
 | 
					 | 
				
			||||||
			} else if (hwinfo->formats & SND_PCM_FMT_U16_LE) {
 | 
					 | 
				
			||||||
				hwparams->format.format = SND_PCM_SFMT_U16_LE;
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				return -EINVAL;
 | 
					 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			break;
 | 
									width1 += 8;
 | 
				
			||||||
		case SND_PCM_SFMT_S16_LE:
 | 
									if (width1 > 32)
 | 
				
			||||||
			if (hwinfo->formats & SND_PCM_FMT_U16_LE) {
 | 
										width = 8;
 | 
				
			||||||
				hwparams->format.format = SND_PCM_SFMT_U16_LE;
 | 
					 | 
				
			||||||
			} else if (hwinfo->formats & SND_PCM_FMT_S8) {
 | 
					 | 
				
			||||||
				hwparams->format.format = SND_PCM_SFMT_S8;
 | 
					 | 
				
			||||||
			} else if (hwinfo->formats & SND_PCM_FMT_U8) {
 | 
					 | 
				
			||||||
				hwparams->format.format = SND_PCM_SFMT_U8;
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				return -EINVAL;
 | 
					 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case SND_PCM_SFMT_U16_LE:
 | 
					 | 
				
			||||||
			if (hwinfo->formats & SND_PCM_FMT_S16_LE) {
 | 
					 | 
				
			||||||
				hwparams->format.format = SND_PCM_SFMT_S16_LE;
 | 
					 | 
				
			||||||
			} else if (hwinfo->formats & SND_PCM_FMT_U8) {
 | 
					 | 
				
			||||||
				hwparams->format.format = SND_PCM_SFMT_U8;
 | 
					 | 
				
			||||||
			} else if (hwinfo->formats & SND_PCM_FMT_S8) {
 | 
					 | 
				
			||||||
				hwparams->format.format = SND_PCM_SFMT_S8;
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
			return -EINVAL;
 | 
								return -EINVAL;
 | 
				
			||||||
			}
 | 
							_found:
 | 
				
			||||||
			break;
 | 
								hwparams->format.format = format1;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								int i;
 | 
				
			||||||
 | 
								switch (format) {
 | 
				
			||||||
			case SND_PCM_SFMT_MU_LAW:
 | 
								case SND_PCM_SFMT_MU_LAW:
 | 
				
			||||||
			if (hwinfo->formats & SND_PCM_FMT_S16_LE) {
 | 
					 | 
				
			||||||
				hwparams->format.format = SND_PCM_SFMT_S16_LE;
 | 
					 | 
				
			||||||
			} else if (hwinfo->formats & SND_PCM_FMT_U16_LE) {
 | 
					 | 
				
			||||||
				hwparams->format.format = SND_PCM_SFMT_U16_LE;
 | 
					 | 
				
			||||||
			} else if (hwinfo->formats & SND_PCM_FMT_S8) {
 | 
					 | 
				
			||||||
				hwparams->format.format = SND_PCM_SFMT_S8;
 | 
					 | 
				
			||||||
			} else if (hwinfo->formats & SND_PCM_FMT_U8) {
 | 
					 | 
				
			||||||
				hwparams->format.format = SND_PCM_SFMT_U8;
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				return -EINVAL;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
#ifndef __KERNEL__
 | 
					#ifndef __KERNEL__
 | 
				
			||||||
			case SND_PCM_SFMT_A_LAW:
 | 
								case SND_PCM_SFMT_A_LAW:
 | 
				
			||||||
			if (hwinfo->formats & SND_PCM_FMT_S16_LE) {
 | 
					 | 
				
			||||||
				hwparams->format.format = SND_PCM_SFMT_S16_LE;
 | 
					 | 
				
			||||||
			} else if (hwinfo->formats & SND_PCM_FMT_U16_LE) {
 | 
					 | 
				
			||||||
				hwparams->format.format = SND_PCM_SFMT_U16_LE;
 | 
					 | 
				
			||||||
			} else if (hwinfo->formats & SND_PCM_FMT_S8) {
 | 
					 | 
				
			||||||
				hwparams->format.format = SND_PCM_SFMT_S8;
 | 
					 | 
				
			||||||
			} else if (hwinfo->formats & SND_PCM_FMT_U8) {
 | 
					 | 
				
			||||||
				hwparams->format.format = SND_PCM_SFMT_U8;
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				return -EINVAL;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			case SND_PCM_SFMT_IMA_ADPCM:
 | 
								case SND_PCM_SFMT_IMA_ADPCM:
 | 
				
			||||||
			if (hwinfo->formats & SND_PCM_FMT_S16_LE) {
 | 
					 | 
				
			||||||
				hwparams->format.format = SND_PCM_SFMT_S16_LE;
 | 
					 | 
				
			||||||
			} else if (hwinfo->formats & SND_PCM_FMT_U16_LE) {
 | 
					 | 
				
			||||||
				hwparams->format.format = SND_PCM_SFMT_U16_LE;
 | 
					 | 
				
			||||||
			} else if (hwinfo->formats & SND_PCM_FMT_S8) {
 | 
					 | 
				
			||||||
				hwparams->format.format = SND_PCM_SFMT_S8;
 | 
					 | 
				
			||||||
			} else if (hwinfo->formats & SND_PCM_FMT_U8) {
 | 
					 | 
				
			||||||
				hwparams->format.format = SND_PCM_SFMT_U8;
 | 
					 | 
				
			||||||
			} else {
 | 
					 | 
				
			||||||
				return -EINVAL;
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
									for (i = 0; i < sizeof(preferred_formats) / sizeof(preferred_formats[0]); ++i) {
 | 
				
			||||||
 | 
										int format1 = preferred_formats[i];
 | 
				
			||||||
 | 
										if (hwinfo->formats & (1 << format1)) {
 | 
				
			||||||
 | 
											hwparams->format.format = format1;
 | 
				
			||||||
 | 
											break;
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
									if (i == sizeof(preferred_formats)/sizeof(preferred_formats[0]))
 | 
				
			||||||
 | 
										return -EINVAL;
 | 
				
			||||||
 | 
									break;
 | 
				
			||||||
			default:
 | 
								default:
 | 
				
			||||||
				return -EINVAL;
 | 
									return -EINVAL;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* voices */
 | 
						/* voices */
 | 
				
			||||||
      	if (params->format.voices < hwinfo->min_voices ||
 | 
					      	if (params->format.voices < hwinfo->min_voices ||
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,6 +23,8 @@
 | 
				
			||||||
#include "../../include/driver.h"
 | 
					#include "../../include/driver.h"
 | 
				
			||||||
#include "../../include/pcm.h"
 | 
					#include "../../include/pcm.h"
 | 
				
			||||||
#include "../../include/pcm_plugin.h"
 | 
					#include "../../include/pcm_plugin.h"
 | 
				
			||||||
 | 
					#define bswap_16(x) __swab16((x))
 | 
				
			||||||
 | 
					#define bswap_32(x) __swab32((x))
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
| 
						 | 
					@ -38,101 +40,152 @@
 | 
				
			||||||
 *  Basic linear conversion plugin
 | 
					 *  Basic linear conversion plugin
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 
 | 
					 
 | 
				
			||||||
typedef enum {
 | 
					typedef void (*conv_f)(void *src, void *dst, size_t size);
 | 
				
			||||||
	_8BIT_16BIT,
 | 
					 | 
				
			||||||
	_8BIT_24BIT,
 | 
					 | 
				
			||||||
	_8BIT_32BIT,
 | 
					 | 
				
			||||||
	_16BIT_8BIT,
 | 
					 | 
				
			||||||
	_16BIT_24BIT,
 | 
					 | 
				
			||||||
	_16BIT_32BIT,
 | 
					 | 
				
			||||||
	_24BIT_8BIT,
 | 
					 | 
				
			||||||
	_24BIT_16BIT,
 | 
					 | 
				
			||||||
	_24BIT_32BIT,
 | 
					 | 
				
			||||||
	_32BIT_8BIT,
 | 
					 | 
				
			||||||
	_32BIT_16BIT,
 | 
					 | 
				
			||||||
	_32BIT_24BIT
 | 
					 | 
				
			||||||
} combination_t;
 | 
					 | 
				
			||||||
 
 | 
					 | 
				
			||||||
typedef enum {
 | 
					 | 
				
			||||||
	NONE = 0,
 | 
					 | 
				
			||||||
	SOURCE = 1,
 | 
					 | 
				
			||||||
	DESTINATION = 2,
 | 
					 | 
				
			||||||
	BOTH = 3,
 | 
					 | 
				
			||||||
	SIGN = 4,
 | 
					 | 
				
			||||||
	SIGN_NONE = 4,
 | 
					 | 
				
			||||||
	SIGN_SOURCE = 5,
 | 
					 | 
				
			||||||
	SIGN_DESTINATION = 6,
 | 
					 | 
				
			||||||
	SIGN_BOTH = 7,
 | 
					 | 
				
			||||||
} endian_t;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct linear_private_data {
 | 
					struct linear_private_data {
 | 
				
			||||||
	combination_t cmd;
 | 
						int src_sample_size, dst_sample_size;
 | 
				
			||||||
	endian_t endian;
 | 
						conv_f func;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void linear_conv_8bit_16bit(unsigned char *src_ptr,
 | 
					#define CONV_FUNC(name, srctype, dsttype, val) \
 | 
				
			||||||
				   unsigned short *dst_ptr,
 | 
					static void conv_##name(void *src_ptr, void *dst_ptr, size_t size) \
 | 
				
			||||||
				   size_t size)
 | 
					{ \
 | 
				
			||||||
{
 | 
						unsigned srctype *srcp = src_ptr; \
 | 
				
			||||||
	while (size--)
 | 
						unsigned dsttype *dstp = dst_ptr; \
 | 
				
			||||||
		*dst_ptr++ = ((unsigned short)*src_ptr++) << 8;
 | 
						while (size--) { \
 | 
				
			||||||
 | 
							unsigned srctype src = *srcp++; \
 | 
				
			||||||
 | 
							*dstp++ = val; \
 | 
				
			||||||
 | 
						} \
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void linear_conv_8bit_16bit_swap(unsigned char *src_ptr,
 | 
					CONV_FUNC(8_sign, char, char, src ^ 0x80)
 | 
				
			||||||
					unsigned short *dst_ptr,
 | 
					 | 
				
			||||||
					size_t size)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	while (size--)
 | 
					 | 
				
			||||||
		*dst_ptr++ = (unsigned short)*src_ptr++;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void linear_conv_sign_8bit_16bit(unsigned char *src_ptr,
 | 
					CONV_FUNC(8_16, char, short, (unsigned short)src << 8)
 | 
				
			||||||
					unsigned short *dst_ptr,
 | 
					CONV_FUNC(8_16_end, char, short, (unsigned short)src)
 | 
				
			||||||
					size_t size)
 | 
					CONV_FUNC(8_16_sign, char, short, (unsigned short)(src ^ 0x80) << 8)
 | 
				
			||||||
{
 | 
					CONV_FUNC(8_16_sign_end, char, short, (unsigned short)src ^ 0x80)
 | 
				
			||||||
	while (size--)
 | 
					 | 
				
			||||||
		*dst_ptr++ = (((unsigned short)*src_ptr++) << 8) ^ 0x8000;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void linear_conv_sign_8bit_16bit_swap(unsigned char *src_ptr,
 | 
					CONV_FUNC(8_32, char, long, (unsigned long)src << 24)
 | 
				
			||||||
					     unsigned short *dst_ptr,
 | 
					CONV_FUNC(8_32_end, char, long, (unsigned long)src)
 | 
				
			||||||
					     size_t size)
 | 
					CONV_FUNC(8_32_sign, char, long, (unsigned long)(src ^ 0x80) << 24)
 | 
				
			||||||
{
 | 
					CONV_FUNC(8_32_sign_end, char, long, (unsigned long)src ^ 0x80)
 | 
				
			||||||
	while (size--)
 | 
					 | 
				
			||||||
		*dst_ptr++ = ((unsigned short)*src_ptr++) ^ 0x80;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void linear_conv_16bit_8bit(unsigned short *src_ptr,
 | 
					CONV_FUNC(16_8, short, char, src >> 8)
 | 
				
			||||||
				   unsigned char *dst_ptr,
 | 
					CONV_FUNC(16_end_8, short, char, src)
 | 
				
			||||||
				   size_t size)
 | 
					CONV_FUNC(16_8_sign, short, char, (src >> 8) ^ 0x80)
 | 
				
			||||||
{
 | 
					CONV_FUNC(16_end_8_sign, short, char, src ^ 0x80;)
 | 
				
			||||||
	while (size--)
 | 
					 | 
				
			||||||
		*dst_ptr++ = (*src_ptr++) >> 8;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void linear_conv_16bit_8bit_swap(unsigned short *src_ptr,
 | 
					CONV_FUNC(16_sign, short, short, src ^ 0x8000)
 | 
				
			||||||
					unsigned char *dst_ptr,
 | 
					CONV_FUNC(16_end, short, short, bswap_16(src))
 | 
				
			||||||
					size_t size)
 | 
					CONV_FUNC(16_end_sign, short, short, bswap_16(src) ^ 0x8000)
 | 
				
			||||||
{
 | 
					CONV_FUNC(16_sign_end, short, short, bswap_16(src ^ 0x8000))
 | 
				
			||||||
	while (size--)
 | 
					CONV_FUNC(16_end_sign_end, short, short, src ^ 0x80)
 | 
				
			||||||
		*dst_ptr++ = (unsigned char)*src_ptr++;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void linear_conv_sign_16bit_8bit(unsigned short *src_ptr,
 | 
					CONV_FUNC(16_32, short, long, (unsigned long)src << 16)
 | 
				
			||||||
					unsigned char *dst_ptr,
 | 
					CONV_FUNC(16_32_sign, short, long, (unsigned long)(src ^ 0x8000) << 16)
 | 
				
			||||||
					size_t size)
 | 
					CONV_FUNC(16_32_end, short, long, (unsigned long)bswap_16(src))
 | 
				
			||||||
{
 | 
					CONV_FUNC(16_32_sign_end, short, long, (unsigned long)bswap_16(src ^ 0x8000))
 | 
				
			||||||
	while (size--)
 | 
					CONV_FUNC(16_end_32, short, long, (unsigned long)bswap_16(src) << 16)
 | 
				
			||||||
		*dst_ptr++ = (((unsigned short)*src_ptr++) >> 8) ^ 0x80;
 | 
					CONV_FUNC(16_end_32_sign, short, long, (unsigned long)(bswap_16(src) ^ 0x8000) << 16)
 | 
				
			||||||
}
 | 
					CONV_FUNC(16_end_32_end, short, long, (unsigned long)src)
 | 
				
			||||||
 | 
					CONV_FUNC(16_end_32_sign_end, short, long, (unsigned long)src ^ 0x80)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CONV_FUNC(32_8, long, char, src >> 24)
 | 
				
			||||||
 | 
					CONV_FUNC(32_end_8, long, char, src)
 | 
				
			||||||
 | 
					CONV_FUNC(32_8_sign, long, char, (src >> 24) ^ 0x80)
 | 
				
			||||||
 | 
					CONV_FUNC(32_end_8_sign, long, char, src ^ 0x80;)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CONV_FUNC(32_16, long, short, src >> 16)
 | 
				
			||||||
 | 
					CONV_FUNC(32_16_sign, long, short, (src >> 16) ^ 0x8000)
 | 
				
			||||||
 | 
					CONV_FUNC(32_16_end, long, short, bswap_16(src >> 16))
 | 
				
			||||||
 | 
					CONV_FUNC(32_16_sign_end, long, short, bswap_16((src >> 16) ^ 0x8000))
 | 
				
			||||||
 | 
					CONV_FUNC(32_end_16, long, short, bswap_16(src))
 | 
				
			||||||
 | 
					CONV_FUNC(32_end_16_sign, long, short, bswap_16(src) ^ 0x8000)
 | 
				
			||||||
 | 
					CONV_FUNC(32_end_16_end, long, short, src)
 | 
				
			||||||
 | 
					CONV_FUNC(32_end_16_sign_end, long, short, src ^ 0x80)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					CONV_FUNC(32_sign, long, long, src ^ 0x80000000)
 | 
				
			||||||
 | 
					CONV_FUNC(32_end, long, long, bswap_32(src))
 | 
				
			||||||
 | 
					CONV_FUNC(32_end_sign, long, long, bswap_32(src) ^ 0x80000000)
 | 
				
			||||||
 | 
					CONV_FUNC(32_sign_end, long, long, bswap_32(src) ^ 0x80)
 | 
				
			||||||
 | 
					CONV_FUNC(32_end_sign_end, long, long, src ^ 0x80)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* src_wid dst_wid src_endswap, dst_endswap, sign_swap */
 | 
				
			||||||
 | 
					conv_f convert_functions[3][3][2][2][2] = {
 | 
				
			||||||
 | 
						NULL,			/* 8->8: Nothing to do */
 | 
				
			||||||
 | 
						conv_8_sign,		/* 8->8 sign: conv_8_sign */
 | 
				
			||||||
 | 
						NULL,			/* 8->8 dst_end: Nothing to do */
 | 
				
			||||||
 | 
						conv_8_sign,		/* 8->8 dst_end sign: conv_8_sign */
 | 
				
			||||||
 | 
						NULL,			/* 8->8 src_end: Nothing to do */
 | 
				
			||||||
 | 
						conv_8_sign,		/* 8->8 src_end sign: conv_8_sign */
 | 
				
			||||||
 | 
						NULL,			/* 8->8 src_end dst_end: Nothing to do */
 | 
				
			||||||
 | 
						conv_8_sign,		/* 8->8 src_end dst_end sign: conv_8_sign */
 | 
				
			||||||
 | 
						conv_8_16,		/* 8->16: conv_8_16 */
 | 
				
			||||||
 | 
						conv_8_16_sign,		/* 8->16 sign: conv_8_16_sign */
 | 
				
			||||||
 | 
						conv_8_16_end,		/* 8->16 dst_end: conv_8_16_end */
 | 
				
			||||||
 | 
						conv_8_16_sign_end,	/* 8->16 dst_end sign: conv_8_16_sign_end */
 | 
				
			||||||
 | 
						conv_8_16,		/* 8->16 src_end: conv_8_16 */
 | 
				
			||||||
 | 
						conv_8_16_sign,		/* 8->16 src_end sign: conv_8_16_sign */
 | 
				
			||||||
 | 
						conv_8_16_end,		/* 8->16 src_end dst_end: conv_8_16_end */
 | 
				
			||||||
 | 
						conv_8_16_sign_end,	/* 8->16 src_end dst_end sign: conv_8_16_sign_end */
 | 
				
			||||||
 | 
						conv_8_32,			/* 8->32: conv_8_32 */
 | 
				
			||||||
 | 
						conv_8_32_sign,			/* 8->32 sign: conv_8_32_sign */
 | 
				
			||||||
 | 
						conv_8_32_end,			/* 8->32 dst_end: conv_8_32_end */
 | 
				
			||||||
 | 
						conv_8_32_sign_end,			/* 8->32 dst_end sign: conv_8_32_sign_end */
 | 
				
			||||||
 | 
						conv_8_32,			/* 8->32 src_end: conv_8_32 */
 | 
				
			||||||
 | 
						conv_8_32_sign,			/* 8->32 src_end sign: conv_8_32_sign */
 | 
				
			||||||
 | 
						conv_8_32_end,			/* 8->32 src_end dst_end: conv_8_32_end */
 | 
				
			||||||
 | 
						conv_8_32_sign_end,			/* 8->32 src_end dst_end sign: conv_8_32_sign_end */
 | 
				
			||||||
 | 
						conv_16_8,		/* 16->8: conv_16_8 */
 | 
				
			||||||
 | 
						conv_16_8_sign,		/* 16->8 sign: conv_16_8_sign */
 | 
				
			||||||
 | 
						conv_16_8,		/* 16->8 dst_end: conv_16_8 */
 | 
				
			||||||
 | 
						conv_16_8_sign,		/* 16->8 dst_end sign: conv_16_8_sign */
 | 
				
			||||||
 | 
						conv_16_end_8,		/* 16->8 src_end: conv_16_end_8 */
 | 
				
			||||||
 | 
						conv_16_end_8_sign,	/* 16->8 src_end sign: conv_16_end_8_sign */
 | 
				
			||||||
 | 
						conv_16_end_8,		/* 16->8 src_end dst_end: conv_16_end_8 */
 | 
				
			||||||
 | 
						conv_16_end_8_sign,	/* 16->8 src_end dst_end sign: conv_16_end_8_sign */
 | 
				
			||||||
 | 
						NULL,			/* 16->16: Nothing to do */
 | 
				
			||||||
 | 
						conv_16_sign,		/* 16->16 sign: conv_16_sign */
 | 
				
			||||||
 | 
						conv_16_end,		/* 16->16 dst_end: conv_16_end */
 | 
				
			||||||
 | 
						conv_16_sign_end,	/* 16->16 dst_end sign: conv_16_sign_end */
 | 
				
			||||||
 | 
						conv_16_end,		/* 16->16 src_end: conv_16_end */
 | 
				
			||||||
 | 
						conv_16_end_sign,	/* 16->16 src_end sign: conv_16_end_sign */
 | 
				
			||||||
 | 
						NULL,			/* 16->16 src_end dst_end: Nothing to do */
 | 
				
			||||||
 | 
						conv_16_end_sign_end,	/* 16->16 src_end dst_end sign: conv_16_end_sign_end */
 | 
				
			||||||
 | 
						conv_16_32,		/* 16->32: conv_16_32 */
 | 
				
			||||||
 | 
						conv_16_32_sign,	/* 16->32 sign: conv_16_32_sign */
 | 
				
			||||||
 | 
						conv_16_32_end,		/* 16->32 dst_end: conv_16_32_end */
 | 
				
			||||||
 | 
						conv_16_32_sign_end,	/* 16->32 dst_end sign: conv_16_32_sign_end */
 | 
				
			||||||
 | 
						conv_16_end_32,		/* 16->32 src_end: conv_16_end_32 */
 | 
				
			||||||
 | 
						conv_16_end_32_sign,	/* 16->32 src_end sign: conv_16_end_32_sign */
 | 
				
			||||||
 | 
						conv_16_end_32_end,	/* 16->32 src_end dst_end: conv_16_end_32_end */
 | 
				
			||||||
 | 
						conv_16_end_32_sign_end,/* 16->32 src_end dst_end sign: conv_16_end_32_sign_end */
 | 
				
			||||||
 | 
						conv_32_8,		/* 32->8: conv_32_8 */
 | 
				
			||||||
 | 
						conv_32_8_sign,		/* 32->8 sign: conv_32_8_sign */
 | 
				
			||||||
 | 
						conv_32_8,		/* 32->8 dst_end: conv_32_8 */
 | 
				
			||||||
 | 
						conv_32_8_sign,		/* 32->8 dst_end sign: conv_32_8_sign */
 | 
				
			||||||
 | 
						conv_32_end_8,		/* 32->8 src_end: conv_32_end_8 */
 | 
				
			||||||
 | 
						conv_32_end_8_sign,	/* 32->8 src_end sign: conv_32_end_8_sign */
 | 
				
			||||||
 | 
						conv_32_end_8,		/* 32->8 src_end dst_end: conv_32_end_8 */
 | 
				
			||||||
 | 
						conv_32_end_8_sign,	/* 32->8 src_end dst_end sign: conv_32_end_8_sign */
 | 
				
			||||||
 | 
						conv_32_16,		/* 32->16: conv_32_16 */
 | 
				
			||||||
 | 
						conv_32_16_sign,	/* 32->16 sign: conv_32_16_sign */
 | 
				
			||||||
 | 
						conv_32_16_end,		/* 32->16 dst_end: conv_32_16_end */
 | 
				
			||||||
 | 
						conv_32_16_sign_end,	/* 32->16 dst_end sign: conv_32_16_sign_end */
 | 
				
			||||||
 | 
						conv_32_end_16,		/* 32->16 src_end: conv_32_end_16 */
 | 
				
			||||||
 | 
						conv_32_end_16_sign,	/* 32->16 src_end sign: conv_32_end_16_sign */
 | 
				
			||||||
 | 
						conv_32_end_16_end,	/* 32->16 src_end dst_end: conv_32_end_16_end */
 | 
				
			||||||
 | 
						conv_32_end_16_sign_end,/* 32->16 src_end dst_end sign: conv_32_end_16_sign_end */
 | 
				
			||||||
 | 
						NULL,			/* 32->32: Nothing to do */
 | 
				
			||||||
 | 
						conv_32_sign,		/* 32->32 sign: conv_32_sign */
 | 
				
			||||||
 | 
						conv_32_end,		/* 32->32 dst_end: conv_32_end */
 | 
				
			||||||
 | 
						conv_32_sign_end,	/* 32->32 dst_end sign: conv_32_sign_end */
 | 
				
			||||||
 | 
						conv_32_end,		/* 32->32 src_end: conv_32_end */
 | 
				
			||||||
 | 
						conv_32_end_sign,	/* 32->32 src_end sign: conv_32_end_sign */
 | 
				
			||||||
 | 
						NULL,			/* 32->32 src_end dst_end: Nothing to do */
 | 
				
			||||||
 | 
						conv_32_end_sign_end	/* 32->32 src_end dst_end sign: conv_32_end_sign_end */
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void linear_conv_sign_16bit_8bit_swap(unsigned short *src_ptr,
 | 
					 | 
				
			||||||
					     unsigned char *dst_ptr,
 | 
					 | 
				
			||||||
					     size_t size)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
	while (size--)
 | 
					 | 
				
			||||||
		*dst_ptr++ = ((unsigned char)*src_ptr++) ^ 0x80;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
static ssize_t linear_transfer(snd_pcm_plugin_t *plugin,
 | 
					static ssize_t linear_transfer(snd_pcm_plugin_t *plugin,
 | 
				
			||||||
			       char *src_ptr, size_t src_size,
 | 
								       char *src_ptr, size_t src_size,
 | 
				
			||||||
| 
						 | 
					@ -148,51 +201,12 @@ static ssize_t linear_transfer(snd_pcm_plugin_t *plugin,
 | 
				
			||||||
	data = (struct linear_private_data *)snd_pcm_plugin_extra_data(plugin);
 | 
						data = (struct linear_private_data *)snd_pcm_plugin_extra_data(plugin);
 | 
				
			||||||
	if (data == NULL)
 | 
						if (data == NULL)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	switch (data->cmd) {
 | 
						if (src_size % data->src_sample_size != 0)
 | 
				
			||||||
	case _8BIT_16BIT:
 | 
					 | 
				
			||||||
		if ((dst_size >> 1) < src_size)
 | 
					 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
		switch (data->endian) {
 | 
						if (dst_size < src_size*data->dst_sample_size/data->src_sample_size)
 | 
				
			||||||
		case NONE:
 | 
					 | 
				
			||||||
			linear_conv_8bit_16bit(src_ptr, (short *)dst_ptr, src_size);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case DESTINATION:
 | 
					 | 
				
			||||||
			linear_conv_8bit_16bit_swap(src_ptr, (short *)dst_ptr, src_size);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case SIGN_NONE:
 | 
					 | 
				
			||||||
			linear_conv_sign_8bit_16bit(src_ptr, (short *)dst_ptr, src_size);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case SIGN_DESTINATION:
 | 
					 | 
				
			||||||
			linear_conv_sign_8bit_16bit_swap(src_ptr, (short *)dst_ptr, src_size);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
		}
 | 
						data->func(src_ptr, dst_ptr, src_size / data->src_sample_size);
 | 
				
			||||||
		return src_size << 1;
 | 
						return src_size*data->dst_sample_size/data->src_sample_size;
 | 
				
			||||||
	case _16BIT_8BIT:
 | 
					 | 
				
			||||||
		if (dst_size < (src_size >> 1))
 | 
					 | 
				
			||||||
			return -EINVAL;
 | 
					 | 
				
			||||||
		src_size >>= 1;
 | 
					 | 
				
			||||||
		switch (data->endian) {
 | 
					 | 
				
			||||||
		case NONE:
 | 
					 | 
				
			||||||
			linear_conv_16bit_8bit((short *)src_ptr, dst_ptr, src_size);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case SOURCE:
 | 
					 | 
				
			||||||
			linear_conv_16bit_8bit_swap((short *)src_ptr, dst_ptr, src_size);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case SIGN_NONE:
 | 
					 | 
				
			||||||
			linear_conv_sign_16bit_8bit((short *)src_ptr, dst_ptr, src_size);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		case SIGN_SOURCE:
 | 
					 | 
				
			||||||
			linear_conv_sign_16bit_8bit_swap((short *)src_ptr, dst_ptr, src_size);
 | 
					 | 
				
			||||||
			break;
 | 
					 | 
				
			||||||
		default:
 | 
					 | 
				
			||||||
			return -EINVAL;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return src_size;
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return -EIO;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static ssize_t linear_src_size(snd_pcm_plugin_t *plugin, size_t size)
 | 
					static ssize_t linear_src_size(snd_pcm_plugin_t *plugin, size_t size)
 | 
				
			||||||
| 
						 | 
					@ -202,27 +216,9 @@ static ssize_t linear_src_size(snd_pcm_plugin_t *plugin, size_t size)
 | 
				
			||||||
	if (!plugin || size <= 0)
 | 
						if (!plugin || size <= 0)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	data = (struct linear_private_data *)snd_pcm_plugin_extra_data(plugin);
 | 
						data = (struct linear_private_data *)snd_pcm_plugin_extra_data(plugin);
 | 
				
			||||||
	switch (data->cmd) {
 | 
						if (data == NULL)
 | 
				
			||||||
	case _8BIT_16BIT:
 | 
							return -EINVAL;
 | 
				
			||||||
	case _16BIT_24BIT:
 | 
						return size*data->src_sample_size/data->dst_sample_size;
 | 
				
			||||||
	case _16BIT_32BIT:
 | 
					 | 
				
			||||||
		return size / 2;
 | 
					 | 
				
			||||||
	case _8BIT_24BIT:
 | 
					 | 
				
			||||||
	case _8BIT_32BIT:
 | 
					 | 
				
			||||||
		return size / 4;
 | 
					 | 
				
			||||||
	case _16BIT_8BIT:
 | 
					 | 
				
			||||||
	case _24BIT_16BIT:
 | 
					 | 
				
			||||||
	case _32BIT_16BIT:
 | 
					 | 
				
			||||||
		return size * 2;
 | 
					 | 
				
			||||||
	case _24BIT_8BIT:
 | 
					 | 
				
			||||||
	case _32BIT_8BIT:
 | 
					 | 
				
			||||||
		return size * 4;
 | 
					 | 
				
			||||||
	case _24BIT_32BIT:
 | 
					 | 
				
			||||||
	case _32BIT_24BIT:
 | 
					 | 
				
			||||||
		return size;
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return -EIO;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static ssize_t linear_dst_size(snd_pcm_plugin_t *plugin, size_t size)
 | 
					static ssize_t linear_dst_size(snd_pcm_plugin_t *plugin, size_t size)
 | 
				
			||||||
| 
						 | 
					@ -232,27 +228,9 @@ static ssize_t linear_dst_size(snd_pcm_plugin_t *plugin, size_t size)
 | 
				
			||||||
	if (!plugin || size <= 0)
 | 
						if (!plugin || size <= 0)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	data = (struct linear_private_data *)snd_pcm_plugin_extra_data(plugin);
 | 
						data = (struct linear_private_data *)snd_pcm_plugin_extra_data(plugin);
 | 
				
			||||||
	switch (data->cmd) {
 | 
						if (data == NULL)
 | 
				
			||||||
	case _8BIT_16BIT:
 | 
							return -EINVAL;
 | 
				
			||||||
	case _16BIT_24BIT:
 | 
						return size*data->dst_sample_size/data->src_sample_size;
 | 
				
			||||||
	case _16BIT_32BIT:
 | 
					 | 
				
			||||||
		return size * 2;
 | 
					 | 
				
			||||||
	case _8BIT_24BIT:
 | 
					 | 
				
			||||||
	case _8BIT_32BIT:
 | 
					 | 
				
			||||||
		return size * 4;
 | 
					 | 
				
			||||||
	case _16BIT_8BIT:
 | 
					 | 
				
			||||||
	case _24BIT_16BIT:
 | 
					 | 
				
			||||||
	case _32BIT_16BIT:
 | 
					 | 
				
			||||||
		return size / 2;
 | 
					 | 
				
			||||||
	case _24BIT_8BIT:
 | 
					 | 
				
			||||||
	case _32BIT_8BIT:
 | 
					 | 
				
			||||||
		return size / 4;
 | 
					 | 
				
			||||||
	case _24BIT_32BIT:
 | 
					 | 
				
			||||||
	case _32BIT_24BIT:
 | 
					 | 
				
			||||||
		return size;
 | 
					 | 
				
			||||||
	default:
 | 
					 | 
				
			||||||
		return -EIO;
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int snd_pcm_plugin_build_linear(snd_pcm_format_t *src_format,
 | 
					int snd_pcm_plugin_build_linear(snd_pcm_format_t *src_format,
 | 
				
			||||||
| 
						 | 
					@ -261,8 +239,8 @@ int snd_pcm_plugin_build_linear(snd_pcm_format_t *src_format,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct linear_private_data *data;
 | 
						struct linear_private_data *data;
 | 
				
			||||||
	snd_pcm_plugin_t *plugin;
 | 
						snd_pcm_plugin_t *plugin;
 | 
				
			||||||
	combination_t cmd;
 | 
						conv_f func;
 | 
				
			||||||
	int width1, width2, endian1, endian2, sign1, sign2;
 | 
						int src_endian, dst_endian, sign, src_width, dst_width;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!r_plugin)
 | 
						if (!r_plugin)
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
| 
						 | 
					@ -279,69 +257,66 @@ int snd_pcm_plugin_build_linear(snd_pcm_format_t *src_format,
 | 
				
			||||||
	      snd_pcm_format_linear(dst_format->format)))
 | 
						      snd_pcm_format_linear(dst_format->format)))
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	width1 = snd_pcm_format_width(src_format->format);
 | 
						sign = (snd_pcm_format_signed(src_format->format) !=
 | 
				
			||||||
	sign1 = snd_pcm_format_signed(src_format->format);
 | 
							snd_pcm_format_signed(dst_format->format));
 | 
				
			||||||
	width2 = snd_pcm_format_width(dst_format->format);
 | 
						src_width = snd_pcm_format_width(src_format->format);
 | 
				
			||||||
	sign2 = snd_pcm_format_signed(dst_format->format);
 | 
						dst_width = snd_pcm_format_width(dst_format->format);
 | 
				
			||||||
#if __BYTE_ORDER == __LITTLE_ENDIAN
 | 
					#if __BYTE_ORDER == __LITTLE_ENDIAN
 | 
				
			||||||
	endian1 = snd_pcm_format_little_endian(src_format->format);
 | 
						src_endian = snd_pcm_format_big_endian(src_format->format);
 | 
				
			||||||
	endian2 = snd_pcm_format_little_endian(dst_format->format);
 | 
						dst_endian = snd_pcm_format_big_endian(dst_format->format);
 | 
				
			||||||
#elif __BYTE_ORDER == __BIG_ENDIAN
 | 
					#elif __BYTE_ORDER == __BIG_ENDIAN
 | 
				
			||||||
	endian1 = snd_pcm_format_big_endian(src_format->format);
 | 
						src_endian = snd_pcm_format_little_endian(src_format->format);
 | 
				
			||||||
	endian2 = snd_pcm_format_big_endian(dst_format->format);
 | 
						dst_endian = snd_pcm_format_little_endian(dst_format->format);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
#error "Unsupported endian..."
 | 
					#error "Unsupported endian..."
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	cmd = _8BIT_16BIT;
 | 
					
 | 
				
			||||||
	switch (width1) {
 | 
						switch (src_width) {
 | 
				
			||||||
	case 8:
 | 
						case 8:
 | 
				
			||||||
		switch (width2) {
 | 
							src_width = 0;
 | 
				
			||||||
		case 16:	cmd = _8BIT_16BIT; break;
 | 
					 | 
				
			||||||
		case 24:	cmd = _8BIT_24BIT; break;
 | 
					 | 
				
			||||||
		case 32:	cmd = _8BIT_32BIT; break;
 | 
					 | 
				
			||||||
		default:	return -EINVAL;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 16:
 | 
						case 16:
 | 
				
			||||||
		switch (width2) {
 | 
							src_width = 1;
 | 
				
			||||||
		case 8:		cmd = _16BIT_8BIT; break;
 | 
					 | 
				
			||||||
		case 24:	cmd = _16BIT_24BIT; break;
 | 
					 | 
				
			||||||
		case 32:	cmd = _16BIT_32BIT; break;
 | 
					 | 
				
			||||||
		default:	return -EINVAL;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		break;
 | 
					 | 
				
			||||||
	case 24:
 | 
					 | 
				
			||||||
		switch (width2) {
 | 
					 | 
				
			||||||
		case 8:		cmd = _24BIT_8BIT; break;
 | 
					 | 
				
			||||||
		case 16:	cmd = _24BIT_16BIT; break;
 | 
					 | 
				
			||||||
		case 32:	cmd = _24BIT_32BIT; break;
 | 
					 | 
				
			||||||
		default:	return -EINVAL;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 32:
 | 
						case 32:
 | 
				
			||||||
		switch (width2) {
 | 
							src_width = 2;
 | 
				
			||||||
		case 8:		cmd = _32BIT_8BIT; break;
 | 
					 | 
				
			||||||
		case 16:	cmd = _32BIT_16BIT; break;
 | 
					 | 
				
			||||||
		case 24:	cmd = _32BIT_24BIT; break;
 | 
					 | 
				
			||||||
		default:	return -EINVAL;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return -EINVAL;
 | 
							return -EINVAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
						switch (dst_width) {
 | 
				
			||||||
 | 
						case 8:
 | 
				
			||||||
 | 
							dst_width = 0;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 16:
 | 
				
			||||||
 | 
							dst_width = 1;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						case 32:
 | 
				
			||||||
 | 
							dst_width = 2;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
 | 
						default:
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (src_endian < 0)
 | 
				
			||||||
 | 
							src_endian = 0;
 | 
				
			||||||
 | 
						if (dst_endian < 0)
 | 
				
			||||||
 | 
							src_endian = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						func = convert_functions[src_width][dst_width][src_endian][dst_endian][sign];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (func == NULL)
 | 
				
			||||||
 | 
							return -EINVAL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	plugin = snd_pcm_plugin_build("linear format conversion",
 | 
						plugin = snd_pcm_plugin_build("linear format conversion",
 | 
				
			||||||
				      sizeof(struct linear_private_data));
 | 
									      sizeof(struct linear_private_data));
 | 
				
			||||||
	if (plugin == NULL)
 | 
						if (plugin == NULL)
 | 
				
			||||||
		return -ENOMEM;
 | 
							return -ENOMEM;
 | 
				
			||||||
	data = (struct linear_private_data *)snd_pcm_plugin_extra_data(plugin);
 | 
						data = (struct linear_private_data *)snd_pcm_plugin_extra_data(plugin);
 | 
				
			||||||
	data->cmd = cmd;
 | 
						data->func = func;
 | 
				
			||||||
	data->endian = NONE;
 | 
						data->src_sample_size = 1 << src_width;
 | 
				
			||||||
	if (endian1 == 0)
 | 
						data->dst_sample_size = 1 << dst_width;
 | 
				
			||||||
		data->endian |= SOURCE;
 | 
					
 | 
				
			||||||
	if (endian2 == 0)
 | 
					 | 
				
			||||||
		data->endian |= DESTINATION;
 | 
					 | 
				
			||||||
	if (sign1 != sign2)
 | 
					 | 
				
			||||||
		data->endian |= SIGN;
 | 
					 | 
				
			||||||
	plugin->transfer = linear_transfer;
 | 
						plugin->transfer = linear_transfer;
 | 
				
			||||||
	plugin->src_size = linear_src_size;
 | 
						plugin->src_size = linear_src_size;
 | 
				
			||||||
	plugin->dst_size = linear_dst_size;
 | 
						plugin->dst_size = linear_dst_size;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue