/*
**	tx1v32 -- Merge a 1-voice dump into a 32-voice dump
**	tx32v1 -- Extract a 1-voice dump from a 32-voice dump
**	Return 0 for failure, 1 for success.
**	psl, 3/88
*/

#include <stdio.h>
#include <midi.h>
#include <dx7voice.h>

#define	OOOOOX	0x01	/* 1 bit mask */
#define	OOOOXX	0x03	/* 2 bit mask */
#define	OOOXXX	0x07	/* 3 bit mask */
#define	OOXXXX	0x0F	/* 4 bit mask */

tx1v32(v1, n, v32)	/* merge v1 into v32 in slot n */
u_char	*v1, *v32;	/* These point to the data AFTER the header */
{
	register u_char *f, *t;
	register int op;

	if (n < 0 || n >= 32			/* out of range */
	 || *v1 == SX_CMD)			/* common error */
	    return(0);
	for (op = 0; op < 6; op++) {
	    f = &v1[op * DX7OPLEN];
	    t = &v32[n * DX732VOXLEN + op * DX732VOPLEN];
	    bcopy(&f[0], &t[0], 11);		/* R1 through RD */
	    t[11] = (f[12] << 2) + f[11];	/* RC | LC */
	    t[12] = (f[20] << 3) + f[13];	/* PD | RS */
	    t[13] = (f[15] << 2) + f[14];	/* KVS | AMS */
	    t[14] = f[16];			/* OL */
	    t[15] = (f[18] << 1) + f[17];	/* FC | M */
	    t[16] = f[19];			/* FF */
	}
	f = v1;
	t = &v32[n * DX732VOXLEN];
	bcopy(&f[126], &t[102], 9);		/* PR1 through ALS */
	t[111] = (f[136] << 3) + f[135];	/* OKS | FB */
	bcopy(&f[137], &t[112], 4);		/* LFS through LAMD */
	t[116] = (f[143] << 4) + (f[142] << 1) + f[141];/* LPMS | LFW | LFKS */
	bcopy(&f[144], &t[117], 11);		/* TRNP, VNAM */
	return(1);
}

tx32v1(v32, n, v1)	/* extract slot n of v32 into v1 */
u_char	*v32, *v1;	/* These point to the data AFTER the header */
{
	register u_char *f, *t;
	register int op;

	if (n < 0 || n >= 32			/* out of range */
	 || *v32 == SX_CMD)			/* common error */
	    return(0);
	for (op = 0; op < 6; op++) {
	    f = &v32[n * DX732VOXLEN + op * DX732VOPLEN];
	    t = &v1[op * DX7OPLEN];
	    bcopy(&f[0], &t[0], 11);		/* R1 through RD */
	    t[11] = (f[11] & OOOOXX);		/* LC */
	    t[12] = (f[11] >> 2);		/* RC */
	    t[13] = (f[12] & OOOXXX);		/* RS */
	    t[14] = (f[13] & OOOOXX);		/* AMS */
	    t[15] = (f[13] >> 2);		/* KVS */
	    t[16] = f[14];			/* OL */
	    t[17] = (f[15] & OOOOOX);		/* M */
	    t[18] = (f[15] >> 1);		/* FC */
	    t[19] = f[16];			/* FF */
	    t[20] = (f[12] >> 3);		/* PD */
	}
	f = &v32[n * DX732VOXLEN];
	t = v1;
	bcopy(&f[102], &t[126], 9);		/* PR1 through ALS */
	t[135] = (f[111] & OOOXXX);		/* FB */
	t[136] = (f[111] >> 3);			/* OKS */
	bcopy(&f[112], &t[137], 4);		/* LFS through LAMD */
	t[141] = (f[116] & OOOOOX);		/* LFKS */
	t[142] = ((f[116] >> 1) & OOOXXX);	/* LFW */
	t[143] = (f[116] >> 4);			/* LPMS */
	bcopy(&f[117], &t[144], 11);		/* TRNP, VNAM */
	return(1);
}
