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:
OBattler
2024-03-01 06:52:48 +01:00
parent 71ecdc1b55
commit e0d80aefb4
18 changed files with 683 additions and 193 deletions

View File

@@ -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;

View File

@@ -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);

View File

@@ -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);

View File

@@ -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

View File

@@ -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);
}

View File

@@ -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;
}

View File

@@ -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"))

View File

@@ -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) {

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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:

View File

@@ -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));

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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)
{

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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)
{