示例#1
0
static uint32_t resampler_cb(void *userdata, float **data)
{
   audioport_t *port = userdata;
   uint32_t has_read = 0;

   if (port->sample_cb)
      has_read = port->sample_cb(port->re_pull_buffer, CELL_AUDIO_BLOCK_SAMPLES * port->channels * sizeof(int16_t), port->userdata);
   else
   {
      has_read = CELL_AUDIO_BLOCK_SAMPLES * port->channels;
      sys_lwmutex_lock(&port->lock, SYS_NO_TIMEOUT);
      uint32_t avail = fifo_read_avail(port->buffer);
      if (avail < CELL_AUDIO_BLOCK_SAMPLES * port->channels * sizeof(int16_t))
         has_read = avail / sizeof(int16_t);

      fifo_read(port->buffer, port->re_pull_buffer, has_read * sizeof(int16_t));
      sys_lwmutex_unlock(&port->lock);
      sys_lwcond_signal(&port->cond);
   }

   if (has_read < CELL_AUDIO_BLOCK_SAMPLES * port->channels * 2)
      memset(port->re_pull_buffer + has_read, 0, (CELL_AUDIO_BLOCK_SAMPLES * port->channels - has_read) * sizeof(int16_t));

   audio_convert_s16_to_float_altivec(port->re_buffer, port->re_pull_buffer, CELL_AUDIO_BLOCK_SAMPLES * port->channels);

   *data = port->re_buffer;
   return CELL_AUDIO_BLOCK_SAMPLES;
}
示例#2
0
static void pull_event_loop(audioport_t *port, sys_event_queue_t id)
{
   sys_event_t event;

   int16_t *in_buf = memalign(128, CELL_AUDIO_BLOCK_SAMPLES * port->channels * sizeof(int16_t));
   float *conv_buf = memalign(128, CELL_AUDIO_BLOCK_SAMPLES * port->channels * sizeof(float));
   while (!port->quit_thread)
   {
      uint32_t has_read = 0;
      if (port->sample_cb)
         has_read = port->sample_cb(in_buf, CELL_AUDIO_BLOCK_SAMPLES * port->channels, port->userdata);
      else
      {
         has_read = CELL_AUDIO_BLOCK_SAMPLES * port->channels;
         sys_lwmutex_lock(&port->lock, SYS_NO_TIMEOUT);
         uint32_t avail = fifo_read_avail(port->buffer);
         if (avail < CELL_AUDIO_BLOCK_SAMPLES * port->channels * sizeof(int16_t))
            has_read = avail / sizeof(int16_t);

         fifo_read(port->buffer, in_buf, has_read * sizeof(int16_t));
         sys_lwmutex_unlock(&port->lock);
      }

      if (has_read < CELL_AUDIO_BLOCK_SAMPLES * port->channels)
         memset(in_buf + has_read, 0, (CELL_AUDIO_BLOCK_SAMPLES * port->channels - has_read) * sizeof(int16_t));

      resampler_int16_t_to_float(conv_buf, in_buf, CELL_AUDIO_BLOCK_SAMPLES * port->channels);
      sys_event_queue_receive(id, &event, SYS_NO_TIMEOUT);
      cellAudioAddData(port->audio_port, conv_buf, CELL_AUDIO_BLOCK_SAMPLES, 1.0);

      pthread_cond_signal(&port->cond);
   }
   free(conv_buf);
}
示例#3
0
static void event_loop(uint64_t data)
#endif
{
   float out_tmp[CELL_AUDIO_BLOCK_SAMPLES * AUDIO_CHANNELS]
      __attribute__((aligned(16)));
   sys_event_queue_t id;
   sys_ipc_key_t key;
   sys_event_t event;
   ps3_audio_t *aud = data;

   cellAudioCreateNotifyEventQueue(&id, &key);
   cellAudioSetNotifyEventQueue(key);

   while (!aud->quit_thread)
   {
      sys_event_queue_receive(id, &event, SYS_NO_TIMEOUT);

      sys_lwmutex_lock(&aud->lock, SYS_NO_TIMEOUT);
      if (fifo_read_avail(aud->buffer) >= sizeof(out_tmp))
         fifo_read(aud->buffer, out_tmp, sizeof(out_tmp));
      else
         memset(out_tmp, 0, sizeof(out_tmp));
      sys_lwmutex_unlock(&aud->lock);
      sys_lwcond_signal(&aud->cond);

      cellAudioAddData(aud->audio_port, out_tmp,
            CELL_AUDIO_BLOCK_SAMPLES, 1.0);
   }

   cellAudioRemoveNotifyEventQueue(key);
   sys_ppu_thread_exit(0);
}
示例#4
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);
}
示例#5
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);
   }
示例#6
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;
}
示例#7
0
s32 sys_lwcond_wait(PPUThread& ppu, vm::ptr<sys_lwcond_t> lwcond, u64 timeout)
{
	sysPrxForUser.trace("sys_lwcond_wait(lwcond=*0x%x, timeout=0x%llx)", lwcond, timeout);

	const be_t<u32> tid = ppu.get_id();

	const vm::ptr<sys_lwmutex_t> lwmutex = lwcond->lwmutex;

	if (lwmutex->vars.owner.load() != tid)
	{
		// if not owner of the mutex
		return CELL_EPERM;
	}

	// save old recursive value
	const be_t<u32> recursive_value = lwmutex->recursive_count;

	// set special value
	lwmutex->vars.owner = lwmutex_reserved;
	lwmutex->recursive_count = 0;

	// call the syscall
	s32 res = _sys_lwcond_queue_wait(ppu, lwcond->lwcond_queue, lwmutex->sleep_queue, timeout);

	if (res == CELL_OK || res == CELL_ESRCH)
	{
		if (res == CELL_OK)
		{
			lwmutex->all_info--;
		}

		// restore owner and recursive value
		const auto old = lwmutex->vars.owner.exchange(tid);
		lwmutex->recursive_count = recursive_value;

		if (old != lwmutex_reserved)
		{
			throw EXCEPTION("Locking failed (lwmutex=*0x%x, owner=0x%x)", lwmutex, old);
		}

		return res;
	}

	if (res == CELL_EBUSY || res == CELL_ETIMEDOUT)
	{
		const s32 res2 = sys_lwmutex_lock(ppu, lwmutex, 0);

		if (res2 == CELL_OK)
		{
			// if successfully locked, restore recursive value
			lwmutex->recursive_count = recursive_value;

			return res == CELL_EBUSY ? CELL_OK : res;
		}

		return res2;
	}

	if (res == CELL_EDEADLK)
	{
		// restore owner and recursive value
		const auto old = lwmutex->vars.owner.exchange(tid);
		lwmutex->recursive_count = recursive_value;

		if (old != lwmutex_reserved)
		{
			throw EXCEPTION("Locking failed (lwmutex=*0x%x, owner=0x%x)", lwmutex, old);
		}

		return CELL_ETIMEDOUT;
	}

	throw EXCEPTION("Unexpected syscall result (lwcond=*0x%x, result=0x%x)", lwcond, res);
}
示例#8
0
int __libc_lock_acquire(__libc_lock_t *lock)
{
	if(SYS_LWMUTEX_UNINITIALIZED(lock))
    __libc_auto_lock_allocate(lock);
	return  sys_lwmutex_lock(lock,0);
}
s32 sys_lwcond_wait(PPUThread& CPU, vm::ptr<sys_lwcond_t> lwcond, u64 timeout)
{
	sysPrxForUser.Log("sys_lwcond_wait(lwcond=*0x%x, timeout=0x%llx)", lwcond, timeout);

	const be_t<u32> tid = be_t<u32>::make(CPU.GetId());

	const vm::ptr<sys_lwmutex_t> lwmutex = lwcond->lwmutex;

	if (lwmutex->owner.read_relaxed() != tid)
	{
		// if not owner of the mutex
		return CELL_EPERM;
	}

	// save old recursive value
	const be_t<u32> recursive_value = lwmutex->recursive_count;

	// set special value
	lwmutex->owner = { lwmutex::reserved };
	lwmutex->recursive_count = 0;

	// call the syscall
	s32 res = _sys_lwcond_queue_wait(CPU, lwcond->lwcond_queue, lwmutex->sleep_queue, timeout);

	if (res == CELL_OK || res == CELL_ESRCH)
	{
		if (res == CELL_OK)
		{
			lwmutex->all_info--;
		}

		// restore owner and recursive value
		const auto old = lwmutex->owner.exchange(tid);
		lwmutex->recursive_count = recursive_value;

		if (old.data() != se32(lwmutex_reserved) && !Emu.IsStopped())
		{
			sysPrxForUser.Fatal("sys_lwcond_wait(lwcond=*0x%x): locking failed (lwmutex->owner=0x%x)", lwcond, old);
		}

		return res;
	}

	if (res == CELL_EBUSY || res == CELL_ETIMEDOUT)
	{
		const s32 res2 = sys_lwmutex_lock(CPU, lwmutex, 0);

		if (res2 == CELL_OK)
		{
			// if successfully locked, restore recursive value
			lwmutex->recursive_count = recursive_value;

			return res == CELL_EBUSY ? CELL_OK : res;
		}

		return res2;
	}

	if (res == CELL_EDEADLK)
	{
		// restore owner and recursive value
		const auto old = lwmutex->owner.exchange(tid);
		lwmutex->recursive_count = recursive_value;

		if (old.data() != se32(lwmutex_reserved) && !Emu.IsStopped())
		{
			sysPrxForUser.Fatal("sys_lwcond_wait(lwcond=*0x%x): locking failed after timeout (lwmutex->owner=0x%x)", lwcond, old);
		}

		return CELL_ETIMEDOUT;
	}

	sysPrxForUser.Fatal("sys_lwcond_wait(lwcond=*0x%x): unexpected syscall result (0x%x)", lwcond, res);
	return res;
}