summaryrefslogtreecommitdiff
path: root/Source/Core/AudioCommon
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/AudioCommon')
-rw-r--r--Source/Core/AudioCommon/CMakeLists.txt5
-rw-r--r--Source/Core/AudioCommon/Src/AOSoundStream.cpp6
-rw-r--r--Source/Core/AudioCommon/Src/AOSoundStream.h12
-rw-r--r--Source/Core/AudioCommon/Src/AlsaSoundStream.cpp32
-rw-r--r--Source/Core/AudioCommon/Src/AudioCommon.cpp7
-rw-r--r--Source/Core/AudioCommon/Src/CoreAudioSoundStream.h6
-rw-r--r--Source/Core/AudioCommon/Src/DPL2Decoder.cpp52
-rw-r--r--Source/Core/AudioCommon/Src/DSoundStream.cpp2
-rw-r--r--Source/Core/AudioCommon/Src/DSoundStream.h52
-rw-r--r--Source/Core/AudioCommon/Src/Mixer.cpp11
-rw-r--r--Source/Core/AudioCommon/Src/NullSoundStream.h18
-rw-r--r--Source/Core/AudioCommon/Src/OpenALStream.cpp2
-rw-r--r--Source/Core/AudioCommon/Src/OpenSLESStream.cpp145
-rw-r--r--Source/Core/AudioCommon/Src/OpenSLESStream.h48
-rw-r--r--Source/Core/AudioCommon/Src/SoundStream.h10
-rw-r--r--Source/Core/AudioCommon/Src/WaveFile.cpp10
-rw-r--r--Source/Core/AudioCommon/Src/XAudio2Stream.cpp6
17 files changed, 310 insertions, 114 deletions
diff --git a/Source/Core/AudioCommon/CMakeLists.txt b/Source/Core/AudioCommon/CMakeLists.txt
index 3b6d0cea4d..939956460d 100644
--- a/Source/Core/AudioCommon/CMakeLists.txt
+++ b/Source/Core/AudioCommon/CMakeLists.txt
@@ -6,6 +6,11 @@ set(SRCS Src/AudioCommon.cpp
set(LIBS "")
+if(ANDROID)
+ set(SRCS ${SRCS} Src/OpenSLESStream.cpp)
+ set(LIBS ${LIBS} OpenSLES)
+endif(ANDROID)
+
if(ALSA_FOUND)
set(SRCS ${SRCS} Src/AlsaSoundStream.cpp)
set(LIBS ${LIBS} ${ALSA_LIBRARIES})
diff --git a/Source/Core/AudioCommon/Src/AOSoundStream.cpp b/Source/Core/AudioCommon/Src/AOSoundStream.cpp
index 99ae2e661c..0ec6451666 100644
--- a/Source/Core/AudioCommon/Src/AOSoundStream.cpp
+++ b/Source/Core/AudioCommon/Src/AOSoundStream.cpp
@@ -34,7 +34,7 @@ void AOSound::SoundLoop()
format.channels = 2;
format.rate = m_mixer->GetSampleRate();
format.byte_format = AO_FMT_LITTLE;
-
+
device = ao_open_live(default_driver, &format, NULL /* no options */);
if (!device)
{
@@ -49,7 +49,7 @@ void AOSound::SoundLoop()
while (!threadData)
{
m_mixer->Mix(realtimeBuffer, numBytesToRender >> 2);
-
+
{
std::lock_guard<std::mutex> lk(soundCriticalSection);
ao_play(device, (char*)realtimeBuffer, numBytesToRender);
@@ -62,7 +62,7 @@ void AOSound::SoundLoop()
bool AOSound::Start()
{
memset(realtimeBuffer, 0, sizeof(realtimeBuffer));
-
+
thread = std::thread(std::mem_fun(&AOSound::SoundLoop), this);
return true;
}
diff --git a/Source/Core/AudioCommon/Src/AOSoundStream.h b/Source/Core/AudioCommon/Src/AOSoundStream.h
index a631596f02..0c11586b42 100644
--- a/Source/Core/AudioCommon/Src/AOSoundStream.h
+++ b/Source/Core/AudioCommon/Src/AOSoundStream.h
@@ -45,21 +45,21 @@ public:
AOSound(CMixer *mixer) : SoundStream(mixer) {}
virtual ~AOSound();
-
+
virtual bool Start();
-
+
virtual void SoundLoop();
-
+
virtual void Stop();
-
+
static bool isValid() {
return true;
}
-
+
virtual bool usesMixer() const {
return true;
}
-
+
virtual void Update();
#else
diff --git a/Source/Core/AudioCommon/Src/AlsaSoundStream.cpp b/Source/Core/AudioCommon/Src/AlsaSoundStream.cpp
index 710275d55a..d9b9016114 100644
--- a/Source/Core/AudioCommon/Src/AlsaSoundStream.cpp
+++ b/Source/Core/AudioCommon/Src/AlsaSoundStream.cpp
@@ -88,7 +88,7 @@ bool AlsaSound::AlsaInit()
snd_pcm_hw_params_t *hwparams;
snd_pcm_uframes_t buffer_size,buffer_size_max;
unsigned int periods;
-
+
err = snd_pcm_open(&handle, "default", SND_PCM_STREAM_PLAYBACK, 0);
if (err < 0)
{
@@ -97,7 +97,7 @@ bool AlsaSound::AlsaInit()
}
snd_pcm_hw_params_alloca(&hwparams);
-
+
err = snd_pcm_hw_params_any(handle, hwparams);
if (err < 0)
{
@@ -111,8 +111,8 @@ bool AlsaSound::AlsaInit()
ERROR_LOG(AUDIO, "Access type not available: %s\n", snd_strerror(err));
return false;
}
-
- err = snd_pcm_hw_params_set_format(handle, hwparams, SND_PCM_FORMAT_S16_LE);
+
+ err = snd_pcm_hw_params_set_format(handle, hwparams, SND_PCM_FORMAT_S16_LE);
if (err < 0)
{
ERROR_LOG(AUDIO, "Sample format not available: %s\n", snd_strerror(err));
@@ -126,14 +126,14 @@ bool AlsaSound::AlsaInit()
ERROR_LOG(AUDIO, "Rate not available: %s\n", snd_strerror(err));
return false;
}
-
- err = snd_pcm_hw_params_set_channels(handle, hwparams, 2);
+
+ err = snd_pcm_hw_params_set_channels(handle, hwparams, 2);
if (err < 0)
{
ERROR_LOG(AUDIO, "Channels count not available: %s\n", snd_strerror(err));
return false;
}
-
+
periods = BUFFER_SIZE_MAX / FRAME_COUNT_MIN;
err = snd_pcm_hw_params_set_periods_max(handle, hwparams, &periods, &dir);
if (err < 0)
@@ -153,10 +153,10 @@ bool AlsaSound::AlsaInit()
err = snd_pcm_hw_params(handle, hwparams);
if (err < 0)
{
- ERROR_LOG(AUDIO, "Unable to install hw params: %s\n", snd_strerror(err));
+ ERROR_LOG(AUDIO, "Unable to install hw params: %s\n", snd_strerror(err));
return false;
}
-
+
err = snd_pcm_hw_params_get_buffer_size(hwparams, &buffer_size);
if (err < 0)
{
@@ -176,10 +176,10 @@ bool AlsaSound::AlsaInit()
frames_to_deliver = buffer_size / periods;
//limit the minimum size. pulseaudio advertises a minimum of 32 samples.
if (frames_to_deliver < FRAME_COUNT_MIN)
- frames_to_deliver = FRAME_COUNT_MIN;
+ frames_to_deliver = FRAME_COUNT_MIN;
//it is probably a bad idea to try to send more than one buffer of data
if ((unsigned int)frames_to_deliver > buffer_size)
- frames_to_deliver = buffer_size;
+ frames_to_deliver = buffer_size;
NOTICE_LOG(AUDIO, "ALSA gave us a %ld sample \"hardware\" buffer with %d periods. Will send %d samples per fragments.\n", buffer_size, periods, frames_to_deliver);
snd_pcm_sw_params_alloca(&swparams);
@@ -187,21 +187,21 @@ bool AlsaSound::AlsaInit()
err = snd_pcm_sw_params_current(handle, swparams);
if (err < 0)
{
- ERROR_LOG(AUDIO, "cannot init sw params: %s\n", snd_strerror(err));
+ ERROR_LOG(AUDIO, "cannot init sw params: %s\n", snd_strerror(err));
return false;
}
-
+
err = snd_pcm_sw_params_set_start_threshold(handle, swparams, 0U);
if (err < 0)
{
- ERROR_LOG(AUDIO, "cannot set start thresh: %s\n", snd_strerror(err));
+ ERROR_LOG(AUDIO, "cannot set start thresh: %s\n", snd_strerror(err));
return false;
}
-
+
err = snd_pcm_sw_params(handle, swparams);
if (err < 0)
{
- ERROR_LOG(AUDIO, "cannot set sw params: %s\n", snd_strerror(err));
+ ERROR_LOG(AUDIO, "cannot set sw params: %s\n", snd_strerror(err));
return false;
}
diff --git a/Source/Core/AudioCommon/Src/AudioCommon.cpp b/Source/Core/AudioCommon/Src/AudioCommon.cpp
index e14b9ac45e..2f299d0edb 100644
--- a/Source/Core/AudioCommon/Src/AudioCommon.cpp
+++ b/Source/Core/AudioCommon/Src/AudioCommon.cpp
@@ -26,6 +26,7 @@
#include "CoreAudioSoundStream.h"
#include "OpenALStream.h"
#include "PulseAudioStream.h"
+#include "OpenSLESStream.h"
#include "../../Core/Src/Movie.h"
#include "../../Core/Src/ConfigManager.h"
@@ -55,7 +56,8 @@ namespace AudioCommon
soundStream = new CoreAudioSound(mixer);
else if (backend == BACKEND_PULSEAUDIO && PulseAudio::isValid())
soundStream = new PulseAudio(mixer);
-
+ else if (backend == BACKEND_OPENSLES && OpenSLESStream::isValid())
+ soundStream = new OpenSLESStream(mixer);
if (soundStream != NULL)
{
UpdateSoundStream();
@@ -116,7 +118,8 @@ namespace AudioCommon
backends.push_back(BACKEND_PULSEAUDIO);
if (OpenALStream::isValid())
backends.push_back(BACKEND_OPENAL);
-
+ if (OpenSLESStream::isValid())
+ backends.push_back(BACKEND_OPENSLES);
return backends;
}
diff --git a/Source/Core/AudioCommon/Src/CoreAudioSoundStream.h b/Source/Core/AudioCommon/Src/CoreAudioSoundStream.h
index 581e4aabd8..34db5ac837 100644
--- a/Source/Core/AudioCommon/Src/CoreAudioSoundStream.h
+++ b/Source/Core/AudioCommon/Src/CoreAudioSoundStream.h
@@ -30,19 +30,19 @@ class CoreAudioSound : public SoundStream
public:
CoreAudioSound(CMixer *mixer);
virtual ~CoreAudioSound();
-
+
virtual bool Start();
virtual void SetVolume(int volume);
virtual void SoundLoop();
virtual void Stop();
-
+
static bool isValid() {
return true;
}
virtual bool usesMixer() const {
return true;
}
-
+
virtual void Update();
private:
diff --git a/Source/Core/AudioCommon/Src/DPL2Decoder.cpp b/Source/Core/AudioCommon/Src/DPL2Decoder.cpp
index 6a63f696de..c33333fb47 100644
--- a/Source/Core/AudioCommon/Src/DPL2Decoder.cpp
+++ b/Source/Core/AudioCommon/Src/DPL2Decoder.cpp
@@ -130,15 +130,15 @@ returns 0 if OK, -1 if fail
*/
float* design_fir(unsigned int *n, float* fc, float opt)
{
- unsigned int o = *n & 1; // Indicator for odd filter length
- unsigned int end = ((*n + 1) >> 1) - o; // Loop end
- unsigned int i; // Loop index
+ unsigned int o = *n & 1; // Indicator for odd filter length
+ unsigned int end = ((*n + 1) >> 1) - o; // Loop end
+ unsigned int i; // Loop index
- float k1 = 2 * float(M_PI); // 2*pi*fc1
- float k2 = 0.5f * (float)(1 - o);// Constant used if the filter has even length
- float g = 0.0f; // Gain
- float t1; // Temporary variables
- float fc1; // Cutoff frequencies
+ float k1 = 2 * float(M_PI); // 2*pi*fc1
+ float k2 = 0.5f * (float)(1 - o); // Constant used if the filter has even length
+ float g = 0.0f; // Gain
+ float t1; // Temporary variables
+ float fc1; // Cutoff frequencies
// Sanity check
if(*n==0) return NULL;
@@ -241,18 +241,18 @@ void matrix_decode(const float *in, const int k, const int il,
float *_rr, float *_cf)
{
static const float M9_03DB = 0.3535533906f;
- static const float MATAGCTRIG = 8.0f; /* (Fuzzy) AGC trigger */
- static const float MATAGCDECAY = 1.0f; /* AGC baseline decay rate (1/samp.) */
+ static const float MATAGCTRIG = 8.0f; /* (Fuzzy) AGC trigger */
+ static const float MATAGCDECAY = 1.0f; /* AGC baseline decay rate (1/samp.) */
static const float MATCOMPGAIN = 0.37f; /* Cross talk compensation gain, 0.50 - 0.55 is full cancellation. */
const int kr = (k + olddelay) % _dlbuflen;
float l_gain = (_l_fwr + _r_fwr) / (1 + _l_fwr + _l_fwr);
float r_gain = (_l_fwr + _r_fwr) / (1 + _r_fwr + _r_fwr);
- /* The 2nd axis has strong gain fluctuations, and therefore require
- limits. The factor corresponds to the 1 / amplification of (Lt
- - Rt) when (Lt, Rt) is strongly correlated. (e.g. during
- dialogues). It should be bigger than -12 dB to prevent
- distortion. */
+ // The 2nd axis has strong gain fluctuations, and therefore require
+ // limits. The factor corresponds to the 1 / amplification of (Lt
+ // - Rt) when (Lt, Rt) is strongly correlated. (e.g. during
+ // dialogues). It should be bigger than -12 dB to prevent
+ // distortion.
float lmr_lim_fwr = _lmr_fwr > M9_03DB * _lpr_fwr ? _lmr_fwr : M9_03DB * _lpr_fwr;
float lpr_gain = (_lpr_fwr + lmr_lim_fwr) / (1 + _lpr_fwr + _lpr_fwr);
float lmr_gain = (_lpr_fwr + lmr_lim_fwr) / (1 + lmr_lim_fwr + lmr_lim_fwr);
@@ -275,9 +275,9 @@ void matrix_decode(const float *in, const int k, const int il,
if (decode_rear)
{
_lr[kr] = _rr[kr] = (l_agc - r_agc) * (float)M_SQRT1_2;
- /* Stereo rear channel is steered with the same AGC steering as
- the decoding matrix. Note this requires a fast updating AGC
- at the order of 20 ms (which is the case here). */
+ // Stereo rear channel is steered with the same AGC steering as
+ // the decoding matrix. Note this requires a fast updating AGC
+ // at the order of 20 ms (which is the case here).
_lr[kr] *= (_l_fwr + _l_fwr) / (1 + _l_fwr + _r_fwr);
_rr[kr] *= (_r_fwr + _r_fwr) / (1 + _l_fwr + _r_fwr);
}
@@ -298,16 +298,16 @@ void matrix_decode(const float *in, const int k, const int il,
_rf[k] = (lpr_agc - lmr_agc) * (float)M_SQRT1_2;
/*** CENTER FRONT CANCELLATION ***/
- /* A heuristic approach exploits that Lt + Rt gain contains the
- information about Lt, Rt correlation. This effectively reshapes
- the front and rear "cones" to concentrate Lt + Rt to C and
- introduce Lt - Rt in L, R. */
+ // A heuristic approach exploits that Lt + Rt gain contains the
+ // information about Lt, Rt correlation. This effectively reshapes
+ // the front and rear "cones" to concentrate Lt + Rt to C and
+ // introduce Lt - Rt in L, R.
/* 0.67677 is the empirical lower bound for lpr_gain. */
c_gain = 8 * (*_adapt_lpr_gain - 0.67677f);
c_gain = c_gain > 0 ? c_gain : 0;
- /* c_gain should not be too high, not even reaching full
- cancellation (~ 0.50 - 0.55 at current AGC implementation), or
- the center will sound too narrow. */
+ // c_gain should not be too high, not even reaching full
+ // cancellation (~ 0.50 - 0.55 at current AGC implementation), or
+ // the center will sound too narrow. */
c_gain = MATCOMPGAIN / (1 + c_gain * c_gain);
c_agc_cfk = c_gain * _cf[k];
_lf[k] -= c_agc_cfk;
@@ -317,7 +317,7 @@ void matrix_decode(const float *in, const int k, const int il,
void dpl2decode(float *samples, int numsamples, float *out)
{
- static const unsigned int FWRDURATION = 240; /* FWR average duration (samples) */
+ static const unsigned int FWRDURATION = 240; // FWR average duration (samples)
static const int cfg_delay = 0;
static const unsigned int fmt_freq = 48000;
static const unsigned int fmt_nchannels = 2; // input channels
diff --git a/Source/Core/AudioCommon/Src/DSoundStream.cpp b/Source/Core/AudioCommon/Src/DSoundStream.cpp
index b252dc90c5..42c9f4f156 100644
--- a/Source/Core/AudioCommon/Src/DSoundStream.cpp
+++ b/Source/Core/AudioCommon/Src/DSoundStream.cpp
@@ -122,7 +122,7 @@ void DSound::SoundLoop()
bool DSound::Start()
{
if (FAILED(DirectSoundCreate8(0, &ds, 0)))
- return false;
+ return false;
if (hWnd)
{
HRESULT hr = ds->SetCooperativeLevel((HWND)hWnd, DSSCL_PRIORITY);
diff --git a/Source/Core/AudioCommon/Src/DSoundStream.h b/Source/Core/AudioCommon/Src/DSoundStream.h
index 2575a263bb..f2b8276114 100644
--- a/Source/Core/AudioCommon/Src/DSoundStream.h
+++ b/Source/Core/AudioCommon/Src/DSoundStream.h
@@ -31,33 +31,33 @@
class DSound : public SoundStream
{
#ifdef _WIN32
- std::thread thread;
- Common::Event soundSyncEvent;
- void *hWnd;
-
- IDirectSound8* ds;
- IDirectSoundBuffer* dsBuffer;
-
- int bufferSize; //i bytes
+ std::thread thread;
+ Common::Event soundSyncEvent;
+ void *hWnd;
+
+ IDirectSound8* ds;
+ IDirectSoundBuffer* dsBuffer;
+
+ int bufferSize; //i bytes
int m_volume;
-
- // playback position
- int currentPos;
- int lastPos;
- short realtimeBuffer[BUFSIZE / sizeof(short)];
-
- inline int FIX128(int x)
+
+ // playback position
+ int currentPos;
+ int lastPos;
+ short realtimeBuffer[BUFSIZE / sizeof(short)];
+
+ inline int FIX128(int x)
{
return x & (~127);
- }
+ }
- inline int ModBufferSize(int x)
+ inline int ModBufferSize(int x)
{
return (x + bufferSize) % bufferSize;
- }
+ }
- bool CreateBuffer();
- bool WriteDataToBuffer(DWORD dwOffset, char* soundData, DWORD dwSoundBytes);
+ bool CreateBuffer();
+ bool WriteDataToBuffer(DWORD dwOffset, char* soundData, DWORD dwSoundBytes);
public:
DSound(CMixer *mixer, void *_hWnd = NULL)
@@ -70,16 +70,16 @@ public:
, hWnd(_hWnd)
{}
- virtual ~DSound() {}
+ virtual ~DSound() {}
virtual bool Start();
- virtual void SoundLoop();
+ virtual void SoundLoop();
virtual void SetVolume(int volume);
- virtual void Stop();
+ virtual void Stop();
virtual void Clear(bool mute);
- static bool isValid() { return true; }
- virtual bool usesMixer() const { return true; }
- virtual void Update();
+ static bool isValid() { return true; }
+ virtual bool usesMixer() const { return true; }
+ virtual void Update();
#else
public:
diff --git a/Source/Core/AudioCommon/Src/Mixer.cpp b/Source/Core/AudioCommon/Src/Mixer.cpp
index b55fd56c97..6c5b6bcceb 100644
--- a/Source/Core/AudioCommon/Src/Mixer.cpp
+++ b/Source/Core/AudioCommon/Src/Mixer.cpp
@@ -67,7 +67,7 @@ unsigned int CMixer::Mix(short* samples, unsigned int numSamples)
{
static const __m128i sr_mask =
_mm_set_epi32(0x0C0D0E0FL, 0x08090A0BL,
- 0x04050607L, 0x00010203L);
+ 0x04050607L, 0x00010203L);
for (unsigned int i = 0; i < numLeft * 2; i += 8)
{
@@ -99,12 +99,11 @@ unsigned int CMixer::Mix(short* samples, unsigned int numSamples)
if ((m_indexR2 & INDEX_MASK) == (m_indexW & INDEX_MASK)) //..if it exists
m_indexR2 = m_indexR;
-
s16 l1 = Common::swap16(m_buffer[m_indexR & INDEX_MASK]); //current
s16 l2 = Common::swap16(m_buffer[m_indexR2 & INDEX_MASK]); //next
- int sampleL = ((l1 << 16) + (l2 - l1) * (u16)frac) >> 16;
- samples[i+1] = sampleL;
-
+ int sampleL = ((l1 << 16) + (l2 - l1) * (u16)frac) >> 16;
+ samples[i+1] = sampleL;
+
s16 r1 = Common::swap16(m_buffer[(m_indexR + 1) & INDEX_MASK]); //current
s16 r2 = Common::swap16(m_buffer[(m_indexR2 + 1) & INDEX_MASK]); //next
int sampleR = ((r1 << 16) + (r2 - r1) * (u16)frac) >> 16;
@@ -116,8 +115,6 @@ unsigned int CMixer::Mix(short* samples, unsigned int numSamples)
}
}
-
-
} else {
numLeft = 0;
}
diff --git a/Source/Core/AudioCommon/Src/NullSoundStream.h b/Source/Core/AudioCommon/Src/NullSoundStream.h
index 5ce78cccec..c0a5e8cb7c 100644
--- a/Source/Core/AudioCommon/Src/NullSoundStream.h
+++ b/Source/Core/AudioCommon/Src/NullSoundStream.h
@@ -25,24 +25,24 @@
class NullSound : public SoundStream
{
- // playback position
- short realtimeBuffer[BUF_SIZE / sizeof(short)];
+ // playback position
+ short realtimeBuffer[BUF_SIZE / sizeof(short)];
public:
NullSound(CMixer *mixer, void *hWnd = NULL)
: SoundStream(mixer)
{}
- virtual ~NullSound() {}
-
+ virtual ~NullSound() {}
+
virtual bool Start();
- virtual void SoundLoop();
+ virtual void SoundLoop();
virtual void SetVolume(int volume);
- virtual void Stop();
+ virtual void Stop();
virtual void Clear(bool mute);
- static bool isValid() { return true; }
- virtual bool usesMixer() const { return true; }
- virtual void Update();
+ static bool isValid() { return true; }
+ virtual bool usesMixer() const { return true; }
+ virtual void Update();
};
#endif //_NULLSOUNDSTREAM_H_
diff --git a/Source/Core/AudioCommon/Src/OpenALStream.cpp b/Source/Core/AudioCommon/Src/OpenALStream.cpp
index 7d1c45175b..83feb44364 100644
--- a/Source/Core/AudioCommon/Src/OpenALStream.cpp
+++ b/Source/Core/AudioCommon/Src/OpenALStream.cpp
@@ -295,7 +295,6 @@ void OpenALStream::SoundLoop()
{
ERROR_LOG(AUDIO, "Error occurred while buffering float32 data: %08x", err);
}
-
}
#endif
if (!float32_capable)
@@ -308,7 +307,6 @@ void OpenALStream::SoundLoop()
stereo[i * 2 + 1] = (short)((float)sampleBuffer[i * 2 + 1] * (1 << 16));
}
alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_STEREO16, stereo, nSamples * 2 * 2, ulFrequency);
-
}
}
diff --git a/Source/Core/AudioCommon/Src/OpenSLESStream.cpp b/Source/Core/AudioCommon/Src/OpenSLESStream.cpp
new file mode 100644
index 0000000000..b0913a1895
--- /dev/null
+++ b/Source/Core/AudioCommon/Src/OpenSLESStream.cpp
@@ -0,0 +1,145 @@
+// Copyright (C) 2003 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifdef ANDROID
+#include "Common.h"
+#include <assert.h>
+#include "OpenSLESStream.h"
+
+#include <SLES/OpenSLES.h>
+#include <SLES/OpenSLES_Android.h>
+
+// engine interfaces
+static SLObjectItf engineObject;
+static SLEngineItf engineEngine;
+static SLObjectItf outputMixObject;
+
+// buffer queue player interfaces
+static SLObjectItf bqPlayerObject = NULL;
+static SLPlayItf bqPlayerPlay;
+static SLAndroidSimpleBufferQueueItf bqPlayerBufferQueue;
+static SLMuteSoloItf bqPlayerMuteSolo;
+static SLVolumeItf bqPlayerVolume;
+static CMixer *g_mixer;
+#define BUFFER_SIZE 512
+#define BUFFER_SIZE_IN_SAMPLES (BUFFER_SIZE / 2)
+
+// Double buffering.
+static short buffer[2][BUFFER_SIZE];
+static int curBuffer = 0;
+
+static void bqPlayerCallback(SLAndroidSimpleBufferQueueItf bq, void *context) {
+ assert(bq == bqPlayerBufferQueue);
+ assert(NULL == context);
+
+ short *nextBuffer = buffer[curBuffer];
+ int nextSize = sizeof(buffer[0]);
+
+ SLresult result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, nextBuffer, nextSize);
+
+ // Comment from sample code:
+ // the most likely other result is SL_RESULT_BUFFER_INSUFFICIENT,
+ // which for this code example would indicate a programming error
+ assert(SL_RESULT_SUCCESS == result);
+
+ curBuffer ^= 1; // Switch buffer
+ // Render to the fresh buffer
+ g_mixer->Mix(reinterpret_cast<short *>(buffer[curBuffer]), BUFFER_SIZE_IN_SAMPLES);
+}
+bool OpenSLESStream::Start()
+{
+ SLresult result;
+ // create engine
+ result = slCreateEngine(&engineObject, 0, NULL, 0, NULL, NULL);
+ assert(SL_RESULT_SUCCESS == result);
+ result = (*engineObject)->Realize(engineObject, SL_BOOLEAN_FALSE);
+ assert(SL_RESULT_SUCCESS == result);
+ result = (*engineObject)->GetInterface(engineObject, SL_IID_ENGINE, &engineEngine);
+ assert(SL_RESULT_SUCCESS == result);
+ result = (*engineEngine)->CreateOutputMix(engineEngine, &outputMixObject, 0, 0, 0);
+ assert(SL_RESULT_SUCCESS == result);
+ result = (*outputMixObject)->Realize(outputMixObject, SL_BOOLEAN_FALSE);
+ assert(SL_RESULT_SUCCESS == result);
+
+ SLDataLocator_AndroidSimpleBufferQueue loc_bufq = {SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, 2};
+ SLDataFormat_PCM format_pcm = {
+ SL_DATAFORMAT_PCM,
+ 2,
+ SL_SAMPLINGRATE_44_1,
+ SL_PCMSAMPLEFORMAT_FIXED_16,
+ SL_PCMSAMPLEFORMAT_FIXED_16,
+ SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT,
+ SL_BYTEORDER_LITTLEENDIAN
+ };
+
+ SLDataSource audioSrc = {&loc_bufq, &format_pcm};
+
+ // configure audio sink
+ SLDataLocator_OutputMix loc_outmix = {SL_DATALOCATOR_OUTPUTMIX, outputMixObject};
+ SLDataSink audioSnk = {&loc_outmix, NULL};
+
+ // create audio player
+ const SLInterfaceID ids[2] = {SL_IID_BUFFERQUEUE, SL_IID_VOLUME};
+ const SLboolean req[2] = {SL_BOOLEAN_TRUE, SL_BOOLEAN_TRUE};
+ result = (*engineEngine)->CreateAudioPlayer(engineEngine, &bqPlayerObject, &audioSrc, &audioSnk, 2, ids, req);
+ assert(SL_RESULT_SUCCESS == result);
+
+ result = (*bqPlayerObject)->Realize(bqPlayerObject, SL_BOOLEAN_FALSE);
+ assert(SL_RESULT_SUCCESS == result);
+ result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_PLAY, &bqPlayerPlay);
+ assert(SL_RESULT_SUCCESS == result);
+ result = (*bqPlayerObject)->GetInterface(bqPlayerObject, SL_IID_BUFFERQUEUE,
+ &bqPlayerBufferQueue);
+ assert(SL_RESULT_SUCCESS == result);
+ result = (*bqPlayerBufferQueue)->RegisterCallback(bqPlayerBufferQueue, bqPlayerCallback, NULL);
+ assert(SL_RESULT_SUCCESS == result);
+ result = (*bqPlayerPlay)->SetPlayState(bqPlayerPlay, SL_PLAYSTATE_PLAYING);
+ assert(SL_RESULT_SUCCESS == result);
+
+ // Render and enqueue a first buffer. (or should we just play the buffer empty?)
+ curBuffer = 0;
+
+ result = (*bqPlayerBufferQueue)->Enqueue(bqPlayerBufferQueue, buffer[curBuffer], sizeof(buffer[curBuffer]));
+ if (SL_RESULT_SUCCESS != result) {
+ return false;
+ }
+ curBuffer ^= 1;
+ g_mixer = m_mixer;
+ return true;
+}
+
+void OpenSLESStream::Stop()
+{
+ if (bqPlayerObject != NULL) {
+ (*bqPlayerObject)->Destroy(bqPlayerObject);
+ bqPlayerObject = NULL;
+ bqPlayerPlay = NULL;
+ bqPlayerBufferQueue = NULL;
+ bqPlayerMuteSolo = NULL;
+ bqPlayerVolume = NULL;
+ }
+ if (outputMixObject != NULL) {
+ (*outputMixObject)->Destroy(outputMixObject);
+ outputMixObject = NULL;
+ }
+ if (engineObject != NULL) {
+ (*engineObject)->Destroy(engineObject);
+ engineObject = NULL;
+ engineEngine = NULL;
+ }
+}
+#endif
diff --git a/Source/Core/AudioCommon/Src/OpenSLESStream.h b/Source/Core/AudioCommon/Src/OpenSLESStream.h
new file mode 100644
index 0000000000..f49160c4bc
--- /dev/null
+++ b/Source/Core/AudioCommon/Src/OpenSLESStream.h
@@ -0,0 +1,48 @@
+// Copyright (C) 2003 Dolphin Project.
+
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, version 2.0.
+
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License 2.0 for more details.
+
+// A copy of the GPL 2.0 should have been included with the program.
+// If not, see http://www.gnu.org/licenses/
+
+// Official SVN repository and contact information can be found at
+// http://code.google.com/p/dolphin-emu/
+
+#ifndef _OPENSLSTREAM_H_
+#define _OPENSLSTREAM_H_
+
+#include "Thread.h"
+#include "SoundStream.h"
+
+class OpenSLESStream : public SoundStream
+{
+#ifdef ANDROID
+public:
+ OpenSLESStream(CMixer *mixer, void *hWnd = NULL)
+ : SoundStream(mixer)
+ {};
+
+ virtual ~OpenSLESStream() {};
+
+ virtual bool Start();
+ virtual void Stop();
+ static bool isValid() { return true; }
+ virtual bool usesMixer() const { return true; }
+
+private:
+ std::thread thread;
+ Common::Event soundSyncEvent;
+#else
+public:
+ OpenSLESStream(CMixer *mixer, void *hWnd = NULL): SoundStream(mixer) {}
+#endif // HAVE_OPENSL
+};
+
+#endif
diff --git a/Source/Core/AudioCommon/Src/SoundStream.h b/Source/Core/AudioCommon/Src/SoundStream.h
index bb53c0f74d..1322cc19ac 100644
--- a/Source/Core/AudioCommon/Src/SoundStream.h
+++ b/Source/Core/AudioCommon/Src/SoundStream.h
@@ -27,17 +27,17 @@ class SoundStream
protected:
CMixer *m_mixer;
- // We set this to shut down the sound thread.
- // 0=keep playing, 1=stop playing NOW.
- volatile int threadData;
- bool m_logAudio;
+ // We set this to shut down the sound thread.
+ // 0=keep playing, 1=stop playing NOW.
+ volatile int threadData;
+ bool m_logAudio;
WaveFileWriter g_wave_writer;
bool m_muted;
public:
SoundStream(CMixer *mixer) : m_mixer(mixer), threadData(0), m_logAudio(false), m_muted(false) {}
virtual ~SoundStream() { delete m_mixer;}
-
+
static bool isValid() { return false; }
virtual CMixer *GetMixer() const { return m_mixer; }
virtual bool Start() { return false; }
diff --git a/Source/Core/AudioCommon/Src/WaveFile.cpp b/Source/Core/AudioCommon/Src/WaveFile.cpp
index d98348b8bf..3cab3cea68 100644
--- a/Source/Core/AudioCommon/Src/WaveFile.cpp
+++ b/Source/Core/AudioCommon/Src/WaveFile.cpp
@@ -104,21 +104,21 @@ void WaveFileWriter::AddStereoSamples(const short *sample_data, u32 count)
{
if (!file)
PanicAlertT("WaveFileWriter - file not open.");
-
+
if (skip_silence)
{
bool all_zero = true;
-
+
for (u32 i = 0; i < count * 2; i++)
{
if (sample_data[i])
all_zero = false;
}
-
+
if (all_zero)
return;
}
-
+
file.WriteBytes(sample_data, count * 4);
audio_size += count * 4;
}
@@ -134,7 +134,7 @@ void WaveFileWriter::AddStereoSamplesBE(const short *sample_data, u32 count)
if (skip_silence)
{
bool all_zero = true;
-
+
for (u32 i = 0; i < count * 2; i++)
{
if (sample_data[i])
diff --git a/Source/Core/AudioCommon/Src/XAudio2Stream.cpp b/Source/Core/AudioCommon/Src/XAudio2Stream.cpp
index f60842d960..0537f183c6 100644
--- a/Source/Core/AudioCommon/Src/XAudio2Stream.cpp
+++ b/Source/Core/AudioCommon/Src/XAudio2Stream.cpp
@@ -95,10 +95,10 @@ void StreamingVoiceContext::OnBufferEnd(void* context)
if (!m_source_voice || !context)
return;
-
+
//m_sound_sync_event->Wait(); // sync
//m_sound_sync_event->Spin(); // or tight sync
-
+
m_mixer->Mix(static_cast<short*>(context), SAMPLES_PER_BUFFER);
SubmitBuffer(static_cast<BYTE*>(context));
}
@@ -183,6 +183,6 @@ void XAudio2::Stop()
m_mastering_voice->DestroyVoice();
m_mastering_voice = nullptr;
}
-
+
m_xaudio2.reset(); // release interface
}