static void update_voices(MilkymistAC97State *s) { if (s->regs[R_D_CTRL] & CTRL_EN) { AUD_set_active_out(s->voice_out, 1); } else { AUD_set_active_out(s->voice_out, 0); } if (s->regs[R_U_CTRL] & CTRL_EN) { AUD_set_active_in(s->voice_in, 1); } else { AUD_set_active_in(s->voice_in, 0); } }
static void control (SB16State *s, int hold) { int dma = s->use_hdma ? s->hdma : s->dma; s->dma_running = hold; ldebug ("hold %d high %d dma %d\n", hold, s->use_hdma, dma); if (hold) { DMA_hold_DREQ (dma); AUD_set_active_out (s->voice, 1); } else { DMA_release_DREQ (dma); AUD_set_active_out (s->voice, 0); } }
static void control (SB16State *s, int hold) { int dma = s->use_hdma ? s->hdma : s->dma; IsaDma *isa_dma = s->use_hdma ? s->isa_hdma : s->isa_dma; IsaDmaClass *k = ISADMA_GET_CLASS(isa_dma); s->dma_running = hold; ldebug ("hold %d high %d dma %d\n", hold, s->use_hdma, dma); if (hold) { k->hold_DREQ(isa_dma, dma); AUD_set_active_out (s->voice, 1); } else { k->release_DREQ(isa_dma, dma); AUD_set_active_out (s->voice, 0); } }
static int usb_audio_set_output_altset(USBAudioState *s, int altset) { switch (altset) { case ALTSET_OFF: streambuf_init(&s->out.buf, s->buffer); AUD_set_active_out(s->out.voice, false); break; case ALTSET_ON: AUD_set_active_out(s->out.voice, true); break; default: return -1; } if (s->debug) { fprintf(stderr, "usb-audio: set interface %d\n", altset); } s->out.altset = altset; return 0; }
static void adlib_write(void *opaque, uint32_t nport, uint32_t val) { AdlibState *s = opaque; int a = nport & 3; s->active = 1; AUD_set_active_out (s->voice, 1); adlib_kill_timers (s); OPLWrite (s->opl, a, val); }
static void milkymist_ac97_reset(DeviceState *d) { MilkymistAC97State *s = container_of(d, MilkymistAC97State, busdev.qdev); int i; for (i = 0; i < R_MAX; i++) { s->regs[i] = 0; } AUD_set_active_in(s->voice_in, 0); AUD_set_active_out(s->voice_out, 0); }
static void milkymist_ac97_reset(DeviceState *d) { MilkymistAC97State *s = MILKYMIST_AC97(d); int i; for (i = 0; i < R_MAX; i++) { s->regs[i] = 0; } AUD_set_active_in(s->voice_in, 0); AUD_set_active_out(s->voice_out, 0); }
static int virtio_audio_load(QEMUFile *f, void *opaque, int version_id) { VirtIOAudio *s = opaque; VirtIOAudioStream *stream; int i; int mode; if (version_id != 1) return -EINVAL; /* FIXME: Do bad things happen if there is a transfer in progress? */ virtio_load(&s->vdev, f); for (i = 0; i < NUM_STREAMS; i++) { stream = &s->stream[i]; stream->has_buffer = 0; stream->data_left = 0; if (stream->in_voice) { AUD_close_in(&s->card, stream->in_voice); stream->in_voice = NULL; } if (stream->out_voice) { AUD_close_out(&s->card, stream->out_voice); stream->out_voice = NULL; } mode = qemu_get_byte(f); stream->fmt.endianness = qemu_get_byte(f); stream->fmt.nchannels = qemu_get_be16(f); stream->fmt.fmt = qemu_get_be32(f); stream->fmt.freq = qemu_get_be32(f); if (mode & 2) { stream->in_voice = AUD_open_in(&s->card, stream->in_voice, "virtio-audio.in", stream, virtio_audio_callback, &stream->fmt); AUD_set_active_in(stream->in_voice, mode & 1); } else if (mode & 4) { stream->out_voice = AUD_open_out(&s->card, stream->out_voice, "virtio-audio.out", stream, virtio_audio_callback, &stream->fmt); AUD_set_active_out(stream->out_voice, mode & 1); } } return 0; }
static void enable_audio(struct goldfish_audio_state *s, int enable) { // enable or disable the output voice if (s->voice != NULL) { AUD_set_active_out(s->voice, (enable & (AUDIO_INT_WRITE_BUFFER_1_EMPTY | AUDIO_INT_WRITE_BUFFER_2_EMPTY)) != 0); goldfish_audio_buff_reset( s->out_buff1 ); goldfish_audio_buff_reset( s->out_buff2 ); } if (s->voicein) { AUD_set_active_in (s->voicein, (enable & AUDIO_INT_READ_BUFFER_FULL) != 0); goldfish_audio_buff_reset( s->in_buff ); } s->current_buffer = 0; }
static IO_WRITE_PROTO (adlib_write) { AdlibState *s = opaque; int a = nport & 3; s->active = 1; AUD_set_active_out (s->voice, 1); adlib_kill_timers (s); #ifdef HAS_YMF262 YMF262Write (0, a, val); #else OPLWrite (s->opl, a, val); #endif }
static void adlib_write(void *opaque, uint32_t nport, uint32_t val) { AdlibState *s = opaque; int a = nport & 3; s->active = 1; AUD_set_active_out (s->voice, 1); adlib_kill_timers (s); #ifdef HAS_YMF262 YMF262Write (0, a, val); #else OPLWrite (s->opl, a, val); #endif }
static void hda_audio_set_running(HDAAudioStream *st, bool running) { if (st->node == NULL) { return; } if (st->running == running) { return; } st->running = running; dprint(st->state, 1, "%s: %s (stream %d)\n", st->node->name, st->running ? "on" : "off", st->stream); if (st->output) { AUD_set_active_out(st->voice.out, st->running); } else { AUD_set_active_in(st->voice.in, st->running); } }
static void cs_reset_voices (CSState *s, uint32_t val) { int xtal; struct audsettings as; #ifdef DEBUG_XLAW if (val == 0 || val == 32) val = (1 << 4) | (1 << 5); #endif xtal = val & 1; as.freq = freqs[xtal][(val >> 1) & 7]; if (as.freq == -1) { lerr ("unsupported frequency (val=%#x)\n", val); goto error; } as.nchannels = (val & (1 << 4)) ? 2 : 1; as.endianness = 0; s->tab = NULL; switch ((val >> 5) & ((s->dregs[MODE_And_ID] & MODE2) ? 7 : 3)) { case 0: as.fmt = AUD_FMT_U8; s->shift = as.nchannels == 2; break; case 1: s->tab = MuLawDecompressTable; goto x_law; case 3: s->tab = ALawDecompressTable; x_law: as.fmt = AUD_FMT_S16; as.endianness = AUDIO_HOST_ENDIANNESS; s->shift = as.nchannels == 2; break; case 6: as.endianness = 1; case 2: as.fmt = AUD_FMT_S16; s->shift = as.nchannels; break; case 7: case 4: lerr ("attempt to use reserved format value (%#x)\n", val); goto error; case 5: lerr ("ADPCM 4 bit IMA compatible format is not supported\n"); goto error; } s->voice = AUD_open_out ( &s->card, s->voice, "cs4231a", s, cs_audio_callback, &as ); if (s->dregs[Interface_Configuration] & PEN) { if (!s->dma_running) { DMA_hold_DREQ (s->dma); AUD_set_active_out (s->voice, 1); s->transferred = 0; } s->dma_running = 1; } else { if (s->dma_running) { DMA_release_DREQ (s->dma); AUD_set_active_out (s->voice, 0); } s->dma_running = 0; } return; error: if (s->dma_running) { DMA_release_DREQ (s->dma); AUD_set_active_out (s->voice, 0); } }
/* Command queue. */ static void virtio_audio_handle_cmd(VirtIODevice *vdev, VirtQueue *vq) { VirtIOAudio *s = to_virtio_audio(vdev); VirtIOAudioStream *stream; VirtQueueElement elem; int out_n; uint32_t *p; int len; size_t out_bytes; uint32_t value; while (virtqueue_pop(s->cmd_vq, &elem)) { size_t bytes_transferred = 0; for (out_n = 0; out_n < elem.out_num; out_n++) { p = (uint32_t *)elem.out_sg[out_n].iov_base; len = elem.out_sg[out_n].iov_len; while (len > 0) { if (len < 12) { BADF("Bad command length\n"); break; } DPRINTF("Command %d %d %d\n", ldl_p(p), ldl_p(p + 1), ldl_p (p + 2)); value = ldl_p(p + 1); if (value >= NUM_STREAMS) break; stream = &s->stream[value]; value = ldl_p(p + 2); switch (ldl_p(p)) { case VIRTIO_AUDIO_CMD_SET_ENDIAN: stream->fmt.endianness = value; break; case VIRTIO_AUDIO_CMD_SET_CHANNELS: stream->fmt.nchannels = value; break; case VIRTIO_AUDIO_CMD_SET_FMT: stream->fmt.fmt = value; break; case VIRTIO_AUDIO_CMD_SET_FREQ: stream->fmt.freq = value; break; case VIRTIO_AUDIO_CMD_INIT: out_bytes = 0; if (value == 1) { if (stream->out_voice) { AUD_close_out(&s->card, stream->out_voice); stream->out_voice = NULL; } stream->in_voice = AUD_open_in(&s->card, stream->in_voice, "virtio-audio.in", stream, virtio_audio_callback, &stream->fmt); virtio_audio_cmd_result(0, &elem, &out_bytes); } else if (value == 0) { if (stream->in_voice) { AUD_close_in(&s->card, stream->in_voice); stream->in_voice = NULL; } stream->out_voice = AUD_open_out(&s->card, stream->out_voice, "virtio-audio.out", stream, virtio_audio_callback, &stream->fmt); value = AUD_get_buffer_size_out(stream->out_voice); virtio_audio_cmd_result(value, &elem, &out_bytes); } else { // let us close all down if (stream->out_voice) { AUD_close_out(&s->card, stream->out_voice); stream->out_voice = NULL; } if (stream->in_voice) { AUD_close_in(&s->card, stream->in_voice); stream->in_voice = NULL; } } bytes_transferred += out_bytes; break; case VIRTIO_AUDIO_CMD_RUN: if (stream->in_voice) { AUD_set_active_in(stream->in_voice, value); } else if (stream->out_voice) { AUD_set_active_out(stream->out_voice, value); } else { DPRINTF("Cannot execute CMD_RUN as no voice is active\n"); } break; } p += 3; len -= 12; bytes_transferred += 12; } } virtqueue_push(s->cmd_vq, &elem, bytes_transferred); virtio_notify(vdev, s->cmd_vq); } }
static void cs_write (void *opaque, target_phys_addr_t addr, uint64_t val64, unsigned size) { CSState *s = opaque; uint32_t saddr, iaddr, val; saddr = addr; val = val64; switch (saddr) { case Index_Address: if (!(s->regs[Index_Address] & MCE) && (val & MCE) && (s->dregs[Interface_Configuration] & (3 << 3))) s->aci_counter = conf.aci_counter; s->regs[Index_Address] = val & ~(1 << 7); break; case Index_Data: if (!(s->dregs[MODE_And_ID] & MODE2)) iaddr = s->regs[Index_Address] & 0x0f; else iaddr = s->regs[Index_Address] & 0x1f; switch (iaddr) { case RESERVED: case RESERVED_2: case RESERVED_3: lwarn ("attempt to write %#x to reserved indirect register %d\n", val, iaddr); break; case FS_And_Playback_Data_Format: if (s->regs[Index_Address] & MCE) { cs_reset_voices (s, val); } else { if (s->dregs[Alternate_Feature_Status] & PMCE) { val = (val & ~0x0f) | (s->dregs[iaddr] & 0x0f); cs_reset_voices (s, val); } else { lwarn ("[P]MCE(%#x, %#x) is not set, val=%#x\n", s->regs[Index_Address], s->dregs[Alternate_Feature_Status], val); break; } } s->dregs[iaddr] = val; break; case Interface_Configuration: val &= ~(1 << 5); /* D5 is reserved */ s->dregs[iaddr] = val; if (val & PPIO) { lwarn ("PIO is not supported (%#x)\n", val); break; } if (val & PEN) { if (!s->dma_running) { cs_reset_voices (s, s->dregs[FS_And_Playback_Data_Format]); } } else { if (s->dma_running) { DMA_release_DREQ (s->dma); AUD_set_active_out (s->voice, 0); s->dma_running = 0; } } break; case Error_Status_And_Initialization: lwarn ("attempt to write to read only register %d\n", iaddr); break; case MODE_And_ID: dolog ("val=%#x\n", val); if (val & MODE2) s->dregs[iaddr] |= MODE2; else s->dregs[iaddr] &= ~MODE2; break; case Alternate_Feature_Enable_I: if (val & TE) lerr ("timer is not yet supported\n"); s->dregs[iaddr] = val; break; case Alternate_Feature_Status: if ((s->dregs[iaddr] & PI) && !(val & PI)) { /* XXX: TI CI */ qemu_irq_lower (s->pic); s->regs[Status] &= ~INT; } s->dregs[iaddr] = val; break; case Version_Chip_ID: lwarn ("write to Version_Chip_ID register %#x\n", val); s->dregs[iaddr] = val; break; default: s->dregs[iaddr] = val; break; } dolog ("written value %#x to indirect register %d\n", val, iaddr); break; case Status: if (s->regs[Status] & INT) { qemu_irq_lower (s->pic); } s->regs[Status] &= ~INT; s->dregs[Alternate_Feature_Status] &= ~(PI | CI | TI); break; case PIO_Data: lwarn ("attempt to write value %#x to PIO register\n", val); break; } }