diff options
author | 2020-03-28 02:24:20 +0100 | |
---|---|---|
committer | 2020-03-28 02:25:05 +0100 | |
commit | b6ce59f77aa729dbecea7111ff30d6b4f55c22b3 (patch) | |
tree | 04e146253e82f38a05f489244b18f33e1e5b2e8d | |
parent | 4139da509729a51c51ba034ecb745910a02a8727 (diff) |
-vgmplay: Added multiple spectrogram visualization modes. [Ryan Holtz]
-rw-r--r-- | src/devices/sound/vgm_visualizer.cpp | 53 | ||||
-rw-r--r-- | src/devices/sound/vgm_visualizer.h | 16 | ||||
-rw-r--r-- | src/mame/drivers/vgmplay.cpp | 5 |
3 files changed, 67 insertions, 7 deletions
diff --git a/src/devices/sound/vgm_visualizer.cpp b/src/devices/sound/vgm_visualizer.cpp index bceeed2b0d6..0ed9aff7049 100644 --- a/src/devices/sound/vgm_visualizer.cpp +++ b/src/devices/sound/vgm_visualizer.cpp @@ -246,10 +246,26 @@ void vgmviz_device::device_reset() { memset(m_waterfall_buf[i], 0, sizeof(int) * 256); } + + m_spec_mode = SPEC_RAW; } //------------------------------------------------- +// cycle_spectrogram - cycle the spectrogram mode +// among the valid spectrogram modes. +//------------------------------------------------- + +void vgmviz_device::cycle_spectrogram() +{ + m_spec_mode = (spec_mode)((int)m_spec_mode + 1); + if (m_spec_mode == SPEC_COUNT) + { + m_spec_mode = SPEC_RAW; + } +} + +//------------------------------------------------- // sound_stream_update - update the outgoing // audio stream and process as necessary //------------------------------------------------- @@ -420,6 +436,8 @@ void vgmviz_device::device_add_mconfig(machine_config &config) uint32_t vgmviz_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect) { + bitmap.fill(0, cliprect); + find_levels(); const pen_t *pal = m_palette->pens(); @@ -443,23 +461,48 @@ uint32_t vgmviz_device::screen_update(screen_device &screen, bitmap_rgb32 &bitma m_curr_peaks[chan] *= 0.99f; } + int bar_size = 1; + switch (m_spec_mode) + { + default: + bar_size = 1; + break; + case SPEC_BAR4: + bar_size = 4; + break; + case SPEC_BAR8: + bar_size = 8; + break; + case SPEC_BAR16: + bar_size = 16; + break; + } + int total_bars = FFT_LENGTH / 2; WDL_FFT_COMPLEX *bins[2] = { (WDL_FFT_COMPLEX *)m_fft_buf[0], (WDL_FFT_COMPLEX *)m_fft_buf[1] }; - for (int bar = 0; bar < total_bars; bar++) + for (int bar = 0; bar < total_bars; bar += bar_size) { if (bar < 2) { continue; } - int permuted = WDL_fft_permute(FFT_LENGTH/2, bar); - float val = (bins[0][permuted].re + bins[1][permuted].re) * 0.5f; - int level = int(logf(val * 32768.0f) * 63.0f); + float max_val = 0.0f; + for (int sub_bar = 0; sub_bar < bar_size && (bar + sub_bar) < total_bars; sub_bar++) + { + int permuted = WDL_fft_permute(FFT_LENGTH/2, bar + sub_bar); + max_val = std::max<float>((bins[0][permuted].re + bins[1][permuted].re) * 0.5f, max_val); + } + int level = int(logf(max_val * 32768.0f) * 63.0f); for (int y = 0; y < 512; y++) { int bar_y = 511 - y; uint32_t *line = &bitmap.pix32(y + 256); bool lit = bar_y <= level; - line[bar + 16] = pal[lit ? (256 + bar) : black_idx]; + const int x_limit = bar_size == 1 ? 1 : bar_size - 1; + for (int x = 0; x < x_limit; x++) + { + line[(bar - 2) + x + 16] = pal[lit ? (256 + bar) : black_idx]; + } } } diff --git a/src/devices/sound/vgm_visualizer.h b/src/devices/sound/vgm_visualizer.h index 7e782a59bcc..60b54d0cde9 100644 --- a/src/devices/sound/vgm_visualizer.h +++ b/src/devices/sound/vgm_visualizer.h @@ -46,8 +46,20 @@ public: vgmviz_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0); virtual ~vgmviz_device(); + void cycle_spectrogram(); + protected: - static constexpr int FFT_LENGTH = 1024; + enum spec_mode : int + { + SPEC_RAW, + SPEC_BAR4, + SPEC_BAR8, + SPEC_BAR16, + + SPEC_COUNT + }; + + static constexpr int FFT_LENGTH = 512; // device-level overrides virtual void device_add_mconfig(machine_config &config) override; @@ -83,7 +95,7 @@ protected: float m_curr_levels[2]; float m_curr_peaks[2]; float m_window[FFT_LENGTH]; - float m_power; + spec_mode m_spec_mode; }; #endif // MAME_SOUND_VGMVIZ_H diff --git a/src/mame/drivers/vgmplay.cpp b/src/mame/drivers/vgmplay.cpp index 2b7460c6f6c..aabd6805dfe 100644 --- a/src/mame/drivers/vgmplay.cpp +++ b/src/mame/drivers/vgmplay.cpp @@ -393,6 +393,7 @@ enum vgmplay_inputs : uint8_t VGMPLAY_PLAY, VGMPLAY_RESTART, VGMPLAY_LOOP, + VGMPLAY_SPEC, }; class vgmplay_state : public driver_device @@ -3154,6 +3155,9 @@ INPUT_CHANGED_MEMBER(vgmplay_state::key_pressed) case VGMPLAY_LOOP: m_vgmplay->toggle_loop(); break; + case VGMPLAY_SPEC: + m_mixer->cycle_spectrogram(); + break; } } @@ -3164,6 +3168,7 @@ static INPUT_PORTS_START( vgmplay ) PORT_BIT(0x0004, IP_ACTIVE_HIGH, IPT_BUTTON3) PORT_CHANGED_MEMBER(DEVICE_SELF, vgmplay_state, key_pressed, VGMPLAY_PLAY) PORT_NAME("Play") PORT_BIT(0x0008, IP_ACTIVE_HIGH, IPT_BUTTON4) PORT_CHANGED_MEMBER(DEVICE_SELF, vgmplay_state, key_pressed, VGMPLAY_RESTART) PORT_NAME("Restart") PORT_BIT(0x0010, IP_ACTIVE_HIGH, IPT_BUTTON5) PORT_CHANGED_MEMBER(DEVICE_SELF, vgmplay_state, key_pressed, VGMPLAY_LOOP) PORT_NAME("Loop") + PORT_BIT(0x0020, IP_ACTIVE_HIGH, IPT_BUTTON6) PORT_CHANGED_MEMBER(DEVICE_SELF, vgmplay_state, key_pressed, VGMPLAY_SPEC) PORT_NAME("Spectrogram Mode") INPUT_PORTS_END void vgmplay_state::file_map(address_map &map) |