Moved OPL2 and OPL3 to a new 49716 Hz source so resampling is no longer needed, also fixed SB OPL and PC Speaker filtering (OPL was being downsampled to the selected DSP sample rate, which is incorrect, and the PC Speaker filter was using the wrong filter index in some liens).
This commit is contained in:
@@ -5,7 +5,7 @@
|
||||
|
||||
/* fc=150Hz */
|
||||
static inline float
|
||||
adgold_highpass_iir(int i, float NewSample)
|
||||
adgold_highpass_iir(int c, int i, float NewSample)
|
||||
{
|
||||
float ACoef[NCoef + 1] = {
|
||||
0.98657437157334349000,
|
||||
@@ -19,28 +19,28 @@ adgold_highpass_iir(int i, float NewSample)
|
||||
0.97261396931534050000
|
||||
};
|
||||
|
||||
static float y[2][NCoef + 1]; /* output samples */
|
||||
static float x[2][NCoef + 1]; /* input samples */
|
||||
static float y[2][2][NCoef + 1]; /* output samples */
|
||||
static float x[2][2][NCoef + 1]; /* input samples */
|
||||
int n;
|
||||
|
||||
/* shift the old samples */
|
||||
for (n = NCoef; n > 0; n--) {
|
||||
x[i][n] = x[i][n - 1];
|
||||
y[i][n] = y[i][n - 1];
|
||||
x[c][i][n] = x[c][i][n - 1];
|
||||
y[c][i][n] = y[c][i][n - 1];
|
||||
}
|
||||
|
||||
/* Calculate the new output */
|
||||
x[i][0] = NewSample;
|
||||
y[i][0] = ACoef[0] * x[i][0];
|
||||
x[c][i][0] = NewSample;
|
||||
y[c][i][0] = ACoef[0] * x[c][i][0];
|
||||
for (n = 1; n <= NCoef; n++)
|
||||
y[i][0] += ACoef[n] * x[i][n] - BCoef[n] * y[i][n];
|
||||
y[c][i][0] += ACoef[n] * x[c][i][n] - BCoef[n] * y[c][i][n];
|
||||
|
||||
return y[i][0];
|
||||
return y[c][i][0];
|
||||
}
|
||||
|
||||
/* fc=150Hz */
|
||||
static inline float
|
||||
adgold_lowpass_iir(int i, float NewSample)
|
||||
adgold_lowpass_iir(int c, int i, float NewSample)
|
||||
{
|
||||
float ACoef[NCoef + 1] = {
|
||||
0.00009159473951071446,
|
||||
@@ -54,23 +54,23 @@ adgold_lowpass_iir(int i, float NewSample)
|
||||
0.97261396931306277000
|
||||
};
|
||||
|
||||
static float y[2][NCoef + 1]; /* output samples */
|
||||
static float x[2][NCoef + 1]; /* input samples */
|
||||
static float y[2][2][NCoef + 1]; /* output samples */
|
||||
static float x[2][2][NCoef + 1]; /* input samples */
|
||||
int n;
|
||||
|
||||
/* shift the old samples */
|
||||
for (n = NCoef; n > 0; n--) {
|
||||
x[i][n] = x[i][n - 1];
|
||||
y[i][n] = y[i][n - 1];
|
||||
x[c][i][n] = x[c][i][n - 1];
|
||||
y[c][i][n] = y[c][i][n - 1];
|
||||
}
|
||||
|
||||
/* Calculate the new output */
|
||||
x[i][0] = NewSample;
|
||||
y[i][0] = ACoef[0] * x[i][0];
|
||||
x[c][i][0] = NewSample;
|
||||
y[c][i][0] = ACoef[0] * x[c][i][0];
|
||||
for (n = 1; n <= NCoef; n++)
|
||||
y[i][0] += ACoef[n] * x[i][n] - BCoef[n] * y[i][n];
|
||||
y[c][i][0] += ACoef[n] * x[c][i][n] - BCoef[n] * y[c][i][n];
|
||||
|
||||
return y[i][0];
|
||||
return y[c][i][0];
|
||||
}
|
||||
|
||||
/* fc=56Hz */
|
||||
@@ -197,8 +197,8 @@ low_iir(int c, int i, double NewSample)
|
||||
0.93726236021404663000
|
||||
};
|
||||
|
||||
static double y[3][2][NCoef + 1]; /* output samples */
|
||||
static double x[3][2][NCoef + 1]; /* input samples */
|
||||
static double y[4][2][NCoef + 1]; /* output samples */
|
||||
static double x[4][2][NCoef + 1]; /* input samples */
|
||||
int n;
|
||||
|
||||
/* shift the old samples */
|
||||
@@ -232,8 +232,8 @@ low_cut_iir(int c, int i, double NewSample)
|
||||
0.93726236021916731000
|
||||
};
|
||||
|
||||
static double y[3][2][NCoef + 1]; /* output samples */
|
||||
static double x[3][2][NCoef + 1]; /* input samples */
|
||||
static double y[4][2][NCoef + 1]; /* output samples */
|
||||
static double x[4][2][NCoef + 1]; /* input samples */
|
||||
int n;
|
||||
|
||||
/* shift the old samples */
|
||||
@@ -266,8 +266,8 @@ high_iir(int c, int i, double NewSample)
|
||||
-1.36640781670578510000,
|
||||
0.52352474706139873000
|
||||
};
|
||||
static double y[3][2][NCoef + 1]; /* output samples */
|
||||
static double x[3][2][NCoef + 1]; /* input samples */
|
||||
static double y[4][2][NCoef + 1]; /* output samples */
|
||||
static double x[4][2][NCoef + 1]; /* input samples */
|
||||
int n;
|
||||
|
||||
/* shift the old samples */
|
||||
@@ -300,8 +300,8 @@ high_cut_iir(int c, int i, double NewSample)
|
||||
-1.36640781666419950000,
|
||||
0.52352474703279628000
|
||||
};
|
||||
static double y[3][2][NCoef + 1]; /* output samples */
|
||||
static double x[3][2][NCoef + 1]; /* input samples */
|
||||
static double y[4][2][NCoef + 1]; /* output samples */
|
||||
static double x[4][2][NCoef + 1]; /* input samples */
|
||||
int n;
|
||||
|
||||
/* shift the old samples */
|
||||
@@ -334,8 +334,8 @@ deemph_iir(int i, double NewSample)
|
||||
-1.05429146278569141337,
|
||||
0.26412280202756849290
|
||||
};
|
||||
static double y[3][NCoef + 1]; /* output samples */
|
||||
static double x[3][NCoef + 1]; /* input samples */
|
||||
static double y[4][NCoef + 1]; /* output samples */
|
||||
static double x[4][NCoef + 1]; /* input samples */
|
||||
int n;
|
||||
|
||||
/* shift the old samples */
|
||||
@@ -372,8 +372,8 @@ sb_iir(int c, int i, double NewSample)
|
||||
0.55326988968868285000
|
||||
};
|
||||
|
||||
static double y[3][2][NCoef + 1]; /* output samples */
|
||||
static double x[3][2][NCoef + 1]; /* input samples */
|
||||
static double y[4][2][NCoef + 1]; /* output samples */
|
||||
static double x[4][2][NCoef + 1]; /* input samples */
|
||||
int n;
|
||||
|
||||
/* shift the old samples */
|
||||
@@ -395,13 +395,13 @@ sb_iir(int c, int i, double NewSample)
|
||||
#define NCoef 1
|
||||
#define SB16_NCoef 51
|
||||
|
||||
extern double low_fir_sb16_coef[3][SB16_NCoef];
|
||||
extern double low_fir_sb16_coef[4][SB16_NCoef];
|
||||
|
||||
static inline double
|
||||
low_fir_sb16(int c, int i, double NewSample)
|
||||
{
|
||||
static double x[3][2][SB16_NCoef + 1]; // input samples
|
||||
static int pos[3] = { 0, 0 };
|
||||
static double x[4][2][SB16_NCoef + 1]; // input samples
|
||||
static int pos[4] = { 0, 0, 0, 0 };
|
||||
double out = 0.0;
|
||||
int n;
|
||||
|
||||
|
@@ -143,7 +143,6 @@ typedef struct sb_t {
|
||||
emu8k_t emu8k;
|
||||
void *gameport;
|
||||
|
||||
int pos;
|
||||
int pnp;
|
||||
|
||||
uint8_t pos_regs[8];
|
||||
@@ -165,6 +164,7 @@ extern uint8_t sb_ct1745_mixer_read(uint16_t addr, void *priv);
|
||||
extern void sb_ct1745_mixer_reset(sb_t *sb);
|
||||
|
||||
extern void sb_get_buffer_sbpro(int32_t *buffer, int len, void *priv);
|
||||
extern void sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv);
|
||||
extern void sbpro_filter_cd_audio(int channel, double *buffer, void *priv);
|
||||
extern void sb16_awe32_filter_cd_audio(int channel, double *buffer, void *priv);
|
||||
extern void sb_close(void *priv);
|
||||
|
@@ -97,6 +97,8 @@ typedef struct sb_dsp_t {
|
||||
int sb_irqm16;
|
||||
int sb_irqm401;
|
||||
|
||||
uint8_t sb_has_real_opl;
|
||||
|
||||
uint8_t sb_asp_regs[256];
|
||||
uint8_t sb_asp_mode;
|
||||
|
||||
@@ -158,6 +160,8 @@ extern void sb_dsp_speed_changed(sb_dsp_t *dsp);
|
||||
|
||||
extern void sb_dsp_poll(sb_dsp_t *dsp, int16_t *l, int16_t *r);
|
||||
|
||||
extern void sb_dsp_set_real_opl(sb_dsp_t *dsp, uint8_t has_real_opl);
|
||||
|
||||
extern void sb_dsp_set_stereo(sb_dsp_t *dsp, int stereo);
|
||||
|
||||
extern void sb_dsp_update(sb_dsp_t *dsp);
|
||||
|
@@ -33,6 +33,9 @@ extern int sound_gain;
|
||||
#define SOUND_FREQ FREQ_48000
|
||||
#define SOUNDBUFLEN (SOUND_FREQ / 50)
|
||||
|
||||
#define MUSIC_FREQ FREQ_49716
|
||||
#define MUSICBUFLEN (MUSIC_FREQ / 36)
|
||||
|
||||
#define CD_FREQ FREQ_44100
|
||||
#define CD_BUFLEN (CD_FREQ / 10)
|
||||
|
||||
@@ -47,12 +50,18 @@ extern int speakval;
|
||||
extern int speakon;
|
||||
|
||||
extern int sound_pos_global;
|
||||
extern int music_pos_global;
|
||||
|
||||
extern int sound_card_current[SOUND_CARD_MAX];
|
||||
|
||||
extern void sound_add_handler(void (*get_buffer)(int32_t *buffer,
|
||||
int len, void *priv),
|
||||
void *priv);
|
||||
|
||||
extern void music_add_handler(void (*get_buffer)(int32_t *buffer,
|
||||
int len, void *priv),
|
||||
void *priv);
|
||||
|
||||
extern void sound_set_cd_audio_filter(void (*filter)(int channel,
|
||||
double *buffer, void *priv),
|
||||
void *priv);
|
||||
@@ -86,6 +95,7 @@ extern void sound_cd_thread_reset(void);
|
||||
extern void closeal(void);
|
||||
extern void inital(void);
|
||||
extern void givealbuffer(void *buf);
|
||||
extern void givealbuffer_music(void *buf);
|
||||
extern void givealbuffer_cd(void *buf);
|
||||
|
||||
#define sb_vibra16c_onboard_relocate_base sb_vibra16s_onboard_relocate_base
|
||||
|
@@ -38,10 +38,11 @@
|
||||
#define FREQ SOUND_FREQ
|
||||
#define BUFLEN SOUNDBUFLEN
|
||||
|
||||
ALuint buffers[4]; /* front and back buffers */
|
||||
ALuint buffers_cd[4]; /* front and back buffers */
|
||||
ALuint buffers_midi[4]; /* front and back buffers */
|
||||
static ALuint source[3]; /* audio source */
|
||||
ALuint buffers[4]; /* front and back buffers */
|
||||
ALuint buffers_music[4]; /* front and back buffers */
|
||||
ALuint buffers_cd[4]; /* front and back buffers */
|
||||
ALuint buffers_midi[4]; /* front and back buffers */
|
||||
static ALuint source[4]; /* audio source */
|
||||
|
||||
static int midi_freq = 44100;
|
||||
static int midi_buf_size = 4410;
|
||||
@@ -99,9 +100,10 @@ closeal(void)
|
||||
alSourceStopv(sources, source);
|
||||
alDeleteSources(sources, source);
|
||||
|
||||
if (sources == 3)
|
||||
if (sources == 4)
|
||||
alDeleteBuffers(4, buffers_midi);
|
||||
alDeleteBuffers(4, buffers_cd);
|
||||
alDeleteBuffers(4, buffers_music);
|
||||
alDeleteBuffers(4, buffers);
|
||||
|
||||
alutExit();
|
||||
@@ -132,16 +134,18 @@ inital(void)
|
||||
if (strcmp(mdn, "none") && strcmp(mdn, SYSTEM_MIDI_INTERNAL_NAME))
|
||||
init_midi = 1; /* If the device is neither none, nor system MIDI, initialize the
|
||||
MIDI buffer and source, otherwise, do not. */
|
||||
sources = 2 + !!init_midi;
|
||||
sources = 3 + !!init_midi;
|
||||
|
||||
if (sound_is_float) {
|
||||
buf = (float *) calloc((BUFLEN << 1), sizeof(float));
|
||||
cd_buf = (float *) calloc((CD_BUFLEN << 1), sizeof(float));
|
||||
buf = (float *) calloc((BUFLEN << 1), sizeof(float));
|
||||
music_buf = (float *) calloc((MUSIC_BUFLEN << 1), sizeof(float));
|
||||
cd_buf = (float *) calloc((CD_BUFLEN << 1), sizeof(float));
|
||||
if (init_midi)
|
||||
midi_buf = (float *) calloc(midi_buf_size, sizeof(float));
|
||||
} else {
|
||||
buf_int16 = (int16_t *) calloc((BUFLEN << 1), sizeof(int16_t));
|
||||
cd_buf_int16 = (int16_t *) calloc((CD_BUFLEN << 1), sizeof(int16_t));
|
||||
buf_int16 = (int16_t *) calloc((BUFLEN << 1), sizeof(int16_t));
|
||||
music_buf_int16 = (int16_t *) calloc((MUSIC_BUFLEN << 1), sizeof(int16_t));
|
||||
cd_buf_int16 = (int16_t *) calloc((CD_BUFLEN << 1), sizeof(int16_t));
|
||||
if (init_midi)
|
||||
midi_buf_int16 = (int16_t *) calloc(midi_buf_size, sizeof(int16_t));
|
||||
}
|
||||
@@ -189,11 +193,13 @@ inital(void)
|
||||
for (uint8_t c = 0; c < 4; c++) {
|
||||
if (sound_is_float) {
|
||||
alBufferData(buffers[c], AL_FORMAT_STEREO_FLOAT32, buf, BUFLEN * 2 * sizeof(float), FREQ);
|
||||
alBufferData(buffers_music[c], AL_FORMAT_STEREO_FLOAT32, buf, MUSIC_BUFLEN * 2 * sizeof(float), MUSIC_FREQ);
|
||||
alBufferData(buffers_cd[c], AL_FORMAT_STEREO_FLOAT32, cd_buf, CD_BUFLEN * 2 * sizeof(float), CD_FREQ);
|
||||
if (init_midi)
|
||||
alBufferData(buffers_midi[c], AL_FORMAT_STEREO_FLOAT32, midi_buf, midi_buf_size * sizeof(float), midi_freq);
|
||||
} else {
|
||||
alBufferData(buffers[c], AL_FORMAT_STEREO16, buf_int16, BUFLEN * 2 * sizeof(int16_t), FREQ);
|
||||
alBufferData(buffers_music[c], AL_FORMAT_STEREO16, buf_int16, MUSIC_BUFLEN * 2 * sizeof(int16_t), MUSIC_FREQ);
|
||||
alBufferData(buffers_cd[c], AL_FORMAT_STEREO16, cd_buf_int16, CD_BUFLEN * 2 * sizeof(int16_t), CD_FREQ);
|
||||
if (init_midi)
|
||||
alBufferData(buffers_midi[c], AL_FORMAT_STEREO16, midi_buf_int16, midi_buf_size * sizeof(int16_t), midi_freq);
|
||||
@@ -201,23 +207,27 @@ inital(void)
|
||||
}
|
||||
|
||||
alSourceQueueBuffers(source[0], 4, buffers);
|
||||
alSourceQueueBuffers(source[1], 4, buffers_cd);
|
||||
alSourceQueueBuffers(source[1], 4, buffers_music);
|
||||
alSourceQueueBuffers(source[2], 4, buffers_cd);
|
||||
if (init_midi)
|
||||
alSourceQueueBuffers(source[2], 4, buffers_midi);
|
||||
alSourceQueueBuffers(source[3], 4, buffers_midi);
|
||||
alSourcePlay(source[0]);
|
||||
alSourcePlay(source[1]);
|
||||
alSourcePlay(source[2]);
|
||||
if (init_midi)
|
||||
alSourcePlay(source[2]);
|
||||
alSourcePlay(source[3]);
|
||||
|
||||
if (sound_is_float) {
|
||||
if (init_midi)
|
||||
free(midi_buf);
|
||||
free(cd_buf);
|
||||
free(music_buf);
|
||||
free(buf);
|
||||
} else {
|
||||
if (init_midi)
|
||||
free(midi_buf_int16);
|
||||
free(cd_buf_int16);
|
||||
free(music_buf_int16);
|
||||
free(buf_int16);
|
||||
}
|
||||
|
||||
@@ -263,14 +273,20 @@ givealbuffer(void *buf)
|
||||
givealbuffer_common(buf, 0, BUFLEN << 1, FREQ);
|
||||
}
|
||||
|
||||
void
|
||||
givealbuffer_music(void *buf)
|
||||
{
|
||||
givealbuffer_common(buf, 1, MUSIC_BUFLEN << 1, MUSIC_FREQ);
|
||||
}
|
||||
|
||||
void
|
||||
givealbuffer_cd(void *buf)
|
||||
{
|
||||
givealbuffer_common(buf, 1, CD_BUFLEN << 1, CD_FREQ);
|
||||
givealbuffer_common(buf, 2, CD_BUFLEN << 1, CD_FREQ);
|
||||
}
|
||||
|
||||
void
|
||||
givealbuffer_midi(void *buf, uint32_t size)
|
||||
{
|
||||
givealbuffer_common(buf, 2, size, midi_freq);
|
||||
givealbuffer_common(buf, 3, size, midi_freq);
|
||||
}
|
||||
|
@@ -112,7 +112,7 @@ adlib_init(UNUSED(const device_t *info))
|
||||
adlib->opl.read, NULL, NULL,
|
||||
adlib->opl.write, NULL, NULL,
|
||||
adlib->opl.priv);
|
||||
sound_add_handler(adlib_get_buffer, adlib);
|
||||
music_add_handler(adlib_get_buffer, adlib);
|
||||
return adlib;
|
||||
}
|
||||
|
||||
|
@@ -788,13 +788,10 @@ adgold_get_buffer(int32_t *buffer, int len, void *priv)
|
||||
|
||||
int c;
|
||||
|
||||
const int32_t *opl_buf = adgold->opl.update(adgold->opl.priv);
|
||||
adgold_update(adgold);
|
||||
|
||||
for (c = 0; c < len * 2; c += 2) {
|
||||
adgold_buffer[c] = ((opl_buf[c] * adgold->fm_vol_l) >> 7) / 2;
|
||||
adgold_buffer[c] += ((adgold->mma_buffer[0][c >> 1] * adgold->samp_vol_l) >> 7) / 4;
|
||||
adgold_buffer[c + 1] = ((opl_buf[c + 1] * adgold->fm_vol_r) >> 7) / 2;
|
||||
adgold_buffer[c + 1] += ((adgold->mma_buffer[1][c >> 1] * adgold->samp_vol_r) >> 7) / 4;
|
||||
}
|
||||
|
||||
@@ -857,8 +854,8 @@ adgold_get_buffer(int32_t *buffer, int len, void *priv)
|
||||
|
||||
/*Output is deliberately halved to avoid clipping*/
|
||||
temp = ((int32_t) adgold_buffer[c] * adgold->vol_l) >> 17;
|
||||
lowpass = adgold_lowpass_iir(0, temp);
|
||||
highpass = adgold_highpass_iir(0, temp);
|
||||
lowpass = adgold_lowpass_iir(0, 0, temp);
|
||||
highpass = adgold_highpass_iir(0, 0, temp);
|
||||
if (adgold->bass > 6)
|
||||
temp += (lowpass * bass_attenuation[adgold->bass]) >> 14;
|
||||
else if (adgold->bass < 6)
|
||||
@@ -874,8 +871,124 @@ adgold_get_buffer(int32_t *buffer, int len, void *priv)
|
||||
buffer[c] += temp;
|
||||
|
||||
temp = ((int32_t) adgold_buffer[c + 1] * adgold->vol_r) >> 17;
|
||||
lowpass = adgold_lowpass_iir(1, temp);
|
||||
highpass = adgold_highpass_iir(1, temp);
|
||||
lowpass = adgold_lowpass_iir(0, 1, temp);
|
||||
highpass = adgold_highpass_iir(0, 1, temp);
|
||||
if (adgold->bass > 6)
|
||||
temp += (lowpass * bass_attenuation[adgold->bass]) >> 14;
|
||||
else if (adgold->bass < 6)
|
||||
temp = highpass + ((temp * bass_cut[adgold->bass]) >> 14);
|
||||
if (adgold->treble > 6)
|
||||
temp += (highpass * treble_attenuation[adgold->treble]) >> 14;
|
||||
else if (adgold->treble < 6)
|
||||
temp = lowpass + ((temp * treble_cut[adgold->treble]) >> 14);
|
||||
if (temp < -32768)
|
||||
temp = -32768;
|
||||
if (temp > 32767)
|
||||
temp = 32767;
|
||||
buffer[c + 1] += temp;
|
||||
}
|
||||
|
||||
adgold->pos = 0;
|
||||
|
||||
free(adgold_buffer);
|
||||
}
|
||||
|
||||
static void
|
||||
adgold_get_music_buffer(int32_t *buffer, int len, void *priv)
|
||||
{
|
||||
adgold_t *adgold = (adgold_t *) priv;
|
||||
int16_t *adgold_buffer = malloc(sizeof(int16_t) * len * 2);
|
||||
if (adgold_buffer == NULL)
|
||||
fatal("adgold_buffer = NULL");
|
||||
|
||||
int c;
|
||||
|
||||
const int32_t *opl_buf = adgold->opl.update(adgold->opl.priv);
|
||||
adgold_update(adgold);
|
||||
|
||||
for (c = 0; c < len * 2; c += 2) {
|
||||
adgold_buffer[c] = ((opl_buf[c] * adgold->fm_vol_l) >> 7) / 2;
|
||||
adgold_buffer[c + 1] = ((opl_buf[c + 1] * adgold->fm_vol_r) >> 7) / 2;
|
||||
}
|
||||
|
||||
if (adgold->surround_enabled)
|
||||
ym7128_apply(&adgold->ym7128, adgold_buffer, len);
|
||||
|
||||
switch (adgold->adgold_38x_regs[0x8] & 6) {
|
||||
case 0:
|
||||
for (c = 0; c < len * 2; c++)
|
||||
adgold_buffer[c] = 0;
|
||||
break;
|
||||
case 2: /*Left channel only*/
|
||||
for (c = 0; c < len * 2; c += 2)
|
||||
adgold_buffer[c + 1] = adgold_buffer[c];
|
||||
break;
|
||||
case 4: /*Right channel only*/
|
||||
for (c = 0; c < len * 2; c += 2)
|
||||
adgold_buffer[c] = adgold_buffer[c + 1];
|
||||
break;
|
||||
case 6: /*Left and right channels*/
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (adgold->adgold_38x_regs[0x8] & 0x18) {
|
||||
case 0x00: /*Forced mono*/
|
||||
for (c = 0; c < len * 2; c += 2)
|
||||
adgold_buffer[c] = adgold_buffer[c + 1] = ((int32_t) adgold_buffer[c] + (int32_t) adgold_buffer[c + 1]) / 2;
|
||||
break;
|
||||
case 0x08: /*Linear stereo*/
|
||||
break;
|
||||
case 0x10: /*Pseudo stereo*/
|
||||
/*Filter left channel, leave right channel unchanged*/
|
||||
/*Filter cutoff is largely a guess*/
|
||||
for (c = 0; c < len * 2; c += 2)
|
||||
adgold_buffer[c] += adgold_pseudo_stereo_iir(adgold_buffer[c]);
|
||||
break;
|
||||
case 0x18: /*Spatial stereo*/
|
||||
/*Quite probably wrong, I only have the diagram in the TDA8425 datasheet
|
||||
and a very vague understanding of how op-amps work to go on*/
|
||||
for (c = 0; c < len * 2; c += 2) {
|
||||
int16_t l = adgold_buffer[c];
|
||||
int16_t r = adgold_buffer[c + 1];
|
||||
|
||||
adgold_buffer[c] += (r / 3) + ((l * 2) / 3);
|
||||
adgold_buffer[c + 1] += (l / 3) + ((r * 2) / 3);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
for (c = 0; c < len * 2; c += 2) {
|
||||
int32_t temp;
|
||||
int32_t lowpass;
|
||||
int32_t highpass;
|
||||
|
||||
/*Output is deliberately halved to avoid clipping*/
|
||||
temp = ((int32_t) adgold_buffer[c] * adgold->vol_l) >> 17;
|
||||
lowpass = adgold_lowpass_iir(1, 0, temp);
|
||||
highpass = adgold_highpass_iir(1, 0, temp);
|
||||
if (adgold->bass > 6)
|
||||
temp += (lowpass * bass_attenuation[adgold->bass]) >> 14;
|
||||
else if (adgold->bass < 6)
|
||||
temp = highpass + ((temp * bass_cut[adgold->bass]) >> 14);
|
||||
if (adgold->treble > 6)
|
||||
temp += (highpass * treble_attenuation[adgold->treble]) >> 14;
|
||||
else if (adgold->treble < 6)
|
||||
temp = lowpass + ((temp * treble_cut[adgold->treble]) >> 14);
|
||||
if (temp < -32768)
|
||||
temp = -32768;
|
||||
if (temp > 32767)
|
||||
temp = 32767;
|
||||
buffer[c] += temp;
|
||||
|
||||
temp = ((int32_t) adgold_buffer[c + 1] * adgold->vol_r) >> 17;
|
||||
lowpass = adgold_lowpass_iir(1, 1, temp);
|
||||
highpass = adgold_highpass_iir(1, 1, temp);
|
||||
if (adgold->bass > 6)
|
||||
temp += (lowpass * bass_attenuation[adgold->bass]) >> 14;
|
||||
else if (adgold->bass < 6)
|
||||
@@ -892,7 +1005,6 @@ adgold_get_buffer(int32_t *buffer, int len, void *priv)
|
||||
}
|
||||
|
||||
adgold->opl.reset_buffer(adgold->opl.priv);
|
||||
adgold->pos = 0;
|
||||
|
||||
free(adgold_buffer);
|
||||
}
|
||||
@@ -1054,6 +1166,8 @@ adgold_init(UNUSED(const device_t *info))
|
||||
timer_add(&adgold->adgold_mma_timer_count, adgold_timer_poll, adgold, 1);
|
||||
|
||||
sound_add_handler(adgold_get_buffer, adgold);
|
||||
music_add_handler(adgold_get_music_buffer, adgold);
|
||||
|
||||
sound_set_cd_audio_filter(adgold_filter_cd_audio, adgold);
|
||||
|
||||
if (device_get_config_int("receive_input"))
|
||||
|
@@ -1237,6 +1237,7 @@ azt_init(const device_t *info)
|
||||
if (azt2316a->sb->opl_enabled)
|
||||
fm_driver_get(FM_YMF262, &azt2316a->sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&azt2316a->sb->dsp, 1);
|
||||
sb_dsp_init(&azt2316a->sb->dsp, SBPRO2, azt2316a->type, azt2316a);
|
||||
sb_dsp_setaddr(&azt2316a->sb->dsp, azt2316a->cur_addr);
|
||||
sb_dsp_setirq(&azt2316a->sb->dsp, azt2316a->cur_irq);
|
||||
@@ -1253,6 +1254,8 @@ azt_init(const device_t *info)
|
||||
|
||||
azt2316a_create_config_word(azt2316a);
|
||||
sound_add_handler(azt2316a_get_buffer, azt2316a);
|
||||
if (azt2316a->sb->opl_enabled)
|
||||
music_add_handler(sb_get_music_buffer_sbpro, azt2316a->sb);
|
||||
sound_set_cd_audio_filter(sbpro_filter_cd_audio, azt2316a->sb);
|
||||
|
||||
if (azt2316a->cur_mpu401_enabled) {
|
||||
|
@@ -543,13 +543,31 @@ cs423x_ctxswitch_write(uint16_t addr, UNUSED(uint8_t val), void *priv)
|
||||
|
||||
static void
|
||||
cs423x_get_buffer(int32_t *buffer, int len, void *priv)
|
||||
{
|
||||
cs423x_t *dev = (cs423x_t *) priv;
|
||||
|
||||
/* Output audio from the WSS codec, and also the OPL if we're in charge of it. */
|
||||
ad1848_update(&dev->ad1848);
|
||||
|
||||
/* Don't output anything if the analog section is powered down. */
|
||||
if (!(dev->indirect_regs[2] & 0xa4)) {
|
||||
for (int c = 0; c < len * 2; c += 2) {
|
||||
buffer[c] += dev->ad1848.buffer[c] / 2;
|
||||
buffer[c + 1] += dev->ad1848.buffer[c + 1] / 2;
|
||||
}
|
||||
}
|
||||
|
||||
dev->ad1848.pos = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
cs423x_get_music_buffer(int32_t *buffer, int len, void *priv)
|
||||
{
|
||||
cs423x_t *dev = (cs423x_t *) priv;
|
||||
int opl_wss = dev->opl_wss;
|
||||
const int32_t *opl_buf = NULL;
|
||||
|
||||
/* Output audio from the WSS codec, and also the OPL if we're in charge of it. */
|
||||
ad1848_update(&dev->ad1848);
|
||||
if (opl_wss)
|
||||
opl_buf = dev->sb->opl.update(dev->sb->opl.priv);
|
||||
|
||||
@@ -560,13 +578,9 @@ cs423x_get_buffer(int32_t *buffer, int len, void *priv)
|
||||
buffer[c] += (opl_buf[c] * dev->ad1848.fm_vol_l) >> 16;
|
||||
buffer[c + 1] += (opl_buf[c + 1] * dev->ad1848.fm_vol_r) >> 16;
|
||||
}
|
||||
|
||||
buffer[c] += dev->ad1848.buffer[c] / 2;
|
||||
buffer[c + 1] += dev->ad1848.buffer[c + 1] / 2;
|
||||
}
|
||||
}
|
||||
|
||||
dev->ad1848.pos = 0;
|
||||
if (opl_wss)
|
||||
dev->sb->opl.reset_buffer(dev->sb->opl.priv);
|
||||
}
|
||||
@@ -846,6 +860,7 @@ cs423x_init(const device_t *info)
|
||||
/* Initialize RAM, registers and WSS codec. */
|
||||
cs423x_reset(dev);
|
||||
sound_add_handler(cs423x_get_buffer, dev);
|
||||
music_add_handler(cs423x_get_music_buffer, dev);
|
||||
|
||||
/* Add Control/RAM backdoor handlers for CS4235. */
|
||||
dev->ad1848.cram_priv = dev;
|
||||
|
@@ -55,7 +55,8 @@
|
||||
#define WRBUF_DELAY 1
|
||||
#define RSM_FRAC 10
|
||||
|
||||
#define OPL_FREQ FREQ_48000
|
||||
// #define OPL_FREQ FREQ_48000
|
||||
#define OPL_FREQ FREQ_49716
|
||||
|
||||
// Channel types
|
||||
enum {
|
||||
@@ -189,7 +190,7 @@ typedef struct {
|
||||
pc_timer_t timers[2];
|
||||
|
||||
int pos;
|
||||
int32_t buffer[SOUNDBUFLEN * 2];
|
||||
int32_t buffer[MUSICBUFLEN * 2];
|
||||
} nuked_drv_t;
|
||||
|
||||
enum {
|
||||
@@ -1381,11 +1382,20 @@ nuked_generate_resampled(nuked_t *dev, int32_t *bufp)
|
||||
dev->samplecnt += 1 << RSM_FRAC;
|
||||
}
|
||||
|
||||
void
|
||||
nuked_generate_raw(nuked_t *dev, int32_t *bufp)
|
||||
{
|
||||
nuked_generate(dev, dev->samples);
|
||||
|
||||
bufp[0] = (int32_t) dev->samples[0];
|
||||
bufp[1] = (int32_t) dev->samples[1];
|
||||
}
|
||||
|
||||
void
|
||||
nuked_generate_stream(nuked_t *dev, int32_t *sndptr, uint32_t num)
|
||||
{
|
||||
for (uint32_t i = 0; i < num; i++) {
|
||||
nuked_generate_resampled(dev, sndptr);
|
||||
nuked_generate_raw(dev, sndptr);
|
||||
sndptr += 2;
|
||||
}
|
||||
}
|
||||
@@ -1533,14 +1543,14 @@ nuked_drv_update(void *priv)
|
||||
{
|
||||
nuked_drv_t *dev = (nuked_drv_t *) priv;
|
||||
|
||||
if (dev->pos >= sound_pos_global)
|
||||
if (dev->pos >= music_pos_global)
|
||||
return dev->buffer;
|
||||
|
||||
nuked_generate_stream(&dev->opl,
|
||||
&dev->buffer[dev->pos * 2],
|
||||
sound_pos_global - dev->pos);
|
||||
music_pos_global - dev->pos);
|
||||
|
||||
for (; dev->pos < sound_pos_global; dev->pos++) {
|
||||
for (; dev->pos < music_pos_global; dev->pos++) {
|
||||
dev->buffer[dev->pos * 2] /= 2;
|
||||
dev->buffer[(dev->pos * 2) + 1] /= 2;
|
||||
}
|
||||
|
@@ -51,10 +51,11 @@ enum {
|
||||
|
||||
class YMFMChipBase {
|
||||
public:
|
||||
YMFMChipBase(UNUSED(uint32_t clock), fm_type type, UNUSED(uint32_t samplerate))
|
||||
YMFMChipBase(UNUSED(uint32_t clock), fm_type type, uint32_t samplerate)
|
||||
: m_buf_pos(0)
|
||||
, m_flags(0)
|
||||
, m_type(type)
|
||||
, m_samplerate(samplerate)
|
||||
{
|
||||
memset(m_buffer, 0, sizeof(m_buffer));
|
||||
}
|
||||
@@ -79,10 +80,11 @@ public:
|
||||
virtual void set_clock(uint32_t clock) = 0;
|
||||
|
||||
protected:
|
||||
int32_t m_buffer[SOUNDBUFLEN * 2];
|
||||
int m_buf_pos;
|
||||
int8_t m_flags;
|
||||
fm_type m_type;
|
||||
int32_t m_buffer[MUSICBUFLEN * 2];
|
||||
int m_buf_pos;
|
||||
int8_t m_flags;
|
||||
fm_type m_type;
|
||||
uint32_t m_samplerate;
|
||||
};
|
||||
|
||||
template <typename ChipType>
|
||||
@@ -170,6 +172,11 @@ public:
|
||||
|
||||
virtual void generate_resampled(int32_t *data, uint32_t num_samples) override
|
||||
{
|
||||
if (m_samplerate == FREQ_49716) {
|
||||
generate(data, num_samples);
|
||||
return;
|
||||
}
|
||||
|
||||
for (uint32_t i = 0; i < num_samples; i++) {
|
||||
while (m_samplecnt >= m_rateratio) {
|
||||
m_oldsamples[0] = m_samples[0];
|
||||
@@ -206,14 +213,26 @@ public:
|
||||
|
||||
virtual int32_t *update() override
|
||||
{
|
||||
if (m_buf_pos >= sound_pos_global)
|
||||
return m_buffer;
|
||||
if (m_samplerate == FREQ_49716) {
|
||||
if (m_buf_pos >= music_pos_global)
|
||||
return m_buffer;
|
||||
|
||||
generate_resampled(&m_buffer[m_buf_pos * 2], sound_pos_global - m_buf_pos);
|
||||
generate(&m_buffer[m_buf_pos * 2], music_pos_global - m_buf_pos);
|
||||
|
||||
for (; m_buf_pos < sound_pos_global; m_buf_pos++) {
|
||||
m_buffer[m_buf_pos * 2] /= 2;
|
||||
m_buffer[(m_buf_pos * 2) + 1] /= 2;
|
||||
for (; m_buf_pos < music_pos_global; m_buf_pos++) {
|
||||
m_buffer[m_buf_pos * 2] /= 2;
|
||||
m_buffer[(m_buf_pos * 2) + 1] /= 2;
|
||||
}
|
||||
} else {
|
||||
if (m_buf_pos >= sound_pos_global)
|
||||
return m_buffer;
|
||||
|
||||
generate_resampled(&m_buffer[m_buf_pos * 2], sound_pos_global - m_buf_pos);
|
||||
|
||||
for (; m_buf_pos < sound_pos_global; m_buf_pos++) {
|
||||
m_buffer[m_buf_pos * 2] /= 2;
|
||||
m_buffer[(m_buf_pos * 2) + 1] /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
return m_buffer;
|
||||
@@ -314,11 +333,11 @@ ymfm_drv_init(const device_t *info)
|
||||
switch (info->local) {
|
||||
default:
|
||||
case FM_YM3812:
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym3812>(3579545, FM_YM3812, OPL_FREQ);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ym3812>(3579545, FM_YM3812, FREQ_49716);
|
||||
break;
|
||||
|
||||
case FM_YMF262:
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ymf262>(14318181, FM_YMF262, OPL_FREQ);
|
||||
fm = (YMFMChipBase *) new YMFMChip<ymfm::ymf262>(14318181, FM_YMF262, FREQ_49716);
|
||||
break;
|
||||
|
||||
case FM_YMF289B:
|
||||
|
@@ -391,6 +391,9 @@ optimc_init(const device_t *info)
|
||||
optimc->sb = calloc(1, sizeof(sb_t));
|
||||
optimc->sb->opl_enabled = 1;
|
||||
|
||||
optimc->fm_type = (info->local & OPTIMC_OPL4) ? FM_YMF278B : FM_YMF262;
|
||||
|
||||
sb_dsp_set_real_opl(&optimc->sb->dsp, optimc->fm_type != FM_YMF278B);
|
||||
sb_dsp_init(&optimc->sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, optimc);
|
||||
sb_dsp_setaddr(&optimc->sb->dsp, optimc->cur_addr);
|
||||
sb_dsp_setirq(&optimc->sb->dsp, optimc->cur_irq);
|
||||
@@ -400,7 +403,6 @@ optimc_init(const device_t *info)
|
||||
optimc->sb->opl_mixer = optimc;
|
||||
optimc->sb->opl_mix = optimc_filter_opl;
|
||||
|
||||
optimc->fm_type = (info->local & OPTIMC_OPL4) ? FM_YMF278B : FM_YMF262;
|
||||
fm_driver_get(optimc->fm_type, &optimc->sb->opl);
|
||||
io_sethandler(optimc->cur_addr + 0, 0x0004, optimc->sb->opl.read, NULL, NULL, optimc->sb->opl.write, NULL, NULL, optimc->sb->opl.priv);
|
||||
io_sethandler(optimc->cur_addr + 8, 0x0002, optimc->sb->opl.read, NULL, NULL, optimc->sb->opl.write, NULL, NULL, optimc->sb->opl.priv);
|
||||
@@ -411,6 +413,10 @@ optimc_init(const device_t *info)
|
||||
io_sethandler(optimc->cur_addr + 4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, optimc->sb);
|
||||
|
||||
sound_add_handler(optimc_get_buffer, optimc);
|
||||
if (optimc->fm_type == FM_YMF278B)
|
||||
sound_add_handler(sb_get_music_buffer_sbpro, optimc->sb);
|
||||
else
|
||||
music_add_handler(sb_get_music_buffer_sbpro, optimc->sb);
|
||||
sound_set_cd_audio_filter(sbpro_filter_cd_audio, optimc->sb); /* CD audio filter for the default context */
|
||||
|
||||
optimc->mpu = (mpu_t *) malloc(sizeof(mpu_t));
|
||||
|
@@ -728,20 +728,29 @@ pas16_get_buffer(int32_t *buffer, int len, void *priv)
|
||||
{
|
||||
pas16_t *pas16 = (pas16_t *) priv;
|
||||
|
||||
const int32_t *opl_buf = pas16->opl.update(pas16->opl.priv);
|
||||
sb_dsp_update(&pas16->dsp);
|
||||
pas16_update(pas16);
|
||||
for (int c = 0; c < len * 2; c++) {
|
||||
buffer[c] += opl_buf[c];
|
||||
buffer[c] += (int16_t) (sb_iir(0, c & 1, (double) pas16->dsp.buffer[c]) / 1.3) / 2;
|
||||
buffer[c] += (pas16->pcm_buffer[c & 1][c >> 1] / 2);
|
||||
}
|
||||
|
||||
pas16->pos = 0;
|
||||
pas16->opl.reset_buffer(pas16->opl.priv);
|
||||
pas16->dsp.pos = 0;
|
||||
}
|
||||
|
||||
void
|
||||
pas16_get_music_buffer(int32_t *buffer, int len, void *priv)
|
||||
{
|
||||
pas16_t *pas16 = (pas16_t *) priv;
|
||||
|
||||
const int32_t *opl_buf = pas16->opl.update(pas16->opl.priv);
|
||||
for (int c = 0; c < len * 2; c++)
|
||||
buffer[c] += opl_buf[c];
|
||||
|
||||
pas16->opl.reset_buffer(pas16->opl.priv);
|
||||
}
|
||||
|
||||
static void *
|
||||
pas16_init(UNUSED(const device_t *info))
|
||||
{
|
||||
@@ -756,6 +765,7 @@ pas16_init(UNUSED(const device_t *info))
|
||||
timer_add(&pas16->pit.timer[0], pas16_pcm_poll, pas16, 0);
|
||||
|
||||
sound_add_handler(pas16_get_buffer, pas16);
|
||||
music_add_handler(pas16_get_music_buffer, pas16);
|
||||
|
||||
return pas16;
|
||||
}
|
||||
|
@@ -185,10 +185,6 @@ sb_get_buffer_sb2(int32_t *buffer, int len, void *priv)
|
||||
double out_mono = 0.0;
|
||||
double out_l = 0.0;
|
||||
double out_r = 0.0;
|
||||
const int32_t *opl_buf = NULL;
|
||||
|
||||
if (sb->opl_enabled)
|
||||
opl_buf = sb->opl.update(sb->opl.priv);
|
||||
|
||||
sb_dsp_update(&sb->dsp);
|
||||
|
||||
@@ -200,17 +196,12 @@ sb_get_buffer_sb2(int32_t *buffer, int len, void *priv)
|
||||
out_l = 0.0;
|
||||
out_r = 0.0;
|
||||
|
||||
if (sb->opl_enabled)
|
||||
out_mono = ((double) opl_buf[c]) * 0.7171630859375;
|
||||
|
||||
if (sb->cms_enabled) {
|
||||
out_l += sb->cms.buffer[c];
|
||||
out_r += sb->cms.buffer[c + 1];
|
||||
}
|
||||
out_l += out_mono;
|
||||
out_r += out_mono;
|
||||
|
||||
if (((sb->opl_enabled) || (sb->cms_enabled)) && sb->mixer_enabled) {
|
||||
if (sb->cms_enabled && sb->mixer_enabled) {
|
||||
out_l *= mixer->fm;
|
||||
out_r *= mixer->fm;
|
||||
}
|
||||
@@ -234,17 +225,55 @@ sb_get_buffer_sb2(int32_t *buffer, int len, void *priv)
|
||||
buffer[c + 1] += (int32_t) out_r;
|
||||
}
|
||||
|
||||
sb->pos = 0;
|
||||
|
||||
if (sb->opl_enabled)
|
||||
sb->opl.reset_buffer(sb->opl.priv);
|
||||
|
||||
sb->dsp.pos = 0;
|
||||
|
||||
if (sb->cms_enabled)
|
||||
sb->cms.pos = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
sb_get_music_buffer_sb2(int32_t *buffer, int len, void *priv)
|
||||
{
|
||||
sb_t *sb = (sb_t *) priv;
|
||||
const sb_ct1335_mixer_t *mixer = &sb->mixer_sb2;
|
||||
double out_mono = 0.0;
|
||||
double out_l = 0.0;
|
||||
double out_r = 0.0;
|
||||
const int32_t *opl_buf = NULL;
|
||||
|
||||
if (!sb->opl_enabled)
|
||||
return;
|
||||
|
||||
opl_buf = sb->opl.update(sb->opl.priv);
|
||||
|
||||
for (int c = 0; c < len * 2; c += 2) {
|
||||
out_mono = 0.0;
|
||||
out_l = 0.0;
|
||||
out_r = 0.0;
|
||||
|
||||
if (sb->opl_enabled)
|
||||
out_mono = ((double) opl_buf[c]) * 0.7171630859375;
|
||||
|
||||
out_l += out_mono;
|
||||
out_r += out_mono;
|
||||
|
||||
if (sb->mixer_enabled) {
|
||||
out_l *= mixer->fm;
|
||||
out_r *= mixer->fm;
|
||||
}
|
||||
|
||||
if (sb->mixer_enabled) {
|
||||
out_l *= mixer->master;
|
||||
out_r *= mixer->master;
|
||||
}
|
||||
|
||||
buffer[c] += (int32_t) out_l;
|
||||
buffer[c + 1] += (int32_t) out_r;
|
||||
}
|
||||
|
||||
sb->opl.reset_buffer(sb->opl.priv);
|
||||
}
|
||||
|
||||
static void
|
||||
sb2_filter_cd_audio(UNUSED(int channel), double *buffer, void *priv)
|
||||
{
|
||||
@@ -253,10 +282,10 @@ sb2_filter_cd_audio(UNUSED(int channel), double *buffer, void *priv)
|
||||
double c;
|
||||
|
||||
if (sb->mixer_enabled) {
|
||||
c = ((sb_iir(1, 0, *buffer) / 1.3) * mixer->cd) / 3.0;
|
||||
c = ((sb_iir(2, 0, *buffer) / 1.3) * mixer->cd) / 3.0;
|
||||
*buffer = c * mixer->master;
|
||||
} else {
|
||||
c = (((sb_iir(1, 0, (*buffer)) / 1.3) * 65536) / 3.0) / 65536.0;
|
||||
c = (((sb_iir(2, 0, (*buffer)) / 1.3) * 65536) / 3.0) / 65536.0;
|
||||
*buffer = c;
|
||||
}
|
||||
}
|
||||
@@ -268,16 +297,6 @@ sb_get_buffer_sbpro(int32_t *buffer, int len, void *priv)
|
||||
const sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro;
|
||||
double out_l = 0.0;
|
||||
double out_r = 0.0;
|
||||
const int32_t *opl_buf = NULL;
|
||||
const int32_t *opl2_buf = NULL;
|
||||
|
||||
if (sb->opl_enabled) {
|
||||
if (sb->dsp.sb_type == SBPRO) {
|
||||
opl_buf = sb->opl.update(sb->opl.priv);
|
||||
opl2_buf = sb->opl2.update(sb->opl2.priv);
|
||||
} else
|
||||
opl_buf = sb->opl.update(sb->opl.priv);
|
||||
}
|
||||
|
||||
sb_dsp_update(&sb->dsp);
|
||||
|
||||
@@ -285,21 +304,6 @@ sb_get_buffer_sbpro(int32_t *buffer, int len, void *priv)
|
||||
out_l = 0.0;
|
||||
out_r = 0.0;
|
||||
|
||||
if (sb->opl_enabled) {
|
||||
if (sb->dsp.sb_type == SBPRO) {
|
||||
/* Two chips for LEFT and RIGHT channels.
|
||||
Each chip stores data into the LEFT channel only (no sample alternating.) */
|
||||
out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375;
|
||||
out_r = (((double) opl2_buf[c]) * mixer->fm_r) * 0.7171630859375;
|
||||
} else {
|
||||
out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375;
|
||||
out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375;
|
||||
if (sb->opl_mix && sb->opl_mixer) {
|
||||
sb->opl_mix(sb->opl_mixer, &out_l, &out_r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* TODO: Implement the stereo switch on the mixer instead of on the dsp? */
|
||||
if (mixer->output_filter) {
|
||||
out_l += (sb_iir(0, 0, (double) sb->dsp.buffer[c]) * mixer->voice_l) / 3.9;
|
||||
@@ -317,15 +321,57 @@ sb_get_buffer_sbpro(int32_t *buffer, int len, void *priv)
|
||||
buffer[c + 1] += (int32_t) out_r;
|
||||
}
|
||||
|
||||
sb->pos = 0;
|
||||
sb->dsp.pos = 0;
|
||||
}
|
||||
|
||||
if (sb->opl_enabled) {
|
||||
sb->opl.reset_buffer(sb->opl.priv);
|
||||
if (sb->dsp.sb_type == SBPRO)
|
||||
sb->opl2.reset_buffer(sb->opl2.priv);
|
||||
void
|
||||
sb_get_music_buffer_sbpro(int32_t *buffer, int len, void *priv)
|
||||
{
|
||||
sb_t *sb = (sb_t *) priv;
|
||||
const sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro;
|
||||
double out_l = 0.0;
|
||||
double out_r = 0.0;
|
||||
const int32_t *opl_buf = NULL;
|
||||
const int32_t *opl2_buf = NULL;
|
||||
|
||||
if (!sb->opl_enabled)
|
||||
return;
|
||||
|
||||
if (sb->dsp.sb_type == SBPRO) {
|
||||
opl_buf = sb->opl.update(sb->opl.priv);
|
||||
opl2_buf = sb->opl2.update(sb->opl2.priv);
|
||||
} else
|
||||
opl_buf = sb->opl.update(sb->opl.priv);
|
||||
|
||||
sb_dsp_update(&sb->dsp);
|
||||
|
||||
for (int c = 0; c < len * 2; c += 2) {
|
||||
out_l = 0.0;
|
||||
out_r = 0.0;
|
||||
|
||||
if (sb->dsp.sb_type == SBPRO) {
|
||||
/* Two chips for LEFT and RIGHT channels.
|
||||
Each chip stores data into the LEFT channel only (no sample alternating.) */
|
||||
out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375;
|
||||
out_r = (((double) opl2_buf[c]) * mixer->fm_r) * 0.7171630859375;
|
||||
} else {
|
||||
out_l = (((double) opl_buf[c]) * mixer->fm_l) * 0.7171630859375;
|
||||
out_r = (((double) opl_buf[c + 1]) * mixer->fm_r) * 0.7171630859375;
|
||||
if (sb->opl_mix && sb->opl_mixer)
|
||||
sb->opl_mix(sb->opl_mixer, &out_l, &out_r);
|
||||
}
|
||||
|
||||
/* TODO: recording CD, Mic with AGC or line in. Note: mic volume does not affect recording. */
|
||||
out_l *= mixer->master_l;
|
||||
out_r *= mixer->master_r;
|
||||
|
||||
buffer[c] += (int32_t) out_l;
|
||||
buffer[c + 1] += (int32_t) out_r;
|
||||
}
|
||||
|
||||
sb->dsp.pos = 0;
|
||||
sb->opl.reset_buffer(sb->opl.priv);
|
||||
if (sb->dsp.sb_type == SBPRO)
|
||||
sb->opl2.reset_buffer(sb->opl2.priv);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -338,7 +384,7 @@ sbpro_filter_cd_audio(int channel, double *buffer, void *priv)
|
||||
double master = channel ? mixer->master_r : mixer->master_l;
|
||||
|
||||
if (mixer->output_filter)
|
||||
c = (sb_iir(1, channel, *buffer) * cd) / 3.9;
|
||||
c = (sb_iir(2, channel, *buffer) * cd) / 3.9;
|
||||
else
|
||||
c = (*buffer * cd) / 3.0;
|
||||
*buffer = c * master;
|
||||
@@ -349,21 +395,9 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv)
|
||||
{
|
||||
sb_t *sb = (sb_t *) priv;
|
||||
const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16;
|
||||
int dsp_rec_pos = sb->dsp.record_pos_write;
|
||||
int c_emu8k = 0;
|
||||
int c_record;
|
||||
int32_t in_l;
|
||||
int32_t in_r;
|
||||
double out_l = 0.0;
|
||||
double out_r = 0.0;
|
||||
double bass_treble;
|
||||
const int32_t *opl_buf = NULL;
|
||||
|
||||
if (sb->opl_enabled)
|
||||
opl_buf = sb->opl.update(sb->opl.priv);
|
||||
|
||||
if (sb->dsp.sb_type > SB16)
|
||||
emu8k_update(&sb->emu8k);
|
||||
|
||||
sb_dsp_update(&sb->dsp);
|
||||
|
||||
@@ -371,25 +405,6 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv)
|
||||
out_l = 0.0;
|
||||
out_r = 0.0;
|
||||
|
||||
if (sb->dsp.sb_type > SB16)
|
||||
c_emu8k = ((((c / 2) * FREQ_44100) / SOUND_FREQ) * 2);
|
||||
|
||||
if (sb->opl_enabled) {
|
||||
out_l = ((double) opl_buf[c]) * mixer->fm_l * 0.7171630859375;
|
||||
out_r = ((double) opl_buf[c + 1]) * mixer->fm_r * 0.7171630859375;
|
||||
}
|
||||
|
||||
if (sb->dsp.sb_type > SB16) {
|
||||
out_l += (((double) sb->emu8k.buffer[c_emu8k]) * mixer->fm_l);
|
||||
out_r += (((double) sb->emu8k.buffer[c_emu8k + 1]) * mixer->fm_r);
|
||||
}
|
||||
|
||||
/* TODO: Multi-recording mic with agc/+20db, CD, and line in with channel inversion */
|
||||
in_l = (mixer->input_selector_left & INPUT_MIDI_L) ? ((int32_t) out_l) : 0 + (mixer->input_selector_left & INPUT_MIDI_R) ? ((int32_t) out_r)
|
||||
: 0;
|
||||
in_r = (mixer->input_selector_right & INPUT_MIDI_L) ? ((int32_t) out_l) : 0 + (mixer->input_selector_right & INPUT_MIDI_R) ? ((int32_t) out_r)
|
||||
: 0;
|
||||
|
||||
if (mixer->output_filter) {
|
||||
/* We divide by 3 to get the volume down to normal. */
|
||||
out_l += (low_fir_sb16(0, 0, (double) sb->dsp.buffer[c]) * mixer->voice_l) / 3.0;
|
||||
@@ -440,8 +455,100 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv)
|
||||
out_r = (out_l *bass_treble + high_cut_iir(0, 1, out_r) * (1.0 - bass_treble));
|
||||
}
|
||||
|
||||
buffer[c] += (int32_t) (out_l * mixer->output_gain_L);
|
||||
buffer[c + 1] += (int32_t) (out_r * mixer->output_gain_R);
|
||||
}
|
||||
|
||||
sb->dsp.pos = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
sb_get_music_buffer_sb16_awe32(int32_t *buffer, int len, void *priv)
|
||||
{
|
||||
sb_t *sb = (sb_t *) priv;
|
||||
const sb_ct1745_mixer_t *mixer = &sb->mixer_sb16;
|
||||
int dsp_rec_pos = sb->dsp.record_pos_write;
|
||||
int c_emu8k = 0;
|
||||
int c_record;
|
||||
int32_t in_l;
|
||||
int32_t in_r;
|
||||
double out_l = 0.0;
|
||||
double out_r = 0.0;
|
||||
double bass_treble;
|
||||
const int32_t *opl_buf = NULL;
|
||||
|
||||
if (sb->opl_enabled)
|
||||
opl_buf = sb->opl.update(sb->opl.priv);
|
||||
|
||||
if (sb->dsp.sb_type > SB16)
|
||||
emu8k_update(&sb->emu8k);
|
||||
|
||||
for (int c = 0; c < len * 2; c += 2) {
|
||||
out_l = 0.0;
|
||||
out_r = 0.0;
|
||||
|
||||
if (sb->dsp.sb_type > SB16)
|
||||
c_emu8k = ((((c / 2) * FREQ_44100) / MUSIC_FREQ) * 2);
|
||||
|
||||
if (sb->opl_enabled) {
|
||||
out_l = ((double) opl_buf[c]) * mixer->fm_l * 0.7171630859375;
|
||||
out_r = ((double) opl_buf[c + 1]) * mixer->fm_r * 0.7171630859375;
|
||||
}
|
||||
|
||||
if (sb->dsp.sb_type > SB16) {
|
||||
out_l += (((double) sb->emu8k.buffer[c_emu8k]) * mixer->fm_l);
|
||||
out_r += (((double) sb->emu8k.buffer[c_emu8k + 1]) * mixer->fm_r);
|
||||
}
|
||||
|
||||
/* TODO: Multi-recording mic with agc/+20db, CD, and line in with channel inversion */
|
||||
in_l = (mixer->input_selector_left & INPUT_MIDI_L) ? ((int32_t) out_l) : 0 + (mixer->input_selector_left & INPUT_MIDI_R) ? ((int32_t) out_r)
|
||||
: 0;
|
||||
in_r = (mixer->input_selector_right & INPUT_MIDI_L) ? ((int32_t) out_l) : 0 + (mixer->input_selector_right & INPUT_MIDI_R) ? ((int32_t) out_r)
|
||||
: 0;
|
||||
|
||||
out_l *= mixer->master_l;
|
||||
out_r *= mixer->master_r;
|
||||
|
||||
/* This is not exactly how one does bass/treble controls, but the end result is like it.
|
||||
A better implementation would reduce the CPU usage. */
|
||||
if (mixer->bass_l != 8) {
|
||||
bass_treble = sb_bass_treble_4bits[mixer->bass_l];
|
||||
|
||||
if (mixer->bass_l > 8)
|
||||
out_l += (low_iir(1, 0, out_l) * bass_treble);
|
||||
else if (mixer->bass_l < 8)
|
||||
out_l = (out_l *bass_treble + low_cut_iir(1, 0, out_l) * (1.0 - bass_treble));
|
||||
}
|
||||
|
||||
if (mixer->bass_r != 8) {
|
||||
bass_treble = sb_bass_treble_4bits[mixer->bass_r];
|
||||
|
||||
if (mixer->bass_r > 8)
|
||||
out_r += (low_iir(1, 1, out_r) * bass_treble);
|
||||
else if (mixer->bass_r < 8)
|
||||
out_r = (out_r *bass_treble + low_cut_iir(1, 1, out_r) * (1.0 - bass_treble));
|
||||
}
|
||||
|
||||
if (mixer->treble_l != 8) {
|
||||
bass_treble = sb_bass_treble_4bits[mixer->treble_l];
|
||||
|
||||
if (mixer->treble_l > 8)
|
||||
out_l += (high_iir(1, 0, out_l) * bass_treble);
|
||||
else if (mixer->treble_l < 8)
|
||||
out_l = (out_l *bass_treble + high_cut_iir(1, 0, out_l) * (1.0 - bass_treble));
|
||||
}
|
||||
|
||||
if (mixer->treble_r != 8) {
|
||||
bass_treble = sb_bass_treble_4bits[mixer->treble_r];
|
||||
|
||||
if (mixer->treble_r > 8)
|
||||
out_r += (high_iir(1, 1, out_r) * bass_treble);
|
||||
else if (mixer->treble_r < 8)
|
||||
out_r = (out_l *bass_treble + high_cut_iir(1, 1, out_r) * (1.0 - bass_treble));
|
||||
}
|
||||
|
||||
if (sb->dsp.sb_enable_i) {
|
||||
c_record = dsp_rec_pos + ((c * sb->dsp.sb_freq) / SOUND_FREQ);
|
||||
c_record = dsp_rec_pos + ((c * sb->dsp.sb_freq) / MUSIC_FREQ);
|
||||
in_l <<= mixer->input_gain_L;
|
||||
in_r <<= mixer->input_gain_R;
|
||||
|
||||
@@ -467,13 +574,9 @@ sb_get_buffer_sb16_awe32(int32_t *buffer, int len, void *priv)
|
||||
sb->dsp.record_pos_write += ((len * sb->dsp.sb_freq) / 24000);
|
||||
sb->dsp.record_pos_write &= 0xffff;
|
||||
|
||||
sb->pos = 0;
|
||||
|
||||
if (sb->opl_enabled)
|
||||
sb->opl.reset_buffer(sb->opl.priv);
|
||||
|
||||
sb->dsp.pos = 0;
|
||||
|
||||
if (sb->dsp.sb_type > SB16)
|
||||
sb->emu8k.pos = 0;
|
||||
}
|
||||
@@ -492,7 +595,7 @@ sb16_awe32_filter_cd_audio(int channel, double *buffer, void *priv)
|
||||
double output_gain = (channel ? mixer->output_gain_R : mixer->output_gain_L);
|
||||
|
||||
if (mixer->output_filter)
|
||||
c = (low_fir_sb16(1, channel, *buffer) * cd) / 3.0;
|
||||
c = (low_fir_sb16(2, channel, *buffer) * cd) / 3.0;
|
||||
else
|
||||
c = ((*buffer) * cd) / 3.0;
|
||||
c *= master;
|
||||
@@ -503,18 +606,18 @@ sb16_awe32_filter_cd_audio(int channel, double *buffer, void *priv)
|
||||
bass_treble = sb_bass_treble_4bits[bass];
|
||||
|
||||
if (bass > 8)
|
||||
c += (low_iir(1, channel, c) * bass_treble);
|
||||
c += (low_iir(2, channel, c) * bass_treble);
|
||||
else if (bass < 8)
|
||||
c = (c * bass_treble + low_cut_iir(1, channel, c) * (1.0 - bass_treble));
|
||||
c = (c * bass_treble + low_cut_iir(2, channel, c) * (1.0 - bass_treble));
|
||||
}
|
||||
|
||||
if (treble != 8) {
|
||||
bass_treble = sb_bass_treble_4bits[treble];
|
||||
|
||||
if (treble > 8)
|
||||
c += (high_iir(1, channel, c) * bass_treble);
|
||||
c += (high_iir(2, channel, c) * bass_treble);
|
||||
else if (treble < 8)
|
||||
c = (c * bass_treble + high_cut_iir(1, channel, c) * (1.0 - bass_treble));
|
||||
c = (c * bass_treble + high_cut_iir(2, channel, c) * (1.0 - bass_treble));
|
||||
}
|
||||
|
||||
*buffer = c * output_gain;
|
||||
@@ -534,7 +637,7 @@ sb16_awe32_filter_pc_speaker(int channel, double *buffer, void *priv)
|
||||
double output_gain = (channel ? mixer->output_gain_R : mixer->output_gain_L);
|
||||
|
||||
if (mixer->output_filter)
|
||||
c = (low_fir_sb16(2, channel, *buffer) * spk) / 3.0;
|
||||
c = (low_fir_sb16(3, channel, *buffer) * spk) / 3.0;
|
||||
else
|
||||
c = ((*buffer) * spk) / 3.0;
|
||||
c *= master;
|
||||
@@ -545,18 +648,18 @@ sb16_awe32_filter_pc_speaker(int channel, double *buffer, void *priv)
|
||||
bass_treble = sb_bass_treble_4bits[bass];
|
||||
|
||||
if (bass > 8)
|
||||
c += (low_iir(2, channel, c) * bass_treble);
|
||||
c += (low_iir(3, channel, c) * bass_treble);
|
||||
else if (bass < 8)
|
||||
c = (c * bass_treble + low_cut_iir(1, channel, c) * (1.0 - bass_treble));
|
||||
c = (c * bass_treble + low_cut_iir(3, channel, c) * (1.0 - bass_treble));
|
||||
}
|
||||
|
||||
if (treble != 8) {
|
||||
bass_treble = sb_bass_treble_4bits[treble];
|
||||
|
||||
if (treble > 8)
|
||||
c += (high_iir(2, channel, c) * bass_treble);
|
||||
c += (high_iir(3, channel, c) * bass_treble);
|
||||
else if (treble < 8)
|
||||
c = (c * bass_treble + high_cut_iir(1, channel, c) * (1.0 - bass_treble));
|
||||
c = (c * bass_treble + high_cut_iir(3, channel, c) * (1.0 - bass_treble));
|
||||
}
|
||||
|
||||
*buffer = c * output_gain;
|
||||
@@ -1706,6 +1809,7 @@ sb_1_init(UNUSED(const device_t *info))
|
||||
if (sb->opl_enabled)
|
||||
fm_driver_get(FM_YM3812, &sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, SB1, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_setaddr(&sb->dsp, addr);
|
||||
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
|
||||
@@ -1731,6 +1835,8 @@ sb_1_init(UNUSED(const device_t *info))
|
||||
|
||||
sb->mixer_enabled = 0;
|
||||
sound_add_handler(sb_get_buffer_sb2, sb);
|
||||
if (sb->opl_enabled)
|
||||
music_add_handler(sb_get_music_buffer_sb2, sb);
|
||||
sound_set_cd_audio_filter(sb2_filter_cd_audio, sb);
|
||||
|
||||
if (device_get_config_int("receive_input"))
|
||||
@@ -1754,6 +1860,7 @@ sb_15_init(UNUSED(const device_t *info))
|
||||
if (sb->opl_enabled)
|
||||
fm_driver_get(FM_YM3812, &sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, SB15, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_setaddr(&sb->dsp, addr);
|
||||
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
|
||||
@@ -1781,6 +1888,8 @@ sb_15_init(UNUSED(const device_t *info))
|
||||
|
||||
sb->mixer_enabled = 0;
|
||||
sound_add_handler(sb_get_buffer_sb2, sb);
|
||||
if (sb->opl_enabled)
|
||||
music_add_handler(sb_get_music_buffer_sb2, sb);
|
||||
sound_set_cd_audio_filter(sb2_filter_cd_audio, sb);
|
||||
|
||||
if (device_get_config_int("receive_input"))
|
||||
@@ -1802,6 +1911,7 @@ sb_mcv_init(UNUSED(const device_t *info))
|
||||
if (sb->opl_enabled)
|
||||
fm_driver_get(FM_YM3812, &sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, SB15, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_setaddr(&sb->dsp, 0);
|
||||
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
|
||||
@@ -1809,6 +1919,8 @@ sb_mcv_init(UNUSED(const device_t *info))
|
||||
|
||||
sb->mixer_enabled = 0;
|
||||
sound_add_handler(sb_get_buffer_sb2, sb);
|
||||
if (sb->opl_enabled)
|
||||
music_add_handler(sb_get_music_buffer_sb2, sb);
|
||||
sound_set_cd_audio_filter(sb2_filter_cd_audio, sb);
|
||||
|
||||
/* I/O handlers activated in sb_mcv_write */
|
||||
@@ -1847,6 +1959,7 @@ sb_2_init(UNUSED(const device_t *info))
|
||||
if (sb->opl_enabled)
|
||||
fm_driver_get(FM_YM3812, &sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, SB2, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_setaddr(&sb->dsp, addr);
|
||||
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
|
||||
@@ -1890,6 +2003,8 @@ sb_2_init(UNUSED(const device_t *info))
|
||||
} else
|
||||
sb->mixer_enabled = 0;
|
||||
sound_add_handler(sb_get_buffer_sb2, sb);
|
||||
if (sb->opl_enabled)
|
||||
music_add_handler(sb_get_music_buffer_sb2, sb);
|
||||
sound_set_cd_audio_filter(sb2_filter_cd_audio, sb);
|
||||
|
||||
if (device_get_config_int("receive_input"))
|
||||
@@ -1939,6 +2054,7 @@ sb_pro_v1_init(UNUSED(const device_t *info))
|
||||
sb->opl2.set_do_cycles(sb->opl2.priv, 0);
|
||||
}
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, SBPRO, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_setaddr(&sb->dsp, addr);
|
||||
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
|
||||
@@ -1970,6 +2086,8 @@ sb_pro_v1_init(UNUSED(const device_t *info))
|
||||
sb_ct1345_mixer_write, NULL, NULL,
|
||||
sb);
|
||||
sound_add_handler(sb_get_buffer_sbpro, sb);
|
||||
if (sb->opl_enabled)
|
||||
music_add_handler(sb_get_music_buffer_sbpro, sb);
|
||||
sound_set_cd_audio_filter(sbpro_filter_cd_audio, sb);
|
||||
|
||||
if (device_get_config_int("receive_input"))
|
||||
@@ -1995,6 +2113,7 @@ sb_pro_v2_init(UNUSED(const device_t *info))
|
||||
if (sb->opl_enabled)
|
||||
fm_driver_get(FM_YMF262, &sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_setaddr(&sb->dsp, addr);
|
||||
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
|
||||
@@ -2022,6 +2141,8 @@ sb_pro_v2_init(UNUSED(const device_t *info))
|
||||
sb_ct1345_mixer_write, NULL, NULL,
|
||||
sb);
|
||||
sound_add_handler(sb_get_buffer_sbpro, sb);
|
||||
if (sb->opl_enabled)
|
||||
music_add_handler(sb_get_music_buffer_sbpro, sb);
|
||||
sound_set_cd_audio_filter(sbpro_filter_cd_audio, sb);
|
||||
|
||||
if (device_get_config_int("receive_input"))
|
||||
@@ -2044,11 +2165,14 @@ sb_pro_mcv_init(UNUSED(const device_t *info))
|
||||
sb->opl_enabled = 1;
|
||||
fm_driver_get(FM_YMF262, &sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_ct1345_mixer_reset(sb);
|
||||
|
||||
sb->mixer_enabled = 1;
|
||||
sound_add_handler(sb_get_buffer_sbpro, sb);
|
||||
if (sb->opl_enabled)
|
||||
music_add_handler(sb_get_music_buffer_sbpro, sb);
|
||||
sound_set_cd_audio_filter(sbpro_filter_cd_audio, sb);
|
||||
|
||||
/* I/O handlers activated in sb_pro_mcv_write */
|
||||
@@ -2070,11 +2194,14 @@ sb_pro_compat_init(UNUSED(const device_t *info))
|
||||
|
||||
fm_driver_get(FM_YMF262, &sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, SBPRO2, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_ct1345_mixer_reset(sb);
|
||||
|
||||
sb->mixer_enabled = 1;
|
||||
sound_add_handler(sb_get_buffer_sbpro, sb);
|
||||
if (sb->opl_enabled)
|
||||
music_add_handler(sb_get_music_buffer_sbpro, sb);
|
||||
|
||||
sb->mpu = (mpu_t *) malloc(sizeof(mpu_t));
|
||||
memset(sb->mpu, 0, sizeof(mpu_t));
|
||||
@@ -2097,6 +2224,7 @@ sb_16_init(UNUSED(const device_t *info))
|
||||
if (sb->opl_enabled)
|
||||
fm_driver_get(info->local, &sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, (info->local != FM_YMF289B));
|
||||
sb_dsp_init(&sb->dsp, (info->local == FM_YMF289B) ? SBAWE32PNP : SB16, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_setaddr(&sb->dsp, addr);
|
||||
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
|
||||
@@ -2126,6 +2254,12 @@ sb_16_init(UNUSED(const device_t *info))
|
||||
io_sethandler(addr + 4, 0x0002, sb_ct1745_mixer_read, NULL, NULL,
|
||||
sb_ct1745_mixer_write, NULL, NULL, sb);
|
||||
sound_add_handler(sb_get_buffer_sb16_awe32, sb);
|
||||
if (sb->opl_enabled) {
|
||||
if (info->local == FM_YMF289B)
|
||||
sound_add_handler(sb_get_music_buffer_sb16_awe32, sb);
|
||||
else
|
||||
music_add_handler(sb_get_music_buffer_sb16_awe32, sb);
|
||||
}
|
||||
sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb);
|
||||
if (device_get_config_int("control_pc_speaker"))
|
||||
sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb);
|
||||
@@ -2157,6 +2291,7 @@ sb_16_reply_mca_init(UNUSED(const device_t *info))
|
||||
sb->opl_enabled = 1;
|
||||
fm_driver_get(FM_YMF262, &sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_setdma16_supported(&sb->dsp, 1);
|
||||
sb_dsp_setdma16_enabled(&sb->dsp, 1);
|
||||
@@ -2165,6 +2300,8 @@ sb_16_reply_mca_init(UNUSED(const device_t *info))
|
||||
sb->mixer_enabled = 1;
|
||||
sb->mixer_sb16.output_filter = 1;
|
||||
sound_add_handler(sb_get_buffer_sb16_awe32, sb);
|
||||
if (sb->opl_enabled)
|
||||
music_add_handler(sb_get_music_buffer_sb16_awe32, sb);
|
||||
sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb);
|
||||
if (device_get_config_int("control_pc_speaker"))
|
||||
sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb);
|
||||
@@ -2207,6 +2344,8 @@ sb_16_pnp_init(UNUSED(const device_t *info))
|
||||
sb->mixer_enabled = 1;
|
||||
sb->mixer_sb16.output_filter = 1;
|
||||
sound_add_handler(sb_get_buffer_sb16_awe32, sb);
|
||||
if (sb->opl_enabled)
|
||||
music_add_handler(sb_get_music_buffer_sb16_awe32, sb);
|
||||
sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb);
|
||||
if (device_get_config_int("control_pc_speaker"))
|
||||
sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb);
|
||||
@@ -2225,6 +2364,7 @@ sb_16_pnp_init(UNUSED(const device_t *info))
|
||||
|
||||
isapnp_add_card(sb_16_pnp_rom, sizeof(sb_16_pnp_rom), sb_16_pnp_config_changed, NULL, NULL, NULL, sb);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_setaddr(&sb->dsp, 0);
|
||||
sb_dsp_setirq(&sb->dsp, 0);
|
||||
sb_dsp_setdma8(&sb->dsp, ISAPNP_DMA_DISABLED);
|
||||
@@ -2262,6 +2402,7 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info))
|
||||
sb->opl_enabled = 1;
|
||||
fm_driver_get(FM_YMF262, &sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, (info->local == 0) ? SBAWE64 : SBAWE32PNP, SB_SUBTYPE_DEFAULT, sb);
|
||||
/* The ViBRA 16XV does 16-bit DMA through 8-bit DMA. */
|
||||
sb_dsp_setdma16_supported(&sb->dsp, info->local != 0);
|
||||
@@ -2270,6 +2411,8 @@ sb_vibra16_pnp_init(UNUSED(const device_t *info))
|
||||
sb->mixer_enabled = 1;
|
||||
sb->mixer_sb16.output_filter = 1;
|
||||
sound_add_handler(sb_get_buffer_sb16_awe32, sb);
|
||||
if (sb->opl_enabled)
|
||||
music_add_handler(sb_get_music_buffer_sb16_awe32, sb);
|
||||
sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb);
|
||||
if (device_get_config_int("control_pc_speaker"))
|
||||
sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb);
|
||||
@@ -2340,6 +2483,7 @@ sb_16_compat_init(const device_t *info)
|
||||
|
||||
fm_driver_get(FM_YMF262, &sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, SB16, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_setdma16_supported(&sb->dsp, 1);
|
||||
sb_dsp_setdma16_enabled(&sb->dsp, 1);
|
||||
@@ -2347,6 +2491,8 @@ sb_16_compat_init(const device_t *info)
|
||||
|
||||
sb->mixer_enabled = 1;
|
||||
sound_add_handler(sb_get_buffer_sb16_awe32, sb);
|
||||
if (sb->opl_enabled)
|
||||
music_add_handler(sb_get_music_buffer_sb16_awe32, sb);
|
||||
|
||||
sb->mpu = (mpu_t *) malloc(sizeof(mpu_t));
|
||||
memset(sb->mpu, 0, sizeof(mpu_t));
|
||||
@@ -2411,6 +2557,7 @@ sb_awe32_init(UNUSED(const device_t *info))
|
||||
if (sb->opl_enabled)
|
||||
fm_driver_get(FM_YMF262, &sb->opl);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb_dsp_init(&sb->dsp, SBAWE32, SB_SUBTYPE_DEFAULT, sb);
|
||||
sb_dsp_setaddr(&sb->dsp, addr);
|
||||
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
|
||||
@@ -2440,6 +2587,8 @@ sb_awe32_init(UNUSED(const device_t *info))
|
||||
io_sethandler(addr + 4, 0x0002, sb_ct1745_mixer_read, NULL, NULL,
|
||||
sb_ct1745_mixer_write, NULL, NULL, sb);
|
||||
sound_add_handler(sb_get_buffer_sb16_awe32, sb);
|
||||
if (sb->opl_enabled)
|
||||
music_add_handler(sb_get_music_buffer_sb16_awe32, sb);
|
||||
sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb);
|
||||
if (device_get_config_int("control_pc_speaker"))
|
||||
sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb);
|
||||
@@ -2482,9 +2631,12 @@ sb_awe32_pnp_init(const device_t *info)
|
||||
sb_dsp_setdma16_supported(&sb->dsp, 1);
|
||||
sb_ct1745_mixer_reset(sb);
|
||||
|
||||
sb_dsp_set_real_opl(&sb->dsp, 1);
|
||||
sb->mixer_enabled = 1;
|
||||
sb->mixer_sb16.output_filter = 1;
|
||||
sound_add_handler(sb_get_buffer_sb16_awe32, sb);
|
||||
if (sb->opl_enabled)
|
||||
music_add_handler(sb_get_music_buffer_sb16_awe32, sb);
|
||||
sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb);
|
||||
if (device_get_config_int("control_pc_speaker"))
|
||||
sound_set_pc_speaker_filter(sb16_awe32_filter_pc_speaker, sb);
|
||||
|
@@ -115,7 +115,7 @@ uint8_t adjustMap2[24] = {
|
||||
252, 0, 252, 0
|
||||
};
|
||||
|
||||
double low_fir_sb16_coef[3][SB16_NCoef];
|
||||
double low_fir_sb16_coef[4][SB16_NCoef];
|
||||
|
||||
#ifdef ENABLE_SB_DSP_LOG
|
||||
int sb_dsp_do_log = ENABLE_SB_DSP_LOG;
|
||||
@@ -1256,8 +1256,12 @@ sb_dsp_init(sb_dsp_t *dsp, int type, int subtype, void *parent)
|
||||
/* Initialise SB16 filter to same cutoff as 8-bit SBs (3.2 kHz). This will be recalculated when
|
||||
a set frequency command is sent. */
|
||||
recalc_sb16_filter(0, 3200 * 2);
|
||||
recalc_sb16_filter(1, FREQ_44100);
|
||||
recalc_sb16_filter(2, 18939);
|
||||
if (dsp->sb_has_real_opl)
|
||||
recalc_sb16_filter(1, FREQ_49716);
|
||||
else
|
||||
recalc_sb16_filter(1, FREQ_48000);
|
||||
recalc_sb16_filter(2, FREQ_44100);
|
||||
recalc_sb16_filter(3, 18939);
|
||||
|
||||
/* Initialize SB16 8051 RAM and ASP internal RAM */
|
||||
memset(dsp->sb_8051_ram, 0x00, sizeof(dsp->sb_8051_ram));
|
||||
@@ -1283,6 +1287,12 @@ sb_dsp_setaddr(sb_dsp_t *dsp, uint16_t addr)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sb_dsp_set_real_opl(sb_dsp_t *dsp, uint8_t has_real_opl)
|
||||
{
|
||||
dsp->sb_has_real_opl = has_real_opl;
|
||||
}
|
||||
|
||||
void
|
||||
sb_dsp_set_stereo(sb_dsp_t *dsp, int stereo)
|
||||
{
|
||||
|
@@ -80,21 +80,28 @@ static void
|
||||
wss_get_buffer(int32_t *buffer, int len, void *priv)
|
||||
{
|
||||
wss_t *wss = (wss_t *) priv;
|
||||
const int32_t *opl_buf = NULL;
|
||||
|
||||
if (wss->opl_enabled)
|
||||
opl_buf = wss->opl.update(wss->opl.priv);
|
||||
|
||||
ad1848_update(&wss->ad1848);
|
||||
for (int c = 0; c < len * 2; c++)
|
||||
buffer[c] += wss->ad1848.buffer[c] / 2;
|
||||
|
||||
wss->ad1848.pos = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
wss_get_music_buffer(int32_t *buffer, int len, void *priv)
|
||||
{
|
||||
wss_t *wss = (wss_t *) priv;
|
||||
const int32_t *opl_buf = NULL;
|
||||
|
||||
opl_buf = wss->opl.update(wss->opl.priv);
|
||||
|
||||
for (int c = 0; c < len * 2; c++) {
|
||||
if (opl_buf)
|
||||
buffer[c] += opl_buf[c];
|
||||
buffer[c] += wss->ad1848.buffer[c] / 2;
|
||||
}
|
||||
|
||||
if (wss->opl_enabled)
|
||||
wss->opl.reset_buffer(wss->opl.priv);
|
||||
wss->ad1848.pos = 0;
|
||||
wss->opl.reset_buffer(wss->opl.priv);
|
||||
}
|
||||
|
||||
void *
|
||||
@@ -131,6 +138,9 @@ wss_init(UNUSED(const device_t *info))
|
||||
|
||||
sound_add_handler(wss_get_buffer, wss);
|
||||
|
||||
if (wss->opl_enabled)
|
||||
music_add_handler(wss_get_music_buffer, wss);
|
||||
|
||||
return wss;
|
||||
}
|
||||
|
||||
@@ -214,6 +224,9 @@ ncr_audio_init(UNUSED(const device_t *info))
|
||||
|
||||
sound_add_handler(wss_get_buffer, wss);
|
||||
|
||||
if (wss->opl_enabled)
|
||||
music_add_handler(wss_get_music_buffer, wss);
|
||||
|
||||
return wss;
|
||||
}
|
||||
|
||||
|
@@ -53,9 +53,11 @@ typedef struct {
|
||||
|
||||
int sound_card_current[SOUND_CARD_MAX] = { 0, 0, 0, 0 };
|
||||
int sound_pos_global = 0;
|
||||
int music_pos_global = 0;
|
||||
int sound_gain = 0;
|
||||
|
||||
static sound_handler_t sound_handlers[8];
|
||||
static sound_handler_t music_handlers[8];
|
||||
|
||||
static thread_t *sound_cd_thread_h;
|
||||
static event_t *sound_cd_event;
|
||||
@@ -63,9 +65,15 @@ static event_t *sound_cd_start_event;
|
||||
static int32_t *outbuffer;
|
||||
static float *outbuffer_ex;
|
||||
static int16_t *outbuffer_ex_int16;
|
||||
static int32_t *outbuffer_m;
|
||||
static float *outbuffer_m_ex;
|
||||
static int16_t *outbuffer_m_ex_int16;
|
||||
static int sound_handlers_num;
|
||||
static int music_handlers_num;
|
||||
static pc_timer_t sound_poll_timer;
|
||||
static uint64_t sound_poll_latch;
|
||||
static pc_timer_t music_poll_timer;
|
||||
static uint64_t music_poll_latch;
|
||||
|
||||
static int16_t cd_buffer[CDROM_NUM][CD_BUFLEN * 2];
|
||||
static float cd_out_buffer[CD_BUFLEN * 2];
|
||||
@@ -395,6 +403,28 @@ sound_realloc_buffers(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
music_realloc_buffers(void)
|
||||
{
|
||||
if (outbuffer_m_ex != NULL) {
|
||||
free(outbuffer_m_ex);
|
||||
outbuffer_m_ex = NULL;
|
||||
}
|
||||
|
||||
if (outbuffer_m_ex_int16 != NULL) {
|
||||
free(outbuffer_m_ex_int16);
|
||||
outbuffer_m_ex_int16 = NULL;
|
||||
}
|
||||
|
||||
if (sound_is_float) {
|
||||
outbuffer_m_ex = calloc(MUSICBUFLEN * 2, sizeof(float));
|
||||
memset(outbuffer_m_ex, 0x00, MUSICBUFLEN * 2 * sizeof(float));
|
||||
} else {
|
||||
outbuffer_m_ex_int16 = calloc(MUSICBUFLEN * 2, sizeof(int16_t));
|
||||
memset(outbuffer_m_ex_int16, 0x00, MUSICBUFLEN * 2 * sizeof(int16_t));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sound_init(void)
|
||||
{
|
||||
@@ -403,10 +433,18 @@ sound_init(void)
|
||||
outbuffer_ex = NULL;
|
||||
outbuffer_ex_int16 = NULL;
|
||||
|
||||
outbuffer_m_ex = NULL;
|
||||
outbuffer_m_ex_int16 = NULL;
|
||||
|
||||
outbuffer = NULL;
|
||||
outbuffer = calloc(SOUNDBUFLEN * 2, sizeof(int32_t));
|
||||
memset(outbuffer, 0x00, SOUNDBUFLEN * 2 * sizeof(int32_t));
|
||||
|
||||
outbuffer_m = NULL;
|
||||
outbuffer_m = calloc(MUSICBUFLEN * 2, sizeof(int32_t));
|
||||
memset(outbuffer_m, 0x00, MUSICBUFLEN * 2 * sizeof(int32_t));
|
||||
|
||||
|
||||
for (uint8_t i = 0; i < CDROM_NUM; i++) {
|
||||
if (cdrom[i].bus_type != CDROM_BUS_DISABLED)
|
||||
available_cdrom_drives++;
|
||||
@@ -438,6 +476,14 @@ sound_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *priv), void
|
||||
sound_handlers_num++;
|
||||
}
|
||||
|
||||
void
|
||||
music_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *priv), void *priv)
|
||||
{
|
||||
music_handlers[music_handlers_num].get_buffer = get_buffer;
|
||||
music_handlers[music_handlers_num].priv = priv;
|
||||
music_handlers_num++;
|
||||
}
|
||||
|
||||
void
|
||||
sound_set_cd_audio_filter(void (*filter)(int channel, double *buffer, void *priv), void *priv)
|
||||
{
|
||||
@@ -502,10 +548,48 @@ sound_poll(UNUSED(void *priv))
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
music_poll(UNUSED(void *priv))
|
||||
{
|
||||
timer_advance_u64(&music_poll_timer, music_poll_latch);
|
||||
|
||||
music_pos_global++;
|
||||
if (music_pos_global == MUSICBUFLEN) {
|
||||
int c;
|
||||
|
||||
memset(outbuffer_m, 0x00, MUSICBUFLEN * 2 * sizeof(int32_t));
|
||||
|
||||
for (c = 0; c < music_handlers_num; c++)
|
||||
music_handlers[c].get_buffer(outbuffer_m, MUSICBUFLEN, music_handlers[c].priv);
|
||||
|
||||
for (c = 0; c < MUSICBUFLEN * 2; c++) {
|
||||
if (sound_is_float)
|
||||
outbuffer_m_ex[c] = ((float) outbuffer_m[c]) / (float) 32768.0;
|
||||
else {
|
||||
if (outbuffer_m[c] > 32767)
|
||||
outbuffer_m[c] = 32767;
|
||||
if (outbuffer_m[c] < -32768)
|
||||
outbuffer_m[c] = -32768;
|
||||
|
||||
outbuffer_m_ex_int16[c] = outbuffer_m[c];
|
||||
}
|
||||
}
|
||||
|
||||
if (sound_is_float)
|
||||
givealbuffer_music(outbuffer_m_ex);
|
||||
else
|
||||
givealbuffer_music(outbuffer_m_ex_int16);
|
||||
|
||||
music_pos_global = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
sound_speed_changed(void)
|
||||
{
|
||||
sound_poll_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) SOUND_FREQ));
|
||||
|
||||
music_poll_latch = (uint64_t) ((double) TIMER_USEC * (1000000.0 / (double) MUSIC_FREQ));
|
||||
}
|
||||
|
||||
void
|
||||
@@ -513,6 +597,8 @@ sound_reset(void)
|
||||
{
|
||||
sound_realloc_buffers();
|
||||
|
||||
music_realloc_buffers();
|
||||
|
||||
midi_out_device_init();
|
||||
midi_in_device_init();
|
||||
|
||||
@@ -523,6 +609,11 @@ sound_reset(void)
|
||||
sound_handlers_num = 0;
|
||||
memset(sound_handlers, 0x00, 8 * sizeof(sound_handler_t));
|
||||
|
||||
timer_add(&music_poll_timer, music_poll, NULL, 1);
|
||||
|
||||
music_handlers_num = 0;
|
||||
memset(music_handlers, 0x00, 8 * sizeof(sound_handler_t));
|
||||
|
||||
filter_cd_audio = NULL;
|
||||
filter_cd_audio_p = NULL;
|
||||
|
||||
|
@@ -51,6 +51,7 @@ static int initialized = 0;
|
||||
static IXAudio2 *xaudio2 = NULL;
|
||||
static IXAudio2MasteringVoice *mastervoice = NULL;
|
||||
static IXAudio2SourceVoice *srcvoice = NULL;
|
||||
static IXAudio2SourceVoice *srcvoicemusic = NULL;
|
||||
static IXAudio2SourceVoice *srcvoicemidi = NULL;
|
||||
static IXAudio2SourceVoice *srcvoicecd = NULL;
|
||||
|
||||
@@ -164,6 +165,12 @@ inital(void)
|
||||
return;
|
||||
}
|
||||
|
||||
fmt.nSamplesPerSec = MUSIC_FREQ;
|
||||
fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
|
||||
fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign;
|
||||
|
||||
IXAudio2_CreateSourceVoice(xaudio2, &srcvoicemusic, &fmt, 0, 2.0f, &callbacks, NULL, NULL);
|
||||
|
||||
fmt.nSamplesPerSec = CD_FREQ;
|
||||
fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
|
||||
fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign;
|
||||
@@ -173,6 +180,7 @@ inital(void)
|
||||
IXAudio2SourceVoice_SetVolume(srcvoice, 1, XAUDIO2_COMMIT_NOW);
|
||||
IXAudio2SourceVoice_Start(srcvoice, 0, XAUDIO2_COMMIT_NOW);
|
||||
IXAudio2SourceVoice_Start(srcvoicecd, 0, XAUDIO2_COMMIT_NOW);
|
||||
IXAudio2SourceVoice_Start(srcvoicemusic, 0, XAUDIO2_COMMIT_NOW);
|
||||
|
||||
const char *mdn = midi_out_device_get_internal_name(midi_output_device_current);
|
||||
|
||||
@@ -196,6 +204,8 @@ closeal(void)
|
||||
initialized = 0;
|
||||
IXAudio2SourceVoice_Stop(srcvoice, 0, XAUDIO2_COMMIT_NOW);
|
||||
IXAudio2SourceVoice_FlushSourceBuffers(srcvoice);
|
||||
IXAudio2SourceVoice_Stop(srcvoicemusic, 0, XAUDIO2_COMMIT_NOW);
|
||||
IXAudio2SourceVoice_FlushSourceBuffers(srcvoicemusic);
|
||||
IXAudio2SourceVoice_Stop(srcvoicecd, 0, XAUDIO2_COMMIT_NOW);
|
||||
IXAudio2SourceVoice_FlushSourceBuffers(srcvoicecd);
|
||||
if (srcvoicemidi) {
|
||||
@@ -203,8 +213,9 @@ closeal(void)
|
||||
IXAudio2SourceVoice_FlushSourceBuffers(srcvoicemidi);
|
||||
IXAudio2SourceVoice_DestroyVoice(srcvoicemidi);
|
||||
}
|
||||
IXAudio2SourceVoice_DestroyVoice(srcvoice);
|
||||
IXAudio2SourceVoice_DestroyVoice(srcvoicecd);
|
||||
IXAudio2SourceVoice_DestroyVoice(srcvoicemusic);
|
||||
IXAudio2SourceVoice_DestroyVoice(srcvoice);
|
||||
IXAudio2MasteringVoice_DestroyVoice(mastervoice);
|
||||
IXAudio2_Release(xaudio2);
|
||||
srcvoice = srcvoicecd = srcvoicemidi = NULL;
|
||||
@@ -249,6 +260,12 @@ givealbuffer(void *buf)
|
||||
givealbuffer_common(buf, srcvoice, BUFLEN << 1);
|
||||
}
|
||||
|
||||
void
|
||||
givealbuffer_music(void *buf)
|
||||
{
|
||||
givealbuffer_common(buf, srcvoicemusic, MUSICBUFLEN << 1);
|
||||
}
|
||||
|
||||
void
|
||||
givealbuffer_cd(void *buf)
|
||||
{
|
||||
|
Reference in New Issue
Block a user