/*****************************************************************************

        D2dBuffer.cpp
        Copyright (c) 2008 Laurent de Soras

*Tab=3***********************************************************************/



#if defined (_MSC_VER)
	#pragma warning (1 : 4130 4223 4705 4706)
	#pragma warning (4 : 4355 4786 4800)
#endif



/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/

#include	"D2dBuffer.h"
#include	"Voice.h"

#include	<cassert>



/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/



D2dBuffer::D2dBuffer ()
:	file_ptr (0)
/*,	buffer_ptr ()
,	buf_length ()
,	total_length (0)
,	buf_pos ()
,	buf_flag ()*/
{
	buffer_ptr [0] = 0;
	buffer_ptr [1] = 0;
	buf_length [0] = 0;
	buf_length [1] = 0;
	buf_pos [0] = 0;
	buf_pos [1] = 0;
	buf_flag [0] = 0;
	buf_flag [1] = 0;
}



D2dBuffer::~D2dBuffer ()
{
	deallocate ();
}



/*==========================================================================*/
/*      Nom: allocate                                                       */
/*      Description: Cherche un emplacement de cache pour le sample D2D     */
/*                   d'une voie donnee. L'emplacement occupe par le sample  */
/*                   precedent est libere, et un autre est recherche. S'il  */
/*                   y en a un qui convient dans le cache, il est utilise,  */
/*                   sinon un nouveau est cree. Si aucun emplacement n'est  */
/*                   libre, rien n'est fait.                                */
/*      Parametres en entree:                                               */
/*        - voice_index: numero de la voix qui doit s'offir une place dans  */
/*                       le cache.                                          */
/*==========================================================================*/

void	D2dBuffer::allocate (Voice &voice)
{
	LWORD				resol;
	LWORD				buffer_size;
	void *			alloc_ptr;

	/* Libere le buffer du sample precedent */
	deallocate ();

	/* Calcule la taille necessaire */
	resol = voice.spl.resol * voice.spl.tracks;
	buffer_size = (voice.spl.d2d.midbuf1_len + voice.spl.d2d.midbuf2_len) * resol;

	alloc_ptr = new BYTE [buffer_size];
	if (alloc_ptr != 0)
	{
		/* Construit le nouveau descripteur */
		file_ptr       = voice.spl.d2d.file_ptr;
		buffer_ptr [0] = alloc_ptr;
		buffer_ptr [1] =   (BYTE *)alloc_ptr
								+ voice.spl.d2d.midbuf1_len * resol;
		buf_length [0] = voice.spl.d2d.midbuf1_len;
		buf_length [1] = voice.spl.d2d.midbuf2_len;
		total_length   = buffer_size;
		buf_pos [0]    = voice.spl.d2d.startbuf_len;
		buf_pos [1]    = buf_pos [0] + buf_length [0];
		buf_flag [0]   = false;
		buf_flag [1]   = false;
	}
}



void	D2dBuffer::deallocate ()
{
	if (buffer_ptr [0] != 0)
	{
		delete [] buffer_ptr [0];
		buffer_ptr [0] = 0;
	}
}



/*\\\ PROTECTED \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/



/*\\\ PRIVATE \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/



/*\\\ EOF \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
