This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

 

  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.

 

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.