/*
 *  Copyright (c) by Jaroslav Kysela <perex@perex.cz>
 *
 *
 *   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
 *
 */

#include <linux/time.h>
#include <linux/export.h>
#include <sound/core.h>
#include <sound/gus.h>
#define __GUS_TABLES_ALLOC__
#include "gus_tables.h"

EXPORT_SYMBOL(snd_gf1_atten_table); /* for snd-gus-synth module */

unsigned short snd_gf1_lvol_to_gvol_raw(unsigned int vol)
{
	unsigned short e, m, tmp;

	if (vol > 65535)
		vol = 65535;
	tmp = vol;
	e = 7;
	if (tmp < 128) {
		while (e > 0 && tmp < (1 << e))
			e--;
	} else {
		while (tmp > 255) {
			tmp >>= 1;
			e++;
		}
	}
	m = vol - (1 << e);
	if (m > 0) {
		if (e > 8)
			m >>= e - 8;
		else if (e < 8)
			m <<= 8 - e;
		m &= 255;
	}
	return (e << 8) | m;
}

#if 0

unsigned int snd_gf1_gvol_to_lvol_raw(unsigned short gf1_vol)
{
	unsigned int rvol;
	unsigned short e, m;

	if (!gf1_vol)
		return 0;
	e = gf1_vol >> 8;
	m = (unsigned char) gf1_vol;
	rvol = 1 << e;
	if (e > 8)
		return rvol | (m << (e - 8));
	return rvol | (m >> (8 - e));
}

unsigned int snd_gf1_calc_ramp_rate(struct snd_gus_card * gus,
				    unsigned short start,
				    unsigned short end,
				    unsigned int us)
{
	static unsigned char vol_rates[19] =
	{
		23, 24, 26, 28, 29, 31, 32, 34,
		36, 37, 39, 40, 42, 44, 45, 47,
		49, 50, 52
	};
	unsigned short range, increment, value, i;

	start >>= 4;
	end >>= 4;
	if (start < end)
		us /= end - start;
	else
		us /= start - end;
	range = 4;
	value = gus->gf1.enh_mode ?
	    vol_rates[0] :
	    vol_rates[gus->gf1.active_voices - 14];
	for (i = 0; i < 3; i++) {
		if (us < value) {
			range = i;
			break;
		} else
			value <<= 3;
	}
	if (range == 4) {
		range = 3;
		increment = 1;
	} else
		increment = (value + (value >> 1)) / us;
	return (range << 6) | (increment & 0x3f);
}

#endif  /*  0  */

unsigned short snd_gf1_translate_freq(struct snd_gus_card * gus, unsigned int freq16)
{
	freq16 >>= 3;
	if (freq16 < 50)
		freq16 = 50;
	if (freq16 & 0xf8000000) {
		freq16 = ~0xf8000000;
		snd_printk(KERN_ERR "snd_gf1_translate_freq: overflow - freq = 0x%x\n", freq16);
	}
	return ((freq16 << 9) + (gus->gf1.playback_freq >> 1)) / gus->gf1.playback_freq;
}

#if 0

short snd_gf1_compute_vibrato(short cents, unsigned short fc_register)
{
	static short vibrato_table[] =
	{
		0, 0, 32, 592, 61, 1175, 93, 1808,
		124, 2433, 152, 3007, 182, 3632, 213, 4290,
		241, 4834, 255, 5200
	};

	long depth;
	short *vi1, *vi2, pcents, v1;

	pcents = cents < 0 ? -cents : cents;
	for (vi1 = vibrato_table, vi2 = vi1 + 2; pcents > *vi2; vi1 = vi2, vi2 += 2);
	v1 = *(vi1 + 1);
	/* The FC table above is a list of pairs. The first number in the pair     */
	/* is the cents index from 0-255 cents, and the second number in the       */
	/* pair is the FC adjustment needed to change the pitch by the indexed     */
	/* number of cents. The table was created for an FC of 32768.              */
	/* The following expression does a linear interpolation against the        */
	/* approximated log curve in the table above, and then scales the number   */
	/* by the FC before the LFO. This calculation also adjusts the output      */
	/* value to produce the appropriate depth for the hardware. The depth      */
	/* is 2 * desired FC + 1.                                                  */
	depth = (((int) (*(vi2 + 1) - *vi1) * (pcents - *vi1) / (*vi2 - *vi1)) + v1) * fc_register >> 14;
	if (depth)
		depth++;
	if (depth > 255)
		depth = 255;
	return cents < 0 ? -(short) depth : (short) depth;
}

unsigned short snd_gf1_compute_pitchbend(unsigned short pitchbend, unsigned short sens)
{
	static long log_table[] = {1024, 1085, 1149, 1218, 1290, 1367, 1448, 1534, 1625, 1722, 1825, 1933};
	int wheel, sensitivity;
	unsigned int mantissa, f1, f2;
	unsigned short semitones, f1_index, f2_index, f1_power, f2_power;
	char bend_down = 0;
	int bend;

	if (!sens)
		return 1024;
	wheel = (int) pitchbend - 8192;
	sensitivity = ((int) sens * wheel) / 128;
	if (sensitivity < 0) {
		bend_down = 1;
		sensitivity = -sensitivity;
	}
	semitones = (unsigned int) (sensitivity >> 13);
	mantissa = sensitivity % 8192;
	f1_index = semitones % 12;
	f2_index = (semitones + 1) % 12;
	f1_power = semitones / 12;
	f2_power = (semitones + 1) / 12;
	f1 = log_table[f1_index] << f1_power;
	f2 = log_table[f2_index] << f2_power;
	bend = (int) ((((f2 - f1) * mantissa) >> 13) + f1);
	if (bend_down)
		bend = 1048576L / bend;
	return bend;
}

unsigned short snd_gf1_compute_freq(unsigned int freq,
				    unsigned int rate,
				    unsigned short mix_rate)
{
	unsigned int fc;
	int scale = 0;

	while (freq >= 4194304L) {
		scale++;
		freq >>= 1;
	}
	fc = (freq << 10) / rate;
	if (fc > 97391L) {
		fc = 97391;
		snd_printk(KERN_ERR "patch: (1) fc frequency overflow - %u\n", fc);
	}
	fc = (fc * 44100UL) / mix_rate;
	while (scale--)
		fc <<= 1;
	if (fc > 65535L) {
		fc = 65535;
		snd_printk(KERN_ERR "patch: (2) fc frequency overflow - %u\n", fc);
	}
	return (unsigned short) fc;
}

#endif  /*  0  */
