CD-ROM CUE indexes are now respected for skip even if prestart is 0 (fixes CUE+BIN images that use indexes for pregap), CD Audio attenuation is now done per the specification, and proper sound card filtering and volume calculation now applies to CD Audio.
This commit is contained in:
@@ -718,7 +718,8 @@ cdi_add_track(cd_img_t *cdi, track_t *cur, uint64_t *shift, uint64_t prestart, u
|
||||
uint64_t skip, temp;
|
||||
track_t *prev = NULL;
|
||||
|
||||
if (prestart > 0) {
|
||||
/* Skip *MUST* be calculated even if prestart is 0. */
|
||||
if (prestart >= 0) {
|
||||
if (prestart > cur->start)
|
||||
return 0;
|
||||
skip = cur->start - prestart;
|
||||
|
@@ -14,7 +14,9 @@ typedef struct ad1848_t
|
||||
int count;
|
||||
|
||||
int16_t out_l, out_r;
|
||||
|
||||
|
||||
uint32_t cd_vol_l, cd_vol_r;
|
||||
|
||||
int enable;
|
||||
|
||||
int irq, dma;
|
||||
|
@@ -45,6 +45,8 @@ extern int sound_card_current;
|
||||
|
||||
extern void sound_add_handler(void (*get_buffer)(int32_t *buffer, \
|
||||
int len, void *p), void *p);
|
||||
extern void sound_set_cd_audio_filter(void (*filter)(int channel, \
|
||||
float *buffer, void *p), void *p);
|
||||
|
||||
extern int sound_card_available(int card);
|
||||
extern char *sound_card_getname(int card);
|
||||
|
@@ -56,7 +56,6 @@ void ad1848_write(uint16_t addr, uint8_t val, void *p)
|
||||
{
|
||||
ad1848_t *ad1848 = (ad1848_t *)p;
|
||||
double freq;
|
||||
uint32_t new_cd_vol_l, new_cd_vol_r;
|
||||
switch (addr & 3)
|
||||
{
|
||||
case 0: /*Index*/
|
||||
@@ -126,18 +125,13 @@ void ad1848_write(uint16_t addr, uint8_t val, void *p)
|
||||
|
||||
if (ad1848->type == AD1848_TYPE_CS4231) { /* TODO: configure CD volume for CS4248/AD1848 too */
|
||||
if (ad1848->regs[0x12] & 0x80)
|
||||
new_cd_vol_l = 0;
|
||||
ad1848->cd_vol_l = 0;
|
||||
else
|
||||
new_cd_vol_l = ad1848_vols_5bits_aux_gain[ad1848->regs[0x12] & 0x1f];
|
||||
ad1848->cd_vol_l = ad1848_vols_5bits_aux_gain[ad1848->regs[0x12] & 0x1f];
|
||||
if (ad1848->regs[0x13] & 0x80)
|
||||
new_cd_vol_r = 0;
|
||||
ad1848->cd_vol_r = 0;
|
||||
else
|
||||
new_cd_vol_r = ad1848_vols_5bits_aux_gain[ad1848->regs[0x13] & 0x1f];
|
||||
|
||||
/* Apparently there is no master volume to modulate here
|
||||
(The windows mixer just adjusts all registers at the same
|
||||
time when the master slider is adjusted) */
|
||||
sound_set_cd_volume(new_cd_vol_l, new_cd_vol_r);
|
||||
ad1848->cd_vol_r = ad1848_vols_5bits_aux_gain[ad1848->regs[0x13] & 0x1f];
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
@@ -223,10 +217,20 @@ static void ad1848_poll(void *p)
|
||||
else
|
||||
{
|
||||
ad1848->out_l = ad1848->out_r = 0;
|
||||
sound_set_cd_volume(0, 0);
|
||||
ad1848->cd_vol_l = ad1848->cd_vol_r = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void ad1848_filter_cd_audio(int channel, float *buffer, void *p)
|
||||
{
|
||||
ad1848_t *ad1848 = (ad1848_t *)p;
|
||||
int32_t c;
|
||||
uint32_t volume = channel ? ad1848->cd_vol_r : ad1848->cd_vol_l;
|
||||
|
||||
c = (((int32_t) buffer) * volume) >> 16;
|
||||
*buffer = (float) c;
|
||||
}
|
||||
|
||||
void ad1848_init(ad1848_t *ad1848, int type)
|
||||
{
|
||||
int c;
|
||||
@@ -294,4 +298,6 @@ void ad1848_init(ad1848_t *ad1848, int type)
|
||||
ad1848->type = type;
|
||||
|
||||
timer_add(&ad1848->timer_count, ad1848_poll, ad1848, 0);
|
||||
|
||||
sound_set_cd_audio_filter(ad1848_filter_cd_audio, ad1848);
|
||||
}
|
||||
|
@@ -611,12 +611,6 @@ static void es1371_outl(uint16_t port, uint32_t val, void *p)
|
||||
es1371->master_vol_r = codec_attn[0x1f - (val & 0x1f)];
|
||||
}
|
||||
break;
|
||||
case 0x12: /*CD volume*/
|
||||
if (val & 0x8000)
|
||||
sound_set_cd_volume(0, 0);
|
||||
else
|
||||
sound_set_cd_volume(codec_attn[0x1f - ((val >> 8) & 0x1f)] * 2, codec_attn[0x1f - (val & 0x1f)] * 2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -1145,7 +1139,7 @@ static void es1371_update(es1371_t *es1371)
|
||||
l = (es1371->dac[0].out_l * es1371->dac[0].vol_l) >> 12;
|
||||
l += ((es1371->dac[1].out_l * es1371->dac[1].vol_l) >> 12);
|
||||
r = (es1371->dac[0].out_r * es1371->dac[0].vol_r) >> 12;
|
||||
r += ((es1371->dac[1].out_r * es1371->dac[1].vol_r) >> 12);
|
||||
r += ((es1371->dac[1].out_r * es1371->dac[1].vol_r) >> 12);
|
||||
|
||||
l >>= 1;
|
||||
r >>= 1;
|
||||
@@ -1270,6 +1264,24 @@ static void es1371_get_buffer(int32_t *buffer, int len, void *p)
|
||||
es1371->pos = 0;
|
||||
}
|
||||
|
||||
static void es1371_filter_cd_audio(int channel, float *buffer, void *p)
|
||||
{
|
||||
es1371_t *es1371 = (es1371_t *)p;
|
||||
int32_t c;
|
||||
int32_t volume, val = (int32_t) (uint32_t) es1371->codec_regs[0x12];
|
||||
int master = channel ? es1371->master_vol_r : es1371->master_vol_l;
|
||||
|
||||
if (val & 0x8000)
|
||||
volume = 0;
|
||||
else
|
||||
volume = channel ? codec_attn[0x1f - (val & 0x1f)] : codec_attn[0x1f - ((val >> 8) & 0x1f)];
|
||||
|
||||
c = (((int32_t) buffer) * volume) >> 15;
|
||||
c = (c * master) >> 15;
|
||||
|
||||
*buffer = (float) c;
|
||||
}
|
||||
|
||||
static inline double sinc(double x)
|
||||
{
|
||||
return sin(M_PI * x) / (M_PI * x);
|
||||
@@ -1312,6 +1324,7 @@ static void *es1371_init(const device_t *info)
|
||||
memset(es1371, 0, sizeof(es1371_t));
|
||||
|
||||
sound_add_handler(es1371_get_buffer, es1371);
|
||||
sound_set_cd_audio_filter(es1371_filter_cd_audio, es1371);
|
||||
|
||||
es1371->card = pci_add_card(info->local ? PCI_ADD_SOUND : PCI_ADD_NORMAL, es1371_pci_read, es1371_pci_write, es1371);
|
||||
|
||||
|
@@ -123,6 +123,14 @@ static void sb_get_buffer_sb2(int32_t *buffer, int len, void *p)
|
||||
sb->dsp.pos = 0;
|
||||
}
|
||||
|
||||
static void sb2_filter_cd_audio(int channel, float *buffer, void *p)
|
||||
{
|
||||
int32_t c;
|
||||
|
||||
c = (int32_t)(((sb_iir(0, *buffer) / 1.3) * 65536) / 3) >> 16;
|
||||
*buffer = (float) c;
|
||||
}
|
||||
|
||||
static void sb_get_buffer_sb2_mixer(int32_t *buffer, int len, void *p)
|
||||
{
|
||||
sb_t *sb = (sb_t *)p;
|
||||
@@ -160,6 +168,17 @@ static void sb_get_buffer_sb2_mixer(int32_t *buffer, int len, void *p)
|
||||
sb->dsp.pos = 0;
|
||||
}
|
||||
|
||||
static void sb2_mixer_filter_cd_audio(int channel, float *buffer, void *p)
|
||||
{
|
||||
sb_t *sb = (sb_t *)p;
|
||||
sb_ct1335_mixer_t *mixer = &sb->mixer_sb2;
|
||||
int32_t c;
|
||||
|
||||
c = (int32_t)(((sb_iir(0, *buffer) / 1.3) * mixer->voice) / 3) >> 15;
|
||||
c = (c * mixer->master) >> 15;
|
||||
*buffer = (float) c;
|
||||
}
|
||||
|
||||
void sb_get_buffer_sbpro(int32_t *buffer, int len, void *p)
|
||||
{
|
||||
sb_t *sb = (sb_t *)p;
|
||||
@@ -227,6 +246,22 @@ void sb_get_buffer_sbpro(int32_t *buffer, int len, void *p)
|
||||
sb->dsp.pos = 0;
|
||||
}
|
||||
|
||||
static void sbpro_filter_cd_audio(int channel, float *buffer, void *p)
|
||||
{
|
||||
sb_t *sb = (sb_t *)p;
|
||||
sb_ct1345_mixer_t *mixer = &sb->mixer_sbpro;
|
||||
int32_t c;
|
||||
int32_t voice = channel ? mixer->voice_r : mixer->voice_l;
|
||||
int32_t master = channel ? mixer->master_r : mixer->master_l;
|
||||
|
||||
if (mixer->output_filter)
|
||||
c = (int32_t)(((sb_iir(channel, *buffer) / 1.3) * voice) / 3) >> 15;
|
||||
else
|
||||
c = ((int32_t)(((int32_t) *buffer) * voice) / 3) >> 15;
|
||||
c = (c * master) >> 15;
|
||||
*buffer = (float) c;
|
||||
}
|
||||
|
||||
static void sb_get_buffer_sb16(int32_t *buffer, int len, void *p)
|
||||
{
|
||||
sb_t *sb = (sb_t *)p;
|
||||
@@ -308,6 +343,32 @@ int old_dsp_rec_pos=0;
|
||||
int buf_written=0;
|
||||
int last_crecord=0;
|
||||
#endif
|
||||
|
||||
static void sb16_awe32_filter_cd_audio(int channel, float *buffer, void *p)
|
||||
{
|
||||
sb_t *sb = (sb_t *)p;
|
||||
sb_ct1745_mixer_t *mixer = &sb->mixer_sb16;
|
||||
int32_t c;
|
||||
int32_t voice = channel ? mixer->voice_r : mixer->voice_l;
|
||||
int32_t master = channel ? mixer->master_r : mixer->master_l;
|
||||
int32_t bass = channel ? mixer->bass_r : mixer->bass_l;
|
||||
int32_t treble = channel ? mixer->treble_r : mixer->treble_l;
|
||||
int32_t output_gain = channel ? mixer->output_gain_R : mixer->output_gain_L;
|
||||
|
||||
c = ((int32_t)(low_fir_sb16(channel, *buffer) * voice) / 3) >> 15;
|
||||
c = (c * master) >> 15;
|
||||
|
||||
if (bass != 8 || treble != 8) {
|
||||
/* 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 (bass>8) c += (int32_t)(low_iir(channel, (float)c)*sb_bass_treble_4bits[bass]);
|
||||
if (treble>8) c += (int32_t)(high_iir(channel, (float)c)*sb_bass_treble_4bits[treble]);
|
||||
if (bass<8) c = (int32_t)((c )*sb_bass_treble_4bits[bass] + low_cut_iir(channel, (float)c)*(1.f-sb_bass_treble_4bits[bass]));
|
||||
if (treble<8) c = (int32_t)((c )*sb_bass_treble_4bits[treble] + high_cut_iir(channel, (float)c)*(1.f-sb_bass_treble_4bits[treble]));
|
||||
}
|
||||
|
||||
*buffer = (float) (c << output_gain);
|
||||
}
|
||||
|
||||
static void sb_get_buffer_emu8k(int32_t *buffer, int len, void *p)
|
||||
{
|
||||
sb_t *sb = (sb_t *)p;
|
||||
@@ -460,9 +521,6 @@ void sb_ct1335_mixer_write(uint16_t addr, uint8_t val, void *p)
|
||||
mixer->fm = sb_att_4dbstep_3bits[(mixer->regs[0x06] >> 1)&0x7];
|
||||
mixer->cd = sb_att_4dbstep_3bits[(mixer->regs[0x08] >> 1)&0x7];
|
||||
mixer->voice = sb_att_7dbstep_2bits[(mixer->regs[0x0A] >> 1)&0x3];
|
||||
|
||||
sound_set_cd_volume(((uint32_t)mixer->master * (uint32_t)mixer->cd) / 32768,
|
||||
((uint32_t)mixer->master * (uint32_t)mixer->cd) / 32768);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -582,8 +640,6 @@ void sb_ct1345_mixer_write(uint16_t addr, uint8_t val, void *p)
|
||||
}
|
||||
|
||||
/* TODO: pcspeaker volume? Or is it not worth? */
|
||||
sound_set_cd_volume(((uint32_t)mixer->master_l * (uint32_t)mixer->cd_l) / 32768,
|
||||
((uint32_t)mixer->master_r * (uint32_t)mixer->cd_r) / 32768);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -785,8 +841,6 @@ void sb_ct1745_mixer_write(uint16_t addr, uint8_t val, void *p)
|
||||
mixer->treble_r = mixer->regs[0x45] >> 4;
|
||||
|
||||
/*TODO: pcspeaker volume, with "output_selector" check? or better not? */
|
||||
sound_set_cd_volume(((uint32_t)mixer->master_l * (uint32_t)mixer->cd_l) / 32768,
|
||||
((uint32_t)mixer->master_r * (uint32_t)mixer->cd_r) / 32768);
|
||||
sb_log("sb_ct1745: Received register WRITE: %02X\t%02X\n", mixer->index, mixer->regs[mixer->index]);
|
||||
}
|
||||
}
|
||||
@@ -1070,6 +1124,7 @@ void *sb_1_init(const device_t *info)
|
||||
io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
|
||||
}
|
||||
sound_add_handler(sb_get_buffer_sb2, sb);
|
||||
sound_set_cd_audio_filter(sb2_filter_cd_audio, sb);
|
||||
|
||||
if (device_get_config_int("receive_input"))
|
||||
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp);
|
||||
@@ -1100,6 +1155,7 @@ void *sb_15_init(const device_t *info)
|
||||
io_sethandler(0x0388, 0x0002, opl2_read, NULL, NULL, opl2_write, NULL, NULL, &sb->opl);
|
||||
}
|
||||
sound_add_handler(sb_get_buffer_sb2, sb);
|
||||
sound_set_cd_audio_filter(sb2_filter_cd_audio, sb);
|
||||
|
||||
if (device_get_config_int("receive_input"))
|
||||
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp);
|
||||
@@ -1123,6 +1179,7 @@ void *sb_mcv_init(const device_t *info)
|
||||
sb_dsp_setirq(&sb->dsp, device_get_config_int("irq"));
|
||||
sb_dsp_setdma8(&sb->dsp, device_get_config_int("dma"));
|
||||
sound_add_handler(sb_get_buffer_sb2, sb);
|
||||
sound_set_cd_audio_filter(sb2_filter_cd_audio, sb);
|
||||
/* I/O handlers activated in sb_mcv_write */
|
||||
mca_add(sb_mcv_read, sb_mcv_write, sb_mcv_feedb, NULL, sb);
|
||||
sb->pos_regs[0] = 0x84;
|
||||
@@ -1174,9 +1231,11 @@ void *sb_2_init(const device_t *info)
|
||||
{
|
||||
io_sethandler(mixer_addr+4, 0x0002, sb_ct1335_mixer_read, NULL, NULL, sb_ct1335_mixer_write, NULL, NULL, sb);
|
||||
sound_add_handler(sb_get_buffer_sb2_mixer, sb);
|
||||
}
|
||||
else
|
||||
sound_add_handler(sb_get_buffer_sb2, sb);
|
||||
sound_set_cd_audio_filter(sb2_mixer_filter_cd_audio, sb);
|
||||
} else {
|
||||
sound_add_handler(sb_get_buffer_sb2, sb);
|
||||
sound_set_cd_audio_filter(sb2_filter_cd_audio, sb);
|
||||
}
|
||||
|
||||
if (device_get_config_int("receive_input"))
|
||||
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp);
|
||||
@@ -1252,6 +1311,7 @@ void *sb_pro_v1_init(const device_t *info)
|
||||
}
|
||||
io_sethandler(addr+4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, sb);
|
||||
sound_add_handler(sb_get_buffer_sbpro, sb);
|
||||
sound_set_cd_audio_filter(sbpro_filter_cd_audio, sb);
|
||||
|
||||
if (device_get_config_int("receive_input"))
|
||||
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp);
|
||||
@@ -1287,6 +1347,7 @@ void *sb_pro_v2_init(const device_t *info)
|
||||
}
|
||||
io_sethandler(addr+4, 0x0002, sb_ct1345_mixer_read, NULL, NULL, sb_ct1345_mixer_write, NULL, NULL, sb);
|
||||
sound_add_handler(sb_get_buffer_sbpro, sb);
|
||||
sound_set_cd_audio_filter(sbpro_filter_cd_audio, sb);
|
||||
|
||||
if (device_get_config_int("receive_input"))
|
||||
midi_in_handler(1, sb_dsp_input_msg, sb_dsp_input_sysex, &sb->dsp);
|
||||
@@ -1310,6 +1371,7 @@ void *sb_pro_mcv_init(const device_t *info)
|
||||
sb_ct1345_mixer_reset(sb);
|
||||
/* I/O handlers activated in sb_mcv_write */
|
||||
sound_add_handler(sb_get_buffer_sbpro, sb);
|
||||
sound_set_cd_audio_filter(sbpro_filter_cd_audio, sb);
|
||||
|
||||
/* I/O handlers activated in sb_pro_mcv_write */
|
||||
mca_add(sb_pro_mcv_read, sb_pro_mcv_write, sb_mcv_feedb, NULL, sb);
|
||||
@@ -1345,6 +1407,7 @@ void *sb_16_init(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, sb);
|
||||
sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb);
|
||||
if (mpu_addr) {
|
||||
sb->mpu = (mpu_t *) malloc(sizeof(mpu_t));
|
||||
memset(sb->mpu, 0, sizeof(mpu_t));
|
||||
@@ -1391,6 +1454,7 @@ void *sb_awe32_init(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_emu8k, sb);
|
||||
sound_set_cd_audio_filter(sb16_awe32_filter_cd_audio, sb);
|
||||
if (mpu_addr) {
|
||||
sb->mpu = (mpu_t *) malloc(sizeof(mpu_t));
|
||||
memset(sb->mpu, 0, sizeof(mpu_t));
|
||||
|
@@ -16,6 +16,7 @@
|
||||
* Copyright 2008-2020 Sarah Walker.
|
||||
* Copyright 2016-2020 Miran Grca.
|
||||
*/
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
@@ -76,6 +77,9 @@ static int cd_buf_update = CD_BUFLEN / SOUNDBUFLEN;
|
||||
static volatile int cdaudioon = 0;
|
||||
static int cd_thread_enable = 0;
|
||||
|
||||
static void (*filter_cd_audio)(int channel, float *buffer, void *p) = NULL;
|
||||
static void *filter_cd_audio_p = NULL;
|
||||
|
||||
|
||||
static const SOUND_CARD sound_cards[] =
|
||||
{
|
||||
@@ -241,8 +245,20 @@ sound_cd_thread(void *param)
|
||||
audio_vol_r = 255.0;
|
||||
}
|
||||
|
||||
audio_vol_l /= 511.0;
|
||||
audio_vol_r /= 511.0;
|
||||
/* Calculate attenuation per the specification. */
|
||||
if (audio_vol_l >= 255.0)
|
||||
audio_vol_l = 1.0;
|
||||
else if (audio_vol_l > 0.0)
|
||||
audio_vol_l = (48.0 + (20.0 * log(audio_vol_l / 256.0))) / 48.0;
|
||||
else
|
||||
audio_vol_l = 0.0;
|
||||
|
||||
if (audio_vol_r >= 255.0)
|
||||
audio_vol_r = 1.0;
|
||||
else if (audio_vol_r > 0.0)
|
||||
audio_vol_r = (48.0 + (20.0 * log(audio_vol_r / 256.0))) / 48.0;
|
||||
else
|
||||
audio_vol_r = 0.0;
|
||||
|
||||
if (cdrom[i].get_channel) {
|
||||
channel_select[0] = cdrom[i].get_channel(cdrom[i].priv, 0);
|
||||
@@ -256,16 +272,6 @@ sound_cd_thread(void *param)
|
||||
/*Apply ATAPI channel select*/
|
||||
cd_buffer_temp[0] = cd_buffer_temp[1] = 0.0;
|
||||
|
||||
#if 0
|
||||
if (channel_select[0] & 1)
|
||||
cd_buffer_temp[0] += ((float) cd_buffer[i][c]) * audio_vol_l;
|
||||
if (channel_select[0] & 2)
|
||||
cd_buffer_temp[1] += ((float) cd_buffer[i][c]) * audio_vol_l;
|
||||
if (channel_select[1] & 1)
|
||||
cd_buffer_temp[0] += ((float) cd_buffer[i][c + 1]) * audio_vol_r;
|
||||
if (channel_select[1] & 2)
|
||||
cd_buffer_temp[1] += ((float) cd_buffer[i][c + 1]) * audio_vol_r;
|
||||
#else
|
||||
if ((audio_vol_l != 0.0) && (channel_select[0] != 0)) {
|
||||
if (channel_select[0] & 1)
|
||||
cd_buffer_temp[0] += ((float) cd_buffer[i][c]); /* Channel 0 => Port 0 */
|
||||
@@ -283,11 +289,12 @@ sound_cd_thread(void *param)
|
||||
|
||||
cd_buffer_temp[1] *= audio_vol_r; /* Multiply Port 1 by Port 1 volume */
|
||||
}
|
||||
#endif
|
||||
|
||||
/*Apply sound card CD volume*/
|
||||
cd_buffer_temp[0] *= ((float) cd_vol_l) / 32768.0;
|
||||
cd_buffer_temp[1] *= ((float) cd_vol_r) / 32768.0;
|
||||
/* Apply sound card CD volume and filters */
|
||||
if (filter_cd_audio != NULL) {
|
||||
filter_cd_audio(0, &(cd_buffer_temp[0]), filter_cd_audio_p);
|
||||
filter_cd_audio(1, &(cd_buffer_temp[0]), filter_cd_audio_p);
|
||||
}
|
||||
|
||||
if (sound_is_float) {
|
||||
cd_out_buffer[c] += (cd_buffer_temp[0] / 32768.0);
|
||||
@@ -376,6 +383,16 @@ sound_add_handler(void (*get_buffer)(int32_t *buffer, int len, void *p), void *p
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sound_set_cd_audio_filter(void (*filter)(int channel, float *buffer, void *p), void *p)
|
||||
{
|
||||
if ((filter_cd_audio != NULL) || (filter == NULL)) {
|
||||
filter_cd_audio = filter;
|
||||
filter_cd_audio_p = p;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
sound_poll(void *priv)
|
||||
{
|
||||
@@ -442,6 +459,10 @@ sound_reset(void)
|
||||
timer_add(&sound_poll_timer, sound_poll, NULL, 1);
|
||||
|
||||
sound_handlers_num = 0;
|
||||
memset(sound_handlers, 0x00, 8 * sizeof(sound_handler_t));
|
||||
|
||||
filter_cd_audio = NULL;
|
||||
filter_cd_audio_p = NULL;
|
||||
|
||||
sound_set_cd_volume(65535, 65535);
|
||||
}
|
||||
|
Reference in New Issue
Block a user