diff options
Diffstat (limited to 'Source/Core/AudioCommon')
| -rw-r--r-- | Source/Core/AudioCommon/CMakeLists.txt | 5 | ||||
| -rw-r--r-- | Source/Core/AudioCommon/Src/AOSoundStream.cpp | 6 | ||||
| -rw-r--r-- | Source/Core/AudioCommon/Src/AOSoundStream.h | 12 | ||||
| -rw-r--r-- | Source/Core/AudioCommon/Src/AlsaSoundStream.cpp | 32 | ||||
| -rw-r--r-- | Source/Core/AudioCommon/Src/AudioCommon.cpp | 7 | ||||
| -rw-r--r-- | Source/Core/AudioCommon/Src/CoreAudioSoundStream.h | 6 | ||||
| -rw-r--r-- | Source/Core/AudioCommon/Src/DPL2Decoder.cpp | 52 | ||||
| -rw-r--r-- | Source/Core/AudioCommon/Src/DSoundStream.cpp | 2 | ||||
| -rw-r--r-- | Source/Core/AudioCommon/Src/DSoundStream.h | 52 | ||||
| -rw-r--r-- | Source/Core/AudioCommon/Src/Mixer.cpp | 11 | ||||
| -rw-r--r-- | Source/Core/AudioCommon/Src/NullSoundStream.h | 18 | ||||
| -rw-r--r-- | Source/Core/AudioCommon/Src/OpenALStream.cpp | 2 | ||||
| -rw-r--r-- | Source/Core/AudioCommon/Src/OpenSLESStream.cpp | 145 | ||||
| -rw-r--r-- | Source/Core/AudioCommon/Src/OpenSLESStream.h | 48 | ||||
| -rw-r--r-- | Source/Core/AudioCommon/Src/SoundStream.h | 10 | ||||
| -rw-r--r-- | Source/Core/AudioCommon/Src/WaveFile.cpp | 10 | ||||
| -rw-r--r-- | Source/Core/AudioCommon/Src/XAudio2Stream.cpp | 6 |
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 } |
