This repository has been archived by the owner on Dec 2, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 225
/
SimplePlaySoundStream.h
131 lines (103 loc) · 4.05 KB
/
SimplePlaySoundStream.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//--------------------------------------------------------------------------------------
// SimplePlaySoundStream.h
//
// Advanced Technology Group (ATG)
// Copyright (C) Microsoft Corporation. All rights reserved.
//--------------------------------------------------------------------------------------
#pragma once
#include "DeviceResources.h"
#include "StepTimer.h"
#include "WAVStreamer.h"
//--------------------------------------------------------------------------------------
// Name: struct PlaySoundStreamVoiceContext
// Desc: Frees up the audio buffer after processing
//--------------------------------------------------------------------------------------
struct PlaySoundStreamVoiceContext : public IXAudio2VoiceCallback
{
STDMETHOD_(void, OnVoiceProcessingPassStart) (UINT32) override {}
STDMETHOD_(void, OnVoiceProcessingPassEnd)() override {}
STDMETHOD_(void, OnStreamEnd)() override {}
STDMETHOD_(void, OnBufferStart)(void*) override {}
STDMETHOD_(void, OnBufferEnd)(void* pBufferContext) override
{
SetEvent(m_hBufferEndEvent);
//
// Free up the memory chunk holding the PCM data that was read from disk earlier.
// In a game you would probably return this memory to a pool.
//
free(pBufferContext);
}
STDMETHOD_(void, OnLoopEnd)(void*) override {}
STDMETHOD_(void, OnVoiceError)(void*, HRESULT) override {}
HANDLE m_hBufferEndEvent;
PlaySoundStreamVoiceContext() noexcept(false) : m_hBufferEndEvent(nullptr)
{
m_hBufferEndEvent = CreateEventEx(nullptr, nullptr, 0, EVENT_ALL_ACCESS);
if (!m_hBufferEndEvent)
{
throw std::exception("CreateEvent");
}
}
virtual ~PlaySoundStreamVoiceContext()
{
if (m_hBufferEndEvent)
{
CloseHandle(m_hBufferEndEvent);
m_hBufferEndEvent = nullptr;
}
}
};
// A basic sample implementation that creates a D3D11 device and
// provides a render loop.
class Sample
{
public:
Sample() noexcept(false);
~Sample() = default;
Sample(Sample&&) = default;
Sample& operator= (Sample&&) = default;
Sample(Sample const&) = delete;
Sample& operator= (Sample const&) = delete;
// Initialization and management
void Initialize(IUnknown* window);
// Basic game loop
void Tick();
// Messages
void OnSuspending();
void OnResuming();
private:
static const uint32_t STREAMING_BUFFER_SIZE = 65536;
static const size_t MAX_BUFFER_COUNT = 3;
void Update(DX::StepTimer const& timer);
void Render();
void Clear();
void CreateDeviceDependentResources();
void CreateWindowSizeDependentResources();
static DWORD WINAPI ReadFileThread(LPVOID lpParam);
static DWORD WINAPI SubmitAudioBufferThread(LPVOID lpParam);
HRESULT LoadPCMFile(const wchar_t* szFilename);
// Device resources.
std::unique_ptr<DX::DeviceResources> m_deviceResources;
// Rendering loop timer.
uint64_t m_frame;
DX::StepTimer m_timer;
// Input devices.
std::unique_ptr<DirectX::GamePad> m_gamePad;
// Render objects.
std::unique_ptr<DirectX::GraphicsMemory> m_graphicsMemory;
std::unique_ptr<DirectX::SpriteBatch> m_spriteBatch;
std::unique_ptr<DirectX::SpriteFont> m_font;
Microsoft::WRL::ComPtr<ID3D11ShaderResourceView> m_background;
// Audio objects.
Microsoft::WRL::ComPtr<IXAudio2> m_pXAudio2;
IXAudio2MasteringVoice* m_pMasteringVoice;
IXAudio2SourceVoice* m_pSourceVoice;
bool m_DoneSubmitting;
PlaySoundStreamVoiceContext m_VoiceContext;
WaveFile m_WaveFile;
uint32_t m_waveSize;
uint32_t m_currentPosition;
XAUDIO2_BUFFER m_Buffers[MAX_BUFFER_COUNT];
size_t m_NumberOfBuffersProduced;
size_t m_NumberOfBuffersConsumed;
};