summary refs log tree commit diff stats
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)
downloadfocaccia-qemu-c0fe3827ea18f7d29550f2ff2495cec2fe7a3d94.tar.gz
focaccia-qemu-c0fe3827ea18f7d29550f2ff2495cec2fe7a3d94.zip
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;
 }