示例#1
0
static ssize_t rs_write(void *data, const void *buf, size_t size)
{
   rsd_t *rsd = (rsd_t*)data;

   if (rsd->has_error)
      return -1;

   if (rsd->nonblock)
   {
      size_t avail, write_amt;

      rsd_callback_lock(rsd->rd);

      avail = fifo_write_avail(rsd->buffer);
      write_amt = avail > size ? size : avail;

      fifo_write(rsd->buffer, buf, write_amt);
      rsd_callback_unlock(rsd->rd);
      return write_amt;
   }
   else
   {
      size_t written = 0;
      while (written < size && !rsd->has_error)
      {
         size_t avail;
         rsd_callback_lock(rsd->rd);

         avail = fifo_write_avail(rsd->buffer);

         if (avail == 0)
         {
            rsd_callback_unlock(rsd->rd);
            if (!rsd->has_error)
            {
               slock_lock(rsd->cond_lock);
               scond_wait(rsd->cond, rsd->cond_lock);
               slock_unlock(rsd->cond_lock);
            }
         }
         else
         {
            size_t write_amt = size - written > avail ? avail : size - written;
            fifo_write(rsd->buffer, (const char*)buf + written, write_amt);
            rsd_callback_unlock(rsd->rd);
            written += write_amt;
         }
      }
      return written;
   }
}
示例#2
0
static ssize_t alsa_thread_write(void *data, const void *buf, size_t size)
{
   alsa_thread_t *alsa = (alsa_thread_t*)data;

   if (alsa->thread_dead)
      return -1;

   if (alsa->nonblock)
   {
      size_t avail;
      size_t write_amt;

      slock_lock(alsa->fifo_lock);
      avail           = fifo_write_avail(alsa->buffer);
      write_amt       = MIN(avail, size);

      fifo_write(alsa->buffer, buf, write_amt);
      slock_unlock(alsa->fifo_lock);

      return write_amt;
   }
   else
   {
      size_t written = 0;
      while (written < size && !alsa->thread_dead)
      {
         size_t avail;
         slock_lock(alsa->fifo_lock);
         avail = fifo_write_avail(alsa->buffer);

         if (avail == 0)
         {
            slock_unlock(alsa->fifo_lock);
            slock_lock(alsa->cond_lock);
            if (!alsa->thread_dead)
               scond_wait(alsa->cond, alsa->cond_lock);
            slock_unlock(alsa->cond_lock);
         }
         else
         {
            size_t write_amt = MIN(size - written, avail);
            fifo_write(alsa->buffer,
                  (const char*)buf + written, write_amt);
            slock_unlock(alsa->fifo_lock);
            written += write_amt;
         }
      }
      return written;
   }
}
示例#3
0
文件: ffemu.c 项目: Wyrick/RetroArch
bool ffemu_push_audio(ffemu_t *handle, const struct ffemu_audio_data *data)
{
   for (;;)
   {
      slock_lock(handle->lock);
      unsigned avail = fifo_write_avail(handle->audio_fifo);
      slock_unlock(handle->lock);

      if (!handle->alive)
         return false;

      if (avail >= data->frames * handle->params.channels * sizeof(int16_t))
         break;

      slock_lock(handle->cond_lock);
      if (handle->can_sleep)
      {
         handle->can_sleep = false;
         scond_wait(handle->cond, handle->cond_lock);
         handle->can_sleep = true;
      }
      else
         scond_signal(handle->cond);

      slock_unlock(handle->cond_lock);
   }

   slock_lock(handle->lock);
   fifo_write(handle->audio_fifo, data->data, data->frames * handle->params.channels * sizeof(int16_t));
   slock_unlock(handle->lock);
   scond_signal(handle->cond);

   return true;
}
示例#4
0
static ssize_t dsound_write(void *data, const void *buf_, size_t size)
{
   size_t written = 0;
   dsound_t *ds = (dsound_t*)data;
   const uint8_t *buf = (const uint8_t*)buf_;

   if (!ds->thread_alive)
      return -1;

   while (size > 0)
   {
      size_t avail;

      EnterCriticalSection(&ds->crit);
      avail = fifo_write_avail(ds->buffer);
      if (avail > size)
         avail = size;

      fifo_write(ds->buffer, buf, avail);
      LeaveCriticalSection(&ds->crit);

      buf     += avail;
      size    -= avail;
      written += avail;

      if (ds->nonblock || !ds->thread_alive)
         break;

      if (avail == 0)
         WaitForSingleObject(ds->event, INFINITE);
   }

   return written;
}
示例#5
0
static size_t coreaudio_write_avail(void *data)
{
   coreaudio_t *dev = (coreaudio_t*)data;
   pthread_mutex_lock(&dev->lock);
   size_t avail = fifo_write_avail(dev->buffer);
   pthread_mutex_unlock(&dev->lock);
   return avail;
}
示例#6
0
static size_t dsound_write_avail(void *data)
{
   dsound_t *ds = (dsound_t*)data;
   EnterCriticalSection(&ds->crit);
   size_t avail = fifo_write_avail(ds->buffer);
   LeaveCriticalSection(&ds->crit);
   return avail;
}
示例#7
0
static uint32_t audioport_write_avail(cell_audio_handle_t handle)
{
   audioport_t *port = handle;

   sys_lwmutex_lock(&port->lock, SYS_NO_TIMEOUT);
   uint32_t ret = fifo_write_avail(port->buffer);
   sys_lwmutex_unlock(&port->lock);
   return ret / sizeof(int16_t);
}
示例#8
0
static ssize_t ps3_audio_write(void *data, const void *buf, size_t size)
{
   ps3_audio_t *aud = data;

   if (aud->nonblocking)
   {
      if (fifo_write_avail(aud->buffer) < size)
         return 0;
   }

   while (fifo_write_avail(aud->buffer) < size)
      sys_lwcond_wait(&aud->cond, 0);

   sys_lwmutex_lock(&aud->lock, SYS_NO_TIMEOUT);
   fifo_write(aud->buffer, buf, size);
   sys_lwmutex_unlock(&aud->lock);

   return size;
}
示例#9
0
static ssize_t sdl_audio_write(void *data, const void *buf, size_t size)
{
   sdl_audio_t *sdl = (sdl_audio_t*)data;

   ssize_t ret = 0;
   if (sdl->nonblock)
   {
      SDL_LockAudio();
      size_t avail = fifo_write_avail(sdl->buffer);
      size_t write_amt = avail > size ? size : avail;
      fifo_write(sdl->buffer, buf, write_amt);
      SDL_UnlockAudio();
      ret = write_amt;
   }
   else
   {
      size_t written = 0;
      while (written < size)
      {
         SDL_LockAudio();
         size_t avail = fifo_write_avail(sdl->buffer);

         if (avail == 0)
         {
            SDL_UnlockAudio();
            slock_lock(sdl->lock);
            scond_wait(sdl->cond, sdl->lock);
            slock_unlock(sdl->lock);
         }
         else
         {
            size_t write_amt = size - written > avail ? avail : size - written;
            fifo_write(sdl->buffer, (const char*)buf + written, write_amt);
            SDL_UnlockAudio();
            written += write_amt;
         }
      }
      ret = written;
   }

   return ret;
}
示例#10
0
static size_t alsa_write_avail(void *data)
{
   alsa_t *alsa = (alsa_t*)data;

   if (alsa->thread_dead)
      return 0;
   slock_lock(alsa->fifo_lock);
   size_t val = fifo_write_avail(alsa->buffer);
   slock_unlock(alsa->fifo_lock);
   return val;
}
示例#11
0
bool ffemu_push_video(ffemu_t *handle, const struct ffemu_video_data *data)
{
   unsigned y;
   bool drop_frame = handle->video.frame_drop_count++ % handle->video.frame_drop_ratio;
   handle->video.frame_drop_count %= handle->video.frame_drop_ratio;
   if (drop_frame)
      return true;

   for (;;)
   {
      slock_lock(handle->lock);
      unsigned avail = fifo_write_avail(handle->attr_fifo);
      slock_unlock(handle->lock);

      if (!handle->alive)
         return false;

      if (avail >= sizeof(*data))
         break;

      slock_lock(handle->cond_lock);
      if (handle->can_sleep)
      {
         handle->can_sleep = false;
         scond_wait(handle->cond, handle->cond_lock);
         handle->can_sleep = true;
      }
      else
         scond_signal(handle->cond);

      slock_unlock(handle->cond_lock);
   }

   slock_lock(handle->lock);

   // Tightly pack our frame to conserve memory. libretro tends to use a very large pitch.
   struct ffemu_video_data attr_data = *data;

   if (attr_data.is_dupe)
      attr_data.width = attr_data.height = attr_data.pitch = 0;
   else
      attr_data.pitch = attr_data.width * handle->video.pix_size;

   fifo_write(handle->attr_fifo, &attr_data, sizeof(attr_data));

   int offset = 0;
   for (y = 0; y < attr_data.height; y++, offset += data->pitch)
      fifo_write(handle->video_fifo, (const uint8_t*)data->data + offset, attr_data.pitch);

   slock_unlock(handle->lock);
   scond_signal(handle->cond);

   return true;
}
示例#12
0
static size_t coreaudio_write_avail(void *data)
{
   size_t avail;
   coreaudio_t *dev = (coreaudio_t*)data;

   slock_lock(dev->lock);
   avail = fifo_write_avail(dev->buffer);
   slock_unlock(dev->lock);

   return avail;
}
示例#13
0
static size_t rs_write_avail(void *data)
{
   rsd_t *rsd = (rsd_t*)data;

   if (rsd->has_error)
      return 0;
   rsd_callback_lock(rsd->rd);
   size_t val = fifo_write_avail(rsd->buffer);
   rsd_callback_unlock(rsd->rd);
   return val;
}
示例#14
0
static ssize_t coreaudio_write(void *data, const void *buf_, size_t size)
{
   coreaudio_t *dev = (coreaudio_t*)data;

   const uint8_t *buf = (const uint8_t*)buf_;
   size_t written = 0;

#ifdef IOS
   struct timeval time;
   gettimeofday(&time, 0);
   
   struct timespec timeout;
   memset(&timeout, 0, sizeof(timeout));
   timeout.tv_sec = time.tv_sec + 3;
   timeout.tv_nsec = time.tv_usec * 1000;
#endif

   while (!g_interrupted && size > 0)
   {
      pthread_mutex_lock(&dev->lock);

      size_t write_avail = fifo_write_avail(dev->buffer);
      if (write_avail > size)
         write_avail = size;

      fifo_write(dev->buffer, buf, write_avail);
      buf += write_avail;
      written += write_avail;
      size -= write_avail;

      if (dev->nonblock)
      {
         pthread_mutex_unlock(&dev->lock);
         break;
      }

#ifdef IOS
      if (write_avail == 0 && pthread_cond_timedwait(&dev->cond, &dev->lock, &timeout) == ETIMEDOUT)
         g_interrupted = true;
#else
      if (write_avail == 0)
         pthread_cond_wait(&dev->cond, &dev->lock);
#endif
      pthread_mutex_unlock(&dev->lock);
   }

   return written;
}
示例#15
0
static bool ffmpeg_push_audio(void *data,
      const struct ffemu_audio_data *audio_data)
{
   ffmpeg_t *handle = (ffmpeg_t*)data;

   if (!handle || !audio_data)
      return false;

   if (!handle->config.audio_enable)
      return true;

   for (;;)
   {
      unsigned avail;
      slock_lock(handle->lock);
      avail = fifo_write_avail(handle->audio_fifo);
      slock_unlock(handle->lock);

      if (!handle->alive)
         return false;

      if (avail >= audio_data->frames * handle->params.channels
            * sizeof(int16_t))
         break;

      slock_lock(handle->cond_lock);
      if (handle->can_sleep)
      {
         handle->can_sleep = false;
         scond_wait(handle->cond, handle->cond_lock);
         handle->can_sleep = true;
      }
      else
         scond_signal(handle->cond);

      slock_unlock(handle->cond_lock);
   }

   slock_lock(handle->lock);
   fifo_write(handle->audio_fifo, audio_data->data,
         audio_data->frames * handle->params.channels * sizeof(int16_t));
   slock_unlock(handle->lock);
   scond_signal(handle->cond);

   return true;
}
示例#16
0
static ssize_t coreaudio_write(void *data, const void *buf_, size_t size,
      bool is_perfcnt_enable)
{
   coreaudio_t *dev   = (coreaudio_t*)data;
   const uint8_t *buf = (const uint8_t*)buf_;
   size_t written     = 0;

   while (!g_interrupted && size > 0)
   {
      size_t write_avail;

      slock_lock(dev->lock);

      write_avail = fifo_write_avail(dev->buffer);
      if (write_avail > size)
         write_avail = size;

      fifo_write(dev->buffer, buf, write_avail);
      buf += write_avail;
      written += write_avail;
      size -= write_avail;

      if (dev->nonblock)
      {
         slock_unlock(dev->lock);
         break;
      }

#if TARGET_OS_IPHONE
      if (write_avail == 0 && !scond_wait_timeout(
               dev->cond, dev->lock, 3000000))
         g_interrupted = true;
#else
      if (write_avail == 0)
         scond_wait(dev->cond, dev->lock);
#endif
      slock_unlock(dev->lock);
   }

   return written;
}
示例#17
0
static void libusb_hid_device_send_control(void *data,
      uint8_t* data_buf, size_t size)
{
   struct libusb_adapter *adapter = (struct libusb_adapter*)data;

   if (!adapter)
      return;

   slock_lock(adapter->send_control_lock);

   if (fifo_write_avail(adapter->send_control_buffer) >= size + sizeof(size))
   {
      fifo_write(adapter->send_control_buffer, &size, sizeof(size));
      fifo_write(adapter->send_control_buffer, data_buf, size);
   }
   else
   {
      RARCH_WARN("adapter write buffer is full, cannot write send control\n");
   }
   slock_unlock(adapter->send_control_lock);
}
示例#18
0
static int32_t audioport_write(cell_audio_handle_t handle, const int16_t *data, uint32_t samples)
{
   int32_t ret = samples;
   uint32_t bytes = samples * sizeof(int16_t);

   audioport_t *port = handle;
   while (bytes)
   {
      sys_lwmutex_lock(&port->lock, SYS_NO_TIMEOUT);
      uint32_t avail = fifo_write_avail(port->buffer);
      sys_lwmutex_unlock(&port->lock);

      uint32_t to_write = avail < bytes ? avail : bytes;
      if (to_write)
      {
	 sys_lwmutex_lock(&port->lock, SYS_NO_TIMEOUT);
         fifo_write(port->buffer, data, to_write);
	 sys_lwmutex_unlock(&port->lock);
         bytes -= to_write;
         data += to_write >> 1;
      }
      else
         sys_lwcond_wait(&port->cond, 0);
   }