(nw) It helps if you're using the same data types in both places (VGM

visualiser device and WDL FFT libarary).

I changed the VGM visualiser to use single-precision float which is the
default for WDL FFT.  GCC's loop vectoriser can make better use of SSE
with single-precision maths, and the extra precision shouldn't be needed
for the visualisation.  If this is a problem, let me know and I'll
revert this and flip the WDL FFT library over the other way.
This commit is contained in:
Vas Crabb 2020-03-07 06:58:07 +11:00
parent 1400e65cde
commit ddfe149872
3 changed files with 38 additions and 38 deletions

View File

@ -2191,7 +2191,7 @@ end
--------------------------------------------------
project "wdlfft"
uuid "74ca017e-fa0d-48b8-81d6-8081a37be14c"
uuid "74ca017e-fa0d-48b8-81d6-8081a37be14c"
kind "StaticLib"
configuration { "gmake or ninja" }

View File

@ -76,15 +76,15 @@ void vgmviz_device::device_start()
void vgmviz_device::fill_window()
{
double window_pos_delta = (3.14159265358979 * 2) / FFT_LENGTH;
double power = 0;
float window_pos_delta = (3.14159265358979f * 2) / FFT_LENGTH;
float power = 0;
for (int i = 0; i < (FFT_LENGTH / 2) + 1; i++)
{
double window_pos = i * window_pos_delta;
m_window[i] = 0.53836 - cos(window_pos) * 0.46164;
float window_pos = i * window_pos_delta;
m_window[i] = 0.53836f - cosf(window_pos) * 0.46164f;
power += m_window[i];
}
power = 0.5 / (power * 2.0 - m_window[FFT_LENGTH / 2]);
power = 0.5f / (power * 2.0f - m_window[FFT_LENGTH / 2]);
for (int i = 0; i < (FFT_LENGTH / 2) + 1; i++)
{
m_window[i] *= power;
@ -99,11 +99,11 @@ void vgmviz_device::fill_window()
void vgmviz_device::apply_window(uint32_t buf_index)
{
double *audio_l = m_audio_buf[buf_index][0];
double *audio_r = m_audio_buf[buf_index][1];
double *buf_l = m_fft_buf[0];
double *buf_r = m_fft_buf[1];
double *window = m_window;
float *audio_l = m_audio_buf[buf_index][0];
float *audio_r = m_audio_buf[buf_index][1];
float *buf_l = m_fft_buf[0];
float *buf_r = m_fft_buf[1];
float *window = m_window;
for (int i = 0; i < (FFT_LENGTH / 2) + 1; i++)
{
*buf_l++ = *audio_l++ * *window;
@ -133,7 +133,7 @@ void vgmviz_device::apply_fft()
for (int chan = 0; chan < 2; chan++)
{
WDL_FFT_COMPLEX* cmpl = (WDL_FFT_COMPLEX*)m_fft_buf[chan] + i;
cmpl->re = sqrt(cmpl->re * cmpl->re + cmpl->im * cmpl->im);
cmpl->re = sqrtf(cmpl->re * cmpl->re + cmpl->im * cmpl->im);
}
}
}
@ -156,13 +156,13 @@ void vgmviz_device::apply_waterfall()
{
continue;
}
double val = 0.0;
float val = 0.0f;
for (int i = 0; i < bar_step; i++)
{
int permuted = WDL_fft_permute(FFT_LENGTH / 2, (bar * bar_step) + i);
val = std::max<WDL_FFT_REAL>(bins[0][permuted].re + bins[1][permuted].re, val);
}
int level = (int)(log(val * 32768.0) * 31.0);
int level = int(logf(val * 32768.0f) * 31.0f);
m_waterfall_buf[m_waterfall_length % (FFT_LENGTH / 2 + 16)][255 - bar] = (level < 0) ? 0 : (level > 255 ? 255 : level);
}
m_waterfall_length++;
@ -177,15 +177,15 @@ void vgmviz_device::find_levels()
{
if (m_audio_frames_available < 2 || m_current_rate == 0)
{
m_curr_levels[0] = 0.0;
m_curr_levels[1] = 0.0;
m_curr_peaks[0] = 0.0;
m_curr_peaks[1] = 0.0;
m_curr_levels[0] = 0.0f;
m_curr_levels[1] = 0.0f;
m_curr_peaks[0] = 0.0f;
m_curr_peaks[1] = 0.0f;
return;
}
m_curr_levels[0] = 0.0;
m_curr_levels[1] = 0.0;
m_curr_levels[0] = 0.0f;
m_curr_levels[1] = 0.0f;
int read_index = m_audio_fill_index;
const int samples_needed = m_current_rate / 60;
@ -229,17 +229,17 @@ void vgmviz_device::device_reset()
{
for (int i = 0; i < 2; i++)
{
memset(m_audio_buf[i][0], 0, sizeof(double) * FFT_LENGTH);
memset(m_audio_buf[i][1], 0, sizeof(double) * FFT_LENGTH);
memset(m_audio_buf[i][0], 0, sizeof(float) * FFT_LENGTH);
memset(m_audio_buf[i][1], 0, sizeof(float) * FFT_LENGTH);
m_audio_count[i] = 0;
}
memset(m_fft_buf[0], 0, sizeof(double) * FFT_LENGTH);
memset(m_fft_buf[1], 0, sizeof(double) * FFT_LENGTH);
memset(m_fft_buf[0], 0, sizeof(float) * FFT_LENGTH);
memset(m_fft_buf[1], 0, sizeof(float) * FFT_LENGTH);
m_current_rate = 0;
m_audio_fill_index = 0;
m_audio_frames_available = 0;
memset(m_curr_levels, 0, sizeof(double) * 2);
memset(m_curr_peaks, 0, sizeof(double) * 2);
memset(m_curr_levels, 0, sizeof(float) * 2);
memset(m_curr_peaks, 0, sizeof(float) * 2);
m_waterfall_length = 0;
for (int i = 0; i < 1024; i++)
@ -275,7 +275,7 @@ void vgmviz_device::sound_stream_update(sound_stream &stream, stream_sample_t **
for (int i = 0; i < m_outputs; i++)
{
m_audio_buf[m_audio_fill_index][i][m_audio_count[m_audio_fill_index]] = (outputs[i][pos] + 32768.0) / 65336.0;
m_audio_buf[m_audio_fill_index][i][m_audio_count[m_audio_fill_index]] = (outputs[i][pos] + 32768.0f) / 65336.0f;
}
m_audio_count[m_audio_fill_index]++;
@ -427,8 +427,8 @@ uint32_t vgmviz_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma
const int black_idx = (512 + FFT_LENGTH / 2);
for (int chan = 0; chan < 2; chan++)
{
int level = (int)(m_curr_levels[chan] * 255.0);
int peak = (int)(m_curr_peaks[chan] * 255.0);
int level = int(m_curr_levels[chan] * 255.0f);
int peak = int(m_curr_peaks[chan] * 255.0f);
for (int y = 0; y < 512; y++)
{
int bar_y = 255 - (y >> 1);
@ -440,7 +440,7 @@ uint32_t vgmviz_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma
}
}
chan_x += 8;
m_curr_peaks[chan] *= 0.99;
m_curr_peaks[chan] *= 0.99f;
}
int total_bars = FFT_LENGTH / 2;
@ -452,8 +452,8 @@ uint32_t vgmviz_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma
continue;
}
int permuted = WDL_fft_permute(FFT_LENGTH/2, bar);
double val = (bins[0][permuted].re + bins[1][permuted].re) * 0.5;
int level = (int)(log(val * 32768.0) * 63.0);
float val = (bins[0][permuted].re + bins[1][permuted].re) * 0.5f;
int level = int(logf(val * 32768.0f) * 63.0f);
for (int y = 0; y < 512; y++)
{
int bar_y = 511 - y;

View File

@ -70,8 +70,8 @@ protected:
required_device<screen_device> m_screen;
required_device<palette_device> m_palette;
double m_audio_buf[2][2][FFT_LENGTH];
double m_fft_buf[2][FFT_LENGTH];
float m_audio_buf[2][2][FFT_LENGTH];
float m_fft_buf[2][FFT_LENGTH];
int m_current_rate;
int m_audio_fill_index;
int m_audio_frames_available;
@ -80,10 +80,10 @@ protected:
int m_waterfall_length;
int m_waterfall_buf[1024][256];
double m_curr_levels[2];
double m_curr_peaks[2];
double m_window[FFT_LENGTH];
double m_power;
float m_curr_levels[2];
float m_curr_peaks[2];
float m_window[FFT_LENGTH];
float m_power;
};
#endif // MAME_SOUND_VGMVIZ_H