⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pcm_plugin.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
        	err = snd_pcm_plugin_build_rate(plug,        					&srcformat, &tmpformat,						&plugin);		pdprintf("rate down resampling: src=%i, dst=%i returns %i\n", srcformat.rate, tmpformat.rate, err);		if (err < 0) {			snd_pcm_plugin_free(plugin);			return err;		}      					    		err = snd_pcm_plugin_append(plugin);		if (err < 0) {			snd_pcm_plugin_free(plugin);			return err;		}		srcformat = tmpformat;		src_access = dst_access;        }	/* channels extension  */	if (srcformat.channels < dstformat.channels) {		int sv = srcformat.channels;		int dv = dstformat.channels;		route_ttable_entry_t *ttable = snd_kcalloc(dv * sv * sizeof(*ttable), GFP_KERNEL);		if (ttable == NULL)			return -ENOMEM;#if 0		{			int v;			for (v = 0; v < sv; ++v)				ttable[v * sv + v] = FULL;		}#else		{			/* Playback is spreaded on all channels */			int vd, vs;			for (vd = 0, vs = 0; vd < dv; ++vd) {				ttable[vd * sv + vs] = FULL;				vs++;				if (vs == sv)					vs = 0;			}		}#endif		tmpformat.channels = dstformat.channels;		if (snd_pcm_format_linear(dstformat.format))			tmpformat.format = dstformat.format;		err = snd_pcm_plugin_build_route(plug,						 &srcformat, &tmpformat,						 ttable, &plugin);		kfree(ttable);		pdprintf("channels extension: src=%i, dst=%i returns %i\n", srcformat.channels, tmpformat.channels, err);		if (err < 0) {			snd_pcm_plugin_free(plugin);			return err;		}      					    		err = snd_pcm_plugin_append(plugin);		if (err < 0) {			snd_pcm_plugin_free(plugin);			return err;		}		srcformat = tmpformat;		src_access = dst_access;	}	/* format change */	if (srcformat.format != dstformat.format) {		tmpformat.format = dstformat.format;		if (tmpformat.format == SNDRV_PCM_FORMAT_MU_LAW) {			err = snd_pcm_plugin_build_mulaw(plug,							 &srcformat, &tmpformat,							 &plugin);		}		else if (snd_pcm_format_linear(srcformat.format) &&			 snd_pcm_format_linear(tmpformat.format)) {			err = snd_pcm_plugin_build_linear(plug,							  &srcformat, &tmpformat,							  &plugin);		}		else			return -EINVAL;		pdprintf("format change: src=%i, dst=%i returns %i\n", srcformat.format, tmpformat.format, err);		if (err < 0)			return err;		err = snd_pcm_plugin_append(plugin);		if (err < 0) {			snd_pcm_plugin_free(plugin);			return err;		}		srcformat = tmpformat;		src_access = dst_access;	}	/* de-interleave */	if (src_access != dst_access) {		err = snd_pcm_plugin_build_copy(plug,						&srcformat,						&tmpformat,						&plugin);		pdprintf("interleave change (copy: returns %i)\n", err);		if (err < 0)			return err;		err = snd_pcm_plugin_append(plugin);		if (err < 0) {			snd_pcm_plugin_free(plugin);			return err;		}	}	return 0;}snd_pcm_sframes_t snd_pcm_plug_client_channels_buf(snd_pcm_plug_t *plug,					 char *buf,					 snd_pcm_uframes_t count,					 snd_pcm_plugin_channel_t **channels){	snd_pcm_plugin_t *plugin;	snd_pcm_plugin_channel_t *v;	snd_pcm_plugin_format_t *format;	int width, nchannels, channel;	int stream = snd_pcm_plug_stream(plug);	snd_assert(buf != NULL, return -ENXIO);	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {		plugin = snd_pcm_plug_first(plug);		format = &plugin->src_format;	} else {		plugin = snd_pcm_plug_last(plug);		format = &plugin->dst_format;	}	v = plugin->buf_channels;	*channels = v;	if ((width = snd_pcm_format_physical_width(format->format)) < 0)		return width;	nchannels = format->channels;	snd_assert(plugin->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED || format->channels <= 1, return -ENXIO);	for (channel = 0; channel < nchannels; channel++, v++) {		v->frames = count;		v->enabled = 1;		v->wanted = (stream == SNDRV_PCM_STREAM_CAPTURE);		v->area.addr = buf;		v->area.first = channel * width;		v->area.step = nchannels * width;	}	return count;}int snd_pcm_plug_playback_channels_mask(snd_pcm_plug_t *plug,					bitset_t *client_vmask){	snd_pcm_plugin_t *plugin = snd_pcm_plug_last(plug);	if (plugin == NULL) {		return 0;	} else {		int schannels = plugin->dst_format.channels;		bitset_t bs[bitset_size(schannels)];		bitset_t *srcmask;		bitset_t *dstmask = bs;		int err;		bitset_one(dstmask, schannels);		if (plugin == NULL) {			bitset_and(client_vmask, dstmask, schannels);			return 0;		}		while (1) {			err = plugin->src_channels_mask(plugin, dstmask, &srcmask);			if (err < 0)				return err;			dstmask = srcmask;			if (plugin->prev == NULL)				break;			plugin = plugin->prev;		}		bitset_and(client_vmask, dstmask, plugin->src_format.channels);		return 0;	}}int snd_pcm_plug_capture_channels_mask(snd_pcm_plug_t *plug,				       bitset_t *client_vmask){	snd_pcm_plugin_t *plugin = snd_pcm_plug_first(plug);	if (plugin == NULL) {		return 0;	} else {		int schannels = plugin->src_format.channels;		bitset_t bs[bitset_size(schannels)];		bitset_t *srcmask = bs;		bitset_t *dstmask;		int err;		bitset_one(srcmask, schannels);		while (1) {			err = plugin->dst_channels_mask(plugin, srcmask, &dstmask);			if (err < 0)				return err;			srcmask = dstmask;			if (plugin->next == NULL)				break;			plugin = plugin->next;		}		bitset_and(client_vmask, srcmask, plugin->dst_format.channels);		return 0;	}}static int snd_pcm_plug_playback_disable_useless_channels(snd_pcm_plug_t *plug,							  snd_pcm_plugin_channel_t *src_channels){	snd_pcm_plugin_t *plugin = snd_pcm_plug_first(plug);	unsigned int nchannels = plugin->src_format.channels;	bitset_t bs[bitset_size(nchannels)];	bitset_t *srcmask = bs;	int err;	unsigned int channel;	for (channel = 0; channel < nchannels; channel++) {		if (src_channels[channel].enabled)			bitset_set(srcmask, channel);		else			bitset_reset(srcmask, channel);	}	err = snd_pcm_plug_playback_channels_mask(plug, srcmask);	if (err < 0)		return err;	for (channel = 0; channel < nchannels; channel++) {		if (!bitset_get(srcmask, channel))			src_channels[channel].enabled = 0;	}	return 0;}static int snd_pcm_plug_capture_disable_useless_channels(snd_pcm_plug_t *plug,							 snd_pcm_plugin_channel_t *src_channels,							 snd_pcm_plugin_channel_t *client_channels){	snd_pcm_plugin_t *plugin = snd_pcm_plug_last(plug);	unsigned int nchannels = plugin->dst_format.channels;	bitset_t bs[bitset_size(nchannels)];	bitset_t *dstmask = bs;	bitset_t *srcmask;	int err;	unsigned int channel;	for (channel = 0; channel < nchannels; channel++) {		if (client_channels[channel].enabled)			bitset_set(dstmask, channel);		else			bitset_reset(dstmask, channel);	}	while (plugin) {		err = plugin->src_channels_mask(plugin, dstmask, &srcmask);		if (err < 0)			return err;		dstmask = srcmask;		plugin = plugin->prev;	}	plugin = snd_pcm_plug_first(plug);	nchannels = plugin->src_format.channels;	for (channel = 0; channel < nchannels; channel++) {		if (!bitset_get(dstmask, channel))			src_channels[channel].enabled = 0;	}	return 0;}snd_pcm_sframes_t snd_pcm_plug_write_transfer(snd_pcm_plug_t *plug, snd_pcm_plugin_channel_t *src_channels, snd_pcm_uframes_t size){	snd_pcm_plugin_t *plugin, *next;	snd_pcm_plugin_channel_t *dst_channels;	int err;	snd_pcm_sframes_t frames = size;	if ((err = snd_pcm_plug_playback_disable_useless_channels(plug, src_channels)) < 0)		return err;		plugin = snd_pcm_plug_first(plug);	while (plugin && frames > 0) {		if ((next = plugin->next) != NULL) {			snd_pcm_sframes_t frames1 = frames;			if (plugin->dst_frames)				frames1 = plugin->dst_frames(plugin, frames);			if ((err = next->client_channels(next, frames1, &dst_channels)) < 0) {				return err;			}			if (err != frames1) {				frames = err;				if (plugin->src_frames)					frames = plugin->src_frames(plugin, frames1);			}		} else			dst_channels = NULL;		pdprintf("write plugin: %s, %li\n", plugin->name, frames);		if ((frames = plugin->transfer(plugin, src_channels, dst_channels, frames)) < 0)			return frames;		src_channels = dst_channels;		plugin = next;	}	return snd_pcm_plug_client_size(plug, frames);}snd_pcm_sframes_t snd_pcm_plug_read_transfer(snd_pcm_plug_t *plug, snd_pcm_plugin_channel_t *dst_channels_final, snd_pcm_uframes_t size){	snd_pcm_plugin_t *plugin, *next;	snd_pcm_plugin_channel_t *src_channels, *dst_channels;	snd_pcm_sframes_t frames = size;	int err;	frames = snd_pcm_plug_slave_size(plug, frames);	if (frames < 0)		return frames;	src_channels = NULL;	plugin = snd_pcm_plug_first(plug);	while (plugin && frames > 0) {		if ((next = plugin->next) != NULL) {			if ((err = plugin->client_channels(plugin, frames, &dst_channels)) < 0) {				return err;			}			frames = err;			if (!plugin->prev) {				if ((err = snd_pcm_plug_capture_disable_useless_channels(plug, dst_channels, dst_channels_final)) < 0)					return err;			}		} else {			dst_channels = dst_channels_final;		}		pdprintf("read plugin: %s, %li\n", plugin->name, frames);		if ((frames = plugin->transfer(plugin, src_channels, dst_channels, frames)) < 0)			return frames;		plugin = next;		src_channels = dst_channels;	}	return frames;}int snd_pcm_area_silence(const snd_pcm_channel_area_t *dst_area, size_t dst_offset,			 size_t samples, int format){	/* FIXME: sub byte resolution and odd dst_offset */	char *dst;	unsigned int dst_step;	int width;	u_int64_t silence;	if (!dst_area->addr)		return 0;	dst = dst_area->addr + (dst_area->first + dst_area->step * dst_offset) / 8;	width = snd_pcm_format_physical_width(format);	silence = snd_pcm_format_silence_64(format);	if (dst_area->step == (unsigned int) width) {		size_t dwords = samples * width / 64;		u_int64_t *dst64 = (u_int64_t *)dst;		samples -= dwords * 64 / width;		while (dwords-- > 0)			*dst64++ = silence;		if (samples == 0)			return 0;		dst = (char *)dst64;	}	dst_step = dst_area->step / 8;	switch (width) {	case 4: {		u_int8_t s0 = silence & 0xf0;		u_int8_t s1 = silence & 0x0f;		int dstbit = dst_area->first % 8;		int dstbit_step = dst_area->step % 8;		while (samples-- > 0) {			if (dstbit) {				*dst &= 0xf0;				*dst |= s1;			} else {				*dst &= 0x0f;				*dst |= s0;			}			dst += dst_step;			dstbit += dstbit_step;			if (dstbit == 8) {				dst++;				dstbit = 0;			}		}		break;	}	case 8: {		u_int8_t sil = silence;		while (samples-- > 0) {			*dst = sil;			dst += dst_step;		}		break;	}	case 16: {		u_int16_t sil = silence;		while (samples-- > 0) {			*(u_int16_t*)dst = sil;			dst += dst_step;		}		break;	}	case 32: {		u_int32_t sil = silence;		while (samples-- > 0) {			*(u_int32_t*)dst = sil;			dst += dst_step;		}		break;	}	case 64: {		while (samples-- > 0) {			*(u_int64_t*)dst = silence;			dst += dst_step;		}		break;	}	default:		snd_BUG();	}	return 0;}int snd_pcm_area_copy(const snd_pcm_channel_area_t *src_area, size_t src_offset,		      const snd_pcm_channel_area_t *dst_area, size_t dst_offset,		      size_t samples, int format){	/* FIXME: sub byte resolution and odd dst_offset */	char *src, *dst;	int width;	int src_step, dst_step;	src = src_area->addr + (src_area->first + src_area->step * src_offset) / 8;	if (!src_area->addr)		return snd_pcm_area_silence(dst_area, dst_offset, samples, format);	dst = dst_area->addr + (dst_area->first + dst_area->step * dst_offset) / 8;	if (!dst_area->addr)		return 0;	width = snd_pcm_format_physical_width(format);	if (src_area->step == (unsigned int) width &&	    dst_area->step == (unsigned int) width) {		size_t bytes = samples * width / 8;		samples -= bytes * 8 / width;		memcpy(dst, src, bytes);		if (samples == 0)			return 0;	}	src_step = src_area->step / 8;	dst_step = dst_area->step / 8;	switch (width) {	case 4: {		int srcbit = src_area->first % 8;		int srcbit_step = src_area->step % 8;		int dstbit = dst_area->first % 8;		int dstbit_step = dst_area->step % 8;		while (samples-- > 0) {			unsigned char srcval;			if (srcbit)				srcval = *src & 0x0f;			else				srcval = *src & 0xf0;			if (dstbit)				*dst &= 0xf0;			else				*dst &= 0x0f;			*dst |= srcval;			src += src_step;			srcbit += srcbit_step;			if (srcbit == 8) {				src++;				srcbit = 0;			}			dst += dst_step;			dstbit += dstbit_step;			if (dstbit == 8) {				dst++;				dstbit = 0;			}		}		break;	}	case 8: {		while (samples-- > 0) {			*dst = *src;			src += src_step;			dst += dst_step;		}		break;	}	case 16: {		while (samples-- > 0) {			*(u_int16_t*)dst = *(u_int16_t*)src;			src += src_step;			dst += dst_step;		}		break;	}	case 32: {		while (samples-- > 0) {			*(u_int32_t*)dst = *(u_int32_t*)src;			src += src_step;			dst += dst_step;		}		break;	}	case 64: {		while (samples-- > 0) {			*(u_int64_t*)dst = *(u_int64_t*)src;			src += src_step;			dst += dst_step;		}		break;	}	default:		snd_BUG();	}	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -