- implemented dummy sound input support (returns silence) and prepared the
ES1370 emulation to use it. TODO #1: implement real sound input in the lowlevel sound modules TODO #2: implement sound input in the SB16 TODO #3: rewrite sound output code to use the same API
This commit is contained in:
parent
c78026a9a2
commit
f6ac6abd92
@ -104,7 +104,6 @@ bx_es1370_c::bx_es1370_c()
|
||||
|
||||
s.dac1_timer_index = BX_NULL_TIMER_HANDLE;
|
||||
s.dac2_timer_index = BX_NULL_TIMER_HANDLE;
|
||||
s.adc_timer_index = BX_NULL_TIMER_HANDLE;
|
||||
}
|
||||
|
||||
bx_es1370_c::~bx_es1370_c()
|
||||
@ -112,6 +111,9 @@ bx_es1370_c::~bx_es1370_c()
|
||||
if (s.dac2_outputinit) {
|
||||
soundmod->closewaveoutput();
|
||||
}
|
||||
if (s.adc_inputinit) {
|
||||
soundmod->closewaveinput();
|
||||
}
|
||||
delete soundmod;
|
||||
|
||||
BX_DEBUG(("Exit"));
|
||||
@ -130,6 +132,7 @@ void bx_es1370_c::init(void)
|
||||
|
||||
DEV_sound_init_module("default", &BX_ES1370_THIS soundmod, BX_ES1370_THIS_PTR);
|
||||
BX_ES1370_THIS s.dac2_outputinit = 0;
|
||||
BX_ES1370_THIS s.adc_inputinit = 0;
|
||||
|
||||
if (BX_ES1370_THIS s.dac1_timer_index == BX_NULL_TIMER_HANDLE) {
|
||||
BX_ES1370_THIS s.dac1_timer_index = bx_pc_system.register_timer
|
||||
@ -141,11 +144,6 @@ void bx_es1370_c::init(void)
|
||||
(BX_ES1370_THIS_PTR, es1370_timer_handler, 1, 1, 0, "es1370.dac2");
|
||||
// DAC2 timer: inactive, continuous, frequency variable
|
||||
}
|
||||
if (BX_ES1370_THIS s.adc_timer_index == BX_NULL_TIMER_HANDLE) {
|
||||
BX_ES1370_THIS s.adc_timer_index = bx_pc_system.register_timer
|
||||
(BX_ES1370_THIS_PTR, es1370_timer_handler, 1, 1, 0, "es1370.adc");
|
||||
// ADC timer: inactive, continuous, frequency variable
|
||||
}
|
||||
|
||||
BX_INFO(("ES1370 initialized"));
|
||||
}
|
||||
@ -428,23 +426,27 @@ void bx_es1370_c::es1370_timer(void)
|
||||
{
|
||||
int timer_id;
|
||||
unsigned i;
|
||||
|
||||
timer_id = bx_pc_system.triggeredTimerID();
|
||||
i = (timer_id == BX_ES1370_THIS s.dac1_timer_index) ? 0 : 1;
|
||||
run_channel(i, timer_id, BX_SOUNDLOW_WAVEPACKETSIZE);
|
||||
}
|
||||
|
||||
void bx_es1370_c::run_channel(unsigned chan, int timer_id, Bit32u buflen)
|
||||
{
|
||||
Bit32u new_status = BX_ES1370_THIS s.status;
|
||||
Bit32u addr, sc, csc_bytes, cnt, size, left, transfered, temp;
|
||||
Bit8u tmpbuf[BX_SOUNDLOW_WAVEPACKETSIZE];
|
||||
bx_bool irq = 0;
|
||||
|
||||
timer_id = bx_pc_system.triggeredTimerID();
|
||||
if (timer_id == BX_ES1370_THIS s.dac1_timer_index) {
|
||||
i = 0;
|
||||
} else if (timer_id == BX_ES1370_THIS s.dac2_timer_index) {
|
||||
i = 1;
|
||||
} else {
|
||||
i = 2;
|
||||
}
|
||||
chan_t *d = &BX_ES1370_THIS s.chan[i];
|
||||
chan_t *d = &BX_ES1370_THIS s.chan[chan];
|
||||
|
||||
if (!(BX_ES1370_THIS s.ctl & ctl_ch_en[i]) || (BX_ES1370_THIS s.sctl & sctl_ch_pause[i])) {
|
||||
bx_pc_system.deactivate_timer(timer_id);
|
||||
if (!(BX_ES1370_THIS s.ctl & ctl_ch_en[chan]) || (BX_ES1370_THIS s.sctl & sctl_ch_pause[chan])) {
|
||||
if (chan == ADC_CHANNEL) {
|
||||
BX_ES1370_THIS soundmod->stopwaverecord();
|
||||
} else {
|
||||
bx_pc_system.deactivate_timer(timer_id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -455,18 +457,17 @@ void bx_es1370_c::es1370_timer(void)
|
||||
size = d->frame_cnt & 0xffff;
|
||||
left = ((size - cnt + 1) << 2) + d->leftover;
|
||||
transfered = 0;
|
||||
temp = BX_MIN(BX_SOUNDLOW_WAVEPACKETSIZE, BX_MIN(left, csc_bytes));
|
||||
temp = BX_MIN(buflen, BX_MIN(left, csc_bytes));
|
||||
addr += (cnt << 2) + d->leftover;
|
||||
|
||||
if (i == ADC_CHANNEL) {
|
||||
// TODO: audio input
|
||||
if (chan == ADC_CHANNEL) {
|
||||
BX_ES1370_THIS soundmod->getwavepacket(temp, tmpbuf);
|
||||
DEV_MEM_WRITE_PHYSICAL_BLOCK(addr, temp, tmpbuf);
|
||||
transfered = temp;
|
||||
memset(tmpbuf, 0, transfered);
|
||||
DEV_MEM_WRITE_PHYSICAL_BLOCK(addr, transfered, tmpbuf);
|
||||
} else {
|
||||
// TODO: DAC1 audio output
|
||||
DEV_MEM_READ_PHYSICAL_BLOCK(addr, temp, tmpbuf);
|
||||
if ((i == DAC2_CHANNEL) && BX_ES1370_THIS s.dac2_outputinit) {
|
||||
if ((chan == DAC2_CHANNEL) && BX_ES1370_THIS s.dac2_outputinit) {
|
||||
BX_ES1370_THIS soundmod->sendwavepacket(temp, tmpbuf);
|
||||
}
|
||||
transfered = temp;
|
||||
@ -475,7 +476,7 @@ void bx_es1370_c::es1370_timer(void)
|
||||
if (csc_bytes == transfered) {
|
||||
irq = 1;
|
||||
d->scount = sc | (sc << 16);
|
||||
BX_DEBUG(("%s: all samples played - signalling IRQ (if enabled)", chan_name[i]));
|
||||
BX_DEBUG(("%s: all samples played/recorded - signalling IRQ (if enabled)", chan_name[chan]));
|
||||
} else {
|
||||
irq = 0;
|
||||
d->scount = sc | (((csc_bytes - transfered - 1) >> d->shift) << 16);
|
||||
@ -483,8 +484,8 @@ void bx_es1370_c::es1370_timer(void)
|
||||
|
||||
cnt += (transfered + d->leftover) >> 2;
|
||||
|
||||
if (BX_ES1370_THIS s.sctl & sctl_loop_sel[i]) {
|
||||
BX_ERROR(("%s: non looping mode not supported", chan_name[i]));
|
||||
if (BX_ES1370_THIS s.sctl & sctl_loop_sel[chan]) {
|
||||
BX_ERROR(("%s: non looping mode not supported", chan_name[chan]));
|
||||
} else {
|
||||
d->frame_cnt = size;
|
||||
if (cnt <= d->frame_cnt) {
|
||||
@ -495,8 +496,8 @@ void bx_es1370_c::es1370_timer(void)
|
||||
d->leftover = (transfered + d->leftover) & 3;
|
||||
|
||||
if (irq) {
|
||||
if (BX_ES1370_THIS s.sctl & (1 << (8 + i))) {
|
||||
new_status |= (4 >> i);
|
||||
if (BX_ES1370_THIS s.sctl & (1 << (8 + chan))) {
|
||||
new_status |= (4 >> chan);
|
||||
}
|
||||
}
|
||||
if (new_status != BX_ES1370_THIS s.status) {
|
||||
@ -504,6 +505,13 @@ void bx_es1370_c::es1370_timer(void)
|
||||
}
|
||||
}
|
||||
|
||||
Bit32u bx_es1370_c::es1370_adc_handler(void *this_ptr, Bit32u buflen)
|
||||
{
|
||||
bx_es1370_c *class_ptr = (bx_es1370_c *) this_ptr;
|
||||
class_ptr->run_channel(ADC_CHANNEL, 0, buflen);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void bx_es1370_c::set_irq_level(bx_bool level)
|
||||
{
|
||||
DEV_pci_set_irq(BX_ES1370_THIS s.devfunc, BX_ES1370_THIS s.pci_conf[0x3d], level);
|
||||
@ -572,6 +580,16 @@ void bx_es1370_c::update_voices(Bit32u ctl, Bit32u sctl, bx_bool force)
|
||||
BX_ES1370_THIS s.dac2_outputinit = 1;
|
||||
}
|
||||
}
|
||||
} else if (i == ADC_CHANNEL) {
|
||||
if (!BX_ES1370_THIS s.adc_inputinit) {
|
||||
ret = BX_ES1370_THIS soundmod->openwaveinput(SIM->get_param_string(BXPN_ES1370_WAVEDEV)->getptr(),
|
||||
es1370_adc_handler);
|
||||
if (ret != BX_SOUNDLOW_OK) {
|
||||
BX_ERROR(("could not open wave input device"));
|
||||
} else {
|
||||
BX_ES1370_THIS s.adc_inputinit = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -581,31 +599,42 @@ void bx_es1370_c::update_voices(Bit32u ctl, Bit32u sctl, bx_bool force)
|
||||
|
||||
if (i == DAC1_CHANNEL) {
|
||||
timer_id = BX_ES1370_THIS s.dac1_timer_index;
|
||||
} else if (i == DAC2_CHANNEL) {
|
||||
timer_id = BX_ES1370_THIS s.dac2_timer_index;
|
||||
} else {
|
||||
timer_id = BX_ES1370_THIS s.adc_timer_index;
|
||||
timer_id = BX_ES1370_THIS s.dac2_timer_index;
|
||||
}
|
||||
if (on) {
|
||||
BX_INFO(("%s: freq = %d, nchannels %d, fmt %d, shift %d",
|
||||
chan_name[i], new_freq, 1 << (new_fmt & 1), (new_fmt & 2) ? 16 : 8, d->shift));
|
||||
if (i != DAC2_CHANNEL) {
|
||||
BX_ERROR(("channel %s not supported yet", chan_name[i]));
|
||||
} else if (BX_ES1370_THIS s.dac2_outputinit) {
|
||||
ret = BX_ES1370_THIS soundmod->startwaveplayback(new_freq, (new_fmt >> 1) ? 16 : 8, (new_fmt & 1), (new_fmt >> 1));
|
||||
if (ret != BX_SOUNDLOW_OK) {
|
||||
BX_ES1370_THIS soundmod->closewaveoutput();
|
||||
BX_ES1370_THIS s.dac2_outputinit = 0;
|
||||
BX_ERROR(("could not start wave playback"));
|
||||
}
|
||||
if (i == ADC_CHANNEL) {
|
||||
if (BX_ES1370_THIS s.adc_inputinit) {
|
||||
ret = BX_ES1370_THIS soundmod->startwaverecord(new_freq, (new_fmt >> 1) ? 16 : 8, (new_fmt & 1), (new_fmt >> 1));
|
||||
}
|
||||
} else {
|
||||
if ((i == DAC2_CHANNEL) && BX_ES1370_THIS s.dac2_outputinit) {
|
||||
ret = BX_ES1370_THIS soundmod->startwaveplayback(new_freq, (new_fmt >> 1) ? 16 : 8, (new_fmt & 1), (new_fmt >> 1));
|
||||
if (ret != BX_SOUNDLOW_OK) {
|
||||
BX_ES1370_THIS soundmod->closewaveoutput();
|
||||
BX_ES1370_THIS s.dac2_outputinit = 0;
|
||||
BX_ERROR(("could not start wave playback"));
|
||||
}
|
||||
}
|
||||
timer_val = (Bit64u)BX_SOUNDLOW_WAVEPACKETSIZE * 1000000 / (new_freq << d->shift);
|
||||
bx_pc_system.activate_timer(timer_id, timer_val, 1);
|
||||
}
|
||||
timer_val = (Bit64u)BX_SOUNDLOW_WAVEPACKETSIZE * 1000000 / (new_freq << d->shift);
|
||||
bx_pc_system.activate_timer(timer_id, timer_val, 1);
|
||||
} else {
|
||||
if ((i == DAC2_CHANNEL) && BX_ES1370_THIS s.dac2_outputinit) {
|
||||
BX_ES1370_THIS soundmod->stopwaveplayback();
|
||||
if (i == ADC_CHANNEL) {
|
||||
if (BX_ES1370_THIS s.adc_inputinit) {
|
||||
BX_ES1370_THIS soundmod->stopwaverecord();
|
||||
}
|
||||
} else {
|
||||
if ((i == DAC2_CHANNEL) && BX_ES1370_THIS s.dac2_outputinit) {
|
||||
BX_ES1370_THIS soundmod->stopwaveplayback();
|
||||
}
|
||||
bx_pc_system.deactivate_timer(timer_id);
|
||||
}
|
||||
bx_pc_system.deactivate_timer(timer_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -49,8 +49,8 @@ typedef struct {
|
||||
|
||||
int dac1_timer_index;
|
||||
int dac2_timer_index;
|
||||
int adc_timer_index;
|
||||
bx_bool dac2_outputinit;
|
||||
bx_bool adc_inputinit;
|
||||
|
||||
Bit32u base_ioaddr;
|
||||
Bit8u devfunc;
|
||||
@ -80,10 +80,13 @@ private:
|
||||
BX_ES1370_SMF void update_status(Bit32u new_status);
|
||||
BX_ES1370_SMF void check_lower_irq(Bit32u sctl);
|
||||
BX_ES1370_SMF void update_voices(Bit32u ctl, Bit32u sctl, bx_bool force);
|
||||
BX_ES1370_SMF void run_channel(unsigned channel, int timer_id, Bit32u buflen);
|
||||
|
||||
static void es1370_timer_handler(void *);
|
||||
void es1370_timer(void);
|
||||
|
||||
static Bit32u es1370_adc_handler(void *, Bit32u len);
|
||||
|
||||
static Bit32u read_handler(void *this_ptr, Bit32u address, unsigned io_len);
|
||||
static void write_handler(void *this_ptr, Bit32u address, Bit32u value, unsigned io_len);
|
||||
#if !BX_USE_ES1370_SMF
|
||||
|
@ -137,4 +137,60 @@ int bx_sound_lowlevel_c::closewaveoutput()
|
||||
return BX_SOUNDLOW_OK;
|
||||
}
|
||||
|
||||
int bx_sound_lowlevel_c::openwaveinput(const char *wavedev, sound_record_handler_t rh)
|
||||
{
|
||||
UNUSED(wavedev);
|
||||
record_handler = rh;
|
||||
record_timer_index = bx_pc_system.register_timer(this, record_timer_handler, 1, 1, 0, "soundmod");
|
||||
// record timer: inactive, continuous, frequency variable
|
||||
return BX_SOUNDLOW_OK;
|
||||
}
|
||||
|
||||
int bx_sound_lowlevel_c::startwaverecord(int frequency, int bits, bx_bool stereo, int format)
|
||||
{
|
||||
Bit64u timer_val;
|
||||
Bit8u shift = 0;
|
||||
|
||||
UNUSED(format);
|
||||
if (bits == 16) shift++;
|
||||
if (stereo) shift++;
|
||||
record_packet_size = (frequency / 10) << shift; // 0.1 sec
|
||||
if (record_packet_size > BX_SOUNDLOW_WAVEPACKETSIZE) {
|
||||
record_packet_size = BX_SOUNDLOW_WAVEPACKETSIZE;
|
||||
}
|
||||
timer_val = (Bit64u)record_packet_size * 1000000 / (frequency << shift);
|
||||
bx_pc_system.activate_timer(record_timer_index, timer_val, 1);
|
||||
return BX_SOUNDLOW_OK;
|
||||
}
|
||||
|
||||
int bx_sound_lowlevel_c::getwavepacket(int length, Bit8u data[])
|
||||
{
|
||||
memset(data, 0, length);
|
||||
return BX_SOUNDLOW_OK;
|
||||
}
|
||||
|
||||
int bx_sound_lowlevel_c::stopwaverecord()
|
||||
{
|
||||
bx_pc_system.deactivate_timer(record_timer_index);
|
||||
return BX_SOUNDLOW_OK;
|
||||
}
|
||||
|
||||
int bx_sound_lowlevel_c::closewaveinput()
|
||||
{
|
||||
stopwaverecord();
|
||||
return BX_SOUNDLOW_OK;
|
||||
}
|
||||
|
||||
void bx_sound_lowlevel_c::record_timer_handler(void *this_ptr)
|
||||
{
|
||||
bx_sound_lowlevel_c *class_ptr = (bx_sound_lowlevel_c *) this_ptr;
|
||||
|
||||
class_ptr->record_timer();
|
||||
}
|
||||
|
||||
void bx_sound_lowlevel_c::record_timer(void)
|
||||
{
|
||||
record_handler(this->device, record_packet_size);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -29,6 +29,8 @@
|
||||
#define BX_SOUNDLOW_OK 0
|
||||
#define BX_SOUNDLOW_ERR 1
|
||||
|
||||
typedef Bit32u (*sound_record_handler_t)(void *arg, Bit32u len);
|
||||
|
||||
// Pseudo device that loads the lowlevel sound module
|
||||
class bx_soundmod_ctl_c : public bx_soundmod_ctl_stub_c {
|
||||
public:
|
||||
@ -63,6 +65,18 @@ public:
|
||||
virtual int sendwavepacket(int length, Bit8u data[]);
|
||||
virtual int stopwaveplayback();
|
||||
virtual int closewaveoutput();
|
||||
|
||||
virtual int openwaveinput(const char *wavedev, sound_record_handler_t rh);
|
||||
virtual int startwaverecord(int frequency, int bits, bx_bool stereo, int format);
|
||||
virtual int getwavepacket(int length, Bit8u data[]);
|
||||
virtual int stopwaverecord();
|
||||
virtual int closewaveinput();
|
||||
|
||||
static void record_timer_handler(void *);
|
||||
void record_timer(void);
|
||||
protected:
|
||||
logfunctions *device;
|
||||
int record_timer_index;
|
||||
int record_packet_size;;
|
||||
sound_record_handler_t record_handler;
|
||||
};
|
||||
|
Loading…
x
Reference in New Issue
Block a user