  | 
   XM Player 
   Submitted by  |   
  
  
This is a small XM replay library i have been working on for some weeks.
It also included players for MOD/S3M/IT, but these are too buggy
to be released. It is kept portable and should work on any c compiler
with not too many changes (critical sections / device driver).
Maybe I'll release the complete library with MOD/S3M/XM/IT some day,
but there's still quite some work to be done..
The library is released as public domain. Use it for whatever you want,
I won't care.
  
 | 
 
 
 
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/src/vbf/vbf_util.c] - (9,199 bytes)
 
 #include <vbf/vbf_util.h>
  // to do:
// - read_line_*()
int
vbf_read_u64(vbf_t *vbf, int endianess, u64 *val)
{
	vbf_size_t size;
	int status;
  	if (status = vbf_read(vbf, (char*)val, sizeof(u64), &size) < 0)
	{
		return status;
	}
  	if (size != sizeof(u64))
	{
		return VBF_ERR_GENERIC;
	}
  #ifdef SYS_SMALL_ENDIAN
	if (endianess == VBF_BIG_ENDIAN)
#else
	if (endianess == VBF_SMALL_ENDIAN)
#endif
	{
		*val = ((*val & 0xff00000000000000) >> 56) +
			   ((*val & 0x00ff000000000000) >> 40) +
			   ((*val & 0x0000ff0000000000) >> 24) +
			   ((*val & 0x000000ff00000000) >>  8) +
			   ((*val & 0x00000000ff000000) <<  8) +
			   ((*val & 0x0000000000ff0000) << 24) +
			   ((*val & 0x000000000000ff00) << 40) +
			   ((*val & 0x00000000000000ff) << 56);
	}
  	return 0;
}
  int
vbf_read_i64(vbf_t *vbf, int endianess, i64 *val)
{
	vbf_size_t size;
	int status;
  	if (status = vbf_read(vbf, val, sizeof(i64), &size) < 0)
	{
		return status;
	}
  	if (size != sizeof(i64))
	{
		return VBF_ERR_GENERIC;
	}
  #ifdef SYS_SMALL_ENDIAN
	if (endianess == VBF_BIG_ENDIAN)
#else
	if (endianess == VBF_SMALL_ENDIAN)
#endif
	{
		*val = ((*val & 0xff00000000000000) >> 56) +
			   ((*val & 0x00ff000000000000) >> 40) +
			   ((*val & 0x0000ff0000000000) >> 24) +
			   ((*val & 0x000000ff00000000) >>  8) +
			   ((*val & 0x00000000ff000000) <<  8) +
			   ((*val & 0x0000000000ff0000) << 24) +
			   ((*val & 0x000000000000ff00) << 40) +
			   ((*val & 0x00000000000000ff) << 56);
	}
  	return 0;
}
  int
vbf_read_u32(vbf_t *vbf, int endianess, u32 *val)
{
	vbf_size_t size;
	int status;
  	if (status = vbf_read(vbf, val, sizeof(u32), &size) < 0)
	{
		return status;
	}
  	if (size != sizeof(u32))
	{
		return VBF_ERR_GENERIC;
	}
  #ifdef SYS_SMALL_ENDIAN
	if (endianess == VBF_BIG_ENDIAN)
#else
	if (endianess == VBF_SMALL_ENDIAN)
#endif
	{
		*val = ((*val & 0xff000000) >> 24) +
			   ((*val & 0x00ff0000) >>  8) +
			   ((*val & 0x0000ff00) <<  8) +
			   ((*val & 0x000000ff) << 24);
	}
  	return 0;
}
  int
vbf_read_i32(vbf_t *vbf, int endianess, i32 *val)
{
	vbf_size_t size;
	int status;
  	if (status = vbf_read(vbf, val, sizeof(i32), &size) < 0)
	{
		return status;
	}
  	if (size != sizeof(i32))
	{
		return VBF_ERR_GENERIC;
	}
  #ifdef SYS_SMALL_ENDIAN
	if (endianess == VBF_BIG_ENDIAN)
#else
	if (endianess == VBF_SMALL_ENDIAN)
#endif
	{
		*val = ((*val & 0xff000000) >> 24) +
			   ((*val & 0x00ff0000) >>  8) +
			   ((*val & 0x0000ff00) <<  8) +
			   ((*val & 0x000000ff) << 24);
	}
  	return 0;
}
  int
vbf_read_u16(vbf_t *vbf, int endianess, u16 *val)
{
	vbf_size_t size;
	int status;
  	if (status = vbf_read(vbf, val, sizeof(u16), &size) < 0)
	{
		return status;
	}
  	if (size != sizeof(u16))
	{
		return VBF_ERR_GENERIC;
	}
  #ifdef SYS_SMALL_ENDIAN
	if (endianess == VBF_BIG_ENDIAN)
#else
	if (endianess == VBF_SMALL_ENDIAN)
#endif
	{
		*val = ((*val & 0xff00) >> 8) +
			   ((*val & 0x00ff) << 8);
	}
  	return 0;
}
  int
vbf_read_i16(vbf_t *vbf, int endianess, i16 *val)
{
	vbf_size_t size;
	int status;
  	if (status = vbf_read(vbf, val, sizeof(i16), &size) < 0)
	{
		return status;
	}
  	if (size != sizeof(i16))
	{
		return VBF_ERR_GENERIC;
	}
  #ifdef SYS_SMALL_ENDIAN
	if (endianess == VBF_BIG_ENDIAN)
#else
	if (endianess == VBF_SMALL_ENDIAN)
#endif
	{
		*val = ((*val & 0xff00) >> 8) +
			   ((*val & 0x00ff) << 8);
	}
  	return 0;
}
  int
vbf_read_u8(vbf_t *vbf, int endianess, u8 *val)
{
	vbf_size_t size;
	int status;
  	if (status = vbf_read(vbf, val, sizeof(u8), &size) < 0)
	{
		return status;
	}
  	if (size != sizeof(u8))
	{
		return VBF_ERR_GENERIC;
	}
  	return 0;
}
  int
vbf_read_i8(vbf_t *vbf, int endianess, i8 *val)
{
	vbf_size_t size;
	int status;
  	if (status = vbf_read(vbf, val, sizeof(i8), &size) < 0)
	{
		return status;
	}
  	if (size != sizeof(i8))
	{
		return VBF_ERR_GENERIC;
	}
  	return 0;
}
  int
vbf_read_float32(vbf_t *vbf, int endianess, float32 *val)
{
	return vbf_read_u32(vbf, endianess, (u32*)val);
}
  int
vbf_read_float64(vbf_t *vbf, int endianess, float64 *val)
{
	return vbf_read_u64(vbf, endianess, (u64*)val);
}
  int
vbf_read_array_u64(vbf_t *vbf, int endianess, int num, u64 *val)
{
	vbf_size_t size;
	int status;
  	if (status = vbf_read(vbf, (char*)val, sizeof(u64) * num, &size) < 0)
	{
		return status;
	}
  	if ((unsigned int)size != sizeof(u64) * num)
	{
		return VBF_ERR_GENERIC;
	}
  #ifdef SYS_SMALL_ENDIAN
	if (endianess == VBF_BIG_ENDIAN)
#else
	if (endianess == VBF_SMALL_ENDIAN)
#endif
	{
		while(num--)
		{
			*val = ((*val & 0xff00000000000000) >> 56) +
				   ((*val & 0x00ff000000000000) >> 40) +
				   ((*val & 0x0000ff0000000000) >> 24) +
				   ((*val & 0x000000ff00000000) >>  8) +
				   ((*val & 0x00000000ff000000) <<  8) +
				   ((*val & 0x0000000000ff0000) << 24) +
				   ((*val & 0x000000000000ff00) << 40) +
				   ((*val & 0x00000000000000ff) << 56);
			val++;
		}
	}
  	return 0;
}
  int
vbf_read_array_i64(vbf_t *vbf, int endianess, int num, i64 *val)
{
	vbf_size_t size;
	int status;
  	if (status = vbf_read(vbf, val, sizeof(i64) * num, &size) < 0)
	{
		return status;
	}
  	if ((unsigned int)size != sizeof(i64) * num)
	{
		return VBF_ERR_GENERIC;
	}
  #ifdef SYS_SMALL_ENDIAN
	if (endianess == VBF_BIG_ENDIAN)
#else
	if (endianess == VBF_SMALL_ENDIAN)
#endif
	{
		while(num--)
		{
			*val = ((*val & 0xff00000000000000) >> 56) +
				   ((*val & 0x00ff000000000000) >> 40) +
				   ((*val & 0x0000ff0000000000) >> 24) +
				   ((*val & 0x000000ff00000000) >>  8) +
				   ((*val & 0x00000000ff000000) <<  8) +
				   ((*val & 0x0000000000ff0000) << 24) +
				   ((*val & 0x000000000000ff00) << 40) +
				   ((*val & 0x00000000000000ff) << 56);
			val++;
		}
	}
  	return 0;
}
  int
vbf_read_array_u32(vbf_t *vbf, int endianess, int num, u32 *val)
{
	vbf_size_t size;
	int status;
  	if (status = vbf_read(vbf, val, sizeof(u32) * num, &size) < 0)
	{
		return status;
	}
  	if ((unsigned int)size != sizeof(u32) * num)
	{
		return VBF_ERR_GENERIC;
	}
  #ifdef SYS_SMALL_ENDIAN
	if (endianess == VBF_BIG_ENDIAN)
#else
	if (endianess == VBF_SMALL_ENDIAN)
#endif
	{
		while(num--)
		{
			*val = ((*val & 0xff000000) >> 24) +
				   ((*val & 0x00ff0000) >>  8) +
				   ((*val & 0x0000ff00) <<  8) +
				   ((*val & 0x000000ff) << 24);
			val++;
		}
	}
  	return 0;
}
  int
vbf_read_array_i32(vbf_t *vbf, int endianess, int num, i32 *val)
{
	vbf_size_t size;
	int status;
  	if (status = vbf_read(vbf, val, sizeof(i32) * num, &size) < 0)
	{
		return status;
	}
  	if ((unsigned int)size != sizeof(i32) * num)
	{
		return VBF_ERR_GENERIC;
	}
  #ifdef SYS_SMALL_ENDIAN
	if (endianess == VBF_BIG_ENDIAN)
#else
	if (endianess == VBF_SMALL_ENDIAN)
#endif
	{
		while(num--)
		{
			*val = ((*val & 0xff000000) >> 24) +
				   ((*val & 0x00ff0000) >>  8) +
				   ((*val & 0x0000ff00) <<  8) +
				   ((*val & 0x000000ff) << 24);
			val++;
		}
	}
  	return 0;
}
  int
vbf_read_array_u16(vbf_t *vbf, int endianess, int num, u16 *val)
{
	vbf_size_t size;
	int status;
  	if (status = vbf_read(vbf, val, sizeof(u16) * num, &size) < 0)
	{
		return status;
	}
  	if ((unsigned int)size != sizeof(u16) * num)
	{
		return VBF_ERR_GENERIC;
	}
  #ifdef SYS_SMALL_ENDIAN
	if (endianess == VBF_BIG_ENDIAN)
#else
	if (endianess == VBF_SMALL_ENDIAN)
#endif
	{
		while(num--)
		{
			*val = ((*val & 0xff00) >> 8) +
				   ((*val & 0x00ff) << 8);
			val++;
		}
	}
  	return 0;
}
  int
vbf_read_array_i16(vbf_t *vbf, int endianess, int num, i16 *val)
{
	vbf_size_t size;
	int status;
  	if (status = vbf_read(vbf, val, sizeof(i16) * num, &size) < 0)
	{
		return status;
	}
  	if ((unsigned int)size != sizeof(i16) * num)
	{
		return VBF_ERR_GENERIC;
	}
  #ifdef SYS_SMALL_ENDIAN
	if (endianess == VBF_BIG_ENDIAN)
#else
	if (endianess == VBF_SMALL_ENDIAN)
#endif
	{
		while(num--)
		{
			*val = ((*val & 0xff00) >> 8) +
				   ((*val & 0x00ff) << 8);
		}
	}
  	return 0;
}
  int
vbf_read_array_u8(vbf_t *vbf, int endianess, int num, u8 *val)
{
	vbf_size_t size;
	int status;
  	if (status = vbf_read(vbf, val, sizeof(u8) * num, &size) < 0)
	{
		return status;
	}
  	if ((unsigned int)size != sizeof(u8) * num)
	{
		return VBF_ERR_GENERIC;
	}
  	return 0;
}
  int
vbf_read_array_i8(vbf_t *vbf, int endianess, int num, i8 *val)
{
	return vbf_read_array_u8(vbf, endianess, num, (u8*)val);
}
  int
vbf_read_array_float32(vbf_t *vbf, int endianess, int num, float32 *val)
{
	return vbf_read_array_u32(vbf, endianess, num, (u32*)val);
}
  int
vbf_read_array_float64(vbf_t *vbf, int endianess, int num, float64 *val)
{
	return vbf_read_array_u64(vbf, endianess, num, (u64*)val);
}
  int
vbf_read_line_char(vbf_t *vbf, char *buf, int max, int *read)
{
	return VBF_ERR_GENERIC;
}
  int
vbf_read_line_wide_char(vbf_t *vbf, int endianess, wide_char *buf, int max, int *read)
{
	return VBF_ERR_GENERIC;
}
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/src/vbf/vbf.c] - (4,505 bytes)
 
 #include <vbf/vbf.h>
  /*
  to do
-----
  - equivalent of ungetc(...) ??
  */
  static int vbf_raw_read(struct vbf_s *vbf, void *buffer, vbf_size_t size, vbf_size_t *out_size);
static int vbf_raw_write(struct vbf_s *vbf, void *buffer, vbf_size_t size, vbf_size_t *out_size);
static int vbf_raw_ioctl(struct vbf_s *vbf, int command, void *buffer, vbf_size_t size, vbf_size_t *out_size);
static int vbf_raw_seek_rel(struct vbf_s *vbf, vbf_size_t new_pos);
static int vbf_raw_close(struct vbf_s *vbf);
  int
vbf_create(vbf_t *vbf)
{
	vbf->data   = 0;
	vbf->mode   = 0;
	vbf->length = 0;
	vbf->pos    = 0;
  	vbf->raw_read     = vbf_raw_read;
	vbf->raw_write    = vbf_raw_write;
	vbf->raw_ioctl    = vbf_raw_ioctl;
	vbf->raw_seek_rel = vbf_raw_seek_rel;
	vbf->raw_close    = vbf_raw_close;
  	return 0;
}
  int
vbf_destroy(vbf_t *vbf)
{
	if (vbf->mode & VBF_ATTR_OPEN)
	{
		return vbf_close(vbf);
	}
  	return 0;
}
  int
vbf_seek_beg(vbf_t *vbf, vbf_size_t pos)
{
	vbf_size_t new_pos;
  	if (vbf->mode & VBF_ATTR_OPEN == 0)
	{
		return VBF_ERR_NOT_OPEN;
	}
  	if (vbf->mode & VBF_ATTR_SEEK == 0)
	{
		return VBF_ERR_NO_SEEK;
	}
  	if (vbf->mode & VBF_ATTR_LENGTH == 0)
	{
		return VBF_ERR_NO_LENGTH;
	}
  	if (pos < 0 || pos > vbf->length)
	{
		return VBF_ERR_BAD_POS;
	}
  	new_pos = pos - vbf->pos;
  	if (!new_pos)
	{
		return 0;
	}
  	return vbf->raw_seek_rel(vbf, new_pos);
}
  int
vbf_seek_cur(vbf_t *vbf, vbf_size_t pos)
{
	vbf_size_t abs_pos;
  	if (vbf->mode & VBF_ATTR_OPEN == 0)
	{
		return VBF_ERR_NOT_OPEN;
	}
  	if (vbf->mode & VBF_ATTR_SEEK == 0)
	{
		return VBF_ERR_NO_SEEK;
	}
  	if (!pos)
	{
		return 0;
	}
  	if (vbf->mode & VBF_ATTR_LENGTH)
	{
		abs_pos = pos + vbf->pos;
  		if (abs_pos < 0 || abs_pos > vbf->length)
		{
			return VBF_ERR_BAD_POS;
		}
	}
  	return vbf->raw_seek_rel(vbf, pos);
}
  int
vbf_seek_end(vbf_t *vbf, vbf_size_t pos)
{
	return vbf_seek_beg(vbf, vbf->length + pos);
}
  int
vbf_tell(vbf_t *vbf, vbf_size_t *pos)
{
	if (vbf->mode & VBF_ATTR_OPEN == 0)
	{
		return VBF_ERR_NOT_OPEN;
	}
  	if (vbf->mode & VBF_ATTR_LENGTH == 0)
	{
		return VBF_ERR_NO_LENGTH;
	}
  	*pos = vbf->pos;
  	return 0;
}
  int
vbf_size(vbf_t *vbf, vbf_size_t *size)
{
	if (vbf->mode & VBF_ATTR_OPEN == 0)
	{
		return VBF_ERR_NOT_OPEN;
	}
	
	if (vbf->mode & VBF_ATTR_LENGTH == 0)
	{
		return VBF_ERR_NO_LENGTH;
	}
  	*size = vbf->length;
  	return 0;
}
  int
vbf_mode(vbf_t *vbf, int *mode)
{
	if (vbf->mode & VBF_ATTR_OPEN == 0)
	{
		return VBF_ERR_NOT_OPEN;
	}
  	*mode = vbf->mode;
  	return 0;
}
  int
vbf_read(vbf_t *vbf, void *buffer, vbf_size_t size, vbf_size_t *out_size)
{
	if (vbf->mode & VBF_ATTR_OPEN == 0)
	{
		return VBF_ERR_NOT_OPEN;
	}
  	if (vbf->mode & VBF_ATTR_READ == 0)
	{
		return VBF_ERR_NO_READ;
	}
  	if (vbf->mode & VBF_ATTR_LENGTH)
	{
		if (vbf->pos + size > vbf->length)
		{
			size = vbf->length - vbf->pos;
		}
	}
  	return vbf->raw_read(vbf, buffer, size, out_size);
}
  int
vbf_write(vbf_t *vbf, void *buffer, vbf_size_t size, vbf_size_t *out_size)
{
	if (vbf->mode & VBF_ATTR_OPEN == 0)
	{
		return VBF_ERR_NOT_OPEN;
	}
  	if (vbf->mode & VBF_ATTR_WRITE == 0)
	{
		return VBF_ERR_NO_WRITE;
	}
  	if (vbf->mode & VBF_ATTR_LENGTH && !(vbf->mode & VBF_ATTR_APPEND))
	{
		if (vbf->pos + size > vbf->length)
		{
			size = vbf->length - vbf->pos;
		}
	}
  	return vbf->raw_write(vbf, buffer, size, out_size);
}
  int
vbf_ioctl(vbf_t *vbf, int command, void *buffer, vbf_size_t size, vbf_size_t *out_size)
{
	if (vbf->mode & VBF_ATTR_OPEN == 0)
	{
		return VBF_ERR_NOT_OPEN;
	}
  	return vbf->raw_ioctl(vbf, command, buffer, size, out_size);
}
  int
vbf_close(vbf_t *vbf)
{
	if (vbf->mode & VBF_ATTR_OPEN == 0)
	{
		return VBF_ERR_NOT_OPEN;
	}
  	return vbf->raw_close(vbf);
}
  static int
vbf_raw_read(struct vbf_s *vbf, void *buffer, vbf_size_t size, vbf_size_t *out_size)
{
	return VBF_ERR_GENERIC;
}
  static int
vbf_raw_write(struct vbf_s *vbf, void *buffer, vbf_size_t size, vbf_size_t *out_size)
{
	return VBF_ERR_GENERIC;
}
  static int
vbf_raw_ioctl(struct vbf_s *vbf, int command, void *buffer, vbf_size_t size, vbf_size_t *out_size)
{
	return VBF_ERR_GENERIC;
}
  static int
vbf_raw_seek_rel(struct vbf_s *vbf, vbf_size_t new_pos)
{
	return VBF_ERR_GENERIC;
}
  static int
vbf_raw_close(struct vbf_s *vbf)
{
	vbf->mode = 0;
  	return 0;
}
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/src/vbf/vbf_std.c] - (1,816 bytes)
 
 #include <vbf/vbf_std.h>
  /*
  to do
-----
  - detection of attributes
  */
  static int vbf_std_raw_read(struct vbf_s *vbf, void *buffer, vbf_size_t size, vbf_size_t *out_size);
static int vbf_std_raw_write(struct vbf_s *vbf, void *buffer, vbf_size_t size, vbf_size_t *out_size);
static int vbf_std_raw_ioctl(struct vbf_s *vbf, int command, void *buffer, vbf_size_t size, vbf_size_t *out_size);
static int vbf_std_raw_seek_rel(struct vbf_s *vbf, vbf_size_t new_pos);
static int vbf_std_raw_close(struct vbf_s *vbf);
  int
vbf_std_open(vbf_t *vbf, FILE *file)
{
	vbf_create(vbf);
  	vbf->mode = VBF_ATTR_LENGTH | VBF_ATTR_SEEK |
				VBF_ATTR_OPEN   | VBF_ATTR_READ;
  	vbf->data = file;
  	fseek(file, 0, SEEK_END);
	vbf->length = ftell(file);
	fseek(file, 0, SEEK_SET);
  	vbf->raw_read     = vbf_std_raw_read;
	vbf->raw_write    = vbf_std_raw_write;
	vbf->raw_ioctl    = vbf_std_raw_ioctl;
	vbf->raw_seek_rel = vbf_std_raw_seek_rel;
	vbf->raw_close    = vbf_std_raw_close;
  	return 0;
}
  static int
vbf_std_raw_read(struct vbf_s *vbf, void *buffer, vbf_size_t size, vbf_size_t *out_size)
{
	if (!size)
	{
		return 0;
	}
  	fread(buffer, size, 1, (FILE*)vbf->data);
	vbf->pos += size;
  	if (out_size)
	{
		*out_size = size;
	}
  	return 0;
}
  static int
vbf_std_raw_write(struct vbf_s *vbf, void *buffer, vbf_size_t size, vbf_size_t *out_size)
{
	return 0;
}
  static int
vbf_std_raw_ioctl(struct vbf_s *vbf, int command, void *buffer, vbf_size_t size, vbf_size_t *out_size)
{
	return VBF_ERR_GENERIC;
}
  static int
vbf_std_raw_seek_rel(struct vbf_s *vbf, vbf_size_t new_pos)
{
	fseek((FILE*)vbf->data, new_pos, SEEK_CUR);
	vbf->pos += new_pos;
  	return 0;
}
  static int
vbf_std_raw_close(struct vbf_s *vbf)
{
	vbf->mode = 0;
  	return 0;
}
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/src/vbf/vbf_mem.c] - (1,849 bytes)
 
 #include <vbf/vbf_mem.h>
  /*
  to do
-----
  - add support of all attributes
  */
  static int vbf_mem_raw_read(struct vbf_s *vbf, void *buffer, vbf_size_t size, vbf_size_t *out_size);
static int vbf_mem_raw_write(struct vbf_s *vbf, void *buffer, vbf_size_t size, vbf_size_t *out_size);
static int vbf_mem_raw_ioctl(struct vbf_s *vbf, int command, void *buffer, vbf_size_t size, vbf_size_t *out_size);
static int vbf_mem_raw_seek_rel(struct vbf_s *vbf, vbf_size_t new_pos);
static int vbf_mem_raw_close(struct vbf_s *vbf);
  static void __copy_memory__(char *src, char *dst, vbf_size_t size)
{
	while(size-- > 0)
	{
		*(dst++) = *(src++);
	}
}
  int
vbf_mem_open(vbf_t *vbf, void *buffer, vbf_size_t size)
{
	vbf_create(vbf);
  	vbf->mode = VBF_ATTR_LENGTH | VBF_ATTR_SEEK |
				VBF_ATTR_OPEN   | VBF_ATTR_READ;
  	vbf->length = size;
	vbf->data = buffer;
  	vbf->raw_read     = vbf_mem_raw_read;
	vbf->raw_write    = vbf_mem_raw_write;
	vbf->raw_ioctl    = vbf_mem_raw_ioctl;
	vbf->raw_seek_rel = vbf_mem_raw_seek_rel;
	vbf->raw_close    = vbf_mem_raw_close;
  	return 0;
}
  static int
vbf_mem_raw_read(struct vbf_s *vbf, void *buffer, vbf_size_t size, vbf_size_t *out_size)
{
	__copy_memory__((char*)vbf->data + vbf->pos, (char*)buffer, size);
	vbf->pos += size;
  	if (out_size)
	{
		*out_size = size;
	}
  	return 0;
}
  static int
vbf_mem_raw_write(struct vbf_s *vbf, void *buffer, vbf_size_t size, vbf_size_t *out_size)
{
	return 0;
}
  static int
vbf_mem_raw_ioctl(struct vbf_s *vbf, int command, void *buffer, vbf_size_t size, vbf_size_t *out_size)
{
	return VBF_ERR_GENERIC;
}
  static int
vbf_mem_raw_seek_rel(struct vbf_s *vbf, vbf_size_t new_pos)
{
	vbf->pos += new_pos;
  	return 0;
}
  static int
vbf_mem_raw_close(struct vbf_s *vbf)
{
	vbf->mode = 0;
  	return 0;
}
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/src/mpl/biquad.c] - (3,988 bytes)
 
 #include <mpl/biquad.h>
#include <math.h>
  #define LN2O2 0.34657359027997265470861606072909
  void
mpl__biquad_lp(mpl__biquad_coeff_t *biquad, float32 omega, float32 bandwidth)
{
	float64 sn, cs, al, a0, a1, a2, b0, b1, b2, ooa0;
  	sn = sin(omega);
	cs = cos(omega);
	al = sn * sinh(LN2O2 * bandwidth * omega / sn);
  	b0 = (1 - cs) * 0.5;
	b1 = 1 - cs;
	b2 = (1 - cs) * 0.5;
	a0 = 1 + al;
	a1 = -2 * cs;
	a2 = 1 - al;
  	ooa0 = 1.0f / a0;
  	biquad->a0 = b0 * ooa0;
	biquad->a1 = b1 * ooa0;
	biquad->a2 = b2 * ooa0;
	biquad->b1 = -a1 * ooa0;
	biquad->b2 = -a2 * ooa0;
}
  void
mpl__biquad_bp(mpl__biquad_coeff_t *biquad, float32 omega, float32 bandwidth)
{
	float64 sn, cs, al, a0, a1, a2, b0, b1, b2, ooa0;
  	sn = sin(omega);
	cs = cos(omega);
	al = sn * sinh(LN2O2 * bandwidth * omega / sn);
  	b0 = al;
	b1 = 0;
	b2 = -al;
	a0 = 1 + al;
	a1 = -2 * cs;
	a2 = 1 - al;
  	ooa0 = 1.0f / a0;
  	biquad->a0 = b0 * ooa0;
	biquad->a1 = b1 * ooa0;
	biquad->a2 = b2 * ooa0;
	biquad->b1 = -a1 * ooa0;
	biquad->b2 = -a2 * ooa0;
}
  void
mpl__biquad_hp(mpl__biquad_coeff_t *biquad, float32 omega, float32 bandwidth)
{
	float64 sn, cs, al, a0, a1, a2, b0, b1, b2, ooa0;
  	sn = sin(omega);
	cs = cos(omega);
	al = sn * sinh(LN2O2 * bandwidth * omega / sn);
  	b0 = (1 + cs) * 0.5;
	b1 = -(1 + cs);
	b2 = (1 + cs) * 0.5;
	a0 = 1 + al;
	a1 = -2 * cs;
	a2 = 1 - al;
  	ooa0 = 1.0f / a0;
  	biquad->a0 = b0 * ooa0;
	biquad->a1 = b1 * ooa0;
	biquad->a2 = b2 * ooa0;
	biquad->b1 = -a1 * ooa0;
	biquad->b2 = -a2 * ooa0;
}
  void
mpl__biquad_no(mpl__biquad_coeff_t *biquad, float32 omega, float32 bandwidth)
{
	float64 sn, cs, al, a0, a1, a2, b0, b1, b2, ooa0;
  	sn = sin(omega);
	cs = cos(omega);
	al = sn * sinh(LN2O2 * bandwidth * omega / sn);
  	b0 = 1;
	b1 = -2 * cs;
	b2 = 1;
	a0 = 1 + al;
	a1 = b1;
	a2 = 1 - al;
  	ooa0 = 1.0f / a0;
  	biquad->a0 = b0 * ooa0;
	biquad->a1 = b1 * ooa0;
	biquad->a2 = b2 * ooa0;
	biquad->b1 = -a1 * ooa0;
	biquad->b2 = -a2 * ooa0;
}
  void
mpl__biquad_peq(mpl__biquad_coeff_t *biquad, float32 omega, float32 bandwidth, float32 dbgain)
{
	float64 sn, cs, al, a, a0, a1, a2, b0, b1, b2, ooa, ooa0;
  	sn = sin(omega);
	cs = cos(omega);
	a  = pow(10, dbgain * 0.025);
	ooa = 1.0 / a;
	al = sn * sinh(LN2O2 * bandwidth * omega / sn);
  	b0 = 1 + al * a;
	b1 = -2 * cs;
	b2 = 1 - al * a;
	a0 = 1 + al * ooa;
	a1 = b1;
	a2 = 1 - al * ooa;
  	ooa0 = 1.0f / a0;
  	biquad->a0 = b0 * ooa0;
	biquad->a1 = b1 * ooa0;
	biquad->a2 = b2 * ooa0;
	biquad->b1 = -a1 * ooa0;
	biquad->b2 = -a2 * ooa0;
}
  void
mpl__biquad_ls(mpl__biquad_coeff_t *biquad, float32 omega, float32 dbgain, float32 slope)
{
	float64 sn, cs, be, a, a0, a1, a2, b0, b1, b2, ooa0, ap1, am1;
  	sn  = sin(omega);
	cs  = cos(omega);
	a   = pow(10, dbgain * 0.025);
	ap1 = a + 1;
	am1 = a - 1;
	be  = sqrt((a * a + 1) / slope - am1 * am1);
  	b0 = a * (ap1 - am1 * cs + be * sn);
	b1 = 2* a * (am1 - ap1 * cs);
	b2 = a * (ap1 - am1 * cs - be * sn);
	a0 = ap1 + am1 * cs + be * sn;
	a1 = -2 * (am1 + ap1 * cs);
	a2 = ap1 + am1 * cs - be * sn;
  	ooa0 = 1.0f / a0;
  	biquad->a0 = b0 * ooa0;
	biquad->a1 = b1 * ooa0;
	biquad->a2 = b2 * ooa0;
	biquad->b1 = -a1 * ooa0;
	biquad->b2 = -a2 * ooa0;
}
  void
mpl__biquad_hs(mpl__biquad_coeff_t *biquad, float32 omega, float32 dbgain, float32 slope)
{
	float64 sn, cs, be, a, a0, a1, a2, b0, b1, b2, ooa0, ap1, am1;
  	sn  = sin(omega);
	cs  = cos(omega);
	a   = pow(10, dbgain * 0.025);
	ap1 = a + 1;
	am1 = a - 1;
	be  = sqrt((a * a + 1) / slope - am1 * am1);
  	b0 = a * (ap1 + am1 * cs + be * sn);
	b1 = -2 * a * (am1 + ap1 * cs);
	b2 = a * (ap1 + am1 * cs - be * sn);
	a0 = ap1 - am1 * cs + be * sn;
	a1 = 2 * (am1 - ap1 * cs);
	a2 = ap1 - am1 * cs - be * sn;
  	ooa0 = 1.0f / a0;
  	biquad->a0 = b0 * ooa0;
	biquad->a1 = b1 * ooa0;
	biquad->a2 = b2 * ooa0;
	biquad->b1 = -a1 * ooa0;
	biquad->b2 = -a2 * ooa0;
}
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/src/mpl/snddev.c] - (7,285 bytes)
 
 #include <mpl/snddev.h>
  // dev
int
mpl__snd_dev_set_vol(mpl__snd_dev_t *dev, float32 vol, float32 pan_lr, float32 pan_fb)
{
	return dev->set_vol(dev->internal_data, vol, pan_lr, pan_fb);
}
  int
mpl__snd_dev_get_vol(mpl__snd_dev_t *dev, float32 *vol, float32 *pan_lr, float32 *pan_fb)
{
	return dev->get_vol(dev->internal_data, vol, pan_lr, pan_fb);
}
  int
mpl__snd_dev_set_output_options(mpl__snd_dev_t *dev, mpl__snd_dev_output_t opt)
{
	return dev->set_output_options(dev->internal_data, opt);
}
  int
mpl__snd_dev_get_output_options(mpl__snd_dev_t *dev, mpl__snd_dev_output_t *opt)
{
	return dev->get_output_options(dev->internal_data, opt);
}
  int
mpl__snd_dev_set_latency(mpl__snd_dev_t *dev, int latency)
{
	return dev->set_latency(dev->internal_data, latency);
}
  int
mpl__snd_dev_get_latency(mpl__snd_dev_t *dev)
{
	return dev->get_latency(dev->internal_data);
}
  int
mpl__snd_dev_set_option(mpl__snd_dev_t *dev, char *option, char *value)
{
	return dev->set_option(dev->internal_data, option, value);
}
  int
mpl__snd_dev_get_option(mpl__snd_dev_t *dev, char *option, char **value)
{
	return dev->get_option(dev->internal_data, option, value);
}
  int
mpl__snd_dev_get_proc(mpl__snd_dev_t *dev, char *name, void_func_t *proc)
{
	return dev->get_proc(dev->internal_data, name, proc);
}
  int
mpl__snd_dev_create_mixer(mpl__snd_dev_t *dev, mpl__snd_mixer_t **mixer, mpl__snd_mixer_opt_t opt)
{
	return dev->create_mixer(dev->internal_data, mixer, opt);
}
  int
mpl__snd_dev_destroy_mixer(mpl__snd_dev_t *dev, mpl__snd_mixer_t *mixer)
{
	return dev->destroy_mixer(dev->internal_data, mixer);
}
  int
mpl__snd_dev_create_stream(mpl__snd_dev_t *dev, mpl__snd_stream_t **stream, mpl__snd_stream_opt_t opt)
{
	return dev->create_stream(dev->internal_data, stream, opt);
}
  int
mpl__snd_dev_destroy_stream(mpl__snd_dev_t *dev, mpl__snd_stream_t *stream)
{
	return dev->destroy_stream(dev->internal_data, stream);
}
  // mixer
int
mpl__snd_mixer_reset(mpl__snd_mixer_t *mixer)
{
	return mixer->reset(mixer->internal_data);
}
  int
mpl__snd_mixer_pause(mpl__snd_mixer_t *mixer)
{
	return mixer->pause(mixer->internal_data);
}
  int
mpl__snd_mixer_stop(mpl__snd_mixer_t *mixer)
{
	return mixer->stop(mixer->internal_data);
}
  int
mpl__snd_mixer_upload_sample(mpl__snd_mixer_t *mixer, mpl__snd_mixer_smp_t sample)
{
	return mixer->upload_sample(mixer->internal_data, sample);
}
  int
mpl__snd_mixer_destroy_sample(mpl__snd_mixer_t *mixer, int handle)
{
	return mixer->destroy_sample(mixer->internal_data, handle);
}
  int
mpl__snd_mixer_set_vol(mpl__snd_mixer_t *mixer, float32 vol, float32 pan_lr, float32 pan_fb)
{
 	return mixer->set_vol(mixer->internal_data, vol, pan_lr, pan_fb);
}
  int
mpl__snd_mixer_get_vol(mpl__snd_mixer_t *mixer, float32 *vol, float32 *pan_lr, float32 *pan_fb)
{
	return mixer->get_vol(mixer->internal_data, vol, pan_lr, pan_fb);
}
  int
mpl__snd_mixer_get_output_options(mpl__snd_mixer_t *mixer, mpl__snd_dev_output_t *opt)
{
	return mixer->get_output_options(mixer->internal_data, opt);
}
  int
mpl__snd_mixer_get_latency(mpl__snd_mixer_t *mixer)
{
	return mixer->get_latency(mixer->internal_data);
}
  int
mpl__snd_mixer_get_num_channels(mpl__snd_mixer_t *mixer)
{
	return mixer->get_num_channels(mixer->internal_data);
}
  int
mpl__snd_mixer_get_num_active_channels(mpl__snd_mixer_t *mixer)
{
	return mixer->get_num_active_channels(mixer->internal_data);
}
  int
mpl__snd_mixer_get_free_channel(mpl__snd_mixer_t *mixer)
{
	return mixer->get_free_channel(mixer->internal_data);
}
  int
mpl__snd_mixer_is_channel_active(mpl__snd_mixer_t *mixer, int ch)
{
	return mixer->is_channel_active(mixer->internal_data, ch);
}
  int
mpl__snd_mixer_set_channel_vol(mpl__snd_mixer_t *mixer, int ch, float32 vol, float32 pan_lr, float32 pan_fb)
{
	return mixer->set_channel_vol(mixer->internal_data, ch, vol, pan_lr, pan_fb);
}
  int
mpl__snd_mixer_set_channel_freq(mpl__snd_mixer_t *mixer, int ch, float freq)
{
	return mixer->set_channel_freq(mixer->internal_data, ch, freq);
}
  int
mpl__snd_mixer_set_channel_pos(mpl__snd_mixer_t *mixer, int ch, double pos, int dir)
{
	return mixer->set_channel_pos(mixer->internal_data, ch, pos, dir);
}
  int
mpl__snd_mixer_play_channel(mpl__snd_mixer_t *mixer, int ch, int handle, float32 freq, float32 vol, float32 pan_lr, float32 pan_fb, float64 pos, int dir)
{
	return mixer->play_channel(mixer->internal_data, ch, handle, freq, vol, pan_lr, pan_fb, pos, dir);
}
  int
mpl__snd_mixer_stop_channel(mpl__snd_mixer_t *mixer, int ch)
{
	return mixer->stop_channel(mixer->internal_data, ch);
}
  int
mpl__snd_mixer_set_option(mpl__snd_mixer_t *mixer, char *option, char *value)
{
	return mixer->set_option(mixer->internal_data, option, value);
}
  int
mpl__snd_mixer_get_option(mpl__snd_mixer_t *mixer, char *option, char **value)
{
	return mixer->get_option(mixer->internal_data, option, value);
}
  int
mpl__snd_mixer_get_proc(mpl__snd_mixer_t *mixer, char *name, void_func_t *proc)
{
	return mixer->get_proc(mixer->internal_data, name, proc);
}
  int
mpl__snd_mixer_set_call_back(mpl__snd_mixer_t *mixer, mpl__snd_call_back_t call_back)
{
	return mixer->set_call_back(mixer->internal_data, call_back);
}
  // stream
int
mpl__snd_stream_set_vol(mpl__snd_stream_t *stream, float32 vol, float32 pan_lr, float32 pan_fb)
{
	return stream->set_vol(stream->internal_data, vol, pan_lr, pan_fb);
}
  int
mpl__snd_stream_get_vol(mpl__snd_stream_t *stream, float32 *vol, float32 *pan_lr, float32 *pan_fb)
{
	return stream->get_vol(stream->internal_data, vol, pan_lr, pan_fb);
}
  int
mpl__snd_stream_get_output_options(mpl__snd_stream_t *stream, mpl__snd_dev_output_t *opt)
{
	return stream->get_output_options(stream->internal_data, opt);
}
  int
mpl__snd_stream_set_input_format(mpl__snd_stream_t *stream, mpl__snd_stream_format_t *opt)
{
	return stream->set_input_format(stream->internal_data, opt);
}
  int
mpl__snd_stream_get_input_format(mpl__snd_stream_t *stream, mpl__snd_stream_format_t *opt)
{
	return stream->get_input_format(stream->internal_data, opt);
}
  int
mpl__snd_stream_get_latency(mpl__snd_stream_t *stream)
{
	return stream->get_latency(stream->internal_data);
}
  int
mpl__snd_stream_get_buffer_size(mpl__snd_stream_t *stream)
{
	return stream->get_buffer_size(stream->internal_data);
}
  int
mpl__snd_stream_set_option(mpl__snd_stream_t *stream, char *option, char *value)
{
	return stream->set_option(stream->internal_data, option, value);
}
  int
mpl__snd_stream_get_option(mpl__snd_stream_t *stream, char *option, char **value)
{
	return stream->get_option(stream->internal_data, option, value);
}
  int
mpl__snd_stream_get_proc(mpl__snd_stream_t *stream, char *name, void_func_t *proc)
{
	return stream->get_proc(stream->internal_data, name, proc);
}
  int
mpl__snd_stream_write(mpl__snd_stream_t *stream, void *data, int length)
{
	return stream->write(stream->internal_data, data, length);
}
  int
mpl__snd_stream_set_call_back(mpl__snd_stream_t *stream, mpl__snd_call_back_t call_back)
{
	return stream->set_call_back(stream->internal_data, call_back);
}
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/src/mpl/ml.c] - (910 bytes)
 
 #include <mpl/ml.h>
  int
mpl__ml_load(mpl__ml_t *ml, vbf_t *file, mpl__md_t **md)
{
	return ml->load(ml->internal_data, file, md);
}
  int
mpl__ml_destroy(mpl__ml_t *ml, mpl__md_t *md)
{
	return ml->destroy(ml->internal_data, md);
}
  int
mpl__ml_create_mp(mpl__ml_t *ml, mpl__md_t *md, mpl__msg_box_t *mb, mpl__mp_t **mp)
{
	return ml->create_mp(ml->internal_data, md, mb, mp);
}
  int
mpl__ml_destroy_mp(mpl__ml_t *ml, mpl__mp_t **mp)
{
	return ml->destroy_mp(ml->internal_data, mp);
}
  int
mpl__ml_set_option(mpl__ml_t *ml, char *option, char *value)
{
	return ml->set_option(ml->internal_data, option, value);
}
  int
mpl__ml_get_option(mpl__ml_t *ml, char *option, char **value)
{
	return ml->get_option(ml->internal_data, option, value);
}
  int
mpl__ml_get_proc(mpl__ml_t *ml, char *name, void_func_t *proc)
{
	return ml->get_proc(ml->internal_data, name, proc);
}
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/src/mpl/mp.c] - (1,274 bytes)
 
 #include <mpl/mp.h>
  int
mpl__mp_set_dev(mpl__mp_t *mp, mpl__snd_dev_t *dev)
{
	return mp->set_dev(mp->internal_data, dev);
}
  int
mpl__mp_reset(mpl__mp_t *mp)
{
	return mp->reset(mp->internal_data);
}
  int
mpl__mp_play(mpl__mp_t *mp)
{
	return mp->play(mp->internal_data);
}
  int
mpl__mp_stop(mpl__mp_t *mp)
{
	return mp->stop(mp->internal_data);
}
  int
mpl__mp_set_loop(mpl__mp_t *mp, int loop)
{
	return mp->set_loop(mp->internal_data, loop);
}
  int
mpl__mp_set_pos(mpl__mp_t *mp, int pos)
{
	return mp->set_pos(mp->internal_data, pos);
}
  int
mpl__mp_get_pos(mpl__mp_t *mp)
{
	return mp->get_pos(mp->internal_data);
}
  int
mpl__mp_set_vol(mpl__mp_t *mp, float32 vol)
{
	return mp->set_vol(mp->internal_data, vol);
}
  int
mpl__mp_get_vol(mpl__mp_t *mp, float32 *vol)
{
	return mp->get_vol(mp->internal_data, vol);
}
  int
mpl__mp_set_option(mpl__mp_t *mp, char *option, char *value)
{
	return mp->set_option(mp->internal_data, option, value);
}
  int
mpl__mp_get_option(mpl__mp_t *mp, char *option, char **value)
{
	return mp->get_option(mp->internal_data, option, value);
}
  int
mpl__mp_get_proc(mpl__mp_t *mp, char *name, void_func_t *proc)
{
	return mp->get_proc(mp->internal_data, name, proc);
}
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/src/mpl/mx.c] - (1,129 bytes)
 
 #include <mpl/mx.h>
  int
mpl__mixer_set_output_options(mpl__mixer_t *mx, mpl__snd_dev_output_t *opt, int latency)
{
	return mx->set_output_options(mx->internal_data, opt, latency);
}
  int
mpl__mixer_set_options(mpl__mixer_t *mx, mpl__mixer_opt_t *opt)
{
	return mx->set_options(mx->internal_data, opt);
}
  int
mpl__mixer_get_options(mpl__mixer_t *mx, mpl__mixer_opt_t *opt)
{
	return mx->get_options(mx->internal_data, opt);
}
  int
mpl__mixer_get_proc(mpl__mixer_t *mx, char *name, void_func_t *func)
{
	return mx->get_proc(mx->internal_data, name, func);
}
  int 
mpl__mixer_get_interface(mpl__mixer_t *mx, mpl__snd_mixer_t **mixer)
{
	return mx->get_interface(mx->internal_data, mixer);
}
  int
mpl__mixer_set_vol(mpl__mixer_t *mx, float32 vol, float32 pan_lr, float32 pan_fb)
{
	return mx->set_vol(mx->internal_data, vol, pan_lr, pan_fb);
}
  int
mpl__mixer_mix(mpl__mixer_t *mx, void *buffer, int length)
{
	return mx->mix(mx->internal_data, buffer, length);
}
  int
mpl__mixer_get_num_active_channels(mpl__mixer_t *mx)
{
	return mx->get_num_active_channels(mx->internal_data);
}
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/src/mpl/dsp_std.c] - (3,679 bytes)
 
 #include <mpl/dsp_std.h>
#include <mpl/sys/mem.h>
  /*
	to do
	-----
      - optimize (especially 24 bit adding)
	- dsp_convert_format() -> 24_bit
    - dsp_resample()
*/
  int
mpl__dsp_add(void *src, void *dst, int size, int ch_num, float32 vol, int format)
{
	int num;
  	num = size * ch_num;
  	switch(format)
	{
	case MPL__SND_DEV_FMT_8BIT:
		while(num--)
		{
			((i8*)dst)[num] += (i8) (((i8*)src)[num] * vol);
		}
		break;
	case MPL__SND_DEV_FMT_16BIT:
		while(num--)
		{
			((i16*)dst)[num] += (i16) (((i16*)src)[num] * vol);
		}
		break;
	case MPL__SND_DEV_FMT_24BIT:
		while(num--)
		{
//			*((i32*)dst) = ((*((i32*)dst) & 0xffffff) + (i32)((*((i32*)src) & 0xffffff) * vol)) & 0xffffff;
//			((i8*)src) += 3;
//			((i8*)dst) += 3;
		}
		break;
	case MPL__SND_DEV_FMT_32BIT:
		while(num--)
		{
			((i32*)dst)[num] += (i32) (((i32*)src)[num] * vol);
		}
		break;
	case MPL__SND_DEV_FMT_FLOAT_32BIT:
		while(num--)
		{
			((float32*)dst)[num] += ((float32*)src)[num] * vol;
		}
		break;
	default:
		return -1;
	}
  	return 0;
}
  int
mpl__dsp_sub(void *src, void *dst, int size, int ch_num, float32 vol, int format)
{
	return mpl__dsp_add(src, dst, size, ch_num, -vol, format);
}
  int
mpl__dsp_move(void *src, void *dst, int size, int ch_num, float32 vol, int format)
{
	switch(format)
	{
	case MPL__SND_DEV_FMT_8BIT:
		break;
	case MPL__SND_DEV_FMT_16BIT:
		size *= 2;
		break;
	case MPL__SND_DEV_FMT_24BIT:
		size *= 3;
		break;
	case MPL__SND_DEV_FMT_32BIT:
		size *= 4;
		break;
	case MPL__SND_DEV_FMT_FLOAT_32BIT:
		size *= 4;
		break;
	default:
		return -1;
	}
  	size *= ch_num;
  	mpl__mem_copy(src, dst, size);
  	return 0;
}
  int
mpl__dsp_conv_format(void *src, void *dst, int src_format, int dst_format, int size, int ch_num, float32 vol)
{
	float32 *buf;
    int cnt;
 
    if (dst_format != MPL__SND_DEV_FMT_FLOAT_32BIT)
    {
        if (mpl__mem_alloc(4 * size * ch_num, (void**)&buf) < MPL__ERR_OK)
        {
             return MPL__ERR_NOMEM;
        }
    }
    else
    {
        buf = (float32*) dst;
    }
      cnt = size * ch_num;
  	switch(src_format)
	{
	case MPL__SND_DEV_FMT_8BIT:
        vol *= 1.0f / 256.0f;
		while(cnt--)
		{
			buf[cnt] = ((i8*)src)[cnt] * vol;
		}
		break;
	case MPL__SND_DEV_FMT_16BIT:
        vol *= 1.0f / 65536.0f;
		while(cnt--)
		{
			buf[cnt] = ((i16*)src)[cnt] * vol;
		}
		break;
	case MPL__SND_DEV_FMT_24BIT:
/*        vol *= 1.0f / 16777216.0f;
		while(cnt--)
		{
			buf[cnt] = (((i32*)src)[cnt] & 0xffffff) * vol;
  			((i8*)src) += 3;
		}*/
		break;
	case MPL__SND_DEV_FMT_32BIT:
        vol *= 1.0f / 4294967296.0f;
		while(cnt--)
		{
			buf[cnt] = ((i32*)src)[cnt] * vol;
		}
		break;
	case MPL__SND_DEV_FMT_FLOAT_32BIT:
		while(cnt--)
		{
			buf[cnt] = ((float32*)src)[cnt] * vol;
		}
		break;
	}
      if (dst_format == MPL__SND_DEV_FMT_FLOAT_32BIT)
    {
        return MPL__ERR_OK;
    }
      cnt = size * ch_num;
  	switch(dst_format)
	{
	case MPL__SND_DEV_FMT_8BIT:
        vol = 256.0f;
		while(cnt--)
		{
			((i8*)dst)[cnt] = (i8)(buf[cnt] * vol);
		}
		break;
	case MPL__SND_DEV_FMT_16BIT:
        vol = 65536.0f;
		while(cnt--)
		{
			((i16*)dst)[cnt] = (i16)(buf[cnt] * vol);
		}
		break;
	case MPL__SND_DEV_FMT_24BIT:
        vol = 16777216.0f;
		while(cnt--)
		{
            // how to implement it portable?!?
		}
		break;
	case MPL__SND_DEV_FMT_32BIT:
        vol = 4294967296.0f;
		while(cnt--)
		{
			((i32*)dst)[cnt] = (i32)(buf[cnt] * vol);
		}
		break;
	}
  	mpl__mem_free(buf);
  	return MPL__ERR_OK;
}
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/src/mpl/string.c] - (486 bytes)
 
 #include <mpl/string.h>
  int
mpl__string_cmp_char(char *str1, char *str2)
{
	while(*str2 != '\0' && *str1 == *str2)
	{
		str1++;
		str2++;
	}
  	if (*str1 == *str2)
	{
		return MPL__STRING_EQUAL;
	}
  	return MPL__STRING_UNEQUAL;
}
  int
mpl__string_cmp_wide_char(wide_char *str1, wide_char *str2)
{
	while(*str2 != '\0' && *str1 == *str2)
	{
		str1++;
		str2++;
	}
  	if (*str1 == *str2)
	{
		return MPL__STRING_EQUAL;
	}
  	return MPL__STRING_UNEQUAL;
}
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/src/mpl/sd_std.c] - (3,381 bytes)
 
 #include <mpl/sd_std.h>
#include <mpl/sys/mem.h>
  static int cmd_set_vol(void *data, float32 vol, float32 pan_lr, float32 pan_fb);
static int cmd_get_vol(void *data, float32 *vol, float32 *pan_lr, float32 *pan_fb);
static int cmd_set_output_options(void *data, mpl__snd_dev_output_t opt);
static int cmd_get_output_options(void *data, mpl__snd_dev_output_t *opt);
static int cmd_set_latency(void *data, int latency);
static int cmd_get_latency(void *data);
static int cmd_set_option(void *data, char *option, char *value);
static int cmd_get_option(void *data, char *option, char **value);
static int cmd_get_proc(void *data, char *name, void_func_t *proc);
static int cmd_create_mixer(void *data, mpl__snd_mixer_t **mixer, mpl__snd_mixer_opt_t opt);
static int cmd_destroy_mixer(void *data, mpl__snd_mixer_t *mixer);
static int cmd_create_stream(void *data, mpl__snd_stream_t **stream, mpl__snd_stream_opt_t opt);
static int cmd_destroy_stream(void *data, mpl__snd_stream_t *stream);
  static int
cmd_set_vol(void *data, float32 vol, float32 pan_lr, float32 pan_fb)
{
	return MPL__ERR_GENERIC;
}
  static int
cmd_get_vol(void *data, float32 *vol, float32 *pan_lr, float32 *pan_fb)
{
	return MPL__ERR_GENERIC;
}
  static int
cmd_set_output_options(void *data, mpl__snd_dev_output_t opt)
{
	return MPL__ERR_GENERIC;
}
  static int
cmd_get_output_options(void *data, mpl__snd_dev_output_t *opt)
{
	return MPL__ERR_GENERIC;
}
  static int
cmd_set_latency(void *data, int latency)
{
	return MPL__ERR_GENERIC;
}
  static int
cmd_get_latency(void *data)
{
	return MPL__ERR_GENERIC;
}
  static int
cmd_set_option(void *data, char *option, char *value)
{
	return MPL__ERR_GENERIC;
}
  static int
cmd_get_option(void *data, char *option, char **value)
{
	return MPL__ERR_GENERIC;
}
  static int
cmd_get_proc(void *data, char *name, void_func_t *proc)
{
	return MPL__ERR_GENERIC;
}
  static int
cmd_create_mixer(void *data, mpl__snd_mixer_t **mixer, mpl__snd_mixer_opt_t opt)
{
	return MPL__ERR_GENERIC;
}
  static int
cmd_destroy_mixer(void *data, mpl__snd_mixer_t *mixer)
{
	return MPL__ERR_GENERIC;
}
  static int
cmd_create_stream(void *data, mpl__snd_stream_t **stream, mpl__snd_stream_opt_t opt)
{
	return MPL__ERR_GENERIC;
}
  static int
cmd_destroy_stream(void *data, mpl__snd_stream_t *stream)
{
	return MPL__ERR_GENERIC;
}
  int
mpl__sd_std_create(mpl__snd_dev_t **sd, int  (*mx_create)(mpl__mixer_t **mixer), void (*mx_destroy)(mpl__mixer_t *mixer))
{
	int result;
  	result = mpl__mem_alloc(sizeof(mpl__snd_dev_t), (void**)sd);
  	if (result < MPL__ERR_OK)
	{
		return result;
	}
  	(*sd)->create_mixer       = cmd_create_mixer;
	(*sd)->create_stream      = cmd_create_stream;
	(*sd)->destroy_mixer      = cmd_destroy_mixer;
	(*sd)->destroy_stream     = cmd_destroy_stream;
	(*sd)->get_latency        = cmd_get_latency;
	(*sd)->get_option         = cmd_get_option;
	(*sd)->get_output_options = cmd_get_output_options;
	(*sd)->get_proc           = cmd_get_proc;
	(*sd)->get_vol            = cmd_get_vol;
	(*sd)->set_latency        = cmd_set_latency;
	(*sd)->set_option         = cmd_set_option;
	(*sd)->set_output_options = cmd_set_output_options;
	(*sd)->set_vol            = cmd_set_vol;
  	return MPL__ERR_GENERIC;
}
  void
mpl__sd_std_destroy(mpl__snd_dev_t *sd)
{
}
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/src/mpl/ml_xm.c] - (9,603 bytes)
 
 #include <mpl/sys/mem.h>
#include <mpl/ml_xm.h>
  static int
clip_to(int value, int min, int max)
{
	if (value < min)
	{
		return min;
	}
  	if (value > max)
	{
		return max;
	}
  	return value;
}
  int
mpl__xm_destruct(mpl__xm_t *xm)
{
	int cnt1, cnt2;
  	if (xm)
	{
		if (xm->inst)
		{
			for(cnt1 = 0; cnt1 < xm->inst_num; cnt1++)
			{
				if (xm->inst[cnt1].smp_num)
				{
					for(cnt2 = 0; cnt2 < xm->inst[cnt1].smp_num; cnt2++)
					{
						if (xm->inst[cnt1].smp[cnt2].data)
						{
							mpl__mem_free(xm->inst[cnt1].smp[cnt2].data);
						}
					}
  					mpl__mem_free(xm->inst[cnt1].smp);
				}
			}
  			mpl__mem_free(xm->inst);
		}
  		if (xm->pat_num)
		{
			for(cnt1 = 0; cnt1 < xm->pat_num; cnt1++)
			{
				if (xm->pat[cnt1])
				{
					mpl__mem_free(xm->pat[cnt1]);
				}
			}
		}
	}
  	return 0;
}
  #define return_false(err) { mpl__xm_destruct(xm); return err; }
#define seek_to(a)	{if (vbf_seek_beg(file, a) < 0) return_false(MPL__ERR_GENERIC);}
#define read_i8() {if (vbf_read_i8(file, VBF_SMALL_ENDIAN, &tmp_i8) < 0) return_false(MPL__ERR_GENERIC);}
#define read_u8() {if (vbf_read_u8(file, VBF_SMALL_ENDIAN, &tmp_u8) < 0) return_false(MPL__ERR_GENERIC);}
#define read_u16() {if (vbf_read_u16(file, VBF_SMALL_ENDIAN, &tmp_u16) < 0) return_false(MPL__ERR_GENERIC);}
#define read_u32() {if (vbf_read_u32(file, VBF_SMALL_ENDIAN, &tmp_u32) < 0) return_false(MPL__ERR_GENERIC);}
  int
mpl__xm_load(vbf_t *file, mpl__xm_t *xm)
{
	int mode, attr;
	u8 ID[] = "Extended Module: ", raw[32], tmp_u8;
	i8 tmp_i8;
	u16 tmp_u16;
	u32 tmp_u32;
	vbf_size_t tmp_size, pos;
	u32 h_size, packed_pat_size, ctrl, smp_index;
	i32 cnt1, cnt2, cnt3;
	mpl__xm_sample_t *smp;
	mpl__xm_inst_t *inst;
  	if (vbf_mode(file, &mode) < 0)
	{
		return MPL__ERR_GENERIC;
	}
  	attr = VBF_ATTR_OPEN | VBF_ATTR_READ | VBF_ATTR_LENGTH | VBF_ATTR_SEEK;
  	if ((mode & attr) != attr)
	{
		return MPL__ERR_GENERIC;
	}
	
	mpl__mem_set_zero(xm, sizeof(mpl__xm_t));
  	seek_to(0);
  	if (vbf_read(file, raw, 17, &tmp_size) < 0 || tmp_size < 17)
	{
		return MPL__ERR_GENERIC;
	}
  	for(cnt1 = 0; cnt1 < 17; cnt1++)
	{
		if (raw[cnt1] != ID[cnt1])
		{
			return MPL__ERR_GENERIC;
		}
	}
  	seek_to(37);
  	read_u8();
  	if (tmp_u8 != 0x1A)
	{
		return_false(MPL__ERR_GENERIC);
	}
  //	to do
//	if (vbf_read_u16(vbf, VBF_SMALL_ENDIAN, tmp_u16) < 0 || tmp_u16 != 0x104)
//	{
//		return_false;
//	}
	seek_to(17);
  	if (vbf_read(file, xm->title, 20, &tmp_size) < 0 || tmp_size < 20)
	{
		return_false(MPL__ERR_GENERIC);
	}
  	xm->title[20] = 0;
  	if (vbf_seek_beg(file, 38) < 0)
	{
		return_false(MPL__ERR_GENERIC);
	}
  	if (vbf_read(file, xm->tracker, 20, &tmp_size) < 0 || tmp_size < 20)
	{
		return_false(MPL__ERR_GENERIC);
	}
  	xm->tracker[20] = 0;
  	seek_to(60);
	read_u32();
	h_size = tmp_u32;
  	read_u16();
	xm->length      = tmp_u16;
	read_u16();
	xm->restart_pos = tmp_u16;
	read_u16();
	xm->ch_num      = tmp_u16;
	read_u16();
	xm->pat_num     = tmp_u16;
	read_u16();
	xm->inst_num    = tmp_u16;
	read_u8();
	xm->freq_table  = tmp_u8 & 1;
	read_u8();
	read_u16();
	xm->speed       = tmp_u16;
	read_u16();
	xm->bpm         = tmp_u16;
  	seek_to(80);
  	for(cnt1 = 0; cnt1 < 256; cnt1++)
	{
		read_u8();
		xm->order[cnt1] = tmp_u8;
	}
  	pos = 60 + h_size;
	seek_to(pos);
  	for(cnt1 = 0; cnt1 < xm->pat_num; cnt1++)
	{
		read_u32();
		h_size = tmp_u32;
		read_u8();
		read_u16();
		xm->pat_length[cnt1] = tmp_u16;
		read_u16();
		packed_pat_size = tmp_u16;
  		if (mpl__mem_alloc(xm->pat_length[cnt1] * xm->ch_num * sizeof(mpl__xm_cell_t),
			(void**)&xm->pat[cnt1]) <= MPL__ERR_GENERIC)
		{
			return_false(MPL__ERR_NOMEM);
		}
		pos += h_size;
		seek_to(pos);
  		if (!packed_pat_size)
		{
			for(cnt2 = 0; cnt2 < xm->pat_length[cnt1] * xm->ch_num; cnt2++)
			{
					xm->pat[cnt1][cnt2].key    = MPL__XM_NO_NOTE;
					xm->pat[cnt1][cnt2].inst   = 0;
					xm->pat[cnt1][cnt2].volume = 0;
					xm->pat[cnt1][cnt2].effect = 0;
					xm->pat[cnt1][cnt2].param  = 0;
			}
		}
		else
		{
			for(cnt2 = 0; cnt2 < xm->pat_length[cnt1] * xm->ch_num; cnt2++)
			{
				read_u8();
				ctrl = tmp_u8;
  				if (ctrl & 0x80)
				{
					if (ctrl & 1) { read_u8(); } else { tmp_u8 = MPL__XM_NO_NOTE; }
					xm->pat[cnt1][cnt2].key    = tmp_u8 && tmp_u8 < MPL__XM_NO_NOTE ? tmp_u8 : MPL__XM_NO_NOTE;
					if (ctrl & 2) { read_u8(); } else { tmp_u8 = 0; }
					xm->pat[cnt1][cnt2].inst   = tmp_u8;
					if (ctrl & 4) { read_u8(); } else { tmp_u8 = 0; }
					xm->pat[cnt1][cnt2].volume = tmp_u8;
					if (ctrl & 8) { read_u8(); } else { tmp_u8 = 0; }
					xm->pat[cnt1][cnt2].effect = tmp_u8;
					if (ctrl & 16) { read_u8(); } else { tmp_u8 = 0; }
					xm->pat[cnt1][cnt2].param  = tmp_u8;
				}
				else
				{
					xm->pat[cnt1][cnt2].key    = ctrl && ctrl < MPL__XM_NO_NOTE ? ctrl : MPL__XM_NO_NOTE;
					read_u8();
					xm->pat[cnt1][cnt2].inst   = tmp_u8;
					read_u8();
					xm->pat[cnt1][cnt2].volume = tmp_u8;
					read_u8();
					xm->pat[cnt1][cnt2].effect = tmp_u8;
					read_u8();
					xm->pat[cnt1][cnt2].param  = tmp_u8;
				}
			}
		}
  		pos += packed_pat_size;
		seek_to(pos);
	}
  	if (mpl__mem_alloc(sizeof(mpl__xm_inst_t) * xm->inst_num, (void**)&xm->inst) <= MPL__ERR_GENERIC)
	{
		return_false(MPL__ERR_NOMEM);
	}
  	mpl__mem_set_zero(xm->inst, sizeof(mpl__xm_inst_t) * xm->inst_num);
  	smp_index = 0;
  	for(cnt1 = 0; cnt1 < xm->inst_num; cnt1++)
	{
		vbf_tell(file, &pos);
  		read_u32();
		h_size = tmp_u32;
  		inst = xm->inst + cnt1;
  		if (vbf_read(file, inst->name, 22, &tmp_size) < 0 || tmp_size < 22) return_false(MPL__ERR_GENERIC);
		inst->name[22] = 0;
  		read_u8();
		read_u16();
		inst->smp_num = tmp_u16;
  		if (inst->smp_num)
		{
			read_u32();
			for(cnt2 = 0; cnt2 < 96; cnt2++)
			{
				read_u8();
				inst->note2smp[cnt2] = tmp_u8;
			}
  			for(cnt2 = 0; cnt2 < 12; cnt2++)
			{
				read_u16();
				inst->vol_env[cnt2].x = tmp_u16;
				read_u16();
				inst->vol_env[cnt2].y = tmp_u16;
			}
  			for(cnt2 = 0; cnt2 < 12; cnt2++)
			{
				read_u16();
				inst->pan_env[cnt2].x = tmp_u16;
				read_u16();
				inst->pan_env[cnt2].y = tmp_u16;
			}
  			read_u8();
			inst->vol_num      = tmp_u8;
			read_u8();
			inst->pan_num      = tmp_u8;
			read_u8();
			inst->vol_sus      = tmp_u8;
			read_u8();
			inst->vol_loop_beg = tmp_u8;
			read_u8();
			inst->vol_loop_end = tmp_u8;
			read_u8();
			inst->pan_sus      = tmp_u8;
			read_u8();
			inst->pan_loop_beg = tmp_u8;
			read_u8();
			inst->pan_loop_end = tmp_u8;
			read_u8();
			inst->vol_type     = tmp_u8;
			read_u8();
			inst->pan_type     = tmp_u8;
  			read_u8();
			inst->vib_type     = tmp_u8;
			read_u8();
			inst->vib_sweep    = tmp_u8;
			read_u8();
			inst->vib_depth    = tmp_u8;
			read_u8();
			inst->vib_rate     = tmp_u8;
  			read_u16();
			inst->vol_fade_out = 2 * tmp_u16;
		}
  		pos += h_size;
		seek_to(pos);
  		if (inst->smp_num)
		{
			if (mpl__mem_alloc(sizeof(mpl__xm_sample_t) * inst->smp_num, (void**)&inst->smp) <= MPL__ERR_GENERIC)
			{
				return_false(MPL__ERR_NOMEM);
			}
  			mpl__mem_set_zero(inst->smp, sizeof(mpl__xm_sample_t) * inst->smp_num);
		}
  		for(cnt2 = 0; cnt2 < inst->smp_num; cnt2++)
		{
			smp = inst->smp + cnt2;
  			read_u32();
			smp->length = tmp_u32;
			read_u32();
			smp->loop_begin = tmp_u32;
			read_u32();
			smp->loop_end = tmp_u32;
  			if (smp->loop_begin >= smp->length)
			{
				smp->loop_begin = 0;
			}
  			smp->loop_end += smp->loop_begin;
  			if (smp->loop_end > smp->length)
			{
				smp->loop_end = smp->length;
			}
  			read_u8();
			smp->vol = tmp_u8;
			read_i8();
			smp->finetune = tmp_i8;
			read_u8();
			smp->format = tmp_u8;
			read_u8();
			smp->pan = tmp_u8;
			read_i8();
			smp->rel_note = tmp_i8;
  			if (smp->loop_begin == smp->loop_end)
			{
				smp->format &= ~(MPL__XM_SMP_LOOP | MPL__XM_SMP_BIDI_LOOP);
			}
  			if (smp->format & MPL__XM_SMP_16BIT)
			{
				smp->length     >>= 1;
				smp->loop_begin >>= 1;
				smp->loop_end   >>= 1;
			}
  			read_u8();
  			if (vbf_read(file, smp->name, 22, &tmp_size) < 0 || tmp_size < 22)
			{
				return_false(MPL__ERR_GENERIC);
			}
  			smp->name[22] = 0;
  			smp->index = smp_index++;
  			if (smp->index >= 300)
			{
				return_false(MPL__ERR_GENERIC);
			}
		}
  		for(cnt2 = 0; cnt2 < inst->smp_num; cnt2++)
		{
			smp = inst->smp + cnt2;
  			if (smp->length == 0)
			{
				continue;
			}
  			if (mpl__mem_alloc(smp->length * (1 + (smp->format & MPL__XM_SMP_16BIT ? 1 : 0)), &smp->data) <= MPL__ERR_GENERIC)
			{
				return_false(MPL__ERR_NOMEM);
			}
  			if (smp->format & MPL__XM_SMP_16BIT)
			{
				i16 *cur = (i16*)smp->data;
  				if (vbf_read_array_i16(file, VBF_SMALL_ENDIAN, smp->length, cur) < 0)
				{
					return_false(MPL__ERR_GENERIC);
				}
  				for(cnt3 = 1; cnt3 < smp->length; cnt3++)
				{
					cur[cnt3] += cur[cnt3 - 1];
				}
			}
			else
			{
				i8 *cur = (i8*)smp->data;
  				if (vbf_read(file, cur, smp->length, &tmp_size) < 0 || tmp_size < smp->length)
				{
					return_false(MPL__ERR_GENERIC);
				}
  				for(cnt3 = 1; cnt3 < smp->length; cnt3++)
				{
					cur[cnt3] += cur[cnt3 - 1];
				}
			}
		}
	}
  	xm->smp_index_num = smp_index;
  	return MPL__ERR_OK;
}
  #undef return_false
#undef seek_to
#undef read_i8
#undef read_u8
#undef read_u16
#undef read_u32
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/src/mpl/mp_xm.c] - (37,378 bytes)
 
 /*
  bugs
----
  - does MPL__XM_EFF_SMP_OFFSET retrigger?
- cpplay.xm - ahhhhhhhhhh
- crash while playing Enter_the_Merregnon.xm (traxinspace Merregnon compo)
- -27-.xm by floppi -> wrong frequencies
- instrument loading ???
- note delay (btw note delay also has to retrigger if issued with no note!)
- retrig ??
- key off
- do_vol() -> case XM_VOL_EFF_VIB
- note with invalid sample number has to stop current sample
  to do
-----
  - multi threading !!
- new_note()
  
*/
  #include <mpl/sys/mem.h>
#include <mpl/string.h>
#include <mpl/mp_xm.h>
#include <math.h>
  static int sinus_table[32]=
{
  0, 24, 49, 74, 97,120,141,161,
180,197,212,224,235,244,250,253,
255,253,250,244,235,224,212,197,
180,161,141,120, 97, 74, 49, 24
};
  static int mp_cmd_reset(void *internal_data);
  static int
clip_to(int value, int min, int max)
{
	if (value < min)
	{
		return min;
	}
  	if (value > max)
	{
		return max;
	}
  	return value;
}
  static int
linear_note_to_period(int note, int fine_tune)
{
	return (int)(7680.0f - note * 64.0f - fine_tune * 0.5f);
}
  static float32
linear_period_to_freq(int per)
{
	return (float32)(8363.0 * pow(2.0, (4608.0 - per) * 0.00130208333333));
}
  static int
note_to_period(int note, int fine_tune)
{
	float32 period, diff;
  	period = (float32) pow(2.0f, (132.0f - note) * 0.08333333333f) * 13.375f;
  	if (fine_tune < 0 && note)
	{
		diff = period - (float32)pow(2.0f, (132.0f - note + 1) * 0.08333333333f) * 13.375f;
		diff *= (float32)fabs(fine_tune);
		diff /= -128;
	}
	else
	{
		diff = (float32)pow(2.0f, (132.0f - note - 1) * 0.08333333333f) * 13.375f - period;
		diff *= fine_tune;
		diff /= 128;
	}
  	period += diff;
  	return (int)period;
}
  static float32
period_to_freq(int per)
{
	return 14317056.0f / per;
}
  static mpl__xm_cell_t*
get_row(mpl__mp_xm_t *pl)
{
	return pl->xm->pat[pl->xm->order[pl->pat_cur]] + pl->row_cur * pl->xm->ch_num;
}
  static void run_tick(mpl__mp_xm_t *player, int param);
  static void
update_ctrl(mpl__mp_xm_t *pl)
{
	float32 vol, pan, freq;
	mpl__snd_dev_output_t opt;
	mpl__mp_xm_chan_t *p_ch;
	int cur;
  	mpl__snd_mixer_get_output_options(pl->mixer, &opt);
  	for(cur = 0; cur < pl->xm->ch_num; cur++)
	{
  		p_ch = pl->ch + cur;
  		p_ch->active = mpl__snd_mixer_is_channel_active(pl->mixer, cur);
  		if (!p_ch->active & !(p_ch->ctrl & MPL__XM_CTRL_START))
		{
			continue;
		}
  		if (!p_ch->p_smp)
		{
			continue;
		}
  		if (p_ch->ctrl & MPL__XM_CTRL_STOP)
		{
			mpl__snd_mixer_stop_channel(pl->mixer, cur);
  			p_ch->active = 0;
			p_ch->ctrl = 0;
  			continue;
		}
  
		if (p_ch->ctrl & (MPL__XM_CTRL_START | MPL__XM_CTRL_VOL))
		{
			p_ch->vol = clip_to(p_ch->vol, 0, 64);
  			vol = (float32)clip_to(p_ch->vol + p_ch->vol_delta, 0, 128);
			vol = vol * p_ch->env_vol * p_ch->fade_out_vol;
			vol = vol * (1.0f / (64.0f * 65536.0f * 64.0f));
  			p_ch->pan = clip_to(p_ch->pan, 0, 255);
  			pan = clip_to(p_ch->pan + p_ch->pan_delta + (p_ch->env_pan << 2) - 128, 16, 239) * (1.0f / 255.0f);
		}
	
		if (p_ch->ctrl & (MPL__XM_CTRL_START | MPL__XM_CTRL_PER))
		{
			p_ch->per = clip_to(p_ch->per, 56, 100000);
  
			if (pl->xm->freq_table & MPL__XM_FREQ_TABLE_LINEAR)
			{
				freq = linear_period_to_freq(clip_to(p_ch->per + p_ch->per_delta, 56, 100000));
			}
			else
			{
				freq = period_to_freq(clip_to(p_ch->per + p_ch->per_delta, 56, 100000));
			}
  			if (freq < 50)
			{
				freq = 50;
			}
		}
  		if (p_ch->ctrl & MPL__XM_CTRL_START)
		{
			if (pl->smp_handle[p_ch->p_smp->index] < 0)
			{
				continue;
			}
  			mpl__snd_mixer_play_channel(pl->mixer, cur, pl->smp_handle[p_ch->p_smp->index], freq, vol, pan, 0.5f, p_ch->smp_offset, MPL__SND_DEV_DIR_FORWARDS);
  			p_ch->smp_offset = 0;
			p_ch->ctrl = 0;
		}
  		if (p_ch->ctrl & MPL__XM_CTRL_PER)
		{
			mpl__snd_mixer_set_channel_freq(pl->mixer, cur, freq);
		}
  		if (p_ch->ctrl & MPL__XM_CTRL_VOL)
		{
			mpl__snd_mixer_set_channel_vol(pl->mixer, cur, vol, pan, 0.5f);
		}
  		p_ch->ctrl = 0;
	}
  	if (pl->ctrl & MPL__XM_PL_CTRL_VOL)
	{
		pl->glob_vol = clip_to(pl->glob_vol, 0, 64);
  		vol = pl->vol * pl->glob_vol * (1.0f / 64.0f);
  		mpl__snd_mixer_set_vol(pl->mixer, vol, 0.5f, 0.5f);
	}
  	if (pl->ctrl & MPL__XM_PL_CTRL_BPM)
	{
		mpl__snd_call_back_t cb;
  		cb.func   = (mpl__snd_call_back_func_t)run_tick;
		cb.data   = pl;
		cb.param  = 0;
		cb.period = 2500.0f / pl->bpm;
  		mpl__snd_mixer_set_call_back(pl->mixer, cb);
	}
  	pl->ctrl = 0;
}
  static long
get_random()
{
	static long seed = 37842;
    unsigned long low, high;
  	low  = 16807 * (seed & 0xFFFF);
	high = 16807 * (long)((unsigned long)seed >> 16);
  	low = low + ((high & 0x7FFF) << 16);
  	if (low > 2147483647L)
	{
		low = (low & 2147483647L) + 1;
	}
  	low = low + (high >> 15);
  	if (low > 2147483647L)
	{
		low = (low & 2147483647L) + 1;
	}
  	return seed = (long)low;
}
  static void
do_vibrato(mpl__mp_xm_chan_t *p_ch, int exp, int update_pos)
{
	int delta, temp;
  	temp = p_ch->vib_pos & 31;
  	switch (p_ch->wave_control & 3)
	{
		case 0:
			delta = (int)(fabs(sin(p_ch->vib_pos * 0.0981747704246f) * 256.0f));
			break;
		case 1:
/*			temp <<= 3;
  			if (p_ch->vib_pos < 0)
			{
				temp = 255 - temp;
			}
  			delta = temp;
			break;
		case 2:
		case 3:
			delta = get_random() & 0xff;*/
			break;
	};
  	delta *= p_ch->vib_depth;
	delta >>= 7;
	delta <<= exp;
  	p_ch->ctrl |= MPL__XM_CTRL_PER;
  	if (p_ch->vib_pos >= 0)
	{
		p_ch->per_delta = -delta;
	}
	else
	{
		p_ch->per_delta = delta;
	}
  	if (!update_pos)
	{
		return;
	}
  	p_ch->vib_pos += p_ch->vib_speed;
  	if (p_ch->vib_pos > 31)
	{
		p_ch->vib_pos -= 64;
	}
}
  static void
do_inst_vibrato(mpl__mp_xm_chan_t *p_ch)
{
	int delta;
  	if (!p_ch->p_inst)
	{
		return;
	}
  	switch (p_ch->wave_control & 3)
	{
		case 0:
			delta = (int)((sin(p_ch->inst_vib_pos * 0.0245437f)) * 64.0f);
			break;
		case 1:
			delta = 64;
			if (p_ch->inst_vib_pos > 127)
			{
				delta = -64;
			}
			break;
		case 2:
		case 3:
			delta = (get_random() & 0x8f) - 64;
			break;
	};
  	delta *= p_ch->p_inst->vib_depth;
  	if (p_ch->p_inst->vib_sweep)
	{
		delta = delta * p_ch->inst_vib_sweep_pos / p_ch->p_inst->vib_sweep;
	}
  	delta >>= 6;
  	p_ch->per_delta += delta;
	p_ch->ctrl      |= MPL__XM_CTRL_PER;
  	if (++p_ch->inst_vib_sweep_pos > p_ch->p_inst->vib_sweep)
	{
		p_ch->inst_vib_sweep_pos = p_ch->p_inst->vib_sweep;
	}
  	p_ch->inst_vib_pos += p_ch->p_inst->vib_rate;
  	if (p_ch->inst_vib_pos > 255)
	{
		p_ch->inst_vib_pos -= 256;
	}
}
  
static void
do_tremolo(mpl__mp_xm_chan_t *p_ch)
{
    int delta;
      switch((p_ch->wave_control >> 4) & 3)
	{
	case 0:
		delta = sinus_table[p_ch->tremolo_pos&31];
		break;
	case 1:
		delta = p_ch->tremolo_pos < 32 ?
				p_ch->tremolo_pos << 3 :
				255 - (p_ch->tremolo_pos << 3);
		break;
	case 2:
		delta = 255;
		break;
	case 3:
		delta = get_random() & 0xff;
		break;
    };
      delta *= p_ch->tremolo_depth;
	delta >>= 6;
      if (p_ch->tremolo_pos < 32)
	{
		delta = -delta;
	}
  	p_ch->vol_delta = delta;
	p_ch->ctrl     |= MPL__XM_CTRL_VOL;
      p_ch->tremolo_pos += p_ch->tremolo_speed;
  	while(p_ch->tremolo_pos >= 64)
	{
		p_ch->tremolo_pos -= 64;
	}
}
 
 
  static void
do_porta(mpl__mp_xm_chan_t *p_ch)
{
	if (p_ch->porta_period)
	{
		p_ch->per  += clip_to(p_ch->porta_period - p_ch->per, -p_ch->porta_speed, p_ch->porta_speed);
		p_ch->ctrl |= MPL__XM_CTRL_PER;
	}
}
  static void
do_tremor(mpl__mp_xm_chan_t *p_ch)
{
	if ((p_ch->tremor_spd >> 4) + (p_ch->tremor_spd & 15) == 0)
	{
		p_ch->tremor_pos = 0;
		return;
	}
  	p_ch->tremor_pos %= (p_ch->tremor_spd >> 4) + (p_ch->tremor_spd & 15);
  	if (p_ch->tremor_pos < (p_ch->tremor_spd >> 4))
	{
		p_ch->vol_delta = 0;
	}
	else
	{
		p_ch->vol_delta = -p_ch->vol;
	}
  	p_ch->ctrl |= MPL__XM_CTRL_VOL;
  	p_ch->tremor_pos++;
}
  static void
do_env_vol(mpl__mp_xm_chan_t *p_ch)
{
	mpl__xm_point_t *cur, *next;
	int pos, tick_inc = 1, divide;
  	if (!p_ch->p_inst->vol_num)
	{
		return;
	}
  	pos = 0;
  	if (p_ch->p_inst->vol_num > 1)
	{
		while(p_ch->env_vol_tick >= p_ch->p_inst->vol_env[pos + 1].x && pos < p_ch->p_inst->vol_num - 1)
		{
			pos++;
		}
	}
  	if (p_ch->env_vol_tick == p_ch->p_inst->vol_env[pos].x)
	{
		if ((p_ch->p_inst->vol_type & MPL__XM_ENV_LOOP) &&
			pos == p_ch->p_inst->vol_loop_end)
		{
			pos                = p_ch->p_inst->vol_loop_beg;
			p_ch->env_vol_tick = p_ch->p_inst->vol_env[pos].x;
		}
  		if ((p_ch->p_inst->vol_type & MPL__XM_ENV_SUSTAIN) && pos == p_ch->p_inst->vol_sus && !p_ch->key_off)
		{
			tick_inc = 0;
		}
  		if (pos == p_ch->p_inst->vol_num - 1)
		{
			tick_inc = 0;
		}
	}
  	cur  = p_ch->p_inst->vol_env + pos;
	next = cur;
  	if (p_ch->p_inst->vol_num > 1 && pos < p_ch->p_inst->vol_num - 1)
	{
		next++;
	}
  	divide = next->x - cur->x;
  	if (divide > 1)
	{
		p_ch->env_vol = cur->y + (next->y - cur->y) * (p_ch->env_vol_tick - cur->x) / divide;
	}
	else
	{
		p_ch->env_vol = cur->y;
	}
  	p_ch->ctrl |= MPL__XM_CTRL_VOL;
  	if (tick_inc)
	{
		p_ch->env_vol_tick++;
	}
}
  static void
do_env_pan(mpl__mp_xm_chan_t *p_ch)
{
	mpl__xm_point_t *cur, *next;
	int pos, tick_inc = 1, divide;
  	if (!p_ch->p_inst->pan_num)
	{
		p_ch->env_pan_tick++;
		return;
	}
  	pos = 0;
  	if (p_ch->p_inst->pan_num > 1)
	{
		while(p_ch->env_pan_tick >= p_ch->p_inst->pan_env[pos + 1].x  && pos < p_ch->p_inst->pan_num - 1)
		{
			pos++;
		}
	}
  	if (p_ch->env_pan_tick == p_ch->p_inst->pan_env[pos].x)
	{
		if ((p_ch->p_inst->pan_type & MPL__XM_ENV_LOOP) &&
			pos == p_ch->p_inst->pan_loop_end)
		{
			pos                = p_ch->p_inst->pan_loop_beg;
			p_ch->env_pan_tick = p_ch->p_inst->pan_env[pos].x;
		}
  		if ((p_ch->p_inst->pan_type & MPL__XM_ENV_SUSTAIN) && pos == p_ch->p_inst->pan_sus && !p_ch->key_off)
		{
			tick_inc = 0;
		}
  		if (pos == p_ch->p_inst->pan_num - 1)
		{
			tick_inc = 0;
		}
	}
  	cur  = p_ch->p_inst->pan_env + pos;
	next = cur;
  	if (p_ch->p_inst->pan_num > 1 && pos < p_ch->p_inst->pan_num - 1)
	{
		next++;
	}
  	divide = next->x - cur->x;
  	if (divide > 1)
	{
		p_ch->env_pan = cur->y + (next->y - cur->y) * (p_ch->env_pan_tick - cur->x) / divide;
	}
	else
	{
		p_ch->env_pan = cur->y;
	}
  	p_ch->ctrl |= MPL__XM_CTRL_VOL;
  	if (tick_inc)
	{
		p_ch->env_pan_tick++;
	}
}
  static void
do_vol_slide(mpl__mp_xm_chan_t *p_ch, int slide_value)
{
	int param_x, param_y;
  	param_x = slide_value >> 4;
	param_y = slide_value & 0xf;
  	if (param_x)
	{
		p_ch->vol += param_x;
	}
	else
	{
		if (param_y)
		{
			p_ch->vol -= param_y;
		}
	}
  	p_ch->ctrl |= MPL__XM_CTRL_VOL;
}
  static void
do_vol(mpl__mp_xm_t *pl, mpl__mp_xm_chan_t *p_ch, int vol)
{
	if (vol < 0x10)
	{
		return;
	}
  	if (vol <= 0x50 && !pl->tick_cur)
	{
		p_ch->vol   = vol - 0x10;
		p_ch->ctrl |= MPL__XM_CTRL_VOL;
	}
  	switch(vol & 0xf0)
	{
	case MPL__XM_VOL_EFF_VOL_SLIDE_DOWN:
		if (pl->tick_cur)
		{
			p_ch->vol  = p_ch->vol - (vol & 0xf);
			p_ch->ctrl |= MPL__XM_CTRL_VOL;
		}
		break;
	case MPL__XM_VOL_EFF_VOL_SLIDE_UP:
		if (pl->tick_cur)
		{
			p_ch->vol  = p_ch->vol + (vol & 0xf);
			p_ch->ctrl |= MPL__XM_CTRL_VOL;
		}
		break;
	case MPL__XM_VOL_EFF_FINE_VOL_SLIDE_DOWN:
		if (!pl->tick_cur)
		{
			p_ch->vol  = p_ch->vol - (vol & 0xf);
			p_ch->ctrl |= MPL__XM_CTRL_VOL;
		}
		break;
	case MPL__XM_VOL_EFF_FINE_VOL_SLIDE_UP:
		if (!pl->tick_cur)
		{
			p_ch->vol  = p_ch->vol + (vol & 0xf);
			p_ch->ctrl |= MPL__XM_CTRL_VOL;
		}
		break;
	case MPL__XM_VOL_EFF_VIB_SPEED:
		if (!pl->tick_cur)
		{
			p_ch->vib_speed = vol & 0xf;
		}
		break;
	case MPL__XM_VOL_EFF_VIB:
		if (!pl->tick_cur)
		{
			p_ch->vib_depth = vol & 0xf;
			do_vibrato(p_ch, 2, 1);
		}
		else
		{
			do_vibrato(p_ch, 2, 0);
		}
  		break;
	case MPL__XM_VOL_EFF_PAN:
		if (!pl->tick_cur)
		{
			p_ch->pan = (vol & 0xf) << 4;
			p_ch->ctrl |= MPL__XM_CTRL_VOL;
		}
		break;
	case MPL__XM_VOL_EFF_PAN_SLIDE_LEFT:
		p_ch->pan   = p_ch->pan - (vol & 0xf);
		p_ch->ctrl |= MPL__XM_CTRL_VOL;
		break;
	case MPL__XM_VOL_EFF_PAN_SLIDE_RIGHT:
		p_ch->pan   = p_ch->pan + (vol & 0xf);
		p_ch->ctrl |= MPL__XM_CTRL_VOL;
		break;
	case MPL__XM_VOL_EFF_PORTA:
		if (vol & 0xf)
		{
			p_ch->porta_speed = (vol & 0xf) << 6;
		}
/*
		if (pl->tick_cur)
		{
			do_porta(p_ch);
		}
		else
		{
			p_ch->porta_period = p_ch->dst_per;
		}*/
		break;
	}
}
  static void
new_smp(mpl__mp_xm_chan_t *p_ch)
{
	if (!p_ch->p_smp || p_ch->key == MPL__XM_NO_NOTE)
	{
		return;
	}
  	p_ch->vol                = p_ch->p_smp->vol;
	p_ch->env_vol            = 64;
	p_ch->env_vol_tick       = 0;
	p_ch->fade_out_vol       = 65536;
	p_ch->pan                = p_ch->p_smp->pan;
	p_ch->env_pan            = 32;
	p_ch->env_pan_tick       = 0;
	p_ch->key_off            = 0;
	p_ch->inst_vib_sweep_pos = 0;
	p_ch->inst_vib_pos       = 0;
	p_ch->retrig_vol_slide   = 1;
  	if ((p_ch->wave_control & 0xf) < 4)
	{
		p_ch->vib_pos = 0;
	}
  	if ((p_ch->wave_control >> 4) < 4)
	{
		p_ch->tremolo_pos = 0;
	}
  	p_ch->ctrl |= MPL__XM_CTRL_VOL;
}
  static void
retrig(mpl__mp_xm_chan_t *p_ch)
{
	if (!p_ch->p_smp || p_ch->key == MPL__XM_NO_NOTE)
	{
		return;
	}
  	p_ch->env_vol            = 64;
	p_ch->env_vol_tick       = 0;
	p_ch->fade_out_vol       = 65536;
  	p_ch->env_pan            = 32;
	p_ch->env_pan_tick       = 0;
  	p_ch->inst_vib_sweep_pos = 0;
	p_ch->inst_vib_pos       = 0;
  	if ((p_ch->wave_control & 0xf) < 4)
	{
		p_ch->vib_pos = 0;
	}
  	if ((p_ch->wave_control >> 4) < 4)
	{
		p_ch->tremolo_pos = 0;
	}
  	p_ch->ctrl |= MPL__XM_CTRL_START | MPL__XM_CTRL_VOL;
}
  static void
new_note(mpl__mp_xm_chan_t *p_ch)
{
}
  static void
update_row(mpl__mp_xm_t *pl)
{
	int ch;
	mpl__xm_cell_t *row_cur, *cell;
	mpl__xm_t *xm;
	mpl__mp_xm_chan_t *p_ch;
	mpl__msg_t msg;
	int pattern_jump, pattern_break, porta;
	int param, param_x, param_y;
	int old_vol, old_pan, old_per;
  	xm = pl->xm;
  	if (pl->pat_cur >= xm->length)
	{
		if (pl->loop == MPL__MP_LOOP_NONE)
		{
			mp_cmd_reset(pl);
  			if (pl->mb)
			{
				msg.msg = MPL__MP_MSG_END;
  				mpl__msg_box_send(pl->mb, &msg);
			}
  			return;
		}
  		pl->bpm = xm->bpm;
		pl->speed = xm->speed;
		pl->row_cur = 0;
		pl->pat_cur = 0;
		pl->delay = 0;
  		if (pl->loop != MPL__MP_LOOP_FOREVER)
		{
			pl->loop--;
		}
  		if (pl->mb)
		{
			msg.msg = MPL__MP_MSG_RESTART;
  			mpl__msg_box_send(pl->mb, &msg);
		}
	}
  	pattern_jump = 0;
	pattern_break = 0;
  	pl->row_next = pl->row_cur + 1;
  	row_cur = get_row(pl);
  	for(ch = 0; ch < pl->xm->ch_num; ch++)
	{
		cell = &row_cur[ch];
		p_ch  = &pl->ch[ch];
  		if (ch == 4)
		{
			ch = ch;
		}
  		porta = cell->effect == MPL__XM_EFF_PORTA || 
				cell->effect == MPL__XM_EFF_PORTA_VOL_SLIDE ||
				(cell->volume & 0xf0) == MPL__XM_VOL_EFF_PORTA;
  		if (cell->key < MPL__XM_KEY_OFF && !porta)
		{
			p_ch->key = cell->key - 1;
		}
  		if (cell->inst)
		{
			p_ch->inst = cell->inst;
		}
  		if (cell->key < MPL__XM_KEY_OFF && cell->inst && !porta)
		{
			if (cell->inst <= xm->inst_num)
			{
				int note2smp;
  				p_ch->p_inst = xm->inst + p_ch->inst - 1;
  				note2smp = p_ch->p_inst->note2smp[p_ch->key];
  				if (note2smp >= p_ch->p_inst->smp_num)
				{
					p_ch->inst = 0;
					p_ch->p_inst = 0;
					p_ch->p_smp = 0;
				}
				else
				{
					p_ch->p_smp  = p_ch->p_inst->smp + note2smp;
				}
			}
			else
			{
				p_ch->inst = 0;
				p_ch->p_inst = 0;
				p_ch->p_smp = 0;
			}
		}
  		if (p_ch->eff == MPL__XM_EFF_TREMOLO && cell->effect != MPL__XM_EFF_TREMOLO)
		{
			p_ch->vol += p_ch->vol_delta;
		}
  		p_ch->vol_delta = 0;
		p_ch->per_delta = 0;
  		if (p_ch->p_inst)
		{
			if (cell->key < MPL__XM_KEY_OFF)
			{
				int period;
  				p_ch->real_key = cell->key + p_ch->p_smp->rel_note - 1;
  				if (xm->freq_table & MPL__XM_FREQ_TABLE_LINEAR)
				{
					period = linear_note_to_period(p_ch->real_key, pl->smp_fine_tune[p_ch->p_smp->index]);
				}
				else
				{
					period = note_to_period(p_ch->real_key, pl->smp_fine_tune[p_ch->p_smp->index]);
				}
  				if (porta)
				{
					p_ch->dst_per = period;
				}
				else
				{
					p_ch->per   = period;
					p_ch->ctrl |= MPL__XM_CTRL_START;
				}
  			}
  			if (cell->inst)
			{
				new_smp(p_ch);
			}
		}
  		old_vol = p_ch->vol;
		old_pan = p_ch->pan;
		old_per = p_ch->per;
  		do_vol(pl, p_ch, cell->volume);
  		if (cell->key == MPL__XM_KEY_OFF || cell->effect == MPL__XM_EFF_KEY_OFF)
		{
			p_ch->key_off = 1;
		}
  		if (cell->effect == 0 && cell->param == 0)
		{
			goto no_effects;
		}
  		param   = cell->param;
		param_x = param >> 4;
		param_y = param & 0xf;
  		switch(cell->effect)
		{
		case MPL__XM_EFF_ARPEGGIO:
			break;
		case MPL__XM_EFF_PORTA_UP:
			if (param)
			{
				p_ch->porta_up = param << 2;
			}
			break;
		case MPL__XM_EFF_PORTA_DOWN:
			if (param)
			{
				p_ch->porta_down = param << 2;
			}
			break;
		case MPL__XM_EFF_PORTA:
			if (param)
			{
				p_ch->porta_speed = param << 2;
			}
			p_ch->porta_period = p_ch->dst_per;
			break;
		case MPL__XM_EFF_VIB:
			if (param_x)
			{
				p_ch->vib_speed = param_x;
			}
			if (param_y)
			{
				p_ch->vib_depth = param_y;
			}
			do_vibrato(p_ch, 2, 0);
			break;
		case MPL__XM_EFF_PORTA_VOL_SLIDE:
			if (param)
			{
				p_ch->porta_vol_slide = param;
			}
			p_ch->porta_period = p_ch->dst_per;
			break;
		case MPL__XM_EFF_VIB_VOL_SLIDE:
			if (param)
			{
				p_ch->vib_vol_slide = param;
			}
			do_vibrato(p_ch, 2, 0);
			break;
		case MPL__XM_EFF_TREMOLO:
			if (cell->param & 0xf0)
			{
				p_ch->tremolo_speed = param_x;
			}
			if (cell->param & 0xf)
			{
				p_ch->tremolo_depth = param_y;
			}
			break;
		case MPL__XM_EFF_PAN:
			p_ch->pan   = param;
			p_ch->ctrl |= MPL__XM_CTRL_VOL;
			break;
		case MPL__XM_EFF_SMP_OFFSET:
			p_ch->smp_offset = param << 8;
			p_ch->ctrl      |= MPL__XM_CTRL_START;
			break;
		case MPL__XM_EFF_VOL_SLIDE:
			if (param)
			{
				p_ch->vol_slide = param;
			}
			break;
		case MPL__XM_EFF_POS_JUMP:
			if (param < xm->length)
			{
				pl->pat_next = param;
				pattern_jump = 1;
			}
			break;
		case MPL__XM_EFF_VOL:
			p_ch->vol   = param;
			p_ch->ctrl |= MPL__XM_CTRL_VOL;
			break;
		case MPL__XM_EFF_PAT_BREAK:
			pl->row_next  = param_x * 10 + param_y;
			pattern_break = 1;
			break;
		case MPL__XM_EFF_MOD_EXT:
			switch(param_x)
			{
			case MPL__XM_EXT_EFF_FINE_PORTA_UP:
				if (param_y)
				{
					p_ch->fporta_up = param_y << 2;
				}
				p_ch->per -= p_ch->fporta_up;
				break;
			case MPL__XM_EXT_EFF_FINE_PORTA_DOWN:
				if (param_y)
				{
					p_ch->fporta_down = param_y << 2;
				}
				p_ch->per += p_ch->fporta_down;
				break;
			case MPL__XM_EXT_EFF_GLISSANDO:
				// *fart*
				break;
			case MPL__XM_EXT_EFF_VIB_WAVE:
				p_ch->wave_control &= 0xf0;
				p_ch->wave_control |= param_y;
				break;
			case MPL__XM_EXT_EFF_FINE_TUNE:
				if (p_ch->p_smp)
				{
					pl->smp_fine_tune[p_ch->p_smp->index] = param_y;
				}
				break;
			case MPL__XM_EXT_EFF_PAT_LOOP:
				if (param_y == 0)
				{
					p_ch->loop_row = pl->row_cur;
				}
				else
				{
					if (!p_ch->loop_num)
					{
						p_ch->loop_num = param_y;
					}
					else
					{
						p_ch->loop_num--;
					}
					if (p_ch->loop_num)
					{
						pl->row_next = p_ch->loop_row - 1;
					}
				}
				break;
			case MPL__XM_EXT_EFF_TREMOLO_WAVE:
				p_ch->wave_control &= 0xf;
				p_ch->wave_control |= param_y << 4;
				break;
			case MPL__XM_EXT_EFF_PAN:
				p_ch->pan   = param_y << 4;
				p_ch->ctrl |= MPL__XM_CTRL_VOL;
				break;
			case MPL__XM_EXT_EFF_RETRIG:
				break;
			case MPL__XM_EXT_EFF_FINE_VOL_SLIDE_UP:
				if (param_y)
				{
					p_ch->fvol_slide_up = param_y;
				}
				p_ch->vol  += p_ch->fvol_slide_up;
				p_ch->ctrl |= MPL__XM_CTRL_VOL;
				break;
			case MPL__XM_EXT_EFF_FINE_VOL_SLIDE_DOWN:
				if (param_y)
				{
					p_ch->fvol_slide_down = param_y;
				}
				p_ch->vol  -= p_ch->fvol_slide_up;
				p_ch->ctrl |= MPL__XM_CTRL_VOL;
				break;
			case MPL__XM_EXT_EFF_NOTE_CUT:
				break;
			case MPL__XM_EXT_EFF_NOTE_DELAY:
/*				p_ch->vol   = old_vol;
				p_ch->pan   = old_pan;
				p_ch->per   = old_per;
				p_ch->ctrl &= ~(MPL__XM_CTRL_START|MPL__XM_CTRL_VOL|MPL__XM_CTRL_PER);*/
				break;
			case MPL__XM_EXT_EFF_PAT_DELAY:
				pl->delay = param_y * pl->speed;
				break;
			default:
				break;
			}
			break;
		case MPL__XM_EFF_SPEED:
			if (param < 32)
			{
				pl->speed = param;
			}
			else
			{
				pl->bpm        = param;
				pl->ctrl      |= MPL__XM_PL_CTRL_BPM;
			}
			break;
		case MPL__XM_EFF_GLOB_VOL:
			pl->glob_vol = param;
			pl->ctrl    |= MPL__XM_PL_CTRL_VOL;
			break;
		case MPL__XM_EFF_GLOB_VOL_SLIDE:
			pl->glob_vol_slide = param;
			pl->ctrl          |= MPL__XM_PL_CTRL_VOL;
			break;
		case MPL__XM_EFF_KEY_OFF:
			break;
		case MPL__XM_EFF_ENV_POS:
			if (p_ch->p_inst)
			{
				if (p_ch->p_inst->vol_type & MPL__XM_ENV_ON)
				{
					p_ch->env_vol_tick = param;
				}
			}
			break;
		case MPL__XM_EFF_PAN_SLIDE:
			if (param)
			{
				p_ch->pan_slide = param;
			}
			break;
		case MPL__XM_EFF_RETRIG_VOL_SLIDE:
			if (param)
			{
				p_ch->retrig_vol_slide = param;
			}
			break;
		case MPL__XM_EFF_TREMOR:
			if (param)
			{
				p_ch->tremor_spd = param;
			}
			do_tremor(p_ch);
			break;
		case MPL__XM_EFF_EXTRA_FINE_PORTA:
			switch(param_x)
			{
			case 1:
				if (param_y)
				{
					p_ch->efporta_up = param_y;
				}
				p_ch->per  -= p_ch->efporta_up;
				p_ch->ctrl |= MPL__XM_CTRL_PER;
				break;
			case 2:
				if (param_y)
				{
					p_ch->efporta_down = param_y;
				}
				p_ch->per  += p_ch->efporta_down;
				p_ch->ctrl |= MPL__XM_CTRL_PER;
				break;
			default:
				break;
			}
			break;
		default:
			break;
		}
no_effects:
		if (p_ch->p_inst)
		{
			if (p_ch->p_inst->vol_type & MPL__XM_ENV_ON)
			{
				do_env_vol(p_ch);
			}
			else
			{
				if (p_ch->key_off)
				{
					p_ch->env_vol = 0;
				}
			}
  			if (p_ch->p_inst->pan_type & MPL__XM_ENV_ON)
			{
				do_env_pan(p_ch);
			}
  			if (p_ch->key_off)
			{
				p_ch->fade_out_vol = clip_to(p_ch->fade_out_vol - p_ch->p_inst->vol_fade_out, 0, 65536);
				p_ch->ctrl        |= MPL__XM_CTRL_VOL;
			}
		}
  		do_inst_vibrato(p_ch);
	}
  	if (pattern_break && !pattern_jump)
	{
		pl->pat_next++;
	}
  	if (!pattern_break && pattern_jump)
	{
		pl->row_next=0;
	}
  	if (pl->row_next >= xm->pat_length[xm->order[pl->pat_cur]])
	{
		pl->row_next = 0;
		pl->pat_next++;
	}
}
  void
update_effects(mpl__mp_xm_t *pl)
{
	int ch;
	mpl__xm_cell_t *row_cur, *cell;
	mpl__xm_t *xm;
	mpl__mp_xm_chan_t *p_ch;
  	xm = pl->xm;
	row_cur = get_row(pl);
  	for(ch = 0; ch < xm->ch_num; ch++)
	{
		int param, param_x, param_y;
  		cell = &row_cur[ch];
		p_ch = &pl->ch[ch];
  		p_ch->per_delta = 0;
		p_ch->vol_delta = 0;
  		do_vol(pl, p_ch, cell->volume);
  		if (cell->effect == 0 && cell->param == 0)
		{
			goto no_effects;
		}
  		param   = cell->param;
		param_x = param >> 4;
		param_y = param & 0xf;
  		switch(cell->effect)
		{
		case MPL__XM_EFF_ARPEGGIO:
			switch(pl->tick_cur % 3)
			{
			case 1:
				if (p_ch->p_smp)
				{
					if (xm->freq_table & MPL__XM_FREQ_TABLE_LINEAR)
					{
						p_ch->per_delta = param_x << 6;
					}
					else
					{
						p_ch->per_delta = note_to_period(p_ch->real_key + param_x, pl->smp_fine_tune[p_ch->p_smp->index]) - note_to_period(p_ch->real_key, pl->smp_fine_tune[p_ch->p_smp->index]);
					}
  					p_ch->ctrl |= MPL__XM_CTRL_PER;
				}
				break;
			case 2:
				if (p_ch->p_smp)
				{
					if (xm->freq_table & MPL__XM_FREQ_TABLE_LINEAR)
					{
						p_ch->per_delta = param_y << 6;
					}
					else
					{
						p_ch->per_delta = note_to_period(p_ch->real_key + param_y, pl->smp_fine_tune[p_ch->p_smp->index]) - note_to_period(p_ch->real_key, pl->smp_fine_tune[p_ch->p_smp->index]);
					}
					p_ch->ctrl |= MPL__XM_CTRL_PER;
				}
				break;
			default:
				p_ch->ctrl |= MPL__XM_CTRL_PER;
				break;
			}
			break;
		case MPL__XM_EFF_PORTA_UP:
			p_ch->per  -= p_ch->porta_up;
			p_ch->ctrl |= MPL__XM_CTRL_PER;
			break;
		case MPL__XM_EFF_PORTA_DOWN:
			p_ch->per  += p_ch->porta_down;
			p_ch->ctrl |= MPL__XM_CTRL_PER;
			break;
		case MPL__XM_EFF_PORTA:
			do_porta(p_ch);
			break;
		case MPL__XM_EFF_VIB:
			do_vibrato(p_ch, 2, 1);
			break;
		case MPL__XM_EFF_PORTA_VOL_SLIDE:
			do_porta(p_ch);
			do_vol_slide(p_ch, p_ch->porta_vol_slide);
			break;
		case MPL__XM_EFF_VIB_VOL_SLIDE:
			do_vibrato(p_ch, 2, 1);
			do_vol_slide(p_ch, p_ch->vib_vol_slide);
			break;
		case MPL__XM_EFF_TREMOLO:
			do_tremolo(p_ch);
			break;
		case MPL__XM_EFF_PAN:
			break;
		case MPL__XM_EFF_SMP_OFFSET:
			break;
		case MPL__XM_EFF_VOL_SLIDE:
			do_vol_slide(p_ch, p_ch->vol_slide);
			break;
		case MPL__XM_EFF_POS_JUMP:
			break;
		case MPL__XM_EFF_VOL:
			break;
		case MPL__XM_EFF_PAT_BREAK:
			break;
		case MPL__XM_EFF_MOD_EXT:
			switch(param & 0xf0)
			{
			case MPL__XM_EXT_EFF_FINE_PORTA_UP:
				break;
			case MPL__XM_EXT_EFF_FINE_PORTA_DOWN:
				break;
			case MPL__XM_EXT_EFF_GLISSANDO:
				break;
			case MPL__XM_EXT_EFF_VIB_WAVE:
				break;
			case MPL__XM_EXT_EFF_FINE_TUNE:
				break;
			case MPL__XM_EXT_EFF_PAT_LOOP:
				break;
			case MPL__XM_EXT_EFF_TREMOLO_WAVE:
				break;
			case MPL__XM_EXT_EFF_PAN:
				break;
			case MPL__XM_EXT_EFF_RETRIG:
				if (!param_y)
				{
					return;
				}
				if (!(pl->tick_cur % param_y))
				{
					retrig(p_ch);
				}
				break;
			case MPL__XM_EXT_EFF_FINE_VOL_SLIDE_UP:
				break;
			case MPL__XM_EXT_EFF_FINE_VOL_SLIDE_DOWN:
				break;
			case MPL__XM_EXT_EFF_NOTE_CUT:
				if (pl->tick_cur == param_y)
				{
					p_ch->ctrl |= MPL__XM_CTRL_STOP;
				}
				break;
			case MPL__XM_EXT_EFF_NOTE_DELAY:
/*				if (pl->tick_cur == param_y)
				{
					if (p_ch->p_smp)
					{
						new_smp(p_ch);
						do_vol(pl, p_ch, cell->volume);
						p_ch->ctrl |= XM_CTRL_START|XM_CTRL_PER|XM_CTRL_VOL;
					}
				}
				else
				{
					p_ch->ctrl &= ~(XM_CTRL_START|XM_CTRL_PER|XM_CTRL_VOL);
				}*/
				break;
			case MPL__XM_EXT_EFF_PAT_DELAY:
				break;
			default:
				break;
			}
			break;
		case MPL__XM_EFF_SPEED:
			break;
		case MPL__XM_EFF_GLOB_VOL:
			break;
		case MPL__XM_EFF_GLOB_VOL_SLIDE:
			param_x = pl->glob_vol_slide >> 4;
			param_y = pl->glob_vol_slide & 0xf;
			if (param_x)
			{
				pl->glob_vol += param_x;
			}
			else
			{
				if (param_y)
				{
					pl->glob_vol -= param_y;
				}
			}
			pl->ctrl |= MPL__XM_PL_CTRL_VOL;
			break;
		case MPL__XM_EFF_KEY_OFF:
			if (pl->tick_cur == param)
			{
				p_ch->key_off = 1;
			}
			break;
		case MPL__XM_EFF_ENV_POS:
			break;
		case MPL__XM_EFF_PAN_SLIDE:
			param_x = p_ch->pan_slide >> 4;
			param_y = p_ch->pan_slide & 0xf;
			if (param_x)
			{
				p_ch->pan += param_x;
			}
			else
			{
				if (param_y)
				{
					p_ch->pan -= param_y;
				}
			}
			p_ch->ctrl |= MPL__XM_CTRL_VOL;
			break;
		case MPL__XM_EFF_RETRIG_VOL_SLIDE:
			if (!(p_ch->retrig_vol_slide & 0xf))
			{
				break;
			}
			if (pl->tick_cur % (p_ch->retrig_vol_slide & 0xf))
			{
				break;
			}
  			retrig(p_ch);
  			switch(p_ch->retrig_vol_slide & 0xf0)
			{
			case 0x10: p_ch->vol -= 1;	break;
			case 0x90: p_ch->vol += 1; break;
			case 0x20: p_ch->vol -= 2; break;
			case 0xA0: p_ch->vol += 2; break;
			case 0x30: p_ch->vol -= 4; break;
			case 0xB0: p_ch->vol += 4; break;
			case 0x40: p_ch->vol -= 8; break;
			case 0xC0: p_ch->vol += 8; break;
			case 0x50: p_ch->vol -= 16; break;
			case 0xD0: p_ch->vol += 16; break;
			case 0x60: p_ch->vol = (p_ch->vol << 1) / 3; break;
			case 0xE0: p_ch->vol = (p_ch->vol * 3) >> 1; break;
			case 0x70: p_ch->vol >>= 1; break;
			case 0xF0: p_ch->vol <<= 1; break;
			}
  			p_ch->ctrl |= MPL__XM_CTRL_VOL;
  			break;
		case MPL__XM_EFF_TREMOR:
			do_tremor(p_ch);
			break;
		case MPL__XM_EFF_EXTRA_FINE_PORTA:
			break;
		default:
			break;
		}
  no_effects:
  		if (p_ch->p_inst)
		{
			if (p_ch->key_off)
			{
				p_ch->fade_out_vol = clip_to(p_ch->fade_out_vol - p_ch->p_inst->vol_fade_out, 0, 65536);
				p_ch->ctrl        |= MPL__XM_CTRL_VOL;
			}
  			if (p_ch->p_inst->vol_type & MPL__XM_ENV_ON)
			{
				do_env_vol(p_ch);
			}
			else
			{
				if (p_ch->key_off)
				{
					p_ch->env_vol = 0;
				}
			}
  			if (p_ch->p_inst->pan_type & MPL__XM_ENV_ON)
			{
				do_env_pan(p_ch);
			}
		}
  		do_inst_vibrato(p_ch);
	}
}
  static void
run_tick(mpl__mp_xm_t *pl, int param)
{
	if (!pl->xm->length)
	{
		return;
	}
  	if (pl->tick_cur >= pl->speed)
	{
		pl->tick_cur = 0;
  		if (!pl->delay)
		{
			pl->pat_cur = pl->pat_next;
			pl->row_cur	= pl->row_next;
			update_row(pl);
		}
		else
		{
			pl->delay--;
		}
	}
	else
	{
		update_effects(pl);
	}
  	update_ctrl(pl);
  	pl->tick_cur++;
}
  ////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
///  interface  ////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
static int
mp_cmd_reset(void *internal_data)
{
	mpl__mp_xm_t *pl = (mpl__mp_xm_t*)internal_data;
	mpl__mp_xm_chan_t *p_ch;
	int ch, inst, smp;
  	pl->bpm            = pl->xm->bpm;
	pl->ctrl          |= MPL__XM_PL_CTRL_BPM;
	pl->speed          = pl->xm->speed;
	pl->tick_cur       = pl->speed;
	pl->pat_cur        = 0;
	pl->pat_next       = 0;
	pl->row_cur        = 0;
	pl->row_next       = 0;
	pl->delay          = 0;
	pl->glob_vol       = 64;
	pl->glob_vol_slide = 0;
	pl->delay          = 0;
  	mpl__mem_set_zero(pl->ch, sizeof(mpl__mp_xm_chan_t) * 32);
  	for(inst = 0; inst < pl->xm->inst_num; inst++)
	{
		for(smp = 0; smp < pl->xm->inst[inst].smp_num; smp++)
		{
			pl->smp_fine_tune[pl->xm->inst[inst].smp[smp].index] = pl->xm->inst[inst].smp[smp].finetune;
		}
	}
  	for(ch = 0; ch < 64; ch++)
	{
		p_ch = pl->ch + ch;
  		p_ch->pan = 0x80;
		p_ch->key = MPL__XM_NO_NOTE;
	}
  	if (pl->dev)
	{
		if (!pl->paused)
		{
			mpl__snd_mixer_pause(pl->mixer);
  			pl->paused = 1;
		}
  		mpl__snd_mixer_stop(pl->mixer);
  		run_tick(pl, 0);
	}
  	return 0;
}
  static int
mp_cmd_set_dev(void *internal_data, mpl__snd_dev_t *dev)
{
	mpl__mp_xm_t *pl = (mpl__mp_xm_t*)internal_data;
	mpl__snd_mixer_opt_t opt;
	mpl__snd_dev_output_t output;
	mpl__snd_mixer_smp_t upload;
	int inst, smp, cur;
	mpl__xm_sample_t *p_smp;
  	if (pl->dev)
	{
		mpl__snd_dev_destroy_mixer(pl->dev, pl->mixer);
  		pl->dev = 0;
		pl->mixer = 0;
	}
  	if (!dev)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	if (mpl__snd_dev_get_output_options(dev, &output) < 0)
	{
		return MPL__ERR_GENERIC;
	}
  	opt.latency = MPL__SND_DEV_LATENCY_HIGH;
	opt.ch_num  = pl->xm->ch_num;
	opt.smp_num = pl->xm->smp_index_num;
  	if (mpl__snd_dev_create_mixer(dev, &pl->mixer, opt) < 0)
	{
		return MPL__ERR_GENERIC;
	}
  	pl->dev = dev;
  	for (cur = 0; cur < pl->xm->smp_index_num; cur++)
	{
		pl->smp_handle[cur] = -1;
	}
  	for(inst = 0; inst < pl->xm->inst_num; inst++)
	{
		for(smp = 0; smp < pl->xm->inst[inst].smp_num; smp++)
		{
			p_smp = pl->xm->inst[inst].smp + smp;
  			if (p_smp->length < 4)
			{
				continue;
			}
  			upload.format = p_smp->format & MPL__XM_SMP_16BIT ? MPL__SND_DEV_FMT_16BIT : MPL__SND_DEV_FMT_8BIT;
			upload.channels = 1;
			upload.freq = 8363;
			upload.loop = p_smp->loop_begin;
			upload.data = p_smp->data;
  			switch(p_smp->format & 3)
			{
			default:
			case MPL__XM_SMP_NO_LOOP:
				upload.loopmode = MPL__SND_DEV_FMT_NONLOOPING;
				upload.length   = p_smp->length;
				break;
			case MPL__XM_SMP_LOOP:
				upload.loopmode = MPL__SND_DEV_FMT_LOOPING;
				upload.length   = p_smp->loop_end;
				break;
			case MPL__XM_SMP_BIDI_LOOP:
				upload.loopmode = MPL__SND_DEV_FMT_BIDILOOPING;
				upload.length   = p_smp->loop_end;
				break;
			}
  			upload.vol    = 1.0f;
			upload.pan_lr = 0.5f;
			upload.pan_fb = 0.5f;
  			pl->smp_handle[p_smp->index] = mpl__snd_mixer_upload_sample(pl->mixer, upload);
  			if (pl->smp_handle[p_smp->index] < 0)
			{
				mpl__snd_dev_destroy_mixer(pl->dev, pl->mixer);
  				pl->dev   = 0;
				pl->mixer = 0;
  				return MPL__ERR_GENERIC;
			}
		}
	}
  	pl->ctrl          |= MPL__XM_PL_CTRL_BPM;
  	if (pl->paused)
	{
		mpl__snd_mixer_pause(pl->mixer);
	}
  	run_tick(pl, 0);
  	return 0;
}
  static int
mp_cmd_play(void *internal_data)
{
	mpl__mp_xm_t *pl = (mpl__mp_xm_t*)internal_data;
  	if (!pl->dev)
	{
		return MPL__ERR_GENERIC;
	}
  	if (pl->paused)
	{
		mpl__snd_mixer_pause(pl->mixer);
		pl->paused = 0;
  		return MPL__ERR_OK;
	}
  	return MPL__ERR_GENERIC;
}
  static int
mp_cmd_stop(void *internal_data)
{
	mpl__mp_xm_t *pl = (mpl__mp_xm_t*)internal_data;
  	if (!pl->dev)
	{
		return MPL__ERR_GENERIC;
	}
  	if (!pl->paused)
	{
		mpl__snd_mixer_pause(pl->mixer);
		pl->paused = 1;
  		return MPL__ERR_OK;
	}
  	return MPL__ERR_GENERIC;
}
  static int
mp_cmd_set_loop(void *internal_data, int loop)
{
	mpl__mp_xm_t *pl = (mpl__mp_xm_t*)internal_data;
  	if (loop < 0 && loop != MPL__MP_LOOP_FOREVER)
	{
		return MPL__ERR_GENERIC;
	}
  	pl->loop = loop;
  	return MPL__ERR_OK;
}
  static int
mp_cmd_set_pos(void *internal_data, int pos)
{
	mpl__mp_xm_t *pl = (mpl__mp_xm_t*)internal_data;
	int pat_next, row_next;
	int cur = 0;
  	pat_next = pos >> 24;
	row_next = pos & 0xfff;
  	if (pat_next < 0 || pat_next >= pl->xm->length)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	if (row_next < 0 || row_next >= pl->xm->pat_length[pat_next])
	{
		return MPL__ERR_BAD_PARAM;
	}
  	pl->pat_next = pat_next;
	pl->row_next = row_next;
  	for(cur = 0; cur < pl->xm->ch_num; cur++)
	{
		pl->ch[cur].loop_num = 0;
	}
  	return 0;
}
  static int
mp_cmd_get_pos(void *internal_data)
{
	mpl__mp_xm_t *pl = (mpl__mp_xm_t*)internal_data;
  	return (pl->pat_cur << 24) + pl->row_cur;
}
  static int
mp_cmd_set_vol(void *internal_data, float32 vol)
{
	mpl__mp_xm_t *pl = (mpl__mp_xm_t*)internal_data;
  	pl->vol = vol;
  	pl->glob_vol = clip_to(pl->glob_vol, 0, 64);
  	vol = pl->vol * pl->glob_vol * (1.0f / 64.0f);
  	mpl__snd_mixer_set_vol(pl->mixer, vol, 0.5f, 0.5f);
  	return 0;
}
  static int
mp_cmd_get_vol(void *internal_data, float32 *vol)
{
	mpl__mp_xm_t *pl = (mpl__mp_xm_t*)internal_data;
  	*vol = pl->vol;
  	return 0;
}
  static int
mp_cmd_set_option(void *internal_data, char *option, char *value)
{
	mpl__mp_xm_t *pl = (mpl__mp_xm_t*)internal_data;
  	return MPL__ERR_GENERIC;
}
  static int
mp_cmd_get_option(void *internal_data, char *option, char **value)
{
	mpl__mp_xm_t *pl = (mpl__mp_xm_t*)internal_data;
  	return MPL__ERR_GENERIC;
}
  static int
mp_cmd_get_proc(void *internal_data, char *name, void_func_t *proc)
{
	mpl__mp_xm_t *pl = (mpl__mp_xm_t*)internal_data;
  	return MPL__ERR_GENERIC;
}
  ////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
///  creation  /////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
int
mpl__mp_xm_construct(mpl__xm_t *xm, mpl__mp_t *mp, mpl__msg_box_t *mb)
{
	mpl__mp_xm_t *pl;
  	if (mpl__mem_alloc(sizeof(mpl__mp_xm_t), (void**)&pl) <= MPL__ERR_GENERIC)
	{
		return MPL__ERR_NOMEM;
	}
  	mpl__mem_set_zero(pl, sizeof(mpl__mp_xm_t));
  	pl->xm     = xm;
	pl->vol    = 0.5f;
	pl->mb     = mb;
	pl->paused = 1;
  	mp_cmd_reset(pl);
  	mp->get_option = mp_cmd_get_option;
	mp->get_pos    = mp_cmd_get_pos;
	mp->get_proc   = mp_cmd_get_proc;
	mp->get_vol    = mp_cmd_get_vol;
	mp->play       = mp_cmd_play;
	mp->reset      = mp_cmd_reset;
	mp->set_dev    = mp_cmd_set_dev;
	mp->set_loop   = mp_cmd_set_loop;
	mp->set_option = mp_cmd_set_option;
	mp->set_pos    = mp_cmd_set_pos;
	mp->set_vol    = mp_cmd_set_vol;
	mp->stop       = mp_cmd_stop;
  	mp->internal_data = pl;
  	return 0;
}
  int
mpl__mp_xm_destruct(mpl__mp_t *mp)
{
	mpl__mp_xm_t *pl = (mpl__mp_xm_t*)mp->internal_data;
  	if (pl->mixer)
	{
		mpl__snd_dev_destroy_mixer(pl->dev, pl->mixer);
	}
  	mpl__mem_free(mp->internal_data);
  	return 0;
}
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/src/mpl/sys/critsect.c] - (907 bytes)
 
 #include <mpl/sys/critsect.h>
#include <mpl/sys/mem.h>
  int
mpl__cs_create(mpl__critical_section_t **cs)
{
	int result;
  	result = mpl__mem_alloc(sizeof(mpl__critical_section_t), (void**)cs);
  	if (result <= MPL__ERR_GENERIC)
	{
		return result;
	}
  	result = mpl__cs_construct(*cs);
  	if (result <= MPL__ERR_GENERIC)
	{
		return result;
	}
  	return 0;
}
  int
mpl__cs_destroy(mpl__critical_section_t *cs)
{
	mpl__cs_destruct(cs);
	mpl__mem_free(cs);
	
	return 0;
}
  int
mpl__cs_construct(mpl__critical_section_t *cs)
{
	InitializeCriticalSection(cs);
  	return 0;
}
  int
mpl__cs_destruct(mpl__critical_section_t *cs)
{
	DeleteCriticalSection(cs);
  	return 0;
}
  int
mpl__cs_enter(mpl__critical_section_t *cs)
{
	EnterCriticalSection(cs);
  	return 0;
}
  int
mpl__cs_leave(mpl__critical_section_t *cs)
{
	LeaveCriticalSection(cs);
  	return 0;
}
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/src/mpl/sys/msg_box.c] - (1,706 bytes)
 
 #include <mpl/sys/msg_box.h>
#include <mpl/sys/mem.h>
  int
mpl__msg_box_create(mpl__msg_box_t **mb, int max)
{
	int result;
  	result = mpl__mem_alloc(sizeof(mpl__msg_box_t), (void**)mb);
  	if (result <= MPL__ERR_GENERIC)
	{
		return result;
	}
  	result = mpl__msg_box_construct(*mb, max);
  	if (result <= MPL__ERR_GENERIC)
	{
		mpl__mem_free(*mb);
  		return result;
	}
  	return 0;
}
  int
mpl__msg_box_destroy(mpl__msg_box_t *mb)
{
	mpl__msg_box_destruct(mb);
  	mpl__mem_free(mb);
  	return 0;
}
  int
mpl__msg_box_construct(mpl__msg_box_t *mb, int max)
{
	int result;
  	result = mpl__mem_alloc(sizeof(mpl__msg_t) * max, (void**)&mb->msg);
	
	if (result <= MPL__ERR_GENERIC)
	{
		return result;
	}
  	mb->first = 0;
	mb->last  = 0;
	mb->cnt   = 0;
	mb->max   = max;
  	result = mpl__cs_construct(&mb->cs);
  	if (result <= MPL__ERR_GENERIC)
	{
		mpl__mem_free(mb->msg);
  		return result;
	}
  	return 0;
}
  int
mpl__msg_box_destruct(mpl__msg_box_t *mb)
{
	mpl__cs_destruct(&mb->cs);
  	mpl__mem_free(mb->msg);
  	return 0;
}
  int
mpl__msg_box_send(mpl__msg_box_t *mb, mpl__msg_t *msg)
{
	mpl__cs_enter(&mb->cs);
  	if (mb->cnt >= mb->max)
	{
		return MPL__ERR_MSG_BOX_FULL;
	}
  	mb->msg[mb->last] = *msg;
  	if (++mb->last >= mb->max)
	{
		mb->last = 0;
	}
  	mb->cnt++;
  	mpl__cs_leave(&mb->cs);
  	return 0;
}
  int
mpl__msg_box_receive(mpl__msg_box_t *mb, mpl__msg_t *msg)
{
	mpl__cs_enter(&mb->cs);
  	if (mb->cnt == 0)
	{
		return MPL__ERR_MSG_BOX_EMPTY;
	}
  	*msg = mb->msg[mb->first];
  	if (++mb->first >= mb->max)
	{
		mb->first = 0;
	}
  	mb->cnt--;
  	mpl__cs_leave(&mb->cs);
  	return 0;
}
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/src/mpl/sys/mem.c] - (1,440 bytes)
 
  /*
	to do
	-----
  	- statistics
	- slab allocator? (a lot faster than standard malloc implementation)
*/
  #include <mpl/sys/mem.h>
#include <mpl/sys/critsect.h>
#include <stdlib.h>
  static mpl__critical_section_t l_cs;
  int
mpl__mem_alloc(mpl__mem_size_t size, void **mem)
{
	void *memblock;
	
//	mpl__cs_enter(&l_cs);
	memblock = malloc(size);
//	mpl__cs_leave(&l_cs);
	if (!memblock)
	{
		return MPL__ERR_NOMEM;
	}
  	*mem = memblock;
  	return 0;
}
  int
mpl__mem_get_size(mpl__mem_size_t *size, void *mem)
{
	return MPL__ERR_GENERIC;
}
  int
mpl__mem_resize(mpl__mem_size_t newsize, int onlyexpand, void **mem)
{
	return MPL__ERR_GENERIC;
}
  int
mpl__mem_free(void *mem)
{
	mpl__cs_enter(&l_cs);
	free(mem);
	mpl__cs_leave(&l_cs);
  	return 0;
}
  int
mpl__mem_copy(void *src, void *dst, mpl__mem_size_t size)
{
	char *s, *d;
	int cnt;
  	s = (char*) src;
	d = (char*) dst;
  	if ((mpl__mem_size_t)src > (mpl__mem_size_t)dst)
	{
		cnt = 0;
  		while(cnt < size)
		{
			d[cnt] = s[cnt];
			cnt++;
		}
	}
	else
	{
		while(size--)
		{
			d[size] = s[size];
		}
	}
  	return 0;
}
  int
mpl__mem_set_zero(void *mem, mpl__mem_size_t size)
{
	char *m;
  	m = (char*) mem;
  	while(size--)
	{
		m[size] = 0;
	}
  	return 0;
}
  int
mpl__mem_init()
{
	if (mpl__cs_construct(&l_cs) < MPL__ERR_GENERIC)
	{
		return MPL__ERR_GENERIC;
	}
  	return 0;
}
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/src/mpl/mx_std.c] - (37,454 bytes)
 
 #include <mpl/sys/mem.h>
#include <mpl/mx_std.h>
#include <mpl/string.h>
#include <mpl/dsp_std.h>
  // formats: mono/stereo, 8/16/24/32/float
// to do
// - better error checks
// - more mixer functions? (four channels, etc.)
// - lagrange interpolation?
// - 24 bit mixing
// - extensions: "EXT_FILTER EXT_REVERB EXT_CHORUS EXT_FX"
// - quality improvement
  #define RAMPING 0.02f
  #define CHECK_FOR_ERRORS
  static int command_reset(void *internal);
static int command_pause(void *internal);
static int command_stop(void *internal);
static int command_upload_sample(void *internal, mpl__snd_mixer_smp_t sample);
static int command_destroy_sample(void *internal, int handle);
static int command_set_sustain_loop(mpl__snd_mixer_t *sndmx, int handle, int begin, int end, int mode);
static int command_end_sustain(mpl__snd_mixer_t *sndmx, int ch);
static int command_set_vol(void *internal, float32 vol, float32 pan_lr, float32 pan_fb);
static int command_get_vol(void *internal, float32 *vol, float32 *pan_lr, float32 *pan_fb);
static int command_get_output_options(void *internal, mpl__snd_dev_output_t *opt);
static int command_get_latency(void *internal);
static int command_get_num_channels(void *internal);
static int command_get_num_active_channels(void *internal);
static int command_get_free_channel(void *internal);
static int command_is_channel_active(void *internal, int ch);
static int command_get_free_channel(void *internal);
static int command_is_channel_active(void *internal, int ch);
static int command_set_channel_vol(void *internal, int ch, float32 vol, float32 pan_lr, float32 pan_fb);
static int command_set_channel_freq(void *internal, int ch, float32 freq);
static int command_set_channel_pos(void *internal, int ch, float64 pos, int dir);
static int command_play_channel(void *internal, int ch, int handle, float32 freq, float32 vol, float32 pan_lr, float32 pan_fb, float64 pos, int dir);
static int command_stop_channel(void *internal, int ch);
static int command_set_option(void *internal, char *option, char *value);
static int command_get_option(void *internal, char *option, char **value);
static int command_get_proc(void *internal, char *name, void_func_t *proc);
static int command_set_call_back(void *internal, mpl__snd_call_back_t call_back);
  static int mixer_command_set_output_options(void *internal, mpl__snd_dev_output_t *opt, int latency);
static int mixer_command_set_options(void *internal, mpl__mixer_opt_t *opt);
static int mixer_command_get_options(void *internal, mpl__mixer_opt_t *opt);
static int mixer_command_get_proc(void *internal, char *name, void_func_t *func);
static int mixer_command_set_vol(void *internal, float32 vol, float32 pan_lr, float32 pan_fb);
static int mixer_command_mix(void *internal, void *buffer, int length);
static int mixer_command_get_num_active_channels(void *internal);
  ///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
// no interpolation
//#define __INTERPOLATE__(valm1, val0, val1, val2, t) (val0)
// linear interpolation
//#define __INTERPOLATE__(valm1, val0, val1, val2, t) (val0 + (val1 - val0) * t)
// spline interpolation
#define __INTERPOLATE__(valm1, val0, val1, val2, t) (((((3.0f * (val0 - val1) - valm1 + val2) * 0.5f) * t + (2.0f * val1 + valm1 - (5.0f * val0 + val2) * 0.5f)) * t + ((val1 - valm1) * 0.5f)) * t + val0)
#define __RAMP___(a,b,c, d) {if (b) {a+=c;b--;if(!b) a=d;}}
#define __RAMP__ {__RAMP___(p_ch->vol_left, p_ch->vol_left_ramp_num, p_ch->vol_left_ramp, p_ch->vol_left_dst) __RAMP___(p_ch->vol_right, p_ch->vol_right_ramp_num, p_ch->vol_right_ramp, p_ch->vol_right_dst) __RAMP___(p_ch->vol_center, p_ch->vol_center_ramp_num, p_ch->vol_center_ramp, p_ch->vol_center_dst)}
  void
mix_inner_loop(mpl__mx_std_t *mx, int ch, float64 step, float32 *buf, int pos, int num)
{
	mpl__mx_std_smp_t *p_smp;
	mpl__mx_std_ch_t *p_ch;
	float32 *smp, tmp, pos_fract;
	int pos_int;
  	p_ch  = mx->ch + ch;
	p_smp = mx->smp + p_ch->smp;
	smp   = (float32*)p_smp->smp.data;
  	switch(2 * (mx->output.channels - 1) + p_smp->smp.channels)
	{
	case 1:
		while(num--)
		{
			pos_int   = (int)p_ch->pos;
			pos_fract = (float32)(p_ch->pos - pos_int);
  			buf[pos++] += __INTERPOLATE__(smp[pos_int],     smp[pos_int + 1],
				                          smp[pos_int + 2], smp[pos_int + 3],
										  pos_fract) * p_ch->vol_center;
  			__RAMP__
  			p_ch->pos += step;
		}
		break;
	case 2:
		while(num--)
		{
			pos_int   = (int)p_ch->pos;
			pos_fract = (float32)(p_ch->pos - pos_int);
			pos_int <<= 1;
  			buf[pos]   += __INTERPOLATE__(smp[pos_int],     smp[pos_int + 2],
				                          smp[pos_int + 4], smp[pos_int + 6],
										  pos_fract) * p_ch->vol_left;
  			buf[pos++] += __INTERPOLATE__(smp[pos_int + 1], smp[pos_int + 3],
				                          smp[pos_int + 5], smp[pos_int + 7],
										  pos_fract) * p_ch->vol_right;
  			__RAMP__
  			p_ch->pos += step;
		}
		break;
	case 3:
		pos <<= 1;
  		while(num--)
		{
			pos_int   = (int)p_ch->pos;
			pos_fract = (float32)(p_ch->pos - pos_int);
  			tmp = __INTERPOLATE__(smp[pos_int],     smp[pos_int + 1],
				                  smp[pos_int + 2], smp[pos_int + 3],
				   			      pos_fract);
  			buf[pos++] += tmp * p_ch->vol_left;
			buf[pos++] += tmp * p_ch->vol_right;
  			__RAMP__
  			p_ch->pos += step;
		}
		break;
	case 4:
		pos <<= 1;
  		while(num--)
		{
			pos_int   = (int)p_ch->pos;
			pos_fract = (float32)(p_ch->pos - pos_int);
			pos_int <<= 1;
  			buf[pos++] += __INTERPOLATE__(smp[pos_int],     smp[pos_int + 2],
				                          smp[pos_int + 4], smp[pos_int + 6],
										  pos_fract) * p_ch->vol_left;
  			buf[pos++] += __INTERPOLATE__(smp[pos_int + 1], smp[pos_int + 3],
				                          smp[pos_int + 5], smp[pos_int + 7],
										  pos_fract) * p_ch->vol_right;
  			__RAMP__
  			p_ch->pos += step;
		}
		break;
	}
}
  #undef __INTERPOLATE__
#undef __RAMP___
#undef __RAMP__
  static void
patch_smp(mpl__mx_std_ch_t *p_ch, mpl__mx_std_smp_t *p_smp)
{
	float32 *data;
  	if (p_ch->loop_mode != MPL__SND_DEV_FMT_LOOPING)
	{
		return;
	}
  	data = (float32*)p_smp->smp.data;
  	if (p_ch->pos < p_ch->loop_beg)
	{
		switch(p_smp->smp.channels)
		{
		case 1:
			p_ch->patch[0] = data[p_ch->loop_beg];
			break;
		case 2:
			p_ch->patch[0] = data[p_ch->loop_beg];
			p_ch->patch[1] = data[p_ch->loop_beg + 1];
			break;
		}
	}
	else
	{
		switch(p_smp->smp.channels)
		{
		case 1:
			p_ch->patch[0] = data[p_ch->loop_beg];
  			data[p_ch->loop_beg] = data[p_ch->loop_end];
			break;
		case 2:
			p_ch->patch[0] = data[p_ch->loop_beg];
			p_ch->patch[1] = data[p_ch->loop_beg + 1];
  			data[p_ch->loop_beg]     = data[p_ch->loop_end];
			data[p_ch->loop_beg + 1] = data[p_ch->loop_end + 1];
			break;
		}
	}
  	switch(p_smp->smp.channels)
	{
	case 1:
		p_ch->patch[1] = data[p_ch->loop_end + 1];
		p_ch->patch[2] = data[p_ch->loop_end + 2];
		p_ch->patch[3] = data[p_ch->loop_end + 3];
  		data[p_ch->loop_end + 1] = data[p_ch->loop_beg + 1];
		data[p_ch->loop_end + 2] = data[p_ch->loop_beg + 2];
		data[p_ch->loop_end + 3] = data[p_ch->loop_beg + 3];
		break;
	case 2:
		p_ch->patch[2] = data[p_ch->loop_end * 2 + 2];
		p_ch->patch[3] = data[p_ch->loop_end * 2 + 3];
		p_ch->patch[4] = data[p_ch->loop_end * 2 + 4];
		p_ch->patch[5] = data[p_ch->loop_end * 2 + 5];
		p_ch->patch[6] = data[p_ch->loop_end * 2 + 6];
		p_ch->patch[7] = data[p_ch->loop_end * 2 + 7];
  		data[p_ch->loop_end * 2 + 2] = data[p_ch->loop_beg * 2 + 2];
		data[p_ch->loop_end * 2 + 3] = data[p_ch->loop_beg * 2 + 3];
		data[p_ch->loop_end * 2 + 4] = data[p_ch->loop_beg * 2 + 4];
		data[p_ch->loop_end * 2 + 5] = data[p_ch->loop_beg * 2 + 5];
		data[p_ch->loop_end * 2 + 4] = data[p_ch->loop_beg * 2 + 6];
		data[p_ch->loop_end * 2 + 5] = data[p_ch->loop_beg * 2 + 7];
		break;
	}
}
  static void
undo_patch(mpl__mx_std_ch_t *p_ch, mpl__mx_std_smp_t *p_smp)
{
	float32 *data;
  	if (p_ch->loop_mode != MPL__SND_DEV_FMT_LOOPING)
	{
		return;
	}
  	data = (float32*)p_smp->smp.data;
  	switch(p_smp->smp.channels)
	{
	case 1:
		data[p_ch->loop_beg]     = p_ch->patch[0];
		data[p_ch->loop_end + 1] = p_ch->patch[1];
		data[p_ch->loop_end + 2] = p_ch->patch[2];
		data[p_ch->loop_end + 3] = p_ch->patch[3];
		break;
	case 2:
		data[p_ch->loop_beg * 2]     = p_ch->patch[0];
		data[p_ch->loop_beg * 2]     = p_ch->patch[1];
		data[p_ch->loop_end * 2 + 2] = p_ch->patch[2];
		data[p_ch->loop_end * 2 + 3] = p_ch->patch[3];
		data[p_ch->loop_end * 2 + 4] = p_ch->patch[4];
		data[p_ch->loop_end * 2 + 5] = p_ch->patch[5];
		data[p_ch->loop_end * 2 + 6] = p_ch->patch[6];
		data[p_ch->loop_end * 2 + 7] = p_ch->patch[7];
		break;
	}
}
  static int
calc_samples_left(mpl__mx_std_ch_t *p_ch, float64 fratio, float64 oofratio)
{
	int tmp;
  	if (p_ch->dir == MPL__SND_DEV_DIR_FORWARDS)
	{
		tmp = (int)((p_ch->loop_end - p_ch->pos) * oofratio);
  		if (p_ch->loop_mode != MPL__SND_DEV_FMT_BIDILOOPING)
		{
			if (tmp * fratio + p_ch->pos < p_ch->loop_end) 
			{
				tmp++;
			}
		}
	}
	else
	{
		if (p_ch->pos < p_ch->loop_beg)
		{
			tmp =  (int)(p_ch->pos * oofratio);
		}
		else
		{
			tmp = (int)((p_ch->pos - p_ch->loop_beg) * oofratio);
		}
	}
  	if (tmp < 0)
	{
		tmp = 0;
	}
  	return tmp;
}
  static int
fix_loop(mpl__mx_std_ch_t *p_ch, float64 *step, float64 fratio, float64 oofratio)
{
	if (p_ch->loop_mode == MPL__SND_DEV_FMT_NONLOOPING)
	{
		return 0;
	}
  	if (p_ch->loop_mode == MPL__SND_DEV_FMT_LOOPING)
	{
		while(!calc_samples_left(p_ch, fratio, oofratio))
		{
			p_ch->pos -= p_ch->loop_end - p_ch->loop_beg;
		}
  		if ((int)p_ch->pos < 0)
		{
			
			p_ch->pos += fratio;
		}
  		return 1;
	}
  	if (p_ch->loop_mode == MPL__SND_DEV_FMT_BIDILOOPING)
	{
		*step     = - *step;
		p_ch->dir = (~p_ch->dir) & 1;
  		return 1;
	}
  	return 0;
}
  #define PAN2VOL_LEFT(pan) ((pan) <= 0.5f ? 1.0f : (1.0f - (pan)) * 2.0f)
#define PAN2VOL_RIGHT(pan) ((pan) >= 0.5f ? 1.0f : (pan) * 2.0f)
  static void
mix_channel(mpl__mx_std_t *mx, int ch, float32 *buf, i32 buf_pos, i32 num)
{
	i32 samples_left, cnt;
	float64 fratio, oofratio, step;
	float32 vol;
	mpl__mx_std_smp_t *p_smp;
	mpl__mx_std_ch_t *p_ch;
  	p_ch  = mx->ch + ch;
	p_smp = mx->smp + p_ch->smp;
  	fratio   = p_ch->freq / mx->output.freq;
	oofratio =          1 / fratio;
  	step      = fratio * (p_ch->dir == MPL__SND_DEV_DIR_FORWARDS ? 1 : -1);
  	if (ch < mx->ch_num)
	{
		vol                  = p_smp->smp.vol * p_ch->vol * mx->vol_global * mx->vol_local;
		p_ch->vol_left_dst   = vol * PAN2VOL_LEFT(p_ch->pan_lr + p_smp->smp.pan_lr + mx->pan_lr_global + mx->pan_lr_local - 1.5f);
		p_ch->vol_right_dst  = vol * PAN2VOL_RIGHT(p_ch->pan_lr + p_smp->smp.pan_lr + mx->pan_lr_global + mx->pan_lr_local - 1.5f);
		p_ch->vol_center_dst = vol;
	}
	else
	{
		p_ch->vol_left_dst   = 0;
		p_ch->vol_right_dst  = 0;
		p_ch->vol_center_dst = 0;
	}
  	if (p_ch->vol_left_dst != p_ch->vol_left)
	{
		if (p_ch->vol_left_dst > p_ch->vol_left)
		{
			p_ch->vol_left_ramp = mx->ramp;
			p_ch->vol_left_ramp_num = (int)((p_ch->vol_left_dst - p_ch->vol_left) / mx->ramp);
		}
		else
		{
			p_ch->vol_left_ramp = -mx->ramp;
			p_ch->vol_left_ramp_num = (int)((p_ch->vol_left - p_ch->vol_left_dst) / mx->ramp);
		}
	}
  	if (p_ch->vol_right_dst != p_ch->vol_right)
	{
		if (p_ch->vol_right_dst > p_ch->vol_right)
		{
			p_ch->vol_right_ramp = mx->ramp;
			p_ch->vol_right_ramp_num = (int)((p_ch->vol_right_dst - p_ch->vol_right) / mx->ramp);
		}
		else
		{
			p_ch->vol_right_ramp = -mx->ramp;
			p_ch->vol_right_ramp_num = (int)((p_ch->vol_right - p_ch->vol_right_dst) / mx->ramp);
		}
	}
  	if (p_ch->vol_center_dst != p_ch->vol_center)
	{
		if (p_ch->vol_center_dst > p_ch->vol_center)
		{
			p_ch->vol_center_ramp = mx->ramp;
			p_ch->vol_center_ramp_num = (int)((p_ch->vol_center_dst - p_ch->vol_center) / mx->ramp);
		}
		else
		{
			p_ch->vol_center_ramp = -mx->ramp;
			p_ch->vol_center_ramp_num = (int)((p_ch->vol_center - p_ch->vol_center_dst) / mx->ramp);
		}
	}
	
	cnt = num;
  	while(cnt)
	{
		samples_left = calc_samples_left(p_ch, fratio, oofratio);
  		if (samples_left == 0)
		{
			if (!fix_loop(p_ch, &step, fratio, oofratio))
			{
				p_ch->playing = 0;
  				return;
			}
  			samples_left = calc_samples_left(p_ch, fratio, oofratio);
		}
  		if (samples_left == 0)
		{
			p_ch->playing = 0;
  			return;
		}
  		samples_left = samples_left < cnt ? samples_left : cnt;
  		if (samples_left < 0)
		{
			samples_left=0;
		}
  		patch_smp(p_ch, p_smp);
		mix_inner_loop(mx, ch, step, buf, buf_pos, samples_left);
		undo_patch(p_ch, p_smp);
  		if (p_ch->vol_left == 0 && p_ch->vol_right == 0 &&
			ch >= mx->ch_num)
		{
			p_ch->playing = 0;
  			return;
		}
  		cnt     -= samples_left;
		buf_pos += samples_left;
	}
}
  static void
filter_dc(mpl__mx_std_t *mx, float32 *buf, int length)
{
	if(mx->output.channels > 1)
	{
		while(length--)
		{
			mx->dc_spd[0] = mx->dc_spd[0] + (*buf - mx->dc_pos[0]) * 0.000004567f;
			mx->dc_pos[0] = mx->dc_pos[0] + mx->dc_spd[0];
			*buf          = *buf - mx->dc_pos[0];
			buf++;
			mx->dc_spd[1] = mx->dc_spd[1] + (*buf - mx->dc_pos[1]) * 0.000004567f;
			mx->dc_pos[1] = mx->dc_pos[1] + mx->dc_spd[1];
			*buf          = *buf - mx->dc_pos[1];
			buf++;
		}
	}
	else
	{
		while(length--)
		{
			mx->dc_spd[0] = mx->dc_spd[0] + (*buf - mx->dc_pos[0]) * 0.000004567f;
			mx->dc_pos[0] = mx->dc_pos[0] + mx->dc_spd[0];
			*buf          = *buf - mx->dc_pos[0];
			buf++;
		}
  		mx->dc_spd[1] = mx->dc_spd[0];
		mx->dc_pos[1] = mx->dc_pos[0];
	}
}
  #undef PAN2VOL_LEFT
#undef PAN2VOL_RIGHT
  static void
quantize(float32 *src, void *dest, int length, int format)
{
	i32 tmp_i32;
	i64 tmp_i64;
  
	switch(format)
	{
	case MPL__SND_DEV_FMT_8BIT:
		while(length--)
		{
			tmp_i32 = (i32)(src[length] * 128.0f);
  			if (tmp_i32 < -128) tmp_i32 = -125;
			if (tmp_i32 > 127) tmp_i32 = 125;
  			((i8*)dest)[length] = (i8)tmp_i32;
		}
		break;
	case MPL__SND_DEV_FMT_16BIT:
		while(length--)
		{
			tmp_i32 = (i32)(src[length] * 32768.0f);
  			if (tmp_i32 < -32768) tmp_i32 = -32760;
			if (tmp_i32 > 32767) tmp_i32 = 32760;
  			((i16*)dest)[length] = (i16)tmp_i32;
		}
		break;
	case MPL__SND_DEV_FMT_24BIT:
		// to do
		break;
	case MPL__SND_DEV_FMT_32BIT:
		while(length--)
		{
			tmp_i64 = (i64)(src[length] * 2147483648.0f);
  			if (tmp_i64 < -(i64)2147483648) tmp_i64 = -(i64)2147483640;
			if (tmp_i64 > 2147483647)       tmp_i64 = 2147483640;
  			((i32*)dest)[length] = (i32)tmp_i64;
		}
		break;
	case MPL__SND_DEV_FMT_FLOAT_32BIT:
		while(length--)
		{
			((float32*)dest)[length] = src[length];
		}
		break;
	}
}
  ///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
static int
command_reset(void *internal)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
	int smp, ch;
  	for(ch = 0; ch < mx->ch_num * 2; ch++)
	{
		mx->ch[ch].playing = 0;
	}
  	for(smp = 0; smp < mx->smp_num; smp++)
	{
		if (mx->smp[smp].smp.data)
		{
			mpl__mem_free(mx->smp[smp].smp.data);
		}
  		mx->smp[smp].exists = 0;
	}
  	mx->paused = 0;
  	return 0;
}
  static int
command_pause(void *internal)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
  	mx->paused ^= 1;
  	return 0;
}
  static int
command_stop(void *internal)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
	int ch;
  	for(ch = 0; ch < mx->ch_num; ch++)
	{
		mx->ch[ch + mx->ch_num] = mx->ch[ch];
		mx->ch[ch].playing      = 0;
	}
  	return 0;
}
  static int
command_upload_sample(void *internal, mpl__snd_mixer_smp_t sample)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
	int smp, size;
	float32 *data;
  	for(smp = 0; smp < mx->smp_num; smp++)
	{
		if (!mx->smp[smp].exists) break;
	}
  	if (smp == mx->smp_num)
	{
		return MPL__ERR_GENERIC;
	}
  #ifdef CHECK_FOR_ERRORS
  	if (sample.channels != 1 &&
		sample.channels != 2)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	if (sample.format < MPL__SND_DEV_FMT_8BIT || sample.format > MPL__SND_DEV_FMT_FLOAT_32BIT)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	if (sample.loopmode != MPL__SND_DEV_FMT_NONLOOPING &&
		sample.loopmode != MPL__SND_DEV_FMT_LOOPING    &&
		sample.loopmode != MPL__SND_DEV_FMT_BIDILOOPING)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	if (sample.length == 0)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	if (sample.loopmode != MPL__SND_DEV_FMT_NONLOOPING && sample.loop >= sample.length)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	if (sample.pan_fb < 0.0f || sample.pan_fb > 1.0f ||
		sample.pan_lr < 0.0f || sample.pan_fb > 1.0f)
	{
		return MPL__ERR_BAD_PARAM;
	}
  #endif
  	size = sizeof(float32) * sample.channels;
  	mx->smp[smp].smp = sample;
  	mx->smp[smp].sus_loop_beg  = sample.loop;
	mx->smp[smp].sus_loop_end  = sample.length;
	mx->smp[smp].sus_loop_mode = sample.loopmode;
  	if (mpl__mem_alloc(size * (sample.length + 4), &mx->smp[smp].smp.data) <= MPL__ERR_GENERIC)
	{
		return MPL__ERR_NOMEM;
	}
  	data = (float32*) mx->smp[smp].smp.data;
  	if (mpl__dsp_conv_format(sample.data, data + sample.channels,
		sample.format, MPL__SND_DEV_FMT_FLOAT_32BIT, sample.length,
		sample.channels, 1.0f) < MPL__ERR_OK)
	{
		mpl__mem_free((void*)data);
  		return MPL__ERR_GENERIC;
	}
  
	switch(sample.channels)
	{
	case 1:
		data[0]                 = data[1];
		data[sample.length + 1] = data[sample.length];
		data[sample.length + 2] = data[sample.length];
		data[sample.length + 3] = data[sample.length];
		break;
	case 2:
		data[0]                 = data[2];
		data[1]                 = data[3];
		data[sample.length * 2 + 2] = data[sample.length * 2];
		data[sample.length * 2 + 3] = data[sample.length * 2 + 1];
		data[sample.length * 2 + 4] = data[sample.length * 2];
		data[sample.length * 2 + 5] = data[sample.length * 2 + 1];
		data[sample.length * 2 + 6] = data[sample.length * 2];
		data[sample.length * 2 + 7] = data[sample.length * 2 + 1];
		break;
	}
  	mx->smp[smp].exists = 1;
  	return smp;
}
  static int
command_destroy_sample(void *internal, int handle)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
	int ch;
  #ifdef CHECK_FOR_ERRORS
  	if (handle < 0 || handle >= mx->smp_num)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	if (!mx->smp[handle].exists)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	for(ch = 0; ch < mx->ch_num * 2; ch++)
	{
		if (mx->ch[ch].playing && mx->ch[ch].smp == handle)
		{
			return MPL__ERR_BAD_PARAM;
		}
	}
#endif
  	mpl__mem_free(mx->smp[handle].smp.data);
  	mx->smp[handle].exists = 0;
  	return 0;
}
  static int
command_set_sustain_loop(mpl__snd_mixer_t *sndmx, int handle, int begin, int end, int mode)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) sndmx->internal_data;
	mpl__mx_std_smp_t *smp;
  #ifdef CHECK_FOR_ERRORS
  	if (handle < 0 || handle >= mx->smp_num)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	smp = mx->smp + handle;
  	if (!smp->exists)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	if (end > smp->smp.length)
	{
		return MPL__ERR_BAD_PARAM;
	}
  #endif
  	smp->sus_loop_beg  = begin;
	smp->sus_loop_end  = end;
	smp->sus_loop_mode = mode;
  	return 0;
}
  static int
command_end_sustain(mpl__snd_mixer_t *sndmx, int ch)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) sndmx->internal_data;
	mpl__mx_std_smp_t *smp;
  #ifdef CHECK_FOR_ERRORS
  	if (ch < 0 || ch >= mx->ch_num)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	if (!mx->ch[ch].playing)
	{
		return MPL__ERR_GENERIC;
	}
  	smp = &mx->smp[mx->ch[ch].smp];
  #endif
  	mx->ch[ch].loop_beg  = smp->smp.loop;
	mx->ch[ch].loop_end  = smp->smp.length;
	mx->ch[ch].loop_mode = smp->smp.loopmode;
  	return 0;
}
  static int
command_set_vol(void *internal, float32 vol, float32 pan_lr, float32 pan_fb)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
  #ifdef CHECK_FOR_ERRORS
	if (pan_lr < 0.0f || pan_lr > 1.0f ||
		pan_fb < 0.0f || pan_fb > 1.0f)
	{
		return MPL__ERR_BAD_PARAM;
	}
#endif
  	mx->vol_local    = vol;
	mx->pan_lr_local = pan_lr;
	mx->pan_fb_local = pan_fb;
  	return 0;
}
  static int
command_get_vol(void *internal, float32 *vol, float32 *pan_lr, float32 *pan_fb)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
  	*vol    = mx->vol_local;
	*pan_lr = mx->pan_lr_local;
	*pan_fb = mx->pan_fb_local;
  	return 0;
}
  static int
command_get_output_options(void *internal, mpl__snd_dev_output_t *opt)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
  	*opt = mx->output;
  	return 0;
}
  static int
command_get_latency(void *internal)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
  	return mx->latency;
}
  static int
command_get_num_channels(void *internal)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
  	return mx->ch_num;
}
  static int
command_get_num_active_channels(void *internal)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
	int ch, num;
  	num = 0;
  	for(ch = 0; ch < mx->ch_num; ch++)
	{
		if (mx->ch[ch].playing)
		{
			num++;
		}
	}
  	return num;
}
  static int
command_get_free_channel(void *internal)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
	int ch;
  	for(ch = 0; ch < mx->ch_num; ch++)
	{
		if (!mx->ch[ch].playing)
		{
			return ch;
		}
	}
  	return MPL__ERR_GENERIC;
}
  static int
command_is_channel_active(void *internal, int ch)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
  #ifdef CHECK_FOR_ERRORS
  	if (ch < 0 || ch >= mx->ch_num)
	{
		return MPL__ERR_BAD_PARAM;
	}
  #endif
  	return mx->ch[ch].playing != 0;
}
  static int
command_set_channel_vol(void *internal, int ch, float32 vol, float32 pan_lr, float32 pan_fb)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
  #ifdef CHECK_FOR_ERRORS
  	if (ch < 0 || ch >= mx->ch_num)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	if (!mx->ch[ch].playing)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	if (pan_lr < 0.0f || pan_lr > 1.0f ||
		pan_fb < 0.0f || pan_fb > 1.0f)
	{
		return MPL__ERR_BAD_PARAM;
	}
  #endif
  	mx->ch[ch].vol    = vol;
	mx->ch[ch].pan_lr = pan_lr;
  	return 0;
}
  static int
command_set_channel_freq(void *internal, int ch, float32 freq)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
  #ifdef CHECK_FOR_ERRORS
  	if (ch < 0 || ch >= mx->ch_num)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	if (!mx->ch[ch].playing)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	if (freq <= 0 || freq > 1000000)
	{
		return MPL__ERR_BAD_PARAM;
	}
  #endif
  	mx->ch[ch].freq = freq;
  	return -1;
}
  static int
command_set_channel_pos(void *internal, int ch, float64 pos, int dir)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
  #ifdef CHECK_FOR_ERRORS
  	if (ch < 0 || ch >= mx->ch_num)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	if (!mx->ch[ch].playing)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	if (dir != MPL__SND_DEV_DIR_FORWARDS || dir != MPL__SND_DEV_DIR_BACKWARDS)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	if (pos < 0 || pos >= mx->ch[ch].loop_end)
	{
		return MPL__ERR_BAD_PARAM;
	}
  #endif
  	mx->ch[ch + mx->ch_num] = mx->ch[ch];
  	mx->ch[ch].pos        = pos;
	mx->ch[ch].dir        = dir;
	mx->ch[ch].vol_left   = 0;
	mx->ch[ch].vol_right  = 0;
	mx->ch[ch].vol_center = 0;
  
	return 0;
}
  static int
command_play_channel(void *internal, int ch, int handle, float32 freq, float32 vol, float32 pan_lr, float32 pan_fb, float64 pos, int dir)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
	mpl__mx_std_smp_t *smp;
  #ifdef CHECK_FOR_ERRORS
  	if (ch < 0 || ch >= mx->ch_num)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	if (handle < 0 || handle >= mx->smp_num)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	smp = mx->smp + handle;
  	if (!smp->exists)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	if (freq != -1 && (freq < 1 || freq > 1000000))
	{
		return MPL__ERR_BAD_PARAM;
	}
  	if (dir != -1 && dir != MPL__SND_DEV_DIR_FORWARDS && dir != MPL__SND_DEV_DIR_BACKWARDS)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	if (pan_lr < 0.0f || pan_lr > 1.0f ||
		pan_fb < 0.0f || pan_fb > 1.0f)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	if (pos < 0 || pos >= smp->sus_loop_end)
	{
		return MPL__ERR_BAD_PARAM;
	}
  #endif
  	mx->ch[ch + mx->ch_num] = mx->ch[ch];
  	mx->ch[ch].pos        = pos;
	mx->ch[ch].dir        = dir;
	mx->ch[ch].smp        = handle;
	mx->ch[ch].freq       = freq == -1 ? mx->smp[handle].smp.freq : freq;
	mx->ch[ch].vol        = vol;
	mx->ch[ch].pan_lr     = pan_lr;
	mx->ch[ch].vol_left   = 0;
	mx->ch[ch].vol_right  = 0;
	mx->ch[ch].vol_center = 0;
	mx->ch[ch].loop_beg   = smp->sus_loop_beg;
	mx->ch[ch].loop_end   = smp->sus_loop_end;
	mx->ch[ch].loop_mode  = smp->sus_loop_mode;
	mx->ch[ch].playing    = 1;
  	return 0;
}
  static int
command_stop_channel(void *internal, int ch)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
  #ifdef CHECK_FOR_ERRORS
  	if (ch < 0 || ch >= mx->ch_num)
	{
		return MPL__ERR_BAD_PARAM;
	}
  #endif
  	mx->ch[ch + mx->ch_num] = mx->ch[ch];
	mx->ch[ch].playing      = 0;
  	return 0;
}
  static int
command_set_option(void *internal, char *option, char *value)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
  	return MPL__ERR_BAD_PARAM;
}
  static int
command_get_option(void *internal, char *option, char **value)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
  	if (mpl__string_cmp_char(option, "ID") == MPL__STRING_EQUAL)
	{
		*value = "standard mixer";
  		return 0;
	}
  	if (mpl__string_cmp_char(option, "VERSION") == MPL__STRING_EQUAL)
	{
		*value = "0.01";
  		return 0;
	}
  	if (mpl__string_cmp_char(option, "AUTHOR") == MPL__STRING_EQUAL)
	{
		*value = "";
  		return 0;
	}
  	if (mpl__string_cmp_char(option, "EXTENSIONS") == MPL__STRING_EQUAL)
	{
		*value = "EXT_SUSTAIN_LOOP";
  		return 0;
	}
  	return MPL__ERR_BAD_PARAM;
}
  static int
command_get_proc(void *internal, char *name, void_func_t *proc)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
  	if (mpl__string_cmp_char(name, MPL__FUNC_SND_MIXER_SET_SUSTAIN_LOOP) == MPL__STRING_EQUAL)
	{
		*proc = (void_func_t)command_set_sustain_loop;
		return 1;
	}
  	if (mpl__string_cmp_char(name, MPL__FUNC_SND_MIXER_END_SUSTAIN) == MPL__STRING_EQUAL)
	{
		*proc = (void_func_t)command_end_sustain;
  		return 0;
	}
  	return MPL__ERR_BAD_PARAM;
}
  static int
command_set_call_back(void *internal, mpl__snd_call_back_t call_back)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
  	mx->call_back        = call_back;
  	mx->count_down_frac += mx->call_back.period * mx->output.freq * 0.001;
	mx->count_down       = (int)(mx->count_down_frac);
	mx->count_down_frac -= mx->count_down;
  	return 0;
}
  ///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
static int
mixer_command_set_output_options(void *internal, mpl__snd_dev_output_t *opt, int latency)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
  #ifdef CHECK_FOR_ERRORS
  	if (opt->channels != 1 &&
		opt->channels != 2)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	if (opt->format < MPL__SND_DEV_FMT_8BIT || opt->format > MPL__SND_DEV_FMT_FLOAT_32BIT)
	{
		return MPL__ERR_BAD_PARAM;
	}
  	if (opt->latency != MPL__SND_DEV_LATENCY_HIGH && opt->latency != MPL__SND_DEV_LATENCY_HIGH)
	{
		return MPL__ERR_BAD_PARAM;
	}
  #endif
  	mx->dc_spd[0]     = 0;
	mx->dc_pos[0]     = 0;
	mx->dc_spd[1]     = 0;
	mx->dc_pos[1]     = 0;
  	mx->output  = *opt;
	mx->latency = latency;
  	mx->ramp    = 1.0f / (opt->freq * RAMPING);
  	mx->count_down = (int)(mx->count_down * opt->freq / mx->output.freq);
  	return 0;
}
  static int
mixer_command_set_options(void *internal, mpl__mixer_opt_t *opt)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
	mpl__mx_std_ch_t *ch=0;
	mpl__mx_std_smp_t *smp=0;
  	if (opt->ch_num != -1)
	{
		int cur;
  		if (opt->ch_num < 1 || opt->ch_num > 256)
		{
			return MPL__ERR_BAD_PARAM;
		}
  		for(cur = 0; cur < mx->ch_num; cur++)
		{
			if (mx->ch[cur].playing)
			{
				return MPL__ERR_GENERIC;
			}
		}
  	}
  	if (opt->smp_num != -1)
	{
		int cur;
  		if (opt->smp_num < 1 || opt->smp_num > 256)
		{
			return MPL__ERR_BAD_PARAM;
		}
  		for(cur = 0; cur < mx->smp_num; cur++)
		{
			if (mx->smp[cur].exists)
			{
				return MPL__ERR_GENERIC;
			}
		}
	}
  	if (opt->mem_usage != -1)
	{
		if (opt->mem_usage != MPL__MX_MEM_AGGRESSIVE && opt->mem_usage != MPL__MX_MEM_LOW)
		{
			return MPL__ERR_BAD_PARAM;
		}
	}
  	if (opt->qual != -1)
	{
		if (opt->qual != MPL__MX_HQ && opt->qual != MPL__MX_LQ)
		{
			return MPL__ERR_BAD_PARAM;
		}
  	}
  	if (opt->smp_num != -1)
	{
		if (mpl__mem_alloc(opt->smp_num * sizeof(mpl__mx_std_smp_t), (void**)&smp) <= MPL__ERR_GENERIC)
		{
			return MPL__ERR_NOMEM;
		}
  		mpl__mem_set_zero(smp, opt->smp_num * sizeof(mpl__mx_std_smp_t));
	}
  	if (opt->ch_num != -1)
	{
		if (mpl__mem_alloc(opt->ch_num * 2 * sizeof(mpl__mx_std_ch_t), (void**)&ch) <= MPL__ERR_GENERIC)
		{
			if (smp)
			{
				mpl__mem_free(smp);
			}
			
			return MPL__ERR_NOMEM;
		}
  		mpl__mem_set_zero(ch, opt->ch_num * 2 * sizeof(mpl__mx_std_ch_t));
	}
  	if (opt->ch_num != -1)
	{
		int cur;
  		mpl__mem_free(mx->ch);
  		mx->ch     = ch;
		mx->ch_num = opt->ch_num;
  		for(cur = 0; cur < mx->ch_num * 2; cur++)
		{
			mx->ch[cur].playing = 0;
		}
	}
  	if (opt->smp_num != -1)
	{
		int cur;
  		for(cur = 0; cur < mx->smp_num; cur++)
		{
			if (mx->smp[cur].exists && mx->smp[cur].smp.data)
			{
				mpl__mem_free(mx->smp[cur].smp.data);
			}
		}
  		mpl__mem_free(mx->smp);
  		mx->smp     = smp;
		mx->smp_num = opt->smp_num;
  		for(cur = 0; cur < mx->smp_num; cur++)
		{
			mx->smp[cur].exists = 0;
		}
	}
  	if (opt->mem_usage != -1)
	{
		mx->mem_usage = opt->mem_usage;
	}
  	if (opt->qual != -1)
	{
  		mx->qual = opt->qual;
	}
  	return 0;
}
  static int
mixer_command_get_options(void *internal, mpl__mixer_opt_t *opt)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
  	opt->ch_num    = mx->ch_num;
	opt->smp_num   = mx->smp_num;
	opt->mem_usage = mx->mem_usage;
	opt->qual      = mx->qual;
  	return 0;
}
  static int
mixer_command_get_proc(void *internal, char *name, void_func_t *func)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
  	return MPL__ERR_BAD_PARAM;
}
  static int
mixer_command_set_vol(void *internal, float32 vol, float32 pan_lr, float32 pan_fb)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
	
#ifdef CHECK_FOR_ERRORS
	
	if (pan_lr < 0.0f || pan_lr > 1.0f ||
		pan_fb < 0.0f || pan_fb > 1.0f)
	{
		return MPL__ERR_BAD_PARAM;
	}
	
#endif
	
	mx->vol_global    = vol;
	mx->pan_lr_global = pan_lr;
	mx->pan_fb_global = pan_fb;
  	return 0;
}
  static int
mixer_command_mix(void *internal, void *buffer, int length)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
	mpl__mx_std_ch_t *ch;
	mpl__mx_std_smp_t *smp;
	float32 *mix_buf;
	int mix_buf_size, mix_buf_pos, cnt, gap_size;
  	mix_buf_size = mx->output.channels * length;
  //	bad (and slow)
	if (mpl__mem_alloc(sizeof(float32) * mix_buf_size, (void**)&mix_buf) <= MPL__ERR_GENERIC)
	{
		return MPL__ERR_NOMEM;
	}
  	mix_buf_pos = 0;
  	for(cnt = 0; cnt < mix_buf_size ; cnt++)
	{
		mix_buf[cnt] = 0;
	}
  	if (mx->paused)
	{
		goto convert;
	}
  	while(mix_buf_pos < length)
	{
		gap_size = length - mix_buf_pos;
  		if (mx->call_back.func)
		{
			if (!mx->count_down)
			{
				mx->call_back.func(mx->call_back.data, mx->call_back.param);
  				mx->count_down_frac += mx->call_back.period * mx->output.freq * 0.001;
				mx->count_down       = (int)(mx->count_down_frac);
				mx->count_down_frac -= mx->count_down;
			}
  			gap_size = gap_size < mx->count_down ? gap_size : mx->count_down;
		}
  		for(cnt = 0; cnt < mx->ch_num * 2; cnt++)
		{
			ch = mx->ch + cnt;
  			if (!ch->playing)
			{
				continue;
			}
  			smp = mx->smp + ch->smp;
  			mix_channel(mx, cnt, mix_buf, mix_buf_pos, gap_size);
		}
  		mix_buf_pos    += gap_size;
		mx->count_down -= gap_size;
	}
  convert:
	//filter_dc(mx, mix_buf, length);
	quantize(mix_buf, buffer, length * mx->output.channels, mx->output.format);
  	mpl__mem_free(mix_buf);
  	return 0;
}
  static int
mixer_command_get_num_active_channels(void *internal)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
	int ch, cnt;
  	cnt = 0;
  	for(ch = 0; ch < mx->ch_num; ch++)
	{
		if (mx->ch[ch].playing)
		{
			cnt++;
		}
	}
  	return cnt;
}
  static int
mixer_command_get_interface(void *internal, mpl__snd_mixer_t **mixer)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) internal;
  	*mixer = &mx->iface;
  	return 0;
}
  ///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
int
mpl__mx_std_create(mpl__mixer_t **mixer)
{
	mpl__mx_std_t *mx;
  	if (mpl__mem_alloc(sizeof(mpl__mixer_t), (void**)mixer) <= MPL__ERR_GENERIC)
	{
		return MPL__ERR_NOMEM;
	}
  	if (mpl__mem_alloc(sizeof(mpl__mx_std_t), (void**)&mx) <= MPL__ERR_GENERIC)
	{
		mpl__mem_free(*mixer);
  		return MPL__ERR_NOMEM;
	}
  	if (mpl__mem_alloc(sizeof(mpl__mx_std_ch_t) * 2, (void**)&mx->ch) <= MPL__ERR_GENERIC)
	{
		mpl__mem_free(*mixer);
		mpl__mem_free(mx);
  		return MPL__ERR_NOMEM;
	}
  	if (mpl__mem_alloc(sizeof(mpl__mx_std_smp_t), (void**)&mx->smp) <= MPL__ERR_GENERIC)
	{
		mpl__mem_free(*mixer);
		mpl__mem_free(mx);
		mpl__mem_free(mx->ch);
  		return MPL__ERR_NOMEM;
	}
  	(*mixer)->get_interface           = mixer_command_get_interface;
	(*mixer)->get_num_active_channels = mixer_command_get_num_active_channels;
	(*mixer)->get_options             = mixer_command_get_options;
	(*mixer)->get_proc                = mixer_command_get_proc;
	(*mixer)->mix                     = mixer_command_mix;
	(*mixer)->set_options             = mixer_command_set_options;
	(*mixer)->set_output_options      = mixer_command_set_output_options;
	(*mixer)->set_vol                 = mixer_command_set_vol;
  	(*mixer)->internal_data = mx;
  	mx->iface.destroy_sample          = command_destroy_sample;
	mx->iface.get_free_channel        = command_get_free_channel;
	mx->iface.get_latency             = command_get_latency;
	mx->iface.get_num_active_channels = command_get_num_active_channels;
	mx->iface.get_num_channels        = command_get_num_channels;
	mx->iface.get_option              = command_get_option;
	mx->iface.get_output_options      = command_get_output_options;
	mx->iface.get_proc                = command_get_proc;
	mx->iface.get_vol                 = command_get_vol;
	mx->iface.is_channel_active       = command_is_channel_active;
	mx->iface.pause                   = command_pause;
	mx->iface.play_channel            = command_play_channel;
	mx->iface.reset                   = command_reset;
	mx->iface.set_call_back           = command_set_call_back;
	mx->iface.set_channel_freq        = command_set_channel_freq;
	mx->iface.set_channel_pos         = command_set_channel_pos;
	mx->iface.set_channel_vol         = command_set_channel_vol;
	mx->iface.set_option              = command_set_option;
	mx->iface.set_vol                 = command_set_vol;
	mx->iface.stop                    = command_stop;
	mx->iface.stop_channel            = command_stop_channel;
	mx->iface.upload_sample           = command_upload_sample;
  	mx->iface.internal_data = mx;
  	mx->smp_num         = 1;
	mx->smp->exists     = 0;
  	mx->ch_num          = 1;
	mx->ch[0].playing   = 0;
	mx->ch[1].playing   = 0;
  	mx->count_down_frac = 0;
	mx->call_back.func  = 0;
	mx->latency         = 0;
	mx->mem_usage       = MPL__MX_MEM_LOW;
	mx->output.channels = 2;
	mx->output.format   = MPL__SND_DEV_FMT_16BIT;
	mx->output.freq     = 44100;
	mx->output.latency  = MPL__SND_DEV_LATENCY_HIGH;
	mx->paused          = 0;
	mx->qual            = MPL__MX_HQ;
	mx->vol_global      = 1.0f;
	mx->pan_lr_global   = 0.5f;
	mx->pan_fb_global   = 0.5f;
	mx->vol_local       = 1.0f;
	mx->pan_lr_local    = 0.5f;
	mx->pan_fb_local    = 0.5f;
	mx->dc_spd[0]       = 0;
	mx->dc_pos[0]       = 0;
	mx->dc_spd[1]       = 0;
	mx->dc_pos[1]       = 0;
	mx->ramp            = 1.0f / (44100 * RAMPING);
  	return 0;
}
  void
mpl__mx_std_destroy(mpl__mixer_t *mixer)
{
	mpl__mx_std_t *mx = (mpl__mx_std_t*) mixer->internal_data;
  	mpl__mem_free(mx->ch);
	mpl__mem_free(mx->smp);
	mpl__mem_free(mx);
	mpl__mem_free(mixer);
}
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/src/main.c] - (6,817 bytes)
 
 #include <windows.h>
#include <malloc.h>
#include <process.h>
#include <mmsystem.h>
#include <dsound.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <conio.h>
  #include <stdio.h>
#include <vbf/vbf_std.h>
#include <mpl/mx_std.h>
#include <mpl/ml_xm.h>
#include <mpl/sys/mem.h>
  #define PLAYFREQ 44100
  mpl__mixer_t *mixah;
  LPDIRECTSOUND8 ds8 = 0;
WAVEFORMATEX format;
DSBUFFERDESC desc;
LPDIRECTSOUNDBUFFER8 buf = 0;
int bufpos;
  void *tmpbuf;
int tmpbufsize;
int kill=0;
int playing=0;
  double sine_pos = 0;
  void
fillwf(WAVEFORMATEX *wf, int ch, int freq, int bits)
{
	wf->wFormatTag      = WAVE_FORMAT_PCM;
	wf->nChannels       = ch;
	wf->nSamplesPerSec  = freq;
	wf->wBitsPerSample  = bits;
	wf->nBlockAlign     = bits * ch >> 3;
	wf->nAvgBytesPerSec = wf->nSamplesPerSec * wf->nBlockAlign;
}
  int
init()
{
	if (FAILED(DirectSoundCreate8(0, &ds8, 0)))
	{
		return -1;
	}
  	if (FAILED(ds8->lpVtbl->SetCooperativeLevel(ds8, GetForegroundWindow(), DSSCL_NORMAL)))
	{
		return -1;
	}
  	kill = 0;
  	return 0;
}
  void
shutitdown()
{
	if (playing)
	{
		kill = 1;
  		while(kill) Sleep(5);
	}
  	if (buf)
	{
		IUnknown_Release(buf);
		buf = 0;
	}
  	if (ds8)
	{
		IUnknown_Release(ds8);
		ds8 = 0;
	}
}
  
int
setprimarybufferformat(int ch, int freq, int bits)
{
	LPDIRECTSOUNDBUFFER primbuf;
	WAVEFORMATEX format;
	DSBUFFERDESC desc;
  
	desc.dwBufferBytes = 0;
	desc.lpwfxFormat   = 0;
	desc.dwFlags       = DSBCAPS_PRIMARYBUFFER;
	desc.dwSize        = sizeof(DSBUFFERDESC);
	desc.dwReserved    = 0;
  	if (FAILED(ds8->lpVtbl->CreateSoundBuffer(ds8, &desc, &primbuf, 0)))
	{
		return -1;
	}
  	fillwf(&format, ch, freq, bits);
  	if (FAILED(primbuf->lpVtbl->SetFormat(primbuf, &format)))
	{
		IUnknown_Release(primbuf);
  		return -1;
	}
  	IUnknown_Release(primbuf);
  	return 0;
}
  
int
calc_space_left()
{
	int readpos, writepos;
  	buf->lpVtbl->GetCurrentPosition(buf, &readpos, &writepos);
  	if (bufpos < readpos)
	{
		return readpos - bufpos;
	}
  	return desc.dwBufferBytes - bufpos + readpos;
}
  int
write_data(void *data, mpl__mem_size_t size)
{
	int result, length1, length2;
	void *address1, *address2;
  	result = buf->lpVtbl->Lock(buf, bufpos, size,
							   &address1, &length1,
							   &address2, &length2,
							   0);
  	if (result == DSERR_BUFFERLOST)
	{
		buf->lpVtbl->Restore(buf);
  		result = buf->lpVtbl->Lock(buf, bufpos, size,
								   &address1, &length1,
								   &address2, &length2,
								   0);
	}
  	if (result != DS_OK)
	{
		return 0;
	}
  	mpl__mem_copy(data, address1, length1);
  	if (length2)
	{
		mpl__mem_copy(((i8*)data) + length1, address2, length2);
	}
  	buf->lpVtbl->Unlock(buf, address1, length1, address2, length2);
  	return 1;
}
  int
fillbuf()
{
	mpl__mixer_mix(mixah, tmpbuf, tmpbufsize);
	
	return 0;
}
  void __cdecl
dsthread(void *param)
{
	fillbuf();
  	while(!kill)
	{
		if (calc_space_left() > tmpbufsize * format.nBlockAlign)
		{
			write_data(tmpbuf, tmpbufsize * format.nBlockAlign);
  			bufpos += tmpbufsize * format.nBlockAlign;
			bufpos %= desc.dwBufferBytes;
  			fillbuf();
		}
  		Sleep(5);
	}
  	kill = 0;
}
  int
setparams(int ch, int freq, int bits)
{
	if (buf)
	{
		IUnknown_Release(buf);
		buf = 0;
	}
  	fillwf(&format, ch, freq, bits);
  	desc.dwBufferBytes = format.nBlockAlign * (int)(freq * 0.1);
	desc.lpwfxFormat   = &format;
	desc.dwFlags       = DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2;
	desc.dwSize        = sizeof(DSBUFFERDESC);
	desc.dwReserved    = 0;
  	if (FAILED(ds8->lpVtbl->CreateSoundBuffer(ds8, &desc, (struct IDirectSoundBuffer**)&buf, 0)))
	{
		return -1;
	}
  	tmpbufsize = (desc.dwBufferBytes / format.nBlockAlign) >> 2;
  	if (mpl__mem_alloc(format.nBlockAlign * tmpbufsize, &tmpbuf) <= MPL__ERR_GENERIC)
	{
		IUnknown_Release(buf);
		buf = 0;
		return -1;
	}
  	SetThreadPriority((HANDLE)_beginthread(dsthread, 0, 0), THREAD_PRIORITY_TIME_CRITICAL);
  	return 0;
}
  int
play()
{
	if (buf->lpVtbl->Play(buf, 0, 0, DSBPLAY_LOOPING) != DS_OK)
	{
		return -1;
	}
  	playing = 1;
  	return 0;
}
  int
clear()
{
	int result, length;
	char *bufpnt;
  	result = buf->lpVtbl->Lock(buf, 0, desc.dwBufferBytes,
							   &bufpnt, &length,
							   0, 0,
							   0);
  	if (result == DSERR_BUFFERLOST)
	{
		buf->lpVtbl->Restore(buf);
  		result = buf->lpVtbl->Lock(buf, 0, desc.dwBufferBytes,
								   &bufpnt, &length,
								   0, 0,
								   0);
	}
  	if (result != DS_OK)
	{
		return 0;
	}
  	while(length--)
	{
		bufpnt[length] = 0;
	}
  	buf->lpVtbl->Unlock(buf, bufpnt, desc.dwBufferBytes, 0, 0);
  	return 1;
}
  void
stop()
{
	buf->lpVtbl->Stop(buf);
  	playing = 0;
}
  int
cmd_cm(void *internal, mpl__snd_mixer_t **mixer, mpl__snd_mixer_opt_t opt)
{
	mpl__mixer_opt_t mopt;
	mpl__mixer_t *mx;
	mpl__snd_dev_output_t out;
  	mpl__mx_std_create(&mx);
  	mixah = mx;
  	mopt.ch_num = opt.ch_num;
	mopt.mem_usage = 0;
	mopt.qual = MPL__MX_HQ;
	mopt.smp_num = opt.smp_num;
  	mpl__mixer_set_options(mx, &mopt);
	mpl__mixer_set_vol(mx, 1.0f, 0.5f, 0.5f);
  	out.channels = 2;
	out.format = MPL__SND_DEV_FMT_16BIT;
	out.freq = PLAYFREQ;
	out.latency = 0;
  	mpl__mixer_set_output_options(mx, &out, 100);
  	mpl__mixer_get_interface(mx, mixer);
  	return 0;
}
  int
cmd_dm(void *internal, mpl__snd_mixer_t *mixer)
{
	return 0;
}
  int
cmd_goo(void *internal, mpl__snd_dev_output_t *opt)
{
	opt->channels = 2;
	opt->format = 2;
	opt->freq = PLAYFREQ;
	opt->latency = 0;
  	return 0;
}
  i16 buffer[2 * 10 * PLAYFREQ];
  int
main(int argc, char **argv)
{
  	mpl__xm_t xm;
	mpl__mp_t mp;
	vbf_t file;
	mpl__snd_dev_t dev;
	FILE *rg;
  	mpl__mem_init();
  	if (argc != 2)
	{
		printf("syntax: %s filename.xm\n", argv[0]);
		return 0;
	}
  	dev.create_mixer = cmd_cm;
	dev.destroy_mixer = cmd_dm;
	dev.get_output_options = cmd_goo;
  	rg = fopen(argv[1], "rb");
	if (!rg)
	{
		printf("file not found\n");
		return 0;
	}
	
	vbf_std_open(&file, rg);
	mpl__xm_load(&file, &xm);
	vbf_close(&file);
	fclose(rg);
  	if (mpl__mp_xm_construct(&xm, &mp, 0) < MPL__ERR_OK)
	{
		printf("error\n");
		return 0;
	}
  	if (mpl__mp_set_dev(&mp, &dev) < MPL__ERR_OK)
	{
		printf("couldn't set device\n");
		return 0;
	}
	
	if (mpl__mp_set_vol(&mp, 0.6f) < MPL__ERR_OK)
	{
		printf("error\n");
		return 0;
	}
  	if (mpl__mp_play(&mp) < MPL__ERR_OK)
	{
		printf("error\n");
		return 0;
	}
  	mpl__mp_set_loop(&mp, 4);
  	init();
	setparams(2, PLAYFREQ, 16);
	clear();
	play();
  	printf("playin'.....\n");
  	while(!kbhit()) Sleep(100);
	stop();
  	return 0;
}
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/inc/sys_cfg.h] - (771 bytes)
 
 #ifndef sys_cfg_h_n423788423342
#define sys_cfg_h_n423788423342
  typedef __int64              i64;
typedef unsigned __int64     u64;
//typedef long long            i64;
//typedef unsigned long long   u64;
typedef int                  i32;
typedef unsigned int         u32;
typedef short                i16;
typedef unsigned short       u16;
typedef char                 i8;
typedef unsigned char        u8;
  typedef float                float32;
typedef double               float64;
//typedef long double          float80;
typedef short                wide_char;
  typedef void(*void_func_t)(void);
  #define SYS_SMALL_ENDIAN     1
//#define SYS_BIG_ENDIAN       1
//#define SYS_MINI_VERSION     1
#define inline_function __inline
  #endif
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/inc/vbf/vbf_mem.h] - (184 bytes)
 
 #ifndef vbf_mem_h_n4237878942373243422348
#define vbf_mem_h_n4237878942373243422348
  #include <vbf/vbf.h>
  int vbf_mem_open(vbf_t *vbf, void *buffer, vbf_size_t size);
  #endif
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/inc/vbf/vbf_std.h] - (183 bytes)
 
 #ifndef vbf_std_h_n478278423789423789342
#define vbf_std_h_n478278423789423789342
  #include <vbf/vbf.h>
#include <stdio.h>
  int vbf_std_open(vbf_t *vbf, FILE *file);
  #endif
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/inc/vbf/vbf_util.h] - (1,654 bytes)
 
 #ifndef vbf_util_h_n4782378243893
#define  vbf_util_h_n4782378243893
  #include <vbf/vbf.h>
#include <sys_cfg.h>
  #define VBF_BIG_ENDIAN       0
#define VBF_SMALL_ENDIAN     1
  int vbf_read_u64(vbf_t *vbf, int endianess, u64 *val);
int vbf_read_i64(vbf_t *vbf, int endianess, i64 *val);
int vbf_read_u32(vbf_t *vbf, int endianess, u32 *val);
int vbf_read_i32(vbf_t *vbf, int endianess, i32 *val);
int vbf_read_u16(vbf_t *vbf, int endianess, u16 *val);
int vbf_read_i16(vbf_t *vbf, int endianess, i16 *val);
int vbf_read_u8(vbf_t *vbf, int endianess, u8 *val);
int vbf_read_i8(vbf_t *vbf, int endianess, i8 *val);
int vbf_read_float32(vbf_t *vbf, int endianess, float32 *val);
int vbf_read_float64(vbf_t *vbf, int endianess, float64 *val);
  int vbf_read_array_u64(vbf_t *vbf, int endianess, int num, u64 *val);
int vbf_read_array_i64(vbf_t *vbf, int endianess, int num, i64 *val);
int vbf_read_array_u32(vbf_t *vbf, int endianess, int num, u32 *val);
int vbf_read_array_i32(vbf_t *vbf, int endianess, int num, i32 *val);
int vbf_read_array_u16(vbf_t *vbf, int endianess, int num, u16 *val);
int vbf_read_array_i16(vbf_t *vbf, int endianess, int num, i16 *val);
int vbf_read_array_u8(vbf_t *vbf, int endianess, int num, u8 *val);
int vbf_read_array_i8(vbf_t *vbf, int endianess, int num, i8 *val);
int vbf_read_array_float32(vbf_t *vbf, int endianess, int num, float32 *val);
int vbf_read_array_float64(vbf_t *vbf, int endianess, int num, float64 *val);
  int vbf_read_line_char(vbf_t *vbf, char *buf, int max, int *read);
int vbf_read_line_wide_char(vbf_t *vbf, int endianess, wide_char *buf, int max, int *read);
  #endif
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/inc/vbf/vbf.h] - (1,632 bytes)
 
 #ifndef vbf_h_n423789784923789423
#define vbf_h_n423789784923789423
  #include <sys_cfg.h>
  #define VBF_ATTR_OPEN     1
#define VBF_ATTR_READ     2
#define VBF_ATTR_WRITE    4
#define VBF_ATTR_APPEND   8
#define VBF_ATTR_SEEK     16
#define VBF_ATTR_LENGTH   32
  #define VBF_ERR_GENERIC   -1
#define VBF_ERR_BAD_POS   -2
#define VBF_ERR_NOT_OPEN  -3
#define VBF_ERR_NO_LENGTH -4
#define VBF_ERR_NO_SEEK   -5
#define VBF_ERR_NO_READ   -6
#define VBF_ERR_NO_WRITE  -7
  typedef long int vbf_size_t;
  typedef struct vbf_s {
	int        mode;
	vbf_size_t pos, length;
	void       *data;
  	int (*raw_read)(struct vbf_s *vbf, void *buffer, vbf_size_t size, vbf_size_t *out_size);
	int (*raw_write)(struct vbf_s *vbf, void *buffer, vbf_size_t size, vbf_size_t *out_size);
	int (*raw_ioctl)(struct vbf_s *vbf, int command, void *buffer, vbf_size_t size, vbf_size_t *out_size);
	int (*raw_seek_rel)(struct vbf_s *vbf, vbf_size_t new_pos);
	int (*raw_close)(struct vbf_s *vbf);
} vbf_t;
  int vbf_create(vbf_t *vbf);
int vbf_destroy(vbf_t *vbf);
  int vbf_seek_beg(vbf_t *vbf, vbf_size_t pos);
int vbf_seek_cur(vbf_t *vbf, vbf_size_t pos);
int vbf_seek_end(vbf_t *vbf, vbf_size_t pos);
int vbf_tell(vbf_t *vbf, vbf_size_t *pos);
int vbf_size(vbf_t *vbf, vbf_size_t *size);
int vbf_mode(vbf_t *vbf, int *mode);
int vbf_read(vbf_t *vbf, void *buffer, vbf_size_t size, vbf_size_t *out_size);
int vbf_write(vbf_t *vbf, void *buffer, vbf_size_t size, vbf_size_t *out_size);
int vbf_ioctl(vbf_t *vbf, int command, void *buffer, vbf_size_t size, vbf_size_t *out_size);
int vbf_close(vbf_t *vbf);
  #endif
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/inc/mpl/biquad.h] - (867 bytes)
 
 #ifndef biquad_h_n43287238497789234
#define biquad_h_n43287238497789234
  #include <sys_cfg.h>
  /*
usage:
  y[n] = a0 * x[n] + a1 * x[n-1] + a2 * x[n-2] +
                   b1 * y[n-1] + b2 * y[n-2]
*/
  typedef struct {
	double a0, a1, a2,
		       b1, b2;
} mpl__biquad_coeff_t;
  void mpl__fil_lp(mpl__biquad_coeff_t *fil, float omega, float bandwidth);
void mpl__fil_bp(mpl__biquad_coeff_t *fil, float omega, float bandwidth);
void mpl__fil_hp(mpl__biquad_coeff_t *fil, float omega, float bandwidth);
void mpl__fil_no(mpl__biquad_coeff_t *fil, float omega, float bandwidth);
void mpl__fil_peq(mpl__biquad_coeff_t *fil, float omega, float bandwidth, float dbgain);
void mpl__fil_ls(mpl__biquad_coeff_t *fil, float omega, float dbgain, float slope);
void mpl__fil_hs(mpl__biquad_coeff_t *fil, float omega, float dbgain, float slope);
  #endif
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/inc/mpl/sd_std.h] - (445 bytes)
 
 #ifndef sd_std_h_n34782823478789234
#define sd_std_h_n34782823478789234
  #include <mpl/mx.h>
  typedef struct mpl__sd_std_s {
	int  (*mx_create)(mpl__mixer_t **mixer);
	void (*mx_destroy)(mpl__mixer_t *mixer);
  	mpl__mixer_t *mx[4];
} mpl__sd_std_t;
  int mpl__sd_std_create(mpl__snd_dev_t **sd, int  (*mx_create)(mpl__mixer_t **mixer), void (*mx_destroy)(mpl__mixer_t *mixer));
void mpl__sd_std_destroy(mpl__snd_dev_t *sd);
  #endif   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/inc/mpl/error.h] - (469 bytes)
 
 #ifndef error_h_n473784923
#define error_h_n473784923
  // to be done
#define MPL__ERR_OK                                0
#define MPL__ERR_GENERIC                          -1
#define MPL__ERR_BAD_PARAM                        -2
  #define MPL__ERR_NOMEM                            -3
  #define MPL__ERR_MSG_BOX_FULL                     -4
#define MPL__ERR_MSG_BOX_EMPTY                    -5
  #define MPL__ERR_EOS                              -6
  #endif
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/inc/mpl/ml.h] - (1,176 bytes)
 
 #ifndef ml_h_n31783892389
#define ml_h_n31783892389
  #include <mpl/sys/msg_box.h>
#include <vbf/vbf.h>
#include <mpl/mp.h>
#include <mpl/error.h>
  typedef void mpl__md_t;
  typedef struct mpl__ml_s {
	int (*load)(void *internal, vbf_t *file, mpl__md_t **md);
	int (*destroy)(void *internal, mpl__md_t *md);
  	int (*create_mp)(void *internal, mpl__md_t *md, mpl__msg_box_t *mb, mpl__mp_t **mp);
	int (*destroy_mp)(void *internal, mpl__mp_t **mp);
  	int (*set_option)(void *internal, char *option, char *value);
	int (*get_option)(void *internal, char *option, char **value);
	int (*get_proc)(void *internal, char *name, void_func_t *proc);
  	void *internal_data;
} mpl__ml_t;
  int mpl__ml_load(mpl__ml_t *ml, vbf_t *file, mpl__md_t **md);
int mpl__ml_destroy(mpl__ml_t *ml, mpl__md_t *md);
int mpl__ml_create_mp(mpl__ml_t *ml, mpl__md_t *md, mpl__msg_box_t *mb, mpl__mp_t **mp);
int mpl__ml_destroy_mp(mpl__ml_t *ml, mpl__mp_t **mp);
int mpl__ml_set_option(mpl__ml_t *ml, char *option, char *value);
int mpl__ml_get_option(mpl__ml_t *ml, char *option, char **value);
int mpl__ml_get_proc(mpl__ml_t *ml, char *name, void_func_t *proc);
  
#endif
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/inc/mpl/mp.h] - (1,564 bytes)
 
 #ifndef mp_h_n432789237
#define mp_h_n432789237
  #include <mpl/snddev.h>
  #define MPL__MP_LOOP_NONE      0
#define MPL__MP_LOOP_FOREVER   -1
  #define MPL__MP_MSG_RESTART    0
#define MPL__MP_MSG_END        1
  typedef struct mpl__mp_s {
	int (*set_dev)(void *internal_data, mpl__snd_dev_t *dev);
  	int (*reset)(void *internal_data);
  	int (*play)(void *internal_data);
	int (*stop)(void *internal_data);
	int (*set_loop)(void *internal_data, int loop);
  	// typically: 0xXXXYYY (XXX = pattern, YYY = row)
	int (*set_pos)(void *internal_data, int pos);
	int (*get_pos)(void *internal_data);
  	int (*set_vol)(void *internal_data, float32 vol);
	int (*get_vol)(void *internal_data, float32 *vol);
  	int (*set_option)(void *internal, char *option, char *value);
	int (*get_option)(void *internal, char *option, char **value);
	int (*get_proc)(void *internal, char *name, void_func_t *proc);
  	void *internal_data;
} mpl__mp_t;
  int mpl__mp_set_dev(mpl__mp_t *mp, mpl__snd_dev_t *dev);
int mpl__mp_reset(mpl__mp_t *mp);
int mpl__mp_play(mpl__mp_t *mp);
int mpl__mp_stop(mpl__mp_t *mp);
int mpl__mp_set_loop(mpl__mp_t *mp, int loop);
int mpl__mp_set_pos(mpl__mp_t *mp, int pos);
int mpl__mp_get_pos(mpl__mp_t *mp);
int mpl__mp_set_vol(mpl__mp_t *mp, float32 vol);
int mpl__mp_get_vol(mpl__mp_t *mp, float32 *vol);
int mpl__mp_set_option(mpl__mp_t *mp, char *option, char *value);
int mpl__mp_get_option(mpl__mp_t *mp, char *option, char **value);
int mpl__mp_get_proc(mpl__mp_t *mp, char *name, void_func_t *proc);
  #endif
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/inc/mpl/mx.h] - (1,585 bytes)
 
 #ifndef mx_h_n7238478432789423
#define mx_h_n7238478432789423
  #include <mpl/snddev.h>
  #define MPL__MX_MEM_AGGRESSIVE   0
#define MPL__MX_MEM_LOW          1
  #define MPL__MX_HQ               0  // high quality
#define MPL__MX_LQ               1  // low quality
typedef struct mpl__mixer_opt_s {
	int ch_num, smp_num, mem_usage, qual;
} mpl__mixer_opt_t;
  typedef struct mpl__mixer_s {
	int (*set_output_options)(void *internal, mpl__snd_dev_output_t *opt, int latency);
	int (*set_options)(void *internal, mpl__mixer_opt_t *opt);
	int (*get_options)(void *internal, mpl__mixer_opt_t *opt);
	int (*get_proc)(void *internal, char *name, void_func_t *func);
	int (*get_interface)(void *internal, mpl__snd_mixer_t **mixer);
  	int (*set_vol)(void *internal, float32 vol, float32 pan_lr, float32 pan_fb);
  	int (*mix)(void *internal, void *buffer, int length);
  	int (*get_num_active_channels)(void *internal);
  	void *internal_data;
} mpl__mixer_t;
  int mpl__mixer_set_output_options(mpl__mixer_t *mx, mpl__snd_dev_output_t *opt, int latency);
int mpl__mixer_set_options(mpl__mixer_t *mx, mpl__mixer_opt_t *opt);
int mpl__mixer_get_options(mpl__mixer_t *mx, mpl__mixer_opt_t *opt);
int mpl__mixer_get_proc(mpl__mixer_t *mx, char *name, void_func_t *func);
int mpl__mixer_get_interface(mpl__mixer_t *mx, mpl__snd_mixer_t **mixer);
int mpl__mixer_set_vol(mpl__mixer_t *mx, float32 vol, float32 pan_lr, float32 pan_fb);
int mpl__mixer_mix(mpl__mixer_t *mx, void *buffer, int length);
int mpl__mixer_get_num_active_channels(mpl__mixer_t *mx);
  #endif
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/inc/mpl/snddev.h] - (9,913 bytes)
 
 #ifndef snddev_h_n478237842378
#define snddev_h_n478237842378
  // notes:
//
// data is always signed (any need for unsigned data?!?)
  #include <sys_cfg.h>
#include <mpl/error.h>
  #define MPL__SND_DEV_FMT_NONLOOPING    0
#define MPL__SND_DEV_FMT_LOOPING       1
#define MPL__SND_DEV_FMT_BIDILOOPING   2
  #define MPL__SND_DEV_FMT_8BIT          1
#define MPL__SND_DEV_FMT_16BIT         2
#define MPL__SND_DEV_FMT_24BIT         3
#define MPL__SND_DEV_FMT_32BIT         4
#define MPL__SND_DEV_FMT_FLOAT_32BIT   5
  #define MPL__SND_DEV_LATENCY_HIGH      0
#define MPL__SND_DEV_LATENCY_LOW       1
  #define MPL__SND_DEV_DIR_FORWARDS      0
#define MPL__SND_DEV_DIR_BACKWARDS     1
  typedef struct mpl__snd_dev_output_s {
	int format;
	int channels;
	float32 freq;
	int latency;
} mpl__snd_dev_output_t;
  typedef void(*mpl__snd_call_back_func_t)(void *data, int param);
  typedef struct mpl__snd_mixer_call_back_s {
	mpl__snd_call_back_func_t	func;
	void						*data;
	int							param;
	float64						period;
} mpl__snd_call_back_t;
  typedef struct mpl__snd_dev_smp_s {
	int			format;
	int			channels;
	int			loopmode;
	int			loop;
	int			length;
	float32		vol;
	float32		pan_lr;
	float32		pan_fb;
	float32		freq;
	void		*data;
} mpl__snd_mixer_smp_t;
  typedef struct mpl__snd_mixer_s {
	int (*reset)(void *internal);  // stops playing, toasts samples
	int (*pause)(void *internal);  // 1 -> paused | 0 -> unpaused ; doesn't run callback
	int (*stop)(void *internal);
  	int (*upload_sample)(void *internal, mpl__snd_mixer_smp_t sample);
	int (*destroy_sample)(void *internal, int handle);
  	int (*set_vol)(void *internal, float32 vol, float32 pan_lr, float32 pan_fb);
	int (*get_vol)(void *internal, float32 *vol, float32 *pan_lr, float32 *pan_fb);
  	int (*get_output_options)(void *internal, mpl__snd_dev_output_t *opt);
	int (*get_latency)(void *internal);   // ms
	int (*get_num_channels)(void *internal);
	int (*get_num_active_channels)(void *internal);
	int (*get_free_channel)(void *internal);
	int (*is_channel_active)(void *internal, int ch);
  	int (*set_channel_vol)(void *internal, int ch, float32 vol, float32 pan_lr, float32 pan_fb);
	int (*set_channel_freq)(void *internal, int ch, float32 freq);
	int (*set_channel_pos)(void *internal, int ch, float64 pos, int dir);
	int (*play_channel)(void *internal, int ch, int handle, float32 freq, float32 vol, float32 pan_lr, float32 pan_fb, float64 pos, int dir);
	int (*stop_channel)(void *internal, int ch);
  	/*
		getoption(...)
  		"ID"
		"VERSION"
		"AUTHOR"
		"EXTENSIONS" -> e.g. "EXT_MMX EXT_EQ EXT_REVERB"....
	*/
	int (*set_option)(void *internal, char *option, char *value);
	int (*get_option)(void *internal, char *option, char **value);
	int (*get_proc)(void *internal, char *name, void_func_t *proc);
  	int (*set_call_back)(void *internal, mpl__snd_call_back_t call_back);
  	void *internal_data;
} mpl__snd_mixer_t;
  typedef struct mpl__snd_mixer_opt_s {
	int			ch_num;   // min number of channels
	int			smp_num;  // min number of samples
	int			latency;
} mpl__snd_mixer_opt_t;
  typedef struct mpl__snd_stream_format_s {
	int			format;
	int			channels;
	float32		freq;
} mpl__snd_stream_format_t;
  typedef struct mpl__snd_stream_opt_s {
	mpl__snd_stream_format_t	format;
	int							latency;
} mpl__snd_stream_opt_t;
  typedef struct mpl__snd_stream_s {
	int (*set_vol)(void *internal, float32 vol, float32 pan_lr, float32 pan_fb);
	int (*get_vol)(void *internal, float32 *vol, float32 *pan_lr, float32 *pan_fb);
  	int (*get_output_options)(void *internal, mpl__snd_dev_output_t *opt);
	int (*set_input_format)(void *internal, mpl__snd_stream_format_t *opt);
	int (*get_input_format)(void *internal, mpl__snd_stream_format_t *opt);
	int (*get_latency)(void *internal);   // ms
	int (*get_buffer_size)(void *internal); // ms
	int (*write)(void *internal, void *data, int length);
  	int (*set_option)(void *internal, char *option, char *value);
	int (*get_option)(void *internal, char *option, char **value);
	int (*get_proc)(void *internal, char *name, void_func_t *proc);
  	int (*set_call_back)(void *internal, mpl__snd_call_back_t call_back);
  	void *internal_data;
} mpl__snd_stream_t;
  typedef struct mpl__snd_dev_s {
	int (*set_vol)(void *internal, float32 vol, float32 pan_lr, float32 pan_fb);
	int (*get_vol)(void *internal, float32 *vol, float32 *pan_lr, float32 *pan_fb);
  	int (*set_output_options)(void *internal, mpl__snd_dev_output_t opt);
	int (*get_output_options)(void *internal, mpl__snd_dev_output_t *opt);
  	int (*set_latency)(void *internal, int latency);
	int (*get_latency)(void *internal);   // ms
	int (*set_option)(void *internal, char *option, char *value);
	int (*get_option)(void *internal, char *option, char **value);
	int (*get_proc)(void *internal, char *name, void_func_t *proc);
  	int (*create_mixer)(void *internal, mpl__snd_mixer_t **mixer, mpl__snd_mixer_opt_t opt);
	int (*destroy_mixer)(void *internal, mpl__snd_mixer_t *mixer);
  	int (*create_stream)(void *internal, mpl__snd_stream_t **stream, mpl__snd_stream_opt_t opt);
	int (*destroy_stream)(void *internal, mpl__snd_stream_t *stream);
  	void *internal_data;
} mpl__snd_dev_t;
  // dev
int mpl__snd_dev_set_vol(mpl__snd_dev_t *dev, float32 vol, float32 pan_lr, float32 pan_fb);
int mpl__snd_dev_get_vol(mpl__snd_dev_t *dev, float32 *vol, float32 *pan_lr, float32 *pan_fb);
int mpl__snd_dev_set_output_options(mpl__snd_dev_t *dev, mpl__snd_dev_output_t opt);
int mpl__snd_dev_get_output_options(mpl__snd_dev_t *dev, mpl__snd_dev_output_t *opt);
int mpl__snd_dev_set_latency(mpl__snd_dev_t *dev, int latency);
int mpl__snd_dev_get_latency(mpl__snd_dev_t *dev);
int mpl__snd_dev_set_option(mpl__snd_dev_t *dev, char *option, char *value);
int mpl__snd_dev_get_option(mpl__snd_dev_t *dev, char *option, char **value);
int mpl__snd_dev_get_proc(mpl__snd_dev_t *dev, char *name, void_func_t *proc);
int mpl__snd_dev_create_mixer(mpl__snd_dev_t *dev, mpl__snd_mixer_t **mixer, mpl__snd_mixer_opt_t opt);
int mpl__snd_dev_destroy_mixer(mpl__snd_dev_t *dev, mpl__snd_mixer_t *mixer);
int mpl__snd_dev_create_stream(mpl__snd_dev_t *dev, mpl__snd_stream_t **stream, mpl__snd_stream_opt_t opt);
int mpl__snd_dev_destroy_stream(mpl__snd_dev_t *dev, mpl__snd_stream_t *stream);
  // mixer
int mpl__snd_mixer_reset(mpl__snd_mixer_t *mixer);  // stops playing, toasts samples
int mpl__snd_mixer_pause(mpl__snd_mixer_t *mixer);  // 1 -> paused | 0 -> unpaused ; doesn't run callback
int mpl__snd_mixer_stop(mpl__snd_mixer_t *mixer);
int mpl__snd_mixer_upload_sample(mpl__snd_mixer_t *mixer, mpl__snd_mixer_smp_t sample);
int mpl__snd_mixer_destroy_sample(mpl__snd_mixer_t *mixer, int handle);
int mpl__snd_mixer_set_vol(mpl__snd_mixer_t *mixer, float32 vol, float32 pan_lr, float32 pan_fb);
int mpl__snd_mixer_get_vol(mpl__snd_mixer_t *mixer, float32 *vol, float32 *pan_lr, float32 *pan_fb);
int mpl__snd_mixer_get_output_options(mpl__snd_mixer_t *mixer, mpl__snd_dev_output_t *opt);
int mpl__snd_mixer_get_latency(mpl__snd_mixer_t *mixer);   // ms
int mpl__snd_mixer_get_num_channels(mpl__snd_mixer_t *mixer);
int mpl__snd_mixer_get_num_active_channels(mpl__snd_mixer_t *mixer);
int mpl__snd_mixer_get_free_channel(mpl__snd_mixer_t *mixer);
int mpl__snd_mixer_is_channel_active(mpl__snd_mixer_t *mixer, int ch);
int mpl__snd_mixer_set_channel_vol(mpl__snd_mixer_t *mixer, int ch, float32 vol, float32 pan_lr, float32 pan_fb);
int mpl__snd_mixer_set_channel_freq(mpl__snd_mixer_t *mixer, int ch, float32 freq);
int mpl__snd_mixer_set_channel_pos(mpl__snd_mixer_t *mixer, int ch, float64 pos, int dir);
int mpl__snd_mixer_play_channel(mpl__snd_mixer_t *mixer, int ch, int handle, float32 freq, float32 vol, float32 pan_lr, float32 pan_fb, float64 pos, int dir);
int mpl__snd_mixer_stop_channel(mpl__snd_mixer_t *mixer, int ch);
int mpl__snd_mixer_set_option(mpl__snd_mixer_t *mixer, char *option, char *value);
int mpl__snd_mixer_get_option(mpl__snd_mixer_t *mixer, char *option, char **value);
int mpl__snd_mixer_get_proc(mpl__snd_mixer_t *mixer, char *name, void_func_t *proc);
int mpl__snd_mixer_set_call_back(mpl__snd_mixer_t *mixer, mpl__snd_call_back_t call_back);
  // stream
int mpl__snd_stream_set_vol(mpl__snd_stream_t *stream, float32 vol, float32 pan_lr, float32 pan_fb);
int mpl__snd_stream_get_vol(mpl__snd_stream_t *stream, float32 *vol, float32 *pan_lr, float32 *pan_fb);
int mpl__snd_stream_get_output_options(mpl__snd_stream_t *stream, mpl__snd_dev_output_t *opt);
int mpl__snd_stream_set_input_format(mpl__snd_stream_t *stream, mpl__snd_stream_format_t *opt);
int mpl__snd_stream_get_input_format(mpl__snd_stream_t *stream, mpl__snd_stream_format_t *opt);
int mpl__snd_stream_get_latency(mpl__snd_stream_t *stream);   // ms
int mpl__snd_stream_get_buffer_size(mpl__snd_stream_t *stream); // ms
int mpl__snd_stream_set_option(mpl__snd_stream_t *stream, char *option, char *value);
int mpl__snd_stream_get_option(mpl__snd_stream_t *stream, char *option, char **value);
int mpl__snd_stream_get_proc(mpl__snd_stream_t *stream, char *name, void_func_t *proc);
int mpl__snd_stream_write(mpl__snd_stream_t *stream, void *data, int length);
int mpl__snd_stream_set_call_back(mpl__snd_stream_t *stream, mpl__snd_call_back_t call_back);
  
//////////////////////////////////////////////////////////////
// extensions
#define MPL__EXT_SND_MIXER_SUSTAIN_LOOP      "EXT_SUSTAIN_LOOP"
#define MPL__FUNC_SND_MIXER_SET_SUSTAIN_LOOP "mpl__snd_mixer_set_sustain_loop"
#define MPL__FUNC_SND_MIXER_END_SUSTAIN      "mpl__snd_mixer_end_sustain"
  typedef int (*mpl__snd_mixer_set_sustain_loop_t)(mpl__snd_mixer_t *sndmx, int handle, int begin, int end, int mode);
typedef int (*mpl__snd_mixer_end_sustain_t)(mpl__snd_mixer_t *sndmx, int ch);
  
#endif
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/inc/mpl/string.h] - (283 bytes)
 
 #ifndef string_h_n42378789234
#define string_h_n42378789234
  #include <sys_cfg.h>
  #define MPL__STRING_EQUAL     1
#define MPL__STRING_UNEQUAL   0
  int mpl__string_cmp_char(char *str1, char *str2);
int mpl__string_cmp_wide_char(wide_char *str1, wide_char *str2);
  #endif
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/inc/mpl/mp_xm.h] - (6,534 bytes)
 
 #ifndef mp_xm_h_n42378789234789342
#define mp_xm_h_n42378789234789342
  #include <vbf/vbf_util.h>
#include <mpl/sys/msg_box.h>
#include <mpl/mp.h>
  #define MPL__XM_FREQ_TABLE_LINEAR             1
  #define MPL__XM_SMP_LOOP_BITS                 0x03
  #define MPL__XM_SMP_NO_LOOP                   0
#define MPL__XM_SMP_LOOP                      1
#define MPL__XM_SMP_BIDI_LOOP                 2
  #define MPL__XM_SMP_16BIT                     16
  // vol/pan envelope
#define MPL__XM_ENV_ON                        1
#define MPL__XM_ENV_SUSTAIN                   2
#define MPL__XM_ENV_LOOP                      4
  #define MPL__XM_NO_NOTE                       98
#define MPL__XM_KEY_OFF                       97
  #define MPL__XM_EFF_ARPEGGIO                  0x00
#define MPL__XM_EFF_PORTA_UP                  0x01
#define MPL__XM_EFF_PORTA_DOWN                0x02
#define MPL__XM_EFF_PORTA                     0x03
#define MPL__XM_EFF_VIB                       0x04
#define MPL__XM_EFF_PORTA_VOL_SLIDE           0x05
#define MPL__XM_EFF_VIB_VOL_SLIDE             0x06
#define MPL__XM_EFF_TREMOLO                   0x07
#define MPL__XM_EFF_PAN                       0x08
#define MPL__XM_EFF_SMP_OFFSET                0x09
#define MPL__XM_EFF_VOL_SLIDE                 0x0A
#define MPL__XM_EFF_POS_JUMP                  0x0B
#define MPL__XM_EFF_VOL                       0x0C
#define MPL__XM_EFF_PAT_BREAK                 0x0D
#define MPL__XM_EFF_MOD_EXT                   0x0E
#define MPL__XM_EFF_SPEED                     0x0F
#define MPL__XM_EFF_GLOB_VOL                  0x10
#define MPL__XM_EFF_GLOB_VOL_SLIDE            0x11
#define MPL__XM_EFF_KEY_OFF                   0x14
#define MPL__XM_EFF_ENV_POS                   0x15
#define MPL__XM_EFF_PAN_SLIDE                 0x19
#define MPL__XM_EFF_RETRIG_VOL_SLIDE          0x1B
#define MPL__XM_EFF_TREMOR                    0x1D
#define MPL__XM_EFF_EXTRA_FINE_PORTA          0x21
  // Exx effects
#define MPL__XM_EXT_EFF_FINE_PORTA_UP         0x10
#define MPL__XM_EXT_EFF_FINE_PORTA_DOWN       0x20
#define MPL__XM_EXT_EFF_GLISSANDO             0x30
#define MPL__XM_EXT_EFF_VIB_WAVE              0x40
#define MPL__XM_EXT_EFF_FINE_TUNE             0x50
#define MPL__XM_EXT_EFF_PAT_LOOP              0x60
#define MPL__XM_EXT_EFF_TREMOLO_WAVE          0x70
#define MPL__XM_EXT_EFF_PAN                   0x80
#define MPL__XM_EXT_EFF_RETRIG                0x90
#define MPL__XM_EXT_EFF_FINE_VOL_SLIDE_UP     0xA0
#define MPL__XM_EXT_EFF_FINE_VOL_SLIDE_DOWN   0xB0
#define MPL__XM_EXT_EFF_NOTE_CUT              0xC0
#define MPL__XM_EXT_EFF_NOTE_DELAY            0xD0
#define MPL__XM_EXT_EFF_PAT_DELAY             0xE0
  #define MPL__XM_VOL_EFF_VOL_SLIDE_DOWN        0x60
#define MPL__XM_VOL_EFF_VOL_SLIDE_UP          0x70
#define MPL__XM_VOL_EFF_FINE_VOL_SLIDE_DOWN   0x80
#define MPL__XM_VOL_EFF_FINE_VOL_SLIDE_UP     0x90
#define MPL__XM_VOL_EFF_VIB_SPEED             0xA0
#define MPL__XM_VOL_EFF_VIB                   0xB0
#define MPL__XM_VOL_EFF_PAN                   0xC0
#define MPL__XM_VOL_EFF_PAN_SLIDE_LEFT        0xD0
#define MPL__XM_VOL_EFF_PAN_SLIDE_RIGHT       0xE0
#define MPL__XM_VOL_EFF_PORTA                 0xF0
  #define MPL__XM_CTRL_VOL                      1
#define MPL__XM_CTRL_PER                      2
#define MPL__XM_CTRL_START                    4
#define MPL__XM_CTRL_STOP                     8
  #define MPL__XM_PL_CTRL_BPM                   1
#define MPL__XM_PL_CTRL_VOL                   2
  typedef struct {
	int				index;
  	char			name[23];
	
	int				loop_begin;
	int				loop_end;
  	int				vol;
	int				pan;
  	int				rel_note;
	int				finetune;
  	int				length;
	int				format;
	void*			data;
} mpl__xm_sample_t;
  typedef struct {
	int x, y;
} mpl__xm_point_t;
  typedef struct {
	char			name[23];
  	int				note2smp[96];
  	mpl__xm_point_t vol_env[12];
	int				vol_num;
	int				vol_sus;
	int				vol_loop_beg;
	int				vol_loop_end;
	int				vol_type;
  	int             vol_fade_out;
  	mpl__xm_point_t	pan_env[12];
	int				pan_num;
	int				pan_sus;
	int				pan_loop_beg;
	int				pan_loop_end;
	int				pan_type;
  	int				vib_type;
	int				vib_sweep;
	int				vib_depth;
	int				vib_rate;
  	int				smp_num;
	mpl__xm_sample_t *smp;
} mpl__xm_inst_t;
  typedef struct {
	u8				key;
	u8				inst;
	u8				volume;
	u8				effect;
	u8				param;
} mpl__xm_cell_t;
  typedef struct {
	char			title[21];
	char			tracker[21];
  	int				restart_pos;
	int				length;
	int				order[256];
  	int				inst_num;
	mpl__xm_inst_t*		inst;
	int				smp_index_num;
  	int				pat_num;
	mpl__xm_cell_t*		pat[256];
	int				pat_length[256];
  	int				ch_num;
	int				bpm, speed;
	int				freq_table;
} mpl__xm_t;
  typedef struct {
	int				active;
	int				ctrl;
	int				key;
	int				real_key;
	int				key_off;
	int				eff;
  	int				inst;
	mpl__xm_inst_t	*p_inst;
	mpl__xm_sample_t *p_smp;
//	double			sample_pos;
	int				smp_offset;
  	int				vol;
	int				vol_delta;
	int				env_vol;
	int				env_vol_tick;
	int				fade_out_vol;
  	int				pan;
	int				pan_delta;
	int				env_pan;
	int				env_pan_tick;
  	int				per;
	int				per_delta;
	int				dst_per;
  	int				porta_period;
	int				porta_speed;
  	int				vib_speed;
	int				vib_depth;
	int				vib_pos;
  	int				inst_vib_sweep_pos;
	int				inst_vib_pos;
  	int				tremolo_speed;
	int				tremolo_depth;
	int				tremolo_pos;
  	int				vol_slide;
	int				fvol_slide_up;
	int				fvol_slide_down;
	int				vib_vol_slide;
	int				porta_vol_slide;
	int				retrig_vol_slide;
	int				pan_slide;
  	int				loop_row;
	int				loop_num;
  	int				porta_up;
	int				porta_down;
	int				fporta_up;
	int				fporta_down;
	int				efporta_up;
	int				efporta_down;
  	int				tremor_pos;
	int				tremor_spd;
  	int				wave_control;
} mpl__mp_xm_chan_t;
  typedef struct {
	mpl__xm_t		*xm;
  	int				pat_cur;
	int				pat_next;
	int				row_cur;
	int				row_next;
  	int				bpm;
	int				speed;
	int				tick_cur;
	int				delay;
	int				ctrl;
	int				paused;
  	mpl__mp_xm_chan_t ch[64];
  	int				smp_handle[300];
	int             smp_fine_tune[300];
  	float32			vol;
	int				glob_vol, glob_vol_slide;
  	int				loop;
  	mpl__snd_dev_t	*dev;
	mpl__snd_mixer_t *mixer;
	mpl__msg_box_t	*mb;
} mpl__mp_xm_t;
  int mpl__mp_xm_construct(mpl__xm_t *xm, mpl__mp_t *mp, mpl__msg_box_t *mb);
int mpl__mp_xm_destruct(mpl__mp_t *mp);
  #endif
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/inc/mpl/ml_xm.h] - (193 bytes)
 
 #ifndef ml_xm_h_n4378789243234890
#define ml_xm_h_n4378789243234890
  #include <mpl/mp_xm.h>
  int mpl__xm_load(vbf_t *file, mpl__xm_t *xm);
int mpl__xm_destruct(mpl__xm_t *xm);
  #endif
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/inc/mpl/dsp_std.h] - (484 bytes)
 
 #ifndef dsp_std_h_n43782784923
#define dsp_std_h_n43782784923
  #include <mpl/snddev.h>
  int mpl__dsp_add(void *src, void *dst, int size, int ch_num, float32 vol, int format);
int mpl__dsp_sub(void *src, void *dst, int size, int ch_num, float32 vol, int format);
int mpl__dsp_move(void *src, void *dst, int size, int ch_num, float32 vol, int format);
int mpl__dsp_conv_format(void *src, void *dst, int src_format, int dst_format, int size, int ch_num, float32 vol);
  #endif
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/inc/mpl/mx_std.h] - (1,461 bytes)
 
 #ifndef mx_std_h_n37842789342789
#define mx_std_h_37842789342789
  // standard mixer
#include <mpl/mx.h>
  typedef struct {
	int					exists;
	mpl__snd_mixer_smp_t smp;
	int					sus_loop_beg;
	int					sus_loop_end;
	int					sus_loop_mode;
//	int					locked;
} mpl__mx_std_smp_t;
  typedef struct {
	int					playing;
	int					smp;
	float32				patch[8];
	float32				vol_left, vol_right, vol_center;
	float32				vol_left_ramp, vol_right_ramp, vol_center_ramp;
	int					vol_left_ramp_num, vol_right_ramp_num, vol_center_ramp_num;
	float32				vol_left_dst, vol_right_dst, vol_center_dst;
	float32				vol, pan_lr;
	float32				freq;
	float64				pos;
	int					dir;
	int					loop_beg;
	int					loop_end;
	int					loop_mode;
} mpl__mx_std_ch_t;
  typedef struct {
	mpl__mx_std_smp_t	*smp;
	int					smp_num;
	mpl__mx_std_ch_t	*ch;
	int					ch_num;
  	int					latency;
	int					paused;
	int					mem_usage;
	int					qual;
	mpl__snd_dev_output_t output;
	float32				vol_local;
	float32				pan_lr_local;
	float32				pan_fb_local;
	float32				vol_global;
	float32				pan_lr_global;
	float32				pan_fb_global;
  	float32				ramp;
	float32				dc_spd[2], dc_pos[2];
//	float32				quant[2];
  	mpl__snd_mixer_t	iface;
	mpl__snd_call_back_t call_back;
	float64				count_down_frac;
	int					count_down;
} mpl__mx_std_t;
  int  mpl__mx_std_create(mpl__mixer_t **mixer);
void mpl__mx_std_destroy(mpl__mixer_t *mixer);
  #endif
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/inc/mpl/sys/critsect.h] - (502 bytes)
 
 #ifndef critsect_h_n423784238
#define critsect_h_n423784238
  #include <windows.h>
#include <sys_cfg.h>
#include <mpl/error.h>
  typedef CRITICAL_SECTION mpl__critical_section_t;
  int mpl__cs_create(mpl__critical_section_t **cs);
int mpl__cs_destroy(mpl__critical_section_t *cs);
int mpl__cs_construct(mpl__critical_section_t *cs);
int mpl__cs_destruct(mpl__critical_section_t *cs);
int mpl__cs_enter(mpl__critical_section_t *cs);
int mpl__cs_leave(mpl__critical_section_t *cs);
  #endif
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/inc/mpl/sys/mem.h] - (510 bytes)
 
 #ifndef mem_h_n78923478924
#define mem_h_n78923478924
  #include <sys_cfg.h>
#include <mpl/error.h>
  typedef int mpl__mem_size_t;
  int mpl__mem_init();
int mpl__mem_alloc(mpl__mem_size_t size, void **mem);
int mpl__mem_get_size(mpl__mem_size_t *size, void *mem);
int mpl__mem_resize(mpl__mem_size_t newsize, int onlyexpand, void **mem);
int mpl__mem_free(void *mem);
int mpl__mem_copy(void *src, void *dst, mpl__mem_size_t size);
int mpl__mem_set_zero(void *mem, mpl__mem_size_t size);
  #endif
   |  
  
 | 
 
  
Currently browsing [playxm.zip] (61,482 bytes) - [playxm/inc/mpl/sys/msg_box.h] - (760 bytes)
 
 #ifndef msg_box_h_n43789423798
#define msg_box_h_n43789423798
  #include <sys_cfg.h>
#include <mpl/sys/critsect.h>
#include <mpl/error.h>
  typedef struct mpl__msg_s {
	int					msg;
	int					param[8];
	void				*data;
} mpl__msg_t;
  typedef struct mpl__msg_box_s {
	mpl__msg_t				*msg;
	int						max;
	int						cnt;
	int						first;
	int						last;
	mpl__critical_section_t	cs;
} mpl__msg_box_t;
  int mpl__msg_box_create(mpl__msg_box_t **mb, int max);
int mpl__msg_box_destroy(mpl__msg_box_t *mb);
int mpl__msg_box_construct(mpl__msg_box_t *mb, int max);
int mpl__msg_box_destruct(mpl__msg_box_t *mb);
int mpl__msg_box_send(mpl__msg_box_t *mb, mpl__msg_t *msg);
int mpl__msg_box_receive(mpl__msg_box_t *mb, mpl__msg_t *msg);
  #endif
   |  
  
 | 
 
 
 
The zip file viewer built into the Developer Toolbox made use
of the zlib library, as well as the zlibdll source additions.
 
 
 |