The class NonCopyable is, like the name says, supposed to disallow
copying. But should it allow moving?
For a long time, NonCopyable used to not allow moving. (It declared
a deleted copy constructor and assigment operator without declaring
a move constructor and assignment operator, making the compiler
implicitly delete the move constructor and assignment operator.)
That's fine if the classes that inherit from NonCopyable don't need
to be movable or if writing the move constructor and assignment
operator by hand is fine, but that's not the case for all classes,
as I discovered when I was working on the DirectoryBlob PR.
Because of that, I decided to make NonCopyable movable in c7602cc,
allowing me to use NonCopyable in DirectoryBlob.h. That was however
an unfortunate decision, because some of the classes that inherit
from NonCopyable have incorrect behavior when moved by default-
generated move constructors and assignment operators, and do not
explicitly delete the move constructors and assignment operators,
relying on NonCopyable being non-movable.
So what can we do about this? There are four solutions that I can
think of:
1. Make NonCopyable non-movable and tell DirectoryBlob to suck it.
2. Keep allowing moving NonCopyable, and expect that classes that
don't support moving will delete the move constructor and
assignment operator manually. Not only is this inconsistent
(having classes disallow copying one way and disallow moving
another way), but deleting the move constructor and assignment
operator manually is too easy to forget compared to how tricky
the resulting problems are.
3. Have one "MovableNonCopyable" and one "NonMovableNonCopyable".
It works, but it feels rather silly...
4. Don't have a NonCopyable class at all. Considering that deleting
the copy constructor and assignment operator only takes two lines
of code, I don't see much of a reason to keep NonCopyable. I
suppose that there was more of a point in having NonCopyable back
in the pre-C++11 days, when it wasn't possible to use "= delete".
I decided to go with the fourth one (like the commit title says).
The implementation of the commit is fairly straight-forward, though
I would like to point out that I skipped adding "= delete" lines
for classes whose only reason for being uncopyable is that they
contain uncopyable classes like File::IOFile and std::unique_ptr,
because the compiler makes such classes uncopyable automatically.
It seems to make no difference besides allowing lower latencies and more
stability on hardware OpenAL cards. Maybe the Wait() call waits for too
long, causing buffers underruns.
Before these changes each value of latency were actually 5ms, with a
minimum latency of ~10 ms. If it was set to 4 ms on the UI, the actual
latency was 10 + 5 * 4 = 30 ms.
Now 30 ms on the UI means 30 ms on the backend.
OpenALStream was querying the backend for AL_EXT_float32 support (which
suceeds), but AL_FORMAT_STEREO_FLOAT32 was defined incorrectly.
Also changes OpenALStream to query for AL_EXT_MCFORMATS (multichannel
support) rather than hard-coding that it doesn't work on macOS.
Fixes an error with the CoreAudio backend, which apparently doesn't
allow you to set the volume before starting the stream:
```
59:31:087 AudioCommon/CoreAudioSoundStream.cpp:97 E[Audio]: error setting volume
```
This shouldn't cause any problems with other backends, since the mixer
starts with silence anyways.
This moves all the byte swapping utilities into a header named Swap.h.
A dedicated header is much more preferable here due to the size of the
code itself. In general usage throughout the codebase, CommonFuncs.h was
generally only included for these functions anyway. These being in their
own header avoids dumping the lesser used utilities into scope. As well
as providing a localized area for more utilities related to byte
swapping in the future (should they be needed). This also makes it nicer
to identify which files depend on the byte swapping utilities in
particular.
Since this is a completely new header, moving the code uncovered a few
indirect includes, as well as making some other inclusions unnecessary.
We (the Microsoft C++ team) use the dolphin project as part of our "Real world code" tests.
I noticed a few issues in windows specific code when building dolphin with the MSVC compiler
in its conformance mode (/permissive-). For more information on /permissive- see our blog
https://blogs.msdn.microsoft.com/vcblog/2016/11/16/permissive-switch/.
These changes are to address 3 different types of issues:
1) Use of qualified names in member declarations
struct A {
void A::f() { } // error C4596: illegal qualified name in member declaration
// remove redundant 'A::' to fix
};
2) Binding a non-const reference to a temporary
struct S{};
// If arg is in 'in' parameter, then it should be made const.
void func(S& arg){}
int main() {
//error C2664: 'void func(S &)': cannot convert argument 1 from 'S' to 'S &'
//note: A non-const reference may only be bound to an lvalue
func( S() );
//Work around this by creating a local, and using it to call the function
S s;
func( s );
}
3) Add missing #include <intrin.h>
Because of the workaround you are using in the code you will need to include
this. This is because of changes in the libraries and not /permissive-
The NullAudio backend is guaranteed to be compiled in, so no reason
to check it.
In addition to that, if it wasn't valid, it wouldn't work as a fallback
in InitSoundStream as there are uses to g_sound_stream later.
Making changes to ConfigManager.h has always been a pain, because
it means rebuilding half of Dolphin, since a lot of files depend on
and include this header.
However, it turns out some includes are unnecessary. This commit
removes ConfigManager includes from files which don't contain
SConfig or GPUDeterminismMode or GPU_DETERMINISM (which means the
ConfigManager include is not used).
(I've also had to get rid of some indirect includes.)
Makes the buffering code a bit more explicit (circular buffer, but
blocks until individual buffers get unqueued by OpenAL), and fixes a
bug in the startup of Super Mario Sunshine:
https://bugs.dolphin-emu.org/issues/9811
Replaces old and simple usages of std::atomic<bool> with Common::Flag
(which was introduced after the initial usage), so it's clear that
the variable is a flag and because Common::Flag is well tested.
This also replaces the ready logic in WiimoteReal with Common::Event
since it was basically just unnecessarily reimplementing Common::Event.
Fix Frame Advance and FifoPlayer pause/unpause/stop.
CPU::EnableStepping is not atomic but is called from multiple threads
which races and leaves the system in a random state; also instruction
stepping was unstable, m_StepEvent had an almost random value because
of the dual purpose it served which could cause races where CPU::Run
would SingleStep when it was supposed to be sleeping.
FifoPlayer never FinishStateMove()d which was causing it to deadlock.
Rather than partially reimplementing CPU::Run, just use CPUCoreBase
and then call CPU::Run(). More DRY and less likely to have weird bugs
specific to the player (i.e the previous freezing on pause/stop).
Refactor PowerPC::state into CPU since it manages the state of the
CPU Thread which is controlled by CPU, not PowerPC. This simplifies
the architecture somewhat and eliminates races that can be caused by
calling PowerPC state functions directly instead of using CPU's
(because they bypassed the EnableStepping lock).
We don't throttle by frames, we throttle by coretiming speed.
So looking up VI for calculating the speed was just very wrong.
The new ini option is a float, 1.0f for fullspeed.
In the GUI, percentual values are used.
snd_pcm_writei() is meant to block block until all samples are written,
but apparently in some situations it can block for much longer, prehaps
even a infinite time, in the case of virtual machine FifoCI runs in.
Because it grabed a mutex before blocking, it could also block the
Clear() call for an infinite length of time, blocking dolphin's emu
thread.
snd_pcm_writei() also takes 10-15 seconds if you run dolphin under GDB
and can randomly take 5 or so seconds during normal usage.
By moving all the pause code to the ALSA thread, Clear() no-longer
blocks and everyone keeps their sanity.
When the emulation is paused and the ALSA backend is used, make the audio
thread wait on a condition variable instead of busy-waiting. This commit
fixes bug #7729
Since the ALSA API is not thread-safe, calls to snd_pcm_drop() and snd_pcm_prepare()
in AlsaSound::Clear() are protected by the same mutex as the condition variable in AlsaSound::SoundLoop()
to make sure that we do not call these functions while a call to
snd_pcm_writei() is ongoing.
This fixes a race condition:
Before this commit, there was a race condition when starting a game:
Core::EmuThread(), after having started (but not necessarily completed)
the initialization of the audio thread, calls Core::SetState() which calls
CCPU::EnableStepping(), which in turns calls AudioCommon::ClearAudioBuffer().
This means that SoundStream::Clear() can be called before
AlsaSound::AlsaInit() has completed.
If the selected audio backend fails to Start() (which could happen for
example if there is no audio device), we currently still use the backend
anyway. This can lead to crashes on some platforms (such as Windows) and
is outright wrong anyway.
This commit fallbacks to the Null audio backend if the selected backend
couldn't be started.
This fixes bug #6001
We had to lock audiocommon with the old asynchron HLE audio emulation,
now our Mixer is just a plain FIFO which may underrun.
Of course, this will stutter, but underruning the audio backend is likely worse.
For more information:
https://docs.google.com/document/d/1tBEgsJh7QiwNwepXI0eobfK3U8LkJButSyeuFt1degM/edit?usp=sharing
removed: SSE includes (not used)
added: 16bit -> float -> 16bit functions
added: linear interpolator and high-quality (windowed-sinc) interpolator functions (including Resampler class)
added: dithering
changed: renamed variables and reformatted a few things to fit with style guide (braces, #include->const)
changed: use s16, u16, s32, u32 etc
changed: store samples and do all computations as floats
changed: volume from 0 - 255