pimp_envelope.cpp 2.87 KB
Newer Older
1
2
3
4
5
#include "pimp_envelope.h"
#include "pimp_debug.h"

#include <stdio.h>

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#if 0
int __pimp_envelope_find_node(const pimp_envelope *env, int tick)
{
	ASSERT(NULL != env);
	
	for (int i = 1; i < env->node_count - 1; ++i)
	{
		if (env->node_tick[i] <= tick)
		{
			return i - 1;
		}
	}
	return 0;
}
#endif

22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#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++;

	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

Erik Faye-Lund's avatar
Erik Faye-Lund committed
77
int __pimp_envelope_sample(pimp_envelope_state *state)
78
{
Erik Faye-Lund's avatar
Erik Faye-Lund committed
79
	ASSERT(NULL != state);
80

81
82
83
84
85
	/* 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)
	 */
86
87
88
89
90
91
92
	
	s32 delta = state->env->node_delta[state->current_node];
	u32 internal_tick = state->current_tick - state->env->node_tick[state->current_node];
	
	int val = state->env->node_magnitude[state->current_node];
	val += ((long long)delta * internal_tick) >> 9;
	
Erik Faye-Lund's avatar
Erik Faye-Lund committed
93
94
95
96
97
98
99
	return val << 2;
}

void __pimp_envelope_advance_tick(pimp_envelope_state *state, bool sustain)
{
	ASSERT(NULL != state);
	
100
	/* advance a tick */
101
	state->current_tick++;
102
103
104
	
	/* check for sustain loop */
	if ((state->env->flags & (1 << 1)) && (sustain == true))
105
	{
106
		if (state->current_tick >= state->env->sustain_loop_end)
107
		{
108
109
			state->current_node = state->env->sustain_loop_start;
			state->current_tick = state->env->node_tick[state->current_node];
110
		}
111
112
113
114
115
116
117
	}
	
	/* check if we have passed the current node
	 * we don't need to clamp the envelope-pos to the end, since the last delta is zero
	 */
	if (state->current_node < (state->env->node_count - 1))
	{
118
119
120
121
122
123
		if (state->current_tick >= state->env->node_tick[state->current_node + 1])
		{
			state->current_node++;
		}
	}
}