mirror of
https://github.com/holub/mame
synced 2025-04-20 15:32:45 +03:00
-vgmplay: Added a visualizer. [Ryan Holtz, Justin Frankel]
This commit is contained in:
parent
fd0af13422
commit
bcefd95275
@ -1541,3 +1541,17 @@ if (SOUNDS["SWP30"]~=null) then
|
||||
MAME_DIR .. "src/devices/sound/swp30.h",
|
||||
}
|
||||
end
|
||||
|
||||
---------------------------------------------------
|
||||
--
|
||||
--@src/devices/sound/vgm_visualizer.h,SOUNDS["VGMVIZ"] = true
|
||||
---------------------------------------------------
|
||||
|
||||
if (SOUNDS["VGMVIZ"]~=null) then
|
||||
files {
|
||||
MAME_DIR .. "src/devices/sound/vgm_visualizer.cpp",
|
||||
MAME_DIR .. "src/devices/sound/vgm_visualizer.h",
|
||||
MAME_DIR .. "src/devices/sound/fft.cpp",
|
||||
MAME_DIR .. "src/devices/sound/fft.h",
|
||||
}
|
||||
end
|
||||
|
1206
src/devices/sound/fft.cpp
Normal file
1206
src/devices/sound/fft.cpp
Normal file
File diff suppressed because it is too large
Load Diff
82
src/devices/sound/fft.h
Normal file
82
src/devices/sound/fft.h
Normal file
@ -0,0 +1,82 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Justin Frankel
|
||||
/*
|
||||
WDL - fft.h
|
||||
Copyright (C) 2006 and later Cockos Incorporated
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
||||
|
||||
|
||||
This file defines the interface to the WDL FFT library. These routines are based on the
|
||||
DJBFFT library, which are Copyright 1999 D. J. Bernstein, djb@pobox.com
|
||||
|
||||
The DJB FFT web page is: http://cr.yp.to/djbfft.html
|
||||
|
||||
|
||||
This file is modified from the original; it has been reformatted for 4-space
|
||||
tabs.
|
||||
*/
|
||||
|
||||
#ifndef WDL_FFT_H
|
||||
#define WDL_FFT_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef WDL_FFT_REALSIZE
|
||||
#define WDL_FFT_REALSIZE 8
|
||||
#endif
|
||||
|
||||
#if WDL_FFT_REALSIZE == 4
|
||||
typedef float WDL_FFT_REAL;
|
||||
#elif WDL_FFT_REALSIZE == 8
|
||||
typedef double WDL_FFT_REAL;
|
||||
#else
|
||||
#error invalid FFT item size
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
WDL_FFT_REAL re;
|
||||
WDL_FFT_REAL im;
|
||||
} WDL_FFT_COMPLEX;
|
||||
|
||||
extern void WDL_fft_init();
|
||||
|
||||
extern void WDL_fft_complexmul(WDL_FFT_COMPLEX *dest, WDL_FFT_COMPLEX *src, int len);
|
||||
extern void WDL_fft_complexmul2(WDL_FFT_COMPLEX *dest, WDL_FFT_COMPLEX *src, WDL_FFT_COMPLEX *src2, int len);
|
||||
extern void WDL_fft_complexmul3(WDL_FFT_COMPLEX *destAdd, WDL_FFT_COMPLEX *src, WDL_FFT_COMPLEX *src2, int len);
|
||||
|
||||
/* Expects WDL_FFT_COMPLEX input[0..len-1] scaled by 1.0/len, returns
|
||||
WDL_FFT_COMPLEX output[0..len-1] order by WDL_fft_permute(len). */
|
||||
extern void WDL_fft(WDL_FFT_COMPLEX *, int len, int isInverse);
|
||||
|
||||
/* Expects WDL_FFT_REAL input[0..len-1] scaled by 0.5/len, returns
|
||||
WDL_FFT_COMPLEX output[0..len/2-1], for len >= 4 order by
|
||||
WDL_fft_permute(len/2). Note that output[len/2].re is stored in
|
||||
output[0].im. */
|
||||
extern void WDL_real_fft(WDL_FFT_REAL *, int len, int isInverse);
|
||||
|
||||
extern int WDL_fft_permute(int fftsize, int idx);
|
||||
extern int *WDL_fft_permute_tab(int fftsize);
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
483
src/devices/sound/vgm_visualizer.cpp
Normal file
483
src/devices/sound/vgm_visualizer.cpp
Normal file
@ -0,0 +1,483 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
/***************************************************************************
|
||||
|
||||
vgm_visualizer.cpp
|
||||
|
||||
Virtual VGM visualizer device.
|
||||
|
||||
Provides a waterfall view, spectrograph view, and VU view.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#include "emu.h"
|
||||
#include "sound/vgm_visualizer.h"
|
||||
#include "fft.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
|
||||
static float lerp(float a, float b, float f)
|
||||
{
|
||||
return (b - a) * f + a;
|
||||
}
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
// device type definition
|
||||
DEFINE_DEVICE_TYPE(VGMVIZ, vgmviz_device, "vgmviz", "VGM Visualizer")
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// LIVE DEVICE
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// vgmviz_device - constructor
|
||||
//-------------------------------------------------
|
||||
|
||||
vgmviz_device::vgmviz_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
|
||||
: device_t(mconfig, VGMVIZ, tag, owner, clock)
|
||||
, device_mixer_interface(mconfig, *this, 2)
|
||||
, m_screen(*this, "screen")
|
||||
, m_palette(*this, "palette")
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// ~vgmviz_device - destructor
|
||||
//-------------------------------------------------
|
||||
|
||||
vgmviz_device::~vgmviz_device()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_start - handle device startup
|
||||
//-------------------------------------------------
|
||||
|
||||
void vgmviz_device::device_start()
|
||||
{
|
||||
WDL_fft_init();
|
||||
fill_window();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// fill_window - fill in the windowing data
|
||||
//-------------------------------------------------
|
||||
|
||||
void vgmviz_device::fill_window()
|
||||
{
|
||||
double window_pos_delta = (3.14159265358979 * 2) / FFT_LENGTH;
|
||||
double 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;
|
||||
power += m_window[i];
|
||||
}
|
||||
power = 0.5 / (power * 2.0 - m_window[FFT_LENGTH / 2]);
|
||||
for (int i = 0; i < (FFT_LENGTH / 2) + 1; i++)
|
||||
{
|
||||
m_window[i] *= power;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// fill_window - apply windowing data to the
|
||||
// mixed signal
|
||||
//-------------------------------------------------
|
||||
|
||||
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;
|
||||
for (int i = 0; i < (FFT_LENGTH / 2) + 1; i++)
|
||||
{
|
||||
*buf_l++ = *audio_l++ * *window;
|
||||
*buf_r++ = *audio_r++ * *window;
|
||||
window++;
|
||||
}
|
||||
for (int i = 0; i < (FFT_LENGTH / 2) - 1; i++)
|
||||
{
|
||||
window--;
|
||||
*buf_l++ = *audio_l++ * *window;
|
||||
*buf_r++ = *audio_r++ * *window;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// apply_fft - run the FFT on the windowed data
|
||||
//-------------------------------------------------
|
||||
|
||||
void vgmviz_device::apply_fft()
|
||||
{
|
||||
WDL_real_fft((WDL_FFT_REAL*)m_fft_buf[0], FFT_LENGTH, 0);
|
||||
WDL_real_fft((WDL_FFT_REAL*)m_fft_buf[1], FFT_LENGTH, 0);
|
||||
|
||||
for (int i = 1; i < FFT_LENGTH/2; i++)
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// apply_waterfall - calculate the waterfall-view
|
||||
// data
|
||||
//-------------------------------------------------
|
||||
|
||||
void vgmviz_device::apply_waterfall()
|
||||
{
|
||||
int total_bars = FFT_LENGTH / 2;
|
||||
int bar_step = total_bars / 256;
|
||||
WDL_FFT_COMPLEX* bins[2] = { (WDL_FFT_COMPLEX*)m_fft_buf[0], (WDL_FFT_COMPLEX*)m_fft_buf[1] };
|
||||
int bar_index = 0;
|
||||
for (int bar = 0; bar < 256; bar++, bar_index += bar_step)
|
||||
{
|
||||
if (bar_index < 2)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
double val = 0.0;
|
||||
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);
|
||||
m_waterfall_buf[m_waterfall_length % (FFT_LENGTH / 2 + 16)][255 - bar] = (level < 0) ? 0 : (level > 255 ? 255 : level);
|
||||
}
|
||||
m_waterfall_length++;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// find_levels - find average and peak levels
|
||||
//-------------------------------------------------
|
||||
|
||||
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;
|
||||
return;
|
||||
}
|
||||
|
||||
m_curr_levels[0] = 0.0;
|
||||
m_curr_levels[1] = 0.0;
|
||||
|
||||
int read_index = m_audio_fill_index;
|
||||
const int samples_needed = m_current_rate / 60;
|
||||
int samples_remaining = samples_needed;
|
||||
int samples_found = 0;
|
||||
do
|
||||
{
|
||||
for (int i = std::min<int>(FFT_LENGTH - 1, m_audio_count[read_index]); i >= 0 && samples_remaining > 0; i--, samples_remaining--)
|
||||
{
|
||||
for (int chan = 0; chan < 2; chan++)
|
||||
{
|
||||
if (m_audio_buf[read_index][chan][i] > m_curr_levels[chan])
|
||||
{
|
||||
m_curr_levels[chan] += m_audio_buf[read_index][chan][i];
|
||||
}
|
||||
}
|
||||
samples_found++;
|
||||
samples_remaining--;
|
||||
}
|
||||
read_index = 1 - m_audio_fill_index;
|
||||
} while (samples_remaining > 0 && read_index != m_audio_fill_index);
|
||||
|
||||
if (samples_found > 0)
|
||||
{
|
||||
for (int chan = 0; chan < 2; chan++)
|
||||
{
|
||||
if (m_curr_levels[chan] > m_curr_peaks[chan])
|
||||
{
|
||||
m_curr_peaks[chan] = m_curr_levels[chan];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_reset - handle device reset
|
||||
//-------------------------------------------------
|
||||
|
||||
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);
|
||||
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);
|
||||
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);
|
||||
|
||||
m_waterfall_length = 0;
|
||||
for (int i = 0; i < 1024; i++)
|
||||
{
|
||||
memset(m_waterfall_buf[i], 0, sizeof(int) * 256);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// sound_stream_update - update the outgoing
|
||||
// audio stream and process as necessary
|
||||
//-------------------------------------------------
|
||||
|
||||
void vgmviz_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
|
||||
{
|
||||
// clear output buffers
|
||||
for (int output = 0; output < m_outputs; output++)
|
||||
std::fill_n(outputs[output], samples, 0);
|
||||
|
||||
m_current_rate = stream.sample_rate();
|
||||
|
||||
// loop over samples
|
||||
const u8 *outmap = &m_outputmap[0];
|
||||
|
||||
// for each input, add it to the appropriate output
|
||||
for (int pos = 0; pos < samples; pos++)
|
||||
{
|
||||
for (int inp = 0; inp < m_auto_allocated_inputs; inp++)
|
||||
{
|
||||
outputs[outmap[inp]][pos] += inputs[inp][pos];
|
||||
}
|
||||
|
||||
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_count[m_audio_fill_index]++;
|
||||
if (m_audio_count[m_audio_fill_index] >= FFT_LENGTH)
|
||||
{
|
||||
apply_window(m_audio_fill_index);
|
||||
apply_fft();
|
||||
apply_waterfall();
|
||||
|
||||
m_audio_fill_index = 1 - m_audio_fill_index;
|
||||
if (m_audio_frames_available < 2)
|
||||
{
|
||||
m_audio_frames_available++;
|
||||
}
|
||||
m_audio_count[m_audio_fill_index] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// init_palette - initialize the palette
|
||||
//-------------------------------------------------
|
||||
|
||||
void vgmviz_device::init_palette(palette_device &palette) const
|
||||
{
|
||||
for (int i = 0; i < 256; i++)
|
||||
{
|
||||
float percent = (float)i / 255.0f;
|
||||
if (percent < 0.75f)
|
||||
{
|
||||
float r = lerp(0.0f, 1.0f, percent / 0.75f);
|
||||
float g = 1.0f;
|
||||
float b = 0.0f;
|
||||
palette.set_pen_color(i, rgb_t((uint8_t)(r * 255), (uint8_t)(g * 255), (uint8_t)(b * 255)));
|
||||
}
|
||||
else
|
||||
{
|
||||
float r = lerp(1.0f, 1.0f, (percent - 0.75f) / 0.25f);
|
||||
float g = lerp(1.0f, 0.0f, (percent - 0.75f) / 0.25f);
|
||||
float b = 0.0f;
|
||||
palette.set_pen_color(i, rgb_t((uint8_t)(r * 255), (uint8_t)(g * 255), (uint8_t)(b * 255)));
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < FFT_LENGTH / 2; i++)
|
||||
{
|
||||
double h = ((double)i / (FFT_LENGTH / 2)) * 360.0;
|
||||
double s = 1.0;
|
||||
double v = 1.0;
|
||||
|
||||
double c = s * v;
|
||||
double x = c * (1 - abs(fmod(h / 60.0, 2.0) - 1.0));
|
||||
double m = v - c;
|
||||
double rs = 0.0;
|
||||
double gs = 0.0;
|
||||
double bs = 0.0;
|
||||
|
||||
if (h >= 0.0 && h < 60.0)
|
||||
{
|
||||
rs = c;
|
||||
gs = x;
|
||||
bs = 0.0;
|
||||
}
|
||||
else if (h >= 60.0 && h < 120.0)
|
||||
{
|
||||
rs = x;
|
||||
gs = c;
|
||||
bs = 0.0;
|
||||
}
|
||||
else if (h >= 120.0 && h < 180.0)
|
||||
{
|
||||
rs = 0.0;
|
||||
gs = c;
|
||||
bs = x;
|
||||
}
|
||||
else if (h >= 180.0 && h < 240.0)
|
||||
{
|
||||
rs = 0.0;
|
||||
gs = x;
|
||||
bs = c;
|
||||
}
|
||||
else if (h >= 240.0 && h < 300.0)
|
||||
{
|
||||
rs = x;
|
||||
gs = 0.0;
|
||||
bs = c;
|
||||
}
|
||||
else if (h < 360.0)
|
||||
{
|
||||
rs = c;
|
||||
gs = 0.0;
|
||||
bs = x;
|
||||
}
|
||||
|
||||
palette.set_pen_color(i + 256, rgb_t((uint8_t)((rs + m) * 255), (uint8_t)((gs + m) * 255), (uint8_t)((bs + m) * 255)));
|
||||
}
|
||||
|
||||
for (int y = 0; y < 256; y++)
|
||||
{
|
||||
float percent = (float)y / 255.0f;
|
||||
if (percent < 0.75f)
|
||||
{
|
||||
float r = 0.0f;
|
||||
float g = 0.0f;
|
||||
float b = lerp(0.0f, 1.0f, percent / 0.5f);
|
||||
palette.set_pen_color(y + 256 + FFT_LENGTH / 2, rgb_t((uint8_t)(r * 255), (uint8_t)(g * 255), (uint8_t)(b * 255)));
|
||||
}
|
||||
else
|
||||
{
|
||||
float r = lerp(0.0f, 1.0f, (percent - 0.5f) / 0.5f);
|
||||
float g = lerp(0.0f, 1.0f, (percent - 0.5f) / 0.5f);
|
||||
float b = 1.0f;
|
||||
palette.set_pen_color(y + 256 + FFT_LENGTH / 2, rgb_t((uint8_t)(r * 255), (uint8_t)(g * 255), (uint8_t)(b * 255)));
|
||||
}
|
||||
}
|
||||
|
||||
palette.set_pen_color(512 + FFT_LENGTH / 2, rgb_t(0, 0, 0));
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// device_add_mconfig - handle device setup
|
||||
//-------------------------------------------------
|
||||
|
||||
void vgmviz_device::device_add_mconfig(machine_config &config)
|
||||
{
|
||||
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
|
||||
m_screen->set_refresh_hz(60);
|
||||
m_screen->set_vblank_time(ATTOSECONDS_IN_USEC(2500));
|
||||
m_screen->set_size(FFT_LENGTH / 2 + 16, 768);
|
||||
m_screen->set_visarea(0, FFT_LENGTH / 2 + 15, 0, 767);
|
||||
m_screen->set_screen_update(FUNC(vgmviz_device::screen_update));
|
||||
|
||||
PALETTE(config, m_palette, FUNC(vgmviz_device::init_palette), 512 + FFT_LENGTH / 2 + 1);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// screen_update - update vu meters
|
||||
//-------------------------------------------------
|
||||
|
||||
uint32_t vgmviz_device::screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect)
|
||||
{
|
||||
find_levels();
|
||||
|
||||
const pen_t *pal = m_palette->pens();
|
||||
int chan_x = 0;
|
||||
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);
|
||||
for (int y = 0; y < 512; y++)
|
||||
{
|
||||
int bar_y = 255 - (y >> 1);
|
||||
for (int x = 0; x < 7; x++)
|
||||
{
|
||||
uint32_t *line = &bitmap.pix32(y + 256);
|
||||
bool lit = bar_y <= level || bar_y == peak;
|
||||
line[chan_x + x] = pal[lit ? bar_y : black_idx];
|
||||
}
|
||||
}
|
||||
chan_x += 8;
|
||||
m_curr_peaks[chan] *= 0.99;
|
||||
}
|
||||
|
||||
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++)
|
||||
{
|
||||
if (bar < 2)
|
||||
{
|
||||
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);
|
||||
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 width = FFT_LENGTH / 2 + 16;
|
||||
for (int y = 0; y < 256; y++)
|
||||
{
|
||||
uint32_t* line = &bitmap.pix32(y);
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
if (m_waterfall_length < width)
|
||||
{
|
||||
const int sample = m_waterfall_buf[x][y];
|
||||
*line++ = pal[256 + FFT_LENGTH / 2 + sample];
|
||||
}
|
||||
else
|
||||
{
|
||||
const int sample = m_waterfall_buf[((m_waterfall_length - width) + x) % width][y];
|
||||
*line++ = pal[256 + FFT_LENGTH / 2 + sample];
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
89
src/devices/sound/vgm_visualizer.h
Normal file
89
src/devices/sound/vgm_visualizer.h
Normal file
@ -0,0 +1,89 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Ryan Holtz
|
||||
/***************************************************************************
|
||||
|
||||
vgm_visualizer.h
|
||||
|
||||
Virtual VGM visualizer device.
|
||||
|
||||
Provides a waterfall view, spectrograph view, and VU view.
|
||||
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef MAME_SOUND_VGMVIZ_H
|
||||
#define MAME_SOUND_VGMVIZ_H
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "screen.h"
|
||||
#include "emupal.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
//**************************************************************************
|
||||
// GLOBAL VARIABLES
|
||||
//**************************************************************************
|
||||
|
||||
// device type definition
|
||||
DECLARE_DEVICE_TYPE(VGMVIZ, vgmviz_device)
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// TYPE DEFINITIONS
|
||||
//**************************************************************************
|
||||
|
||||
// ======================> vgmviz_device
|
||||
|
||||
class vgmviz_device : public device_t, public device_mixer_interface
|
||||
{
|
||||
public:
|
||||
// construction/destruction
|
||||
vgmviz_device(const machine_config &mconfig, const char *tag, device_t *owner)
|
||||
: vgmviz_device(mconfig, tag, owner, 0)
|
||||
{
|
||||
}
|
||||
vgmviz_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
|
||||
virtual ~vgmviz_device();
|
||||
|
||||
protected:
|
||||
static constexpr int FFT_LENGTH = 1024;
|
||||
|
||||
// device-level overrides
|
||||
virtual void device_add_mconfig(machine_config &config) override;
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
|
||||
// device_sound_interface-level overrides
|
||||
void sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples) override;
|
||||
|
||||
void init_palette(palette_device &palette) const;
|
||||
|
||||
uint32_t screen_update(screen_device &screen, bitmap_rgb32 &bitmap, const rectangle &cliprect);
|
||||
|
||||
void fill_window();
|
||||
void apply_window(uint32_t buf_index);
|
||||
void apply_fft();
|
||||
void apply_waterfall();
|
||||
void find_levels();
|
||||
|
||||
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];
|
||||
int m_current_rate;
|
||||
int m_audio_fill_index;
|
||||
int m_audio_frames_available;
|
||||
int m_audio_count[2];
|
||||
bool m_audio_available;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
#endif // MAME_SOUND_VGMVIZ_H
|
@ -44,6 +44,7 @@
|
||||
#include "sound/segapcm.h"
|
||||
#include "sound/sn76496.h"
|
||||
#include "sound/upd7759.h"
|
||||
#include "sound/vgm_visualizer.h"
|
||||
#include "sound/x1_010.h"
|
||||
#include "sound/ym2151.h"
|
||||
#include "sound/ym2413.h"
|
||||
@ -447,6 +448,7 @@ public:
|
||||
private:
|
||||
std::vector<uint8_t> m_file_data;
|
||||
required_device<vgmplay_device> m_vgmplay;
|
||||
required_device<vgmviz_device> m_mixer;
|
||||
required_device<speaker_device> m_lspeaker;
|
||||
required_device<speaker_device> m_rspeaker;
|
||||
required_device_array<sn76489_device, 2> m_sn76489;
|
||||
@ -2548,6 +2550,7 @@ READ8_MEMBER(vgmplay_device::ga20_rom_r)
|
||||
vgmplay_state::vgmplay_state(const machine_config &mconfig, device_type type, const char *tag)
|
||||
: driver_device(mconfig, type, tag)
|
||||
, m_vgmplay(*this, "vgmplay")
|
||||
, m_mixer(*this, "mixer")
|
||||
, m_lspeaker(*this, "lspeaker")
|
||||
, m_rspeaker(*this, "rspeaker")
|
||||
, m_sn76489(*this, "sn76489.%d", 0)
|
||||
@ -3464,184 +3467,184 @@ void vgmplay_state::vgmplay(machine_config &config)
|
||||
config.set_default_layout(layout_vgmplay);
|
||||
|
||||
SN76489(config, m_sn76489[0], 0);
|
||||
m_sn76489[0]->add_route(0, "lspeaker", 0.5);
|
||||
m_sn76489[0]->add_route(0, "rspeaker", 0.5);
|
||||
m_sn76489[0]->add_route(0, m_mixer, 0.5, AUTO_ALLOC_INPUT, 0);
|
||||
m_sn76489[0]->add_route(0, m_mixer, 0.5, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
SN76489(config, m_sn76489[1], 0);
|
||||
m_sn76489[1]->add_route(0, "lspeaker", 0.5);
|
||||
m_sn76489[1]->add_route(0, "rspeaker", 0.5);
|
||||
m_sn76489[1]->add_route(0, m_mixer, 0.5, AUTO_ALLOC_INPUT, 0);
|
||||
m_sn76489[1]->add_route(0, m_mixer, 0.5, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
YM2413(config, m_ym2413[0], 0);
|
||||
m_ym2413[0]->add_route(ALL_OUTPUTS, "lspeaker", 1);
|
||||
m_ym2413[0]->add_route(ALL_OUTPUTS, "rspeaker", 1);
|
||||
m_ym2413[0]->add_route(ALL_OUTPUTS, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_ym2413[0]->add_route(ALL_OUTPUTS, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
YM2413(config, m_ym2413[1], 0);
|
||||
m_ym2413[1]->add_route(ALL_OUTPUTS, "lspeaker", 1);
|
||||
m_ym2413[1]->add_route(ALL_OUTPUTS, "rspeaker", 1);
|
||||
m_ym2413[1]->add_route(ALL_OUTPUTS, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_ym2413[1]->add_route(ALL_OUTPUTS, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
YM2612(config, m_ym2612[0], 0);
|
||||
m_ym2612[0]->add_route(0, "lspeaker", 1);
|
||||
m_ym2612[0]->add_route(1, "rspeaker", 1);
|
||||
m_ym2612[0]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_ym2612[0]->add_route(1, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
YM2612(config, m_ym2612[1], 0);
|
||||
m_ym2612[1]->add_route(0, "lspeaker", 1);
|
||||
m_ym2612[1]->add_route(1, "rspeaker", 1);
|
||||
m_ym2612[1]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_ym2612[1]->add_route(1, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
YM2151(config, m_ym2151[0], 0);
|
||||
m_ym2151[0]->add_route(0, "lspeaker", 1);
|
||||
m_ym2151[0]->add_route(1, "rspeaker", 1);
|
||||
m_ym2151[0]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_ym2151[0]->add_route(1, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
YM2151(config, m_ym2151[1], 0);
|
||||
m_ym2151[1]->add_route(0, "lspeaker", 1);
|
||||
m_ym2151[1]->add_route(1, "rspeaker", 1);
|
||||
m_ym2151[1]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_ym2151[1]->add_route(1, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
SEGAPCM(config, m_segapcm[0], 0);
|
||||
m_segapcm[0]->set_addrmap(0, &vgmplay_state::segapcm_map<0>);
|
||||
m_segapcm[0]->add_route(0, "lspeaker", 1);
|
||||
m_segapcm[0]->add_route(1, "rspeaker", 1);
|
||||
m_segapcm[0]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_segapcm[0]->add_route(1, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
SEGAPCM(config, m_segapcm[1], 0);
|
||||
m_segapcm[1]->set_addrmap(0, &vgmplay_state::segapcm_map<1>);
|
||||
m_segapcm[1]->add_route(0, "lspeaker", 1);
|
||||
m_segapcm[1]->add_route(1, "rspeaker", 1);
|
||||
m_segapcm[1]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_segapcm[1]->add_route(1, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
RF5C68(config, m_rf5c68, 0);
|
||||
m_rf5c68->set_addrmap(0, &vgmplay_state::rf5c68_map<0>);
|
||||
m_rf5c68->add_route(0, "lspeaker", 1);
|
||||
m_rf5c68->add_route(1, "rspeaker", 1);
|
||||
m_rf5c68->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_rf5c68->add_route(1, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
// TODO: prevent error.log spew
|
||||
YM2203(config, m_ym2203[0], 0);
|
||||
m_ym2203[0]->add_route(ALL_OUTPUTS, "lspeaker", 0.25);
|
||||
m_ym2203[0]->add_route(ALL_OUTPUTS, "rspeaker", 0.25);
|
||||
m_ym2203[0]->add_route(ALL_OUTPUTS, m_mixer, 0.25, AUTO_ALLOC_INPUT, 0);
|
||||
m_ym2203[0]->add_route(ALL_OUTPUTS, m_mixer, 0.25, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
YM2203(config, m_ym2203[1], 0);
|
||||
m_ym2203[1]->add_route(ALL_OUTPUTS, "lspeaker", 0.25);
|
||||
m_ym2203[1]->add_route(ALL_OUTPUTS, "rspeaker", 0.25);
|
||||
m_ym2203[1]->add_route(ALL_OUTPUTS, m_mixer, 0.25, AUTO_ALLOC_INPUT, 0);
|
||||
m_ym2203[1]->add_route(ALL_OUTPUTS, m_mixer, 0.25, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
// TODO: prevent error.log spew
|
||||
YM2608(config, m_ym2608[0], 0);
|
||||
m_ym2608[0]->set_addrmap(0, &vgmplay_state::ym2608_map<0>);
|
||||
m_ym2608[0]->add_route(0, "lspeaker", 0.25);
|
||||
m_ym2608[0]->add_route(0, "rspeaker", 0.25);
|
||||
m_ym2608[0]->add_route(1, "lspeaker", 1.00);
|
||||
m_ym2608[0]->add_route(2, "rspeaker", 1.00);
|
||||
m_ym2608[0]->add_route(0, m_mixer, 0.25, AUTO_ALLOC_INPUT, 0);
|
||||
m_ym2608[0]->add_route(0, m_mixer, 0.25, AUTO_ALLOC_INPUT, 1);
|
||||
m_ym2608[0]->add_route(1, m_mixer, 1.00, AUTO_ALLOC_INPUT, 0);
|
||||
m_ym2608[0]->add_route(2, m_mixer, 1.00, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
YM2608(config, m_ym2608[1], 0);
|
||||
m_ym2608[1]->set_addrmap(0, &vgmplay_state::ym2608_map<1>);
|
||||
m_ym2608[1]->add_route(0, "lspeaker", 0.25);
|
||||
m_ym2608[1]->add_route(0, "rspeaker", 0.25);
|
||||
m_ym2608[1]->add_route(1, "lspeaker", 1.00);
|
||||
m_ym2608[1]->add_route(2, "rspeaker", 1.00);
|
||||
m_ym2608[1]->add_route(0, m_mixer, 0.25, AUTO_ALLOC_INPUT, 0);
|
||||
m_ym2608[1]->add_route(0, m_mixer, 0.25, AUTO_ALLOC_INPUT, 1);
|
||||
m_ym2608[1]->add_route(1, m_mixer, 1.00, AUTO_ALLOC_INPUT, 0);
|
||||
m_ym2608[1]->add_route(2, m_mixer, 1.00, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
// TODO: prevent error.log spew
|
||||
YM2610(config, m_ym2610[0], 0);
|
||||
m_ym2610[0]->set_addrmap(0, &vgmplay_state::ym2610_adpcm_a_map<0>);
|
||||
m_ym2610[0]->set_addrmap(1, &vgmplay_state::ym2610_adpcm_b_map<0>);
|
||||
m_ym2610[0]->add_route(0, "lspeaker", 0.25);
|
||||
m_ym2610[0]->add_route(0, "rspeaker", 0.25);
|
||||
m_ym2610[0]->add_route(1, "lspeaker", 0.50);
|
||||
m_ym2610[0]->add_route(2, "rspeaker", 0.50);
|
||||
m_ym2610[0]->add_route(0, m_mixer, 0.25, AUTO_ALLOC_INPUT, 0);
|
||||
m_ym2610[0]->add_route(0, m_mixer, 0.25, AUTO_ALLOC_INPUT, 1);
|
||||
m_ym2610[0]->add_route(1, m_mixer, 0.50, AUTO_ALLOC_INPUT, 0);
|
||||
m_ym2610[0]->add_route(2, m_mixer, 0.50, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
YM2610(config, m_ym2610[1], 0);
|
||||
m_ym2610[1]->set_addrmap(0, &vgmplay_state::ym2610_adpcm_a_map<1>);
|
||||
m_ym2610[1]->set_addrmap(1, &vgmplay_state::ym2610_adpcm_b_map<1>);
|
||||
m_ym2610[1]->add_route(0, "lspeaker", 0.25);
|
||||
m_ym2610[1]->add_route(0, "rspeaker", 0.25);
|
||||
m_ym2610[1]->add_route(1, "lspeaker", 0.50);
|
||||
m_ym2610[1]->add_route(2, "rspeaker", 0.50);
|
||||
m_ym2610[1]->add_route(0, m_mixer, 0.25, AUTO_ALLOC_INPUT, 0);
|
||||
m_ym2610[1]->add_route(0, m_mixer, 0.25, AUTO_ALLOC_INPUT, 1);
|
||||
m_ym2610[1]->add_route(1, m_mixer, 0.50, AUTO_ALLOC_INPUT, 0);
|
||||
m_ym2610[1]->add_route(2, m_mixer, 0.50, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
YM3812(config, m_ym3812[0], 0);
|
||||
m_ym3812[0]->add_route(ALL_OUTPUTS, "lspeaker", 0.5);
|
||||
m_ym3812[0]->add_route(ALL_OUTPUTS, "rspeaker", 0.5);
|
||||
m_ym3812[0]->add_route(ALL_OUTPUTS, m_mixer, 0.5, AUTO_ALLOC_INPUT, 0);
|
||||
m_ym3812[0]->add_route(ALL_OUTPUTS, m_mixer, 0.5, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
YM3812(config, m_ym3812[1], 0);
|
||||
m_ym3812[1]->add_route(ALL_OUTPUTS, "lspeaker", 0.5);
|
||||
m_ym3812[1]->add_route(ALL_OUTPUTS, "rspeaker", 0.5);
|
||||
m_ym3812[1]->add_route(ALL_OUTPUTS, m_mixer, 0.5, AUTO_ALLOC_INPUT, 0);
|
||||
m_ym3812[1]->add_route(ALL_OUTPUTS, m_mixer, 0.5, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
YM3526(config, m_ym3526[0], 0);
|
||||
m_ym3526[0]->add_route(ALL_OUTPUTS, "lspeaker", 0.5);
|
||||
m_ym3526[0]->add_route(ALL_OUTPUTS, "rspeaker", 0.5);
|
||||
m_ym3526[0]->add_route(ALL_OUTPUTS, m_mixer, 0.5, AUTO_ALLOC_INPUT, 0);
|
||||
m_ym3526[0]->add_route(ALL_OUTPUTS, m_mixer, 0.5, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
YM3526(config, m_ym3526[1], 0);
|
||||
m_ym3526[1]->add_route(ALL_OUTPUTS, "lspeaker", 0.5);
|
||||
m_ym3526[1]->add_route(ALL_OUTPUTS, "rspeaker", 0.5);
|
||||
m_ym3526[1]->add_route(ALL_OUTPUTS, m_mixer, 0.5, AUTO_ALLOC_INPUT, 0);
|
||||
m_ym3526[1]->add_route(ALL_OUTPUTS, m_mixer, 0.5, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
Y8950(config, m_y8950[0], 0);
|
||||
m_y8950[0]->set_addrmap(0, &vgmplay_state::y8950_map<0>);
|
||||
m_y8950[0]->add_route(ALL_OUTPUTS, "lspeaker", 0.40);
|
||||
m_y8950[0]->add_route(ALL_OUTPUTS, "rspeaker", 0.40);
|
||||
m_y8950[0]->add_route(ALL_OUTPUTS, m_mixer, 0.40, AUTO_ALLOC_INPUT, 0);
|
||||
m_y8950[0]->add_route(ALL_OUTPUTS, m_mixer, 0.40, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
Y8950(config, m_y8950[1], 0);
|
||||
m_y8950[1]->set_addrmap(0, &vgmplay_state::y8950_map<1>);
|
||||
m_y8950[1]->add_route(ALL_OUTPUTS, "lspeaker", 0.40);
|
||||
m_y8950[1]->add_route(ALL_OUTPUTS, "rspeaker", 0.40);
|
||||
m_y8950[1]->add_route(ALL_OUTPUTS, m_mixer, 0.40, AUTO_ALLOC_INPUT, 0);
|
||||
m_y8950[1]->add_route(ALL_OUTPUTS, m_mixer, 0.40, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
YMF262(config, m_ymf262[0], 0);
|
||||
m_ymf262[0]->add_route(0, "lspeaker", 1.00);
|
||||
m_ymf262[0]->add_route(1, "rspeaker", 1.00);
|
||||
m_ymf262[0]->add_route(2, "lspeaker", 1.00);
|
||||
m_ymf262[0]->add_route(3, "rspeaker", 1.00);
|
||||
m_ymf262[0]->add_route(0, m_mixer, 1.00, AUTO_ALLOC_INPUT, 0);
|
||||
m_ymf262[0]->add_route(1, m_mixer, 1.00, AUTO_ALLOC_INPUT, 1);
|
||||
m_ymf262[0]->add_route(2, m_mixer, 1.00, AUTO_ALLOC_INPUT, 0);
|
||||
m_ymf262[0]->add_route(3, m_mixer, 1.00, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
YMF262(config, m_ymf262[1], 0);
|
||||
m_ymf262[1]->add_route(0, "lspeaker", 1.00);
|
||||
m_ymf262[1]->add_route(1, "rspeaker", 1.00);
|
||||
m_ymf262[1]->add_route(2, "lspeaker", 1.00);
|
||||
m_ymf262[1]->add_route(3, "rspeaker", 1.00);
|
||||
m_ymf262[1]->add_route(0, m_mixer, 1.00, AUTO_ALLOC_INPUT, 0);
|
||||
m_ymf262[1]->add_route(1, m_mixer, 1.00, AUTO_ALLOC_INPUT, 1);
|
||||
m_ymf262[1]->add_route(2, m_mixer, 1.00, AUTO_ALLOC_INPUT, 0);
|
||||
m_ymf262[1]->add_route(3, m_mixer, 1.00, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
// TODO: prevent error.log spew
|
||||
YMF278B(config, m_ymf278b[0], 0);
|
||||
m_ymf278b[0]->set_addrmap(0, &vgmplay_state::ymf278b_map<0>);
|
||||
m_ymf278b[0]->add_route(0, "lspeaker", 1.00);
|
||||
m_ymf278b[0]->add_route(1, "rspeaker", 1.00);
|
||||
m_ymf278b[0]->add_route(2, "lspeaker", 1.00);
|
||||
m_ymf278b[0]->add_route(3, "rspeaker", 1.00);
|
||||
m_ymf278b[0]->add_route(4, "lspeaker", 1.00);
|
||||
m_ymf278b[0]->add_route(5, "rspeaker", 1.00);
|
||||
m_ymf278b[0]->add_route(0, m_mixer, 1.00, AUTO_ALLOC_INPUT, 0);
|
||||
m_ymf278b[0]->add_route(1, m_mixer, 1.00, AUTO_ALLOC_INPUT, 1);
|
||||
m_ymf278b[0]->add_route(2, m_mixer, 1.00, AUTO_ALLOC_INPUT, 0);
|
||||
m_ymf278b[0]->add_route(3, m_mixer, 1.00, AUTO_ALLOC_INPUT, 1);
|
||||
m_ymf278b[0]->add_route(4, m_mixer, 1.00, AUTO_ALLOC_INPUT, 0);
|
||||
m_ymf278b[0]->add_route(5, m_mixer, 1.00, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
YMF278B(config, m_ymf278b[1], 0);
|
||||
m_ymf278b[1]->set_addrmap(0, &vgmplay_state::ymf278b_map<1>);
|
||||
m_ymf278b[1]->add_route(0, "lspeaker", 1.00);
|
||||
m_ymf278b[1]->add_route(1, "rspeaker", 1.00);
|
||||
m_ymf278b[1]->add_route(2, "lspeaker", 1.00);
|
||||
m_ymf278b[1]->add_route(3, "rspeaker", 1.00);
|
||||
m_ymf278b[1]->add_route(4, "lspeaker", 1.00);
|
||||
m_ymf278b[1]->add_route(5, "rspeaker", 1.00);
|
||||
m_ymf278b[1]->add_route(0, m_mixer, 1.00, AUTO_ALLOC_INPUT, 0);
|
||||
m_ymf278b[1]->add_route(1, m_mixer, 1.00, AUTO_ALLOC_INPUT, 1);
|
||||
m_ymf278b[1]->add_route(2, m_mixer, 1.00, AUTO_ALLOC_INPUT, 0);
|
||||
m_ymf278b[1]->add_route(3, m_mixer, 1.00, AUTO_ALLOC_INPUT, 1);
|
||||
m_ymf278b[1]->add_route(4, m_mixer, 1.00, AUTO_ALLOC_INPUT, 0);
|
||||
m_ymf278b[1]->add_route(5, m_mixer, 1.00, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
YMF271(config, m_ymf271[0], 0);
|
||||
m_ymf271[0]->set_addrmap(0, &vgmplay_state::ymf271_map<0>);
|
||||
m_ymf271[0]->add_route(0, "lspeaker", 0.25);
|
||||
m_ymf271[0]->add_route(1, "rspeaker", 0.25);
|
||||
m_ymf271[0]->add_route(2, "lspeaker", 0.25);
|
||||
m_ymf271[0]->add_route(3, "rspeaker", 0.25);
|
||||
m_ymf271[0]->add_route(0, m_mixer, 0.25, AUTO_ALLOC_INPUT, 0);
|
||||
m_ymf271[0]->add_route(1, m_mixer, 0.25, AUTO_ALLOC_INPUT, 1);
|
||||
m_ymf271[0]->add_route(2, m_mixer, 0.25, AUTO_ALLOC_INPUT, 0);
|
||||
m_ymf271[0]->add_route(3, m_mixer, 0.25, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
YMF271(config, m_ymf271[1], 0);
|
||||
m_ymf271[1]->set_addrmap(0, &vgmplay_state::ymf271_map<0>);
|
||||
m_ymf271[1]->add_route(0, "lspeaker", 0.25);
|
||||
m_ymf271[1]->add_route(1, "rspeaker", 0.25);
|
||||
m_ymf271[1]->add_route(2, "lspeaker", 0.25);
|
||||
m_ymf271[1]->add_route(3, "rspeaker", 0.25);
|
||||
m_ymf271[1]->add_route(0, m_mixer, 0.25, AUTO_ALLOC_INPUT, 0);
|
||||
m_ymf271[1]->add_route(1, m_mixer, 0.25, AUTO_ALLOC_INPUT, 1);
|
||||
m_ymf271[1]->add_route(2, m_mixer, 0.25, AUTO_ALLOC_INPUT, 0);
|
||||
m_ymf271[1]->add_route(3, m_mixer, 0.25, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
// TODO: prevent error.log spew
|
||||
YMZ280B(config, m_ymz280b[0], 0);
|
||||
m_ymz280b[0]->set_addrmap(0, &vgmplay_state::ymz280b_map<0>);
|
||||
m_ymz280b[0]->add_route(0, "lspeaker", 0.25);
|
||||
m_ymz280b[0]->add_route(1, "rspeaker", 0.25);
|
||||
m_ymz280b[0]->add_route(0, m_mixer, 0.25, AUTO_ALLOC_INPUT, 0);
|
||||
m_ymz280b[0]->add_route(1, m_mixer, 0.25, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
YMZ280B(config, m_ymz280b[1], 0);
|
||||
m_ymz280b[1]->set_addrmap(0, &vgmplay_state::ymz280b_map<1>);
|
||||
m_ymz280b[1]->add_route(0, "lspeaker", 0.25);
|
||||
m_ymz280b[1]->add_route(1, "rspeaker", 0.25);
|
||||
m_ymz280b[1]->add_route(0, m_mixer, 0.25, AUTO_ALLOC_INPUT, 0);
|
||||
m_ymz280b[1]->add_route(1, m_mixer, 0.25, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
RF5C164(config, m_rf5c164, 0);
|
||||
m_rf5c164->set_addrmap(0, &vgmplay_state::rf5c164_map<0>);
|
||||
m_rf5c164->add_route(0, "lspeaker", 1);
|
||||
m_rf5c164->add_route(1, "rspeaker", 1);
|
||||
m_rf5c164->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_rf5c164->add_route(1, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
/// TODO: rewrite to generate audio without using DAC devices
|
||||
SEGA_32X_NTSC(config, m_sega32x, 0, "sega32x_maincpu", "sega32x_scanline_timer");
|
||||
m_sega32x->add_route(0, "lspeaker", 1.00);
|
||||
m_sega32x->add_route(1, "rspeaker", 1.00);
|
||||
m_sega32x->add_route(0, m_mixer, 1.00, AUTO_ALLOC_INPUT, 0);
|
||||
m_sega32x->add_route(1, m_mixer, 1.00, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
auto& sega32x_maincpu(M68000(config, "sega32x_maincpu", 0));
|
||||
sega32x_maincpu.set_disable();
|
||||
@ -3653,228 +3656,232 @@ void vgmplay_state::vgmplay(machine_config &config)
|
||||
|
||||
// TODO: prevent error.log spew
|
||||
AY8910(config, m_ay8910[0], 0);
|
||||
m_ay8910[0]->add_route(ALL_OUTPUTS, "lspeaker", 0.33);
|
||||
m_ay8910[0]->add_route(ALL_OUTPUTS, "rspeaker", 0.33);
|
||||
m_ay8910[0]->add_route(ALL_OUTPUTS, m_mixer, 0.33, AUTO_ALLOC_INPUT, 0);
|
||||
m_ay8910[0]->add_route(ALL_OUTPUTS, m_mixer, 0.33, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
AY8910(config, m_ay8910[1], 0);
|
||||
m_ay8910[1]->add_route(ALL_OUTPUTS, "lspeaker", 0.33);
|
||||
m_ay8910[1]->add_route(ALL_OUTPUTS, "rspeaker", 0.33);
|
||||
m_ay8910[1]->add_route(ALL_OUTPUTS, m_mixer, 0.33, AUTO_ALLOC_INPUT, 0);
|
||||
m_ay8910[1]->add_route(ALL_OUTPUTS, m_mixer, 0.33, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
DMG_APU(config, m_dmg[0], 0);
|
||||
m_dmg[0]->add_route(0, "lspeaker", 1);
|
||||
m_dmg[0]->add_route(0, "rspeaker", 1);
|
||||
m_dmg[0]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_dmg[0]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
DMG_APU(config, m_dmg[1], 0);
|
||||
m_dmg[1]->add_route(0, "lspeaker", 1);
|
||||
m_dmg[1]->add_route(0, "rspeaker", 1);
|
||||
m_dmg[1]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_dmg[1]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
N2A03(config, m_nescpu[0], 0);
|
||||
m_nescpu[0]->set_addrmap(AS_PROGRAM, &vgmplay_state::nescpu_map<0>);
|
||||
m_nescpu[0]->set_disable();
|
||||
m_nescpu[0]->add_route(ALL_OUTPUTS, "lspeaker", 0.50);
|
||||
m_nescpu[0]->add_route(ALL_OUTPUTS, "rspeaker", 0.50);
|
||||
m_nescpu[0]->add_route(ALL_OUTPUTS, m_mixer, 0.50, AUTO_ALLOC_INPUT, 0);
|
||||
m_nescpu[0]->add_route(ALL_OUTPUTS, m_mixer, 0.50, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
N2A03(config, m_nescpu[1], 0);
|
||||
m_nescpu[1]->set_addrmap(AS_PROGRAM, &vgmplay_state::nescpu_map<1>);
|
||||
m_nescpu[1]->set_disable();
|
||||
m_nescpu[1]->add_route(ALL_OUTPUTS, "lspeaker", 0.50);
|
||||
m_nescpu[1]->add_route(ALL_OUTPUTS, "rspeaker", 0.50);
|
||||
m_nescpu[1]->add_route(ALL_OUTPUTS, m_mixer, 0.50, AUTO_ALLOC_INPUT, 0);
|
||||
m_nescpu[1]->add_route(ALL_OUTPUTS, m_mixer, 0.50, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
MULTIPCM(config, m_multipcm[0], 0);
|
||||
m_multipcm[0]->set_addrmap(0, &vgmplay_state::multipcm_map<0>);
|
||||
m_multipcm[0]->add_route(0, "lspeaker", 1);
|
||||
m_multipcm[0]->add_route(1, "rspeaker", 1);
|
||||
m_multipcm[0]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_multipcm[0]->add_route(1, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
MULTIPCM(config, m_multipcm[1], 0);
|
||||
m_multipcm[1]->set_addrmap(0, &vgmplay_state::multipcm_map<1>);
|
||||
m_multipcm[1]->add_route(0, "lspeaker", 1);
|
||||
m_multipcm[1]->add_route(1, "rspeaker", 1);
|
||||
m_multipcm[1]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_multipcm[1]->add_route(1, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
UPD7759(config, m_upd7759[0], 0);
|
||||
m_upd7759[0]->drq().set(FUNC(vgmplay_state::upd7759_drq_w<0>));
|
||||
m_upd7759[0]->set_addrmap(0, &vgmplay_state::upd7759_map<0>);
|
||||
m_upd7759[0]->add_route(ALL_OUTPUTS, "lspeaker", 1.0);
|
||||
m_upd7759[0]->add_route(ALL_OUTPUTS, "rspeaker", 1.0);
|
||||
m_upd7759[0]->add_route(ALL_OUTPUTS, m_mixer, 1.0, AUTO_ALLOC_INPUT, 0);
|
||||
m_upd7759[0]->add_route(ALL_OUTPUTS, m_mixer, 1.0, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
UPD7759(config, m_upd7759[1], 0);
|
||||
m_upd7759[1]->drq().set(FUNC(vgmplay_state::upd7759_drq_w<1>));
|
||||
m_upd7759[1]->set_addrmap(0, &vgmplay_state::upd7759_map<1>);
|
||||
m_upd7759[1]->add_route(ALL_OUTPUTS, "lspeaker", 1.0);
|
||||
m_upd7759[1]->add_route(ALL_OUTPUTS, "rspeaker", 1.0);
|
||||
m_upd7759[1]->add_route(ALL_OUTPUTS, m_mixer, 1.0, AUTO_ALLOC_INPUT, 0);
|
||||
m_upd7759[1]->add_route(ALL_OUTPUTS, m_mixer, 1.0, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
OKIM6258(config, m_okim6258[0], 0);
|
||||
m_okim6258[0]->add_route(ALL_OUTPUTS, "lspeaker", 0.5);
|
||||
m_okim6258[0]->add_route(ALL_OUTPUTS, "rspeaker", 0.5);
|
||||
m_okim6258[0]->add_route(ALL_OUTPUTS, m_mixer, 0.5, AUTO_ALLOC_INPUT, 0);
|
||||
m_okim6258[0]->add_route(ALL_OUTPUTS, m_mixer, 0.5, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
OKIM6258(config, m_okim6258[1], 0);
|
||||
m_okim6258[1]->add_route(ALL_OUTPUTS, "lspeaker", 0.5);
|
||||
m_okim6258[1]->add_route(ALL_OUTPUTS, "rspeaker", 0.5);
|
||||
m_okim6258[1]->add_route(ALL_OUTPUTS, m_mixer, 0.5, AUTO_ALLOC_INPUT, 0);
|
||||
m_okim6258[1]->add_route(ALL_OUTPUTS, m_mixer, 0.5, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
OKIM6295(config, m_okim6295[0], 0, okim6295_device::PIN7_HIGH);
|
||||
m_okim6295[0]->set_addrmap(0, &vgmplay_state::okim6295_map<0>);
|
||||
m_okim6295[0]->add_route(ALL_OUTPUTS, "lspeaker", 0.25);
|
||||
m_okim6295[0]->add_route(ALL_OUTPUTS, "rspeaker", 0.25);
|
||||
m_okim6295[0]->add_route(ALL_OUTPUTS, m_mixer, 0.25, AUTO_ALLOC_INPUT, 0);
|
||||
m_okim6295[0]->add_route(ALL_OUTPUTS, m_mixer, 0.25, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
OKIM6295(config, m_okim6295[1], 0, okim6295_device::PIN7_HIGH);
|
||||
m_okim6295[1]->set_addrmap(0, &vgmplay_state::okim6295_map<1>);
|
||||
m_okim6295[1]->add_route(ALL_OUTPUTS, "lspeaker", 0.25);
|
||||
m_okim6295[1]->add_route(ALL_OUTPUTS, "rspeaker", 0.25);
|
||||
m_okim6295[1]->add_route(ALL_OUTPUTS, m_mixer, 0.25, AUTO_ALLOC_INPUT, 0);
|
||||
m_okim6295[1]->add_route(ALL_OUTPUTS, m_mixer, 0.25, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
K051649(config, m_k051649[0], 0);
|
||||
m_k051649[0]->add_route(ALL_OUTPUTS, "lspeaker", 0.33);
|
||||
m_k051649[0]->add_route(ALL_OUTPUTS, "rspeaker", 0.33);
|
||||
m_k051649[0]->add_route(ALL_OUTPUTS, m_mixer, 0.33, AUTO_ALLOC_INPUT, 0);
|
||||
m_k051649[0]->add_route(ALL_OUTPUTS, m_mixer, 0.33, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
K051649(config, m_k051649[1], 0);
|
||||
m_k051649[1]->add_route(ALL_OUTPUTS, "lspeaker", 0.33);
|
||||
m_k051649[1]->add_route(ALL_OUTPUTS, "rspeaker", 0.33);
|
||||
m_k051649[1]->add_route(ALL_OUTPUTS, m_mixer, 0.33, AUTO_ALLOC_INPUT, 0);
|
||||
m_k051649[1]->add_route(ALL_OUTPUTS, m_mixer, 0.33, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
K054539(config, m_k054539[0], 0);
|
||||
m_k054539[0]->set_addrmap(0, &vgmplay_state::k054539_map<0>);
|
||||
m_k054539[0]->add_route(0, "lspeaker", 1);
|
||||
m_k054539[0]->add_route(1, "rspeaker", 1);
|
||||
m_k054539[0]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_k054539[0]->add_route(1, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
K054539(config, m_k054539[1], 0);
|
||||
m_k054539[1]->set_addrmap(0, &vgmplay_state::k054539_map<1>);
|
||||
m_k054539[1]->add_route(0, "lspeaker", 1);
|
||||
m_k054539[1]->add_route(1, "rspeaker", 1);
|
||||
m_k054539[1]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_k054539[1]->add_route(1, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
// TODO: prevent error.log spew
|
||||
H6280(config, m_huc6280[0], 0);
|
||||
m_huc6280[0]->set_disable();
|
||||
m_huc6280[0]->add_route(0, "lspeaker", 1);
|
||||
m_huc6280[0]->add_route(1, "rspeaker", 1);
|
||||
m_huc6280[0]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_huc6280[0]->add_route(1, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
H6280(config, m_huc6280[1], 0);
|
||||
m_huc6280[1]->set_disable();
|
||||
m_huc6280[1]->add_route(0, "lspeaker", 1);
|
||||
m_huc6280[1]->add_route(1, "rspeaker", 1);
|
||||
m_huc6280[1]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_huc6280[1]->add_route(1, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
C140(config, m_c140[0], 0);
|
||||
m_c140[0]->set_addrmap(0, &vgmplay_state::c140_map<0>);
|
||||
m_c140[0]->add_route(0, "lspeaker", 0.50);
|
||||
m_c140[0]->add_route(1, "rspeaker", 0.50);
|
||||
m_c140[0]->add_route(0, m_mixer, 0.50, AUTO_ALLOC_INPUT, 0);
|
||||
m_c140[0]->add_route(1, m_mixer, 0.50, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
C140(config, m_c140[1], 0);
|
||||
m_c140[1]->set_addrmap(0, &vgmplay_state::c140_map<1>);
|
||||
m_c140[1]->add_route(0, "lspeaker", 0.50);
|
||||
m_c140[1]->add_route(1, "rspeaker", 0.50);
|
||||
m_c140[1]->add_route(0, m_mixer, 0.50, AUTO_ALLOC_INPUT, 0);
|
||||
m_c140[1]->add_route(1, m_mixer, 0.50, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
K053260(config, m_k053260[0], 0);
|
||||
m_k053260[0]->set_addrmap(0, &vgmplay_state::k053260_map<0>);
|
||||
m_k053260[0]->add_route(0, "lspeaker", 1);
|
||||
m_k053260[0]->add_route(1, "rspeaker", 1);
|
||||
m_k053260[0]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_k053260[0]->add_route(1, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
K053260(config, m_k053260[1], 0);
|
||||
m_k053260[1]->set_addrmap(0, &vgmplay_state::k053260_map<1>);
|
||||
m_k053260[1]->add_route(0, "lspeaker", 1);
|
||||
m_k053260[1]->add_route(1, "rspeaker", 1);
|
||||
m_k053260[1]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_k053260[1]->add_route(1, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
POKEY(config, m_pokey[0], 0);
|
||||
m_pokey[0]->add_route(ALL_OUTPUTS, "lspeaker", 0.5);
|
||||
m_pokey[0]->add_route(ALL_OUTPUTS, "rspeaker", 0.5);
|
||||
m_pokey[0]->add_route(ALL_OUTPUTS, m_mixer, 0.5, AUTO_ALLOC_INPUT, 0);
|
||||
m_pokey[0]->add_route(ALL_OUTPUTS, m_mixer, 0.5, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
POKEY(config, m_pokey[1], 0);
|
||||
m_pokey[1]->add_route(ALL_OUTPUTS, "lspeaker", 0.5);
|
||||
m_pokey[1]->add_route(ALL_OUTPUTS, "rspeaker", 0.5);
|
||||
m_pokey[1]->add_route(ALL_OUTPUTS, m_mixer, 0.5, AUTO_ALLOC_INPUT, 0);
|
||||
m_pokey[1]->add_route(ALL_OUTPUTS, m_mixer, 0.5, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
QSOUND(config, m_qsound, 0);
|
||||
m_qsound->set_addrmap(0, &vgmplay_state::qsound_map<0>);
|
||||
m_qsound->add_route(0, "lspeaker", 1);
|
||||
m_qsound->add_route(1, "rspeaker", 1);
|
||||
m_qsound->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_qsound->add_route(1, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
SCSP(config, m_scsp[0], 0);
|
||||
m_scsp[0]->set_addrmap(0, &vgmplay_state::scsp_map<0>);
|
||||
m_scsp[0]->add_route(0, "lspeaker", 1);
|
||||
m_scsp[0]->add_route(1, "rspeaker", 1);
|
||||
m_scsp[0]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_scsp[0]->add_route(1, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
SCSP(config, m_scsp[1], 0);
|
||||
m_scsp[1]->set_addrmap(0, &vgmplay_state::scsp_map<1>);
|
||||
m_scsp[1]->add_route(0, "lspeaker", 1);
|
||||
m_scsp[1]->add_route(1, "rspeaker", 1);
|
||||
m_scsp[1]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_scsp[1]->add_route(1, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
WSWAN_SND(config, m_wswan[0], 0);
|
||||
m_wswan[0]->set_addrmap(0, &vgmplay_state::wswan_map<0>);
|
||||
m_wswan[0]->add_route(0, "lspeaker", 0.50);
|
||||
m_wswan[0]->add_route(1, "rspeaker", 0.50);
|
||||
m_wswan[0]->add_route(0, m_mixer, 0.50, AUTO_ALLOC_INPUT, 0);
|
||||
m_wswan[0]->add_route(1, m_mixer, 0.50, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
WSWAN_SND(config, m_wswan[1], 0);
|
||||
m_wswan[1]->set_addrmap(0, &vgmplay_state::wswan_map<1>);
|
||||
m_wswan[1]->add_route(0, "lspeaker", 0.50);
|
||||
m_wswan[1]->add_route(1, "rspeaker", 0.50);
|
||||
m_wswan[1]->add_route(0, m_mixer, 0.50, AUTO_ALLOC_INPUT, 0);
|
||||
m_wswan[1]->add_route(1, m_mixer, 0.50, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
VBOYSND(config, m_vsu_vue[0], 0);
|
||||
m_vsu_vue[0]->add_route(0, "lspeaker", 1.0);
|
||||
m_vsu_vue[0]->add_route(1, "rspeaker", 1.0);
|
||||
m_vsu_vue[0]->add_route(0, m_mixer, 1.0, AUTO_ALLOC_INPUT, 0);
|
||||
m_vsu_vue[0]->add_route(1, m_mixer, 1.0, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
VBOYSND(config, m_vsu_vue[1], 0);
|
||||
m_vsu_vue[1]->add_route(0, "lspeaker", 1.0);
|
||||
m_vsu_vue[1]->add_route(1, "rspeaker", 1.0);
|
||||
m_vsu_vue[1]->add_route(0, m_mixer, 1.0, AUTO_ALLOC_INPUT, 0);
|
||||
m_vsu_vue[1]->add_route(1, m_mixer, 1.0, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
SAA1099(config, m_saa1099[0], 0);
|
||||
m_saa1099[0]->add_route(ALL_OUTPUTS, "lspeaker", 0.5);
|
||||
m_saa1099[0]->add_route(ALL_OUTPUTS, "rspeaker", 0.5);
|
||||
m_saa1099[0]->add_route(ALL_OUTPUTS, m_mixer, 0.5, AUTO_ALLOC_INPUT, 0);
|
||||
m_saa1099[0]->add_route(ALL_OUTPUTS, m_mixer, 0.5, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
SAA1099(config, m_saa1099[1], 0);
|
||||
m_saa1099[1]->add_route(ALL_OUTPUTS, "lspeaker", 0.5);
|
||||
m_saa1099[1]->add_route(ALL_OUTPUTS, "rspeaker", 0.5);
|
||||
m_saa1099[1]->add_route(ALL_OUTPUTS, m_mixer, 0.5, AUTO_ALLOC_INPUT, 0);
|
||||
m_saa1099[1]->add_route(ALL_OUTPUTS, m_mixer, 0.5, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
ES5503(config, m_es5503[0], 0);
|
||||
m_es5503[0]->set_channels(2);
|
||||
m_es5503[0]->set_addrmap(0, &vgmplay_state::es5503_map<0>);
|
||||
m_es5503[0]->add_route(ALL_OUTPUTS, "lspeaker", 0.5);
|
||||
m_es5503[0]->add_route(ALL_OUTPUTS, "rspeaker", 0.5);
|
||||
m_es5503[0]->add_route(ALL_OUTPUTS, m_mixer, 0.5, AUTO_ALLOC_INPUT, 0);
|
||||
m_es5503[0]->add_route(ALL_OUTPUTS, m_mixer, 0.5, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
ES5503(config, m_es5503[1], 0);
|
||||
m_es5503[1]->set_channels(2);
|
||||
m_es5503[1]->set_addrmap(0, &vgmplay_state::es5503_map<1>);
|
||||
m_es5503[1]->add_route(ALL_OUTPUTS, "lspeaker", 0.5);
|
||||
m_es5503[1]->add_route(ALL_OUTPUTS, "rspeaker", 0.5);
|
||||
m_es5503[1]->add_route(ALL_OUTPUTS, m_mixer, 0.5, AUTO_ALLOC_INPUT, 0);
|
||||
m_es5503[1]->add_route(ALL_OUTPUTS, m_mixer, 0.5, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
ES5505(config, m_es5505[0], 0);
|
||||
// TODO m_es5505[0]->set_addrmap(0, &vgmplay_state::es5505_map<0>);
|
||||
m_es5505[0]->set_channels(1);
|
||||
m_es5505[0]->add_route(0, "lspeaker", 0.5);
|
||||
m_es5505[0]->add_route(1, "rspeaker", 0.5);
|
||||
m_es5505[0]->add_route(0, m_mixer, 0.5, AUTO_ALLOC_INPUT, 0);
|
||||
m_es5505[0]->add_route(1, m_mixer, 0.5, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
ES5505(config, m_es5505[1], 0);
|
||||
// TODO m_es5505[1]->set_addrmap(0, &vgmplay_state::es5505_map<1>);
|
||||
m_es5505[1]->set_channels(1);
|
||||
m_es5505[1]->add_route(0, "lspeaker", 0.5);
|
||||
m_es5505[1]->add_route(1, "rspeaker", 0.5);
|
||||
m_es5505[1]->add_route(0, m_mixer, 0.5, AUTO_ALLOC_INPUT, 0);
|
||||
m_es5505[1]->add_route(1, m_mixer, 0.5, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
X1_010(config, m_x1_010[0], 0);
|
||||
m_x1_010[0]->set_addrmap(0, &vgmplay_state::x1_010_map<0>);
|
||||
m_x1_010[0]->add_route(0, "lspeaker", 1);
|
||||
m_x1_010[0]->add_route(1, "rspeaker", 1);
|
||||
m_x1_010[0]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_x1_010[0]->add_route(1, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
X1_010(config, m_x1_010[1], 0);
|
||||
m_x1_010[1]->set_addrmap(0, &vgmplay_state::x1_010_map<1>);
|
||||
m_x1_010[1]->add_route(0, "lspeaker", 1);
|
||||
m_x1_010[1]->add_route(1, "rspeaker", 1);
|
||||
m_x1_010[1]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_x1_010[1]->add_route(1, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
C352(config, m_c352[0], 0, 1);
|
||||
m_c352[0]->set_addrmap(0, &vgmplay_state::c352_map<0>);
|
||||
m_c352[0]->add_route(0, "lspeaker", 1);
|
||||
m_c352[0]->add_route(1, "rspeaker", 1);
|
||||
m_c352[0]->add_route(2, "lspeaker", 1);
|
||||
m_c352[0]->add_route(3, "rspeaker", 1);
|
||||
m_c352[0]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_c352[0]->add_route(1, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
m_c352[0]->add_route(2, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_c352[0]->add_route(3, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
C352(config, m_c352[1], 0, 1);
|
||||
m_c352[1]->set_addrmap(0, &vgmplay_state::c352_map<1>);
|
||||
m_c352[1]->add_route(0, "lspeaker", 1);
|
||||
m_c352[1]->add_route(1, "rspeaker", 1);
|
||||
m_c352[1]->add_route(2, "lspeaker", 1);
|
||||
m_c352[1]->add_route(3, "rspeaker", 1);
|
||||
m_c352[1]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_c352[1]->add_route(1, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
m_c352[1]->add_route(2, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_c352[1]->add_route(3, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
IREMGA20(config, m_ga20[0], 0);
|
||||
m_ga20[0]->set_addrmap(0, &vgmplay_state::ga20_map<0>);
|
||||
m_ga20[0]->add_route(0, "lspeaker", 1);
|
||||
m_ga20[0]->add_route(1, "rspeaker", 1);
|
||||
m_ga20[0]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_ga20[0]->add_route(1, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
IREMGA20(config, m_ga20[1], 0);
|
||||
m_ga20[1]->set_addrmap(0, &vgmplay_state::ga20_map<1>);
|
||||
m_ga20[1]->add_route(0, "lspeaker", 1);
|
||||
m_ga20[1]->add_route(1, "rspeaker", 1);
|
||||
m_ga20[1]->add_route(0, m_mixer, 1, AUTO_ALLOC_INPUT, 0);
|
||||
m_ga20[1]->add_route(1, m_mixer, 1, AUTO_ALLOC_INPUT, 1);
|
||||
|
||||
VGMVIZ(config, m_mixer, 0);
|
||||
m_mixer->add_route(0, "lspeaker", 1);
|
||||
m_mixer->add_route(1, "rspeaker", 1);
|
||||
|
||||
SPEAKER(config, m_lspeaker).front_left();
|
||||
SPEAKER(config, m_rspeaker).front_right();
|
||||
|
@ -215,9 +215,7 @@
|
||||
<cpanel element="act_label_ga20"><bounds x="49" y="22.2" width="10" height="1.6" /></cpanel>
|
||||
</group>
|
||||
|
||||
<view name="Internal Layout">
|
||||
<bounds left="0" right="60" top="0" bottom="55" />
|
||||
|
||||
<group name="lights">
|
||||
<cpanel element="static_black2"><bounds x="0" y="4" width="11" height="5" /></cpanel>
|
||||
<cpanel element="static_black2"><bounds x="12" y="4" width="11" height="5" /></cpanel>
|
||||
<cpanel element="static_black2"><bounds x="24" y="4" width="11" height="5" /></cpanel>
|
||||
@ -237,5 +235,14 @@
|
||||
<cpanel element="hl1" inputtag="CONTROLS" inputmask="0x0010"><bounds x="48" y="4" width="11" height="5" /><color alpha="0.15" /></cpanel>
|
||||
|
||||
<group ref="activity"><bounds x="0" y="21" width="60" height="34" /></group>
|
||||
</group>
|
||||
|
||||
<view name="Full View">
|
||||
<group ref="lights"><bounds x="0" y="0" width="60" height="55" /></group>
|
||||
<screen index="0"><bounds x="60" y="0" width="60" height="55" /></screen>
|
||||
</view>
|
||||
|
||||
<view name="Lights + Controls">
|
||||
<group ref="lights"><bounds x="0" y="0" width="60" height="55" /></group>
|
||||
</view>
|
||||
</mamelayout>
|
||||
|
Loading…
Reference in New Issue
Block a user