mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-12 01:30:49 +01:00
Add simple channel downmixer to play >8ch files
This commit is contained in:
parent
fb63ad4aae
commit
eebc83a0c8
@ -23,6 +23,7 @@ LANGUAGE LANG_ENGLISH, SUBLANG_NEUTRAL
|
||||
//
|
||||
// Dialog
|
||||
//
|
||||
//elements: text, id, x, y, width, height [, style [, extended-style]]
|
||||
|
||||
IDD_CONFIG DIALOGEX 0, 0, 187, 156
|
||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
|
||||
@ -40,6 +41,8 @@ BEGIN
|
||||
CONTROL "Loop forever",IDC_LOOP_FOREVER,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,7,70,77,10
|
||||
CONTROL "Ignore looping",IDC_IGNORE_LOOP,"Button",BS_AUTORADIOBUTTON | WS_TABSTOP,7,83,77,10
|
||||
CONTROL "Disable subsongs",IDC_DISABLE_SUBSONGS,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,99,87,10
|
||||
LTEXT "Downmix",IDC_STATIC,7,115,48,12
|
||||
EDITTEXT IDC_DOWNMIX_CHANNELS,52,112,37,14,ES_AUTOHSCROLL
|
||||
END
|
||||
|
||||
|
||||
|
@ -20,6 +20,7 @@ static const GUID guid_cfg_LoopCount = { 0xfc8dfd72, 0xfae8, 0x44cc, { 0xbe, 0x9
|
||||
static const GUID guid_cfg_FadeLength = { 0x61da7ef1, 0x56a5, 0x4368, { 0xae, 0x6, 0xec, 0x6f, 0xd7, 0xe6, 0x15, 0x5d } };
|
||||
static const GUID guid_cfg_FadeDelay = { 0x73907787, 0xaf49, 0x4659, { 0x96, 0x8e, 0x9f, 0x70, 0xa1, 0x62, 0x49, 0xc4 } };
|
||||
static const GUID guid_cfg_DisableSubsongs = { 0xa8cdd664, 0xb32b, 0x4a36, { 0x83, 0x07, 0xa0, 0x4c, 0xcd, 0x52, 0xa3, 0x7c } };
|
||||
static const GUID guid_cfg_DownmixChannels = { 0x5a0e65dd, 0xeb37, 0x4c67, { 0x9a, 0xb1, 0x3f, 0xb0, 0xc9, 0x7e, 0xb0, 0xe0 } };
|
||||
|
||||
static cfg_bool cfg_LoopForever(guid_cfg_LoopForever, DEFAULT_LOOP_FOREVER);
|
||||
static cfg_bool cfg_IgnoreLoop(guid_cfg_IgnoreLoop, DEFAULT_IGNORE_LOOP);
|
||||
@ -27,6 +28,7 @@ static cfg_string cfg_LoopCount(guid_cfg_LoopCount, DEFAULT_LOOP_COUNT);
|
||||
static cfg_string cfg_FadeLength(guid_cfg_FadeLength, DEFAULT_FADE_SECONDS);
|
||||
static cfg_string cfg_FadeDelay(guid_cfg_FadeDelay, DEFAULT_FADE_DELAY_SECONDS);
|
||||
static cfg_bool cfg_DisableSubsongs(guid_cfg_DisableSubsongs, DEFAULT_DISABLE_SUBSONGS);
|
||||
static cfg_string cfg_DownmixChannels(guid_cfg_DownmixChannels, DEFAULT_DOWNMIX_CHANNELS);
|
||||
|
||||
// Needs to be here in rder to access the static config
|
||||
void input_vgmstream::load_settings()
|
||||
@ -38,6 +40,7 @@ void input_vgmstream::load_settings()
|
||||
loop_forever = cfg_LoopForever;
|
||||
ignore_loop = cfg_IgnoreLoop;
|
||||
disable_subsongs = cfg_DisableSubsongs;
|
||||
sscanf(cfg_DownmixChannels.get_ptr(),"%d",&downmix_channels);
|
||||
}
|
||||
|
||||
const char * vgmstream_prefs::get_name()
|
||||
@ -70,6 +73,8 @@ BOOL vgmstreamPreferences::OnInitDialog(CWindow, LPARAM)
|
||||
|
||||
CheckDlgButton(IDC_DISABLE_SUBSONGS, cfg_DisableSubsongs?BST_CHECKED:BST_UNCHECKED);
|
||||
|
||||
uSetDlgItemText(m_hWnd, IDC_DOWNMIX_CHANNELS, cfg_DownmixChannels);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@ -93,6 +98,8 @@ void vgmstreamPreferences::reset()
|
||||
uSetDlgItemText(m_hWnd, IDC_FADE_DELAY_SECONDS, DEFAULT_FADE_DELAY_SECONDS);
|
||||
|
||||
CheckDlgButton(IDC_DISABLE_SUBSONGS, DEFAULT_DISABLE_SUBSONGS?BST_CHECKED:BST_UNCHECKED);
|
||||
|
||||
uSetDlgItemText(m_hWnd, IDC_DOWNMIX_CHANNELS, DEFAULT_DOWNMIX_CHANNELS);
|
||||
}
|
||||
|
||||
|
||||
@ -107,6 +114,7 @@ void vgmstreamPreferences::apply()
|
||||
double temp_fade_delay_seconds;
|
||||
double temp_loop_count;
|
||||
int consumed;
|
||||
int temp_downmix_channels;
|
||||
|
||||
pfc::string buf;
|
||||
buf = uGetDlgItemText(m_hWnd, IDC_FADE_SECONDS);
|
||||
@ -141,6 +149,18 @@ void vgmstreamPreferences::apply()
|
||||
"Error",MB_OK|MB_ICONERROR);
|
||||
return;
|
||||
} else cfg_FadeDelay = buf.get_ptr();
|
||||
|
||||
buf = uGetDlgItemText(m_hWnd, IDC_DOWNMIX_CHANNELS);
|
||||
if (sscanf(buf.get_ptr(),"%d%n",&temp_downmix_channels,&consumed)<1
|
||||
|| consumed!=strlen(buf.get_ptr()) ||
|
||||
temp_downmix_channels<0) {
|
||||
uMessageBox(m_hWnd,
|
||||
"Invalid value for Downmix Channels\n"
|
||||
"Must be a number greater than or equal to zero",
|
||||
"Error",MB_OK|MB_ICONERROR);
|
||||
return;
|
||||
} else cfg_DownmixChannels = buf.get_ptr();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -166,6 +186,9 @@ bool vgmstreamPreferences::HasChanged()
|
||||
if(FadeDelay != uGetDlgItemText(m_hWnd, IDC_FADE_DELAY_SECONDS)) return true;
|
||||
if(LoopCount != uGetDlgItemText(m_hWnd, IDC_LOOP_COUNT)) return true;
|
||||
|
||||
pfc::string DownmixChannels(cfg_DownmixChannels);
|
||||
if(DownmixChannels != uGetDlgItemText(m_hWnd, IDC_DOWNMIX_CHANNELS)) return true;
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
#define DEFAULT_LOOP_FOREVER false
|
||||
#define DEFAULT_IGNORE_LOOP false
|
||||
#define DEFAULT_DISABLE_SUBSONGS false
|
||||
#define DEFAULT_DOWNMIX_CHANNELS "8"
|
||||
|
||||
class vgmstreamPreferences : public CDialogImpl<vgmstreamPreferences>, public preferences_page_instance {
|
||||
public:
|
||||
@ -42,6 +43,7 @@ public:
|
||||
COMMAND_HANDLER_EX(IDC_FADE_DELAY_SECONDS, EN_CHANGE, OnEditChange)
|
||||
COMMAND_HANDLER_EX(IDC_LOOP_COUNT, EN_CHANGE, OnEditChange)
|
||||
COMMAND_HANDLER_EX(IDC_DISABLE_SUBSONGS, BN_CLICKED, OnEditChange)
|
||||
COMMAND_HANDLER_EX(IDC_DOWNMIX_CHANNELS, EN_CHANGE, OnEditChange)
|
||||
END_MSG_MAP()
|
||||
private:
|
||||
BOOL OnInitDialog(CWindow, LPARAM);
|
||||
|
@ -56,6 +56,7 @@ input_vgmstream::input_vgmstream() {
|
||||
loop_forever = false;
|
||||
ignore_loop = 0;
|
||||
disable_subsongs = false;
|
||||
downmix_channels = 0;
|
||||
|
||||
load_settings();
|
||||
}
|
||||
@ -228,8 +229,38 @@ bool input_vgmstream::decode_run(audio_chunk & p_chunk,abort_callback & p_abort)
|
||||
}
|
||||
}
|
||||
|
||||
/* downmix enabled (foobar refuses to do more than 8 channels) */
|
||||
if (downmix_channels > 0 && downmix_channels < vgmstream->channels) {
|
||||
short temp_buffer[OUTBUF_SIZE];
|
||||
int s, ch;
|
||||
|
||||
for (s = 0; s < samples_to_do; s++) {
|
||||
/* copy channels up to max */
|
||||
for (ch = 0; ch < downmix_channels; ch++) {
|
||||
temp_buffer[s*downmix_channels + ch] = sample_buffer[s*vgmstream->channels + ch];
|
||||
}
|
||||
/* then mix the rest */
|
||||
for (ch = downmix_channels; ch < vgmstream->channels; ch++) {
|
||||
int downmix_ch = ch % downmix_channels;
|
||||
int new_sample = ((int)temp_buffer[s*downmix_channels + downmix_ch] + (int)sample_buffer[s*vgmstream->channels + ch]);
|
||||
new_sample = (int)(new_sample * 0.7); /* limit clipping without removing too much loudness... hopefully */
|
||||
if (new_sample > 32767) new_sample = 32767;
|
||||
else if (new_sample < -32768) new_sample = -32768;
|
||||
temp_buffer[s*downmix_channels + downmix_ch] = (short)new_sample;
|
||||
}
|
||||
}
|
||||
|
||||
/* copy back to global buffer... in case of multithreading stuff? */
|
||||
memcpy(sample_buffer,temp_buffer, samples_to_do*downmix_channels*sizeof(short));
|
||||
|
||||
bytes = (samples_to_do*downmix_channels * sizeof(sample_buffer[0]));
|
||||
p_chunk.set_data_fixedpoint((char*)sample_buffer, bytes, vgmstream->sample_rate, downmix_channels, 16, audio_chunk::g_guess_channel_config(downmix_channels));
|
||||
}
|
||||
else {
|
||||
bytes = (samples_to_do*vgmstream->channels * sizeof(sample_buffer[0]));
|
||||
p_chunk.set_data_fixedpoint((char*)sample_buffer, bytes, vgmstream->sample_rate, vgmstream->channels, 16, audio_chunk::g_guess_channel_config(vgmstream->channels));
|
||||
}
|
||||
|
||||
|
||||
decode_pos_samples+=samples_to_do;
|
||||
decode_pos_ms=decode_pos_samples*1000LL/vgmstream->sample_rate;
|
||||
@ -407,7 +438,10 @@ void input_vgmstream::get_subsong_info(t_uint32 p_subsong, pfc::string_base & ti
|
||||
title.set_string(p, e - p);
|
||||
|
||||
if (!disable_subsongs && infostream && infostream->num_streams > 1) {
|
||||
sprintf(temp,"#%d",infostream->stream_index);
|
||||
int info_subsong = infostream->stream_index;
|
||||
if (info_subsong==0)
|
||||
info_subsong = 1;
|
||||
sprintf(temp,"#%d",info_subsong);
|
||||
title += temp;
|
||||
|
||||
if (infostream->stream_name[0] != '\0') {
|
||||
|
@ -61,6 +61,7 @@ class input_vgmstream : public input_stubs {
|
||||
bool force_ignore_loop;
|
||||
int ignore_loop;
|
||||
bool disable_subsongs;
|
||||
int downmix_channels;
|
||||
|
||||
/* helpers */
|
||||
VGMSTREAM * init_vgmstream_foo(t_uint32 p_subsong, const char * const filename, abort_callback & p_abort);
|
||||
|
@ -14,6 +14,7 @@
|
||||
#define IDC_THREAD_PRIORITY_TEXT 1007
|
||||
#define IDC_DEFAULT_BUTTON 1008
|
||||
#define IDC_DISABLE_SUBSONGS 1009
|
||||
#define IDC_DOWNMIX_CHANNELS 1010
|
||||
|
||||
// Next default values for new objects
|
||||
//
|
||||
|
Loading…
Reference in New Issue
Block a user