aboutsummaryrefslogtreecommitdiff
path: root/hw
diff options
context:
space:
mode:
authorbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2005-11-05 18:55:28 +0000
committerbellard <bellard@c046a42c-6fe2-441c-8c8c-71466251a162>2005-11-05 18:55:28 +0000
commitc0fe3827ea18f7d29550f2ff2495cec2fe7a3d94 (patch)
tree2a9572602c93a5424a488929b56f29ac610a1641 /hw
parentf04308e45274d0e74546870ea7b02aaef07b077e (diff)
audio merge (malc)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1601 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw')
-rw-r--r--hw/adlib.c40
-rw-r--r--hw/es1370.c49
-rw-r--r--hw/pc.c22
-rw-r--r--hw/sb16.c78
4 files changed, 131 insertions, 58 deletions
diff --git a/hw/adlib.c b/hw/adlib.c
index 70de4ffab1..fa2a03dffc 100644
--- a/hw/adlib.c
+++ b/hw/adlib.c
@@ -53,6 +53,7 @@ static struct {
} conf = {0x220, 44100};
typedef struct {
+ QEMUSoundCard card;
int ticking[2];
int enabled;
int active;
@@ -70,7 +71,7 @@ typedef struct {
#endif
} AdlibState;
-static AdlibState adlib;
+static AdlibState glob_adlib;
static void adlib_stop_opl_timer (AdlibState *s, size_t n)
{
@@ -90,7 +91,7 @@ static void adlib_kill_timers (AdlibState *s)
if (s->ticking[i]) {
uint64_t delta;
- delta = AUD_time_stamp_get_elapsed_usec_out (s->voice, &s->ats);
+ delta = AUD_get_elapsed_usec_out (s->voice, &s->ats);
ldebug (
"delta = %f dexp = %f expired => %d\n",
delta / 1000000.0,
@@ -141,10 +142,11 @@ static IO_READ_PROTO(adlib_read)
static void timer_handler (int c, double interval_Sec)
{
- AdlibState *s = &adlib;
+ AdlibState *s = &glob_adlib;
unsigned n = c & 1;
#ifdef DEBUG
double interval;
+ int64_t exp;
#endif
if (interval_Sec == 0.0) {
@@ -262,16 +264,23 @@ static void Adlib_fini (AdlibState *s)
s->active = 0;
s->enabled = 0;
+ AUD_remove_card (&s->card);
}
-void Adlib_init (void)
+int Adlib_init (AudioState *audio)
{
- AdlibState *s = &adlib;
+ AdlibState *s = &glob_adlib;
+ audsettings_t as;
+
+ if (!audio) {
+ dolog ("No audio state\n");
+ return -1;
+ }
#ifdef HAS_YMF262
if (YMF262Init (1, 14318180, conf.freq)) {
dolog ("YMF262Init %d failed\n", conf.freq);
- return;
+ return -1;
}
else {
YMF262SetTimerHandler (0, timer_handler, 0);
@@ -281,7 +290,7 @@ void Adlib_init (void)
s->opl = OPLCreate (OPL_TYPE_YM3812, 3579545, conf.freq);
if (!s->opl) {
dolog ("OPLCreate %d failed\n", conf.freq);
- return;
+ return -1;
}
else {
OPLSetTimerHandler (s->opl, timer_handler, 0);
@@ -289,18 +298,23 @@ void Adlib_init (void)
}
#endif
+ as.freq = conf.freq;
+ as.nchannels = SHIFT;
+ as.fmt = AUD_FMT_S16;
+
+ AUD_register_card (audio, "adlib", &s->card);
+
s->voice = AUD_open_out (
+ &s->card,
s->voice,
"adlib",
s,
adlib_callback,
- conf.freq,
- SHIFT,
- AUD_FMT_S16
+ &as
);
if (!s->voice) {
Adlib_fini (s);
- return;
+ return -1;
}
s->samples = AUD_get_buffer_size_out (s->voice) >> SHIFT;
@@ -310,7 +324,7 @@ void Adlib_init (void)
dolog ("not enough memory for adlib mixing buffer (%d)\n",
s->samples << SHIFT);
Adlib_fini (s);
- return;
+ return -1;
}
register_ioport_read (0x388, 4, 1, adlib_read, s);
@@ -321,4 +335,6 @@ void Adlib_init (void)
register_ioport_read (conf.port + 8, 2, 1, adlib_read, s);
register_ioport_write (conf.port + 8, 2, 1, adlib_write, s);
+
+ return 0;
}
diff --git a/hw/es1370.c b/hw/es1370.c
index 0191f5fdf8..fc7ac0a96e 100644
--- a/hw/es1370.c
+++ b/hw/es1370.c
@@ -265,6 +265,7 @@ struct chan {
typedef struct ES1370State {
PCIDevice *pci_dev;
+ QEMUSoundCard card;
struct chan chan[NB_CHANNELS];
SWVoiceOut *dac_voice[2];
SWVoiceIn *adc_voice;
@@ -341,11 +342,11 @@ static void es1370_reset (ES1370State *s)
d->scount = 0;
d->leftover = 0;
if (i == ADC_CHANNEL) {
- AUD_close_in (s->adc_voice);
+ AUD_close_in (&s->card, s->adc_voice);
s->adc_voice = NULL;
}
else {
- AUD_close_out (s->dac_voice[i]);
+ AUD_close_out (&s->card, s->dac_voice[i]);
s->dac_voice[i] = NULL;
}
}
@@ -417,28 +418,32 @@ static void es1370_update_voices (ES1370State *s, uint32_t ctl, uint32_t sctl)
(new_fmt & 2) ? AUD_FMT_S16 : AUD_FMT_U8,
d->shift);
if (new_freq) {
+ audsettings_t as;
+
+ as.freq = new_freq;
+ as.nchannels = 1 << (new_fmt & 1);
+ as.fmt = (new_fmt & 2) ? AUD_FMT_S16 : AUD_FMT_U8;
+
if (i == ADC_CHANNEL) {
s->adc_voice =
AUD_open_in (
+ &s->card,
s->adc_voice,
"es1370.adc",
s,
es1370_adc_callback,
- new_freq,
- 1 << (new_fmt & 1),
- (new_fmt & 2) ? AUD_FMT_S16 : AUD_FMT_U8
+ &as
);
}
else {
s->dac_voice[i] =
AUD_open_out (
+ &s->card,
s->dac_voice[i],
i ? "es1370.dac2" : "es1370.dac1",
s,
i ? es1370_dac2_callback : es1370_dac1_callback,
- new_freq,
- 1 << (new_fmt & 1),
- (new_fmt & 2) ? AUD_FMT_S16 : AUD_FMT_U8
+ &as
);
}
}
@@ -761,7 +766,7 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel,
while (temp) {
int acquired, to_copy;
- to_copy = audio_MIN (temp, sizeof (tmpbuf));
+ to_copy = audio_MIN ((size_t) temp, sizeof (tmpbuf));
acquired = AUD_read (s->adc_voice, tmpbuf, to_copy);
if (!acquired)
break;
@@ -779,7 +784,7 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel,
while (temp) {
int copied, to_copy;
- to_copy = audio_MIN (temp, sizeof (tmpbuf));
+ to_copy = audio_MIN ((size_t) temp, sizeof (tmpbuf));
cpu_physical_memory_read (addr, tmpbuf, to_copy);
copied = AUD_write (voice, tmpbuf, to_copy);
if (!copied)
@@ -812,7 +817,7 @@ static void es1370_transfer_audio (ES1370State *s, struct chan *d, int loop_sel,
else {
d->frame_cnt = size;
- if (cnt <= d->frame_cnt)
+ if ((uint32_t) cnt <= d->frame_cnt)
d->frame_cnt |= cnt << 16;
}
@@ -876,6 +881,10 @@ static void es1370_map (PCIDevice *pci_dev, int region_num,
PCIES1370State *d = (PCIES1370State *) pci_dev;
ES1370State *s = &d->es1370;
+ (void) region_num;
+ (void) size;
+ (void) type;
+
register_ioport_write (addr, 0x40 * 4, 1, es1370_writeb, s);
register_ioport_write (addr, 0x40 * 2, 2, es1370_writew, s);
register_ioport_write (addr, 0x40, 4, es1370_writel, s);
@@ -923,13 +932,13 @@ static int es1370_load (QEMUFile *f, void *opaque, int version_id)
qemu_get_be32s (f, &d->frame_cnt);
if (i == ADC_CHANNEL) {
if (s->adc_voice) {
- AUD_close_in (s->adc_voice);
+ AUD_close_in (&s->card, s->adc_voice);
s->adc_voice = NULL;
}
}
else {
if (s->dac_voice[i]) {
- AUD_close_out (s->dac_voice[i]);
+ AUD_close_out (&s->card, s->dac_voice[i]);
s->dac_voice[i] = NULL;
}
}
@@ -953,12 +962,22 @@ static void es1370_on_reset (void *opaque)
es1370_reset (s);
}
-int es1370_init (PCIBus *bus)
+int es1370_init (PCIBus *bus, AudioState *audio)
{
PCIES1370State *d;
ES1370State *s;
uint8_t *c;
+ if (!bus) {
+ dolog ("No PCI bus\n");
+ return -1;
+ }
+
+ if (!audio) {
+ dolog ("No audio state\n");
+ return -1;
+ }
+
d = (PCIES1370State *) pci_register_device (bus, "ES1370",
sizeof (PCIES1370State),
-1, NULL, NULL);
@@ -1002,6 +1021,8 @@ int es1370_init (PCIBus *bus)
pci_register_io_region (&d->dev, 0, 256, PCI_ADDRESS_SPACE_IO, es1370_map);
register_savevm ("es1370", 0, 1, es1370_save, es1370_load, s);
qemu_register_reset (es1370_on_reset, s);
+
+ AUD_register_card (audio, "es1370", &s->card);
es1370_reset (s);
return 0;
}
diff --git a/hw/pc.c b/hw/pc.c
index 90a0e48fa1..324f5367d1 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -601,19 +601,23 @@ static void pc_init1(int ram_size, int vga_ram_size, int boot_device,
DMA_init(0);
if (audio_enabled) {
- AUD_init();
- if (sb16_enabled)
- SB16_init ();
+ AudioState *audio;
+
+ audio = AUD_init();
+ if (audio) {
+ if (sb16_enabled)
+ SB16_init (audio);
#ifdef CONFIG_ADLIB
- if (adlib_enabled)
- Adlib_init ();
+ if (adlib_enabled)
+ Adlib_init (audio);
#endif
#ifdef CONFIG_GUS
- if (gus_enabled)
- GUS_init ();
+ if (gus_enabled)
+ GUS_init (audio);
#endif
- if (pci_enabled && es1370_enabled)
- es1370_init (pci_bus);
+ if (pci_enabled && es1370_enabled)
+ es1370_init (pci_bus, audio);
+ }
}
floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table);
diff --git a/hw/sb16.c b/hw/sb16.c
index e79d192789..4414af3d8a 100644
--- a/hw/sb16.c
+++ b/hw/sb16.c
@@ -53,6 +53,7 @@ static struct {
} conf = {5, 4, 5, 1, 5, 0x220};
typedef struct SB16State {
+ QEMUSoundCard card;
int irq;
int dma;
int hdma;
@@ -108,9 +109,6 @@ typedef struct SB16State {
uint8_t mixer_regs[256];
} SB16State;
-/* XXX: suppress that and use a context */
-static struct SB16State dsp;
-
static void SB_audio_callback (void *opaque, int free);
static int magic_of_irq (int irq)
@@ -242,15 +240,21 @@ static void dma_cmd8 (SB16State *s, int mask, int dma_len)
s->block_size, s->dma_auto, s->fifo, s->highspeed);
if (s->freq) {
+ audsettings_t as;
+
s->audio_free = 0;
+
+ as.freq = s->freq;
+ as.nchannels = 1 << s->fmt_stereo;
+ as.fmt = s->fmt;
+
s->voice = AUD_open_out (
+ &s->card,
s->voice,
"sb16",
s,
SB_audio_callback,
- s->freq,
- 1 << s->fmt_stereo,
- s->fmt
+ &as
);
}
@@ -330,15 +334,21 @@ static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
}
if (s->freq) {
+ audsettings_t as;
+
s->audio_free = 0;
+
+ as.freq = s->freq;
+ as.nchannels = 1 << s->fmt_stereo;
+ as.fmt = s->fmt;
+
s->voice = AUD_open_out (
+ &s->card,
s->voice,
"sb16",
s,
SB_audio_callback,
- s->freq,
- 1 << s->fmt_stereo,
- s->fmt
+ &as
);
}
@@ -349,7 +359,7 @@ static void dma_cmd (SB16State *s, uint8_t cmd, uint8_t d0, int dma_len)
static inline void dsp_out_data (SB16State *s, uint8_t val)
{
ldebug ("outdata %#x\n", val);
- if (s->out_data_len < sizeof (s->out_data)) {
+ if ((size_t) s->out_data_len < sizeof (s->out_data)) {
s->out_data[s->out_data_len++] = val;
}
}
@@ -1018,6 +1028,7 @@ static void reset_mixer (SB16State *s)
static IO_WRITE_PROTO(mixer_write_indexb)
{
SB16State *s = opaque;
+ (void) nport;
s->mixer_nreg = val;
}
@@ -1025,10 +1036,8 @@ static IO_WRITE_PROTO(mixer_write_datab)
{
SB16State *s = opaque;
+ (void) nport;
ldebug ("mixer_write [%#x] <- %#x\n", s->mixer_nreg, val);
- if (s->mixer_nreg > sizeof (s->mixer_regs)) {
- return;
- }
switch (s->mixer_nreg) {
case 0x00:
@@ -1088,6 +1097,8 @@ static IO_WRITE_PROTO(mixer_write_indexw)
static IO_READ_PROTO(mixer_read)
{
SB16State *s = opaque;
+
+ (void) nport;
#ifndef DEBUG_SB16_MOST
if (s->mixer_nreg != 0x82) {
ldebug ("mixer_read[%#x] -> %#x\n",
@@ -1111,11 +1122,12 @@ static int write_audio (SB16State *s, int nchan, int dma_pos,
while (temp) {
int left = dma_len - dma_pos;
- int to_copy, copied;
+ int copied;
+ size_t to_copy;
to_copy = audio_MIN (temp, left);
- if (to_copy > sizeof(tmpbuf)) {
- to_copy = sizeof(tmpbuf);
+ if (to_copy > sizeof (tmpbuf)) {
+ to_copy = sizeof (tmpbuf);
}
copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
@@ -1308,21 +1320,27 @@ static int SB_load (QEMUFile *f, void *opaque, int version_id)
qemu_get_buffer (f, s->mixer_regs, 256);
if (s->voice) {
- AUD_close_out (s->voice);
+ AUD_close_out (&s->card, s->voice);
s->voice = NULL;
}
if (s->dma_running) {
if (s->freq) {
+ audsettings_t as;
+
s->audio_free = 0;
+
+ as.freq = s->freq;
+ as.nchannels = 1 << s->fmt_stereo;
+ as.fmt = s->fmt;
+
s->voice = AUD_open_out (
+ &s->card,
s->voice,
"sb16",
s,
SB_audio_callback,
- s->freq,
- 1 << s->fmt_stereo,
- s->fmt
+ &as
);
}
@@ -1332,13 +1350,25 @@ static int SB_load (QEMUFile *f, void *opaque, int version_id)
return 0;
}
-void SB16_init (void)
+int SB16_init (AudioState *audio)
{
- SB16State *s = &dsp;
+ SB16State *s;
int i;
static const uint8_t dsp_write_ports[] = {0x6, 0xc};
static const uint8_t dsp_read_ports[] = {0x6, 0xa, 0xc, 0xd, 0xe, 0xf};
+ if (!audio) {
+ dolog ("No audio state\n");
+ return -1;
+ }
+
+ s = qemu_mallocz (sizeof (*s));
+ if (!s) {
+ dolog ("Could not allocate memory for SB16 (%d bytes)\n",
+ sizeof (*s));
+ return -1;
+ }
+
s->cmd = -1;
s->irq = conf.irq;
s->dma = conf.dma;
@@ -1356,7 +1386,7 @@ void SB16_init (void)
reset_mixer (s);
s->aux_ts = qemu_new_timer (vm_clock, aux_timer, s);
if (!s->aux_ts) {
- dolog ("Can not create auxiliary timer\n");
+ dolog ("warning: Could not create auxiliary timer\n");
}
for (i = 0; i < LENOFA (dsp_write_ports); i++) {
@@ -1377,4 +1407,6 @@ void SB16_init (void)
s->can_write = 1;
register_savevm ("sb16", 0, 1, SB_save, SB_load, s);
+ AUD_register_card (audio, "sb16", &s->card);
+ return 0;
}