/*
 *  Patch transfer callback for Emu10k1
 *
 *  Copyright (C) 2000 Takashi iwai <tiwai@suse.de>
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU 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 General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */
/*
 * All the code for loading in a patch.  There is very little that is
 * chip specific here.  Just the actual writing to the board.
 */

#include "emu10k1_synth_local.h"

/*
 */
#define BLANK_LOOP_START	4
#define BLANK_LOOP_END		8
#define BLANK_LOOP_SIZE		12
#define BLANK_HEAD_SIZE		32

/*
 * allocate a sample block and copy data from userspace
 */
int
snd_emu10k1_sample_new(struct snd_emux *rec, struct snd_sf_sample *sp,
		       struct snd_util_memhdr *hdr,
		       const void __user *data, long count)
{
	int offset;
	int truesize, size, loopsize, blocksize;
	int loopend, sampleend;
	unsigned int start_addr;
	struct snd_emu10k1 *emu;

	emu = rec->hw;
	if (snd_BUG_ON(!sp || !hdr))
		return -EINVAL;

	if (sp->v.size == 0) {
		snd_printd("emu: rom font for sample %d\n", sp->v.sample);
		return 0;
	}

	/* recalculate address offset */
	sp->v.end -= sp->v.start;
	sp->v.loopstart -= sp->v.start;
	sp->v.loopend -= sp->v.start;
	sp->v.start = 0;

	/* some samples have invalid data.  the addresses are corrected in voice info */
	sampleend = sp->v.end;
	if (sampleend > sp->v.size)
		sampleend = sp->v.size;
	loopend = sp->v.loopend;
	if (loopend > sampleend)
		loopend = sampleend;

	/* be sure loop points start < end */
	if (sp->v.loopstart >= sp->v.loopend) {
		int tmp = sp->v.loopstart;
		sp->v.loopstart = sp->v.loopend;
		sp->v.loopend = tmp;
	}

	/* compute true data size to be loaded */
	truesize = sp->v.size + BLANK_HEAD_SIZE;
	loopsize = 0;
#if 0 /* not supported */
	if (sp->v.mode_flags & (SNDRV_SFNT_SAMPLE_BIDIR_LOOP|SNDRV_SFNT_SAMPLE_REVERSE_LOOP))
		loopsize = sp->v.loopend - sp->v.loopstart;
	truesize += loopsize;
#endif
	if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_NO_BLANK)
		truesize += BLANK_LOOP_SIZE;

	/* try to allocate a memory block */
	blocksize = truesize;
	if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
		blocksize *= 2;
	sp->block = snd_emu10k1_synth_alloc(emu, blocksize);
	if (sp->block == NULL) {
		snd_printd("emu10k1: synth malloc failed (size=%d)\n", blocksize);
		/* not ENOMEM (for compatibility with OSS) */
		return -ENOSPC;
	}
	/* set the total size */
	sp->v.truesize = blocksize;

	/* write blank samples at head */
	offset = 0;
	size = BLANK_HEAD_SIZE;
	if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
		size *= 2;
	if (offset + size > blocksize)
		return -EINVAL;
	snd_emu10k1_synth_bzero(emu, sp->block, offset, size);
	offset += size;

	/* copy start->loopend */
	size = loopend;
	if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
		size *= 2;
	if (offset + size > blocksize)
		return -EINVAL;
	if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size)) {
		snd_emu10k1_synth_free(emu, sp->block);
		sp->block = NULL;
		return -EFAULT;
	}
	offset += size;
	data += size;

#if 0 /* not suppported yet */
	/* handle reverse (or bidirectional) loop */
	if (sp->v.mode_flags & (SNDRV_SFNT_SAMPLE_BIDIR_LOOP|SNDRV_SFNT_SAMPLE_REVERSE_LOOP)) {
		/* copy loop in reverse */
		if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) {
			int woffset;
			unsigned short *wblock = (unsigned short*)block;
			woffset = offset / 2;
			if (offset + loopsize * 2 > blocksize)
				return -EINVAL;
			for (i = 0; i < loopsize; i++)
				wblock[woffset + i] = wblock[woffset - i -1];
			offset += loopsize * 2;
		} else {
			if (offset + loopsize > blocksize)
				return -EINVAL;
			for (i = 0; i < loopsize; i++)
				block[offset + i] = block[offset - i -1];
			offset += loopsize;
		}

		/* modify loop pointers */
		if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_BIDIR_LOOP) {
			sp->v.loopend += loopsize;
		} else {
			sp->v.loopstart += loopsize;
			sp->v.loopend += loopsize;
		}
		/* add sample pointer */
		sp->v.end += loopsize;
	}
#endif

	/* loopend -> sample end */
	size = sp->v.size - loopend;
	if (size < 0)
		return -EINVAL;
	if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
		size *= 2;
	if (snd_emu10k1_synth_copy_from_user(emu, sp->block, offset, data, size)) {
		snd_emu10k1_synth_free(emu, sp->block);
		sp->block = NULL;
		return -EFAULT;
	}
	offset += size;

	/* clear rest of samples (if any) */
	if (offset < blocksize)
		snd_emu10k1_synth_bzero(emu, sp->block, offset, blocksize - offset);

	if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_NO_BLANK) {
		/* if no blank loop is attached in the sample, add it */
		if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_SINGLESHOT) {
			sp->v.loopstart = sp->v.end + BLANK_LOOP_START;
			sp->v.loopend = sp->v.end + BLANK_LOOP_END;
		}
	}

#if 0 /* not supported yet */
	if (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_UNSIGNED) {
		/* unsigned -> signed */
		if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS)) {
			unsigned short *wblock = (unsigned short*)block;
			for (i = 0; i < truesize; i++)
				wblock[i] ^= 0x8000;
		} else {
			for (i = 0; i < truesize; i++)
				block[i] ^= 0x80;
		}
	}
#endif

	/* recalculate offset */
	start_addr = BLANK_HEAD_SIZE * 2;
	if (! (sp->v.mode_flags & SNDRV_SFNT_SAMPLE_8BITS))
		start_addr >>= 1;
	sp->v.start += start_addr;
	sp->v.end += start_addr;
	sp->v.loopstart += start_addr;
	sp->v.loopend += start_addr;

	return 0;
}

/*
 * free a sample block
 */
int
snd_emu10k1_sample_free(struct snd_emux *rec, struct snd_sf_sample *sp,
			struct snd_util_memhdr *hdr)
{
	struct snd_emu10k1 *emu;

	emu = rec->hw;
	if (snd_BUG_ON(!sp || !hdr))
		return -EINVAL;

	if (sp->block) {
		snd_emu10k1_synth_free(emu, sp->block);
		sp->block = NULL;
	}
	return 0;
}

