示例#1
0
static int winwave_run_in (HWVoiceIn *hw)
{
    WaveVoiceIn *wave = (WaveVoiceIn *) hw;
    int live = audio_pcm_hw_get_live_in (hw);
    int dead = hw->samples - live;
    int decr, ret;

    if (!dead) {
        return 0;
    }

    EnterCriticalSection (&wave->crit_sect);
    {
        decr = audio_MIN (dead, wave->avail);
        wave->avail -= decr;
    }
    LeaveCriticalSection (&wave->crit_sect);

    ret = decr;
    while (decr) {
        int left = hw->samples - hw->wpos;
        int conv = audio_MIN (left, decr);
        hw->conv (hw->conv_buf + hw->wpos,
                  advance (wave->pcm_buf, wave->rpos << hw->info.shift),
                  conv);

        wave->rpos = (wave->rpos + conv) % hw->samples;
        hw->wpos = (hw->wpos + conv) % hw->samples;
        decr -= conv;
    }

    winwave_add_buffers (wave, ret);
    return ret;
}
示例#2
0
文件: coreaudio.c 项目: 0-14N/NDroid
static int coreaudio_run_out (HWVoiceOut *hw, int live)
{
    int decr;
    coreaudioVoice *core = CORE_OUT(hw);

    if (coreaudio_voice_lock (core, "coreaudio_run_out")) {
        return 0;
    }

    if (core->decr > live) {
        ldebug ("core->decr %d live %d core->live %d\n",
                core->decr,
                live,
                core->live);
    }

    decr = audio_MIN (core->decr, live);
    core->decr -= decr;

    core->live = live - decr;
    hw->rpos = core->pos;

    coreaudio_voice_unlock (core, "coreaudio_run_out");
    return decr;
}
示例#3
0
文件: cs4231a.c 项目: ESOS-Lab/VSSIM
static int cs_write_audio (CSState *s, int nchan, int dma_pos,
                           int dma_len, int len)
{
    int temp, net;
    uint8_t tmpbuf[4096];

    temp = len;
    net = 0;

    while (temp) {
        int left = dma_len - dma_pos;
        int copied;
        size_t to_copy;

        to_copy = audio_MIN (temp, left);
        if (to_copy > sizeof (tmpbuf)) {
            to_copy = sizeof (tmpbuf);
        }

        copied = DMA_read_memory (nchan, tmpbuf, dma_pos, to_copy);
        if (s->tab) {
            int i;
            int16_t linbuf[4096];

            for (i = 0; i < copied; ++i)
                linbuf[i] = s->tab[tmpbuf[i]];
            copied = AUD_write (s->voice, linbuf, copied << 1);
            copied >>= 1;
        }
        else {
示例#4
0
static int genode_run_out(HWVoiceOut *hw)
{
	GenodeVoiceOut * const out = (GenodeVoiceOut *)hw;
	Pcm_out_buffer & pcm_buf   = out->pcm_buf;

	int const live = audio_pcm_hw_get_live_out(&out->hw);
	if (!live)
		return 0;

	int const decr     = audio_MIN(live, out->hw.samples);
	size_t const avail = pcm_buf.read_avail();

	if ((avail / (VBOX_SAMPLE_SIZE*VBOX_CHANNELS)) < decr)
		Genode::error(__func__, ": avail: ", avail, " < decr ", decr);

	char buf[decr*VBOX_SAMPLE_SIZE*VBOX_CHANNELS];
	pcm_buf.read(buf, sizeof(buf), true);

	int const samples = write_samples(out, (int16_t*)buf, decr);
	if (samples == 0) return 0;

	pcm_buf.read_advance(samples * (VBOX_SAMPLE_SIZE*VBOX_CHANNELS));

	out->hw.rpos = (out->hw.rpos + samples) % out->hw.samples;
	return samples;
}
示例#5
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);
    }
}
示例#6
0
/* capture */
static int qesd_run_in (HWVoiceIn *hw)
{
    int  wpos, liveSamples, totalSamples;
    int  grabSamples;
    ESDVoiceIn *esd = (ESDVoiceIn *) hw;

    wpos        = hw->wpos;
    liveSamples = audio_pcm_hw_get_live_in (hw);
    grabSamples = hw->samples - liveSamples;
    totalSamples = 0;

    while (grabSamples > 0) {
        ssize_t  nread;
        int      chunkSamples = audio_MIN (grabSamples, hw->samples - wpos);
        int      chunkBytes   = chunkSamples << hw->info.shift;
        int      readSamples, readBytes;
        void*    buf          = advance (esd->pcm_buf, wpos);

    AGAIN:
        nread = read (esd->fd, buf, chunkBytes);
        if (nread == -1) {
            if (errno == EINTR)
                goto AGAIN;
            if (errno == EAGAIN || errno == EWOULDBLOCK)
                break;

            qesd_logerr (errno, "read failed: %s\n", strerror(errno));
            break;
        }
        if (nread == 0)
            break;

        readSamples = nread >> hw->info.shift;
        readBytes   = readSamples << hw->info.shift;

        if (readBytes != nread) {
            dolog ("warning: Misaligned read %d (requested %d), "
                    "alignment %d\n",
                    nread, readBytes, hw->info.align + 1);
        }

        hw->conv (hw->conv_buf + wpos, buf, readSamples,
                  &nominal_volume);

        wpos = (wpos + readSamples) % hw->samples;
        grabSamples  -= readSamples;
        totalSamples += readSamples;
    }
    hw->wpos = wpos;
    return totalSamples;
}
示例#7
0
static int qesd_run_out (HWVoiceOut *hw)
{
    ESDVoiceOut *esd = (ESDVoiceOut *) hw;
    int  liveSamples, totalSamples;
    int  rpos, nwrite, writeSamples, writeBytes;

    liveSamples  = audio_pcm_hw_get_live_out (hw);
    rpos         = hw->rpos;
    totalSamples = 0;

    while (liveSamples > 0) {
        int  chunkSamples = audio_MIN (liveSamples, hw->samples - rpos);
        int  chunkBytes   = chunkSamples << hw->info.shift;
        struct st_sample *src = hw->mix_buf + rpos;

        hw->clip (esd->pcm_buf, src, chunkSamples);

    AGAIN:
        nwrite = write (esd->fd, esd->pcm_buf, chunkBytes);
        if (nwrite == -1) {
            if (errno == EINTR)
                goto AGAIN;
            if (errno == EAGAIN || errno == EWOULDBLOCK)
                break;
            qesd_logerr (errno, "write failed: %s\n", strerror(errno));
            O("EsounD output thread write error: %s", strerror(errno));
            break;
        }
        if (nwrite == 0)
            break;

        writeSamples = nwrite >> hw->info.shift;
        writeBytes   = writeSamples << hw->info.shift;
        if (writeBytes != nwrite) {
            dolog ("warning: Misaligned write %d (requested %d), "
                    "alignment %d\n",
                    nwrite, writeBytes, hw->info.align + 1);
        }
        rpos          = (rpos + writeSamples) % hw->samples;
        totalSamples += writeSamples;
        liveSamples  -= writeSamples;
    }
    hw->rpos = rpos;
    return totalSamples;
}
示例#8
0
static int qpa_run_out (HWVoiceOut *hw, int live)
{
    int decr;
    PAVoiceOut *pa = (PAVoiceOut *) hw;

    if (audio_pt_lock(&pa->pt, __func__)) {
        return 0;
    }

    decr = audio_MIN (live, pa->decr);
    pa->decr -= decr;
    pa->live = live - decr;
    hw->rpos = pa->rpos;
    if (pa->live > 0) {
        audio_pt_unlock_and_signal(&pa->pt, __func__);
    }
    else {
        audio_pt_unlock(&pa->pt, __func__);
    }
    return decr;
}
示例#9
0
文件: paaudio.c 项目: CPFL/gxen
static int qpa_run_out (HWVoiceOut *hw)
{
    int live, decr;
    PAVoiceOut *pa = (PAVoiceOut *) hw;

    if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) {
        return 0;
    }

    live = audio_pcm_hw_get_live_out (hw);
    decr = audio_MIN (live, pa->decr);
    pa->decr -= decr;
    pa->live = live - decr;
    hw->rpos = pa->rpos;
    if (pa->live > 0) {
        audio_pt_unlock_and_signal (&pa->pt, AUDIO_FUNC);
    }
    else {
        audio_pt_unlock (&pa->pt, AUDIO_FUNC);
    }
    return decr;
}
示例#10
0
static int qpa_run_in (HWVoiceIn *hw)
{
    int live, incr, dead;
    PAVoiceIn *pa = (PAVoiceIn *) hw;

    if (audio_pt_lock(&pa->pt, __func__)) {
        return 0;
    }

    live = audio_pcm_hw_get_live_in (hw);
    dead = hw->samples - live;
    incr = audio_MIN (dead, pa->incr);
    pa->incr -= incr;
    pa->dead = dead - incr;
    hw->wpos = pa->wpos;
    if (pa->dead > 0) {
        audio_pt_unlock_and_signal(&pa->pt, __func__);
    }
    else {
        audio_pt_unlock(&pa->pt, __func__);
    }
    return incr;
}
示例#11
0
static int winwave_run_out (HWVoiceOut *hw, int live)
{
    WaveVoiceOut *wave = (WaveVoiceOut *) hw;
    int decr;
    int doreset;

    EnterCriticalSection (&wave->crit_sect);
    {
        decr = audio_MIN (live, wave->avail);
        decr = audio_pcm_hw_clip_out (hw, wave->pcm_buf, decr, wave->pending);
        wave->pending += decr;
        wave->avail -= decr;
    }
    LeaveCriticalSection (&wave->crit_sect);

    doreset = hw->poll_mode && (wave->pending >= conf.dac_samples);
    if (doreset && !ResetEvent (wave->event)) {
        dolog ("DAC ResetEvent failed %lx\n", GetLastError ());
    }

    while (wave->pending >= conf.dac_samples) {
        MMRESULT mr;
        WAVEHDR *h = &wave->hdrs[wave->curhdr];

        h->dwUser = 0;
        mr = waveOutWrite (wave->hwo, h, sizeof (*h));
        if (mr != MMSYSERR_NOERROR) {
            winwave_logerr (mr, "waveOutWrite(%d)", wave->curhdr);
            break;
        }

        wave->pending -= conf.dac_samples;
        wave->curhdr = (wave->curhdr + 1) % conf.dac_headers;
    }

    return decr;
}
示例#12
0
/* capture */
static void *qpa_thread_in (void *arg)
{
    PAVoiceIn *pa = arg;
    HWVoiceIn *hw = &pa->hw;

    if (audio_pt_lock(&pa->pt, __func__)) {
        return NULL;
    }

    for (;;) {
        int incr, to_grab, wpos;

        for (;;) {
            if (pa->done) {
                goto exit;
            }

            if (pa->dead > 0) {
                break;
            }

            if (audio_pt_wait(&pa->pt, __func__)) {
                goto exit;
            }
        }

        incr = to_grab = audio_MIN(pa->dead, pa->samples >> 5);
        wpos = pa->wpos;

        if (audio_pt_unlock(&pa->pt, __func__)) {
            return NULL;
        }

        while (to_grab) {
            int error;
            int chunk = audio_MIN (to_grab, hw->samples - wpos);
            void *buf = advance (pa->pcm_buf, wpos);

            if (qpa_simple_read (pa, buf,
                                 chunk << hw->info.shift, &error) < 0) {
                qpa_logerr (error, "pa_simple_read failed\n");
                return NULL;
            }

            hw->conv (hw->conv_buf + wpos, buf, chunk);
            wpos = (wpos + chunk) % hw->samples;
            to_grab -= chunk;
        }

        if (audio_pt_lock(&pa->pt, __func__)) {
            return NULL;
        }

        pa->wpos = wpos;
        pa->dead -= incr;
        pa->incr += incr;
    }

 exit:
    audio_pt_unlock(&pa->pt, __func__);
    return NULL;
}
示例#13
0
static void *qpa_thread_out (void *arg)
{
    PAVoiceOut *pa = arg;
    HWVoiceOut *hw = &pa->hw;

    if (audio_pt_lock(&pa->pt, __func__)) {
        return NULL;
    }

    for (;;) {
        int decr, to_mix, rpos;

        for (;;) {
            if (pa->done) {
                goto exit;
            }

            if (pa->live > 0) {
                break;
            }

            if (audio_pt_wait(&pa->pt, __func__)) {
                goto exit;
            }
        }

        decr = to_mix = audio_MIN(pa->live, pa->samples >> 5);
        rpos = pa->rpos;

        if (audio_pt_unlock(&pa->pt, __func__)) {
            return NULL;
        }

        while (to_mix) {
            int error;
            int chunk = audio_MIN (to_mix, hw->samples - rpos);
            struct st_sample *src = hw->mix_buf + rpos;

            hw->clip (pa->pcm_buf, src, chunk);

            if (qpa_simple_write (pa, pa->pcm_buf,
                                  chunk << hw->info.shift, &error) < 0) {
                qpa_logerr (error, "pa_simple_write failed\n");
                return NULL;
            }

            rpos = (rpos + chunk) % hw->samples;
            to_mix -= chunk;
        }

        if (audio_pt_lock(&pa->pt, __func__)) {
            return NULL;
        }

        pa->rpos = rpos;
        pa->live -= decr;
        pa->decr += decr;
    }

 exit:
    audio_pt_unlock(&pa->pt, __func__);
    return NULL;
}
示例#14
0
文件: paaudio.c 项目: 0-14N/NDroid
/* capture */
static void *qpa_thread_in (void *arg)
{
    PAVoiceIn *pa = arg;
    HWVoiceIn *hw = &pa->hw;
    int threshold;

    threshold = conf.divisor ? hw->samples / conf.divisor : 0;

    if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) {
        return NULL;
    }

    for (;;) {
        int incr, to_grab, wpos;

        for (;;) {
            if (pa->done) {
                goto exit;
            }

            if (pa->dead > threshold) {
                break;
            }

            if (audio_pt_wait (&pa->pt, AUDIO_FUNC)) {
                goto exit;
            }
        }

        incr = to_grab = pa->dead;
        wpos = hw->wpos;

        if (audio_pt_unlock (&pa->pt, AUDIO_FUNC)) {
            return NULL;
        }

        while (to_grab) {
            int error;
            int chunk = audio_MIN (to_grab, hw->samples - wpos);
            void *buf = advance (pa->pcm_buf, wpos);

            if (FF(pa_simple_read) (pa->s, buf,
                                chunk << hw->info.shift, &error) < 0) {
                qpa_logerr (error, "pa_simple_read failed\n");
                return NULL;
            }

            hw->conv (hw->conv_buf + wpos, buf, chunk, &nominal_volume);
            wpos = (wpos + chunk) % hw->samples;
            to_grab -= chunk;
        }

        if (audio_pt_lock (&pa->pt, AUDIO_FUNC)) {
            return NULL;
        }

        pa->wpos = wpos;
        pa->dead -= incr;
        pa->incr += incr;
    }

 exit:
    audio_pt_unlock (&pa->pt, AUDIO_FUNC);
    return NULL;
}
示例#15
0
/* report the number of captured samples to the audio subsystem */
static int
winaudio_in_run (HWVoiceIn *hw)
{
    WinAudioIn*  s        = (WinAudioIn*) hw;
    int          captured = 0;
    int          has_buffer;
    int          live = hw->samples - hw->total_samples_captured;

    if (!live) {
#if 0
        static int  counter;
        if (++counter == 100) {
            D("0"); fflush(stdout);
            counter = 0;
        }
#endif
            return 0;
    }

    EnterCriticalSection( &s->lock );
    has_buffer = (s->read_count > 0);
    LeaveCriticalSection( &s->lock );

    if (has_buffer > 0) {
        while (live > 0) {
            WAVEHDR*      wav_buffer  = s->buffers + s->read_index;
            int           wav_bytes   = (s->read_size - s->read_pos);
            int           wav_samples = audio_MIN(wav_bytes >> hw->info.shift, live);
            int           hw_samples  = audio_MIN(hw->samples - hw->wpos, live);
            struct st_sample*  dst    = hw->conv_buf + hw->wpos;
            uint8_t*      src         = (uint8_t*)wav_buffer->lpData + s->read_pos;

            if (wav_samples > hw_samples) {
                wav_samples = hw_samples;
            }

            wav_bytes = wav_samples << hw->info.shift;

            D("%s: buffer:%d pos:%d size:%d wsamples:%d wbytes:%d live:%d wpos:%d hwsamples:%d\n",
               __FUNCTION__, s->read_index, s->read_pos, s->read_size, wav_samples, wav_bytes, live,
               hw->wpos, hw->samples);

            hw->conv(dst, src, wav_samples, &nominal_volume);

            hw->wpos += wav_samples;
            if (hw->wpos >= hw->samples)
                hw->wpos -= hw->samples;

            live        -= wav_samples;
            captured    += wav_samples;
            s->read_pos += wav_bytes;
            if (s->read_pos == s->read_size) {
                s->read_pos    = 0;
                s->read_index += 1;
                if (s->read_index == NUM_IN_BUFFERS)
                    s->read_index = 0;

                waveInAddBuffer( s->wavein, wav_buffer, sizeof(*wav_buffer) );

                EnterCriticalSection( &s->lock );
                if (--s->read_count == 0) {
                    live = 0;
                }
                LeaveCriticalSection( &s->lock );
            }
        }
    }
    return  captured;
}
示例#16
0
static int
winaudio_out_run (HWVoiceOut *hw, int live)
{
    WinAudioOut*  s      = (WinAudioOut*) hw;
    int           played = 0;
    int           has_buffer;

    if (!live) {
        return 0;
    }

    EnterCriticalSection( &s->lock );
    has_buffer = (s->write_count > 0);
    LeaveCriticalSection( &s->lock );

    if (has_buffer) {
        while (live > 0) {
            WAVEHDR*      wav_buffer  = s->buffers + s->write_index;
            int           wav_bytes   = (s->write_size - s->write_pos);
            int           wav_samples = audio_MIN(wav_bytes >> hw->info.shift, live);
            int           hw_samples  = audio_MIN(hw->samples - hw->rpos, live);
            struct st_sample*  src         = hw->mix_buf + hw->rpos;
            uint8_t*      dst         = (uint8_t*)wav_buffer->lpData + s->write_pos;

            if (wav_samples > hw_samples) {
                    wav_samples = hw_samples;
            }

            wav_bytes = wav_samples << hw->info.shift;

            //D("run_out: buffer:%d pos:%d size:%d wsamples:%d wbytes:%d live:%d rpos:%d hwsamples:%d\n", s->write_index,
            //   s->write_pos, s->write_size, wav_samples, wav_bytes, live, hw->rpos, hw->samples);
            hw->clip (dst, src, wav_samples);
            hw->rpos += wav_samples;
            if (hw->rpos >= hw->samples)
                    hw->rpos -= hw->samples;

            live         -= wav_samples;
            played       += wav_samples;
            s->write_pos += wav_bytes;
            if (s->write_pos == s->write_size) {
#if xxDEBUG
                int64_t  now  = qemu_get_clock(vm_clock) - start_time;
                int64_t  diff = now - last_time;

                D("run_out: (%7.3f:%7d):waveOutWrite buffer:%d\n",
                   now/1e9, (now-last_time)/1e9, s->write_index);
                last_time = now;
#endif
                waveOutWrite( s->waveout, wav_buffer, sizeof(*wav_buffer) );
                s->write_pos    = 0;
                s->write_index += 1;
                if (s->write_index == NUM_OUT_BUFFERS)
                    s->write_index = 0;

                EnterCriticalSection( &s->lock );
                if (--s->write_count == 0) {
                        live = 0;
                }
                LeaveCriticalSection( &s->lock );
            }
        }

    }
    return played;
}