mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-01-31 02:23:51 +00:00
Merge pull request #12910 from hrydgard/sdl-sample-rate-sysinfo
SDL: Show the actually used sample rate in system info.
This commit is contained in:
commit
02fdf0083f
@ -47,7 +47,6 @@
|
||||
#include "Core/Util/AudioFormat.h"
|
||||
|
||||
StereoResampler resampler;
|
||||
AudioDebugStats g_AudioDebugStats;
|
||||
|
||||
// Should be used to lock anything related to the outAudioQueue.
|
||||
// atomic locks are used on the lock. TODO: make this lock-free
|
||||
@ -100,7 +99,7 @@ static void __AudioCPUMHzChange() {
|
||||
|
||||
|
||||
void __AudioInit() {
|
||||
memset(&g_AudioDebugStats, 0, sizeof(g_AudioDebugStats));
|
||||
resampler.ResetStatCounters();
|
||||
mixFrequency = 44100;
|
||||
srcFrequency = 0;
|
||||
|
||||
@ -459,9 +458,8 @@ int __AudioMix(short *outstereo, int numFrames, int sampleRate) {
|
||||
return resampler.Mix(outstereo, numFrames, false, sampleRate);
|
||||
}
|
||||
|
||||
const AudioDebugStats *__AudioGetDebugStats() {
|
||||
resampler.GetAudioDebugStats(&g_AudioDebugStats);
|
||||
return &g_AudioDebugStats;
|
||||
void __AudioGetDebugStats(char *buf, size_t bufSize) {
|
||||
resampler.GetAudioDebugStats(buf, bufSize);
|
||||
}
|
||||
|
||||
void __PushExternalAudio(const s32 *audio, int numSamples) {
|
||||
|
@ -26,6 +26,7 @@ struct AudioDebugStats {
|
||||
int underrunCount;
|
||||
int overrunCount;
|
||||
int instantSampleRate;
|
||||
int targetSampleRate;
|
||||
int lastPushSize;
|
||||
};
|
||||
|
||||
@ -44,7 +45,7 @@ void __AudioWakeThreads(AudioChannel &chan, int result, int step);
|
||||
void __AudioWakeThreads(AudioChannel &chan, int result);
|
||||
|
||||
int __AudioMix(short *outstereo, int numSamples, int sampleRate);
|
||||
const AudioDebugStats *__AudioGetDebugStats();
|
||||
void __AudioGetDebugStats(char *buf, size_t bufSize);
|
||||
void __PushExternalAudio(const s32 *audio, int numSamples); // Should not be used in-game, only at the menu!
|
||||
|
||||
// Audio Dumping stuff
|
||||
|
@ -56,16 +56,7 @@
|
||||
|
||||
StereoResampler::StereoResampler()
|
||||
: m_bufsize(MAX_SAMPLES_DEFAULT)
|
||||
, m_lowwatermark(LOW_WATERMARK_DEFAULT)
|
||||
, m_input_sample_rate(44100)
|
||||
, m_indexW(0)
|
||||
, m_indexR(0)
|
||||
, m_numLeftI(0.0f)
|
||||
, m_frac(0)
|
||||
, underrunCount_(0)
|
||||
, overrunCount_(0)
|
||||
, sample_rate_(0.0f)
|
||||
, lastBufSize_(0) {
|
||||
, m_lowwatermark(LOW_WATERMARK_DEFAULT) {
|
||||
// Need to have space for the worst case in case it changes.
|
||||
m_buffer = new int16_t[MAX_SAMPLES_EXTRA * 2]();
|
||||
|
||||
@ -75,7 +66,9 @@ StereoResampler::StereoResampler()
|
||||
|
||||
// If framerate is "close"...
|
||||
if (refresh != 60.0f && refresh > 50.0f && refresh < 70.0f) {
|
||||
SetInputSampleRate((int)(44100 * (refresh / 60.0f)));
|
||||
int input_sample_rate = (int)(44100 * (refresh / 60.0f));
|
||||
ILOG("StereoResampler: Adjusting target sample rate to %dHz", input_sample_rate);
|
||||
SetInputSampleRate(input_sample_rate);
|
||||
}
|
||||
|
||||
UpdateBufferSize();
|
||||
@ -273,16 +266,32 @@ void StereoResampler::PushSamples(const s32 *samples, unsigned int num_samples)
|
||||
lastPushSize_ = num_samples;
|
||||
}
|
||||
|
||||
void StereoResampler::GetAudioDebugStats(AudioDebugStats *stats) {
|
||||
stats->buffered = lastBufSize_;
|
||||
stats->underrunCount += underrunCount_;
|
||||
void StereoResampler::GetAudioDebugStats(char *buf, size_t bufSize) {
|
||||
snprintf(buf, bufSize,
|
||||
"Audio buffer: %d/%d (low watermark: %d)\n"
|
||||
"Underruns: %d\n"
|
||||
"Overruns: %d\n"
|
||||
"Sample rate: %d (input: %d)\n"
|
||||
"Push size: %d\n",
|
||||
lastBufSize_,
|
||||
m_bufsize * 2,
|
||||
m_lowwatermark,
|
||||
underrunCountTotal_,
|
||||
overrunCountTotal_,
|
||||
(int)sample_rate_,
|
||||
m_input_sample_rate,
|
||||
lastPushSize_);
|
||||
underrunCountTotal_ += underrunCount_;
|
||||
overrunCountTotal_ += overrunCount_;
|
||||
underrunCount_ = 0;
|
||||
stats->overrunCount += overrunCount_;
|
||||
overrunCount_ = 0;
|
||||
stats->watermark = m_lowwatermark;
|
||||
stats->bufsize = m_bufsize * 2;
|
||||
stats->instantSampleRate = (int)sample_rate_;
|
||||
stats->lastPushSize = lastPushSize_;
|
||||
}
|
||||
|
||||
void StereoResampler::ResetStatCounters() {
|
||||
underrunCount_ = 0;
|
||||
overrunCount_ = 0;
|
||||
underrunCountTotal_ = 0;
|
||||
overrunCountTotal_ = 0;
|
||||
}
|
||||
|
||||
void StereoResampler::SetInputSampleRate(unsigned int rate) {
|
||||
|
@ -42,7 +42,8 @@ public:
|
||||
|
||||
void DoState(PointerWrap &p);
|
||||
|
||||
void GetAudioDebugStats(AudioDebugStats *stats);
|
||||
void GetAudioDebugStats(char *buf, size_t bufSize);
|
||||
void ResetStatCounters();
|
||||
|
||||
protected:
|
||||
void UpdateBufferSize();
|
||||
@ -50,15 +51,17 @@ protected:
|
||||
|
||||
int m_bufsize;
|
||||
int m_lowwatermark;
|
||||
unsigned int m_input_sample_rate;
|
||||
unsigned int m_input_sample_rate = 44100;
|
||||
int16_t *m_buffer;
|
||||
volatile u32 m_indexW;
|
||||
volatile u32 m_indexR;
|
||||
float m_numLeftI;
|
||||
u32 m_frac;
|
||||
int underrunCount_;
|
||||
int overrunCount_;
|
||||
float sample_rate_;
|
||||
int lastBufSize_;
|
||||
int lastPushSize_;
|
||||
volatile u32 m_indexW = 0;
|
||||
volatile u32 m_indexR = 0;
|
||||
float m_numLeftI = 0.0f;
|
||||
u32 m_frac = 0;
|
||||
int underrunCount_ = 0;
|
||||
int overrunCount_ = 0;
|
||||
int underrunCountTotal_ = 0;
|
||||
int overrunCountTotal_ = 0;
|
||||
float sample_rate_ = 0.0;
|
||||
int lastBufSize_ = 0;
|
||||
int lastPushSize_ = 0;
|
||||
};
|
||||
|
@ -68,6 +68,8 @@ static int g_DesktopWidth = 0;
|
||||
static int g_DesktopHeight = 0;
|
||||
static float g_RefreshRate = 60.f;
|
||||
|
||||
static SDL_AudioSpec g_retFmt;
|
||||
|
||||
int getDisplayNumber(void) {
|
||||
int displayNumber = 0;
|
||||
char * displayNumberStr;
|
||||
@ -90,7 +92,7 @@ static SDL_AudioDeviceID audioDev = 0;
|
||||
|
||||
// Must be called after NativeInit().
|
||||
static void InitSDLAudioDevice(const std::string &name = "") {
|
||||
SDL_AudioSpec fmt, ret_fmt;
|
||||
SDL_AudioSpec fmt;
|
||||
memset(&fmt, 0, sizeof(fmt));
|
||||
fmt.freq = 44100;
|
||||
fmt.format = AUDIO_S16;
|
||||
@ -106,24 +108,25 @@ static void InitSDLAudioDevice(const std::string &name = "") {
|
||||
|
||||
audioDev = 0;
|
||||
if (!startDevice.empty()) {
|
||||
audioDev = SDL_OpenAudioDevice(startDevice.c_str(), 0, &fmt, &ret_fmt, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
|
||||
audioDev = SDL_OpenAudioDevice(startDevice.c_str(), 0, &fmt, &g_retFmt, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
|
||||
if (audioDev <= 0) {
|
||||
WLOG("Failed to open audio device: %s", startDevice.c_str());
|
||||
}
|
||||
}
|
||||
if (audioDev <= 0) {
|
||||
audioDev = SDL_OpenAudioDevice(nullptr, 0, &fmt, &ret_fmt, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
|
||||
ILOG("SDL: Trying a different device");
|
||||
audioDev = SDL_OpenAudioDevice(nullptr, 0, &fmt, &g_retFmt, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE);
|
||||
}
|
||||
if (audioDev <= 0) {
|
||||
ELOG("Failed to open audio: %s", SDL_GetError());
|
||||
} else {
|
||||
if (ret_fmt.samples != fmt.samples) // Notify, but still use it
|
||||
ELOG("Output audio samples: %d (requested: %d)", ret_fmt.samples, fmt.samples);
|
||||
if (ret_fmt.freq != fmt.freq || ret_fmt.format != fmt.format || ret_fmt.channels != fmt.channels) {
|
||||
if (g_retFmt.samples != fmt.samples) // Notify, but still use it
|
||||
ELOG("Output audio samples: %d (requested: %d)", g_retFmt.samples, fmt.samples);
|
||||
if (g_retFmt.freq != fmt.freq || g_retFmt.format != fmt.format || g_retFmt.channels != fmt.channels) {
|
||||
ELOG("Sound buffer format does not match requested format.");
|
||||
ELOG("Output audio freq: %d (requested: %d)", ret_fmt.freq, fmt.freq);
|
||||
ELOG("Output audio format: %d (requested: %d)", ret_fmt.format, fmt.format);
|
||||
ELOG("Output audio channels: %d (requested: %d)", ret_fmt.channels, fmt.channels);
|
||||
ELOG("Output audio freq: %d (requested: %d)", g_retFmt.freq, fmt.freq);
|
||||
ELOG("Output audio format: %d (requested: %d)", g_retFmt.format, fmt.format);
|
||||
ELOG("Output audio channels: %d (requested: %d)", g_retFmt.channels, fmt.channels);
|
||||
ELOG("Provided output format does not match requirement, turning audio off");
|
||||
SDL_CloseAudioDevice(audioDev);
|
||||
}
|
||||
@ -319,7 +322,9 @@ std::string System_GetProperty(SystemProperty prop) {
|
||||
int System_GetPropertyInt(SystemProperty prop) {
|
||||
switch (prop) {
|
||||
case SYSPROP_AUDIO_SAMPLE_RATE:
|
||||
return 44100;
|
||||
return g_retFmt.freq;
|
||||
case SYSPROP_AUDIO_FRAMES_PER_BUFFER:
|
||||
return g_retFmt.samples;
|
||||
case SYSPROP_DEVICE_TYPE:
|
||||
#if defined(MOBILE_DEVICE)
|
||||
return DEVICE_TYPE_MOBILE;
|
||||
|
@ -502,7 +502,7 @@ void SystemInfoScreen::CreateViews() {
|
||||
deviceSpecs->Add(new ItemHeader(si->T("OS Information")));
|
||||
deviceSpecs->Add(new InfoItem(si->T("Memory Page Size"), StringFromFormat(si->T("%d bytes"), GetMemoryProtectPageSize())));
|
||||
deviceSpecs->Add(new InfoItem(si->T("RW/RX exclusive"), PlatformIsWXExclusive() ? di->T("Active") : di->T("Inactive")));
|
||||
#ifdef ANDROID
|
||||
#if PPSSPP_PLATFORM(ANDROID)
|
||||
deviceSpecs->Add(new InfoItem(si->T("Sustained perf mode"), System_GetPropertyBool(SYSPROP_SUPPORTS_SUSTAINED_PERF_MODE) ? di->T("Supported") : di->T("Unsupported")));
|
||||
#endif
|
||||
|
||||
@ -512,14 +512,19 @@ void SystemInfoScreen::CreateViews() {
|
||||
#endif
|
||||
deviceSpecs->Add(new InfoItem(si->T("PPSSPP build"), build));
|
||||
|
||||
#ifdef __ANDROID__
|
||||
deviceSpecs->Add(new ItemHeader(si->T("Audio Information")));
|
||||
deviceSpecs->Add(new InfoItem(si->T("Sample rate"), StringFromFormat("%d Hz", System_GetPropertyInt(SYSPROP_AUDIO_SAMPLE_RATE))));
|
||||
deviceSpecs->Add(new InfoItem(si->T("Frames per buffer"), StringFromFormat("%d", System_GetPropertyInt(SYSPROP_AUDIO_FRAMES_PER_BUFFER))));
|
||||
int framesPerBuffer = System_GetPropertyInt(SYSPROP_AUDIO_FRAMES_PER_BUFFER);
|
||||
if (framesPerBuffer > 0) {
|
||||
deviceSpecs->Add(new InfoItem(si->T("Frames per buffer"), StringFromFormat("%d", framesPerBuffer)));
|
||||
}
|
||||
#if PPSSPP_PLATFORM(ANDROID)
|
||||
deviceSpecs->Add(new InfoItem(si->T("Optimal sample rate"), StringFromFormat("%d Hz", System_GetPropertyInt(SYSPROP_AUDIO_OPTIMAL_SAMPLE_RATE))));
|
||||
deviceSpecs->Add(new InfoItem(si->T("Optimal frames per buffer"), StringFromFormat("%d", System_GetPropertyInt(SYSPROP_AUDIO_OPTIMAL_FRAMES_PER_BUFFER))));
|
||||
#endif
|
||||
|
||||
deviceSpecs->Add(new ItemHeader(si->T("Display Information")));
|
||||
#if PPSSPP_PLATFORM(ANDROID)
|
||||
deviceSpecs->Add(new InfoItem(si->T("Native Resolution"), StringFromFormat("%dx%d",
|
||||
System_GetPropertyInt(SYSPROP_DISPLAY_XRES),
|
||||
System_GetPropertyInt(SYSPROP_DISPLAY_YRES))));
|
||||
|
@ -1265,19 +1265,8 @@ static void DrawDebugStats(DrawBuffer *draw2d, const Bounds &bounds) {
|
||||
|
||||
static void DrawAudioDebugStats(DrawBuffer *draw2d, const Bounds &bounds) {
|
||||
FontID ubuntu24("UBUNTU24");
|
||||
char statbuf[1024] = { 0 };
|
||||
const AudioDebugStats *stats = __AudioGetDebugStats();
|
||||
snprintf(statbuf, sizeof(statbuf),
|
||||
"Audio buffer: %d/%d (low watermark: %d)\n"
|
||||
"Underruns: %d\n"
|
||||
"Overruns: %d\n"
|
||||
"Sample rate: %d\n"
|
||||
"Push size: %d\n",
|
||||
stats->buffered, stats->bufsize, stats->watermark,
|
||||
stats->underrunCount,
|
||||
stats->overrunCount,
|
||||
stats->instantSampleRate,
|
||||
stats->lastPushSize);
|
||||
char statbuf[4096] = { 0 };
|
||||
__AudioGetDebugStats(statbuf, sizeof(statbuf));
|
||||
draw2d->SetFontScale(0.7f, 0.7f);
|
||||
draw2d->DrawTextRect(ubuntu24, statbuf, bounds.x + 11, bounds.y + 31, bounds.w - 20, bounds.h - 30, 0xc0000000, FLAG_DYNAMIC_ASCII | FLAG_WRAP_TEXT);
|
||||
draw2d->DrawTextRect(ubuntu24, statbuf, bounds.x + 10, bounds.y + 30, bounds.w - 20, bounds.h - 30, 0xFFFFFFFF, FLAG_DYNAMIC_ASCII | FLAG_WRAP_TEXT);
|
||||
|
Loading…
x
Reference in New Issue
Block a user