summaryrefslogtreecommitdiff
path: root/dumb/dumb-0.9.3/src
diff options
context:
space:
mode:
Diffstat (limited to 'dumb/dumb-0.9.3/src')
-rw-r--r--dumb/dumb-0.9.3/src/allegro/alplay.c277
-rw-r--r--dumb/dumb-0.9.3/src/allegro/datduh.c60
-rw-r--r--dumb/dumb-0.9.3/src/allegro/datit.c62
-rw-r--r--dumb/dumb-0.9.3/src/allegro/datitq.c64
-rw-r--r--dumb/dumb-0.9.3/src/allegro/datmod.c61
-rw-r--r--dumb/dumb-0.9.3/src/allegro/datmodq.c64
-rw-r--r--dumb/dumb-0.9.3/src/allegro/dats3m.c61
-rw-r--r--dumb/dumb-0.9.3/src/allegro/dats3mq.c64
-rw-r--r--dumb/dumb-0.9.3/src/allegro/datunld.c31
-rw-r--r--dumb/dumb-0.9.3/src/allegro/datxm.c62
-rw-r--r--dumb/dumb-0.9.3/src/allegro/datxmq.c64
-rw-r--r--dumb/dumb-0.9.3/src/allegro/packfile.c98
-rw-r--r--dumb/dumb-0.9.3/src/core/atexit.c71
-rw-r--r--dumb/dumb-0.9.3/src/core/duhlen.c42
-rw-r--r--dumb/dumb-0.9.3/src/core/duhtag.c38
-rw-r--r--dumb/dumb-0.9.3/src/core/dumbfile.c401
-rw-r--r--dumb/dumb-0.9.3/src/core/loadduh.c42
-rw-r--r--dumb/dumb-0.9.3/src/core/makeduh.c132
-rw-r--r--dumb/dumb-0.9.3/src/core/rawsig.c44
-rw-r--r--dumb/dumb-0.9.3/src/core/readduh.c107
-rw-r--r--dumb/dumb-0.9.3/src/core/register.c104
-rw-r--r--dumb/dumb-0.9.3/src/core/rendduh.c184
-rw-r--r--dumb/dumb-0.9.3/src/core/rendsig.c344
-rw-r--r--dumb/dumb-0.9.3/src/core/unload.c64
-rw-r--r--dumb/dumb-0.9.3/src/helpers/clickrem.c281
-rw-r--r--dumb/dumb-0.9.3/src/helpers/memfile.c96
-rw-r--r--dumb/dumb-0.9.3/src/helpers/resamp2.inc134
-rw-r--r--dumb/dumb-0.9.3/src/helpers/resamp3.inc371
-rw-r--r--dumb/dumb-0.9.3/src/helpers/resample.c385
-rw-r--r--dumb/dumb-0.9.3/src/helpers/resample.inc167
-rw-r--r--dumb/dumb-0.9.3/src/helpers/sampbuf.c64
-rw-r--r--dumb/dumb-0.9.3/src/helpers/silence.c29
-rw-r--r--dumb/dumb-0.9.3/src/helpers/stdfile.c93
-rw-r--r--dumb/dumb-0.9.3/src/it/itload.c42
-rw-r--r--dumb/dumb-0.9.3/src/it/itload2.c29
-rw-r--r--dumb/dumb-0.9.3/src/it/itmisc.c247
-rw-r--r--dumb/dumb-0.9.3/src/it/itorder.c63
-rw-r--r--dumb/dumb-0.9.3/src/it/itread.c1202
-rw-r--r--dumb/dumb-0.9.3/src/it/itread2.c29
-rw-r--r--dumb/dumb-0.9.3/src/it/itrender.c3739
-rw-r--r--dumb/dumb-0.9.3/src/it/itunload.c72
-rw-r--r--dumb/dumb-0.9.3/src/it/loadmod.c42
-rw-r--r--dumb/dumb-0.9.3/src/it/loadmod2.c29
-rw-r--r--dumb/dumb-0.9.3/src/it/loads3m.c42
-rw-r--r--dumb/dumb-0.9.3/src/it/loads3m2.c29
-rw-r--r--dumb/dumb-0.9.3/src/it/loadxm.c42
-rw-r--r--dumb/dumb-0.9.3/src/it/loadxm2.c29
-rw-r--r--dumb/dumb-0.9.3/src/it/readmod.c604
-rw-r--r--dumb/dumb-0.9.3/src/it/readmod2.c29
-rw-r--r--dumb/dumb-0.9.3/src/it/reads3m.c670
-rw-r--r--dumb/dumb-0.9.3/src/it/reads3m2.c29
-rw-r--r--dumb/dumb-0.9.3/src/it/readxm.c1007
-rw-r--r--dumb/dumb-0.9.3/src/it/readxm2.c29
-rw-r--r--dumb/dumb-0.9.3/src/it/xmeffect.c242
54 files changed, 0 insertions, 12407 deletions
diff --git a/dumb/dumb-0.9.3/src/allegro/alplay.c b/dumb/dumb-0.9.3/src/allegro/alplay.c
deleted file mode 100644
index 1bd09249..00000000
--- a/dumb/dumb-0.9.3/src/allegro/alplay.c
+++ /dev/null
@@ -1,277 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * alplay.c - Functions to play a DUH through / / \ \
- * an Allegro audio stream. | < / \_
- * | \/ /\ /
- * By entheh. \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <stdlib.h>
-
-#include <allegro.h>
-
-#include "aldumb.h"
-
-
-
-#define ADP_PLAYING 1
-
-struct AL_DUH_PLAYER
-{
- int flags;
- long bufsize;
- int freq;
- AUDIOSTREAM *stream;
- DUH_SIGRENDERER *sigrenderer; /* If this is NULL, stream is invalid. */
- float volume;
- int silentcount;
-};
-
-
-
-AL_DUH_PLAYER *al_start_duh(DUH *duh, int n_channels, long pos, float volume, long bufsize, int freq)
-{
- AL_DUH_PLAYER *dp;
-
- /* This restriction is imposed by Allegro. */
- ASSERT(n_channels > 0);
- ASSERT(n_channels <= 2);
-
- if (!duh)
- return NULL;
-
- dp = malloc(sizeof(*dp));
- if (!dp)
- return NULL;
-
- dp->flags = ADP_PLAYING;
- dp->bufsize = bufsize;
- dp->freq = freq;
-
- dp->stream = play_audio_stream(bufsize, 16, n_channels - 1, freq, 255, 128);
-
- if (!dp->stream) {
- free(dp);
- return NULL;
- }
-
- voice_set_priority(dp->stream->voice, 255);
-
- dp->sigrenderer = duh_start_sigrenderer(duh, 0, n_channels, pos);
-
- if (!dp->sigrenderer) {
- stop_audio_stream(dp->stream);
- free(dp);
- return NULL;
- }
-
- dp->volume = volume;
- dp->silentcount = 0;
-
- return dp;
-}
-
-
-
-void al_stop_duh(AL_DUH_PLAYER *dp)
-{
- if (dp) {
- if (dp->sigrenderer) {
- duh_end_sigrenderer(dp->sigrenderer);
- stop_audio_stream(dp->stream);
- }
- free(dp);
- }
-}
-
-
-
-void al_pause_duh(AL_DUH_PLAYER *dp)
-{
- if (dp && dp->sigrenderer && (dp->flags & ADP_PLAYING)) {
- voice_stop(dp->stream->voice);
- dp->flags &= ~ADP_PLAYING;
- }
-}
-
-
-
-void al_resume_duh(AL_DUH_PLAYER *dp)
-{
- if (dp && dp->sigrenderer && !(dp->flags & ADP_PLAYING)) {
- voice_start(dp->stream->voice);
- dp->flags |= ADP_PLAYING;
- }
-}
-
-
-
-void al_duh_set_priority(AL_DUH_PLAYER *dp, int priority)
-{
- if (dp && dp->sigrenderer)
- voice_set_priority(dp->stream->voice, priority);
-}
-
-
-
-void al_duh_set_volume(AL_DUH_PLAYER *dp, float volume)
-{
- if (dp)
- dp->volume = volume;
-}
-
-
-
-float al_duh_get_volume(AL_DUH_PLAYER *dp)
-{
- return dp ? dp->volume : 0;
-}
-
-
-
-int al_poll_duh(AL_DUH_PLAYER *dp)
-{
- unsigned short *sptr;
- long n;
- long size;
- int n_channels;
-
- if (!dp || !dp->sigrenderer)
- return 1;
-
- if (!(dp->flags & ADP_PLAYING))
- return 0;
-
- sptr = get_audio_stream_buffer(dp->stream);
-
- if (!sptr)
- return 0;
-
- n = duh_render(dp->sigrenderer, 16, 1, dp->volume, 65536.0 / dp->freq, dp->bufsize, sptr);
-
- if (n == 0) {
- if (++dp->silentcount >= 2) {
- duh_end_sigrenderer(dp->sigrenderer);
- free_audio_stream_buffer(dp->stream);
- stop_audio_stream(dp->stream);
- dp->sigrenderer = NULL;
- return 1;
- }
- }
-
- n_channels = duh_sigrenderer_get_n_channels(dp->sigrenderer);
- n *= n_channels;
- size = dp->bufsize * n_channels;
- for (; n < size; n++)
- sptr[n] = 0x8000;
-
- free_audio_stream_buffer(dp->stream);
-
- return 0;
-}
-
-
-
-long al_duh_get_position(AL_DUH_PLAYER *dp)
-{
- return dp ? duh_sigrenderer_get_position(dp->sigrenderer) : -1;
-}
-
-
-
-AL_DUH_PLAYER *al_duh_encapsulate_sigrenderer(DUH_SIGRENDERER *sigrenderer, float volume, long bufsize, int freq)
-{
- AL_DUH_PLAYER *dp;
- int n_channels;
-
- if (!sigrenderer)
- return NULL;
-
- dp = malloc(sizeof(*dp));
- if (!dp)
- return NULL;
-
- n_channels = duh_sigrenderer_get_n_channels(sigrenderer);
-
- /* This restriction is imposed by Allegro. */
- ASSERT(n_channels > 0);
- ASSERT(n_channels <= 2);
-
- dp->flags = ADP_PLAYING;
- dp->bufsize = bufsize;
- dp->freq = freq;
-
- dp->stream = play_audio_stream(bufsize, 16, n_channels - 1, freq, 255, 128);
-
- if (!dp->stream) {
- free(dp);
- return NULL;
- }
-
- voice_set_priority(dp->stream->voice, 255);
-
- dp->sigrenderer = sigrenderer;
-
- dp->volume = volume;
- dp->silentcount = 0;
-
- return dp;
-}
-
-
-
-DUH_SIGRENDERER *al_duh_get_sigrenderer(AL_DUH_PLAYER *dp)
-{
- return dp ? dp->sigrenderer : NULL;
-}
-
-
-
-/* IMPORTANT: This function will return NULL if the music has ended. */
-// Should this be changed? User might want to hack the underlying SIGRENDERER
-// and resurrect it (e.g. change pattern number), before it gets destroyed...
-DUH_SIGRENDERER *al_duh_decompose_to_sigrenderer(AL_DUH_PLAYER *dp)
-{
- if (dp) {
- DUH_SIGRENDERER *sigrenderer = dp->sigrenderer;
- if (sigrenderer) stop_audio_stream(dp->stream);
- free(dp);
- return sigrenderer;
- }
- return NULL;
-}
-
-
-
-/* DEPRECATED */
-AL_DUH_PLAYER *al_duh_encapsulate_renderer(DUH_SIGRENDERER *dr, float volume, long bufsize, int freq)
-{
- return al_duh_encapsulate_sigrenderer(dr, volume, bufsize, freq);
-}
-
-
-
-/* DEPRECATED */
-DUH_SIGRENDERER *al_duh_get_renderer(AL_DUH_PLAYER *dp)
-{
- return al_duh_get_sigrenderer(dp);
-}
-
-
-
-/* DEPRECATED */
-DUH_SIGRENDERER *al_duh_decompose_to_renderer(AL_DUH_PLAYER *dp)
-{
- return al_duh_decompose_to_sigrenderer(dp);
-}
diff --git a/dumb/dumb-0.9.3/src/allegro/datduh.c b/dumb/dumb-0.9.3/src/allegro/datduh.c
deleted file mode 100644
index 672e3c82..00000000
--- a/dumb/dumb-0.9.3/src/allegro/datduh.c
+++ /dev/null
@@ -1,60 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * datduh.c - Integration with Allegro's / / \ \
- * datafiles. | < / \_
- * | \/ /\ /
- * By entheh. \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <allegro.h>
-
-#include "aldumb.h"
-#include "internal/aldumb.h"
-
-
-
-static void *dat_read_duh(PACKFILE *f, long size)
-{
- DUMBFILE *df;
- DUH *duh;
-
- (void)size;
-
- df = dumbfile_open_packfile(f);
-
- if (!df)
- return NULL;
-
- duh = read_duh(df);
-
- dumbfile_close(df);
-
- return duh;
-}
-
-
-
-/* dumb_register_dat_duh(): tells Allegro about the DUH datafile object. If
- * you intend to load a datafile containing a DUH object, you must call this
- * function first. It is recommended you pass DAT_DUH, but you may have a
- * reason to use a different type (apart from pride, that doesn't count).
- */
-void dumb_register_dat_duh(long type)
-{
- register_datafile_object(
- type,
- &dat_read_duh,
- &_dat_unload_duh
- );
-}
diff --git a/dumb/dumb-0.9.3/src/allegro/datit.c b/dumb/dumb-0.9.3/src/allegro/datit.c
deleted file mode 100644
index 8f58f142..00000000
--- a/dumb/dumb-0.9.3/src/allegro/datit.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * datit.c - Integration of IT files with / / \ \
- * Allegro's datafiles. | < / \_
- * | \/ /\ /
- * By entheh. \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <allegro.h>
-
-#include "aldumb.h"
-#include "internal/aldumb.h"
-
-
-
-static void *dat_read_it(PACKFILE *f, long size)
-{
- DUMBFILE *df;
- DUH *duh;
-
- (void)size;
-
- df = dumbfile_open_packfile(f);
-
- if (!df)
- return NULL;
-
- duh = dumb_read_it(df);
-
- dumbfile_close(df);
-
- return duh;
-}
-
-
-
-/* dumb_register_dat_it(): tells Allegro about the IT datafile object. If you
- * intend to load a datafile containing an IT object, you must call this
- * function first. It is recommended you pass DUMB_DAT_IT, but you may have a
- * reason to use a different type (perhaps you already have a datafile with
- * IT files in and they use a different type).
- */
-void dumb_register_dat_it(long type)
-{
- register_datafile_object(
- type,
- &dat_read_it,
- &_dat_unload_duh
- );
-}
-
diff --git a/dumb/dumb-0.9.3/src/allegro/datitq.c b/dumb/dumb-0.9.3/src/allegro/datitq.c
deleted file mode 100644
index 70792977..00000000
--- a/dumb/dumb-0.9.3/src/allegro/datitq.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * datitq.c - Integration of IT files with / / \ \
- * Allegro's datafiles. | < / \_
- * | \/ /\ /
- * By entheh. \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <allegro.h>
-
-#include "aldumb.h"
-#include "internal/aldumb.h"
-
-
-
-static void *dat_read_it_quick(PACKFILE *f, long size)
-{
- DUMBFILE *df;
- DUH *duh;
-
- (void)size;
-
- df = dumbfile_open_packfile(f);
-
- if (!df)
- return NULL;
-
- duh = dumb_read_it_quick(df);
-
- dumbfile_close(df);
-
- return duh;
-}
-
-
-
-/* dumb_register_dat_it_quick(): tells Allegro about the IT datafile object.
- * If you intend to load a datafile containing an IT object, you must call
- * this function first. It is recommended you pass DUMB_DAT_IT, but you may
- * have a reason to use a different type (perhaps you already have a datafile
- * with IT files in and they use a different type).
- *
- * This installs the quick loader: the song length and fast seek points are
- * not calculated.
- */
-void dumb_register_dat_it_quick(long type)
-{
- register_datafile_object(
- type,
- &dat_read_it_quick,
- &_dat_unload_duh
- );
-}
diff --git a/dumb/dumb-0.9.3/src/allegro/datmod.c b/dumb/dumb-0.9.3/src/allegro/datmod.c
deleted file mode 100644
index 850b17b4..00000000
--- a/dumb/dumb-0.9.3/src/allegro/datmod.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * datmod.c - Integration of MOD files with / / \ \
- * Allegro's datafiles. | < / \_
- * | \/ /\ /
- * By entheh. \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <allegro.h>
-
-#include "aldumb.h"
-#include "internal/aldumb.h"
-
-
-
-static void *dat_read_mod(PACKFILE *f, long size)
-{
- DUMBFILE *df;
- DUH *duh;
-
- (void)size;
-
- df = dumbfile_open_packfile(f);
-
- if (!df)
- return NULL;
-
- duh = dumb_read_mod(df);
-
- dumbfile_close(df);
-
- return duh;
-}
-
-
-
-/* dumb_register_dat_mod(): tells Allegro about the MOD datafile object. If
- * you intend to load a datafile containing a MOD object, you must call this
- * function first. It is recommended you pass DUMB_DAT_MOD, but you may have
- * a reason to use a different type (perhaps you already have a datafile with
- * MOD files in and they use a different type).
- */
-void dumb_register_dat_mod(long type)
-{
- register_datafile_object(
- type,
- &dat_read_mod,
- &_dat_unload_duh
- );
-}
diff --git a/dumb/dumb-0.9.3/src/allegro/datmodq.c b/dumb/dumb-0.9.3/src/allegro/datmodq.c
deleted file mode 100644
index 27947351..00000000
--- a/dumb/dumb-0.9.3/src/allegro/datmodq.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * datmodq.c - Integration of MOD files with / / \ \
- * Allegro's datafiles. | < / \_
- * | \/ /\ /
- * By entheh. \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <allegro.h>
-
-#include "aldumb.h"
-#include "internal/aldumb.h"
-
-
-
-static void *dat_read_mod_quick(PACKFILE *f, long size)
-{
- DUMBFILE *df;
- DUH *duh;
-
- (void)size;
-
- df = dumbfile_open_packfile(f);
-
- if (!df)
- return NULL;
-
- duh = dumb_read_mod_quick(df);
-
- dumbfile_close(df);
-
- return duh;
-}
-
-
-
-/* dumb_register_dat_mod_quick(): tells Allegro about the MOD datafile object.
- * If you intend to load a datafile containing a MOD object, you must call this
- * function first. It is recommended you pass DUMB_DAT_MOD, but you may have
- * a reason to use a different type (perhaps you already have a datafile with
- * MOD files in and they use a different type).
- *
- * This installs the quick loader: the song length and fast seek points are
- * not calculated.
- */
-void dumb_register_dat_mod_quick(long type)
-{
- register_datafile_object(
- type,
- &dat_read_mod_quick,
- &_dat_unload_duh
- );
-}
diff --git a/dumb/dumb-0.9.3/src/allegro/dats3m.c b/dumb/dumb-0.9.3/src/allegro/dats3m.c
deleted file mode 100644
index a0fc7442..00000000
--- a/dumb/dumb-0.9.3/src/allegro/dats3m.c
+++ /dev/null
@@ -1,61 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * dats3m.c - Integration of S3M files with / / \ \
- * Allegro's datafiles. | < / \_
- * | \/ /\ /
- * By entheh. \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <allegro.h>
-
-#include "aldumb.h"
-#include "internal/aldumb.h"
-
-
-
-static void *dat_read_s3m(PACKFILE *f, long size)
-{
- DUMBFILE *df;
- DUH *duh;
-
- (void)size;
-
- df = dumbfile_open_packfile(f);
-
- if (!df)
- return NULL;
-
- duh = dumb_read_s3m(df);
-
- dumbfile_close(df);
-
- return duh;
-}
-
-
-
-/* dumb_register_dat_s3m(): tells Allegro about the S3M datafile object. If
- * you intend to load a datafile containing an S3M object, you must call this
- * function first. It is recommended you pass DUMB_DAT_S3M, but you may have
- * a reason to use a different type (perhaps you already have a datafile with
- * S3M files in and they use a different type).
- */
-void dumb_register_dat_s3m(long type)
-{
- register_datafile_object(
- type,
- &dat_read_s3m,
- &_dat_unload_duh
- );
-}
diff --git a/dumb/dumb-0.9.3/src/allegro/dats3mq.c b/dumb/dumb-0.9.3/src/allegro/dats3mq.c
deleted file mode 100644
index ce14c343..00000000
--- a/dumb/dumb-0.9.3/src/allegro/dats3mq.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * dats3mq.c - Integration of S3M files with / / \ \
- * Allegro's datafiles. | < / \_
- * | \/ /\ /
- * By entheh. \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <allegro.h>
-
-#include "aldumb.h"
-#include "internal/aldumb.h"
-
-
-
-static void *dat_read_s3m_quick(PACKFILE *f, long size)
-{
- DUMBFILE *df;
- DUH *duh;
-
- (void)size;
-
- df = dumbfile_open_packfile(f);
-
- if (!df)
- return NULL;
-
- duh = dumb_read_s3m_quick(df);
-
- dumbfile_close(df);
-
- return duh;
-}
-
-
-
-/* dumb_register_dat_s3m_quick(): tells Allegro about the S3M datafile object.
- * If you intend to load a datafile containing an S3M object, you must call this
- * function first. It is recommended you pass DUMB_DAT_S3M, but you may have
- * a reason to use a different type (perhaps you already have a datafile with
- * S3M files in and they use a different type).
- *
- * This installs the quick loader: the song length and fast seek points are
- * not calculated.
- */
-void dumb_register_dat_s3m_quick(long type)
-{
- register_datafile_object(
- type,
- &dat_read_s3m_quick,
- &_dat_unload_duh
- );
-}
diff --git a/dumb/dumb-0.9.3/src/allegro/datunld.c b/dumb/dumb-0.9.3/src/allegro/datunld.c
deleted file mode 100644
index 71906445..00000000
--- a/dumb/dumb-0.9.3/src/allegro/datunld.c
+++ /dev/null
@@ -1,31 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * datunld.c - Unload function for integration / / \ \
- * with Allegro's datafiles. | < / \_
- * | \/ /\ /
- * By entheh. \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <allegro.h>
-
-#include "aldumb.h"
-#include "internal/aldumb.h"
-
-
-
-void _dat_unload_duh(void *duh)
-{
- unload_duh(duh);
-}
-
diff --git a/dumb/dumb-0.9.3/src/allegro/datxm.c b/dumb/dumb-0.9.3/src/allegro/datxm.c
deleted file mode 100644
index 6cb98d87..00000000
--- a/dumb/dumb-0.9.3/src/allegro/datxm.c
+++ /dev/null
@@ -1,62 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * datxm.c - Integration of XM files with / / \ \
- * Allegro's datafiles. | < / \_
- * | \/ /\ /
- * By entheh. \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <allegro.h>
-
-#include "aldumb.h"
-#include "internal/aldumb.h"
-
-
-
-static void *dat_read_xm(PACKFILE *f, long size)
-{
- DUMBFILE *df;
- DUH *duh;
-
- (void)size;
-
- df = dumbfile_open_packfile(f);
-
- if (!df)
- return NULL;
-
- duh = dumb_read_xm(df);
-
- dumbfile_close(df);
-
- return duh;
-}
-
-
-
-/* dumb_register_dat_xm(): tells Allegro about the XM datafile object. If you
- * intend to load a datafile containing an XM object, you must call this
- * function first. It is recommended you pass DUMB_DAT_XM, but you may have a
- * reason to use a different type (perhaps you already have a datafile with
- * XM files in and they use a different type).
- */
-void dumb_register_dat_xm(long type)
-{
- register_datafile_object(
- type,
- &dat_read_xm,
- &_dat_unload_duh
- );
-}
-
diff --git a/dumb/dumb-0.9.3/src/allegro/datxmq.c b/dumb/dumb-0.9.3/src/allegro/datxmq.c
deleted file mode 100644
index a16ab1eb..00000000
--- a/dumb/dumb-0.9.3/src/allegro/datxmq.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * datxmq.c - Integration of XM files with / / \ \
- * Allegro's datafiles. | < / \_
- * | \/ /\ /
- * By entheh. \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <allegro.h>
-
-#include "aldumb.h"
-#include "internal/aldumb.h"
-
-
-
-static void *dat_read_xm_quick(PACKFILE *f, long size)
-{
- DUMBFILE *df;
- DUH *duh;
-
- (void)size;
-
- df = dumbfile_open_packfile(f);
-
- if (!df)
- return NULL;
-
- duh = dumb_read_xm_quick(df);
-
- dumbfile_close(df);
-
- return duh;
-}
-
-
-
-/* dumb_register_dat_xm_quick(): tells Allegro about the XM datafile object.
- * If you intend to load a datafile containing an XM object, you must call this
- * function first. It is recommended you pass DUMB_DAT_XM, but you may have a
- * reason to use a different type (perhaps you already have a datafile with
- * XM files in and they use a different type).
- *
- * This installs the quick loader: the song length and fast seek points are
- * not calculated.
- */
-void dumb_register_dat_xm_quick(long type)
-{
- register_datafile_object(
- type,
- &dat_read_xm_quick,
- &_dat_unload_duh
- );
-}
diff --git a/dumb/dumb-0.9.3/src/allegro/packfile.c b/dumb/dumb-0.9.3/src/allegro/packfile.c
deleted file mode 100644
index 525baebd..00000000
--- a/dumb/dumb-0.9.3/src/allegro/packfile.c
+++ /dev/null
@@ -1,98 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * packfile.c - Packfile input module. / / \ \
- * | < / \_
- * By entheh. | \/ /\ /
- * \_ / > /
- * Note that this does not use file compression; | \ / /
- * for that you must open the file yourself and | ' /
- * then use dumbfile_open_packfile(). \__/
- */
-
-#include <allegro.h>
-
-#include "aldumb.h"
-
-
-
-static void *dumb_packfile_open(const char *filename)
-{
- return pack_fopen(filename, F_READ);
-}
-
-
-
-static int dumb_packfile_skip(void *f, long n)
-{
- return pack_fseek(f, n);
-}
-
-
-
-static int dumb_packfile_getc(void *f)
-{
- return pack_getc(f);
-}
-
-
-
-static long dumb_packfile_getnc(char *ptr, long n, void *f)
-{
- return pack_fread(ptr, n, f);
-}
-
-
-
-static void dumb_packfile_close(void *f)
-{
- pack_fclose(f);
-}
-
-
-
-static DUMBFILE_SYSTEM packfile_dfs = {
- &dumb_packfile_open,
- &dumb_packfile_skip,
- &dumb_packfile_getc,
- &dumb_packfile_getnc,
- &dumb_packfile_close
-};
-
-
-
-void dumb_register_packfiles(void)
-{
- register_dumbfile_system(&packfile_dfs);
-}
-
-
-
-static DUMBFILE_SYSTEM packfile_dfs_leave_open = {
- NULL,
- &dumb_packfile_skip,
- &dumb_packfile_getc,
- &dumb_packfile_getnc,
- NULL
-};
-
-
-
-DUMBFILE *dumbfile_open_packfile(PACKFILE *p)
-{
- return dumbfile_open_ex(p, &packfile_dfs_leave_open);
-}
-
-
-
-DUMBFILE *dumbfile_from_packfile(PACKFILE *p)
-{
- return p ? dumbfile_open_ex(p, &packfile_dfs) : NULL;
-}
diff --git a/dumb/dumb-0.9.3/src/core/atexit.c b/dumb/dumb-0.9.3/src/core/atexit.c
deleted file mode 100644
index 16c6abdb..00000000
--- a/dumb/dumb-0.9.3/src/core/atexit.c
+++ /dev/null
@@ -1,71 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * atexit.c - Library Clean-up Management. / / \ \
- * | < / \_
- * By entheh. | \/ /\ /
- * \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <stdlib.h>
-
-#include "dumb.h"
-#include "internal/dumb.h"
-
-
-
-typedef struct DUMB_ATEXIT_PROC
-{
- struct DUMB_ATEXIT_PROC *next;
- void (*proc)(void);
-}
-DUMB_ATEXIT_PROC;
-
-
-
-static DUMB_ATEXIT_PROC *dumb_atexit_proc = NULL;
-
-
-
-int dumb_atexit(void (*proc)(void))
-{
- DUMB_ATEXIT_PROC *dap = dumb_atexit_proc;
-
- while (dap) {
- if (dap->proc == proc) return 0;
- dap = dap->next;
- }
-
- dap = malloc(sizeof(*dap));
-
- if (!dap)
- return -1;
-
- dap->next = dumb_atexit_proc;
- dap->proc = proc;
- dumb_atexit_proc = dap;
-
- return 0;
-}
-
-
-
-void dumb_exit(void)
-{
- while (dumb_atexit_proc) {
- DUMB_ATEXIT_PROC *next = dumb_atexit_proc->next;
- (*dumb_atexit_proc->proc)();
- free(dumb_atexit_proc);
- dumb_atexit_proc = next;
- }
-}
diff --git a/dumb/dumb-0.9.3/src/core/duhlen.c b/dumb/dumb-0.9.3/src/core/duhlen.c
deleted file mode 100644
index 4d79fc09..00000000
--- a/dumb/dumb-0.9.3/src/core/duhlen.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * duhlen.c - Functions to set and return the / / \ \
- * length of a DUH. | < / \_
- * | \/ /\ /
- * By entheh. \_ / > /
- * | \ / /
- * Note that the length of a DUH is a constant | ' /
- * stored in the DUH struct and in the DUH disk \__/
- * format. It will be calculated on loading for
- * other formats in which the length is not explicitly stored. Also note that
- * it does not necessarily correspond to the length of time for which the DUH
- * will generate samples. Rather it represents a suitable point for a player
- * such as Winamp to stop, and in any good DUH it will allow for any final
- * flourish to fade out and be appreciated.
- */
-
-#include "dumb.h"
-#include "internal/dumb.h"
-
-
-
-long duh_get_length(DUH *duh)
-{
- return duh ? duh->length : 0;
-}
-
-
-
-void duh_set_length(DUH *duh, long length)
-{
- if (duh)
- duh->length = length;
-}
diff --git a/dumb/dumb-0.9.3/src/core/duhtag.c b/dumb/dumb-0.9.3/src/core/duhtag.c
deleted file mode 100644
index b150467d..00000000
--- a/dumb/dumb-0.9.3/src/core/duhtag.c
+++ /dev/null
@@ -1,38 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * duhtag.c - Function to return the tags stored / / \ \
- * in a DUH struct (typically author | < / \_
- * information). | \/ /\ /
- * \_ / > /
- * By entheh. | \ / /
- * | ' /
- * \__/
- */
-
-#include <string.h>
-
-#include "dumb.h"
-#include "internal/dumb.h"
-
-
-
-const char *duh_get_tag(DUH *duh, const char *key)
-{
- int i;
- ASSERT(key);
- if (!duh || !duh->tag) return NULL;
-
- for (i = 0; i < duh->n_tags; i++)
- if (strcmp(key, duh->tag[i][0]) == 0)
- return duh->tag[i][1];
-
- return NULL;
-}
diff --git a/dumb/dumb-0.9.3/src/core/dumbfile.c b/dumb/dumb-0.9.3/src/core/dumbfile.c
deleted file mode 100644
index 71108c0c..00000000
--- a/dumb/dumb-0.9.3/src/core/dumbfile.c
+++ /dev/null
@@ -1,401 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * dumbfile.c - Hookable, strictly sequential / / \ \
- * file input functions. | < / \_
- * | \/ /\ /
- * By entheh. \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <stdlib.h>
-
-#include "dumb.h"
-
-
-
-static DUMBFILE_SYSTEM *the_dfs = NULL;
-
-
-
-void register_dumbfile_system(DUMBFILE_SYSTEM *dfs)
-{
- ASSERT(dfs);
- ASSERT(dfs->open);
- ASSERT(dfs->getc);
- ASSERT(dfs->close);
- the_dfs = dfs;
-}
-
-
-
-struct DUMBFILE
-{
- DUMBFILE_SYSTEM *dfs;
- void *file;
- long pos;
-};
-
-
-
-DUMBFILE *dumbfile_open(const char *filename)
-{
- DUMBFILE *f;
-
- ASSERT(the_dfs);
-
- f = malloc(sizeof(*f));
-
- if (!f)
- return NULL;
-
- f->dfs = the_dfs;
-
- f->file = (*the_dfs->open)(filename);
-
- if (!f->file) {
- free(f);
- return NULL;
- }
-
- f->pos = 0;
-
- return f;
-}
-
-
-
-DUMBFILE *dumbfile_open_ex(void *file, DUMBFILE_SYSTEM *dfs)
-{
- DUMBFILE *f;
-
- ASSERT(dfs);
- ASSERT(dfs->getc);
- ASSERT(file);
-
- f = malloc(sizeof(*f));
-
- if (!f) {
- if (dfs->close)
- (*dfs->close)(file);
- return NULL;
- }
-
- f->dfs = dfs;
- f->file = file;
-
- f->pos = 0;
-
- return f;
-}
-
-
-
-long dumbfile_pos(DUMBFILE *f)
-{
- ASSERT(f);
-
- return f->pos;
-}
-
-
-
-int dumbfile_skip(DUMBFILE *f, long n)
-{
- int rv;
-
- ASSERT(f);
- ASSERT(n >= 0);
-
- if (f->pos < 0)
- return -1;
-
- f->pos += n;
-
- if (f->dfs->skip) {
- rv = (*f->dfs->skip)(f->file, n);
- if (rv) {
- f->pos = -1;
- return rv;
- }
- } else {
- while (n) {
- rv = (*f->dfs->getc)(f->file);
- if (rv < 0) {
- f->pos = -1;
- return rv;
- }
- n--;
- }
- }
-
- return 0;
-}
-
-
-
-int dumbfile_getc(DUMBFILE *f)
-{
- int rv;
-
- ASSERT(f);
-
- if (f->pos < 0)
- return -1;
-
- rv = (*f->dfs->getc)(f->file);
-
- if (rv < 0) {
- f->pos = -1;
- return rv;
- }
-
- f->pos++;
-
- return rv;
-}
-
-
-
-int dumbfile_igetw(DUMBFILE *f)
-{
- int l, h;
-
- ASSERT(f);
-
- if (f->pos < 0)
- return -1;
-
- l = (*f->dfs->getc)(f->file);
- if (l < 0) {
- f->pos = -1;
- return l;
- }
-
- h = (*f->dfs->getc)(f->file);
- if (h < 0) {
- f->pos = -1;
- return h;
- }
-
- f->pos += 2;
-
- return l | (h << 8);
-}
-
-
-
-int dumbfile_mgetw(DUMBFILE *f)
-{
- int l, h;
-
- ASSERT(f);
-
- if (f->pos < 0)
- return -1;
-
- h = (*f->dfs->getc)(f->file);
- if (h < 0) {
- f->pos = -1;
- return h;
- }
-
- l = (*f->dfs->getc)(f->file);
- if (l < 0) {
- f->pos = -1;
- return l;
- }
-
- f->pos += 2;
-
- return l | (h << 8);
-}
-
-
-
-long dumbfile_igetl(DUMBFILE *f)
-{
- unsigned long rv, b;
-
- ASSERT(f);
-
- if (f->pos < 0)
- return -1;
-
- rv = (*f->dfs->getc)(f->file);
- if ((signed long)rv < 0) {
- f->pos = -1;
- return rv;
- }
-
- b = (*f->dfs->getc)(f->file);
- if ((signed long)b < 0) {
- f->pos = -1;
- return b;
- }
- rv |= b << 8;
-
- b = (*f->dfs->getc)(f->file);
- if ((signed long)b < 0) {
- f->pos = -1;
- return b;
- }
- rv |= b << 16;
-
- b = (*f->dfs->getc)(f->file);
- if ((signed long)b < 0) {
- f->pos = -1;
- return b;
- }
- rv |= b << 24;
-
- f->pos += 4;
-
- return rv;
-}
-
-
-
-long dumbfile_mgetl(DUMBFILE *f)
-{
- unsigned long rv, b;
-
- ASSERT(f);
-
- if (f->pos < 0)
- return -1;
-
- rv = (*f->dfs->getc)(f->file);
- if ((signed long)rv < 0) {
- f->pos = -1;
- return rv;
- }
- rv <<= 24;
-
- b = (*f->dfs->getc)(f->file);
- if ((signed long)b < 0) {
- f->pos = -1;
- return b;
- }
- rv |= b << 16;
-
- b = (*f->dfs->getc)(f->file);
- if ((signed long)b < 0) {
- f->pos = -1;
- return b;
- }
- rv |= b << 8;
-
- b = (*f->dfs->getc)(f->file);
- if ((signed long)b < 0) {
- f->pos = -1;
- return b;
- }
- rv |= b;
-
- f->pos += 4;
-
- return rv;
-}
-
-
-
-unsigned long dumbfile_cgetul(DUMBFILE *f)
-{
- unsigned long rv = 0;
- int v;
-
- do {
- v = dumbfile_getc(f);
-
- if (v < 0)
- return v;
-
- rv <<= 7;
- rv |= v & 0x7F;
- } while (v & 0x80);
-
- return rv;
-}
-
-
-
-signed long dumbfile_cgetsl(DUMBFILE *f)
-{
- unsigned long rv = dumbfile_cgetul(f);
-
- if (f->pos < 0)
- return rv;
-
- return (rv >> 1) | (rv << 31);
-}
-
-
-
-long dumbfile_getnc(char *ptr, long n, DUMBFILE *f)
-{
- long rv;
-
- ASSERT(f);
- ASSERT(n >= 0);
-
- if (f->pos < 0)
- return -1;
-
- if (f->dfs->getnc) {
- rv = (*f->dfs->getnc)(ptr, n, f->file);
- if (rv < n) {
- f->pos = -1;
- return MAX(rv, 0);
- }
- } else {
- for (rv = 0; rv < n; rv++) {
- int c = (*f->dfs->getc)(f->file);
- if (c < 0) {
- f->pos = -1;
- return rv;
- }
- *ptr++ = c;
- }
- }
-
- f->pos += rv;
-
- return rv;
-}
-
-
-
-int dumbfile_error(DUMBFILE *f)
-{
- ASSERT(f);
-
- return f->pos < 0;
-}
-
-
-
-int dumbfile_close(DUMBFILE *f)
-{
- int rv;
-
- ASSERT(f);
-
- rv = f->pos < 0;
-
- if (f->dfs->close)
- (*f->dfs->close)(f->file);
-
- free(f);
-
- return rv;
-}
diff --git a/dumb/dumb-0.9.3/src/core/loadduh.c b/dumb/dumb-0.9.3/src/core/loadduh.c
deleted file mode 100644
index 7dfe5cc1..00000000
--- a/dumb/dumb-0.9.3/src/core/loadduh.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * loadduh.c - Code to read a DUH from a file, / / \ \
- * opening and closing the file for | < / \_
- * you. | \/ /\ /
- * \_ / > /
- * By entheh. | \ / /
- * | ' /
- * \__/
- */
-
-#include "dumb.h"
-#include "internal/dumb.h"
-
-
-
-/* load_duh(): loads a .duh file, returning a pointer to a DUH struct.
- * When you have finished with it, you must pass the pointer to unload_duh()
- * so that the memory can be freed.
- */
-DUH *load_duh(const char *filename)
-{
- DUH *duh;
- DUMBFILE *f = dumbfile_open(filename);
-
- if (!f)
- return NULL;
-
- duh = read_duh(f);
-
- dumbfile_close(f);
-
- return duh;
-}
diff --git a/dumb/dumb-0.9.3/src/core/makeduh.c b/dumb/dumb-0.9.3/src/core/makeduh.c
deleted file mode 100644
index 8345fe4f..00000000
--- a/dumb/dumb-0.9.3/src/core/makeduh.c
+++ /dev/null
@@ -1,132 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * makeduh.c - Function to construct a DUH from / / \ \
- * its components. | < / \_
- * | \/ /\ /
- * By entheh. \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "dumb.h"
-#include "internal/dumb.h"
-
-
-
-static DUH_SIGNAL *make_signal(DUH_SIGTYPE_DESC *desc, sigdata_t *sigdata)
-{
- DUH_SIGNAL *signal;
-
- ASSERT((desc->start_sigrenderer && desc->end_sigrenderer) || (!desc->start_sigrenderer && !desc->end_sigrenderer));
- ASSERT(desc->sigrenderer_generate_samples && desc->sigrenderer_get_current_sample);
-
- signal = malloc(sizeof(*signal));
-
- if (!signal) {
- if (desc->unload_sigdata)
- if (sigdata)
- (*desc->unload_sigdata)(sigdata);
- return NULL;
- }
-
- signal->desc = desc;
- signal->sigdata = sigdata;
-
- return signal;
-}
-
-
-
-DUH *make_duh(
- long length,
- int n_tags,
- const char *const tags[][2],
- int n_signals,
- DUH_SIGTYPE_DESC *desc[],
- sigdata_t *sigdata[]
-)
-{
- DUH *duh = malloc(sizeof(*duh));
- int i;
- int fail;
-
- if (duh) {
- duh->n_signals = n_signals;
-
- duh->signal = malloc(n_signals * sizeof(*duh->signal));
-
- if (!duh->signal) {
- free(duh);
- duh = NULL;
- }
- }
-
- if (!duh) {
- for (i = 0; i < n_signals; i++)
- if (desc[i]->unload_sigdata)
- if (sigdata[i])
- (*desc[i]->unload_sigdata)(sigdata[i]);
- return NULL;
- }
-
- duh->n_tags = 0;
- duh->tag = NULL;
-
- fail = 0;
-
- for (i = 0; i < n_signals; i++) {
- duh->signal[i] = make_signal(desc[i], sigdata[i]);
- if (!duh->signal[i])
- fail = 1;
- }
-
- if (fail) {
- unload_duh(duh);
- return NULL;
- }
-
- duh->length = length;
-
- {
- int mem = n_tags * 2; /* account for NUL terminators here */
- char *ptr;
-
- for (i = 0; i < n_tags; i++)
- mem += strlen(tags[i][0]) + strlen(tags[i][1]);
-
- if (mem <= 0) return duh;
-
- duh->tag = malloc(n_tags * sizeof(*duh->tag));
- if (!duh->tag) return duh;
- duh->tag[0][0] = malloc(mem);
- if (!duh->tag[0][0]) {
- free(duh->tag);
- duh->tag = NULL;
- return duh;
- }
- duh->n_tags = n_tags;
- ptr = duh->tag[0][0];
- for (i = 0; i < n_tags; i++) {
- duh->tag[i][0] = ptr;
- strcpy(ptr, tags[i][0]);
- ptr += strlen(tags[i][0]) + 1;
- duh->tag[i][1] = ptr;
- strcpy(ptr, tags[i][1]);
- ptr += strlen(tags[i][1]) + 1;
- }
- }
-
- return duh;
-}
diff --git a/dumb/dumb-0.9.3/src/core/rawsig.c b/dumb/dumb-0.9.3/src/core/rawsig.c
deleted file mode 100644
index 926c9906..00000000
--- a/dumb/dumb-0.9.3/src/core/rawsig.c
+++ /dev/null
@@ -1,44 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * rawsig.c - Function to retrieve raw signal / / \ \
- * data from a DUH provided you know | < / \_
- * what type of signal it is. | \/ /\ /
- * \_ / > /
- * By entheh. | \ / /
- * | ' /
- * \__/
- */
-
-#include <stdlib.h>
-
-#include "dumb.h"
-#include "internal/dumb.h"
-
-
-
-/* You have to specify the type of sigdata, proving you know what to do with
- * the pointer. If you get it wrong, you can expect NULL back.
- */
-sigdata_t *duh_get_raw_sigdata(DUH *duh, int sig, long type)
-{
- 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;
-
- return NULL;
-}
diff --git a/dumb/dumb-0.9.3/src/core/readduh.c b/dumb/dumb-0.9.3/src/core/readduh.c
deleted file mode 100644
index 514b04a0..00000000
--- a/dumb/dumb-0.9.3/src/core/readduh.c
+++ /dev/null
@@ -1,107 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * readduh.c - Code to read a DUH from an open / / \ \
- * file. | < / \_
- * | \/ /\ /
- * By entheh. \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <stdlib.h>
-
-#include "dumb.h"
-#include "internal/dumb.h"
-
-
-
-static DUH_SIGNAL *read_signal(DUH *duh, DUMBFILE *f)
-{
- DUH_SIGNAL *signal;
- long type;
-
- signal = malloc(sizeof(*signal));
-
- if (!signal)
- return NULL;
-
- type = dumbfile_mgetl(f);
- if (dumbfile_error(f)) {
- free(signal);
- return NULL;
- }
-
- signal->desc = _dumb_get_sigtype_desc(type);
- if (!signal->desc) {
- free(signal);
- return NULL;
- }
-
- if (signal->desc->load_sigdata) {
- signal->sigdata = (*signal->desc->load_sigdata)(duh, f);
- if (!signal->sigdata) {
- free(signal);
- return NULL;
- }
- } else
- signal->sigdata = NULL;
-
- return signal;
-}
-
-
-
-/* read_duh(): reads a DUH from an already open DUMBFILE, and returns its
- * pointer, or null on error. The file is not closed.
- */
-DUH *read_duh(DUMBFILE *f)
-{
- DUH *duh;
- int i;
-
- if (dumbfile_mgetl(f) != DUH_SIGNATURE)
- return NULL;
-
- duh = malloc(sizeof(*duh));
- if (!duh)
- return NULL;
-
- duh->length = dumbfile_igetl(f);
- if (dumbfile_error(f) || duh->length <= 0) {
- free(duh);
- return NULL;
- }
-
- duh->n_signals = dumbfile_igetl(f);
- if (dumbfile_error(f) || duh->n_signals <= 0) {
- free(duh);
- return NULL;
- }
-
- duh->signal = malloc(sizeof(*duh->signal) * duh->n_signals);
- if (!duh->signal) {
- free(duh);
- return NULL;
- }
-
- for (i = 0; i < duh->n_signals; i++)
- duh->signal[i] = NULL;
-
- for (i = 0; i < duh->n_signals; i++) {
- if (!(duh->signal[i] = read_signal(duh, f))) {
- unload_duh(duh);
- return NULL;
- }
- }
-
- return duh;
-}
diff --git a/dumb/dumb-0.9.3/src/core/register.c b/dumb/dumb-0.9.3/src/core/register.c
deleted file mode 100644
index 66dd4524..00000000
--- a/dumb/dumb-0.9.3/src/core/register.c
+++ /dev/null
@@ -1,104 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * register.c - Signal type registration. / / \ \
- * | < / \_
- * By entheh. | \/ /\ /
- * \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <stdlib.h>
-
-#include "dumb.h"
-#include "internal/dumb.h"
-
-
-
-static DUH_SIGTYPE_DESC_LINK *sigtype_desc = NULL;
-static DUH_SIGTYPE_DESC_LINK **sigtype_desc_tail = &sigtype_desc;
-
-
-
-/* destroy_sigtypes(): frees all memory allocated while registering signal
- * types. This function is set up to be called by dumb_exit().
- */
-static void destroy_sigtypes(void)
-{
- DUH_SIGTYPE_DESC_LINK *desc_link = sigtype_desc, *next;
- sigtype_desc = NULL;
- sigtype_desc_tail = &sigtype_desc;
-
- while (desc_link) {
- next = desc_link->next;
- free(desc_link);
- desc_link = next;
- }
-}
-
-
-
-/* dumb_register_sigtype(): registers a new signal type with DUMB. The signal
- * type is identified by a four-character string (e.g. "WAVE"), which you can
- * encode using the the DUMB_ID() macro (e.g. DUMB_ID('W','A','V','E')). The
- * signal's behaviour is defined by four functions, whose pointers you pass
- * here. See the documentation for details.
- *
- * If a DUH tries to use a signal that has not been registered using this
- * function, then the library will fail to load the DUH.
- */
-void dumb_register_sigtype(DUH_SIGTYPE_DESC *desc)
-{
- DUH_SIGTYPE_DESC_LINK *desc_link = sigtype_desc;
-
- ASSERT((desc->load_sigdata && desc->unload_sigdata) || (!desc->load_sigdata && !desc->unload_sigdata));
- ASSERT((desc->start_sigrenderer && desc->end_sigrenderer) || (!desc->start_sigrenderer && !desc->end_sigrenderer));
- ASSERT(desc->sigrenderer_generate_samples && desc->sigrenderer_get_current_sample);
-
- if (desc_link) {
- do {
- if (desc_link->desc->type == desc->type) {
- desc_link->desc = desc;
- return;
- }
- desc_link = desc_link->next;
- } while (desc_link);
- } else
- dumb_atexit(&destroy_sigtypes);
-
- desc_link = *sigtype_desc_tail = malloc(sizeof(DUH_SIGTYPE_DESC_LINK));
-
- if (!desc_link)
- return;
-
- desc_link->next = NULL;
- sigtype_desc_tail = &desc_link->next;
-
- desc_link->desc = desc;
-}
-
-
-
-/* _dumb_get_sigtype_desc(): searches the registered functions for a signal
- * type matching the parameter. If such a sigtype is found, it returns a
- * pointer to a sigtype descriptor containing the necessary functions to
- * manage the signal. If none is found, it returns NULL.
- */
-DUH_SIGTYPE_DESC *_dumb_get_sigtype_desc(long type)
-{
- DUH_SIGTYPE_DESC_LINK *desc_link = sigtype_desc;
-
- while (desc_link && desc_link->desc->type != type)
- desc_link = desc_link->next;
-
- return desc_link ? desc_link->desc : NULL;
-}
diff --git a/dumb/dumb-0.9.3/src/core/rendduh.c b/dumb/dumb-0.9.3/src/core/rendduh.c
deleted file mode 100644
index 1639b938..00000000
--- a/dumb/dumb-0.9.3/src/core/rendduh.c
+++ /dev/null
@@ -1,184 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * rendduh.c - Functions for rendering a DUH into / / \ \
- * an end-user sample format. | < / \_
- * | \/ /\ /
- * By entheh. \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <stdlib.h>
-#include <limits.h>
-
-#include "dumb.h"
-#include "internal/dumb.h"
-
-
-
-/* On the x86, we can use some tricks to speed stuff up */
-#if (defined _MSC_VER) || (defined __DJGPP__) || (defined __MINGW__)
-// Can't we detect Linux and other x86 platforms here? :/
-
-#define FAST_MID(var, min, max) { \
- var -= (min); \
- var &= (~var) >> (sizeof(var) * CHAR_BIT - 1); \
- var += (min); \
- var -= (max); \
- var &= var >> (sizeof(var) * CHAR_BIT - 1); \
- var += (max); \
-}
-
-#define CONVERT8(src, pos, signconv) { \
- signed int f = (src + 0x8000) >> 16; \
- FAST_MID(f, -128, 127); \
- ((char*)sptr)[pos] = (char)f ^ signconv; \
-}
-
-#define CONVERT16(src, pos, signconv) { \
- signed int f = (src + 0x80) >> 8; \
- FAST_MID(f, -32768, 32767); \
- ((short*)sptr)[pos] = (short)(f ^ signconv); \
-}
-
-#else
-
-#define CONVERT8(src, pos, signconv) \
-{ \
- signed int f = (src + 0x8000) >> 16; \
- f = MID(-128, f, 127); \
- ((char *)sptr)[pos] = (char)f ^ signconv; \
-}
-
-
-
-#define CONVERT16(src, pos, signconv) \
-{ \
- signed int f = (src + 0x80) >> 8; \
- f = MID(-32768, f, 32767); \
- ((short *)sptr)[pos] = (short)(f ^ signconv); \
-}
-
-#endif
-
-
-
-/* DEPRECATED */
-DUH_SIGRENDERER *duh_start_renderer(DUH *duh, int n_channels, long pos)
-{
- return duh_start_sigrenderer(duh, 0, n_channels, pos);
-}
-
-
-
-long duh_render(
- DUH_SIGRENDERER *sigrenderer,
- int bits, int unsign,
- float volume, float delta,
- long size, void *sptr
-)
-{
- long n;
-
- sample_t **sampptr;
-
- int n_channels;
-
- ASSERT(bits == 8 || bits == 16);
- ASSERT(sptr);
-
- if (!sigrenderer)
- return 0;
-
- n_channels = duh_sigrenderer_get_n_channels(sigrenderer);
-
- ASSERT(n_channels > 0);
- /* This restriction will be removed when need be. At the moment, tightly
- * optimised loops exist for exactly one or two channels.
- */
- ASSERT(n_channels <= 2);
-
- sampptr = allocate_sample_buffer(n_channels, size);
-
- if (!sampptr)
- return 0;
-
- dumb_silence(sampptr[0], n_channels * size);
-
- size = duh_sigrenderer_generate_samples(sigrenderer, volume, delta, size, sampptr);
-
- if (bits == 16) {
- int signconv = unsign ? 0x8000 : 0x0000;
-
- for (n = 0; n < size * n_channels; n++) {
- CONVERT16(sampptr[0][n], n, signconv);
- }
- } else {
- char signconv = unsign ? 0x80 : 0x00;
-
- for (n = 0; n < size * n_channels; n++) {
- CONVERT8(sampptr[0][n], n, signconv);
- }
- }
-
- destroy_sample_buffer(sampptr);
-
- return size;
-}
-
-
-
-/* DEPRECATED */
-int duh_renderer_get_n_channels(DUH_SIGRENDERER *dr)
-{
- return duh_sigrenderer_get_n_channels(dr);
-}
-
-
-
-/* DEPRECATED */
-long duh_renderer_get_position(DUH_SIGRENDERER *dr)
-{
- return duh_sigrenderer_get_position(dr);
-}
-
-
-
-/* DEPRECATED */
-void duh_end_renderer(DUH_SIGRENDERER *dr)
-{
- duh_end_sigrenderer(dr);
-}
-
-
-
-/* DEPRECATED */
-DUH_SIGRENDERER *duh_renderer_encapsulate_sigrenderer(DUH_SIGRENDERER *sigrenderer)
-{
- return sigrenderer;
-}
-
-
-
-/* DEPRECATED */
-DUH_SIGRENDERER *duh_renderer_get_sigrenderer(DUH_SIGRENDERER *dr)
-{
- return dr;
-}
-
-
-
-/* DEPRECATED */
-DUH_SIGRENDERER *duh_renderer_decompose_to_sigrenderer(DUH_SIGRENDERER *dr)
-{
- return dr;
-}
diff --git a/dumb/dumb-0.9.3/src/core/rendsig.c b/dumb/dumb-0.9.3/src/core/rendsig.c
deleted file mode 100644
index 1b7cf65f..00000000
--- a/dumb/dumb-0.9.3/src/core/rendsig.c
+++ /dev/null
@@ -1,344 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * rendsig.c - Wrappers to render samples from / / \ \
- * the signals in a DUH. | < / \_
- * | \/ /\ /
- * By entheh. \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <stdlib.h>
-
-#include "dumb.h"
-#include "internal/dumb.h"
-
-
-
-struct DUH_SIGRENDERER
-{
- DUH_SIGTYPE_DESC *desc;
-
- sigrenderer_t *sigrenderer;
-
- int n_channels;
-
- long pos;
- int subpos;
-
- DUH_SIGRENDERER_SAMPLE_ANALYSER_CALLBACK callback;
- void *callback_data;
-};
-
-
-
-DUH_SIGRENDERER *duh_start_sigrenderer(DUH *duh, int sig, int n_channels, long pos)
-{
- DUH_SIGRENDERER *sigrenderer;
-
- DUH_SIGNAL *signal;
- DUH_START_SIGRENDERER proc;
-
- if (!duh)
- return NULL;
-
- if ((unsigned int)sig >= (unsigned int)duh->n_signals)
- return NULL;
-
- signal = duh->signal[sig];
- if (!signal)
- return NULL;
-
- sigrenderer = malloc(sizeof(*sigrenderer));
- if (!sigrenderer)
- return NULL;
-
- sigrenderer->desc = signal->desc;
-
- proc = sigrenderer->desc->start_sigrenderer;
-
- if (proc) {
- duh->signal[sig] = NULL;
- sigrenderer->sigrenderer = (*proc)(duh, signal->sigdata, n_channels, pos);
- duh->signal[sig] = signal;
-
- if (!sigrenderer->sigrenderer) {
- free(sigrenderer);
- return NULL;
- }
- } else
- sigrenderer->sigrenderer = NULL;
-
- sigrenderer->n_channels = n_channels;
-
- sigrenderer->pos = pos;
- sigrenderer->subpos = 0;
-
- sigrenderer->callback = NULL;
-
- return sigrenderer;
-}
-
-
-
-#include <stdio.h>
-void duh_sigrenderer_set_callback(
- DUH_SIGRENDERER *sigrenderer,
- DUH_SIGRENDERER_CALLBACK callback, void *data
-)
-{
- (void)sigrenderer;
- (void)callback;
- (void)data;
- fprintf(stderr,
- "Call to deprecated function duh_sigrenderer_set_callback(). The callback\n"
- "was not installed. See dumb/docs/deprec.txt for how to fix this.\n");
-}
-
-
-
-void duh_sigrenderer_set_analyser_callback(
- DUH_SIGRENDERER *sigrenderer,
- DUH_SIGRENDERER_ANALYSER_CALLBACK callback, void *data
-)
-{
- (void)sigrenderer;
- (void)callback;
- (void)data;
- fprintf(stderr,
- "Call to deprecated function duh_sigrenderer_set_analyser_callback(). The\n"
- "callback was not installed. See dumb/docs/deprec.txt for how to fix this.\n");
-}
-
-
-
-void duh_sigrenderer_set_sample_analyser_callback(
- DUH_SIGRENDERER *sigrenderer,
- DUH_SIGRENDERER_SAMPLE_ANALYSER_CALLBACK callback, void *data
-)
-{
- if (sigrenderer) {
- sigrenderer->callback = callback;
- sigrenderer->callback_data = data;
- }
-}
-
-
-
-int duh_sigrenderer_get_n_channels(DUH_SIGRENDERER *sigrenderer)
-{
- return sigrenderer ? sigrenderer->n_channels : 0;
-}
-
-
-
-long duh_sigrenderer_get_position(DUH_SIGRENDERER *sigrenderer)
-{
- return sigrenderer ? sigrenderer->pos : -1;
-}
-
-
-
-void duh_sigrenderer_set_sigparam(
- DUH_SIGRENDERER *sigrenderer,
- unsigned char id, long value
-)
-{
- DUH_SIGRENDERER_SET_SIGPARAM proc;
-
- if (!sigrenderer) return;
-
- proc = sigrenderer->desc->sigrenderer_set_sigparam;
- if (proc)
- (*proc)(sigrenderer->sigrenderer, id, value);
- else
- TRACE("Parameter #%d = %ld for signal %c%c%c%c, which does not take parameters.\n",
- (int)id,
- value,
- (int)(sigrenderer->desc->type >> 24),
- (int)(sigrenderer->desc->type >> 16),
- (int)(sigrenderer->desc->type >> 8),
- (int)(sigrenderer->desc->type));
-}
-
-
-
-long duh_sigrenderer_generate_samples(
- DUH_SIGRENDERER *sigrenderer,
- float volume, float delta,
- long size, sample_t **samples
-)
-{
- long rendered;
- LONG_LONG t;
-
- if (!sigrenderer) return 0;
-
- rendered = (*sigrenderer->desc->sigrenderer_generate_samples)
- (sigrenderer->sigrenderer, volume, delta, size, samples);
-
- if (rendered) {
- if (sigrenderer->callback)
- (*sigrenderer->callback)(sigrenderer->callback_data,
- (const sample_t *const *)samples, sigrenderer->n_channels, rendered);
-
- t = sigrenderer->subpos + (LONG_LONG)(delta * 65536.0 + 0.5) * rendered;
-
- sigrenderer->pos += (long)(t >> 16);
- sigrenderer->subpos = (int)t & 65535;
- }
-
- return rendered;
-}
-
-
-
-/* DEPRECATED */
-long duh_sigrenderer_get_samples(
- DUH_SIGRENDERER *sigrenderer,
- float volume, float delta,
- long size, sample_t **samples
-)
-{
- sample_t **s;
- long rendered;
- long i;
- int j;
- if (!samples) return duh_sigrenderer_generate_samples(sigrenderer, volume, delta, size, NULL);
- s = allocate_sample_buffer(sigrenderer->n_channels, size);
- if (!s) return 0;
- dumb_silence(s[0], sigrenderer->n_channels * size);
- rendered = duh_sigrenderer_generate_samples(sigrenderer, volume, delta, size, s);
- for (j = 0; j < sigrenderer->n_channels; j++)
- for (i = 0; i < rendered; i++)
- samples[j][i] += s[0][i*sigrenderer->n_channels+j];
- destroy_sample_buffer(s);
- return rendered;
-}
-
-
-
-/* DEPRECATED */
-long duh_render_signal(
- DUH_SIGRENDERER *sigrenderer,
- float volume, float delta,
- long size, sample_t **samples
-)
-{
- sample_t **s;
- long rendered;
- long i;
- int j;
- if (!samples) return duh_sigrenderer_generate_samples(sigrenderer, volume, delta, size, NULL);
- s = allocate_sample_buffer(sigrenderer->n_channels, size);
- if (!s) return 0;
- dumb_silence(s[0], sigrenderer->n_channels * size);
- rendered = duh_sigrenderer_generate_samples(sigrenderer, volume, delta, size, s);
- for (j = 0; j < sigrenderer->n_channels; j++)
- for (i = 0; i < rendered; i++)
- samples[j][i] += s[0][i*sigrenderer->n_channels+j] >> 8;
- destroy_sample_buffer(s);
- return rendered;
-}
-
-
-
-void duh_sigrenderer_get_current_sample(DUH_SIGRENDERER *sigrenderer, float volume, sample_t *samples)
-{
- if (sigrenderer)
- (*sigrenderer->desc->sigrenderer_get_current_sample)(sigrenderer->sigrenderer, volume, samples);
-}
-
-
-
-void duh_end_sigrenderer(DUH_SIGRENDERER *sigrenderer)
-{
- if (sigrenderer) {
- if (sigrenderer->desc->end_sigrenderer)
- if (sigrenderer->sigrenderer)
- (*sigrenderer->desc->end_sigrenderer)(sigrenderer->sigrenderer);
-
- free(sigrenderer);
- }
-}
-
-
-
-DUH_SIGRENDERER *duh_encapsulate_raw_sigrenderer(sigrenderer_t *vsigrenderer, DUH_SIGTYPE_DESC *desc, int n_channels, long pos)
-{
- DUH_SIGRENDERER *sigrenderer;
-
- if (desc->start_sigrenderer && !vsigrenderer) return NULL;
-
- sigrenderer = malloc(sizeof(*sigrenderer));
- if (!sigrenderer) {
- if (desc->end_sigrenderer)
- if (vsigrenderer)
- (*desc->end_sigrenderer)(vsigrenderer);
- return NULL;
- }
-
- sigrenderer->desc = desc;
- sigrenderer->sigrenderer = vsigrenderer;
-
- sigrenderer->n_channels = n_channels;
-
- sigrenderer->pos = pos;
- sigrenderer->subpos = 0;
-
- sigrenderer->callback = NULL;
-
- return sigrenderer;
-}
-
-
-
-sigrenderer_t *duh_get_raw_sigrenderer(DUH_SIGRENDERER *sigrenderer, long type)
-{
- if (sigrenderer && sigrenderer->desc->type == type)
- return sigrenderer->sigrenderer;
-
- return NULL;
-}
-
-
-
-#if 0
-// This function is disabled because we don't know whether we want to destroy
-// the sigrenderer if the type doesn't match. We don't even know if we need
-// the function at all. Who would want to keep an IT_SIGRENDERER (for
-// instance) without keeping the DUH_SIGRENDERER?
-sigrenderer_t *duh_decompose_to_raw_sigrenderer(DUH_SIGRENDERER *sigrenderer, long type)
-{
- if (sigrenderer && sigrenderer->desc->type == type) {
-
-
-
- if (sigrenderer) {
- if (sigrenderer->desc->end_sigrenderer)
- if (sigrenderer->sigrenderer)
- (*sigrenderer->desc->end_sigrenderer)(sigrenderer->sigrenderer);
-
- free(sigrenderer);
- }
-
-
-
-
-
-
- return sigrenderer->sigrenderer;
- }
-
- return NULL;
-}
-#endif
diff --git a/dumb/dumb-0.9.3/src/core/unload.c b/dumb/dumb-0.9.3/src/core/unload.c
deleted file mode 100644
index 11d81e26..00000000
--- a/dumb/dumb-0.9.3/src/core/unload.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * unload.c - Code to free a DUH from memory. / / \ \
- * | < / \_
- * By entheh. | \/ /\ /
- * \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <stdlib.h>
-
-#include "dumb.h"
-#include "internal/dumb.h"
-
-
-
-static void destroy_signal(DUH_SIGNAL *signal)
-{
- if (signal) {
- if (signal->desc)
- if (signal->desc->unload_sigdata)
- if (signal->sigdata)
- (*signal->desc->unload_sigdata)(signal->sigdata);
-
- free(signal);
- }
-}
-
-
-
-/* unload_duh(): destroys a DUH struct. You must call this for every DUH
- * struct created, when you've finished with it.
- */
-void unload_duh(DUH *duh)
-{
- int i;
-
- if (duh) {
- if (duh->signal) {
- for (i = 0; i < duh->n_signals; i++)
- destroy_signal(duh->signal[i]);
-
- free(duh->signal);
- }
-
- if (duh->tag) {
- if (duh->tag[0][0])
- free(duh->tag[0][0]);
- free(duh->tag);
- }
-
- free(duh);
- }
-}
diff --git a/dumb/dumb-0.9.3/src/helpers/clickrem.c b/dumb/dumb-0.9.3/src/helpers/clickrem.c
deleted file mode 100644
index 9109e324..00000000
--- a/dumb/dumb-0.9.3/src/helpers/clickrem.c
+++ /dev/null
@@ -1,281 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * clickrem.c - Click removal helpers. / / \ \
- * | < / \_
- * By entheh. | \/ /\ /
- * \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <stdlib.h>
-#include <math.h>
-#include "dumb.h"
-
-
-
-typedef struct DUMB_CLICK DUMB_CLICK;
-
-
-struct DUMB_CLICK_REMOVER
-{
- DUMB_CLICK *click;
- int n_clicks;
-
- int offset;
-};
-
-
-struct DUMB_CLICK
-{
- DUMB_CLICK *next;
- long pos;
- sample_t step;
-};
-
-
-
-DUMB_CLICK_REMOVER *dumb_create_click_remover(void)
-{
- DUMB_CLICK_REMOVER *cr = malloc(sizeof(*cr));
- if (!cr) return NULL;
-
- cr->click = NULL;
- cr->n_clicks = 0;
-
- cr->offset = 0;
-
- return cr;
-}
-
-
-
-void dumb_record_click(DUMB_CLICK_REMOVER *cr, long pos, sample_t step)
-{
- DUMB_CLICK *click;
-
- ASSERT(pos >= 0);
-
- if (!cr || !step) return;
-
- if (pos == 0) {
- cr->offset -= step;
- return;
- }
-
- click = malloc(sizeof(*click));
- if (!click) return;
-
- click->pos = pos;
- click->step = step;
-
- click->next = cr->click;
- cr->click = click;
- cr->n_clicks++;
-}
-
-
-
-static DUMB_CLICK *dumb_click_mergesort(DUMB_CLICK *click, int n_clicks)
-{
- int i;
- DUMB_CLICK *c1, *c2, **cp;
-
- if (n_clicks <= 1) return click;
-
- /* Split the list into two */
- c1 = click;
- cp = &c1;
- for (i = 0; i < n_clicks; i += 2) cp = &(*cp)->next;
- c2 = *cp;
- *cp = NULL;
-
- /* Sort the sublists */
- c1 = dumb_click_mergesort(c1, (n_clicks + 1) >> 1);
- c2 = dumb_click_mergesort(c2, n_clicks >> 1);
-
- /* Merge them */
- cp = &click;
- while (c1 && c2) {
- if (c1->pos > c2->pos) {
- *cp = c2;
- c2 = c2->next;
- } else {
- *cp = c1;
- c1 = c1->next;
- }
- cp = &(*cp)->next;
- }
- if (c2)
- *cp = c2;
- else
- *cp = c1;
-
- return click;
-}
-
-
-
-void dumb_remove_clicks(DUMB_CLICK_REMOVER *cr, sample_t *samples, long length, int step, float halflife)
-{
- DUMB_CLICK *click;
- long pos = 0;
- int offset;
- int factor;
-
- if (!cr) return;
-
- factor = (int)floor(pow(0.5, 1.0/halflife) * (1U << 31));
-
- click = dumb_click_mergesort(cr->click, cr->n_clicks);
- cr->click = NULL;
- cr->n_clicks = 0;
-
- length *= step;
-
- while (click) {
- DUMB_CLICK *next = click->next;
- int end = click->pos * step;
- ASSERT(end <= length);
- offset = cr->offset;
- if (offset < 0) {
- offset = -offset;
- while (pos < end) {
- samples[pos] -= offset;
- offset = (int)((LONG_LONG)(offset << 1) * factor >> 32);
- pos += step;
- }
- offset = -offset;
- } else {
- while (pos < end) {
- samples[pos] += offset;
- offset = (int)((LONG_LONG)(offset << 1) * factor >> 32);
- pos += step;
- }
- }
- cr->offset = offset - click->step;
- free(click);
- click = next;
- }
-
- offset = cr->offset;
- if (offset < 0) {
- offset = -offset;
- while (pos < length) {
- samples[pos] -= offset;
- offset = (int)((LONG_LONG)(offset << 1) * factor >> 32);
- pos += step;
- }
- offset = -offset;
- } else {
- while (pos < length) {
- samples[pos] += offset;
- offset = (int)((LONG_LONG)(offset << 1) * factor >> 32);
- pos += step;
- }
- }
- cr->offset = offset;
-}
-
-
-
-sample_t dumb_click_remover_get_offset(DUMB_CLICK_REMOVER *cr)
-{
- return cr ? cr->offset : 0;
-}
-
-
-
-void dumb_destroy_click_remover(DUMB_CLICK_REMOVER *cr)
-{
- if (cr) {
- DUMB_CLICK *click = cr->click;
- while (click) {
- DUMB_CLICK *next = click->next;
- free(click);
- click = next;
- }
- free(cr);
- }
-}
-
-
-
-DUMB_CLICK_REMOVER **dumb_create_click_remover_array(int n)
-{
- int i;
- DUMB_CLICK_REMOVER **cr;
- if (n <= 0) return NULL;
- cr = malloc(n * sizeof(*cr));
- if (!cr) return NULL;
- for (i = 0; i < n; i++) cr[i] = dumb_create_click_remover();
- return cr;
-}
-
-
-
-void dumb_record_click_array(int n, DUMB_CLICK_REMOVER **cr, long pos, sample_t *step)
-{
- if (cr) {
- int i;
- for (i = 0; i < n; i++)
- dumb_record_click(cr[i], pos, step[i]);
- }
-}
-
-
-
-void dumb_record_click_negative_array(int n, DUMB_CLICK_REMOVER **cr, long pos, sample_t *step)
-{
- if (cr) {
- int i;
- for (i = 0; i < n; i++)
- dumb_record_click(cr[i], pos, -step[i]);
- }
-}
-
-
-
-void dumb_remove_clicks_array(int n, DUMB_CLICK_REMOVER **cr, sample_t **samples, long length, float halflife)
-{
- if (cr) {
- int i;
- for (i = 0; i < n >> 1; i++) {
- dumb_remove_clicks(cr[i << 1], samples[i], length, 2, halflife);
- dumb_remove_clicks(cr[(i << 1) + 1], samples[i] + 1, length, 2, halflife);
- }
- if (n & 1)
- dumb_remove_clicks(cr[i << 1], samples[i], length, 1, halflife);
- }
-}
-
-
-
-void dumb_click_remover_get_offset_array(int n, DUMB_CLICK_REMOVER **cr, sample_t *offset)
-{
- if (cr) {
- int i;
- for (i = 0; i < n; i++)
- if (cr[i]) offset[i] += cr[i]->offset;
- }
-}
-
-
-
-void dumb_destroy_click_remover_array(int n, DUMB_CLICK_REMOVER **cr)
-{
- if (cr) {
- int i;
- for (i = 0; i < n; i++) dumb_destroy_click_remover(cr[i]);
- free(cr);
- }
-}
diff --git a/dumb/dumb-0.9.3/src/helpers/memfile.c b/dumb/dumb-0.9.3/src/helpers/memfile.c
deleted file mode 100644
index b65ab5f7..00000000
--- a/dumb/dumb-0.9.3/src/helpers/memfile.c
+++ /dev/null
@@ -1,96 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * memfile.c - Module for reading data from / / \ \
- * memory using a DUMBFILE. | < / \_
- * | \/ /\ /
- * By entheh. \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "dumb.h"
-
-
-
-typedef struct MEMFILE MEMFILE;
-
-struct MEMFILE
-{
- const char *ptr;
- long left;
-};
-
-
-
-static int dumb_memfile_skip(void *f, long n)
-{
- MEMFILE *m = f;
- if (n > m->left) return -1;
- m->ptr += n;
- m->left -= n;
- return 0;
-}
-
-
-
-static int dumb_memfile_getc(void *f)
-{
- MEMFILE *m = f;
- if (m->left <= 0) return -1;
- m->left--;
- return *(const unsigned char *)m->ptr++;
-}
-
-
-
-static long dumb_memfile_getnc(char *ptr, long n, void *f)
-{
- MEMFILE *m = f;
- if (n > m->left) n = m->left;
- memcpy(ptr, m->ptr, n);
- m->ptr += n;
- m->left -= n;
- return n;
-}
-
-
-
-static void dumb_memfile_close(void *f)
-{
- free(f);
-}
-
-
-
-static DUMBFILE_SYSTEM memfile_dfs = {
- NULL,
- &dumb_memfile_skip,
- &dumb_memfile_getc,
- &dumb_memfile_getnc,
- &dumb_memfile_close
-};
-
-
-
-DUMBFILE *dumbfile_open_memory(const char *data, long size)
-{
- MEMFILE *m = malloc(sizeof(*m));
- if (!m) return NULL;
-
- m->ptr = data;
- m->left = size;
-
- return dumbfile_open_ex(m, &memfile_dfs);
-}
diff --git a/dumb/dumb-0.9.3/src/helpers/resamp2.inc b/dumb/dumb-0.9.3/src/helpers/resamp2.inc
deleted file mode 100644
index 2619bd71..00000000
--- a/dumb/dumb-0.9.3/src/helpers/resamp2.inc
+++ /dev/null
@@ -1,134 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * resamp2.inc - Resampling helper template. / / \ \
- * | < / \_
- * By Bob and entheh. | \/ /\ /
- * \_ / > /
- * In order to find a good trade-off between | \ / /
- * speed and accuracy in this code, some tests | ' /
- * were carried out regarding the behaviour of \__/
- * long long ints with gcc. The following code
- * was tested:
- *
- * int a, b, c;
- * c = ((long long)a * b) >> 16;
- *
- * DJGPP GCC Version 3.0.3 generated the following assembly language code for
- * the multiplication and scaling, leaving the 32-bit result in EAX.
- *
- * movl -8(%ebp), %eax ; read one int into EAX
- * imull -4(%ebp) ; multiply by the other; result goes in EDX:EAX
- * shrdl $16, %edx, %eax ; shift EAX right 16, shifting bits in from EDX
- *
- * Note that a 32*32->64 multiplication is performed, allowing for high
- * accuracy. On the Pentium 2 and above, shrdl takes two cycles (generally),
- * so it is a minor concern when four multiplications are being performed
- * (the cubic resampler). On the Pentium MMX and earlier, it takes four or
- * more cycles, so this method is unsuitable for use in the low-quality
- * resamplers.
- *
- * Since "long long" is a gcc-specific extension, we use LONG_LONG instead,
- * defined in dumb.h. We may investigate later what code MSVC generates, but
- * if it seems too slow then we suggest you use a good compiler.
- *
- * FIXME: these comments are somewhat out of date now.
- */
-
-
-
-#define SUFFIX3 _1
-
-/* For convenience, returns nonzero on stop. */
-static int process_pickup(DUMB_RESAMPLER *resampler)
-{
- if (resampler->overshot < 0) {
- resampler->overshot = 0;
- dumb_resample(resampler, NULL, 2, MONO_DEST_VOLUME_ZEROS, 1.0f); /* Doesn't matter which SUFFIX3. */
- COPYSRC(resampler->X, 0, resampler->X, 1);
- }
-
- for (;;) {
- SRCTYPE *src = resampler->src;
-
- if (resampler->dir < 0) {
- if (resampler->overshot >= 3 && resampler->pos+3 >= resampler->start) COPYSRC(resampler->X, 0, src, resampler->pos+3);
- if (resampler->overshot >= 2 && resampler->pos+2 >= resampler->start) COPYSRC(resampler->X, 1, src, resampler->pos+2);
- if (resampler->overshot >= 1 && resampler->pos+1 >= resampler->start) COPYSRC(resampler->X, 2, src, resampler->pos+1);
- resampler->overshot = resampler->start - resampler->pos - 1;
- } else {
- if (resampler->overshot >= 3 && resampler->pos-3 < resampler->end) COPYSRC(resampler->X, 0, src, resampler->pos-3);
- if (resampler->overshot >= 2 && resampler->pos-2 < resampler->end) COPYSRC(resampler->X, 1, src, resampler->pos-2);
- if (resampler->overshot >= 1 && resampler->pos-1 < resampler->end) COPYSRC(resampler->X, 2, src, resampler->pos-1);
- resampler->overshot = resampler->pos - resampler->end;
- }
-
- if (resampler->overshot < 0) {
- resampler->overshot = 0;
- return 0;
- }
-
- if (!resampler->pickup) {
- resampler->dir = 0;
- return 1;
- }
- (*resampler->pickup)(resampler, resampler->pickup_data);
- if (resampler->dir == 0) return 1;
- ASSERT(resampler->dir == -1 || resampler->dir == 1);
- }
-}
-
-
-
-/* Create mono destination resampler. */
-/* SUFFIX3 was set above. */
-#define VOLUME_PARAMETERS MONO_DEST_VOLUME_PARAMETERS
-#define VOLUME_VARIABLES MONO_DEST_VOLUME_VARIABLES
-#define SET_VOLUME_VARIABLES SET_MONO_DEST_VOLUME_VARIABLES
-#define VOLUMES_ARE_ZERO MONO_DEST_VOLUMES_ARE_ZERO
-#define MIX_ALIAS(op, offset) MONO_DEST_MIX_ALIAS(op, offset)
-#define MIX_LINEAR(op, o0, o1) MONO_DEST_MIX_LINEAR(op, o0, o1)
-#define MIX_CUBIC(op, x0, x3, o0, o1, o2, o3) MONO_DEST_MIX_CUBIC(op, x0, x3, o0, o1, o2, o3)
-#define MIX_ZEROS(op) *dst++ op 0
-#include "resamp3.inc"
-
-/* Create stereo destination resampler. */
-#define SUFFIX3 _2
-#define VOLUME_PARAMETERS float volume_left, float volume_right
-#define VOLUME_VARIABLES lvol, rvol
-#define SET_VOLUME_VARIABLES { \
- lvol = (int)floor(volume_left * 65536.0 + 0.5); \
- rvol = (int)floor(volume_right * 65536.0 + 0.5); \
-}
-#define VOLUMES_ARE_ZERO (lvol == 0 && rvol == 0)
-#define MIX_ALIAS(op, offset) STEREO_DEST_MIX_ALIAS(op, offset)
-#define MIX_LINEAR(op, o0, o1) STEREO_DEST_MIX_LINEAR(op, o0, o1)
-#define MIX_CUBIC(op, x0, x3, o0, o1, o2, o3) STEREO_DEST_MIX_CUBIC(op, x0, x3, o0, o1, o2, o3)
-#define MIX_ZEROS(op) { *dst++ op 0; *dst++ op 0; }
-#include "resamp3.inc"
-
-
-
-#undef STEREO_DEST_MIX_CUBIC
-#undef MONO_DEST_MIX_CUBIC
-#undef STEREO_DEST_MIX_LINEAR
-#undef MONO_DEST_MIX_LINEAR
-#undef STEREO_DEST_MIX_ALIAS
-#undef MONO_DEST_MIX_ALIAS
-#undef MONO_DEST_VOLUMES_ARE_ZERO
-#undef SET_MONO_DEST_VOLUME_VARIABLES
-#undef MONO_DEST_VOLUME_ZEROS
-#undef MONO_DEST_VOLUME_VARIABLES
-#undef MONO_DEST_VOLUME_PARAMETERS
-#undef COPYSRC2
-#undef COPYSRC
-#undef DIVIDE_BY_SRC_CHANNELS
-#undef SRC_CHANNELS
-#undef SUFFIX2
diff --git a/dumb/dumb-0.9.3/src/helpers/resamp3.inc b/dumb/dumb-0.9.3/src/helpers/resamp3.inc
deleted file mode 100644
index 4bdada3d..00000000
--- a/dumb/dumb-0.9.3/src/helpers/resamp3.inc
+++ /dev/null
@@ -1,371 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * resamp3.inc - Resampling helper template. / / \ \
- * | < / \_
- * By Bob and entheh. | \/ /\ /
- * \_ / > /
- * In order to find a good trade-off between | \ / /
- * speed and accuracy in this code, some tests | ' /
- * were carried out regarding the behaviour of \__/
- * long long ints with gcc. The following code
- * was tested:
- *
- * int a, b, c;
- * c = ((long long)a * b) >> 16;
- *
- * DJGPP GCC Version 3.0.3 generated the following assembly language code for
- * the multiplication and scaling, leaving the 32-bit result in EAX.
- *
- * movl -8(%ebp), %eax ; read one int into EAX
- * imull -4(%ebp) ; multiply by the other; result goes in EDX:EAX
- * shrdl $16, %edx, %eax ; shift EAX right 16, shifting bits in from EDX
- *
- * Note that a 32*32->64 multiplication is performed, allowing for high
- * accuracy. On the Pentium 2 and above, shrdl takes two cycles (generally),
- * so it is a minor concern when four multiplications are being performed
- * (the cubic resampler). On the Pentium MMX and earlier, it takes four or
- * more cycles, so this method is unsuitable for use in the low-quality
- * resamplers.
- *
- * Since "long long" is a gcc-specific extension, we use LONG_LONG instead,
- * defined in dumb.h. We may investigate later what code MSVC generates, but
- * if it seems too slow then we suggest you use a good compiler.
- *
- * FIXME: these comments are somewhat out of date now.
- */
-
-
-
-long dumb_resample(DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, VOLUME_PARAMETERS, float delta)
-{
- int dt;
- int VOLUME_VARIABLES;
- long done;
- long todo;
- int quality;
-
- if (!resampler || resampler->dir == 0) return 0;
- ASSERT(resampler->dir == -1 || resampler->dir == 1);
-
- done = 0;
- dt = (int)(delta * 65536.0 + 0.5);
- SET_VOLUME_VARIABLES;
-
- if (VOLUMES_ARE_ZERO) dst = NULL;
-
- init_cubic();
-
- quality = dumb_resampling_quality;
- if (quality > resampler->max_quality) quality = resampler->max_quality;
- else if (quality < resampler->min_quality) quality = resampler->min_quality;
-
- while (done < dst_size) {
- if (process_pickup(resampler)) return done;
-
- if ((resampler->dir ^ dt) < 0)
- dt = -dt;
-
- if (resampler->dir < 0)
- todo = (long)((((LONG_LONG)(resampler->pos - resampler->start) << 16) + resampler->subpos - dt) / -dt);
- else
- todo = (long)((((LONG_LONG)(resampler->end - resampler->pos) << 16) - resampler->subpos - 1 + dt) / dt);
-
- if (todo < 0)
- todo = 0;
- else if (todo > dst_size - done)
- todo = dst_size - done;
-
- done += todo;
-
- {
- SRCTYPE *src = resampler->src;
- long pos = resampler->pos;
- int subpos = resampler->subpos;
- long diff = pos;
- long overshot;
- if (resampler->dir < 0) {
- if (!dst) {
- /* Silence or simulation */
- LONG_LONG new_subpos = subpos + (LONG_LONG)dt * todo;
- pos += (long)(new_subpos >> 16);
- subpos = (long)new_subpos & 65535;
- } else if (quality <= DUMB_RQ_ALIASING) {
- /* Aliasing, backwards */
- 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]) {
- // TODO: check what happens when multiple tempo slides occur per row
- HEAVYASSERT(pos >= resampler->start);
- MIX_ALIAS(+=, 0);
- subpos += dt;
- pos += subpos >> 16;
- x -= (subpos >> 16) * SRC_CHANNELS;
- subpos &= 65535;
- todo--;
- }
- x = xstart = &src[pos*SRC_CHANNELS];
- LOOP4(todo,
- MIX_ALIAS(+=, 2);
- subpos += dt;
- x += (subpos >> 16) * SRC_CHANNELS;
- subpos &= 65535;
- );
- pos += DIVIDE_BY_SRC_CHANNELS(x - xstart);
- } else if (quality <= DUMB_RQ_LINEAR) {
- /* Linear interpolation, backwards */
- SRCTYPE xbuf[3*SRC_CHANNELS];
- SRCTYPE *x = &xbuf[1*SRC_CHANNELS];
- COPYSRC(xbuf, 0, resampler->X, 1);
- COPYSRC(xbuf, 1, resampler->X, 2);
- COPYSRC(xbuf, 2, src, pos);
- while (todo && x < &xbuf[3*SRC_CHANNELS]) {
- HEAVYASSERT(pos >= resampler->start);
- MIX_LINEAR(+=, 0, -1);
- subpos += dt;
- pos += subpos >> 16;
- x -= (subpos >> 16) * SRC_CHANNELS;
- subpos &= 65535;
- todo--;
- }
- // TODO: use xstart for others too
- x = &src[pos*SRC_CHANNELS];
- LOOP4(todo,
- HEAVYASSERT(pos >= resampler->start);
- MIX_LINEAR(+=, 1, 2);
- subpos += dt;
- pos += subpos >> 16;
- x += (subpos >> 16) * SRC_CHANNELS;
- subpos &= 65535;
- );
- } else {
- /* Cubic interpolation, backwards */
- SRCTYPE xbuf[6*SRC_CHANNELS];
- SRCTYPE *x = &xbuf[3*SRC_CHANNELS];
- COPYSRC(xbuf, 0, resampler->X, 0);
- COPYSRC(xbuf, 1, resampler->X, 1);
- COPYSRC(xbuf, 2, resampler->X, 2);
- COPYSRC(xbuf, 3, src, pos);
- if (pos-1 >= resampler->start) COPYSRC(xbuf, 4, src, pos-1);
- if (pos-2 >= resampler->start) COPYSRC(xbuf, 5, src, pos-2);
- while (todo && x < &xbuf[6*SRC_CHANNELS]) {
- HEAVYASSERT(pos >= resampler->start);
- MIX_CUBIC(+=, x, x, 0, -1, -2, -3);
- subpos += dt;
- pos += subpos >> 16;
- x -= (subpos >> 16) * SRC_CHANNELS;
- subpos &= 65535;
- todo--;
- }
- x = &src[pos*SRC_CHANNELS];
- LOOP4(todo,
- HEAVYASSERT(pos >= resampler->start);
- MIX_CUBIC(+=, x, x, 0, 1, 2, 3);
- subpos += dt;
- pos += subpos >> 16;
- x += (subpos >> 16) * SRC_CHANNELS;
- subpos &= 65535;
- );
- }
- diff = diff - pos;
- overshot = resampler->start - pos - 1;
- if (diff >= 3) {
- COPYSRC2(resampler->X, 0, overshot < 3, src, pos+3);
- COPYSRC2(resampler->X, 1, overshot < 2, src, pos+2);
- COPYSRC2(resampler->X, 2, overshot < 1, src, pos+1);
- } else if (diff >= 2) {
- COPYSRC(resampler->X, 0, resampler->X, 2);
- COPYSRC2(resampler->X, 1, overshot < 2, src, pos+2);
- COPYSRC2(resampler->X, 2, overshot < 1, src, pos+1);
- } else if (diff >= 1) {
- COPYSRC(resampler->X, 0, resampler->X, 1);
- COPYSRC(resampler->X, 1, resampler->X, 2);
- COPYSRC2(resampler->X, 2, overshot < 1, src, pos+1);
- }
- } else {
- if (!dst) {
- /* Silence or simulation */
- LONG_LONG new_subpos = subpos + (LONG_LONG)dt * todo;
- pos += (long)(new_subpos >> 16);
- subpos = (long)new_subpos & 65535;
- } else if (dumb_resampling_quality <= DUMB_RQ_ALIASING) {
- /* Aliasing, forwards */
- 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]) {
- HEAVYASSERT(pos < resampler->end);
- MIX_ALIAS(+=, 0);
- subpos += dt;
- pos += subpos >> 16;
- x += (subpos >> 16) * SRC_CHANNELS;
- subpos &= 65535;
- todo--;
- }
- x = xstart = &src[pos*SRC_CHANNELS];
- LOOP4(todo,
- MIX_ALIAS(+=, -2);
- subpos += dt;
- x += (subpos >> 16) * SRC_CHANNELS;
- subpos &= 65535;
- );
- pos += DIVIDE_BY_SRC_CHANNELS(x - xstart);
- } else if (dumb_resampling_quality <= DUMB_RQ_LINEAR) {
- /* Linear interpolation, forwards */
- SRCTYPE xbuf[3*SRC_CHANNELS];
- SRCTYPE *x = &xbuf[1*SRC_CHANNELS];
- COPYSRC(xbuf, 0, resampler->X, 1);
- COPYSRC(xbuf, 1, resampler->X, 2);
- COPYSRC(xbuf, 2, src, pos);
- while (todo && x < &xbuf[3*SRC_CHANNELS]) {
- HEAVYASSERT(pos < resampler->end);
- MIX_LINEAR(+=, -1, 0);
- subpos += dt;
- pos += subpos >> 16;
- x += (subpos >> 16) * SRC_CHANNELS;
- subpos &= 65535;
- todo--;
- }
- x = &src[pos*SRC_CHANNELS];
- LOOP4(todo,
- HEAVYASSERT(pos < resampler->end);
- MIX_LINEAR(+=, -2, -1);
- subpos += dt;
- pos += subpos >> 16;
- x += (subpos >> 16) * SRC_CHANNELS;
- subpos &= 65535;
- );
- } else {
- /* Cubic interpolation, forwards */
- SRCTYPE xbuf[6*SRC_CHANNELS];
- SRCTYPE *x = &xbuf[3*SRC_CHANNELS];
- COPYSRC(xbuf, 0, resampler->X, 0);
- COPYSRC(xbuf, 1, resampler->X, 1);
- COPYSRC(xbuf, 2, resampler->X, 2);
- COPYSRC(xbuf, 3, src, pos);
- if (pos+1 < resampler->end) COPYSRC(xbuf, 4, src, pos+1);
- if (pos+2 < resampler->end) COPYSRC(xbuf, 5, src, pos+2);
- while (todo && x < &xbuf[6*SRC_CHANNELS]) {
- HEAVYASSERT(pos < resampler->end);
- MIX_CUBIC(+=, x, x, -3, -2, -1, 0);
- subpos += dt;
- pos += subpos >> 16;
- x += (subpos >> 16) * SRC_CHANNELS;
- subpos &= 65535;
- todo--;
- }
- x = &src[pos*SRC_CHANNELS];
- LOOP4(todo,
- HEAVYASSERT(pos < resampler->end);
- MIX_CUBIC(+=, x, x, -3, -2, -1, 0);
- subpos += dt;
- pos += subpos >> 16;
- x += (subpos >> 16) * SRC_CHANNELS;
- subpos &= 65535;
- );
- }
- diff = pos - diff;
- overshot = pos - resampler->end;
- if (diff >= 3) {
- COPYSRC2(resampler->X, 0, overshot < 3, src, pos-3);
- COPYSRC2(resampler->X, 1, overshot < 2, src, pos-2);
- COPYSRC2(resampler->X, 2, overshot < 1, src, pos-1);
- } else if (diff >= 2) {
- COPYSRC(resampler->X, 0, resampler->X, 2);
- COPYSRC2(resampler->X, 1, overshot < 2, src, pos-2);
- COPYSRC2(resampler->X, 2, overshot < 1, src, pos-1);
- } else if (diff >= 1) {
- COPYSRC(resampler->X, 0, resampler->X, 1);
- COPYSRC(resampler->X, 1, resampler->X, 2);
- COPYSRC2(resampler->X, 2, overshot < 1, src, pos-1);
- }
- }
- resampler->pos = pos;
- resampler->subpos = subpos;
- }
- }
-
- return done;
-}
-
-
-
-void dumb_resample_get_current_sample(DUMB_RESAMPLER *resampler, VOLUME_PARAMETERS, sample_t *dst)
-{
- int VOLUME_VARIABLES;
- SRCTYPE *src;
- long pos;
- int subpos;
- int quality;
- SRCTYPE *x;
-
- if (!resampler || resampler->dir == 0) { MIX_ZEROS(=); return; }
- ASSERT(resampler->dir == -1 || resampler->dir == 1);
-
- if (process_pickup(resampler)) { MIX_ZEROS(=); return; }
-
- SET_VOLUME_VARIABLES;
-
- if (VOLUMES_ARE_ZERO) { MIX_ZEROS(=); return; }
-
- init_cubic();
-
- quality = dumb_resampling_quality;
- if (quality > resampler->max_quality) quality = resampler->max_quality;
- else if (quality < resampler->min_quality) quality = resampler->min_quality;
-
- src = resampler->src;
- pos = resampler->pos;
- subpos = resampler->subpos;
- x = resampler->X;
-
- if (resampler->dir < 0) {
- HEAVYASSERT(pos >= resampler->start);
- if (dumb_resampling_quality <= 0) {
- /* Aliasing, backwards */
- MIX_ALIAS(=, 1);
- } else if (quality <= DUMB_RQ_LINEAR) {
- /* Linear interpolation, backwards */
- MIX_LINEAR(=, 2, 1);
- } else {
- /* Cubic interpolation, backwards */
- MIX_CUBIC(=, src, x, pos, 2, 1, 0);
- }
- } else {
- HEAVYASSERT(pos < resampler->end);
- if (dumb_resampling_quality <= 0) {
- /* Aliasing */
- MIX_ALIAS(=, 1);
- } else if (dumb_resampling_quality <= DUMB_RQ_LINEAR) {
- /* Linear interpolation, forwards */
- MIX_LINEAR(=, 1, 2);
- } else {
- /* Cubic interpolation, forwards */
- MIX_CUBIC(=, x, src, 0, 1, 2, pos);
- }
- }
-}
-
-
-
-#undef MIX_ZEROS
-#undef MIX_CUBIC
-#undef MIX_LINEAR
-#undef MIX_ALIAS
-#undef VOLUMES_ARE_ZERO
-#undef SET_VOLUME_VARIABLES
-#undef VOLUME_VARIABLES
-#undef VOLUME_PARAMETERS
-#undef SUFFIX3
diff --git a/dumb/dumb-0.9.3/src/helpers/resample.c b/dumb/dumb-0.9.3/src/helpers/resample.c
deleted file mode 100644
index 3baafd0d..00000000
--- a/dumb/dumb-0.9.3/src/helpers/resample.c
+++ /dev/null
@@ -1,385 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * resample.c - Resampling helpers. / / \ \
- * | < / \_
- * By Bob and entheh. | \/ /\ /
- * \_ / > /
- * In order to find a good trade-off between | \ / /
- * speed and accuracy in this code, some tests | ' /
- * were carried out regarding the behaviour of \__/
- * long long ints with gcc. The following code
- * was tested:
- *
- * int a, b, c;
- * c = ((long long)a * b) >> 16;
- *
- * DJGPP GCC Version 3.0.3 generated the following assembly language code for
- * the multiplication and scaling, leaving the 32-bit result in EAX.
- *
- * movl -8(%ebp), %eax ; read one int into EAX
- * imull -4(%ebp) ; multiply by the other; result goes in EDX:EAX
- * shrdl $16, %edx, %eax ; shift EAX right 16, shifting bits in from EDX
- *
- * Note that a 32*32->64 multiplication is performed, allowing for high
- * accuracy. On the Pentium 2 and above, shrdl takes two cycles (generally),
- * so it is a minor concern when four multiplications are being performed
- * (the cubic resampler). On the Pentium MMX and earlier, it takes four or
- * more cycles, so this method is unsuitable for use in the low-quality
- * resamplers.
- *
- * Since "long long" is a gcc-specific extension, we use LONG_LONG instead,
- * defined in dumb.h. We may investigate later what code MSVC generates, but
- * if it seems too slow then we suggest you use a good compiler.
- *
- * FIXME: these comments are somewhat out of date now.
- */
-
-#include <math.h>
-#include "dumb.h"
-
-
-
-/* Compile with -DHEAVYDEBUG if you want to make sure the pick-up function is
- * called when it should be. There will be a considerable performance hit,
- * since at least one condition has to be tested for every sample generated.
- */
-#ifdef HEAVYDEBUG
-#define HEAVYASSERT(cond) ASSERT(cond)
-#else
-#define HEAVYASSERT(cond)
-#endif
-
-
-
-/* A global variable for controlling resampling quality wherever a local
- * specification doesn't override it. The following values are valid:
- *
- * 0 - DUMB_RQ_ALIASING - fastest
- * 1 - DUMB_RQ_LINEAR
- * 2 - DUMB_RQ_CUBIC - nicest
- *
- * Values outside the range 0-2 will behave the same as the nearest
- * value within the range.
- */
-int dumb_resampling_quality = DUMB_RQ_CUBIC;
-
-
-
-//#define MULSC(a, b) ((int)((LONG_LONG)(a) * (b) >> 16))
-//#define MULSC(a, b) ((a) * ((b) >> 2) >> 14)
-#define MULSC(a, b) ((int)((LONG_LONG)((a) << 4) * ((b) << 12) >> 32))
-#define MULSC16(a, b) ((int)((LONG_LONG)((a) << 12) * ((b) << 12) >> 32))
-
-
-
-/* Executes the content 'iterator' times.
- * Clobbers the 'iterator' variable.
- * The loop is unrolled by four.
- */
-#define LOOP4(iterator, CONTENT) \
-{ \
- if ((iterator) & 2) { \
- CONTENT; \
- CONTENT; \
- } \
- if ((iterator) & 1) { \
- CONTENT; \
- } \
- (iterator) >>= 2; \
- while (iterator) { \
- CONTENT; \
- CONTENT; \
- CONTENT; \
- CONTENT; \
- (iterator)--; \
- } \
-}
-
-
-
-#define PASTERAW(a, b) a ## b /* This does not expand macros in b ... */
-#define PASTE(a, b) PASTERAW(a, b) /* ... but b is expanded during this substitution. */
-
-#define X PASTE(x.x, SRCBITS)
-
-
-
-/* Cubic resampler: look-up tables
- *
- * a = 1.5*x1 - 1.5*x2 + 0.5*x3 - 0.5*x0
- * b = 2*x2 + x0 - 2.5*x1 - 0.5*x3
- * c = 0.5*x2 - 0.5*x0
- * d = x1
- *
- * x = a*t*t*t + b*t*t + c*t + d
- * = (-0.5*x0 + 1.5*x1 - 1.5*x2 + 0.5*x3) * t*t*t +
- * ( 1*x0 - 2.5*x1 + 2 *x2 - 0.5*x3) * t*t +
- * (-0.5*x0 + 0.5*x2 ) * t +
- * ( 1*x1 )
- * = (-0.5*t*t*t + 1 *t*t - 0.5*t ) * x0 +
- * ( 1.5*t*t*t - 2.5*t*t + 1) * x1 +
- * (-1.5*t*t*t + 2 *t*t + 0.5*t ) * x2 +
- * ( 0.5*t*t*t - 0.5*t*t ) * x3
- * = A0(t) * x0 + A1(t) * x1 + A2(t) * x2 + A3(t) * x3
- *
- * A0, A1, A2 and A3 stay within the range [-1,1].
- * In the tables, they are scaled with 14 fractional bits.
- *
- * Turns out we don't need to store A2 and A3; they are symmetrical to A1 and A0.
- *
- * TODO: A0 and A3 stay very small indeed. Consider different scale/resolution?
- */
-
-static short cubicA0[1025], cubicA1[1025];
-
-static void init_cubic(void)
-{
- unsigned int t; /* 3*1024*1024*1024 is within range if it's unsigned */
- static int done = 0;
- if (done) return;
- done = 1;
- for (t = 0; t < 1025; t++) {
- /* int casts to pacify warnings about negating unsigned values */
- cubicA0[t] = -(int)( t*t*t >> 17) + (int)( t*t >> 6) - (int)(t << 3);
- cubicA1[t] = (int)(3*t*t*t >> 17) - (int)(5*t*t >> 7) + (int)(1 << 14);
- }
-}
-
-
-
-/* Create resamplers for 24-in-32-bit source samples. */
-
-/* #define SUFFIX
- * MSVC warns if we try to paste a null SUFFIX, so instead we define
- * special macros for the function names that don't bother doing the
- * corresponding paste. The more generic definitions are further down.
- */
-#define process_pickup PASTE(process_pickup, SUFFIX2)
-#define dumb_resample PASTE(PASTE(dumb_resample, SUFFIX2), SUFFIX3)
-#define dumb_resample_get_current_sample PASTE(PASTE(dumb_resample_get_current_sample, SUFFIX2), SUFFIX3)
-
-#define SRCTYPE sample_t
-#define SRCBITS 24
-#define ALIAS(x, vol) MULSC(x, vol)
-#define LINEAR(x0, x1) (x0 + MULSC(x1 - x0, subpos))
-/*
-#define SET_CUBIC_COEFFICIENTS(x0, x1, x2, x3) { \
- a = (3 * (x1 - x2) + (x3 - x0)) >> 1; \
- b = ((x2 << 2) + (x0 << 1) - (5 * x1 + x3)) >> 1; \
- c = (x2 - x0) >> 1; \
-}
-#define CUBIC(d) MULSC(MULSC(MULSC(MULSC(a, subpos) + b, subpos) + c, subpos) + d, vol)
-*/
-#define CUBIC(x0, x1, x2, x3) ( \
- MULSC(x0, cubicA0[subpos >> 6] << 2) + \
- MULSC(x1, cubicA1[subpos >> 6] << 2) + \
- MULSC(x2, cubicA1[1 + (subpos >> 6 ^ 1023)] << 2) + \
- MULSC(x3, cubicA0[1 + (subpos >> 6 ^ 1023)] << 2))
-#define CUBICVOL(x, vol) MULSC(x, vol)
-#include "resample.inc"
-
-/* Undefine the simplified macros. */
-#undef dumb_resample_get_current_sample
-#undef dumb_resample
-#undef process_pickup
-
-
-/* Now define the proper ones that use SUFFIX. */
-#define dumb_reset_resampler PASTE(dumb_reset_resampler, SUFFIX)
-#define dumb_start_resampler PASTE(dumb_start_resampler, SUFFIX)
-#define process_pickup PASTE(PASTE(process_pickup, SUFFIX), SUFFIX2)
-#define dumb_resample PASTE(PASTE(PASTE(dumb_resample, SUFFIX), SUFFIX2), SUFFIX3)
-#define dumb_resample_get_current_sample PASTE(PASTE(PASTE(dumb_resample_get_current_sample, SUFFIX), SUFFIX2), SUFFIX3)
-#define dumb_end_resampler PASTE(dumb_end_resampler, SUFFIX)
-
-/* Create resamplers for 16-bit source samples. */
-#define SUFFIX _16
-#define SRCTYPE short
-#define SRCBITS 16
-#define ALIAS(x, vol) (x * vol >> 8)
-#define LINEAR(x0, x1) ((x0 << 8) + MULSC16(x1 - x0, subpos))
-/*
-#define SET_CUBIC_COEFFICIENTS(x0, x1, x2, x3) { \
- a = (3 * (x1 - x2) + (x3 - x0)) << 7; \
- b = ((x2 << 2) + (x0 << 1) - (5 * x1 + x3)) << 7; \
- c = (x2 - x0) << 7; \
-}
-#define CUBIC(d) MULSC(MULSC(MULSC(MULSC(a, subpos) + b, subpos) + c, subpos) + (d << 8), vol)
-*/
-#define CUBIC(x0, x1, x2, x3) ( \
- x0 * cubicA0[subpos >> 6] + \
- x1 * cubicA1[subpos >> 6] + \
- x2 * cubicA1[1 + (subpos >> 6 ^ 1023)] + \
- x3 * cubicA0[1 + (subpos >> 6 ^ 1023)])
-#define CUBICVOL(x, vol) (int)((LONG_LONG)(x) * (vol << 10) >> 32)
-#include "resample.inc"
-
-/* Create resamplers for 8-bit source samples. */
-#define SUFFIX _8
-#define SRCTYPE signed char
-#define SRCBITS 8
-#define ALIAS(x, vol) (x * vol)
-#define LINEAR(x0, x1) ((x0 << 16) + (x1 - x0) * subpos)
-/*
-#define SET_CUBIC_COEFFICIENTS(x0, x1, x2, x3) { \
- a = 3 * (x1 - x2) + (x3 - x0); \
- b = ((x2 << 2) + (x0 << 1) - (5 * x1 + x3)) << 15; \
- c = (x2 - x0) << 15; \
-}
-#define CUBIC(d) MULSC(MULSC(MULSC((a * subpos >> 1) + b, subpos) + c, subpos) + (d << 16), vol)
-*/
-#define CUBIC(x0, x1, x2, x3) (( \
- x0 * cubicA0[subpos >> 6] + \
- x1 * cubicA1[subpos >> 6] + \
- x2 * cubicA1[1 + (subpos >> 6 ^ 1023)] + \
- x3 * cubicA0[1 + (subpos >> 6 ^ 1023)]) << 6)
-#define CUBICVOL(x, vol) (int)((LONG_LONG)(x) * (vol << 12) >> 32)
-#include "resample.inc"
-
-
-#undef dumb_reset_resampler
-#undef dumb_start_resampler
-#undef process_pickup
-#undef dumb_resample
-#undef dumb_resample_get_current_sample
-#undef dumb_end_resampler
-
-
-
-void dumb_reset_resampler_n(int n, DUMB_RESAMPLER *resampler, void *src, int src_channels, long pos, long start, long end)
-{
- if (n == 8)
- dumb_reset_resampler_8(resampler, src, src_channels, pos, start, end);
- else if (n == 16)
- dumb_reset_resampler_16(resampler, src, src_channels, pos, start, end);
- else
- dumb_reset_resampler(resampler, src, src_channels, pos, start, end);
-}
-
-
-
-DUMB_RESAMPLER *dumb_start_resampler_n(int n, void *src, int src_channels, long pos, long start, long end)
-{
- if (n == 8)
- return dumb_start_resampler_8(src, src_channels, pos, start, end);
- else if (n == 16)
- return dumb_start_resampler_16(src, src_channels, pos, start, end);
- else
- return dumb_start_resampler(src, src_channels, pos, start, end);
-}
-
-
-
-long dumb_resample_n_1_1(int n, DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, float volume, float delta)
-{
- if (n == 8)
- return dumb_resample_8_1_1(resampler, dst, dst_size, volume, delta);
- else if (n == 16)
- return dumb_resample_16_1_1(resampler, dst, dst_size, volume, delta);
- else
- return dumb_resample_1_1(resampler, dst, dst_size, volume, delta);
-}
-
-
-
-long dumb_resample_n_1_2(int n, DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, float volume_left, float volume_right, float delta)
-{
- if (n == 8)
- return dumb_resample_8_1_2(resampler, dst, dst_size, volume_left, volume_right, delta);
- else if (n == 16)
- return dumb_resample_16_1_2(resampler, dst, dst_size, volume_left, volume_right, delta);
- else
- return dumb_resample_1_2(resampler, dst, dst_size, volume_left, volume_right, delta);
-}
-
-
-
-long dumb_resample_n_2_1(int n, DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, float volume_left, float volume_right, float delta)
-{
- if (n == 8)
- return dumb_resample_8_2_1(resampler, dst, dst_size, volume_left, volume_right, delta);
- else if (n == 16)
- return dumb_resample_16_2_1(resampler, dst, dst_size, volume_left, volume_right, delta);
- else
- return dumb_resample_2_1(resampler, dst, dst_size, volume_left, volume_right, delta);
-}
-
-
-
-long dumb_resample_n_2_2(int n, DUMB_RESAMPLER *resampler, sample_t *dst, long dst_size, float volume_left, float volume_right, float delta)
-{
- if (n == 8)
- return dumb_resample_8_2_2(resampler, dst, dst_size, volume_left, volume_right, delta);
- else if (n == 16)
- return dumb_resample_16_2_2(resampler, dst, dst_size, volume_left, volume_right, delta);
- else
- return dumb_resample_2_2(resampler, dst, dst_size, volume_left, volume_right, delta);
-}
-
-
-
-void dumb_resample_get_current_sample_n_1_1(int n, DUMB_RESAMPLER *resampler, float volume, sample_t *dst)
-{
- if (n == 8)
- dumb_resample_get_current_sample_8_1_1(resampler, volume, dst);
- else if (n == 16)
- dumb_resample_get_current_sample_16_1_1(resampler, volume, dst);
- else
- dumb_resample_get_current_sample_1_1(resampler, volume, dst);
-}
-
-
-
-void dumb_resample_get_current_sample_n_1_2(int n, DUMB_RESAMPLER *resampler, float volume_left, float volume_right, sample_t *dst)
-{
- if (n == 8)
- dumb_resample_get_current_sample_8_1_2(resampler, volume_left, volume_right, dst);
- else if (n == 16)
- dumb_resample_get_current_sample_16_1_2(resampler, volume_left, volume_right, dst);
- else
- dumb_resample_get_current_sample_1_2(resampler, volume_left, volume_right, dst);
-}
-
-
-
-void dumb_resample_get_current_sample_n_2_1(int n, DUMB_RESAMPLER *resampler, float volume_left, float volume_right, sample_t *dst)
-{
- if (n == 8)
- dumb_resample_get_current_sample_8_2_1(resampler, volume_left, volume_right, dst);
- else if (n == 16)
- dumb_resample_get_current_sample_16_2_1(resampler, volume_left, volume_right, dst);
- else
- dumb_resample_get_current_sample_2_1(resampler, volume_left, volume_right, dst);
-}
-
-
-
-void dumb_resample_get_current_sample_n_2_2(int n, DUMB_RESAMPLER *resampler, float volume_left, float volume_right, sample_t *dst)
-{
- if (n == 8)
- dumb_resample_get_current_sample_8_2_2(resampler, volume_left, volume_right, dst);
- else if (n == 16)
- dumb_resample_get_current_sample_16_2_2(resampler, volume_left, volume_right, dst);
- else
- dumb_resample_get_current_sample_2_2(resampler, volume_left, volume_right, dst);
-}
-
-
-
-void dumb_end_resampler_n(int n, DUMB_RESAMPLER *resampler)
-{
- if (n == 8)
- dumb_end_resampler_8(resampler);
- else if (n == 16)
- dumb_end_resampler_16(resampler);
- else
- dumb_end_resampler(resampler);
-}
diff --git a/dumb/dumb-0.9.3/src/helpers/resample.inc b/dumb/dumb-0.9.3/src/helpers/resample.inc
deleted file mode 100644
index 7a80423a..00000000
--- a/dumb/dumb-0.9.3/src/helpers/resample.inc
+++ /dev/null
@@ -1,167 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * resample.inc - Resampling helper template. / / \ \
- * | < / \_
- * By Bob and entheh. | \/ /\ /
- * \_ / > /
- * In order to find a good trade-off between | \ / /
- * speed and accuracy in this code, some tests | ' /
- * were carried out regarding the behaviour of \__/
- * long long ints with gcc. The following code
- * was tested:
- *
- * int a, b, c;
- * c = ((long long)a * b) >> 16;
- *
- * DJGPP GCC Version 3.0.3 generated the following assembly language code for
- * the multiplication and scaling, leaving the 32-bit result in EAX.
- *
- * movl -8(%ebp), %eax ; read one int into EAX
- * imull -4(%ebp) ; multiply by the other; result goes in EDX:EAX
- * shrdl $16, %edx, %eax ; shift EAX right 16, shifting bits in from EDX
- *
- * Note that a 32*32->64 multiplication is performed, allowing for high
- * accuracy. On the Pentium 2 and above, shrdl takes two cycles (generally),
- * so it is a minor concern when four multiplications are being performed
- * (the cubic resampler). On the Pentium MMX and earlier, it takes four or
- * more cycles, so this method is unsuitable for use in the low-quality
- * resamplers.
- *
- * Since "long long" is a gcc-specific extension, we use LONG_LONG instead,
- * defined in dumb.h. We may investigate later what code MSVC generates, but
- * if it seems too slow then we suggest you use a good compiler.
- *
- * FIXME: these comments are somewhat out of date now.
- */
-
-
-
-void dumb_reset_resampler(DUMB_RESAMPLER *resampler, SRCTYPE *src, int src_channels, long pos, long start, long end)
-{
- int i;
- resampler->src = src;
- resampler->pos = pos;
- resampler->subpos = 0;
- resampler->start = start;
- resampler->end = end;
- resampler->dir = 1;
- resampler->pickup = NULL;
- resampler->pickup_data = NULL;
- resampler->min_quality = 0;
- resampler->max_quality = DUMB_RQ_N_LEVELS - 1;
- for (i = 0; i < src_channels*3; i++) resampler->X[i] = 0;
- resampler->overshot = -1;
-}
-
-
-
-DUMB_RESAMPLER *dumb_start_resampler(SRCTYPE *src, int src_channels, long pos, long start, long end)
-{
- DUMB_RESAMPLER *resampler = malloc(sizeof(*resampler));
- if (!resampler) return NULL;
- dumb_reset_resampler(resampler, src, src_channels, pos, start, end);
- return resampler;
-}
-
-
-
-/* Create mono source resampler. */
-#define SUFFIX2 _1
-#define SRC_CHANNELS 1
-#define DIVIDE_BY_SRC_CHANNELS(x) (x)
-#define COPYSRC(dstarray, dstindex, srcarray, srcindex) (dstarray)[dstindex] = (srcarray)[srcindex]
-#define COPYSRC2(dstarray, dstindex, condition, srcarray, srcindex) (dstarray)[dstindex] = condition ? (srcarray)[srcindex] : 0
-#define MONO_DEST_VOLUME_PARAMETERS float volume
-#define MONO_DEST_VOLUME_VARIABLES vol
-#define MONO_DEST_VOLUME_ZEROS 0
-#define SET_MONO_DEST_VOLUME_VARIABLES vol = (int)floor(volume * 65536.0 + 0.5)
-#define MONO_DEST_VOLUMES_ARE_ZERO (vol == 0)
-#define MONO_DEST_MIX_ALIAS(op, offset) *dst++ op ALIAS(x[offset], vol)
-#define STEREO_DEST_MIX_ALIAS(op, offset) { \
- int xm = x[offset]; \
- *dst++ op ALIAS(xm, lvol); \
- *dst++ op ALIAS(xm, rvol); \
-}
-#define MONO_DEST_MIX_LINEAR(op, o0, o1) *dst++ op MULSC(LINEAR(x[o0], x[o1]), vol)
-#define STEREO_DEST_MIX_LINEAR(op, o0, o1) { \
- int xm = LINEAR(x[o0], x[o1]); \
- *dst++ op MULSC(xm, lvol); \
- *dst++ op MULSC(xm, rvol); \
-}
-#define MONO_DEST_MIX_CUBIC(op, x0, x3, o0, o1, o2, o3) *dst++ op CUBICVOL(CUBIC(x0[o0], x[o1], x[o2], x3[o3]), vol)
-#define STEREO_DEST_MIX_CUBIC(op, x0, x3, o0, o1, o2, o3) { \
- int xm = CUBIC(x0[o0], x[o1], x[o2], x3[o3]); \
- *dst++ op CUBICVOL(xm, lvol); \
- *dst++ op CUBICVOL(xm, rvol); \
-}
-#include "resamp2.inc"
-
-/* Create stereo source resampler. */
-#define SUFFIX2 _2
-#define SRC_CHANNELS 2
-#define DIVIDE_BY_SRC_CHANNELS(x) ((x) >> 1)
-#define COPYSRC(dstarray, dstindex, srcarray, srcindex) { \
- (dstarray)[(dstindex)*2] = (srcarray)[(srcindex)*2]; \
- (dstarray)[(dstindex)*2+1] = (srcarray)[(srcindex)*2+1]; \
-}
-#define COPYSRC2(dstarray, dstindex, condition, srcarray, srcindex) { \
- if (condition) { \
- (dstarray)[(dstindex)*2] = (srcarray)[(srcindex)*2]; \
- (dstarray)[(dstindex)*2+1] = (srcarray)[(srcindex)*2+1]; \
- } else { \
- (dstarray)[(dstindex)*2] = 0; \
- (dstarray)[(dstindex)*2+1] = 0; \
- } \
-}
-#define MONO_DEST_VOLUME_PARAMETERS float volume_left, float volume_right
-#define MONO_DEST_VOLUME_VARIABLES lvol, rvol
-#define MONO_DEST_VOLUME_ZEROS 0, 0
-#define SET_MONO_DEST_VOLUME_VARIABLES { \
- lvol = (int)floor(volume_left * 65536.0 + 0.5); \
- rvol = (int)floor(volume_right * 65536.0 + 0.5); \
-}
-#define MONO_DEST_VOLUMES_ARE_ZERO (lvol == 0 && rvol == 0)
-#define MONO_DEST_MIX_ALIAS(op, offset) *dst++ op ALIAS(x[(offset)*2], lvol) + ALIAS(x[(offset)*2+1], rvol)
-#define STEREO_DEST_MIX_ALIAS(op, offset) { \
- *dst++ op ALIAS(x[(offset)*2], lvol); \
- *dst++ op ALIAS(x[(offset)*2+1], rvol); \
-}
-#define MONO_DEST_MIX_LINEAR(op, o0, o1) *dst++ op MULSC(LINEAR(x[(o0)*2], x[(o1)*2]), lvol) + MULSC(LINEAR(x[(o0)*2+1], x[(o1)*2+1]), rvol)
-#define STEREO_DEST_MIX_LINEAR(op, o0, o1) { \
- *dst++ op MULSC(LINEAR(x[(o0)*2], x[(o1)*2]), lvol); \
- *dst++ op MULSC(LINEAR(x[(o0)*2+1], x[(o1)*2+1]), rvol); \
-}
-#define MONO_DEST_MIX_CUBIC(op, x0, x3, o0, o1, o2, o3) *dst++ op \
- CUBICVOL(CUBIC(x0[(o0)*2], x[(o1)*2], x[(o2)*2], x3[(o3)*2]), lvol) + \
- CUBICVOL(CUBIC(x0[(o0)*2+1], x[(o1)*2+1], x[(o2)*2+1], x3[(o3)*2+1]), rvol)
-#define STEREO_DEST_MIX_CUBIC(op, x0, x3, o0, o1, o2, o3) { \
- *dst++ op CUBICVOL(CUBIC(x0[(o0)*2], x[(o1)*2], x[(o2)*2], x3[(o3)*2]), lvol); \
- *dst++ op CUBICVOL(CUBIC(x0[(o0)*2+1], x[(o1)*2+1], x[(o2)*2+1], x3[(o3)*2+1]), rvol); \
-}
-#include "resamp2.inc"
-
-
-
-void dumb_end_resampler(DUMB_RESAMPLER *resampler)
-{
- if (resampler)
- free(resampler);
-}
-
-
-
-#undef CUBICVOL
-#undef CUBIC
-#undef LINEAR
-#undef ALIAS
-#undef SRCBITS
-#undef SRCTYPE
-#undef SUFFIX
diff --git a/dumb/dumb-0.9.3/src/helpers/sampbuf.c b/dumb/dumb-0.9.3/src/helpers/sampbuf.c
deleted file mode 100644
index 6a80f1fa..00000000
--- a/dumb/dumb-0.9.3/src/helpers/sampbuf.c
+++ /dev/null
@@ -1,64 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * sampbuf.c - Helper for allocating sample / / \ \
- * buffers. | < / \_
- * | \/ /\ /
- * By entheh. \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <stdlib.h>
-#include "dumb.h"
-
-
-
-/* DEPRECATED */
-sample_t **create_sample_buffer(int n_channels, long length)
-{
- int i;
- sample_t **samples = malloc(n_channels * sizeof(*samples));
- if (!samples) return NULL;
- samples[0] = malloc(n_channels * length * sizeof(*samples[0]));
- if (!samples[0]) {
- free(samples);
- return NULL;
- }
- for (i = 1; i < n_channels; i++) samples[i] = samples[i-1] + length;
- return samples;
-}
-
-
-
-sample_t **allocate_sample_buffer(int n_channels, long length)
-{
- int i;
- sample_t **samples = malloc(((n_channels + 1) >> 1) * sizeof(*samples));
- if (!samples) return NULL;
- samples[0] = malloc(n_channels * length * sizeof(*samples[0]));
- if (!samples[0]) {
- free(samples);
- return NULL;
- }
- for (i = 1; i < (n_channels + 1) >> 1; i++) samples[i] = samples[i-1] + length*2;
- return samples;
-}
-
-
-
-void destroy_sample_buffer(sample_t **samples)
-{
- if (samples) {
- free(samples[0]);
- free(samples);
- }
-}
diff --git a/dumb/dumb-0.9.3/src/helpers/silence.c b/dumb/dumb-0.9.3/src/helpers/silence.c
deleted file mode 100644
index 4d5fdcf4..00000000
--- a/dumb/dumb-0.9.3/src/helpers/silence.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * silence.c - Silencing helper. / / \ \
- * | < / \_
- * By entheh. | \/ /\ /
- * \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <string.h>
-#include "dumb.h"
-
-
-
-void dumb_silence(sample_t *samples, long length)
-{
- memset(samples, 0, length * sizeof(*samples));
-}
-
diff --git a/dumb/dumb-0.9.3/src/helpers/stdfile.c b/dumb/dumb-0.9.3/src/helpers/stdfile.c
deleted file mode 100644
index 2f02539a..00000000
--- a/dumb/dumb-0.9.3/src/helpers/stdfile.c
+++ /dev/null
@@ -1,93 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * stdfile.c - stdio file input module. / / \ \
- * | < / \_
- * By entheh. | \/ /\ /
- * \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <stdio.h>
-
-#include "dumb.h"
-
-
-
-static void *dumb_stdfile_open(const char *filename)
-{
- return fopen(filename, "rb");
-}
-
-
-
-static int dumb_stdfile_skip(void *f, long n)
-{
- return fseek(f, n, SEEK_CUR);
-}
-
-
-
-static int dumb_stdfile_getc(void *f)
-{
- return fgetc(f);
-}
-
-
-
-static long dumb_stdfile_getnc(char *ptr, long n, void *f)
-{
- return fread(ptr, 1, n, f);
-}
-
-
-
-static void dumb_stdfile_close(void *f)
-{
- fclose(f);
-}
-
-
-
-static DUMBFILE_SYSTEM stdfile_dfs = {
- &dumb_stdfile_open,
- &dumb_stdfile_skip,
- &dumb_stdfile_getc,
- &dumb_stdfile_getnc,
- &dumb_stdfile_close
-};
-
-
-
-void dumb_register_stdfiles(void)
-{
- register_dumbfile_system(&stdfile_dfs);
-}
-
-
-
-static DUMBFILE_SYSTEM stdfile_dfs_leave_open = {
- NULL,
- &dumb_stdfile_skip,
- &dumb_stdfile_getc,
- &dumb_stdfile_getnc,
- NULL
-};
-
-
-
-DUMBFILE *dumbfile_open_stdfile(FILE *p)
-{
- DUMBFILE *d = dumbfile_open_ex(p, &stdfile_dfs_leave_open);
-
- return d;
-}
diff --git a/dumb/dumb-0.9.3/src/it/itload.c b/dumb/dumb-0.9.3/src/it/itload.c
deleted file mode 100644
index a26f5e10..00000000
--- a/dumb/dumb-0.9.3/src/it/itload.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * itload.c - Code to read an Impulse Tracker / / \ \
- * file, opening and closing it for | < / \_
- * you. | \/ /\ /
- * \_ / > /
- * By entheh. Don't worry Bob, you're credited | \ / /
- * in itread.c! | ' /
- * \__/
- */
-
-#include "dumb.h"
-#include "internal/it.h"
-
-
-
-/* dumb_load_it_quick(): loads an IT file into a DUH struct, returning a
- * pointer to the DUH struct. When you have finished with it, you must pass
- * the pointer to unload_duh() so that the memory can be freed.
- */
-DUH *dumb_load_it_quick(const char *filename)
-{
- DUH *duh;
- DUMBFILE *f = dumbfile_open(filename);
-
- if (!f)
- return NULL;
-
- duh = dumb_read_it_quick(f);
-
- dumbfile_close(f);
-
- return duh;
-}
diff --git a/dumb/dumb-0.9.3/src/it/itload2.c b/dumb/dumb-0.9.3/src/it/itload2.c
deleted file mode 100644
index 2dd65a71..00000000
--- a/dumb/dumb-0.9.3/src/it/itload2.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * itload2.c - Function to read an Impulse Tracker / / \ \
- * file, opening and closing it for | < / \_
- * you, and do an initial run-through. | \/ /\ /
- * \_ / > /
- * Split off from itload.c by entheh. | \ / /
- * | ' /
- * \__/
- */
-
-#include "dumb.h"
-
-
-
-DUH *dumb_load_it(const char *filename)
-{
- DUH *duh = dumb_load_it_quick(filename);
- dumb_it_do_initial_runthrough(duh);
- return duh;
-}
diff --git a/dumb/dumb-0.9.3/src/it/itmisc.c b/dumb/dumb-0.9.3/src/it/itmisc.c
deleted file mode 100644
index fc62c188..00000000
--- a/dumb/dumb-0.9.3/src/it/itmisc.c
+++ /dev/null
@@ -1,247 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * itmisc.c - Miscellaneous functions relating / / \ \
- * to module files. | < / \_
- * | \/ /\ /
- * By entheh. \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include "dumb.h"
-#include "internal/it.h"
-
-
-
-DUMB_IT_SIGDATA *duh_get_it_sigdata(DUH *duh)
-{
- return duh_get_raw_sigdata(duh, 0, SIGTYPE_IT);
-}
-
-
-
-const unsigned char *dumb_it_sd_get_song_message(DUMB_IT_SIGDATA *sd)
-{
- return sd ? sd->song_message : NULL;
-}
-
-
-
-int dumb_it_sd_get_n_orders(DUMB_IT_SIGDATA *sd)
-{
- return sd ? sd->n_orders : 0;
-}
-
-
-
-int dumb_it_sd_get_n_samples(DUMB_IT_SIGDATA *sd)
-{
- return sd ? sd->n_samples : 0;
-}
-
-
-
-int dumb_it_sd_get_n_instruments(DUMB_IT_SIGDATA *sd)
-{
- return sd ? sd->n_instruments : 0;
-}
-
-
-
-const unsigned char *dumb_it_sd_get_sample_name(DUMB_IT_SIGDATA *sd, int i)
-{
- ASSERT(sd && sd->sample && i >= 0 && i < sd->n_samples);
- return sd->sample[i].name;
-}
-
-
-
-const unsigned char *dumb_it_sd_get_sample_filename(DUMB_IT_SIGDATA *sd, int i)
-{
- ASSERT(sd && sd->sample && i >= 0 && i < sd->n_samples);
- return sd->sample[i].filename;
-}
-
-
-
-const unsigned char *dumb_it_sd_get_instrument_name(DUMB_IT_SIGDATA *sd, int i)
-{
- ASSERT(sd && sd->instrument && i >= 0 && i < sd->n_instruments);
- return sd->instrument[i].name;
-}
-
-
-
-const unsigned char *dumb_it_sd_get_instrument_filename(DUMB_IT_SIGDATA *sd, int i)
-{
- ASSERT(sd && sd->instrument && i >= 0 && i < sd->n_instruments);
- return sd->instrument[i].filename;
-}
-
-
-
-int dumb_it_sd_get_initial_global_volume(DUMB_IT_SIGDATA *sd)
-{
- return sd ? sd->global_volume : 0;
-}
-
-
-
-void dumb_it_sd_set_initial_global_volume(DUMB_IT_SIGDATA *sd, int gv)
-{
- if (sd) sd->global_volume = gv;
-}
-
-
-
-int dumb_it_sd_get_mixing_volume(DUMB_IT_SIGDATA *sd)
-{
- return sd ? sd->mixing_volume : 0;
-}
-
-
-
-void dumb_it_sd_set_mixing_volume(DUMB_IT_SIGDATA *sd, int mv)
-{
- if (sd) sd->mixing_volume = mv;
-}
-
-
-
-int dumb_it_sd_get_initial_speed(DUMB_IT_SIGDATA *sd)
-{
- return sd ? sd->speed : 0;
-}
-
-
-
-void dumb_it_sd_set_initial_speed(DUMB_IT_SIGDATA *sd, int speed)
-{
- if (sd) sd->speed = speed;
-}
-
-
-
-int dumb_it_sd_get_initial_tempo(DUMB_IT_SIGDATA *sd)
-{
- return sd ? sd->tempo : 0;
-}
-
-
-
-void dumb_it_sd_set_initial_tempo(DUMB_IT_SIGDATA *sd, int tempo)
-{
- if (sd) sd->tempo = tempo;
-}
-
-
-
-int dumb_it_sd_get_initial_channel_volume(DUMB_IT_SIGDATA *sd, int channel)
-{
- ASSERT(channel >= 0 && channel < DUMB_IT_N_CHANNELS);
- return sd ? sd->channel_volume[channel] : 0;
-}
-
-void dumb_it_sd_set_initial_channel_volume(DUMB_IT_SIGDATA *sd, int channel, int volume)
-{
- ASSERT(channel >= 0 && channel < DUMB_IT_N_CHANNELS);
- if (sd) sd->channel_volume[channel] = volume;
-}
-
-
-
-int dumb_it_sr_get_current_order(DUMB_IT_SIGRENDERER *sr)
-{
- return sr ? sr->order : -1;
-}
-
-
-
-int dumb_it_sr_get_current_row(DUMB_IT_SIGRENDERER *sr)
-{
- return sr ? sr->row : -1;
-}
-
-
-
-int dumb_it_sr_get_global_volume(DUMB_IT_SIGRENDERER *sr)
-{
- return sr ? sr->globalvolume : 0;
-}
-
-
-
-void dumb_it_sr_set_global_volume(DUMB_IT_SIGRENDERER *sr, int gv)
-{
- if (sr) sr->globalvolume = gv;
-}
-
-
-
-int dumb_it_sr_get_tempo(DUMB_IT_SIGRENDERER *sr)
-{
- return sr ? sr->tempo : 0;
-}
-
-
-
-void dumb_it_sr_set_tempo(DUMB_IT_SIGRENDERER *sr, int tempo)
-{
- if (sr) sr->tempo = tempo;
-}
-
-
-
-int dumb_it_sr_get_speed(DUMB_IT_SIGRENDERER *sr)
-{
- return sr ? sr->speed : 0;
-}
-
-
-
-void dumb_it_sr_set_speed(DUMB_IT_SIGRENDERER *sr, int speed)
-{
- if (sr) sr->speed = speed;
-}
-
-
-
-int dumb_it_sr_get_channel_volume(DUMB_IT_SIGRENDERER *sr, int channel)
-{
- return sr ? sr->channel[channel].channelvolume : 0;
-}
-
-
-
-void dumb_it_sr_set_channel_volume(DUMB_IT_SIGRENDERER *sr, int channel, int volume)
-{
- if (sr) sr->channel[channel].channelvolume = volume;
-}
-
-
-
-void dumb_it_sr_set_channel_muted(DUMB_IT_SIGRENDERER *sr, int channel, int muted)
-{
- if (sr) {
- if (muted)
- sr->channel[channel].flags |= IT_CHANNEL_MUTED;
- else
- sr->channel[channel].flags &= ~IT_CHANNEL_MUTED;
- }
-}
-
-
-
-int dumb_it_sr_get_channel_muted(DUMB_IT_SIGRENDERER *sr, int channel)
-{
- return sr ? (sr->channel[channel].flags & IT_CHANNEL_MUTED) != 0 : 0;
-}
diff --git a/dumb/dumb-0.9.3/src/it/itorder.c b/dumb/dumb-0.9.3/src/it/itorder.c
deleted file mode 100644
index 6959f054..00000000
--- a/dumb/dumb-0.9.3/src/it/itorder.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * itorder.c - Code to fix invalid patterns in / / \ \
- * the pattern table. | < / \_
- * | \/ /\ /
- * By Julien Cugniere. \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-
-
-#include <stdlib.h>
-
-#include "dumb.h"
-#include "internal/it.h"
-
-
-
-/* This function ensures that any pattern mentioned in the order table but
- * not present in the pattern table is treated as an empty 64 rows pattern.
- * This is done by adding such a dummy pattern at the end of the pattern
- * table, and redirect invalid orders to it.
- * Patterns 254 and 255 are left untouched, unless the signal is an XM.
- */
-int _dumb_it_fix_invalid_orders(DUMB_IT_SIGDATA *sigdata)
-{
- int i;
- int found_some = 0;
-
- int first_invalid = sigdata->n_patterns;
- int last_invalid = (sigdata->flags & IT_WAS_AN_XM) ? 255 : 253;
-
- for (i = 0; i < sigdata->n_orders; i++) {
- if (sigdata->order[i] >= first_invalid && sigdata->order[i] <= last_invalid) {
- sigdata->order[i] = sigdata->n_patterns;
- found_some = 1;
- }
- }
-
- if (found_some) {
- IT_PATTERN *new_pattern = realloc(sigdata->pattern, sizeof(*sigdata->pattern) * (sigdata->n_patterns + 1));
- if (!new_pattern)
- return -1;
-
- new_pattern[sigdata->n_patterns].n_rows = 64;
- new_pattern[sigdata->n_patterns].n_entries = 0;
- new_pattern[sigdata->n_patterns].entry = NULL;
- sigdata->pattern = new_pattern;
- sigdata->n_patterns++;
- }
-
- return 0;
-}
diff --git a/dumb/dumb-0.9.3/src/it/itread.c b/dumb/dumb-0.9.3/src/it/itread.c
deleted file mode 100644
index 3d95beaa..00000000
--- a/dumb/dumb-0.9.3/src/it/itread.c
+++ /dev/null
@@ -1,1202 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * itread.c - Code to read an Impulse Tracker / / \ \
- * module from an open file. | < / \_
- * | \/ /\ /
- * Based on the loader from an IT player by Bob. \_ / > /
- * Adapted for DUMB by entheh. | \ / /
- * | ' /
- * \__/
- */
-
-#include <stdlib.h>
-#include <string.h>//might not be necessary later; required for memset
-
-#include "dumb.h"
-#include "internal/it.h"
-
-
-
-#define INVESTIGATE_OLD_INSTRUMENTS
-
-
-
-static int it_seek(DUMBFILE *f, long offset)
-{
- long pos = dumbfile_pos(f);
-
- if (pos > offset)
- return -1;
-
- if (pos < offset)
- if (dumbfile_skip(f, offset - pos))
- return -1;
-
- return 0;
-}
-
-
-
-typedef unsigned char byte;
-typedef unsigned short word;
-typedef unsigned long dword;
-
-
-
-static unsigned char *sourcebuf = NULL;
-static unsigned char *sourcepos = NULL;
-static unsigned char *sourceend;
-static int rembits = 0;
-
-
-
-static int readblock(DUMBFILE *f)
-{
- long size;
- int c;
-
- size = dumbfile_igetw(f);
- if (size < 0)
- return size;
-
- sourcebuf = malloc(size);
- if (!sourcebuf)
- return -1;
-
- c = dumbfile_getnc((char *)sourcebuf, size, f);
- if (c < size) {
- free(sourcebuf);
- sourcebuf = NULL;
- return -1;
- }
-
- sourcepos = sourcebuf;
- sourceend = sourcebuf + size;
- rembits = 8;
- return 0;
-}
-
-
-
-static void freeblock(void)
-{
- free(sourcebuf);
- sourcebuf = NULL;
-}
-
-
-
-static int readbits(int bitwidth)
-{
- int val = 0;
- int b = 0;
-
- if (sourcepos >= sourceend) return val;
-
- while (bitwidth > rembits) {
- val |= *sourcepos++ << b;
- if (sourcepos >= sourceend) return val;
- b += rembits;
- bitwidth -= rembits;
- rembits = 8;
- }
-
- val |= (*sourcepos & ((1 << bitwidth) - 1)) << b;
- *sourcepos >>= bitwidth;
- rembits -= bitwidth;
-
- return val;
-}
-
-
-
-/** WARNING - do we even need to pass `right`? */
-/** WARNING - why bother memsetting at all? The whole array is written... */
-// if we do memset, dumb_silence() would be neater...
-static int decompress8(DUMBFILE *f, signed char *data, int len, int cmwt)
-{
- int blocklen, blockpos;
- byte bitwidth;
- word val;
- char d1, d2;
-
- memset(data, 0, len * sizeof(*data));
-
- while (len > 0) {
- //Read a block of compressed data:
- if (readblock(f))
- return -1;
- //Set up a few variables
- blocklen = (len < 0x8000) ? len : 0x8000; //Max block length is 0x8000 bytes
- blockpos = 0;
- bitwidth = 9;
- d1 = d2 = 0;
- //Start the decompression:
- while (blockpos < blocklen) {
- //Read a value:
- val = (word)readbits(bitwidth);
- //Check for bit width change:
-
- if (bitwidth < 7) { //Method 1:
- if (val == (1 << (bitwidth - 1))) {
- val = (word)readbits(3) + 1;
- bitwidth = (val < bitwidth) ? val : val + 1;
- continue;
- }
- }
- else if (bitwidth < 9) { //Method 2
- byte border = (0xFF >> (9 - bitwidth)) - 4;
-
- if (val > border && val <= (border + 8)) {
- val -= border;
- bitwidth = (val < bitwidth) ? val : val + 1;
- continue;
- }
- }
- else if (bitwidth == 9) { //Method 3
- if (val & 0x100) {
- bitwidth = (val + 1) & 0xFF;
- continue;
- }
- }
- else { //Illegal width, abort ?
- freeblock();
- return -1;
- }
-
- //Expand the value to signed byte:
- {
- char v; //The sample value:
- if (bitwidth < 8) {
- byte shift = 8 - bitwidth;
- v = (val << shift);
- v >>= shift;
- }
- else
- v = (char)val;
-
- //And integrate the sample value
- //(It always has to end with integration doesn't it ? ;-)
- d1 += v;
- d2 += d1;
- }
-
- //Store !
- /* Version 2.15 was an unofficial version with hacked compression
- * code. Yay, better compression :D
- */
- *data++ = cmwt == 0x215 ? d2 : d1;
- len--;
- blockpos++;
- }
- freeblock();
- }
- return 0;
-}
-
-
-
-static int decompress16(DUMBFILE *f, short *data, int len, int cmwt)
-{
- int blocklen, blockpos;
- byte bitwidth;
- long val;
- short d1, d2;
-
- memset(data, 0, len * sizeof(*data));
-
- while (len > 0) {
- //Read a block of compressed data:
- if (readblock(f))
- return -1;
- //Set up a few variables
- blocklen = (len < 0x4000) ? len : 0x4000; // Max block length is 0x4000 bytes
- blockpos = 0;
- bitwidth = 17;
- d1 = d2 = 0;
- //Start the decompression:
- while (blockpos < blocklen) {
- val = readbits(bitwidth);
- //Check for bit width change:
-
- if (bitwidth < 7) { //Method 1:
- if (val == (1 << (bitwidth - 1))) {
- val = readbits(4) + 1;
- bitwidth = (val < bitwidth) ? val : val + 1;
- continue;
- }
- }
- else if (bitwidth < 17) { //Method 2
- word border = (0xFFFF >> (17 - bitwidth)) - 8;
-
- if (val > border && val <= (border + 16)) {
- val -= border;
- bitwidth = val < bitwidth ? val : val + 1;
- continue;
- }
- }
- else if (bitwidth == 17) { //Method 3
- if (val & 0x10000) {
- bitwidth = (val + 1) & 0xFF;
- continue;
- }
- }
- else { //Illegal width, abort ?
- freeblock();
- return -1;
- }
-
- //Expand the value to signed byte:
- {
- short v; //The sample value:
- if (bitwidth < 16) {
- byte shift = 16 - bitwidth;
- v = (short)(val << shift);
- v >>= shift;
- }
- else
- v = (short)val;
-
- //And integrate the sample value
- //(It always has to end with integration doesn't it ? ;-)
- d1 += v;
- d2 += d1;
- }
-
- //Store !
- /* Version 2.15 was an unofficial version with hacked compression
- * code. Yay, better compression :D
- */
- *data++ = cmwt == 0x215 ? d2 : d1;
- len--;
- blockpos++;
- }
- freeblock();
- }
- return 0;
-}
-
-
-
-static int it_read_envelope(IT_ENVELOPE *envelope, DUMBFILE *f)
-{
- int n;
-
- envelope->flags = dumbfile_getc(f);
- envelope->n_nodes = dumbfile_getc(f);
- envelope->loop_start = dumbfile_getc(f);
- envelope->loop_end = dumbfile_getc(f);
- envelope->sus_loop_start = dumbfile_getc(f);
- envelope->sus_loop_end = dumbfile_getc(f);
- for (n = 0; n < envelope->n_nodes; n++) {
- envelope->node_y[n] = dumbfile_getc(f);
- envelope->node_t[n] = dumbfile_igetw(f);
- }
- dumbfile_skip(f, 75 - envelope->n_nodes * 3 + 1);
-
- if (envelope->n_nodes <= 0)
- envelope->flags &= ~IT_ENVELOPE_ON;
- else {
- if (envelope->loop_end >= envelope->n_nodes || envelope->loop_start > envelope->loop_end) envelope->flags &= ~IT_ENVELOPE_LOOP_ON;
- if (envelope->sus_loop_end >= envelope->n_nodes || envelope->sus_loop_start > envelope->sus_loop_end) envelope->flags &= ~IT_ENVELOPE_SUSTAIN_LOOP;
- }
-
- return dumbfile_error(f);
-}
-
-
-
-static int it_read_old_instrument(IT_INSTRUMENT *instrument, DUMBFILE *f)
-{
- int n;
-
- if (dumbfile_mgetl(f) != IT_INSTRUMENT_SIGNATURE)
- return -1;
-
- dumbfile_getnc(instrument->filename, 13, f);
- instrument->filename[13] = 0;
-
- instrument->volume_envelope.flags = dumbfile_getc(f);
- instrument->volume_envelope.loop_start = dumbfile_getc(f);
- instrument->volume_envelope.loop_end = dumbfile_getc(f);
- instrument->volume_envelope.sus_loop_start = dumbfile_getc(f);
- instrument->volume_envelope.sus_loop_end = dumbfile_getc(f);
-
- /* Skip two unused bytes. */
- dumbfile_skip(f, 2);
-
- /* In the old instrument format, fadeout ranges from 0 to 64, and is
- * subtracted at intervals from a value starting at 512. In the new
- * format, all these values are doubled. Therefore we double when loading
- * from the old instrument format - that way we don't have to think about
- * it later.
- */
- instrument->fadeout = dumbfile_igetw(f) << 1;
- instrument->new_note_action = dumbfile_getc(f);
- instrument->dup_check_type = dumbfile_getc(f);
- instrument->dup_check_action = DCA_NOTE_CUT; // This might be wrong!
- /** WARNING - what is the duplicate check action for old-style instruments? */
-
- /* Skip Tracker Version and Number of Samples. These are only used in
- * separate instrument files. Also skip unused byte.
- */
- dumbfile_skip(f, 4);
-
- dumbfile_getnc(instrument->name, 26, f);
- instrument->name[26] = 0;
-
- /* Skip unused bytes following the Instrument Name. */
- dumbfile_skip(f, 6);
-
- instrument->pp_separation = 0;
- instrument->pp_centre = 60;
- instrument->global_volume = 128;
- /** WARNING - should global_volume be 64 or something? */
- instrument->default_pan = 32;
- /** WARNING - should default_pan be 128, meaning don`t use? */
- instrument->random_volume = 0;
- instrument->random_pan = 0;
-
- for (n = 0; n < 120; n++) {
- instrument->map_note[n] = dumbfile_getc(f);
- instrument->map_sample[n] = dumbfile_getc(f);
- }
-
- /* Skip "Volume envelope (200 bytes)". */
- // - need to know better what this is for though.
- dumbfile_skip(f, 200);
-
-#ifdef INVESTIGATE_OLD_INSTRUMENTS
- fprintf(stderr, "Inst %02d Env:", n);
-#endif
-
- for (n = 0; n < 25; n++)
- {
- instrument->volume_envelope.node_t[n] = dumbfile_getc(f);
- instrument->volume_envelope.node_y[n] = dumbfile_getc(f);
-
-#ifdef INVESTIGATE_OLD_INSTRUMENTS
- fprintf(stderr, " %d,%d",
- instrument->volume_envelope.node_t[n],
- instrument->volume_envelope.node_y[n]);
-#endif
-
- // This loop is unfinished, as we can probably escape from it before
- // the end if we want to. Hence the otherwise useless dumbfile_skip()
- // call below.
- }
- dumbfile_skip(f, 50 - (n << 1));
- instrument->volume_envelope.n_nodes = n;
-
-#ifdef INVESTIGATE_OLD_INSTRUMENTS
- fprintf(stderr, "\n");
-#endif
-
- if (dumbfile_error(f))
- return -1;
-
- {
- IT_ENVELOPE *envelope = &instrument->volume_envelope;
- if (envelope->n_nodes <= 0)
- envelope->flags &= ~IT_ENVELOPE_ON;
- else {
- if (envelope->loop_end >= envelope->n_nodes || envelope->loop_start > envelope->loop_end) envelope->flags &= ~IT_ENVELOPE_LOOP_ON;
- if (envelope->sus_loop_end >= envelope->n_nodes || envelope->sus_loop_start > envelope->sus_loop_end) envelope->flags &= ~IT_ENVELOPE_SUSTAIN_LOOP;
- }
- }
-
- instrument->filter_cutoff = 127;
- instrument->filter_resonance = 0;
-
- instrument->pan_envelope.flags = 0;
- instrument->pitch_envelope.flags = 0;
-
- return 0;
-}
-
-
-
-static int it_read_instrument(IT_INSTRUMENT *instrument, DUMBFILE *f)
-{
- int n;
-
- if (dumbfile_mgetl(f) != IT_INSTRUMENT_SIGNATURE)
- return -1;
-
- dumbfile_getnc(instrument->filename, 13, f);
- instrument->filename[13] = 0;
-
- instrument->new_note_action = dumbfile_getc(f);
- instrument->dup_check_type = dumbfile_getc(f);
- instrument->dup_check_action = dumbfile_getc(f);
- instrument->fadeout = dumbfile_igetw(f);
- instrument->pp_separation = dumbfile_getc(f);
- instrument->pp_centre = dumbfile_getc(f);
- instrument->global_volume = dumbfile_getc(f);
- instrument->default_pan = dumbfile_getc(f);
- instrument->random_volume = dumbfile_getc(f);
- instrument->random_pan = dumbfile_getc(f);
-
- /* Skip Tracker Version and Number of Samples. These are only used in
- * separate instrument files. Also skip unused byte.
- */
- dumbfile_skip(f, 4);
-
- dumbfile_getnc(instrument->name, 26, f);
- instrument->name[26] = 0;
-
- instrument->filter_cutoff = dumbfile_getc(f);
- instrument->filter_resonance = dumbfile_getc(f);
-
- /* Skip MIDI Channel, Program and Bank. */
- dumbfile_skip(f, 4);
-
- for (n = 0; n < 120; n++) {
- instrument->map_note[n] = dumbfile_getc(f);
- instrument->map_sample[n] = dumbfile_getc(f);
- }
-
- if (dumbfile_error(f))
- return -1;
-
- if (it_read_envelope(&instrument->volume_envelope, f)) return -1;
- if (it_read_envelope(&instrument->pan_envelope, f)) return -1;
- if (it_read_envelope(&instrument->pitch_envelope, f)) return -1;
-
- return 0;
-}
-
-
-
-static int it_read_sample_header(IT_SAMPLE *sample, unsigned char *convert, long *offset, DUMBFILE *f)
-{
- if (dumbfile_mgetl(f) != IT_SAMPLE_SIGNATURE)
- return -1;
-
- dumbfile_getnc(sample->filename, 13, f);
- sample->filename[13] = 0;
-
- sample->global_volume = dumbfile_getc(f);
- sample->flags = dumbfile_getc(f);
- sample->default_volume = dumbfile_getc(f);
-
- dumbfile_getnc(sample->name, 26, f);
- sample->name[26] = 0;
-
- *convert = dumbfile_getc(f);
- sample->default_pan = dumbfile_getc(f);
- sample->length = dumbfile_igetl(f);
- sample->loop_start = dumbfile_igetl(f);
- sample->loop_end = dumbfile_igetl(f);
- sample->C5_speed = dumbfile_igetl(f);
- sample->sus_loop_start = dumbfile_igetl(f);
- sample->sus_loop_end = dumbfile_igetl(f);
-
-#ifdef STEREO_SAMPLES_COUNT_AS_TWO
- if (sample->flags & IT_SAMPLE_STEREO) {
- sample->length >>= 1;
- sample->loop_start >>= 1;
- sample->loop_end >>= 1;
- sample->C5_speed >>= 1;
- sample->sus_loop_start >>= 1;
- sample->sus_loop_end >>= 1;
- }
-#endif
-
- if (sample->flags & IT_SAMPLE_EXISTS) {
- if (sample->length <= 0)
- sample->flags &= ~IT_SAMPLE_EXISTS;
- else {
- if ((unsigned int)sample->loop_end > (unsigned int)sample->length)
- sample->flags &= ~IT_SAMPLE_LOOP;
- else if ((unsigned int)sample->loop_start >= (unsigned int)sample->loop_end)
- sample->flags &= ~IT_SAMPLE_LOOP;
-
- if ((unsigned int)sample->sus_loop_end > (unsigned int)sample->length)
- sample->flags &= ~IT_SAMPLE_SUS_LOOP;
- else if ((unsigned int)sample->sus_loop_start >= (unsigned int)sample->sus_loop_end)
- sample->flags &= ~IT_SAMPLE_SUS_LOOP;
-
- /* We may be able to truncate the sample to save memory. */
- if (sample->flags & IT_SAMPLE_LOOP) {
- if ((sample->flags & IT_SAMPLE_SUS_LOOP) && sample->sus_loop_end >= sample->loop_end)
- sample->length = sample->sus_loop_end;
- else
- sample->length = sample->loop_end;
- }
- }
- }
-
- *offset = dumbfile_igetl(f);
-
- sample->vibrato_speed = dumbfile_getc(f);
- sample->vibrato_depth = dumbfile_getc(f);
- sample->vibrato_rate = dumbfile_getc(f);
- sample->vibrato_waveform = dumbfile_getc(f);
-
- return dumbfile_error(f);
-}
-
-
-
-static long it_read_sample_data(int cmwt, IT_SAMPLE *sample, unsigned char convert, DUMBFILE *f)
-{
- long n;
-
- long datasize = sample->length;
- if (sample->flags & IT_SAMPLE_STEREO) datasize <<= 1;
-
- sample->data = malloc(datasize * (sample->flags & IT_SAMPLE_16BIT ? 2 : 1));
- if (!sample->data)
- return -1;
-
- if (sample->flags & 8) {
- /* If the sample is packed, then we must unpack it. */
-
- /** WARNING - unresolved business here... test with ModPlug? */
-
- if (sample->flags & IT_SAMPLE_STEREO)
- exit(37); // TODO: if this ever happens, maybe sample->length should be doubled below?
-
-/*
-//#ifndef STEREO_SAMPLES_COUNT_AS_TWO
- ASSERT(!(sample->flags & IT_SAMPLE_STEREO));
-//#endif
-*/
- if (sample->flags & IT_SAMPLE_16BIT)
- decompress16(f, sample->data, datasize, cmwt);
- else
- decompress8(f, sample->data, datasize, cmwt);
- } else if (sample->flags & IT_SAMPLE_16BIT) {
- 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
- for (n = 0; n < datasize; n++)
- ((signed char *)sample->data)[n] = dumbfile_getc(f);
-
- if (dumbfile_error(f))
- return -1;
-
- if (!(convert & 1)) {
- /* Convert to signed. */
- if (sample->flags & IT_SAMPLE_16BIT)
- for (n = 0; n < datasize; n++)
- ((short *)sample->data)[n] ^= 0x8000;
- else
- for (n = 0; n < datasize; n++)
- ((signed char *)sample->data)[n] ^= 0x80;
- }
-
- /* NOT SUPPORTED:
- *
- * convert & 4 - Samples stored as delta values
- * convert & 16 - Samples stored as TX-Wave 12-bit values
- * convert & 32 - Left/Right/All Stereo prompt
- */
-
- return 0;
-}
-
-
-
-#define DETECT_DUPLICATE_CHANNELS
-#ifdef DETECT_DUPLICATE_CHANNELS
-#include <stdio.h>
-#endif
-static int it_read_pattern(IT_PATTERN *pattern, DUMBFILE *f, unsigned char *buffer)
-{
- unsigned char cmask[DUMB_IT_N_CHANNELS];
- unsigned char cnote[DUMB_IT_N_CHANNELS];
- unsigned char cinstrument[DUMB_IT_N_CHANNELS];
- unsigned char cvolpan[DUMB_IT_N_CHANNELS];
- unsigned char ceffect[DUMB_IT_N_CHANNELS];
- unsigned char ceffectvalue[DUMB_IT_N_CHANNELS];
-#ifdef DETECT_DUPLICATE_CHANNELS
- IT_ENTRY *dupentry[DUMB_IT_N_CHANNELS];
-#endif
-
- int n_entries = 0;
- int buflen;
- int bufpos = 0;
-
- IT_ENTRY *entry;
-
- unsigned char channel;
- unsigned char mask;
-
- memset(cmask, 0, sizeof(cmask));
- memset(cnote, 0, sizeof(cnote));
- memset(cinstrument, 0, sizeof(cinstrument));
- memset(cvolpan, 0, sizeof(cvolpan));
- memset(ceffect, 0, sizeof(ceffect));
- memset(ceffectvalue, 0, sizeof(ceffectvalue));
-#ifdef DETECT_DUPLICATE_CHANNELS
- {
- int i;
- for (i = 0; i < DUMB_IT_N_CHANNELS; i++) dupentry[i] = NULL;
- }
-#endif
-
- buflen = dumbfile_igetw(f);
- pattern->n_rows = dumbfile_igetw(f);
-
- /* Skip four unused bytes. */
- dumbfile_skip(f, 4);
-
- if (dumbfile_error(f))
- return -1;
-
- /* Read in the pattern data. */
- dumbfile_getnc(buffer, buflen, f);
-
- if (dumbfile_error(f))
- return -1;
-
- /* Scan the pattern data, and work out how many entries we need room for. */
- while (bufpos < buflen) {
- unsigned char b = buffer[bufpos++];
-
- if (b == 0) {
- /* End of row */
- n_entries++;
- continue;
- }
-
- channel = (b - 1) & 63;
-
- if (b & 128)
- cmask[channel] = mask = buffer[bufpos++];
- else
- mask = cmask[channel];
-
- {
- static const unsigned char used[16] = {0, 1, 1, 2, 1, 2, 2, 3, 2, 3, 3, 4, 3, 4, 4, 5};
- n_entries += (mask != 0);
- bufpos += used[mask & 15];
- }
- }
-
- pattern->n_entries = n_entries;
-
- pattern->entry = malloc(n_entries * sizeof(*pattern->entry));
-
- if (!pattern->entry)
- return -1;
-
- bufpos = 0;
- memset(cmask, 0, sizeof(cmask));
-
- entry = pattern->entry;
-
- while (bufpos < buflen) {
- unsigned char b = buffer[bufpos++];
-
- if (b == 0) {
- /* End of row */
- IT_SET_END_ROW(entry);
- entry++;
-#ifdef DETECT_DUPLICATE_CHANNELS
- {
- int i;
- for (i = 0; i < DUMB_IT_N_CHANNELS; i++) dupentry[i] = NULL;
- }
-#endif
- continue;
- }
-
- channel = (b - 1) & 63;
-
- if (b & 128)
- cmask[channel] = mask = buffer[bufpos++];
- else
- mask = cmask[channel];
-
- if (mask) {
- entry->mask = (mask & 15) | (mask >> 4);
- entry->channel = channel;
-
- if (mask & IT_ENTRY_NOTE)
- cnote[channel] = entry->note = buffer[bufpos++];
- else if (mask & (IT_ENTRY_NOTE << 4))
- entry->note = cnote[channel];
-
- if (mask & IT_ENTRY_INSTRUMENT)
- cinstrument[channel] = entry->instrument = buffer[bufpos++];
- else if (mask & (IT_ENTRY_INSTRUMENT << 4))
- entry->instrument = cinstrument[channel];
-
- if (mask & IT_ENTRY_VOLPAN)
- cvolpan[channel] = entry->volpan = buffer[bufpos++];
- else if (mask & (IT_ENTRY_VOLPAN << 4))
- entry->volpan = cvolpan[channel];
-
- if (mask & IT_ENTRY_EFFECT) {
- ceffect[channel] = entry->effect = buffer[bufpos++];
- ceffectvalue[channel] = entry->effectvalue = buffer[bufpos++];
- } else {
- entry->effect = ceffect[channel];
- entry->effectvalue = ceffectvalue[channel];
- }
-
-#ifdef DETECT_DUPLICATE_CHANNELS
- if (dupentry[channel]) {
- FILE *f = fopen("dupentry.txt", "a");
- if (!f) abort();
- fprintf(f, "Two events on channel %d:", channel);
- fprintf(f, " Event #1:");
- if (dupentry[channel]->mask & IT_ENTRY_NOTE ) fprintf(f, " %03d", dupentry[channel]->note ); else fprintf(f, " ...");
- if (dupentry[channel]->mask & IT_ENTRY_INSTRUMENT) fprintf(f, " %03d", dupentry[channel]->instrument); else fprintf(f, " ...");
- if (dupentry[channel]->mask & IT_ENTRY_VOLPAN ) fprintf(f, " %03d", dupentry[channel]->volpan ); else fprintf(f, " ...");
- if (dupentry[channel]->mask & IT_ENTRY_EFFECT) fprintf(f, " %c%02X\n", 'A' - 1 + dupentry[channel]->effect, dupentry[channel]->effectvalue); else fprintf(f, " ...\n");
- fprintf(f, " Event #2:");
- if (entry->mask & IT_ENTRY_NOTE ) fprintf(f, " %03d", entry->note ); else fprintf(f, " ...");
- if (entry->mask & IT_ENTRY_INSTRUMENT) fprintf(f, " %03d", entry->instrument); else fprintf(f, " ...");
- if (entry->mask & IT_ENTRY_VOLPAN ) fprintf(f, " %03d", entry->volpan ); else fprintf(f, " ...");
- if (entry->mask & IT_ENTRY_EFFECT) fprintf(f, " %c%02X\n", 'A' - 1 + entry->effect, entry->effectvalue); else fprintf(f, " ...\n");
- fclose(f);
- }
- dupentry[channel] = entry;
-#endif
-
- entry++;
- }
- }
-
- ASSERT(entry == pattern->entry + n_entries);
-
- return 0;
-}
-
-
-
-/* Currently we assume the sample data are stored after the sample headers in
- * module files. This assumption may be unjustified; let me know if you have
- * trouble.
- */
-
-#define IT_COMPONENT_SONG_MESSAGE 1
-#define IT_COMPONENT_INSTRUMENT 2
-#define IT_COMPONENT_PATTERN 3
-#define IT_COMPONENT_SAMPLE 4
-
-typedef struct IT_COMPONENT
-{
- unsigned char type;
- unsigned char n;
- long offset;
- short sampfirst; /* component[sampfirst] = first sample data after this */
- short sampnext; /* sampnext is used to create linked lists of sample data */
-}
-IT_COMPONENT;
-
-
-
-static int it_component_compare(const void *e1, const void *e2)
-{
- return ((const IT_COMPONENT *)e1)->offset -
- ((const IT_COMPONENT *)e2)->offset;
-}
-
-
-
-static sigdata_t *it_load_sigdata(DUMBFILE *f)
-{
- DUMB_IT_SIGDATA *sigdata;
-
- int cwt, cmwt;
- int special;
- int message_length, message_offset;
-
- IT_COMPONENT *component;
- int n_components = 0;
-
- unsigned char sample_convert[256];
-
- int n;
-
- unsigned char *buffer;
-
- if (dumbfile_mgetl(f) != IT_SIGNATURE)
- return NULL;
-
- sigdata = malloc(sizeof(*sigdata));
-
- if (!sigdata)
- return NULL;
-
- sigdata->song_message = NULL;
- sigdata->order = NULL;
- sigdata->instrument = NULL;
- sigdata->sample = NULL;
- sigdata->pattern = NULL;
- sigdata->midi = NULL;
- sigdata->checkpoint = NULL;
-
- dumbfile_getnc(sigdata->name, 26, f);
- sigdata->name[26] = 0;
-
- /* Skip pattern row highlight info. */
- dumbfile_skip(f, 2);
-
- sigdata->n_orders = dumbfile_igetw(f);
- sigdata->n_instruments = dumbfile_igetw(f);
- sigdata->n_samples = dumbfile_igetw(f);
- sigdata->n_patterns = dumbfile_igetw(f);
-
- cwt = dumbfile_igetw(f);
- cmwt = dumbfile_igetw(f);
-
- sigdata->flags = dumbfile_igetw(f);
- special = dumbfile_igetw(f);
-
- sigdata->global_volume = dumbfile_getc(f);
- sigdata->mixing_volume = dumbfile_getc(f);
- sigdata->speed = dumbfile_getc(f);
- if (sigdata->speed == 0) sigdata->speed = 6; // Should we? What about tempo?
- sigdata->tempo = dumbfile_getc(f);
- sigdata->pan_separation = dumbfile_getc(f); /** WARNING: use this */
-
- /* Skip Pitch Wheel Depth */
- dumbfile_skip(f, 1);
-
- message_length = dumbfile_igetw(f);
- message_offset = dumbfile_igetl(f);
-
- /* Skip Reserved. */
- dumbfile_skip(f, 4);
-
- dumbfile_getnc(sigdata->channel_pan, DUMB_IT_N_CHANNELS, f);
- dumbfile_getnc(sigdata->channel_volume, DUMB_IT_N_CHANNELS, f);
-
- if (dumbfile_error(f) || sigdata->n_orders <= 0 || sigdata->n_instruments > 256 || sigdata->n_samples > 256 || sigdata->n_patterns > 256) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- sigdata->order = malloc(sigdata->n_orders);
- if (!sigdata->order) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- if (sigdata->n_instruments) {
- sigdata->instrument = malloc(sigdata->n_instruments * sizeof(*sigdata->instrument));
- if (!sigdata->instrument) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- }
-
- if (sigdata->n_samples) {
- sigdata->sample = malloc(sigdata->n_samples * sizeof(*sigdata->sample));
- if (!sigdata->sample) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- for (n = 0; n < sigdata->n_samples; n++)
- sigdata->sample[n].data = NULL;
- }
-
- if (sigdata->n_patterns) {
- sigdata->pattern = malloc(sigdata->n_patterns * sizeof(*sigdata->pattern));
- if (!sigdata->pattern) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- for (n = 0; n < sigdata->n_patterns; n++)
- sigdata->pattern[n].entry = NULL;
- }
-
- dumbfile_getnc(sigdata->order, sigdata->n_orders, f);
- sigdata->restart_position = 0;
-
- component = malloc(769 * sizeof(*component));
- if (!component) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- if (special & 1) {
- component[n_components].type = IT_COMPONENT_SONG_MESSAGE;
- component[n_components].offset = message_offset;
- component[n_components].sampfirst = -1;
- n_components++;
- }
-
- for (n = 0; n < sigdata->n_instruments; n++) {
- component[n_components].type = IT_COMPONENT_INSTRUMENT;
- component[n_components].n = n;
- component[n_components].offset = dumbfile_igetl(f);
- component[n_components].sampfirst = -1;
- n_components++;
- }
-
- for (n = 0; n < sigdata->n_samples; n++) {
- component[n_components].type = IT_COMPONENT_SAMPLE;
- component[n_components].n = n;
- component[n_components].offset = dumbfile_igetl(f);
- component[n_components].sampfirst = -1;
- n_components++;
- }
-
- for (n = 0; n < sigdata->n_patterns; n++) {
- long offset = dumbfile_igetl(f);
- if (offset) {
- component[n_components].type = IT_COMPONENT_PATTERN;
- component[n_components].n = n;
- component[n_components].offset = offset;
- component[n_components].sampfirst = -1;
- n_components++;
- } else {
- /* Empty 64-row pattern */
- sigdata->pattern[n].n_rows = 64;
- sigdata->pattern[n].n_entries = 0;
- }
- }
-
- if (dumbfile_error(f)) {
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- if (!(sigdata->flags & 128) != !(special & 8)) {
- fprintf(stderr, "Flags Bit 7 (\"Request embedded MIDI configuration\"): %s\n", sigdata->flags & 128 ? "=SET=" : "clear");
- fprintf(stderr, "Special Bit 3 (\"MIDI configuration embedded\") : %s\n", special & 8 ? "=SET=" : "clear");
- fprintf(stderr, "entheh would like to investigate this IT file.\n");
- fprintf(stderr, "Please contact him! entheh@users.sf.net\n");
- }
-
- if (special & 8) {
- /* MIDI configuration is embedded. */
- unsigned char mididata[32];
- int i;
- sigdata->midi = malloc(sizeof(*sigdata->midi));
- if (!sigdata->midi) {
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- // Should we be happy with this outcome in some situations?
- }
- // What are we skipping?
- i = dumbfile_igetw(f);
- if (dumbfile_error(f) || dumbfile_skip(f, 8*i)) {
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- /* Read embedded MIDI configuration */
- // What are the first 9 commands for?
- if (dumbfile_skip(f, 32*9)) {
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- for (i = 0; i < 16; i++) {
- unsigned char len = 0;
- int j, leftdigit = -1;
- if (dumbfile_getnc(mididata, 32, f) < 32) {
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- sigdata->midi->SFmacroz[i] = 0;
- for (j = 0; j < 32; j++) {
- if (leftdigit >= 0) {
- if (mididata[j] == 0) {
- sigdata->midi->SFmacro[i][len++] = leftdigit;
- break;
- } else if (mididata[j] == ' ')
- sigdata->midi->SFmacro[i][len++] = leftdigit;
- else if (mididata[j] >= '0' && mididata[j] <= '9')
- sigdata->midi->SFmacro[i][len++] = (leftdigit << 4) | (mididata[j] - '0');
- else if (mididata[j] >= 'A' && mididata[j] <= 'F')
- sigdata->midi->SFmacro[i][len++] = (leftdigit << 4) | (mididata[j] - 'A' + 0xA);
- leftdigit = -1;
- } else if (mididata[j] == 0)
- break;
- else if (mididata[j] == 'z')
- sigdata->midi->SFmacroz[i] |= 1 << len++;
- else if (mididata[j] >= '0' && mididata[j] <= '9')
- leftdigit = mididata[j] - '0';
- else if (mididata[j] >= 'A' && mididata[j] <= 'F')
- leftdigit = mididata[j] - 'A' + 0xA;
- }
- sigdata->midi->SFmacrolen[i] = len;
- }
- for (i = 0; i < 128; i++) {
- unsigned char len = 0;
- int j, leftdigit = -1;
- dumbfile_getnc(mididata, 32, f);
- for (j = 0; j < 32; j++) {
- if (leftdigit >= 0) {
- if (mididata[j] == 0) {
- sigdata->midi->Zmacro[i][len++] = leftdigit;
- break;
- } else if (mididata[j] == ' ')
- sigdata->midi->Zmacro[i][len++] = leftdigit;
- else if (mididata[j] >= '0' && mididata[j] <= '9')
- sigdata->midi->Zmacro[i][len++] = (leftdigit << 4) | (mididata[j] - '0');
- else if (mididata[j] >= 'A' && mididata[j] <= 'F')
- sigdata->midi->Zmacro[i][len++] = (leftdigit << 4) | (mididata[j] - 'A' + 0xA);
- leftdigit = -1;
- } else if (mididata[j] == 0)
- break;
- else if (mididata[j] >= '0' && mididata[j] <= '9')
- leftdigit = mididata[j] - '0';
- else if (mididata[j] >= 'A' && mididata[j] <= 'F')
- leftdigit = mididata[j] - 'A' + 0xA;
- }
- sigdata->midi->Zmacrolen[i] = len;
- }
- }
-
- sigdata->flags &= IT_REAL_FLAGS;
-
- qsort(component, n_components, sizeof(IT_COMPONENT), &it_component_compare);
-
- buffer = malloc(65536);
- if (!buffer) {
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- for (n = 0; n < n_components; n++) {
- long offset;
- int m;
-
- if (it_seek(f, component[n].offset)) {
- free(buffer);
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- switch (component[n].type) {
-
- case IT_COMPONENT_SONG_MESSAGE:
- sigdata->song_message = malloc(message_length + 1);
- if (sigdata->song_message) {
- if (dumbfile_getnc(sigdata->song_message, message_length, f) < message_length) {
- free(buffer);
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- sigdata->song_message[message_length] = 0;
- }
- break;
-
- case IT_COMPONENT_INSTRUMENT:
- if (cmwt < 0x200)
- m = it_read_old_instrument(&sigdata->instrument[component[n].n], f);
- else
- m = it_read_instrument(&sigdata->instrument[component[n].n], f);
-
- if (m) {
- free(buffer);
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- break;
-
- case IT_COMPONENT_PATTERN:
- if (it_read_pattern(&sigdata->pattern[component[n].n], f, buffer)) {
- free(buffer);
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- break;
-
- case IT_COMPONENT_SAMPLE:
- if (it_read_sample_header(&sigdata->sample[component[n].n], &sample_convert[component[n].n], &offset, f)) {
- free(buffer);
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- if (sigdata->sample[component[n].n].flags & IT_SAMPLE_EXISTS) {
- short *sample;
-
- for (m = n + 1; m < n_components; m++)
- if (component[m].offset > offset)
- break;
- m--;
-
- sample = &component[m].sampfirst;
-
- while (*sample >= 0 && component[*sample].offset <= offset)
- sample = &component[*sample].sampnext;
-
- component[n].sampnext = *sample;
- *sample = n;
-
- component[n].offset = offset;
- }
- }
-
- m = component[n].sampfirst;
-
- while (m >= 0) {
- if (it_seek(f, component[m].offset)) {
- free(buffer);
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- if (it_read_sample_data(cmwt, &sigdata->sample[component[m].n], sample_convert[component[m].n], f)) {
- free(buffer);
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- m = component[m].sampnext;
- }
- }
-
- free(buffer);
- free(component);
-
- _dumb_it_fix_invalid_orders(sigdata);
-
- return sigdata;
-}
-
-
-
-DUH *dumb_read_it_quick(DUMBFILE *f)
-{
- sigdata_t *sigdata;
-
- DUH_SIGTYPE_DESC *descptr = &_dumb_sigtype_it;
-
- sigdata = it_load_sigdata(f);
-
- if (!sigdata)
- return NULL;
-
- {
- const char *tag[1][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);
- }
-}
diff --git a/dumb/dumb-0.9.3/src/it/itread2.c b/dumb/dumb-0.9.3/src/it/itread2.c
deleted file mode 100644
index e152737e..00000000
--- a/dumb/dumb-0.9.3/src/it/itread2.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * itread2.c - Function to read an Impulse Tracker / / \ \
- * module from an open file and do an | < / \_
- * initial run-through. | \/ /\ /
- * \_ / > /
- * Split off from itread.c by entheh. | \ / /
- * | ' /
- * \__/
- */
-
-#include "dumb.h"
-
-
-
-DUH *dumb_read_it(DUMBFILE *f)
-{
- DUH *duh = dumb_read_it_quick(f);
- dumb_it_do_initial_runthrough(duh);
- return duh;
-}
diff --git a/dumb/dumb-0.9.3/src/it/itrender.c b/dumb/dumb-0.9.3/src/it/itrender.c
deleted file mode 100644
index b74b8452..00000000
--- a/dumb/dumb-0.9.3/src/it/itrender.c
+++ /dev/null
@@ -1,3739 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * itrender.c - Code to render an Impulse Tracker / / \ \
- * module. | < / \_
- * | \/ /\ /
- * Written - painstakingly - by entheh. \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <math.h>
-#include <stdlib.h>
-
-#include "dumb.h"
-#include "internal/it.h"
-
-
-
-static IT_PLAYING *dup_playing(IT_PLAYING *src, IT_CHANNEL *dstchannel, IT_CHANNEL *srcchannel)
-{
- IT_PLAYING *dst;
-
- if (!src) return NULL;
-
- dst = malloc(sizeof(*dst));
- if (!dst) return NULL;
-
- dst->flags = src->flags;
-
- ASSERT(src->channel);
- dst->channel = &dstchannel[src->channel - srcchannel];
- dst->sample = src->sample;
- dst->instrument = src->instrument;
- dst->env_instrument = src->env_instrument;
-
- dst->sampnum = src->sampnum;
- dst->instnum = src->instnum;
-
- dst->channel_volume = src->channel_volume;
-
- dst->volume = src->volume;
- dst->pan = src->pan;
-
- dst->note = src->note;
-
- dst->filter_cutoff = src->filter_cutoff;
- dst->filter_resonance = src->filter_resonance;
-
- dst->true_filter_cutoff = src->true_filter_cutoff;
- dst->true_filter_resonance = src->true_filter_resonance;
-
- dst->vibrato_speed = src->vibrato_speed;
- dst->vibrato_depth = src->vibrato_depth;
- dst->vibrato_n = src->vibrato_n;
- dst->vibrato_time = src->vibrato_time;
-
- dst->tremolo_speed = src->tremolo_speed;
- dst->tremolo_depth = src->tremolo_depth;
- dst->tremolo_time = src->tremolo_time;
-
- dst->sample_vibrato_time = src->sample_vibrato_time;
- dst->sample_vibrato_depth = src->sample_vibrato_depth;
-
- dst->slide = src->slide;
- dst->delta = src->delta;
-
- dst->volume_envelope = src->volume_envelope;
- dst->pan_envelope = src->pan_envelope;
- dst->pitch_envelope = src->pitch_envelope;
-
- dst->fadeoutcount = src->fadeoutcount;
-
- dst->filter_state[0] = src->filter_state[0];
- dst->filter_state[1] = src->filter_state[1];
-
- dst->resampler = src->resampler;
- dst->resampler.pickup_data = dst;
- dst->time_lost = src->time_lost;
-
- return dst;
-}
-
-
-
-static void dup_channel(IT_CHANNEL *dst, IT_CHANNEL *src)
-{
- dst->flags = src->flags;
-
- dst->volume = src->volume;
- dst->volslide = src->volslide;
- dst->xm_volslide = src->xm_volslide;
- dst->panslide = src->panslide;
-
- dst->pan = src->pan;
- dst->truepan = src->truepan;
-
- dst->channelvolume = src->channelvolume;
- dst->channelvolslide = src->channelvolslide;
-
- dst->instrument = src->instrument;
- dst->note = src->note;
-
- dst->SFmacro = src->SFmacro;
-
- dst->filter_cutoff = src->filter_cutoff;
- dst->filter_resonance = src->filter_resonance;
-
- dst->key_off_count = src->key_off_count;
- dst->note_cut_count = src->note_cut_count;
- dst->note_delay_count = src->note_delay_count;
- dst->note_delay_entry = src->note_delay_entry;
-
- dst->arpeggio = src->arpeggio;
- dst->retrig = src->retrig;
- dst->xm_retrig = src->xm_retrig;
- dst->retrig_tick = src->retrig_tick;
-
- dst->tremor_time = src->tremor_time;
-
- dst->portamento = src->portamento;
- dst->toneporta = src->toneporta;
- dst->destnote = src->destnote;
-
- dst->sample = src->sample;
- dst->truenote = src->truenote;
-
- dst->midi_state = src->midi_state;
-
- dst->lastvolslide = src->lastvolslide;
- dst->lastDKL = src->lastDKL;
- dst->lastEF = src->lastEF;
- dst->lastG = src->lastG;
- dst->lastHspeed = src->lastHspeed;
- dst->lastHdepth = src->lastHdepth;
- dst->lastRspeed = src->lastRspeed;
- dst->lastRdepth = src->lastRdepth;
- dst->lastI = src->lastI;
- dst->lastJ = src->lastJ;
- dst->lastN = src->lastN;
- dst->lastO = src->lastO;
- dst->high_offset = src->high_offset;
- dst->lastP = src->lastP;
- dst->lastQ = src->lastQ;
- dst->lastS = src->lastS;
- dst->pat_loop_row = src->pat_loop_row;
- dst->pat_loop_count = src->pat_loop_count;
- dst->pat_loop_end_row = src->pat_loop_end_row;
- dst->lastW = src->lastW;
-
- dst->xm_lastE1 = src->xm_lastE1;
- dst->xm_lastE2 = src->xm_lastE2;
- dst->xm_lastEA = src->xm_lastEA;
- dst->xm_lastEB = src->xm_lastEB;
- dst->xm_lastX1 = src->xm_lastX1;
- dst->xm_lastX2 = src->xm_lastX2;
-
- dst->playing = dup_playing(src->playing, dst, src);
-}
-
-
-
-/* Allocate the new callbacks first, then pass them to this function!
- * It will free them on failure.
- */
-static DUMB_IT_SIGRENDERER *dup_sigrenderer(DUMB_IT_SIGRENDERER *src, int n_channels, IT_CALLBACKS *callbacks)
-{
- DUMB_IT_SIGRENDERER *dst;
- int i;
-
- if (!src) {
- if (callbacks) free(callbacks);
- return NULL;
- }
-
- dst = malloc(sizeof(*dst));
- if (!dst) {
- if (callbacks) free(callbacks);
- return NULL;
- }
-
- dst->sigdata = src->sigdata;
-
- dst->n_channels = n_channels;
-
- dst->globalvolume = src->globalvolume;
- dst->globalvolslide = src->globalvolslide;
-
- dst->tempo = src->tempo;
- dst->temposlide = src->temposlide;
-
- for (i = 0; i < DUMB_IT_N_CHANNELS; i++)
- dup_channel(&dst->channel[i], &src->channel[i]);
-
- for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++)
- dst->playing[i] = dup_playing(src->playing[i], dst->channel, src->channel);
-
- dst->tick = src->tick;
- dst->speed = src->speed;
- dst->rowcount = src->rowcount;
-
- dst->order = src->order;
- dst->row = src->row;
- dst->processorder = src->processorder;
- dst->processrow = src->processrow;
- dst->breakrow = src->breakrow;
- dst->pat_loop_row = src->pat_loop_row;
-
- dst->n_rows = src->n_rows;
-
- dst->entry_start = src->entry_start;
- dst->entry = src->entry;
- dst->entry_end = src->entry_end;
-
- dst->time_left = src->time_left;
- dst->sub_time_left = src->sub_time_left;
-
- dst->click_remover = NULL;
-
- dst->callbacks = callbacks;
-
- return dst;
-}
-
-
-
-static IT_MIDI default_midi = {
- /* unsigned char SFmacro[16][16]; */
- {
- {0xF0, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
- },
- /* unsigned char SFmacrolen[16]; */
- {4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},
- /* unsigned short SFmacroz[16]; */
- /* Bitfield; bit 0 set = z in first position */
- {
- 0x0008, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
- 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000
- },
- /* unsigned char Zmacro[128][16]; */
- {
- {0xF0, 0xF0, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0xF0, 0xF0, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0xF0, 0xF0, 0x01, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0xF0, 0xF0, 0x01, 0x18, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0xF0, 0xF0, 0x01, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0xF0, 0xF0, 0x01, 0x28, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0xF0, 0xF0, 0x01, 0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0xF0, 0xF0, 0x01, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0xF0, 0xF0, 0x01, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0xF0, 0xF0, 0x01, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0xF0, 0xF0, 0x01, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0xF0, 0xF0, 0x01, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0xF0, 0xF0, 0x01, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0xF0, 0xF0, 0x01, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0xF0, 0xF0, 0x01, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0xF0, 0xF0, 0x01, 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
-
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
- {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}
- },
- /* unsigned char Zmacrolen[128]; */
- {
- 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
- }
-};
-
-
-
-static void it_reset_filter_state(IT_FILTER_STATE *state)
-{
- state->currsample = 0;
- state->prevsample = 0;
-}
-
-
-
-#define LOG10 2.30258509299
-
-/* IMPORTANT: This function expects one extra sample in 'src' so it can apply
- * click removal. It reads size samples, starting from src[0], and writes its
- * output starting at dst[pos]. The pos parameter is required for getting
- * click removal right.
- */
-static void it_filter(DUMB_CLICK_REMOVER *cr, IT_FILTER_STATE *state, sample_t *dst, long pos, sample_t *src, long size, int step, int sampfreq, int cutoff, int resonance)
-{
- sample_t currsample = state->currsample;
- sample_t prevsample = state->prevsample;
-
- float a, b, c;
-
- long datasize;
-
- {
- float inv_angle = (float)(sampfreq * pow(0.5, 0.25 + cutoff*(1.0/(24<<IT_ENVELOPE_SHIFT))) * (1.0/(2*3.14159265358979323846*110.0)));
- float loss = (float)exp(resonance*(-LOG10*1.2/128.0));
- float d, e;
-#if 0
- loss *= 2; // This is the mistake most players seem to make!
-#endif
-
-#if 1
- d = (1.0f - loss) / inv_angle;
- if (d > 2.0f) d = 2.0f;
- d = (loss - d) * inv_angle;
- e = inv_angle * inv_angle;
- a = 1.0f / (1.0f + d + e);
- c = -e * a;
- b = 1.0f - a - c;
-#else
- a = 1.0f / (inv_angle*inv_angle + inv_angle*loss + loss);
- c = -(inv_angle*inv_angle) * a;
- b = 1.0f - a - c;
-#endif
- }
-
- dst += pos * step;
- datasize = size * step;
-
-#define INT_FILTERS
-#ifdef INT_FILTERS
-#define MULSCA(a, b) ((int)((LONG_LONG)((a) << 4) * (b) >> 32))
-#define SCALEB 12
- {
- int ai = (int)(a * (1 << (16+SCALEB)));
- int bi = (int)(b * (1 << (16+SCALEB)));
- int ci = (int)(c * (1 << (16+SCALEB)));
- int i;
-
- if (cr) {
- sample_t startstep = MULSCA(src[0], ai) + MULSCA(currsample, bi) + MULSCA(prevsample, ci);
- dumb_record_click(cr, pos, startstep);
- }
-
- for (i = 0; i < datasize; i += step) {
- {
- sample_t newsample = MULSCA(src[i], ai) + MULSCA(currsample, bi) + MULSCA(prevsample, ci);
- prevsample = currsample;
- currsample = newsample;
- }
- dst[i] += currsample;
- }
-
- if (cr) {
- sample_t endstep = MULSCA(src[datasize], ai) + MULSCA(currsample, bi) + MULSCA(prevsample, ci);
- dumb_record_click(cr, pos + size, -endstep);
- }
- }
-#else
-#error This version is broken - it does not use step, and state should contain floats for it
- if (cr) {
- float startstep = src[0]*a + currsample*b + prevsample*c;
- dumb_record_click(cr, pos, (sample_t)startstep);
- }
-
- {
- int i = size % 3;
- while (i > 0) {
- {
- float newsample = *src++*a + currsample*b + prevsample*c;
- prevsample = currsample;
- currsample = newsample;
- }
- *dst++ += (sample_t)currsample;
- i--;
- }
- i = size / 3;
- while (i > 0) {
- float newsample;
- /* Gotta love unrolled loops! */
- *dst++ += (sample_t)(newsample = *src++*a + currsample*b + prevsample*c);
- *dst++ += (sample_t)(prevsample = *src++*a + newsample*b + currsample*c);
- *dst++ += (sample_t)(currsample = *src++*a + prevsample*b + newsample*c);
- i--;
- }
- }
-
- if (cr) {
- float endstep = src[datasize]*a + currsample*b + prevsample*c;
- dumb_record_click(cr, pos + size, -(sample_t)endstep);
- }
-#endif
-
- state->currsample = currsample;
- state->prevsample = prevsample;
-}
-
-#undef LOG10
-
-
-
-static signed char it_sine[256] = {
- 0, 2, 3, 5, 6, 8, 9, 11, 12, 14, 16, 17, 19, 20, 22, 23,
- 24, 26, 27, 29, 30, 32, 33, 34, 36, 37, 38, 39, 41, 42, 43, 44,
- 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59,
- 59, 60, 60, 61, 61, 62, 62, 62, 63, 63, 63, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 63, 63, 63, 62, 62, 62, 61, 61, 60, 60,
- 59, 59, 58, 57, 56, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46,
- 45, 44, 43, 42, 41, 39, 38, 37, 36, 34, 33, 32, 30, 29, 27, 26,
- 24, 23, 22, 20, 19, 17, 16, 14, 12, 11, 9, 8, 6, 5, 3, 2,
- 0, -2, -3, -5, -6, -8, -9,-11,-12,-14,-16,-17,-19,-20,-22,-23,
- -24,-26,-27,-29,-30,-32,-33,-34,-36,-37,-38,-39,-41,-42,-43,-44,
- -45,-46,-47,-48,-49,-50,-51,-52,-53,-54,-55,-56,-56,-57,-58,-59,
- -59,-60,-60,-61,-61,-62,-62,-62,-63,-63,-63,-64,-64,-64,-64,-64,
- -64,-64,-64,-64,-64,-64,-63,-63,-63,-62,-62,-62,-61,-61,-60,-60,
- -59,-59,-58,-57,-56,-56,-55,-54,-53,-52,-51,-50,-49,-48,-47,-46,
- -45,-44,-43,-42,-41,-39,-38,-37,-36,-34,-33,-32,-30,-29,-27,-26,
- -24,-23,-22,-20,-19,-17,-16,-14,-12,-11, -9, -8, -6, -5, -3, -2
-};
-
-
-
-#if 0
-/** WARNING: use these! */
-/** JULIEN: Plus for XM compatibility it could be interesting to rename
- * it_sawtooth[] to it_rampdown[], and add an it_rampup[].
- * Also, still for XM compat', twood be good if it was possible to tell the
- * the player not to retrig' the waveform on a new instrument.
- * Both of these are only for completness though, as I don't think it would
- * be very noticeable ;)
- */
-/** ENTHEH: IT also has the 'don't retrig' thingy :) */
-
-static signed char it_sawtooth[256] = {
- 64, 63, 63, 62, 62, 61, 61, 60, 60, 59, 59, 58, 58, 57, 57, 56,
- 56, 55, 55, 54, 54, 53, 53, 52, 52, 51, 51, 50, 50, 49, 49, 48,
- 48, 47, 47, 46, 46, 45, 45, 44, 44, 43, 43, 42, 42, 41, 41, 40,
- 40, 39, 39, 38, 38, 37, 37, 36, 36, 35, 35, 34, 34, 33, 33, 32,
- 32, 31, 31, 30, 30, 29, 29, 28, 28, 27, 27, 26, 26, 25, 25, 24,
- 24, 23, 23, 22, 22, 21, 21, 20, 20, 19, 19, 18, 18, 17, 17, 16,
- 16, 15, 15, 14, 14, 13, 13, 12, 12, 11, 11, 10, 10, 9, 9, 8,
- 8, 7, 7, 6, 6, 5, 5, 4, 4, 3, 3, 2, 2, 1, 1, 0,
- 0, -1, -1, -2, -2, -3, -3, -4, -4, -5, -5, -6, -6, -7, -7, -8,
- -8, -9, -9,-10,-10,-11,-11,-12,-12,-13,-13,-14,-14,-15,-15,-16,
- -16,-17,-17,-18,-18,-19,-19,-20,-20,-21,-21,-22,-22,-23,-23,-24,
- -24,-25,-25,-26,-26,-27,-27,-28,-28,-29,-29,-30,-30,-31,-31,-32,
- -32,-33,-33,-34,-34,-35,-35,-36,-36,-37,-37,-38,-38,-39,-39,-40,
- -40,-41,-41,-42,-42,-43,-43,-44,-44,-45,-45,-46,-46,-47,-47,-48,
- -48,-49,-49,-50,-50,-51,-51,-52,-52,-53,-53,-54,-54,-55,-55,-56,
- -56,-57,-57,-58,-58,-59,-59,-60,-60,-61,-61,-62,-62,-63,-63,-64
-};
-
-
-
-static signed char it_squarewave[256] = {
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-
-#endif
-
-
-
-static void reset_tick_counts(DUMB_IT_SIGRENDERER *sigrenderer)
-{
- int i;
-
- for (i = 0; i < DUMB_IT_N_CHANNELS; i++) {
- IT_CHANNEL *channel = &sigrenderer->channel[i];
- channel->key_off_count = 0;
- channel->note_cut_count = 0;
- channel->note_delay_count = 0;
- }
-}
-
-
-
-static void reset_effects(DUMB_IT_SIGRENDERER *sigrenderer)
-{
- int i;
-
- sigrenderer->globalvolslide = 0;
- sigrenderer->temposlide = 0;
-
- for (i = 0; i < DUMB_IT_N_CHANNELS; i++) {
- IT_CHANNEL *channel = &sigrenderer->channel[i];
- channel->volslide = 0;
- channel->xm_volslide = 0;
- channel->panslide = 0;
- channel->channelvolslide = 0;
- channel->arpeggio = 0;
- channel->retrig = 0;
- if (channel->xm_retrig) {
- channel->xm_retrig = 0;
- channel->retrig_tick = 0;
- }
- channel->tremor_time &= 127;
- channel->portamento = 0;
- channel->toneporta = 0;
- if (channel->playing) {
- channel->playing->vibrato_n = 0;
- channel->playing->tremolo_speed = 0;
- channel->playing->tremolo_depth = 0;
- }
- }
-}
-
-
-
-static void update_tremor(IT_CHANNEL *channel)
-{
- if ((channel->tremor_time & 128) && channel->playing) {
- if (channel->tremor_time == 128)
- channel->tremor_time = (channel->lastI >> 4) | 192;
- else if (channel->tremor_time == 192)
- channel->tremor_time = (channel->lastI & 15) | 128;
- else
- channel->tremor_time--;
- }
-}
-
-
-
-static void it_pickup_loop(DUMB_RESAMPLER *resampler, void *data)
-{
- resampler->pos -= resampler->end - resampler->start;
- ((IT_PLAYING *)data)->time_lost += resampler->end - resampler->start;
-}
-
-
-
-static void it_pickup_pingpong_loop(DUMB_RESAMPLER *resampler, void *data)
-{
- if (resampler->dir < 0) {
- resampler->pos = (resampler->start << 1) - 1 - resampler->pos;
- resampler->subpos ^= 65535;
- resampler->dir = 1;
- ((IT_PLAYING *)data)->time_lost += (resampler->end - resampler->start) << 1;
- } else {
- resampler->pos = (resampler->end << 1) - 1 - resampler->pos;
- resampler->subpos ^= 65535;
- resampler->dir = -1;
- }
-}
-
-
-
-static void it_pickup_stop_at_end(DUMB_RESAMPLER *resampler, void *data)
-{
- (void)data;
-
- if (resampler->dir < 0) {
- resampler->pos = (resampler->start << 1) - 1 - resampler->pos;
- resampler->subpos ^= 65535;
- /* By rights, time_lost would be updated here. However, there is no
- * need at this point; it will not be used.
- *
- * ((IT_PLAYING *)data)->time_lost += (resampler->src_end - resampler->src_start) << 1;
- */
- resampler->dir = 1;
- } else
- 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)) {
- playing->resampler.start = playing->sample->sus_loop_start;
- playing->resampler.end = playing->sample->sus_loop_end;
- if (playing->sample->flags & IT_SAMPLE_PINGPONG_SUS_LOOP)
- playing->resampler.pickup = &it_pickup_pingpong_loop;
- else
- playing->resampler.pickup = &it_pickup_loop;
- } else if (playing->sample->flags & IT_SAMPLE_LOOP) {
- playing->resampler.start = playing->sample->loop_start;
- playing->resampler.end = playing->sample->loop_end;
- if (playing->sample->flags & IT_SAMPLE_PINGPONG_LOOP)
- playing->resampler.pickup = &it_pickup_pingpong_loop;
- else
- playing->resampler.pickup = &it_pickup_loop;
- } else {
- if (playing->sample->flags & IT_SAMPLE_SUS_LOOP)
- playing->resampler.start = playing->sample->sus_loop_start;
- else
- playing->resampler.start = 0;
- playing->resampler.end = playing->sample->length;
- playing->resampler.pickup = &it_pickup_stop_at_end;
- }
- ASSERT(playing->resampler.pickup_data == playing);
-}
-
-
-
-/* This should be called whenever the sample or sample position changes. */
-static void it_playing_reset_resamplers(IT_PLAYING *playing, long pos)
-{
- int bits = playing->sample->flags & IT_SAMPLE_16BIT ? 16 : 8;
- int channels = playing->sample->flags & IT_SAMPLE_STEREO ? 2 : 1;
- dumb_reset_resampler_n(bits, &playing->resampler, playing->sample->data, channels, pos, 0, 0);
- playing->resampler.pickup_data = playing;
- playing->time_lost = 0;
- playing->flags &= ~IT_PLAYING_DEAD;
- it_playing_update_resamplers(playing);
-}
-
-
-
-static void update_retrig(IT_CHANNEL *channel)
-{
- if (channel->xm_retrig) {
- channel->retrig_tick--;
- if (channel->retrig_tick <= 0) {
- if (channel->playing) it_playing_reset_resamplers(channel->playing, 0);
- channel->retrig_tick = channel->xm_retrig;
- }
- } else if (channel->retrig & 0x0F) {
- channel->retrig_tick--;
- if (channel->retrig_tick <= 0) {
- if (channel->retrig < 0x10) {
- } else if (channel->retrig < 0x20) {
- channel->volume--;
- if (channel->volume > 64) channel->volume = 0;
- } else if (channel->retrig < 0x30) {
- channel->volume -= 2;
- if (channel->volume > 64) channel->volume = 0;
- } else if (channel->retrig < 0x40) {
- channel->volume -= 4;
- if (channel->volume > 64) channel->volume = 0;
- } else if (channel->retrig < 0x50) {
- channel->volume -= 8;
- if (channel->volume > 64) channel->volume = 0;
- } else if (channel->retrig < 0x60) {
- channel->volume -= 16;
- if (channel->volume > 64) channel->volume = 0;
- } else if (channel->retrig < 0x70) {
- channel->volume <<= 1;
- channel->volume /= 3;
- } else if (channel->retrig < 0x80) {
- channel->volume >>= 1;
- } else if (channel->retrig < 0x90) {
- } else if (channel->retrig < 0xA0) {
- channel->volume++;
- if (channel->volume > 64) channel->volume = 64;
- } else if (channel->retrig < 0xB0) {
- channel->volume += 2;
- if (channel->volume > 64) channel->volume = 64;
- } else if (channel->retrig < 0xC0) {
- channel->volume += 4;
- if (channel->volume > 64) channel->volume = 64;
- } else if (channel->retrig < 0xD0) {
- channel->volume += 8;
- if (channel->volume > 64) channel->volume = 64;
- } else if (channel->retrig < 0xE0) {
- channel->volume += 16;
- if (channel->volume > 64) channel->volume = 64;
- } else if (channel->retrig < 0xF0) {
- channel->volume *= 3;
- channel->volume >>= 1;
- if (channel->volume > 64) channel->volume = 64;
- } else {
- channel->volume <<= 1;
- if (channel->volume > 64) channel->volume = 64;
- }
- if (channel->playing) it_playing_reset_resamplers(channel->playing, 0);
- channel->retrig_tick = channel->retrig & 0x0F;
- }
- }
-}
-
-
-
-static void update_smooth_effects(DUMB_IT_SIGRENDERER *sigrenderer)
-{
- int i;
-
- for (i = 0; i < DUMB_IT_N_CHANNELS; i++) {
- IT_CHANNEL *channel = &sigrenderer->channel[i];
- IT_PLAYING *playing = channel->playing;
-
- if (playing) {
- playing->vibrato_time += playing->vibrato_n *
- (playing->vibrato_speed << 2);
- playing->tremolo_time += playing->tremolo_speed << 2;
- }
- }
-}
-
-
-
-static void update_effects(DUMB_IT_SIGRENDERER *sigrenderer)
-{
- int i;
-
- if (sigrenderer->globalvolslide) {
- sigrenderer->globalvolume += sigrenderer->globalvolslide;
- if (sigrenderer->globalvolume > 128) {
- if (sigrenderer->globalvolslide >= 0)
- sigrenderer->globalvolume = 128;
- else
- sigrenderer->globalvolume = 0;
- }
- }
-
- if (sigrenderer->temposlide) {
- sigrenderer->tempo += sigrenderer->temposlide;
- if (sigrenderer->tempo < 32) {
- if (sigrenderer->temposlide >= 0)
- sigrenderer->tempo = 255;
- else
- sigrenderer->tempo = 32;
- }
- }
-
- for (i = 0; i < DUMB_IT_N_CHANNELS; i++) {
- IT_CHANNEL *channel = &sigrenderer->channel[i];
- IT_PLAYING *playing = channel->playing;
-
- if (channel->xm_volslide) {
- channel->volume += channel->xm_volslide;
- if (channel->volume > 64) {
- if (channel->xm_volslide >= 0)
- channel->volume = 64;
- else
- channel->volume = 0;
- }
- }
-
- if (channel->volslide) {
- channel->volume += channel->volslide;
- if (channel->volume > 64) {
- if (channel->volslide >= 0)
- channel->volume = 64;
- else
- channel->volume = 0;
- }
- }
-
- if (channel->panslide && !IT_IS_SURROUND(channel->pan)) {
- if (sigrenderer->sigdata->flags & IT_WAS_AN_XM) {
- if (channel->panslide == -128)
- channel->truepan = 32;
- else
- channel->truepan = MID(32, channel->truepan + channel->panslide*64, 32+255*64);
- } else {
- channel->pan += channel->panslide;
- if (channel->pan > 64) {
- if (channel->panslide >= 0)
- channel->pan = 64;
- else
- channel->pan = 0;
- }
- channel->truepan = channel->pan << IT_ENVELOPE_SHIFT;
- }
- }
-
- if (channel->channelvolslide) {
- channel->channelvolume += channel->channelvolslide;
- if (channel->channelvolume > 64) {
- if (channel->channelvolslide >= 0)
- channel->channelvolume = 64;
- else
- channel->channelvolume = 0;
- }
- if (channel->playing)
- channel->playing->channel_volume = channel->channelvolume;
- }
-
- update_tremor(channel);
-
- channel->arpeggio = (channel->arpeggio << 4) | (channel->arpeggio >> 8);
- channel->arpeggio &= 0xFFF;
-
- update_retrig(channel);
-
- if (playing) {
- playing->slide += channel->portamento;
-
- if (sigrenderer->sigdata->flags & IT_LINEAR_SLIDES) {
- if (channel->toneporta && channel->destnote < 120) {
- int currpitch = ((playing->note - 60) << 8) + playing->slide;
- int destpitch = (channel->destnote - 60) << 8;
- if (currpitch > destpitch) {
- currpitch -= channel->toneporta;
- if (currpitch < destpitch) {
- currpitch = destpitch;
- channel->destnote = IT_NOTE_OFF;
- }
- } else if (currpitch < destpitch) {
- currpitch += channel->toneporta;
- if (currpitch > destpitch) {
- currpitch = destpitch;
- channel->destnote = IT_NOTE_OFF;
- }
- }
- playing->slide = currpitch - ((playing->note - 60) << 8);
- }
- } else {
- if (channel->toneporta && channel->destnote < 120) {
- float amiga_multiplier = playing->sample->C5_speed * (1.0f / AMIGA_DIVISOR);
-
- float deltanote = (float)pow(DUMB_SEMITONE_BASE, 60 - playing->note);
- /* deltanote is 1.0 for C-5, 0.5 for C-6, etc. */
-
- float deltaslid = deltanote - playing->slide * amiga_multiplier;
-
- float destdelta = (float)pow(DUMB_SEMITONE_BASE, 60 - channel->destnote);
- if (deltaslid < destdelta) {
- playing->slide -= channel->toneporta;
- deltaslid = deltanote - playing->slide * amiga_multiplier;
- if (deltaslid > destdelta) {
- playing->note = channel->destnote;
- playing->slide = 0;
- channel->destnote = IT_NOTE_OFF;
- }
- } else {
- playing->slide += channel->toneporta;
- deltaslid = deltanote - playing->slide * amiga_multiplier;
- if (deltaslid < destdelta) {
- playing->note = channel->destnote;
- playing->slide = 0;
- channel->destnote = IT_NOTE_OFF;
- }
- }
- }
- }
- }
- }
-
- update_smooth_effects(sigrenderer);
-}
-
-
-
-// This function should be renamed; it doesn't do the 'Update Pattern Variables' operation ittech.txt describes
-/* Returns 1 if a pattern loop is happening. */
-static int update_pattern_variables(DUMB_IT_SIGRENDERER *sigrenderer, IT_ENTRY *entry)
-{
- IT_CHANNEL *channel = &sigrenderer->channel[(int)entry->channel];
-
- if (entry->mask & IT_ENTRY_EFFECT) {
- switch (entry->effect) {
- case IT_JUMP_TO_ORDER:
- sigrenderer->breakrow = 0;
- sigrenderer->processorder = entry->effectvalue - 1;
- sigrenderer->processrow = 0xFFFE;
- break;
-
- case IT_S:
- {
- unsigned char effectvalue = entry->effectvalue;
- if (effectvalue == 0)
- effectvalue = channel->lastS;
- channel->lastS = effectvalue;
- switch (effectvalue >> 4) {
- //case IT_S7:
- case IT_S_PATTERN_LOOP:
- {
- unsigned char v = effectvalue & 15;
- if (v == 0)
- channel->pat_loop_row = sigrenderer->processrow;
- else {
- if (channel->pat_loop_count == 0) {
- channel->pat_loop_count = v;
- sigrenderer->breakrow = channel->pat_loop_row;
- if (sigrenderer->sigdata->flags & IT_WAS_AN_XM) {
- /* For XM files, if a loop occurs by itself, keep breakrow set for when the pattern ends - fun bug in FT2! */
- if (sigrenderer->processrow < 0xFFFE) {
- /* Infinite pattern loops are possible, so we check whether the pattern loop we're hitting now is earlier than the last one we hit. */
- if (sigrenderer->processrow < channel->pat_loop_end_row)
- sigrenderer->processorder = 0xFFFE; /* suspect infinite loop, so trigger loop callback */
- else
- sigrenderer->processorder = 0xFFFF; /* don't trigger loop callback */
- channel->pat_loop_end_row = sigrenderer->processrow;
- sigrenderer->processrow = 0xFFFF; /* special case: don't reset breakrow or pat_loop_end_row */
- }
- } else {
- /* IT files do this regardless of other flow control effects seen here. */
- sigrenderer->processorder = 0xFFFF; /* special case: don't trigger loop callback */
- sigrenderer->processrow = 0xFFFE;
- }
- return 1;
- } else if (--channel->pat_loop_count) {
- sigrenderer->breakrow = channel->pat_loop_row;
- if (sigrenderer->sigdata->flags & IT_WAS_AN_XM) {
- /* For XM files, if a loop occurs by itself, keep breakrow set for when the pattern ends - fun bug in FT2! */
- if (sigrenderer->processrow < 0xFFFE) {
- /* Infinite pattern loops are possible, so we check whether the pattern loop we're hitting now is earlier than the last one we hit. */
- if (sigrenderer->processrow < channel->pat_loop_end_row)
- sigrenderer->processorder = 0xFFFE; /* suspect infinite loop, so trigger loop callback */
- else
- sigrenderer->processorder = 0xFFFF; /* don't trigger loop callback */
- channel->pat_loop_end_row = sigrenderer->processrow;
- sigrenderer->processrow = 0xFFFF; /* special case: don't reset breakrow or pat_loop_end_row */
- }
- } else {
- /* IT files do this regardless of other flow control effects seen here. */
- sigrenderer->processorder = 0xFFFF; /* special case: don't trigger loop callback */
- sigrenderer->processrow = 0xFFFE;
- }
- return 1;
- } else if (sigrenderer->sigdata->flags & IT_WAS_AN_XM) {
- channel->pat_loop_end_row = 0;
- // TODO
- /* Findings:
- - If a pattern loop completes successfully, and then the pattern terminates, then the next pattern will start on the row corresponding to the E60.
- - If a pattern loop doesn't do any loops, and then the pattern terminates, then the next pattern will start on the first row.
- - If a break appears to the left of the pattern loop, it jumps into the relevant position in the next pattern, and that's it.
- - If a break appears to the right of the pattern loop, it jumps to the start of the next pattern, and that's it.
- - If we jump, then effect a loop using an old E60, and then the pattern ends, the next pattern starts on the row corresponding to the E60.
- - Theory: breakrow is not cleared when it's a pattern loop effect!
- */
- //if (sigrenderer->processrow < 0xFFFE) // I have no idea if this is correct or not - FT2 is so weird :(
- // sigrenderer->breakrow = channel->pat_loop_row; /* emulate bug in FT2 */
- } else
- channel->pat_loop_row = sigrenderer->processrow + 1;
- }
- }
- break;
- case IT_S_PATTERN_DELAY:
- sigrenderer->rowcount = 1 + (effectvalue & 15);
- break;
- }
- }
- }
- }
-
- return 0;
-}
-
-
-
-/* This function guarantees that channel->sample will always be valid if it
- * is nonzero. In other words, to check if it is valid, simply check if it is
- * nonzero.
- */
-static void instrument_to_sample(DUMB_IT_SIGDATA *sigdata, IT_CHANNEL *channel)
-{
- if (sigdata->flags & IT_USE_INSTRUMENTS) {
- if (channel->instrument >= 1 && channel->instrument <= sigdata->n_instruments) {
- if (channel->note < 120) {
- channel->sample = sigdata->instrument[channel->instrument-1].map_sample[channel->note];
- channel->truenote = sigdata->instrument[channel->instrument-1].map_note[channel->note];
- } else
- channel->sample = 0;
- } else
- channel->sample = 0;
- } else {
- channel->sample = channel->instrument;
- channel->truenote = channel->note;
- }
- if (!(channel->sample >= 1 && channel->sample <= sigdata->n_samples && (sigdata->sample[channel->sample-1].flags & IT_SAMPLE_EXISTS)))
- channel->sample = 0;
-}
-
-
-
-static void fix_sample_looping(IT_PLAYING *playing)
-{
- if ((playing->sample->flags & (IT_SAMPLE_LOOP | IT_SAMPLE_SUS_LOOP)) ==
- (IT_SAMPLE_LOOP | IT_SAMPLE_SUS_LOOP)) {
- if (playing->resampler.dir < 0) {
- playing->resampler.pos = (playing->sample->sus_loop_end << 1) - 1 - playing->resampler.pos;
- playing->resampler.subpos ^= 65535;
- playing->resampler.dir = 1;
- }
-
- playing->resampler.pos += playing->time_lost;
- }
-}
-
-
-
-static void it_compatible_gxx_retrigger(DUMB_IT_SIGDATA *sigdata, IT_CHANNEL *channel)
-{
- channel->playing->volume_envelope.next_node = 0;
- channel->playing->volume_envelope.tick = 0;
- channel->playing->pan_envelope.next_node = 0;
- channel->playing->pan_envelope.tick = 0;
- channel->playing->pitch_envelope.next_node = 0;
- channel->playing->pitch_envelope.tick = 0;
- channel->playing->fadeoutcount = 1024;
- // Should we remove IT_PLAYING_BACKGROUND? Test with sample with sustain loop...
- channel->playing->flags &= ~(IT_PLAYING_BACKGROUND | IT_PLAYING_SUSTAINOFF | IT_PLAYING_FADING | IT_PLAYING_DEAD);
- it_playing_update_resamplers(channel->playing);
-
- if (channel->sample)
- if (sigdata->flags & IT_USE_INSTRUMENTS)
- channel->playing->env_instrument = &sigdata->instrument[channel->instrument-1];
-}
-
-
-
-static void it_note_off(IT_PLAYING *playing)
-{
- if (playing) {
- playing->flags |= IT_PLAYING_BACKGROUND | IT_PLAYING_SUSTAINOFF;
- fix_sample_looping(playing);
- it_playing_update_resamplers(playing);
- if (playing->instrument)
- if ((playing->instrument->volume_envelope.flags & (IT_ENVELOPE_ON | IT_ENVELOPE_LOOP_ON)) != IT_ENVELOPE_ON)
- playing->flags |= IT_PLAYING_FADING;
- }
-}
-
-
-
-static void xm_note_off(DUMB_IT_SIGDATA *sigdata, IT_CHANNEL *channel)
-{
- if (channel->playing) {
- if (!(sigdata->instrument[channel->instrument-1].volume_envelope.flags & IT_ENVELOPE_ON))
- //if (!(entry->mask & IT_ENTRY_INSTRUMENT))
- // dunno what that was there for ...
- channel->volume = 0;
- channel->playing->flags |= IT_PLAYING_SUSTAINOFF | IT_PLAYING_FADING;
- it_playing_update_resamplers(channel->playing);
- }
-}
-
-
-
-static void it_retrigger_note(DUMB_IT_SIGRENDERER *sigrenderer, IT_CHANNEL *channel)
-{
- DUMB_IT_SIGDATA *sigdata = sigrenderer->sigdata;
- unsigned char nna;
- int i;
-
- if (channel->playing) {
-#ifdef INVALID_NOTES_CAUSE_NOTE_CUT
- if (channel->note == IT_NOTE_OFF)
- nna = NNA_NOTE_OFF;
- else if (channel->note >= 120 || !channel->playing->instrument || (channel->playing->flags & IT_PLAYING_DEAD))
- nna = NNA_NOTE_CUT;
- else
- nna = channel->playing->instrument->new_note_action;
-#else
- if (channel->note == IT_NOTE_CUT)
- nna = NNA_NOTE_CUT;
- if (channel->note >= 120)
- nna = NNA_NOTE_OFF;
- else if (!channel->playing->instrument || (channel->playing->flags & IT_PLAYING_DEAD))
- nna = NNA_NOTE_CUT;
- else
- nna = channel->playing->instrument->new_note_action;
-#endif
-
- switch (nna) {
- case NNA_NOTE_CUT:
- free(channel->playing);
- channel->playing = NULL;
- break;
- case NNA_NOTE_OFF:
- it_note_off(channel->playing);
- break;
- case NNA_NOTE_FADE:
- channel->playing->flags |= IT_PLAYING_BACKGROUND | IT_PLAYING_FADING;
- break;
- }
- }
-
- if (channel->sample == 0 || channel->note >= 120)
- return;
-
- channel->destnote = IT_NOTE_OFF;
-
- if (channel->playing) {
- for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) {
- if (!sigrenderer->playing[i]) {
- sigrenderer->playing[i] = channel->playing;
- channel->playing = NULL;
- break;
- }
- }
-/** WARNING - come up with some more heuristics for replacing old notes */
-#if 0
- if (channel->playing) {
- for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) {
- if (sigrenderer->playing[i]->flags & IT_PLAYING_BACKGROUND) {
- write_seqtime();
- sequence_c(SEQUENCE_STOP_SIGNAL);
- sequence_c(i);
- channel->VChannel = &module->VChannel[i];
- break;
- }
- }
- }
-#endif
- }
-
- if (channel->playing)
- free(channel->playing);
-
- channel->playing = malloc(sizeof(*channel->playing));
-
- if (!channel->playing)
- return;
-
- channel->playing->flags = 0;
- channel->playing->channel = channel;
- channel->playing->sample = &sigdata->sample[channel->sample-1];
- if (sigdata->flags & IT_USE_INSTRUMENTS)
- channel->playing->instrument = &sigdata->instrument[channel->instrument-1];
- else
- channel->playing->instrument = NULL;
- channel->playing->env_instrument = channel->playing->instrument;
- channel->playing->sampnum = channel->sample;
- channel->playing->instnum = channel->instrument;
- channel->playing->channel_volume = channel->channelvolume;
- channel->playing->note = channel->truenote;
- channel->playing->filter_cutoff = 127;
- channel->playing->filter_resonance = 0;
- channel->playing->true_filter_cutoff = 127 << 8;
- channel->playing->true_filter_resonance = 0;
- channel->playing->vibrato_speed = 0;
- channel->playing->vibrato_depth = 0;
- channel->playing->vibrato_n = 0;
- channel->playing->vibrato_time = 0;
- channel->playing->tremolo_speed = 0;
- channel->playing->tremolo_depth = 0;
- channel->playing->tremolo_time = 0;
- channel->playing->sample_vibrato_time = 0;
- channel->playing->sample_vibrato_depth = 0;
- channel->playing->slide = 0;
- channel->playing->volume_envelope.next_node = 0;
- channel->playing->volume_envelope.tick = 0;
- channel->playing->pan_envelope.next_node = 0;
- channel->playing->pan_envelope.tick = 0;
- channel->playing->pitch_envelope.next_node = 0;
- channel->playing->pitch_envelope.tick = 0;
- channel->playing->fadeoutcount = 1024;
- it_reset_filter_state(&channel->playing->filter_state[0]);
- it_reset_filter_state(&channel->playing->filter_state[1]);
- it_playing_reset_resamplers(channel->playing, 0);
-
- /** WARNING - is everything initialised? */
-}
-
-
-
-static void get_default_volpan(DUMB_IT_SIGDATA *sigdata, IT_CHANNEL *channel)
-{
- if (channel->sample == 0)
- return;
-
- channel->volume = sigdata->sample[channel->sample-1].default_volume;
-
- if (sigdata->flags & IT_WAS_AN_XM) {
- if (!(sigdata->flags & IT_WAS_A_MOD))
- channel->truepan = 32 + sigdata->sample[channel->sample-1].default_pan*64;
- return;
- }
-
- {
- int pan = sigdata->sample[channel->sample-1].default_pan;
- if (pan >= 128 && pan <= 192) {
- channel->pan = pan - 128;
- return;
- }
- }
-
- if (sigdata->flags & IT_USE_INSTRUMENTS) {
- IT_INSTRUMENT *instrument = &sigdata->instrument[channel->instrument-1];
- if (instrument->default_pan <= 64)
- channel->pan = instrument->default_pan;
- if (instrument->filter_cutoff >= 128)
- channel->filter_cutoff = instrument->filter_cutoff - 128;
- if (instrument->filter_resonance >= 128)
- channel->filter_resonance = instrument->filter_resonance - 128;
- }
-}
-
-
-
-static void get_true_pan(DUMB_IT_SIGDATA *sigdata, IT_CHANNEL *channel)
-{
- channel->truepan = channel->pan << IT_ENVELOPE_SHIFT;
-
- if (!IT_IS_SURROUND_SHIFTED(channel->truepan) && (sigdata->flags & IT_USE_INSTRUMENTS)) {
- IT_INSTRUMENT *instrument = &sigdata->instrument[channel->instrument-1];
- int truepan = channel->truepan;
- truepan += (channel->note - instrument->pp_centre) * instrument->pp_separation << (IT_ENVELOPE_SHIFT - 3);
- channel->truepan = (unsigned short)MID(0, truepan, 64 << IT_ENVELOPE_SHIFT);
- }
-}
-
-
-
-static void post_process_it_volpan(DUMB_IT_SIGRENDERER *sigrenderer, IT_ENTRY *entry)
-{
- IT_CHANNEL *channel = &sigrenderer->channel[(int)entry->channel];
-
- if (entry->mask & IT_ENTRY_VOLPAN) {
- if (entry->volpan <= 84) {
- /* Volume */
- /* Fine volume slide up */
- /* Fine volume slide down */
- } else if (entry->volpan <= 94) {
- /* Volume slide up */
- unsigned char v = entry->volpan - 85;
- if (v == 0)
- v = channel->lastvolslide;
- channel->lastvolslide = v;
- /* = effect Dx0 where x == entry->volpan - 85 */
- channel->volslide = v;
- } else if (entry->volpan <= 104) {
- /* Volume slide down */
- unsigned char v = entry->volpan - 95;
- if (v == 0)
- v = channel->lastvolslide;
- channel->lastvolslide = v;
- /* = effect D0x where x == entry->volpan - 95 */
- channel->volslide = -v;
- } else if (entry->volpan <= 114) {
- /* Portamento down */
- unsigned char v = (entry->volpan - 105) << 2;
- if (v == 0)
- v = channel->lastEF;
- channel->lastEF = v;
- channel->portamento -= v << 4;
- } else if (entry->volpan <= 124) {
- /* Portamento up */
- unsigned char v = (entry->volpan - 115) << 2;
- if (v == 0)
- v = channel->lastEF;
- channel->lastEF = v;
- channel->portamento += v << 4;
- } else if (entry->volpan <= 202) {
- /* Pan */
- /* Tone Portamento */
- } else if (entry->volpan <= 212) {
- /* Vibrato */
- /* This is unaffected by IT_OLD_EFFECTS. However, if v == 0, then any doubling of depth that happened before (with Hxy in the effect column) will be preserved. */
- unsigned char v = entry->volpan - 203;
- if (v == 0)
- v = channel->lastHdepth;
- else {
- v <<= 2;
- channel->lastHdepth = v;
- }
- if (channel->playing) {
- channel->playing->vibrato_speed = channel->lastHspeed;
- channel->playing->vibrato_depth = v;
- channel->playing->vibrato_n++;
- }
- }
- }
-}
-
-
-
-static void it_send_midi(DUMB_IT_SIGRENDERER *sigrenderer, IT_CHANNEL *channel, unsigned char midi_byte)
-{
- if (sigrenderer->callbacks->midi)
- if ((*sigrenderer->callbacks->midi)(sigrenderer->callbacks->midi_data, channel - sigrenderer->channel, midi_byte))
- return;
-
- switch (channel->midi_state) {
- case 4: /* Ready to receive resonance parameter */
- if (midi_byte < 0x80) channel->filter_resonance = midi_byte;
- channel->midi_state = 0;
- break;
- case 3: /* Ready to receive cutoff parameter */
- if (midi_byte < 0x80) channel->filter_cutoff = midi_byte;
- channel->midi_state = 0;
- break;
- case 2: /* Ready for byte specifying which parameter will follow */
- if (midi_byte == 0) /* Cutoff */
- channel->midi_state = 3;
- else if (midi_byte == 1) /* Resonance */
- channel->midi_state = 4;
- else
- channel->midi_state = 0;
- break;
- default: /* Counting initial F0 bytes */
- switch (midi_byte) {
- case 0xF0:
- channel->midi_state++;
- break;
- case 0xFA:
- case 0xFC:
- case 0xFF:
- /* Reset filter parameters for all channels */
- {
- int i;
- for (i = 0; i < DUMB_IT_N_CHANNELS; i++) {
- sigrenderer->channel[i].filter_cutoff = 127;
- sigrenderer->channel[i].filter_resonance = 0;
- //// should we be resetting channel[i].playing->filter_* here?
- }
- }
- /* Fall through */
- default:
- channel->midi_state = 0;
- break;
- }
- }
-}
-
-
-
-static void xm_envelope_calculate_value(IT_ENVELOPE *envelope, IT_PLAYING_ENVELOPE *pe)
-{
- if (pe->next_node <= 0)
- pe->value = envelope->node_y[0] << IT_ENVELOPE_SHIFT;
- else if (pe->next_node >= envelope->n_nodes)
- pe->value = envelope->node_y[envelope->n_nodes-1] << IT_ENVELOPE_SHIFT;
- else {
- int ys = envelope->node_y[pe->next_node-1] << IT_ENVELOPE_SHIFT;
- int ts = envelope->node_t[pe->next_node-1];
- int te = envelope->node_t[pe->next_node];
-
- if (ts == te)
- pe->value = ys;
- else {
- int ye = envelope->node_y[pe->next_node] << IT_ENVELOPE_SHIFT;
- int t = pe->tick;
-
- pe->value = ys + (ye - ys) * (t - ts) / (te - ts);
- }
- }
-}
-
-
-
-/* Returns 1 if a callback caused termination of playback. */
-static int process_effects(DUMB_IT_SIGRENDERER *sigrenderer, IT_ENTRY *entry, int ignore_cxx)
-{
- DUMB_IT_SIGDATA *sigdata = sigrenderer->sigdata;
-
- IT_CHANNEL *channel = &sigrenderer->channel[(int)entry->channel];
-
- if (entry->mask & IT_ENTRY_EFFECT) {
- switch (entry->effect) {
-/*
-Notes about effects (as compared to other module formats)
-
-C This is now in *HEX*. (Used to be in decimal in ST3)
-E/F/G/H/U You need to check whether the song uses Amiga/Linear slides.
-H/U Vibrato in Impulse Tracker is two times finer than in
- any other tracker and is updated EVERY tick.
- If "Old Effects" is *ON*, then the vibrato is played in the
- normal manner (every non-row tick and normal depth)
-E/F/G These commands ALL share the same memory.
-Oxx Offsets to samples are to the 'xx00th' SAMPLE. (ie. for
- 16 bit samples, the offset is xx00h*2)
- Oxx past the sample end will be ignored, unless "Old Effects"
- is ON, in which case the Oxx will play from the end of the
- sample.
-Yxy This uses a table 4 times larger (hence 4 times slower) than
- vibrato or tremelo. If the waveform is set to random, then
- the 'speed' part of the command is interpreted as a delay.
-*/
- case IT_SET_SPEED:
- if (entry->effectvalue)
- sigrenderer->tick = sigrenderer->speed = entry->effectvalue;
- else if (sigdata->flags & IT_WAS_AN_XM) {
- sigrenderer->speed = 0;
- if (sigrenderer->callbacks->xm_speed_zero && (*sigrenderer->callbacks->xm_speed_zero)(sigrenderer->callbacks->xm_speed_zero_data))
- return 1;
- }
- break;
-
- case IT_BREAK_TO_ROW:
- if (ignore_cxx) break;
- sigrenderer->breakrow = entry->effectvalue;
- sigrenderer->processrow = 0xFFFE;
- break;
-
- case IT_VOLSLIDE_VIBRATO:
- if (channel->playing) {
- channel->playing->vibrato_speed = channel->lastHspeed;
- channel->playing->vibrato_depth = channel->lastHdepth;
- channel->playing->vibrato_n++;
- }
- /* Fall through and process volume slide. */
- case IT_VOLUME_SLIDE:
- case IT_VOLSLIDE_TONEPORTA:
- /* The tone portamento component is handled elsewhere. */
- {
- unsigned char v = entry->effectvalue;
- if (!(sigdata->flags & IT_WAS_A_MOD)) {
- if (v == 0)
- v = channel->lastDKL;
- channel->lastDKL = v;
- }
- if ((v & 0x0F) == 0) { /* Dx0 */
- channel->volslide = v >> 4;
- if (channel->volslide == 15 && !(sigdata->flags & IT_WAS_AN_XM)) {
- channel->volume += 15;
- if (channel->volume > 64) channel->volume = 64;
- }
- } else if ((v & 0xF0) == 0) { /* D0x */
- channel->volslide = -v;
- if (channel->volslide == -15 && !(sigdata->flags & IT_WAS_AN_XM)) {
- channel->volume -= 15;
- if (channel->volume > 64) channel->volume = 0;
- }
- } else if ((v & 0x0F) == 0x0F) { /* DxF */
- channel->volume += v >> 4;
- if (channel->volume > 64) channel->volume = 64;
- } else if ((v & 0xF0) == 0xF0) { /* DFx */
- channel->volume -= v & 15;
- if (channel->volume > 64) channel->volume = 0;
- }
- }
- break;
- case IT_XM_FINE_VOLSLIDE_DOWN:
- {
- unsigned char v = entry->effectvalue;
- if (v == 0)
- v = channel->xm_lastEB;
- channel->xm_lastEB = v;
- channel->volume -= v;
- if (channel->volume > 64) channel->volume = 0;
- }
- break;
- case IT_XM_FINE_VOLSLIDE_UP:
- {
- unsigned char v = entry->effectvalue;
- if (v == 0)
- v = channel->xm_lastEA;
- channel->xm_lastEA = v;
- channel->volume += v;
- if (channel->volume > 64) channel->volume = 64;
- }
- break;
- case IT_PORTAMENTO_DOWN:
- {
- unsigned char v = entry->effectvalue;
- if (sigdata->flags & IT_WAS_AN_XM) {
- if (!(sigdata->flags & IT_WAS_A_MOD)) {
- if (v == 0xF0)
- v |= channel->xm_lastE2;
- else if (v >= 0xF0)
- channel->xm_lastE2 = v & 15;
- else if (v == 0xE0)
- v |= channel->xm_lastX2;
- else
- channel->xm_lastX2 = v & 15;
- }
- } else {
- if (v == 0)
- v = channel->lastEF;
- channel->lastEF = v;
- }
- if (channel->playing) {
- if ((v & 0xF0) == 0xF0)
- channel->playing->slide -= (v & 15) << 4;
- else if ((v & 0xF0) == 0xE0)
- channel->playing->slide -= (v & 15) << 2;
- else
- channel->portamento -= v << 4;
- }
- }
- break;
- case IT_PORTAMENTO_UP:
- {
- unsigned char v = entry->effectvalue;
- if (sigdata->flags & IT_WAS_AN_XM) {
- if (!(sigdata->flags & IT_WAS_A_MOD)) {
- if (v == 0xF0)
- v |= channel->xm_lastE1;
- else if (v >= 0xF0)
- channel->xm_lastE1 = v & 15;
- else if (v == 0xE0)
- v |= channel->xm_lastX1;
- else
- channel->xm_lastX1 = v & 15;
- }
- } else {
- if (v == 0)
- v = channel->lastEF;
- channel->lastEF = v;
- }
- if (channel->playing) {
- if ((v & 0xF0) == 0xF0)
- channel->playing->slide += (v & 15) << 4;
- else if ((v & 0xF0) == 0xE0)
- channel->playing->slide += (v & 15) << 2;
- else
- channel->portamento += v << 4;
- }
- }
- break;
- case IT_XM_PORTAMENTO_DOWN:
- {
- unsigned char v = entry->effectvalue;
- if (!(sigdata->flags & IT_WAS_A_MOD)) {
- if (v == 0)
- v = channel->lastJ;
- channel->lastJ = v;
- }
- if (channel->playing)
- channel->portamento -= v << 4;
- }
- break;
- case IT_XM_PORTAMENTO_UP:
- {
- unsigned char v = entry->effectvalue;
- if (!(sigdata->flags & IT_WAS_A_MOD)) {
- if (v == 0)
- v = channel->lastEF;
- channel->lastEF = v;
- }
- if (channel->playing)
- channel->portamento += v << 4;
- }
- break;
- case IT_XM_KEY_OFF:
- channel->key_off_count = entry->effectvalue;
- if (!channel->key_off_count) xm_note_off(sigdata, channel);
- break;
- case IT_VIBRATO:
- {
- unsigned char speed = entry->effectvalue >> 4;
- unsigned char depth = entry->effectvalue & 15;
- if (speed == 0)
- speed = channel->lastHspeed;
- channel->lastHspeed = speed;
- if (depth == 0)
- depth = channel->lastHdepth;
- else {
- if (sigdata->flags & IT_OLD_EFFECTS)
- depth <<= 3;
- else
- depth <<= 2;
- channel->lastHdepth = depth;
- }
- if (channel->playing) {
- channel->playing->vibrato_speed = speed;
- channel->playing->vibrato_depth = depth;
- channel->playing->vibrato_n++;
- }
- }
- break;
- case IT_TREMOR:
- {
- unsigned char v = entry->effectvalue;
- if (v == 0)
- v = channel->lastI;
- else if (!(sigdata->flags & IT_OLD_EFFECTS)) {
- if (v & 0xF0) v -= 0x10;
- if (v & 0x0F) v -= 0x01;
- }
- channel->lastI = v;
- channel->tremor_time |= 128;
- }
- update_tremor(channel);
- break;
- case IT_ARPEGGIO:
- {
- unsigned char v = entry->effectvalue;
- /* XM files have no memory for arpeggio (000 = no effect)
- * and we use lastJ for portamento down instead.
- */
- if (!(sigdata->flags & IT_WAS_AN_XM)) {
- if (v == 0)
- v = channel->lastJ;
- channel->lastJ = v;
- }
- channel->arpeggio = v;
- }
- break;
- case IT_SET_CHANNEL_VOLUME:
- if (sigdata->flags & IT_WAS_AN_XM)
- channel->volume = MIN(entry->effectvalue, 64);
- else if (entry->effectvalue <= 64)
- channel->channelvolume = entry->effectvalue;
-#ifdef VOLUME_OUT_OF_RANGE_SETS_MAXIMUM
- else
- channel->channelvolume = 64;
-#endif
- if (channel->playing)
- channel->playing->channel_volume = channel->channelvolume;
- break;
- case IT_CHANNEL_VOLUME_SLIDE:
- {
- unsigned char v = entry->effectvalue;
- if (v == 0)
- v = channel->lastN;
- channel->lastN = v;
- if ((v & 0x0F) == 0) { /* Nx0 */
- channel->channelvolslide = v >> 4;
- } else if ((v & 0xF0) == 0) { /* N0x */
- channel->channelvolslide = -v;
- } else {
- if ((v & 0x0F) == 0x0F) { /* NxF */
- channel->channelvolume += v >> 4;
- if (channel->channelvolume > 64) channel->channelvolume = 64;
- } else if ((v & 0xF0) == 0xF0) { /* NFx */
- channel->channelvolume -= v & 15;
- if (channel->channelvolume > 64) channel->channelvolume = 0;
- } else
- break;
- if (channel->playing)
- channel->playing->channel_volume = channel->channelvolume;
- }
- }
- break;
- case IT_SET_SAMPLE_OFFSET:
- {
- unsigned char v = entry->effectvalue;
- if (sigdata->flags & IT_WAS_A_MOD) {
- if (v == 0) break;
- } else {
- if (v == 0)
- v = channel->lastO;
- channel->lastO = v;
- }
- /* Note: we set the offset even if tone portamento is
- * specified. Impulse Tracker does the same.
- */
- if (entry->mask & IT_ENTRY_NOTE) {
- if (channel->playing) {
- int offset = ((int)channel->high_offset << 16) | ((int)v << 8);
- IT_PLAYING *playing = channel->playing;
- IT_SAMPLE *sample = playing->sample;
- int end;
- if ((sample->flags & IT_SAMPLE_SUS_LOOP) && !(playing->flags & IT_PLAYING_SUSTAINOFF))
- end = sample->sus_loop_end;
- else if (sample->flags & IT_SAMPLE_LOOP)
- end = sample->loop_end;
- else
- end = sample->length;
- if (offset < end)
- it_playing_reset_resamplers(playing, offset);
- else if (sigdata->flags & IT_OLD_EFFECTS)
- it_playing_reset_resamplers(playing, end);
- }
- }
- }
- break;
- case IT_PANNING_SLIDE:
- /** JULIEN: guess what? the docs are wrong! (how unusual ;)
- * Pxy seems to memorize its previous value... and there
- * might be other mistakes like that... (sigh!)
- */
- /** ENTHEH: umm... but... the docs say that Pxy memorises its
- * value... don't they? :o
- */
- {
- unsigned char v = entry->effectvalue;
- int p = channel->truepan;
- if (sigdata->flags & IT_WAS_AN_XM)
- p >>= 6;
- else {
- p = (p + 128) >> 8;
- channel->pan = p;
- }
- if (v == 0)
- v = channel->lastP;
- channel->lastP = v;
- if ((v & 0x0F) == 0) { /* Px0 */
- channel->panslide = v >> 4;
- } else if ((v & 0xF0) == 0) { /* P0x */
- channel->panslide = -v;
- } else if ((v & 0x0F) == 0x0F) { /* PxF */
- p += v >> 4;
- } else if ((v & 0xF0) == 0xF0) { /* PFx */
- p -= v & 15;
- }
- if (sigdata->flags & IT_WAS_AN_XM)
- channel->truepan = 32 + MID(0, p, 255) * 64;
- else if (!IT_IS_SURROUND(channel->pan)) {
- channel->pan = p;
- channel->truepan = p << 8;
- }
- }
- break;
- case IT_RETRIGGER_NOTE:
- {
- unsigned char v = entry->effectvalue;
- if (sigdata->flags & IT_WAS_AN_XM) {
- if ((v & 0x0F) == 0) v |= channel->lastQ & 0x0F;
- if ((v & 0xF0) == 0) v |= channel->lastQ & 0xF0;
- } else {
- if (v == 0)
- v = channel->lastQ;
- }
- channel->lastQ = v;
- if ((v & 0x0F) == 0) v |= 0x01;
- channel->retrig = v;
- if (entry->mask & IT_ENTRY_NOTE) {
- channel->retrig_tick = v & 0x0F;
- /* Emulate a bug */
- if (sigdata->flags & IT_WAS_AN_XM)
- update_retrig(channel);
- } else
- update_retrig(channel);
- }
- break;
- case IT_XM_RETRIGGER_NOTE:
- channel->retrig_tick = channel->xm_retrig = entry->effectvalue;
- if (entry->effectvalue == 0)
- if (channel->playing) it_playing_reset_resamplers(channel->playing, 0);
- break;
- case IT_TREMOLO:
- {
- unsigned char speed = entry->effectvalue >> 4;
- unsigned char depth = entry->effectvalue & 15;
- if (speed == 0)
- speed = channel->lastRspeed;
- channel->lastRspeed = speed;
- if (depth == 0)
- depth = channel->lastRdepth;
- channel->lastRdepth = depth;
- if (channel->playing) {
- channel->playing->tremolo_speed = speed;
- channel->playing->tremolo_depth = depth;
- }
- }
- break;
- case IT_S:
- {
- /* channel->lastS was set in update_pattern_variables(). */
- unsigned char effectvalue = channel->lastS;
- switch (effectvalue >> 4) {
- //case IT_S_SET_FILTER:
- //case IT_S_SET_GLISSANDO_CONTROL:
- //case IT_S_FINETUNE:
- //case IT_S_SET_VIBRATO_WAVEFORM:
- //case IT_S_SET_TREMOLO_WAVEFORM:
- //case IT_S_SET_PANBRELLO_WAVEFORM:
- /* Waveforms for commands S3x, S4x and S5x:
- * 0: Sine wave
- * 1: Ramp down
- * 2: Square wave
- * 3: Random wave
- */
- case IT_S_FINE_PATTERN_DELAY:
- sigrenderer->tick += effectvalue & 15;
- break;
- //case IT_S7:
- case IT_S_SET_PAN:
- ASSERT(!(sigdata->flags & IT_WAS_AN_XM));
- channel->pan =
- ((effectvalue & 15) << 2) |
- ((effectvalue & 15) >> 2);
- channel->truepan = channel->pan << IT_ENVELOPE_SHIFT;
- break;
- case IT_S_SET_SURROUND_SOUND:
- if ((effectvalue & 15) == 1) {
- channel->pan = IT_SURROUND;
- channel->truepan = channel->pan << IT_ENVELOPE_SHIFT;
- }
- break;
- case IT_S_SET_HIGH_OFFSET:
- channel->high_offset = effectvalue & 15;
- break;
- //case IT_S_PATTERN_LOOP:
- case IT_S_DELAYED_NOTE_CUT:
- channel->note_cut_count = effectvalue & 15;
- if (!channel->note_cut_count) {
- if (sigdata->flags & IT_WAS_AN_XM)
- channel->volume = 0;
- else
- channel->note_cut_count = 1;
- }
- break;
- case IT_S_SET_MIDI_MACRO:
- channel->SFmacro = effectvalue & 15;
- break;
- }
- }
- break;
- case IT_SET_SONG_TEMPO:
- {
- unsigned char v = entry->effectvalue;
- if (v == 0)
- v = channel->lastW;
- channel->lastW = v;
- if (v < 0x10)
- sigrenderer->temposlide = -v;
- else if (v < 0x20)
- sigrenderer->temposlide = v & 15;
- else
- sigrenderer->tempo = v;
- }
- break;
- case IT_FINE_VIBRATO:
- {
- unsigned char speed = entry->effectvalue >> 4;
- unsigned char depth = entry->effectvalue & 15;
- if (speed == 0)
- speed = channel->lastHspeed;
- channel->lastHspeed = speed;
- if (depth == 0)
- depth = channel->lastHdepth;
- else {
- if (sigdata->flags & IT_OLD_EFFECTS)
- depth <<= 1;
- channel->lastHdepth = depth;
- }
- if (channel->playing) {
- channel->playing->vibrato_speed = speed;
- channel->playing->vibrato_depth = depth;
- channel->playing->vibrato_n++;
- }
- }
- break;
- case IT_SET_GLOBAL_VOLUME:
- if (entry->effectvalue <= 128)
- sigrenderer->globalvolume = entry->effectvalue;
-#ifdef VOLUME_OUT_OF_RANGE_SETS_MAXIMUM
- else
- sigrenderer->globalvolume = 128;
-#endif
- break;
- case IT_GLOBAL_VOLUME_SLIDE:
- {
- unsigned char v = entry->effectvalue;
- if (v == 0)
- v = channel->lastW;
- channel->lastW = v;
- if ((v & 0x0F) == 0) { /* Wx0 */
- sigrenderer->globalvolslide =
- (sigdata->flags & IT_WAS_AN_XM) ? (v >> 4)*2 : (v >> 4);
- } else if ((v & 0xF0) == 0) { /* W0x */
- sigrenderer->globalvolslide =
- (sigdata->flags & IT_WAS_AN_XM) ? (-v)*2 : (-v);
- } else if ((v & 0x0F) == 0x0F) { /* WxF */
- sigrenderer->globalvolume += v >> 4;
- if (sigrenderer->globalvolume > 128) sigrenderer->globalvolume = 128;
- } else if ((v & 0xF0) == 0xF0) { /* WFx */
- sigrenderer->globalvolume -= v & 15;
- if (sigrenderer->globalvolume > 128) sigrenderer->globalvolume = 0;
- }
- }
- break;
- case IT_SET_PANNING:
- if (sigdata->flags & IT_WAS_AN_XM)
- channel->truepan = 32 + entry->effectvalue*64;
- else {
- channel->pan = (entry->effectvalue + 2) >> 2;
- channel->truepan = channel->pan << IT_ENVELOPE_SHIFT;
- }
- break;
- //case IT_PANBRELLO:
- case IT_MIDI_MACRO:
- {
- IT_MIDI *midi = sigdata->midi ? sigdata->midi : &default_midi;
- if (entry->effectvalue >= 0x80) {
- int n = midi->Zmacrolen[entry->effectvalue-0x80];
- int i;
- for (i = 0; i < n; i++)
- it_send_midi(sigrenderer, channel, midi->Zmacro[entry->effectvalue-0x80][i]);
- } else {
- int n = midi->SFmacrolen[channel->SFmacro];
- int i, j;
- for (i = 0, j = 1; i < n; i++, j <<= 1)
- it_send_midi(sigrenderer, channel,
- (unsigned char)(midi->SFmacroz[channel->SFmacro] & j ?
- entry->effectvalue : midi->SFmacro[channel->SFmacro][i]));
- }
- }
- break;
- case IT_XM_SET_ENVELOPE_POSITION:
- if (channel->playing && channel->playing->env_instrument) {
- IT_ENVELOPE *envelope = &channel->playing->env_instrument->volume_envelope;
- if (envelope->flags & IT_ENVELOPE_ON) {
- IT_PLAYING_ENVELOPE *pe = &channel->playing->volume_envelope;
- pe->tick = entry->effectvalue;
- if (pe->tick >= envelope->node_t[envelope->n_nodes-1])
- pe->tick = envelope->node_t[envelope->n_nodes-1];
- pe->next_node = 0;
- while (pe->tick > envelope->node_t[pe->next_node]) pe->next_node++;
- xm_envelope_calculate_value(envelope, pe);
- }
- }
- break;
- }
- }
-
- if (!(sigdata->flags & IT_WAS_AN_XM))
- post_process_it_volpan(sigrenderer, entry);
-
- return 0;
-}
-
-
-
-static int process_it_note_data(DUMB_IT_SIGRENDERER *sigrenderer, IT_ENTRY *entry)
-{
- DUMB_IT_SIGDATA *sigdata = sigrenderer->sigdata;
- IT_CHANNEL *channel = &sigrenderer->channel[(int)entry->channel];
-
- // When tone portamento and instrument are specified:
- // If Gxx is off:
- // - same sample, do nothing but portamento
- // - diff sample, retrigger all but keep current note+slide + do porta
- // - if instrument is invalid, nothing; if sample is invalid, cut
- // If Gxx is on:
- // - same sample or new sample invalid, retrigger envelopes and initialise note value for portamento to 'seek' to
- // - diff sample/inst, start using new envelopes
- // When tone portamento is specified alone, sample won't change.
- // TODO: consider what happens with instrument alone after all this...
-
- if (entry->mask & (IT_ENTRY_NOTE | IT_ENTRY_INSTRUMENT)) {
- if (entry->mask & IT_ENTRY_INSTRUMENT)
- channel->instrument = entry->instrument;
- instrument_to_sample(sigdata, channel);
- if (channel->note < 120) {
- if ((sigdata->flags & IT_USE_INSTRUMENTS) && channel->sample == 0)
- return 1;
- if (entry->mask & IT_ENTRY_INSTRUMENT)
- get_default_volpan(sigdata, channel);
- } else
- it_retrigger_note(sigrenderer, channel); /* Stop the note */
- }
-
- /** WARNING: This is not ideal, since channel->playing might not get allocated owing to lack of memory... */
- if (((entry->mask & IT_ENTRY_VOLPAN) && entry->volpan >= 193 && entry->volpan <= 202) ||
- ((entry->mask & IT_ENTRY_EFFECT) && (entry->effect == IT_TONE_PORTAMENTO || entry->effect == IT_VOLSLIDE_TONEPORTA)))
- {
- if (channel->playing && (entry->mask & IT_ENTRY_INSTRUMENT)) {
- if (sigdata->flags & IT_COMPATIBLE_GXX)
- it_compatible_gxx_retrigger(sigdata, channel);
- else if ((!(sigdata->flags & IT_USE_INSTRUMENTS) ||
- (channel->instrument >= 1 && channel->instrument <= sigdata->n_instruments)) &&
- channel->sample != channel->playing->sampnum)
- {
- unsigned char note = channel->playing->note;
- int slide = channel->playing->slide;
- it_retrigger_note(sigrenderer, channel);
- if (channel->playing) {
- channel->playing->note = note;
- channel->playing->slide = slide;
- // Should we be preserving sample_vibrato_time? depth?
- }
- }
- }
-
- if ((entry->mask & IT_ENTRY_VOLPAN) && entry->volpan >= 193 && entry->volpan <= 202) {
- /* Tone Portamento in the volume column */
- static const unsigned char slidetable[] = {0, 1, 4, 8, 16, 32, 64, 96, 128, 255};
- unsigned char v = slidetable[entry->volpan - 193];
- if (sigdata->flags & IT_COMPATIBLE_GXX) {
- if (v == 0)
- v = channel->lastG;
- channel->lastG = v;
- } else {
- if (v == 0)
- v = channel->lastEF;
- channel->lastEF = v;
- }
- if ((entry->mask & IT_ENTRY_NOTE) || ((sigdata->flags & IT_COMPATIBLE_GXX) && (entry->mask & IT_ENTRY_INSTRUMENT))) {
- if (channel->sample)
- channel->destnote = channel->truenote;
- else
- channel->destnote = channel->note;
- }
- channel->toneporta = v << 4;
- } else {
- /* Tone Portamento in the effect column */
- unsigned char v;
- if (entry->effect == IT_TONE_PORTAMENTO)
- v = entry->effectvalue;
- else
- v = 0;
- if (sigdata->flags & IT_COMPATIBLE_GXX) {
- if (v == 0)
- v = channel->lastG;
- channel->lastG = v;
- } else {
- if (v == 0)
- v = channel->lastEF;
- channel->lastEF = v;
- }
- if ((entry->mask & IT_ENTRY_NOTE) || ((sigdata->flags & IT_COMPATIBLE_GXX) && (entry->mask & IT_ENTRY_INSTRUMENT))) {
- if (channel->sample)
- channel->destnote = channel->truenote;
- else
- channel->destnote = channel->note;
- }
- channel->toneporta = v << 4;
- }
- if (channel->playing) goto skip_start_note;
- }
-
- if ((entry->mask & IT_ENTRY_NOTE) ||
- ((entry->mask & IT_ENTRY_INSTRUMENT) && (!channel->playing || entry->instrument != channel->playing->instnum)))
- {
- if (channel->note < 120) {
- get_true_pan(sigdata, channel);
- it_retrigger_note(sigrenderer, channel);
- }
- }
-
- skip_start_note:
-
- if (entry->mask & IT_ENTRY_VOLPAN) {
- if (entry->volpan <= 64) {
- /* Volume */
- channel->volume = entry->volpan;
- } else if (entry->volpan <= 74) {
- /* Fine volume slide up */
- unsigned char v = entry->volpan - 65;
- if (v == 0)
- v = channel->lastvolslide;
- channel->lastvolslide = v;
- /* = effect DxF where x == entry->volpan - 65 */
- channel->volume += v;
- if (channel->volume > 64) channel->volume = 64;
- } else if (entry->volpan <= 84) {
- /* Fine volume slide down */
- unsigned char v = entry->volpan - 75;
- if (v == 0)
- v = channel->lastvolslide;
- channel->lastvolslide = v;
- /* = effect DFx where x == entry->volpan - 75 */
- channel->volume -= v;
- if (channel->volume > 64) channel->volume = 0;
- } else if (entry->volpan < 128) {
- /* Volume slide up */
- /* Volume slide down */
- /* Portamento down */
- /* Portamento up */
- } else if (entry->volpan <= 192) {
- /* Pan */
- channel->pan = entry->volpan - 128;
- channel->truepan = channel->pan << IT_ENVELOPE_SHIFT;
- }
- /* else */
- /* Tone Portamento */
- /* Vibrato */
- }
- return 0;
-}
-
-
-
-static void retrigger_xm_envelopes(IT_PLAYING *playing)
-{
- playing->volume_envelope.next_node = 0;
- playing->volume_envelope.tick = -1;
- playing->pan_envelope.next_node = 0;
- playing->pan_envelope.tick = -1;
- playing->fadeoutcount = 1024;
-}
-
-
-
-static void process_xm_note_data(DUMB_IT_SIGRENDERER *sigrenderer, IT_ENTRY *entry)
-{
- DUMB_IT_SIGDATA *sigdata = sigrenderer->sigdata;
- IT_CHANNEL *channel = &sigrenderer->channel[(int)entry->channel];
-
- if (entry->mask & IT_ENTRY_INSTRUMENT) {
- channel->instrument = entry->instrument;
- instrument_to_sample(sigdata, channel);
- if (channel->playing) {
- /* Retrigger vol/pan envelopes if enabled, and cancel fadeout.
- * Also reset vol/pan to that of _original_ instrument.
- */
- channel->playing->flags &= ~(IT_PLAYING_SUSTAINOFF | IT_PLAYING_FADING);
- it_playing_update_resamplers(channel->playing);
-
- channel->volume = channel->playing->sample->default_volume;
- if (!(sigdata->flags & IT_WAS_A_MOD))
- channel->truepan = 32 + channel->playing->sample->default_pan*64;
-
- retrigger_xm_envelopes(channel->playing);
- }
- }
-
- if (!((entry->mask & IT_ENTRY_EFFECT) && entry->effect == IT_XM_KEY_OFF && entry->effectvalue == 0) &&
- (entry->mask & IT_ENTRY_NOTE))
- {
- if (!(entry->mask & IT_ENTRY_INSTRUMENT))
- instrument_to_sample(sigdata, channel);
-
- if (channel->note >= 120)
- xm_note_off(sigdata, channel);
- else if (channel->sample == 0) {
- /** If we get here, one of the following is the case:
- ** 1. The instrument has never been specified on this channel.
- ** 2. The specified instrument is invalid.
- ** 3. The instrument has no sample mapped to the selected note.
- ** What should happen?
- **
- ** Experimentation shows that any existing note stops and cannot
- ** be brought back. A subsequent instrument change fixes that.
- **/
- if (channel->playing) {
- free(channel->playing);
- channel->playing = NULL;
- }
- return;
- } else if (channel->playing && (entry->mask & IT_ENTRY_VOLPAN) && ((entry->volpan>>4) == 0xF)) {
- /* Don't retrigger note; portamento in the volume column. */
- } else if (channel->playing &&
- (entry->mask & IT_ENTRY_EFFECT) &&
- (entry->effect == IT_TONE_PORTAMENTO ||
- entry->effect == IT_VOLSLIDE_TONEPORTA)) {
- /* Don't retrigger note; portamento in the effects column. */
- } else {
- channel->destnote = IT_NOTE_OFF;
-
- if (!channel->playing) {
- channel->playing = malloc(sizeof(*channel->playing));
- if (!channel->playing)
- return;
- // Adding the following seems to do the trick for the case where a piece starts with an instrument alone and then some notes alone.
- retrigger_xm_envelopes(channel->playing);
- }
-
- channel->playing->flags = 0;
- channel->playing->channel = channel;
- channel->playing->sample = &sigdata->sample[channel->sample-1];
- if (sigdata->flags & IT_USE_INSTRUMENTS)
- channel->playing->instrument = &sigdata->instrument[channel->instrument-1];
- else
- channel->playing->instrument = NULL;
- channel->playing->env_instrument = channel->playing->instrument;
- channel->playing->sampnum = channel->sample;
- channel->playing->instnum = channel->instrument;
- channel->playing->channel_volume = channel->channelvolume;
- channel->playing->note = channel->truenote;
- channel->playing->filter_cutoff = 127;
- channel->playing->filter_resonance = 0;
- channel->playing->true_filter_cutoff = 127 << 8;
- channel->playing->true_filter_resonance = 0;
- channel->playing->vibrato_speed = 0;
- channel->playing->vibrato_depth = 0;
- channel->playing->vibrato_n = 0;
- channel->playing->vibrato_time = 0;
- channel->playing->tremolo_speed = 0;
- channel->playing->tremolo_depth = 0;
- channel->playing->tremolo_time = 0;
- channel->playing->sample_vibrato_time = 0;
- channel->playing->sample_vibrato_depth = 0;
- channel->playing->slide = 0;
- it_reset_filter_state(&channel->playing->filter_state[0]); // Are these
- it_reset_filter_state(&channel->playing->filter_state[1]); // necessary?
- it_playing_reset_resamplers(channel->playing, 0);
-
- /** WARNING - is everything initialised? */
- }
- }
-
- if (!((entry->mask & IT_ENTRY_EFFECT) && entry->effect == IT_XM_KEY_OFF && entry->effectvalue == 0) &&
- (entry->mask & (IT_ENTRY_NOTE | IT_ENTRY_INSTRUMENT)) == (IT_ENTRY_NOTE | IT_ENTRY_INSTRUMENT))
- {
- if (channel->playing) retrigger_xm_envelopes(channel->playing);
- get_default_volpan(sigdata, channel);
- }
-
- if ((entry->mask & IT_ENTRY_VOLPAN) && ((entry->volpan>>4) == 0xF)) {
- /* Tone Portamento */
- unsigned char v = (entry->volpan & 15) << 4;
- if (v == 0)
- v = channel->lastG;
- channel->lastG = v;
- if (entry->mask & IT_ENTRY_NOTE)
- if (channel->sample)
- channel->destnote = channel->truenote;
- channel->toneporta = v << 4;
- } else if ((entry->mask & IT_ENTRY_EFFECT) &&
- (entry->effect == IT_TONE_PORTAMENTO ||
- entry->effect == IT_VOLSLIDE_TONEPORTA)) {
- unsigned char v;
- if (entry->effect == IT_TONE_PORTAMENTO)
- v = entry->effectvalue;
- else
- v = 0;
- if (v == 0)
- v = channel->lastG;
- channel->lastG = v;
- if (entry->mask & IT_ENTRY_NOTE)
- if (channel->sample)
- channel->destnote = channel->truenote;
- channel->toneporta = v << 4;
- }
-
- if (entry->mask & IT_ENTRY_VOLPAN) {
- int effect = entry->volpan >> 4;
- int value = entry->volpan & 15;
- switch (effect) {
- case 0x6: /* Volume slide down */
- channel->xm_volslide = -value;
- break;
- case 0x7: /* Volume slide up */
- channel->xm_volslide = value;
- break;
- case 0x8: /* Fine volume slide down */
- channel->volume -= value;
- if (channel->volume > 64) channel->volume = 0;
- break;
- case 0x9: /* Fine volume slide up */
- channel->volume += value;
- if (channel->volume > 64) channel->volume = 64;
- break;
- case 0xA: /* Set vibrato speed */
- if (value)
- channel->lastHspeed = value;
- if (channel->playing)
- channel->playing->vibrato_speed = channel->lastHspeed;
- break;
- case 0xB: /* Vibrato */
- if (value)
- channel->lastHdepth = value << 2; /** WARNING: correct ? */
- if (channel->playing) {
- channel->playing->vibrato_depth = channel->lastHdepth;
- channel->playing->vibrato_speed = channel->lastHspeed;
- channel->playing->vibrato_n++;
- }
- break;
- case 0xC: /* Set panning */
- channel->truepan = 32 + value*(17*64);
- break;
- case 0xD: /* Pan slide left */
- /* -128 is a special case for emulating a 'feature' in FT2.
- * As soon as effects are processed, it goes hard left.
- */
- channel->panslide = value ? -value : -128;
- break;
- case 0xE: /* Pan slide Right */
- channel->panslide = value;
- break;
- case 0xF: /* Tone porta */
- break;
- default: /* Volume */
- channel->volume = entry->volpan - 0x10;
- break;
- }
- }
-}
-
-
-
-/* This function assumes !IT_IS_END_ROW(entry). */
-static int process_note_data(DUMB_IT_SIGRENDERER *sigrenderer, IT_ENTRY *entry, int ignore_cxx)
-{
- DUMB_IT_SIGDATA *sigdata = sigrenderer->sigdata;
-
- if (sigdata->flags & IT_WAS_AN_XM)
- process_xm_note_data(sigrenderer, entry);
- else
- if (process_it_note_data(sigrenderer, entry)) return 0;
-
- return process_effects(sigrenderer, entry, ignore_cxx);
-}
-
-
-
-static int process_entry(DUMB_IT_SIGRENDERER *sigrenderer, IT_ENTRY *entry, int ignore_cxx)
-{
- IT_CHANNEL *channel = &sigrenderer->channel[(int)entry->channel];
-
- if (entry->mask & IT_ENTRY_NOTE)
- channel->note = entry->note;
-
- if ((entry->mask & IT_ENTRY_EFFECT) && entry->effect == IT_S) {
- /* channel->lastS was set in update_pattern_variables(). */
- unsigned char effectvalue = channel->lastS;
- if (effectvalue >> 4 == IT_S_NOTE_DELAY) {
- channel->note_delay_count = effectvalue & 15;
- if (channel->note_delay_count == 0)
- channel->note_delay_count = 1;
- channel->note_delay_entry = entry;
- return 0;
- }
- }
-
- return process_note_data(sigrenderer, entry, ignore_cxx);
-}
-
-
-
-static void update_tick_counts(DUMB_IT_SIGRENDERER *sigrenderer)
-{
- int i;
-
- for (i = 0; i < DUMB_IT_N_CHANNELS; i++) {
- IT_CHANNEL *channel = &sigrenderer->channel[i];
-
- if (channel->key_off_count) {
- channel->key_off_count--;
- if (channel->key_off_count == 0)
- xm_note_off(sigrenderer->sigdata, channel);
- } else if (channel->note_cut_count) {
- channel->note_cut_count--;
- if (channel->note_cut_count == 0) {
- if (sigrenderer->sigdata->flags & IT_WAS_AN_XM)
- channel->volume = 0;
- else if (channel->playing) {
- free(channel->playing);
- channel->playing = NULL;
- }
- }
- } else if (channel->note_delay_count) {
- channel->note_delay_count--;
- if (channel->note_delay_count == 0)
- process_note_data(sigrenderer, channel->note_delay_entry, 0);
- /* Don't bother checking the return value; if the note
- * was delayed, there can't have been a speed=0.
- */
- }
- }
-}
-
-
-
-static int envelope_get_y(IT_ENVELOPE *envelope, IT_PLAYING_ENVELOPE *pe)
-{
-#if 1
- (void)envelope; //TODO: remove the parameter
- return pe->value;
-#else
- int ys, ye;
- int ts, te;
- int t;
-
- if (pe->next_node <= 0)
- return envelope->node_y[0] << IT_ENVELOPE_SHIFT;
-
- if (pe->next_node >= envelope->n_nodes)
- return envelope->node_y[envelope->n_nodes-1] << IT_ENVELOPE_SHIFT;
-
- ys = envelope->node_y[pe->next_node-1] << IT_ENVELOPE_SHIFT;
- ts = envelope->node_t[pe->next_node-1];
- te = envelope->node_t[pe->next_node];
-
- if (ts == te)
- return ys;
-
- ye = envelope->node_y[pe->next_node] << IT_ENVELOPE_SHIFT;
-
- t = pe->tick;
-
- return ys + (ye - ys) * (t - ts) / (te - ts);
-#endif
-}
-
-
-
-#if 0
-static int it_envelope_end(IT_PLAYING *playing, IT_ENVELOPE *envelope, IT_PLAYING_ENVELOPE *pe)
-{
- if (pe->next_node >= envelope->n_nodes)
- return 1;
-
- if (pe->tick < envelope->node_t[pe->next_node]) return 0;
-
- if ((envelope->flags & IT_ENVELOPE_LOOP_ON) &&
- envelope->loop_end >= pe->next_node &&
- envelope->node_t[envelope->loop_end] <= pe->tick) return 0;
-
- if ((envelope->flags & IT_ENVELOPE_SUSTAIN_LOOP) &&
- !(playing->flags & IT_PLAYING_SUSTAINOFF) &&
- envelope->sus_loop_end >= pe->next_node &&
- envelope->node_t[envelope->sus_loop_end] <= pe->tick) return 0;
-
- if (envelope->node_t[envelope->n_nodes-1] <= pe->tick) return 1;
-
- return 0;
-}
-#endif
-
-
-
-/* Returns 1 when fading should be initiated for a volume envelope. */
-static int update_it_envelope(IT_PLAYING *playing, IT_ENVELOPE *envelope, IT_PLAYING_ENVELOPE *pe)
-{
- if (!(envelope->flags & IT_ENVELOPE_ON))
- return 0;
-
- ASSERT(envelope->n_nodes > 0);
-
- if (pe->next_node <= 0)
- pe->value = envelope->node_y[0] << IT_ENVELOPE_SHIFT;
- else if (pe->next_node >= envelope->n_nodes) {
- pe->value = envelope->node_y[envelope->n_nodes-1] << IT_ENVELOPE_SHIFT;
- return 1;
- } else {
- int ys = envelope->node_y[pe->next_node-1] << IT_ENVELOPE_SHIFT;
- int ts = envelope->node_t[pe->next_node-1];
- int te = envelope->node_t[pe->next_node];
-
- if (ts == te)
- pe->value = ys;
- else {
- int ye = envelope->node_y[pe->next_node] << IT_ENVELOPE_SHIFT;
- int t = pe->tick;
-
- pe->value = ys + (ye - ys) * (t - ts) / (te - ts);
- }
- }
-
- pe->tick++;
- while (pe->tick >= envelope->node_t[pe->next_node]) {
- pe->next_node++;
- if ((envelope->flags & IT_ENVELOPE_SUSTAIN_LOOP) && !(playing->flags & IT_PLAYING_SUSTAINOFF)) {
- if (pe->next_node > envelope->sus_loop_end) {
- pe->next_node = envelope->sus_loop_start;
- ASSERT(pe->next_node < envelope->n_nodes);
- pe->tick = envelope->node_t[envelope->sus_loop_start];
- return 0;
- }
- } else if (envelope->flags & IT_ENVELOPE_LOOP_ON) {
- if (pe->next_node > envelope->loop_end) {
- pe->next_node = envelope->loop_start;
- ASSERT(pe->next_node < envelope->n_nodes);
- pe->tick = envelope->node_t[envelope->loop_start];
- return 0;
- }
- }
- if (pe->next_node >= envelope->n_nodes)
- return 0;
- }
- return 0;
-}
-
-
-
-static void update_it_envelopes(IT_PLAYING *playing)
-{
- IT_ENVELOPE *envelope = &playing->env_instrument->volume_envelope;
- IT_PLAYING_ENVELOPE *pe = &playing->volume_envelope;
-
- if (update_it_envelope(playing, envelope, pe)) {
- playing->flags |= IT_PLAYING_FADING;
- if (pe->value == 0)
- playing->flags |= IT_PLAYING_DEAD;
- }
-
- update_it_envelope(playing, &playing->env_instrument->pan_envelope, &playing->pan_envelope);
- update_it_envelope(playing, &playing->env_instrument->pitch_envelope, &playing->pitch_envelope);
-}
-
-
-
-static int xm_envelope_is_sustaining(IT_PLAYING *playing, IT_ENVELOPE *envelope, IT_PLAYING_ENVELOPE *pe)
-{
- if ((envelope->flags & IT_ENVELOPE_SUSTAIN_LOOP) && !(playing->flags & IT_PLAYING_SUSTAINOFF))
- if (envelope->sus_loop_start < envelope->n_nodes)
- if (pe->tick == envelope->node_t[envelope->sus_loop_start])
- return 1;
- return 0;
-}
-
-
-
-static void update_xm_envelope(IT_PLAYING *playing, IT_ENVELOPE *envelope, IT_PLAYING_ENVELOPE *pe)
-{
- if (!(envelope->flags & IT_ENVELOPE_ON))
- return;
-
- if (xm_envelope_is_sustaining(playing, envelope, pe))
- return;
-
- if (pe->tick >= envelope->node_t[envelope->n_nodes-1])
- return;
-
- pe->tick++;
-
- /* pe->next_node must be kept up to date for envelope_get_y(). */
- while (pe->tick > envelope->node_t[pe->next_node])
- pe->next_node++;
-
- if ((envelope->flags & IT_ENVELOPE_LOOP_ON) && envelope->loop_end < envelope->n_nodes) {
- if (pe->tick == envelope->node_t[envelope->loop_end]) {
- pe->next_node = MID(0, envelope->loop_start, envelope->n_nodes - 1);
- pe->tick = envelope->node_t[pe->next_node];
- }
- }
-
- xm_envelope_calculate_value(envelope, pe);
-}
-
-
-
-static void update_xm_envelopes(IT_PLAYING *playing)
-{
- update_xm_envelope(playing, &playing->env_instrument->volume_envelope, &playing->volume_envelope);
- update_xm_envelope(playing, &playing->env_instrument->pan_envelope, &playing->pan_envelope);
-}
-
-
-
-static void update_fadeout(DUMB_IT_SIGDATA *sigdata, IT_PLAYING *playing)
-{
- if (playing->flags & IT_PLAYING_FADING) {
- playing->fadeoutcount -= playing->env_instrument->fadeout;
- if (playing->fadeoutcount <= 0) {
- playing->fadeoutcount = 0;
- if (!(sigdata->flags & IT_WAS_AN_XM))
- playing->flags |= IT_PLAYING_DEAD;
- }
- }
-}
-
-
-
-static void process_playing(DUMB_IT_SIGDATA *sigdata, IT_PLAYING *playing)
-{
- if (playing->instrument) {
- if (sigdata->flags & IT_WAS_AN_XM)
- update_xm_envelopes(playing);
- else
- update_it_envelopes(playing);
- update_fadeout(sigdata, playing);
- }
-
- //Calculate final volume if required
- //Calculate final pan if required
-
- if (sigdata->flags & IT_WAS_AN_XM) {
- /* 'depth' is used to store the tick number for XM files. */
- if (playing->sample_vibrato_depth < playing->sample->vibrato_rate)
- playing->sample_vibrato_depth++;
- } else {
- playing->sample_vibrato_depth += playing->sample->vibrato_rate;
- if (playing->sample_vibrato_depth > playing->sample->vibrato_depth << 8)
- playing->sample_vibrato_depth = playing->sample->vibrato_depth << 8;
- }
-
- playing->sample_vibrato_time += playing->sample->vibrato_speed;
-}
-
-
-
-static void process_all_playing(DUMB_IT_SIGRENDERER *sigrenderer)
-{
- DUMB_IT_SIGDATA *sigdata = sigrenderer->sigdata;
- int i;
-
- for (i = 0; i < DUMB_IT_N_CHANNELS; i++) {
- IT_CHANNEL *channel = &sigrenderer->channel[i];
- IT_PLAYING *playing = channel->playing;
-
- if (playing) {
- int vibrato_shift = it_sine[playing->vibrato_time];
- vibrato_shift *= playing->vibrato_n;
- vibrato_shift *= playing->vibrato_depth;
- vibrato_shift >>= 4;
-
- if (sigdata->flags & IT_OLD_EFFECTS)
- vibrato_shift = -vibrato_shift;
-
- playing->volume = channel->volume;
- playing->pan = channel->truepan;
-
- if (sigdata->flags & IT_LINEAR_SLIDES) {
- int currpitch = ((playing->note - 60) << 8) + playing->slide
- + vibrato_shift;
-
- /* We add a feature here, which is that of keeping the pitch
- * within range. Otherwise it crashes. Trust me. It happened.
- * The limit 32768 gives almost 11 octaves either way.
- */
- if (currpitch < -32768)
- currpitch = -32768;
- else if (currpitch > 32767)
- currpitch = 32767;
-
- playing->delta = (float)pow(DUMB_PITCH_BASE, currpitch);
- playing->delta *= playing->sample->C5_speed / 65536.0f;
- } else {
- int slide = playing->slide + vibrato_shift;
-
- playing->delta = (float)pow(DUMB_SEMITONE_BASE, 60 - playing->note);
- /* playing->delta is 1.0 for C-5, 0.5 for C-6, etc. */
-
- playing->delta *= 1.0f / playing->sample->C5_speed;
-
- playing->delta -= slide / AMIGA_DIVISOR;
-
- if (playing->delta < (1.0f / 65536.0f) / 32768.0f) {
- // Should XM notes die if Amiga slides go out of range?
- playing->flags |= IT_PLAYING_DEAD;
- continue;
- }
-
- playing->delta = (1.0f / 65536.0f) / playing->delta;
- }
-
- playing->delta *= (float)pow(DUMB_SEMITONE_BASE, channel->arpeggio >> 8);
-
- playing->filter_cutoff = channel->filter_cutoff;
- playing->filter_resonance = channel->filter_resonance;
- }
- }
-
- for (i = 0; i < DUMB_IT_N_CHANNELS; i++) {
- if (sigrenderer->channel[i].playing) {
- process_playing(sigdata, sigrenderer->channel[i].playing);
- if (!(sigdata->flags & IT_WAS_AN_XM)) {
- //if ((sigrenderer->channel[i].playing->flags & (IT_PLAYING_BACKGROUND | IT_PLAYING_DEAD)) == (IT_PLAYING_BACKGROUND | IT_PLAYING_DEAD)) {
- // This change was made so Gxx would work correctly when a note faded out or whatever. Let's hope nothing else was broken by it.
- if (sigrenderer->channel[i].playing->flags & IT_PLAYING_DEAD) {
- free(sigrenderer->channel[i].playing);
- sigrenderer->channel[i].playing = NULL;
- }
- }
- }
- }
-
- for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) {
- if (sigrenderer->playing[i]) {
- process_playing(sigdata, sigrenderer->playing[i]);
- if (sigrenderer->playing[i]->flags & IT_PLAYING_DEAD) {
- free(sigrenderer->playing[i]);
- sigrenderer->playing[i] = NULL;
- }
- }
- }
-}
-
-
-
-static int process_tick(DUMB_IT_SIGRENDERER *sigrenderer)
-{
- DUMB_IT_SIGDATA *sigdata = sigrenderer->sigdata;
-
- // Set note vol/freq to vol/freq set for each channel
-
- if (sigrenderer->speed && --sigrenderer->tick == 0) {
- reset_tick_counts(sigrenderer);
- sigrenderer->tick = sigrenderer->speed;
- sigrenderer->rowcount--;
- if (sigrenderer->rowcount == 0) {
- sigrenderer->rowcount = 1;
-
- sigrenderer->processrow++;
-
- if (sigrenderer->processrow >= sigrenderer->n_rows) {
- IT_PATTERN *pattern;
- int n;
- int processorder = sigrenderer->processorder;
-
- if (sigrenderer->processrow == 0xFFFE + 1) { /* It was incremented above! */
- sigrenderer->processrow = sigrenderer->breakrow;
- sigrenderer->breakrow = 0;
- for (n = 0; n < DUMB_IT_N_CHANNELS; n++) sigrenderer->channel[n].pat_loop_end_row = 0;
- } else
- sigrenderer->processrow = sigrenderer->breakrow;
-
- if (sigrenderer->processorder == 0xFFFF)
- sigrenderer->processorder = sigrenderer->order - 1;
-
- for (;;) {
- sigrenderer->processorder++;
-
- if (sigrenderer->processorder >= sigdata->n_orders) {
- sigrenderer->processorder = sigdata->restart_position;
- if (sigrenderer->processorder >= sigdata->n_orders) {
- /* Restarting beyond end. We'll loop for now. */
- sigrenderer->processorder = -1;
- continue;
- }
- }
-
- n = sigdata->order[sigrenderer->processorder];
-
- if (n < sigdata->n_patterns)
- break;
-
-#ifdef INVALID_ORDERS_END_SONG
- if (n != IT_ORDER_SKIP)
- sigrenderer->processorder = -1;
-#else
- if (n == IT_ORDER_END)
- sigrenderer->processorder = -1;
-#endif
- }
-
- pattern = &sigdata->pattern[n];
-
- n = sigrenderer->n_rows;
- sigrenderer->n_rows = pattern->n_rows;
-
- if (sigrenderer->processrow >= sigrenderer->n_rows)
- sigrenderer->processrow = 0;
-
-/** WARNING - everything pertaining to a new pattern initialised? */
-
- sigrenderer->entry = sigrenderer->entry_start = pattern->entry;
- sigrenderer->entry_end = sigrenderer->entry + pattern->n_entries;
-
- /* If n_rows was 0, we're only just starting. Don't do anything weird here. */
- if (n && (processorder == 0xFFFF ? sigrenderer->order > sigrenderer->processorder : sigrenderer->order >= sigrenderer->processorder)) {
- if (sigrenderer->callbacks->loop) {
- if ((*sigrenderer->callbacks->loop)(sigrenderer->callbacks->loop_data))
- return 1;
- if (sigrenderer->speed == 0)
- goto speed0; /* I love goto */
- }
- }
- sigrenderer->order = sigrenderer->processorder;
-
- n = sigrenderer->processrow;
- while (n) {
- while (sigrenderer->entry < sigrenderer->entry_end) {
- if (IT_IS_END_ROW(sigrenderer->entry)) {
- sigrenderer->entry++;
- break;
- }
- sigrenderer->entry++;
- }
- n--;
- }
- sigrenderer->row = sigrenderer->processrow;
- } else {
- if (sigrenderer->entry) {
- while (sigrenderer->entry < sigrenderer->entry_end) {
- if (IT_IS_END_ROW(sigrenderer->entry)) {
- sigrenderer->entry++;
- break;
- }
- sigrenderer->entry++;
- }
- sigrenderer->row++;
- } else {
- sigrenderer->entry = sigrenderer->entry_start;
- sigrenderer->row = 0;
- }
- }
-
- reset_effects(sigrenderer);
-
- {
- IT_ENTRY *entry = sigrenderer->entry;
- int ignore_cxx = 0;
-
- while (entry < sigrenderer->entry_end && !IT_IS_END_ROW(entry))
- ignore_cxx |= update_pattern_variables(sigrenderer, entry++);
-
- entry = sigrenderer->entry;
-
- while (entry < sigrenderer->entry_end && !IT_IS_END_ROW(entry))
- if (process_entry(sigrenderer, entry++, sigdata->flags & IT_WAS_AN_XM ? 0 : ignore_cxx))
- return 1;
- }
-
- if (!(sigdata->flags & IT_OLD_EFFECTS))
- update_smooth_effects(sigrenderer);
- } else {
- {
- IT_ENTRY *entry = sigrenderer->entry;
-
- while (entry < sigrenderer->entry_end && !IT_IS_END_ROW(entry))
- process_effects(sigrenderer, entry++, 0);
- /* Don't bother checking the return value; if there
- * was a pattern delay, there can't be a speed=0.
- */
- }
-
- update_effects(sigrenderer);
- }
- } else {
- speed0:
- update_effects(sigrenderer);
- update_tick_counts(sigrenderer);
- }
-
- process_all_playing(sigrenderer);
-
- {
- LONG_LONG t = sigrenderer->sub_time_left + ((LONG_LONG)TICK_TIME_DIVIDEND << 16) / sigrenderer->tempo;
- sigrenderer->time_left += (int)(t >> 16);
- sigrenderer->sub_time_left = (int)t & 65535;
- }
-
- return 0;
-}
-
-
-
-int dumb_it_max_to_mix = 64;
-
-
-
-static float calculate_volume(DUMB_IT_SIGRENDERER *sigrenderer, IT_PLAYING *playing, float volume)
-{
- if (volume != 0) {
- int vol;
-
- if (playing->channel->flags & IT_CHANNEL_MUTED)
- return 0;
-
- if ((playing->channel->tremor_time & 192) == 128)
- return 0;
-
- vol = it_sine[playing->tremolo_time];
- vol *= playing->tremolo_depth;
-
- vol = (playing->volume << 5) + vol;
-
- if (vol <= 0)
- return 0;
-
- if (vol > 64 << 5)
- vol = 64 << 5;
-
- volume *= vol; /* 64 << 5 */
- volume *= playing->sample->global_volume; /* 64 */
- volume *= playing->channel_volume; /* 64 */
- volume *= sigrenderer->globalvolume; /* 128 */
- volume *= sigrenderer->sigdata->mixing_volume; /* 128 */
- volume *= 1.0f / ((64 << 5) * 64.0f * 64.0f * 128.0f * 128.0f);
-
- if (volume && playing->instrument) {
- if (playing->env_instrument->volume_envelope.flags & IT_ENVELOPE_ON) {
- volume *= envelope_get_y(&playing->env_instrument->volume_envelope, &playing->volume_envelope);
- volume *= 1.0f / (64 << IT_ENVELOPE_SHIFT);
- }
- volume *= playing->instrument->global_volume; /* 128 */
- volume *= playing->fadeoutcount; /* 1024 */
- volume *= 1.0f / (128.0f * 1024.0f);
- }
- }
-
- return volume;
-}
-
-
-
-static int apply_pan_envelope(IT_PLAYING *playing)
-{
- int pan = playing->pan;
- if (pan <= 64 << IT_ENVELOPE_SHIFT && playing->env_instrument && (playing->env_instrument->pan_envelope.flags & IT_ENVELOPE_ON)) {
- int p = envelope_get_y(&playing->env_instrument->pan_envelope, &playing->pan_envelope);
- if (pan > 32 << IT_ENVELOPE_SHIFT)
- p *= (64 << IT_ENVELOPE_SHIFT) - pan;
- else
- p *= pan;
- pan += p >> (5 + IT_ENVELOPE_SHIFT);
- }
- return pan;
-}
-
-
-
-/* Note: if a click remover is provided, and store_end_sample is set, then
- * the end point will be computed twice. This situation should not arise.
- */
-static long render_playing(DUMB_IT_SIGRENDERER *sigrenderer, IT_PLAYING *playing, float volume, float delta, long pos, long size, sample_t **samples, int store_end_sample, int *left_to_mix)
-{
- int bits;
-
- int pan;
- float span; /* separated pan, range -1 to 1; garbage for surround */
-
- long size_rendered;
-
- if (playing->flags & IT_PLAYING_DEAD)
- return 0;
-
- if (*left_to_mix <= 0)
- volume = 0;
-
- bits = playing->sample->flags & IT_SAMPLE_16BIT ? 16 : 8;
-
- pan = apply_pan_envelope(playing);
- span = (pan - (32<<8)) * sigrenderer->sigdata->pan_separation * (1.0f / ((32<<8) * 128));
-
- if (volume == 0) {
- if (playing->sample->flags & IT_SAMPLE_STEREO)
- size_rendered = dumb_resample_n_2_1(bits, &playing->resampler, NULL, size, 0, 0, delta);
- else
- size_rendered = dumb_resample_n_1_1(bits, &playing->resampler, NULL, size, 0, delta);
- } else {
- if (sigrenderer->n_channels == 2) {
- float lvol, rvol;
- lvol = volume;
- if (!IT_IS_SURROUND_SHIFTED(pan)) lvol *= 1.0f - span;
- rvol = -lvol;
- if (!IT_IS_SURROUND_SHIFTED(pan)) rvol += 2.0f * volume;
- if (playing->sample->flags & IT_SAMPLE_STEREO) {
- if (sigrenderer->click_remover) {
- sample_t click[2];
- dumb_resample_get_current_sample_n_2_2(bits, &playing->resampler, lvol, rvol, click);
- dumb_record_click(sigrenderer->click_remover[0], pos, click[0]);
- dumb_record_click(sigrenderer->click_remover[1], pos, click[1]);
- }
- size_rendered = dumb_resample_n_2_2(bits, &playing->resampler, samples[0] + pos*2, size, lvol, rvol, delta);
- if (store_end_sample) {
- sample_t click[2];
- dumb_resample_get_current_sample_n_2_2(bits, &playing->resampler, lvol, rvol, click);
- samples[0][(pos + size_rendered) * 2] = click[0];
- samples[0][(pos + size_rendered) * 2 + 1] = click[1];
- }
- if (sigrenderer->click_remover) {
- sample_t click[2];
- dumb_resample_get_current_sample_n_2_2(bits, &playing->resampler, lvol, rvol, click);
- dumb_record_click(sigrenderer->click_remover[0], pos + size_rendered, -click[0]);
- dumb_record_click(sigrenderer->click_remover[1], pos + size_rendered, -click[1]);
- }
- } else {
- if (sigrenderer->click_remover) {
- sample_t click[2];
- dumb_resample_get_current_sample_n_1_2(bits, &playing->resampler, lvol, rvol, click);
- dumb_record_click(sigrenderer->click_remover[0], pos, click[0]);
- dumb_record_click(sigrenderer->click_remover[1], pos, click[1]);
- }
- size_rendered = dumb_resample_n_1_2(bits, &playing->resampler, samples[0] + pos*2, size, lvol, rvol, delta);
- if (store_end_sample) {
- sample_t click[2];
- dumb_resample_get_current_sample_n_1_2(bits, &playing->resampler, lvol, rvol, click);
- samples[0][(pos + size_rendered) * 2] = click[0];
- samples[0][(pos + size_rendered) * 2 + 1] = click[1];
- }
- if (sigrenderer->click_remover) {
- sample_t click[2];
- dumb_resample_get_current_sample_n_1_2(bits, &playing->resampler, lvol, rvol, click);
- dumb_record_click(sigrenderer->click_remover[0], pos + size_rendered, -click[0]);
- dumb_record_click(sigrenderer->click_remover[1], pos + size_rendered, -click[1]);
- }
- }
- } else {
- if (playing->sample->flags & IT_SAMPLE_STEREO) {
- float lvol, rvol;
- lvol = 0.5f * volume;
- if (!IT_IS_SURROUND_SHIFTED(pan)) lvol *= 1.0f - span;
- rvol = lvol;
- if (!IT_IS_SURROUND_SHIFTED(pan)) rvol = volume - rvol;
- if (sigrenderer->click_remover) {
- sample_t click;
- dumb_resample_get_current_sample_n_2_1(bits, &playing->resampler, lvol, rvol, &click);
- dumb_record_click(sigrenderer->click_remover[0], pos, click);
- }
- size_rendered = dumb_resample_n_2_1(bits, &playing->resampler, samples[0] + pos, size, lvol, rvol, delta);
- if (store_end_sample)
- dumb_resample_get_current_sample_n_2_1(bits, &playing->resampler, lvol, rvol, &samples[0][pos + size_rendered]);
- if (sigrenderer->click_remover) {
- sample_t click;
- dumb_resample_get_current_sample_n_2_1(bits, &playing->resampler, lvol, rvol, &click);
- dumb_record_click(sigrenderer->click_remover[0], pos + size_rendered, -click);
- }
- } else {
- if (sigrenderer->click_remover) {
- sample_t click;
- dumb_resample_get_current_sample_n_1_1(bits, &playing->resampler, volume, &click);
- dumb_record_click(sigrenderer->click_remover[0], pos, click);
- }
- size_rendered = dumb_resample_n_1_1(bits, &playing->resampler, samples[0] + pos, size, volume, delta);
- if (store_end_sample)
- dumb_resample_get_current_sample_n_1_1(bits, &playing->resampler, volume, &samples[0][pos + size_rendered]);
- if (sigrenderer->click_remover) {
- sample_t click;
- dumb_resample_get_current_sample_n_1_1(bits, &playing->resampler, volume, &click);
- dumb_record_click(sigrenderer->click_remover[0], pos + size_rendered, -click);
- }
- }
- }
- (*left_to_mix)--;
- }
-
- if (playing->resampler.dir == 0)
- playing->flags |= IT_PLAYING_DEAD;
-
- return size_rendered;
-}
-
-
-
-typedef struct IT_TO_MIX
-{
- IT_PLAYING *playing;
- float volume;
-}
-IT_TO_MIX;
-
-
-
-static int it_to_mix_compare(const void *e1, const void *e2)
-{
- if (((const IT_TO_MIX *)e1)->volume > ((const IT_TO_MIX *)e2)->volume)
- return -1;
-
- if (((const IT_TO_MIX *)e1)->volume < ((const IT_TO_MIX *)e2)->volume)
- return 1;
-
- return 0;
-}
-
-
-
-static void apply_pitch_modifications(DUMB_IT_SIGDATA *sigdata, IT_PLAYING *playing, float *delta, int *cutoff)
-{
- {
- int sample_vibrato_shift = it_sine[playing->sample_vibrato_time];
-
- if (sigdata->flags & IT_WAS_AN_XM) {
- int depth = playing->sample->vibrato_depth; /* True depth */
- if (playing->sample->vibrato_rate) {
- depth *= playing->sample_vibrato_depth; /* Tick number */
- depth /= playing->sample->vibrato_rate; /* XM sweep */
- }
- sample_vibrato_shift *= depth;
- } else
- sample_vibrato_shift *= playing->sample_vibrato_depth >> 8;
-
- sample_vibrato_shift >>= 4;
-
- *delta *= (float)pow(DUMB_PITCH_BASE, sample_vibrato_shift);
- }
-
- if (playing->env_instrument &&
- (playing->env_instrument->pitch_envelope.flags & IT_ENVELOPE_ON))
- {
- int p = envelope_get_y(&playing->env_instrument->pitch_envelope, &playing->pitch_envelope);
- if (playing->env_instrument->pitch_envelope.flags & IT_ENVELOPE_PITCH_IS_FILTER)
- *cutoff = (*cutoff * (p+(32<<IT_ENVELOPE_SHIFT))) >> (6 + IT_ENVELOPE_SHIFT);
- else
- *delta *= (float)pow(DUMB_PITCH_BASE, p >> (IT_ENVELOPE_SHIFT - 7));
- }
-}
-
-
-
-static void render(DUMB_IT_SIGRENDERER *sigrenderer, float volume, float delta, long pos, long size, sample_t **samples)
-{
- int i;
-
- int n_to_mix = 0;
- IT_TO_MIX to_mix[DUMB_IT_TOTAL_CHANNELS];
- int left_to_mix = dumb_it_max_to_mix;
-
- sample_t **samples_to_filter = NULL;
-
- for (i = 0; i < DUMB_IT_N_CHANNELS; i++) {
- if (sigrenderer->channel[i].playing && !(sigrenderer->channel[i].playing->flags & IT_PLAYING_DEAD)) {
- to_mix[n_to_mix].playing = sigrenderer->channel[i].playing;
- to_mix[n_to_mix].volume = volume == 0 ? 0 : calculate_volume(sigrenderer, sigrenderer->channel[i].playing, volume);
- n_to_mix++;
- }
- }
-
- for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) {
- if (sigrenderer->playing[i]) { /* Won't be dead; it would have been freed. */
- to_mix[n_to_mix].playing = sigrenderer->playing[i];
- to_mix[n_to_mix].volume = volume == 0 ? 0 : calculate_volume(sigrenderer, sigrenderer->playing[i], volume);
- n_to_mix++;
- }
- }
-
- if (volume != 0)
- qsort(to_mix, n_to_mix, sizeof(IT_TO_MIX), &it_to_mix_compare);
-
- for (i = 0; i < n_to_mix; i++) {
- IT_PLAYING *playing = to_mix[i].playing;
- float note_delta = delta * playing->delta;
- int cutoff = playing->filter_cutoff << IT_ENVELOPE_SHIFT;
-
- apply_pitch_modifications(sigrenderer->sigdata, playing, &note_delta, &cutoff);
-
- if (cutoff != 127 << IT_ENVELOPE_SHIFT || playing->filter_resonance != 0) {
- playing->true_filter_cutoff = cutoff;
- playing->true_filter_resonance = playing->filter_resonance;
- }
-
- if (to_mix[i].volume && (playing->true_filter_cutoff != 127 << IT_ENVELOPE_SHIFT || playing->true_filter_resonance != 0)) {
- if (!samples_to_filter) {
- samples_to_filter = allocate_sample_buffer(sigrenderer->n_channels, size + 1);
- if (!samples_to_filter) {
- render_playing(sigrenderer, playing, 0, note_delta, pos, size, NULL, 0, &left_to_mix);
- continue;
- }
- }
- {
- long size_rendered;
- DUMB_CLICK_REMOVER **cr = sigrenderer->click_remover;
- dumb_silence(samples_to_filter[0], sigrenderer->n_channels * (size + 1));
- sigrenderer->click_remover = NULL;
- size_rendered = render_playing(sigrenderer, playing, to_mix[i].volume, note_delta, 0, size, samples_to_filter, 1, &left_to_mix);
- sigrenderer->click_remover = cr;
- if (sigrenderer->n_channels == 2) {
- it_filter(cr ? cr[0] : NULL, &playing->filter_state[0], samples[0], pos, samples_to_filter[0], size_rendered,
- 2, (int)(65536.0f/delta), playing->true_filter_cutoff, playing->true_filter_resonance);
- it_filter(cr ? cr[1] : NULL, &playing->filter_state[1], samples[0]+1, pos, samples_to_filter[0]+1, size_rendered,
- 2, (int)(65536.0f/delta), playing->true_filter_cutoff, playing->true_filter_resonance);
- } else {
- it_filter(cr ? cr[0] : NULL, &playing->filter_state[0], samples[0], pos, samples_to_filter[0], size_rendered,
- 1, (int)(65536.0f/delta), playing->true_filter_cutoff, playing->true_filter_resonance);
- }
- // FIXME: filtering is not prevented by low left_to_mix!
- // FIXME: change 'warning' to 'FIXME' everywhere
- }
- } else {
- it_reset_filter_state(&playing->filter_state[0]);
- it_reset_filter_state(&playing->filter_state[1]);
- render_playing(sigrenderer, playing, to_mix[i].volume, note_delta, pos, size, samples, 0, &left_to_mix);
- }
- }
-
- destroy_sample_buffer(samples_to_filter);
-
- for (i = 0; i < DUMB_IT_N_CHANNELS; i++) {
- if (sigrenderer->channel[i].playing) {
- //if ((sigrenderer->channel[i].playing->flags & (IT_PLAYING_BACKGROUND | IT_PLAYING_DEAD)) == (IT_PLAYING_BACKGROUND | IT_PLAYING_DEAD)) {
- // This change was made so Gxx would work correctly when a note faded out or whatever. Let's hope nothing else was broken by it.
- if (sigrenderer->channel[i].playing->flags & IT_PLAYING_DEAD) {
- free(sigrenderer->channel[i].playing);
- sigrenderer->channel[i].playing = NULL;
- }
- }
- }
-
- for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++) {
- if (sigrenderer->playing[i]) {
- if (sigrenderer->playing[i]->flags & IT_PLAYING_DEAD) {
- free(sigrenderer->playing[i]);
- sigrenderer->playing[i] = NULL;
- }
- }
- }
-}
-
-
-
-static DUMB_IT_SIGRENDERER *init_sigrenderer(DUMB_IT_SIGDATA *sigdata, int n_channels, int startorder, IT_CALLBACKS *callbacks, DUMB_CLICK_REMOVER **cr)
-{
- DUMB_IT_SIGRENDERER *sigrenderer;
- int i;
-
- if (startorder > sigdata->n_orders) {
- free(callbacks);
- dumb_destroy_click_remover_array(n_channels, cr);
- return NULL;
- }
-
- sigrenderer = malloc(sizeof(*sigrenderer));
- if (!sigrenderer) {
- free(callbacks);
- dumb_destroy_click_remover_array(n_channels, cr);
- return NULL;
- }
-
- sigrenderer->callbacks = callbacks;
- sigrenderer->click_remover = cr;
-
- sigrenderer->sigdata = sigdata;
- sigrenderer->n_channels = n_channels;
- sigrenderer->globalvolume = sigdata->global_volume;
- sigrenderer->tempo = sigdata->tempo;
-
- for (i = 0; i < DUMB_IT_N_CHANNELS; i++) {
- IT_CHANNEL *channel = &sigrenderer->channel[i];
-#if IT_CHANNEL_MUTED != 1
-#error this is wrong
-#endif
- channel->flags = sigdata->channel_pan[i] >> 7;
- channel->volume = (sigdata->flags & IT_WAS_AN_XM) ? 0 : 64;
- channel->pan = sigdata->channel_pan[i] & 0x7F;
- channel->truepan = channel->pan << IT_ENVELOPE_SHIFT;
- channel->channelvolume = sigdata->channel_volume[i];
- channel->instrument = 0;
- channel->note = 0;
- channel->SFmacro = 0;
- channel->filter_cutoff = 127;
- channel->filter_resonance = 0;
- channel->xm_retrig = 0;
- channel->retrig_tick = 0;
- channel->tremor_time = 0;
- channel->midi_state = 0;
- channel->lastvolslide = 0;
- channel->lastDKL = 0;
- channel->lastEF = 0;
- channel->lastG = 0;
- channel->lastHspeed = 0;
- channel->lastHdepth = 0;
- channel->lastRspeed = 0;
- channel->lastRdepth = 0;
- channel->lastI = 0;
- channel->lastJ = 0;
- channel->lastN = 0;
- channel->lastO = 0;
- channel->high_offset = 0;
- channel->lastP = 0;
- channel->lastQ = 0;
- channel->lastS = 0;
- channel->pat_loop_row = 0;
- channel->pat_loop_count = 0;
- channel->pat_loop_end_row = 0;
- channel->lastW = 0;
- channel->xm_lastE1 = 0;
- channel->xm_lastE2 = 0;
- channel->xm_lastEA = 0;
- channel->xm_lastEB = 0;
- channel->xm_lastX1 = 0;
- channel->xm_lastX2 = 0;
- channel->playing = NULL;
- }
-
- for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++)
- sigrenderer->playing[i] = NULL;
-
- sigrenderer->speed = sigdata->speed;
-
- sigrenderer->processrow = 0xFFFE;
- sigrenderer->n_rows = 0;
- sigrenderer->breakrow = 0;
- sigrenderer->pat_loop_row = -1;
- sigrenderer->rowcount = 1;
- sigrenderer->order = startorder;
- sigrenderer->row = 0;
- sigrenderer->processorder = startorder - 1;
- sigrenderer->tick = 1;
-
- {
- int order;
- for (order = 0; order < sigdata->n_orders; order++) {
- int n = sigdata->order[order];
- if (n < sigdata->n_patterns) goto found_valid_order;
-#ifdef INVALID_ORDERS_END_SONG
- if (n != IT_ORDER_SKIP)
-#else
- if (n == IT_ORDER_END)
-#endif
- break;
- }
- /* If we get here, there were no valid orders in the song. */
- _dumb_it_end_sigrenderer(sigrenderer);
- return NULL;
- }
- found_valid_order:
-
- sigrenderer->time_left = 0;
- sigrenderer->sub_time_left = 0;
-
- return sigrenderer;
-}
-
-
-
-void dumb_it_set_loop_callback(DUMB_IT_SIGRENDERER *sigrenderer, int (*callback)(void *data), void *data)
-{
- if (sigrenderer) {
- sigrenderer->callbacks->loop = callback;
- sigrenderer->callbacks->loop_data = data;
- }
-}
-
-
-
-void dumb_it_set_xm_speed_zero_callback(DUMB_IT_SIGRENDERER *sigrenderer, int (*callback)(void *data), void *data)
-{
- if (sigrenderer) {
- sigrenderer->callbacks->xm_speed_zero = callback;
- sigrenderer->callbacks->xm_speed_zero_data = data;
- }
-}
-
-
-
-void dumb_it_set_midi_callback(DUMB_IT_SIGRENDERER *sigrenderer, int (*callback)(void *data, int channel, unsigned char midi_byte), void *data)
-{
- if (sigrenderer) {
- sigrenderer->callbacks->midi = callback;
- sigrenderer->callbacks->midi_data = data;
- }
-}
-
-
-
-static IT_CALLBACKS *create_callbacks(void)
-{
- IT_CALLBACKS *callbacks = malloc(sizeof(*callbacks));
- if (!callbacks) return NULL;
- callbacks->loop = NULL;
- callbacks->xm_speed_zero = NULL;
- callbacks->midi = NULL;
- return callbacks;
-}
-
-
-
-static DUMB_IT_SIGRENDERER *dumb_it_init_sigrenderer(DUMB_IT_SIGDATA *sigdata, int n_channels, int startorder)
-{
- IT_CALLBACKS *callbacks;
-
- if (!sigdata) return NULL;
-
- callbacks = create_callbacks();
- if (!callbacks) return NULL;
-
- return init_sigrenderer(sigdata, n_channels, startorder, callbacks,
- dumb_create_click_remover_array(n_channels));
-}
-
-
-
-DUH_SIGRENDERER *dumb_it_start_at_order(DUH *duh, int n_channels, int startorder)
-{
- DUMB_IT_SIGDATA *itsd = duh_get_it_sigdata(duh);
- DUMB_IT_SIGRENDERER *itsr = dumb_it_init_sigrenderer(itsd, n_channels, startorder);
- return duh_encapsulate_it_sigrenderer(itsr, n_channels, 0);
-}
-
-
-
-static sigrenderer_t *it_start_sigrenderer(DUH *duh, sigdata_t *vsigdata, int n_channels, long pos)
-{
- DUMB_IT_SIGDATA *sigdata = vsigdata;
- DUMB_IT_SIGRENDERER *sigrenderer;
-
- (void)duh;
-
- {
- IT_CALLBACKS *callbacks = create_callbacks();
- if (!callbacks) return NULL;
-
- if (sigdata->checkpoint) {
- IT_CHECKPOINT *checkpoint = sigdata->checkpoint;
- while (checkpoint->next && checkpoint->next->time < pos)
- checkpoint = checkpoint->next;
- sigrenderer = dup_sigrenderer(checkpoint->sigrenderer, n_channels, callbacks);
- if (!sigrenderer) return NULL;
- sigrenderer->click_remover = dumb_create_click_remover_array(n_channels);
- pos -= checkpoint->time;
- } else {
- sigrenderer = init_sigrenderer(sigdata, n_channels, 0, callbacks,
- dumb_create_click_remover_array(n_channels));
- if (!sigrenderer) return NULL;
- }
- }
-
- while (pos >= sigrenderer->time_left) {
- render(sigrenderer, 0, 1.0f, 0, sigrenderer->time_left, NULL);
-
- pos -= sigrenderer->time_left;
- sigrenderer->time_left = 0;
-
- if (process_tick(sigrenderer)) {
- _dumb_it_end_sigrenderer(sigrenderer);
- return NULL;
- }
- }
-
- render(sigrenderer, 0, 1.0f, 0, pos, NULL);
- sigrenderer->time_left -= pos;
-
- return sigrenderer;
-}
-
-
-
-static long it_sigrenderer_get_samples(
- sigrenderer_t *vsigrenderer,
- float volume, float delta,
- long size, sample_t **samples
-)
-{
- DUMB_IT_SIGRENDERER *sigrenderer = vsigrenderer;
- long pos;
- int dt;
- long todo;
- LONG_LONG t;
-
- if (sigrenderer->order < 0) return 0; // problematic
-
- pos = 0;
- dt = (int)(delta * 65536.0f + 0.5f);
-
- /* When samples is finally used in render_playing(), it won't be used if
- * volume is 0.
- */
- if (!samples) volume = 0;
-
- for (;;) {
- todo = (long)((((LONG_LONG)sigrenderer->time_left << 16) | sigrenderer->sub_time_left) / dt);
-
- if (todo >= size)
- break;
-
- render(sigrenderer, volume, delta, pos, todo, samples);
-
- pos += todo;
- size -= todo;
-
- t = sigrenderer->sub_time_left - (LONG_LONG)todo * dt;
- sigrenderer->sub_time_left = (long)t & 65535;
- sigrenderer->time_left += (long)(t >> 16);
-
- if (process_tick(sigrenderer)) {
- sigrenderer->order = -1;
- sigrenderer->row = -1;
- return pos;
- }
- }
-
- render(sigrenderer, volume, delta, pos, size, samples);
-
- pos += size;
-
- t = sigrenderer->sub_time_left - (LONG_LONG)size * dt;
- sigrenderer->sub_time_left = (long)t & 65535;
- sigrenderer->time_left += (long)(t >> 16);
-
- if (samples)
- dumb_remove_clicks_array(sigrenderer->n_channels, sigrenderer->click_remover, samples, pos, 512.0f / delta);
-
- return pos;
-}
-
-
-
-static void it_sigrenderer_get_current_sample(sigrenderer_t *vsigrenderer, float volume, sample_t *samples)
-{
- DUMB_IT_SIGRENDERER *sigrenderer = vsigrenderer;
- (void)volume; // for consideration: in any of these such functions, is 'volume' going to be required?
- dumb_click_remover_get_offset_array(sigrenderer->n_channels, sigrenderer->click_remover, samples);
-}
-
-
-
-void _dumb_it_end_sigrenderer(sigrenderer_t *vsigrenderer)
-{
- DUMB_IT_SIGRENDERER *sigrenderer = vsigrenderer;
-
- int i;
-
- if (sigrenderer) {
- for (i = 0; i < DUMB_IT_N_CHANNELS; i++)
- if (sigrenderer->channel[i].playing)
- free(sigrenderer->channel[i].playing);
-
- for (i = 0; i < DUMB_IT_N_NNA_CHANNELS; i++)
- if (sigrenderer->playing[i])
- free(sigrenderer->playing[i]);
-
- dumb_destroy_click_remover_array(sigrenderer->n_channels, sigrenderer->click_remover);
-
- if (sigrenderer->callbacks)
- free(sigrenderer->callbacks);
-
- free(vsigrenderer);
- }
-}
-
-
-
-DUH_SIGTYPE_DESC _dumb_sigtype_it = {
- SIGTYPE_IT,
- NULL,
- &it_start_sigrenderer,
- NULL,
- &it_sigrenderer_get_samples,
- &it_sigrenderer_get_current_sample,
- &_dumb_it_end_sigrenderer,
- &_dumb_it_unload_sigdata
-};
-
-
-
-DUH_SIGRENDERER *duh_encapsulate_it_sigrenderer(DUMB_IT_SIGRENDERER *it_sigrenderer, int n_channels, long pos)
-{
- return duh_encapsulate_raw_sigrenderer(it_sigrenderer, &_dumb_sigtype_it, n_channels, pos);
-}
-
-
-
-DUMB_IT_SIGRENDERER *duh_get_it_sigrenderer(DUH_SIGRENDERER *sigrenderer)
-{
- return duh_get_raw_sigrenderer(sigrenderer, SIGTYPE_IT);
-}
-
-
-
-/* Values of 64 or more will access NNA channels here. */
-void dumb_it_sr_get_channel_state(DUMB_IT_SIGRENDERER *sr, int channel, DUMB_IT_CHANNEL_STATE *state)
-{
- IT_PLAYING *playing;
- int t; /* temporary var for holding accurate pan and filter cutoff */
- float delta;
- ASSERT(channel < DUMB_IT_TOTAL_CHANNELS);
- if (!sr) { state->sample = 0; return; }
- if (channel >= DUMB_IT_N_CHANNELS) {
- playing = sr->playing[channel - DUMB_IT_N_CHANNELS];
- if (!playing) { state->sample = 0; return; }
- } else {
- playing = sr->channel[channel].playing;
- if (!playing) { state->sample = 0; return; }
- }
-
- if (playing->flags & IT_PLAYING_DEAD) { state->sample = 0; return; }
-
- state->channel = playing->channel - sr->channel;
- state->sample = playing->sampnum;
- state->volume = calculate_volume(sr, playing, 1.0f);
-
- t = apply_pan_envelope(playing);
- state->pan = (unsigned char)((t + 128) >> IT_ENVELOPE_SHIFT);
- state->subpan = (signed char)t;
-
- delta = playing->delta * 65536.0f;
- t = playing->filter_cutoff << IT_ENVELOPE_SHIFT;
- apply_pitch_modifications(sr->sigdata, playing, &delta, &t);
- state->freq = (int)delta;
- if (t == 127 << IT_ENVELOPE_SHIFT && playing->filter_resonance == 0) {
- state->filter_resonance = playing->true_filter_resonance;
- t = playing->true_filter_cutoff;
- } else
- state->filter_resonance = playing->filter_resonance;
- state->filter_cutoff = (unsigned char)(t >> 8);
- state->filter_subcutoff = (unsigned char)t;
-}
-
-
-
-int dumb_it_callback_terminate(void *data)
-{
- (void)data;
- return 1;
-}
-
-
-
-int dumb_it_callback_midi_block(void *data, int channel, unsigned char midi_byte)
-{
- (void)data;
- (void)channel;
- (void)midi_byte;
- return 1;
-}
-
-
-
-#define IT_CHECKPOINT_INTERVAL (30 * 65536) /* Half a minute */
-
-
-
-/* Returns the length of the module, up until it first loops. */
-long dumb_it_build_checkpoints(DUMB_IT_SIGDATA *sigdata)
-{
- IT_CHECKPOINT *checkpoint;
- if (!sigdata) return 0;
- checkpoint = sigdata->checkpoint;
- while (checkpoint) {
- IT_CHECKPOINT *next = checkpoint->next;
- _dumb_it_end_sigrenderer(checkpoint->sigrenderer);
- free(checkpoint);
- checkpoint = next;
- }
- sigdata->checkpoint = NULL;
- checkpoint = malloc(sizeof(*checkpoint));
- if (!checkpoint) return 0;
- checkpoint->time = 0;
- checkpoint->sigrenderer = dumb_it_init_sigrenderer(sigdata, 0, 0);
- if (!checkpoint->sigrenderer) {
- free(checkpoint);
- return 0;
- }
- checkpoint->sigrenderer->callbacks->loop = &dumb_it_callback_terminate;
- checkpoint->sigrenderer->callbacks->xm_speed_zero = &dumb_it_callback_terminate;
- sigdata->checkpoint = checkpoint;
-
- for (;;) {
- long l;
- DUMB_IT_SIGRENDERER *sigrenderer = dup_sigrenderer(checkpoint->sigrenderer, 0, checkpoint->sigrenderer->callbacks);
- checkpoint->sigrenderer->callbacks = NULL;
- if (!sigrenderer) {
- checkpoint->next = NULL;
- return checkpoint->time;
- }
-
- l = it_sigrenderer_get_samples(sigrenderer, 0, 1.0f, IT_CHECKPOINT_INTERVAL, NULL);
- if (l < IT_CHECKPOINT_INTERVAL) {
- _dumb_it_end_sigrenderer(sigrenderer);
- checkpoint->next = NULL;
- return checkpoint->time + l;
- }
-
- checkpoint->next = malloc(sizeof(*checkpoint->next));
- if (!checkpoint->next) {
- _dumb_it_end_sigrenderer(sigrenderer);
- return checkpoint->time + IT_CHECKPOINT_INTERVAL;
- }
-
- checkpoint->next->time = checkpoint->time + IT_CHECKPOINT_INTERVAL;
- checkpoint = checkpoint->next;
- checkpoint->sigrenderer = sigrenderer;
- }
-}
-
-
-
-void dumb_it_do_initial_runthrough(DUH *duh)
-{
- if (duh) {
- DUMB_IT_SIGDATA *sigdata = duh_get_it_sigdata(duh);
-
- if (sigdata)
- duh_set_length(duh, dumb_it_build_checkpoints(sigdata));
- }
-}
diff --git a/dumb/dumb-0.9.3/src/it/itunload.c b/dumb/dumb-0.9.3/src/it/itunload.c
deleted file mode 100644
index efed192a..00000000
--- a/dumb/dumb-0.9.3/src/it/itunload.c
+++ /dev/null
@@ -1,72 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * itunload.c - Code to free an Impulse Tracker / / \ \
- * module from memory. | < / \_
- * | \/ /\ /
- * By entheh. \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <stdlib.h>
-
-#include "dumb.h"
-#include "internal/it.h"
-
-
-
-void _dumb_it_unload_sigdata(sigdata_t *vsigdata)
-{
- if (vsigdata) {
- DUMB_IT_SIGDATA *sigdata = vsigdata;
- int n;
-
- if (sigdata->song_message)
- free(sigdata->song_message);
-
- if (sigdata->order)
- free(sigdata->order);
-
- if (sigdata->instrument)
- free(sigdata->instrument);
-
- if (sigdata->sample) {
- for (n = 0; n < sigdata->n_samples; n++)
- if (sigdata->sample[n].data)
- free(sigdata->sample[n].data);
-
- free(sigdata->sample);
- }
-
- if (sigdata->pattern) {
- for (n = 0; n < sigdata->n_patterns; n++)
- if (sigdata->pattern[n].entry)
- free(sigdata->pattern[n].entry);
- free(sigdata->pattern);
- }
-
- if (sigdata->midi)
- free(sigdata->midi);
-
- {
- IT_CHECKPOINT *checkpoint = sigdata->checkpoint;
- while (checkpoint) {
- IT_CHECKPOINT *next = checkpoint->next;
- _dumb_it_end_sigrenderer(checkpoint->sigrenderer);
- free(checkpoint);
- checkpoint = next;
- }
- }
-
- free(vsigdata);
- }
-}
diff --git a/dumb/dumb-0.9.3/src/it/loadmod.c b/dumb/dumb-0.9.3/src/it/loadmod.c
deleted file mode 100644
index 121e2881..00000000
--- a/dumb/dumb-0.9.3/src/it/loadmod.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * loadmod.c - Code to read a good old-fashioned / / \ \
- * Amiga module file, opening and | < / \_
- * closing it for you. | \/ /\ /
- * \_ / > /
- * By entheh. | \ / /
- * | ' /
- * \__/
- */
-
-#include "dumb.h"
-#include "internal/it.h"
-
-
-
-/* dumb_load_mod_quick(): loads a MOD file into a DUH struct, returning a
- * pointer to the DUH struct. When you have finished with it, you must
- * pass the pointer to unload_duh() so that the memory can be freed.
- */
-DUH *dumb_load_mod_quick(const char *filename)
-{
- DUH *duh;
- DUMBFILE *f = dumbfile_open(filename);
-
- if (!f)
- return NULL;
-
- duh = dumb_read_mod_quick(f);
-
- dumbfile_close(f);
-
- return duh;
-}
diff --git a/dumb/dumb-0.9.3/src/it/loadmod2.c b/dumb/dumb-0.9.3/src/it/loadmod2.c
deleted file mode 100644
index ec705f81..00000000
--- a/dumb/dumb-0.9.3/src/it/loadmod2.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * loadmod2.c - Function to read a good old- / / \ \
- * fashioned Amiga module file, | < / \_
- * opening and closing it for you, | \/ /\ /
- * and do an initial run-through. \_ / > /
- * | \ / /
- * Split off from loadmod.c by entheh. | ' /
- * \__/
- */
-
-#include "dumb.h"
-
-
-
-DUH *dumb_load_mod(const char *filename)
-{
- DUH *duh = dumb_load_mod_quick(filename);
- dumb_it_do_initial_runthrough(duh);
- return duh;
-}
diff --git a/dumb/dumb-0.9.3/src/it/loads3m.c b/dumb/dumb-0.9.3/src/it/loads3m.c
deleted file mode 100644
index 777151c6..00000000
--- a/dumb/dumb-0.9.3/src/it/loads3m.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * loads3m.c - Code to read a ScreamTracker 3 / / \ \
- * file, opening and closing it for | < / \_
- * you. | \/ /\ /
- * \_ / > /
- * By entheh. | \ / /
- * | ' /
- * \__/
- */
-
-#include "dumb.h"
-#include "internal/it.h"
-
-
-
-/* dumb_load_s3m_quick(): loads an S3M file into a DUH struct, returning
- * a pointer to the DUH struct. When you have finished with it, you must
- * pass the pointer to unload_duh() so that the memory can be freed.
- */
-DUH *dumb_load_s3m_quick(const char *filename)
-{
- DUH *duh;
- DUMBFILE *f = dumbfile_open(filename);
-
- if (!f)
- return NULL;
-
- duh = dumb_read_s3m_quick(f);
-
- dumbfile_close(f);
-
- return duh;
-}
diff --git a/dumb/dumb-0.9.3/src/it/loads3m2.c b/dumb/dumb-0.9.3/src/it/loads3m2.c
deleted file mode 100644
index 8b55e83d..00000000
--- a/dumb/dumb-0.9.3/src/it/loads3m2.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * loads3m2.c - Function to read a ScreamTracker 3 / / \ \
- * file, opening and closing it for | < / \_
- * you, and do an initial run-through. | \/ /\ /
- * \_ / > /
- * Split off from loads3m.c by entheh. | \ / /
- * | ' /
- * \__/
- */
-
-#include "dumb.h"
-
-
-
-DUH *dumb_load_s3m(const char *filename)
-{
- DUH *duh = dumb_load_s3m_quick(filename);
- dumb_it_do_initial_runthrough(duh);
- return duh;
-}
diff --git a/dumb/dumb-0.9.3/src/it/loadxm.c b/dumb/dumb-0.9.3/src/it/loadxm.c
deleted file mode 100644
index 2c8067cb..00000000
--- a/dumb/dumb-0.9.3/src/it/loadxm.c
+++ /dev/null
@@ -1,42 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * loadxm.c - Code to read a Fast Tracker II / / \ \
- * file, opening and closing it for | < / \_
- * you. | \/ /\ /
- * \_ / > /
- * By entheh. | \ / /
- * | ' /
- * \__/
- */
-
-#include "dumb.h"
-#include "internal/it.h"
-
-
-
-/* dumb_load_xm_quick(): loads an XM file into a DUH struct, returning a
- * pointer to the DUH struct. When you have finished with it, you must
- * pass the pointer to unload_duh() so that the memory can be freed.
- */
-DUH *dumb_load_xm_quick(const char *filename)
-{
- DUH *duh;
- DUMBFILE *f = dumbfile_open(filename);
-
- if (!f)
- return NULL;
-
- duh = dumb_read_xm_quick(f);
-
- dumbfile_close(f);
-
- return duh;
-}
diff --git a/dumb/dumb-0.9.3/src/it/loadxm2.c b/dumb/dumb-0.9.3/src/it/loadxm2.c
deleted file mode 100644
index a596542a..00000000
--- a/dumb/dumb-0.9.3/src/it/loadxm2.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * loadxm2.c - Function to read a Fast Tracker II / / \ \
- * file, opening and closing it for | < / \_
- * you, and do an initial run-through. | \/ /\ /
- * \_ / > /
- * Split off from loadxm.c by entheh. | \ / /
- * | ' /
- * \__/
- */
-
-#include "dumb.h"
-
-
-
-DUH *dumb_load_xm(const char *filename)
-{
- DUH *duh = dumb_load_xm_quick(filename);
- dumb_it_do_initial_runthrough(duh);
- return duh;
-}
diff --git a/dumb/dumb-0.9.3/src/it/readmod.c b/dumb/dumb-0.9.3/src/it/readmod.c
deleted file mode 100644
index 52d27305..00000000
--- a/dumb/dumb-0.9.3/src/it/readmod.c
+++ /dev/null
@@ -1,604 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * readmod.c - Code to read a good old-fashioned / / \ \
- * Amiga module from an open file. | < / \_
- * | \/ /\ /
- * By entheh. \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-#include "dumb.h"
-#include "internal/it.h"
-
-
-
-static int it_mod_read_pattern(IT_PATTERN *pattern, DUMBFILE *f, int n_channels, unsigned char *buffer)
-{
- int pos;
- int channel;
- int row;
- IT_ENTRY *entry;
-
- pattern->n_rows = 64;
-
- if (n_channels == 0) {
- /* Read the first four channels, leaving gaps for the rest. */
- for (pos = 0; pos < 64*8*4; pos += 8*4)
- dumbfile_getnc(buffer + pos, 4*4, f);
- /* Read the other channels into the gaps we left. */
- for (pos = 4*4; pos < 64*8*4; pos += 8*4)
- dumbfile_getnc(buffer + pos, 4*4, f);
-
- n_channels = 8;
- } else
- dumbfile_getnc(buffer, 64 * n_channels * 4, f);
-
- if (dumbfile_error(f))
- return -1;
-
- /* compute number of entries */
- pattern->n_entries = 64; /* Account for the row end markers */
- pos = 0;
- for (row = 0; row < 64; row++) {
- for (channel = 0; channel < n_channels; channel++) {
- if (buffer[pos+0] | buffer[pos+1] | buffer[pos+2] | buffer[pos+3])
- pattern->n_entries++;
- pos += 4;
- }
- }
-
- pattern->entry = malloc(pattern->n_entries * sizeof(*pattern->entry));
- if (!pattern->entry)
- return -1;
-
- entry = pattern->entry;
- pos = 0;
- for (row = 0; row < 64; row++) {
- for (channel = 0; channel < n_channels; channel++) {
- if (buffer[pos+0] | buffer[pos+1] | buffer[pos+2] | buffer[pos+3]) {
- unsigned char sample = (buffer[pos+0] & 0xF0) | (buffer[pos+2] >> 4);
- int period = ((int)(buffer[pos+0] & 0x0F) << 8) | buffer[pos+1];
-
- entry->channel = channel;
- entry->mask = 0;
-
- if (period) {
- int note;
- entry->mask |= IT_ENTRY_NOTE;
-
- /* frequency = (AMIGA_DIVISOR / 8) / (period * 2)
- * C-1: period = 214 -> frequency = 16726
- * so, set C5_speed to 16726
- * and period = 214 should translate to C5 aka 60
- * halve the period, go up an octive
- *
- * period = 214 / pow(DUMB_SEMITONE_BASE, note - 60)
- * pow(DUMB_SEMITONE_BASE, note - 60) = 214 / period
- * note - 60 = log(214/period) / log(DUMB_SEMITONE_BASE)
- */
- note = (int)floor(log(214.0/period) / log(DUMB_SEMITONE_BASE) + 60.5);
- entry->note = MID(0, note, 119);
- // or should we preserve the period?
- //entry->note = buffer[pos+0] & 0x0F; /* High nibble */
- //entry->volpan = buffer[pos+1]; /* Low byte */
- // and what about finetune?
- }
-
- if (sample) {
- entry->mask |= IT_ENTRY_INSTRUMENT;
- entry->instrument = sample;
- }
-
- _dumb_it_xm_convert_effect(buffer[pos+2] & 0x0F, buffer[pos+3], entry);
-
- entry++;
- }
- pos += 4;
- }
- IT_SET_END_ROW(entry);
- entry++;
- }
-
- return 0;
-}
-
-
-
-static int it_mod_read_sample_header(IT_SAMPLE *sample, DUMBFILE *f)
-{
- int finetune;
-
-/**
- 21 22 Chars Sample 1 name. If the name is not a full
- 22 chars in length, it will be null
- terminated.
-
-If
-the sample name begins with a '#' character (ASCII $23 (35)) then this is
-assumed not to be an instrument name, and is probably a message.
-*/
- dumbfile_getnc(sample->name, 22, f);
- sample->name[22] = 0;
-
- sample->filename[0] = 0;
-
- sample->length = dumbfile_mgetw(f) << 1;
- finetune = (signed char)(dumbfile_getc(f) << 4) >> 4; /* signed nibble */
-/** Each finetune step changes the note 1/8th of a semitone. */
- sample->global_volume = 64;
- sample->default_volume = dumbfile_getc(f); // Should we be setting global_volume to this instead?
- sample->loop_start = dumbfile_mgetw(f) << 1;
- sample->loop_end = sample->loop_start + (dumbfile_mgetw(f) << 1);
-/**
-Once this sample has been played completely from beginning
-to end, if the repeat length (next field) is greater than two bytes it
-will loop back to this position in the sample and continue playing. Once
-it has played for the repeat length, it continues to loop back to the
-repeat start offset. This means the sample continues playing until it is
-told to stop.
-*/
-
- if (sample->length <= 0) {
- sample->flags = 0;
- return 0;
- }
-
- sample->flags = IT_SAMPLE_EXISTS;
-
- sample->default_pan = 0;
- sample->C5_speed = (long)(16726.0*pow(DUMB_PITCH_BASE, finetune*32));
- // the above line might be wrong
-
- if (sample->loop_end > sample->length)
- sample->loop_end = sample->length;
-
- if (sample->loop_end - sample->loop_start > 2)
- sample->flags |= IT_SAMPLE_LOOP;
-
- sample->vibrato_speed = 0;
- sample->vibrato_depth = 0;
- sample->vibrato_rate = 0;
- sample->vibrato_waveform = 0; // do we have to set _all_ these?
-
- return dumbfile_error(f);
-}
-
-
-
-static int it_mod_read_sample_data(IT_SAMPLE *sample, DUMBFILE *f)
-{
- long i;
- long truncated_size;
-
- /* let's get rid of the sample data coming after the end of the loop */
- if ((sample->flags & IT_SAMPLE_LOOP) && sample->loop_end < sample->length) {
- truncated_size = sample->length - sample->loop_end;
- sample->length = sample->loop_end;
- } else {
- truncated_size = 0;
- }
-
- if (sample->length) {
- sample->data = malloc(sample->length);
-
- if (!sample->data)
- return -1;
-
- /* Sample data are stored in "8-bit two's compliment format" (sic). */
- for (i = 0; i < sample->length; i++)
- ((signed char *)sample->data)[i] = dumbfile_getc(f);
- } else
- sample->flags &= ~IT_SAMPLE_EXISTS;
-
- /* skip truncated data */
- dumbfile_skip(f, truncated_size);
- // Should we be truncating it?
-
- if (dumbfile_error(f))
- return -1;
-
- return 0;
-}
-
-
-
-typedef struct BUFFERED_MOD BUFFERED_MOD;
-
-struct BUFFERED_MOD
-{
- unsigned char *buffered;
- long ptr, len;
- DUMBFILE *remaining;
-};
-
-
-
-static int buffer_mod_skip(void *f, long n)
-{
- BUFFERED_MOD *bm = f;
- if (bm->buffered) {
- bm->ptr += n;
- if (bm->ptr >= bm->len) {
- free(bm->buffered);
- bm->buffered = NULL;
- return dumbfile_skip(bm->remaining, bm->ptr - bm->len);
- }
- return 0;
- }
- return dumbfile_skip(bm->remaining, n);
-}
-
-
-
-static int buffer_mod_getc(void *f)
-{
- BUFFERED_MOD *bm = f;
- if (bm->buffered) {
- int rv = bm->buffered[bm->ptr++];
- if (bm->ptr >= bm->len) {
- free(bm->buffered);
- bm->buffered = NULL;
- }
- return rv;
- }
- return dumbfile_getc(bm->remaining);
-}
-
-
-
-static long buffer_mod_getnc(char *ptr, long n, void *f)
-{
- BUFFERED_MOD *bm = f;
- if (bm->buffered) {
- int left = bm->len - bm->ptr;
- if (n >= left) {
- int rv;
- memcpy(ptr, bm->buffered + bm->ptr, left);
- free(bm->buffered);
- bm->buffered = NULL;
- rv = dumbfile_getnc(ptr + left, n - left, bm->remaining);
- return left + MAX(rv, 0);
- }
- memcpy(ptr, bm->buffered + bm->ptr, n);
- bm->ptr += n;
- return n;
- }
- return dumbfile_getnc(ptr, n, bm->remaining);
-}
-
-
-
-static void buffer_mod_close(void *f)
-{
- BUFFERED_MOD *bm = f;
- if (bm->buffered) free(bm->buffered);
- /* Do NOT close bm->remaining */
- free(f);
-}
-
-
-
-DUMBFILE_SYSTEM buffer_mod_dfs = {
- NULL,
- &buffer_mod_skip,
- &buffer_mod_getc,
- &buffer_mod_getnc,
- &buffer_mod_close
-};
-
-
-
-#define MOD_FFT_OFFSET (20 + 31*(22+2+1+1+2+2) + 1 + 1 + 128)
-
-static DUMBFILE *dumbfile_buffer_mod(DUMBFILE *f, unsigned long *fft)
-{
- BUFFERED_MOD *bm = malloc(sizeof(*bm));
- if (!bm) return NULL;
-
- bm->buffered = malloc(MOD_FFT_OFFSET + 4);
- if (!bm->buffered) {
- free(bm);
- return NULL;
- }
-
- bm->len = dumbfile_getnc(bm->buffered, MOD_FFT_OFFSET + 4, f);
-
- if (bm->len > 0) {
- if (bm->len >= MOD_FFT_OFFSET + 4)
- *fft = (unsigned long)bm->buffered[MOD_FFT_OFFSET ] << 24
- | (unsigned long)bm->buffered[MOD_FFT_OFFSET+1] << 16
- | (unsigned long)bm->buffered[MOD_FFT_OFFSET+2] << 8
- | (unsigned long)bm->buffered[MOD_FFT_OFFSET+3];
- else
- *fft = 0;
- bm->ptr = 0;
- } else {
- free(bm->buffered);
- bm->buffered = NULL;
- }
-
- bm->remaining = f;
-
- return dumbfile_open_ex(bm, &buffer_mod_dfs);
-}
-
-
-
-static DUMB_IT_SIGDATA *it_mod_load_sigdata(DUMBFILE *f)
-{
- DUMB_IT_SIGDATA *sigdata;
- int n_channels;
- int i;
- unsigned long fft;
-
- f = dumbfile_buffer_mod(f, &fft);
- if (!f)
- return NULL;
-
- sigdata = malloc(sizeof(*sigdata));
- if (!sigdata) {
- dumbfile_close(f);
- return NULL;
- }
-
- /**
- 1 20 Chars Title of the song. If the title is not a
- full 20 chars in length, it will be null-
- terminated.
- */
- if (dumbfile_getnc(sigdata->name, 20, f) < 20) {
- free(sigdata);
- dumbfile_close(f);
- return NULL;
- }
- sigdata->name[20] = 0;
-
- sigdata->n_samples = 31;
-
- switch (fft) {
- case DUMB_ID('M','.','K','.'):
- case DUMB_ID('M','!','K','!'):
- case DUMB_ID('M','&','K','!'):
- case DUMB_ID('N','.','T','.'):
- case DUMB_ID('F','L','T','4'):
- n_channels = 4;
- break;
- case DUMB_ID('F','L','T','8'):
- n_channels = 0;
- /* 0 indicates a special case; two four-channel patterns must be
- * combined into one eight-channel pattern. Pattern indexes must
- * be halved. Why oh why do they obfuscate so?
- */
- for (i = 0; i < 128; i++)
- sigdata->order[i] >>= 1;
- break;
- case DUMB_ID('C','D','8','1'):
- case DUMB_ID('O','C','T','A'):
- case DUMB_ID('O','K','T','A'):
- n_channels = 8;
- break;
- case DUMB_ID('1','6','C','N'):
- n_channels = 16;
- break;
- case DUMB_ID('3','2','C','N'):
- n_channels = 32;
- break;
- default:
- /* If we get an illegal tag, assume 4 channels 15 samples. */
- if ((fft & 0x0000FFFFL) == DUMB_ID(0,0,'C','H')) {
- if (fft >= '1' << 24 && fft < '4' << 24) {
- n_channels = ((fft & 0x00FF0000L) >> 16) - '0';
- if ((unsigned int)n_channels >= 10) {
- /* Rightmost character wasn't a digit. */
- n_channels = 4;
- sigdata->n_samples = 15;
- } else {
- n_channels += (((fft & 0xFF000000L) >> 24) - '0') * 10;
- /* MODs should really only go up to 32 channels, but we're lenient. */
- if ((unsigned int)(n_channels - 1) >= DUMB_IT_N_CHANNELS - 1) {
- /* No channels or too many? Can't be right... */
- n_channels = 4;
- sigdata->n_samples = 15;
- }
- }
- } else {
- n_channels = 4;
- sigdata->n_samples = 15;
- }
- } else if ((fft & 0x00FFFFFFL) == DUMB_ID(0,'C','H','N')) {
- n_channels = (fft >> 24) - '0';
- if ((unsigned int)(n_channels - 1) >= 9) {
- /* Character was '0' or it wasn't a digit */
- n_channels = 4;
- sigdata->n_samples = 15;
- }
- } else if ((fft & 0xFFFFFF00L) == DUMB_ID('T','D','Z',0)) {
- n_channels = (fft & 0x000000FFL) - '0';
- if ((unsigned int)(n_channels - 1) >= 9) {
- /* We've been very lenient, given that it should have
- * been 1, 2 or 3, but this MOD has been very naughty and
- * must be punished.
- */
- n_channels = 4;
- sigdata->n_samples = 15;
- }
- } else {
- n_channels = 4;
- sigdata->n_samples = 15;
- }
- }
-
- sigdata->sample = malloc(sigdata->n_samples * sizeof(*sigdata->sample));
- if (!sigdata->sample) {
- free(sigdata);
- dumbfile_close(f);
- return NULL;
- }
-
- sigdata->song_message = NULL;
- sigdata->order = NULL;
- sigdata->instrument = NULL;
- sigdata->pattern = NULL;
- sigdata->midi = NULL;
- sigdata->checkpoint = NULL;
-
- sigdata->n_instruments = 0;
-
- for (i = 0; i < sigdata->n_samples; i++)
- sigdata->sample[i].data = NULL;
-
- for (i = 0; i < sigdata->n_samples; i++) {
- if (it_mod_read_sample_header(&sigdata->sample[i], f)) {
- _dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- return NULL;
- }
- }
-
- sigdata->n_orders = dumbfile_getc(f);
- sigdata->restart_position = dumbfile_getc(f);
- // what if this is >= 127? what about with Fast Tracker II?
-
- if (sigdata->n_orders <= 0 || sigdata->n_orders > 128) { // is this right?
- _dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- return NULL;
- }
-
- //if (sigdata->restart_position >= sigdata->n_orders)
- //sigdata->restart_position = 0;
-
- sigdata->order = malloc(128); /* We may need to scan the extra ones! */
- if (!sigdata->order) {
- _dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- return NULL;
- }
- if (dumbfile_getnc(sigdata->order, 128, f) < 128) {
- _dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- return NULL;
- }
-
- /* "The old NST format contains only 15 samples (instead of 31). Further
- * it doesn't contain a file format tag (id). So Pattern data offset is
- * at 20+15*30+1+1+128."
- * - Then I shall assume the File Format Tag never exists if there are
- * only 15 samples. I hope this isn't a faulty assumption...
- */
- if (sigdata->n_samples == 31)
- dumbfile_skip(f, 4);
-
- /* Work out how many patterns there are. */
- sigdata->n_patterns = -1;
- for (i = 0; i < 128; i++)
- if (sigdata->n_patterns < sigdata->order[i])
- sigdata->n_patterns = sigdata->order[i];
- sigdata->n_patterns++;
-
- /* May as well try to save a tiny bit of memory. */
- if (sigdata->n_orders < 128) {
- unsigned char *order = realloc(sigdata->order, sigdata->n_orders);
- if (order) sigdata->order = order;
- }
-
- sigdata->pattern = malloc(sigdata->n_patterns * sizeof(*sigdata->pattern));
- if (!sigdata->pattern) {
- _dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- return NULL;
- }
- for (i = 0; i < sigdata->n_patterns; i++)
- sigdata->pattern[i].entry = NULL;
-
- /* Read in the patterns */
- {
- unsigned char *buffer = malloc(256 * n_channels); /* 64 rows * 4 bytes */
- if (!buffer) {
- _dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- return NULL;
- }
- for (i = 0; i < sigdata->n_patterns; i++) {
- if (it_mod_read_pattern(&sigdata->pattern[i], f, n_channels, buffer) != 0) {
- free(buffer);
- _dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- return NULL;
- }
- }
- free(buffer);
- }
-
- /* And finally, the sample data */
- for (i = 0; i < sigdata->n_samples; i++) {
- if (it_mod_read_sample_data(&sigdata->sample[i], f)) {
- _dumb_it_unload_sigdata(sigdata);
- dumbfile_close(f);
- return NULL;
- }
- }
-
- dumbfile_close(f); /* Destroy the BUFFERED_MOD DUMBFILE we were using. */
- /* The DUMBFILE originally passed to our function is intact. */
-
- /* Now let's initialise the remaining variables, and we're done! */
- sigdata->flags = IT_WAS_AN_XM | IT_WAS_A_MOD | IT_OLD_EFFECTS | IT_COMPATIBLE_GXX | IT_STEREO;
-
- sigdata->global_volume = 128;
- sigdata->mixing_volume = 48;
- /* We want 50 ticks per second; 50/6 row advances per second;
- * 50*10=500 row advances per minute; 500/4=125 beats per minute.
- */
- sigdata->speed = 6;
- sigdata->tempo = 125;
- sigdata->pan_separation = 128;
-
- memset(sigdata->channel_volume, 64, DUMB_IT_N_CHANNELS);
-
- for (i = 0; i < DUMB_IT_N_CHANNELS; i += 4) {
- sigdata->channel_pan[i+0] = 16;
- sigdata->channel_pan[i+1] = 48;
- sigdata->channel_pan[i+2] = 48;
- sigdata->channel_pan[i+3] = 16;
- }
-
- _dumb_it_fix_invalid_orders(sigdata);
-
- return sigdata;
-}
-
-
-
-DUH *dumb_read_mod_quick(DUMBFILE *f)
-{
- sigdata_t *sigdata;
-
- DUH_SIGTYPE_DESC *descptr = &_dumb_sigtype_it;
-
- sigdata = it_mod_load_sigdata(f);
-
- if (!sigdata)
- return NULL;
-
- {
- const char *tag[1][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);
- }
-}
diff --git a/dumb/dumb-0.9.3/src/it/readmod2.c b/dumb/dumb-0.9.3/src/it/readmod2.c
deleted file mode 100644
index a031b47e..00000000
--- a/dumb/dumb-0.9.3/src/it/readmod2.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * readmod2.c - Function to read a good old- / / \ \
- * fashioned Amiga module from an | < / \_
- * open file and do an initial | \/ /\ /
- * run-through. \_ / > /
- * | \ / /
- * Split off from readmod.c by entheh. | ' /
- * \__/
- */
-
-#include "dumb.h"
-
-
-
-DUH *dumb_read_mod(DUMBFILE *f)
-{
- DUH *duh = dumb_read_mod_quick(f);
- dumb_it_do_initial_runthrough(duh);
- return duh;
-}
diff --git a/dumb/dumb-0.9.3/src/it/reads3m.c b/dumb/dumb-0.9.3/src/it/reads3m.c
deleted file mode 100644
index 97d09d7d..00000000
--- a/dumb/dumb-0.9.3/src/it/reads3m.c
+++ /dev/null
@@ -1,670 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * reads3m.c - Code to read a ScreamTracker 3 / / \ \
- * module from an open file. | < / \_
- * | \/ /\ /
- * By entheh. \_ / > /
- * | \ / /
- * | ' /
- * \__/
- */
-
-// IT_STEREO... :o
-#include <stdlib.h>
-#include <string.h>
-
-#include "dumb.h"
-#include "internal/it.h"
-
-
-
-/** WARNING: this is duplicated in itread.c */
-static int it_seek(DUMBFILE *f, long offset)
-{
- long pos = dumbfile_pos(f);
-
- if (pos > offset)
- return -1;
-
- if (pos < offset)
- if (dumbfile_skip(f, offset - pos))
- return -1;
-
- return 0;
-}
-
-
-
-static int it_s3m_read_sample_header(IT_SAMPLE *sample, long *offset, DUMBFILE *f)
-{
- unsigned char type;
- int flags;
-
- type = dumbfile_getc(f);
-
- if (type > 1) {
- /** WARNING: no adlib support */
- }
-
- dumbfile_getnc(sample->filename, 13, f);
- sample->filename[13] = 0;
-
- *offset = dumbfile_igetw(f) << 4;
-
- sample->length = dumbfile_igetl(f);
- sample->loop_start = dumbfile_igetl(f);
- sample->loop_end = dumbfile_igetl(f);
-
- sample->default_volume = dumbfile_getc(f);
-
- dumbfile_skip(f, 1);
-
- if (dumbfile_getc(f) != 0)
- /* Sample is packed apparently (or error reading from file). We don't
- * know how to read packed samples.
- */
- return -1;
-
- flags = dumbfile_getc(f);
-
- sample->C5_speed = dumbfile_igetl(f) << 1;
-
- /* Skip four unused bytes and three internal variables. */
- dumbfile_skip(f, 4+2+2+4);
-
- dumbfile_getnc(sample->name, 28, f);
- sample->name[28] = 0;
-
- if (type == 0) {
- /* Looks like no-existy. Anyway, there's for sure no 'SCRS' ... */
- sample->flags &= ~IT_SAMPLE_EXISTS;
- return dumbfile_error(f);
- }
-
- if (dumbfile_mgetl(f) != DUMB_ID('S','C','R','S'))
- return -1;
-
- sample->global_volume = 64;
-
- sample->flags = IT_SAMPLE_EXISTS;
- if (flags & 1) sample->flags |= IT_SAMPLE_LOOP;
- if (flags & 2) sample->flags |= IT_SAMPLE_STEREO;
- if (flags & 4) sample->flags |= IT_SAMPLE_16BIT;
-
- sample->default_pan = 0; // 0 = don't use, or 160 = centre?
-
- if (sample->length <= 0)
- sample->flags &= ~IT_SAMPLE_EXISTS;
- else if (sample->flags & IT_SAMPLE_LOOP) {
- if ((unsigned int)sample->loop_end > (unsigned int)sample->length)
- sample->flags &= ~IT_SAMPLE_LOOP;
- else if ((unsigned int)sample->loop_start >= (unsigned int)sample->loop_end)
- sample->flags &= ~IT_SAMPLE_LOOP;
- else
- /* ScreamTracker seems not to save what comes after the loop end
- * point, but rather to assume it is a duplicate of what comes at
- * the loop start point. I am not completely sure of this though.
- * It is easy to evade; simply truncate the sample.
- */
- sample->length = sample->loop_end;
- }
-
-
- //Do we need to set all these?
- sample->vibrato_speed = 0;
- sample->vibrato_depth = 0;
- sample->vibrato_rate = 0;
- sample->vibrato_waveform = IT_VIBRATO_SINE;
-
- return dumbfile_error(f);
-}
-
-
-
-static int it_s3m_read_sample_data(IT_SAMPLE *sample, int ffi, DUMBFILE *f)
-{
- long n;
-
- long datasize = sample->length;
- if (sample->flags & IT_SAMPLE_STEREO) datasize <<= 1;
-
- sample->data = malloc(datasize * (sample->flags & IT_SAMPLE_16BIT ? 2 : 1));
- if (!sample->data)
- return -1;
-
- if (sample->flags & IT_SAMPLE_STEREO) {
- if (sample->flags & IT_SAMPLE_16BIT) {
- 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 {
- 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 if (sample->flags & IT_SAMPLE_16BIT)
- for (n = 0; n < sample->length; n++)
- ((short *)sample->data)[n] = dumbfile_igetw(f);
- else
- for (n = 0; n < sample->length; n++)
- ((signed char *)sample->data)[n] = dumbfile_getc(f);
-
- if (dumbfile_error(f))
- return -1;
-
- if (ffi != 1) {
- /* Convert to signed. */
- if (sample->flags & IT_SAMPLE_16BIT)
- for (n = 0; n < datasize; n++)
- ((short *)sample->data)[n] ^= 0x8000;
- else
- for (n = 0; n < datasize; n++)
- ((signed char *)sample->data)[n] ^= 0x80;
- }
-
- return 0;
-}
-
-
-
-static int it_s3m_read_pattern(IT_PATTERN *pattern, DUMBFILE *f, unsigned char *buffer)
-{
- int buflen = 0;
- int bufpos = 0;
-
- IT_ENTRY *entry;
-
- unsigned char channel;
-
- /* Haha, this is hilarious!
- *
- * Well, after some experimentation, it seems that different S3M writers
- * define the format in different ways. The S3M docs say that the first
- * two bytes hold the "length of [the] packed pattern", and the packed
- * pattern data follow. Judging by the contents of ARMANI.S3M, packaged
- * with ScreamTracker itself, the measure of length _includes_ the two
- * bytes used to store the length; in other words, we should read
- * (length - 2) more bytes. However, aryx.s3m, packaged with ModPlug
- * Tracker, excludes these two bytes, so (length) more bytes must be
- * read.
- *
- * Call me crazy, but I just find it insanely funny that the format was
- * misunderstood in this way :D
- *
- * Now we can't just risk reading two extra bytes, because then we
- * overshoot, and DUMBFILEs don't support backward seeking (for a good
- * reason). Luckily, there is a way. We can read the data little by
- * little, and stop when we have 64 rows in memory. Provided we protect
- * against buffer overflow, this method should work with all sensibly
- * written S3M files. If you find one for which it does not work, please
- * let me know at entheh@users.sf.net so I can look at it.
- */
-
- /* Discard the length. */
- dumbfile_skip(f, 2);
-
- if (dumbfile_error(f))
- return -1;
-
- pattern->n_rows = 0;
- pattern->n_entries = 0;
-
- /* Read in the pattern data, little by little, and work out how many
- * entries we need room for. Sorry, but this is just so funny...
- */
- for (;;) {
- unsigned char b = buffer[buflen++] = dumbfile_getc(f);
-
-#if 1
- static const unsigned char used[8] = {0, 2, 1, 3, 2, 4, 3, 5};
- channel = b & 31;
- b >>= 5;
- pattern->n_entries++;
- if (b) {
- if (buflen + used[b] >= 65536) return -1;
- dumbfile_getnc(buffer + buflen, used[b], f);
- buflen += used[b];
- } else {
- /* End of row */
- if (++pattern->n_rows == 64) break;
- if (buflen >= 65536) return -1;
- }
-#else
- if (b == 0) {
- /* End of row */
- pattern->n_entries++;
- if (++pattern->n_rows == 64) break;
- if (buflen >= 65536) return -1;
- } else {
- static const unsigned char used[8] = {0, 2, 1, 3, 2, 4, 3, 5};
- channel = b & 31;
- b >>= 5;
- if (b) {
- pattern->n_entries++;
- if (buflen + used[b] >= 65536) return -1;
- dumbfile_getnc(buffer + buflen, used[b], f);
- buflen += used[b];
- }
- }
-#endif
-
- /* We have ensured that buflen < 65536 at this point, so it is safe
- * to iterate and read at least one more byte without checking.
- * However, now would be a good time to check for errors reading from
- * the file.
- */
-
- if (dumbfile_error(f))
- return -1;
- }
-
- pattern->entry = malloc(pattern->n_entries * sizeof(*pattern->entry));
-
- if (!pattern->entry)
- return -1;
-
- entry = pattern->entry;
-
- while (bufpos < buflen) {
- unsigned char b = buffer[bufpos++];
-
-#if 1
- if (!(b & ~31))
-#else
- if (b == 0)
-#endif
- {
- /* End of row */
- IT_SET_END_ROW(entry);
- entry++;
- continue;
- }
-
- channel = b & 31;
-
- if (b & 224) {
- entry->mask = 0;
- entry->channel = channel;
-
- if (b & 32) {
- unsigned char n = buffer[bufpos++];
- if (n != 255) {
- if (n == 254)
- entry->note = IT_NOTE_CUT;
- else
- entry->note = (n >> 4) * 12 + (n & 15);
- entry->mask |= IT_ENTRY_NOTE;
- }
-
- entry->instrument = buffer[bufpos++];
- if (entry->instrument)
- entry->mask |= IT_ENTRY_INSTRUMENT;
- }
-
- if (b & 64) {
- entry->volpan = buffer[bufpos++];
- if (entry->volpan != 255)
- entry->mask |= IT_ENTRY_VOLPAN;
- }
-
- if (b & 128) {
- entry->effect = buffer[bufpos++];
- entry->effectvalue = buffer[bufpos++];
- if (entry->effect != 255) {
- entry->mask |= IT_ENTRY_EFFECT;
- if (entry->effect == IT_BREAK_TO_ROW)
- entry->effectvalue -= (entry->effectvalue >> 4) * 6;
- }
- /** WARNING: ARGH! CONVERT TEH EFFECTS!@~ */
- }
-
- entry++;
- }
- }
-
- ASSERT(entry == pattern->entry + pattern->n_entries);
-
- return 0;
-}
-
-
-
-/** WARNING: this is duplicated in itread.c - also bad practice to use the same struct name unless they are unified in a header */
-/* Currently we assume the sample data are stored after the sample headers in
- * module files. This assumption may be unjustified; let me know if you have
- * trouble.
- */
-
-#define IT_COMPONENT_INSTRUMENT 1
-#define IT_COMPONENT_PATTERN 2
-#define IT_COMPONENT_SAMPLE 3
-
-typedef struct IT_COMPONENT
-{
- unsigned char type;
- unsigned char n;
- long offset;
- short sampfirst; /* component[sampfirst] = first sample data after this */
- short sampnext; /* sampnext is used to create linked lists of sample data */
-}
-IT_COMPONENT;
-
-
-
-static int it_component_compare(const void *e1, const void *e2)
-{
- return ((const IT_COMPONENT *)e1)->offset -
- ((const IT_COMPONENT *)e2)->offset;
-}
-
-
-
-static DUMB_IT_SIGDATA *it_s3m_load_sigdata(DUMBFILE *f)
-{
- DUMB_IT_SIGDATA *sigdata;
-
- int flags, cwtv, ffi;
- int default_pan_present;
-
- IT_COMPONENT *component;
- int n_components = 0;
-
- int n;
-
- unsigned char *buffer;
-
- sigdata = malloc(sizeof(*sigdata));
- if (!sigdata) return NULL;
-
- dumbfile_getnc(sigdata->name, 28, f);
- sigdata->name[28] = 0;
-
- if (dumbfile_getc(f) != 0x1A || dumbfile_getc(f) != 16) {
- free(sigdata);
- return NULL;
- }
-
- dumbfile_skip(f, 2);
-
- sigdata->song_message = NULL;
- sigdata->order = NULL;
- sigdata->instrument = NULL;
- sigdata->sample = NULL;
- sigdata->pattern = NULL;
- sigdata->midi = NULL;
- sigdata->checkpoint = NULL;
-
- sigdata->n_orders = dumbfile_igetw(f);
- sigdata->n_instruments = 0;
- sigdata->n_samples = dumbfile_igetw(f);
- sigdata->n_patterns = dumbfile_igetw(f);
-
- if (dumbfile_error(f) || sigdata->n_orders <= 0 || sigdata->n_samples > 256 || sigdata->n_patterns > 256) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- sigdata->order = malloc(sigdata->n_orders);
- if (!sigdata->order) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- if (sigdata->n_samples) {
- sigdata->sample = malloc(sigdata->n_samples * sizeof(*sigdata->sample));
- if (!sigdata->sample) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- for (n = 0; n < sigdata->n_samples; n++)
- sigdata->sample[n].data = NULL;
- }
-
- if (sigdata->n_patterns) {
- sigdata->pattern = malloc(sigdata->n_patterns * sizeof(*sigdata->pattern));
- if (!sigdata->pattern) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- for (n = 0; n < sigdata->n_patterns; n++)
- sigdata->pattern[n].entry = NULL;
- }
-
- flags = dumbfile_igetw(f);
-
- cwtv = dumbfile_igetw(f);
-
- if (cwtv == 0x1300) {
- /** WARNING: volume slides on every frame */
- }
-
- ffi = dumbfile_igetw(f);
-
- /** WARNING: which ones? */
- sigdata->flags = IT_STEREO | IT_OLD_EFFECTS | IT_COMPATIBLE_GXX;
-
- if (dumbfile_mgetl(f) != DUMB_ID('S','C','R','M')) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- sigdata->global_volume = dumbfile_getc(f) << 1;
- sigdata->speed = dumbfile_getc(f);
- if (sigdata->speed == 0) sigdata->speed = 6; // Should we? What about tempo?
- sigdata->tempo = dumbfile_getc(f);
- /*master_volume = */dumbfile_getc(f); // 7 bits; +128 for stereo
- //what do we do with master_volume? it's not the same as mixing volume...
- sigdata->mixing_volume = 48;
-
- /* Skip GUS Ultra Click Removal byte. */
- dumbfile_getc(f);
-
- default_pan_present = dumbfile_getc(f);
-
- dumbfile_skip(f, 8);
-
- /* Skip Special Custom Data Pointer. */
- /** WARNING: investigate this? */
- dumbfile_igetw(f);
-
- /* Channel settings for 32 channels, 255=unused, +128=disabled */
- {
- int i;
- for (i = 0; i < 32; i++) {
- int c = dumbfile_getc(f);
- if (!(c & (128 | 16))) { /* +128=disabled, +16=Adlib */
- sigdata->channel_volume[i] = 64;
- sigdata->channel_pan[i] = c & 8 ? 12 : 3;
- /** WARNING: ah, but it should be 7 for mono... */
- } else {
- /** WARNING: this could be improved if we support channel muting... */
- sigdata->channel_volume[i] = 0;
- sigdata->channel_pan[i] = 7;
- }
- }
- }
-
- /* Orders, byte each, length = sigdata->n_orders (should be even) */
- dumbfile_getnc(sigdata->order, sigdata->n_orders, f);
- sigdata->restart_position = 0;
-
- component = malloc(768*sizeof(*component));
- if (!component) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- for (n = 0; n < sigdata->n_samples; n++) {
- component[n_components].type = IT_COMPONENT_SAMPLE;
- component[n_components].n = n;
- component[n_components].offset = dumbfile_igetw(f) << 4;
- component[n_components].sampfirst = -1;
- n_components++;
- }
-
- for (n = 0; n < sigdata->n_patterns; n++) {
- long offset = dumbfile_igetw(f) << 4;
- if (offset) {
- component[n_components].type = IT_COMPONENT_PATTERN;
- component[n_components].n = n;
- component[n_components].offset = offset;
- component[n_components].sampfirst = -1;
- n_components++;
- } else {
- /** WARNING: Empty 64-row pattern ... ? (this does happen!) */
- sigdata->pattern[n].n_rows = 64;
- sigdata->pattern[n].n_entries = 0;
- }
- }
-
- qsort(component, n_components, sizeof(IT_COMPONENT), &it_component_compare);
-
- /* I found a really dumb S3M file that claimed to contain default pan
- * data but didn't contain any. Programs would load it by reading part of
- * the first instrument header, assuming the data to be default pan
- * positions, and then rereading the instrument module. We cannot do this
- * without obfuscating the file input model, so we insert an extra check
- * here that we won't overrun the start of the first component.
- */
- if (default_pan_present == 252 && component[0].offset >= dumbfile_pos(f) + 32) {
- /* Channel default pan positions */
- int i;
- for (i = 0; i < 32; i++) {
- int c = dumbfile_getc(f);
- if (c & 32)
- sigdata->channel_pan[i] = c & 15;
- }
- }
-
- {
- int i;
- for (i = 0; i < 32; i++) {
- sigdata->channel_pan[i] -= (sigdata->channel_pan[i] & 8) >> 3;
- sigdata->channel_pan[i] = ((int)sigdata->channel_pan[i] << 5) / 7;
- }
- }
-
- sigdata->pan_separation = 128;
-
- if (dumbfile_error(f)) {
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- buffer = malloc(65536);
- if (!buffer) {
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- for (n = 0; n < n_components; n++) {
- long offset;
- int m;
-
- if (it_seek(f, component[n].offset)) {
- free(buffer);
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- switch (component[n].type) {
-
- case IT_COMPONENT_PATTERN:
- if (it_s3m_read_pattern(&sigdata->pattern[component[n].n], f, buffer)) {
- free(buffer);
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- break;
-
- case IT_COMPONENT_SAMPLE:
- if (it_s3m_read_sample_header(&sigdata->sample[component[n].n], &offset, f)) {
- free(buffer);
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- if (sigdata->sample[component[n].n].flags & IT_SAMPLE_EXISTS) {
- short *sample;
-
- for (m = n + 1; m < n_components; m++)
- if (component[m].offset > offset)
- break;
- m--;
-
- sample = &component[m].sampfirst;
-
- while (*sample >= 0 && component[*sample].offset <= offset)
- sample = &component[*sample].sampnext;
-
- component[n].sampnext = *sample;
- *sample = n;
-
- component[n].offset = offset;
- }
- }
-
- m = component[n].sampfirst;
-
- while (m >= 0) {
- if (it_seek(f, component[m].offset)) {
- free(buffer);
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- if (it_s3m_read_sample_data(&sigdata->sample[component[m].n], ffi, f)) {
- free(buffer);
- free(component);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- m = component[m].sampnext;
- }
- }
-
- free(buffer);
- free(component);
-
- _dumb_it_fix_invalid_orders(sigdata);
-
- return sigdata;
-}
-
-
-
-DUH *dumb_read_s3m_quick(DUMBFILE *f)
-{
- sigdata_t *sigdata;
-
- DUH_SIGTYPE_DESC *descptr = &_dumb_sigtype_it;
-
- sigdata = it_s3m_load_sigdata(f);
-
- if (!sigdata)
- return NULL;
-
- {
- const char *tag[1][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);
- }
-}
diff --git a/dumb/dumb-0.9.3/src/it/reads3m2.c b/dumb/dumb-0.9.3/src/it/reads3m2.c
deleted file mode 100644
index c9447c26..00000000
--- a/dumb/dumb-0.9.3/src/it/reads3m2.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * reads3m2.c - Function to read a ScreamTracker 3 / / \ \
- * module from an open file and do an | < / \_
- * initial run-through. | \/ /\ /
- * \_ / > /
- * Split off from reads3m.c by entheh. | \ / /
- * | ' /
- * \__/
- */
-
-#include "dumb.h"
-
-
-
-DUH *dumb_read_s3m(DUMBFILE *f)
-{
- DUH *duh = dumb_read_s3m_quick(f);
- dumb_it_do_initial_runthrough(duh);
- return duh;
-}
diff --git a/dumb/dumb-0.9.3/src/it/readxm.c b/dumb/dumb-0.9.3/src/it/readxm.c
deleted file mode 100644
index 53f80d50..00000000
--- a/dumb/dumb-0.9.3/src/it/readxm.c
+++ /dev/null
@@ -1,1007 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * readxm.c - Code to read a Fast Tracker II / / \ \
- * module from an open file. | < / \_
- * | \/ /\ /
- * By Julien Cugniere. Some bits of code taken \_ / > /
- * from reads3m.c. | \ / /
- * | ' /
- * \__/
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <math.h>
-
-#include "dumb.h"
-#include "internal/it.h"
-
-
-
-/** TODO:
-
- * XM_TREMOLO doesn't sound quite right...
- * XM_E_SET_FINETUNE done but not tested yet.
- * XM_SET_ENVELOPE_POSITION todo.
-
- * VIBRATO conversion needs to be checked (sample/effect/volume). Plus check
- that effect memory is correct when using XM_VOLSLIDE_VIBRATO.
- - sample vibrato (instrument vibrato) is now handled correctly. - entheh
-
- * XM_E_SET_VIBRATO/TREMOLO_CONTROL: effectvalue&4 -> don't retrig wave when
- a new instrument is played. In retrigger_note()?. Is it worth implementing?
-
- * Lossy fadeout approximation. 0..31 converted to 0 --> won't fade at all.
-
- * Replace DUMB's sawtooth by ramp_down/ramp_up. Update XM loader.
-
- * A lot of things need to be reset when the end of the song is reached.
-
- * It seems that IT and XM don't behave the same way when dealing with
- mixed loops. When IT encounters multiple SBx (x>0) commands on the same
- row, it decrements the loop count for all, but only execute the loop of
- the last one (highest channel). FT2 only decrements the loop count of the
- last one. Not that I know of any modules using so convoluted combinations!
-
- * Maybe we could remove patterns that don't appear in the order table ? Or
- provide a function to "optimize" a DUMB_IT_SIGDATA ?
-
-*/
-
-
-
-#define XM_LINEAR_FREQUENCY 1 /* otherwise, use amiga slides */
-
-#define XM_ENTRY_PACKED 128
-#define XM_ENTRY_NOTE 1
-#define XM_ENTRY_INSTRUMENT 2
-#define XM_ENTRY_VOLUME 4
-#define XM_ENTRY_EFFECT 8
-#define XM_ENTRY_EFFECTVALUE 16
-
-#define XM_NOTE_OFF 97
-
-#define XM_ENVELOPE_ON 1
-#define XM_ENVELOPE_SUSTAIN 2
-#define XM_ENVELOPE_LOOP 4
-
-#define XM_SAMPLE_NO_LOOP 0
-#define XM_SAMPLE_FORWARD_LOOP 1
-#define XM_SAMPLE_PINGPONG_LOOP 2
-#define XM_SAMPLE_16BIT 16
-#define XM_SAMPLE_STEREO 32
-
-#define XM_VIBRATO_SINE 0
-#define XM_VIBRATO_SQUARE 1
-#define XM_VIBRATO_RAMP_DOWN 2
-#define XM_VIBRATO_RAMP_UP 3
-
-
-
-/* Probably useless :) */
-static const char xm_convert_vibrato[] = {
- IT_VIBRATO_SINE,
- IT_VIBRATO_SQUARE,
- IT_VIBRATO_SAWTOOTH,
- IT_VIBRATO_SAWTOOTH
-};
-
-
-
-#define XM_MAX_SAMPLES_PER_INSTRUMENT 16
-
-
-
-/* Extra data that doesn't fit inside IT_INSTRUMENT */
-typedef struct XM_INSTRUMENT_EXTRA
-{
- int n_samples;
- int vibrato_type;
- int vibrato_sweep; /* 0-0xFF */
- int vibrato_depth; /* 0-0x0F */
- int vibrato_speed; /* 0-0x3F */
-}
-XM_INSTRUMENT_EXTRA;
-
-
-
-/* Frees the original block if it can't resize it or if size is 0, and acts
- * as malloc if ptr is NULL.
- */
-static void *safe_realloc(void *ptr, size_t size)
-{
- if (ptr == NULL)
- return malloc(size);
-
- if (size == 0) {
- free(ptr);
- return NULL;
- } else {
- void *new_block = realloc(ptr, size);
- if (!new_block)
- free(ptr);
- return new_block;
- }
-}
-
-
-
-/* The interpretation of the XM volume column is left to the player. Here, we
- * just filter bad values.
- */
-// This function is so tiny now, should we inline it?
-static void it_xm_convert_volume(int volume, IT_ENTRY *entry)
-{
- entry->mask |= IT_ENTRY_VOLPAN;
- entry->volpan = volume;
-
- switch (volume >> 4) {
- case 0xA: /* set vibrato speed */
- case 0xB: /* vibrato */
- case 0xF: /* tone porta */
- case 0x6: /* vol slide up */
- case 0x7: /* vol slide down */
- case 0x8: /* fine vol slide up */
- case 0x9: /* fine vol slide down */
- case 0xC: /* set panning */
- case 0xD: /* pan slide left */
- case 0xE: /* pan slide right */
- case 0x1: /* set volume */
- case 0x2: /* set volume */
- case 0x3: /* set volume */
- case 0x4: /* set volume */
- break;
-
- case 0x5:
- if (volume == 0x50)
- break; /* set volume */
- /* else fall through */
-
- default:
- entry->mask &= ~IT_ENTRY_VOLPAN;
- break;
- }
-}
-
-
-
-static int it_xm_read_pattern(IT_PATTERN *pattern, DUMBFILE *f, int n_channels, unsigned char *buffer)
-{
- int size;
- int pos;
- int channel;
- int row;
- int effect, effectvalue;
- IT_ENTRY *entry;
-
- /* pattern header size */
- if (dumbfile_igetl(f) != 0x09) {
- TRACE("XM error: unexpected pattern header size\n");
- return -1;
- }
-
- /* pattern data packing type */
- if (dumbfile_getc(f) != 0) {
- TRACE("XM error: unexpected pattern packing type\n");
- return -1;
- }
-
- pattern->n_rows = dumbfile_igetw(f); /* 1..256 */
- size = dumbfile_igetw(f);
- pattern->n_entries = 0;
-
- if (dumbfile_error(f))
- return -1;
-
- if (size == 0)
- return 0;
-
- if (size > 1280 * n_channels) {
- TRACE("XM error: pattern data size > %d bytes\n", 1280 * n_channels);
- return -1;
- }
-
- if (dumbfile_getnc(buffer, size, f) < size)
- return -1;
-
- /* compute number of entries */
- pattern->n_entries = 0;
- pos = channel = row = 0;
- while (pos < size) {
- if (!(buffer[pos] & XM_ENTRY_PACKED) || (buffer[pos] & 31))
- pattern->n_entries++;
-
- channel++;
- if (channel >= n_channels) {
- channel = 0;
- row++;
- pattern->n_entries++;
- }
-
- if (buffer[pos] & XM_ENTRY_PACKED) {
- static const char offset[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4,
- 1, 2, 2, 3, 2, 3, 3, 4, 2, 3, 3, 4, 3, 4, 4, 5 };
- pos += 1 + offset[buffer[pos] & 31];
- } else {
- pos += 5;
- }
- }
-
- if (row != pattern->n_rows) {
- TRACE("XM error: wrong number of rows in pattern data\n");
- return -1;
- }
-
- pattern->entry = malloc(pattern->n_entries * sizeof(*pattern->entry));
- if (!pattern->entry)
- return -1;
-
- /* read the entries */
- entry = pattern->entry;
- pos = channel = row = 0;
- while (pos < size) {
- unsigned char mask;
-
- if (buffer[pos] & XM_ENTRY_PACKED)
- mask = buffer[pos++] & 31;
- else
- mask = 31;
-
- if (mask) {
- ASSERT(entry < pattern->entry + pattern->n_entries);
-
- entry->channel = channel;
- entry->mask = 0;
-
- if (mask & XM_ENTRY_NOTE) {
- int note = buffer[pos++]; /* 1-96 <=> C0-B7 */
- entry->note = (note == XM_NOTE_OFF) ? (IT_NOTE_OFF) : (note-1);
- entry->mask |= IT_ENTRY_NOTE;
- }
-
- if (mask & XM_ENTRY_INSTRUMENT) {
- entry->instrument = buffer[pos++]; /* 1-128 */
- entry->mask |= IT_ENTRY_INSTRUMENT;
- }
-
- if (mask & XM_ENTRY_VOLUME)
- it_xm_convert_volume(buffer[pos++], entry);
-
- effect = effectvalue = 0;
- if (mask & XM_ENTRY_EFFECT) effect = buffer[pos++];
- if (mask & XM_ENTRY_EFFECTVALUE) effectvalue = buffer[pos++];
- _dumb_it_xm_convert_effect(effect, effectvalue, entry);
-
- entry++;
- }
-
- channel++;
- if (channel >= n_channels) {
- channel = 0;
- row++;
- IT_SET_END_ROW(entry);
- entry++;
- }
- }
-
- return 0;
-}
-
-
-
-static int it_xm_make_envelope(IT_ENVELOPE *envelope, const unsigned short *data, int y_offset)
-{
- int i, pos;
-
- if (envelope->n_nodes > 12) {
- TRACE("XM error: wrong number of envelope nodes (%d)\n", envelope->n_nodes);
- envelope->n_nodes = 0;
- return -1;
- }
-
- pos = 0;
- for (i = 0; i < envelope->n_nodes; i++) {
- envelope->node_t[i] = data[pos++];
- if (data[pos] > 64) {
- TRACE("XM error: out-of-range envelope node (node_y[%d]=%d)\n", i, data[pos]);
- envelope->n_nodes = 0;
- return -1;
- }
- envelope->node_y[i] = (signed char)(data[pos++] + y_offset);
- }
-
- return 0;
-}
-
-
-
-static int it_xm_read_instrument(IT_INSTRUMENT *instrument, XM_INSTRUMENT_EXTRA *extra, DUMBFILE *f)
-{
- unsigned long size, bytes_read;
- unsigned short vol_points[24];
- unsigned short pan_points[24];
- int i, type;
-
- /* Header size. Tends to be more than the actual size of the structure.
- * So unread bytes must be skipped before reading the first sample
- * header.
- */
- size = dumbfile_igetl(f);
-
- dumbfile_getnc(instrument->name, 22, f);
- instrument->name[22] = 0;
- instrument->filename[0] = 0;
- dumbfile_skip(f, 1); /* Instrument type. Should be 0, but seems random. */
- extra->n_samples = dumbfile_igetw(f);
-
- if (dumbfile_error(f) || (unsigned int)extra->n_samples > XM_MAX_SAMPLES_PER_INSTRUMENT)
- return -1;
-
- bytes_read = 4 + 22 + 1 + 2;
-
- if (extra->n_samples) {
- /* sample header size */
- if (dumbfile_igetl(f) != 0x28) {
- TRACE("XM error: unexpected sample header size\n");
- return -1;
- }
-
- /* sample map */
- for (i = 0; i < 96; i++) {
- instrument->map_sample[i] = dumbfile_getc(f) + 1;
- instrument->map_note[i] = i;
- }
-
- if (dumbfile_error(f))
- return 1;
-
- /* volume/panning envelopes */
- for (i = 0; i < 24; i++)
- vol_points[i] = dumbfile_igetw(f);
- for (i = 0; i < 24; i++)
- pan_points[i] = dumbfile_igetw(f);
-
- instrument->volume_envelope.n_nodes = dumbfile_getc(f);
- instrument->pan_envelope.n_nodes = dumbfile_getc(f);
-
- if (dumbfile_error(f))
- return -1;
-
- instrument->volume_envelope.sus_loop_start = dumbfile_getc(f);
- instrument->volume_envelope.loop_start = dumbfile_getc(f);
- instrument->volume_envelope.loop_end = dumbfile_getc(f);
-
- instrument->pan_envelope.sus_loop_start = dumbfile_getc(f);
- instrument->pan_envelope.loop_start = dumbfile_getc(f);
- instrument->pan_envelope.loop_end = dumbfile_getc(f);
-
- /* The envelope handler for XM files won't use sus_loop_end. */
-
- type = dumbfile_getc(f);
- instrument->volume_envelope.flags = 0;
- if ((type & XM_ENVELOPE_ON) && instrument->volume_envelope.n_nodes)
- instrument->volume_envelope.flags |= IT_ENVELOPE_ON;
- if (type & XM_ENVELOPE_LOOP) instrument->volume_envelope.flags |= IT_ENVELOPE_LOOP_ON;
-#if 1
- if (type & XM_ENVELOPE_SUSTAIN) instrument->volume_envelope.flags |= IT_ENVELOPE_SUSTAIN_LOOP;
-#else // This is now handled in itrender.c
- /* let's avoid fading out when reaching the last envelope node */
- if (!(type & XM_ENVELOPE_LOOP)) {
- instrument->volume_envelope.loop_start = instrument->volume_envelope.n_nodes-1;
- instrument->volume_envelope.loop_end = instrument->volume_envelope.n_nodes-1;
- }
- instrument->volume_envelope.flags |= IT_ENVELOPE_LOOP_ON;
-#endif
-
- type = dumbfile_getc(f);
- instrument->pan_envelope.flags = 0;
- if ((type & XM_ENVELOPE_ON) && instrument->pan_envelope.n_nodes)
- instrument->pan_envelope.flags |= IT_ENVELOPE_ON;
- if (type & XM_ENVELOPE_LOOP) instrument->pan_envelope.flags |= IT_ENVELOPE_LOOP_ON; // should this be here?
- if (type & XM_ENVELOPE_SUSTAIN) instrument->pan_envelope.flags |= IT_ENVELOPE_SUSTAIN_LOOP;
-
- if (it_xm_make_envelope(&instrument->volume_envelope, vol_points, 0) != 0) {
- TRACE("XM error: volume envelope\n");
- if (instrument->volume_envelope.flags & IT_ENVELOPE_ON) return -1;
- }
-
- if (it_xm_make_envelope(&instrument->pan_envelope, pan_points, -32) != 0) {
- TRACE("XM error: pan envelope\n");
- if (instrument->pan_envelope.flags & IT_ENVELOPE_ON) return -1;
- }
-
- instrument->pitch_envelope.flags = 0;
-
- extra->vibrato_type = dumbfile_getc(f);
- extra->vibrato_sweep = dumbfile_getc(f);
- extra->vibrato_depth = dumbfile_getc(f);
- extra->vibrato_speed = dumbfile_getc(f);
-
- if (dumbfile_error(f) || extra->vibrato_type >= 4)
- return -1;
-
- /** WARNING: lossy approximation */
- instrument->fadeout = (dumbfile_igetw(f)*128 + 64)/0xFFF;
-
- dumbfile_skip(f, 2); /* reserved */
-
- bytes_read += 4 + 96 + 48 + 48 + 14*1 + 2 + 2;
- } else
- for (i = 0; i < 96; i++)
- instrument->map_sample[i] = 0;
-
- if (dumbfile_skip(f, size - bytes_read))
- return -1;
-
- instrument->new_note_action = NNA_NOTE_CUT;
- instrument->dup_check_type = DCT_OFF;
- instrument->dup_check_action = DCA_NOTE_CUT;
- instrument->pp_separation = 0;
- instrument->pp_centre = 60; /* C-5 */
- instrument->global_volume = 128;
- instrument->default_pan = 32;
- instrument->random_volume = 0;
- instrument->random_pan = 0;
- instrument->filter_cutoff = 0;
- instrument->filter_resonance = 0;
-
- return 0;
-}
-
-
-
-/* I (entheh) have two XM files saved by a very naughty program. After a
- * 16-bit sample, it saved a rogue byte. The length of the sample was indeed
- * an odd number, incremented to include the rogue byte.
- *
- * In this function we are converting sample lengths and loop points so they
- * are measured in samples. This means we forget about the extra bytes, and
- * they don't get skipped. So we fail trying to read the next instrument.
- *
- * To get around this, this function returns the number of rogue bytes that
- * won't be accounted for by reading sample->length samples. It returns a
- * negative number on failure.
- */
-static int it_xm_read_sample_header(IT_SAMPLE *sample, DUMBFILE *f)
-{
- int type;
- int relative_note_number; /* relative to C4 */
- int finetune;
- int roguebytes;
- int roguebytesmask;
-
- sample->length = dumbfile_igetl(f);
- sample->loop_start = dumbfile_igetl(f);
- sample->loop_end = sample->loop_start + dumbfile_igetl(f);
- sample->global_volume = 64;
- sample->default_volume = dumbfile_getc(f);
- finetune = (signed char)dumbfile_getc(f); /* -128..127 <=> -1 semitone .. +127/128 of a semitone */
- type = dumbfile_getc(f);
- sample->default_pan = dumbfile_getc(f); /* 0-255 */
- relative_note_number = (signed char)dumbfile_getc(f);
-
- dumbfile_skip(f, 1); /* reserved */
-
- dumbfile_getnc(sample->name, 22, f);
- sample->name[22] = 0;
-
- sample->filename[0] = 0;
-
- if (dumbfile_error(f))
- return -1;
-
- sample->C5_speed = (long)(16726.0*pow(DUMB_SEMITONE_BASE, relative_note_number)*pow(DUMB_PITCH_BASE, finetune*2));
-
- sample->flags = IT_SAMPLE_EXISTS;
-
- roguebytes = (int)sample->length;
- roguebytesmask = 3;
-
- if (type & XM_SAMPLE_16BIT) {
- sample->flags |= IT_SAMPLE_16BIT;
- sample->length >>= 1;
- sample->loop_start >>= 1;
- sample->loop_end >>= 1;
- } else
- roguebytesmask >>= 1;
-
- if (type & XM_SAMPLE_STEREO) {
- sample->flags |= IT_SAMPLE_STEREO;
- sample->length >>= 1;
- sample->loop_start >>= 1;
- sample->loop_end >>= 1;
- } else
- roguebytesmask >>= 1;
-
- roguebytes &= roguebytesmask;
-
- if ((unsigned int)sample->loop_start < (unsigned int)sample->loop_end) {
- if (type & XM_SAMPLE_FORWARD_LOOP) sample->flags |= IT_SAMPLE_LOOP;
- if (type & XM_SAMPLE_PINGPONG_LOOP) sample->flags |= IT_SAMPLE_LOOP | IT_SAMPLE_PINGPONG_LOOP;
- }
-
- if (sample->length <= 0)
- sample->flags &= ~IT_SAMPLE_EXISTS;
- else if ((unsigned int)sample->loop_end > (unsigned int)sample->length)
- sample->flags &= ~IT_SAMPLE_LOOP;
- else if ((unsigned int)sample->loop_start >= (unsigned int)sample->loop_end)
- sample->flags &= ~IT_SAMPLE_LOOP;
-
- return roguebytes;
-}
-
-
-
-static int it_xm_read_sample_data(IT_SAMPLE *sample, unsigned char roguebytes, DUMBFILE *f)
-{
- int old;
- long i;
- long truncated_size;
- int n_channels;
- long datasize;
-
- if (!(sample->flags & IT_SAMPLE_EXISTS))
- return dumbfile_skip(f, roguebytes);
-
- /* let's get rid of the sample data coming after the end of the loop */
- if ((sample->flags & IT_SAMPLE_LOOP) && sample->loop_end < sample->length) {
- truncated_size = sample->length - sample->loop_end;
- sample->length = sample->loop_end;
- } else {
- truncated_size = 0;
- }
-
- n_channels = sample->flags & IT_SAMPLE_STEREO ? 2 : 1;
- datasize = sample->length * n_channels;
-
- sample->data = malloc(datasize * (sample->flags & IT_SAMPLE_16BIT ? 2 : 1));
- if (!sample->data)
- return -1;
-
- /* sample data is stored as signed delta values */
- old = 0;
- if (sample->flags & IT_SAMPLE_16BIT)
- for (i = 0; i < sample->length; i++)
- ((short *)sample->data)[i*n_channels] = old += dumbfile_igetw(f);
- else
- for (i = 0; i < sample->length; i++)
- ((signed char *)sample->data)[i*n_channels] = old += dumbfile_getc(f);
-
- /* skip truncated data */
- dumbfile_skip(f, (sample->flags & IT_SAMPLE_16BIT) ? (2*truncated_size) : (truncated_size));
-
- if (sample->flags & IT_SAMPLE_STEREO) {
- old = 0;
- if (sample->flags & IT_SAMPLE_16BIT)
- for (i = 1; i < datasize; i += 2)
- ((short *)sample->data)[i] = old += dumbfile_igetw(f);
- else
- for (i = 1; i < datasize; i += 2)
- ((signed char *)sample->data)[i] = old += dumbfile_getc(f);
-
- /* skip truncated data */
- dumbfile_skip(f, (sample->flags & IT_SAMPLE_16BIT) ? (2*truncated_size) : (truncated_size));
- }
-
- dumbfile_skip(f, roguebytes);
-
- if (dumbfile_error(f))
- return -1;
-
- return 0;
-}
-
-
-
-/* "Real programmers don't document. If it was hard to write,
- * it should be hard to understand."
- *
- * (Never trust the documentation provided with a tracker.
- * Real files are the only truth...)
- */
-static DUMB_IT_SIGDATA *it_xm_load_sigdata(DUMBFILE *f)
-{
- DUMB_IT_SIGDATA *sigdata;
- char id_text[18];
-
- int flags;
- int n_channels;
- int total_samples;
- int i, j;
-
- /* check ID text */
- if (dumbfile_getnc(id_text, 17, f) < 17)
- return NULL;
- id_text[17] = 0;
- if (strcmp(id_text, "Extended Module: ") != 0) {
- TRACE("XM error: Not an Extended Module\n");
- return NULL;
- }
-
- sigdata = malloc(sizeof(*sigdata));
- if (!sigdata)
- return NULL;
-
- /* song name */
- if (dumbfile_getnc(sigdata->name, 20, f) < 20) {
- free(sigdata);
- return NULL;
- }
- sigdata->name[20] = 0;
-
- if (dumbfile_getc(f) != 0x1A) {
- TRACE("XM error: 0x1A not found\n");
- free(sigdata);
- return NULL;
- }
-
- /* tracker name */
- if (dumbfile_skip(f, 20)) {
- free(sigdata);
- return NULL;
- }
-
- /* version number */
- if (dumbfile_igetw(f) != 0x0104) {
- TRACE("XM error: wrong format version\n");
- free(sigdata);
- return NULL;
- }
-
- /*
- ------------------
- --- Header ---
- ------------------
- */
-
- /* header size */
- if (dumbfile_igetl(f) != 0x0114) {
- TRACE("XM error: unexpected header size\n");
- free(sigdata);
- return NULL;
- }
-
- sigdata->song_message = NULL;
- sigdata->order = NULL;
- sigdata->instrument = NULL;
- sigdata->sample = NULL;
- sigdata->pattern = NULL;
- sigdata->midi = NULL;
- sigdata->checkpoint = NULL;
-
- sigdata->n_samples = 0;
- sigdata->n_orders = dumbfile_igetw(f);
- sigdata->restart_position = dumbfile_igetw(f);
- n_channels = dumbfile_igetw(f); /* max 32 but we'll be lenient */
- sigdata->n_patterns = dumbfile_igetw(f);
- sigdata->n_instruments = dumbfile_igetw(f); /* max 128 */
- flags = dumbfile_igetw(f);
- sigdata->speed = dumbfile_igetw(f);
- if (sigdata->speed == 0) sigdata->speed = 6; // Should we? What about tempo?
- sigdata->tempo = dumbfile_igetw(f);
-
- /* sanity checks */
- if (dumbfile_error(f) || sigdata->n_orders <= 0 || sigdata->n_orders > 256 || sigdata->n_patterns > 256 || sigdata->n_instruments > 128 || n_channels > DUMB_IT_N_CHANNELS) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- //if (sigdata->restart_position >= sigdata->n_orders)
- //sigdata->restart_position = 0;
-
- /* order table */
- sigdata->order = malloc(sigdata->n_orders*sizeof(*sigdata->order));
- if (!sigdata->order) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- dumbfile_getnc(sigdata->order, sigdata->n_orders, f);
- dumbfile_skip(f, 256 - sigdata->n_orders);
-
- if (dumbfile_error(f)) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- /*
- --------------------
- --- Patterns ---
- --------------------
- */
-
- sigdata->pattern = malloc(sigdata->n_patterns * sizeof(*sigdata->pattern));
- if (!sigdata->pattern) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- for (i = 0; i < sigdata->n_patterns; i++)
- sigdata->pattern[i].entry = NULL;
-
- {
- unsigned char *buffer = malloc(1280 * n_channels); /* 256 rows * 5 bytes */
- if (!buffer) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- for (i = 0; i < sigdata->n_patterns; i++) {
- if (it_xm_read_pattern(&sigdata->pattern[i], f, n_channels, buffer) != 0) {
- free(buffer);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- }
- free(buffer);
- }
-
- /*
- -----------------------------------
- --- Instruments and Samples ---
- -----------------------------------
- */
-
- sigdata->instrument = malloc(sigdata->n_instruments * sizeof(*sigdata->instrument));
- if (!sigdata->instrument) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- /* With XM, samples are not global, they're part of an instrument. In a
- * file, each instrument is stored with its samples. Because of this, I
- * don't know how to find how many samples are present in the file. Thus
- * I have to do n_instruments reallocation on sigdata->sample.
- * Looking at FT2, it doesn't seem possible to have more than 16 samples
- * per instrument (even though n_samples is stored as 2 bytes). So maybe
- * we could allocate a 128*16 array of samples, and shrink it back to the
- * correct size when we know it?
- * Alternatively, I could allocate samples by blocks of N (still O(n)),
- * or double the number of allocated samples when I need more (O(log n)).
- */
- total_samples = 0;
- sigdata->sample = NULL;
-
- for (i = 0; i < sigdata->n_instruments; i++) {
- XM_INSTRUMENT_EXTRA extra;
-
- if (it_xm_read_instrument(&sigdata->instrument[i], &extra, f) < 0) {
- TRACE("XM error: instrument %d\n", i+1);
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
-
- if (extra.n_samples) {
- unsigned char roguebytes[XM_MAX_SAMPLES_PER_INSTRUMENT];
-
- /* adjust instrument sample map (make indices absolute) */
- for (j = 0; j < 96; j++)
- sigdata->instrument[i].map_sample[j] += total_samples;
-
- sigdata->sample = safe_realloc(sigdata->sample, sizeof(*sigdata->sample)*(total_samples+extra.n_samples));
- if (!sigdata->sample) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- for (j = total_samples; j < total_samples+extra.n_samples; j++)
- sigdata->sample[j].data = NULL;
-
- /* read instrument's samples */
- for (j = 0; j < extra.n_samples; j++) {
- IT_SAMPLE *sample = &sigdata->sample[total_samples+j];
- int b = it_xm_read_sample_header(sample, f);
- if (b < 0) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- roguebytes[j] = b;
- // Any reason why these can't be set inside it_xm_read_sample_header()?
- sample->vibrato_speed = extra.vibrato_speed;
- sample->vibrato_depth = extra.vibrato_depth;
- sample->vibrato_rate = extra.vibrato_sweep;
- /* Rate and sweep don't match, but the difference is
- * accounted for in itrender.c.
- */
- sample->vibrato_waveform = xm_convert_vibrato[extra.vibrato_type];
- }
- for (j = 0; j < extra.n_samples; j++) {
- if (it_xm_read_sample_data(&sigdata->sample[total_samples+j], roguebytes[j], f) != 0) {
- _dumb_it_unload_sigdata(sigdata);
- return NULL;
- }
- }
- total_samples += extra.n_samples;
- }
- }
-
- sigdata->n_samples = total_samples;
-
- sigdata->flags = IT_WAS_AN_XM | IT_OLD_EFFECTS | IT_COMPATIBLE_GXX | IT_STEREO | IT_USE_INSTRUMENTS;
- // Are we OK with IT_COMPATIBLE_GXX off?
- //
- // When specifying note + instr + tone portamento, and an old note is still playing (even after note off):
- // - If Compatible Gxx is on, the new note will be triggered only if the instrument _changes_.
- // - If Compatible Gxx is off, the new note will always be triggered, provided the instrument is specified.
- // - FT2 seems to do the latter (unconfirmed).
-
- // Err, wait. XM playback has its own code. The change made to the IT
- // playbackc code didn't affect XM playback. Forget this then. There's
- // still a bug in XM playback though, and it'll need some investigation...
- // tomorrow...
-
- // UPDATE: IT_COMPATIBLE_GXX is required to be on, so that tone porta has
- // separate memory from portamento.
-
- if (flags & XM_LINEAR_FREQUENCY)
- sigdata->flags |= IT_LINEAR_SLIDES;
-
- sigdata->global_volume = 128;
- sigdata->mixing_volume = 48;
- sigdata->pan_separation = 128;
-
- memset(sigdata->channel_volume, 64, DUMB_IT_N_CHANNELS);
- memset(sigdata->channel_pan, 32, DUMB_IT_N_CHANNELS);
-
- _dumb_it_fix_invalid_orders(sigdata);
-
- return sigdata;
-}
-
-
-
-#if 0 // no fucking way, dude!
-
-/* The length returned is the time required to play from the beginning of the
- * file to the last row of the last order (which is when the player will
- * loop). Depending on the song, the sound might stop sooner.
- * Due to fixed point roundoffs, I think this is only reliable to the second.
- * Full precision could be achieved by using a double during the computation,
- * or maybe a LONG_LONG.
- */
-long it_compute_length(const DUMB_IT_SIGDATA *sigdata)
-{
- IT_PATTERN *pattern;
- int tempo, speed;
- int loop_start[IT_N_CHANNELS];
- char loop_count[IT_N_CHANNELS];
- int order, entry;
- int row_first_entry = 0;
- int jump, jump_dest;
- int delay, fine_delay;
- int i;
- long t;
-
- if (!sigdata)
- return 0;
-
- tempo = sigdata->tempo;
- speed = sigdata->speed;
- order = entry = 0;
- jump = jump_dest = 0;
- t = 0;
-
- /* for each PATTERN */
- for (order = 0; order < sigdata->n_orders; order++) {
-
- if (sigdata->order[order] == IT_ORDER_END) break;
- if (sigdata->order[order] == IT_ORDER_SKIP) continue;
-
- for (i = 0; i < IT_N_CHANNELS; i++)
- loop_count[i] = -1;
-
- pattern = &sigdata->pattern[ sigdata->order[order] ];
- entry = 0;
- if (jump == IT_BREAK_TO_ROW) {
- int row = 0;
- while (row < jump_dest)
- if (pattern->entry[entry++].channel >= IT_N_CHANNELS)
- row++;
- }
-
- /* for each ROW */
- while (entry < pattern->n_entries) {
- row_first_entry = entry;
- delay = fine_delay = 0;
- jump = 0;
-
- /* for each note NOTE */
- while (entry < pattern->n_entries && pattern->entry[entry].channel < IT_N_CHANNELS) {
- int value = pattern->entry[entry].effectvalue;
- int channel = pattern->entry[entry].channel;
-
- switch (pattern->entry[entry].effect) {
-
- case IT_SET_SPEED: speed = value; break;
-
- case IT_JUMP_TO_ORDER:
- if (value <= order) /* infinite loop */
- return 0;
- jump = IT_JUMP_TO_ORDER;
- jump_dest = value;
- break;
-
- case IT_BREAK_TO_ROW:
- jump = IT_BREAK_TO_ROW;
- jump_dest = value;
- break;
-
- case IT_S:
- switch (HIGH(value)) {
- case IT_S_PATTERN_DELAY: delay = LOW(value); break;
- case IT_S_FINE_PATTERN_DELAY: fine_delay = LOW(value); break;
- case IT_S_PATTERN_LOOP:
- if (LOW(value) == 0) {
- loop_start[channel] = row_first_entry;
- } else {
- if (loop_count[channel] == -1)
- loop_count[channel] = LOW(value);
-
- if (loop_count[channel]) {
- jump = IT_S_PATTERN_LOOP;
- jump_dest = loop_start[channel];
- }
- loop_count[channel]--;
- }
- break;
- }
- break;
-
- case IT_SET_SONG_TEMPO:
- switch (HIGH(value)) { /* slides happen every non-row frames */
- case 0: tempo = tempo - LOW(value)*(speed-1); break;
- case 1: tempo = tempo + LOW(value)*(speed-1); break;
- default: tempo = value;
- }
- tempo = MID(32, tempo, 255);
- break;
- }
-
- entry++;
- }
-
- /* end of ROW */
- entry++;
- t += TICK_TIME_DIVIDEND * (speed*(1+delay) + fine_delay) / tempo;
-
- if (jump == IT_JUMP_TO_ORDER) {
- order = jump_dest - 1;
- break;
- } else if (jump == IT_BREAK_TO_ROW)
- break;
- else if (jump == IT_S_PATTERN_LOOP)
- entry = jump_dest - 1;
- }
-
- /* end of PATTERN */
- }
-
- return t;
-}
-
-#endif /* 0 */
-
-
-
-DUH *dumb_read_xm_quick(DUMBFILE *f)
-{
- sigdata_t *sigdata;
-
- DUH_SIGTYPE_DESC *descptr = &_dumb_sigtype_it;
-
- sigdata = it_xm_load_sigdata(f);
-
- if (!sigdata)
- return NULL;
-
- {
- const char *tag[1][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);
- }
-}
diff --git a/dumb/dumb-0.9.3/src/it/readxm2.c b/dumb/dumb-0.9.3/src/it/readxm2.c
deleted file mode 100644
index b678bd2d..00000000
--- a/dumb/dumb-0.9.3/src/it/readxm2.c
+++ /dev/null
@@ -1,29 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * readxm2.c - Function to read a Fast Tracker II / / \ \
- * module from an open file and do an | < / \_
- * initial run-through. | \/ /\ /
- * \_ / > /
- * Split off from readxm.c by entheh. | \ / /
- * | ' /
- * \__/
- */
-
-#include "dumb.h"
-
-
-
-DUH *dumb_read_xm(DUMBFILE *f)
-{
- DUH *duh = dumb_read_xm_quick(f);
- dumb_it_do_initial_runthrough(duh);
- return duh;
-}
diff --git a/dumb/dumb-0.9.3/src/it/xmeffect.c b/dumb/dumb-0.9.3/src/it/xmeffect.c
deleted file mode 100644
index cd39749a..00000000
--- a/dumb/dumb-0.9.3/src/it/xmeffect.c
+++ /dev/null
@@ -1,242 +0,0 @@
-/* _______ ____ __ ___ ___
- * \ _ \ \ / \ / \ \ / / ' ' '
- * | | \ \ | | || | \/ | . .
- * | | | | | | || ||\ /| |
- * | | | | | | || || \/ | | ' ' '
- * | | | | | | || || | | . .
- * | |_/ / \ \__// || | |
- * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
- * / \
- * / . \
- * xmeffect.c - Code for converting MOD/XM / / \ \
- * effects to IT effects. | < / \_
- * | \/ /\ /
- * By Julien Cugniere. Ripped out of readxm.c \_ / > /
- * by entheh. | \ / /
- * | ' /
- * \__/
- */
-
-
-
-#include <stdlib.h>
-#include <string.h>
-
-#include "dumb.h"
-#include "internal/it.h"
-
-
-
-#if 0
-unsigned char **_dumb_malloc2(int w, int h)
-{
- unsigned char **line = malloc(h * sizeof(*line));
- int i;
- if (!line) return NULL;
-
- line[0] = malloc(w * h * sizeof(*line[0]));
- if (!line[0]) {
- free(line);
- return NULL;
- }
-
- for (i = 1; i < h; i++)
- line[i] = line[i-1] + w;
-
- memset(line[0], 0, w*h);
-
- return line;
-}
-
-
-
-void _dumb_free2(unsigned char **line)
-{
- if (line) {
- if (line[0])
- free(line[0]);
- free(line);
- }
-}
-
-
-
-/* Effects having a memory. 2 means that the two parts of the effectvalue
- * should be handled separately.
- */
-static const char xm_has_memory[] = {
-/* 0 1 2 3 4 5 6 7 8 9 A B C D (E) F G H K L P R T (X) */
- 0, 1, 1, 1, 2, 1, 1, 2, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0,
-
-/* E0 E1 E2 E3 E4 E5 E6 E7 E9 EA EB EC ED EE X1 X2 */
- 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
-};
-#endif
-
-
-
-/* Effects marked with 'special' are handled specifically in itrender.c */
-void _dumb_it_xm_convert_effect(int effect, int value, IT_ENTRY *entry)
-{
-const int log = 0;
-
- if ((!effect && !value) || (effect >= XM_N_EFFECTS))
- return;
-
-if (log) printf("%c%02X", (effect<10)?('0'+effect):('A'+effect-10), value);
-
- /* Linearisation of the effect number... */
- if (effect == XM_E) {
- effect = EBASE + HIGH(value);
- value = LOW(value);
- } else if (effect == XM_X) {
- effect = XBASE + HIGH(value);
- value = LOW(value);
- }
-
-if (log) printf(" - %2d %02X", effect, value);
-
-#if 0 // This should be handled in itrender.c!
- /* update effect memory */
- switch (xm_has_memory[effect]) {
- case 1:
- if (!value)
- value = memory[entry->channel][effect];
- else
- memory[entry->channel][effect] = value;
- break;
-
- case 2:
- if (!HIGH(value))
- SET_HIGH(value, HIGH(memory[entry->channel][effect]));
- else
- SET_HIGH(memory[entry->channel][effect], HIGH(value));
-
- if (!LOW(value))
- SET_LOW(value, LOW(memory[entry->channel][effect]));
- else
- SET_LOW(memory[entry->channel][effect], LOW(value));
- break;
- }
-#endif
-
- /* convert effect */
- entry->mask |= IT_ENTRY_EFFECT;
- switch (effect) {
-
- case XM_APPREGIO: effect = IT_ARPEGGIO; break;
- case XM_VIBRATO: effect = IT_VIBRATO; break;
- case XM_TONE_PORTAMENTO: effect = IT_TONE_PORTAMENTO; break; /** TODO: glissando control */
- case XM_TREMOLO: effect = IT_TREMOLO; break;
- case XM_SET_PANNING: effect = IT_SET_PANNING; break;
- case XM_SAMPLE_OFFSET: effect = IT_SET_SAMPLE_OFFSET; break;
- case XM_POSITION_JUMP: effect = IT_JUMP_TO_ORDER; break;
- case XM_MULTI_RETRIG: effect = IT_RETRIGGER_NOTE; break;
- case XM_TREMOR: effect = IT_TREMOR; break;
- case XM_PORTAMENTO_UP: effect = IT_XM_PORTAMENTO_UP; break;
- case XM_PORTAMENTO_DOWN: effect = IT_XM_PORTAMENTO_DOWN; break;
- case XM_SET_CHANNEL_VOLUME: effect = IT_SET_CHANNEL_VOLUME; break; /* special */
- case XM_VOLSLIDE_TONEPORTA: effect = IT_VOLSLIDE_TONEPORTA; break; /* special */
- case XM_VOLSLIDE_VIBRATO: effect = IT_VOLSLIDE_VIBRATO; break; /* special */
-
- case XM_PATTERN_BREAK:
- effect = IT_BREAK_TO_ROW;
- value = BCD_TO_NORMAL(value);
- break;
-
- case XM_VOLUME_SLIDE: /* special */
- effect = IT_VOLUME_SLIDE;
- value = HIGH(value) ? EFFECT_VALUE(HIGH(value), 0) : EFFECT_VALUE(0, LOW(value));
- break;
-
- case XM_PANNING_SLIDE:
- effect = IT_PANNING_SLIDE;
- value = HIGH(value) ? EFFECT_VALUE(HIGH(value), 0) : EFFECT_VALUE(0, LOW(value));
- //value = HIGH(value) ? EFFECT_VALUE(0, HIGH(value)) : EFFECT_VALUE(LOW(value), 0);
- break;
-
- case XM_GLOBAL_VOLUME_SLIDE: /* special */
- effect = IT_GLOBAL_VOLUME_SLIDE;
- value = HIGH(value) ? EFFECT_VALUE(HIGH(value), 0) : EFFECT_VALUE(0, LOW(value));
- break;
-
- case XM_SET_TEMPO_BPM:
- effect = (value < 0x20) ? (IT_SET_SPEED) : (IT_SET_SONG_TEMPO);
- break;
-
- case XM_SET_GLOBAL_VOLUME:
- effect = IT_SET_GLOBAL_VOLUME;
- value *= 2;
- break;
-
- case XM_KEY_OFF:
- effect = IT_XM_KEY_OFF;
- break;
-
- case XM_SET_ENVELOPE_POSITION:
- effect = IT_XM_SET_ENVELOPE_POSITION;
- break;
-
- case EBASE+XM_E_SET_FILTER: effect = SBASE+IT_S_SET_FILTER; break;
- case EBASE+XM_E_SET_GLISSANDO_CONTROL: effect = SBASE+IT_S_SET_GLISSANDO_CONTROL; break; /** TODO */
- case EBASE+XM_E_SET_FINETUNE: effect = SBASE+IT_S_FINETUNE; break; /** TODO */
- case EBASE+XM_E_SET_LOOP: effect = SBASE+IT_S_PATTERN_LOOP; break;
- case EBASE+XM_E_NOTE_CUT: effect = SBASE+IT_S_DELAYED_NOTE_CUT; break;
- case EBASE+XM_E_NOTE_DELAY: effect = SBASE+IT_S_NOTE_DELAY; break;
- case EBASE+XM_E_PATTERN_DELAY: effect = SBASE+IT_S_PATTERN_DELAY; break;
- case EBASE+XM_E_FINE_VOLSLIDE_UP: effect = IT_XM_FINE_VOLSLIDE_UP; break;
- case EBASE+XM_E_FINE_VOLSLIDE_DOWN: effect = IT_XM_FINE_VOLSLIDE_DOWN; break;
-
- case EBASE + XM_E_FINE_PORTA_UP:
- effect = IT_PORTAMENTO_UP;
- value = EFFECT_VALUE(0xF, value);
- break;
-
- case EBASE + XM_E_FINE_PORTA_DOWN:
- effect = IT_PORTAMENTO_DOWN;
- value = EFFECT_VALUE(0xF, value);
- break;
-
- case EBASE + XM_E_RETRIG_NOTE:
- effect = IT_XM_RETRIGGER_NOTE;
- value = EFFECT_VALUE(0, value);
- break;
-
- case EBASE + XM_E_SET_VIBRATO_CONTROL:
- effect = SBASE+IT_S_SET_VIBRATO_WAVEFORM;
- value &= ~4; /** TODO: value&4 -> don't retrig wave */
- break;
-
- case EBASE + XM_E_SET_TREMOLO_CONTROL:
- effect = SBASE+IT_S_SET_TREMOLO_WAVEFORM;
- value &= ~4; /** TODO: value&4 -> don't retrig wave */
- break;
-
- case XBASE + XM_X_EXTRAFINE_PORTA_UP:
- effect = IT_PORTAMENTO_UP;
- value = EFFECT_VALUE(0xE, value);
- break;
-
- case XBASE + XM_X_EXTRAFINE_PORTA_DOWN:
- effect = IT_PORTAMENTO_DOWN;
- value = EFFECT_VALUE(0xE, value);
- break;
-
- default:
- /* user effect (often used in demos for synchronisation) */
- entry->mask &= ~IT_ENTRY_EFFECT;
- }
-
-if (log) printf(" - %2d %02X", effect, value);
-
- /* Inverse linearisation... */
- if (effect >= SBASE && effect < SBASE+16) {
- value = EFFECT_VALUE(effect-SBASE, value);
- effect = IT_S;
- }
-
-if (log) printf(" - %c%02X\n", 'A'+effect-1, value);
-
- entry->effect = effect;
- entry->effectvalue = value;
-}