Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

- Updated scripting branch to latest version in trunk.

git-svn-id: http://mancubus.net/svn/hosted/zdoom/zdoom/branches/scripting@4337 a95907f1-e10c-0410-b46f-9e587ccb1026
  • Loading branch information...
commit e3baca2464380364f281980255bcee967b4b1c53 2 parents e123916 + 7f81579
rheit authored
Showing with 15,968 additions and 3,535 deletions.
  1. +1 −0  CMakeLists.txt
  2. +5 −0 dumb/CMakeLists.txt
  3. +13 −1 dumb/include/dumb.h
  4. +77 −0 dumb/include/internal/blip_buf.h
  5. +28 −4 dumb/include/internal/it.h
  6. +19 −0 dumb/src/core/makeduh.c
  7. +20 −6 dumb/src/core/rawsig.c
  8. +354 −0 dumb/src/helpers/blip_buf.c
  9. +7 −2 dumb/src/helpers/resamp2.inc
  10. +47 −36 dumb/src/helpers/resamp3.inc
  11. +5 −5 dumb/src/helpers/resample.c
  12. +98 −18 dumb/src/helpers/resample.inc
  13. +1 −1  dumb/src/it/itmisc.c
  14. +246 −24 dumb/src/it/itread.c
  15. +597 −192 dumb/src/it/itrender.c
  16. +42 −0 dumb/src/it/loadokt.c
  17. +29 −0 dumb/src/it/loadokt2.c
  18. +2 −0  dumb/src/it/readam.c
  19. +4 −4 dumb/src/it/readasy.c
  20. +1 −0  dumb/src/it/readdsmf.c
  21. +66 −38 dumb/src/it/readmod.c
  22. +558 −0 dumb/src/it/readokt.c
  23. +29 −0 dumb/src/it/readokt2.c
  24. +1 −1  dumb/src/it/readoldpsm.c
  25. +2 −2 dumb/src/it/reads3m.c
  26. +96 −48 dumb/src/it/readstm.c
  27. +212 −16 dumb/src/it/readxm.c
  28. +2 −0  dumb/src/it/xmeffect.c
  29. +24 −0 dumb/vc6/dumb_static/dumb_static.vcproj
  30. +3 −0  specs/udmf_zdoom.txt
  31. +11 −3 specs/usdf.txt
  32. +44 −3 src/CMakeLists.txt
  33. +1 −1  src/actionspecials.h
  34. +7 −1 src/actor.h
  35. +40 −21 src/am_map.cpp
  36. +3 −2 src/b_bot.cpp
  37. +6 −6 src/b_game.cpp
  38. +8 −8 src/bbannouncer.cpp
  39. +1 −1  src/c_cmds.cpp
  40. +3 −3 src/c_console.cpp
  41. +80 −87 src/c_cvars.cpp
  42. +17 −10 src/c_cvars.h
  43. +18 −28 src/c_dispatch.cpp
  44. +0 −1  src/c_dispatch.h
  45. +3 −1 src/cmdlib.cpp
  46. +1 −1  src/cmdlib.h
  47. +62 −2 src/compatibility.cpp
  48. +107 −2 src/configfile.cpp
  49. +2 −0  src/configfile.h
  50. +2 −1  src/d_iwad.cpp
  51. +144 −12 src/d_main.cpp
  52. +55 −15 src/d_net.cpp
  53. +432 −260 src/d_netinfo.cpp
  54. +117 −42 src/d_player.h
  55. +4 −1 src/decallib.cpp
  56. +1 −0  src/dobjgc.cpp
  57. +2 −1  src/doomdef.h
  58. +3 −2 src/dthinker.cpp
  59. +2 −2 src/fragglescript/t_func.cpp
  60. +2 −2 src/g_doom/a_archvile.cpp
  61. +13 −7 src/g_doom/a_bossbrain.cpp
  62. +2 −2 src/g_doom/a_bruiser.cpp
  63. +2 −2 src/g_doom/a_cacodemon.cpp
  64. +2 −2 src/g_doom/a_demon.cpp
  65. +2 −2 src/g_doom/a_doomimp.cpp
  66. +11 −7 src/g_doom/a_doomweaps.cpp
  67. +0 −1  src/g_doom/a_lostsoul.cpp
  68. +0 −1  src/g_doom/a_painelemental.cpp
  69. +2 −2 src/g_doom/a_revenant.cpp
  70. +3 −2 src/g_doom/a_scriptedmarine.cpp
  71. +24 −19 src/g_game.cpp
  72. +2 −2 src/g_heretic/a_chicken.cpp
  73. +4 −4 src/g_heretic/a_dsparil.cpp
  74. +2 −2 src/g_heretic/a_hereticmisc.cpp
  75. +6 −6 src/g_heretic/a_hereticweaps.cpp
  76. +4 −4 src/g_heretic/a_ironlich.cpp
  77. +2 −2 src/g_heretic/a_knight.cpp
  78. +2 −2 src/g_heretic/a_wizard.cpp
  79. +2 −2 src/g_hexen/a_bishop.cpp
  80. +4 −4 src/g_hexen/a_dragon.cpp
  81. +1 −1  src/g_hexen/a_flechette.cpp
  82. +12 −10 src/g_hexen/a_hexenspecialdecs.cpp
  83. +1 −1  src/g_hexen/a_korax.cpp
  84. +2 −2 src/g_hexen/a_serpent.cpp
  85. +2 −2 src/g_hexen/a_spike.cpp
  86. +30 −15 src/g_level.cpp
  87. +5 −2 src/g_level.h
  88. +11 −2 src/g_mapinfo.cpp
  89. +10 −10 src/g_raven/a_minotaur.cpp
  90. +1 −3 src/g_shared/a_action.cpp
  91. +39 −8 src/g_shared/a_artifacts.cpp
  92. +8 −0 src/g_shared/a_artifacts.h
  93. +43 −22 src/g_shared/a_decals.cpp
  94. +62 −10 src/g_shared/a_morph.cpp
  95. +34 −2 src/g_shared/a_pickups.cpp
  96. +14 −1 src/g_shared/a_pickups.h
  97. +30 −10 src/g_shared/a_randomspawner.cpp
  98. +2 −1  src/g_shared/a_sharedglobal.h
  99. +6 −14 src/g_shared/a_skies.cpp
  100. +23 −9 src/g_shared/a_weapons.cpp
  101. +70 −10 src/g_shared/hudmessages.cpp
  102. +27 −2 src/g_shared/sbar.h
  103. +2 −2 src/g_shared/sbar_mugshot.cpp
  104. +36 −32 src/g_shared/sbarinfo.cpp
  105. +42 −17 src/g_shared/sbarinfo_commands.cpp
  106. +113 −13 src/g_shared/shared_hud.cpp
  107. +57 −8 src/g_shared/shared_sbar.cpp
  108. +1 −1  src/g_strife/a_entityboss.cpp
  109. +1 −1  src/g_strife/a_oracle.cpp
  110. +2 −2 src/g_strife/a_programmer.cpp
  111. +1 −1  src/g_strife/a_sentinel.cpp
  112. +2 −2 src/g_strife/a_stalker.cpp
  113. +2 −2 src/g_strife/a_strifeweapons.cpp
  114. +18 −14 src/g_strife/strife_sbar.cpp
  115. +59 −13 src/gameconfigfile.cpp
  116. +2 −0  src/gameconfigfile.h
  117. +1 −0  src/gi.cpp
  118. +1 −0  src/gi.h
  119. +13 −13 src/hu_scores.cpp
  120. +2 −2 src/i_net.cpp
  121. +3 −3 src/info.cpp
  122. +5 −0 src/info.h
  123. +52 −31 src/intermission/intermission.cpp
  124. +17 −9 src/intermission/intermission_parse.cpp
  125. +9 −0 src/m_bbox.h
  126. +5 −3 src/m_cheat.cpp
  127. +45 −4 src/m_png.cpp
  128. +2 −4 src/m_random.cpp
  129. +3 −2 src/menu/joystickmenu.cpp
  130. +3 −2 src/menu/listmenu.cpp
  131. +2 −2 src/menu/loadsavemenu.cpp
  132. +3 −2 src/menu/menu.cpp
  133. +2 −1  src/menu/menu.h
  134. +9 −9 src/menu/menudef.cpp
  135. +2 −2 src/menu/messagebox.cpp
  136. +4 −4 src/menu/playerdisplay.cpp
  137. +32 −29 src/menu/playermenu.cpp
  138. +1 −0  src/name.cpp
  139. +1 −1  src/name.h
  140. +17 −0 src/namedef.h
  141. +10 −3 src/nodebuild.cpp
  142. +4 −0 src/nodebuild.h
  143. +14 −0 src/nodebuild_events.cpp
  144. +12 −5 src/nodebuild_extract.cpp
  145. +14 −0 src/nodebuild_gl.cpp
  146. +3 −0  src/nodebuild_utility.cpp
  147. +1,868 −0 src/oplsynth/OPL3.cpp
  148. +1,447 −0 src/oplsynth/dosbox/opl.cpp
  149. +231 −0 src/oplsynth/dosbox/opl.h
  150. +153 −440 src/oplsynth/fmopl.cpp
  151. +0 −42 src/oplsynth/fmopl.h
  152. +73 −43 src/oplsynth/mlopl_io.cpp
  153. +8 −3 src/oplsynth/music_opl_mididevice.cpp
  154. +5 −5 src/oplsynth/music_opldumper_mididevice.cpp
  155. +8 −6 src/oplsynth/muslib.h
  156. +29 −0 src/oplsynth/opl.h
  157. +26 −28 src/oplsynth/opl_mus_player.cpp
  158. +2 −1  src/oplsynth/opl_mus_player.h
  159. +8 −4 src/p_3dfloors.cpp
  160. +1 −1  src/p_3dfloors.h
  161. +1,725 −197 src/p_acs.cpp
  162. +113 −3 src/p_acs.h
  163. +9 −8 src/p_buildmap.cpp
  164. +32 −6 src/p_enemy.cpp
  165. +10 −3 src/p_floor.cpp
  166. +60 −69 src/p_glnodes.cpp
  167. +67 −48 src/p_interaction.cpp
  168. +10 −4 src/p_lnspec.cpp
  169. +20 −11 src/p_local.h
  170. +196 −162 src/p_map.cpp
  171. +179 −168 src/p_mobj.cpp
  172. +94 −67 src/p_pspr.cpp
  173. +1 −1  src/p_pspr.h
  174. +5 −5 src/p_saveg.cpp
  175. +4 −4 src/p_sectors.cpp
  176. +136 −88 src/p_setup.cpp
  177. +31 −11 src/p_setup.h
  178. +5 −1 src/p_spec.cpp
  179. +1 −0  src/p_spec.h
  180. +26 −6 src/p_states.cpp
  181. +5 −8 src/p_teleport.cpp
  182. +3 −2 src/p_terrain.cpp
  183. +54 −21 src/p_things.cpp
  184. +1 −1  src/p_tick.cpp
  185. +28 −9 src/p_trace.cpp
  186. +11 −1 src/p_trace.h
  187. +49 −7 src/p_udmf.cpp
  188. +1 −0  src/p_usdf.cpp
  189. +86 −82 src/p_user.cpp
  190. +34 −10 src/po_man.cpp
  191. +1 −0  src/po_man.h
  192. +23 −12 src/r_bsp.cpp
  193. +1 −1  src/r_data/r_translate.cpp
  194. +32 −1 src/r_data/voxels.cpp
  195. +1 −0  src/r_data/voxels.h
  196. +9 −2 src/r_defs.h
  197. +1 −1  src/r_main.cpp
  198. +40 −14 src/r_plane.cpp
  199. +1 −1  src/r_plane.h
  200. +1 −1  src/r_polymost.cpp
  201. +170 −59 src/r_segs.cpp
  202. +3 −4 src/r_sky.cpp
  203. +77 −27 src/r_things.cpp
  204. +24 −11 src/r_things.h
  205. +13 −11 src/r_utility.cpp
  206. +2 −4 src/resourcefiles/file_7z.cpp
  207. +0 −2  src/resourcefiles/file_directory.cpp
  208. +277 −12 src/resourcefiles/file_wad.cpp
  209. +4 −7 src/resourcefiles/file_zip.cpp
  210. +2 −7 src/resourcefiles/resourcefile.cpp
  211. +11 −4 src/s_advsound.cpp
  212. +27 −4 src/s_sound.cpp
  213. +4 −0 src/s_sound.h
  214. +1 −1  src/sc_man_scanner.re
  215. +1 −0  src/sdl/crashcatcher.c
  216. +90 −1 src/sdl/hardware.cpp
  217. +30 −0 src/sdl/hardware.h
  218. +10 −28 src/sdl/i_system.cpp
  219. +9 −0 src/sdl/sdlvideo.cpp
  220. +14 −0 src/sound/fmodsound.cpp
  221. +3 −0  src/sound/fmodsound.h
  222. +2 −0  src/sound/i_musicinterns.h
  223. +3 −0  src/sound/i_sound.cpp
  224. +3 −0  src/sound/i_sound.h
  225. +9 −0 src/sound/music_dumb.cpp
  226. +41 −23 src/sound/music_fluidsynth_mididevice.cpp
  227. +15 −3 src/sound/music_mus_opl.cpp
  228. +6 −1 src/sound/music_softsynth_mididevice.cpp
  229. +0 −1  src/st_stuff.h
  230. +2 −2 src/stats.cpp
  231. +31 −0 src/tarray.h
  232. +1 −1  src/textures/multipatchtexture.cpp
  233. +19 −6 src/textures/texturemanager.cpp
  234. +2 −0  src/textures/textures.h
  235. +7 −3 src/thingdef/thingdef.h
  236. +522 −140 src/thingdef/thingdef_codeptr.cpp
  237. +16 −7 src/thingdef/thingdef_data.cpp
  238. +7 −3 src/thingdef/thingdef_expression.cpp
  239. +1 −9 src/thingdef/thingdef_parse.cpp
  240. +118 −5 src/thingdef/thingdef_properties.cpp
  241. +14 −3 src/thingdef/thingdef_states.cpp
  242. +1 −1  src/timidity/instrum_dls.cpp
  243. +27 −2 src/v_draw.cpp
  244. +104 −29 src/v_font.cpp
  245. +2 −2 src/v_video.cpp
  246. +1 −0  src/v_video.h
  247. +2 −2 src/vectors.h
  248. +67 −0 src/w_wad.cpp
  249. +2 −1  src/w_wad.h
  250. +7 −5 src/wi_stuff.cpp
  251. +3 −2 src/win32/fb_d3d9.cpp
  252. +7 −0 tools/lemon/CMakeLists.txt
  253. +6 −4 wadsrc/CMakeLists.txt
  254. +9 −2 wadsrc/static/actors/actor.txt
  255. +65 −14 wadsrc/static/actors/constants.txt
  256. +1 −1  wadsrc/static/actors/doom/doommisc.txt
  257. +1 −1  wadsrc/static/actors/doom/doomweapons.txt
  258. +12 −10 wadsrc/static/actors/doom/scriptedmarine.txt
  259. +7 −7 wadsrc/static/actors/heretic/dsparil.txt
  260. +4 −0 wadsrc/static/actors/heretic/ironlich.txt
  261. +11 −11 wadsrc/static/actors/hexen/demons.txt
  262. +1 −0  wadsrc/static/actors/hexen/firedemon.txt
  263. +0 −1  wadsrc/static/actors/hexen/pig.txt
  264. +1 −0  wadsrc/static/actors/raven/artitele.txt
  265. +3 −2 wadsrc/static/actors/shared/inventory.txt
  266. +3 −1 wadsrc/static/actors/strife/peasants.txt
  267. +3 −3 wadsrc/static/actors/strife/strifestuff.txt
  268. +0 −1  wadsrc/static/actors/strife/strifeweapons.txt
  269. +56 −0 wadsrc/static/compatibility.txt
  270. +33 −0 wadsrc/static/iwadinfo.txt
  271. +35 −1 wadsrc/static/language.enu
  272. +1,748 −0 wadsrc/static/language.ptb
  273. +117 −0 wadsrc/static/mapinfo/doom2.txt
  274. +67 −0 wadsrc/static/mapinfo/doom2bfg.txt
  275. +45 −10 wadsrc/static/menudef.txt
  276. +6 −0 wadsrc/static/textures.txt
  277. +4 −4 wadsrc/static/xlat/base.txt
  278. +0 −2  wadsrc/static/xlat/doom_base.txt
  279. +3 −0  wadsrc/static/xlat/heretic.txt
  280. +9 −9 wadsrc/static/xlat/strife.txt
  281. +20 −40 zdoom.vcproj
  282. +1 −1  zlib/CMakeLists.txt
View
1  CMakeLists.txt
@@ -1,4 +1,5 @@
cmake_minimum_required( VERSION 2.4 )
+project(ZDoom)
IF( NOT CMAKE_BUILD_TYPE )
SET( CMAKE_BUILD_TYPE Debug CACHE STRING
View
5 dumb/CMakeLists.txt
@@ -36,6 +36,7 @@ add_library( dumb
src/core/rendsig.c
src/core/unload.c
src/helpers/barray.c
+ src/helpers/blip_buf.c
src/helpers/clickrem.c
src/helpers/memfile.c
src/helpers/resample.c
@@ -60,6 +61,8 @@ add_library( dumb
src/it/loadmod2.c
src/it/loadmtm.c
src/it/loadmtm2.c
+ src/it/loadokt.c
+ src/it/loadokt2.c
src/it/loadoldpsm.c
src/it/loadoldpsm2.c
src/it/loadpsm.c
@@ -83,6 +86,8 @@ add_library( dumb
src/it/readmod.c
src/it/readmod2.c
src/it/readmtm.c
+ src/it/readokt.c
+ src/it/readokt2.c
src/it/readoldpsm.c
src/it/readpsm.c
src/it/readptm.c
View
14 dumb/include/dumb.h
@@ -233,7 +233,6 @@ int32 DUMBEXPORT duh_get_length(DUH *duh);
const char *DUMBEXPORT duh_get_tag(DUH *duh, const char *key);
-
/* Signal Rendering Functions */
typedef struct DUH_SIGRENDERER DUH_SIGRENDERER;
@@ -396,6 +395,8 @@ void DUMBEXPORT dumb_it_set_global_volume_zero_callback(DUMB_IT_SIGRENDERER *sig
int DUMBCALLBACK dumb_it_callback_terminate(void *data);
int DUMBCALLBACK dumb_it_callback_midi_block(void *data, int channel, unsigned char midi_byte);
+/* dumb_*_mod*: restrict |= 1-Don't read 15 sample files / 2-Use old pattern counting method */
+
DUH *DUMBEXPORT dumb_load_it(const char *filename);
DUH *DUMBEXPORT dumb_load_xm(const char *filename);
DUH *DUMBEXPORT dumb_load_s3m(const char *filename);
@@ -408,6 +409,7 @@ DUH *DUMBEXPORT dumb_load_old_psm(const char * filename);
DUH *DUMBEXPORT dumb_load_mtm(const char *filename);
DUH *DUMBEXPORT dumb_load_riff(const char *filename);
DUH *DUMBEXPORT dumb_load_asy(const char *filename);
+DUH *DUMBEXPORT dumb_load_okt(const char *filename);
DUH *DUMBEXPORT dumb_read_it(DUMBFILE *f);
DUH *DUMBEXPORT dumb_read_xm(DUMBFILE *f);
@@ -421,6 +423,7 @@ DUH *DUMBEXPORT dumb_read_old_psm(DUMBFILE *f);
DUH *DUMBEXPORT dumb_read_mtm(DUMBFILE *f);
DUH *DUMBEXPORT dumb_read_riff(DUMBFILE *f);
DUH *DUMBEXPORT dumb_read_asy(DUMBFILE *f);
+DUH *DUMBEXPORT dumb_read_okt(DUMBFILE *f);
DUH *DUMBEXPORT dumb_load_it_quick(const char *filename);
DUH *DUMBEXPORT dumb_load_xm_quick(const char *filename);
@@ -434,6 +437,7 @@ DUH *DUMBEXPORT dumb_load_old_psm_quick(const char * filename);
DUH *DUMBEXPORT dumb_load_mtm_quick(const char *filename);
DUH *DUMBEXPORT dumb_load_riff_quick(const char *filename);
DUH *DUMBEXPORT dumb_load_asy_quick(const char *filename);
+DUH *DUMBEXPORT dumb_load_okt_quick(const char *filename);
DUH *DUMBEXPORT dumb_read_it_quick(DUMBFILE *f);
DUH *DUMBEXPORT dumb_read_xm_quick(DUMBFILE *f);
@@ -447,6 +451,7 @@ DUH *DUMBEXPORT dumb_read_old_psm_quick(DUMBFILE *f);
DUH *DUMBEXPORT dumb_read_mtm_quick(DUMBFILE *f);
DUH *DUMBEXPORT dumb_read_riff_quick(DUMBFILE *f);
DUH *DUMBEXPORT dumb_read_asy_quick(DUMBFILE *f);
+DUH *DUMBEXPORT dumb_read_okt_quick(DUMBFILE *f);
int32 DUMBEXPORT dumb_it_build_checkpoints(DUMB_IT_SIGDATA *sigdata, int startorder);
void DUMBEXPORT dumb_it_do_initial_runthrough(DUH *duh);
@@ -606,6 +611,8 @@ sigdata_t *DUMBEXPORT duh_get_raw_sigdata(DUH *duh, int sig, int32 type);
DUH_SIGRENDERER *DUMBEXPORT duh_encapsulate_raw_sigrenderer(sigrenderer_t *vsigrenderer, DUH_SIGTYPE_DESC *desc, int n_channels, int32 pos);
sigrenderer_t *DUMBEXPORT duh_get_raw_sigrenderer(DUH_SIGRENDERER *sigrenderer, int32 type);
+int DUMBEXPORT duh_add_signal(DUH *duh, DUH_SIGTYPE_DESC *desc, sigdata_t *sigdata);
+
/* Standard Signal Types */
@@ -662,6 +669,8 @@ typedef struct DUMB_VOLUME_RAMP_INFO DUMB_VOLUME_RAMP_INFO;
typedef void (*DUMB_RESAMPLE_PICKUP)(DUMB_RESAMPLER *resampler, void *data);
+#include "internal/blip_buf.h"
+
struct DUMB_RESAMPLER
{
void *src;
@@ -679,6 +688,9 @@ struct DUMB_RESAMPLER
signed char x8[3*2];
} x;
int overshot;
+ int last_clock;
+ int last_amp[2];
+ blip_t* blip_buffer[2];
};
struct DUMB_VOLUME_RAMP_INFO
View
77 dumb/include/internal/blip_buf.h
@@ -0,0 +1,77 @@
+/** \file
+Sample buffer that resamples from input clock rate to output sample rate */
+
+/* blip_buf 1.1.0 */
+#ifndef BLIP_BUF_H
+#define BLIP_BUF_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/** First parameter of most functions is blip_t*, or const blip_t* if nothing
+is changed. */
+typedef struct blip_t blip_t;
+
+/** Creates new buffer that can hold at most sample_count samples. Sets rates
+so that there are blip_max_ratio clocks per sample. Returns pointer to new
+buffer, or NULL if insufficient memory. */
+blip_t* blip_new( int sample_count );
+
+blip_t* blip_dup( blip_t* );
+
+/** Sets approximate input clock rate and output sample rate. For every
+clock_rate input clocks, approximately sample_rate samples are generated. */
+void blip_set_rates( blip_t*, double clock_rate, double sample_rate );
+
+enum { /** Maximum clock_rate/sample_rate ratio. For a given sample_rate,
+clock_rate must not be greater than sample_rate*blip_max_ratio. */
+blip_max_ratio = 1 << 20 };
+
+/** Clears entire buffer. Afterwards, blip_samples_avail() == 0. */
+void blip_clear( blip_t* );
+
+/** Adds positive/negative delta into buffer at specified clock time. */
+void blip_add_delta( blip_t*, unsigned int clock_time, int delta );
+
+/** Same as blip_add_delta(), but uses faster, lower-quality synthesis. */
+void blip_add_delta_fast( blip_t*, unsigned int clock_time, int delta );
+
+/** Length of time frame, in clocks, needed to make sample_count additional
+samples available. */
+int blip_clocks_needed( const blip_t*, int sample_count );
+
+enum { /** Maximum number of samples that can be generated from one time frame. */
+blip_max_frame = 4000 };
+
+/** Makes input clocks before clock_duration available for reading as output
+samples. Also begins new time frame at clock_duration, so that clock time 0 in
+the new time frame specifies the same clock as clock_duration in the old time
+frame specified. Deltas can have been added slightly past clock_duration (up to
+however many clocks there are in two output samples). */
+void blip_end_frame( blip_t*, unsigned int clock_duration );
+
+/** Number of buffered samples available for reading. */
+int blip_samples_avail( const blip_t* );
+
+/** Reads and removes at most 'count' samples and writes them to 'out'. If
+'stereo' is true, writes output to every other element of 'out', allowing easy
+interleaving of two buffers into a stereo sample stream. Outputs 16-bit signed
+samples. Returns number of samples actually read. */
+int blip_read_samples( blip_t*, int out [], int count );
+
+/** Reads the current integrator and returns it */
+int blip_peek_sample( blip_t* );
+
+/** Frees buffer. No effect if NULL is passed. */
+void blip_delete( blip_t* );
+
+
+/* Deprecated */
+typedef blip_t blip_buffer_t;
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif
View
32 dumb/include/internal/it.h
@@ -54,7 +54,7 @@ sigdata->flags & IT_COMPATIBLE_GXX
* handle ambiguities in the format specification. The correct code in each
* case will be determined most likely by experimentation.
*/
-#define STEREO_SAMPLES_COUNT_AS_TWO
+//#define STEREO_SAMPLES_COUNT_AS_TWO
#define INVALID_ORDERS_END_SONG
#define INVALID_NOTES_CAUSE_NOTE_CUT
#define SUSTAIN_LOOP_OVERRIDES_NORMAL_LOOP
@@ -300,7 +300,18 @@ struct IT_SAMPLE
#define IT_PTM_NOTE_SLIDE_DOWN_RETRIG 36
#define IT_PTM_NOTE_SLIDE_UP_RETRIG 37
-#define IT_N_EFFECTS 38
+/* More effects needed for OKT compatibility */
+#define IT_OKT_NOTE_SLIDE_DOWN 38
+#define IT_OKT_NOTE_SLIDE_DOWN_ROW 39
+#define IT_OKT_NOTE_SLIDE_UP 40
+#define IT_OKT_NOTE_SLIDE_UP_ROW 41
+#define IT_OKT_ARPEGGIO_3 42
+#define IT_OKT_ARPEGGIO_4 43
+#define IT_OKT_ARPEGGIO_5 44
+#define IT_OKT_VOLUME_SLIDE_DOWN 45
+#define IT_OKT_VOLUME_SLIDE_UP 46
+
+#define IT_N_EFFECTS 47
/* These represent the top nibble of the command value. */
#define IT_S_SET_FILTER 0 /* Greyed out in IT... */
@@ -399,6 +410,10 @@ struct IT_PATTERN
#define IT_WAS_A_669 1024
+#define IT_WAS_AN_OKT 2048
+
+#define IT_WAS_AN_STM 4096
+
#define IT_ORDER_END 255
#define IT_ORDER_SKIP 254
@@ -452,6 +467,7 @@ struct IT_PLAYING_ENVELOPE
#define IT_PLAYING_SUSTAINOFF 2
#define IT_PLAYING_FADING 4
#define IT_PLAYING_DEAD 8
+#define IT_PLAYING_REVERSE 16
struct IT_PLAYING
{
@@ -586,7 +602,8 @@ struct IT_CHANNEL
unsigned char new_note_action;
- int arpeggio;
+ unsigned int arpeggio;
+ int arpeggio_shift;
unsigned char retrig;
unsigned char xm_retrig;
int retrig_tick;
@@ -601,7 +618,7 @@ struct IT_CHANNEL
int portamento;
int toneporta;
int toneslide;
- unsigned char toneslide_tick, last_toneslide_tick, ptm_toneslide, ptm_last_toneslide;
+ unsigned char toneslide_tick, last_toneslide_tick, ptm_toneslide, ptm_last_toneslide, okt_toneslide;
unsigned char destnote;
unsigned char toneslide_retrig;
@@ -643,6 +660,10 @@ struct IT_CHANNEL
unsigned char xm_lastX1;
unsigned char xm_lastX2;
+ unsigned char inv_loop_delay;
+ unsigned char inv_loop_speed;
+ int inv_loop_offset;
+
IT_PLAYING *playing;
#ifdef BIT_ARRAY_BULLSHIT
@@ -802,6 +823,7 @@ extern DUH_SIGTYPE_DESC _dumb_sigtype_it;
#define XM_E_NOTE_CUT 0xC
#define XM_E_NOTE_DELAY 0xD
#define XM_E_PATTERN_DELAY 0xE
+#define XM_E_SET_MIDI_MACRO 0xF
#define XM_X_EXTRAFINE_PORTA_UP 1
#define XM_X_EXTRAFINE_PORTA_DOWN 2
@@ -880,4 +902,6 @@ void _dumb_it_ptm_convert_effect(int effect, int value, IT_ENTRY *entry);
int32 _dumb_it_read_sample_data_adpcm4(IT_SAMPLE *sample, DUMBFILE *f);
+void _dumb_it_interleave_stereo_sample(IT_SAMPLE *sample);
+
#endif /* INTERNAL_IT_H */
View
19 dumb/src/core/makeduh.c
@@ -130,3 +130,22 @@ DUH *make_duh(
return duh;
}
+
+int DUMBEXPORT duh_add_signal(DUH *duh, DUH_SIGTYPE_DESC *desc, sigdata_t *sigdata)
+{
+ DUH_SIGNAL **signal;
+
+ if ( !duh || !desc || !sigdata ) return -1;
+
+ signal = ( DUH_SIGNAL ** ) realloc( duh->signal, ( duh->n_signals + 1 ) * sizeof( *duh->signal ) );
+ if ( !signal ) return -1;
+ duh->signal = signal;
+
+ memmove( signal + 1, signal, duh->n_signals * sizeof( *signal ) );
+ duh->n_signals++;
+
+ signal[ 0 ] = make_signal( desc, sigdata );
+ if ( !signal[ 0 ] ) return -1;
+
+ return 0;
+}
View
26 dumb/src/core/rawsig.c
@@ -29,16 +29,30 @@
*/
sigdata_t *DUMBEXPORT duh_get_raw_sigdata(DUH *duh, int sig, int32 type)
{
+ int i;
DUH_SIGNAL *signal;
if (!duh) return NULL;
- if ((unsigned int)sig >= (unsigned int)duh->n_signals) return NULL;
-
- signal = duh->signal[sig];
-
- if (signal && signal->desc->type == type)
- return signal->sigdata;
+ if ( sig >= 0 )
+ {
+ if ((unsigned int)sig >= (unsigned int)duh->n_signals) return NULL;
+
+ signal = duh->signal[sig];
+
+ if (signal && signal->desc->type == type)
+ return signal->sigdata;
+ }
+ else
+ {
+ for ( i = 0; i < duh->n_signals; i++ )
+ {
+ signal = duh->signal[i];
+
+ if (signal && signal->desc->type == type)
+ return signal->sigdata;
+ }
+ }
return NULL;
}
View
354 dumb/src/helpers/blip_buf.c
@@ -0,0 +1,354 @@
+/* blip_buf 1.1.0. http://www.slack.net/~ant/ */
+
+#include "internal/blip_buf.h"
+
+#include <assert.h>
+#include <limits.h>
+#include <string.h>
+#include <stdlib.h>
+
+/* Library Copyright (C) 2003-2009 Shay Green. This library is free software;
+you can redistribute it and/or modify it under the terms of the GNU Lesser
+General Public License as published by the Free Software Foundation; either
+version 2.1 of the License, or (at your option) any later version. This
+library is distributed in the hope that it will be useful, but WITHOUT ANY
+WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
+A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
+details. You should have received a copy of the GNU Lesser General Public
+License along with this module; if not, write to the Free Software Foundation,
+Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
+
+#if defined (BLARGG_TEST) && BLARGG_TEST
+ #include "blargg_test.h"
+#endif
+
+/* Equivalent to ULONG_MAX >= 0xFFFFFFFF00000000.
+Avoids constants that don't fit in 32 bits. */
+#if ULONG_MAX/0xFFFFFFFF > 0xFFFFFFFF
+ typedef unsigned long fixed_t;
+ enum { pre_shift = 32 };
+
+#elif defined(ULLONG_MAX)
+ typedef unsigned long long fixed_t;
+ enum { pre_shift = 32 };
+
+#else
+ typedef unsigned fixed_t;
+ enum { pre_shift = 0 };
+
+#endif
+
+enum { time_bits = pre_shift + 20 };
+
+static fixed_t const time_unit = (fixed_t) 1 << time_bits;
+
+enum { bass_shift = 9 }; /* affects high-pass filter breakpoint frequency */
+enum { end_frame_extra = 2 }; /* allows deltas slightly after frame length */
+
+enum { half_width = 8 };
+enum { buf_extra = half_width*2 + end_frame_extra };
+enum { phase_bits = 5 };
+enum { phase_count = 1 << phase_bits };
+enum { delta_bits = 15 };
+enum { delta_unit = 1 << delta_bits };
+enum { frac_bits = time_bits - pre_shift };
+
+/* We could eliminate avail and encode whole samples in offset, but that would
+limit the total buffered samples to blip_max_frame. That could only be
+increased by decreasing time_bits, which would reduce resample ratio accuracy.
+*/
+
+/** Sample buffer that resamples to output rate and accumulates samples
+until they're read out */
+struct blip_t
+{
+ fixed_t factor;
+ fixed_t offset;
+ int avail;
+ int size;
+ int integrator;
+};
+
+typedef int buf_t;
+
+/* probably not totally portable */
+#define SAMPLES( buf ) ((buf_t*) ((buf) + 1))
+
+/* Arithmetic (sign-preserving) right shift */
+#define ARITH_SHIFT( n, shift ) \
+ ((n) >> (shift))
+
+enum { max_sample = +32767 };
+enum { min_sample = -32768 };
+
+#define CLAMP( n ) \
+ {\
+ if ( (short) n != n )\
+ n = ARITH_SHIFT( n, 16 ) ^ max_sample;\
+ }
+
+static void check_assumptions( void )
+{
+ int n;
+
+ #if INT_MAX < 0x7FFFFFFF || UINT_MAX < 0xFFFFFFFF
+ #error "int must be at least 32 bits"
+ #endif
+
+ assert( (-3 >> 1) == -2 ); /* right shift must preserve sign */
+
+ n = max_sample * 2;
+ CLAMP( n );
+ assert( n == max_sample );
+
+ n = min_sample * 2;
+ CLAMP( n );
+ assert( n == min_sample );
+
+ assert( blip_max_ratio <= time_unit );
+ assert( blip_max_frame <= (fixed_t) -1 >> time_bits );
+}
+
+blip_t* blip_new( int size )
+{
+ blip_t* m;
+ assert( size >= 0 );
+
+ m = (blip_t*) malloc( sizeof *m + (size + buf_extra) * sizeof (buf_t) );
+ if ( m )
+ {
+ m->factor = time_unit / blip_max_ratio;
+ m->size = size;
+ blip_clear( m );
+ check_assumptions();
+ }
+ return m;
+}
+
+blip_t* blip_dup( blip_t* m )
+{
+ size_t size = sizeof *m + (m->size + buf_extra) * sizeof(buf_t);
+ blip_t* r = (blip_t*) malloc( size );
+ if ( r ) memcpy( r, m, size );
+ return r;
+}
+
+void blip_delete( blip_t* m )
+{
+ if ( m != NULL )
+ {
+ /* Clear fields in case user tries to use after freeing */
+ memset( m, 0, sizeof *m );
+ free( m );
+ }
+}
+
+void blip_set_rates( blip_t* m, double clock_rate, double sample_rate )
+{
+ double factor = time_unit * sample_rate / clock_rate;
+ m->factor = (fixed_t) factor;
+
+ /* Fails if clock_rate exceeds maximum, relative to sample_rate */
+ assert( 0 <= factor - m->factor && factor - m->factor < 1 );
+
+ /* Avoid requiring math.h. Equivalent to
+ m->factor = (int) ceil( factor ) */
+ if ( m->factor < factor )
+ m->factor++;
+
+ /* At this point, factor is most likely rounded up, but could still
+ have been rounded down in the floating-point calculation. */
+}
+
+void blip_clear( blip_t* m )
+{
+ /* We could set offset to 0, factor/2, or factor-1. 0 is suitable if
+ factor is rounded up. factor-1 is suitable if factor is rounded down.
+ Since we don't know rounding direction, factor/2 accommodates either,
+ with the slight loss of showing an error in half the time. Since for
+ a 64-bit factor this is years, the halving isn't a problem. */
+
+ m->offset = m->factor / 2;
+ m->avail = 0;
+ m->integrator = 0;
+ memset( SAMPLES( m ), 0, (m->size + buf_extra) * sizeof (buf_t) );
+}
+
+int blip_clocks_needed( const blip_t* m, int samples )
+{
+ fixed_t needed;
+
+ /* Fails if buffer can't hold that many more samples */
+ assert( samples >= 0 && m->avail + samples <= m->size );
+
+ needed = (fixed_t) samples * time_unit;
+ if ( needed < m->offset )
+ return 0;
+
+ return (int)((needed - m->offset + m->factor - 1) / m->factor);
+}
+
+void blip_end_frame( blip_t* m, unsigned t )
+{
+ fixed_t off = t * m->factor + m->offset;
+ m->avail += (int)(off >> time_bits);
+ m->offset = off & (time_unit - 1);
+
+ /* Fails if buffer size was exceeded */
+ assert( m->avail <= m->size );
+}
+
+int blip_samples_avail( const blip_t* m )
+{
+ return m->avail;
+}
+
+static void remove_samples( blip_t* m, int count )
+{
+ buf_t* buf = SAMPLES( m );
+ int remain = m->avail + buf_extra - count;
+ m->avail -= count;
+
+ memmove( &buf [0], &buf [count], remain * sizeof buf [0] );
+ memset( &buf [remain], 0, count * sizeof buf [0] );
+}
+
+int blip_read_samples( blip_t* m, int out [], int count )
+{
+ assert( count >= 0 );
+
+ if ( count > m->avail )
+ count = m->avail;
+
+ if ( count )
+ {
+ buf_t const* in = SAMPLES( m );
+ buf_t const* end = in + count;
+ int sum = m->integrator;
+ do
+ {
+ /* Eliminate fraction */
+ int s = ARITH_SHIFT( sum, delta_bits - 8 );
+
+ sum += *in++;
+
+ *out = s;
+ out++;
+
+ /* High-pass filter */
+ sum -= s >> (8 - (delta_bits - bass_shift)); //<< (delta_bits - bass_shift - 8);
+ }
+ while ( in != end );
+ m->integrator = sum;
+
+ remove_samples( m, count );
+ }
+
+ return count;
+}
+
+int blip_peek_sample( blip_t* m )
+{
+ return ARITH_SHIFT( m->integrator, delta_bits - 8 );
+}
+
+/* Things that didn't help performance on x86:
+ __attribute__((aligned(128)))
+ #define short int
+ restrict
+*/
+
+/* Sinc_Generator( 0.9, 0.55, 4.5 ) */
+static short const bl_step [phase_count + 1] [half_width] =
+{
+{ 43, -115, 350, -488, 1136, -914, 5861,21022},
+{ 44, -118, 348, -473, 1076, -799, 5274,21001},
+{ 45, -121, 344, -454, 1011, -677, 4706,20936},
+{ 46, -122, 336, -431, 942, -549, 4156,20829},
+{ 47, -123, 327, -404, 868, -418, 3629,20679},
+{ 47, -122, 316, -375, 792, -285, 3124,20488},
+{ 47, -120, 303, -344, 714, -151, 2644,20256},
+{ 46, -117, 289, -310, 634, -17, 2188,19985},
+{ 46, -114, 273, -275, 553, 117, 1758,19675},
+{ 44, -108, 255, -237, 471, 247, 1356,19327},
+{ 43, -103, 237, -199, 390, 373, 981,18944},
+{ 42, -98, 218, -160, 310, 495, 633,18527},
+{ 40, -91, 198, -121, 231, 611, 314,18078},
+{ 38, -84, 178, -81, 153, 722, 22,17599},
+{ 36, -76, 157, -43, 80, 824, -241,17092},
+{ 34, -68, 135, -3, 8, 919, -476,16558},
+{ 32, -61, 115, 34, -60, 1006, -683,16001},
+{ 29, -52, 94, 70, -123, 1083, -862,15422},
+{ 27, -44, 73, 106, -184, 1152,-1015,14824},
+{ 25, -36, 53, 139, -239, 1211,-1142,14210},
+{ 22, -27, 34, 170, -290, 1261,-1244,13582},
+{ 20, -20, 16, 199, -335, 1301,-1322,12942},
+{ 18, -12, -3, 226, -375, 1331,-1376,12293},
+{ 15, -4, -19, 250, -410, 1351,-1408,11638},
+{ 13, 3, -35, 272, -439, 1361,-1419,10979},
+{ 11, 9, -49, 292, -464, 1362,-1410,10319},
+{ 9, 16, -63, 309, -483, 1354,-1383, 9660},
+{ 7, 22, -75, 322, -496, 1337,-1339, 9005},
+{ 6, 26, -85, 333, -504, 1312,-1280, 8355},
+{ 4, 31, -94, 341, -507, 1278,-1205, 7713},
+{ 3, 35, -102, 347, -506, 1238,-1119, 7082},
+{ 1, 40, -110, 350, -499, 1190,-1021, 6464},
+{ 0, 43, -115, 350, -488, 1136, -914, 5861}
+};
+
+/* Shifting by pre_shift allows calculation using unsigned int rather than
+possibly-wider fixed_t. On 32-bit platforms, this is likely more efficient.
+And by having pre_shift 32, a 32-bit platform can easily do the shift by
+simply ignoring the low half. */
+
+void blip_add_delta( blip_t* m, unsigned time, int delta )
+{
+ unsigned fixed = (unsigned) ((time * m->factor + m->offset) >> pre_shift);
+ buf_t* out = SAMPLES( m ) + m->avail + (fixed >> frac_bits);
+
+ int const phase_shift = frac_bits - phase_bits;
+ int phase = fixed >> phase_shift & (phase_count - 1);
+ short const* in = bl_step [phase];
+ short const* rev = bl_step [phase_count - phase];
+
+ int interp = fixed >> (phase_shift - delta_bits) & (delta_unit - 1);
+ int delta2 = (delta * interp) >> delta_bits;
+ delta -= delta2;
+
+ /* Fails if buffer size was exceeded */
+ assert( out <= &SAMPLES( m ) [m->size + end_frame_extra] );
+
+ out [0] += in[0]*delta + in[half_width+0]*delta2;
+ out [1] += in[1]*delta + in[half_width+1]*delta2;
+ out [2] += in[2]*delta + in[half_width+2]*delta2;
+ out [3] += in[3]*delta + in[half_width+3]*delta2;
+ out [4] += in[4]*delta + in[half_width+4]*delta2;
+ out [5] += in[5]*delta + in[half_width+5]*delta2;
+ out [6] += in[6]*delta + in[half_width+6]*delta2;
+ out [7] += in[7]*delta + in[half_width+7]*delta2;
+
+ in = rev;
+ out [ 8] += in[7]*delta + in[7-half_width]*delta2;
+ out [ 9] += in[6]*delta + in[6-half_width]*delta2;
+ out [10] += in[5]*delta + in[5-half_width]*delta2;
+ out [11] += in[4]*delta + in[4-half_width]*delta2;
+ out [12] += in[3]*delta + in[3-half_width]*delta2;
+ out [13] += in[2]*delta + in[2-half_width]*delta2;
+ out [14] += in[1]*delta + in[1-half_width]*delta2;
+ out [15] += in[0]*delta + in[0-half_width]*delta2;
+}
+
+void blip_add_delta_fast( blip_t* m, unsigned time, int delta )
+{
+ unsigned fixed = (unsigned) ((time * m->factor + m->offset) >> pre_shift);
+ buf_t* out = SAMPLES( m ) + m->avail + (fixed >> frac_bits);
+
+ int interp = fixed >> (frac_bits - delta_bits) & (delta_unit - 1);
+ int delta2 = delta * interp;
+
+ /* Fails if buffer size was exceeded */
+ assert( out <= &SAMPLES( m ) [m->size + end_frame_extra] );
+
+ out [7] += delta * delta_unit - delta2;
+ out [8] += delta2;
+}
View
9 dumb/src/helpers/resamp2.inc
@@ -95,7 +95,8 @@ static int process_pickup(DUMB_RESAMPLER *resampler)
#define SET_VOLUME_VARIABLES SET_MONO_DEST_VOLUME_VARIABLES
#define RETURN_VOLUME_VARIABLES RETURN_MONO_DEST_VOLUME_VARIABLES
#define VOLUMES_ARE_ZERO MONO_DEST_VOLUMES_ARE_ZERO
-#define MIX_ALIAS(op, upd, offset) MONO_DEST_MIX_ALIAS(op, upd, offset)
+#define MIX_ALIAS(count) MONO_DEST_MIX_ALIAS(count)
+#define PEEK_ALIAS MONO_DEST_PEEK_ALIAS
#define MIX_LINEAR(op, upd, o0, o1) MONO_DEST_MIX_LINEAR(op, upd, o0, o1)
#define MIX_CUBIC(op, upd, x0, x3, o0, o1, o2, o3) MONO_DEST_MIX_CUBIC(op, upd, x0, x3, o0, o1, o2, o3)
#define MIX_ZEROS(op) *dst++ op 0
@@ -137,7 +138,8 @@ static int process_pickup(DUMB_RESAMPLER *resampler)
if ( volume_right ) volume_right->volume = (float)rvolr / 16777216.0f; \
}
#define VOLUMES_ARE_ZERO (lvol == 0 && lvolt == 0 && rvol == 0 && rvolt == 0)
-#define MIX_ALIAS(op, upd, offset) STEREO_DEST_MIX_ALIAS(op, upd, offset)
+#define MIX_ALIAS(count) STEREO_DEST_MIX_ALIAS(count)
+#define PEEK_ALIAS STEREO_DEST_PEEK_ALIAS
#define MIX_LINEAR(op, upd, o0, o1) STEREO_DEST_MIX_LINEAR(op, upd, o0, o1)
#define MIX_CUBIC(op, upd, x0, x3, o0, o1, o2, o3) STEREO_DEST_MIX_CUBIC(op, upd, x0, x3, o0, o1, o2, o3)
#define MIX_ZEROS(op) { *dst++ op 0; *dst++ op 0; }
@@ -157,6 +159,9 @@ static int process_pickup(DUMB_RESAMPLER *resampler)
#undef MONO_DEST_VOLUME_ZEROS
#undef MONO_DEST_VOLUME_VARIABLES
#undef MONO_DEST_VOLUME_PARAMETERS
+#undef STEREO_DEST_PEEK_ALIAS
+#undef MONO_DEST_PEEK_ALIAS
+#undef POKE_ALIAS
#undef COPYSRC2
#undef COPYSRC
#undef DIVIDE_BY_SRC_CHANNELS
View
83 dumb/src/helpers/resamp3.inc
@@ -46,12 +46,13 @@
int32 dumb_resample(DUMB_RESAMPLER *resampler, sample_t *dst, int32 dst_size, VOLUME_PARAMETERS, double delta)
{
- int dt;
+ int dt, inv_dt;
int VOLUME_VARIABLES;
long done;
long todo;
LONG_LONG todo64;
int quality;
+ int blip_samples[256*SRC_CHANNELS];
if (!resampler || resampler->dir == 0) return 0;
ASSERT(resampler->dir == -1 || resampler->dir == 1);
@@ -59,6 +60,7 @@ int32 dumb_resample(DUMB_RESAMPLER *resampler, sample_t *dst, int32 dst_size, VO
done = 0;
dt = (int)(delta * 65536.0 + 0.5);
if (dt == 0 || dt == 0x80000000) return 0;
+ inv_dt = (int)(1.0 / delta * 65536.0 + 0.5);
SET_VOLUME_VARIABLES;
if (VOLUMES_ARE_ZERO) dst = NULL;
@@ -104,29 +106,33 @@ int32 dumb_resample(DUMB_RESAMPLER *resampler, sample_t *dst, int32 dst_size, VO
subpos = (long)new_subpos & 65535;
} else if (quality <= DUMB_RQ_ALIASING) {
/* Aliasing, backwards */
- SRCTYPE xbuf[2*SRC_CHANNELS];
+ int todo_clocks = todo << 16, todo_clocks_set = todo_clocks;
+ SRCTYPE xbuf[2*SRC_CHANNELS];
SRCTYPE *x = &xbuf[0];
- SRCTYPE *xstart;
COPYSRC(xbuf, 0, resampler->X, 1);
COPYSRC(xbuf, 1, resampler->X, 2);
- while (todo && x < &xbuf[2*SRC_CHANNELS]) {
+ if ( todo_clocks_set > 256 * 65536 ) todo_clocks_set = 256 * 65536;
+ while (resampler->last_clock < todo_clocks_set && x < &xbuf[2*SRC_CHANNELS]) {
// TODO: check what happens when multiple tempo slides occur per row
HEAVYASSERT(pos >= resampler->start);
- MIX_ALIAS(+=, 1, 0);
- subpos += dt;
- pos += subpos >> 16;
- x -= (subpos >> 16) * SRC_CHANNELS;
- subpos &= 65535;
- todo--;
+ POKE_ALIAS(0);
+ pos--;
+ x += SRC_CHANNELS;
+ }
+ x = &src[pos*SRC_CHANNELS];
+ while ( todo_clocks ) {
+ todo_clocks_set = todo_clocks;
+ if ( todo_clocks_set > 256 * 65536 ) todo_clocks_set = 256 * 65536;
+ todo_clocks -= todo_clocks_set;
+ while ( resampler->last_clock < todo_clocks_set )
+ {
+ POKE_ALIAS(2);
+ pos--;
+ x -= SRC_CHANNELS;
+ }
+ todo = todo_clocks_set >> 16;
+ MIX_ALIAS( todo );
}
- x = xstart = &src[pos*SRC_CHANNELS];
- LOOP4(todo,
- MIX_ALIAS(+=, 1, 2);
- subpos += dt;
- x += (subpos >> 16) * SRC_CHANNELS;
- subpos &= 65535;
- );
- pos += DIVIDE_BY_SRC_CHANNELS((long)(x - xstart));
} else if (quality <= DUMB_RQ_LINEAR) {
/* Linear interpolation, backwards */
SRCTYPE xbuf[3*SRC_CHANNELS];
@@ -205,28 +211,32 @@ int32 dumb_resample(DUMB_RESAMPLER *resampler, sample_t *dst, int32 dst_size, VO
subpos = (long)new_subpos & 65535;
} else if (quality <= DUMB_RQ_ALIASING) {
/* Aliasing, forwards */
+ int todo_clocks = todo << 16, todo_clocks_set = todo_clocks;
SRCTYPE xbuf[2*SRC_CHANNELS];
SRCTYPE *x = &xbuf[0];
- SRCTYPE *xstart;
COPYSRC(xbuf, 0, resampler->X, 1);
COPYSRC(xbuf, 1, resampler->X, 2);
- while (todo && x < &xbuf[2*SRC_CHANNELS]) {
+ if ( todo_clocks_set > 256 * 65536 ) todo_clocks_set = 256 * 65536;
+ while (resampler->last_clock < todo_clocks_set && x < &xbuf[2*SRC_CHANNELS]) {
HEAVYASSERT(pos < resampler->end);
- MIX_ALIAS(+=, 1, 0);
- subpos += dt;
- pos += subpos >> 16;
- x += (subpos >> 16) * SRC_CHANNELS;
- subpos &= 65535;
- todo--;
+ POKE_ALIAS(0);
+ pos++;
+ x += SRC_CHANNELS;
+ }
+ x = &src[pos*SRC_CHANNELS];
+ while ( todo_clocks ) {
+ todo_clocks_set = todo_clocks;
+ if ( todo_clocks_set > 256 * 65536 ) todo_clocks_set = 256 * 65536;
+ todo_clocks -= todo_clocks_set;
+ while ( resampler->last_clock < todo_clocks_set )
+ {
+ POKE_ALIAS(-2);
+ pos++;
+ x += SRC_CHANNELS;
+ }
+ todo = todo_clocks_set >> 16;
+ MIX_ALIAS( todo );
}
- x = xstart = &src[pos*SRC_CHANNELS];
- LOOP4(todo,
- MIX_ALIAS(+=, 1, -2);
- subpos += dt;
- x += (subpos >> 16) * SRC_CHANNELS;
- subpos &= 65535;
- );
- pos += DIVIDE_BY_SRC_CHANNELS((long)(x - xstart));
} else if (quality <= DUMB_RQ_LINEAR) {
/* Linear interpolation, forwards */
SRCTYPE xbuf[3*SRC_CHANNELS];
@@ -339,7 +349,7 @@ void dumb_resample_get_current_sample(DUMB_RESAMPLER *resampler, VOLUME_PARAMETE
HEAVYASSERT(pos >= resampler->start);
if (dumb_resampling_quality <= DUMB_RQ_ALIASING) {
/* Aliasing, backwards */
- MIX_ALIAS(=, 0, 1);
+ PEEK_ALIAS;
} else if (quality <= DUMB_RQ_LINEAR) {
/* Linear interpolation, backwards */
MIX_LINEAR(=, 0, 2, 1);
@@ -351,7 +361,7 @@ void dumb_resample_get_current_sample(DUMB_RESAMPLER *resampler, VOLUME_PARAMETE
HEAVYASSERT(pos < resampler->end);
if (dumb_resampling_quality <= DUMB_RQ_ALIASING) {
/* Aliasing */
- MIX_ALIAS(=, 0, 1);
+ PEEK_ALIAS;
} else if (dumb_resampling_quality <= DUMB_RQ_LINEAR) {
/* Linear interpolation, forwards */
MIX_LINEAR(=, 0, 1, 2);
@@ -368,6 +378,7 @@ void dumb_resample_get_current_sample(DUMB_RESAMPLER *resampler, VOLUME_PARAMETE
#undef MIX_CUBIC
#undef MIX_LINEAR
#undef MIX_ALIAS
+#undef PEEK_ALIAS
#undef VOLUMES_ARE_ZERO
#undef SET_VOLUME_VARIABLES
#undef RETURN_VOLUME_VARIABLES
View
10 dumb/src/helpers/resample.c
@@ -117,9 +117,9 @@ int dumb_resampling_quality = DUMB_RQ_CUBIC;
*/
#define LOOP4(iterator, CONTENT) \
{ \
- while (iterator) { \
+ while ( (iterator)-- ) \
+ { \
CONTENT; \
- (iterator)--; \
} \
}
#endif
@@ -189,7 +189,7 @@ static void init_cubic(void)
#define SRCTYPE sample_t
#define SRCBITS 24
-#define ALIAS(x, vol) MULSC(x, vol)
+#define ALIAS(x) (x >> 8)
#define LINEAR(x0, x1) (x0 + MULSC(x1 - x0, subpos))
/*
#define SET_CUBIC_COEFFICIENTS(x0, x1, x2, x3) { \
@@ -225,7 +225,7 @@ static void init_cubic(void)
#define SUFFIX _16
#define SRCTYPE short
#define SRCBITS 16
-#define ALIAS(x, vol) (x * vol >> 8)
+#define ALIAS(x) (x)
#define LINEAR(x0, x1) ((x0 << 8) + MULSC16(x1 - x0, subpos))
/*
#define SET_CUBIC_COEFFICIENTS(x0, x1, x2, x3) { \
@@ -247,7 +247,7 @@ static void init_cubic(void)
#define SUFFIX _8
#define SRCTYPE signed char
#define SRCBITS 8
-#define ALIAS(x, vol) (x * vol)
+#define ALIAS(x) (x << 8)
#define LINEAR(x0, x1) ((x0 << 16) + (x1 - x0) * subpos)
/*
#define SET_CUBIC_COEFFICIENTS(x0, x1, x2, x3) { \
View
116 dumb/src/helpers/resample.inc
@@ -69,6 +69,11 @@ void dumb_reset_resampler(DUMB_RESAMPLER *resampler, SRCTYPE *src, int src_chann
}
for (i = 0; i < src_channels*3; i++) resampler->X[i] = 0;
resampler->overshot = -1;
+ resampler->last_clock = 0;
+ resampler->last_amp[0] = 0;
+ resampler->last_amp[1] = 0;
+ blip_clear(resampler->blip_buffer[0]);
+ blip_clear(resampler->blip_buffer[1]);
}
@@ -77,6 +82,21 @@ DUMB_RESAMPLER *dumb_start_resampler(SRCTYPE *src, int src_channels, int32 pos,
{
DUMB_RESAMPLER *resampler = malloc(sizeof(*resampler));
if (!resampler) return NULL;
+ resampler->blip_buffer[0] = blip_new( 256 );
+ if (!resampler->blip_buffer[0])
+ {
+ free(resampler);
+ return NULL;
+ }
+ resampler->blip_buffer[1] = blip_new( 256 );
+ if (!resampler->blip_buffer[1])
+ {
+ free(resampler->blip_buffer[0]);
+ free(resampler);
+ return NULL;
+ }
+ blip_set_rates(resampler->blip_buffer[0], 65536, 1);
+ blip_set_rates(resampler->blip_buffer[1], 65536, 1);
dumb_reset_resampler(resampler, src, src_channels, pos, start, end, quality);
return resampler;
}
@@ -123,16 +143,41 @@ DUMB_RESAMPLER *dumb_start_resampler(SRCTYPE *src, int src_channels, int32 pos,
}
#define RETURN_MONO_DEST_VOLUME_VARIABLES if ( volume ) volume->volume = (float)volr / 16777216.0f
#define MONO_DEST_VOLUMES_ARE_ZERO (vol == 0 && volt == 0)
-#define MONO_DEST_MIX_ALIAS(op, upd, offset) { \
- *dst++ op ALIAS(x[offset], vol); \
- if ( upd ) UPDATE_VOLUME( volume, vol ); \
+#define POKE_ALIAS(offset) { \
+ int delta = ALIAS(x[offset]) - resampler->last_amp[0]; \
+ resampler->last_amp[0] += delta; \
+ if ( delta ) blip_add_delta( resampler->blip_buffer[0], resampler->last_clock, delta ); \
+ resampler->last_clock += inv_dt; \
}
-#define STEREO_DEST_MIX_ALIAS(op, upd, offset) { \
- int xm = x[offset]; \
- *dst++ op ALIAS(xm, lvol); \
- *dst++ op ALIAS(xm, rvol); \
- if ( upd ) UPDATE_VOLUME( volume_left, lvol ); \
- if ( upd ) UPDATE_VOLUME( volume_right, rvol ); \
+#define MONO_DEST_PEEK_ALIAS *dst = MULSC( blip_peek_sample( resampler->blip_buffer[0] ), vol )
+#define MONO_DEST_MIX_ALIAS(count) { \
+ int n = 0; \
+ resampler->last_clock -= count * 65536; \
+ blip_end_frame( resampler->blip_buffer[0], count * 65536 ); \
+ blip_read_samples( resampler->blip_buffer[0], blip_samples, count ); \
+ LOOP4( count, \
+ *dst++ += MULSC( blip_samples[n], vol ); \
+ n++; \
+ UPDATE_VOLUME( volume, vol ); \
+ ); \
+}
+#define STEREO_DEST_PEEK_ALIAS { \
+ int sample = blip_peek_sample( resampler->blip_buffer[0] ); \
+ *dst++ = MULSC( sample, lvol ); \
+ *dst++ = MULSC( sample, rvol ); \
+}
+#define STEREO_DEST_MIX_ALIAS(count) { \
+ int sample, n = 0; \
+ resampler->last_clock -= count * 65536; \
+ blip_end_frame( resampler->blip_buffer[0], count * 65536 ); \
+ blip_read_samples( resampler->blip_buffer[0], blip_samples, count ); \
+ LOOP4( count, \
+ sample = blip_samples[n++]; \
+ *dst++ += MULSC( sample, lvol ); \
+ *dst++ += MULSC( sample, rvol ); \
+ UPDATE_VOLUME( volume_left, lvol ); \
+ UPDATE_VOLUME( volume_right, rvol ); \
+ ); \
}
#define MONO_DEST_MIX_LINEAR(op, upd, o0, o1) { \
*dst++ op MULSC(LINEAR(x[o0], x[o1]), vol); \
@@ -208,16 +253,51 @@ DUMB_RESAMPLER *dumb_start_resampler(SRCTYPE *src, int src_channels, int32 pos,
if ( volume_right ) volume_right->volume = (float)rvolr / 16777216.0f; \
}
#define MONO_DEST_VOLUMES_ARE_ZERO (lvol == 0 && lvolt == 0 && rvol == 0 && rvolt == 0)
-#define MONO_DEST_MIX_ALIAS(op, upd, offset) { \
- *dst++ op ALIAS(x[(offset)*2], lvol) + ALIAS(x[(offset)*2+1], rvol); \
- if ( upd ) UPDATE_VOLUME( volume_left, lvol ); \
- if ( upd ) UPDATE_VOLUME( volume_right, rvol ); \
+#define POKE_ALIAS(offset) { \
+ int deltal = ALIAS(x[(offset)*2+0]) - resampler->last_amp[0]; \
+ int deltar = ALIAS(x[(offset)*2+1]) - resampler->last_amp[1]; \
+ resampler->last_amp[0] += deltal; \
+ resampler->last_amp[1] += deltar; \
+ if ( deltal ) blip_add_delta( resampler->blip_buffer[0], resampler->last_clock, deltal ); \
+ if ( deltar ) blip_add_delta( resampler->blip_buffer[1], resampler->last_clock, deltar ); \
+ resampler->last_clock += inv_dt; \
}
-#define STEREO_DEST_MIX_ALIAS(op, upd, offset) { \
- *dst++ op ALIAS(x[(offset)*2], lvol); \
- *dst++ op ALIAS(x[(offset)*2+1], rvol); \
- if ( upd ) UPDATE_VOLUME( volume_left, lvol ); \
- if ( upd ) UPDATE_VOLUME( volume_right, rvol ); \
+#define MONO_DEST_PEEK_ALIAS { \
+ *dst = MULSC( blip_peek_sample( resampler->blip_buffer[0] ), lvol ) + \
+ MULSC( blip_peek_sample( resampler->blip_buffer[1] ), rvol ); \
+}
+#define MONO_DEST_MIX_ALIAS(count) { \
+ int n = 0; \
+ resampler->last_clock -= count * 65536; \
+ blip_end_frame( resampler->blip_buffer[0], count * 65536 ); \
+ blip_end_frame( resampler->blip_buffer[1], count * 65536 ); \
+ blip_read_samples( resampler->blip_buffer[0], blip_samples, count ); \
+ blip_read_samples( resampler->blip_buffer[1], blip_samples + 256, count ); \
+ LOOP4( count, \
+ *dst++ += MULSC( blip_samples[n], lvol ) + MULSC( blip_samples[256+n], rvol ); \
+ n++; \
+ UPDATE_VOLUME( volume_left, lvol ); \
+ UPDATE_VOLUME( volume_right, rvol ); \
+ ); \
+}
+#define STEREO_DEST_PEEK_ALIAS { \
+ *dst++ = MULSC( blip_peek_sample( resampler->blip_buffer[0] ), lvol ); \
+ *dst++ = MULSC( blip_peek_sample( resampler->blip_buffer[1] ), rvol ); \
+}
+#define STEREO_DEST_MIX_ALIAS(count) { \
+ int n = 0; \
+ resampler->last_clock -= count * 65536; \
+ blip_end_frame( resampler->blip_buffer[0], count * 65536 ); \
+ blip_end_frame( resampler->blip_buffer[1], count * 65536 ); \
+ blip_read_samples( resampler->blip_buffer[0], blip_samples, count ); \
+ blip_read_samples( resampler->blip_buffer[1], blip_samples + 256, count ); \
+ LOOP4( count, \
+ *dst++ += MULSC( blip_samples[n], lvol); \
+ *dst++ += MULSC( blip_samples[256+n], rvol); \
+ n++; \
+ UPDATE_VOLUME( volume_left, lvol ); \
+ UPDATE_VOLUME( volume_right, rvol ); \
+ ); \
}
#define MONO_DEST_MIX_LINEAR(op, upd, o0, o1) { \
*dst++ op MULSC(LINEAR(x[(o0)*2], x[(o1)*2]), lvol) + MULSC(LINEAR(x[(o0)*2+1], x[(o1)*2+1]), rvol); \
View
2  dumb/src/it/itmisc.c
@@ -24,7 +24,7 @@
DUMB_IT_SIGDATA *DUMBEXPORT duh_get_it_sigdata(DUH *duh)
{
- return duh_get_raw_sigdata(duh, 0, SIGTYPE_IT);
+ return duh_get_raw_sigdata(duh, -1, SIGTYPE_IT);
}
View
270 dumb/src/it/itread.c
@@ -31,18 +31,71 @@
//#define INVESTIGATE_OLD_INSTRUMENTS
+typedef struct tdumbfile_mem_status
+{
+ const unsigned char * ptr;
+ unsigned offset, size;
+} dumbfile_mem_status;
-static int it_seek(DUMBFILE *f, int32 offset)
+static int dumbfile_mem_skip(void * f, int32 n)
{
- int32 pos = dumbfile_pos(f);
+ dumbfile_mem_status * s = (dumbfile_mem_status *) f;
+ s->offset += n;
+ if (s->offset > s->size)
+ {
+ s->offset = s->size;
+ return 1;
+ }
- if (pos > offset)
- return -1;
+ return 0;
+}
- if (pos < offset)
- if (dumbfile_skip(f, offset - pos))
- return -1;
+
+static int dumbfile_mem_getc(void * f)
+{
+ dumbfile_mem_status * s = (dumbfile_mem_status *) f;
+ if (s->offset < s->size)
+ {
+ return *(s->ptr + s->offset++);
+ }
+ return -1;
+}
+
+
+
+static int32 dumbfile_mem_getnc(char * ptr, int32 n, void * f)
+{
+ dumbfile_mem_status * s = (dumbfile_mem_status *) f;
+ int32 max = s->size - s->offset;
+ if (max > n) max = n;
+ if (max)
+ {
+ memcpy(ptr, s->ptr + s->offset, max);
+ s->offset += max;
+ }
+ return max;
+}
+
+
+
+static DUMBFILE_SYSTEM mem_dfs = {
+ NULL, // open
+ &dumbfile_mem_skip,
+ &dumbfile_mem_getc,
+ &dumbfile_mem_getnc,
+ NULL // close
+};
+
+
+
+static int it_seek(dumbfile_mem_status * s, int32 offset)
+{
+ if ( (unsigned)offset > s->size )
+ return -1;
+
+ s->offset = offset;
+
return 0;
}
@@ -306,6 +359,8 @@ static int it_read_envelope(IT_ENVELOPE *envelope, DUMBFILE *f)
envelope->loop_end = dumbfile_getc(f);
envelope->sus_loop_start = dumbfile_getc(f);
envelope->sus_loop_end = dumbfile_getc(f);
+ if (envelope->n_nodes > 25)
+ envelope->n_nodes = 25;
for (n = 0; n < envelope->n_nodes; n++) {
envelope->node_y[n] = dumbfile_getc(f);
envelope->node_t[n] = dumbfile_igetw(f);
@@ -629,7 +684,7 @@ int32 _dumb_it_read_sample_data_adpcm4(IT_SAMPLE *sample, DUMBFILE *f)
signed char * ptr, * end;
signed char compression_table[16];
if (dumbfile_getnc(compression_table, 16, f) != 16)
- return -1;
+ return -1;
ptr = (signed char *) sample->data;
delta = 0;
@@ -682,15 +737,36 @@ static int32 it_read_sample_data(int cmwt, IT_SAMPLE *sample, unsigned char conv
else
decompress8(f, sample->data, datasize, ((cmwt >= 0x215) && (convert & 4)));
} else if (sample->flags & IT_SAMPLE_16BIT) {
- if (convert & 2)
- for (n = 0; n < datasize; n++)
- ((short *)sample->data)[n] = dumbfile_mgetw(f);
- else
+ if (sample->flags & IT_SAMPLE_STEREO) {
+ if (convert & 2) {
+ for (n = 0; n < datasize; n += 2)
+ ((short *)sample->data)[n] = dumbfile_mgetw(f);
+ for (n = 1; n < datasize; n += 2)
+ ((short *)sample->data)[n] = dumbfile_mgetw(f);
+ } else {
+ for (n = 0; n < datasize; n += 2)
+ ((short *)sample->data)[n] = dumbfile_igetw(f);
+ for (n = 1; n < datasize; n += 2)
+ ((short *)sample->data)[n] = dumbfile_igetw(f);
+ }
+ } else {
+ if (convert & 2)
+ for (n = 0; n < datasize; n++)
+ ((short *)sample->data)[n] = dumbfile_mgetw(f);
+ else
+ for (n = 0; n < datasize; n++)
+ ((short *)sample->data)[n] = dumbfile_igetw(f);
+ }
+ } else {
+ if (sample->flags & IT_SAMPLE_STEREO) {
+ for (n = 0; n < datasize; n += 2)
+ ((signed char *)sample->data)[n] = dumbfile_getc(f);
+ for (n = 1; n < datasize; n += 2)
+ ((signed char *)sample->data)[n] = dumbfile_getc(f);
+ } else
for (n = 0; n < datasize; n++)
- ((short *)sample->data)[n] = dumbfile_igetw(f);
- } else
- for (n = 0; n < datasize; n++)
- ((signed char *)sample->data)[n] = dumbfile_getc(f);
+ ((signed char *)sample->data)[n] = dumbfile_getc(f);
+ }
if (dumbfile_error(f))
return -1;
@@ -934,13 +1010,58 @@ static sigdata_t *it_load_sigdata(DUMBFILE *f)
unsigned char *buffer;
+ unsigned char *file_buffer = NULL;
+ unsigned int file_size = 0;
+ int block_size;
+
+ dumbfile_mem_status memdata;
+
+ do
+ {
+ void * temp = realloc( file_buffer, file_size + 32768 );
+ if ( !temp )
+ {
+ if ( file_buffer ) free( file_buffer );
+ return NULL;
+ }
+ file_buffer = temp;
+ block_size = dumbfile_getnc( file_buffer + file_size, 32768, f );
+ if ( block_size < 0 )
+ {
+ free( file_buffer );
+ return NULL;
+ }
+ file_size += block_size;
+ }
+ while ( block_size == 32768 );
+
+ memdata.ptr = file_buffer;
+ memdata.offset = 0;
+ memdata.size = file_size;
+
+ f = dumbfile_open_ex(&memdata, &mem_dfs);
+
+ if ( !f )
+ {
+ free( file_buffer );
+ return NULL;
+ }
+
if (dumbfile_mgetl(f) != IT_SIGNATURE)
+ {
+ dumbfile_close(f);
+ free(file_buffer);
return NULL;
+ }
sigdata = malloc(sizeof(*sigdata));
if (!sigdata)
+ {
+ dumbfile_close(f);
+ free(file_buffer);
return NULL;
+ }
sigdata->song_message = NULL;
sigdata->order = NULL;
@@ -989,12 +1110,16 @@ static sigdata_t *it_load_sigdata(DUMBFILE *f)
// XXX sample count
if (dumbfile_error(f) || sigdata->n_orders <= 0 || sigdata->n_instruments > 256 || sigdata->n_samples > 4000 || sigdata->n_patterns > 256) {
_dumb_it_unload_sigdata(sigdata);
+ dumbfile_close(f);
+ free(file_buffer);
return NULL;
}
sigdata->order = malloc(sigdata->n_orders);
if (!sigdata->order) {
_dumb_it_unload_sigdata(sigdata);
+ dumbfile_close(f);
+ free(file_buffer);
return NULL;
}
@@ -1002,6 +1127,8 @@ static sigdata_t *it_load_sigdata(DUMBFILE *f)
sigdata->instrument = malloc(sigdata->n_instruments * sizeof(*sigdata->instrument));
if (!sigdata->instrument) {
_dumb_it_unload_sigdata(sigdata);
+ dumbfile_close(f);
+ free(file_buffer);
return NULL;
}
}
@@ -1010,6 +1137,8 @@ static sigdata_t *it_load_sigdata(DUMBFILE *f)
sigdata->sample = malloc(sigdata->n_samples * sizeof(*sigdata->sample));
if (!sigdata->sample) {
_dumb_it_unload_sigdata(sigdata);
+ dumbfile_close(f);
+ free(file_buffer);
return NULL;
}
for (n = 0; n < sigdata->n_samples; n++)
@@ -1020,6 +1149,8 @@ static sigdata_t *it_load_sigdata(DUMBFILE *f)
sigdata->pattern = malloc(sigdata->n_patterns * sizeof(*sigdata->pattern));
if (!sigdata->pattern) {
_dumb_it_unload_sigdata(sigdata);
+ dumbfile_close(f);
+ free(file_buffer);
return NULL;
}
for (n = 0; n < sigdata->n_patterns; n++)
@@ -1032,6 +1163,8 @@ static sigdata_t *it_load_sigdata(DUMBFILE *f)
component = malloc(769 * sizeof(*component));
if (!component) {
_dumb_it_unload_sigdata(sigdata);
+ dumbfile_close(f);
+ free(file_buffer);
return NULL;
}
@@ -1076,6 +1209,8 @@ static sigdata_t *it_load_sigdata(DUMBFILE *f)
if (dumbfile_error(f)) {
free(component);
_dumb_it_unload_sigdata(sigdata);
+ dumbfile_close(f);
+ free(file_buffer);
return NULL;
}
@@ -1096,6 +1231,8 @@ static sigdata_t *it_load_sigdata(DUMBFILE *f)
if (!sigdata->midi) {
free(component);
_dumb_it_unload_sigdata(sigdata);
+ dumbfile_close(f);
+ free(file_buffer);
return NULL;
// Should we be happy with this outcome in some situations?
}
@@ -1104,6 +1241,8 @@ static sigdata_t *it_load_sigdata(DUMBFILE *f)
if (dumbfile_error(f) || dumbfile_skip(f, 8*i)) {
free(component);
_dumb_it_unload_sigdata(sigdata);
+ dumbfile_close(f);
+ free(file_buffer);
return NULL;
}
/* Read embedded MIDI configuration */
@@ -1111,6 +1250,8 @@ static sigdata_t *it_load_sigdata(DUMBFILE *f)
if (dumbfile_skip(f, 32*9)) {
free(component);
_dumb_it_unload_sigdata(sigdata);
+ dumbfile_close(f);
+ free(file_buffer);
return NULL;
}
for (i = 0; i < 16; i++) {
@@ -1119,6 +1260,8 @@ static sigdata_t *it_load_sigdata(DUMBFILE *f)
if (dumbfile_getnc(mididata, 32, f) < 32) {
free(component);
_dumb_it_unload_sigdata(sigdata);
+ dumbfile_close(f);
+ free(file_buffer);
return NULL;
}
sigdata->midi->SFmacroz[i] = 0;
@@ -1174,12 +1317,14 @@ static sigdata_t *it_load_sigdata(DUMBFILE *f)
sigdata->flags &= IT_REAL_FLAGS;
- qsort(component, n_components, sizeof(IT_COMPONENT), &it_component_compare);
+ qsort(component, n_components, sizeof(IT_COMPONENT), &it_component_compare);
buffer = malloc(65536);
if (!buffer) {
free(component);
_dumb_it_unload_sigdata(sigdata);
+ dumbfile_close(f);
+ free(file_buffer);
return NULL;
}
@@ -1208,10 +1353,12 @@ static sigdata_t *it_load_sigdata(DUMBFILE *f)
continue;
}
- if (it_seek(f, component[n].offset)) {
+ if (it_seek(&memdata, component[n].offset)) {
free(buffer);
free(component);
_dumb_it_unload_sigdata(sigdata);
+ dumbfile_close(f);
+ free(file_buffer);
return NULL;
}
@@ -1227,6 +1374,8 @@ static sigdata_t *it_load_sigdata(DUMBFILE *f)
free(buffer);
free(component);
_dumb_it_unload_sigdata(sigdata);
+ dumbfile_close(f);
+ free(file_buffer);
return NULL;
}
sigdata->song_message[message_length] = 0;
@@ -1243,6 +1392,8 @@ static sigdata_t *it_load_sigdata(DUMBFILE *f)
free(buffer);
free(component);
_dumb_it_unload_sigdata(sigdata);
+ dumbfile_close(f);
+ free(file_buffer);
return NULL;
}
break;
@@ -1252,6 +1403,8 @@ static sigdata_t *it_load_sigdata(DUMBFILE *f)
free(buffer);
free(component);
_dumb_it_unload_sigdata(sigdata);
+ dumbfile_close(f);
+ free(file_buffer);
return NULL;
}
break;
@@ -1261,6 +1414,8 @@ static sigdata_t *it_load_sigdata(DUMBFILE *f)
free(buffer);
free(component);
_dumb_it_unload_sigdata(sigdata);
+ dumbfile_close(f);
+ free(file_buffer);
return NULL;
}
@@ -1287,10 +1442,12 @@ static sigdata_t *it_load_sigdata(DUMBFILE *f)
m = component[n].sampfirst;
while (m >= 0) {
- if (it_seek(f, component[m].offset)) {
+ if (it_seek(&memdata, component[m].offset)) {
free(buffer);
free(component);
_dumb_it_unload_sigdata(sigdata);
+ dumbfile_close(f);
+ free(file_buffer);
return NULL;
}
@@ -1298,16 +1455,79 @@ static sigdata_t *it_load_sigdata(DUMBFILE *f)
free(buffer);
free(component);
_dumb_it_unload_sigdata(sigdata);
+ dumbfile_close(f);
+ free(file_buffer);
return NULL;
}
m = component[m].sampnext;
}
- }
-
- free(buffer);
+ }
+
+ for ( n = 0; n < 10; n++ )
+ {
+ if ( dumbfile_getc( f ) == 'X' )
+ {
+ if ( dumbfile_getc( f ) == 'T' )
+ {
+ if ( dumbfile_getc( f ) == 'P' )
+ {
+ if ( dumbfile_getc( f ) == 'M' )
+ {
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if ( !dumbfile_error( f ) && n < 10 )
+ {
+ unsigned int mptx_id = dumbfile_igetl( f );
+ while ( !dumbfile_error( f ) && mptx_id != DUMB_ID('M','P','T','S') )
+ {
+ unsigned int size = dumbfile_igetw( f );
+ switch (mptx_id)
+ {
+ /* TODO: Add instrument extension readers */
+
+ default:
+ dumbfile_skip(f, size * sigdata->n_instruments);
+ break;
+ }
+
+ mptx_id = dumbfile_igetl( f );
+ }
+
+ mptx_id = dumbfile_igetl( f );
+ while ( memdata.offset < file_size )
+ {
+ unsigned int size = dumbfile_igetw( f );
+ switch (mptx_id)
+ {
+ /* TODO: Add more song extension readers */
+
+ case DUMB_ID('D','T','.','.'):
+ if ( size == 2 )
+ sigdata->tempo = dumbfile_igetw( f );
+ else if ( size == 4 )
+ sigdata->tempo = dumbfile_igetl( f );
+ break;
+
+ default:
+ dumbfile_skip(f, size);
+ break;
+ }
+ mptx_id = dumbfile_igetl( f );
+ }
+ }
+
+ free(buffer);
free(component);
+ dumbfile_close(f);
+ free(file_buffer);
+
_dumb_it_fix_invalid_orders(sigdata);
return sigdata;
@@ -1327,9 +1547,11 @@ DUH *DUMBEXPORT dumb_read_it_quick(DUMBFILE *f)
return NULL;
{
- const char *tag[1][2];
+ const char *tag[2][2];
tag[0][0] = "TITLE";
tag[0][1] = ((DUMB_IT_SIGDATA *)sigdata)->name;
- return make_duh(-1, 1, (const char *const (*)[2])tag, 1, &descptr, &sigdata);
+ tag[1][0] = "FORMAT";
+ tag[1][1] = "IT";
+ return make_duh(-1, 2, (const char *const (*)[2])tag, 1, &descptr, &sigdata);
}
}
View
789 dumb/src/it/itrender.c
@@ -29,15 +29,38 @@
#define END_RAMPING
#define RAMP_DOWN
-static IT_PLAYING *alloc_playing(DUMB_IT_SIGRENDERER *itsr)
+static IT_PLAYING *new_playing(DUMB_IT_SIGRENDERER *itsr)
{
+ IT_PLAYING *r;
+
if (itsr->free_playing != NULL)
{
- IT_PLAYING *pl = itsr->free_playing;
- itsr->free_playing = pl->next;
- return pl;
+ r = itsr->free_playing;
+ itsr->free_playing = r->next;
+ blip_clear(r->resampler.blip_buffer[0]);
+ blip_clear(r->resampler.blip_buffer[1]);
+ return r;
+ }
+ r = (IT_PLAYING *)malloc(sizeof(IT_PLAYING));
+ if (r)
+ {
+ r->resampler.blip_buffer[0] = blip_new( 256 );
+ if ( !r->resampler.blip_buffer[0] )
+ {
+ free( r );
+ return NULL;
+ }
+ r->resampler.blip_buffer[1] = blip_new( 256 );
+ if ( !r->resampler.blip_buffer[1] )
+ {
+ free( r->resampler.blip_buffer[0] );
+ free( r );
+ return NULL;
+ }
+ blip_set_rates(r->resampler.blip_buffer[0], 65536, 1);
+ blip_set_rates(r->resampler.blip_buffer[1], 65536, 1);
}
- return (IT_PLAYING *)malloc(sizeof(IT_PLAYING));
+ return r;
}
static void free_playing(DUMB_IT_SIGRENDERER *itsr, IT_PLAYING *playing)
@@ -46,6 +69,13 @@ static void free_playing(DUMB_IT_SIGRENDERER *itsr, IT_PLAYING *playing)
itsr->free_playing = playing;
}
+static void free_playing_orig(IT_PLAYING * r)
+{
+ blip_delete( r->resampler.blip_buffer[1] );
+ blip_delete( r->resampler.blip_buffer[0] );
+ free( r );
+}
+
static IT_PLAYING *dup_playing(IT_PLAYING *src, IT_CHANNEL *dstchannel, IT_CHANNEL *srcchannel)
{
IT_PLAYING *dst;
@@ -135,6 +165,19 @@ static IT_PLAYING *dup_playing(IT_PLAYING *src, IT_CHANNEL *dstchannel, IT_CHANN
dst->resampler = src->resampler;
dst->resampler.pickup_data = dst;
+ dst->resampler.blip_buffer[0] = blip_dup( dst->resampler.blip_buffer[0] );
+ if ( !dst->resampler.blip_buffer[0] )
+ {
+ free( dst );
+ return NULL;
+ }
+ dst->resampler.blip_buffer[1] = blip_dup( dst->resampler.blip_buffer[1] );
+ if ( !dst->resampler.blip_buffer[1] )
+ {
+ blip_delete( dst->resampler.blip_buffer[0] );
+ free( dst );
+ return NULL;
+ }
dst->time_lost = src->time_lost;
//dst->output = src->output;
@@ -175,6 +218,7 @@ static void dup_channel(IT_CHANNEL *dst, IT_CHANNEL *src)
dst->new_note_action = src->new_note_action;
dst->arpeggio = src->arpeggio;
+ dst->arpeggio_shift = src->arpeggio_shift;
dst->retrig = src->retrig;
dst->xm_retrig = src->xm_retrig;
dst->retrig_tick = src->retrig_tick;
@@ -192,6 +236,7 @@ static void dup_channel(IT_CHANNEL *dst, IT_CHANNEL *src)
dst->last_toneslide_tick = src->last_toneslide_tick;
dst->ptm_toneslide = src->ptm_toneslide;
dst->ptm_last_toneslide = src->ptm_last_toneslide;
+ dst->okt_toneslide = src->okt_toneslide;
dst->destnote = src->destnote;
dst->glissando = src->glissando;
@@ -231,6 +276,10 @@ static void dup_channel(IT_CHANNEL *dst, IT_CHANNEL *src)
dst->xm_lastX1 = src->xm_lastX1;
dst->xm_lastX2 = src->xm_lastX2;
+ dst->inv_loop_delay = src->inv_loop_delay;
+ dst->inv_loop_speed = src->inv_loop_speed;
+ dst->inv_loop_offset = src->inv_loop_offset;
+
dst->playing = dup_playing(src->playing, dst, src);
@@ -760,6 +809,7 @@ static void reset_channel_effects(IT_CHANNEL *channel)
channel->panslide = 0;
channel->channelvolslide = 0;
channel->arpeggio = 0;
+ channel->arpeggio_shift = 0;
channel->retrig = 0;
if (channel->xm_retrig) {
channel->xm_retrig = 0;
@@ -775,6 +825,7 @@ static void reset_channel_effects(IT_CHANNEL *channel)
channel->ptm_last_toneslide = 0;
channel->ptm_toneslide = 0;
channel->toneslide_tick = 0;
+ channel->okt_toneslide = 0;
if (channel->playing) {
channel->playing->vibrato_n = 0;
channel->playing->tremolo_speed = 0;
@@ -854,6 +905,15 @@ static void it_pickup_stop_at_end(DUMB_RESAMPLER *resampler, void *data)
+static void it_pickup_stop_after_reverse(DUMB_RESAMPLER *resampler, void *data)
+{
+ (void)data;
+
+ resampler->dir = 0;
+}
+
+
+
static void it_playing_update_resamplers(IT_PLAYING *playing)
{
if ((playing->sample->flags & IT_SAMPLE_SUS_LOOP) && !(playing->flags & IT_PLAYING_SUSTAINOFF)) {
@@ -874,8 +934,13 @@ static void it_playing_update_resamplers(IT_PLAYING *playing)
playing->resampler.pickup = &it_pickup_pingpong_loop;
else
playing->resampler.pickup = &it_pickup_loop;
- } else {
- if (playing->sample->flags & IT_SAMPLE_SUS_LOOP)
+ } else if (playing->flags & IT_PLAYING_REVERSE) {
+ playing->resampler.start = 0;
+ playing->resampler.end = playing->sample->length;
+ playing->resampler.dir = -1;
+ playing->resampler.pickup = &it_pickup_stop_after_reverse;
+ } else {
+ if (playing->sample->flags & IT_SAMPLE_SUS_LOOP)
playing->resampler.start = playing->sample->sus_loop_start;
else
playing->resampler.start = 0;
@@ -981,6 +1046,15 @@ static void update_retrig(DUMB_IT_SIGRENDERER *sigrenderer, IT_CHANNEL *channel)
}
+static void update_smooth_effects_playing(IT_PLAYING *playing)
+{
+ playing->vibrato_time += playing->vibrato_n *
+ (playing->vibrato_speed << 2);
+ playing->tremolo_time += playing->tremolo_speed << 2;
+ playing->panbrello_time += playing->panbrello_speed;
+ if (playing->panbrello_waveform == 3)
+ playing->panbrello_random = (rand() % 129) - 64;
+}
static void update_smooth_effects(DUMB_IT_SIGRENDERER *sigrenderer)
{
@@ -991,12 +1065,42 @@ static void update_smooth_effects(DUMB_IT_SIGRENDERER *sigrenderer)
IT_PLAYING *playing = channel->playing;
if (playing) {
- playing->vibrato_time += playing->vibrato_n *
- (playing->vibrato_speed << 2);
- playing->tremolo_time += playing->tremolo_speed << 2;
- playing->panbrello_time += playing->panbrello_speed;
- if (playing->panbrello_waveform == 3)
- playing->panbrello_random = (rand() % 129) - 64;
+ update_smooth_effects_playing(playing);
+ }
+ }
+
+ for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) {
+ IT_PLAYING *playing = sigrenderer->playing[i];
+
+ if (playing) {
+ update_smooth_effects_playing(playing);
+ }
+ }
+}
+
+
+static const unsigned char pt_tab_invloop[16] =
+{
+ 0x00, 0x05, 0x06, 0x07, 0x08, 0x0A, 0x0B, 0x0D,
+ 0x0F, 0x13, 0x16, 0x1A, 0x20, 0x2B, 0x40, 0x80
+};
+
+static void update_invert_loop(IT_CHANNEL *channel, IT_SAMPLE *sample)
+{
+ channel->inv_loop_delay += pt_tab_invloop[channel->inv_loop_speed];
+ if (channel->inv_loop_delay >= 0x80)
+ {
+ channel->inv_loop_delay = 0;
+
+ if (sample && ((sample->flags & (IT_SAMPLE_EXISTS | IT_SAMPLE_LOOP)) == (IT_SAMPLE_EXISTS | IT_SAMPLE_LOOP)) && !(sample->flags & (IT_SAMPLE_STEREO | IT_SAMPLE_16BIT)))
+ {
+ if (sample->loop_end - sample->loop_start >= 4)
+ {
+ channel->inv_loop_offset++;
+ if (channel->inv_loop_offset >= (sample->loop_end - sample->loop_start)) channel->inv_loop_offset = 0;
+
+ ((char *)sample->data)[sample->loop_start + channel->inv_loop_offset] ^= 0xFF;
+ }
}
}
}
@@ -1005,7 +1109,7 @@ static void update_smooth_effects(DUMB_IT_SIGRENDERER *sigrenderer)
static void update_effects(DUMB_IT_SIGRENDERER *sigrenderer)
{
- int i;
+ int i, j;
if (sigrenderer->globalvolslide) {
sigrenderer->globalvolume += sigrenderer->globalvolslide;
@@ -1042,10 +1146,11 @@ static void update_effects(DUMB_IT_SIGRENDERER *sigrenderer)
}
if (channel->volslide) {
+ int clip = (sigrenderer->sigdata->flags & IT_WAS_AN_S3M) ? 63 : 64;
channel->volume += channel->volslide;
- if (channel->volume > 64) {
+ if (channel->volume > clip) {
if (channel->volslide >= 0)
- channel->volume = 64;
+ channel->volume = clip;
else
channel->volume = 0;
}
@@ -1088,81 +1193,135 @@ static void update_effects(DUMB_IT_SIGRENDERER *sigrenderer)
}
if (channel->playing)
channel->playing->channel_volume = channel->channelvolume;
+ for (j = 0; j < DUMB_IT_N_NNA_CHANNELS; j++) {
+ if (sigrenderer->playing[j] && sigrenderer->playing[j]->channel == channel)
+ sigrenderer->playing[j]->channel_volume = channel->channelvolume;
+ }
}
update_tremor(channel);
- channel->arpeggio = (channel->arpeggio << 4) | (channel->arpeggio >> 8);
- channel->arpeggio &= 0xFFF;
+ if (channel->arpeggio_shift) channel->arpeggio = (channel->arpeggio << 8) | (channel->arpeggio >> channel->arpeggio_shift);