void ADR_CALL ALSAAudioDevice::update() { int ret; int sample_len; int sample_left; char* sample_buf; sample_buf = m_buffer; sample_len = m_buffer_size / 4; sample_left = read(sample_len, sample_buf); while (sample_left > 0) { ret = snd_pcm_writei(m_pcm_handle, sample_buf, sample_left); if (ret == -EAGAIN || (ret > 0 && ret < sample_left)) { snd_pcm_wait(m_pcm_handle, 10); } else if (ret == -ESTRPIPE) { do { snd_pcm_wait(m_pcm_handle, 10); ret = snd_pcm_resume(m_pcm_handle); } while (ret == -EAGAIN); snd_pcm_prepare(m_pcm_handle); } else if (ret == -EPIPE) { snd_pcm_prepare(m_pcm_handle); } if (ret > 0) { sample_buf += ret * 4; sample_left -= ret; } } }
static ssize_t sa_alsa_read( simpleaudio *sa, void *buf, size_t nframes ) { ssize_t frames_read = 0; snd_pcm_t *pcm = (snd_pcm_t *)sa->backend_handle; while ( frames_read < nframes ) { ssize_t r; void * data = buf+frames_read*sa->backend_framesize; ssize_t count = nframes-frames_read; r = snd_pcm_readi(pcm, data, count); if ( r >= 0 ) { frames_read += r; if ( r != count ) fprintf(stderr, "#short+%zd#\n", r); continue; } if (r == -EPIPE) { // Underrun fprintf(stderr, "#"); snd_pcm_prepare(pcm); } else { fprintf(stderr, "snd_pcm_readi: %s\n", snd_strerror(r)); if (r == -EAGAIN || r== -ESTRPIPE) snd_pcm_wait(pcm, 1000); else return r; } } // fprintf(stderr,("[%zd]\n"), frames_read); return frames_read; }
static ssize_t pcm_read(u_char *data, size_t rcount) { ssize_t r; size_t result = 0; size_t count = rcount; if (count != chunk_size) { count = chunk_size; } while (count > 0) { r = readi_func(handle, data, count); if (r == -EAGAIN || (r >= 0 && (size_t)r < count)) { snd_pcm_wait(handle, 1000); } else if (r == -EPIPE) { xrun(); } else if (r == -ESTRPIPE) { suspend(); } else if (r < 0) { error(_("read error: %s"), snd_strerror(r)); exit(EXIT_FAILURE); } if (r > 0) { if (vumeter) compute_max_peak(data, r * hwparams.channels); result += r; count -= r; data += r * bits_per_frame / 8; } } return rcount; }
int audio_write_alsa(cst_audiodev *ad, void *samples, int num_frames) { size_t frame_size; ssize_t res; snd_pcm_t *pcm_handle; char *buf = (char *) samples; int frames_to_write; frames_to_write = num_frames; pcm_handle = (snd_pcm_t *) ad->platform_data; frame_size = BELL_AUDIO_16BIT * ad->channels; while (frames_to_write > 0) { res = snd_pcm_writei(pcm_handle, buf, frames_to_write); //Note pcm_handle open in blocked mode if (res != frames_to_write) { if (res > 0 && res < frames_to_write) { snd_pcm_wait(pcm_handle, 100); } else if (recover_from_error(pcm_handle, res) < 0) { return -1; } } if (res >0) { frames_to_write -= res; buf += res * frame_size; } } return num_frames; }
static int write_to_pcm(int size, const struct snd_pcm_container *sndpcm, int offset) { int err; while (size > 0) { err = snd_pcm_writei(sndpcm->handle, sndpcm->buffer + offset, size); if (err == -EAGAIN || (err >= 0 && err < size)) { snd_pcm_wait(sndpcm->handle, 500); } else if (err == -EPIPE) { loge(E_WRITEPCM S_UNDERRUN, "%s(%d)", snd_strerror(err), err); snd_pcm_prepare(sndpcm->handle); } else if (err < 0) { loge(E_WRITEPCM, "%s(%d)", snd_strerror(err), err); return -1; } if (err > 0) { size -= err; offset += err * sndpcm->frame_bits / 8; } } return 0; }
static int read_from_pcm(struct pcm_container *sndpcm, int frames, struct bat *bat) { int err = 0; int offset = 0; int remain = frames; while (remain > 0) { err = snd_pcm_readi(sndpcm->handle, sndpcm->buffer + offset, remain); if (err == -EAGAIN || (err >= 0 && err < remain)) { snd_pcm_wait(sndpcm->handle, 500); } else if (err == -EPIPE) { snd_pcm_prepare(sndpcm->handle); fprintf(bat->err, _("Overrun: %s(%d)\n"), snd_strerror(err), err); } else if (err < 0) { fprintf(bat->err, _("Read PCM device error: %s(%d)\n"), snd_strerror(err), err); return err; } if (err > 0) { remain -= err; offset += err * sndpcm->frame_bits / 8; } } return 0; }
static ssize_t pcm_write (short *data, size_t count) { ssize_t r; ssize_t result = 0; while (count > 0) { r = snd_pcm_writei (AHandle, data, count); if (r == -EAGAIN || (r >= 0 && (size_t) r < count)) { snd_pcm_wait (AHandle, 1000); } else if (r == -EPIPE) { xrun (); } else if (r == -ESTRPIPE) { suspend (); } else if (r < 0) { fprintf (stderr, "write error: %s", snd_strerror (r)); exit (EXIT_FAILURE); } if (r > 0) { result += r; count -= r; data += r; } } return result; }
static size_t pcm_read(snd_pcm_uframes_t chunk_size, u_char *data, size_t rcount) { ssize_t r; size_t result = 0; size_t count = rcount; if (count != chunk_size) { count = chunk_size; } while (count > 0) { r = snd_pcm_readi(handle, data, count); if (r == -EAGAIN || (r >= 0 && (size_t)r < count)) { snd_pcm_wait(handle, 1000); }else if (r == -EPIPE){ xrun(SND_PCM_STREAM_CAPTURE); }else if (r < 0) { printf("read error: %s", snd_strerror(r)); exit(EXIT_FAILURE); } if (r > 0) { result += r; count -= r; data += r * bits_per_frame / 8; } } return result; }
qint64 OutputALSA::writeAudio(unsigned char *data, qint64 maxSize) { if((maxSize = qMin(maxSize, m_prebuf_size - m_prebuf_fill)) > 0) { memmove(m_prebuf + m_prebuf_fill, data, maxSize); m_prebuf_fill += maxSize; } snd_pcm_uframes_t l = snd_pcm_bytes_to_frames(pcm_handle, m_prebuf_fill); while (l >= m_chunk_size) { snd_pcm_wait(pcm_handle, 10); long m; if ((m = alsa_write(m_prebuf, m_chunk_size)) >= 0) { l -= m; m = snd_pcm_frames_to_bytes(pcm_handle, m); // convert frames to bytes m_prebuf_fill -= m; memmove(m_prebuf, m_prebuf + m, m_prebuf_fill); //move data to begin } else return -1; } return maxSize; }
static guint gst_alsasink_write (GstAudioSink * asink, gpointer data, guint length) { GstAlsaSink *alsa; gint err; gint cptr; gint16 *ptr = data; alsa = GST_ALSA_SINK (asink); if (alsa->iec958 && alsa->need_swap) { guint i; GST_DEBUG_OBJECT (asink, "swapping bytes"); for (i = 0; i < length / 2; i++) { ptr[i] = GUINT16_SWAP_LE_BE (ptr[i]); } } GST_LOG_OBJECT (asink, "received audio samples buffer of %u bytes", length); cptr = length / alsa->bytes_per_sample; GST_ALSA_SINK_LOCK (asink); while (cptr > 0) { /* start by doing a blocking wait for free space. Set the timeout * to 4 times the period time */ err = snd_pcm_wait (alsa->handle, (4 * alsa->period_time / 1000)); if (err < 0) { GST_DEBUG_OBJECT (asink, "wait error, %d", err); } else { GST_DELAY_SINK_LOCK (asink); err = snd_pcm_writei (alsa->handle, ptr, cptr); GST_DELAY_SINK_UNLOCK (asink); } GST_DEBUG_OBJECT (asink, "written %d frames out of %d", err, cptr); if (err < 0) { GST_DEBUG_OBJECT (asink, "Write error: %s", snd_strerror (err)); if (err == -EAGAIN) { continue; } else if (xrun_recovery (alsa, alsa->handle, err) < 0) { goto write_error; } continue; } ptr += snd_pcm_frames_to_bytes (alsa->handle, err); cptr -= err; } GST_ALSA_SINK_UNLOCK (asink); return length - (cptr * alsa->bytes_per_sample); write_error: { GST_ALSA_SINK_UNLOCK (asink); return length; /* skip one period */ } }
static int write_device(AudioDevice *ad, unsigned char *data, int size) { ALSA_data *alsa = (ALSA_data *)ad->private_data; snd_pcm_sframes_t r; ssize_t unit = snd_pcm_samples_to_bytes(alsa->fd, 1) * ad->channels; snd_pcm_uframes_t count = size / unit; while (count > 0) { if ((r = snd_pcm_writei(alsa->fd, data, count)) == -EAGAIN) { //debug_message_fnc(" EAGAIN\n"); snd_pcm_wait(alsa->fd, 1000); } else if (r > 0) { //debug_message_fnc(" wrote %d bytes\n", (int)(r * unit)); ad->bytes_written += r * unit; count -= r; data += r * unit; } else if (r == -EPIPE) { debug_message_fnc("EPIPE: "); if (snd_pcm_state(alsa->fd) == SND_PCM_STATE_XRUN) { if ((r = snd_pcm_prepare(alsa->fd)) < 0) { debug_message("failed\n"); warning_fnc("snd_pcm_prepare() failed."); } else { debug_message("OK\n"); } } } else { warning_fnc(" r = %d < 0...\n", (int)r); } } return 1; }
ssize_t SNDWAV_WritePcm(SNDPCMContainer_t *sndpcm, size_t wcount) { ssize_t r; ssize_t result = 0; uint8_t *data = sndpcm->data_buf; if (wcount < sndpcm->chunk_size) { snd_pcm_format_set_silence(sndpcm->format, data + wcount * sndpcm->bits_per_frame / 8, (sndpcm->chunk_size - wcount) * sndpcm->channels); wcount = sndpcm->chunk_size; } while (wcount > 0) { r = snd_pcm_writei(sndpcm->handle, data, wcount); if (r == -EAGAIN || (r >= 0 && (size_t)r < wcount)) { snd_pcm_wait(sndpcm->handle, 1000); } else if (r == -EPIPE) { snd_pcm_prepare(sndpcm->handle); fprintf(stderr, "<<<<<<<<<<<<<<< Buffer Underrun >>>>>>>>>>>>>>>\n"); } else if (r == -ESTRPIPE) { fprintf(stderr, "<<<<<<<<<<<<<<< Need suspend >>>>>>>>>>>>>>>\n"); } else if (r < 0) { fprintf(stderr, "Error snd_pcm_writei: [%s]", snd_strerror(r)); exit(-1); } if (r > 0) { result += r; wcount -= r; data += r * sndpcm->bits_per_frame / 8; } } return result; }
ssize_t SNDWAV_ReadPcm(SNDPCMContainer_t *sndpcm, size_t rcount) { ssize_t r; size_t result = 0; size_t count = rcount; uint8_t *data = sndpcm->data_buf; if (count != sndpcm->chunk_size) { count = sndpcm->chunk_size; } while (count > 0) { r = snd_pcm_readi(sndpcm->handle, data, count); if (r == -EAGAIN || (r >= 0 && (size_t)r < count)) { snd_pcm_wait(sndpcm->handle, 1000); } else if (r == -EPIPE) { snd_pcm_prepare(sndpcm->handle); fprintf(stderr, "<<<<<<<<<<<<<<< Buffer Underrun >>>>>>>>>>>>>>>\n"); } else if (r == -ESTRPIPE) { fprintf(stderr, "<<<<<<<<<<<<<<< Need suspend >>>>>>>>>>>>>>>\n"); } else if (r < 0) { fprintf(stderr, "Error snd_pcm_writei: [%s]", snd_strerror(r)); exit(-1); } if (r > 0) { result += r; count -= r; data += r * sndpcm->bits_per_frame / 8; } } return rcount; }
static ssize_t pcm_write(u_char *data, size_t count) { ssize_t r; ssize_t result = 0; if (sleep_min == 0 && count < chunk_size) { snd_pcm_format_set_silence(hwparams.format, data + count * bits_per_frame / 8, (chunk_size - count) * hwparams.channels); count = chunk_size; } while (count > 0) { r = snd_pcm_writei(handle, data, count); if (r == -EAGAIN || (r >= 0 && (size_t)r < count)) { snd_pcm_wait(handle, 1000); } else if (r == -EPIPE) { xrun(); } else if (r == -ESTRPIPE) { suspend(); } else if (r < 0) { error(_("write error: %s"), snd_strerror(r)); exit(EXIT_FAILURE); } if (r > 0) { result += r; count -= r; data += r * bits_per_frame / 8; } } return result; }
static snd_pcm_t *open_audiofd( char *device_name, int capture, int rate, int channels, int period, int nperiods ) { int err; snd_pcm_t *handle; snd_pcm_hw_params_t *hwparams; snd_pcm_sw_params_t *swparams; snd_pcm_hw_params_alloca(&hwparams); snd_pcm_sw_params_alloca(&swparams); if ((err = snd_pcm_open(&(handle), device_name, capture ? SND_PCM_STREAM_CAPTURE : SND_PCM_STREAM_PLAYBACK, SND_PCM_NONBLOCK )) < 0) { printf("Capture open error: %s\n", snd_strerror(err)); return NULL; } if ((err = set_hwparams(handle, hwparams,SND_PCM_ACCESS_RW_INTERLEAVED, rate, channels, period, nperiods )) < 0) { printf("Setting of hwparams failed: %s\n", snd_strerror(err)); return NULL; } if ((err = set_swparams(handle, swparams, period)) < 0) { printf("Setting of swparams failed: %s\n", snd_strerror(err)); return NULL; } snd_pcm_start( handle ); snd_pcm_wait( handle, 200 ); return handle; }
void PAPlayer::WaitForStream() { // should we wait for our other stream as well? // currently we don't. if (!m_pStream[m_currentStream]) { snd_pcm_wait(m_pStream[m_currentStream], -1); } }
void write( const char *data, qint64 len ) { if ( !handle ) return; int count=0; qLog(QAudioOutput)<<"frames to write out = "<< snd_pcm_bytes_to_frames( handle, (int)len )<<" ("<<len<<") bytes"; while ( len > 0 ) { int err=0; int frames = snd_pcm_bytes_to_frames( handle, (int)len ); #ifdef ALSA_USE_AVAILABLE if(frames < (int)period_size) return; int available = snd_pcm_avail_update(handle); qLog(QAudioOutput) <<"available space = "<<available; if(available == 0) { while(available < frames) { snd_pcm_wait(handle,period_size/1000); usleep(period_size*10); available = snd_pcm_avail_update(handle); qLog(QAudioOutput) <<"->available space = "<<available; count++; if((count > 5)||(available < 0)) return; } } #endif err = snd_pcm_writei( handle, data, frames ); // Handle errors if ( err >= 0 ) { if(err == 0) count++; int bytes = snd_pcm_frames_to_bytes( handle, err ); qLog(QAudioOutput) << QString("write out = %1").arg(bytes).toLatin1().constData(); data += bytes; len -= bytes; } else { count++; qLog(QAudioOutput) <<"err = "<<err; err = xrun_recovery(err); } if(count > 5) { qLog(QAudioOutput) <<"failing to write, close() and re-open() to try and recover!"; close(); open(); snd_pcm_prepare(handle); break; } } }
/* Play from alsa_buf as many chunks as possible. Move the remaining data * to the beginning of the buffer. Return the number of bytes written * or -1 on error. */ static int play_buf_chunks () { int written = 0; while (alsa_buf_fill >= chunk_size) { int err; err = snd_pcm_writei (handle, alsa_buf + written, chunk_size / bytes_per_frame); if (err == -EAGAIN) { if (snd_pcm_wait(handle, 500) < 0) logit ("snd_pcm_wait() failed"); } else if (err == -EPIPE) { logit ("underrun!"); if ((err = snd_pcm_prepare(handle)) < 0) { error ("Can't recover after underrun: %s", snd_strerror(err)); /* TODO: reopen the device */ return -1; } } else if (err == -ESTRPIPE) { logit ("Suspend, trying to resume"); while ((err = snd_pcm_resume(handle)) == -EAGAIN) sleep (1); if (err < 0) { logit ("Failed, restarting"); if ((err = snd_pcm_prepare(handle)) < 0) { error ("Failed to restart " "device: %s.", snd_strerror(err)); return -1; } } } else if (err < 0) { error ("Can't play: %s", snd_strerror(err)); return -1; } else { int written_bytes = err * bytes_per_frame; written += written_bytes; alsa_buf_fill -= written_bytes; debug ("Played %d bytes", written_bytes); } } debug ("%d bytes remain in alsa_buf", alsa_buf_fill); memmove (alsa_buf, alsa_buf + written, alsa_buf_fill); return written * bytes_per_frame; }
void SoundOutput_alsa::wait() { if(handle == nullptr) { System::sleep(100); return; } /* wait upto 1 second */ snd_pcm_wait(handle, 1000); }
void CL_SoundOutput_alsa::wait() { if(handle == NULL) { CL_System::sleep(100); return; } /* wait upto 1 second */ snd_pcm_wait(handle, 1000); }
void AlsaLayer::audioCallback() { if (!playbackHandle_ or !captureHandle_) return; notifyIncomingCall(); snd_pcm_wait(playbackHandle_, 20); int playbackAvailFrames = 0; if (not safeUpdate(playbackHandle_, playbackAvailFrames)) return; unsigned framesToGet = urgentRingBuffer_.availableForGet(MainBuffer::DEFAULT_ID); if (framesToGet > 0) { // Urgent data (dtmf, incoming call signal) come first. framesToGet = std::min(framesToGet, (unsigned)playbackAvailFrames); playbackBuff_.setFormat(audioFormat_); playbackBuff_.resize(framesToGet); urgentRingBuffer_.get(playbackBuff_, MainBuffer::DEFAULT_ID); playbackBuff_.applyGain(isPlaybackMuted_ ? 0.0 : playbackGain_); playbackBuff_.interleave(playbackIBuff_); write(playbackIBuff_.data(), framesToGet, playbackHandle_); // Consume the regular one as well (same amount of frames) Manager::instance().getMainBuffer().discard(framesToGet, MainBuffer::DEFAULT_ID); } else { // regular audio data playback(playbackAvailFrames); } if (ringtoneHandle_) { AudioLoop *file_tone = Manager::instance().getTelephoneFile(); int ringtoneAvailFrames = 0; if (not safeUpdate(ringtoneHandle_, ringtoneAvailFrames)) return; playbackBuff_.setFormat(audioFormat_); playbackBuff_.resize(ringtoneAvailFrames); if (file_tone) { DEBUG("playback gain %d", playbackGain_); file_tone->getNext(playbackBuff_, playbackGain_); } playbackBuff_.interleave(playbackIBuff_); write(playbackIBuff_.data(), ringtoneAvailFrames, ringtoneHandle_); } // Additionally handle the mic's audio stream if (is_capture_running_) capture(); }
static int alsa_audio_deliver(audio_decoder_t *ad, int samples, int64_t pts, int epoch) { decoder_t *d = (decoder_t *)ad; media_pipe_t *mp = ad->ad_mp; int c; retry: c = snd_pcm_wait(d->h, 100); if(c >= 0) { c = snd_pcm_avail_update(d->h); } if(c == -EPIPE) { snd_pcm_prepare(d->h); usleep(100000); TRACE(TRACE_DEBUG, "ALSA", "Audio underrun"); d->samples = 0; goto retry; } c = MIN(d->max_frames_per_write, c); uint8_t *planes[8] = {0}; planes[0] = d->tmp; c = avresample_read(ad->ad_avr, planes, c); snd_pcm_status_t *status; int err; snd_pcm_status_alloca(&status); if ((err = snd_pcm_status(d->h, status)) >= 0) { if(pts != AV_NOPTS_VALUE) { snd_htimestamp_t hts; snd_pcm_status_get_trigger_htstamp(status, &hts); int64_t ts = hts.tv_sec * 1000000LL + hts.tv_nsec / 1000; ts += d->samples * 1000000LL / ad->ad_out_sample_rate; hts_mutex_lock(&mp->mp_clock_mutex); mp->mp_audio_clock_avtime = ts; mp->mp_audio_clock = pts; mp->mp_audio_clock_epoch = epoch; hts_mutex_unlock(&mp->mp_clock_mutex); } } snd_pcm_sframes_t fr; if(!snd_pcm_delay(d->h, &fr)) ad->ad_delay = 1000000L * fr / ad->ad_out_sample_rate; c = snd_pcm_writei(d->h, d->tmp, c); d->samples += c; return 0; }
unsigned int CAESinkALSA::AddPackets(uint8_t *data, unsigned int frames, bool hasAudio, bool blocking) { if (!m_pcm) { SoftResume(); if(!m_pcm) return 0; CLog::Log(LOGDEBUG, "CAESinkALSA - the grAEken is hunger, feed it (I am the downmost fallback - fix your code)"); } int ret; ret = snd_pcm_avail(m_pcm); if (ret < 0) { HandleError("snd_pcm_avail", ret); ret = 0; } if ((unsigned int)ret < frames) { if(blocking) { ret = snd_pcm_wait(m_pcm, m_timeout); if (ret < 0) HandleError("snd_pcm_wait", ret); } else return 0; } ret = snd_pcm_writei(m_pcm, (void*)data, frames); if (ret < 0) { HandleError("snd_pcm_writei(1)", ret); ret = snd_pcm_writei(m_pcm, (void*)data, frames); if (ret < 0) { HandleError("snd_pcm_writei(2)", ret); ret = 0; } } if ( ret > 0 && snd_pcm_state(m_pcm) == SND_PCM_STATE_PREPARED) snd_pcm_start(m_pcm); return ret; }
int aplaypop() { if (pcm_handle == NULL && aplaypop_open() != 0) return -1; fprintf(stderr, "snd_pcm_state() = %s\n", snd_pcm_state_name(snd_pcm_state(pcm_handle))); int err = snd_pcm_prepare(pcm_handle); if (err != 0) { fprintf(stderr, "snd_pcm_start(): %s\n", snd_strerror(err)); return -1; } int16_t *ptr = (int16_t *)bin_data; int len = sizeof(bin_data) / frame_bytes; while (len > 0) { // The unit of the buffersize depends on the function. Sometimes it is // given in bytes, sometimes the number of frames has to be specified. // One frame is the sample data vector for all channels. // For 16 Bit stereo data, one frame has a length of four bytes. snd_pcm_sframes_t frames = snd_pcm_writei(pcm_handle, ptr, len); fprintf(stderr, " snd_pcm_writei(h, ptr, %d) = %ld\n", len, frames); if (frames == -EAGAIN) { frames = 0; } else if (frames < 0) { // -EPIPE, -ESTRPIPE frames = snd_pcm_recover(pcm_handle, frames, 1/*silent*/); if (frames < 0) { fprintf(stderr, "writei/recover failed: %s\n", snd_strerror(err)); break; } } else if (frames < len) { fprintf(stderr, "Short write (expected %d, wrote %ld)\n", len, frames); } else { break; // All done } len -= frames * frame_bytes; ptr += frames * frame_bytes; snd_pcm_wait(pcm_handle, 10/*ms*/); } err = snd_pcm_drain(pcm_handle); if (err != 0) { fprintf(stderr, "snd_pcm_start(): %s\n", snd_strerror(err)); return -1; } return 0; }
/***************************************************************************** * Demux: Processes the audio frame *****************************************************************************/ static int Demux( demux_t *p_demux ) { demux_sys_t *p_sys = p_demux->p_sys; block_t *p_block = NULL; do { if( p_block ) { es_out_Send( p_demux->out, p_sys->p_es, p_block ); p_block = NULL; } /* Wait for data */ int i_wait = snd_pcm_wait( p_sys->p_alsa_pcm, 10 ); /* See poll() comment in oss.c */ switch( i_wait ) { case 1: { p_block = GrabAudio( p_demux ); if( p_block ) es_out_Control( p_demux->out, ES_OUT_SET_PCR, p_block->i_pts ); } /* FIXME: this is a copy paste from below. Shouldn't be needed * twice. */ case -EPIPE: /* xrun */ snd_pcm_prepare( p_sys->p_alsa_pcm ); break; case -ESTRPIPE: { /* suspend */ int i_resume = snd_pcm_resume( p_sys->p_alsa_pcm ); if( i_resume < 0 && i_resume != -EAGAIN ) snd_pcm_prepare( p_sys->p_alsa_pcm ); break; } /* </FIXME> */ } } while( p_block && p_sys->i_next_demux_date > 0 && p_block->i_pts < p_sys->i_next_demux_date ); if( p_block ) es_out_Send( p_demux->out, p_sys->p_es, p_block ); return 1; }
BOOL auTransferData(Audio* self, snd_pcm_sframes_t (*transfer)(snd_pcm_t*, void*, snd_pcm_uframes_t)) { int numFramesTransferred = 0, error = 0; int numFramesLeft = self->bufferNumFrames; auSample_t* p = self->sampleBuffer; while((numFramesLeft > 0) && self->threadShouldContinueRunning) { error = numFramesTransferred = transfer(self->device, p, numFramesLeft); if(numFramesTransferred < 0) { //fprintf(stderr, "Audio.c: audio device error while transferring samples: %s, attempting to recover... ", snd_strerror(error)); switch(error) { case -EPIPE: //overflow / underflow snd_pcm_wait(self->device, 100); if((error = snd_pcm_avail(self->device)) < 0) //broken pipe usleep(10000); //wait for more samples to come else numFramesLeft = 0; //overrun, skip remaining samples; error = snd_pcm_prepare(self->device); break; case -ESTRPIPE: while(((error = snd_pcm_resume(self->device)) == -EAGAIN) && self->threadShouldContinueRunning) sleep(1); if(error == -ENOSYS) error = snd_pcm_prepare(self->device); break; } if(error < 0) { //fprintf(stderr, "Aborting\n"); self->threadShouldContinueRunning = NO; break; } else { //fprintf(stderr, "Okay\n"); numFramesTransferred = 0; } } p += numFramesTransferred * self->numChannels; numFramesLeft -= numFramesTransferred; } return (numFramesLeft == 0) ? YES : NO; }
snd_pcm_sframes_t XcapAlsaReadiQueue::readi(snd_pcm_t *handle, unsigned char *samples, int chunksize, int queue) { unsigned char *qdata; snd_pcm_sframes_t ret = 0; // not initialized or error if(n == 0 || this->chunksize != chunksize) return -1; if(samples == NULL) return 0; // no more queue if(queue==0) { // queue is empty if(datapool.size() == 0) return snd_pcm_readi(handle, samples, chunksize); // queue is not empty, dequeue qdata = datapool.front(); ret = *((snd_pcm_sframes_t*) qdata); bcopy(qdata+sizeof(snd_pcm_sframes_t), samples, this->chunkbyte); datapool.pop_front(); freepool.push_front(qdata); } // read and queue if(freepool.size() == 0) { ga_error("AlsaReadiQueue: no more queue, dropping eldest\n"); qdata = datapool.front(); datapool.pop_front(); } else { qdata = freepool.front(); freepool.pop_front(); } *((snd_pcm_sframes_t*) qdata) = snd_pcm_readi(handle, qdata+sizeof(snd_pcm_sframes_t), chunksize); if(*((snd_pcm_sframes_t*) qdata) < 0) { freepool.push_front(qdata); if(ret > 0 && *((snd_pcm_sframes_t*) qdata) == -EAGAIN) { ga_error("DEBUG: snd_pcm_wait in queue->readi (qsize=%d)\n", datapool.size()); snd_pcm_wait(handle, 1000); return ret; } return *((snd_pcm_sframes_t*) qdata); } datapool.push_back(qdata); // return ret; }
void *write_pcmdata(void *arg) { dbg("Enter write_pcmdata thread.....\n"); int ret; msg_t pcm_data; snd_pcm_sframes_t avail; common_data_t *p_common_data = (common_data_t *)arg; dbg("PCM handle name = '%s'\n",snd_pcm_name(p_common_data->handle)); dbg("period szie = %lu\n",p_common_data->period_size); while (1) { sem_wait(&p_common_data->queue.wait); if((read_item_from_queue(&p_common_data->queue, &pcm_data)) == EMPTY){ dbg("queue is empty...\n"); //TODO:block? continue; } snd_pcm_prepare(p_common_data->handle); ret = snd_pcm_writei(p_common_data->handle, pcm_data.pcm_msg, p_common_data->period_size); if (ret == -EAGAIN) { //means try again /* wait 1000ms for pcm device to become ready */ dbg_alsa("EAGAIN error, Sleep for 1000ms\n"); snd_pcm_wait(p_common_data->handle, 1000); } else if (ret == -EPIPE) { /* EPIPE means underrun */ snd_pcm_prepare(p_common_data->handle); dbg_alsa("underrun occurred\n"); } else if(ret == -ESTRPIPE) { dbg_alsa("Need suspend\n"); } else if (ret < 0) { dbg_alsa("error from writei: %s\n", snd_strerror(ret)); } ret = snd_pcm_state(p_common_data->handle); dbg("state is %d\n", ret); sem_post(&p_common_data->queue.full); } }
static void* alsa_audio_start(void *aux) { audio_fifo_t *af = aux; snd_pcm_t *h = NULL; int c; int cur_channels = 0; int cur_rate = 0; audio_fifo_data_t *afd; for (;;) { afd = audio_get(af); if (!h || cur_rate != afd->rate || cur_channels != afd->channels) { if (h) snd_pcm_close(h); cur_rate = afd->rate; cur_channels = afd->channels; h = alsa_open("default", cur_rate, cur_channels); if (!h) { fprintf(stderr, "Unable to open ALSA device (%d channels, %d Hz), dying\n", cur_channels, cur_rate); exit(1); } } c = snd_pcm_wait(h, 1000); if (c >= 0) c = snd_pcm_avail_update(h); if (c == -EPIPE) snd_pcm_prepare(h); snd_pcm_writei(h, afd->samples, afd->nsamples); writeFile( &afd->samples ); zfree(afd); } }
void * asource_threadproc(void *arg) { int r; unsigned char *fbuffer; // if(asource_init(NULL) < 0) { exit(-1); } if((fbuffer = (unsigned char*) malloc(audioparam.chunk_bytes)) == NULL) { ga_error("Audio source: malloc failed (%d bytes) - %s\n", audioparam.chunk_bytes, strerror(errno)); exit(-1); } // ga_error("Audio source thread started: tid=%ld\n", ga_gettid()); // while(true) { #ifdef WIN32 r = ga_wasapi_read(&audioparam, fbuffer, audioparam.chunk_size); if(r < 0) { ga_error("Audio source: WASAPI read failed.\n"); break; } #else r = snd_pcm_readi(audioparam.handle, fbuffer, audioparam.chunk_size); if(r == -EAGAIN) { snd_pcm_wait(audioparam.handle, 1000); continue; } else if(r < 0) { ga_error("Audio source: ALSA read failed - %s\n", snd_strerror(r)); break; } #endif audio_source_buffer_fill(fbuffer, r); } // ga_error("audio capture thread terminated.\n"); // return NULL; }