/* CSL - Common Sound Layer
 * Copyright (C) 2000-2001 Stefan Westerfeld and Tim Janik
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
 * Boston, MA 02111-1307, USA.
 */
#ifndef __CSL_PRIVATE_H__
#define __CSL_PRIVATE_H__


#include	<csl/csldefs.h>
#include	<csl/cslmain.h>
#include	<csl/cslpcm.h>
#include	<csl/cslsample.h>

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */


/* --- CSL Driver --- */
typedef struct _CslPcmDriver	      CslPcmDriver;
typedef struct _CslPcmDriverVTable    CslPcmDriverVTable;

typedef struct _CslSampleDriver	      CslSampleDriver;
typedef struct _CslSampleDriverVTable CslSampleDriverVTable;

struct _CslDriver
{
  CslMutex		*mutex;

  /* PCM driver */
  CslPcmDriver          *pcm_data;
  CslPcmDriverVTable	*pcm_vtable;
  unsigned int		 n_pcm_mappings;
  const char	       **pcm_mappings;

  /* Sample driver */
  CslSampleDriver       *sample_data;
  CslSampleDriverVTable *sample_vtable;
};

struct _CslPcmStream
{
  CslDriver   *driver;
  char        *role;
  char        *title;
  unsigned int blocking : 1;
  unsigned int readable : 1;
  unsigned int writable : 1;
  unsigned int packet_mode : 1;
  unsigned int stream_mode : 1;
  unsigned int accessed : 1;	/* been written to or read from */
  unsigned int n_channels : 8;
  unsigned int format : 16;
  unsigned int rate;
  /* buffering */
  unsigned int buffer_size;		/* total n_bytes of buffer */
  unsigned int n_bytes_available;	/* available for read/write */
  unsigned int buffer_watermark;	/* schedule client for
					 * n_bytes_available >= buffer_watermark
					 */
  struct /* valid if packet_mode==TRUE */
  {
    unsigned int    n_total_packets;
    unsigned int    packet_size;	/* n_total_packets * packet_size == buffer_size */
    unsigned int    n_packets_available;
    unsigned int    packet_watermark;	/* in n_packets */
  } packet;
  const char **channel_mappings;	/* array of n_channels size */
};
struct _CslPcmDriverVTable
{
  /* --- driver functions --- */
  CslErrorType	(*pcm_driver_init)	(CslDriver	*driver);
  void		(*pcm_driver_shutdown)	(CslDriver	*driver);
  

  /* --- stream functions --- */
  CslErrorType	(*stream_init)		(CslDriver       *driver,
					 const char	 *role,
					 unsigned int	  rate,
					 unsigned int	  n_channels,
					 CslPcmFormatType format,
					 CslBool          readable, /* FALSE==writable */
					 CslPcmStream   **stream_p);
  void		(*stream_destroy)	(CslPcmStream	 *stream);
  int		(*read)			(CslPcmStream	 *stream,
					 unsigned int	  n_bytes,
					 char		 *bytes);
  int		(*write)		(CslPcmStream	 *stream,
					 unsigned int	  n_bytes,
					 char		 *bytes);
  CslErrorType	(*update_status)	(CslPcmStream	 *stream);
  CslErrorType	(*sync)			(CslPcmStream	 *stream);
  CslErrorType	(*flush)		(CslPcmStream	 *stream);
  CslErrorType	(*set_title)		(CslPcmStream	*stream,
					 const char	*title);
  /* needs to reset packet mode */
  CslErrorType	(*set_stream_mode)	(CslPcmStream	*stream,
					 unsigned int	 buffer_size,
					 unsigned int	 byte_watermark);
  /* needs to reset stream mode */
  CslErrorType	(*set_packet_mode)	(CslPcmStream	*stream,
					 unsigned int	 n_packets,
					 unsigned int	 packet_size,
					 unsigned int	 packet_watermark);
  CslErrorType	(*set_channel_mapping)	(CslPcmStream	*stream,
					 unsigned int	 channel,
					 const char	*mapping);
};

struct _CslSample
{
  CslDriver   *driver;
};

struct _CslSampleDriverVTable
{
  /* driver functions */
  CslErrorType	(*sample_driver_init)	  (CslDriver	*driver);
  void		(*sample_driver_shutdown) (CslDriver	*driver);

  /* sample functions */
  CslErrorType	(*sample_new)		(CslDriver      *driver,
					 const char	*name,
					 const char	*role,
					 const char	*title,
					 CslSample     **sample_p);
  void		(*sample_release)	(CslSample	*sample);
					
  int		(*sample_write)	        (CslSample	*sample,
				 	 unsigned int    n_bytes,
				 	 void           *bytes);
  CslErrorType	(*sample_write_done)	(CslSample	*sample);

  CslErrorType	(*sample_play)		(CslSample	*sample);
  CslBool	(*sample_is_playing)	(CslSample	*sample);
  CslErrorType	(*sample_stop)		(CslSample	*sample);
  CslErrorType	(*sample_wait_done)	(CslSample	*sample);

  CslErrorType	(*sample_cache_add)	(CslSample	*sample);
  CslErrorType	(*sample_cache_find)	(CslDriver      *driver,
					 const char     *name,
					 const char     *role,
					 const char     *title,
					 CslSample     **sample_p);
  void		(*sample_cache_remove)	(CslSample	*sample);
};

/* --- variables --- */
extern CslPcmDriverVTable     _csl_arts_pcm_vtable; 
extern CslSampleDriverVTable  _csl_arts_sample_vtable; 
extern CslPcmDriverVTable     _csl_oss_pcm_vtable;

/* --- macros --- */
#define	DRIVER_LOCK(d)		{ (d)->mutex->lock ((d)->mutex->user_data); }
#define	DRIVER_UNLOCK(d)	{ (d)->mutex->unlock ((d)->mutex->user_data); }

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* __CSL_PRIVATE_H__ */

/* vim:ts=8:sw=2:sts=2
 */
