mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-13 07:57:58 +00:00
Separate WildMidi mixing from event handling
- In order to use ZDoom's own MIDI sequencer event handling must be completely separate from mixing, but WildMidi had them intertwined because it wasn't designed for external sequencers. - Also remove all 'long's defining the output buffers to avoid having something that's 32 bits wide on Windows and 64 bits wide on Linux.
This commit is contained in:
parent
a2ebf771d3
commit
635b496165
3 changed files with 473 additions and 459 deletions
|
@ -269,23 +269,23 @@ _WM_init_reverb(int rate, float room_x, float room_y, float listen_x,
|
||||||
double a1 = -2 * cs;
|
double a1 = -2 * cs;
|
||||||
double a2 = 1 - (alpha / A);
|
double a2 = 1 - (alpha / A);
|
||||||
|
|
||||||
rtn_rvb->coeff[j][i][0] = (signed long int) ((b0 / a0) * 1024.0);
|
rtn_rvb->coeff[j][i][0] = (signed int) ((b0 / a0) * 1024.0);
|
||||||
rtn_rvb->coeff[j][i][1] = (signed long int) ((b1 / a0) * 1024.0);
|
rtn_rvb->coeff[j][i][1] = (signed int) ((b1 / a0) * 1024.0);
|
||||||
rtn_rvb->coeff[j][i][2] = (signed long int) ((b2 / a0) * 1024.0);
|
rtn_rvb->coeff[j][i][2] = (signed int) ((b2 / a0) * 1024.0);
|
||||||
rtn_rvb->coeff[j][i][3] = (signed long int) ((a1 / a0) * 1024.0);
|
rtn_rvb->coeff[j][i][3] = (signed int) ((a1 / a0) * 1024.0);
|
||||||
rtn_rvb->coeff[j][i][4] = (signed long int) ((a2 / a0) * 1024.0);
|
rtn_rvb->coeff[j][i][4] = (signed int) ((a2 / a0) * 1024.0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* init the reverb buffers */
|
/* init the reverb buffers */
|
||||||
rtn_rvb->l_buf_size = (int) ((float) rate * (MAXL_DST / 340.29));
|
rtn_rvb->l_buf_size = (int) ((float) rate * (MAXL_DST / 340.29));
|
||||||
rtn_rvb->l_buf = (long*)malloc(
|
rtn_rvb->l_buf = (int*)malloc(
|
||||||
sizeof(signed long int) * (rtn_rvb->l_buf_size + 1));
|
sizeof(signed int) * (rtn_rvb->l_buf_size + 1));
|
||||||
rtn_rvb->l_out = 0;
|
rtn_rvb->l_out = 0;
|
||||||
|
|
||||||
rtn_rvb->r_buf_size = (int) ((float) rate * (MAXR_DST / 340.29));
|
rtn_rvb->r_buf_size = (int) ((float) rate * (MAXR_DST / 340.29));
|
||||||
rtn_rvb->r_buf = (long*)malloc(
|
rtn_rvb->r_buf = (int*)malloc(
|
||||||
sizeof(signed long int) * (rtn_rvb->r_buf_size + 1));
|
sizeof(signed int) * (rtn_rvb->r_buf_size + 1));
|
||||||
rtn_rvb->r_out = 0;
|
rtn_rvb->r_out = 0;
|
||||||
|
|
||||||
for (i = 0; i < 4; i++) {
|
for (i = 0; i < 4; i++) {
|
||||||
|
@ -313,17 +313,17 @@ void _WM_free_reverb(struct _rvb *rvb) {
|
||||||
free(rvb);
|
free(rvb);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _WM_do_reverb(struct _rvb *rvb, signed long int *buffer, int size) {
|
void _WM_do_reverb(struct _rvb *rvb, signed int *buffer, int size) {
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
signed long int l_buf_flt = 0;
|
signed int l_buf_flt = 0;
|
||||||
signed long int r_buf_flt = 0;
|
signed int r_buf_flt = 0;
|
||||||
signed long int l_rfl = 0;
|
signed int l_rfl = 0;
|
||||||
signed long int r_rfl = 0;
|
signed int r_rfl = 0;
|
||||||
int vol_div = 64;
|
int vol_div = 64;
|
||||||
|
|
||||||
for (i = 0; i < size; i += 2) {
|
for (i = 0; i < size; i += 2) {
|
||||||
signed long int tmp_l_val = 0;
|
signed int tmp_l_val = 0;
|
||||||
signed long int tmp_r_val = 0;
|
signed int tmp_r_val = 0;
|
||||||
/*
|
/*
|
||||||
add the initial reflections
|
add the initial reflections
|
||||||
from each speaker, 4 to go the left, 4 go to the right buffers
|
from each speaker, 4 to go the left, 4 go to the right buffers
|
||||||
|
|
|
@ -29,14 +29,14 @@
|
||||||
|
|
||||||
struct _rvb {
|
struct _rvb {
|
||||||
/* filter data */
|
/* filter data */
|
||||||
signed long int l_buf_flt_in[8][6][2];
|
signed int l_buf_flt_in[8][6][2];
|
||||||
signed long int l_buf_flt_out[8][6][2];
|
signed int l_buf_flt_out[8][6][2];
|
||||||
signed long int r_buf_flt_in[8][6][2];
|
signed int r_buf_flt_in[8][6][2];
|
||||||
signed long int r_buf_flt_out[8][6][2];
|
signed int r_buf_flt_out[8][6][2];
|
||||||
signed long int coeff[8][6][5];
|
signed int coeff[8][6][5];
|
||||||
/* buffer data */
|
/* buffer data */
|
||||||
signed long int *l_buf;
|
signed int *l_buf;
|
||||||
signed long int *r_buf;
|
signed int *r_buf;
|
||||||
int l_buf_size;
|
int l_buf_size;
|
||||||
int r_buf_size;
|
int r_buf_size;
|
||||||
int l_out;
|
int l_out;
|
||||||
|
@ -52,6 +52,6 @@ struct _rvb {
|
||||||
extern void _WM_reset_reverb (struct _rvb *rvb);
|
extern void _WM_reset_reverb (struct _rvb *rvb);
|
||||||
extern struct _rvb *_WM_init_reverb(int rate, float room_x, float room_y, float listen_x, float listen_y);
|
extern struct _rvb *_WM_init_reverb(int rate, float room_x, float room_y, float listen_x, float listen_y);
|
||||||
extern void _WM_free_reverb (struct _rvb *rvb);
|
extern void _WM_free_reverb (struct _rvb *rvb);
|
||||||
extern void _WM_do_reverb (struct _rvb *rvb, signed long int *buffer, int size);
|
extern void _WM_do_reverb (struct _rvb *rvb, signed int *buffer, int size);
|
||||||
|
|
||||||
#endif /* __REVERB_H */
|
#endif /* __REVERB_H */
|
||||||
|
|
|
@ -182,7 +182,7 @@ struct _mdi {
|
||||||
unsigned long int patch_count;
|
unsigned long int patch_count;
|
||||||
signed short int amp;
|
signed short int amp;
|
||||||
|
|
||||||
signed long int *mix_buffer;
|
signed int *mix_buffer;
|
||||||
unsigned long int mix_buffer_size;
|
unsigned long int mix_buffer_size;
|
||||||
|
|
||||||
struct _rvb *reverb;
|
struct _rvb *reverb;
|
||||||
|
@ -3203,20 +3203,216 @@ _end: free(sysex_store);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int *WM_Mix_Linear(midi * handle, int * buffer, unsigned long int count)
|
||||||
|
{
|
||||||
|
struct _mdi *mdi = (struct _mdi *)handle;
|
||||||
|
unsigned long int data_pos;
|
||||||
|
signed int premix, left_mix, right_mix;
|
||||||
|
signed int vol_mul;
|
||||||
|
struct _note *note_data = NULL;
|
||||||
|
|
||||||
|
do {
|
||||||
|
note_data = mdi->note;
|
||||||
|
left_mix = right_mix = 0;
|
||||||
|
if (__builtin_expect((note_data != NULL), 1)) {
|
||||||
|
while (note_data) {
|
||||||
|
/*
|
||||||
|
* ===================
|
||||||
|
* resample the sample
|
||||||
|
* ===================
|
||||||
|
*/
|
||||||
|
data_pos = note_data->sample_pos >> FPBITS;
|
||||||
|
vol_mul = ((note_data->vol_lvl
|
||||||
|
* (note_data->env_level >> 12)) >> FPBITS);
|
||||||
|
|
||||||
|
premix = (note_data->sample->data[data_pos]
|
||||||
|
+ ((note_data->sample->data[data_pos + 1]
|
||||||
|
- note_data->sample->data[data_pos])
|
||||||
|
* (signed long int) (note_data->sample_pos
|
||||||
|
& FPMASK)>> FPBITS)) * vol_mul
|
||||||
|
/ 1024;
|
||||||
|
|
||||||
|
left_mix += premix
|
||||||
|
* mdi->channel[note_data->noteid >> 8].left_adjust;
|
||||||
|
right_mix += premix
|
||||||
|
* mdi->channel[note_data->noteid >> 8].right_adjust;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ========================
|
||||||
|
* sample position checking
|
||||||
|
* ========================
|
||||||
|
*/
|
||||||
|
note_data->sample_pos += note_data->sample_inc;
|
||||||
|
if (__builtin_expect(
|
||||||
|
(note_data->sample_pos > note_data->sample->loop_end),
|
||||||
|
0)) {
|
||||||
|
if (note_data->modes & SAMPLE_LOOP) {
|
||||||
|
note_data->sample_pos =
|
||||||
|
note_data->sample->loop_start
|
||||||
|
+ ((note_data->sample_pos
|
||||||
|
- note_data->sample->loop_start)
|
||||||
|
% note_data->sample->loop_size);
|
||||||
|
} else if (__builtin_expect(
|
||||||
|
(note_data->sample_pos
|
||||||
|
>= note_data->sample->data_length),
|
||||||
|
0)) {
|
||||||
|
if (__builtin_expect((note_data->replay == NULL), 1)) {
|
||||||
|
goto KILL_NOTE;
|
||||||
|
}
|
||||||
|
goto RESTART_NOTE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (__builtin_expect((note_data->env_inc == 0), 0)) {
|
||||||
|
note_data = note_data->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
note_data->env_level += note_data->env_inc;
|
||||||
|
if (__builtin_expect((note_data->env_level > 4194304), 0)) {
|
||||||
|
note_data->env_level =
|
||||||
|
note_data->sample->env_target[note_data->env];
|
||||||
|
}
|
||||||
|
if (__builtin_expect(
|
||||||
|
((note_data->env_inc < 0)
|
||||||
|
&& (note_data->env_level
|
||||||
|
> note_data->sample->env_target[note_data->env]))
|
||||||
|
|| ((note_data->env_inc > 0)
|
||||||
|
&& (note_data->env_level
|
||||||
|
< note_data->sample->env_target[note_data->env])),
|
||||||
|
1)) {
|
||||||
|
note_data = note_data->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
note_data->env_level =
|
||||||
|
note_data->sample->env_target[note_data->env];
|
||||||
|
switch (note_data->env) {
|
||||||
|
case 0:
|
||||||
|
#if 0
|
||||||
|
if (!(note_data->modes & SAMPLE_ENVELOPE)) {
|
||||||
|
note_data->env_inc = 0;
|
||||||
|
note_data = note_data->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (note_data->modes & SAMPLE_SUSTAIN) {
|
||||||
|
note_data->env_inc = 0;
|
||||||
|
note_data = note_data->next;
|
||||||
|
continue;
|
||||||
|
} else if (note_data->modes & SAMPLE_CLAMPED) {
|
||||||
|
note_data->env = 5;
|
||||||
|
if (note_data->env_level
|
||||||
|
> note_data->sample->env_target[5]) {
|
||||||
|
note_data->env_inc =
|
||||||
|
-note_data->sample->env_rate[5];
|
||||||
|
} else {
|
||||||
|
note_data->env_inc =
|
||||||
|
note_data->sample->env_rate[5];
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
if (__builtin_expect((note_data->env_level == 0), 1)) {
|
||||||
|
goto KILL_NOTE;
|
||||||
|
}
|
||||||
|
/* sample release */
|
||||||
|
if (note_data->modes & SAMPLE_LOOP)
|
||||||
|
note_data->modes ^= SAMPLE_LOOP;
|
||||||
|
note_data->env_inc = 0;
|
||||||
|
note_data = note_data->next;
|
||||||
|
continue;
|
||||||
|
case 6:
|
||||||
|
if (__builtin_expect((note_data->replay != NULL), 1)) {
|
||||||
|
RESTART_NOTE: note_data->active = 0;
|
||||||
|
{
|
||||||
|
struct _note *prev_note = NULL;
|
||||||
|
struct _note *nte_array = mdi->note;
|
||||||
|
|
||||||
|
if (nte_array != note_data) {
|
||||||
|
do {
|
||||||
|
prev_note = nte_array;
|
||||||
|
nte_array = nte_array->next;
|
||||||
|
} while (nte_array != note_data);
|
||||||
|
}
|
||||||
|
if (prev_note) {
|
||||||
|
prev_note->next = note_data->replay;
|
||||||
|
} else {
|
||||||
|
mdi->note = note_data->replay;
|
||||||
|
}
|
||||||
|
note_data->replay->next = note_data->next;
|
||||||
|
note_data = note_data->replay;
|
||||||
|
note_data->active = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
KILL_NOTE: note_data->active = 0;
|
||||||
|
{
|
||||||
|
struct _note *prev_note = NULL;
|
||||||
|
struct _note *nte_array = mdi->note;
|
||||||
|
|
||||||
|
if (nte_array != note_data) {
|
||||||
|
do {
|
||||||
|
prev_note = nte_array;
|
||||||
|
nte_array = nte_array->next;
|
||||||
|
} while ((nte_array != note_data)
|
||||||
|
&& (nte_array));
|
||||||
|
}
|
||||||
|
if (prev_note) {
|
||||||
|
prev_note->next = note_data->next;
|
||||||
|
} else {
|
||||||
|
mdi->note = note_data->next;
|
||||||
|
}
|
||||||
|
note_data = note_data->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
note_data->env++;
|
||||||
|
|
||||||
|
if (note_data->is_off == 1) {
|
||||||
|
do_note_off_extra(note_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (note_data->env_level
|
||||||
|
> note_data->sample->env_target[note_data->env]) {
|
||||||
|
note_data->env_inc =
|
||||||
|
-note_data->sample->env_rate[note_data->env];
|
||||||
|
} else {
|
||||||
|
note_data->env_inc =
|
||||||
|
note_data->sample->env_rate[note_data->env];
|
||||||
|
}
|
||||||
|
note_data = note_data->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* =========================
|
||||||
|
* mix the channels together
|
||||||
|
* =========================
|
||||||
|
*/
|
||||||
|
left_mix /= 1024;
|
||||||
|
right_mix /= 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
*buffer++ = left_mix;
|
||||||
|
*buffer++ = right_mix;
|
||||||
|
} while (--count);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
static int WM_GetOutput_Linear(midi * handle, char * buffer,
|
static int WM_GetOutput_Linear(midi * handle, char * buffer,
|
||||||
unsigned long int size) {
|
unsigned long int size) {
|
||||||
unsigned long int buffer_used = 0;
|
unsigned long int buffer_used = 0;
|
||||||
unsigned long int i;
|
unsigned long int i;
|
||||||
struct _mdi *mdi = (struct _mdi *) handle;
|
struct _mdi *mdi = (struct _mdi *) handle;
|
||||||
unsigned long int real_samples_to_mix = 0;
|
unsigned long int real_samples_to_mix = 0;
|
||||||
unsigned long int data_pos;
|
|
||||||
signed long int premix, left_mix, right_mix;
|
|
||||||
signed long int vol_mul;
|
|
||||||
struct _note *note_data = NULL;
|
|
||||||
unsigned long int count;
|
|
||||||
struct _event *event = mdi->current_event;
|
struct _event *event = mdi->current_event;
|
||||||
signed long int *tmp_buffer;
|
int *tmp_buffer;
|
||||||
signed long int *out_buffer;
|
int *out_buffer;
|
||||||
|
int left_mix, right_mix;
|
||||||
|
|
||||||
_WM_Lock(&mdi->lock);
|
_WM_Lock(&mdi->lock);
|
||||||
|
|
||||||
|
@ -3229,7 +3425,7 @@ static int WM_GetOutput_Linear(midi * handle, char * buffer,
|
||||||
} else {
|
} else {
|
||||||
mdi->mix_buffer_size = size / 2;
|
mdi->mix_buffer_size = size / 2;
|
||||||
}
|
}
|
||||||
mdi->mix_buffer = (long*)realloc(mdi->mix_buffer, mdi->mix_buffer_size * sizeof(signed long int));
|
mdi->mix_buffer = (int*)realloc(mdi->mix_buffer, mdi->mix_buffer_size * sizeof(signed int));
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp_buffer = mdi->mix_buffer;
|
tmp_buffer = mdi->mix_buffer;
|
||||||
|
@ -3269,196 +3465,7 @@ static int WM_GetOutput_Linear(midi * handle, char * buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* do mixing here */
|
/* do mixing here */
|
||||||
count = real_samples_to_mix;
|
tmp_buffer = WM_Mix_Linear(handle, tmp_buffer, real_samples_to_mix);
|
||||||
do {
|
|
||||||
note_data = mdi->note;
|
|
||||||
left_mix = right_mix = 0;
|
|
||||||
if (__builtin_expect((note_data != NULL), 1)) {
|
|
||||||
while (note_data) {
|
|
||||||
/*
|
|
||||||
* ===================
|
|
||||||
* resample the sample
|
|
||||||
* ===================
|
|
||||||
*/
|
|
||||||
data_pos = note_data->sample_pos >> FPBITS;
|
|
||||||
vol_mul = ((note_data->vol_lvl
|
|
||||||
* (note_data->env_level >> 12)) >> FPBITS);
|
|
||||||
|
|
||||||
premix = (note_data->sample->data[data_pos]
|
|
||||||
+ ((note_data->sample->data[data_pos + 1]
|
|
||||||
- note_data->sample->data[data_pos])
|
|
||||||
* (signed long int) (note_data->sample_pos
|
|
||||||
& FPMASK)>> FPBITS)) * vol_mul
|
|
||||||
/ 1024;
|
|
||||||
|
|
||||||
left_mix += premix
|
|
||||||
* mdi->channel[note_data->noteid >> 8].left_adjust;
|
|
||||||
right_mix += premix
|
|
||||||
* mdi->channel[note_data->noteid >> 8].right_adjust;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ========================
|
|
||||||
* sample position checking
|
|
||||||
* ========================
|
|
||||||
*/
|
|
||||||
note_data->sample_pos += note_data->sample_inc;
|
|
||||||
if (__builtin_expect(
|
|
||||||
(note_data->sample_pos > note_data->sample->loop_end),
|
|
||||||
0)) {
|
|
||||||
if (note_data->modes & SAMPLE_LOOP) {
|
|
||||||
note_data->sample_pos =
|
|
||||||
note_data->sample->loop_start
|
|
||||||
+ ((note_data->sample_pos
|
|
||||||
- note_data->sample->loop_start)
|
|
||||||
% note_data->sample->loop_size);
|
|
||||||
} else if (__builtin_expect(
|
|
||||||
(note_data->sample_pos
|
|
||||||
>= note_data->sample->data_length),
|
|
||||||
0)) {
|
|
||||||
if (__builtin_expect((note_data->replay == NULL), 1)) {
|
|
||||||
goto KILL_NOTE;
|
|
||||||
}
|
|
||||||
goto RESTART_NOTE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (__builtin_expect((note_data->env_inc == 0), 0)) {
|
|
||||||
note_data = note_data->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
note_data->env_level += note_data->env_inc;
|
|
||||||
if (__builtin_expect((note_data->env_level > 4194304), 0)) {
|
|
||||||
note_data->env_level =
|
|
||||||
note_data->sample->env_target[note_data->env];
|
|
||||||
}
|
|
||||||
if (__builtin_expect(
|
|
||||||
((note_data->env_inc < 0)
|
|
||||||
&& (note_data->env_level
|
|
||||||
> note_data->sample->env_target[note_data->env]))
|
|
||||||
|| ((note_data->env_inc > 0)
|
|
||||||
&& (note_data->env_level
|
|
||||||
< note_data->sample->env_target[note_data->env])),
|
|
||||||
1)) {
|
|
||||||
note_data = note_data->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
note_data->env_level =
|
|
||||||
note_data->sample->env_target[note_data->env];
|
|
||||||
switch (note_data->env) {
|
|
||||||
case 0:
|
|
||||||
#if 0
|
|
||||||
if (!(note_data->modes & SAMPLE_ENVELOPE)) {
|
|
||||||
note_data->env_inc = 0;
|
|
||||||
note_data = note_data->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (note_data->modes & SAMPLE_SUSTAIN) {
|
|
||||||
note_data->env_inc = 0;
|
|
||||||
note_data = note_data->next;
|
|
||||||
continue;
|
|
||||||
} else if (note_data->modes & SAMPLE_CLAMPED) {
|
|
||||||
note_data->env = 5;
|
|
||||||
if (note_data->env_level
|
|
||||||
> note_data->sample->env_target[5]) {
|
|
||||||
note_data->env_inc =
|
|
||||||
-note_data->sample->env_rate[5];
|
|
||||||
} else {
|
|
||||||
note_data->env_inc =
|
|
||||||
note_data->sample->env_rate[5];
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
if (__builtin_expect((note_data->env_level == 0), 1)) {
|
|
||||||
goto KILL_NOTE;
|
|
||||||
}
|
|
||||||
/* sample release */
|
|
||||||
if (note_data->modes & SAMPLE_LOOP)
|
|
||||||
note_data->modes ^= SAMPLE_LOOP;
|
|
||||||
note_data->env_inc = 0;
|
|
||||||
note_data = note_data->next;
|
|
||||||
continue;
|
|
||||||
case 6:
|
|
||||||
if (__builtin_expect((note_data->replay != NULL), 1)) {
|
|
||||||
RESTART_NOTE: note_data->active = 0;
|
|
||||||
{
|
|
||||||
struct _note *prev_note = NULL;
|
|
||||||
struct _note *nte_array = mdi->note;
|
|
||||||
|
|
||||||
if (nte_array != note_data) {
|
|
||||||
do {
|
|
||||||
prev_note = nte_array;
|
|
||||||
nte_array = nte_array->next;
|
|
||||||
} while (nte_array != note_data);
|
|
||||||
}
|
|
||||||
if (prev_note) {
|
|
||||||
prev_note->next = note_data->replay;
|
|
||||||
} else {
|
|
||||||
mdi->note = note_data->replay;
|
|
||||||
}
|
|
||||||
note_data->replay->next = note_data->next;
|
|
||||||
note_data = note_data->replay;
|
|
||||||
note_data->active = 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
KILL_NOTE: note_data->active = 0;
|
|
||||||
{
|
|
||||||
struct _note *prev_note = NULL;
|
|
||||||
struct _note *nte_array = mdi->note;
|
|
||||||
|
|
||||||
if (nte_array != note_data) {
|
|
||||||
do {
|
|
||||||
prev_note = nte_array;
|
|
||||||
nte_array = nte_array->next;
|
|
||||||
} while ((nte_array != note_data)
|
|
||||||
&& (nte_array));
|
|
||||||
}
|
|
||||||
if (prev_note) {
|
|
||||||
prev_note->next = note_data->next;
|
|
||||||
} else {
|
|
||||||
mdi->note = note_data->next;
|
|
||||||
}
|
|
||||||
note_data = note_data->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
note_data->env++;
|
|
||||||
|
|
||||||
if (note_data->is_off == 1) {
|
|
||||||
do_note_off_extra(note_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (note_data->env_level
|
|
||||||
> note_data->sample->env_target[note_data->env]) {
|
|
||||||
note_data->env_inc =
|
|
||||||
-note_data->sample->env_rate[note_data->env];
|
|
||||||
} else {
|
|
||||||
note_data->env_inc =
|
|
||||||
note_data->sample->env_rate[note_data->env];
|
|
||||||
}
|
|
||||||
note_data = note_data->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* =========================
|
|
||||||
* mix the channels together
|
|
||||||
* =========================
|
|
||||||
*/
|
|
||||||
left_mix /= 1024;
|
|
||||||
right_mix /= 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
*tmp_buffer++ = left_mix;
|
|
||||||
*tmp_buffer++ = right_mix;
|
|
||||||
} while (--count);
|
|
||||||
|
|
||||||
buffer_used += real_samples_to_mix * 4;
|
buffer_used += real_samples_to_mix * 4;
|
||||||
size -= (real_samples_to_mix << 2);
|
size -= (real_samples_to_mix << 2);
|
||||||
|
@ -3503,25 +3510,254 @@ static int WM_GetOutput_Linear(midi * handle, char * buffer,
|
||||||
return buffer_used;
|
return buffer_used;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int *WM_Mix_Gauss(midi * handle, int * buffer, unsigned long int count)
|
||||||
|
{
|
||||||
|
struct _mdi *mdi = (struct _mdi *)handle;
|
||||||
|
unsigned long int data_pos;
|
||||||
|
signed int premix, left_mix, right_mix;
|
||||||
|
signed int vol_mul;
|
||||||
|
struct _note *note_data = NULL;
|
||||||
|
signed short int *sptr;
|
||||||
|
double y, xd;
|
||||||
|
double *gptr, *gend;
|
||||||
|
int left, right, temp_n;
|
||||||
|
int ii, jj;
|
||||||
|
|
||||||
|
do {
|
||||||
|
note_data = mdi->note;
|
||||||
|
left_mix = right_mix = 0;
|
||||||
|
if (__builtin_expect((note_data != NULL), 1)) {
|
||||||
|
while (note_data) {
|
||||||
|
/*
|
||||||
|
* ===================
|
||||||
|
* resample the sample
|
||||||
|
* ===================
|
||||||
|
*/
|
||||||
|
data_pos = note_data->sample_pos >> FPBITS;
|
||||||
|
vol_mul = ((note_data->vol_lvl
|
||||||
|
* (note_data->env_level >> 12)) >> FPBITS);
|
||||||
|
|
||||||
|
/* check to see if we're near one of the ends */
|
||||||
|
left = data_pos;
|
||||||
|
right = (note_data->sample->data_length >> FPBITS) - left
|
||||||
|
- 1;
|
||||||
|
temp_n = (right << 1) - 1;
|
||||||
|
if (temp_n <= 0)
|
||||||
|
temp_n = 1;
|
||||||
|
if (temp_n > (left << 1) + 1)
|
||||||
|
temp_n = (left << 1) + 1;
|
||||||
|
|
||||||
|
/* use Newton if we can't fill the window */
|
||||||
|
if (temp_n < gauss_n) {
|
||||||
|
xd = note_data->sample_pos & FPMASK;
|
||||||
|
xd /= (1L << FPBITS);
|
||||||
|
xd += temp_n >> 1;
|
||||||
|
y = 0;
|
||||||
|
sptr = note_data->sample->data
|
||||||
|
+ (note_data->sample_pos >> FPBITS)
|
||||||
|
- (temp_n >> 1);
|
||||||
|
for (ii = temp_n; ii;) {
|
||||||
|
for (jj = 0; jj <= ii; jj++)
|
||||||
|
y += sptr[jj] * newt_coeffs[ii][jj];
|
||||||
|
y *= xd - --ii;
|
||||||
|
}
|
||||||
|
y += *sptr;
|
||||||
|
} else { /* otherwise, use Gauss as usual */
|
||||||
|
y = 0;
|
||||||
|
gptr = &gauss_table[(note_data->sample_pos & FPMASK) *
|
||||||
|
(gauss_n + 1)];
|
||||||
|
gend = gptr + gauss_n;
|
||||||
|
sptr = note_data->sample->data
|
||||||
|
+ (note_data->sample_pos >> FPBITS)
|
||||||
|
- (gauss_n >> 1);
|
||||||
|
do {
|
||||||
|
y += *(sptr++) * *(gptr++);
|
||||||
|
} while (gptr <= gend);
|
||||||
|
}
|
||||||
|
|
||||||
|
premix = (long) (y * vol_mul / 1024);
|
||||||
|
|
||||||
|
left_mix += premix
|
||||||
|
* mdi->channel[note_data->noteid >> 8].left_adjust;
|
||||||
|
right_mix += premix
|
||||||
|
* mdi->channel[note_data->noteid >> 8].right_adjust;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ========================
|
||||||
|
* sample position checking
|
||||||
|
* ========================
|
||||||
|
*/
|
||||||
|
note_data->sample_pos += note_data->sample_inc;
|
||||||
|
if (__builtin_expect(
|
||||||
|
(note_data->sample_pos > note_data->sample->loop_end),
|
||||||
|
0)) {
|
||||||
|
if (note_data->modes & SAMPLE_LOOP) {
|
||||||
|
note_data->sample_pos =
|
||||||
|
note_data->sample->loop_start
|
||||||
|
+ ((note_data->sample_pos
|
||||||
|
- note_data->sample->loop_start)
|
||||||
|
% note_data->sample->loop_size);
|
||||||
|
} else if (__builtin_expect(
|
||||||
|
(note_data->sample_pos
|
||||||
|
>= note_data->sample->data_length),
|
||||||
|
0)) {
|
||||||
|
if (__builtin_expect((note_data->replay == NULL), 1)) {
|
||||||
|
goto KILL_NOTE;
|
||||||
|
}
|
||||||
|
goto RESTART_NOTE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (__builtin_expect((note_data->env_inc == 0), 0)) {
|
||||||
|
note_data = note_data->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
note_data->env_level += note_data->env_inc;
|
||||||
|
if (__builtin_expect((note_data->env_level > 4194304), 0)) {
|
||||||
|
note_data->env_level =
|
||||||
|
note_data->sample->env_target[note_data->env];
|
||||||
|
}
|
||||||
|
if (__builtin_expect(
|
||||||
|
((note_data->env_inc < 0)
|
||||||
|
&& (note_data->env_level
|
||||||
|
> note_data->sample->env_target[note_data->env]))
|
||||||
|
|| ((note_data->env_inc > 0)
|
||||||
|
&& (note_data->env_level
|
||||||
|
< note_data->sample->env_target[note_data->env])),
|
||||||
|
1)) {
|
||||||
|
note_data = note_data->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
note_data->env_level =
|
||||||
|
note_data->sample->env_target[note_data->env];
|
||||||
|
switch (note_data->env) {
|
||||||
|
case 0:
|
||||||
|
#if 0
|
||||||
|
if (!(note_data->modes & SAMPLE_ENVELOPE)) {
|
||||||
|
note_data->env_inc = 0;
|
||||||
|
note_data = note_data->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
if (note_data->modes & SAMPLE_SUSTAIN) {
|
||||||
|
note_data->env_inc = 0;
|
||||||
|
note_data = note_data->next;
|
||||||
|
continue;
|
||||||
|
} else if (note_data->modes & SAMPLE_CLAMPED) {
|
||||||
|
note_data->env = 5;
|
||||||
|
if (note_data->env_level
|
||||||
|
> note_data->sample->env_target[5]) {
|
||||||
|
note_data->env_inc =
|
||||||
|
-note_data->sample->env_rate[5];
|
||||||
|
} else {
|
||||||
|
note_data->env_inc =
|
||||||
|
note_data->sample->env_rate[5];
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
if (__builtin_expect((note_data->env_level == 0), 1)) {
|
||||||
|
goto KILL_NOTE;
|
||||||
|
}
|
||||||
|
/* sample release */
|
||||||
|
if (note_data->modes & SAMPLE_LOOP)
|
||||||
|
note_data->modes ^= SAMPLE_LOOP;
|
||||||
|
note_data->env_inc = 0;
|
||||||
|
note_data = note_data->next;
|
||||||
|
continue;
|
||||||
|
case 6:
|
||||||
|
if (__builtin_expect((note_data->replay != NULL), 1)) {
|
||||||
|
RESTART_NOTE: note_data->active = 0;
|
||||||
|
{
|
||||||
|
struct _note *prev_note = NULL;
|
||||||
|
struct _note *nte_array = mdi->note;
|
||||||
|
|
||||||
|
if (nte_array != note_data) {
|
||||||
|
do {
|
||||||
|
prev_note = nte_array;
|
||||||
|
nte_array = nte_array->next;
|
||||||
|
} while (nte_array != note_data);
|
||||||
|
}
|
||||||
|
if (prev_note) {
|
||||||
|
prev_note->next = note_data->replay;
|
||||||
|
} else {
|
||||||
|
mdi->note = note_data->replay;
|
||||||
|
}
|
||||||
|
note_data->replay->next = note_data->next;
|
||||||
|
note_data = note_data->replay;
|
||||||
|
note_data->active = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
KILL_NOTE: note_data->active = 0;
|
||||||
|
{
|
||||||
|
struct _note *prev_note = NULL;
|
||||||
|
struct _note *nte_array = mdi->note;
|
||||||
|
|
||||||
|
if (nte_array != note_data) {
|
||||||
|
do {
|
||||||
|
prev_note = nte_array;
|
||||||
|
nte_array = nte_array->next;
|
||||||
|
} while ((nte_array != note_data)
|
||||||
|
&& (nte_array));
|
||||||
|
}
|
||||||
|
if (prev_note) {
|
||||||
|
prev_note->next = note_data->next;
|
||||||
|
} else {
|
||||||
|
mdi->note = note_data->next;
|
||||||
|
}
|
||||||
|
note_data = note_data->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
note_data->env++;
|
||||||
|
|
||||||
|
if (note_data->is_off == 1) {
|
||||||
|
do_note_off_extra(note_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (note_data->env_level
|
||||||
|
> note_data->sample->env_target[note_data->env]) {
|
||||||
|
note_data->env_inc =
|
||||||
|
-note_data->sample->env_rate[note_data->env];
|
||||||
|
} else {
|
||||||
|
note_data->env_inc =
|
||||||
|
note_data->sample->env_rate[note_data->env];
|
||||||
|
}
|
||||||
|
note_data = note_data->next;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* =========================
|
||||||
|
* mix the channels together
|
||||||
|
* =========================
|
||||||
|
*/
|
||||||
|
left_mix /= 1024;
|
||||||
|
right_mix /= 1024;
|
||||||
|
}
|
||||||
|
|
||||||
|
*buffer++ = left_mix;
|
||||||
|
*buffer++ = right_mix;
|
||||||
|
} while (--count);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
static int WM_GetOutput_Gauss(midi * handle, char * buffer,
|
static int WM_GetOutput_Gauss(midi * handle, char * buffer,
|
||||||
unsigned long int size) {
|
unsigned long int size) {
|
||||||
unsigned long int buffer_used = 0;
|
unsigned long int buffer_used = 0;
|
||||||
unsigned long int i;
|
unsigned long int i;
|
||||||
struct _mdi *mdi = (struct _mdi *) handle;
|
struct _mdi *mdi = (struct _mdi *) handle;
|
||||||
unsigned long int real_samples_to_mix = 0;
|
unsigned long int real_samples_to_mix = 0;
|
||||||
unsigned long int data_pos;
|
|
||||||
signed long int premix, left_mix, right_mix;
|
|
||||||
signed long int vol_mul;
|
|
||||||
struct _note *note_data = NULL;
|
|
||||||
unsigned long int count;
|
|
||||||
signed short int *sptr;
|
|
||||||
double y, xd;
|
|
||||||
double *gptr, *gend;
|
|
||||||
int left, right, temp_n;
|
|
||||||
int ii, jj;
|
|
||||||
struct _event *event = mdi->current_event;
|
struct _event *event = mdi->current_event;
|
||||||
signed long int *tmp_buffer;
|
signed int *tmp_buffer;
|
||||||
signed long int *out_buffer;
|
signed int *out_buffer;
|
||||||
|
signed int left_mix, right_mix;
|
||||||
|
|
||||||
_WM_Lock(&mdi->lock);
|
_WM_Lock(&mdi->lock);
|
||||||
|
|
||||||
|
@ -3533,7 +3769,7 @@ static int WM_GetOutput_Gauss(midi * handle, char * buffer,
|
||||||
} else {
|
} else {
|
||||||
mdi->mix_buffer_size = size / 2;
|
mdi->mix_buffer_size = size / 2;
|
||||||
}
|
}
|
||||||
mdi->mix_buffer = (long*)realloc(mdi->mix_buffer, mdi->mix_buffer_size * sizeof(signed long int));
|
mdi->mix_buffer = (int*)realloc(mdi->mix_buffer, mdi->mix_buffer_size * sizeof(signed int));
|
||||||
}
|
}
|
||||||
tmp_buffer = mdi->mix_buffer;
|
tmp_buffer = mdi->mix_buffer;
|
||||||
memset(tmp_buffer, 0, ((size / 2) * sizeof(signed long int)));
|
memset(tmp_buffer, 0, ((size / 2) * sizeof(signed long int)));
|
||||||
|
@ -3571,229 +3807,7 @@ static int WM_GetOutput_Gauss(midi * handle, char * buffer,
|
||||||
}
|
}
|
||||||
|
|
||||||
/* do mixing here */
|
/* do mixing here */
|
||||||
count = real_samples_to_mix;
|
tmp_buffer = WM_Mix_Gauss(handle, tmp_buffer, real_samples_to_mix);
|
||||||
do {
|
|
||||||
note_data = mdi->note;
|
|
||||||
left_mix = right_mix = 0;
|
|
||||||
if (__builtin_expect((note_data != NULL), 1)) {
|
|
||||||
while (note_data) {
|
|
||||||
/*
|
|
||||||
* ===================
|
|
||||||
* resample the sample
|
|
||||||
* ===================
|
|
||||||
*/
|
|
||||||
data_pos = note_data->sample_pos >> FPBITS;
|
|
||||||
vol_mul = ((note_data->vol_lvl
|
|
||||||
* (note_data->env_level >> 12)) >> FPBITS);
|
|
||||||
|
|
||||||
/* check to see if we're near one of the ends */
|
|
||||||
left = data_pos;
|
|
||||||
right = (note_data->sample->data_length >> FPBITS) - left
|
|
||||||
- 1;
|
|
||||||
temp_n = (right << 1) - 1;
|
|
||||||
if (temp_n <= 0)
|
|
||||||
temp_n = 1;
|
|
||||||
if (temp_n > (left << 1) + 1)
|
|
||||||
temp_n = (left << 1) + 1;
|
|
||||||
|
|
||||||
/* use Newton if we can't fill the window */
|
|
||||||
if (temp_n < gauss_n) {
|
|
||||||
xd = note_data->sample_pos & FPMASK;
|
|
||||||
xd /= (1L << FPBITS);
|
|
||||||
xd += temp_n >> 1;
|
|
||||||
y = 0;
|
|
||||||
sptr = note_data->sample->data
|
|
||||||
+ (note_data->sample_pos >> FPBITS)
|
|
||||||
- (temp_n >> 1);
|
|
||||||
for (ii = temp_n; ii;) {
|
|
||||||
for (jj = 0; jj <= ii; jj++)
|
|
||||||
y += sptr[jj] * newt_coeffs[ii][jj];
|
|
||||||
y *= xd - --ii;
|
|
||||||
}
|
|
||||||
y += *sptr;
|
|
||||||
} else { /* otherwise, use Gauss as usual */
|
|
||||||
y = 0;
|
|
||||||
gptr = &gauss_table[(note_data->sample_pos & FPMASK) *
|
|
||||||
(gauss_n + 1)];
|
|
||||||
gend = gptr + gauss_n;
|
|
||||||
sptr = note_data->sample->data
|
|
||||||
+ (note_data->sample_pos >> FPBITS)
|
|
||||||
- (gauss_n >> 1);
|
|
||||||
do {
|
|
||||||
y += *(sptr++) * *(gptr++);
|
|
||||||
} while (gptr <= gend);
|
|
||||||
}
|
|
||||||
|
|
||||||
premix = (long) (y * vol_mul / 1024);
|
|
||||||
|
|
||||||
left_mix += premix
|
|
||||||
* mdi->channel[note_data->noteid >> 8].left_adjust;
|
|
||||||
right_mix += premix
|
|
||||||
* mdi->channel[note_data->noteid >> 8].right_adjust;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* ========================
|
|
||||||
* sample position checking
|
|
||||||
* ========================
|
|
||||||
*/
|
|
||||||
note_data->sample_pos += note_data->sample_inc;
|
|
||||||
if (__builtin_expect(
|
|
||||||
(note_data->sample_pos > note_data->sample->loop_end),
|
|
||||||
0)) {
|
|
||||||
if (note_data->modes & SAMPLE_LOOP) {
|
|
||||||
note_data->sample_pos =
|
|
||||||
note_data->sample->loop_start
|
|
||||||
+ ((note_data->sample_pos
|
|
||||||
- note_data->sample->loop_start)
|
|
||||||
% note_data->sample->loop_size);
|
|
||||||
} else if (__builtin_expect(
|
|
||||||
(note_data->sample_pos
|
|
||||||
>= note_data->sample->data_length),
|
|
||||||
0)) {
|
|
||||||
if (__builtin_expect((note_data->replay == NULL), 1)) {
|
|
||||||
goto KILL_NOTE;
|
|
||||||
}
|
|
||||||
goto RESTART_NOTE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (__builtin_expect((note_data->env_inc == 0), 0)) {
|
|
||||||
note_data = note_data->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
note_data->env_level += note_data->env_inc;
|
|
||||||
if (__builtin_expect((note_data->env_level > 4194304), 0)) {
|
|
||||||
note_data->env_level =
|
|
||||||
note_data->sample->env_target[note_data->env];
|
|
||||||
}
|
|
||||||
if (__builtin_expect(
|
|
||||||
((note_data->env_inc < 0)
|
|
||||||
&& (note_data->env_level
|
|
||||||
> note_data->sample->env_target[note_data->env]))
|
|
||||||
|| ((note_data->env_inc > 0)
|
|
||||||
&& (note_data->env_level
|
|
||||||
< note_data->sample->env_target[note_data->env])),
|
|
||||||
1)) {
|
|
||||||
note_data = note_data->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
note_data->env_level =
|
|
||||||
note_data->sample->env_target[note_data->env];
|
|
||||||
switch (note_data->env) {
|
|
||||||
case 0:
|
|
||||||
#if 0
|
|
||||||
if (!(note_data->modes & SAMPLE_ENVELOPE)) {
|
|
||||||
note_data->env_inc = 0;
|
|
||||||
note_data = note_data->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (note_data->modes & SAMPLE_SUSTAIN) {
|
|
||||||
note_data->env_inc = 0;
|
|
||||||
note_data = note_data->next;
|
|
||||||
continue;
|
|
||||||
} else if (note_data->modes & SAMPLE_CLAMPED) {
|
|
||||||
note_data->env = 5;
|
|
||||||
if (note_data->env_level
|
|
||||||
> note_data->sample->env_target[5]) {
|
|
||||||
note_data->env_inc =
|
|
||||||
-note_data->sample->env_rate[5];
|
|
||||||
} else {
|
|
||||||
note_data->env_inc =
|
|
||||||
note_data->sample->env_rate[5];
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 5:
|
|
||||||
if (__builtin_expect((note_data->env_level == 0), 1)) {
|
|
||||||
goto KILL_NOTE;
|
|
||||||
}
|
|
||||||
/* sample release */
|
|
||||||
if (note_data->modes & SAMPLE_LOOP)
|
|
||||||
note_data->modes ^= SAMPLE_LOOP;
|
|
||||||
note_data->env_inc = 0;
|
|
||||||
note_data = note_data->next;
|
|
||||||
continue;
|
|
||||||
case 6:
|
|
||||||
if (__builtin_expect((note_data->replay != NULL), 1)) {
|
|
||||||
RESTART_NOTE: note_data->active = 0;
|
|
||||||
{
|
|
||||||
struct _note *prev_note = NULL;
|
|
||||||
struct _note *nte_array = mdi->note;
|
|
||||||
|
|
||||||
if (nte_array != note_data) {
|
|
||||||
do {
|
|
||||||
prev_note = nte_array;
|
|
||||||
nte_array = nte_array->next;
|
|
||||||
} while (nte_array != note_data);
|
|
||||||
}
|
|
||||||
if (prev_note) {
|
|
||||||
prev_note->next = note_data->replay;
|
|
||||||
} else {
|
|
||||||
mdi->note = note_data->replay;
|
|
||||||
}
|
|
||||||
note_data->replay->next = note_data->next;
|
|
||||||
note_data = note_data->replay;
|
|
||||||
note_data->active = 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
KILL_NOTE: note_data->active = 0;
|
|
||||||
{
|
|
||||||
struct _note *prev_note = NULL;
|
|
||||||
struct _note *nte_array = mdi->note;
|
|
||||||
|
|
||||||
if (nte_array != note_data) {
|
|
||||||
do {
|
|
||||||
prev_note = nte_array;
|
|
||||||
nte_array = nte_array->next;
|
|
||||||
} while ((nte_array != note_data)
|
|
||||||
&& (nte_array));
|
|
||||||
}
|
|
||||||
if (prev_note) {
|
|
||||||
prev_note->next = note_data->next;
|
|
||||||
} else {
|
|
||||||
mdi->note = note_data->next;
|
|
||||||
}
|
|
||||||
note_data = note_data->next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
note_data->env++;
|
|
||||||
|
|
||||||
if (note_data->is_off == 1) {
|
|
||||||
do_note_off_extra(note_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (note_data->env_level
|
|
||||||
> note_data->sample->env_target[note_data->env]) {
|
|
||||||
note_data->env_inc =
|
|
||||||
-note_data->sample->env_rate[note_data->env];
|
|
||||||
} else {
|
|
||||||
note_data->env_inc =
|
|
||||||
note_data->sample->env_rate[note_data->env];
|
|
||||||
}
|
|
||||||
note_data = note_data->next;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* =========================
|
|
||||||
* mix the channels together
|
|
||||||
* =========================
|
|
||||||
*/
|
|
||||||
left_mix /= 1024;
|
|
||||||
right_mix /= 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
*tmp_buffer++ = left_mix;
|
|
||||||
*tmp_buffer++ = right_mix;
|
|
||||||
} while (--count);
|
|
||||||
|
|
||||||
buffer_used += real_samples_to_mix * 4;
|
buffer_used += real_samples_to_mix * 4;
|
||||||
size -= (real_samples_to_mix << 2);
|
size -= (real_samples_to_mix << 2);
|
||||||
|
|
Loading…
Reference in a new issue