#define DUMB_MAJOR_VERSION    0
#define DUMB_MINOR_VERSION    9
#define DUMB_REVISION_VERSION 2

#define DUMB_VERSION DUMB_MAJOR_VERSION*100+DUMB_MINOR_VERSION*100+DUMB_REVISION_VERSION

#define DUMB_VERSION_STR "0.9.2"

#define DUMB_YEAR  2003
#define DUMB_MONTH 4
#define DUMB_DAY   2

#define DUMB_YEAR_STR2  "03"
#define DUMB_YEAR_STR4  "2003"
#define DUMB_MONTH_STR1 "4"
#define DUMB_DAY_STR1   "2"

#define DUMB_DATE DUMB_YEAR*100 + DUMB_MONTH*100 + DUMB_DAY

#undef MIN
#undef MAX
#undef MID

:dword MIN(EAX,EBX)
{
	IF(long EAX>EBX)EAX><EBX;
}

:dword MAX(EAX,EBX)
{
	IF(long EAX<EBX)EAX><EBX;
}

:dword pascal MID(dword a,b,c)
{
	@MAX(@MIN(b,c),a);
}

#undef ABS
:dword ABS(EAX)
{
	IF(long EAX<0)-EAX;
}

dword pascal DUMB_ID(dword a,b,c,d)
{
	$push EBX
	EBX=b<<16;
	EAX=a<<24|EBX;
	EBX=c<<8;
	EAX=EAX|EBX|d;
	$pop EBX
}

/* Basic Sample Type. Normal range is -0x800000 to 0x7FFFFF. */

#define sample_t int

/* File Input Functions */

#define DUH_SIGNATURE '!HUD'

#define DUMB_IT_N_CHANNELS 64
#define DUMB_IT_N_NNA_CHANNELS 192
#define DUMB_IT_TOTAL_CHANNELS DUMB_IT_N_CHANNELS + DUMB_IT_N_NNA_CHANNELS

struct DUMB_IT_CHANNEL_STATE
{
	int channel; /* 0-based; meaningful for NNA channels */
	int sample; /* 1-based; 0 if nothing playing, then other fields undef */
	int freq; /* in Hz */
	float volume; /* 1.0 maximum; affected by ALL factors, inc. mixing vol */
	unsigned char pan; /* 0-64, 100 for surround */
	signed char subpan; /* use (pan + subpan/256.0f) or ((pan<<8)+subpan) */
	unsigned char filter_cutoff;    /* 0-127    cutoff=127 AND resonance=0 */
	unsigned char filter_subcutoff; /* 0-255      -> no filters (subcutoff */
	unsigned char filter_resonance; /* 0-127        always 0 in this case) */
	/* subcutoff only changes from zero if filter envelopes are in use. The
	 * calculation (filter_cutoff + filter_subcutoff/256.0f) gives a more
	 * accurate filter cutoff measurement as a float. It would often be more
	 * useful to use a scaled int such as ((cutoff<<8) + subcutoff).
	 */
};

/* Use pow(DUMB_SEMITONE_BASE, n) to get the 'delta' value to transpose up by
 * n semitones. To transpose down, use negative n.
 */
#define DUMB_SEMITONE_BASE float 1.059463094359295309843105314939748495817

/* Use pow(DUMB_QUARTERTONE_BASE, n) to get the 'delta' value to transpose up
 * by n quartertones. To transpose down, use negative n.
 */
#define DUMB_QUARTERTONE_BASE float 1.029302236643492074463779317738953977823

/* Use pow(DUMB_PITCH_BASE, n) to get the 'delta' value to transpose up by n
 * units. In this case, 256 units represent one semitone; 3072 units
 * represent one octave. These units are used by the sequence signal (SEQU).
 */
#define DUMB_PITCH_BASE float 1.000225659305069791926712241547647863626

/* Resampling Helpers */

#define DUMB_RQ_ALIASING 0
#define DUMB_RQ_LINEAR   1
#define DUMB_RQ_CUBIC    2
#define DUMB_RQ_N_LEVELS 3

struct DUMB_RESAMPLER
{
	dword src;//sample_t *src;
	long pos;
	int subpos;
	long start, end;
	int dir;
	dword pickup;
	dword  pickup_data;
	int min_quality;
	int max_quality;
	/* Everything below this point is internal: do not use. */
	sample_t x[3];
	int overshot;
};

extern WINAPI "dumb.dll"
{
_create_sample_buffer@8;
_destroy_sample_buffer@4;
_duh_encapsulate_it_sigrenderer@12;
_duh_encapsulate_raw_sigrenderer@16;
_duh_end_renderer@4;
_duh_get_it_sigdata@4;
_duh_get_it_sigrenderer@4;
_duh_get_length@4;
_duh_get_raw_sigdata@12;
_duh_get_raw_sigrenderer@8;
_duh_render@28;
_duh_render_signal@20;
_duh_renderer_decompose_to_sigrenderer@4;
_duh_renderer_encapsulate_sigrenderer@4;
_duh_renderer_get_n_channels@4;
_duh_renderer_get_position@4;
_duh_renderer_get_sigrenderer@4;
_duh_sigrenderer_get_current_sample@12;
_duh_sigrenderer_get_n_channels@4;
_duh_sigrenderer_get_position@4;
_duh_sigrenderer_get_samples@20;
_duh_sigrenderer_set_sigparam@12;
_duh_start_renderer@12;
_duh_start_sigrenderer@16;
_dumb_atexit@4;
_dumb_click_remover_get_offset@4;
_dumb_click_remover_get_offset_array@12;
_dumb_create_click_remover@0;
_dumb_create_click_remover_array@4;
_dumb_destroy_click_remover@4;
_dumb_destroy_click_remover_array@8;
_dumb_end_resampler@4;
_dumb_exit@0;
_dumb_it_callback_midi_block@12;
_dumb_it_sd_get_initial_channel_volume@8;
_dumb_it_sd_get_initial_global_volume@4;
_dumb_it_sd_get_initial_speed@4;
_dumb_it_sd_get_initial_tempo@4;
_dumb_it_sd_get_mixing_volume@4;
_dumb_it_sd_get_n_orders@4;
_dumb_it_sd_set_initial_channel_volume@12;
_dumb_it_sd_set_initial_global_volume@8;
_dumb_it_sd_set_initial_speed@8;
_dumb_it_sd_set_initial_tempo@8;
_dumb_it_sd_set_mixing_volume@8;
_dumb_it_set_loop_callback@12;
_dumb_it_set_midi_callback@12;
_dumb_it_set_xm_speed_zero_callback@12;
_dumb_it_sr_get_channel_state@12;
_dumb_it_sr_get_channel_volume@8;
_dumb_it_sr_get_current_order@4;
_dumb_it_sr_get_current_row@4;
_dumb_it_sr_get_global_volume@4;
_dumb_it_sr_get_speed@4;
_dumb_it_sr_get_tempo@4;
_dumb_it_sr_set_channel_volume@12;
_dumb_it_sr_set_global_volume@8;
_dumb_it_sr_set_speed@8;
_dumb_it_sr_set_tempo@8;
_dumb_it_start_at_order@12;
_dumb_load_it@4;
_dumb_load_mod@4;
_dumb_load_s3m@4;
_dumb_load_xm@4;
_dumb_read_it@4;
_dumb_read_mod@4;
_dumb_read_s3m@4;
_dumb_read_xm@4;
_dumb_record_click@12;
_dumb_record_click_array@16;
_dumb_record_click_negative_array@16;
_dumb_register_sigtype@4;
_dumb_register_stdfiles@0;
_dumb_remove_clicks@16;
_dumb_remove_clicks_array@20;
_dumb_resample@20;
_dumb_resample_get_current_sample@8;
_dumb_reset_resampler@20;
_dumb_silence@8;
_dumb_start_resampler@16;
_dumbfile_cgetsl@4;
_dumbfile_cgetul@4;
_dumbfile_close@4;
_dumbfile_error@4;
_dumbfile_getc@4;
_dumbfile_getnc@12;
_dumbfile_igetl@4;
_dumbfile_igetw@4;
_dumbfile_mgetl@4;
_dumbfile_mgetw@4;
_dumbfile_open@4;
_dumbfile_open_ex@8;
_dumbfile_open_memory@8;
_dumbfile_open_stdfile@4;
_dumbfile_pos@4;
_dumbfile_skip@8;
_load_duh@4;
_read_duh@4;
_register_dumbfile_system@4;
_unload_duh@4;
}
