cen64/ai/context.c
queueRAM d7339013a6 Don't make any OpenAL calls if -noaudio option is used.
Also returns error if some OpenAL initialization fails
during ai_context_create().

Fixes #68
2017-05-17 11:54:07 -05:00

102 lines
2.8 KiB
C

//
// ai/context.c: Sound card context management.
//
// CEN64: Cycle-Accurate Nintendo 64 Emulator.
// Copyright (C) 2015, Tyler J. Stachecki.
//
// This file is subject to the terms and conditions defined in
// 'LICENSE', which is part of this source code package.
//
#include "common.h"
#include "ai/context.h"
// Creates and initializes an audio context.
int ai_context_create(struct cen64_ai_context *context) {
uint8_t buf[8];
unsigned i;
context->cur_frequency = 31985;
if ((context->dev = alcOpenDevice(NULL)) == NULL) {
printf("Failed to open the OpenAL device.\n");
return 1;
}
if ((context->ctx = alcCreateContext(context->dev, NULL)) == NULL) {
printf("Failed to create an OpenAL context.\n");
alcCloseDevice(context->dev);
return 1;
}
alcMakeContextCurrent(context->ctx);
// Context/device is setup, create some buffers and a source.
alGenBuffers(sizeof(context->buffers) / sizeof(*context->buffers),
context->buffers);
if (alGetError() != AL_NO_ERROR) {
alcMakeContextCurrent(NULL);
alcDestroyContext(context->ctx);
alcCloseDevice(context->dev);
return 1;
}
alGenSources(1, &context->source);
if (alGetError() != AL_NO_ERROR) {
alDeleteBuffers(sizeof(context->buffers) / sizeof(*context->buffers),
context->buffers);
alcMakeContextCurrent(NULL);
alcDestroyContext(context->ctx);
alcCloseDevice(context->dev);
return 1;
}
// Queue/prime buffers, clear them to prevent pops.
// Playing a little test also allows us to verify
// that we (probably) won't get weird OpenAL errors
// later on if things work now.
memset(buf, 0x0, sizeof(buf));
for (i = 0; i < sizeof(context->buffers) / sizeof(*context->buffers); i++)
alBufferData(context->buffers[i], AL_FORMAT_STEREO16,
buf, sizeof(buf), context->cur_frequency);
context->unqueued_buffers = sizeof(context->buffers) /
sizeof(*context->buffers);
return 0;
}
// Destroys audio contexts made with ai_context_create.
void ai_context_destroy(struct cen64_ai_context *context) {
alDeleteSources(1, &context->source);
alDeleteBuffers(sizeof(context->buffers) / sizeof(*context->buffers),
context->buffers);
alcMakeContextCurrent(NULL);
alcDestroyContext(context->ctx);
alcCloseDevice(context->dev);
}
// Generate buffers for some given frequency.
int ai_switch_frequency(struct cen64_ai_context *context, ALint frequency) {
alDeleteSources(1, &context->source);
alDeleteBuffers(sizeof(context->buffers) / sizeof(*context->buffers),
context->buffers);
alGenBuffers(sizeof(context->buffers) / sizeof(*context->buffers),
context->buffers);
alGenSources(1, &context->source);
context->cur_frequency = frequency;
context->unqueued_buffers = sizeof(context->buffers) /
sizeof(*context->buffers);
return 0;
}