mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-11 07:11:54 +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 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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue