示例#1
0
static void hda_audio_input_cb(void *opaque, int avail)
{
    HDAAudioStream *st = opaque;
    int recv = 0;
    int len;
    bool rc;

    while (avail - recv >= sizeof(st->buf)) {
        if (st->bpos != sizeof(st->buf)) {
            len = AUD_read(st->voice.in, st->buf + st->bpos,
                           sizeof(st->buf) - st->bpos);
            st->bpos += len;
            recv += len;
            if (st->bpos != sizeof(st->buf)) {
                break;
            }
        }
        rc = hda_codec_xfer(&st->state->hda, st->stream, false,
                            st->buf, sizeof(st->buf));
        if (!rc) {
            break;
        }
        st->bpos = 0;
    }
}
示例#2
0
static int virtio_audio_fill(VirtIOAudioStream *stream,
                             int offset, int total_len)
{
    uint8_t *p;
    int to_write;
    int written;
    int size;
    int n;
    struct iovec *iov;
    int iov_len;

    if (stream->in_voice) {
        iov_len = stream->elem.in_num;
        iov = stream->elem.in_sg;
    } else if (stream->out_voice) {
        iov_len = stream->elem.out_num;
        iov = stream->elem.out_sg;
    } else
    {
        DPRINTF("No voice selected skipping block\n");
        return 0;
    }
    written = 0;
    for (n = 0; total_len > 0 && n < iov_len; n++) {
        p = iov[n].iov_base;
        to_write = iov[n].iov_len;
        if (offset) {
            if (offset >= to_write) {
                offset -= to_write;
                continue;
            }
            p += offset;
            to_write -= offset;
            offset = 0;
        }
        if (to_write > total_len)
            to_write = total_len;
        while (to_write) {
            if (stream->in_voice) {
                size = AUD_read(stream->in_voice, p, to_write);
            } else if (stream->out_voice) {
                size = AUD_write(stream->out_voice, p, to_write);
            } else {
                size = 0;
            }
            DPRINTF("Copied %d/%d\n", size, to_write);
            if (size == 0) {
                total_len = 0;
                break;
            }
            to_write -= size;
            total_len -= size;
            written += size;
        }
    }
    return written;
}
示例#3
0
static int
goldfish_audio_buff_recv( struct goldfish_audio_buff*  b, int  avail, struct goldfish_audio_state*  s )
{
    int     missing = b->length - b->offset;
    int     avail2 = (avail > missing) ? missing : avail;
    int     read;

    read = AUD_read(s->voicein, b->data + b->offset, avail2 );
    if (read == 0)
        return 0;

    if (avail2 > 0)
        D("%s: AUD_read(%d) returned %d", __FUNCTION__, avail2, read);

    cpu_physical_memory_write( b->address + b->offset, b->data, read );
    b->offset += read;

    return read;
}
示例#4
0
static void ac97_in_cb(void *opaque, int avail_b)
{
    MilkymistAC97State *s = opaque;
    uint8_t buf[4096];
    uint32_t remaining = s->regs[R_U_REMAINING];
    int temp = audio_MIN(remaining, avail_b);
    uint32_t addr = s->regs[R_U_ADDR];
    int transferred = 0;

    trace_milkymist_ac97_in_cb(avail_b, remaining);

    /* prevent from raising an IRQ */
    if (temp == 0) {
        return;
    }

    while (temp) {
        int acquired, to_copy;

        to_copy = audio_MIN(temp, sizeof(buf));
        acquired = AUD_read(s->voice_in, buf, to_copy);
        if (!acquired) {
            break;
        }

        cpu_physical_memory_write(addr, buf, acquired);

        temp -= acquired;
        addr += acquired;
        transferred += acquired;
    }

    trace_milkymist_ac97_in_cb_transferred(transferred);

    s->regs[R_U_ADDR] = addr;
    s->regs[R_U_REMAINING] -= transferred;

    if ((s->regs[R_U_CTRL] & CTRL_EN) && (s->regs[R_U_REMAINING] == 0)) {
        trace_milkymist_ac97_pulse_irq_dmaw();
        qemu_irq_pulse(s->dmaw_irq);
    }
}