mirror of
				https://github.com/alsa-project/alsa-lib.git
				synced 2025-11-03 09:01:52 -05:00 
			
		
		
		
	dmix: add U8 support
Add support for direct mixing of U8 samples (for devices like some USB headsets or the Tux Droid).
This commit is contained in:
		
							parent
							
								
									a3fe1f7800
								
							
						
					
					
						commit
						6e6f4b9c93
					
				
					 4 changed files with 43 additions and 1 deletions
				
			
		| 
						 | 
					@ -885,6 +885,7 @@ int snd_pcm_direct_initialize_slave(snd_pcm_direct_t *dmix, snd_pcm_t *spcm, str
 | 
				
			||||||
			SND_PCM_FORMAT_S16,
 | 
								SND_PCM_FORMAT_S16,
 | 
				
			||||||
			SND_PCM_FORMAT_S16 ^ SND_PCM_FORMAT_S16_LE ^ SND_PCM_FORMAT_S16_BE,
 | 
								SND_PCM_FORMAT_S16 ^ SND_PCM_FORMAT_S16_LE ^ SND_PCM_FORMAT_S16_BE,
 | 
				
			||||||
			SND_PCM_FORMAT_S24_3LE,
 | 
								SND_PCM_FORMAT_S24_3LE,
 | 
				
			||||||
 | 
								SND_PCM_FORMAT_U8,
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
		snd_pcm_format_t format;
 | 
							snd_pcm_format_t format;
 | 
				
			||||||
		unsigned int i;
 | 
							unsigned int i;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -44,6 +44,11 @@ typedef void (mix_areas_24_t)(unsigned int size,
 | 
				
			||||||
			      volatile signed int *sum, size_t dst_step,
 | 
								      volatile signed int *sum, size_t dst_step,
 | 
				
			||||||
			      size_t src_step, size_t sum_step);
 | 
								      size_t src_step, size_t sum_step);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef void (mix_areas_u8_t)(unsigned int size,
 | 
				
			||||||
 | 
								      volatile unsigned char *dst, unsigned char *src,
 | 
				
			||||||
 | 
								      volatile signed int *sum, size_t dst_step,
 | 
				
			||||||
 | 
								      size_t src_step, size_t sum_step);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct slave_params {
 | 
					struct slave_params {
 | 
				
			||||||
	snd_pcm_format_t format;
 | 
						snd_pcm_format_t format;
 | 
				
			||||||
	int rate;
 | 
						int rate;
 | 
				
			||||||
| 
						 | 
					@ -156,6 +161,7 @@ struct snd_pcm_direct {
 | 
				
			||||||
			mix_areas_16_t *mix_areas_16;
 | 
								mix_areas_16_t *mix_areas_16;
 | 
				
			||||||
			mix_areas_32_t *mix_areas_32;
 | 
								mix_areas_32_t *mix_areas_32;
 | 
				
			||||||
			mix_areas_24_t *mix_areas_24;
 | 
								mix_areas_24_t *mix_areas_24;
 | 
				
			||||||
 | 
								mix_areas_u8_t *mix_areas_u8;
 | 
				
			||||||
		} dmix;
 | 
							} dmix;
 | 
				
			||||||
		struct {
 | 
							struct {
 | 
				
			||||||
		} dsnoop;
 | 
							} dsnoop;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -176,6 +176,10 @@ static void mix_areas(snd_pcm_direct_t *dmix,
 | 
				
			||||||
		sample_size = 3;
 | 
							sample_size = 3;
 | 
				
			||||||
		do_mix_areas = (mix_areas_t *)dmix->u.dmix.mix_areas_24;
 | 
							do_mix_areas = (mix_areas_t *)dmix->u.dmix.mix_areas_24;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
 | 
						case SND_PCM_FORMAT_U8:
 | 
				
			||||||
 | 
							sample_size = 1;
 | 
				
			||||||
 | 
							do_mix_areas = (mix_areas_t *)dmix->u.dmix.mix_areas_u8;
 | 
				
			||||||
 | 
							break;
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -122,7 +122,8 @@ static void mix_select_callbacks(snd_pcm_direct_t *dmix)
 | 
				
			||||||
#define generic_dmix_supported_format \
 | 
					#define generic_dmix_supported_format \
 | 
				
			||||||
	((1ULL << SND_PCM_FORMAT_S16_LE) | (1ULL << SND_PCM_FORMAT_S32_LE) |\
 | 
						((1ULL << SND_PCM_FORMAT_S16_LE) | (1ULL << SND_PCM_FORMAT_S32_LE) |\
 | 
				
			||||||
	 (1ULL << SND_PCM_FORMAT_S16_BE) | (1ULL << SND_PCM_FORMAT_S32_BE) |\
 | 
						 (1ULL << SND_PCM_FORMAT_S16_BE) | (1ULL << SND_PCM_FORMAT_S32_BE) |\
 | 
				
			||||||
	 (1ULL << SND_PCM_FORMAT_S24_3LE))
 | 
						 (1ULL << SND_PCM_FORMAT_S24_3LE) | \
 | 
				
			||||||
 | 
						 (1ULL << SND_PCM_FORMAT_U8))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <byteswap.h>
 | 
					#include <byteswap.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -292,6 +293,35 @@ static void generic_mix_areas_24(unsigned int size,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void generic_mix_areas_u8(unsigned int size,
 | 
				
			||||||
 | 
									 volatile unsigned char *dst,
 | 
				
			||||||
 | 
									 unsigned char *src,
 | 
				
			||||||
 | 
									 volatile signed int *sum,
 | 
				
			||||||
 | 
									 size_t dst_step,
 | 
				
			||||||
 | 
									 size_t src_step,
 | 
				
			||||||
 | 
									 size_t sum_step)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						for (;;) {
 | 
				
			||||||
 | 
							register int sample = *src - 0x80;
 | 
				
			||||||
 | 
							if (*dst == 0x80) {
 | 
				
			||||||
 | 
								*sum = sample;
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								sample += *sum;
 | 
				
			||||||
 | 
								*sum = sample;
 | 
				
			||||||
 | 
								if (sample > 0x7f)
 | 
				
			||||||
 | 
									sample = 0x7f;
 | 
				
			||||||
 | 
								else if (sample < -0x80)
 | 
				
			||||||
 | 
									sample = -0x80;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							*dst = sample + 0x80;
 | 
				
			||||||
 | 
							if (!--size)
 | 
				
			||||||
 | 
								return;
 | 
				
			||||||
 | 
							dst += dst_step;
 | 
				
			||||||
 | 
							src += src_step;
 | 
				
			||||||
 | 
							sum = (signed int *) ((char *)sum + sum_step);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void generic_mix_select_callbacks(snd_pcm_direct_t *dmix)
 | 
					static void generic_mix_select_callbacks(snd_pcm_direct_t *dmix)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -303,6 +333,7 @@ static void generic_mix_select_callbacks(snd_pcm_direct_t *dmix)
 | 
				
			||||||
		dmix->u.dmix.mix_areas_32 = generic_mix_areas_32_swap;
 | 
							dmix->u.dmix.mix_areas_32 = generic_mix_areas_32_swap;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	dmix->u.dmix.mix_areas_24 = generic_mix_areas_24;
 | 
						dmix->u.dmix.mix_areas_24 = generic_mix_areas_24;
 | 
				
			||||||
 | 
						dmix->u.dmix.mix_areas_u8 = generic_mix_areas_u8;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue