/*
 *  PCM Plug-In shared (kernel/library) code
 *  Copyright (c) 1999 by Jaroslav Kysela <perex@perex.cz>
 *  Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
 *
 *
 *   This library is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Library General Public License as
 *   published by the Free Software Foundation; either version 2 of
 *   the License, or (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Library General Public License for more details.
 *
 *   You should have received a copy of the GNU Library General Public
 *   License along with this library; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 */
  
#if 0
#define PLUGIN_DEBUG
#endif

#include <sound/driver.h>
#include <linux/slab.h>
#include <linux/time.h>
#include <linux/vmalloc.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include "pcm_plugin.h"

#define snd_pcm_plug_first(plug) ((plug)->runtime->oss.plugin_first)
#define snd_pcm_plug_last(plug) ((plug)->runtime->oss.plugin_last)

/*
 *  because some cards might have rates "very close", we ignore
 *  all "resampling" requests within +-5%
 */
static int rate_match(unsigned int src_rate, unsigned int dst_rate)
{
	unsigned int low = (src_rate * 95) / 100;
	unsigned int high = (src_rate * 105) / 100;
	return dst_rate >= low && dst_rate <= high;
}

static int snd_pcm_plugin_alloc(struct snd_pcm_plugin *plugin, snd_pcm_uframes_t frames)
{
	struct snd_pcm_plugin_format *format;
	ssize_t width;
	size_t size;
	unsigned int channel;
	struct snd_pcm_plugin_channel *c;

	if (plugin->stream == SNDRV_PCM_STREAM_PLAYBACK) {
		format = &plugin->src_format;
	} else {
		format = &plugin->dst_format;
	}
	if ((width = snd_pcm_format_physical_width(format->format)) < 0)
		return width;
	size = frames * format->channels * width;
	snd_assert((size % 8) == 0, return -ENXIO);
	size /= 8;
	if (plugin->buf_frames < frames) {
		vfree(plugin->buf);
		plugin->buf = vmalloc(size);
		plugin->buf_frames = frames;
	}
	if (!plugin->buf) {
		plugin->buf_frames = 0;
		return -ENOMEM;
	}
	c = plugin->buf_channels;
	if (plugin->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED) {
		for (channel = 0; channel < format->channels; channel++, c++) {
			c->frames = frames;
			c->enabled = 1;
			c->wanted = 0;
			c->area.addr = plugin->buf;
			c->area.first = channel * width;
			c->area.step = format->channels * width;
		}
	} else if (plugin->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) {
		snd_assert((size % format->channels) == 0,);
		size /= format->channels;
		for (channel = 0; channel < format->channels; channel++, c++) {
			c->frames = frames;
			c->enabled = 1;
			c->wanted = 0;
			c->area.addr = plugin->buf + (channel * size);
			c->area.first = 0;
			c->area.step = width;
		}
	} else
		return -EINVAL;
	return 0;
}

int snd_pcm_plug_alloc(struct snd_pcm_substream *plug, snd_pcm_uframes_t frames)
{
	int err;
	snd_assert(snd_pcm_plug_first(plug) != NULL, return -ENXIO);
	if (snd_pcm_plug_stream(plug) == SNDRV_PCM_STREAM_PLAYBACK) {
		struct snd_pcm_plugin *plugin = snd_pcm_plug_first(plug);
		while (plugin->next) {
			if (plugin->dst_frames)
				frames = plugin->dst_frames(plugin, frames);
			snd_assert(frames > 0, return -ENXIO);
			plugin = plugin->next;
			err = snd_pcm_plugin_alloc(plugin, frames);
			if (err < 0)
				return err;
		}
	} else {
		struct snd_pcm_plugin *plugin = snd_pcm_plug_last(plug);
		while (plugin->prev) {
			if (plugin->src_frames)
				frames = plugin->src_frames(plugin, frames);
			snd_assert(frames > 0, return -ENXIO);
			plugin = plugin->prev;
			err = snd_pcm_plugin_alloc(plugin, frames);
			if (err < 0)
				return err;
		}
	}
	return 0;
}


snd_pcm_sframes_t snd_pcm_plugin_client_channels(struct snd_pcm_plugin *plugin,
				       snd_pcm_uframes_t frames,
				       struct snd_pcm_plugin_channel **channels)
{
	*channels = plugin->buf_channels;
	return frames;
}

int snd_pcm_plugin_build(struct snd_pcm_substream *plug,
			 const char *name,
			 struct snd_pcm_plugin_format *src_format,
			 struct snd_pcm_plugin_format *dst_format,
			 size_t extra,
			 struct snd_pcm_plugin **ret)
{
	struct snd_pcm_plugin *plugin;
	unsigned int channels;
	
	snd_assert(plug != NULL, return -ENXIO);
	snd_assert(src_format != NULL && dst_format != NULL, return -ENXIO);
	plugin = kzalloc(sizeof(*plugin) + extra, GFP_KERNEL);
	if (plugin == NULL)
		return -ENOMEM;
	plugin->name = name;
	plugin->plug = plug;
	plugin->stream = snd_pcm_plug_stream(plug);
	plugin->access = SNDRV_PCM_ACCESS_RW_INTERLEAVED;
	plugin->src_format = *src_format;
	plugin->src_width = snd_pcm_format_physical_width(src_format->format);
	snd_assert(plugin->src_width > 0, );
	plugin->dst_format = *dst_format;
	plugin->dst_width = snd_pcm_format_physical_width(dst_format->format);
	snd_assert(plugin->dst_width > 0, );
	if (plugin->stream == SNDRV_PCM_STREAM_PLAYBACK)
		channels = src_format->channels;
	else
		channels = dst_format->channels;
	plugin->buf_channels = kcalloc(channels, sizeof(*plugin->buf_channels), GFP_KERNEL);
	if (plugin->buf_channels == NULL) {
		snd_pcm_plugin_free(plugin);
		return -ENOMEM;
	}
	plugin->client_channels = snd_pcm_plugin_client_channels;
	*ret = plugin;
	return 0;
}

int snd_pcm_plugin_free(struct snd_pcm_plugin *plugin)
{
	if (! plugin)
		return 0;
	if (plugin->private_free)
		plugin->private_free(plugin);
	kfree(plugin->buf_channels);
	vfree(plugin->buf);
	kfree(plugin);
	return 0;
}

snd_pcm_sframes_t snd_pcm_plug_client_size(struct snd_pcm_substream *plug, snd_pcm_uframes_t drv_frames)
{
	struct snd_pcm_plugin *plugin, *plugin_prev, *plugin_next;
	int stream = snd_pcm_plug_stream(plug);

	snd_assert(plug != NULL, return -ENXIO);
	if (drv_frames == 0)
		return 0;
	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
		plugin = snd_pcm_plug_last(plug);
		while (plugin && drv_frames > 0) {
			plugin_prev = plugin->prev;
			if (plugin->src_frames)
				drv_frames = plugin->src_frames(plugin, drv_frames);
			plugin = plugin_prev;
		}
	} else if (stream == SNDRV_PCM_STREAM_CAPTURE) {
		plugin = snd_pcm_plug_first(plug);
		while (plugin && drv_frames > 0) {
			plugin_next = plugin->next;
			if (plugin->dst_frames)
				drv_frames = plugin->dst_frames(plugin, drv_frames);
			plugin = plugin_next;
		}
	} else
		snd_BUG();
	return drv_frames;
}

snd_pcm_sframes_t snd_pcm_plug_slave_size(struct snd_pcm_substream *plug, snd_pcm_uframes_t clt_frames)
{
	struct snd_pcm_plugin *plugin, *plugin_prev, *plugin_next;
	snd_pcm_sframes_t frames;
	int stream = snd_pcm_plug_stream(plug);
	
	snd_assert(plug != NULL, return -ENXIO);
	if (clt_frames == 0)
		return 0;
	frames = clt_frames;
	if (stream == SNDRV_PCM_STREAM_PLAYBACK) {
		plugin = snd_pcm_plug_first(plug);
		while (plugin && frames > 0) {
			plugin_next = plugin->next;
			if (plugin->dst_frames) {
				frames = plugin->dst_frames(plugin, frames);
				if (frames < 0)
					return frames;
			}
			plugin = plugin_next;
		}
	} else if (stream == SNDRV_PCM_STREAM_CAPTURE) {
		plugin = snd_pcm_plug_last(plug);
		while (plugin) {
			plugin_prev = plugin->prev;
			if (plugin->src_frames) {
				frames = plugin->src_frames(plugin, frames);
				if (frames < 0)
					return frames;
			}
			plugin = plugin_prev;
		}
	} else
		snd_BUG();
	return frames;
}

static int snd_pcm_plug_formats(struct snd_mask *mask, int format)
{
	struct snd_mask formats = *mask;
	u64 linfmts = (SNDRV_PCM_FMTBIT_U8 | SNDRV_PCM_FMTBIT_S8 |
		       SNDRV_PCM_FMTBIT_U16_LE | SNDRV_PCM_FMTBIT_S16_LE |
		       SNDRV_PCM_FMTBIT_U16_BE | SNDRV_PCM_FMTBIT_S16_BE |
		       SNDRV_PCM_FMTBIT_U24_LE | SNDRV_PCM_FMTBIT_S24_LE |
		       SNDRV_PCM_FMTBIT_U24_BE | SNDRV_PCM_FMTBIT_S24_BE |
		       SNDRV_PCM_FMTBIT_U24_3LE | SNDRV_PCM_FMTBIT_S24_3LE |
		       SNDRV_PCM_FMTBIT_U24_3BE | SNDRV_PCM_FMTBIT_S24_3BE |
		       SNDRV_PCM_FMTBIT_U32_LE | SNDRV_PCM_FMTBIT_S32_LE |
		       SNDRV_PCM_FMTBIT_U32_BE | SNDRV_PCM_FMTBIT_S32_BE);
	snd_mask_set(&formats, SNDRV_PCM_FORMAT_MU_LAW);
	
	if (formats.bits[0] & (u32)linfmts)
		formats.bits[0] |= (u32)linfmts;
	if (formats.bits[1] & (u32)(linfmts >> 32))
		formats.bits[1] |= (u32)(linfmts >> 32);
	return snd_mask_test(&formats, format);
}

static int preferred_formats[] = {
	SNDRV_PCM_FORMAT_S16_LE,
	SNDRV_PCM_FORMAT_S16_BE,
	SNDRV_PCM_FORMAT_U16_LE,
	SNDRV_PCM_FORMAT_U16_BE,
	SNDRV_PCM_FORMAT_S24_3LE,
	SNDRV_PCM_FORMAT_S24_3BE,
	SNDRV_PCM_FORMAT_U24_3LE,
	SNDRV_PCM_FORMAT_U24_3BE,
	SNDRV_PCM_FORMAT_S24_LE,
	SNDRV_PCM_FORMAT_S24_BE,
	SNDRV_PCM_FORMAT_U24_LE,
	SNDRV_PCM_FORMAT_U24_BE,
	SNDRV_PCM_FORMAT_S32_LE,
	SNDRV_PCM_FORMAT_S32_BE,
	SNDRV_PCM_FORMAT_U32_LE,
	SNDRV_PCM_FORMAT_U32_BE,
	SNDRV_PCM_FORMAT_S8,
	SNDRV_PCM_FORMAT_U8
};

int snd_pcm_plug_slave_format(int format, struct snd_mask *format_mask)
{
	int i;

	if (snd_mask_test(format_mask, format))
		return format;
	if (! snd_pcm_plug_formats(format_mask, format))
		return -EINVAL;
	if (snd_pcm_format_linear(format)) {
		unsigned int width = snd_pcm_format_width(format);
		int unsignd = snd_pcm_format_unsigned(format) > 0;
		int big = snd_pcm_format_big_endian(format) > 0;
		unsigned int badness, best = -1;
		int best_format = -1;
		for (i = 0; i < ARRAY_SIZE(preferred_formats); i++) {
			int f = preferred_formats[i];
			unsigned int w;
			if (!snd_mask_test(format_mask, f))
				continue;
			w = snd_pcm_format_width(f);
			if (w >= width)
				badness = w - width;
			else
				badness = width - w + 32;
			badness += snd_pcm_format_unsigned(f) != unsignd;
			badness += snd_pcm_format_big_endian(f) != big;
			if (badness < best) {
				best_format = f;
				best = badness;
			}
		}
		return best_format >= 0 ? best_format : -EINVAL;
	} else {
		switch (format) {
		case SNDRV_PCM_FORMAT_MU_LAW:
			for (i = 0; i < ARRAY_SIZE(preferred_formats); ++i) {
				int format1 = preferred_formats[i];
				if (snd_mask_test(format_mask, format1))
					return format1;
			}
		default:
			return -EINVAL;
		}
	}
}

int snd_pcm_plug_format_plugins(struct snd_pcm_substream *plug,
				struct snd_pcm_hw_params *params,
				struct snd_pcm_hw_params *slave_params)
{
	struct snd_pcm_plugin_format tmpformat;
	struct snd_pcm_plugin_format dstformat;
	struct snd_pcm_plugin_format srcformat;
	int src_access, dst_access;
	struct snd_pcm_plugin *plugin = NULL;
	int err;
	int stream = snd_pcm_plug_stream(plug);
	int slave_interleaved = (params_channels(slave_params) == 1 ||
				 params_access(slave_params) == SNDRV_PCM_ACCESS_RW_INTERLEAVED);

	switch (stream) {
	case SNDRV_PCM_STREAM_PLAYBACK:
		dstformat.format = params_format(slave_params);
		dstformat.rate = params_rate(slave_params);
		dstformat.channels = params_channels(slave_params);
		srcformat.format = params_format(params);
		srcformat.rate = params_rate(params);
		srcformat.channels = params_channels(params);
		src_access = SNDRV_PCM_ACCESS_RW_INTERLEAVED;
		dst_access = (slave_interleaved ? SNDRV_PCM_ACCESS_RW_INTERLEAVED :
						  SNDRV_PCM_ACCESS_RW_NONINTERLEAVED);
		break;
	case SNDRV_PCM_STREAM_CAPTURE:
		dstformat.format = params_format(params);
		dstformat.rate = params_rate(params);
		dstformat.channels = params_channels(params);
		srcformat.format = params_format(slave_params);
		srcformat.rate = params_rate(slave_params);
		srcformat.channels = params_channels(slave_params);
		src_access = (slave_interleaved ? SNDRV_PCM_ACCESS_RW_INTERLEAVED :
						  SNDRV_PCM_ACCESS_RW_NONINTERLEAVED);
		dst_access = SNDRV_PCM_ACCESS_RW_INTERLEAVED;
		break;
	default:
		snd_BUG();
		return -EINVAL;
	}
	tmpformat = srcformat;
		
	pdprintf("srcformat: format=%i, rate=%i, channels=%i\n", 
		 srcformat.format,
		 srcformat.rate,
		 srcformat.channels);
	pdprintf("dstformat: format=%i, rate=%i, channels=%i\n", 
		 dstformat.format,
		 dstformat.rate,
		 dstformat.channels);

	/* Format change (linearization) */
	if (! rate_match(srcformat.rate, dstformat.rate) &&
	    ! snd_pcm_format_linear(srcformat.format)) {
		if (srcformat.format != SNDRV_PCM_FORMAT_MU_LAW)
			return -EINVAL;
		tmpformat.format = SNDRV_PCM_FORMAT_S16;
		err = snd_pcm_plugin_build_mulaw(plug,
						 &srcformat, &tmpformat,
						 &plugin);
		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;
	}

	/* channels reduction */
	if (srcformat.channels > dstformat.channels) {
		tmpformat.channels = dstformat.channels;
		err = snd_pcm_plugin_build_route(plug, &srcformat, &tmpformat, &plugin);
		pdprintf("channels reduction: src=%i, dst=%i returns %i\n", srcformat.channels, tmpformat.channels, 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;
	}

	/* rate resampling */
	if (!rate_match(srcformat.rate, dstformat.rate)) {
		if (srcformat.format != SNDRV_PCM_FORMAT_S16) {
			/* convert to S16 for resampling */
			tmpformat.format = SNDRV_PCM_FORMAT_S16;
			err = snd_pcm_plugin_build_linear(plug,
							  &srcformat, &tmpformat,
							  &plugin);
			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;
		}
		tmpformat.rate = dstformat.rate;
        	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)
			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 (srcformat.format == SNDRV_PCM_FORMAT_MU_LAW ||
		    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;
	}

	/* channels extension */
	if (srcformat.channels < dstformat.channels) {
		tmpformat.channels = dstformat.channels;
		err = snd_pcm_plugin_build_route(plug, &srcformat, &tmpformat, &plugin);
		pdprintf("channels extension: src=%i, dst=%i returns %i\n", srcformat.channels, tmpformat.channels, 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(struct snd_pcm_substream *plug,
					 char *buf,
					 snd_pcm_uframes_t count,
					 struct snd_pcm_plugin_channel **channels)
{
	struct snd_pcm_plugin *plugin;
	struct snd_pcm_plugin_channel *v;
	struct snd_pcm_plugin_format *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;
}

snd_pcm_sframes_t snd_pcm_plug_write_transfer(struct snd_pcm_substream *plug, struct snd_pcm_plugin_channel *src_channels, snd_pcm_uframes_t size)
{
	struct snd_pcm_plugin *plugin, *next;
	struct snd_pcm_plugin_channel *dst_channels;
	int err;
	snd_pcm_sframes_t frames = size;

	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(struct snd_pcm_substream *plug, struct snd_pcm_plugin_channel *dst_channels_final, snd_pcm_uframes_t size)
{
	struct snd_pcm_plugin *plugin, *next;
	struct snd_pcm_plugin_channel *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;
		} 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 struct snd_pcm_channel_area *dst_area, size_t dst_offset,
			 size_t samples, int format)
{
	/* FIXME: sub byte resolution and odd dst_offset */
	unsigned char *dst;
	unsigned int dst_step;
	int width;
	const unsigned char *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);
	if (width <= 0)
		return -EINVAL;
	if (dst_area->step == (unsigned int) width && width >= 8)
		return snd_pcm_format_set_silence(format, dst, samples);
	silence = snd_pcm_format_silence_64(format);
	if (! silence)
		return -EINVAL;
	dst_step = dst_area->step / 8;
	if (width == 4) {
		/* Ima ADPCM */
		int dstbit = dst_area->first % 8;
		int dstbit_step = dst_area->step % 8;
		while (samples-- > 0) {
			if (dstbit)
				*dst &= 0xf0;
			else
				*dst &= 0x0f;
			dst += dst_step;
			dstbit += dstbit_step;
			if (dstbit == 8) {
				dst++;
				dstbit = 0;
			}
		}
	} else {
		width /= 8;
		while (samples-- > 0) {
			memcpy(dst, silence, width);
			dst += dst_step;
		}
	}
	return 0;
}

int snd_pcm_area_copy(const struct snd_pcm_channel_area *src_area, size_t src_offset,
		      const struct snd_pcm_channel_area *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 (width <= 0)
		return -EINVAL;
	if (src_area->step == (unsigned int) width &&
	    dst_area->step == (unsigned int) width && width >= 8) {
		size_t bytes = samples * width / 8;
		memcpy(dst, src, bytes);
		return 0;
	}
	src_step = src_area->step / 8;
	dst_step = dst_area->step / 8;
	if (width == 4) {
		/* Ima ADPCM */
		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) >> 4;
			if (dstbit)
				*dst = (*dst & 0xf0) | srcval;
			else
				*dst = (*dst & 0x0f) | (srcval << 4);
			src += src_step;
			srcbit += srcbit_step;
			if (srcbit == 8) {
				src++;
				srcbit = 0;
			}
			dst += dst_step;
			dstbit += dstbit_step;
			if (dstbit == 8) {
				dst++;
				dstbit = 0;
			}
		}
	} else {
		width /= 8;
		while (samples-- > 0) {
			memcpy(dst, src, width);
			src += src_step;
			dst += dst_step;
		}
	}
	return 0;
}
