예제 #1
0
static void XAudio2_Update(void) {
	if (do_update && pSourceVoice) {
		do_update = 0;

		while (1) {
			XAUDIO2_VOICE_STATE state;
			XAUDIO2_BUFFER audio_buf;

			#if !defined(DRV_XAUDIO28)
			IXAudio2SourceVoice_GetState(pSourceVoice, &state);
			#else
			IXAudio2SourceVoice_GetState(pSourceVoice, &state, XAUDIO2_VOICE_NOSAMPLESPLAYED);
			#endif
			if (state.BuffersQueued > 0)
				break;
			current_buf %= XAUDIO2_NUM_BUFFERS;
			if (Player_Paused_internal())
				VC_SilenceBytes((SBYTE *) buffers[current_buf], (ULONG) XAUDIO2_BUFFER_SIZE);
			else
				VC_WriteBytes((SBYTE *) buffers[current_buf], (ULONG) XAUDIO2_BUFFER_SIZE);
			memset(&audio_buf, 0, sizeof(XAUDIO2_BUFFER));
			audio_buf.AudioBytes = XAUDIO2_BUFFER_SIZE;
			audio_buf.pAudioData = buffers[current_buf];
			IXAudio2SourceVoice_SubmitSourceBuffer(pSourceVoice, &audio_buf, NULL);
			current_buf++;
			current_buf %= XAUDIO2_NUM_BUFFERS;
		}
		IXAudio2SourceVoice_Start(pSourceVoice, 0, 0);
		threadInUse = 1;
		ResumeThread(UpdateBufferHandle);
	}
}
예제 #2
0
파일: xaudio-c.c 프로젝트: Wyrick/RetroArch
size_t xaudio2_write(xaudio2_t *handle, const void *buf, size_t bytes_)
{
   unsigned bytes = bytes_;
   const uint8_t *buffer = (const uint8_t*)buf;
   while (bytes)
   {
      unsigned need = min(bytes, handle->bufsize - handle->bufptr);
      memcpy(handle->buf + handle->write_buffer * handle->bufsize + handle->bufptr,
            buffer, need);

      handle->bufptr += need;
      buffer += need;
      bytes -= need;

      if (handle->bufptr == handle->bufsize)
      {
         while (handle->buffers == MAX_BUFFERS - 1)
            WaitForSingleObject(handle->hEvent, INFINITE);

         XAUDIO2_BUFFER xa2buffer = {0};
         xa2buffer.AudioBytes = handle->bufsize;
         xa2buffer.pAudioData = handle->buf + handle->write_buffer * handle->bufsize;

         if (FAILED(IXAudio2SourceVoice_SubmitSourceBuffer(handle->pSourceVoice, &xa2buffer, NULL)))
            return 0;

         InterlockedIncrement(&handle->buffers);
         handle->bufptr = 0;
         handle->write_buffer = (handle->write_buffer + 1) & MAX_BUFFERS_MASK;
      }
   }

   return bytes_;
}
예제 #3
0
static DWORD WINAPI UpdateBufferProc(LPVOID lpParameter) {
	while (threadInUse) {
		while (1) {
			XAUDIO2_VOICE_STATE state;
			XAUDIO2_BUFFER audio_buf;

			#if !defined(DRV_XAUDIO28)
			IXAudio2SourceVoice_GetState(pSourceVoice, &state);
			#else
			IXAudio2SourceVoice_GetState(pSourceVoice, &state, XAUDIO2_VOICE_NOSAMPLESPLAYED);
			#endif
			if (state.BuffersQueued >= XAUDIO2_NUM_BUFFERS - 1)
				break;
			MUTEX_LOCK(vars);
			if (Player_Paused_internal())
				VC_SilenceBytes((SBYTE *) buffers[current_buf], (ULONG) XAUDIO2_BUFFER_SIZE);
			else
				VC_WriteBytes((SBYTE *) buffers[current_buf], (ULONG) XAUDIO2_BUFFER_SIZE);
			MUTEX_UNLOCK(vars);
			memset(&audio_buf, 0, sizeof(XAUDIO2_BUFFER));
			audio_buf.AudioBytes = XAUDIO2_BUFFER_SIZE;
			audio_buf.pAudioData = buffers[current_buf];
			IXAudio2SourceVoice_SubmitSourceBuffer(pSourceVoice, &audio_buf, NULL);
			current_buf++;
			current_buf %= XAUDIO2_NUM_BUFFERS;
		}
		WaitForSingleObject(hBufferEvent, INFINITE);
	}
	return 0;
}
예제 #4
0
파일: snd.c 프로젝트: punesemu/puNES
static void INLINE wrbuf(IXAudio2SourceVoice *source, XAUDIO2_BUFFER *x2buf, const BYTE *buffer) {
	x2buf->pAudioData = buffer;

	if(IXAudio2SourceVoice_SubmitSourceBuffer(source, x2buf, NULL) != S_OK) {
		fprintf(stderr, "Unable to submit source buffer\n");
	}
}
예제 #5
0
gc_result gaX_device_queue_xaudio2(ga_DeviceImpl_XAudio2* in_device,
                                   void* in_buffer)
{
  XAUDIO2_BUFFER buf;
  void* data;
  ZeroMemory(&buf, sizeof(XAUDIO2_BUFFER));
  buf.AudioBytes = in_device->numSamples * in_device->sampleSize;
  data = in_device->buffers[in_device->nextBuffer++];
  in_device->nextBuffer %= in_device->numBuffers;
  memcpy(data, in_buffer, buf.AudioBytes);
  buf.pAudioData = data;
  IXAudio2SourceVoice_SubmitSourceBuffer(in_device->source, &buf, 0);
  return GC_SUCCESS;
}
예제 #6
0
파일: xaudio.c 프로젝트: leiradel/RetroArch
static size_t xaudio2_write(xaudio2_t *handle, const uint8_t *buffer, size_t bytes_)
{
   unsigned bytes        = bytes_;

   while (bytes)
   {
      unsigned need   = MIN(bytes, handle->bufsize - handle->bufptr);

      memcpy(handle->buf + handle->write_buffer *
            handle->bufsize + handle->bufptr,
            buffer, need);

      handle->bufptr += need;
      buffer         += need;
      bytes          -= need;

      if (handle->bufptr == handle->bufsize)
      {
         XAUDIO2_BUFFER xa2buffer;

         while (handle->buffers == MAX_BUFFERS - 1)
            WaitForSingleObject(handle->hEvent, INFINITE);

         xa2buffer.Flags      = 0;
         xa2buffer.AudioBytes = handle->bufsize;
         xa2buffer.pAudioData = handle->buf + handle->write_buffer * handle->bufsize;
         xa2buffer.PlayBegin  = 0;
         xa2buffer.PlayLength = 0;
         xa2buffer.LoopBegin  = 0;
         xa2buffer.LoopLength = 0;
         xa2buffer.LoopCount  = 0;
         xa2buffer.pContext   = NULL;

         if (FAILED(IXAudio2SourceVoice_SubmitSourceBuffer(
                     handle->pSourceVoice, &xa2buffer, NULL)))
            return 0;

         InterlockedIncrement((LONG volatile*)&handle->buffers);
         handle->bufptr       = 0;
         handle->write_buffer = (handle->write_buffer + 1) & MAX_BUFFERS_MASK;
      }
   }

   return bytes_;
}
예제 #7
0
static void
XAUDIO2_PlayDevice(_THIS)
{
    XAUDIO2_BUFFER buffer;
    Uint8 *mixbuf = this->hidden->mixbuf;
    Uint8 *nextbuf = this->hidden->nextbuf;
    const int mixlen = this->hidden->mixlen;
    IXAudio2SourceVoice *source = this->hidden->source;
    HRESULT result = S_OK;

    if (!this->enabled) { /* shutting down? */
        return;
    }

    /* Submit the next filled buffer */
    SDL_zero(buffer);
    buffer.AudioBytes = mixlen;
    buffer.pAudioData = nextbuf;
    buffer.pContext = this;

    if (nextbuf == mixbuf) {
        nextbuf += mixlen;
    } else {
        nextbuf = mixbuf;
    }
    this->hidden->nextbuf = nextbuf;

    result = IXAudio2SourceVoice_SubmitSourceBuffer(source, &buffer, NULL);
    if (result == XAUDIO2_E_DEVICE_INVALIDATED) {
        /* !!! FIXME: possibly disconnected or temporary lost. Recover? */
    }

    if (result != S_OK) {  /* uhoh, panic! */
        IXAudio2SourceVoice_FlushSourceBuffers(source);
        SDL_OpenedAudioDeviceDisconnected(this);
    }
}
예제 #8
0
파일: xaudio2.c 프로젝트: ghaith/wine
static void test_looping(IXAudio2 *xa)
{
    HRESULT hr;
    IXAudio2MasteringVoice *master;
    IXAudio2SourceVoice *src;
    WAVEFORMATEX fmt;
    XAUDIO2_BUFFER buf;
    UINT32 played, running_total = 0;

    XA2CALL_0V(StopEngine);

    if(xaudio27)
        hr = IXAudio27_CreateMasteringVoice((IXAudio27*)xa, &master, 2, 44100, 0, 0, NULL);
    else
        hr = IXAudio2_CreateMasteringVoice(xa, &master, 2, 44100, 0, NULL, NULL, AudioCategory_GameEffects);
    ok(hr == S_OK, "CreateMasteringVoice failed: %08x\n", hr);


    fmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
    fmt.nChannels = 2;
    fmt.nSamplesPerSec = 44100;
    fmt.wBitsPerSample = 32;
    fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
    fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign;
    fmt.cbSize = 0;

    XA2CALL(CreateSourceVoice, &src, &fmt, 0, 1.f, &loop_buf, NULL, NULL);
    ok(hr == S_OK, "CreateSourceVoice failed: %08x\n", hr);

    memset(&buf, 0, sizeof(buf));

    buf.AudioBytes = 44100 * fmt.nBlockAlign;
    buf.pAudioData = HeapAlloc(GetProcessHeap(), 0, buf.AudioBytes);
    fill_buf((float*)buf.pAudioData, &fmt, 440, 44100);

    XA2CALL_0(StartEngine);
    ok(hr == S_OK, "StartEngine failed: %08x\n", hr);

    /* play from middle to end */
    buf.PlayBegin = 22050;
    buf.PlayLength = 0;
    buf.LoopBegin = 0;
    buf.LoopLength = 0;
    buf.LoopCount = 0;

    hr = IXAudio2SourceVoice_SubmitSourceBuffer(src, &buf, NULL);
    ok(hr == S_OK, "SubmitSourceBuffer failed: %08x\n", hr);

    played = play_to_completion(src, -1);
    ok(played - running_total == 22050, "Got wrong samples played: %u\n", played - running_total);
    running_total = played;
    ok(nloopends == 0, "Got wrong OnLoopEnd calls: %u\n", nloopends);

    /* play 4410 samples from middle */
    buf.PlayBegin = 22050;
    buf.PlayLength = 4410;
    buf.LoopBegin = 0;
    buf.LoopLength = 0;
    buf.LoopCount = 0;

    hr = IXAudio2SourceVoice_SubmitSourceBuffer(src, &buf, NULL);
    ok(hr == S_OK, "SubmitSourceBuffer failed: %08x\n", hr);

    played = play_to_completion(src, -1);
    ok(played - running_total == 4410, "Got wrong samples played: %u\n", played - running_total);
    running_total = played;
    ok(nloopends == 0, "Got wrong OnLoopEnd calls: %u\n", nloopends);

    /* loop 4410 samples in middle */
    buf.PlayBegin = 0;
    buf.PlayLength = 0;
    buf.LoopBegin = 22050;
    buf.LoopLength = 4410;
    buf.LoopCount = 1;

    hr = IXAudio2SourceVoice_SubmitSourceBuffer(src, &buf, NULL);
    ok(hr == S_OK, "SubmitSourceBuffer failed: %08x\n", hr);

    played = play_to_completion(src, -1);
    ok(played - running_total == 44100 + 4410, "Got wrong samples played: %u\n", played - running_total);
    running_total = played;
    ok(nloopends == 1, "Got wrong OnLoopEnd calls: %u\n", nloopends);

    /* play last half, then loop the whole buffer */
    buf.PlayBegin = 22050;
    buf.PlayLength = 0;
    buf.LoopBegin = 0;
    buf.LoopLength = 0;
    buf.LoopCount = 1;

    hr = IXAudio2SourceVoice_SubmitSourceBuffer(src, &buf, NULL);
    ok(hr == S_OK, "SubmitSourceBuffer failed: %08x\n", hr);

    played = play_to_completion(src, -1);
    ok(played - running_total == 22050 + 44100, "Got wrong samples played: %u\n", played - running_total);
    running_total = played;
    ok(nloopends == 1, "Got wrong OnLoopEnd calls: %u\n", nloopends);

    /* play short segment from middle, loop to the beginning, and end at PlayEnd */
    buf.PlayBegin = 22050;
    buf.PlayLength = 4410;
    buf.LoopBegin = 0;
    buf.LoopLength = 0;
    buf.LoopCount = 1;

    hr = IXAudio2SourceVoice_SubmitSourceBuffer(src, &buf, NULL);
    ok(hr == S_OK, "SubmitSourceBuffer failed: %08x\n", hr);

    played = play_to_completion(src, -1);
    ok(played - running_total == 4410 + (22050 + 4410), "Got wrong samples played: %u\n", played - running_total);
    running_total = played;
    ok(nloopends == 1, "Got wrong OnLoopEnd calls: %u\n", nloopends);

    /* invalid: LoopEnd must be <= PlayEnd
     * xaudio27: play until LoopEnd, loop to beginning, play until PlayEnd */
    buf.PlayBegin = 22050;
    buf.PlayLength = 4410;
    buf.LoopBegin = 0;
    buf.LoopLength = 22050 + 4410 * 2;
    buf.LoopCount = 1;

    hr = IXAudio2SourceVoice_SubmitSourceBuffer(src, &buf, NULL);
    if(xaudio27){
        ok(hr == S_OK, "SubmitSourceBuffer failed: %08x\n", hr);

        played = play_to_completion(src, -1);
        ok(played - running_total == 4410 + (22050 + 4410 * 2), "Got wrong samples played: %u\n", played - running_total);
        running_total = played;
        ok(nloopends == 1, "Got wrong OnLoopEnd calls: %u\n", nloopends);
    }else
        ok(hr == XAUDIO2_E_INVALID_CALL, "SubmitSourceBuffer should have failed: %08x\n", hr);

    /* invalid: LoopEnd must be within play range
     * xaudio27: plays only play range */
    buf.PlayBegin = 22050;
    buf.PlayLength = 0; /* == until end of buffer */
    buf.LoopBegin = 0;
    buf.LoopLength = 22050;
    buf.LoopCount = 1;

    hr = IXAudio2SourceVoice_SubmitSourceBuffer(src, &buf, NULL);
    if(xaudio27){
        ok(hr == S_OK, "SubmitSourceBuffer failed: %08x\n", hr);

        played = play_to_completion(src, -1);
        ok(played - running_total == 22050, "Got wrong samples played: %u\n", played - running_total);
        running_total = played;
        ok(nloopends == 0, "Got wrong OnLoopEnd calls: %u\n", nloopends);
    }else
        ok(hr == XAUDIO2_E_INVALID_CALL, "SubmitSourceBuffer should have failed: %08x\n", hr);

    /* invalid: LoopBegin must be before PlayEnd
     * xaudio27: crashes */
    if(!xaudio27){
        buf.PlayBegin = 0;
        buf.PlayLength = 4410;
        buf.LoopBegin = 22050;
        buf.LoopLength = 4410;
        buf.LoopCount = 1;

        hr = IXAudio2SourceVoice_SubmitSourceBuffer(src, &buf, NULL);
        ok(hr == XAUDIO2_E_INVALID_CALL, "SubmitSourceBuffer should have failed: %08x\n", hr);
    }

    /* infinite looping buffer */
    buf.PlayBegin = 22050;
    buf.PlayLength = 0;
    buf.LoopBegin = 0;
    buf.LoopLength = 0;
    buf.LoopCount = 255;

    hr = IXAudio2SourceVoice_SubmitSourceBuffer(src, &buf, NULL);
    ok(hr == S_OK, "SubmitSourceBuffer failed: %08x\n", hr);

    played = play_to_completion(src, running_total + 88200);
    ok(played - running_total == 22050 + 44100 * 2, "Got wrong samples played: %u\n", played - running_total);
    ok(nloopends == (played - running_total) / 88200 + 1, "Got wrong OnLoopEnd calls: %u\n", nloopends);
    running_total = played;
}
예제 #9
0
파일: xaudio2.c 프로젝트: ghaith/wine
static void test_buffer_callbacks(IXAudio2 *xa)
{
    HRESULT hr;
    IXAudio2MasteringVoice *master;
    IXAudio2SourceVoice *src;
    WAVEFORMATEX fmt;
    XAUDIO2_BUFFER buf;
    XAUDIO2_VOICE_STATE state;
    struct vcb_buf_testdata testdata[5];
    int i;

    obs_calls = 0;
    obe_calls = 0;

    XA2CALL_0V(StopEngine);

    if(xaudio27)
        hr = IXAudio27_CreateMasteringVoice((IXAudio27*)xa, &master, 2, 44100, 0, 0, NULL);
    else
        hr = IXAudio2_CreateMasteringVoice(xa, &master, 2, 44100, 0, NULL, NULL, AudioCategory_GameEffects);
    ok(hr == S_OK, "CreateMasteringVoice failed: %08x\n", hr);

    fmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
    fmt.nChannels = 2;
    fmt.nSamplesPerSec = 44100;
    fmt.wBitsPerSample = 32;
    fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
    fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign;
    fmt.cbSize = 0;

    XA2CALL(CreateSourceVoice, &src, &fmt, 0, 1.f, &vcb_buf, NULL, NULL);
    ok(hr == S_OK, "CreateSourceVoice failed: %08x\n", hr);

    memset(&buf, 0, sizeof(buf));
    buf.AudioBytes = 4410 * fmt.nBlockAlign;
    buf.pAudioData = HeapAlloc(GetProcessHeap(), 0, buf.AudioBytes);
    fill_buf((float*)buf.pAudioData, &fmt, 440, 4410);

    /* submit same buffer fragment 5 times */
    for(i = 0; i < 5; ++i){
        testdata[i].idx = i;
        testdata[i].src = src;
        buf.pContext = &testdata[i];

        hr = IXAudio2SourceVoice_SubmitSourceBuffer(src, &buf, NULL);
        ok(hr == S_OK, "SubmitSourceBuffer failed: %08x\n", hr);
    }

    hr = IXAudio2SourceVoice_Start(src, 0, XAUDIO2_COMMIT_NOW);
    ok(hr == S_OK, "Start failed: %08x\n", hr);


    XA2CALL_0(StartEngine);
    ok(hr == S_OK, "StartEngine failed: %08x\n", hr);

    while(1){
        if(xaudio27)
            IXAudio27SourceVoice_GetState((IXAudio27SourceVoice*)src, &state);
        else
            IXAudio2SourceVoice_GetState(src, &state, 0);
        if(state.SamplesPlayed >= 4410 * 5)
            break;
        Sleep(100);
    }

    ok(state.SamplesPlayed == 4410 * 5, "Got wrong samples played\n");

    HeapFree(GetProcessHeap(), 0, (void*)buf.pAudioData);

    if(xaudio27)
        IXAudio27SourceVoice_DestroyVoice((IXAudio27SourceVoice*)src);
    else
        IXAudio2SourceVoice_DestroyVoice(src);

    IXAudio2MasteringVoice_DestroyVoice(master);
}
예제 #10
0
파일: xaudio2.c 프로젝트: ghaith/wine
static void test_simple_streaming(IXAudio2 *xa)
{
    HRESULT hr;
    IXAudio2MasteringVoice *master;
    IXAudio2SourceVoice *src, *src2;
    IUnknown *vumeter;
    WAVEFORMATEX fmt;
    XAUDIO2_BUFFER buf, buf2;
    XAUDIO2_VOICE_STATE state;
    XAUDIO2_EFFECT_DESCRIPTOR effect;
    XAUDIO2_EFFECT_CHAIN chain;

    memset(&ecb_state, 0, sizeof(ecb_state));
    memset(&src1_state, 0, sizeof(src1_state));
    memset(&src2_state, 0, sizeof(src2_state));

    XA2CALL_0V(StopEngine);

    /* Tests show in native XA2.8, ECB is called from a mixer thread, but VCBs
     * may be called from other threads in any order. So we can't rely on any
     * sequencing between VCB calls.
     *
     * XA2.7 does all mixing from a single thread, so call sequence can be
     * tested. */
    XA2CALL(RegisterForCallbacks, &ecb);
    ok(hr == S_OK, "RegisterForCallbacks failed: %08x\n", hr);

    if(xaudio27)
        hr = IXAudio27_CreateMasteringVoice((IXAudio27*)xa, &master, 2, 44100, 0, 0, NULL);
    else
        hr = IXAudio2_CreateMasteringVoice(xa, &master, 2, 44100, 0, NULL, NULL, AudioCategory_GameEffects);
    ok(hr == S_OK, "CreateMasteringVoice failed: %08x\n", hr);

    /* create first source voice */
    fmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
    fmt.nChannels = 2;
    fmt.nSamplesPerSec = 44100;
    fmt.wBitsPerSample = 32;
    fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
    fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign;
    fmt.cbSize = 0;

    XA2CALL(CreateSourceVoice, &src, &fmt, 0, 1.f, &vcb1, NULL, NULL);
    ok(hr == S_OK, "CreateSourceVoice failed: %08x\n", hr);

    memset(&buf, 0, sizeof(buf));
    buf.AudioBytes = 22050 * fmt.nBlockAlign;
    buf.pAudioData = HeapAlloc(GetProcessHeap(), 0, buf.AudioBytes);
    fill_buf((float*)buf.pAudioData, &fmt, 440, 22050);

    hr = IXAudio2SourceVoice_SubmitSourceBuffer(src, &buf, NULL);
    ok(hr == S_OK, "SubmitSourceBuffer failed: %08x\n", hr);

    hr = IXAudio2SourceVoice_Start(src, 0, XAUDIO2_COMMIT_NOW);
    ok(hr == S_OK, "Start failed: %08x\n", hr);

    /* create second source voice */
    XA2CALL(CreateSourceVoice, &src2, &fmt, 0, 1.f, &vcb2, NULL, NULL);
    ok(hr == S_OK, "CreateSourceVoice failed: %08x\n", hr);

    memset(&buf2, 0, sizeof(buf2));
    buf2.AudioBytes = 22050 * fmt.nBlockAlign;
    buf2.pAudioData = HeapAlloc(GetProcessHeap(), 0, buf2.AudioBytes);
    fill_buf((float*)buf2.pAudioData, &fmt, 220, 22050);

    hr = IXAudio2SourceVoice_SubmitSourceBuffer(src2, &buf2, NULL);
    ok(hr == S_OK, "SubmitSourceBuffer failed: %08x\n", hr);

    hr = IXAudio2SourceVoice_Start(src2, 0, XAUDIO2_COMMIT_NOW);
    ok(hr == S_OK, "Start failed: %08x\n", hr);

    XA2CALL_0(StartEngine);
    ok(hr == S_OK, "StartEngine failed: %08x\n", hr);

    /* hook up volume meter */
    if(xaudio27){
        hr = CoCreateInstance(&CLSID_AudioVolumeMeter, NULL,
                CLSCTX_INPROC_SERVER, &IID_IUnknown, (void**)&vumeter);
        ok(hr == S_OK, "CoCreateInstance(AudioVolumeMeter) failed: %08x\n", hr);
    }else{
        hr = pCreateAudioVolumeMeter(&vumeter);
        ok(hr == S_OK, "CreateAudioVolumeMeter failed: %08x\n", hr);
    }

    effect.InitialState = TRUE;
    effect.OutputChannels = 2;
    effect.pEffect = vumeter;

    chain.EffectCount = 1;
    chain.pEffectDescriptors = &effect;

    hr = IXAudio2MasteringVoice_SetEffectChain(master, &chain);
    ok(hr == S_OK, "SetEffectchain failed: %08x\n", hr);

    IUnknown_Release(vumeter);

    while(1){
        if(xaudio27)
            IXAudio27SourceVoice_GetState((IXAudio27SourceVoice*)src, &state);
        else
            IXAudio2SourceVoice_GetState(src, &state, 0);
        if(state.SamplesPlayed >= 22050)
            break;
        Sleep(100);
    }

    ok(state.SamplesPlayed == 22050, "Got wrong samples played\n");

    HeapFree(GetProcessHeap(), 0, (void*)buf.pAudioData);
    HeapFree(GetProcessHeap(), 0, (void*)buf2.pAudioData);

    if(xaudio27){
        IXAudio27SourceVoice_DestroyVoice((IXAudio27SourceVoice*)src);
        IXAudio27SourceVoice_DestroyVoice((IXAudio27SourceVoice*)src2);
    }else{
        IXAudio2SourceVoice_DestroyVoice(src);
        IXAudio2SourceVoice_DestroyVoice(src2);
    }
    IXAudio2MasteringVoice_DestroyVoice(master);

    XA2CALL_V(UnregisterForCallbacks, &ecb);
}
예제 #11
0
파일: xaudio2.c 프로젝트: kervala/wine
static void test_buffer_callbacks(IXAudio2 *xa)
{
    HRESULT hr;
    IXAudio2MasteringVoice *master;
    IXAudio2SourceVoice *src;
    WAVEFORMATEX fmt;
    XAUDIO2_BUFFER buf;
    XAUDIO2_VOICE_STATE state;
    struct vcb_buf_testdata testdata[5];
    int i, timeout;

    obs_calls = 0;
    obe_calls = 0;

    XA2CALL_0V(StopEngine);

    if(xaudio27)
        hr = IXAudio27_CreateMasteringVoice((IXAudio27*)xa, &master, 2, 44100, 0, 0, NULL);
    else
        hr = IXAudio2_CreateMasteringVoice(xa, &master, 2, 44100, 0, NULL, NULL, AudioCategory_GameEffects);
    ok(hr == S_OK, "CreateMasteringVoice failed: %08x\n", hr);

    /* test OnBufferStart/End callbacks */
    fmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
    fmt.nChannels = 2;
    fmt.nSamplesPerSec = 44100;
    fmt.wBitsPerSample = 32;
    fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
    fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign;
    fmt.cbSize = 0;

    XA2CALL(CreateSourceVoice, &src, &fmt, 0, 1.f, &vcb_buf, NULL, NULL);
    ok(hr == S_OK, "CreateSourceVoice failed: %08x\n", hr);

    memset(&buf, 0, sizeof(buf));
    buf.AudioBytes = 4410 * fmt.nBlockAlign;
    buf.pAudioData = HeapAlloc(GetProcessHeap(), 0, buf.AudioBytes);
    fill_buf((float*)buf.pAudioData, &fmt, 440, 4410);

    /* submit same buffer fragment 5 times */
    for(i = 0; i < 5; ++i){
        testdata[i].idx = i;
        testdata[i].src = src;
        buf.pContext = &testdata[i];

        hr = IXAudio2SourceVoice_SubmitSourceBuffer(src, &buf, NULL);
        ok(hr == S_OK, "SubmitSourceBuffer failed: %08x\n", hr);
    }

    hr = IXAudio2SourceVoice_Start(src, 0, XAUDIO2_COMMIT_NOW);
    ok(hr == S_OK, "Start failed: %08x\n", hr);


    XA2CALL_0(StartEngine);
    ok(hr == S_OK, "StartEngine failed: %08x\n", hr);

    if(xaudio27){
        hr = IXAudio27SourceVoice_SetSourceSampleRate((IXAudio27SourceVoice*)src, 48000);
        todo_wine ok(hr == S_OK, "SetSourceSampleRate failed: %08x\n", hr);
    }else{
        hr = IXAudio2SourceVoice_SetSourceSampleRate(src, 48000);
        ok(hr == XAUDIO2_E_INVALID_CALL, "SetSourceSampleRate should have failed: %08x\n", hr);
    }

    while(1){
        if(xaudio27)
            IXAudio27SourceVoice_GetState((IXAudio27SourceVoice*)src, &state);
        else
            IXAudio2SourceVoice_GetState(src, &state, 0);
        if(state.SamplesPlayed >= 4410 * 5)
            break;
        Sleep(100);
    }

    ok(state.SamplesPlayed == 4410 * 5, "Got wrong samples played\n");

    if(xaudio27)
        IXAudio27SourceVoice_DestroyVoice((IXAudio27SourceVoice*)src);
    else
        IXAudio2SourceVoice_DestroyVoice(src);


    /* test OnStreamEnd callback */
    XA2CALL(CreateSourceVoice, &src, &fmt, 0, 1.f, &loop_buf, NULL, NULL);
    ok(hr == S_OK, "CreateSourceVoice failed: %08x\n", hr);

    buf.Flags = XAUDIO2_END_OF_STREAM;

    hr = IXAudio2SourceVoice_SubmitSourceBuffer(src, &buf, NULL);
    ok(hr == S_OK, "SubmitSourceBuffer failed: %08x\n", hr);

    hr = IXAudio2SourceVoice_Start(src, 0, XAUDIO2_COMMIT_NOW);
    ok(hr == S_OK, "Start failed: %08x\n", hr);

    timeout = 0;
    while(nstreamends == 0 && timeout < 1000){
        Sleep(100);
        timeout += 100;
    }

    ok(nstreamends == 1, "Got wrong number of OnStreamEnd calls: %u\n", nstreamends);

    /* xaudio resets SamplesPlayed after processing an end-of-stream buffer */
    if(xaudio27)
        IXAudio27SourceVoice_GetState((IXAudio27SourceVoice*)src, &state);
    else
        IXAudio2SourceVoice_GetState(src, &state, 0);
    ok(state.SamplesPlayed == 0, "Got wrong samples played\n");

    if(xaudio27)
        IXAudio27SourceVoice_DestroyVoice((IXAudio27SourceVoice*)src);
    else
        IXAudio2SourceVoice_DestroyVoice(src);


    IXAudio2MasteringVoice_DestroyVoice(master);

    HeapFree(GetProcessHeap(), 0, (void*)buf.pAudioData);
}
예제 #12
0
파일: snd.c 프로젝트: punesemu/puNES
BYTE snd_start(void) {
	int psamples;

	if (!cfg->apu.channel[APU_MASTER]) {
		return (EXIT_OK);
	}

	// come prima cosa blocco eventuali riproduzioni
	snd_stop();

	memset(&snd, 0x00, sizeof(_snd));
	memset(&xaudio2, 0x00, sizeof(xaudio2));
	memset(&cbd, 0x00, sizeof(_callback_data));
	snd.cache = &cbd;

	audio_channels(cfg->channels_mode);

	switch (cfg->samplerate) {
		case S48000:
			snd.samplerate = 48000;
			break;
		case S44100:
			snd.samplerate = 44100;
			break;
		case S22050:
			snd.samplerate = 22050;
			break;
		case S11025:
			snd.samplerate = 11025;
			break;
	}

	if (XAudio2Create(&xaudio2.engine, 0, XAUDIO2_DEFAULT_PROCESSOR) != S_OK) {
		MessageBox(NULL,
			"ATTENTION: Unable to create XAudio2 object. Probably you\n"
			"have an incomplete installation of DirectX 10."   ,
			"Error!",
			MB_ICONEXCLAMATION | MB_OK);
		return (EXIT_ERROR);
	}

	if (IXAudio2_CreateMasteringVoice(xaudio2.engine, &xaudio2.master, snd.channels,
			snd.samplerate, 0, 0, NULL) != S_OK) {
		MessageBox(NULL,
			"ATTENTION: Unable to create XAudio2 master voice.",
			"Error!",
			MB_ICONEXCLAMATION | MB_OK);
		return (EXIT_ERROR);
	}

	{
		WAVEFORMATEX wfm;

		memset(&wfm, 0, sizeof(wfm));

		wfm.wFormatTag = WAVE_FORMAT_PCM;
		wfm.nChannels = snd.channels;
		wfm.wBitsPerSample = 16;
		wfm.nSamplesPerSec = snd.samplerate;
		wfm.nBlockAlign = (wfm.nChannels * wfm.wBitsPerSample) / 8;
		wfm.nAvgBytesPerSec = wfm.nSamplesPerSec * wfm.nBlockAlign;
		wfm.cbSize = sizeof(wfm);

		if (IXAudio2_CreateSourceVoice(xaudio2.engine,
				&xaudio2.source,
				&wfm,
				XAUDIO2_VOICE_NOSRC | XAUDIO2_VOICE_NOPITCH,
				XAUDIO2_DEFAULT_FREQ_RATIO,
				&callbacks,
				NULL,
				NULL) != S_OK) {
			MessageBox(NULL,
				"ATTENTION: Unable to create XAudio2 source voice.\n",
				"Error!",
				MB_ICONEXCLAMATION | MB_OK);
			return (EXIT_ERROR);
		}
	}

	{
		double factor = (1.0f / 48000.0f) * (double) snd.samplerate;

		psamples = ((1024 * factor) + ((512 * factor) * cfg->audio_buffer_factor));
	}

	snd.samples = psamples * 2;
	snd.frequency = machine.cpu_hz / (double) snd.samplerate;

	xaudio2.opened = TRUE;

#if !defined (RELEASE)
	xaudio2.tick = gui_get_ms();
#endif

	{
		// dimensione in bytes del buffer
		snd.buffer.size = (psamples * snd.channels * sizeof(*cbd.write)) * 5;

		snd.buffer.limit.low = (snd.buffer.size / 100) * 25;
		snd.buffer.limit.high = (snd.buffer.size / 100) * 55;

#if !defined (RELEASE)
		printf("softw bsize : %-6d - %-6d\n", snd.buffer.size, snd.samples);
		printf("softw limit : %-6d - %-6d\n", snd.buffer.limit.low, snd.buffer.limit.high);
#endif

		// alloco il buffer in memoria
		if (!(cbd.start = (SWORD *) malloc(snd.buffer.size))) {
			MessageBox(NULL,
				"ATTENTION: Unable to allocate audio buffers.\n",
				"Error!",
				MB_ICONEXCLAMATION | MB_OK);
			return (EXIT_ERROR);
		}

		if (!(cbd.silence = (SWORD *) malloc(snd.buffer.size))) {
			MessageBox(NULL,
				"ATTENTION: Unable to allocate silence buffer.\n",
				"Error!",
				MB_ICONEXCLAMATION | MB_OK);
			return (EXIT_ERROR);
		}

		// inizializzo il frame di scrittura
		cbd.write = cbd.start;
		// inizializzo il frame di lettura
		cbd.read = (SBYTE *) cbd.start;
		// punto alla fine del buffer
		cbd.end = cbd.read + snd.buffer.size;
		// creo il lock
		if ((xaudio2.semaphore = CreateSemaphore(NULL, 1, 2, NULL)) == NULL) {
			MessageBox(NULL,
				"ATTENTION: Unable to create XAudio2 semaphore.\n",
				"Error!",
				MB_ICONEXCLAMATION | MB_OK);
			return (EXIT_ERROR);
		}
		// azzero completamente i buffers
		memset(cbd.start, 0x00, snd.buffer.size);
		// azzero completamente il buffer del silenzio
		memset(cbd.silence, 0x00, snd.buffer.size);

		// azzero completamente la struttura XAUDIO2_BUFFER
		memset(&xaudio2.buffer, 0x00, sizeof(xaudio2.buffer));

		xaudio2.buffer.AudioBytes = psamples * sizeof(*cbd.write) * snd.channels;
		//xaudio2.buffer.pAudioData = (const BYTE *) cbd.read;
		xaudio2.buffer.pAudioData = (const BYTE *) cbd.silence;
		xaudio2.buffer.PlayBegin = 0;
		xaudio2.buffer.PlayLength = psamples;
		xaudio2.buffer.LoopBegin = 0;
		xaudio2.buffer.LoopLength = 0;
		xaudio2.buffer.LoopCount = 0;
		xaudio2.buffer.pContext = snd.cache;

		cbd.xa2buffer = &xaudio2.buffer;
		cbd.xa2source = xaudio2.source;
		cbd.lock = xaudio2.semaphore;

		if (IXAudio2SourceVoice_SubmitSourceBuffer(xaudio2.source,
		        (const XAUDIO2_BUFFER *) cbd.xa2buffer, NULL) != S_OK) {
			MessageBox(NULL,
				"ATTENTION: Unable to set sound engine.\n",
				"Error!",
				MB_ICONEXCLAMATION | MB_OK);
			return (EXIT_ERROR);
		}
	}

	if (extcl_snd_start) {
		extcl_snd_start((WORD) snd.samplerate);
	}

	audio_channels_init_mode();

	audio_quality(cfg->audio_quality);

	if(IXAudio2_StartEngine(xaudio2.engine) != S_OK) {
		MessageBox(NULL,
			"ATTENTION: Unable to start sound engine.\n",
			"Error!",
			MB_ICONEXCLAMATION | MB_OK);
		return (EXIT_ERROR);
	}

	if(IXAudio2SourceVoice_Start(xaudio2.source, 0, XAUDIO2_COMMIT_NOW) != S_OK) {
		MessageBox(NULL,
			"ATTENTION: Unable to start source voice.\n",
			"Error!",
			MB_ICONEXCLAMATION | MB_OK);
		return (EXIT_ERROR);
	}

	return (EXIT_OK);
}