File indexing completed on 2024-05-12 04:06:02

0001 /*
0002     SPDX-FileCopyrightText: 2010 Stefan Majewsky <majewsky@gmx.net>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-only
0005 */
0006 
0007 #include "kgameaudioscene.h"
0008 
0009 // own
0010 #include "kgameopenalruntime_p.h"
0011 #include <kdegames_audio_logging.h>
0012 
0013 Q_GLOBAL_STATIC(KGameOpenALRuntime, g_runtime)
0014 
0015 // BEGIN KGameAudioScene
0016 
0017 KGameAudioScene::Capabilities KGameAudioScene::capabilities()
0018 {
0019     return SupportsLowLatencyPlayback | SupportsPositionalPlayback;
0020 }
0021 
0022 QPointF KGameAudioScene::listenerPos()
0023 {
0024     return g_runtime->m_listenerPos;
0025 }
0026 
0027 void KGameAudioScene::setListenerPos(QPointF pos)
0028 {
0029     if (g_runtime->m_listenerPos != pos) {
0030         g_runtime->m_listenerPos = pos;
0031         g_runtime->configureListener();
0032     }
0033 }
0034 
0035 qreal KGameAudioScene::volume()
0036 {
0037     return g_runtime->m_volume;
0038 }
0039 
0040 void KGameAudioScene::setVolume(qreal volume)
0041 {
0042     if (g_runtime->m_volume != volume) {
0043         g_runtime->m_volume = volume;
0044         g_runtime->configureListener();
0045     }
0046 }
0047 
0048 bool KGameAudioScene::hasError()
0049 {
0050     return g_runtime->m_error;
0051 }
0052 
0053 // END KGameAudioScene
0054 // BEGIN KGameOpenALRuntime
0055 
0056 KGameOpenALRuntime::KGameOpenALRuntime()
0057     : m_volume(1)
0058     , m_error(false)
0059     , m_context(nullptr)
0060     , m_device(alcOpenDevice(""))
0061 {
0062     if (!m_device) {
0063         qCWarning(KDEGAMES_AUDIO_LOG) << "Failed to create OpenAL device";
0064         m_error = true;
0065         return;
0066     }
0067     m_context = alcCreateContext(m_device, nullptr);
0068     int error = alcGetError(m_device);
0069     if (error != AL_NO_ERROR) {
0070         qCWarning(KDEGAMES_AUDIO_LOG) << "Failed to create OpenAL context: Error code" << error;
0071         m_error = true;
0072         return;
0073     }
0074     alcMakeContextCurrent(m_context);
0075     configureListener();
0076 }
0077 
0078 KGameOpenALRuntime::~KGameOpenALRuntime()
0079 {
0080     if (m_context == alcGetCurrentContext()) {
0081         alcMakeContextCurrent(nullptr);
0082     }
0083     alcDestroyContext(m_context);
0084     alcCloseDevice(m_device);
0085 }
0086 
0087 KGameOpenALRuntime *KGameOpenALRuntime::instance()
0088 {
0089     return g_runtime;
0090 }
0091 
0092 void KGameOpenALRuntime::configureListener()
0093 {
0094     int error;
0095     alGetError(); // clear error cache
0096     alListener3f(AL_POSITION, m_listenerPos.x(), m_listenerPos.y(), 0);
0097     alListenerf(AL_GAIN, m_volume);
0098     if ((error = alGetError()) != AL_NO_ERROR) {
0099         qCWarning(KDEGAMES_AUDIO_LOG) << "Failed to setup OpenAL listener: Error code" << error;
0100         m_error = true;
0101     }
0102 }
0103 
0104 // END KGameOpenALRuntime