summaryrefslogtreecommitdiff
path: root/Source/Core/AudioCommon
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/AudioCommon')
-rw-r--r--Source/Core/AudioCommon/Src/AudioCommonConfig.cpp6
-rw-r--r--Source/Core/AudioCommon/Src/AudioCommonConfig.h2
-rw-r--r--Source/Core/AudioCommon/Src/Mixer.cpp111
-rw-r--r--Source/Core/AudioCommon/Src/Mixer.h7
4 files changed, 49 insertions, 77 deletions
diff --git a/Source/Core/AudioCommon/Src/AudioCommonConfig.cpp b/Source/Core/AudioCommon/Src/AudioCommonConfig.cpp
index ebec56e41d..f97b0ba75d 100644
--- a/Source/Core/AudioCommon/Src/AudioCommonConfig.cpp
+++ b/Source/Core/AudioCommon/Src/AudioCommonConfig.cpp
@@ -26,14 +26,19 @@ void AudioCommonConfig::Load(IniFile &file) {
file.Get("Config", "Volume", &m_Volume, 75);
#ifdef _WIN32
file.Get("Config", "Backend", &sBackend, BACKEND_DIRECTSOUND);
+ file.Get("Config", "Frequency", &sFrequency, "32,000 Hz");
#elif defined __APPLE__
std::string temp;
file.Get("Config", "Backend", &temp, BACKEND_COREAUDIO);
strncpy(sBackend, temp.c_str(), 128);
+ file.Get("Config", "Frequency", &temp, "32,000 Hz");
+ strncpy(sFrequency, temp.c_str(), 128);
#elif defined __linux__
file.Get("Config", "Backend", &sBackend, BACKEND_ALSA);
+ file.Get("Config", "Frequency", &sFrequency, "32,000 Hz");
#else
file.Get("Config", "Backend", &sBackend, BACKEND_OPENAL);
+ file.Get("Config", "Frequency", &sFrequency, "32,000 Hz");
#endif
}
@@ -43,6 +48,7 @@ void AudioCommonConfig::Set(IniFile &file) {
file.Set("Config", "EnableThrottle", m_EnableThrottle);
file.Set("Config", "EnableJIT", m_EnableJIT);
file.Set("Config", "Backend", sBackend);
+ file.Set("Config", "Frequency", sFrequency);
file.Set("Config", "Volume", m_Volume);
}
diff --git a/Source/Core/AudioCommon/Src/AudioCommonConfig.h b/Source/Core/AudioCommon/Src/AudioCommonConfig.h
index 1267b320b8..524251bb86 100644
--- a/Source/Core/AudioCommon/Src/AudioCommonConfig.h
+++ b/Source/Core/AudioCommon/Src/AudioCommonConfig.h
@@ -39,8 +39,10 @@ struct AudioCommonConfig
int m_Volume;
#ifdef __APPLE__
char sBackend[128];
+ char sFrequency[128];
#else
std::string sBackend;
+ std::string sFrequency;
#endif
// Load from given file
diff --git a/Source/Core/AudioCommon/Src/Mixer.cpp b/Source/Core/AudioCommon/Src/Mixer.cpp
index b4f1be935d..d914f634c5 100644
--- a/Source/Core/AudioCommon/Src/Mixer.cpp
+++ b/Source/Core/AudioCommon/Src/Mixer.cpp
@@ -57,74 +57,39 @@ unsigned int CMixer::Mix(short* samples, unsigned int numSamples)
samples[i] = Common::swap16(m_buffer[(m_indexR + i) & INDEX_MASK]);
m_indexR += numLeft * 2;
}
- else
+ else //linear interpolation
{
- // AyuanX: Up-sampling is not implemented yet
- PanicAlert("Mixer: Up-sampling is not implemented yet!");
-/*
- static int PV1l=0,PV2l=0,PV3l=0,PV4l=0;
- static int PV1r=0,PV2r=0,PV3r=0,PV4r=0;
- static int acc=0;
-
- while (num_stereo_samples) {
- acc += core_sample_rate;
- while (num_stereo_samples && (acc >= 48000)) {
- PV4l=PV3l;
- PV3l=PV2l;
- PV2l=PV1l;
- PV1l=*(samples++); //32bit processing
- PV4r=PV3r;
- PV3r=PV2r;
- PV2r=PV1r;
- PV1r=*(samples++); //32bit processing
- num_stereo_samples--;
- acc-=48000;
- }
-
- // defaults to nearest
- s32 DataL = PV1l;
- s32 DataR = PV1r;
-
- if (m_mode == 1) { //linear
-
- DataL = PV1l + ((PV2l - PV1l)*acc)/48000;
- DataR = PV1r + ((PV2r - PV1r)*acc)/48000;
- }
- else if (m_mode == 2) {//cubic
- s32 a0l = PV1l - PV2l - PV4l + PV3l;
- s32 a0r = PV1r - PV2r - PV4r + PV3r;
- s32 a1l = PV4l - PV3l - a0l;
- s32 a1r = PV4r - PV3r - a0r;
- s32 a2l = PV1l - PV4l;
- s32 a2r = PV1r - PV4r;
- s32 a3l = PV2l;
- s32 a3r = PV2r;
-
- s32 t0l = ((a0l )*acc)/48000;
- s32 t0r = ((a0r )*acc)/48000;
- s32 t1l = ((t0l+a1l)*acc)/48000;
- s32 t1r = ((t0r+a1r)*acc)/48000;
- s32 t2l = ((t1l+a2l)*acc)/48000;
- s32 t2r = ((t1r+a2r)*acc)/48000;
- s32 t3l = ((t2l+a3l));
- s32 t3r = ((t2r+a3r));
-
- DataL = t3l;
- DataR = t3r;
- }
-
- int l = DataL, r = DataR;
- if (l < -32767) l = -32767;
- if (r < -32767) r = -32767;
- if (l > 32767) l = 32767;
- if (r > 32767) r = 32767;
- sample_queue.push(l);
- sample_queue.push(r);
- m_queueSize += 2;
- }
-*/
+ //render numleft sample pairs to samples[]
+ //advance m_indexR with sample position
+ //remember fractional offset
+
+ static u32 frac = 0;
+ const u32 ratio = (u32)( 65536.0f * 32000.0f / (float)m_sampleRate );
+
+ for (u32 i = 0; i < numLeft * 2; i+=2) {
+ u32 m_indexR2 = m_indexR + 2; //next sample
+ 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] = 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;
+ samples[i+1] = sampleR;
+
+ frac += ratio;
+ m_indexR += 2 * (u16)(frac >> 16);
+ frac &= 0xffff;
+ }
}
+
+
} else {
numLeft = 0;
}
@@ -154,7 +119,7 @@ void CMixer::PushSamples(short *samples, unsigned int num_samples)
if (m_throttle)
{
// The auto throttle function. This loop will put a ceiling on the CPU MHz.
- while (Common::AtomicLoad(m_numSamples) >= MAX_SAMPLES - RESERVED_SAMPLES)
+ while (Common::AtomicLoad(m_numSamples) + RESERVED_SAMPLES >= MAX_SAMPLES)
{
if (g_dspInitialize.pEmulatorState)
{
@@ -171,7 +136,7 @@ void CMixer::PushSamples(short *samples, unsigned int num_samples)
}
// Check if we have enough free space
- if (num_samples > MAX_SAMPLES - Common::AtomicLoad(m_numSamples))
+ if (num_samples + Common::AtomicLoad(m_numSamples) > MAX_SAMPLES)
return;
// AyuanX: Actual re-sampling work has been moved to sound thread
@@ -190,12 +155,12 @@ void CMixer::PushSamples(short *samples, unsigned int num_samples)
m_indexW += num_samples * 2;
- if (m_sampleRate != 32000)
- {
- PanicAlert("Mixer: Up-sampling is not implemented yet!");
- }
-
- Common::AtomicAdd(m_numSamples, num_samples);
+ if (m_sampleRate == 32000)
+ Common::AtomicAdd(m_numSamples, num_samples);
+ else if (m_sampleRate == 48000)
+ Common::AtomicAdd(m_numSamples, num_samples * 1.5);
+ else
+ PanicAlert("Mixer: Unsupported sample rate.");
return;
}
diff --git a/Source/Core/AudioCommon/Src/Mixer.h b/Source/Core/AudioCommon/Src/Mixer.h
index dfa4d41828..984ec1c211 100644
--- a/Source/Core/AudioCommon/Src/Mixer.h
+++ b/Source/Core/AudioCommon/Src/Mixer.h
@@ -26,7 +26,7 @@
class CMixer {
public:
- CMixer(unsigned int AISampleRate = 48000, unsigned int DACSampleRate = 48000)
+ CMixer(unsigned int AISampleRate = 48000, unsigned int DACSampleRate = 48000, unsigned int BackendSampleRate = 32000)
: m_aiSampleRate(AISampleRate)
, m_dacSampleRate(DACSampleRate)
, m_bits(16)
@@ -39,9 +39,8 @@ public:
{
// AyuanX: The internal (Core & DSP) sample rate is fixed at 32KHz
// So when AI/DAC sample rate differs than 32KHz, we have to do re-sampling
- // I prefer speed so let's do down-sampling instead of up-sampling
- // If you like better sound than speed, feel free to implement the up-sampling code
- m_sampleRate = 32000;
+ m_sampleRate = BackendSampleRate;
+
INFO_LOG(AUDIO_INTERFACE, "Mixer is initialized (AISampleRate:%i, DACSampleRate:%i)", AISampleRate, DACSampleRate);
}