[Audio] Create settings class

This commit is contained in:
zilmar 2017-09-14 18:07:12 +10:00
parent 0e508ebc20
commit c395e8f55d
8 changed files with 158 additions and 115 deletions

View File

@ -109,6 +109,7 @@ EXPORT void CALL AiUpdate(int32_t /*Wait*/)
EXPORT void CALL CloseDLL(void)
{
WriteTrace(TraceAudioInterface, TraceDebug, "Called");
CleanupAudioSettings();
}
EXPORT void CALL DllAbout(void * /*hParent*/)
@ -159,7 +160,7 @@ EXPORT void CALL RomOpen()
WriteTrace(TraceAudioInterface, TraceDebug, "Start");
if (g_SoundDriver)
{
g_SoundDriver->AI_SetFrequency(DEFAULT_FREQUENCY);
g_SoundDriver->AI_Startup();
}
WriteTrace(TraceAudioInterface, TraceDebug, "Done");
}

View File

@ -3,30 +3,9 @@
* Project64-audio - A Nintendo 64 audio plugin. *
* http://www.pj64-emu.com/ *
* Copyright (C) 2017 Project64. All rights reserved. *
* Copyright (C) 2008-2012 Tillin9, Richard42 *
* *
* License: *
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#pragma once
/* Default start-time size of primary buffer (in equivalent output samples).
This is the buffer where audio is loaded after it's extracted from n64's memory. */
enum { PRIMARY_BUFFER_SIZE = 16384 };
/* Size of a single secondary buffer, in output samples. This is the requested size of OpenSLES's
hardware buffer, this should be a power of two. */
enum { SECONDARY_BUFFER_SIZE = 1024 };
/* This is the requested number of OpenSLES's hardware buffers */
enum { SECONDARY_BUFFER_NBR = 2 };
/* This sets default frequency what is used if rom doesn't want to change it.
Probably only game that needs this is Zelda: Ocarina Of Time Master Quest
*NOTICE* We should try to find out why Demos' frequencies are always wrong
They tend to rely on a default frequency, apparently, never the same one ;) */
enum { DEFAULT_FREQUENCY = 33600 };
extern bool g_SwapChannels;
extern uint32_t g_GameFreq;
#pragma once

View File

@ -8,40 +8,88 @@
* GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html *
* *
****************************************************************************/
#include <Settings/Settings.h>
#include <Project64-audio/trace.h>
#include "SettingsID.h"
#include "AudioSettings.h"
#include "trace.h"
#include "AudioMain.h"
short Set_EnableAudio = 0;
extern bool g_AudioEnabled;
CSettings * g_settings = NULL;
void SettingsChanged(void *)
CSettings::CSettings() :
m_Set_EnableAudio(0),
m_Set_basic_mode(0),
m_Set_debugger(0),
m_Set_log_dir(0),
m_Set_log_flush(0),
m_FlushLogs(false),
m_AudioEnabled(true),
m_advanced_options(false),
m_debugger_enabled(false)
{
g_AudioEnabled = GetSystemSetting(Set_EnableAudio) != 0;
memset(m_log_dir, 0, sizeof(m_log_dir));
RegisterSettings();
ReadSettings();
}
CSettings::~CSettings()
{
}
void CSettings::RegisterSettings(void)
{
SetModuleName("default");
m_Set_EnableAudio = FindSystemSettingId("Enable Audio");
m_Set_basic_mode = FindSystemSettingId("Basic Mode");
m_Set_debugger = FindSystemSettingId("Debugger");
m_Set_log_flush = FindSystemSettingId("Log Auto Flush");
m_Set_log_dir = FindSystemSettingId("Dir:Log");
SetModuleName("Project64-Audio");
RegisterSetting(Set_Logging_MD5, Data_DWORD_General, "MD5", "Logging", g_ModuleLogLevel[TraceMD5], NULL);
RegisterSetting(Set_Logging_Thread, Data_DWORD_General, "Thread", "Logging", g_ModuleLogLevel[TraceThread], NULL);
RegisterSetting(Set_Logging_Path, Data_DWORD_General, "Path", "Logging", g_ModuleLogLevel[TracePath], NULL);
RegisterSetting(Set_Logging_InitShutdown, Data_DWORD_General, "InitShutdown", "Logging", g_ModuleLogLevel[TraceAudioInitShutdown], NULL);
RegisterSetting(Set_Logging_Interface, Data_DWORD_General, "Interface", "Logging", g_ModuleLogLevel[TraceAudioInterface], NULL);
RegisterSetting(Set_Logging_Driver, Data_DWORD_General, "Driver", "Logging", g_ModuleLogLevel[TraceAudioDriver], NULL);
LogLevelChanged();
}
void CSettings::ReadSettings()
{
m_AudioEnabled = m_Set_EnableAudio ? GetSystemSetting(m_Set_EnableAudio) != 0 : true;
m_advanced_options = m_Set_basic_mode ? GetSystemSetting(m_Set_basic_mode) == 0 : false;
m_debugger_enabled = m_advanced_options && m_Set_debugger ? GetSystemSetting(m_Set_debugger) == 1 : false;
if (m_Set_log_dir != 0)
{
GetSystemSettingSz(m_Set_log_dir, m_log_dir, sizeof(m_log_dir));
}
m_FlushLogs = m_Set_log_flush != 0 ? GetSystemSetting(m_Set_log_flush) != 0 : false;
}
void CSettings::LogLevelChanged(void)
{
g_ModuleLogLevel[TraceMD5] = GetSetting(Set_Logging_MD5);
g_ModuleLogLevel[TraceThread] = GetSetting(Set_Logging_Thread);
g_ModuleLogLevel[TracePath] = GetSetting(Set_Logging_Path);
g_ModuleLogLevel[TraceAudioInitShutdown] = GetSetting(Set_Logging_InitShutdown);
g_ModuleLogLevel[TraceAudioInterface] = GetSetting(Set_Logging_Interface);
g_ModuleLogLevel[TraceAudioDriver] = GetSetting(Set_Logging_Driver);
}
void SetupAudioSettings(void)
{
SetModuleName("AndroidAudio");
RegisterSetting(Output_SwapChannels, Data_DWORD_General, "SwapChannels", "", 0, NULL);
RegisterSetting(Output_DefaultFrequency, Data_DWORD_General, "DefaultFrequency", "", DEFAULT_FREQUENCY, NULL);
RegisterSetting(Buffer_PrimarySize, Data_DWORD_General, "BufferPrimarySize", "", PRIMARY_BUFFER_SIZE, NULL);
RegisterSetting(Buffer_SecondarySize, Data_DWORD_General, "BufferSecondarySize", "", SECONDARY_BUFFER_SIZE, NULL);
RegisterSetting(Buffer_SecondaryNbr, Data_DWORD_General, "BufferSecondaryNbr", "", SECONDARY_BUFFER_NBR, NULL);
RegisterSetting(Logging_LogAudioInitShutdown, Data_DWORD_General, "AudioInitShutdown", "Logging", g_ModuleLogLevel[TraceAudioInitShutdown], NULL);
RegisterSetting(Logging_LogAudioInterface, Data_DWORD_General, "AudioInterface", "Logging", g_ModuleLogLevel[TraceAudioInterface], NULL);
g_SwapChannels = GetSetting(Output_SwapChannels) != 0;
g_GameFreq = GetSetting(Output_DefaultFrequency);
g_ModuleLogLevel[TraceAudioInitShutdown] = GetSetting(Logging_LogAudioInitShutdown);
g_ModuleLogLevel[TraceAudioInterface] = GetSetting(Logging_LogAudioInterface);
Set_EnableAudio = FindSystemSettingId("Enable Audio");
if (Set_EnableAudio != 0)
if (g_settings == NULL)
{
SettingsRegisterChange(true, Set_EnableAudio, NULL, SettingsChanged);
g_AudioEnabled = GetSystemSetting(Set_EnableAudio) != 0;
g_settings = new CSettings;
}
}
void CleanupAudioSettings(void)
{
if (g_settings)
{
delete g_settings;
g_settings = NULL;
}
}

View File

@ -9,6 +9,37 @@
* *
****************************************************************************/
#pragma once
#include <Settings/Settings.h>
void SetupAudioSettings(void);
class CSettings
{
public:
CSettings();
~CSettings();
inline bool AudioEnabled(void) const { return m_AudioEnabled; }
inline bool debugger_enabled(void) const { return m_debugger_enabled; }
inline bool FlushLogs(void) const { return m_FlushLogs; }
inline const char * log_dir(void) const { return m_log_dir; }
void ReadSettings();
private:
void RegisterSettings(void);
void LogLevelChanged(void);
short m_Set_EnableAudio;
short m_Set_basic_mode;
short m_Set_debugger;
short m_Set_log_dir;
short m_Set_log_flush;
char m_log_dir[260];
bool m_FlushLogs;
bool m_AudioEnabled;
bool m_advanced_options;
bool m_debugger_enabled;
};
extern CSettings * g_settings;
void SetupAudioSettings(void);
void CleanupAudioSettings(void);

View File

@ -33,6 +33,23 @@ typedef struct threadLock_
} threadLock;
#endif
/* Default start-time size of primary buffer (in equivalent output samples).
This is the buffer where audio is loaded after it's extracted from n64's memory. */
enum { PRIMARY_BUFFER_SIZE = 16384 };
/* Size of a single secondary buffer, in output samples. This is the requested size of OpenSLES's
hardware buffer, this should be a power of two. */
enum { SECONDARY_BUFFER_SIZE = 1024 };
/* This is the requested number of OpenSLES's hardware buffers */
enum { SECONDARY_BUFFER_NBR = 2 };
/* This sets default frequency what is used if rom doesn't want to change it.
Probably only game that needs this is Zelda: Ocarina Of Time Master Quest
*NOTICE* We should try to find out why Demos' frequencies are always wrong
They tend to rely on a default frequency, apparently, never the same one ;) */
enum { DEFAULT_FREQUENCY = 33600 };
/* number of bytes per sample */
enum
{
@ -46,36 +63,24 @@ uint8_t * g_primaryBuffer = NULL;
/* Size of the primary buffer */
uint32_t g_primaryBufferBytes = 0;
/* Size of the primary audio buffer in equivalent output samples */
unsigned int g_PrimaryBufferSize = PRIMARY_BUFFER_SIZE;
/* Pointer to secondary buffers */
uint8_t ** g_secondaryBuffers = NULL;
/* Size of a single secondary buffer */
uint32_t g_secondaryBufferBytes = 0;
/* Size of a single secondary audio buffer in output samples */
uint32_t g_SecondaryBufferSize = SECONDARY_BUFFER_SIZE;
/* Position in the primary buffer where next audio chunk should be placed */
uint32_t g_primaryBufferPos = 0;
/* Index of the next secondary buffer available */
uint32_t g_secondaryBufferIndex = 0;
/* Number of secondary buffers */
uint32_t g_SecondaryBufferNbr = SECONDARY_BUFFER_NBR;
/* Audio frequency, this is usually obtained from the game, but for compatibility we set default value */
uint32_t g_GameFreq = DEFAULT_FREQUENCY;
/* SpeedFactor is used to increase/decrease game playback speed */
uint32_t g_speed_factor = 100;
/* If this is true then left and right channels are swapped */
bool g_SwapChannels = false;
/* Output Audio frequency */
int g_OutputFreq = 44100;
@ -104,7 +109,7 @@ SLAndroidSimpleBufferQueueItf g_bufferQueue = NULL;
static bool CreatePrimaryBuffer(void)
{
WriteTrace(TraceAudioInitShutdown, TraceDebug, "Start");
unsigned int primaryBytes = (unsigned int)(g_PrimaryBufferSize * N64_SAMPLE_BYTES);
unsigned int primaryBytes = (unsigned int)(PRIMARY_BUFFER_SIZE * N64_SAMPLE_BYTES);
WriteTrace(TraceAudioInitShutdown, TraceDebug, "Allocating memory for primary audio buffer: %i bytes.", primaryBytes);
@ -141,7 +146,7 @@ static void CloseAudio(void)
/* Delete Secondary buffers */
if (g_secondaryBuffers != NULL)
{
for (uint32_t i = 0; i < g_SecondaryBufferNbr; i++)
for (uint32_t i = 0; i < SECONDARY_BUFFER_NBR; i++)
{
if (g_secondaryBuffers[i] != NULL)
{
@ -201,12 +206,12 @@ static bool CreateSecondaryBuffers(void)
{
WriteTrace(TraceAudioInitShutdown, TraceDebug, "Start");
bool status = true;
unsigned int secondaryBytes = (unsigned int)(g_SecondaryBufferSize * SLES_SAMPLE_BYTES);
unsigned int secondaryBytes = (unsigned int)(SECONDARY_BUFFER_SIZE * SLES_SAMPLE_BYTES);
WriteTrace(TraceAudioInitShutdown, TraceDebug, "Allocating memory for %d secondary audio buffers: %i bytes.", g_SecondaryBufferNbr, secondaryBytes);
WriteTrace(TraceAudioInitShutdown, TraceDebug, "Allocating memory for %d secondary audio buffers: %i bytes.", SECONDARY_BUFFER_NBR, secondaryBytes);
/* Allocate number of secondary buffers */
g_secondaryBuffers = new uint8_t *[g_SecondaryBufferNbr];
g_secondaryBuffers = new uint8_t *[SECONDARY_BUFFER_NBR];
if (g_secondaryBuffers == NULL)
{
@ -216,7 +221,7 @@ static bool CreateSecondaryBuffers(void)
}
/* Allocate size of each secondary buffers */
for (uint32_t i = 0; i < g_SecondaryBufferNbr; i++)
for (uint32_t i = 0; i < SECONDARY_BUFFER_NBR; i++)
{
g_secondaryBuffers[i] = new uint8_t[secondaryBytes];
@ -389,7 +394,7 @@ void OpenSLESDriver::AI_SetFrequency(uint32_t freq)
{
g_OutputFreq = 11025;
sample_rate = SL_SAMPLINGRATE_11_025;
}
}
else if ((freq / 1000) <= 22)
{
g_OutputFreq = 22050;
@ -409,11 +414,6 @@ void OpenSLESDriver::AI_SetFrequency(uint32_t freq)
WriteTrace(TraceAudioInitShutdown, TraceInfo, "Requesting frequency: %iHz.", g_OutputFreq);
/* reload these because they gets re-assigned from data below, and InitializeAudio can be called more than once */
g_PrimaryBufferSize = GetSetting(Buffer_PrimarySize);
g_SecondaryBufferSize = GetSetting(Buffer_SecondarySize);
g_SecondaryBufferNbr = GetSetting(Buffer_SecondaryNbr);
/* Close everything because InitializeAudio can be called more than once */
CloseAudio();
@ -456,7 +456,7 @@ void OpenSLESDriver::AI_SetFrequency(uint32_t freq)
return;
}
pthread_mutex_lock(&(g_lock.mutex));
g_lock.value = g_lock.limit = g_SecondaryBufferNbr;
g_lock.value = g_lock.limit = SECONDARY_BUFFER_NBR;
pthread_mutex_unlock(&(g_lock.mutex));
/* Engine object */
@ -505,7 +505,7 @@ void OpenSLESDriver::AI_SetFrequency(uint32_t freq)
if (result == SL_RESULT_SUCCESS)
{
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, g_SecondaryBufferNbr };
SLDataLocator_AndroidSimpleBufferQueue loc_bufq = { SL_DATALOCATOR_ANDROIDSIMPLEBUFFERQUEUE, SECONDARY_BUFFER_NBR };
SLDataFormat_PCM format_pcm = { SL_DATAFORMAT_PCM,2, sample_rate, SL_PCMSAMPLEFORMAT_FIXED_16, SL_PCMSAMPLEFORMAT_FIXED_16,
(SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT), SL_BYTEORDER_LITTLEENDIAN };
@ -584,7 +584,12 @@ void OpenSLESDriver::AI_SetFrequency(uint32_t freq)
}
#endif
WriteTrace(TraceAudioInitShutdown, TraceNotice, "Done");
}
}
void OpenSLESDriver::AI_Startup(void)
{
AI_SetFrequency(DEFAULT_FREQUENCY);
}
void OpenSLESDriver::AI_Shutdown(void)
{
@ -601,26 +606,13 @@ void OpenSLESDriver::AI_LenChanged(uint8_t *start, uint32_t length)
for (i = 0; i < length; i += 4)
{
if (g_SwapChannels == 0)
{
/* Left channel */
g_primaryBuffer[g_primaryBufferPos + i] = start[i + 2];
g_primaryBuffer[g_primaryBufferPos + i + 1] = start[i + 3];
/* Left channel */
g_primaryBuffer[g_primaryBufferPos + i] = start[i + 2];
g_primaryBuffer[g_primaryBufferPos + i + 1] = start[i + 3];
/* Right channel */
g_primaryBuffer[g_primaryBufferPos + i + 2] = start[i];
g_primaryBuffer[g_primaryBufferPos + i + 3] = start[i + 1];
}
else
{
/* Left channel */
g_primaryBuffer[g_primaryBufferPos + i] = start[i];
g_primaryBuffer[g_primaryBufferPos + i + 1] = start[i + 1];
/* Right channel */
g_primaryBuffer[g_primaryBufferPos + i + 2] = start[i + 2];
g_primaryBuffer[g_primaryBufferPos + i + 3] = start[i + 3];
}
/* Right channel */
g_primaryBuffer[g_primaryBufferPos + i + 2] = start[i];
g_primaryBuffer[g_primaryBufferPos + i + 3] = start[i + 1];
}
g_primaryBufferPos += i;
}
@ -665,7 +657,7 @@ void OpenSLESDriver::AI_LenChanged(uint8_t *start, uint32_t length)
g_secondaryBufferIndex++;
if (g_secondaryBufferIndex > (g_SecondaryBufferNbr - 1))
if (g_secondaryBufferIndex > (SECONDARY_BUFFER_NBR - 1))
{
g_secondaryBufferIndex = 0;
}

View File

@ -23,6 +23,7 @@ class OpenSLESDriver :
public SoundDriverBase
{
public:
void AI_Startup(void);
void AI_Shutdown(void);
void AI_SetFrequency(uint32_t freq);
void AI_LenChanged(uint8_t *start, uint32_t length);

View File

@ -13,11 +13,10 @@
enum
{
Logging_LogAudioInitShutdown,
Logging_LogAudioInterface,
Output_SwapChannels,
Output_DefaultFrequency,
Buffer_PrimarySize,
Buffer_SecondarySize,
Buffer_SecondaryNbr,
Set_Logging_MD5,
Set_Logging_Thread,
Set_Logging_Path,
Set_Logging_InitShutdown,
Set_Logging_Interface,
Set_Logging_Driver,
};

View File

@ -66,16 +66,8 @@ void SetupTrace(void)
void StartTrace(void)
{
char log_dir[260];
memset(log_dir, 0, sizeof(log_dir));
short logDirSetting = FindSystemSettingId("Dir:Log");
short logFlushSetting = FindSystemSettingId("Log Auto Flush");
if (logDirSetting != 0)
{
GetSystemSettingSz(logDirSetting, log_dir, sizeof(log_dir));
}
if (strlen(log_dir) == 0)
const char * log_dir = g_settings ? g_settings->log_dir() : NULL;
if (log_dir == NULL || log_dir[0] == '\0')
{
return;
}
@ -85,6 +77,6 @@ void StartTrace(void)
{
LogFilePath.DirectoryCreate();
}
g_LogFile = new CTraceFileLog(LogFilePath, GetSystemSetting(logFlushSetting) != 0, CLog::Log_New, 500);
g_LogFile = new CTraceFileLog(LogFilePath, g_settings->FlushLogs(), CLog::Log_New, 500);
TraceAddModule(g_LogFile);
}