Commit 3b4c54c2 authored by Erik Faye-Lund's avatar Erik Faye-Lund
Browse files

added volume fadeout

git-svn-id: https://pimpmobile.svn.sourceforge.net/svnroot/pimpmobile/trunk@117 3d5ecaf0-f903-0410-b953-c2c1a4d75763
parent 6ea399c1
...@@ -8,7 +8,7 @@ ...@@ -8,7 +8,7 @@
/* check the sample-rate calculator at http://www.pineight.com/gba/samplerates/ for more glitch-free samplerates */ /* check the sample-rate calculator at http://www.pineight.com/gba/samplerates/ for more glitch-free samplerates */
/* 0x4000100 = 0xFFFF, 0x4000102 = 0x0083 */ /* 0x4000100 = 0xFFFF, 0x4000102 = 0x0083 */
#define SAMPLERATE (18157.16 * 2) #define SAMPLERATE (18157.16)
/* only 130 bytes big, quite damn pleasing results */ /* only 130 bytes big, quite damn pleasing results */
#define AMIGA_DELTA_LUT_LOG_SIZE 7 #define AMIGA_DELTA_LUT_LOG_SIZE 7
......
...@@ -3,76 +3,21 @@ ...@@ -3,76 +3,21 @@
#include <stdio.h> #include <stdio.h>
#if 0 STATIC int __pimp_envelope_find_node(const pimp_envelope *env, int tick)
int __pimp_envelope_find_node(const pimp_envelope *env, int tick)
{ {
ASSERT(NULL != env); ASSERT(NULL != env);
ASSERT(tick >= 0);
for (int i = 1; i < env->node_count - 1; ++i) for (int i = 1; i < env->node_count; ++i)
{ {
if (env->node_tick[i] <= tick) if (env->node_tick[i] > tick)
{ {
return i - 1; return i - 1;
} }
} }
return 0;
}
#endif
#if 0
unsigned eval_vol_env(pimp_channel_state &chan)
{
ASSERT(NULL != chan.vol_env);
#if 0
/* find the current volume envelope node */
if (chan.vol_env_node = -1)
{
for (int i = 0; i < chan.vol_env->node_count - 1; ++i)
{
if (chan.vol_env->node_tick[i] <= chan.vol_env_tick)
{
chan.vol_env_node = i;
break;
}
}
}
#endif
// TODO: sustain
// the magnitude of the envelope at tick N:
// first, find the last node at or before tick N - its position is M
// then, the magnitude of the envelope at tick N is given by
// magnitude = node_magnitude[M] + ((node_delta[M] * (N-M)) >> 8)
s32 delta = chan.vol_env->node_delta[chan.vol_env_node];
u32 internal_tick = chan.vol_env_tick - chan.vol_env->node_tick[chan.vol_env_node];
int val = chan.vol_env->node_magnitude[chan.vol_env_node];
val += ((long long)delta * internal_tick) >> 9;
chan.vol_env_tick++; return env->node_count - 1;
if (chan.vol_env_node < (chan.vol_env->node_count - 1))
{
#if 0
if (chan.vol_env->flags & (1 << 1))
{
/* sustain loop */
chan.vol_env_tick = 0; // HACK: just used to make the BP06 demo tune play correctly
}
else
#endif
if (chan.vol_env_tick >= chan.vol_env->node_tick[chan.vol_env_node + 1])
{
chan.vol_env_node++;
}
}
return val << 2;
} }
#endif
int __pimp_envelope_sample(pimp_envelope_state *state) int __pimp_envelope_sample(pimp_envelope_state *state)
{ {
...@@ -81,7 +26,7 @@ int __pimp_envelope_sample(pimp_envelope_state *state) ...@@ -81,7 +26,7 @@ int __pimp_envelope_sample(pimp_envelope_state *state)
/* the magnitude of the envelope at tick N: /* the magnitude of the envelope at tick N:
* first, find the last node at or before tick N - its position is M * first, find the last node at or before tick N - its position is M
* then, the magnitude of the envelope at tick N is given by * then, the magnitude of the envelope at tick N is given by
* magnitude = node_magnitude[M] + ((node_delta[M] * (N-M)) >> 8) * magnitude = node_magnitude[M] + ((node_delta[M] * (N - M)) >> 8)
*/ */
s32 delta = state->env->node_delta[state->current_node]; s32 delta = state->env->node_delta[state->current_node];
...@@ -121,3 +66,9 @@ void __pimp_envelope_advance_tick(pimp_envelope_state *state, bool sustain) ...@@ -121,3 +66,9 @@ void __pimp_envelope_advance_tick(pimp_envelope_state *state, bool sustain)
} }
} }
} }
void __pimp_envelope_set_tick(pimp_envelope_state *state, int tick)
{
state->current_node = __pimp_envelope_find_node(state->env, tick);
state->current_tick = tick;
}
...@@ -30,5 +30,6 @@ STATIC INLINE void __pimp_envelope_reset(pimp_envelope_state *state) ...@@ -30,5 +30,6 @@ STATIC INLINE void __pimp_envelope_reset(pimp_envelope_state *state)
int __pimp_envelope_sample(pimp_envelope_state *state); int __pimp_envelope_sample(pimp_envelope_state *state);
void __pimp_envelope_advance_tick(pimp_envelope_state *state, bool sustain); void __pimp_envelope_advance_tick(pimp_envelope_state *state, bool sustain);
void __pimp_envelope_set_tick(pimp_envelope_state *state, int tick);
#endif /* PIMP_ENVELOPE_H */ #endif /* PIMP_ENVELOPE_H */
...@@ -14,28 +14,24 @@ typedef struct ...@@ -14,28 +14,24 @@ typedef struct
const pimp_instrument *instrument; const pimp_instrument *instrument;
const pimp_sample *sample; const pimp_sample *sample;
// const pimp_envelope *vol_env;
pimp_envelope_state vol_env; pimp_envelope_state vol_env;
bool sustain; bool sustain;
s32 period; s32 period;
s32 final_period; s32 final_period;
s32 porta_target; s32 porta_target;
s32 fadeout;
u16 porta_speed; u16 porta_speed;
s8 volume_slide_speed; s8 volume_slide_speed;
u8 note_delay; u8 note_delay;
s8 volume; s8 volume;
u8 pan; u8 pan;
u8 note; u8 note;
u8 effect; u8 effect;
u8 effect_param; u8 effect_param;
u8 volume_command; u8 volume_command;
// u32 vol_env_tick;
// s8 vol_env_node;
u8 note_retrig; u8 note_retrig;
u8 retrig_tick; u8 retrig_tick;
} pimp_channel_state; } pimp_channel_state;
......
...@@ -38,19 +38,28 @@ STATIC void porta_note(pimp_channel_state *chan) ...@@ -38,19 +38,28 @@ STATIC void porta_note(pimp_channel_state *chan)
STATIC int __pimp_channel_get_volume(pimp_channel_state *chan) STATIC int __pimp_channel_get_volume(pimp_channel_state *chan)
{ {
/* FADEOUT: */
int volume = chan->volume; int volume = chan->volume;
if (chan->vol_env.env != 0) if (chan->vol_env.env != 0)
{ {
volume = (volume * __pimp_envelope_sample(&chan->vol_env)) >> 8; volume = (volume * __pimp_envelope_sample(&chan->vol_env)) >> 8;
__pimp_envelope_advance_tick(&chan->vol_env, chan->sustain); __pimp_envelope_advance_tick(&chan->vol_env, chan->sustain);
volume = (volume * chan->fadeout) >> 16;
chan->fadeout -= chan->instrument->volume_fadeout;
if (chan->fadeout <= 0)
{
// TODO: kill sample
chan->fadeout = 0;
}
} }
else else
{ {
if (!chan->sustain) volume = 0; if (!chan->sustain) volume = 0;
} }
// if (chan->sustain == true) printf("%d\n", volume);
return volume; return volume;
} }
...@@ -91,6 +100,7 @@ STATIC void __pimp_mod_context_update_row(pimp_mod_context *ctx) ...@@ -91,6 +100,7 @@ STATIC void __pimp_mod_context_update_row(pimp_mod_context *ctx)
chan->vol_env.env = get_vol_env(chan->instrument); chan->vol_env.env = get_vol_env(chan->instrument);
__pimp_envelope_reset(&chan->vol_env); __pimp_envelope_reset(&chan->vol_env);
chan->sustain = true; chan->sustain = true;
chan->fadeout = 1 << 16;
chan->volume = chan->sample->volume; chan->volume = chan->sample->volume;
volume_dirty = true; volume_dirty = true;
...@@ -128,10 +138,8 @@ STATIC void __pimp_mod_context_update_row(pimp_mod_context *ctx) ...@@ -128,10 +138,8 @@ STATIC void __pimp_mod_context_update_row(pimp_mod_context *ctx)
{ {
chan->period = __pimp_get_amiga_period(((s32)note->note) + chan->sample->rel_note, chan->sample->fine_tune); chan->period = __pimp_get_amiga_period(((s32)note->note) + chan->sample->rel_note, chan->sample->fine_tune);
} }
chan->final_period = chan->period;
chan->sustain = true;
chan->final_period = chan->period;
period_dirty = true; period_dirty = true;
} }
} }
......
No preview for this file type
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment