| 1 | 1 |
deleted file mode 100644 |
| ... | ... |
@@ -1,214 +0,0 @@ |
| 1 |
-/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2 |
|
| 2 |
- * Developed and maintained by the Pcsx2 Development Team. |
|
| 3 |
- * |
|
| 4 |
- * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] |
|
| 5 |
- * |
|
| 6 |
- * SPU2-X is free software: you can redistribute it and/or modify it under the terms |
|
| 7 |
- * of the GNU Lesser General Public License as published by the Free Software Found- |
|
| 8 |
- * ation, either version 3 of the License, or (at your option) any later version. |
|
| 9 |
- * |
|
| 10 |
- * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
|
| 11 |
- * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
|
| 12 |
- * PURPOSE. See the GNU Lesser General Public License for more details. |
|
| 13 |
- * |
|
| 14 |
- * You should have received a copy of the GNU Lesser General Public License |
|
| 15 |
- * along with SPU2-X. If not, see <http://www.gnu.org/licenses/>. |
|
| 16 |
- */ |
|
| 17 |
- |
|
| 18 |
-#pragma once |
|
| 19 |
- |
|
| 20 |
-#include <memory> |
|
| 21 |
-#include <algorithm> |
|
| 22 |
-#include "../types.h" |
|
| 23 |
- |
|
| 24 |
-struct StereoOut16; |
|
| 25 |
-struct StereoOutFloat; |
|
| 26 |
- |
|
| 27 |
-struct StereoOut32 |
|
| 28 |
-{
|
|
| 29 |
- static StereoOut32 Empty; |
|
| 30 |
- |
|
| 31 |
- int32_t Left, Right; |
|
| 32 |
- |
|
| 33 |
- StereoOut32() : Left(0), Right(0) |
|
| 34 |
- {
|
|
| 35 |
- } |
|
| 36 |
- |
|
| 37 |
- StereoOut32(int32_t left, int32_t right) : Left(left), Right(right) |
|
| 38 |
- {
|
|
| 39 |
- } |
|
| 40 |
- |
|
| 41 |
- StereoOut32(const StereoOut16 &src); |
|
| 42 |
- explicit StereoOut32(const StereoOutFloat &src); |
|
| 43 |
- |
|
| 44 |
- StereoOut16 DownSample() const; |
|
| 45 |
- |
|
| 46 |
- StereoOut32 operator+(const StereoOut32 &right) const |
|
| 47 |
- {
|
|
| 48 |
- return StereoOut32(this->Left + right.Left, this->Right + right.Right); |
|
| 49 |
- } |
|
| 50 |
- |
|
| 51 |
- StereoOut32 operator/(int src) const |
|
| 52 |
- {
|
|
| 53 |
- return StereoOut32(this->Left / src, this->Right / src); |
|
| 54 |
- } |
|
| 55 |
-}; |
|
| 56 |
- |
|
| 57 |
-// Number of stereo samples per SndOut block. |
|
| 58 |
-// All drivers must work in units of this size when communicating with |
|
| 59 |
-// SndOut. |
|
| 60 |
-const int SndOutPacketSize = 512; |
|
| 61 |
- |
|
| 62 |
-// edit - zeromus 23-oct-2009 |
|
| 63 |
-// this is hardcoded differently for metaspu |
|
| 64 |
-const int SndOutVolumeShift = 0; |
|
| 65 |
- |
|
| 66 |
-// Samplerate of the SPU2. For accurate playback we need to match this |
|
| 67 |
-// exactly. Trying to scale samplerates and maintain SPU2's Ts timing accuracy |
|
| 68 |
-// is too problematic. :) |
|
| 69 |
-// this is hardcoded differently for metaspu |
|
| 70 |
-// edit - zeromus 23-oct-2009 |
|
| 71 |
-//const int SampleRate = 48000; |
|
| 72 |
-//const int SampleRate = 44100; |
|
| 73 |
-// edit - nitsuja: make it use the global sample rate define |
|
| 74 |
-#include "../SPU.h" |
|
| 75 |
-const int SampleRate = DESMUME_SAMPLE_RATE; |
|
| 76 |
- |
|
| 77 |
-struct StereoOut16 |
|
| 78 |
-{
|
|
| 79 |
- int16_t Left, Right; |
|
| 80 |
- |
|
| 81 |
- StereoOut16() : Left(0), Right(0) |
|
| 82 |
- {
|
|
| 83 |
- } |
|
| 84 |
- |
|
| 85 |
- StereoOut16(const StereoOut32 &src) : Left(src.Left & 0xFFFF), Right(src.Right & 0xFFFF) |
|
| 86 |
- {
|
|
| 87 |
- } |
|
| 88 |
- |
|
| 89 |
- StereoOut16(int16_t left, int16_t right) : Left(left), Right(right) |
|
| 90 |
- {
|
|
| 91 |
- } |
|
| 92 |
- |
|
| 93 |
- void ResampleFrom(const StereoOut32 &src) |
|
| 94 |
- {
|
|
| 95 |
- // Use StereoOut32's built in conversion |
|
| 96 |
- *this = src.DownSample(); |
|
| 97 |
- } |
|
| 98 |
-}; |
|
| 99 |
- |
|
| 100 |
-struct StereoOutFloat |
|
| 101 |
-{
|
|
| 102 |
- float Left, Right; |
|
| 103 |
- |
|
| 104 |
- StereoOutFloat() : Left(0.0f), Right(0.0f) |
|
| 105 |
- {
|
|
| 106 |
- } |
|
| 107 |
- |
|
| 108 |
- explicit StereoOutFloat(const StereoOut32 &src) : Left(src.Left / 2147483647.0f), Right(src.Right / 2147483647.0f) |
|
| 109 |
- {
|
|
| 110 |
- } |
|
| 111 |
- |
|
| 112 |
- explicit StereoOutFloat(int32_t left, int32_t right) : Left(left / 2147483647.0f), Right(right / 2147483647.0f) |
|
| 113 |
- {
|
|
| 114 |
- } |
|
| 115 |
- |
|
| 116 |
- StereoOutFloat(float left, float right) : Left(left), Right(right) |
|
| 117 |
- {
|
|
| 118 |
- } |
|
| 119 |
-}; |
|
| 120 |
- |
|
| 121 |
-// Developer Note: This is a static class only (all static members). |
|
| 122 |
-class SndBuffer |
|
| 123 |
-{
|
|
| 124 |
-private: |
|
| 125 |
- static bool m_underrun_freeze; |
|
| 126 |
- static int32_t m_predictData; |
|
| 127 |
- static float lastPct; |
|
| 128 |
- |
|
| 129 |
- static std::unique_ptr<StereoOut32[]> sndTempBuffer; |
|
| 130 |
- |
|
| 131 |
- static int sndTempProgress; |
|
| 132 |
- |
|
| 133 |
- static std::unique_ptr<StereoOut32[]> m_buffer; |
|
| 134 |
- static int32_t m_size; |
|
| 135 |
- static int32_t m_rpos; |
|
| 136 |
- static int32_t m_wpos; |
|
| 137 |
- static int32_t m_data; |
|
| 138 |
- |
|
| 139 |
- static float lastEmergencyAdj; |
|
| 140 |
- static float cTempo; |
|
| 141 |
- static float eTempo; |
|
| 142 |
- static int freezeTempo; |
|
| 143 |
- |
|
| 144 |
- static void _InitFail(); |
|
| 145 |
- static void _WriteSamples(StereoOut32 *bData, int nSamples); |
|
| 146 |
- static bool CheckUnderrunStatus(int &nSamples, int &quietSampleCount); |
|
| 147 |
- |
|
| 148 |
- static void soundtouchInit(); |
|
| 149 |
- static void timeStretchWrite(); |
|
| 150 |
- static void timeStretchUnderrun(); |
|
| 151 |
- static int32_t timeStretchOverrun(); |
|
| 152 |
- |
|
| 153 |
- static void PredictDataWrite(int samples); |
|
| 154 |
- static float GetStatusPct(); |
|
| 155 |
- static void UpdateTempoChange(); |
|
| 156 |
- |
|
| 157 |
-public: |
|
| 158 |
- static void Init(); |
|
| 159 |
- static void Write(const StereoOut32 &Sample); |
|
| 160 |
- |
|
| 161 |
- // Note: When using with 32 bit output buffers, the user of this function is responsible |
|
| 162 |
- // for shifting the values to where they need to be manually. The fixed point depth of |
|
| 163 |
- // the sample output is determined by the SndOutVolumeShift, which is the number of bits |
|
| 164 |
- // to shift right to get a 16 bit result. |
|
| 165 |
- template<typename T> static void ReadSamples(T *bData) |
|
| 166 |
- {
|
|
| 167 |
- int nSamples = SndOutPacketSize; |
|
| 168 |
- |
|
| 169 |
- // Problem: |
|
| 170 |
- // If the SPU2 gets even the least bit out of sync with the SndOut device, |
|
| 171 |
- // the readpos of the circular buffer will overtake the writepos, |
|
| 172 |
- // leading to a prolonged period of hopscotching read/write accesses (ie, |
|
| 173 |
- // lots of staticy crap sound for several seconds). |
|
| 174 |
- // |
|
| 175 |
- // Fix: |
|
| 176 |
- // If the read position overtakes the write position, abort the |
|
| 177 |
- // transfer immediately and force the SndOut driver to wait until |
|
| 178 |
- // the read buffer has filled up again before proceeding. |
|
| 179 |
- // This will cause one brief hiccup that can never exceed the user's |
|
| 180 |
- // set buffer length in duration. |
|
| 181 |
- |
|
| 182 |
- int quietSamples; |
|
| 183 |
- if (CheckUnderrunStatus(nSamples, quietSamples)) |
|
| 184 |
- {
|
|
| 185 |
- assert(nSamples <= SndOutPacketSize); |
|
| 186 |
- |
|
| 187 |
- // [Air] [TODO]: This loop is probably a candidate for SSE2 optimization. |
|
| 188 |
- |
|
| 189 |
- int endPos = m_rpos + nSamples; |
|
| 190 |
- int secondCopyLen = endPos - m_size; |
|
| 191 |
- const StereoOut32 *rposbuffer = &m_buffer[m_rpos]; |
|
| 192 |
- |
|
| 193 |
- m_data -= nSamples; |
|
| 194 |
- |
|
| 195 |
- if (secondCopyLen > 0) |
|
| 196 |
- {
|
|
| 197 |
- nSamples -= secondCopyLen; |
|
| 198 |
- for (int i = 0; i < secondCopyLen; ++i) |
|
| 199 |
- bData[nSamples + i].ResampleFrom(m_buffer[i]); |
|
| 200 |
- m_rpos = secondCopyLen; |
|
| 201 |
- } |
|
| 202 |
- else |
|
| 203 |
- m_rpos += nSamples; |
|
| 204 |
- |
|
| 205 |
- for (int i = 0; i < nSamples; ++i) |
|
| 206 |
- bData[i].ResampleFrom(rposbuffer[i]); |
|
| 207 |
- } |
|
| 208 |
- |
|
| 209 |
- // If quietSamples != 0 it means we have an underrun... |
|
| 210 |
- // Let's just dull out some silence, because that's usually the least |
|
| 211 |
- // painful way of dealing with underruns: |
|
| 212 |
- memset(bData, 0, quietSamples * sizeof(T)); |
|
| 213 |
- } |
|
| 214 |
-}; |
| ... | ... |
@@ -15,8 +15,7 @@ |
| 15 | 15 |
* along with SPU2-X. If not, see <http://www.gnu.org/licenses/>. |
| 16 | 16 |
*/ |
| 17 | 17 |
|
| 18 |
-#ifndef SNDOUT_H |
|
| 19 |
-#define SNDOUT_H |
|
| 18 |
+#pragma once |
|
| 20 | 19 |
|
| 21 | 20 |
#include <memory> |
| 22 | 21 |
#include <algorithm> |
| ... | ... |
@@ -213,5 +212,3 @@ public: |
| 213 | 212 |
memset(bData, 0, quietSamples * sizeof(T)); |
| 214 | 213 |
} |
| 215 | 214 |
}; |
| 216 |
- |
|
| 217 |
-#endif |
| ... | ... |
@@ -83,7 +83,7 @@ struct StereoOut16 |
| 83 | 83 |
{
|
| 84 | 84 |
} |
| 85 | 85 |
|
| 86 |
- StereoOut16(const StereoOut32 &src) : Left(static_cast<int16_t>(src.Left)), Right(static_cast<int16_t>(src.Right)) |
|
| 86 |
+ StereoOut16(const StereoOut32 &src) : Left(src.Left & 0xFFFF), Right(src.Right & 0xFFFF) |
|
| 87 | 87 |
{
|
| 88 | 88 |
} |
| 89 | 89 |
|
| ... | ... |
@@ -15,20 +15,21 @@ |
| 15 | 15 |
* along with SPU2-X. If not, see <http://www.gnu.org/licenses/>. |
| 16 | 16 |
*/ |
| 17 | 17 |
|
| 18 |
-#pragma once |
|
| 18 |
+#ifndef SNDOUT_H |
|
| 19 |
+#define SNDOUT_H |
|
| 19 | 20 |
|
| 21 |
+#include <memory> |
|
| 20 | 22 |
#include <algorithm> |
| 23 |
+#include "../types.h" |
|
| 21 | 24 |
|
| 22 | 25 |
struct StereoOut16; |
| 23 |
-//struct StereoOut32; |
|
| 24 | 26 |
struct StereoOutFloat; |
| 25 | 27 |
|
| 26 | 28 |
struct StereoOut32 |
| 27 | 29 |
{
|
| 28 | 30 |
static StereoOut32 Empty; |
| 29 | 31 |
|
| 30 |
- int32_t Left; |
|
| 31 |
- int32_t Right; |
|
| 32 |
+ int32_t Left, Right; |
|
| 32 | 33 |
|
| 33 | 34 |
StereoOut32() : Left(0), Right(0) |
| 34 | 35 |
{
|
| ... | ... |
@@ -45,45 +46,38 @@ struct StereoOut32 |
| 45 | 46 |
|
| 46 | 47 |
StereoOut32 operator+(const StereoOut32 &right) const |
| 47 | 48 |
{
|
| 48 |
- return StereoOut32(Left + right.Left, Right + right.Right); |
|
| 49 |
+ return StereoOut32(this->Left + right.Left, this->Right + right.Right); |
|
| 49 | 50 |
} |
| 50 | 51 |
|
| 51 | 52 |
StereoOut32 operator/(int src) const |
| 52 | 53 |
{
|
| 53 |
- return StereoOut32(Left / src, Right / src); |
|
| 54 |
+ return StereoOut32(this->Left / src, this->Right / src); |
|
| 54 | 55 |
} |
| 55 | 56 |
}; |
| 56 | 57 |
|
| 57 | 58 |
// Number of stereo samples per SndOut block. |
| 58 | 59 |
// All drivers must work in units of this size when communicating with |
| 59 | 60 |
// SndOut. |
| 60 |
-static const int SndOutPacketSize = 512; |
|
| 61 |
+const int SndOutPacketSize = 512; |
|
| 61 | 62 |
|
| 62 |
-// Overall master volume shift. |
|
| 63 |
-// Converts the mixer's 32 bit value into a 16 bit value. |
|
| 64 |
-//static const int SndOutVolumeShift = 13; |
|
| 65 |
- |
|
| 66 |
-//edit - zeromus 23-oct-2009 |
|
| 67 |
-//this is hardcoded differently for metaspu |
|
| 68 |
-static const int SndOutVolumeShift = 0; |
|
| 63 |
+// edit - zeromus 23-oct-2009 |
|
| 64 |
+// this is hardcoded differently for metaspu |
|
| 65 |
+const int SndOutVolumeShift = 0; |
|
| 69 | 66 |
|
| 70 | 67 |
// Samplerate of the SPU2. For accurate playback we need to match this |
| 71 | 68 |
// exactly. Trying to scale samplerates and maintain SPU2's Ts timing accuracy |
| 72 | 69 |
// is too problematic. :) |
| 73 |
-//this is hardcoded differently for metaspu |
|
| 74 |
-//edit - zeromus 23-oct-2009 |
|
| 75 |
-////static const int SampleRate = 48000; |
|
| 76 |
-//static const int SampleRate = 44100; |
|
| 77 |
-//edit - nitsuja: make it use the global sample rate define |
|
| 70 |
+// this is hardcoded differently for metaspu |
|
| 71 |
+// edit - zeromus 23-oct-2009 |
|
| 72 |
+//const int SampleRate = 48000; |
|
| 73 |
+//const int SampleRate = 44100; |
|
| 74 |
+// edit - nitsuja: make it use the global sample rate define |
|
| 78 | 75 |
#include "../SPU.h" |
| 79 |
-static const int SampleRate = DESMUME_SAMPLE_RATE; |
|
| 80 |
- |
|
| 81 |
-//extern int FindOutputModuleById(const wchar_t *omodid); |
|
| 76 |
+const int SampleRate = DESMUME_SAMPLE_RATE; |
|
| 82 | 77 |
|
| 83 | 78 |
struct StereoOut16 |
| 84 | 79 |
{
|
| 85 |
- int16_t Left; |
|
| 86 |
- int16_t Right; |
|
| 80 |
+ int16_t Left, Right; |
|
| 87 | 81 |
|
| 88 | 82 |
StereoOut16() : Left(0), Right(0) |
| 89 | 83 |
{
|
| ... | ... |
@@ -97,8 +91,6 @@ struct StereoOut16 |
| 97 | 91 |
{
|
| 98 | 92 |
} |
| 99 | 93 |
|
| 100 |
- //StereoOut32 UpSample() const; |
|
| 101 |
- |
|
| 102 | 94 |
void ResampleFrom(const StereoOut32 &src) |
| 103 | 95 |
{
|
| 104 | 96 |
// Use StereoOut32's built in conversion |
| ... | ... |
@@ -108,8 +100,7 @@ struct StereoOut16 |
| 108 | 100 |
|
| 109 | 101 |
struct StereoOutFloat |
| 110 | 102 |
{
|
| 111 |
- float Left; |
|
| 112 |
- float Right; |
|
| 103 |
+ float Left, Right; |
|
| 113 | 104 |
|
| 114 | 105 |
StereoOutFloat() : Left(0.0f), Right(0.0f) |
| 115 | 106 |
{
|
| ... | ... |
@@ -128,249 +119,6 @@ struct StereoOutFloat |
| 128 | 119 |
} |
| 129 | 120 |
}; |
| 130 | 121 |
|
| 131 |
-//struct Stereo21Out16 |
|
| 132 |
-//{
|
|
| 133 |
-// int16_t Left; |
|
| 134 |
-// int16_t Right; |
|
| 135 |
-// int16_t LFE; |
|
| 136 |
-// |
|
| 137 |
-// void ResampleFrom( const StereoOut32& src ) |
|
| 138 |
-// {
|
|
| 139 |
-// Left = src.Left >> SndOutVolumeShift; |
|
| 140 |
-// Right = src.Right >> SndOutVolumeShift; |
|
| 141 |
-// LFE = (src.Left + src.Right) >> (SndOutVolumeShift + 1); |
|
| 142 |
-// } |
|
| 143 |
-//}; |
|
| 144 |
-// |
|
| 145 |
-//struct StereoQuadOut16 |
|
| 146 |
-//{
|
|
| 147 |
-// int16_t Left; |
|
| 148 |
-// int16_t Right; |
|
| 149 |
-// int16_t LeftBack; |
|
| 150 |
-// int16_t RightBack; |
|
| 151 |
-// |
|
| 152 |
-// void ResampleFrom( const StereoOut32& src ) |
|
| 153 |
-// {
|
|
| 154 |
-// Left = src.Left >> SndOutVolumeShift; |
|
| 155 |
-// Right = src.Right >> SndOutVolumeShift; |
|
| 156 |
-// LeftBack = src.Left >> SndOutVolumeShift; |
|
| 157 |
-// RightBack = src.Right >> SndOutVolumeShift; |
|
| 158 |
-// } |
|
| 159 |
-//}; |
|
| 160 |
-// |
|
| 161 |
-//struct Stereo41Out16 |
|
| 162 |
-//{
|
|
| 163 |
-// int16_t Left; |
|
| 164 |
-// int16_t Right; |
|
| 165 |
-// int16_t LFE; |
|
| 166 |
-// int16_t LeftBack; |
|
| 167 |
-// int16_t RightBack; |
|
| 168 |
-// |
|
| 169 |
-// void ResampleFrom( const StereoOut32& src ) |
|
| 170 |
-// {
|
|
| 171 |
-// Left = src.Left >> SndOutVolumeShift; |
|
| 172 |
-// Right = src.Right >> SndOutVolumeShift; |
|
| 173 |
-// LFE = (src.Left + src.Right) >> (SndOutVolumeShift + 1); |
|
| 174 |
-// LeftBack = src.Left >> SndOutVolumeShift; |
|
| 175 |
-// RightBack = src.Right >> SndOutVolumeShift; |
|
| 176 |
-// } |
|
| 177 |
-//}; |
|
| 178 |
-// |
|
| 179 |
-//struct Stereo51Out16 |
|
| 180 |
-//{
|
|
| 181 |
-// int16_t Left; |
|
| 182 |
-// int16_t Right; |
|
| 183 |
-// int16_t Center; |
|
| 184 |
-// int16_t LFE; |
|
| 185 |
-// int16_t LeftBack; |
|
| 186 |
-// int16_t RightBack; |
|
| 187 |
-// |
|
| 188 |
-// // Implementation Note: Center and Subwoofer/LFE --> |
|
| 189 |
-// // This method is simple and sounds nice. It relies on the speaker/soundcard |
|
| 190 |
-// // systems do to their own low pass / crossover. Manual lowpass is wasted effort |
|
| 191 |
-// // and can't match solid state results anyway. |
|
| 192 |
-// |
|
| 193 |
-// void ResampleFrom( const StereoOut32& src ) |
|
| 194 |
-// {
|
|
| 195 |
-// Left = src.Left >> SndOutVolumeShift; |
|
| 196 |
-// Right = src.Right >> SndOutVolumeShift; |
|
| 197 |
-// Center = (src.Left + src.Right) >> (SndOutVolumeShift + 1); |
|
| 198 |
-// LFE = Center; |
|
| 199 |
-// LeftBack = src.Left >> SndOutVolumeShift; |
|
| 200 |
-// RightBack = src.Right >> SndOutVolumeShift; |
|
| 201 |
-// } |
|
| 202 |
-//}; |
|
| 203 |
-// |
|
| 204 |
-//struct Stereo51Out16DplII |
|
| 205 |
-//{
|
|
| 206 |
-// int16_t Left; |
|
| 207 |
-// int16_t Right; |
|
| 208 |
-// int16_t Center; |
|
| 209 |
-// int16_t LFE; |
|
| 210 |
-// int16_t LeftBack; |
|
| 211 |
-// int16_t RightBack; |
|
| 212 |
-// |
|
| 213 |
-// void ResampleFrom( const StereoOut32& src ) |
|
| 214 |
-// {
|
|
| 215 |
-// static const u8 sLogTable[256] = {
|
|
| 216 |
-// 0x00,0x3C,0x60,0x78,0x8C,0x9C,0xA8,0xB4,0xBE,0xC8,0xD0,0xD8,0xDE,0xE4,0xEA,0xF0, |
|
| 217 |
-// 0xF6,0xFA,0xFE,0x04,0x08,0x0C,0x10,0x14,0x16,0x1A,0x1E,0x20,0x24,0x26,0x2A,0x2C, |
|
| 218 |
-// 0x2E,0x32,0x34,0x36,0x38,0x3A,0x3E,0x40,0x42,0x44,0x46,0x48,0x4A,0x4C,0x4E,0x50, |
|
| 219 |
-// 0x50,0x52,0x54,0x56,0x58,0x5A,0x5A,0x5C,0x5E,0x60,0x60,0x62,0x64,0x66,0x66,0x68, |
|
| 220 |
-// 0x6A,0x6A,0x6C,0x6E,0x6E,0x70,0x70,0x72,0x74,0x74,0x76,0x76,0x78,0x7A,0x7A,0x7C, |
|
| 221 |
-// 0x7C,0x7E,0x7E,0x80,0x80,0x82,0x82,0x84,0x84,0x86,0x86,0x88,0x88,0x8A,0x8A,0x8C, |
|
| 222 |
-// 0x8C,0x8C,0x8E,0x8E,0x90,0x90,0x92,0x92,0x92,0x94,0x94,0x96,0x96,0x96,0x98,0x98, |
|
| 223 |
-// 0x9A,0x9A,0x9A,0x9C,0x9C,0x9C,0x9E,0x9E,0xA0,0xA0,0xA0,0xA2,0xA2,0xA2,0xA4,0xA4, |
|
| 224 |
-// 0xA4,0xA6,0xA6,0xA6,0xA8,0xA8,0xA8,0xAA,0xAA,0xAA,0xAC,0xAC,0xAC,0xAC,0xAE,0xAE, |
|
| 225 |
-// 0xAE,0xB0,0xB0,0xB0,0xB2,0xB2,0xB2,0xB2,0xB4,0xB4,0xB4,0xB6,0xB6,0xB6,0xB6,0xB8, |
|
| 226 |
-// 0xB8,0xB8,0xB8,0xBA,0xBA,0xBA,0xBC,0xBC,0xBC,0xBC,0xBE,0xBE,0xBE,0xBE,0xC0,0xC0, |
|
| 227 |
-// 0xC0,0xC0,0xC2,0xC2,0xC2,0xC2,0xC2,0xC4,0xC4,0xC4,0xC4,0xC6,0xC6,0xC6,0xC6,0xC8, |
|
| 228 |
-// 0xC8,0xC8,0xC8,0xC8,0xCA,0xCA,0xCA,0xCA,0xCC,0xCC,0xCC,0xCC,0xCC,0xCE,0xCE,0xCE, |
|
| 229 |
-// 0xCE,0xCE,0xD0,0xD0,0xD0,0xD0,0xD0,0xD2,0xD2,0xD2,0xD2,0xD2,0xD4,0xD4,0xD4,0xD4, |
|
| 230 |
-// 0xD4,0xD6,0xD6,0xD6,0xD6,0xD6,0xD8,0xD8,0xD8,0xD8,0xD8,0xD8,0xDA,0xDA,0xDA,0xDA, |
|
| 231 |
-// 0xDA,0xDC,0xDC,0xDC,0xDC,0xDC,0xDC,0xDE,0xDE,0xDE,0xDE,0xDE,0xDE,0xE0,0xE0,0xE0, |
|
| 232 |
-// }; |
|
| 233 |
-// |
|
| 234 |
-// static int32_t Gfl=0,Gfr=0; |
|
| 235 |
-// static int32_t LMax=0,RMax=0; |
|
| 236 |
-// |
|
| 237 |
-// static int32_t LAccum; |
|
| 238 |
-// static int32_t RAccum; |
|
| 239 |
-// static int32_t ANum; |
|
| 240 |
-// |
|
| 241 |
-// int32_t ValL = src.Left >> (SndOutVolumeShift-8); |
|
| 242 |
-// int32_t ValR = src.Right >> (SndOutVolumeShift-8); |
|
| 243 |
-// |
|
| 244 |
-// int32_t XL = abs(ValL>>8); |
|
| 245 |
-// int32_t XR = abs(ValR>>8); |
|
| 246 |
-// |
|
| 247 |
-// if(XL>LMax) LMax = XL; |
|
| 248 |
-// if(XR>RMax) RMax = XR; |
|
| 249 |
-// |
|
| 250 |
-// ANum++; |
|
| 251 |
-// if(ANum>=128) |
|
| 252 |
-// {
|
|
| 253 |
-// ANum=0; |
|
| 254 |
-// LAccum = 1+((LAccum * 224 + LMax * 31)>>8); |
|
| 255 |
-// RAccum = 1+((RAccum * 224 + RMax * 31)>>8); |
|
| 256 |
-// |
|
| 257 |
-// LMax = 0; |
|
| 258 |
-// RMax = 0; |
|
| 259 |
-// |
|
| 260 |
-// int32_t Tfl=(RAccum)*255/(LAccum); |
|
| 261 |
-// int32_t Tfr=(LAccum)*255/(RAccum); |
|
| 262 |
-// |
|
| 263 |
-// int gMax = std::max(Tfl,Tfr); |
|
| 264 |
-// Tfl = Tfl*255/gMax; |
|
| 265 |
-// Tfr = Tfr*255/gMax; |
|
| 266 |
-// |
|
| 267 |
-// if(Tfl>255) Tfl=255; |
|
| 268 |
-// if(Tfr>255) Tfr=255; |
|
| 269 |
-// if(Tfl<1) Tfl=1; |
|
| 270 |
-// if(Tfr<1) Tfr=1; |
|
| 271 |
-// |
|
| 272 |
-// Gfl = (Gfl * 200 + Tfl * 56)>>8; |
|
| 273 |
-// Gfr = (Gfr * 200 + Tfr * 56)>>8; |
|
| 274 |
-// |
|
| 275 |
-// } |
|
| 276 |
-// |
|
| 277 |
-// int32_t L,R,C,SUB,SL,SR; |
|
| 278 |
-// |
|
| 279 |
-// C=(ValL+ValR)>>1; //16.8 |
|
| 280 |
-// |
|
| 281 |
-// ValL-=C;//16.8 |
|
| 282 |
-// ValR-=C;//16.8 |
|
| 283 |
-// |
|
| 284 |
-// L=ValL>>8; //16.0 |
|
| 285 |
-// R=ValR>>8; //16.0 |
|
| 286 |
-// C=C>>8; //16.0 |
|
| 287 |
-// SUB = C; |
|
| 288 |
-// |
|
| 289 |
-// {
|
|
| 290 |
-// int32_t Cfl = 1+sLogTable[Gfl]; |
|
| 291 |
-// int32_t Cfr = 1+sLogTable[Gfr]; |
|
| 292 |
-// |
|
| 293 |
-// int32_t VL=(ValL>>4) * Cfl; //16.12 |
|
| 294 |
-// int32_t VR=(ValR>>4) * Cfr; |
|
| 295 |
-// |
|
| 296 |
-// //int32_t SC = (VL-VR)>>15; |
|
| 297 |
-// |
|
| 298 |
-// SL = (((VR/148 - VL/209)>>4)*Cfr)>>8; |
|
| 299 |
-// SR = (((VR/209 - VL/148)>>4)*Cfl)>>8; |
|
| 300 |
-// |
|
| 301 |
-// } |
|
| 302 |
-// |
|
| 303 |
-// // Random-ish values to get it to compile |
|
| 304 |
-// int GainL = 200; |
|
| 305 |
-// int GainR = 200; |
|
| 306 |
-// int GainC = 180; |
|
| 307 |
-// int GainSL = 230; |
|
| 308 |
-// int GainSR = 230; |
|
| 309 |
-// int GainLFE = 200; |
|
| 310 |
-// int AddCLR = 55; |
|
| 311 |
-// |
|
| 312 |
-// int AddCX = (C * AddCLR)>>8; |
|
| 313 |
-// |
|
| 314 |
-// Left = (((L * GainL ))>>8) + AddCX; |
|
| 315 |
-// Right = (((R * GainR ))>>8) + AddCX; |
|
| 316 |
-// Center = (((C * GainC ))>>8); |
|
| 317 |
-// LFE = (((SUB * GainLFE))>>8); |
|
| 318 |
-// LeftBack = (((SL * GainSL ))>>8); |
|
| 319 |
-// RightBack = (((SR * GainSR ))>>8); |
|
| 320 |
-// } |
|
| 321 |
-//}; |
|
| 322 |
-// |
|
| 323 |
-//struct Stereo71Out16 |
|
| 324 |
-//{
|
|
| 325 |
-// int16_t Left; |
|
| 326 |
-// int16_t Right; |
|
| 327 |
-// int16_t Center; |
|
| 328 |
-// int16_t LFE; |
|
| 329 |
-// int16_t LeftBack; |
|
| 330 |
-// int16_t RightBack; |
|
| 331 |
-// int16_t LeftSide; |
|
| 332 |
-// int16_t RightSide; |
|
| 333 |
-// |
|
| 334 |
-// void ResampleFrom( const StereoOut32& src ) |
|
| 335 |
-// {
|
|
| 336 |
-// Left = src.Left >> SndOutVolumeShift; |
|
| 337 |
-// Right = src.Right >> SndOutVolumeShift; |
|
| 338 |
-// Center = (src.Left + src.Right) >> (SndOutVolumeShift + 1); |
|
| 339 |
-// LFE = Center; |
|
| 340 |
-// LeftBack = src.Left >> SndOutVolumeShift; |
|
| 341 |
-// RightBack = src.Right >> SndOutVolumeShift; |
|
| 342 |
-// |
|
| 343 |
-// LeftSide = src.Left >> (SndOutVolumeShift+1); |
|
| 344 |
-// RightSide = src.Right >> (SndOutVolumeShift+1); |
|
| 345 |
-// } |
|
| 346 |
-//}; |
|
| 347 |
-// |
|
| 348 |
-//struct Stereo21Out32 |
|
| 349 |
-//{
|
|
| 350 |
-// int32_t Left; |
|
| 351 |
-// int32_t Right; |
|
| 352 |
-// int32_t LFE; |
|
| 353 |
-//}; |
|
| 354 |
-// |
|
| 355 |
-//struct Stereo41Out32 |
|
| 356 |
-//{
|
|
| 357 |
-// int32_t Left; |
|
| 358 |
-// int32_t Right; |
|
| 359 |
-// int32_t LFE; |
|
| 360 |
-// int32_t LeftBack; |
|
| 361 |
-// int32_t RightBack; |
|
| 362 |
-//}; |
|
| 363 |
-// |
|
| 364 |
-//struct Stereo51Out32 |
|
| 365 |
-//{
|
|
| 366 |
-// int32_t Left; |
|
| 367 |
-// int32_t Right; |
|
| 368 |
-// int32_t Center; |
|
| 369 |
-// int32_t LFE; |
|
| 370 |
-// int32_t LeftBack; |
|
| 371 |
-// int32_t RightBack; |
|
| 372 |
-//}; |
|
| 373 |
- |
|
| 374 | 122 |
// Developer Note: This is a static class only (all static members). |
| 375 | 123 |
class SndBuffer |
| 376 | 124 |
{
|
| ... | ... |
@@ -379,16 +127,11 @@ private: |
| 379 | 127 |
static int32_t m_predictData; |
| 380 | 128 |
static float lastPct; |
| 381 | 129 |
|
| 382 |
- static StereoOut32 *sndTempBuffer; |
|
| 383 |
- static StereoOut16 *sndTempBuffer16; |
|
| 130 |
+ static std::unique_ptr<StereoOut32[]> sndTempBuffer; |
|
| 384 | 131 |
|
| 385 | 132 |
static int sndTempProgress; |
| 386 |
- //static int m_dsp_progress; |
|
| 387 |
- |
|
| 388 |
- //static int m_timestretch_progress; |
|
| 389 |
- static int m_timestretch_writepos; |
|
| 390 | 133 |
|
| 391 |
- static StereoOut32 *m_buffer; |
|
| 134 |
+ static std::unique_ptr<StereoOut32[]> m_buffer; |
|
| 392 | 135 |
static int32_t m_size; |
| 393 | 136 |
static int32_t m_rpos; |
| 394 | 137 |
static int32_t m_wpos; |
| ... | ... |
@@ -398,15 +141,12 @@ private: |
| 398 | 141 |
static float cTempo; |
| 399 | 142 |
static float eTempo; |
| 400 | 143 |
static int freezeTempo; |
| 401 |
- //static int ssFreeze; |
|
| 402 | 144 |
|
| 403 | 145 |
static void _InitFail(); |
| 404 | 146 |
static void _WriteSamples(StereoOut32 *bData, int nSamples); |
| 405 | 147 |
static bool CheckUnderrunStatus(int &nSamples, int &quietSampleCount); |
| 406 | 148 |
|
| 407 | 149 |
static void soundtouchInit(); |
| 408 |
- static void soundtouchClearContents(); |
|
| 409 |
- static void soundtouchCleanup(); |
|
| 410 | 150 |
static void timeStretchWrite(); |
| 411 | 151 |
static void timeStretchUnderrun(); |
| 412 | 152 |
static int32_t timeStretchOverrun(); |
| ... | ... |
@@ -417,10 +157,7 @@ private: |
| 417 | 157 |
|
| 418 | 158 |
public: |
| 419 | 159 |
static void Init(); |
| 420 |
- //static void Cleanup(); |
|
| 421 | 160 |
static void Write(const StereoOut32 &Sample); |
| 422 |
- //static int32_t Test(); |
|
| 423 |
- //static void ClearContents(); |
|
| 424 | 161 |
|
| 425 | 162 |
// Note: When using with 32 bit output buffers, the user of this function is responsible |
| 426 | 163 |
// for shifting the values to where they need to be manually. The fixed point depth of |
| ... | ... |
@@ -450,8 +187,8 @@ public: |
| 450 | 187 |
|
| 451 | 188 |
// [Air] [TODO]: This loop is probably a candidate for SSE2 optimization. |
| 452 | 189 |
|
| 453 |
- const int endPos = m_rpos + nSamples; |
|
| 454 |
- const int secondCopyLen = endPos - m_size; |
|
| 190 |
+ int endPos = m_rpos + nSamples; |
|
| 191 |
+ int secondCopyLen = endPos - m_size; |
|
| 455 | 192 |
const StereoOut32 *rposbuffer = &m_buffer[m_rpos]; |
| 456 | 193 |
|
| 457 | 194 |
m_data -= nSamples; |
| ... | ... |
@@ -477,57 +214,4 @@ public: |
| 477 | 214 |
} |
| 478 | 215 |
}; |
| 479 | 216 |
|
| 480 |
-//class SndOutModule |
|
| 481 |
-//{
|
|
| 482 |
-//public: |
|
| 483 |
-// // Virtual destructor, because it helps fight C+++ funny-business. |
|
| 484 |
-// virtual ~SndOutModule() {}
|
|
| 485 |
-// |
|
| 486 |
-// // Returns a unique identification string for this driver. |
|
| 487 |
-// // (usually just matches the driver's cpp filename) |
|
| 488 |
-// virtual const wchar_t* GetIdent() const=0; |
|
| 489 |
-// |
|
| 490 |
-// // Returns the long name / description for this driver. |
|
| 491 |
-// // (for use in configuration screen) |
|
| 492 |
-// virtual const wchar_t* GetLongName() const=0; |
|
| 493 |
-// |
|
| 494 |
-// virtual int32_t Init()=0; |
|
| 495 |
-// virtual void Close()=0; |
|
| 496 |
-// virtual int32_t Test() const=0; |
|
| 497 |
-// |
|
| 498 |
-// // Gui function: Used to open the configuration box for this driver. |
|
| 499 |
-// virtual void Configure(uptr parent)=0; |
|
| 500 |
-// |
|
| 501 |
-// // Loads settings from the INI file for this driver |
|
| 502 |
-// virtual void ReadSettings()=0; |
|
| 503 |
-// |
|
| 504 |
-// // Saves settings to the INI file for this driver |
|
| 505 |
-// virtual void WriteSettings() const=0; |
|
| 506 |
-// |
|
| 507 |
-// virtual bool Is51Out() const=0; |
|
| 508 |
-// |
|
| 509 |
-// // Returns the number of empty samples in the output buffer. |
|
| 510 |
-// // (which is effectively the amount of data played since the last update) |
|
| 511 |
-// virtual int GetEmptySampleCount() const=0; |
|
| 512 |
-//}; |
|
| 513 |
-// |
|
| 514 |
-// |
|
| 515 |
-//#ifdef _MSC_VER |
|
| 516 |
-////internal |
|
| 517 |
-//extern SndOutModule* WaveOut; |
|
| 518 |
-//extern SndOutModule* DSoundOut; |
|
| 519 |
-//extern SndOutModule* XAudio2Out; |
|
| 520 |
-//#endif |
|
| 521 |
-// |
|
| 522 |
-//extern SndOutModule* mods[]; |
|
| 523 |
-// |
|
| 524 |
-//// ===================================================================================================== |
|
| 525 |
-// |
|
| 526 |
-//extern void RecordStart(); |
|
| 527 |
-//extern void RecordStop(); |
|
| 528 |
-//extern void RecordWrite( const StereoOut16& sample ); |
|
| 529 |
-// |
|
| 530 |
-//extern int32_t DspLoadLibrary(wchar_t *fileName, int modNum); |
|
| 531 |
-//extern void DspCloseLibrary(); |
|
| 532 |
-//extern int DspProcess(int16_t *buffer, int samples); |
|
| 533 |
-//extern void DspUpdate(); // to let the Dsp process window messages |
|
| 217 |
+#endif |
| 1 | 1 |
new file mode 100644 |
| ... | ... |
@@ -0,0 +1,533 @@ |
| 1 |
+/* SPU2-X, A plugin for Emulating the Sound Processing Unit of the Playstation 2 |
|
| 2 |
+ * Developed and maintained by the Pcsx2 Development Team. |
|
| 3 |
+ * |
|
| 4 |
+ * Original portions from SPU2ghz are (c) 2008 by David Quintana [gigaherz] |
|
| 5 |
+ * |
|
| 6 |
+ * SPU2-X is free software: you can redistribute it and/or modify it under the terms |
|
| 7 |
+ * of the GNU Lesser General Public License as published by the Free Software Found- |
|
| 8 |
+ * ation, either version 3 of the License, or (at your option) any later version. |
|
| 9 |
+ * |
|
| 10 |
+ * SPU2-X is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; |
|
| 11 |
+ * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR |
|
| 12 |
+ * PURPOSE. See the GNU Lesser General Public License for more details. |
|
| 13 |
+ * |
|
| 14 |
+ * You should have received a copy of the GNU Lesser General Public License |
|
| 15 |
+ * along with SPU2-X. If not, see <http://www.gnu.org/licenses/>. |
|
| 16 |
+ */ |
|
| 17 |
+ |
|
| 18 |
+#pragma once |
|
| 19 |
+ |
|
| 20 |
+#include <algorithm> |
|
| 21 |
+ |
|
| 22 |
+struct StereoOut16; |
|
| 23 |
+//struct StereoOut32; |
|
| 24 |
+struct StereoOutFloat; |
|
| 25 |
+ |
|
| 26 |
+struct StereoOut32 |
|
| 27 |
+{
|
|
| 28 |
+ static StereoOut32 Empty; |
|
| 29 |
+ |
|
| 30 |
+ int32_t Left; |
|
| 31 |
+ int32_t Right; |
|
| 32 |
+ |
|
| 33 |
+ StereoOut32() : Left(0), Right(0) |
|
| 34 |
+ {
|
|
| 35 |
+ } |
|
| 36 |
+ |
|
| 37 |
+ StereoOut32(int32_t left, int32_t right) : Left(left), Right(right) |
|
| 38 |
+ {
|
|
| 39 |
+ } |
|
| 40 |
+ |
|
| 41 |
+ StereoOut32(const StereoOut16 &src); |
|
| 42 |
+ explicit StereoOut32(const StereoOutFloat &src); |
|
| 43 |
+ |
|
| 44 |
+ StereoOut16 DownSample() const; |
|
| 45 |
+ |
|
| 46 |
+ StereoOut32 operator+(const StereoOut32 &right) const |
|
| 47 |
+ {
|
|
| 48 |
+ return StereoOut32(Left + right.Left, Right + right.Right); |
|
| 49 |
+ } |
|
| 50 |
+ |
|
| 51 |
+ StereoOut32 operator/(int src) const |
|
| 52 |
+ {
|
|
| 53 |
+ return StereoOut32(Left / src, Right / src); |
|
| 54 |
+ } |
|
| 55 |
+}; |
|
| 56 |
+ |
|
| 57 |
+// Number of stereo samples per SndOut block. |
|
| 58 |
+// All drivers must work in units of this size when communicating with |
|
| 59 |
+// SndOut. |
|
| 60 |
+static const int SndOutPacketSize = 512; |
|
| 61 |
+ |
|
| 62 |
+// Overall master volume shift. |
|
| 63 |
+// Converts the mixer's 32 bit value into a 16 bit value. |
|
| 64 |
+//static const int SndOutVolumeShift = 13; |
|
| 65 |
+ |
|
| 66 |
+//edit - zeromus 23-oct-2009 |
|
| 67 |
+//this is hardcoded differently for metaspu |
|
| 68 |
+static const int SndOutVolumeShift = 0; |
|
| 69 |
+ |
|
| 70 |
+// Samplerate of the SPU2. For accurate playback we need to match this |
|
| 71 |
+// exactly. Trying to scale samplerates and maintain SPU2's Ts timing accuracy |
|
| 72 |
+// is too problematic. :) |
|
| 73 |
+//this is hardcoded differently for metaspu |
|
| 74 |
+//edit - zeromus 23-oct-2009 |
|
| 75 |
+////static const int SampleRate = 48000; |
|
| 76 |
+//static const int SampleRate = 44100; |
|
| 77 |
+//edit - nitsuja: make it use the global sample rate define |
|
| 78 |
+#include "../SPU.h" |
|
| 79 |
+static const int SampleRate = DESMUME_SAMPLE_RATE; |
|
| 80 |
+ |
|
| 81 |
+//extern int FindOutputModuleById(const wchar_t *omodid); |
|
| 82 |
+ |
|
| 83 |
+struct StereoOut16 |
|
| 84 |
+{
|
|
| 85 |
+ int16_t Left; |
|
| 86 |
+ int16_t Right; |
|
| 87 |
+ |
|
| 88 |
+ StereoOut16() : Left(0), Right(0) |
|
| 89 |
+ {
|
|
| 90 |
+ } |
|
| 91 |
+ |
|
| 92 |
+ StereoOut16(const StereoOut32 &src) : Left(static_cast<int16_t>(src.Left)), Right(static_cast<int16_t>(src.Right)) |
|
| 93 |
+ {
|
|
| 94 |
+ } |
|
| 95 |
+ |
|
| 96 |
+ StereoOut16(int16_t left, int16_t right) : Left(left), Right(right) |
|
| 97 |
+ {
|
|
| 98 |
+ } |
|
| 99 |
+ |
|
| 100 |
+ //StereoOut32 UpSample() const; |
|
| 101 |
+ |
|
| 102 |
+ void ResampleFrom(const StereoOut32 &src) |
|
| 103 |
+ {
|
|
| 104 |
+ // Use StereoOut32's built in conversion |
|
| 105 |
+ *this = src.DownSample(); |
|
| 106 |
+ } |
|
| 107 |
+}; |
|
| 108 |
+ |
|
| 109 |
+struct StereoOutFloat |
|
| 110 |
+{
|
|
| 111 |
+ float Left; |
|
| 112 |
+ float Right; |
|
| 113 |
+ |
|
| 114 |
+ StereoOutFloat() : Left(0.0f), Right(0.0f) |
|
| 115 |
+ {
|
|
| 116 |
+ } |
|
| 117 |
+ |
|
| 118 |
+ explicit StereoOutFloat(const StereoOut32 &src) : Left(src.Left / 2147483647.0f), Right(src.Right / 2147483647.0f) |
|
| 119 |
+ {
|
|
| 120 |
+ } |
|
| 121 |
+ |
|
| 122 |
+ explicit StereoOutFloat(int32_t left, int32_t right) : Left(left / 2147483647.0f), Right(right / 2147483647.0f) |
|
| 123 |
+ {
|
|
| 124 |
+ } |
|
| 125 |
+ |
|
| 126 |
+ StereoOutFloat(float left, float right) : Left(left), Right(right) |
|
| 127 |
+ {
|
|
| 128 |
+ } |
|
| 129 |
+}; |
|
| 130 |
+ |
|
| 131 |
+//struct Stereo21Out16 |
|
| 132 |
+//{
|
|
| 133 |
+// int16_t Left; |
|
| 134 |
+// int16_t Right; |
|
| 135 |
+// int16_t LFE; |
|
| 136 |
+// |
|
| 137 |
+// void ResampleFrom( const StereoOut32& src ) |
|
| 138 |
+// {
|
|
| 139 |
+// Left = src.Left >> SndOutVolumeShift; |
|
| 140 |
+// Right = src.Right >> SndOutVolumeShift; |
|
| 141 |
+// LFE = (src.Left + src.Right) >> (SndOutVolumeShift + 1); |
|
| 142 |
+// } |
|
| 143 |
+//}; |
|
| 144 |
+// |
|
| 145 |
+//struct StereoQuadOut16 |
|
| 146 |
+//{
|
|
| 147 |
+// int16_t Left; |
|
| 148 |
+// int16_t Right; |
|
| 149 |
+// int16_t LeftBack; |
|
| 150 |
+// int16_t RightBack; |
|
| 151 |
+// |
|
| 152 |
+// void ResampleFrom( const StereoOut32& src ) |
|
| 153 |
+// {
|
|
| 154 |
+// Left = src.Left >> SndOutVolumeShift; |
|
| 155 |
+// Right = src.Right >> SndOutVolumeShift; |
|
| 156 |
+// LeftBack = src.Left >> SndOutVolumeShift; |
|
| 157 |
+// RightBack = src.Right >> SndOutVolumeShift; |
|
| 158 |
+// } |
|
| 159 |
+//}; |
|
| 160 |
+// |
|
| 161 |
+//struct Stereo41Out16 |
|
| 162 |
+//{
|
|
| 163 |
+// int16_t Left; |
|
| 164 |
+// int16_t Right; |
|
| 165 |
+// int16_t LFE; |
|
| 166 |
+// int16_t LeftBack; |
|
| 167 |
+// int16_t RightBack; |
|
| 168 |
+// |
|
| 169 |
+// void ResampleFrom( const StereoOut32& src ) |
|
| 170 |
+// {
|
|
| 171 |
+// Left = src.Left >> SndOutVolumeShift; |
|
| 172 |
+// Right = src.Right >> SndOutVolumeShift; |
|
| 173 |
+// LFE = (src.Left + src.Right) >> (SndOutVolumeShift + 1); |
|
| 174 |
+// LeftBack = src.Left >> SndOutVolumeShift; |
|
| 175 |
+// RightBack = src.Right >> SndOutVolumeShift; |
|
| 176 |
+// } |
|
| 177 |
+//}; |
|
| 178 |
+// |
|
| 179 |
+//struct Stereo51Out16 |
|
| 180 |
+//{
|
|
| 181 |
+// int16_t Left; |
|
| 182 |
+// int16_t Right; |
|
| 183 |
+// int16_t Center; |
|
| 184 |
+// int16_t LFE; |
|
| 185 |
+// int16_t LeftBack; |
|
| 186 |
+// int16_t RightBack; |
|
| 187 |
+// |
|
| 188 |
+// // Implementation Note: Center and Subwoofer/LFE --> |
|
| 189 |
+// // This method is simple and sounds nice. It relies on the speaker/soundcard |
|
| 190 |
+// // systems do to their own low pass / crossover. Manual lowpass is wasted effort |
|
| 191 |
+// // and can't match solid state results anyway. |
|
| 192 |
+// |
|
| 193 |
+// void ResampleFrom( const StereoOut32& src ) |
|
| 194 |
+// {
|
|
| 195 |
+// Left = src.Left >> SndOutVolumeShift; |
|
| 196 |
+// Right = src.Right >> SndOutVolumeShift; |
|
| 197 |
+// Center = (src.Left + src.Right) >> (SndOutVolumeShift + 1); |
|
| 198 |
+// LFE = Center; |
|
| 199 |
+// LeftBack = src.Left >> SndOutVolumeShift; |
|
| 200 |
+// RightBack = src.Right >> SndOutVolumeShift; |
|
| 201 |
+// } |
|
| 202 |
+//}; |
|
| 203 |
+// |
|
| 204 |
+//struct Stereo51Out16DplII |
|
| 205 |
+//{
|
|
| 206 |
+// int16_t Left; |
|
| 207 |
+// int16_t Right; |
|
| 208 |
+// int16_t Center; |
|
| 209 |
+// int16_t LFE; |
|
| 210 |
+// int16_t LeftBack; |
|
| 211 |
+// int16_t RightBack; |
|
| 212 |
+// |
|
| 213 |
+// void ResampleFrom( const StereoOut32& src ) |
|
| 214 |
+// {
|
|
| 215 |
+// static const u8 sLogTable[256] = {
|
|
| 216 |
+// 0x00,0x3C,0x60,0x78,0x8C,0x9C,0xA8,0xB4,0xBE,0xC8,0xD0,0xD8,0xDE,0xE4,0xEA,0xF0, |
|
| 217 |
+// 0xF6,0xFA,0xFE,0x04,0x08,0x0C,0x10,0x14,0x16,0x1A,0x1E,0x20,0x24,0x26,0x2A,0x2C, |
|
| 218 |
+// 0x2E,0x32,0x34,0x36,0x38,0x3A,0x3E,0x40,0x42,0x44,0x46,0x48,0x4A,0x4C,0x4E,0x50, |
|
| 219 |
+// 0x50,0x52,0x54,0x56,0x58,0x5A,0x5A,0x5C,0x5E,0x60,0x60,0x62,0x64,0x66,0x66,0x68, |
|
| 220 |
+// 0x6A,0x6A,0x6C,0x6E,0x6E,0x70,0x70,0x72,0x74,0x74,0x76,0x76,0x78,0x7A,0x7A,0x7C, |
|
| 221 |
+// 0x7C,0x7E,0x7E,0x80,0x80,0x82,0x82,0x84,0x84,0x86,0x86,0x88,0x88,0x8A,0x8A,0x8C, |
|
| 222 |
+// 0x8C,0x8C,0x8E,0x8E,0x90,0x90,0x92,0x92,0x92,0x94,0x94,0x96,0x96,0x96,0x98,0x98, |
|
| 223 |
+// 0x9A,0x9A,0x9A,0x9C,0x9C,0x9C,0x9E,0x9E,0xA0,0xA0,0xA0,0xA2,0xA2,0xA2,0xA4,0xA4, |
|
| 224 |
+// 0xA4,0xA6,0xA6,0xA6,0xA8,0xA8,0xA8,0xAA,0xAA,0xAA,0xAC,0xAC,0xAC,0xAC,0xAE,0xAE, |
|
| 225 |
+// 0xAE,0xB0,0xB0,0xB0,0xB2,0xB2,0xB2,0xB2,0xB4,0xB4,0xB4,0xB6,0xB6,0xB6,0xB6,0xB8, |
|
| 226 |
+// 0xB8,0xB8,0xB8,0xBA,0xBA,0xBA,0xBC,0xBC,0xBC,0xBC,0xBE,0xBE,0xBE,0xBE,0xC0,0xC0, |
|
| 227 |
+// 0xC0,0xC0,0xC2,0xC2,0xC2,0xC2,0xC2,0xC4,0xC4,0xC4,0xC4,0xC6,0xC6,0xC6,0xC6,0xC8, |
|
| 228 |
+// 0xC8,0xC8,0xC8,0xC8,0xCA,0xCA,0xCA,0xCA,0xCC,0xCC,0xCC,0xCC,0xCC,0xCE,0xCE,0xCE, |
|
| 229 |
+// 0xCE,0xCE,0xD0,0xD0,0xD0,0xD0,0xD0,0xD2,0xD2,0xD2,0xD2,0xD2,0xD4,0xD4,0xD4,0xD4, |
|
| 230 |
+// 0xD4,0xD6,0xD6,0xD6,0xD6,0xD6,0xD8,0xD8,0xD8,0xD8,0xD8,0xD8,0xDA,0xDA,0xDA,0xDA, |
|
| 231 |
+// 0xDA,0xDC,0xDC,0xDC,0xDC,0xDC,0xDC,0xDE,0xDE,0xDE,0xDE,0xDE,0xDE,0xE0,0xE0,0xE0, |
|
| 232 |
+// }; |
|
| 233 |
+// |
|
| 234 |
+// static int32_t Gfl=0,Gfr=0; |
|
| 235 |
+// static int32_t LMax=0,RMax=0; |
|
| 236 |
+// |
|
| 237 |
+// static int32_t LAccum; |
|
| 238 |
+// static int32_t RAccum; |
|
| 239 |
+// static int32_t ANum; |
|
| 240 |
+// |
|
| 241 |
+// int32_t ValL = src.Left >> (SndOutVolumeShift-8); |
|
| 242 |
+// int32_t ValR = src.Right >> (SndOutVolumeShift-8); |
|
| 243 |
+// |
|
| 244 |
+// int32_t XL = abs(ValL>>8); |
|
| 245 |
+// int32_t XR = abs(ValR>>8); |
|
| 246 |
+// |
|
| 247 |
+// if(XL>LMax) LMax = XL; |
|
| 248 |
+// if(XR>RMax) RMax = XR; |
|
| 249 |
+// |
|
| 250 |
+// ANum++; |
|
| 251 |
+// if(ANum>=128) |
|
| 252 |
+// {
|
|
| 253 |
+// ANum=0; |
|
| 254 |
+// LAccum = 1+((LAccum * 224 + LMax * 31)>>8); |
|
| 255 |
+// RAccum = 1+((RAccum * 224 + RMax * 31)>>8); |
|
| 256 |
+// |
|
| 257 |
+// LMax = 0; |
|
| 258 |
+// RMax = 0; |
|
| 259 |
+// |
|
| 260 |
+// int32_t Tfl=(RAccum)*255/(LAccum); |
|
| 261 |
+// int32_t Tfr=(LAccum)*255/(RAccum); |
|
| 262 |
+// |
|
| 263 |
+// int gMax = std::max(Tfl,Tfr); |
|
| 264 |
+// Tfl = Tfl*255/gMax; |
|
| 265 |
+// Tfr = Tfr*255/gMax; |
|
| 266 |
+// |
|
| 267 |
+// if(Tfl>255) Tfl=255; |
|
| 268 |
+// if(Tfr>255) Tfr=255; |
|
| 269 |
+// if(Tfl<1) Tfl=1; |
|
| 270 |
+// if(Tfr<1) Tfr=1; |
|
| 271 |
+// |
|
| 272 |
+// Gfl = (Gfl * 200 + Tfl * 56)>>8; |
|
| 273 |
+// Gfr = (Gfr * 200 + Tfr * 56)>>8; |
|
| 274 |
+// |
|
| 275 |
+// } |
|
| 276 |
+// |
|
| 277 |
+// int32_t L,R,C,SUB,SL,SR; |
|
| 278 |
+// |
|
| 279 |
+// C=(ValL+ValR)>>1; //16.8 |
|
| 280 |
+// |
|
| 281 |
+// ValL-=C;//16.8 |
|
| 282 |
+// ValR-=C;//16.8 |
|
| 283 |
+// |
|
| 284 |
+// L=ValL>>8; //16.0 |
|
| 285 |
+// R=ValR>>8; //16.0 |
|
| 286 |
+// C=C>>8; //16.0 |
|
| 287 |
+// SUB = C; |
|
| 288 |
+// |
|
| 289 |
+// {
|
|
| 290 |
+// int32_t Cfl = 1+sLogTable[Gfl]; |
|
| 291 |
+// int32_t Cfr = 1+sLogTable[Gfr]; |
|
| 292 |
+// |
|
| 293 |
+// int32_t VL=(ValL>>4) * Cfl; //16.12 |
|
| 294 |
+// int32_t VR=(ValR>>4) * Cfr; |
|
| 295 |
+// |
|
| 296 |
+// //int32_t SC = (VL-VR)>>15; |
|
| 297 |
+// |
|
| 298 |
+// SL = (((VR/148 - VL/209)>>4)*Cfr)>>8; |
|
| 299 |
+// SR = (((VR/209 - VL/148)>>4)*Cfl)>>8; |
|
| 300 |
+// |
|
| 301 |
+// } |
|
| 302 |
+// |
|
| 303 |
+// // Random-ish values to get it to compile |
|
| 304 |
+// int GainL = 200; |
|
| 305 |
+// int GainR = 200; |
|
| 306 |
+// int GainC = 180; |
|
| 307 |
+// int GainSL = 230; |
|
| 308 |
+// int GainSR = 230; |
|
| 309 |
+// int GainLFE = 200; |
|
| 310 |
+// int AddCLR = 55; |
|
| 311 |
+// |
|
| 312 |
+// int AddCX = (C * AddCLR)>>8; |
|
| 313 |
+// |
|
| 314 |
+// Left = (((L * GainL ))>>8) + AddCX; |
|
| 315 |
+// Right = (((R * GainR ))>>8) + AddCX; |
|
| 316 |
+// Center = (((C * GainC ))>>8); |
|
| 317 |
+// LFE = (((SUB * GainLFE))>>8); |
|
| 318 |
+// LeftBack = (((SL * GainSL ))>>8); |
|
| 319 |
+// RightBack = (((SR * GainSR ))>>8); |
|
| 320 |
+// } |
|
| 321 |
+//}; |
|
| 322 |
+// |
|
| 323 |
+//struct Stereo71Out16 |
|
| 324 |
+//{
|
|
| 325 |
+// int16_t Left; |
|
| 326 |
+// int16_t Right; |
|
| 327 |
+// int16_t Center; |
|
| 328 |
+// int16_t LFE; |
|
| 329 |
+// int16_t LeftBack; |
|
| 330 |
+// int16_t RightBack; |
|
| 331 |
+// int16_t LeftSide; |
|
| 332 |
+// int16_t RightSide; |
|
| 333 |
+// |
|
| 334 |
+// void ResampleFrom( const StereoOut32& src ) |
|
| 335 |
+// {
|
|
| 336 |
+// Left = src.Left >> SndOutVolumeShift; |
|
| 337 |
+// Right = src.Right >> SndOutVolumeShift; |
|
| 338 |
+// Center = (src.Left + src.Right) >> (SndOutVolumeShift + 1); |
|
| 339 |
+// LFE = Center; |
|
| 340 |
+// LeftBack = src.Left >> SndOutVolumeShift; |
|
| 341 |
+// RightBack = src.Right >> SndOutVolumeShift; |
|
| 342 |
+// |
|
| 343 |
+// LeftSide = src.Left >> (SndOutVolumeShift+1); |
|
| 344 |
+// RightSide = src.Right >> (SndOutVolumeShift+1); |
|
| 345 |
+// } |
|
| 346 |
+//}; |
|
| 347 |
+// |
|
| 348 |
+//struct Stereo21Out32 |
|
| 349 |
+//{
|
|
| 350 |
+// int32_t Left; |
|
| 351 |
+// int32_t Right; |
|
| 352 |
+// int32_t LFE; |
|
| 353 |
+//}; |
|
| 354 |
+// |
|
| 355 |
+//struct Stereo41Out32 |
|
| 356 |
+//{
|
|
| 357 |
+// int32_t Left; |
|
| 358 |
+// int32_t Right; |
|
| 359 |
+// int32_t LFE; |
|
| 360 |
+// int32_t LeftBack; |
|
| 361 |
+// int32_t RightBack; |
|
| 362 |
+//}; |
|
| 363 |
+// |
|
| 364 |
+//struct Stereo51Out32 |
|
| 365 |
+//{
|
|
| 366 |
+// int32_t Left; |
|
| 367 |
+// int32_t Right; |
|
| 368 |
+// int32_t Center; |
|
| 369 |
+// int32_t LFE; |
|
| 370 |
+// int32_t LeftBack; |
|
| 371 |
+// int32_t RightBack; |
|
| 372 |
+//}; |
|
| 373 |
+ |
|
| 374 |
+// Developer Note: This is a static class only (all static members). |
|
| 375 |
+class SndBuffer |
|
| 376 |
+{
|
|
| 377 |
+private: |
|
| 378 |
+ static bool m_underrun_freeze; |
|
| 379 |
+ static int32_t m_predictData; |
|
| 380 |
+ static float lastPct; |
|
| 381 |
+ |
|
| 382 |
+ static StereoOut32 *sndTempBuffer; |
|
| 383 |
+ static StereoOut16 *sndTempBuffer16; |
|
| 384 |
+ |
|
| 385 |
+ static int sndTempProgress; |
|
| 386 |
+ //static int m_dsp_progress; |
|
| 387 |
+ |
|
| 388 |
+ //static int m_timestretch_progress; |
|
| 389 |
+ static int m_timestretch_writepos; |
|
| 390 |
+ |
|
| 391 |
+ static StereoOut32 *m_buffer; |
|
| 392 |
+ static int32_t m_size; |
|
| 393 |
+ static int32_t m_rpos; |
|
| 394 |
+ static int32_t m_wpos; |
|
| 395 |
+ static int32_t m_data; |
|
| 396 |
+ |
|
| 397 |
+ static float lastEmergencyAdj; |
|
| 398 |
+ static float cTempo; |
|
| 399 |
+ static float eTempo; |
|
| 400 |
+ static int freezeTempo; |
|
| 401 |
+ //static int ssFreeze; |
|
| 402 |
+ |
|
| 403 |
+ static void _InitFail(); |
|
| 404 |
+ static void _WriteSamples(StereoOut32 *bData, int nSamples); |
|
| 405 |
+ static bool CheckUnderrunStatus(int &nSamples, int &quietSampleCount); |
|
| 406 |
+ |
|
| 407 |
+ static void soundtouchInit(); |
|
| 408 |
+ static void soundtouchClearContents(); |
|
| 409 |
+ static void soundtouchCleanup(); |
|
| 410 |
+ static void timeStretchWrite(); |
|
| 411 |
+ static void timeStretchUnderrun(); |
|
| 412 |
+ static int32_t timeStretchOverrun(); |
|
| 413 |
+ |
|
| 414 |
+ static void PredictDataWrite(int samples); |
|
| 415 |
+ static float GetStatusPct(); |
|
| 416 |
+ static void UpdateTempoChange(); |
|
| 417 |
+ |
|
| 418 |
+public: |
|
| 419 |
+ static void Init(); |
|
| 420 |
+ //static void Cleanup(); |
|
| 421 |
+ static void Write(const StereoOut32 &Sample); |
|
| 422 |
+ //static int32_t Test(); |
|
| 423 |
+ //static void ClearContents(); |
|
| 424 |
+ |
|
| 425 |
+ // Note: When using with 32 bit output buffers, the user of this function is responsible |
|
| 426 |
+ // for shifting the values to where they need to be manually. The fixed point depth of |
|
| 427 |
+ // the sample output is determined by the SndOutVolumeShift, which is the number of bits |
|
| 428 |
+ // to shift right to get a 16 bit result. |
|
| 429 |
+ template<typename T> static void ReadSamples(T *bData) |
|
| 430 |
+ {
|
|
| 431 |
+ int nSamples = SndOutPacketSize; |
|
| 432 |
+ |
|
| 433 |
+ // Problem: |
|
| 434 |
+ // If the SPU2 gets even the least bit out of sync with the SndOut device, |
|
| 435 |
+ // the readpos of the circular buffer will overtake the writepos, |
|
| 436 |
+ // leading to a prolonged period of hopscotching read/write accesses (ie, |
|
| 437 |
+ // lots of staticy crap sound for several seconds). |
|
| 438 |
+ // |
|
| 439 |
+ // Fix: |
|
| 440 |
+ // If the read position overtakes the write position, abort the |
|
| 441 |
+ // transfer immediately and force the SndOut driver to wait until |
|
| 442 |
+ // the read buffer has filled up again before proceeding. |
|
| 443 |
+ // This will cause one brief hiccup that can never exceed the user's |
|
| 444 |
+ // set buffer length in duration. |
|
| 445 |
+ |
|
| 446 |
+ int quietSamples; |
|
| 447 |
+ if (CheckUnderrunStatus(nSamples, quietSamples)) |
|
| 448 |
+ {
|
|
| 449 |
+ assert(nSamples <= SndOutPacketSize); |
|
| 450 |
+ |
|
| 451 |
+ // [Air] [TODO]: This loop is probably a candidate for SSE2 optimization. |
|
| 452 |
+ |
|
| 453 |
+ const int endPos = m_rpos + nSamples; |
|
| 454 |
+ const int secondCopyLen = endPos - m_size; |
|
| 455 |
+ const StereoOut32 *rposbuffer = &m_buffer[m_rpos]; |
|
| 456 |
+ |
|
| 457 |
+ m_data -= nSamples; |
|
| 458 |
+ |
|
| 459 |
+ if (secondCopyLen > 0) |
|
| 460 |
+ {
|
|
| 461 |
+ nSamples -= secondCopyLen; |
|
| 462 |
+ for (int i = 0; i < secondCopyLen; ++i) |
|
| 463 |
+ bData[nSamples + i].ResampleFrom(m_buffer[i]); |
|
| 464 |
+ m_rpos = secondCopyLen; |
|
| 465 |
+ } |
|
| 466 |
+ else |
|
| 467 |
+ m_rpos += nSamples; |
|
| 468 |
+ |
|
| 469 |
+ for (int i = 0; i < nSamples; ++i) |
|
| 470 |
+ bData[i].ResampleFrom(rposbuffer[i]); |
|
| 471 |
+ } |
|
| 472 |
+ |
|
| 473 |
+ // If quietSamples != 0 it means we have an underrun... |
|
| 474 |
+ // Let's just dull out some silence, because that's usually the least |
|
| 475 |
+ // painful way of dealing with underruns: |
|
| 476 |
+ memset(bData, 0, quietSamples * sizeof(T)); |
|
| 477 |
+ } |
|
| 478 |
+}; |
|
| 479 |
+ |
|
| 480 |
+//class SndOutModule |
|
| 481 |
+//{
|
|
| 482 |
+//public: |
|
| 483 |
+// // Virtual destructor, because it helps fight C+++ funny-business. |
|
| 484 |
+// virtual ~SndOutModule() {}
|
|
| 485 |
+// |
|
| 486 |
+// // Returns a unique identification string for this driver. |
|
| 487 |
+// // (usually just matches the driver's cpp filename) |
|
| 488 |
+// virtual const wchar_t* GetIdent() const=0; |
|
| 489 |
+// |
|
| 490 |
+// // Returns the long name / description for this driver. |
|
| 491 |
+// // (for use in configuration screen) |
|
| 492 |
+// virtual const wchar_t* GetLongName() const=0; |
|
| 493 |
+// |
|
| 494 |
+// virtual int32_t Init()=0; |
|
| 495 |
+// virtual void Close()=0; |
|
| 496 |
+// virtual int32_t Test() const=0; |
|
| 497 |
+// |
|
| 498 |
+// // Gui function: Used to open the configuration box for this driver. |
|
| 499 |
+// virtual void Configure(uptr parent)=0; |
|
| 500 |
+// |
|
| 501 |
+// // Loads settings from the INI file for this driver |
|
| 502 |
+// virtual void ReadSettings()=0; |
|
| 503 |
+// |
|
| 504 |
+// // Saves settings to the INI file for this driver |
|
| 505 |
+// virtual void WriteSettings() const=0; |
|
| 506 |
+// |
|
| 507 |
+// virtual bool Is51Out() const=0; |
|
| 508 |
+// |
|
| 509 |
+// // Returns the number of empty samples in the output buffer. |
|
| 510 |
+// // (which is effectively the amount of data played since the last update) |
|
| 511 |
+// virtual int GetEmptySampleCount() const=0; |
|
| 512 |
+//}; |
|
| 513 |
+// |
|
| 514 |
+// |
|
| 515 |
+//#ifdef _MSC_VER |
|
| 516 |
+////internal |
|
| 517 |
+//extern SndOutModule* WaveOut; |
|
| 518 |
+//extern SndOutModule* DSoundOut; |
|
| 519 |
+//extern SndOutModule* XAudio2Out; |
|
| 520 |
+//#endif |
|
| 521 |
+// |
|
| 522 |
+//extern SndOutModule* mods[]; |
|
| 523 |
+// |
|
| 524 |
+//// ===================================================================================================== |
|
| 525 |
+// |
|
| 526 |
+//extern void RecordStart(); |
|
| 527 |
+//extern void RecordStop(); |
|
| 528 |
+//extern void RecordWrite( const StereoOut16& sample ); |
|
| 529 |
+// |
|
| 530 |
+//extern int32_t DspLoadLibrary(wchar_t *fileName, int modNum); |
|
| 531 |
+//extern void DspCloseLibrary(); |
|
| 532 |
+//extern int DspProcess(int16_t *buffer, int samples); |
|
| 533 |
+//extern void DspUpdate(); // to let the Dsp process window messages |