diff options
| author | skidau <skidau@gmail.com> | 2013-03-27 13:19:23 +1100 |
|---|---|---|
| committer | skidau <skidau@gmail.com> | 2013-03-27 13:19:23 +1100 |
| commit | 7784fa4c67cc8d2545f45694d83805e7e89cd583 (patch) | |
| tree | 7724133aabe971ec417d1dea0977a525bb8debfb /Source/Core/AudioCommon | |
| parent | d33c19b0cd2bae982c8d35e86a9d3551f9e5c72f (diff) | |
| parent | 5cea0d9defeaa23e7af94adf7615a44fb2c9c173 (diff) | |
Merge branch 'master' into wii-network
# By Ryan Houdek (185) and others
# Via degasus (12) and others
* master: (625 commits)
Revert "Don't open/close file for every file operation." as it was crashing PokePark in Windows builds.
Array overrun fixed in VertexShaderCache for the DX11 plugin.
Fixed DSPTool build.
Windows build fix
Go back to assuming every HID device is a wiimote on Windows. Fixed issue 6117. Unfixed issue 6031.
VideoSoftware: Improve fog range adjustment by using less magic and more comments.
revert RasterFont for VideoSoftware
ogl: fix virtual xfb
Windows build fix from web interface...
Adjusted the audio loop criteria, using >= on the Wii and == on GC. This fixes the audio static that occurred in Wii games after hours of play.
Forced the exception check only for ARAM DMA transfers. Removed the Eternal Darkness boot hack and replaced it with an exception check.
VideoSoftware: Implement fog range adjustment, fixing issue 6147.
implement 4xSSAA for OGL
move ogl-only settings into backend
Fix description of disable fog, and move it to enhancements tab.
Reverted rd76ca5783743 as it was made obsolete by r1d550f4496e4.
Removed the tracking of the FIFO Writes as it was made obsolete by r1d550f4496e4.
Forced the external exception check to occur sooner by changing the downcount.
Mark the Direct3D9 backend deprecated.
Prefer D3D11 and OpenGL over D3D9 by default.
...
Conflicts:
CMakeLists.txt
Source/Core/Common/Common.vcxproj.filters
Source/Core/Common/Src/CommonPaths.h
Source/Core/Core/Core.vcxproj.filters
Source/Core/Core/Src/Core.cpp
Source/Core/Core/Src/IPC_HLE/WII_IPC_HLE_Device_FileIO.cpp
Source/VSProps/Dolphin.Win32.props
Source/VSProps/Dolphin.x64.props
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 } |
