mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-09-24 03:08:21 +02: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
|
// Dialog
|
||||||
//
|
//
|
||||||
|
//elements: text, id, x, y, width, height [, style [, extended-style]]
|
||||||
|
|
||||||
IDD_CONFIG DIALOGEX 0, 0, 187, 156
|
IDD_CONFIG DIALOGEX 0, 0, 187, 156
|
||||||
STYLE DS_SETFONT | DS_FIXEDSYS | WS_CHILD
|
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 "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 "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
|
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
|
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_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_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_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_LoopForever(guid_cfg_LoopForever, DEFAULT_LOOP_FOREVER);
|
||||||
static cfg_bool cfg_IgnoreLoop(guid_cfg_IgnoreLoop, DEFAULT_IGNORE_LOOP);
|
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_FadeLength(guid_cfg_FadeLength, DEFAULT_FADE_SECONDS);
|
||||||
static cfg_string cfg_FadeDelay(guid_cfg_FadeDelay, DEFAULT_FADE_DELAY_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_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
|
// Needs to be here in rder to access the static config
|
||||||
void input_vgmstream::load_settings()
|
void input_vgmstream::load_settings()
|
||||||
@ -38,6 +40,7 @@ void input_vgmstream::load_settings()
|
|||||||
loop_forever = cfg_LoopForever;
|
loop_forever = cfg_LoopForever;
|
||||||
ignore_loop = cfg_IgnoreLoop;
|
ignore_loop = cfg_IgnoreLoop;
|
||||||
disable_subsongs = cfg_DisableSubsongs;
|
disable_subsongs = cfg_DisableSubsongs;
|
||||||
|
sscanf(cfg_DownmixChannels.get_ptr(),"%d",&downmix_channels);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char * vgmstream_prefs::get_name()
|
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);
|
CheckDlgButton(IDC_DISABLE_SUBSONGS, cfg_DisableSubsongs?BST_CHECKED:BST_UNCHECKED);
|
||||||
|
|
||||||
|
uSetDlgItemText(m_hWnd, IDC_DOWNMIX_CHANNELS, cfg_DownmixChannels);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -93,6 +98,8 @@ void vgmstreamPreferences::reset()
|
|||||||
uSetDlgItemText(m_hWnd, IDC_FADE_DELAY_SECONDS, DEFAULT_FADE_DELAY_SECONDS);
|
uSetDlgItemText(m_hWnd, IDC_FADE_DELAY_SECONDS, DEFAULT_FADE_DELAY_SECONDS);
|
||||||
|
|
||||||
CheckDlgButton(IDC_DISABLE_SUBSONGS, DEFAULT_DISABLE_SUBSONGS?BST_CHECKED:BST_UNCHECKED);
|
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_fade_delay_seconds;
|
||||||
double temp_loop_count;
|
double temp_loop_count;
|
||||||
int consumed;
|
int consumed;
|
||||||
|
int temp_downmix_channels;
|
||||||
|
|
||||||
pfc::string buf;
|
pfc::string buf;
|
||||||
buf = uGetDlgItemText(m_hWnd, IDC_FADE_SECONDS);
|
buf = uGetDlgItemText(m_hWnd, IDC_FADE_SECONDS);
|
||||||
@ -141,6 +149,18 @@ void vgmstreamPreferences::apply()
|
|||||||
"Error",MB_OK|MB_ICONERROR);
|
"Error",MB_OK|MB_ICONERROR);
|
||||||
return;
|
return;
|
||||||
} else cfg_FadeDelay = buf.get_ptr();
|
} 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(FadeDelay != uGetDlgItemText(m_hWnd, IDC_FADE_DELAY_SECONDS)) return true;
|
||||||
if(LoopCount != uGetDlgItemText(m_hWnd, IDC_LOOP_COUNT)) 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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#define DEFAULT_LOOP_FOREVER false
|
#define DEFAULT_LOOP_FOREVER false
|
||||||
#define DEFAULT_IGNORE_LOOP false
|
#define DEFAULT_IGNORE_LOOP false
|
||||||
#define DEFAULT_DISABLE_SUBSONGS false
|
#define DEFAULT_DISABLE_SUBSONGS false
|
||||||
|
#define DEFAULT_DOWNMIX_CHANNELS "8"
|
||||||
|
|
||||||
class vgmstreamPreferences : public CDialogImpl<vgmstreamPreferences>, public preferences_page_instance {
|
class vgmstreamPreferences : public CDialogImpl<vgmstreamPreferences>, public preferences_page_instance {
|
||||||
public:
|
public:
|
||||||
@ -42,6 +43,7 @@ public:
|
|||||||
COMMAND_HANDLER_EX(IDC_FADE_DELAY_SECONDS, EN_CHANGE, OnEditChange)
|
COMMAND_HANDLER_EX(IDC_FADE_DELAY_SECONDS, EN_CHANGE, OnEditChange)
|
||||||
COMMAND_HANDLER_EX(IDC_LOOP_COUNT, 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_DISABLE_SUBSONGS, BN_CLICKED, OnEditChange)
|
||||||
|
COMMAND_HANDLER_EX(IDC_DOWNMIX_CHANNELS, EN_CHANGE, OnEditChange)
|
||||||
END_MSG_MAP()
|
END_MSG_MAP()
|
||||||
private:
|
private:
|
||||||
BOOL OnInitDialog(CWindow, LPARAM);
|
BOOL OnInitDialog(CWindow, LPARAM);
|
||||||
|
@ -56,6 +56,7 @@ input_vgmstream::input_vgmstream() {
|
|||||||
loop_forever = false;
|
loop_forever = false;
|
||||||
ignore_loop = 0;
|
ignore_loop = 0;
|
||||||
disable_subsongs = false;
|
disable_subsongs = false;
|
||||||
|
downmix_channels = 0;
|
||||||
|
|
||||||
load_settings();
|
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]));
|
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));
|
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_samples+=samples_to_do;
|
||||||
decode_pos_ms=decode_pos_samples*1000LL/vgmstream->sample_rate;
|
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);
|
title.set_string(p, e - p);
|
||||||
|
|
||||||
if (!disable_subsongs && infostream && infostream->num_streams > 1) {
|
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;
|
title += temp;
|
||||||
|
|
||||||
if (infostream->stream_name[0] != '\0') {
|
if (infostream->stream_name[0] != '\0') {
|
||||||
|
@ -61,6 +61,7 @@ class input_vgmstream : public input_stubs {
|
|||||||
bool force_ignore_loop;
|
bool force_ignore_loop;
|
||||||
int ignore_loop;
|
int ignore_loop;
|
||||||
bool disable_subsongs;
|
bool disable_subsongs;
|
||||||
|
int downmix_channels;
|
||||||
|
|
||||||
/* helpers */
|
/* helpers */
|
||||||
VGMSTREAM * init_vgmstream_foo(t_uint32 p_subsong, const char * const filename, abort_callback & p_abort);
|
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_THREAD_PRIORITY_TEXT 1007
|
||||||
#define IDC_DEFAULT_BUTTON 1008
|
#define IDC_DEFAULT_BUTTON 1008
|
||||||
#define IDC_DISABLE_SUBSONGS 1009
|
#define IDC_DISABLE_SUBSONGS 1009
|
||||||
|
#define IDC_DOWNMIX_CHANNELS 1010
|
||||||
|
|
||||||
// Next default values for new objects
|
// Next default values for new objects
|
||||||
//
|
//
|
||||||
|
Loading…
Reference in New Issue
Block a user