From c0fe3827ea18f7d29550f2ff2495cec2fe7a3d94 Mon Sep 17 00:00:00 2001 From: bellard Date: Sat, 5 Nov 2005 18:55:28 +0000 Subject: audio merge (malc) git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1601 c046a42c-6fe2-441c-8c8c-71466251a162 --- hw/adlib.c | 40 +++++++++++++++++++++---------- hw/es1370.c | 49 +++++++++++++++++++++++++++----------- hw/pc.c | 22 ++++++++++------- hw/sb16.c | 78 +++++++++++++++++++++++++++++++++++++++++++------------------ 4 files changed, 131 insertions(+), 58 deletions(-) (limited to 'hw') 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; } -- cgit v1.2.1