コード例 #1
0
void SoundOutput_DirectSound::create_sound_buffer()
{
	WAVEFORMATEXTENSIBLE wave_format;
	wave_format.Format.wFormatTag = WAVE_FORMAT_EXTENSIBLE;
	wave_format.Format.nChannels = 2;
	wave_format.Format.nSamplesPerSec = mixing_frequency;
	wave_format.Format.nBlockAlign = get_bytes_per_sample();
	wave_format.Format.nAvgBytesPerSec = wave_format.Format.nSamplesPerSec * wave_format.Format.nBlockAlign;
	wave_format.Format.wBitsPerSample = sizeof(float)*8;
	wave_format.Format.cbSize = 22;
	wave_format.Samples.wValidBitsPerSample = wave_format.Format.wBitsPerSample;
	wave_format.dwChannelMask = SPEAKER_FRONT_LEFT | SPEAKER_FRONT_RIGHT;
	wave_format.SubFormat = KSDATAFORMAT_SUBTYPE_IEEE_FLOAT;

	DSBUFFERDESC desc;
	desc.dwSize = sizeof(DSBUFFERDESC); 
	desc.dwFlags = DSBCAPS_CTRLPOSITIONNOTIFY | DSBCAPS_GLOBALFOCUS | DSBCAPS_GETCURRENTPOSITION2;
	desc.dwBufferBytes = get_buffer_size();
	desc.dwReserved = 0;
	desc.lpwfxFormat = &wave_format.Format; 
	desc.guid3DAlgorithm = GUID_NULL;

	HRESULT err = directsound->CreateSoundBuffer(&desc, &soundbuffer, NULL);
	if (FAILED(err))
		throw Exception("IDirectSound8::CreateSoundBuffer failed");
}
コード例 #2
0
void SoundOutput_DirectSound::write_to_sound_buffer(int write_pos, const float *data, int size)
{
	DWORD size1 = 0, size2 = 0;
	void *ptr1 = 0, *ptr2 = 0;
	HRESULT err = soundbuffer->Lock(write_pos*get_bytes_per_sample(), size*get_bytes_per_sample(), (void **) &ptr1, &size1, (void **) &ptr2, &size2, 0);
	if (FAILED(err))
		throw Exception("IDirectSoundBuffer8::Lock failed");

	char *_data = (char *) data;
	if (ptr1)
		memcpy(ptr1, _data, size1);
	if (ptr2)
		memcpy(ptr2, _data+size1, size2);

	err = soundbuffer->Unlock(ptr1, size1, ptr2, size2);
	if (FAILED(err))
		throw Exception("IDirectSoundBuffer8::Unlock failed");
}
コード例 #3
0
int SoundOutput_DirectSound::find_fragment_write_position()
{
	DWORD play = 0, write = 0;
	HRESULT err = soundbuffer->GetCurrentPosition(&play, &write);
	if (FAILED(err))
		throw Exception("IDirectSoundBuffer8::GetCurrentPosition failed");

	int fragment_index = ((play/get_bytes_per_sample() + frag_size + frag_size/2) / frag_size) % get_fragment_count();
	return fragment_index * frag_size;
}
コード例 #4
0
ファイル: pl_snd.c プロジェクト: 173210/psplib4vita
static int channel_thread(int args, void *argp)
{
  volatile int bufidx = 0;
  int channel = *(int*)argp;
  int i, j;
  unsigned short *ptr_m;
  unsigned int *ptr_s;
  void *bufptr;
  unsigned int samples;
  pl_snd_callback callback;
  pl_snd_channel_info *ch_info;

  ch_info = &sound_stream[channel];
  for (j = 0; j < 2; j++)
    memset(ch_info->sample_buffer[j], 0,
           ch_info->samples[j] * get_bytes_per_sample(channel));

  while (!sound_stop)
  {
    callback = ch_info->callback;
    bufptr = ch_info->sample_buffer[bufidx];
    samples = ch_info->samples[bufidx];

    if (callback && !ch_info->paused)
      /* Use callback to fill buffer */
      callback(bufptr, samples, ch_info->user_data);
    else
    {
      /* Fill buffer with silence */
      if (ch_info->stereo)
        for (i = 0, ptr_s = bufptr; i < samples; i++) *(ptr_s++) = 0;
      else
        for (i = 0, ptr_m = bufptr; i < samples; i++) *(ptr_m++) = 0;
    }

    /* Play sound */
	  play_blocking(channel,
                  ch_info->left_vol,
                  ch_info->right_vol,
                  bufptr);

    /* Switch active buffer */
    bufidx = (bufidx ? 0 : 1);
  }

  sceKernelExitThread(0);
  return 0;
}
コード例 #5
0
void SoundOutput_DirectSound::set_notify_positions()
{
	int num_fragments = get_fragment_count();
	if (num_fragments > 0)
	{
		std::vector<DSBPOSITIONNOTIFY> notify_positions;
		for (int i=0; i<num_fragments; i++)
		{
			DSBPOSITIONNOTIFY notify;
			notify.dwOffset = i*frag_size*get_bytes_per_sample();
			notify.hEventNotify = sleep_event;
			notify_positions.push_back(notify);
		}
		HRESULT result = notify->SetNotificationPositions(num_fragments, &notify_positions[0]);
		if (FAILED(result))
			throw Exception("IDirecTsoundNotify::SetNotificationPositions failed");
	}
}
コード例 #6
0
ファイル: alsa.c プロジェクト: fedoracdu/tyl_player
int write_to_alsa(const void *buf, unsigned int size)
{
	int	ret = 0;

	while (size > 0) {
		ret = snd_pcm_writei(playback_handle, buf, size);
		if (ret == -EAGAIN)
			continue;
		if (ret < 0) {
			if (xrun_recover(ret) < 0) {
				fprintf(stderr, "alsa write error: (%s)\n", snd_strerror(ret));
				break;
			}
		}

		buf += audio_channels * get_bytes_per_sample(audio_format) * ret;
		size -= ret;
	}

	return ret;
}
コード例 #7
0
int SoundOutput_DirectSound::get_buffer_size() const
{
	return frag_size * get_bytes_per_sample() * get_fragment_count();
}
コード例 #8
0
ファイル: pl_snd.c プロジェクト: 173210/psplib4vita
int pl_snd_init(int sample_count,
                int stereo)
{
  int i, j, failed;
  sound_stop = 0;
  sound_ready = 0;

  /* Check sample count */
  if (sample_count <= 0) sample_count = DEFAULT_SAMPLES;
  sample_count = PL_SND_ALIGN_SAMPLE(sample_count);

  pl_snd_channel_info *ch_info;
  for (i = 0; i < AUDIO_CHANNELS; i++)
  {
    ch_info = &sound_stream[i];
    ch_info->sound_ch_handle = -1;
    ch_info->thread_handle = -1;
    ch_info->left_vol = VOLUME_MAX;
    ch_info->right_vol = VOLUME_MAX;
    ch_info->callback = NULL;
    ch_info->user_data = NULL;
    ch_info->paused = 1;
    ch_info->stereo = stereo;

    for (j = 0; j < 2; j++)
    {
      ch_info->sample_buffer[j] = NULL;
      ch_info->samples[j] = 0;
    }
  }

  /* Initialize buffers */
  for (i = 0; i < AUDIO_CHANNELS; i++)
  {
    ch_info = &sound_stream[i];
    for (j = 0; j < 2; j++)
    {
      if (!(ch_info->sample_buffer[j] =
              (short*)malloc(sample_count * get_bytes_per_sample(i))))
      {
        free_buffers();
        return 0;
      }

      ch_info->samples[j] = sample_count;
    }
  }

  /* Initialize channels */
  for (i = 0, failed = 0; i < AUDIO_CHANNELS; i++)
  {
    sound_stream[i].sound_ch_handle =
      sceAudioOutOpenPort(PSP2_AUDIO_OUT_PORT_TYPE_MAIN,
                        sample_count, 48000,
                        (stereo)
                          ? PSP2_AUDIO_OUT_MODE_STEREO
                          : PSP2_AUDIO_OUT_MODE_MONO);

    if (sound_stream[i].sound_ch_handle < 0)
    {
      failed = 1;
      break;
    }
  }

  if (failed)
  {
    for (i = 0; i < AUDIO_CHANNELS; i++)
    {
      if (sound_stream[i].sound_ch_handle != -1)
      {
        sceAudioOutReleasePort(sound_stream[i].sound_ch_handle);
        sound_stream[i].sound_ch_handle = -1;
      }
    }

    free_buffers();
    return 0;
  }

  sound_ready = 1;

  char label[16];
  strcpy(label, "audiotX");

  for (i = 0; i < AUDIO_CHANNELS; i++)
  {
    label[6] = '0' + i;
    sound_stream[i].thread_handle =
      sceKernelCreateThread(label, (void*)&channel_thread, 0x10000100, 0x10000,
        0, 0, NULL);

    if (sound_stream[i].thread_handle < 0)
    {
      sound_stream[i].thread_handle = -1;
      failed = 1;
      break;
    }

    if (sceKernelStartThread(sound_stream[i].thread_handle, sizeof(i), &i) != 0)
    {
      failed = 1;
      break;
    }
  }

  if (failed)
  {
    sound_stop = 1;
    for (i = 0; i < AUDIO_CHANNELS; i++)
    {
      if (sound_stream[i].thread_handle != -1)
      {
        //sceKernelWaitThreadEnd(sound_stream[i].threadhandle,NULL);
        sceKernelDeleteThread(sound_stream[i].thread_handle);
      }

      sound_stream[i].thread_handle = -1;
    }

    sound_ready = 0;
    free_buffers();
    return 0;
  }

  return sample_count;
}