示例#1
0
static int pulse_pause(void)
{
    trace ("pulse_pause\n");
    pulse_free();
    state = OUTPUT_STATE_PAUSED;
    return 0;
}
示例#2
0
static int pulse_stop(void)
{
    trace ("pulse_stop\n");
    state = OUTPUT_STATE_STOPPED;
    deadbeef->streamer_reset(1);
    pulse_free();
    return 0;
}
示例#3
0
size_t wave_write(void* theHandler, char* theMono16BitsWaveBuffer, size_t theSize)
{
  ENTER("wave_write");
  size_t bytes_to_write = theSize;
  char* aBuffer=theMono16BitsWaveBuffer;

  assert(stream);

  size_t aTotalFreeMem=0;

  pthread_mutex_lock(&pulse_mutex);

  while (1) 
    {
      if (my_callback_is_output_enabled 
	  && (0==my_callback_is_output_enabled()))
	{
	  SHOW_TIME("wave_write > my_callback_is_output_enabled: no!");
	  theSize=0;
	  goto terminate;
	}

      aTotalFreeMem = pulse_free();
      if (aTotalFreeMem >= bytes_to_write)
	{
	  SHOW("wave_write > aTotalFreeMem(%d) >= bytes_to_write(%d)\n", aTotalFreeMem, bytes_to_write);
	  break;
	}
 
      // TBD: check if really helpful
      if (aTotalFreeMem >= MAXLENGTH*2)
 	{
 	  aTotalFreeMem = MAXLENGTH*2;
 	}
       
      SHOW("wave_write > wait: aTotalFreeMem(%d) < bytes_to_write(%d)\n", aTotalFreeMem, bytes_to_write);

      // 500: threshold for avoiding too many calls to pulse_write
      if (aTotalFreeMem>500)
	{
	  pulse_write(aBuffer, aTotalFreeMem);
	  bytes_to_write -= aTotalFreeMem;
	  aBuffer += aTotalFreeMem;
	}

      usleep(10000);
    }

  pulse_write(aBuffer, bytes_to_write);

 terminate:
  pthread_mutex_unlock(&pulse_mutex);
  SHOW("wave_write: theSize=%d", theSize);
  SHOW_TIME("wave_write > LEAVE");
  return theSize;
}
示例#4
0
static int pulse_pause(void)
{
    trace ("pulse_pause\n");
    if (state == OUTPUT_STATE_STOPPED)
    {
        return -1;
    }

    pulse_free();
    state = OUTPUT_STATE_PAUSED;
    return 0;
}
示例#5
0
static void pulse_close(snd_ctl_ext_t * ext)
{
	snd_ctl_pulse_t *ctl = ext->private_data;

	assert(ctl);

	if (ctl->p)
		pulse_free(ctl->p);

	free(ctl->source);
	free(ctl->sink);
	free(ctl);
}
示例#6
0
static int pulse_setformat (ddb_waveformat_t *fmt)
{
    int st = state;
    memcpy (&requested_fmt, fmt, sizeof (ddb_waveformat_t));
    if (!s
        || !memcmp (fmt, &plugin.fmt, sizeof (ddb_waveformat_t))) {
        return 0;
    }

    pulse_free ();
    pulse_init ();
    int res = 0;
    if (st == OUTPUT_STATE_PLAYING) {
        res = pulse_play ();
    }
    else if (st == OUTPUT_STATE_PAUSED) {
        res = pulse_pause ();
    }

    return res;
}
示例#7
0
文件: pulse.c 项目: vadmium/deadbeef
static void pulse_thread(void *context)
{
#ifdef __linux__
    prctl(PR_SET_NAME, "deadbeef-pulse", 0, 0, 0, 0);
#endif

    while (!pulse_terminate)
    {
        if (state != OUTPUT_STATE_PLAYING || !deadbeef->streamer_ok_to_read (-1))
        {
            usleep(10000);
            continue;
        }

        int sample_size = plugin.fmt.channels * (plugin.fmt.bps / 8);
        int bs = buffer_size;
        int mod = bs % sample_size;
        if (mod > 0) {
            bs -= mod;
        }

        char buf[bs];
        pulse_callback (buf, sizeof (buf));
        int error;

        deadbeef->mutex_lock(mutex);
        int res = pa_simple_write(s, buf, sizeof (buf), &error);
        deadbeef->mutex_unlock(mutex);

        if (res < 0)
        {
            fprintf(stderr, "pulse: failed to write buffer\n");
            pulse_tid = 0;
            pulse_free ();
            break;
        }
    }
}
示例#8
0
static void *pulse_init(const char *device, unsigned rate, unsigned latency)
{
   pa_sample_spec spec;
   pa_t *pa;
   pa_buffer_attr buffer_attr = {0};
   const pa_buffer_attr *server_attr = NULL;

   memset(&spec, 0, sizeof(spec));
   
   pa = (pa_t*)calloc(1, sizeof(*pa));
   if (!pa)
      goto error;

   pa->mainloop = pa_threaded_mainloop_new();
   if (!pa->mainloop)
      goto error;

   pa->context = pa_context_new(pa_threaded_mainloop_get_api(pa->mainloop), "RetroArch");
   if (!pa->context)
      goto error;

   pa_context_set_state_callback(pa->context, context_state_cb, pa);

   if (pa_context_connect(pa->context, device, PA_CONTEXT_NOFLAGS, NULL) < 0)
      goto error;

   pa_threaded_mainloop_lock(pa->mainloop);
   if (pa_threaded_mainloop_start(pa->mainloop) < 0)
      goto error;

   pa_threaded_mainloop_wait(pa->mainloop);

   if (pa_context_get_state(pa->context) != PA_CONTEXT_READY)
      goto unlock_error;

   spec.format = is_little_endian() ? PA_SAMPLE_FLOAT32LE : PA_SAMPLE_FLOAT32BE;
   spec.channels = 2;
   spec.rate = rate;

   pa->stream = pa_stream_new(pa->context, "audio", &spec, NULL);
   if (!pa->stream)
      goto unlock_error;

   pa_stream_set_state_callback(pa->stream, stream_state_cb, pa);
   pa_stream_set_write_callback(pa->stream, stream_request_cb, pa);
   pa_stream_set_latency_update_callback(pa->stream, stream_latency_update_cb, pa);
   pa_stream_set_underflow_callback(pa->stream, underrun_update_cb, pa);
   pa_stream_set_buffer_attr_callback(pa->stream, buffer_attr_cb, pa);

   buffer_attr.maxlength = -1;
   buffer_attr.tlength = pa_usec_to_bytes(latency * PA_USEC_PER_MSEC, &spec);
   buffer_attr.prebuf = -1;
   buffer_attr.minreq = -1;
   buffer_attr.fragsize = -1;

   if (pa_stream_connect_playback(pa->stream, NULL, &buffer_attr, PA_STREAM_ADJUST_LATENCY, NULL, NULL) < 0)
      goto error;

   pa_threaded_mainloop_wait(pa->mainloop);

   if (pa_stream_get_state(pa->stream) != PA_STREAM_READY)
      goto unlock_error;

   server_attr = pa_stream_get_buffer_attr(pa->stream);
   if (server_attr)
   {
      pa->buffer_size = server_attr->tlength;
      RARCH_LOG("[PulseAudio]: Requested %u bytes buffer, got %u.\n",
            (unsigned)buffer_attr.tlength,
            (unsigned)pa->buffer_size);
   }
   else
      pa->buffer_size = buffer_attr.tlength;

   pa_threaded_mainloop_unlock(pa->mainloop);

   return pa;

unlock_error:
   pa_threaded_mainloop_unlock(pa->mainloop);
error:
   pulse_free(pa); 
   return NULL;
}
示例#9
0
static int pulse_stop(void)
{
    trace ("pulse_stop\n");
    pulse_free();
    return 0;
}