rtems_status_code rtems_termios_read (void *arg) { rtems_libio_rw_args_t *args = arg; struct rtems_termios_tty *tty = args->iop->data1; uint32_t count = args->count; char *buffer = args->buffer; rtems_status_code sc; sc = rtems_semaphore_obtain (tty->isem, RTEMS_WAIT, RTEMS_NO_TIMEOUT); if (sc != RTEMS_SUCCESSFUL) return sc; if (rtems_termios_linesw[tty->t_line].l_read != NULL) { sc = rtems_termios_linesw[tty->t_line].l_read(tty,args); tty->tty_rcvwakeup = 0; rtems_semaphore_release (tty->isem); return sc; } if (tty->cindex == tty->ccount) { tty->cindex = tty->ccount = 0; tty->read_start_column = tty->column; if (tty->device.pollRead != NULL && tty->device.outputUsesInterrupts == TERMIOS_POLLED) sc = fillBufferPoll (tty); else sc = fillBufferQueue (tty); if (sc != RTEMS_SUCCESSFUL) tty->cindex = tty->ccount = 0; } while (count && (tty->cindex < tty->ccount)) { *buffer++ = tty->cbuf[tty->cindex++]; count--; } args->bytes_moved = args->count - count; tty->tty_rcvwakeup = 0; rtems_semaphore_release (tty->isem); return sc; }
/* A method run in a backround thread, to keep filling the queue with new * audio over time. */ void backgroundProc() { /* Temporary storage to read samples into, before passing to OpenAL. * Kept here to avoid reallocating it during playback. */ std::vector<char> buffer(sBufferFrames * mFrameSize); while (!mQuit.load()) { /* First, make sure the buffer queue is filled. */ fillBufferQueue(buffer); ALint state; alGetSourcei(mSource, AL_SOURCE_STATE, &state); if (state != AL_PLAYING && state != AL_PAUSED) { /* If the source is not playing or paused, it either underrun * or hasn't started at all yet. So remove any buffers that * have been played (will be 0 when first starting). */ ALint processed; alGetSourcei(mSource, AL_BUFFERS_PROCESSED, &processed); while (processed > 0) { ALuint bufid; alSourceUnqueueBuffers(mSource, 1, &bufid); --processed; } /* Make sure the buffer queue is still filled, in case another * buffer had finished before checking the state and after the * last fill. If the queue is empty, playback is over. */ if (fillBufferQueue(buffer) == 0) { mQuit.store(true); return; } /* Now start the sound source. */ alSourcePlay(mSource); } ALint processed; alGetSourcei(mSource, AL_BUFFERS_PROCESSED, &processed); if (processed == 0) { /* Wait until a buffer in the queue has been processed. */ do { std::this_thread::sleep_for(std::chrono::milliseconds(50)); if (mQuit.load()) break; alGetSourcei(mSource, AL_BUFFERS_PROCESSED, &processed); } while (processed == 0); } /* Remove processed buffers, then restart the loop to keep the * queue filled. */ while (processed > 0) { ALuint bufid; alSourceUnqueueBuffers(mSource, 1, &bufid); --processed; } } }