コード例 #1
0
static void play(short buf[], int samples) {
  int ret = 0;
  if (alsa_handle == NULL) {
    ret = open_alsa_device();
    if ((ret == 0) && (audio_alsa.volume))
      audio_alsa.volume(set_volume);
  }
  if (ret == 0) {
    pthread_mutex_lock(&alsa_mutex);
    snd_pcm_sframes_t current_delay = 0;
    int err, ignore;
    if ((snd_pcm_state(alsa_handle) == SND_PCM_STATE_PREPARED) ||
        (snd_pcm_state(alsa_handle) == SND_PCM_STATE_RUNNING)) {
      err = snd_pcm_writei(alsa_handle, (char *)buf, samples);
      if (err < 0) {
        ignore = snd_pcm_recover(alsa_handle, err, 0);
        debug(1, "Error %d writing %d samples in play() %s.", err, samples, snd_strerror(err));
      }
    } else {
      debug(1, "Error -- ALSA device in incorrect state (%d) for play.",
            snd_pcm_state(alsa_handle));
      if ((err = snd_pcm_prepare(alsa_handle))) {
        ignore = snd_pcm_recover(alsa_handle, err, 0);
        debug(1, "Error preparing after play error: %s.", snd_strerror(err));
      }
    }
    pthread_mutex_unlock(&alsa_mutex);
  }
}
コード例 #2
0
static uint32_t delay() {
  if (alsa_handle == NULL) {
    return 0;
  } else {
    pthread_mutex_lock(&alsa_mutex);
    snd_pcm_sframes_t current_avail, current_delay = 0;
    int derr, ignore;
    if (snd_pcm_state(alsa_handle) == SND_PCM_STATE_RUNNING) {
      derr = snd_pcm_avail_delay(alsa_handle, &current_avail, &current_delay);
      // current_avail not used
      if (derr != 0) {
        ignore = snd_pcm_recover(alsa_handle, derr, 0);
        debug(1, "Error %d in delay(): %s. Delay reported is %d frames.", derr, snd_strerror(derr),
              current_delay);
        current_delay = -1;
      }
    } else if (snd_pcm_state(alsa_handle) == SND_PCM_STATE_PREPARED) {
      current_delay = 0;
    } else {
      if (snd_pcm_state(alsa_handle) == SND_PCM_STATE_XRUN)
        current_delay = 0;
      else {
        current_delay = -1;
        debug(1, "Error -- ALSA delay(): bad state: %d.", snd_pcm_state(alsa_handle));
      }
      if ((derr = snd_pcm_prepare(alsa_handle))) {
        ignore = snd_pcm_recover(alsa_handle, derr, 0);
        debug(1, "Error preparing after delay error: %s.", snd_strerror(derr));
        current_delay = -1;
      }
    }
    pthread_mutex_unlock(&alsa_mutex);
    return current_delay;
  }
}
コード例 #3
0
ファイル: alsa.c プロジェクト: ColdPie1/openal-soft
static int verify_state(snd_pcm_t *handle)
{
    snd_pcm_state_t state = snd_pcm_state(handle);
    int err;

    switch(state)
    {
        case SND_PCM_STATE_OPEN:
        case SND_PCM_STATE_SETUP:
        case SND_PCM_STATE_PREPARED:
        case SND_PCM_STATE_RUNNING:
        case SND_PCM_STATE_DRAINING:
        case SND_PCM_STATE_PAUSED:
            /* All Okay */
            break;

        case SND_PCM_STATE_XRUN:
            if((err=snd_pcm_recover(handle, -EPIPE, 1)) < 0)
                return err;
            break;
        case SND_PCM_STATE_SUSPENDED:
            if((err=snd_pcm_recover(handle, -ESTRPIPE, 1)) < 0)
                return err;
            break;
        case SND_PCM_STATE_DISCONNECTED:
            return -ENODEV;
    }

    return state;
}
コード例 #4
0
ファイル: audio.c プロジェクト: sobkas/usbrevue
static void * audio_thread_f(void *V) {
  int16_t inbuf[BUFFER_SIZE], outbuf[BUFFER_SIZE];
  int frames;
  audio_callback_t callback = (audio_callback_t) V;

  while (audio_thread_running) {
    frames = snd_pcm_readi(capture_handle, inbuf, BUFFER_SIZE);
    if (frames < 0)
      snd_pcm_recover(capture_handle, frames, 0);
    else if (frames != BUFFER_SIZE)
      fprintf(stderr, "read %d/%d frames\n", frames, BUFFER_SIZE);

    callback(inbuf, outbuf, BUFFER_SIZE);

    frames = snd_pcm_writei(playback_handle, outbuf, BUFFER_SIZE);
    if (frames < 0) {
      snd_pcm_recover(playback_handle, frames, 0);
    } else if (frames != BUFFER_SIZE)
      fprintf(stderr, "wrote %d/%d frames\n", frames, BUFFER_SIZE);
  }

  snd_pcm_drop(playback_handle);
  snd_pcm_close(playback_handle);
  snd_pcm_drop(capture_handle);
  snd_pcm_close(capture_handle);
  return NULL;
}
コード例 #5
0
ファイル: alsa.c プロジェクト: 9heart/DT3
static ALCuint alsa_available_samples(ALCdevice *Device)
{
    alsa_data *data = (alsa_data*)Device->ExtraData;
    snd_pcm_sframes_t avail;

    avail = (Device->Connected ? snd_pcm_avail_update(data->pcmHandle) : 0);
    if(avail < 0)
    {
        ERR("avail update failed: %s\n", snd_strerror(avail));

        if((avail=snd_pcm_recover(data->pcmHandle, avail, 1)) >= 0)
        {
            if(data->doCapture)
                avail = snd_pcm_start(data->pcmHandle);
            if(avail >= 0)
                avail = snd_pcm_avail_update(data->pcmHandle);
        }
        if(avail < 0)
        {
            ERR("restore error: %s\n", snd_strerror(avail));
            aluHandleDisconnect(Device);
        }
    }
    while(avail > 0)
    {
        snd_pcm_sframes_t amt;

        amt = snd_pcm_bytes_to_frames(data->pcmHandle, data->size);
        if(avail < amt) amt = avail;

        amt = snd_pcm_readi(data->pcmHandle, data->buffer, amt);
        if(amt < 0)
        {
            ERR("read error: %s\n", snd_strerror(amt));

            if(amt == -EAGAIN)
                continue;
            if((amt=snd_pcm_recover(data->pcmHandle, amt, 1)) >= 0)
            {
                if(data->doCapture)
                    amt = snd_pcm_start(data->pcmHandle);
                if(amt >= 0)
                    amt = snd_pcm_avail_update(data->pcmHandle);
            }
            if(amt < 0)
            {
                ERR("restore error: %s\n", snd_strerror(amt));
                aluHandleDisconnect(Device);
                break;
            }
            avail = amt;
            continue;
        }

        WriteRingBuffer(data->ring, data->buffer, amt);
        avail -= amt;
    }

    return RingBufferSize(data->ring);
}
コード例 #6
0
    bool readFromInputDevice (AudioBuffer<float>& inputChannelBuffer, const int numSamples)
    {
        jassert (numChannelsRunning <= inputChannelBuffer.getNumChannels());
        float* const* const data = inputChannelBuffer.getArrayOfWritePointers();

        if (isInterleaved)
        {
            scratch.ensureSize ((size_t) ((int) sizeof (float) * numSamples * numChannelsRunning), false);
            scratch.fillWith (0); // (not clearing this data causes warnings in valgrind)

            auto num = snd_pcm_readi (handle, scratch.getData(), (snd_pcm_uframes_t) numSamples);

            if (num < 0)
            {
                if (num == -(EPIPE))
                    overrunCount++;

                if (JUCE_ALSA_FAILED (snd_pcm_recover (handle, (int) num, 1 /* silent */)))
                    return false;
            }


            if (num < numSamples)
                JUCE_ALSA_LOG ("Did not read all samples: num: " << num << ", numSamples: " << numSamples);

            for (int i = 0; i < numChannelsRunning; ++i)
                converter->convertSamples (data[i], 0, scratch.getData(), i, numSamples);
        }
        else
        {
            auto num = snd_pcm_readn (handle, (void**) data, (snd_pcm_uframes_t) numSamples);

            if (num < 0)
            {
                if (num == -(EPIPE))
                    overrunCount++;

                if (JUCE_ALSA_FAILED (snd_pcm_recover (handle, (int) num, 1 /* silent */)))
                    return false;
            }

            if (num < numSamples)
                JUCE_ALSA_LOG ("Did not read all samples: num: " << num << ", numSamples: " << numSamples);

            for (int i = 0; i < numChannelsRunning; ++i)
                converter->convertSamples (data[i], data[i], numSamples);
        }

        return true;
    }
コード例 #7
0
static bool_t alsa_can_read(snd_pcm_t *dev, int frames)
{
	snd_pcm_sframes_t avail;
	int err;

	avail = snd_pcm_avail_update(dev);
	ms_debug("*** %s %d %d", __FUNCTION__, (long)avail, frames);
	if (avail < 0) {
		ms_error("snd_pcm_avail_update: %s\n", snd_strerror(avail));	// most probably -EPIPE
		/* overrun occured, snd_pcm_state() would return SND_PCM_STATE_XRUN
		 FIXME: handle other error conditions*/
		ms_error("*** alsa_can_read fixup, trying to recover");
		snd_pcm_drain(dev); /* Ignore possible error, at least -EAGAIN.*/
		err = snd_pcm_recover(dev, avail, 0);
		if (err){ 
			ms_error("snd_pcm_recover() failed with err %d: %s", err, snd_strerror(err));
			return FALSE;
		}
		err = snd_pcm_start(dev);
		if (err){ 
			ms_error("snd_pcm_start() failed with err %d: %s\n", err, snd_strerror(err)); 
			return FALSE; 
		}
		ms_message("Recovery done\n");
	}
	return avail >= frames;
}
コード例 #8
0
ファイル: pcm.c プロジェクト: kuoney/pcm_example
int main(void)
{
	int err;
	unsigned int i;
	snd_pcm_t *handle;
	snd_pcm_sframes_t frames;
	fill_buffer(buffer);
	if ((err = snd_pcm_open(&handle, device, SND_PCM_STREAM_PLAYBACK, 0)) < 0) {
		printf("Playback open error: %s\n", snd_strerror(err));
		exit(EXIT_FAILURE);
	}
	if ((err = snd_pcm_set_params(handle,
					SND_PCM_FORMAT_U8,
					SND_PCM_ACCESS_RW_INTERLEAVED,
					1,
					11025,
					1,
					500000)) < 0) { /* 0.5sec */
		printf("Playback open error: %s\n", snd_strerror(err));
		exit(EXIT_FAILURE);
	}
	for (i = 0; i < 4; i++) {
		frames = snd_pcm_writei(handle, buffer, sizeof(buffer));
		if (frames < 0)
			frames = snd_pcm_recover(handle, frames, 0);
		if (frames < 0) {
			printf("snd_pcm_writei failed: %s\n", snd_strerror(err));
			break;
		}
		if (frames > 0 && frames < (long)sizeof(buffer))
			printf("Short write (expected %li, wrote %li)\n", (long)sizeof(buffer), frames);
	}
	snd_pcm_close(handle);
	return 0;
}
コード例 #9
0
ファイル: audio_alsa.c プロジェクト: mbedarff/shairport
static void play(short buf[], int samples) {
    int err = snd_pcm_writei(alsa_handle, (char*)buf, samples);
    if (err < 0)
        err = snd_pcm_recover(alsa_handle, err, 0);
    if (err < 0)
        die("Failed to write to PCM device: %s\n", snd_strerror(err));
}
コード例 #10
0
ファイル: alsa.c プロジェクト: TheBaobabTeam/linphone-android
static int alsa_can_read(snd_pcm_t *dev)
{
	snd_pcm_sframes_t avail;
	int err;

	alsa_resume(dev);
	avail = snd_pcm_avail_update(dev);
	/* A buggy driver does not return an error while being in Xrun */
	if (avail >= 0 && snd_pcm_state(dev) == SND_PCM_STATE_XRUN) avail=-EPIPE;
	if (avail < 0) {
		ms_error("snd_pcm_avail_update: %s", snd_strerror(avail));	// most probably -EPIPE
		/* overrun occured, snd_pcm_state() would return SND_PCM_STATE_XRUN
		 FIXME: handle other error conditions*/
		ms_error("*** alsa_can_read fixup, trying to recover");
		snd_pcm_drain(dev); /* Ignore possible error, at least -EAGAIN.*/
		err = snd_pcm_recover(dev, avail, 0);
		if (err){
			ms_error("snd_pcm_recover() failed with err %d: %s", err, snd_strerror(err));
			return -1;
		}
		err = snd_pcm_start(dev);
		if (err){
			ms_error("snd_pcm_start() failed with err %d: %s", err, snd_strerror(err));
			return -1;
		}
		ms_message("Recovery done");
	}
	return avail;
}
コード例 #11
0
ファイル: alsalayer.cpp プロジェクト: ThereIsNoYeti/sflphone
// TODO first frame causes broken pipe (underrun) because not enough data is sent
// we should wait until the handle is ready
void
AlsaLayer::write(SFLAudioSample* buffer, int frames, snd_pcm_t * handle)
{
    // Skip empty buffers
    if (!frames)
        return;

    int err = snd_pcm_writei(handle, (const void*)buffer, frames);

    if (err < 0)
        snd_pcm_recover(handle, err, 0);

    if (err >= 0)
        return;

    switch (err) {

        case -EPIPE:
        case -ESTRPIPE:
        case -EIO: {
            snd_pcm_status_t* status;
            snd_pcm_status_alloca(&status);

            if (ALSA_CALL(snd_pcm_status(handle, status), "Cannot get playback handle status") >= 0)
                if (snd_pcm_status_get_state(status) == SND_PCM_STATE_XRUN) {
                    stopPlaybackStream();
                    preparePlaybackStream();
                    startPlaybackStream();
                }

            ALSA_CALL(snd_pcm_writei(handle, (const void*)buffer, frames), "XRUN handling failed");
            break;
        }

        case -EBADFD: {
            snd_pcm_status_t* status;
            snd_pcm_status_alloca(&status);

            if (ALSA_CALL(snd_pcm_status(handle, status), "Cannot get playback handle status") >= 0) {
                if (snd_pcm_status_get_state(status) == SND_PCM_STATE_SETUP) {
                    ERROR("Writing in state SND_PCM_STATE_SETUP, should be "
                          "SND_PCM_STATE_PREPARED or SND_PCM_STATE_RUNNING");
                    int error = snd_pcm_prepare(handle);

                    if (error < 0) {
                        ERROR("Failed to prepare handle: %s", snd_strerror(error));
                        stopPlaybackStream();
                    }
                }
            }

            break;
        }

        default:
            ERROR("Unknown write error, dropping frames: %s", snd_strerror(err));
            stopPlaybackStream();
            break;
    }
}
コード例 #12
0
TErrors SalsaStream::read(llaAudioPipe& buffer) {
	if(pcm_state_ == CLOSED) {
		LOGGER().warning(E_READ_STREAM, "Attempt to write to a closed stream.");
		return E_READ_STREAM;
	}

	TErrors err;
	if( (err = updateSettings(buffer)) != E_OK) return err;


	char *iraw, **niraw;
	int rc;
	getRawInputBuffers(buffer, &iraw, &niraw);

	if(organization_ == SND_PCM_ACCESS_RW_NONINTERLEAVED) {
		rc = snd_pcm_readn(pcm_, (void**)niraw, buffer.getBufferLength());

	}
	else {
		rc = snd_pcm_readi(pcm_, (void*)iraw, buffer.getBufferLength());
	}

	setBufferLastWrite(buffer, rc);
	if (rc == -EPIPE) {
	  /* EPIPE means underrun */
	  snd_pcm_prepare(pcm_);
	} else if (rc < 0) {
		LOGGER().warning(E_READ_STREAM, snd_strerror(rc));
		snd_pcm_recover(pcm_, rc, 0);
	}


	return E_OK;
}
コード例 #13
0
ファイル: alsa.c プロジェクト: 9heart/DT3
static int xrun_recovery(snd_pcm_t *handle, int err)
{
    err = snd_pcm_recover(handle, err, 1);
    if(err < 0)
        ERR("recover failed: %s\n", snd_strerror(err));
    return err;
}
コード例 #14
0
ファイル: alsa.c プロジェクト: kernelOfTruth/dsp
ssize_t alsa_write(struct codec *c, sample_t *buf, ssize_t frames)
{
	ssize_t n, i = 0;
	struct alsa_state *state = (struct alsa_state *) c->data;

	while (i < frames) {
		n = (frames - i > state->buf_frames) ? state->buf_frames : frames - i;
		state->enc_info->write_func(&buf[i * c->channels], state->buf, n * c->channels);
		try_again:
		n = snd_pcm_writei(state->dev, state->buf, n);
		if (n < 0) {
			if (n == -EPIPE)
				LOG(LL_ERROR, "dsp: alsa: warning: underrun occurred\n");
			n = snd_pcm_recover(state->dev, n, 1);
			if (n < 0) {
				LOG(LL_ERROR, "dsp: alsa: error: write failed\n");
				return i;
			}
			else
				goto try_again;
		}
		i += n;
	}
	return i;
}
コード例 #15
0
ファイル: ALSAPCMPlayer.cpp プロジェクト: Advi42/XCSoar
bool
ALSAPCMPlayer::TryRecoverFromError(snd_pcm_t &alsa_handle, int error)
{
  assert(error < 0);

  if (-EPIPE == error)
    LogFormat("ALSA PCM buffer underrun");
  else if ((-EINTR == error) || (-ESTRPIPE == error))
    LogFormat("ALSA PCM error: %s - trying to recover",
              snd_strerror(error));
  else {
    // snd_pcm_recover() can only handle EPIPE, EINTR and ESTRPIPE
    LogFormat("Unrecoverable ALSA PCM error: %s",
              snd_strerror(error));
    return false;
  }

  int recover_error = snd_pcm_recover(&alsa_handle, error, 1);
  if (0 == recover_error) {
    LogFormat("ALSA PCM successfully recovered");
    return true;
  } else {
    LogFormat("snd_pcm_recover(0x%p, %d, 1) failed: %d - %s",
              &alsa_handle,
              error,
              recover_error,
              snd_strerror(recover_error));
    return false;
  }
}
コード例 #16
0
unsigned int CAESinkALSA::AddPackets(uint8_t *data, unsigned int frames, bool hasAudio, bool blocking)
{
  if (!m_pcm)
  {
    CLog::Log(LOGERROR, "CAESinkALSA - Tried to add packets without a sink");
    return INT_MAX;
  }

  int ret = snd_pcm_writei(m_pcm, (void*)data, frames);
  if (ret < 0)
  {
    CLog::Log(LOGERROR, "CAESinkALSA - snd_pcm_writei(%d) %s - trying to recover", ret, snd_strerror(ret));
    ret = snd_pcm_recover(m_pcm, ret, 1);
    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;
}
コード例 #17
0
int QAudioOutputPrivate::bytesFree() const
{
    if(resuming)
        return period_size;

    if(deviceState != QAudio::ActiveState && deviceState != QAudio::IdleState)
        return 0;

    int frames = snd_pcm_avail_update(handle);
    if (frames == -EPIPE) {
        // Try and handle buffer underrun
        int err = snd_pcm_recover(handle, frames, 0);
        if (err < 0)
            return 0;
        else
            frames = snd_pcm_avail_update(handle);
    } else if (frames < 0) {
        return 0;
    }

    if ((int)frames > (int)buffer_frames)
        frames = buffer_frames;

    return snd_pcm_frames_to_bytes(handle, frames);
}
コード例 #18
0
ファイル: audio.c プロジェクト: jiiksteri/spthui
static void recover_maybe(struct audio *audio)
{
	if (audio->err < 0) {
		audio->err = snd_pcm_recover(audio->pcm, audio->err, 1);
		audio->underruns++;
	}
}
コード例 #19
0
ファイル: rtspeccy.c プロジェクト: sgrady2/C-VtkVis
/* Read as far as you can (when in non-blocking mode) or until our
 * buffer is filled (when in blocking mode). */
int audioRead(void)
{
	if (sound.reprepare)
	{
		int ret;
		ret = snd_pcm_drop(sound.handle);
		if (ret < 0)
		{
			fprintf(stderr, "Error while dropping samples: %s\n",
			        snd_strerror(ret));
		}

		ret = snd_pcm_prepare(sound.handle);
		if (ret < 0)
		{
			fprintf(stderr, "Error while preparing to record: %s\n",
			        snd_strerror(ret));
		}

		sound.reprepare = 0;
	}

	/* Request
	 *   "size - fill" frames
	 * starting at
	 *   "base + numFramesFilled * 2" bytes.
	 * Do "* 2" because we get two bytes per sample.
	 *
	 * When in blocking mode, this always fills the buffer to its
	 * maximum capacity.
	 */
	snd_pcm_sframes_t rc;
	rc = snd_pcm_readi(sound.handle, sound.buffer + (sound.bufferFill * 2),
	                   sound.bufferSizeFrames - sound.bufferFill);
	if (rc == -EPIPE)
	{
		/* EPIPE means overrun */
		snd_pcm_recover(sound.handle, rc, 0);
	}
	else if (rc == -EAGAIN)
	{
		/* Not ready yet. Come back again later. */
	}
	else if (rc < 0)
	{
		fprintf(stderr, "error from read: %s\n", snd_strerror(rc));
	}
	else
	{
		sound.bufferFill += rc;
		if (sound.bufferFill == sound.bufferSizeFrames)
		{
			/* Buffer full. display() can add this to the history. */
			sound.bufferFill = 0;
			sound.bufferReady = 1;
		}
	}

	return rc;
}
コード例 #20
0
ファイル: system.c プロジェクト: jonronen/audio-fx
void* reader_thread(void* param)
{
    int i=0;
    snd_pcm_sframes_t frames;

    while (1) {
        sem_wait(&g_empty_cnt_sem);

        frames = snd_pcm_readi(
                     g_handle_rec,
                     g_rec_buffers[i],
                     NUM_SAMPLES
                 );
        if (frames < 0) {
            printf("snd_pcm_readi failed: %s\n", snd_strerror(frames));
            frames = snd_pcm_recover(g_handle_rec, frames, 0);
        }
        if (frames < 0) {
            printf("snd_pcm_recover failed: %s\n", snd_strerror(frames));
            break;
        }
        if ((frames > 0) && (frames < NUM_SAMPLES))
            printf("Short read (expected %d, read %ld)\n", NUM_SAMPLES, frames);

        sem_post(&g_full_cnt_sem);

        i = (i+1) % NUM_BUFFERS;
    }

    return NULL;
}
コード例 #21
0
ファイル: alsa.c プロジェクト: Ichthyostega/Lumiera
size_t
audio_write(const void* data, size_t amount)
{
  int err;

  amount /= 4;

  for(;;)
    {
      err = snd_pcm_writei(playback_handle, data, amount);

      if(err == -EAGAIN)
        return 0;

      if(err < 0)
        {
          err = snd_pcm_recover(playback_handle, err, 0);

          if(err < 0)
            errx(EXIT_FAILURE, "Audio playback failed: %s", strerror(-err));
        }


      break;
    }

  written += err;

  err *= 4;

  return err;
}
コード例 #22
0
ファイル: sndout_alsa.c プロジェクト: CraigularB/Provenance
int sndout_alsa_write_nb(const void *samples, int len)
{
	snd_pcm_sframes_t left;
	int ret;

	len /= 2;
	if (channels == 2)
		len /= 2;

	left = snd_pcm_avail(handle);
	if (left >= 0 && left < len)
		return 0;

	ret = snd_pcm_writei(handle, samples, len);
	if (ret < 0) {
		ret = snd_pcm_recover(handle, ret, 1);
		if (ret != 0 && failure_counter++ < 5)
			fprintf(stderr, PFX "snd_pcm_recover: %d\n", ret);

		if (silent_period)
			snd_pcm_writei(handle, silent_period, period_size);
		snd_pcm_writei(handle, samples, len);
	}

	return len;
}
コード例 #23
0
mp_sint32 AudioDriver_ALSA::start()
{
	const snd_pcm_channel_area_t *my_areas;
	snd_pcm_uframes_t offset, frames, size;
	snd_async_handler_t *ahandler;
	int err;
	err = snd_async_add_pcm_handler(&ahandler, pcm, async_direct_callback, this);
	if (err < 0) {
		fprintf(stderr, "ALSA: Unable to register async handler (%s)\n", snd_strerror(err));
	}

	for (int count = 0; count < 2; count++) {
		size = period_size;
		while (size > 0) {
			frames = size;
			err = snd_pcm_mmap_begin(pcm, &my_areas, &offset, &frames);
			if (err < 0) {
				if ((err = snd_pcm_recover(pcm, err, 0)) < 0) {
					fprintf(stderr, "ALSA: MMAP begin error: %s\n", snd_strerror(err));
				}
			}
			// Sanity check
			if (my_areas->step != 32 && my_areas->first != 0)
				fprintf(stderr, "ALSA: Unsupported audio format.\n");

			memset(static_cast<char*> (my_areas->addr) + offset*4, 0, frames * 4);
			int commitres = snd_pcm_mmap_commit(pcm, offset, frames);
			if (err < 0 || (snd_pcm_uframes_t)commitres != frames) {
				if ((err = snd_pcm_recover(pcm, commitres >= 0 ? -EPIPE : commitres, 0)) < 0) {
					fprintf(stderr, "ALSA: MMAP commit error: %s\n", snd_strerror(err));
				}
			}
			size -= frames;
		}
	}

\
	err = snd_pcm_start(pcm);
	if (err < 0)
	{
		fprintf(stderr, "ALSA: Could not start PCM device (%s)\n", snd_strerror(err));
		return -1;
	}

	deviceHasStarted = true;
	return 0;
}
コード例 #24
0
void AudioDriverALSA::thread_func(void* p_udata) {

	AudioDriverALSA* ad = (AudioDriverALSA*)p_udata;

	while (!ad->exit_thread) {
		if (!ad->active) {
			for (unsigned int i=0; i < ad->period_size*ad->channels; i++) {
				ad->samples_out[i] = 0;
			};
		} else {
			ad->lock();

			ad->audio_server_process(ad->period_size, ad->samples_in);

			ad->unlock();

			for(unsigned int i=0;i<ad->period_size*ad->channels;i++) {
				ad->samples_out[i]=ad->samples_in[i]>>16;
			}
		};


		int todo = ad->period_size;
		int total = 0;

		while (todo) {
			if (ad->exit_thread)
				break;
			uint8_t* src = (uint8_t*)ad->samples_out;
			int wrote = snd_pcm_writei(ad->pcm_handle, (void*)(src + (total*ad->channels)), todo);

			if (wrote < 0) {
				if (ad->exit_thread)
					break;

				if ( wrote == -EAGAIN ) {
					//can't write yet (though this is blocking..)
					usleep(1000); 
					continue;
				}
				wrote = snd_pcm_recover(ad->pcm_handle, wrote, 0);
				if ( wrote < 0 ) {
					//absolute fail
					fprintf(stderr, "ALSA failed and can't recover: %s\n", snd_strerror(wrote));
					ad->active=false;
					ad->exit_thread=true;
					break;
				}
				continue;
			};

			total += wrote;
			todo -= wrote;
		};
	};

	ad->thread_exited=true;

};
コード例 #25
0
ファイル: audin_alsa.c プロジェクト: kidfolk/FreeRDP
static void* audin_alsa_thread_func(void* arg)
{
	int error;
	uint8* buffer;
	int rbytes_per_frame;
	int tbytes_per_frame;
	snd_pcm_t* capture_handle = NULL;
	AudinALSADevice* alsa = (AudinALSADevice*) arg;

	DEBUG_DVC("in");

	rbytes_per_frame = alsa->actual_channels * alsa->bytes_per_channel;
	tbytes_per_frame = alsa->target_channels * alsa->bytes_per_channel;
	alsa->buffer = (uint8*) xzalloc(tbytes_per_frame * alsa->frames_per_packet);
	alsa->buffer_frames = 0;
	buffer = (uint8*) xzalloc(rbytes_per_frame * alsa->frames_per_packet);
	memset(&alsa->adpcm, 0, sizeof(ADPCM));
	do
	{
		if ((error = snd_pcm_open(&capture_handle, alsa->device_name, SND_PCM_STREAM_CAPTURE, 0)) < 0)
		{
			DEBUG_WARN("snd_pcm_open (%s)", snd_strerror(error));
			break;
		}
		if (!audin_alsa_set_params(alsa, capture_handle))
		{
			break;
		}

		while (!freerdp_thread_is_stopped(alsa->thread))
		{
			error = snd_pcm_readi(capture_handle, buffer, alsa->frames_per_packet);
			if (error == -EPIPE)
			{
				snd_pcm_recover(capture_handle, error, 0);
				continue;
			}
			else if (error < 0)
			{
				DEBUG_WARN("snd_pcm_readi (%s)", snd_strerror(error));
				break;
			}
			if (!audin_alsa_thread_receive(alsa, buffer, error * rbytes_per_frame))
				break;
		}
	} while (0);

	xfree(buffer);
	xfree(alsa->buffer);
	alsa->buffer = NULL;
	if (capture_handle)
		snd_pcm_close(capture_handle);

	freerdp_thread_quit(alsa->thread);

	DEBUG_DVC("out");

	return NULL;
}
コード例 #26
0
ファイル: talsa.c プロジェクト: tanhuacheng/Documents
static void pcm_play (unsigned char* buff, int size)
{
    snd_pcm_sframes_t frames = snd_pcm_writei(handle, buff, size);

    if (frames < 0) {
        frames = snd_pcm_recover(handle, frames, 0);
    }
}
コード例 #27
0
ファイル: apulse-mainloop.c プロジェクト: Alpherie/apulse
static
void
recover_pcm(snd_pcm_t *pcm)
{
    switch (snd_pcm_state(pcm)) {
    case SND_PCM_STATE_XRUN:
        snd_pcm_recover(pcm, -EPIPE, 1);
        break;
    case SND_PCM_STATE_SUSPENDED:
        snd_pcm_recover(pcm, -ESTRPIPE, 1);
        break;
    default:
        snd_pcm_drop(pcm);
        snd_pcm_prepare(pcm);
        break;
    }
}
コード例 #28
0
ファイル: micserver.c プロジェクト: rofl0r/rocksock
static void play(snd_pcm_t *playback_handle, const unsigned char* buf, size_t s) {
	int ret = snd_pcm_writei(playback_handle, buf, s);
	if (ret<0) {
		DPRINTF(2, "write to audio interface failed (%s)\n", snd_strerror(ret));
		snd_pcm_state_t state = snd_pcm_state(playback_handle);
                DPRINTF(2, "%s\n", getstatus_string(state));
                if(state == SND_PCM_STATE_XRUN) snd_pcm_recover(playback_handle, ret, 1);
	}
}
コード例 #29
0
ファイル: pcm-multi-thread.c プロジェクト: Boshin/workspace
int main(int argc, char **argv)
{
	char *buf;
	int i, err;

	if (parse_options(argc, argv))
		return 1;

	err = snd_pcm_open(&pcm, devname, stream, 0);
	if (err < 0) {
		fprintf(stderr, "cannot open pcm %s\n", devname);
		return 1;
	}

	if (setup_params())
		return 1;

	buf = calloc(1, snd_pcm_format_size(format, bufsize) * channels);
	if (!buf) {
		fprintf(stderr, "cannot alloc buffer\n");
		return 1;
	}

	for (i = 0; i < num_threads; i++) {
		if (pthread_create(&peeper_threads[i], NULL, peeper, (void *)(long)i)) {
			fprintf(stderr, "pthread_create error\n");
			return 1;
		}
	}

	if (stream == SND_PCM_STREAM_CAPTURE)
		snd_pcm_start(pcm);
	for (;;) {
		int size = rand() % (bufsize / 2);
		if (stream == SND_PCM_STREAM_PLAYBACK)
			err = snd_pcm_writei(pcm, buf, size);
		else
			err = snd_pcm_readi(pcm, buf, size);
		if (err < 0) {
			fprintf(stderr, "read/write error %d\n", err);
			err = snd_pcm_recover(pcm, err, 0);
			if (err < 0)
				break;
			if (stream == SND_PCM_STREAM_CAPTURE)
				snd_pcm_start(pcm);
		}
	}

	running = 0;
	for (i = 0; i < num_threads; i++)
		pthread_cancel(peeper_threads[i]);
	for (i = 0; i < num_threads; i++)
		pthread_join(peeper_threads[i], NULL);

	return 1;
}
コード例 #30
0
ファイル: alsa.c プロジェクト: LighFusion/surreal
static ALuint ALSANoMMapProc(ALvoid *ptr)
{
    ALCdevice *Device = (ALCdevice*)ptr;
    alsa_data *data = (alsa_data*)Device->ExtraData;
    snd_pcm_sframes_t avail;
    char *WritePtr;

    SetRTPriority();

    while(!data->killNow)
    {
        int state = verify_state(data->pcmHandle);
        if(state < 0)
        {
            ERR("Invalid state detected: %s\n", snd_strerror(state));
            aluHandleDisconnect(Device);
            break;
        }

        WritePtr = data->buffer;
        avail = data->size / snd_pcm_frames_to_bytes(data->pcmHandle, 1);
        aluMixData(Device, WritePtr, avail);

        while(avail > 0)
        {
            int ret = snd_pcm_writei(data->pcmHandle, WritePtr, avail);
            switch (ret)
            {
            case -EAGAIN:
                continue;
            case -ESTRPIPE:
            case -EPIPE:
            case -EINTR:
                ret = snd_pcm_recover(data->pcmHandle, ret, 1);
                if(ret < 0)
                    avail = 0;
                break;
            default:
                if (ret >= 0)
                {
                    WritePtr += snd_pcm_frames_to_bytes(data->pcmHandle, ret);
                    avail -= ret;
                }
                break;
            }
            if (ret < 0)
            {
                ret = snd_pcm_prepare(data->pcmHandle);
                if(ret < 0)
                    break;
            }
        }
    }

    return 0;
}