World of Might and Magic  0.2.0
Open reimplementation of Might and Magic 6 7 8 game engine
Класс OpenALSoundProvider

#include <OpenALSoundProvider.h>

Классы

struct  StreamingTrackBuffer
 
struct  TrackBuffer
 

Открытые члены

 OpenALSoundProvider ()
 
virtual ~OpenALSoundProvider ()
 
bool Initialize ()
 
void Release ()
 
void DeleteStreamingTrack (StreamingTrackBuffer **buffer)
 
void DeleteBuffer16 (TrackBuffer **buffer)
 
float alBufferLength (unsigned int buffer)
 
StreamingTrackBufferCreateStreamingTrack16 (int num_channels, int sample_rate, int bytes_per_sample)
 
void Stream16 (StreamingTrackBuffer *buffer, int num_samples, const void *samples, bool wait=false)
 
TrackBufferCreateTrack16 (int num_channels, int sample_rate, const void *data, size_t size)
 
void PlayTrack16 (TrackBuffer *buffer, bool loop=false, bool wait=false)
 
void SetListenerPosition (float x, float y, float z)
 
void SetOrientation (float yaw, float pitch)
 

Защищенные данные

ALCdevicedevice
 
ALCcontextcontext
 

Подробное описание

См. определение в файле OpenALSoundProvider.h строка 12

Конструктор(ы)

◆ OpenALSoundProvider()

OpenALSoundProvider::OpenALSoundProvider ( )

См. определение в файле OpenALSoundProvider.cpp строка 43

43  {
44  device = nullptr;
45  context = nullptr;
46 }

Перекрестные ссылки context и device.

◆ ~OpenALSoundProvider()

OpenALSoundProvider::~OpenALSoundProvider ( )
virtual

См. определение в файле OpenALSoundProvider.cpp строка 48

48 { Release(); }

Перекрестные ссылки Release().

+ Граф вызовов:

Методы

◆ Initialize()

bool OpenALSoundProvider::Initialize ( )

См. определение в файле OpenALSoundProvider.cpp строка 50

50  {
51  const char *device_names = alcGetString(nullptr, ALC_ALL_DEVICES_SPECIFIER);
52  if (!device_names) {
53  device_names = alcGetString(nullptr, ALC_DEVICE_SPECIFIER);
54  }
55 
56  if (device_names) {
57  for (const char *device_name = device_names; device_name[0];
58  device_name += strlen(device_name) + 1) {
59  log("al: device found \"%s\"", device_name);
60  }
61  }
62 
63  const char *defname = alcGetString(0, ALC_DEFAULT_DEVICE_SPECIFIER);
64 
65  device = alcOpenDevice(defname);
66  if (device == nullptr) {
67  CheckError();
68  log("al: Default sound device not present");
69  return false;
70  }
71 
72  context = alcCreateContext(device, nullptr);
73  if (context == nullptr) {
74  CheckError();
75  Release();
76  return false;
77  }
78 
79  if (alcMakeContextCurrent(context) != ALC_TRUE) {
80  CheckError();
81  Release();
82  return false;
83  }
84 
85  alListener3f(AL_POSITION, 0.f, 0.f, 0.f);
86  alListener3f(AL_VELOCITY, 0.f, 0.f, 0.f);
87  ALfloat listenerOri[] = {0.f, 1.f, 0.f, 0.f, 0.f, -1.f};
88  alListenerfv(AL_ORIENTATION, listenerOri);
89 
90  return true;
91 }

Перекрестные ссылки alcCreateContext(), alcGetString(), alcMakeContextCurrent(), alcOpenDevice(), alListener3f(), alListenerfv(), CheckError(), context, device, log() и Release().

Используется в MPlayer::MPlayer().

+ Граф вызовов:
+ Граф вызова функции:

◆ Release()

void OpenALSoundProvider::Release ( )

См. определение в файле OpenALSoundProvider.cpp строка 106

106  {
107  alcMakeContextCurrent(nullptr);
108  if (context) {
110  }
111  if (device) {
113  }
114 }

Перекрестные ссылки alcCloseDevice(), alcDestroyContext(), alcMakeContextCurrent(), context и device.

Используется в Initialize() и ~OpenALSoundProvider().

+ Граф вызовов:
+ Граф вызова функции:

◆ DeleteStreamingTrack()

void OpenALSoundProvider::DeleteStreamingTrack ( StreamingTrackBuffer **  buffer)

См. определение в файле OpenALSoundProvider.cpp строка 116

116  {
117  if (!buffer && !*buffer) return;
118  auto track = *buffer;
119 
120  int status;
121  alGetSourcei(track->source_id, AL_SOURCE_STATE, &status);
122  if (status == AL_PLAYING) {
123  alSourceStop(track->source_id);
124  if (CheckError()) assert(false);
125  }
126 
127  int num_processed_buffers = 0;
128  int num_queued_buffers = 0;
129  alGetSourcei(track->source_id, AL_BUFFERS_PROCESSED,
130  &num_processed_buffers);
131  alGetSourcei(track->source_id, AL_BUFFERS_QUEUED, &num_queued_buffers);
132  // int num_track_buffers = num_queued_buffers + num_processed_buffers;
133  for (int i = 0; i < num_processed_buffers; ++i) {
134  unsigned int buffer_id;
135  alSourceUnqueueBuffers(track->source_id, 1, &buffer_id);
136  if (!CheckError()) {
137  alDeleteBuffers(1, &buffer_id);
138  } else {
139  assert(false);
140  }
141  }
142 
143  alDeleteSources(1, &track->source_id);
144  CheckError();
145 
146  delete *buffer;
147  *buffer = nullptr;
148 }

Перекрестные ссылки alDeleteBuffers(), alDeleteSources(), alGetSourcei(), alSourceStop(), alSourceUnqueueBuffers() и CheckError().

Используется в Movie::Close().

+ Граф вызовов:
+ Граф вызова функции:

◆ DeleteBuffer16()

void OpenALSoundProvider::DeleteBuffer16 ( TrackBuffer **  buffer)

См. определение в файле OpenALSoundProvider.cpp строка 150

150  {
151  alDeleteBuffers(1, &(*buffer)->buffer_id);
152  CheckError();
153 
154  delete *buffer;
155  *buffer = nullptr;
156 }

Перекрестные ссылки alDeleteBuffers() и CheckError().

+ Граф вызовов:

◆ alBufferLength()

float OpenALSoundProvider::alBufferLength ( unsigned int  buffer)

См. определение в файле OpenALSoundProvider.cpp строка 158

158  {
159  int size, bits, channels, freq;
160 
161  alGetBufferi(buffer, AL_SIZE, &size);
162  alGetBufferi(buffer, AL_BITS, &bits);
163  alGetBufferi(buffer, AL_CHANNELS, &channels);
164  alGetBufferi(buffer, AL_FREQUENCY, &freq);
165  if (CheckError()) {
166  return 0.f;
167  }
168 
169  return (ALfloat)((ALuint)size / channels / (bits / 8)) / (ALfloat)freq;
170 }

Перекрестные ссылки alGetBufferi() и CheckError().

Используется в PlayTrack16().

+ Граф вызовов:
+ Граф вызова функции:

◆ CreateStreamingTrack16()

OpenALSoundProvider::StreamingTrackBuffer * OpenALSoundProvider::CreateStreamingTrack16 ( int  num_channels,
int  sample_rate,
int  bytes_per_sample 
)

См. определение в файле OpenALSoundProvider.cpp строка 173

174  {
175  Assert(bytes_per_sample == 2,
176  "OpenALSoundProvider: unsupported sample size: %u",
177  bytes_per_sample);
178 
179  ALenum sound_format;
180  switch (num_channels) {
181  case 1:
182  sound_format = AL_FORMAT_MONO16;
183  break;
184  case 2:
185  sound_format = AL_FORMAT_STEREO16;
186  break;
187  default:
188  if (alIsExtensionPresent("AL_EXT_MCFORMATS")) {
189  switch (num_channels) {
190  case 4:
191  sound_format = alGetEnumValue("AL_FORMAT_QUAD16");
192  break;
193  case 6:
194  sound_format = alGetEnumValue("AL_FORMAT_51CHN16");
195  break;
196  case 7:
197  sound_format = alGetEnumValue("AL_FORMAT_61CHN16");
198  break;
199  case 8:
200  sound_format = alGetEnumValue("AL_FORMAT_71CHN16");
201  break;
202  }
203  }
204  Error("Unsupported number of audio channels: %u", num_channels);
205  }
206 
207  unsigned int al_source = -1;
208  alGenSources(1, &al_source);
209  if (CheckError()) {
210  return nullptr;
211  }
212 
213  alSourcei(al_source, AL_LOOPING, AL_FALSE);
214  alSourcef(al_source, AL_PITCH, 1.f);
215  alSourcef(al_source, AL_GAIN, 1.f);
216  alSource3f(al_source, AL_POSITION, 0.f, 0.f, 0.f);
217  alSource3f(al_source, AL_VELOCITY, 0.f, 0.f, 0.f);
218 
219  StreamingTrackBuffer *ret = new StreamingTrackBuffer;
220  ret->source_id = al_source;
221  ret->sample_format = sound_format;
222  ret->sample_rate = sample_rate;
223  return ret;
224 }

Перекрестные ссылки alGenSources(), alGetEnumValue(), alIsExtensionPresent(), alSource3f(), alSourcef(), alSourcei(), CheckError(), OpenALSoundProvider::StreamingTrackBuffer::sample_format, OpenALSoundProvider::StreamingTrackBuffer::sample_rate и OpenALSoundProvider::StreamingTrackBuffer::source_id.

Используется в Movie::Load().

+ Граф вызовов:
+ Граф вызова функции:

◆ Stream16()

void OpenALSoundProvider::Stream16 ( StreamingTrackBuffer buffer,
int  num_samples,
const void samples,
bool  wait = false 
)

См. определение в файле OpenALSoundProvider.cpp строка 226

228  {
229  if (buffer == nullptr) {
230  return;
231  }
232 
233  int bytes_per_sample = 2;
234 
235  int num_processed_buffers = 0;
236  alGetSourcei(buffer->source_id, AL_BUFFERS_PROCESSED,
237  &num_processed_buffers);
238  if (num_processed_buffers > 0) {
239  unsigned int *processed_buffer_ids =
240  new unsigned int[num_processed_buffers];
241  alSourceUnqueueBuffers(buffer->source_id, num_processed_buffers,
242  processed_buffer_ids);
243  if (CheckError()) {
244  log("OpenAL: Faile to get played buffers.");
245  } else {
246  alDeleteBuffers(num_processed_buffers, processed_buffer_ids);
247  if (CheckError()) {
248  log("OpenAL: Faile to delete played buffers.");
249  }
250  }
251  delete[] processed_buffer_ids;
252  }
253 
254  unsigned int al_buffer;
255  alGenBuffers(1, &al_buffer);
256  alBufferData(al_buffer, buffer->sample_format, samples,
257  num_samples * bytes_per_sample, buffer->sample_rate);
258  if (CheckError()) {
259  alDeleteBuffers(1, &al_buffer);
260  return;
261  }
262 
263  alSourceQueueBuffers(buffer->source_id, 1, &al_buffer);
264  if (CheckError()) {
265  alDeleteBuffers(1, &al_buffer);
266  return;
267  }
268 
269  volatile int status;
270  alGetSourcei(buffer->source_id, AL_SOURCE_STATE, (int *)&status);
271  if (status != AL_PLAYING) {
272  alSourcePlay(buffer->source_id);
273  if (CheckError()) {
274  assert(false);
275  }
276 
277  if (wait) {
278  do {
279  alGetSourcei(buffer->source_id, AL_SOURCE_STATE,
280  (int *)&status);
281  } while (status == AL_PLAYING);
282  }
283  }
284 }

Перекрестные ссылки alBufferData(), alDeleteBuffers(), alGenBuffers(), alGetSourcei(), alSourcePlay(), alSourceQueueBuffers(), alSourceUnqueueBuffers(), CheckError() и log().

Используется в Movie::GetFrame().

+ Граф вызовов:
+ Граф вызова функции:

◆ CreateTrack16()

OpenALSoundProvider::TrackBuffer * OpenALSoundProvider::CreateTrack16 ( int  num_channels,
int  sample_rate,
const void data,
size_t  size 
)

См. определение в файле OpenALSoundProvider.cpp строка 286

287  {
288  ALenum sound_format;
289  switch (num_channels) {
290  case 1: {
291  sound_format = AL_FORMAT_MONO16;
292  break;
293  }
294  case 2: {
295  sound_format = AL_FORMAT_STEREO16;
296  break;
297  }
298  default: {
299  if (alIsExtensionPresent("AL_EXT_MCFORMATS")) {
300  switch (num_channels) {
301  case 4:
302  sound_format = alGetEnumValue("AL_FORMAT_QUAD16");
303  break;
304  case 6:
305  sound_format = alGetEnumValue("AL_FORMAT_51CHN16");
306  break;
307  case 7:
308  sound_format = alGetEnumValue("AL_FORMAT_61CHN16");
309  break;
310  case 8:
311  sound_format = alGetEnumValue("AL_FORMAT_71CHN16");
312  break;
313  }
314  }
315  Error("Unsupported number of audio channels: %u", num_channels);
316  }
317  }
318 
319  ALuint al_source = -1;
320  alGenSources((ALuint)1, &al_source);
321  if (CheckError()) {
322  return nullptr;
323  }
324 
325  alSourcei(al_source, AL_LOOPING, AL_FALSE);
326  alSourcef(al_source, AL_PITCH, 1.f);
327  alSourcef(al_source, AL_GAIN, 1.f);
328  alSource3f(al_source, AL_POSITION, 0.f, 0.f, 0.f);
329  alSource3f(al_source, AL_VELOCITY, 0.f, 0.f, 0.f);
330 
331  ALuint al_buffer = -1;
332  alGenBuffers(1, &al_buffer);
333  if (CheckError()) {
334  alDeleteSources(1, &al_source);
335  return nullptr;
336  }
337 
338  alBufferData(al_buffer, sound_format, data, size, sample_rate);
339  if (CheckError()) {
340  alDeleteSources(1, &al_source);
341  alDeleteBuffers(1, &al_buffer);
342  return nullptr;
343  }
344 
345  alSourcei(al_source, AL_BUFFER, al_buffer);
346  if (CheckError()) {
347  alDeleteSources(1, &al_source);
348  alDeleteBuffers(1, &al_buffer);
349  return nullptr;
350  }
351 
352  TrackBuffer *ret = new TrackBuffer;
353  ret->source_id = al_source;
354  ret->buffer_id = al_buffer;
355  return ret;
356 }

Перекрестные ссылки alBufferData(), alDeleteBuffers(), alDeleteSources(), alGenBuffers(), alGenSources(), alGetEnumValue(), alIsExtensionPresent(), alSource3f(), alSourcef(), alSourcei(), OpenALSoundProvider::TrackBuffer::buffer_id, CheckError() и OpenALSoundProvider::TrackBuffer::source_id.

+ Граф вызовов:

◆ PlayTrack16()

void OpenALSoundProvider::PlayTrack16 ( TrackBuffer buffer,
bool  loop = false,
bool  wait = false 
)

См. определение в файле OpenALSoundProvider.cpp строка 358

359  {
360  int status;
361  alGetSourcei(buffer->source_id, AL_SOURCE_STATE, (int *)&status);
362  if (status == AL_PLAYING) {
363  return;
364  }
365 
366  alSourcei(buffer->source_id, AL_LOOPING, loop ? AL_TRUE : AL_FALSE);
367  alSourcePlay(buffer->source_id);
368  if (CheckError()) {
369  assert(false);
370  }
371 
372  if (wait && !loop) {
373  float track_length = alBufferLength(buffer->buffer_id);
374  do {
375  float track_offset = 0;
376  alGetSourcef(buffer->source_id, AL_SEC_OFFSET, &track_offset);
377  log("playing: %.4f/%.4f\n", track_offset, track_length);
378 
379  alGetSourcei(buffer->source_id, AL_SOURCE_STATE, (int *)&status);
380  } while (status == AL_PLAYING);
381  }
382 }

Перекрестные ссылки alBufferLength(), alGetSourcef(), alGetSourcei(), alSourcei(), alSourcePlay(), CheckError() и log().

+ Граф вызовов:

◆ SetListenerPosition()

void OpenALSoundProvider::SetListenerPosition ( float  x,
float  y,
float  z 
)

См. определение в файле OpenALSoundProvider.cpp строка 93

93  {
94  alListener3f(AL_POSITION, x, y, z);
95 }

Перекрестные ссылки alListener3f().

Используется в AudioPlayer::PlaySound() и AudioPlayer::UpdateSounds().

+ Граф вызовов:
+ Граф вызова функции:

◆ SetOrientation()

void OpenALSoundProvider::SetOrientation ( float  yaw,
float  pitch 
)

См. определение в файле OpenALSoundProvider.cpp строка 97

97  {
98  float x = cos(pitch) * cos(yaw);
99  float y = sin(yaw) * cos(pitch);
100  float z = -sin(pitch);
101 
102  ALfloat listenerOri[] = {-x, y, z, 0.f, 0.f, 1.f};
103  alListenerfv(AL_ORIENTATION, listenerOri);
104 }

Перекрестные ссылки alListenerfv().

Используется в AudioPlayer::UpdateSounds().

+ Граф вызовов:
+ Граф вызова функции:

Данные класса

◆ device

ALCdevice* OpenALSoundProvider::device
protected

См. определение в файле OpenALSoundProvider.h строка 46

Используется в Initialize(), OpenALSoundProvider() и Release().

◆ context

ALCcontext* OpenALSoundProvider::context
protected

См. определение в файле OpenALSoundProvider.h строка 47

Используется в Initialize(), OpenALSoundProvider() и Release().


Объявления и описания членов классов находятся в файлах:
alGenSources
AL_API void AL_APIENTRY alGenSources(ALsizei n, ALuint *sources)
alcGetString
const ALC_API ALCchar *ALC_APIENTRY alcGetString(ALCdevice *device, ALCenum param)
OpenALSoundProvider::context
ALCcontext * context
Definition: OpenALSoundProvider.h:47
CheckError
bool CheckError()
Definition: OpenALSoundProvider.cpp:31
ALenum
int ALenum
Definition: al.h:65
alcDestroyContext
ALC_API void ALC_APIENTRY alcDestroyContext(ALCcontext *context)
alSourcef
AL_API void AL_APIENTRY alSourcef(ALuint source, ALenum param, ALfloat value)
z
GLdouble GLdouble z
Definition: SDL_opengl_glext.h:407
alIsExtensionPresent
AL_API ALboolean AL_APIENTRY alIsExtensionPresent(const ALchar *extname)
alBufferData
AL_API void AL_APIENTRY alBufferData(ALuint buffer, ALenum format, const ALvoid *data, ALsizei size, ALsizei freq)
alSourceUnqueueBuffers
AL_API void AL_APIENTRY alSourceUnqueueBuffers(ALuint source, ALsizei nb, ALuint *buffers)
alSourceStop
AL_API void AL_APIENTRY alSourceStop(ALuint source)
alListener3f
AL_API void AL_APIENTRY alListener3f(ALenum param, ALfloat value1, ALfloat value2, ALfloat value3)
buffer
EGLContext EGLenum EGLClientBuffer buffer
Definition: SDL_egl.h:952
y
EGLSurface EGLint EGLint y
Definition: SDL_egl.h:1596
x
EGLSurface EGLint x
Definition: SDL_egl.h:1596
alGetSourcei
AL_API void AL_APIENTRY alGetSourcei(ALuint source, ALenum param, ALint *value)
alSourceQueueBuffers
AL_API void AL_APIENTRY alSourceQueueBuffers(ALuint source, ALsizei nb, const ALuint *buffers)
alGetBufferi
AL_API void AL_APIENTRY alGetBufferi(ALuint buffer, ALenum param, ALint *value)
f
GLfloat f
Definition: SDL_opengl_glext.h:1873
OpenALSoundProvider::alBufferLength
float alBufferLength(unsigned int buffer)
Definition: OpenALSoundProvider.cpp:158
alcOpenDevice
ALC_API ALCdevice *ALC_APIENTRY alcOpenDevice(const ALCchar *devicename)
alDeleteBuffers
AL_API void AL_APIENTRY alDeleteBuffers(ALsizei n, const ALuint *buffers)
alSource3f
AL_API void AL_APIENTRY alSource3f(ALuint source, ALenum param, ALfloat value1, ALfloat value2, ALfloat value3)
alListenerfv
AL_API void AL_APIENTRY alListenerfv(ALenum param, const ALfloat *values)
alSourcePlay
AL_API void AL_APIENTRY alSourcePlay(ALuint source)
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1974
alDeleteSources
AL_API void AL_APIENTRY alDeleteSources(ALsizei n, const ALuint *sources)
alSourcei
AL_API void AL_APIENTRY alSourcei(ALuint source, ALenum param, ALint value)
alcCloseDevice
ALC_API ALCboolean ALC_APIENTRY alcCloseDevice(ALCdevice *device)
alGetEnumValue
AL_API ALenum AL_APIENTRY alGetEnumValue(const ALchar *ename)
ALuint
unsigned int ALuint
Definition: al.h:59
OpenALSoundProvider::Release
void Release()
Definition: OpenALSoundProvider.cpp:106
log
void log(const char *format,...)
Definition: OpenALSoundProvider.cpp:24
alGenBuffers
AL_API void AL_APIENTRY alGenBuffers(ALsizei n, ALuint *buffers)
bits
GLenum GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const void * bits
Definition: SDL_opengl_glext.h:6179
alcMakeContextCurrent
ALC_API ALCboolean ALC_APIENTRY alcMakeContextCurrent(ALCcontext *context)
alcCreateContext
ALC_API ALCcontext *ALC_APIENTRY alcCreateContext(ALCdevice *device, const ALCint *attrlist)
size
GLsizeiptr size
Definition: SDL_opengl_glext.h:540
ALfloat
float ALfloat
Definition: al.h:68
samples
GLsizei samples
Definition: SDL_opengl_glext.h:1188
OpenALSoundProvider::device
ALCdevice * device
Definition: OpenALSoundProvider.h:46
alGetSourcef
AL_API void AL_APIENTRY alGetSourcef(ALuint source, ALenum param, ALfloat *value)