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:
Randy Heit 2015-12-28 20:33:41 -06:00
parent a2ebf771d3
commit 635b496165
3 changed files with 473 additions and 459 deletions

View file

@ -269,23 +269,23 @@ _WM_init_reverb(int rate, float room_x, float room_y, float listen_x,
double a1 = -2 * cs;
double a2 = 1 - (alpha / A);
rtn_rvb->coeff[j][i][0] = (signed long int) ((b0 / a0) * 1024.0);
rtn_rvb->coeff[j][i][1] = (signed long int) ((b1 / a0) * 1024.0);
rtn_rvb->coeff[j][i][2] = (signed long int) ((b2 / a0) * 1024.0);
rtn_rvb->coeff[j][i][3] = (signed long int) ((a1 / a0) * 1024.0);
rtn_rvb->coeff[j][i][4] = (signed long int) ((a2 / a0) * 1024.0);
rtn_rvb->coeff[j][i][0] = (signed int) ((b0 / a0) * 1024.0);
rtn_rvb->coeff[j][i][1] = (signed int) ((b1 / a0) * 1024.0);
rtn_rvb->coeff[j][i][2] = (signed int) ((b2 / a0) * 1024.0);
rtn_rvb->coeff[j][i][3] = (signed int) ((a1 / a0) * 1024.0);
rtn_rvb->coeff[j][i][4] = (signed int) ((a2 / a0) * 1024.0);
}
}
/* init the reverb buffers */
rtn_rvb->l_buf_size = (int) ((float) rate * (MAXL_DST / 340.29));
rtn_rvb->l_buf = (long*)malloc(
sizeof(signed long int) * (rtn_rvb->l_buf_size + 1));
rtn_rvb->l_buf = (int*)malloc(
sizeof(signed int) * (rtn_rvb->l_buf_size + 1));
rtn_rvb->l_out = 0;
rtn_rvb->r_buf_size = (int) ((float) rate * (MAXR_DST / 340.29));
rtn_rvb->r_buf = (long*)malloc(
sizeof(signed long int) * (rtn_rvb->r_buf_size + 1));
rtn_rvb->r_buf = (int*)malloc(
sizeof(signed int) * (rtn_rvb->r_buf_size + 1));
rtn_rvb->r_out = 0;
for (i = 0; i < 4; i++) {
@ -313,17 +313,17 @@ void _WM_free_reverb(struct _rvb *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;
signed long int l_buf_flt = 0;
signed long int r_buf_flt = 0;
signed long int l_rfl = 0;
signed long int r_rfl = 0;
signed int l_buf_flt = 0;
signed int r_buf_flt = 0;
signed int l_rfl = 0;
signed int r_rfl = 0;
int vol_div = 64;
for (i = 0; i < size; i += 2) {
signed long int tmp_l_val = 0;
signed long int tmp_r_val = 0;
signed int tmp_l_val = 0;
signed int tmp_r_val = 0;
/*
add the initial reflections
from each speaker, 4 to go the left, 4 go to the right buffers

View file

@ -29,14 +29,14 @@
struct _rvb {
/* filter data */
signed long int l_buf_flt_in[8][6][2];
signed long int l_buf_flt_out[8][6][2];
signed long int r_buf_flt_in[8][6][2];
signed long int r_buf_flt_out[8][6][2];
signed long int coeff[8][6][5];
signed int l_buf_flt_in[8][6][2];
signed int l_buf_flt_out[8][6][2];
signed int r_buf_flt_in[8][6][2];
signed int r_buf_flt_out[8][6][2];
signed int coeff[8][6][5];
/* buffer data */
signed long int *l_buf;
signed long int *r_buf;
signed int *l_buf;
signed int *r_buf;
int l_buf_size;
int r_buf_size;
int l_out;
@ -52,6 +52,6 @@ struct _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 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 */

View file

@ -182,7 +182,7 @@ struct _mdi {
unsigned long int patch_count;
signed short int amp;
signed long int *mix_buffer;
signed int *mix_buffer;
unsigned long int mix_buffer_size;
struct _rvb *reverb;
@ -3203,73 +3203,14 @@ _end: free(sysex_store);
return NULL;
}
static int WM_GetOutput_Linear(midi * handle, char * buffer,
unsigned long int size) {
unsigned long int buffer_used = 0;
unsigned long int i;
static int *WM_Mix_Linear(midi * handle, int * buffer, unsigned long int count)
{
struct _mdi *mdi = (struct _mdi *)handle;
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;
signed int premix, left_mix, right_mix;
signed int vol_mul;
struct _note *note_data = NULL;
unsigned long int count;
struct _event *event = mdi->current_event;
signed long int *tmp_buffer;
signed long int *out_buffer;
_WM_Lock(&mdi->lock);
buffer_used = 0;
memset(buffer, 0, size);
if ( (size / 2) > mdi->mix_buffer_size) {
if ( (size / 2) <= ( mdi->mix_buffer_size * 2 )) {
mdi->mix_buffer_size += MEM_CHUNK;
} else {
mdi->mix_buffer_size = size / 2;
}
mdi->mix_buffer = (long*)realloc(mdi->mix_buffer, mdi->mix_buffer_size * sizeof(signed long int));
}
tmp_buffer = mdi->mix_buffer;
memset(tmp_buffer, 0, ((size / 2) * sizeof(signed long int)));
out_buffer = tmp_buffer;
do {
if (__builtin_expect((!mdi->samples_to_mix), 0)) {
while ((!mdi->samples_to_mix) && (event->do_event)) {
event->do_event(mdi, &event->event_data);
event++;
mdi->samples_to_mix = event->samples_to_next;
mdi->current_event = event;
}
if (!mdi->samples_to_mix) {
if (mdi->info.current_sample
>= mdi->info.approx_total_samples) {
break;
} else if ((mdi->info.approx_total_samples
- mdi->info.current_sample) > (size >> 2)) {
mdi->samples_to_mix = size >> 2;
} else {
mdi->samples_to_mix = mdi->info.approx_total_samples
- mdi->info.current_sample;
}
}
}
if (__builtin_expect((mdi->samples_to_mix > (size >> 2)), 1)) {
real_samples_to_mix = size >> 2;
} else {
real_samples_to_mix = mdi->samples_to_mix;
if (real_samples_to_mix == 0) {
continue;
}
}
/* do mixing here */
count = real_samples_to_mix;
do {
note_data = mdi->note;
left_mix = right_mix = 0;
@ -3456,9 +3397,75 @@ static int WM_GetOutput_Linear(midi * handle, char * buffer,
right_mix /= 1024;
}
*tmp_buffer++ = left_mix;
*tmp_buffer++ = right_mix;
*buffer++ = left_mix;
*buffer++ = right_mix;
} while (--count);
return buffer;
}
static int WM_GetOutput_Linear(midi * handle, char * buffer,
unsigned long int size) {
unsigned long int buffer_used = 0;
unsigned long int i;
struct _mdi *mdi = (struct _mdi *) handle;
unsigned long int real_samples_to_mix = 0;
struct _event *event = mdi->current_event;
int *tmp_buffer;
int *out_buffer;
int left_mix, right_mix;
_WM_Lock(&mdi->lock);
buffer_used = 0;
memset(buffer, 0, size);
if ( (size / 2) > mdi->mix_buffer_size) {
if ( (size / 2) <= ( mdi->mix_buffer_size * 2 )) {
mdi->mix_buffer_size += MEM_CHUNK;
} else {
mdi->mix_buffer_size = size / 2;
}
mdi->mix_buffer = (int*)realloc(mdi->mix_buffer, mdi->mix_buffer_size * sizeof(signed int));
}
tmp_buffer = mdi->mix_buffer;
memset(tmp_buffer, 0, ((size / 2) * sizeof(signed long int)));
out_buffer = tmp_buffer;
do {
if (__builtin_expect((!mdi->samples_to_mix), 0)) {
while ((!mdi->samples_to_mix) && (event->do_event)) {
event->do_event(mdi, &event->event_data);
event++;
mdi->samples_to_mix = event->samples_to_next;
mdi->current_event = event;
}
if (!mdi->samples_to_mix) {
if (mdi->info.current_sample
>= mdi->info.approx_total_samples) {
break;
} else if ((mdi->info.approx_total_samples
- mdi->info.current_sample) > (size >> 2)) {
mdi->samples_to_mix = size >> 2;
} else {
mdi->samples_to_mix = mdi->info.approx_total_samples
- mdi->info.current_sample;
}
}
}
if (__builtin_expect((mdi->samples_to_mix > (size >> 2)), 1)) {
real_samples_to_mix = size >> 2;
} else {
real_samples_to_mix = mdi->samples_to_mix;
if (real_samples_to_mix == 0) {
continue;
}
}
/* do mixing here */
tmp_buffer = WM_Mix_Linear(handle, tmp_buffer, real_samples_to_mix);
buffer_used += real_samples_to_mix * 4;
size -= (real_samples_to_mix << 2);
@ -3503,75 +3510,19 @@ static int WM_GetOutput_Linear(midi * handle, char * buffer,
return buffer_used;
}
static int WM_GetOutput_Gauss(midi * handle, char * buffer,
unsigned long int size) {
unsigned long int buffer_used = 0;
unsigned long int i;
static int *WM_Mix_Gauss(midi * handle, int * buffer, unsigned long int count)
{
struct _mdi *mdi = (struct _mdi *)handle;
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;
signed int premix, left_mix, right_mix;
signed 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;
signed long int *tmp_buffer;
signed long int *out_buffer;
_WM_Lock(&mdi->lock);
buffer_used = 0;
memset(buffer, 0, size);
if ( (size / 2) > mdi->mix_buffer_size) {
if ( (size / 2) <= ( mdi->mix_buffer_size * 2 )) {
mdi->mix_buffer_size += MEM_CHUNK;
} else {
mdi->mix_buffer_size = size / 2;
}
mdi->mix_buffer = (long*)realloc(mdi->mix_buffer, mdi->mix_buffer_size * sizeof(signed long int));
}
tmp_buffer = mdi->mix_buffer;
memset(tmp_buffer, 0, ((size / 2) * sizeof(signed long int)));
out_buffer = tmp_buffer;
do {
if (__builtin_expect((!mdi->samples_to_mix), 0)) {
while ((!mdi->samples_to_mix) && (event->do_event)) {
event->do_event(mdi, &event->event_data);
event++;
mdi->samples_to_mix = event->samples_to_next;
mdi->current_event = event;
}
if (!mdi->samples_to_mix) {
if (mdi->info.current_sample
>= mdi->info.approx_total_samples) {
break;
} else if ((mdi->info.approx_total_samples
- mdi->info.current_sample) > (size >> 2)) {
mdi->samples_to_mix = size >> 2;
} else {
mdi->samples_to_mix = mdi->info.approx_total_samples
- mdi->info.current_sample;
}
}
}
if (__builtin_expect((mdi->samples_to_mix > (size >> 2)), 1)) {
real_samples_to_mix = size >> 2;
} else {
real_samples_to_mix = mdi->samples_to_mix;
if (real_samples_to_mix == 0) {
continue;
}
}
/* do mixing here */
count = real_samples_to_mix;
do {
note_data = mdi->note;
left_mix = right_mix = 0;
@ -3791,9 +3742,72 @@ static int WM_GetOutput_Gauss(midi * handle, char * buffer,
right_mix /= 1024;
}
*tmp_buffer++ = left_mix;
*tmp_buffer++ = right_mix;
*buffer++ = left_mix;
*buffer++ = right_mix;
} while (--count);
return buffer;
}
static int WM_GetOutput_Gauss(midi * handle, char * buffer,
unsigned long int size) {
unsigned long int buffer_used = 0;
unsigned long int i;
struct _mdi *mdi = (struct _mdi *) handle;
unsigned long int real_samples_to_mix = 0;
struct _event *event = mdi->current_event;
signed int *tmp_buffer;
signed int *out_buffer;
signed int left_mix, right_mix;
_WM_Lock(&mdi->lock);
buffer_used = 0;
memset(buffer, 0, size);
if ( (size / 2) > mdi->mix_buffer_size) {
if ( (size / 2) <= ( mdi->mix_buffer_size * 2 )) {
mdi->mix_buffer_size += MEM_CHUNK;
} else {
mdi->mix_buffer_size = size / 2;
}
mdi->mix_buffer = (int*)realloc(mdi->mix_buffer, mdi->mix_buffer_size * sizeof(signed int));
}
tmp_buffer = mdi->mix_buffer;
memset(tmp_buffer, 0, ((size / 2) * sizeof(signed long int)));
out_buffer = tmp_buffer;
do {
if (__builtin_expect((!mdi->samples_to_mix), 0)) {
while ((!mdi->samples_to_mix) && (event->do_event)) {
event->do_event(mdi, &event->event_data);
event++;
mdi->samples_to_mix = event->samples_to_next;
mdi->current_event = event;
}
if (!mdi->samples_to_mix) {
if (mdi->info.current_sample
>= mdi->info.approx_total_samples) {
break;
} else if ((mdi->info.approx_total_samples
- mdi->info.current_sample) > (size >> 2)) {
mdi->samples_to_mix = size >> 2;
} else {
mdi->samples_to_mix = mdi->info.approx_total_samples
- mdi->info.current_sample;
}
}
}
if (__builtin_expect((mdi->samples_to_mix > (size >> 2)), 1)) {
real_samples_to_mix = size >> 2;
} else {
real_samples_to_mix = mdi->samples_to_mix;
if (real_samples_to_mix == 0) {
continue;
}
}
/* do mixing here */
tmp_buffer = WM_Mix_Gauss(handle, tmp_buffer, real_samples_to_mix);
buffer_used += real_samples_to_mix * 4;
size -= (real_samples_to_mix << 2);