/* 

    TiMidity -- Experimental MIDI to WAVE converter
    Copyright (C) 1995 Tuukka Toivonen <toivonen@clinet.fi>

    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., 675 Mass Ave, Cambridge, MA 02139, USA.

    output.c
    
    Audio output (to file / device) functions.
*/

#include "config.h"
#include "output.h"
#include "tables.h"

PlayMode *play_mode_list[] = { &win32_play_mode, 0 };
PlayMode *play_mode = &win32_play_mode;

/*****************************************************************/
/* Some functions to convert signed 32-bit data to other formats */

void
s32tos8 (int32b * lp, int32b c)
{
	int8b *cp = (int8b *) (lp);
	int32b l;
	while (c--)
    {
		l = (*lp++) >> (32 - 8 - GUARD_BITS);
		if (l > 127)
			l = 127;
		else if (l < -128)
			l = -128;
		*cp++ = (int8b) (l);
    }
}

void
s32tou8 (int32b * lp, int32b c)
{
	uint8b *cp = (uint8b *) (lp);
	int32b l;
	while (c--)
    {
		l = (*lp++) >> (32 - 8 - GUARD_BITS);
		if (l > 127)
			l = 127;
		else if (l < -128)
			l = -128;
		*cp++ = 0x80 ^ ((uint8b) l);
    }
}

void
s32tos16 (int32b * lp, int32b c)
{
	int16b *sp = (int16b *) (lp);
	int32b l;
	while (c--)
    {
		l = (*lp++) >> (32 - 16 - GUARD_BITS);
		if (l > 32767)
			l = 32767;
		else if (l < -32768)
			l = -32768;
		*sp++ = (int16b) (l);
    }
}

void
s32tou16 (int32b * lp, int32b c)
{
	uint16b *sp = (uint16b *) (lp);
	int32b l;
	while (c--)
    {
		l = (*lp++) >> (32 - 16 - GUARD_BITS);
		if (l > 32767)
			l = 32767;
		else if (l < -32768)
			l = -32768;
		*sp++ = 0x8000 ^ (uint16b) (l);
    }
}

void
s32tos16x (int32b * lp, int32b c)
{
	int16b *sp = (int16b *) (lp);
	int32b l;
	while (c--)
    {
		l = (*lp++) >> (32 - 16 - GUARD_BITS);
		if (l > 32767)
			l = 32767;
		else if (l < -32768)
			l = -32768;
		*sp++ = XCHG_SHORT ((int16b) (l));
    }
}

void
s32tou16x (int32b * lp, int32b c)
{
	uint16b *sp = (uint16b *) (lp);
	int32b l;
	while (c--)
    {
		l = (*lp++) >> (32 - 16 - GUARD_BITS);
		if (l > 32767)
			l = 32767;
		else if (l < -32768)
			l = -32768;
		*sp++ = XCHG_SHORT (0x8000 ^ (uint16b) (l));
    }
}
