diff options
| author | 2025-06-25 03:56:09 +1000 | |
|---|---|---|
| committer | 2025-06-25 03:56:09 +1000 | |
| commit | af10f3f21cc03a6dcbfde08850f640e26d9cbb9f (patch) | |
| tree | 05895657ff111b3f0ad10640f6ad0cb253cdfadb | |
| parent | 72251989ad8df6f6a1f401c56a1b02ec60938e25 (diff) | |
Various fixes:
ui: The new menus were unusable with a touchscreen, and not conducive to
localisation. It's still not possible to add sound routes with a
touchscreen, but at least it's possible to configure routes that exist.
emu/sound.cpp: Fixed localisation issues, less temporary objects.
emu/audio_effects: Fixed some localisation issues.
plugins/autofire, plugins/inputmacro: Allow deleting autofire buttons or
input macros without needing to use the UI Clear input.
ui/selmenu.cpp, ui/imgcntrl.cpp: Use terse messages for bad media.
Making these messages longer hasn't reduced support burden. Adding the
version will just perpetuate the myth that you need to redownload all
your ROMs for every release.
ui/ui.cpp: Allow info screens to be dismissed by mouse clicks or
touches.
ui/sliders.cpp: Hiding the menu should preserve state. This is a design
choice.
sound: Avoid anything that could possibly depend on static
initialisation order across transaltion units. Allow speaker position
names to be localised.
sound/none.cpp: Don't pretend it can create output streams.
42 files changed, 1873 insertions, 1375 deletions
diff --git a/docs/source/plugins/autofire.rst b/docs/source/plugins/autofire.rst index 2cb974626d2..5dd8eb21cf0 100644 --- a/docs/source/plugins/autofire.rst +++ b/docs/source/plugins/autofire.rst @@ -44,11 +44,10 @@ The options for adding a new autofire button or modifying an existing autofire button are the same. Select **Input** to set the emulated button that you want to simulate pressing -repeatedly. Currently, only player buttons are supported. Typically you’ll set -this to the primary fire button for shooting games. This is most often *P1 -Button 1* or the equivalent for another player, but it might have a -different name. On Konami’s Gradius games, *P1 Button 2* is the primary fire -button. +repeatedly. Only digital inputs are supported. Typically you’ll set this to +the primary fire button for shooting games. This is most often *P1 Button 1* +or the equivalent for another player, but it might have a different name. On +Konami’s Gradius games, *P1 Button 2* is the primary fire button. Select **Hotkey** to set the control (or combination of controls) you’ll use to activate the autofire button. This can be any combination that MAME supports @@ -75,6 +74,13 @@ When modifying an existing autofire button, select **Done** or press the UI Cancel key to return to the list of autofire buttons. Changes take effect immediately. +When modifying an existing autofire button, select **Delete** to delete the +autofire button. The autofire button will be deleted immediately when you +select **Delete** without requiring additional confirmation. You can also +delete an autofire button by highlighting it in the list of autofire buttons +and pressing the UI Clear key (Del/Delete/Forward Delete on the keyboard by +default). + .. _plugins-autofire-notes: diff --git a/docs/source/plugins/inputmacro.rst b/docs/source/plugins/inputmacro.rst index 959faa05fbe..c83e9e00de6 100644 --- a/docs/source/plugins/inputmacro.rst +++ b/docs/source/plugins/inputmacro.rst @@ -24,7 +24,9 @@ their activation sequences (initially there will be no input macros configured). Select a macro to edit it, or choose **Add macro** to set up a new input macro. See :ref:`plugins-inputmacro-settings` for details on editing input macros. You can delete an input macro by highlighting it in the menu and pressing the UI -Clear key (Del/Delete/Forward Delete on the keyboard by default). +Clear key (Del/Delete/Forward Delete on the keyboard by default). You can also +delete a macro by selecting the macro to edit it and then selecting **Delete +macro** from the menu. Input macros are saved in the **inputmacro** folder in the plugin data folder (see the :ref:`homepath option <mame-commandline-homepath>`). A file is created @@ -119,6 +121,12 @@ new macro. When editing an existing macro, select **Done** or press the UI Back key to return to the list of input macros. Changes take effect immediately. +When editing an existing macro, select **Delete macro** to delete the macro. +The macro will be deleted immediately when you select **Delete macro** without +requiring additional confirmation. You can also delete a macro by highlighting +it in the list of macros and pressing the UI Clear key (Del/Delete/Forward +Delete on the keyboard by default). + .. _plugins-inputmacro-examples: diff --git a/docs/source/usingmame/mamemenus.rst b/docs/source/usingmame/mamemenus.rst index 3198f2927f4..1a174c72791 100644 --- a/docs/source/usingmame/mamemenus.rst +++ b/docs/source/usingmame/mamemenus.rst @@ -111,13 +111,12 @@ Network Devices adapters that support bridging to a host network. This item is not shown if there are no network adaptors that support bridging in the running system. Audio Mixer - Shows the :ref:`Audio Mixer <menus-audiomixer>` menu, where you - decide how to connect your system audio inputs and outputs to the - emulated system's microphones and speakers. + Shows the :ref:`Audio Mixer <menus-audiomixer>` menu, where you configure + how MAME routes sound from the emulated system to host system sound outputs, + and from host system sound inputs to the emulated system. Audio Effects - Shows the :ref:`Audio Effects <menus-audioeffects>` menu, which - allows to configure the audio effects applied between the emulated - system's speakers and the actual system audio outputs. + Shows the :ref:`Audio Effects <menus-audioeffects>` menu, where you can + configure audio effects applied to emulated sound output. Slider Controls Shows the Slider Controls menu, where you can adjust various settings, including video adjustments and individual sound channel levels. @@ -300,34 +299,53 @@ ID** to copy the device’s ID to the clipboard. This is useful for setting up Audio Mixer menu ---------------- -The Audio Mixer menu allows to establish connections between emulated -speakers and microphones, and system audio inputs and outputs. It -uses the standard up/down arrows to select a device and/or current -mapping, left/right arrows to change a value (system audio port, -level, channel...) and [ ] to change column. In addition the (by -default) F key adds a full mapping, C a channel mapping, and Delete -clears a mapping. - -A full mapping sends all channels of a speaker to the appropriate(s) -channel(s) of the system output, and similarly retrieves all channels -of a microphone from the appropriate(s) input(s) of a system input. -For instance a mono speaker will send audio to both channels of a -stereo system output. - -A channel mapping maps between one channel of speaker or a microphone -and one channel of a system input or output. It can be a little -tedious, but it allows for instance to take two mono speakers and turn -it into the left and right channels of a system output, which is -useful for some cabinets. - -Every mapping has a configurable volume associated. When changing the -volume, optionally hold shift/ctrl/alt keys to adjust the step amount. - -The mapping configuration is saved in the system cfg file. - -Some OSes propose an external interface to change mappings and volumes -dynamically, for instance pipewire on linux. Mame does its best to -follow that and keep the information in the cfg file for future runs. +The Audio Mixer menu allows you to configure how MAME routes sound from emulated +speakers to system sound outputs, and from system sound inputs to emulated +microphones. There are two kinds of routes: *full routes*, and *channel +routes*: + +* A full output route sends sound from all channels of an emulated sound output + device to a host sound output. MAME automatically decides how to assign + emulated channels (typically speakers) to output channels, based on speaker + position information. +* Similarly, a full input route sends sound from a host sound input to all + channels of an emulated sound input device. MAME automatically decides how + to assign input channels to emulated channels (typically microphones), based + on microphone position information. +* A channel route sends sound from a single emulated sound output channel to a + single host sound output channel, or from a single host sound input channel to + a single emulated sound input channel. + +Only one full route is allowed for each combination of an emulated sound output +or input device and host sound output or input. Only one channel route is +allowed between an individual emulated channel and an individual host sound +channel. + +Routes are grouped by emulated device. For each device, full routes are listed +before channel routes. For each route, you can select the system sound output +or input and adjust the volume from -96 dB (quietest) to +12 dB (loudest). For +channel routes, you can also select the individual emulated channel and host +channel. Select **Delete route** to delete a route. + +To add a full route, highlight a menu item for the emulated device you want to +add the route for and press the UI Audio add full mapping key (F on the keyboard +by default). If possible, a full route will be added and the menu highlight +will move to the newly added route. If routes between the highlighted device +and every host output/input already exist, no route will be added. + +To add a channel route, highlight a menu item for the emulated device you want +to add the route for and press the UI Audio add channel mapping key (C on the +keyboard by default). If possible, a channel route will be added and the menu +highlight will move to the newly added route. If routes between all channels +for the highlighted device and every host output/input channel already exist, no +route will be added. + +Some sound modules allow channel assignments and volumes to be controlled using +an external mixer interface (for example the PipeWire module for Linux has this +capability). In these cases, MAME does its best to follow the changes you make +in the external mixer interface and save changes in its configuration. + +The audio routes are saved in the system configuration file. .. _menus-audioeffects: @@ -335,91 +353,91 @@ follow that and keep the information in the cfg file for future runs. Audio Effects menu ------------------ -This menu allows to configure the audio effects that are applied to -the speaker outputs between the speaker device and the audio mixer. -In other words, the output channels as seen in the audio mixer are the -outputs of the effect chains. Each speaker has an independent effect -chain applied. +The Audio Effects menu allows you to configure audio effects that are applied +to emulated sound output before it’s routed to host sound outputs. An +independent effect chain is applied for each emulated sound output device. -The chain itself is not configurable it is always in order: +The effect chain itself is not configurable. It always consists of these four +effects, in this order: * Filter * Compressor * Reverb -* EQ - -The parameters of each are fully configurable though. A configured -parameter shows as white, a default as grey, and Clear allows to go -back to the default value. The default parameters for the chain of a -given speaker are the parameters of the Default chain, and the default -parameters of the Default chain are fixed. The default chain allows -to create a global setup that one likes and have it applied everywhere -by default. - -In addition, this menu allows to choose the resampler to use when -converting sample rates between emulated devices. The type allows to -choose between a fast, lower quality one, "LoFi", and a slow, high -quality one "HQ". The HQ resampler is configurable. The latency -indicates the max latency of the resampler, which allows better -quality when higher, the filter length balances quality and speed -where a high value is highest quality but slowest speed, and phases -balances quality and resampler creation time, with once again higher -means better but slower. +* Parametric equaliser + +When editing parameters for an output device’s effect chain, inherited default +parameter values are showing dimmed, while parameter values set for that chain +are shown in the normal text colour. Press the UI Clear key (Del/Delete/Forward +Delete on the keyboard by default) to reset a parameter to use the inherited +default value. + +Edit the **Default** chain to set default parameter value that can be inherited +by output device chains. When editing the **Default** chain, you can restore +the built-in default value for a parameter by pressing the UI Clear key +(Del/Delete/Forward Delete on the keyboard by default). + +The Audio Events menu also allows you to configure the algorithm used for audio +sample rate conversion. The default **LoFi** algorithm has modest CPU +requirements. The **HQ** algorithm provides higher quality sample rate +conversion at the expense of requiring substantially higher CPU performance. +The **HQ** algorithm has additional parameters. Increasing the latency can +improve quality. Increasing the filter length or phases can improve quality at +the expense of higher CPU performance requirements. Filter effect ~~~~~~~~~~~~~ -This effect proposes an order-2 high-pass and order-2 low-pass filter. -The high-pass filter allows to remove the DC offset some emulated -hardware has which can create saturation when not needed. The -low-pass filter (defaulting to off) allows to reproduce how muffled -the sound of a number of cabinets and TVs were. +This effect implements a second-order high-pass filter and a second-order +low-pass filter. The high-pass filter allows DC offsets to be removed. The +low-pass filter can simulate the poor high-frequency response typical of many +arcade cabinets and television sets. -The Q factor defines how sharp the transition is, the higher the -sharper. Over 0.7 the filter starts amplifying the frequencies around -the cutoff though, which can be surprising. +The Q factor controls how sharp the transition from the stop band to the +passband is. Higher factors provide a sharper transition. Values over 0.7 +cause the filter to amplify frequencies close to the cutoff frequency, which +may be surprising or undesirable. -Compression effect +Compressor effect ~~~~~~~~~~~~~~~~~~ -This effect implements a somewhat complex compressor which is a -reimplementation of the Versatile Compressor by Alain Paul. The -general effect of a compressor is to amplify sounds under a volume -threshold while keeping the louder sounds as-is. It's particularly -useful when one is not in a very quiet environment and softer sounds -are just lost otherwise. +This effect provides dynamic range compression (it is based on a +reimplementation of Alain Paul’s Versatile Compressor). Dynamic range +compression reduces the difference in volume between the softest and loudest +sounds. It’s useful in a variety of situations, for example it can help make +quiet sounds more audible over background noise. The parameters are: -* Attack: reaction time to loud sounds to reduce the amplification. - -* Release: reaction time to allow the amplification to go back up. - -* Ratio: maximum amplification. - -* Input gain: amplification level at the input. - -* Output gain: amplification level at the output. - -* Convexity: shape of the relationship between distance to the - threshold and ratio value. Steeper the high it is. - -* Threshold: level at which the amplification fully stops. - -* Channel link: at 100 all channels of the same speaker are amplified - identically, at 0 they are fully independent, intermediate values - have intermediate behaviour. - -* Feedback: allows to loop back some of the output to the input. - -* Inertia: makes the ratio move slower. - -* Inertia decay: tweaks the impact of the inertia. - -* Ceiling: maximum allowed level at exit, just before the output - amplification. Does soft-clipping at that level. +Attack + The reaction time to loud sounds to reduce the amplification. +Release + The reaction time to allow the amplification to go back up. +Ratio + The maximum amplification. +Input gain + The amplification level at the input. +Output gain + The amplification level at the output. +Convexity + The shape of the relationship between distance to the threshold and ratio + value. Higher values give a steeper shape. +Threshold + The level at which the amplification fully stops. +Channel link + At 100%, all channels of an output device are amplified identically, while + at 0% they are fully independent. Intermediate values give intermediate + behaviour. +Feedback + Allows some of the output to be fed back to the input. +Inertia + Higher values make the ratio change more slowly. +Inertia decay + Tweaks the impact of the Inertia. +Ceiling + The maximum level allowed just before the output amplification. Causes + soft clipping at that level. Reverb effect @@ -428,13 +446,20 @@ Reverb effect Not implemented yet. -EQ effect -~~~~~~~~~ +Equaliser effect +~~~~~~~~~~~~~~~~ + +A five-band parametric equalizer, allowing to amplify or attenuate specific +frequency bands. -The 5-band parametric equalizer allows to amplify or reduce certain -bands of frequency in the spectrum. The three middle filters, and -also the extreme ones if configured as "Peak", change frequencies -around the cutoff. The Q factor selects the sharpness of the peak, -the higher the sharper. The extreme filters in "Shelf" mode move all -the frequencies under (or over) the cutoff frequency. +The three middle filters are bandpass/bandreject filters, meaning they amplify +or attenuate frequencies around the configured centre frequency. The first +and last filters can also be configured as bandpass/bandreject filter by setting +the mode to **Peak**. Setting the mode to **Shelf** causes the filter to +amplify or attenuate all frequencies below (for the first filter) or above (for +the last filter) the configured cutoff frequency. +The Q factor controls the sharpness of the peak or trough in frequency response +for bandpass/bandreject filters (the Q factor is not adjustable for **Shelf** +mode). Higher Q factors give a sharper shape, affecting a narrower range of +frequencies. diff --git a/plugins/autofire/autofire_menu.lua b/plugins/autofire/autofire_menu.lua index c53dd711f53..64ab58a5885 100644 --- a/plugins/autofire/autofire_menu.lua +++ b/plugins/autofire/autofire_menu.lua @@ -117,6 +117,7 @@ local function handle_main_menu(index, event, buttons) local section, adjusted_index = menu_section(index) if section == MENU_SECTIONS.CONTENT then if event == 'select' then + initial_button = adjusted_index main_selection_save = index current_button = buttons[adjusted_index] table.insert(menu_stack, MENU_TYPES.EDIT) @@ -235,6 +236,9 @@ local function populate_edit_menu() content_height = #menu table.insert(menu, {'---', '', ''}) + table.insert(menu, {_p('plugin-autofire', 'Delete'), '', ''}) + + table.insert(menu, {'---', '', ''}) table.insert(menu, {_p('plugin-autofire', 'Done'), '', ''}) local selection = configure_selection_save @@ -248,10 +252,20 @@ end local function handle_edit_menu(index, event, buttons) local section, adjusted_index = menu_section(index) - if ((section == MENU_SECTIONS.FOOTER) and (event == 'select')) or (event == 'back') then + if (section == MENU_SECTIONS.FOOTER) and (adjusted_index == 2) and (event == 'select') then + table.remove(buttons, initial_button) + if initial_button > #buttons then + main_selection_save = main_selection_save - 1 + end + initial_button = nil configure_menu_active = false table.remove(menu_stack) return true + elseif ((section == MENU_SECTIONS.FOOTER) and (event == 'select')) or (event == 'back') then + configure_menu_active = false + initial_button = nil + table.remove(menu_stack) + return true elseif section == MENU_SECTIONS.CONTENT then return handle_configure_menu(adjusted_index, event) end @@ -303,8 +317,13 @@ end local function populate_button_menu() local function is_supported_input(ioport_field) - -- IPT_BUTTON1 through IPT_BUTTON16 in ioport_type enum (ioport.h) - return ioport_field.type >= 64 and ioport_field.type <= 79 + if ioport_field.is_analog or ioport_field.is_toggle then + return false + elseif (ioport_field.type_class == 'config') or (ioport_field.type_class == 'dipswitch') then + return false + else + return true + end end local function action(field) diff --git a/plugins/inputmacro/inputmacro_menu.lua b/plugins/inputmacro/inputmacro_menu.lua index 48fef405d0f..1680a7c8516 100644 --- a/plugins/inputmacro/inputmacro_menu.lua +++ b/plugins/inputmacro/inputmacro_menu.lua @@ -13,7 +13,9 @@ local commonui local macros local menu_stack -local macros_start_macro -- really for the macros menu, but has to be declared local before edit menu functions +local macros_start_macro -- really for the macros menu, but have to be declared local before edit menu functions +local macros_item_first_macro +local macros_selection_save -- Helpers @@ -104,6 +106,7 @@ local edit_menu_active local edit_insert_position local edit_name_buffer local edit_items +local edit_item_delete local edit_item_exit local edit_switch_poller @@ -460,6 +463,17 @@ local function handle_edit(index, event) local handled, selection = handle_edit_items(index, event) if handled then return true, selection + elseif (index == edit_item_delete) and (event == 'select') then + local macro = macros_selection_save - macros_item_first_macro + 1 + table.remove(macros, macro) + if macro > #macros then + macros_selection_save = macros_selection_save - 1 + end + edit_current_macro = nil + edit_menu_active = false + edit_items = nil + table.remove(menu_stack) + return true, selection elseif (event == 'back') or ((index == edit_item_exit) and (event == 'select')) then edit_current_macro = nil edit_menu_active = false @@ -504,6 +518,10 @@ local function populate_edit() add_edit_items(items) table.insert(items, { '---', '', '' }) + table.insert(items, { _p('plugin-inputmacro', 'Delete macro'), '', '' }) + edit_item_delete = #items + + table.insert(items, { '---', '', '' }) table.insert(items, { _p('plugin-inputmacro', 'Done'), '', '' }) edit_item_exit = #items @@ -519,8 +537,6 @@ end -- Macros menu -local macros_item_first_macro -local macros_selection_save local macros_item_add function handle_macros(index, event) @@ -533,7 +549,7 @@ function handle_macros(index, event) return true end elseif index >= macros_item_first_macro then - macro = index - macros_item_first_macro + 1 + local macro = index - macros_item_first_macro + 1 if event == 'select' then edit_current_macro = macros[macro] edit_insert_position = #edit_current_macro.steps + 1 diff --git a/src/emu/audio_effects/aeffect.cpp b/src/emu/audio_effects/aeffect.cpp index 070db51dc25..0210575c793 100644 --- a/src/emu/audio_effects/aeffect.cpp +++ b/src/emu/audio_effects/aeffect.cpp @@ -3,25 +3,29 @@ #include "emu.h" #include "aeffect.h" -#include "filter.h" + #include "compressor.h" -#include "reverb.h" #include "eq.h" +#include "filter.h" +#include "reverb.h" + +#include "util/language.h" + const char *const audio_effect::effect_names[COUNT] = { - "Filters", - "Compressor", - "Reverb", - "Equalizer" + N_p("audio-effect", "Filters"), + N_p("audio-effect", "Compressor"), + N_p("audio-effect", "Reverb"), + N_p("audio-effect", "Equalizer") }; -audio_effect *audio_effect::create(int type, speaker_device *speaker, u32 sample_rate, audio_effect *def) +std::unique_ptr<audio_effect> audio_effect::create(int type, speaker_device *speaker, u32 sample_rate, audio_effect *def) { switch(type) { - case FILTER: return new audio_effect_filter (speaker, sample_rate, def); - case COMPRESSOR: return new audio_effect_compressor(speaker, sample_rate, def); - case REVERB: return new audio_effect_reverb (speaker, sample_rate, def); - case EQ: return new audio_effect_eq (speaker, sample_rate, def); + case FILTER: return std::make_unique<audio_effect_filter >(speaker, sample_rate, def); + case COMPRESSOR: return std::make_unique<audio_effect_compressor>(speaker, sample_rate, def); + case REVERB: return std::make_unique<audio_effect_reverb >(speaker, sample_rate, def); + case EQ: return std::make_unique<audio_effect_eq >(speaker, sample_rate, def); } return nullptr; } diff --git a/src/emu/audio_effects/aeffect.h b/src/emu/audio_effects/aeffect.h index 987b2d2e1c1..a2ecefcfd3a 100644 --- a/src/emu/audio_effects/aeffect.h +++ b/src/emu/audio_effects/aeffect.h @@ -1,13 +1,14 @@ // license:BSD-3-Clause // copyright-holders:Olivier Galibert - -#pragma once - #ifndef MAME_EMU_AUDIO_EFFECTS_AEFFECT_H #define MAME_EMU_AUDIO_EFFECTS_AEFFECT_H +#pragma once + #include "speaker.h" +#include <memory> + class audio_effect { public: @@ -23,7 +24,7 @@ public: static const char *const effect_names[COUNT]; - static audio_effect *create(int type, speaker_device *speaker, u32 sample_rate, audio_effect *def = nullptr); + static std::unique_ptr<audio_effect> create(int type, speaker_device *speaker, u32 sample_rate, audio_effect *def = nullptr); audio_effect(speaker_device *speaker, u32 sample_rate, audio_effect *def) : m_default(def), m_speaker(speaker), m_channels(speaker ? speaker->channels() : 0), m_sample_rate(sample_rate) {} virtual ~audio_effect() = default; @@ -43,4 +44,4 @@ protected: u32 m_channels, m_sample_rate; }; -#endif +#endif // MAME_EMU_AUDIO_EFFECTS_AEFFECT_H diff --git a/src/emu/audio_effects/eq.cpp b/src/emu/audio_effects/eq.cpp index f04926d6808..367a34eb5cd 100644 --- a/src/emu/audio_effects/eq.cpp +++ b/src/emu/audio_effects/eq.cpp @@ -233,7 +233,7 @@ void audio_effect_eq::build_filter(u32 band) void audio_effect_eq::build_low_shelf(u32 band) { auto &fi = m_filter[band]; - if(!BIT(m_band_mask, band)) { + if(!BIT(m_band_mask, band)) { fi.clear(); return; } @@ -242,30 +242,30 @@ void audio_effect_eq::build_low_shelf(u32 band) float f = std::clamp(float(m_f[band]), 1.0f, sr/2.0f - 1.0f); float V = pow(10, abs(m_db[band])/20); - float K = tan(M_PI*f/sr); + float K = tan(M_PI*f/sr); float K2 = K*K; if(m_db[band] > 0) { - float d = 1 + sqrt(2)*K + K2; - fi.m_b0 = (1 + sqrt(2*V)*K + V*K2)/d; - fi.m_b1 = 2*(V*K2-1)/d; - fi.m_b2 = (1 - sqrt(2*V)*K + V*K2)/d; - fi.m_a1 = 2*(K2-1)/d; - fi.m_a2 = (1 - sqrt(2)*K + K2)/d; - } else { - float d = 1 + sqrt(2*V)*K + V*K2; - fi.m_b0 = (1 + sqrt(2)*K + K2)/d; - fi.m_b1 = 2*(K2-1)/d; - fi.m_b2 = (1 - sqrt(2)*K + K2)/d; - fi.m_a1 = 2*(V*K2-1)/d; - fi.m_a2 = (1 - sqrt(2*V)*K + V*K2)/d; + float d = 1 + sqrt(2)*K + K2; + fi.m_b0 = (1 + sqrt(2*V)*K + V*K2)/d; + fi.m_b1 = 2*(V*K2-1)/d; + fi.m_b2 = (1 - sqrt(2*V)*K + V*K2)/d; + fi.m_a1 = 2*(K2-1)/d; + fi.m_a2 = (1 - sqrt(2)*K + K2)/d; + } else { + float d = 1 + sqrt(2*V)*K + V*K2; + fi.m_b0 = (1 + sqrt(2)*K + K2)/d; + fi.m_b1 = 2*(K2-1)/d; + fi.m_b2 = (1 - sqrt(2)*K + K2)/d; + fi.m_a1 = 2*(V*K2-1)/d; + fi.m_a2 = (1 - sqrt(2*V)*K + V*K2)/d; } } void audio_effect_eq::build_high_shelf(u32 band) { auto &fi = m_filter[band]; - if(!BIT(m_band_mask, band)) { + if(!BIT(m_band_mask, band)) { fi.clear(); return; } @@ -274,7 +274,7 @@ void audio_effect_eq::build_high_shelf(u32 band) float f = std::clamp(float(m_f[band]), 1.0f, sr/2.0f - 1.0f); float V = pow(10, m_db[band]/20); - float K = tan(M_PI*f/sr); + float K = tan(M_PI*f/sr); float K2 = K*K; if(m_db[band] > 0) { @@ -284,7 +284,7 @@ void audio_effect_eq::build_high_shelf(u32 band) fi.m_b2 = (V - sqrt(2*V)*K + K2)/d; fi.m_a1 = 2*(K2-1)/d; fi.m_a2 = (1 - sqrt(2)*K + K2)/d; - } else { + } else { float d = 1 + sqrt(2*V)*K + V*K2; fi.m_b0 = V*(1 + sqrt(2)*K + K2)/d; fi.m_b1 = 2*V*(K2-1)/d; @@ -297,7 +297,7 @@ void audio_effect_eq::build_high_shelf(u32 band) void audio_effect_eq::build_peak(u32 band) { auto &fi = m_filter[band]; - if(!BIT(m_band_mask, band)) { + if(!BIT(m_band_mask, band)) { fi.clear(); return; } @@ -306,7 +306,7 @@ void audio_effect_eq::build_peak(u32 band) float f = std::clamp(float(m_f[band]), 1.0f, sr/2.0f - 1.0f); float V = pow(10, m_db[band]/20); - float K = tan(M_PI*f/sr); + float K = tan(M_PI*f/sr); float K2 = K*K; float Q = m_q[band]; @@ -317,7 +317,7 @@ void audio_effect_eq::build_peak(u32 band) fi.m_b2 = (1 - V*K/Q + K2)/d; fi.m_a1 = fi.m_b1; fi.m_a2 = (1 - K/Q + K2)/d; - } else { + } else { float d = 1 + K/(V*Q) + K2; fi.m_b0 = (1 + K/Q + K2)/d; fi.m_b1 = 2*(K2-1)/d; diff --git a/src/emu/audio_effects/filter.cpp b/src/emu/audio_effects/filter.cpp index df62a3d635e..4107a1e1549 100644 --- a/src/emu/audio_effects/filter.cpp +++ b/src/emu/audio_effects/filter.cpp @@ -230,7 +230,7 @@ void audio_effect_filter::build_highpass() set_fl(m_fh); auto &fi = m_filter[0]; - if(!m_highpass_active) { + if(!m_highpass_active) { fi.clear(); return; } @@ -238,7 +238,7 @@ void audio_effect_filter::build_highpass() float sr = m_sample_rate; float fh = std::clamp(float(m_fh), 1.0f, sr/2.0f - 1.0f); - float K = tan(M_PI*fh/sr); + float K = tan(M_PI*fh/sr); float K2 = K*K; float Q = m_qh; @@ -256,7 +256,7 @@ void audio_effect_filter::build_lowpass() set_fh(m_fl); auto &fi = m_filter[1]; - if(!m_lowpass_active) { + if(!m_lowpass_active) { fi.clear(); return; } @@ -264,7 +264,7 @@ void audio_effect_filter::build_lowpass() float sr = m_sample_rate; float fl = std::clamp(float(m_fl), 1.0f, sr/2.0f - 1.0f); - float K = tan(M_PI*fl/sr); + float K = tan(M_PI*fl/sr); float K2 = K*K; float Q = m_ql; diff --git a/src/emu/audio_effects/reverb.cpp b/src/emu/audio_effects/reverb.cpp index 5ff6d3694da..2db26d1d6bb 100644 --- a/src/emu/audio_effects/reverb.cpp +++ b/src/emu/audio_effects/reverb.cpp @@ -3,7 +3,9 @@ #include "emu.h" #include "reverb.h" -#include "xmlfile.h" + +#include "util/language.h" +#include "util/xmlfile.h" #include <cmath> @@ -20,41 +22,41 @@ // const audio_effect_reverb::preset audio_effect_reverb::presets[] = { - { "Custom", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, - { "Echo Chamber", 0, 12000, 100, 30, 30, 2, 80, 20, 9000, 10, 4, 90, 10, 30, 20 }, - { "Large Room", 0, 8000, 90, 45, 45, 0.5, 40, 64, 8000, 12, 1.2, 90, 10, 30, 20 }, - { "Large Room Bright", 0, 16000, 90, 45, 45, 0.5, 40, 59, 16000, 12, 1.2, 90, 10, 30, 20 }, - { "Large Room Dark", 0, 3600, 90, 45, 45, 1, 20, 70, 3600, 12, 1.4, 90, 10, 30, 20 }, - { "Large Room Drum", 0, 6500, 90, 35, 35, 1, 20, 30, 6500, 16, 1.2, 85, 10, 25, 25 }, - { "Large Room Tiled", 0, 8500, 90, 15, 70, 2, 0, 10, 8500, 12, 1.2, 90, 10, 30, 20 }, - { "Large Room Vocal", 0, 5500, 90, 45, 45, 2, 0, 80, 5500, 4, 1.5, 90, 10, 30, 20 }, - { "Large Room Wooden", 0, 9000, 90, 55, 35, 1, 20, 100, 9000, 12, 1.2, 90, 10, 30, 20 }, - { "Live", 0, 12000, 90, 20, 20, 2, 80, 25, 9000, 25, 1.5, 90, 30, 15, 60 }, - { "Long Reverb 12s", 0, 16000, 100, 25, 25, 1, 20, 80, 10000, 0, 12, 90, 10, 30, 20 }, - { "Long Reverb 30s", 0, 16000, 100, 25, 25, 1, 20, 80, 9000, 0, 30, 90, 10, 30, 20 }, - { "Medium Room", 0, 8000, 80, 30, 30, 0.5, 40, 57, 8000, 8, 0.6, 90, 10, 30, 20 }, - { "Medium Room Bright", 0, 16000, 80, 30, 30, 0.5, 40, 52, 16000, 8, 0.6, 90, 10, 30, 20 }, - { "Medium Room Dark", 0, 3600, 80, 30, 30, 1, 20, 65, 3600, 8, 0.8, 90, 10, 30, 20 }, - { "Medium Room Drum", 0, 6500, 80, 25, 25, 1, 20, 25, 6500, 12, 0.6, 85, 10, 25, 25 }, - { "Medium Room Tiled", 0, 8500, 80, 10, 65, 2, 0, 10, 8500, 8, 0.6, 90, 10, 30, 20 }, - { "Medium Room Vocal", 0, 5500, 80, 30, 30, 2, 0, 75, 5500, 2, 0.9, 90, 10, 30, 20 }, - { "Medium Room Wooden", 0, 9000, 80, 40, 20, 1, 20, 100, 9000, 8, 0.6, 90, 10, 30, 20 }, - { "Shimmer", 0, 8000, 100, 15, 15, 0.5, 40, 50, 8000, 0, 6, 100, 5, 5, 20 }, - { "Small Room", 0, 8000, 70, 15, 15, 0.5, 40, 50, 8000, 4, 0.3, 90, 10, 30, 20 }, - { "Small Room Bright", 0, 16000, 70, 15, 15, 0.5, 40, 45, 16000, 4, 0.3, 90, 10, 30, 20 }, - { "Small Room Dark", 0, 3600, 70, 15, 15, 1, 20, 60, 3600, 4, 0.5, 90, 10, 30, 20 }, - { "Small Room Drum", 0, 6500, 70, 15, 15, 1, 20, 20, 6500, 8, 0.3, 85, 10, 25, 25 }, - { "Small Room Tiled", 0, 8500, 70, 5, 60, 2, 0, 10, 8500, 4, 0.3, 90, 10, 30, 20 }, - { "Small Room Vocal", 0, 5500, 70, 15, 15, 2, 0, 70, 5500, 0, 0.6, 90, 10, 30, 20 }, - { "Small Room Wooden", 0, 9000, 70, 25, 5, 1, 20, 100, 9000, 4, 0.3, 90, 10, 30, 20 }, - { "Tunnel", 0, 8000, 50, 65, 65, 0.5, 10, 80, 6000, 0, 8, 90, 10, 30, 20 }, - { "Very Large Room", 0, 8000, 100, 60, 60, 0.5, 40, 70, 8000, 16, 2.0, 90, 10, 30, 20 }, - { "Very Large Room Bright", 0, 16000, 100, 60, 60, 0.5, 40, 65, 16000, 16, 2.0, 90, 10, 30, 20 }, - { "Very Large Room Dark", 0, 3600, 100, 60, 60, 1, 20, 75, 3600, 16, 2.2, 90, 10, 30, 20 }, - { "Very Large Room Drum", 0, 6500, 100, 45, 45, 1, 20, 35, 6500, 20, 2.0, 85, 10, 25, 25 }, - { "Very Large Room Tiled", 0, 8500, 100, 20, 75, 2, 0, 10, 8500, 16, 2.0, 90, 10, 30, 20 }, - { "Very Large Room Vocal", 0, 5500, 100, 60, 60, 2, 0, 85, 5500, 6, 2.3, 90, 10, 30, 20 }, - { "Very Large Room Wooden", 0, 9000, 100, 70, 50, 1, 20, 100, 9000, 16, 2.0, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Custom"), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { N_p("audio-reverb-preset", "Echo Chamber"), 0, 12000, 100, 30, 30, 2, 80, 20, 9000, 10, 4, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Large Room"), 0, 8000, 90, 45, 45, 0.5, 40, 64, 8000, 12, 1.2, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Large Room Bright"), 0, 16000, 90, 45, 45, 0.5, 40, 59, 16000, 12, 1.2, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Large Room Dark"), 0, 3600, 90, 45, 45, 1, 20, 70, 3600, 12, 1.4, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Large Room Drum"), 0, 6500, 90, 35, 35, 1, 20, 30, 6500, 16, 1.2, 85, 10, 25, 25 }, + { N_p("audio-reverb-preset", "Large Room Tiled"), 0, 8500, 90, 15, 70, 2, 0, 10, 8500, 12, 1.2, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Large Room Vocal"), 0, 5500, 90, 45, 45, 2, 0, 80, 5500, 4, 1.5, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Large Room Wooden"), 0, 9000, 90, 55, 35, 1, 20, 100, 9000, 12, 1.2, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Live"), 0, 12000, 90, 20, 20, 2, 80, 25, 9000, 25, 1.5, 90, 30, 15, 60 }, + { N_p("audio-reverb-preset", "Long Reverb 12s"), 0, 16000, 100, 25, 25, 1, 20, 80, 10000, 0, 12, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Long Reverb 30s"), 0, 16000, 100, 25, 25, 1, 20, 80, 9000, 0, 30, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Medium Room"), 0, 8000, 80, 30, 30, 0.5, 40, 57, 8000, 8, 0.6, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Medium Room Bright"), 0, 16000, 80, 30, 30, 0.5, 40, 52, 16000, 8, 0.6, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Medium Room Dark"), 0, 3600, 80, 30, 30, 1, 20, 65, 3600, 8, 0.8, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Medium Room Drum"), 0, 6500, 80, 25, 25, 1, 20, 25, 6500, 12, 0.6, 85, 10, 25, 25 }, + { N_p("audio-reverb-preset", "Medium Room Tiled"), 0, 8500, 80, 10, 65, 2, 0, 10, 8500, 8, 0.6, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Medium Room Vocal"), 0, 5500, 80, 30, 30, 2, 0, 75, 5500, 2, 0.9, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Medium Room Wooden"), 0, 9000, 80, 40, 20, 1, 20, 100, 9000, 8, 0.6, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Shimmer"), 0, 8000, 100, 15, 15, 0.5, 40, 50, 8000, 0, 6, 100, 5, 5, 20 }, + { N_p("audio-reverb-preset", "Small Room"), 0, 8000, 70, 15, 15, 0.5, 40, 50, 8000, 4, 0.3, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Small Room Bright"), 0, 16000, 70, 15, 15, 0.5, 40, 45, 16000, 4, 0.3, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Small Room Dark"), 0, 3600, 70, 15, 15, 1, 20, 60, 3600, 4, 0.5, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Small Room Drum"), 0, 6500, 70, 15, 15, 1, 20, 20, 6500, 8, 0.3, 85, 10, 25, 25 }, + { N_p("audio-reverb-preset", "Small Room Tiled"), 0, 8500, 70, 5, 60, 2, 0, 10, 8500, 4, 0.3, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Small Room Vocal"), 0, 5500, 70, 15, 15, 2, 0, 70, 5500, 0, 0.6, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Small Room Wooden"), 0, 9000, 70, 25, 5, 1, 20, 100, 9000, 4, 0.3, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Tunnel"), 0, 8000, 50, 65, 65, 0.5, 10, 80, 6000, 0, 8, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Very Large Room"), 0, 8000, 100, 60, 60, 0.5, 40, 70, 8000, 16, 2.0, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Very Large Room Bright"), 0, 16000, 100, 60, 60, 0.5, 40, 65, 16000, 16, 2.0, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Very Large Room Dark"), 0, 3600, 100, 60, 60, 1, 20, 75, 3600, 16, 2.2, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Very Large Room Drum"), 0, 6500, 100, 45, 45, 1, 20, 35, 6500, 20, 2.0, 85, 10, 25, 25 }, + { N_p("audio-reverb-preset", "Very Large Room Tiled"), 0, 8500, 100, 20, 75, 2, 0, 10, 8500, 16, 2.0, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Very Large Room Vocal"), 0, 5500, 100, 60, 60, 2, 0, 85, 5500, 6, 2.3, 90, 10, 30, 20 }, + { N_p("audio-reverb-preset", "Very Large Room Wooden"), 0, 9000, 100, 70, 50, 1, 20, 100, 9000, 16, 2.0, 90, 10, 30, 20 }, }; const audio_effect_reverb::early_reverb_tap_map audio_effect_reverb::tap_maps[15] = { @@ -329,11 +331,11 @@ audio_effect_reverb::audio_effect_reverb(speaker_device *speaker, u32 sample_rat set_late_diffusion_2(0.312); set_late_diffusion_3(0.406); set_late_diffusion_4(0.250); - set_late_decay_0(0.237); - set_late_decay_1(0.938); - set_late_decay_2(0.844); - set_late_decay_3(0.906); - set_late_decay_f(1.000); + set_late_decay_0(0.237); + set_late_decay_1(0.938); + set_late_decay_2(0.844); + set_late_decay_3(0.906); + set_late_decay_f(1.000); m_late_crossfeed = 0.4; set_late_bass_allpass(150, 4); set_late_damping_2(500, 2); diff --git a/src/emu/sound.cpp b/src/emu/sound.cpp index b65285fc67d..2bdd3585564 100644 --- a/src/emu/sound.cpp +++ b/src/emu/sound.cpp @@ -339,12 +339,12 @@ sound_stream::~sound_stream() void sound_stream::add_bw_route(sound_stream *source, int output, int input, float gain) { - m_bw_routes.emplace_back(route_bw(source, output, input, gain)); + m_bw_routes.emplace_back(source, output, input, gain); } void sound_stream::add_fw_route(sound_stream *target, int input, int output) { - m_fw_routes.emplace_back(route_fw(target, input, output)); + m_fw_routes.emplace_back(target, input, output); } bool sound_stream::set_route_gain(sound_stream *source, int source_channel, int target_channel, float gain) @@ -365,7 +365,7 @@ std::vector<sound_stream *> sound_stream::sources() const for(const sound_stream *s : streams) if(s == stream) goto already; - streams.push_back(stream); + streams.emplace_back(stream); already:; } return streams; @@ -379,7 +379,7 @@ std::vector<sound_stream *> sound_stream::targets() const for(const sound_stream *s : streams) if(s == stream) goto already; - streams.push_back(stream); + streams.emplace_back(stream); already:; } return streams; @@ -420,7 +420,7 @@ void sound_stream::add_dependants(std::vector<sound_stream *> &deps) for(sound_stream *dep : deps) if(dep == this) return; - deps.push_back(this); + deps.emplace_back(this); } @@ -734,8 +734,7 @@ sound_manager::~sound_manager() sound_stream *sound_manager::stream_alloc(device_t &device, u32 inputs, u32 outputs, u32 sample_rate, stream_update_delegate callback, sound_stream_flags flags) { - m_stream_list.push_back(std::make_unique<sound_stream>(device, inputs, outputs, sample_rate, callback, flags)); - return m_stream_list.back().get(); + return m_stream_list.emplace_back(std::make_unique<sound_stream>(device, inputs, outputs, sample_rate, callback, flags)).get(); } @@ -803,19 +802,19 @@ void sound_manager::after_devices_init() std::vector<sound_stream *> ready_streams; for(auto &dpc : depcounts) if(dpc.second == 0) - ready_streams.push_back(dpc.first); + ready_streams.emplace_back(dpc.first); // Handle all the ready streams in a lifo matter (better for cache when generating sound) while(!ready_streams.empty()) { sound_stream *stream = ready_streams.back(); // add the stream to the update order - m_ordered_streams.push_back(stream); + m_ordered_streams.emplace_back(stream); ready_streams.resize(ready_streams.size() - 1); // reduce the depcount for all the streams that depend on the updated stream for(sound_stream *target : stream->targets()) if(!--depcounts[target]) // when the depcount is zero, a stream is ready to be updated - ready_streams.push_back(target); + ready_streams.emplace_back(target); } // If not all streams ended up in the sorted list, we have a loop @@ -829,13 +828,13 @@ void sound_manager::after_devices_init() inverted_depcounts[dpc.first] = dpc.first->targets().size(); for(auto &dpc : inverted_depcounts) if(dpc.second == 0) - ready_streams.push_back(dpc.first); + ready_streams.emplace_back(dpc.first); while(!ready_streams.empty()) { sound_stream *stream = ready_streams.back(); ready_streams.resize(ready_streams.size() - 1); for(sound_stream *source : stream->sources()) if(!--inverted_depcounts[source]) - ready_streams.push_back(source); + ready_streams.emplace_back(source); } std::string stream_names; for(auto &dpc : inverted_depcounts) @@ -866,15 +865,15 @@ void sound_manager::after_devices_init() m_outputs_count = 0; for(speaker_device &dev : speaker_device_enumerator(machine().root_device())) { dev.set_id(m_speakers.size()); - m_speakers.emplace_back(speaker_info(dev, machine().sample_rate(), m_outputs_count)); + m_speakers.emplace_back(dev, machine().sample_rate(), m_outputs_count); for(u32 effect = 0; effect != audio_effect::COUNT; effect++) - m_speakers.back().m_effects[effect].m_effect.reset(audio_effect::create(effect, &dev, machine().sample_rate(), m_default_effects[effect].get())); + m_speakers.back().m_effects[effect].m_effect = audio_effect::create(effect, &dev, machine().sample_rate(), m_default_effects[effect].get()); m_outputs_count += dev.inputs(); } for(microphone_device &dev : microphone_device_enumerator(machine().root_device())) { dev.set_id(m_microphones.size()); - m_microphones.emplace_back(microphone_info(dev)); + m_microphones.emplace_back(dev); } // Allocate the buffer to pass for recording @@ -1130,7 +1129,7 @@ std::vector<audio_effect *> sound_manager::effect_chain(s32 index) const { std::vector<audio_effect *> res; for(const auto &e : m_speakers[index].m_effects) - res.push_back(e.m_effect.get()); + res.emplace_back(e.m_effect.get()); return res; } @@ -1138,7 +1137,7 @@ std::vector<audio_effect *> sound_manager::default_effect_chain() const { std::vector<audio_effect *> res; for(const auto &e : m_default_effects) - res.push_back(e.get()); + res.emplace_back(e.get()); return res; } @@ -1210,7 +1209,7 @@ sound_manager::speaker_info::speaker_info(speaker_device &dev, u32 rate, u32 fir m_channels = dev.inputs(); m_stream = dev.stream(); for(u32 i=0; i != audio_effect::COUNT; i++) - m_effects.emplace_back(effect_step(rate, dev.inputs())); + m_effects.emplace_back(rate, dev.inputs()); } sound_manager::microphone_info::microphone_info(microphone_device &dev) : m_dev(dev) @@ -1339,15 +1338,17 @@ void sound_manager::config_load(config_type cfg_type, config_level cfg_level, ut // Mapping configuration m_configs.clear(); for(util::xml::data_node const *node = parentnode->get_child("sound_map"); node != nullptr; node = node->get_next_sibling("sound_map")) { - m_configs.emplace_back(config_mapping { node->get_attribute_string("tag", "") }); + m_configs.emplace_back(config_mapping{ node->get_attribute_string("tag", "") }); auto &config = m_configs.back(); for(util::xml::data_node const *nmap = node->get_child("node_mapping"); nmap != nullptr; nmap = nmap->get_next_sibling("node_mapping")) - config.m_node_mappings.emplace_back(std::pair<std::string, float>(nmap->get_attribute_string("node", ""), nmap->get_attribute_float("db", 0))); - for(util::xml::data_node const *cmap = node->get_child("channel_mapping"); cmap != nullptr; cmap = cmap->get_next_sibling("channel_mapping")) - config.m_channel_mappings.emplace_back(std::tuple<u32, std::string, u32, float>(cmap->get_attribute_int("guest_channel", 0), - cmap->get_attribute_string("node", ""), - cmap->get_attribute_int("node_channel", 0), - cmap->get_attribute_float("db", 0))); + config.m_node_mappings.emplace_back(nmap->get_attribute_string("node", ""), nmap->get_attribute_float("db", 0)); + for(util::xml::data_node const *cmap = node->get_child("channel_mapping"); cmap != nullptr; cmap = cmap->get_next_sibling("channel_mapping")) { + config.m_channel_mappings.emplace_back( + cmap->get_attribute_int("guest_channel", 0), + cmap->get_attribute_string("node", ""), + cmap->get_attribute_int("node_channel", 0), + cmap->get_attribute_float("db", 0)); + } } break; } @@ -1473,24 +1474,24 @@ sound_manager::config_mapping &sound_manager::config_get_sound_io(sound_io_devic for(auto &config : m_configs) if(config.m_name == dev->tag()) return config; - m_configs.emplace_back(config_mapping { dev->tag() }); + m_configs.emplace_back(config_mapping{ dev->tag() }); return m_configs.back(); } -void sound_manager::config_add_sound_io_connection_node(sound_io_device *dev, std::string name, float db) +void sound_manager::config_add_sound_io_connection_node(sound_io_device *dev, std::string_view name, float db) { internal_config_add_sound_io_connection_node(dev, name, db); m_osd_info.m_generation --; mapping_update(); } -void sound_manager::internal_config_add_sound_io_connection_node(sound_io_device *dev, std::string name, float db) +void sound_manager::internal_config_add_sound_io_connection_node(sound_io_device *dev, std::string_view name, float db) { auto &config = config_get_sound_io(dev); for(auto &nmap : config.m_node_mappings) if(nmap.first == name) return; - config.m_node_mappings.emplace_back(std::pair<std::string, float>(name, db)); + config.m_node_mappings.emplace_back(name, db); } void sound_manager::config_add_sound_io_connection_default(sound_io_device *dev, float db) @@ -1506,17 +1507,17 @@ void sound_manager::internal_config_add_sound_io_connection_default(sound_io_dev for(auto &nmap : config.m_node_mappings) if(nmap.first == "") return; - config.m_node_mappings.emplace_back(std::pair<std::string, float>("", db)); + config.m_node_mappings.emplace_back("", db); } -void sound_manager::config_remove_sound_io_connection_node(sound_io_device *dev, std::string name) +void sound_manager::config_remove_sound_io_connection_node(sound_io_device *dev, std::string_view name) { internal_config_remove_sound_io_connection_node(dev, name); m_osd_info.m_generation --; mapping_update(); } -void sound_manager::internal_config_remove_sound_io_connection_node(sound_io_device *dev, std::string name) +void sound_manager::internal_config_remove_sound_io_connection_node(sound_io_device *dev, std::string_view name) { auto &config = config_get_sound_io(dev); for(auto i = config.m_node_mappings.begin(); i != config.m_node_mappings.end(); i++) @@ -1543,14 +1544,14 @@ void sound_manager::internal_config_remove_sound_io_connection_default(sound_io_ } } -void sound_manager::config_set_volume_sound_io_connection_node(sound_io_device *dev, std::string name, float db) +void sound_manager::config_set_volume_sound_io_connection_node(sound_io_device *dev, std::string_view name, float db) { internal_config_set_volume_sound_io_connection_node(dev, name, db); m_osd_info.m_generation --; mapping_update(); } -void sound_manager::internal_config_set_volume_sound_io_connection_node(sound_io_device *dev, std::string name, float db) +void sound_manager::internal_config_set_volume_sound_io_connection_node(sound_io_device *dev, std::string_view name, float db) { auto &config = config_get_sound_io(dev); for(auto &nmap : config.m_node_mappings) @@ -1578,20 +1579,20 @@ void sound_manager::internal_config_set_volume_sound_io_connection_default(sound } -void sound_manager::config_add_sound_io_channel_connection_node(sound_io_device *dev, u32 guest_channel, std::string name, u32 node_channel, float db) +void sound_manager::config_add_sound_io_channel_connection_node(sound_io_device *dev, u32 guest_channel, std::string_view name, u32 node_channel, float db) { internal_config_add_sound_io_channel_connection_node(dev, guest_channel, name, node_channel, db); m_osd_info.m_generation --; mapping_update(); } -void sound_manager::internal_config_add_sound_io_channel_connection_node(sound_io_device *dev, u32 guest_channel, std::string name, u32 node_channel, float db) +void sound_manager::internal_config_add_sound_io_channel_connection_node(sound_io_device *dev, u32 guest_channel, std::string_view name, u32 node_channel, float db) { auto &config = config_get_sound_io(dev); for(auto &cmap : config.m_channel_mappings) if(std::get<0>(cmap) == guest_channel && std::get<1>(cmap) == name && std::get<2>(cmap) == node_channel) return; - config.m_channel_mappings.emplace_back(std::tuple<u32, std::string, u32, float>(guest_channel, name, node_channel, db)); + config.m_channel_mappings.emplace_back(guest_channel, name, node_channel, db); } void sound_manager::config_add_sound_io_channel_connection_default(sound_io_device *dev, u32 guest_channel, u32 node_channel, float db) @@ -1607,17 +1608,17 @@ void sound_manager::internal_config_add_sound_io_channel_connection_default(soun for(auto &cmap : config.m_channel_mappings) if(std::get<0>(cmap) == guest_channel && std::get<1>(cmap) == "" && std::get<2>(cmap) == node_channel) return; - config.m_channel_mappings.emplace_back(std::tuple<u32, std::string, u32, float>(guest_channel, "", node_channel, db)); + config.m_channel_mappings.emplace_back(guest_channel, "", node_channel, db); } -void sound_manager::config_remove_sound_io_channel_connection_node(sound_io_device *dev, u32 guest_channel, std::string name, u32 node_channel) +void sound_manager::config_remove_sound_io_channel_connection_node(sound_io_device *dev, u32 guest_channel, std::string_view name, u32 node_channel) { internal_config_remove_sound_io_channel_connection_node(dev, guest_channel, name, node_channel); m_osd_info.m_generation --; mapping_update(); } -void sound_manager::internal_config_remove_sound_io_channel_connection_node(sound_io_device *dev, u32 guest_channel, std::string name, u32 node_channel) +void sound_manager::internal_config_remove_sound_io_channel_connection_node(sound_io_device *dev, u32 guest_channel, std::string_view name, u32 node_channel) { auto &config = config_get_sound_io(dev); for(auto i = config.m_channel_mappings.begin(); i != config.m_channel_mappings.end(); i++) @@ -1644,14 +1645,14 @@ void sound_manager::internal_config_remove_sound_io_channel_connection_default(s } } -void sound_manager::config_set_volume_sound_io_channel_connection_node(sound_io_device *dev, u32 guest_channel, std::string name, u32 node_channel, float db) +void sound_manager::config_set_volume_sound_io_channel_connection_node(sound_io_device *dev, u32 guest_channel, std::string_view name, u32 node_channel, float db) { internal_config_set_volume_sound_io_channel_connection_node(dev, guest_channel, name, node_channel, db); m_osd_info.m_generation --; mapping_update(); } -void sound_manager::internal_config_set_volume_sound_io_channel_connection_node(sound_io_device *dev, u32 guest_channel, std::string name, u32 node_channel, float db) +void sound_manager::internal_config_set_volume_sound_io_channel_connection_node(sound_io_device *dev, u32 guest_channel, std::string_view name, u32 node_channel, float db) { auto &config = config_get_sound_io(dev); for(auto &cmap : config.m_channel_mappings) @@ -1688,8 +1689,8 @@ void sound_manager::startup_cleanups() for(const auto &config : m_configs) if(config.m_name == dev.tag()) return; - m_configs.emplace_back(config_mapping { dev.tag() }); - m_configs.back().m_node_mappings.emplace_back(std::pair<std::string, float>("", 0.0)); + m_configs.emplace_back(config_mapping{ dev.tag() }); + m_configs.back().m_node_mappings.emplace_back("", 0.0); }; for(sound_io_device &dev : speaker_device_enumerator(machine().root_device())) @@ -1895,30 +1896,31 @@ void sound_manager::osd_information_update() void sound_manager::generate_mapping() { - auto find_node = [this](std::string name) -> u32 { - for(const auto &node : m_osd_info.m_nodes) - if(node.name() == name) - return node.m_id; - return 0; - }; + const auto find_node = + [this] (std::string_view name) -> u32 { + for(const auto &node : m_osd_info.m_nodes) + if(node.name() == name) + return node.m_id; + return 0; + }; m_mappings.clear(); for(speaker_info &speaker : m_speakers) { auto &config = config_get_sound_io(&speaker.m_dev); - m_mappings.emplace_back(mapping { &speaker.m_dev }); + m_mappings.emplace_back(mapping{ &speaker.m_dev }); auto &omap = m_mappings.back(); std::vector<std::string> node_to_remove; for(auto &nmap : config.m_node_mappings) { if(nmap.first == "") { if(m_osd_info.m_default_sink) - omap.m_node_mappings.emplace_back(mapping::node_mapping { m_osd_info.m_default_sink, nmap.second, true }); + omap.m_node_mappings.emplace_back(mapping::node_mapping{ m_osd_info.m_default_sink, nmap.second, true }); } else { u32 node_id = find_node(nmap.first); if(node_id != 0) - omap.m_node_mappings.emplace_back(mapping::node_mapping { node_id, nmap.second, false }); + omap.m_node_mappings.emplace_back(mapping::node_mapping{ node_id, nmap.second, false }); else - node_to_remove.push_back(nmap.first); + node_to_remove.emplace_back(nmap.first); } } @@ -1929,13 +1931,13 @@ void sound_manager::generate_mapping() for(auto &cmap : config.m_channel_mappings) { if(std::get<1>(cmap) == "") { if(m_osd_info.m_default_sink) - omap.m_channel_mappings.emplace_back(mapping::channel_mapping { std::get<0>(cmap), m_osd_info.m_default_sink, std::get<2>(cmap), std::get<3>(cmap), true }); + omap.m_channel_mappings.emplace_back(mapping::channel_mapping{ std::get<0>(cmap), m_osd_info.m_default_sink, std::get<2>(cmap), std::get<3>(cmap), true }); } else { u32 node_id = find_node(std::get<1>(cmap)); if(node_id != 0) - omap.m_channel_mappings.emplace_back(mapping::channel_mapping { std::get<0>(cmap), node_id, std::get<2>(cmap), std::get<3>(cmap), false }); + omap.m_channel_mappings.emplace_back(mapping::channel_mapping{ std::get<0>(cmap), node_id, std::get<2>(cmap), std::get<3>(cmap), false }); else - channel_map_to_remove.push_back(std::tuple<u32, std::string, u32>(std::get<0>(cmap), std::get<1>(cmap), std::get<2>(cmap))); + channel_map_to_remove.emplace_back(std::get<0>(cmap), std::get<1>(cmap), std::get<2>(cmap)); } } @@ -1945,20 +1947,20 @@ void sound_manager::generate_mapping() for(microphone_info &mic : m_microphones) { auto &config = config_get_sound_io(&mic.m_dev); - m_mappings.emplace_back(mapping { &mic.m_dev }); + m_mappings.emplace_back(mapping{ &mic.m_dev }); auto &omap = m_mappings.back(); std::vector<std::string> node_to_remove; for(auto &nmap : config.m_node_mappings) { if(nmap.first == "") { if(m_osd_info.m_default_source) - omap.m_node_mappings.emplace_back(mapping::node_mapping { m_osd_info.m_default_source, nmap.second, true }); + omap.m_node_mappings.emplace_back(mapping::node_mapping{ m_osd_info.m_default_source, nmap.second, true }); } else { u32 node_id = find_node(nmap.first); if(node_id != 0) - omap.m_node_mappings.emplace_back(mapping::node_mapping { node_id, nmap.second, false }); + omap.m_node_mappings.emplace_back(mapping::node_mapping{ node_id, nmap.second, false }); else - node_to_remove.push_back(nmap.first); + node_to_remove.emplace_back(nmap.first); } } @@ -1969,13 +1971,13 @@ void sound_manager::generate_mapping() for(auto &cmap : config.m_channel_mappings) { if(std::get<1>(cmap) == "") { if(m_osd_info.m_default_source) - omap.m_channel_mappings.emplace_back(mapping::channel_mapping { std::get<0>(cmap), m_osd_info.m_default_source, std::get<2>(cmap), std::get<3>(cmap), true }); + omap.m_channel_mappings.emplace_back(mapping::channel_mapping{ std::get<0>(cmap), m_osd_info.m_default_source, std::get<2>(cmap), std::get<3>(cmap), true }); } else { u32 node_id = find_node(std::get<1>(cmap)); if(node_id != 0) - omap.m_channel_mappings.emplace_back(mapping::channel_mapping { std::get<0>(cmap), node_id, std::get<2>(cmap), std::get<3>(cmap), false }); + omap.m_channel_mappings.emplace_back(mapping::channel_mapping{ std::get<0>(cmap), node_id, std::get<2>(cmap), std::get<3>(cmap), false }); else - channel_map_to_remove.push_back(std::tuple<u32, std::string, u32>(std::get<0>(cmap), std::get<1>(cmap), std::get<2>(cmap))); + channel_map_to_remove.emplace_back(std::get<0>(cmap), std::get<1>(cmap), std::get<2>(cmap)); } } @@ -1992,7 +1994,7 @@ std::vector<u32> sound_manager::find_channel_mapping(const osd::channel_position if(pos.is_lfe()) { for(u32 port = 0; port != node->m_port_positions.size(); port++) if(node->m_port_positions[port].is_lfe()) - result.push_back(port); + result.emplace_back(port); return result; } if(pos.is_onreq()) @@ -2008,9 +2010,9 @@ std::vector<u32> sound_manager::find_channel_mapping(const osd::channel_position if(best_dist == -1 || dist < best_dist) { best_dist = dist; result.clear(); - result.push_back(port); + result.emplace_back(port); } else if(best_dist == dist) - result.push_back(port); + result.emplace_back(port); } return result; } @@ -2078,7 +2080,7 @@ void sound_manager::update_osd_streams() // If none exists, create one u32 sid = m_osd_input_streams.size(); - m_osd_input_streams.emplace_back(osd_input_stream(node->m_id, is_system_default ? "" : node->m_name, node->m_sources, rate, is_system_default, dev)); + m_osd_input_streams.emplace_back(node->m_id, is_system_default ? std::string() : std::string(node->m_name), node->m_sources, rate, is_system_default, dev); osd_input_stream &nos = m_osd_input_streams.back(); nos.m_id = machine().osd().sound_stream_source_open(node->m_id, dev->tag(), rate); nos.m_is_channel_mapping = is_channel_mapping; @@ -2107,7 +2109,7 @@ void sound_manager::update_osd_streams() // If none exists, create one u32 sid = m_osd_output_streams.size(); - m_osd_output_streams.emplace_back(osd_output_stream(node->m_id, is_system_default ? "" : node->m_name, node->m_sinks, rate, is_system_default, dev)); + m_osd_output_streams.emplace_back(node->m_id, is_system_default ? std::string() : std::string(node->m_name), node->m_sinks, rate, is_system_default, dev); osd_output_stream &nos = m_osd_output_streams.back(); nos.m_id = machine().osd().sound_stream_sink_open(node->m_id, dev->tag(), rate); nos.m_is_channel_mapping = is_channel_mapping; @@ -2166,7 +2168,7 @@ void sound_manager::update_osd_streams() // If the channel is output and in the to // clear mask, use load, otherwise use add. // Apply the volume too if needed - mixing_steps.emplace_back(mixing_step { + mixing_steps.emplace_back(mixing_step{ (umask & (1 << tchannel)) ? mixing_step::COPY : mixing_step::ADD, osd_index, tchannel, @@ -2194,7 +2196,7 @@ void sound_manager::update_osd_streams() } else linear_volume = osd::db_to_linear(cm.m_db); - mixing_steps.emplace_back(mixing_step { + mixing_steps.emplace_back(mixing_step{ (stream.m_unused_channels_mask & (1 << cm.m_node_channel)) ? mixing_step::COPY : mixing_step::ADD, osd_index, @@ -2230,7 +2232,7 @@ void sound_manager::update_osd_streams() // If the channel is output and in the to // clear mask, use load, otherwise use add. // Apply the volume too if needed - mixing_steps.emplace_back(mixing_step { + mixing_steps.emplace_back(mixing_step{ mixing_step::ADD, osd_index, tchannel, @@ -2258,7 +2260,7 @@ void sound_manager::update_osd_streams() } else linear_volume = osd::db_to_linear(cm.m_db); - mixing_steps.emplace_back(mixing_step { + mixing_steps.emplace_back(mixing_step{ mixing_step::ADD, osd_index, cm.m_node_channel, @@ -2309,7 +2311,7 @@ void sound_manager::update_osd_streams() // If none exists, create one u32 sid = m_osd_input_streams.size(); - m_osd_input_streams.emplace_back(osd_input_stream(node->m_id, is_system_default ? "" : node->m_name, channels, rate, is_system_default, nullptr)); + m_osd_input_streams.emplace_back(node->m_id, is_system_default ? std::string() : std::string(node->m_name), channels, rate, is_system_default, nullptr); osd_input_stream &stream = m_osd_input_streams.back(); stream.m_id = machine().osd().sound_stream_source_open(node->m_id, machine().system().name, rate); stream.m_buffer.set_sync_sample(rate_and_last_sync_to_index(rate)); @@ -2345,7 +2347,7 @@ void sound_manager::update_osd_streams() // If none exists, create one u32 sid = m_osd_output_streams.size(); - m_osd_output_streams.emplace_back(osd_output_stream(node->m_id, is_system_default ? "" : node->m_name, channels, rate, is_system_default, nullptr)); + m_osd_output_streams.emplace_back(node->m_id, is_system_default ? std::string() : std::string(node->m_name), channels, rate, is_system_default, nullptr); osd_output_stream &stream = m_osd_output_streams.back(); stream.m_id = machine().osd().sound_stream_sink_open(node->m_id, machine().system().name, rate); output_stream_per_node[node->m_id] = sid; @@ -2372,7 +2374,7 @@ void sound_manager::update_osd_streams() for(u32 tchannel : targets) { // If the channel is in the to clear mask, use load, otherwise use add // Apply the volume too - mixing_steps.emplace_back(mixing_step { + mixing_steps.emplace_back(mixing_step{ (umask & (1 << tchannel)) ? mixing_step::COPY : mixing_step::ADD, osd_index, tchannel, @@ -2393,7 +2395,7 @@ void sound_manager::update_osd_streams() // If the channel is in the to clear mask, use load, otherwise use add // Apply the volume too - mixing_steps.emplace_back(mixing_step { + mixing_steps.emplace_back(mixing_step{ (umask & (1 << cm.m_node_channel)) ? mixing_step::COPY : mixing_step::ADD, osd_index, cm.m_node_channel, @@ -2417,7 +2419,7 @@ void sound_manager::update_osd_streams() for(u32 tchannel : targets) { // If the channel is in the to clear mask, use load, otherwise use add // Apply the volume too - mixing_steps.emplace_back(mixing_step { + mixing_steps.emplace_back(mixing_step{ mixing_step::ADD, osd_index, tchannel, @@ -2436,7 +2438,7 @@ void sound_manager::update_osd_streams() // If the channel is in the to clear mask, use load, otherwise use add // Apply the volume too - mixing_steps.emplace_back(mixing_step { + mixing_steps.emplace_back(mixing_step{ mixing_step::ADD, osd_index, cm.m_node_channel, @@ -2457,7 +2459,7 @@ void sound_manager::update_osd_streams() if(stream.m_unused_channels_mask) { for(u32 channel = 0; channel != stream.m_channels; channel ++) if(stream.m_unused_channels_mask & (1 << channel)) - m_output_mixing_steps.emplace_back(mixing_step { mixing_step::CLEAR, stream_index, channel, 0, 0, 0.0 }); + m_output_mixing_steps.emplace_back(mixing_step{ mixing_step::CLEAR, stream_index, channel, 0, 0, 0.0 }); } if(!stream.m_volumes.empty()) osd.sound_stream_set_volumes(stream.m_id, stream.m_volumes); @@ -2642,13 +2644,13 @@ void sound_manager::streams_update() const emu::detail::output_buffer_flat<sample_t> &buffer = m_speakers[static_cast<speaker_device &>(sound.device()).get_id()].m_buffer; int samples = buffer.available_samples(); for(int channel = 0; channel != sound.inputs(); channel++) - buffers.emplace_back(std::make_pair(buffer.ptrs(channel, 0), samples)); + buffers.emplace_back(buffer.ptrs(channel, 0), samples); } else { for(int channel = 0; channel != sound.outputs(); channel++) { std::pair<sound_stream *, int> info = sound.output_to_stream_output(channel); const emu::detail::output_buffer_flat<sample_t> &buffer = info.first->m_output_buffer; - buffers.emplace_back(std::make_pair(buffer.ptrs(info.second, 0), buffer.available_samples())); + buffers.emplace_back(buffer.ptrs(info.second, 0), buffer.available_samples()); } } sound_data.emplace(sound.device().tag(), std::move(buffers)); @@ -2779,7 +2781,7 @@ const char *sound_manager::resampler_type_names(u32 type) const using util::lang_translate; if(type == RESAMPLER_HQ) - return _("HQ"); + return _("audio-resampler", "HQ"); else - return _("LoFi"); + return _("audio-resampler", "LoFi"); } diff --git a/src/emu/sound.h b/src/emu/sound.h index 4ded9a942fe..0cd6d9cec4a 100644 --- a/src/emu/sound.h +++ b/src/emu/sound.h @@ -68,6 +68,12 @@ #include "wavwrite.h" #include "interface/audio.h" +#include <string> +#include <string_view> +#include <tuple> +#include <utility> +#include <vector> + #ifndef SOUND_DISABLE_THREADING #include <mutex> #include <thread> @@ -185,7 +191,7 @@ public: // simple getters device_t &device() const { return m_device; } - std::string name() const { return m_name; } + const std::string &name() const { return m_name; } bool input_adaptive() const { return m_input_adaptive; } bool output_adaptive() const { return m_output_adaptive; } bool synchronous() const { return m_synchronous; } @@ -417,17 +423,17 @@ public: u32 outputs_count() const { return m_outputs_count; } // manage the sound_io mapping and volume configuration - void config_add_sound_io_connection_node(sound_io_device *dev, std::string name, float db); + void config_add_sound_io_connection_node(sound_io_device *dev, std::string_view name, float db); void config_add_sound_io_connection_default(sound_io_device *dev, float db); - void config_remove_sound_io_connection_node(sound_io_device *dev, std::string name); + void config_remove_sound_io_connection_node(sound_io_device *dev, std::string_view name); void config_remove_sound_io_connection_default(sound_io_device *dev); - void config_set_volume_sound_io_connection_node(sound_io_device *dev, std::string name, float db); + void config_set_volume_sound_io_connection_node(sound_io_device *dev, std::string_view name, float db); void config_set_volume_sound_io_connection_default(sound_io_device *dev, float db); - void config_add_sound_io_channel_connection_node(sound_io_device *dev, u32 guest_channel, std::string name, u32 node_channel, float db); + void config_add_sound_io_channel_connection_node(sound_io_device *dev, u32 guest_channel, std::string_view name, u32 node_channel, float db); void config_add_sound_io_channel_connection_default(sound_io_device *dev, u32 guest_channel, u32 node_channel, float db); - void config_remove_sound_io_channel_connection_node(sound_io_device *dev, u32 guest_channel, std::string name, u32 node_channel); + void config_remove_sound_io_channel_connection_node(sound_io_device *dev, u32 guest_channel, std::string_view name, u32 node_channel); void config_remove_sound_io_channel_connection_default(sound_io_device *dev, u32 guest_channel, u32 node_channel); - void config_set_volume_sound_io_channel_connection_node(sound_io_device *dev, u32 guest_channel, std::string name, u32 node_channel, float db); + void config_set_volume_sound_io_channel_connection_node(sound_io_device *dev, u32 guest_channel, std::string_view name, u32 node_channel, float db); void config_set_volume_sound_io_channel_connection_default(sound_io_device *dev, u32 guest_channel, u32 node_channel, float db); // mute sound for one of various independent reasons @@ -525,10 +531,10 @@ private: std::vector<float> m_volumes; const audio_resampler *m_resampler; - osd_stream(u32 node, std::string node_name, u32 channels, u32 rate, bool is_system_default, sound_io_device *dev) : + osd_stream(u32 node, std::string &&node_name, u32 channels, u32 rate, bool is_system_default, sound_io_device *dev) : m_id(0), m_node(node), - m_node_name(node_name), + m_node_name(std::move(node_name)), m_channels(channels), m_rate(rate), m_unused_channels_mask(util::make_bitmask<u32>(channels)), @@ -541,8 +547,8 @@ private: struct osd_input_stream : public osd_stream { emu::detail::output_buffer_interleaved<s16> m_buffer; - osd_input_stream(u32 node, std::string node_name, u32 channels, u32 rate, bool is_system_default, sound_io_device *dev) : - osd_stream(node, node_name, channels, rate, is_system_default, dev), + osd_input_stream(u32 node, std::string &&node_name, u32 channels, u32 rate, bool is_system_default, sound_io_device *dev) : + osd_stream(node, std::move(node_name), channels, rate, is_system_default, dev), m_buffer(rate, channels) { } }; @@ -550,8 +556,8 @@ private: struct osd_output_stream : public osd_stream { u32 m_samples; std::vector<s16> m_buffer; - osd_output_stream(u32 node, std::string node_name, u32 channels, u32 rate, bool is_system_default, sound_io_device *dev) : - osd_stream(node, node_name, channels, rate, is_system_default, dev), + osd_output_stream(u32 node, std::string &&node_name, u32 channels, u32 rate, bool is_system_default, sound_io_device *dev) : + osd_stream(node, std::move(node_name), channels, rate, is_system_default, dev), m_samples(0), m_buffer(channels*rate, 0) { } @@ -602,17 +608,17 @@ private: // but don't change generation because we're in the update process config_mapping &config_get_sound_io(sound_io_device *dev); - void internal_config_add_sound_io_connection_node(sound_io_device *dev, std::string name, float db); + void internal_config_add_sound_io_connection_node(sound_io_device *dev, std::string_view name, float db); void internal_config_add_sound_io_connection_default(sound_io_device *dev, float db); - void internal_config_remove_sound_io_connection_node(sound_io_device *dev, std::string name); + void internal_config_remove_sound_io_connection_node(sound_io_device *dev, std::string_view name); void internal_config_remove_sound_io_connection_default(sound_io_device *dev); - void internal_config_set_volume_sound_io_connection_node(sound_io_device *dev, std::string name, float db); + void internal_config_set_volume_sound_io_connection_node(sound_io_device *dev, std::string_view name, float db); void internal_config_set_volume_sound_io_connection_default(sound_io_device *dev, float db); - void internal_config_add_sound_io_channel_connection_node(sound_io_device *dev, u32 guest_channel, std::string name, u32 node_channel, float db); + void internal_config_add_sound_io_channel_connection_node(sound_io_device *dev, u32 guest_channel, std::string_view name, u32 node_channel, float db); void internal_config_add_sound_io_channel_connection_default(sound_io_device *dev, u32 guest_channel, u32 node_channel, float db); - void internal_config_remove_sound_io_channel_connection_node(sound_io_device *dev, u32 guest_channel, std::string name, u32 node_channel); + void internal_config_remove_sound_io_channel_connection_node(sound_io_device *dev, u32 guest_channel, std::string_view name, u32 node_channel); void internal_config_remove_sound_io_channel_connection_default(sound_io_device *dev, u32 guest_channel, u32 node_channel); - void internal_config_set_volume_sound_io_channel_connection_node(sound_io_device *dev, u32 guest_channel, std::string name, u32 node_channel, float db); + void internal_config_set_volume_sound_io_channel_connection_node(sound_io_device *dev, u32 guest_channel, std::string_view name, u32 node_channel, float db); void internal_config_set_volume_sound_io_channel_connection_default(sound_io_device *dev, u32 guest_channel, u32 node_channel, float db); // internal state diff --git a/src/emu/speaker.h b/src/emu/speaker.h index 63fa6e0c86c..531889554d2 100644 --- a/src/emu/speaker.h +++ b/src/emu/speaker.h @@ -47,19 +47,19 @@ public: // configuration helpers sound_io_device &set_position(u32 channel, double x, double y, double z); sound_io_device &set_position(u32 channel, const osd::channel_position &pos); - sound_io_device &front_center(u32 channel = 0) { return set_position(channel, osd::channel_position::FC); } - sound_io_device &front_left(u32 channel = 0) { return set_position(channel, osd::channel_position::FL); } - sound_io_device &front_right(u32 channel = 0) { return set_position(channel, osd::channel_position::FR); } - sound_io_device &rear_center(u32 channel = 0) { return set_position(channel, osd::channel_position::RC); } - sound_io_device &rear_left(u32 channel = 0) { return set_position(channel, osd::channel_position::RL); } - sound_io_device &rear_right(u32 channel = 0) { return set_position(channel, osd::channel_position::RR); } - sound_io_device &headrest_center(u32 channel = 0) { return set_position(channel, osd::channel_position::HC); } - sound_io_device &headrest_left(u32 channel = 0) { return set_position(channel, osd::channel_position::HL); } - sound_io_device &headrest_right(u32 channel = 0) { return set_position(channel, osd::channel_position::RC); } - sound_io_device &backrest(u32 channel = 0) { return set_position(channel, osd::channel_position::BACKREST); } - sound_io_device &unknown(u32 channel = 0) { return set_position(channel, osd::channel_position::UNKNOWN); } - sound_io_device &map_on_request_only(u32 channel = 0) { return set_position(channel, osd::channel_position::ONREQ); } - sound_io_device &lfe(u32 channel = 0) { return set_position(channel, osd::channel_position::LFE); } + sound_io_device &front_center(u32 channel = 0) { return set_position(channel, osd::channel_position::FC()); } + sound_io_device &front_left(u32 channel = 0) { return set_position(channel, osd::channel_position::FL()); } + sound_io_device &front_right(u32 channel = 0) { return set_position(channel, osd::channel_position::FR()); } + sound_io_device &rear_center(u32 channel = 0) { return set_position(channel, osd::channel_position::RC()); } + sound_io_device &rear_left(u32 channel = 0) { return set_position(channel, osd::channel_position::RL()); } + sound_io_device &rear_right(u32 channel = 0) { return set_position(channel, osd::channel_position::RR()); } + sound_io_device &headrest_center(u32 channel = 0) { return set_position(channel, osd::channel_position::HC()); } + sound_io_device &headrest_left(u32 channel = 0) { return set_position(channel, osd::channel_position::HL()); } + sound_io_device &headrest_right(u32 channel = 0) { return set_position(channel, osd::channel_position::RC()); } + sound_io_device &backrest(u32 channel = 0) { return set_position(channel, osd::channel_position::BACKREST()); } + sound_io_device &unknown(u32 channel = 0) { return set_position(channel, osd::channel_position::UNKNOWN()); } + sound_io_device &map_on_request_only(u32 channel = 0) { return set_position(channel, osd::channel_position::ONREQ()); } + sound_io_device &lfe(u32 channel = 0) { return set_position(channel, osd::channel_position::LFE()); } sound_io_device &front() { return front_left(0).front_right(1); } sound_io_device &rear() { return rear_left(0).rear_right(1); } diff --git a/src/frontend/mame/ui/audio_effect_compressor.cpp b/src/frontend/mame/ui/audio_effect_compressor.cpp index ee0aafba414..828e7ff2951 100644 --- a/src/frontend/mame/ui/audio_effect_compressor.cpp +++ b/src/frontend/mame/ui/audio_effect_compressor.cpp @@ -10,11 +10,12 @@ #include "emu.h" #include "ui/audio_effect_compressor.h" -#include "audio_effects/aeffect.h" -#include "audio_effects/compressor.h" #include "ui/ui.h" +#include "audio_effects/aeffect.h" +#include "audio_effects/compressor.h" + namespace ui { menu_audio_effect_compressor::menu_audio_effect_compressor(mame_ui_manager &mui, render_container &container, u16 chain, u16 entry, audio_effect *effect) @@ -22,10 +23,11 @@ menu_audio_effect_compressor::menu_audio_effect_compressor(mame_ui_manager &mui, { m_chain = chain; m_entry = entry; - m_effect = static_cast<audio_effect_compressor *>(effect); - set_heading(util::string_format("%s (%s)", - _(audio_effect::effect_names[audio_effect::COMPRESSOR]), - chain == 0xffff ? _("Default") : machine().sound().effect_chain_tag(chain))); + m_effect = dynamic_cast<audio_effect_compressor *>(effect); + set_heading(util::string_format( + (chain == 0xffff) ? _("menu-aeffect-heading", "%1$s (default)") : _("menu-aeffect-heading", "%1$s (%2$s)"), + _("audio-effect", audio_effect::effect_names[audio_effect::COMPRESSOR]), + (chain == 0xffff) ? "" : machine().sound().effect_chain_tag(chain))); set_process_flags(PROCESS_LR_REPEAT); } @@ -60,91 +62,104 @@ bool menu_audio_effect_compressor::handle(event const *ev) m_effect->set_mode(0); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(_("menu-aeffect-compressor", "Bypass")); + ev->item->set_flags(flag_mode()); return true; case ATTACK: m_effect->set_attack(max(0, m_effect->attack() - (alt_pressed ? 10000 : ctrl_pressed ? 100 : shift_pressed ? 1 : 10))); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_ms(m_effect->attack())); + ev->item->set_flags(flag_lim(m_effect->attack(), 0, 300, m_effect->isset_attack())); return true; case RELEASE: m_effect->set_release(max(0, m_effect->release() - ((alt_pressed && !shift_pressed) ? 10000 : ctrl_pressed ? 1000 : (shift_pressed && alt_pressed) ? 1 : shift_pressed ? 10 : 100))); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_ms(m_effect->release())); + ev->item->set_flags(flag_lim(m_effect->release(), 0, 3000, m_effect->isset_release())); return true; case RATIO: m_effect->set_ratio(max(1, m_effect->ratio() - (alt_pressed ? 10000 : ctrl_pressed ? 5 : shift_pressed ? 0.1 : 1))); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_ratio(m_effect->ratio())); + ev->item->set_flags(flag_lim(m_effect->ratio(), 1, 20, m_effect->isset_ratio())); return true; case INPUT_GAIN: m_effect->set_input_gain(max(-12, m_effect->input_gain() - (alt_pressed ? 10000 : ctrl_pressed ? 6 : shift_pressed ? 0.1 : 1))); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_db(m_effect->input_gain())); + ev->item->set_flags(flag_lim(m_effect->input_gain(), -12, 24, m_effect->isset_input_gain())); return true; case OUTPUT_GAIN: m_effect->set_output_gain(max(-12, m_effect->output_gain() - (alt_pressed ? 10000 : ctrl_pressed ? 6 : shift_pressed ? 0.1 : 1))); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_db(m_effect->output_gain())); + ev->item->set_flags(flag_lim(m_effect->output_gain(), -12, 24, m_effect->isset_output_gain())); return true; case CONVEXITY: m_effect->set_convexity(max(-2, m_effect->convexity() - (alt_pressed ? 10000 : ctrl_pressed ? 0.5 : shift_pressed ? 0.01 : 0.1))); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_2dec(m_effect->convexity())); + ev->item->set_flags(flag_lim(m_effect->convexity(), -2, 2, m_effect->isset_convexity())); return true; case THRESHOLD: m_effect->set_threshold(max(-60, m_effect->threshold() - (alt_pressed ? 10000 : ctrl_pressed ? 20 : shift_pressed ? 1 : 5))); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_db(m_effect->threshold())); + ev->item->set_flags(flag_lim(m_effect->threshold(), -60, 6, m_effect->isset_threshold())); return true; case CHANNEL_LINK: m_effect->set_channel_link(max(0, m_effect->channel_link() - (alt_pressed ? 10000 : ctrl_pressed ? 0.5 : shift_pressed ? 0.01 : 0.1))); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_2dec(m_effect->channel_link())); + ev->item->set_flags(flag_lim(m_effect->channel_link(), 0, 1, m_effect->isset_channel_link())); return true; case FEEDBACK: m_effect->set_feedback(max(0, m_effect->feedback() - (alt_pressed ? 10000 : ctrl_pressed ? 0.5 : shift_pressed ? 0.01 : 0.1))); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_2dec(m_effect->feedback())); + ev->item->set_flags(flag_lim(m_effect->feedback(), 0, 1, m_effect->isset_feedback())); return true; case INERTIA: m_effect->set_inertia(max(-1, m_effect->inertia() - (alt_pressed ? 10000 : ctrl_pressed ? 0.5 : shift_pressed ? 0.01 : 0.1))); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_2dec(m_effect->inertia())); + ev->item->set_flags(flag_lim(m_effect->inertia(), -1, 0.3, m_effect->isset_inertia())); return true; case INERTIA_DECAY: m_effect->set_inertia_decay(max(0.8, m_effect->inertia_decay() - (alt_pressed ? 10000 : ctrl_pressed ? 0.05 : 0.01))); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_2dec(m_effect->inertia_decay())); + ev->item->set_flags(flag_lim(m_effect->inertia_decay(), 0.8, 0.96, m_effect->isset_inertia_decay())); return true; case CEILING: m_effect->set_ceiling(max(0.3, m_effect->ceiling() - (alt_pressed ? 10000 : ctrl_pressed ? 0.5 : shift_pressed ? 0.01 : 0.1))); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_2dec(m_effect->ceiling())); + ev->item->set_flags(flag_lim(m_effect->ceiling(), 0.3, 3, m_effect->isset_ceiling())); return true; } break; @@ -156,91 +171,104 @@ bool menu_audio_effect_compressor::handle(event const *ev) m_effect->set_mode(1); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(_("menu-aeffect-compressor", "Active")); + ev->item->set_flags(flag_mode()); return true; case ATTACK: m_effect->set_attack(min(300, m_effect->attack() + (alt_pressed ? 10000 : ctrl_pressed ? 100 : shift_pressed ? 1 : 10))); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_ms(m_effect->attack())); + ev->item->set_flags(flag_lim(m_effect->attack(), 0, 300, m_effect->isset_attack())); return true; case RELEASE: m_effect->set_release(min(3000, m_effect->release() + ((alt_pressed && !shift_pressed) ? 10000 : ctrl_pressed ? 1000 : (shift_pressed && alt_pressed) ? 1 : shift_pressed ? 10 : 100))); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_ms(m_effect->release())); + ev->item->set_flags(flag_lim(m_effect->release(), 0, 3000, m_effect->isset_release())); return true; case RATIO: m_effect->set_ratio(min(20, m_effect->ratio() + (alt_pressed ? 10000 : ctrl_pressed ? 5 : shift_pressed ? 0.1 : 1))); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_ratio(m_effect->ratio())); + ev->item->set_flags(flag_lim(m_effect->ratio(), 1, 20, m_effect->isset_ratio())); return true; case INPUT_GAIN: m_effect->set_input_gain(min(24, m_effect->input_gain() + (alt_pressed ? 10000 : ctrl_pressed ? 6 : shift_pressed ? 0.1 : 1))); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_db(m_effect->input_gain())); + ev->item->set_flags(flag_lim(m_effect->input_gain(), -12, 24, m_effect->isset_input_gain())); return true; case OUTPUT_GAIN: m_effect->set_output_gain(min(24, m_effect->output_gain() + (alt_pressed ? 10000 : ctrl_pressed ? 6 : shift_pressed ? 0.1 : 1))); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_db(m_effect->output_gain())); + ev->item->set_flags(flag_lim(m_effect->output_gain(), -12, 24, m_effect->isset_output_gain())); return true; case CONVEXITY: m_effect->set_convexity(min(2, m_effect->convexity() + (alt_pressed ? 10000 : ctrl_pressed ? 0.5 : shift_pressed ? 0.01 : 0.1))); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_2dec(m_effect->convexity())); + ev->item->set_flags(flag_lim(m_effect->convexity(), -2, 2, m_effect->isset_convexity())); return true; case THRESHOLD: m_effect->set_threshold(min(6, m_effect->threshold() + (alt_pressed ? 10000 : ctrl_pressed ? 20 : shift_pressed ? 1 : 5))); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_db(m_effect->threshold())); + ev->item->set_flags(flag_lim(m_effect->threshold(), -60, 6, m_effect->isset_threshold())); return true; case CHANNEL_LINK: m_effect->set_channel_link(min(1, m_effect->channel_link() + (alt_pressed ? 10000 : ctrl_pressed ? 0.5 : shift_pressed ? 0.01 : 0.1))); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_2dec(m_effect->channel_link())); + ev->item->set_flags(flag_lim(m_effect->channel_link(), 0, 1, m_effect->isset_channel_link())); return true; case FEEDBACK: m_effect->set_feedback(min(1, m_effect->feedback() + (alt_pressed ? 10000 : ctrl_pressed ? 0.5 : shift_pressed ? 0.01 : 0.1))); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_2dec(m_effect->feedback())); + ev->item->set_flags(flag_lim(m_effect->feedback(), 0, 1, m_effect->isset_feedback())); return true; case INERTIA: m_effect->set_inertia(min(0.3, m_effect->inertia() + (alt_pressed ? 10000 : ctrl_pressed ? 0.5 : shift_pressed ? 0.01 : 0.1))); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_2dec(m_effect->inertia())); + ev->item->set_flags(flag_lim(m_effect->inertia(), -1, 0.3, m_effect->isset_inertia())); return true; case INERTIA_DECAY: m_effect->set_inertia_decay(min(0.96, m_effect->inertia_decay() + (alt_pressed ? 10000 : ctrl_pressed ? 0.05 : 0.01))); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_2dec(m_effect->inertia_decay())); + ev->item->set_flags(flag_lim(m_effect->inertia_decay(), 0.8, 0.96, m_effect->isset_inertia_decay())); return true; case CEILING: m_effect->set_ceiling(min(3, m_effect->ceiling() + (alt_pressed ? 10000 : ctrl_pressed ? 0.5 : shift_pressed ? 0.01 : 0.1))); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_2dec(m_effect->ceiling())); + ev->item->set_flags(flag_lim(m_effect->ceiling(), 0.3, 3, m_effect->isset_ceiling())); return true; } break; @@ -252,91 +280,104 @@ bool menu_audio_effect_compressor::handle(event const *ev) m_effect->reset_mode(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(m_effect->mode() ? _("menu-aeffect-compressor", "Active") : _("menu-aeffect-compressor", "Bypass")); + ev->item->set_flags(flag_mode()); return true; case ATTACK: m_effect->reset_attack(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_ms(m_effect->attack())); + ev->item->set_flags(flag_lim(m_effect->attack(), 0, 300, m_effect->isset_attack())); return true; case RELEASE: m_effect->reset_release(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_ms(m_effect->release())); + ev->item->set_flags(flag_lim(m_effect->release(), 0, 3000, m_effect->isset_release())); return true; case RATIO: m_effect->reset_ratio(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_ratio(m_effect->ratio())); + ev->item->set_flags(flag_lim(m_effect->ratio(), 1, 20, m_effect->isset_ratio())); return true; case INPUT_GAIN: m_effect->reset_input_gain(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_db(m_effect->input_gain())); + ev->item->set_flags(flag_lim(m_effect->input_gain(), -12, 24, m_effect->isset_input_gain())); return true; case OUTPUT_GAIN: m_effect->reset_output_gain(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_db(m_effect->output_gain())); + ev->item->set_flags(flag_lim(m_effect->output_gain(), -12, 24, m_effect->isset_output_gain())); return true; case CONVEXITY: m_effect->reset_convexity(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_2dec(m_effect->convexity())); + ev->item->set_flags(flag_lim(m_effect->convexity(), -2, 2, m_effect->isset_convexity())); return true; case THRESHOLD: m_effect->reset_threshold(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_db(m_effect->threshold())); + ev->item->set_flags(flag_lim(m_effect->threshold(), -60, 6, m_effect->isset_threshold())); return true; case CHANNEL_LINK: m_effect->reset_channel_link(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_2dec(m_effect->channel_link())); + ev->item->set_flags(flag_lim(m_effect->channel_link(), 0, 1, m_effect->isset_channel_link())); return true; case FEEDBACK: m_effect->reset_feedback(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_2dec(m_effect->feedback())); + ev->item->set_flags(flag_lim(m_effect->feedback(), 0, 1, m_effect->isset_feedback())); return true; case INERTIA: m_effect->reset_inertia(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_2dec(m_effect->inertia())); + ev->item->set_flags(flag_lim(m_effect->inertia(), -1, 0.3, m_effect->isset_inertia())); return true; case INERTIA_DECAY: m_effect->reset_inertia_decay(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_2dec(m_effect->inertia_decay())); + ev->item->set_flags(flag_lim(m_effect->inertia_decay(), 0.8, 0.96, m_effect->isset_inertia_decay())); return true; case CEILING: m_effect->reset_ceiling(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_2dec(m_effect->ceiling())); + ev->item->set_flags(flag_lim(m_effect->ceiling(), 0.3, 3, m_effect->isset_ceiling())); return true; } @@ -348,22 +389,22 @@ bool menu_audio_effect_compressor::handle(event const *ev) std::string menu_audio_effect_compressor::format_2dec(float val) { - return util::string_format("%.2f", val); + return util::string_format(_("menu-aeffect-compressor", "%1$.2f"), val); } std::string menu_audio_effect_compressor::format_db(float val) { - return util::string_format("%g dB", val); + return util::string_format(_("menu-aeffect-compressor", "%1$+g dB"), val); } std::string menu_audio_effect_compressor::format_ms(float val) { - return util::string_format("%.0f ms", val); + return util::string_format(_("menu-aeffect-compressor", "%1$.0f ms"), val); } std::string menu_audio_effect_compressor::format_ratio(float val) { - return util::string_format("%g:1", val); + return util::string_format(_("menu-aeffect-compressor", "%1$g:1"), val); } u32 menu_audio_effect_compressor::flag_mode() const @@ -392,24 +433,24 @@ u32 menu_audio_effect_compressor::flag_lim(float value, float min, float max, bo void menu_audio_effect_compressor::populate() { - item_append(_("Mode"), m_effect->mode() ? _("Active") : _("Bypass"), flag_mode(), (void *)MODE); - item_append(_("Threshold"), format_db(m_effect->threshold()), flag_lim(m_effect->threshold(), -60, 6, m_effect->isset_threshold()), (void *)THRESHOLD); - item_append(_("Ratio"), format_ratio(m_effect->ratio()), flag_lim(m_effect->ratio(), 1, 20, m_effect->isset_ratio()), (void *)RATIO); - item_append(_("Attack"), format_ms(m_effect->attack()), flag_lim(m_effect->attack(), 0, 300, m_effect->isset_attack()), (void *)ATTACK); - item_append(_("Release"), format_ms(m_effect->release()), flag_lim(m_effect->release(), 0, 3000, m_effect->isset_release()), (void *)RELEASE); - item_append(_("Input gain"), format_db(m_effect->input_gain()), flag_lim(m_effect->input_gain(), -12, 24, m_effect->isset_input_gain()), (void *)INPUT_GAIN); - item_append(_("Output gain"), format_db(m_effect->output_gain()), flag_lim(m_effect->output_gain(), -12, 24, m_effect->isset_output_gain()), (void *)OUTPUT_GAIN); + item_append(_("menu-aeffect-compressor", "Mode"), m_effect->mode() ? _("menu-aeffect-compressor", "Active") : _("menu-aeffect-compressor", "Bypass"), flag_mode(), (void *)MODE); + item_append(_("menu-aeffect-compressor", "Threshold"), format_db(m_effect->threshold()), flag_lim(m_effect->threshold(), -60, 6, m_effect->isset_threshold()), (void *)THRESHOLD); + item_append(_("menu-aeffect-compressor", "Ratio"), format_ratio(m_effect->ratio()), flag_lim(m_effect->ratio(), 1, 20, m_effect->isset_ratio()), (void *)RATIO); + item_append(_("menu-aeffect-compressor", "Attack"), format_ms(m_effect->attack()), flag_lim(m_effect->attack(), 0, 300, m_effect->isset_attack()), (void *)ATTACK); + item_append(_("menu-aeffect-compressor", "Release"), format_ms(m_effect->release()), flag_lim(m_effect->release(), 0, 3000, m_effect->isset_release()), (void *)RELEASE); + item_append(_("menu-aeffect-compressor", "Input gain"), format_db(m_effect->input_gain()), flag_lim(m_effect->input_gain(), -12, 24, m_effect->isset_input_gain()), (void *)INPUT_GAIN); + item_append(_("menu-aeffect-compressor", "Output gain"), format_db(m_effect->output_gain()), flag_lim(m_effect->output_gain(), -12, 24, m_effect->isset_output_gain()), (void *)OUTPUT_GAIN); item_append(menu_item_type::SEPARATOR); - item_append(_("Convexity"), format_2dec(m_effect->convexity()), flag_lim(m_effect->convexity(), -2, 2, m_effect->isset_convexity()), (void *)CONVEXITY); - item_append(_("Channel link"), format_2dec(m_effect->channel_link()), flag_lim(m_effect->channel_link(), 0, 1, m_effect->isset_channel_link()), (void *)CHANNEL_LINK); - item_append(_("Feedback"), format_2dec(m_effect->feedback()), flag_lim(m_effect->feedback(), 0, 1, m_effect->isset_feedback()), (void *)FEEDBACK); - item_append(_("Inertia"), format_2dec(m_effect->inertia()), flag_lim(m_effect->inertia(), -1, 0.3, m_effect->isset_inertia()), (void *)INERTIA); - item_append(_("Inertia decay"), format_2dec(m_effect->inertia_decay()), flag_lim(m_effect->inertia_decay(), 0.8, 0.96, m_effect->isset_inertia_decay()), (void *)INERTIA_DECAY); - item_append(_("Ceiling"), format_2dec(m_effect->ceiling()), flag_lim(m_effect->ceiling(), 0.3, 3, m_effect->isset_ceiling()), (void *)CEILING); + item_append(_("menu-aeffect-compressor", "Convexity"), format_2dec(m_effect->convexity()), flag_lim(m_effect->convexity(), -2, 2, m_effect->isset_convexity()), (void *)CONVEXITY); + item_append(_("menu-aeffect-compressor", "Channel link"), format_2dec(m_effect->channel_link()), flag_lim(m_effect->channel_link(), 0, 1, m_effect->isset_channel_link()), (void *)CHANNEL_LINK); + item_append(_("menu-aeffect-compressor", "Feedback"), format_2dec(m_effect->feedback()), flag_lim(m_effect->feedback(), 0, 1, m_effect->isset_feedback()), (void *)FEEDBACK); + item_append(_("menu-aeffect-compressor", "Inertia"), format_2dec(m_effect->inertia()), flag_lim(m_effect->inertia(), -1, 0.3, m_effect->isset_inertia()), (void *)INERTIA); + item_append(_("menu-aeffect-compressor", "Inertia decay"), format_2dec(m_effect->inertia_decay()), flag_lim(m_effect->inertia_decay(), 0.8, 0.96, m_effect->isset_inertia_decay()), (void *)INERTIA_DECAY); + item_append(_("menu-aeffect-compressor", "Ceiling"), format_2dec(m_effect->ceiling()), flag_lim(m_effect->ceiling(), 0.3, 3, m_effect->isset_ceiling()), (void *)CEILING); item_append(menu_item_type::SEPARATOR); - item_append(_("Reset All"), 0, (void *)RESET_ALL); + item_append(_("menu-aeffect-compressor", "Reset All"), 0, (void *)RESET_ALL); } void menu_audio_effect_compressor::recompute_metrics(uint32_t width, uint32_t height, float aspect) diff --git a/src/frontend/mame/ui/audio_effect_eq.cpp b/src/frontend/mame/ui/audio_effect_eq.cpp index e867867d43a..514019cae33 100644 --- a/src/frontend/mame/ui/audio_effect_eq.cpp +++ b/src/frontend/mame/ui/audio_effect_eq.cpp @@ -10,14 +10,17 @@ #include "emu.h" #include "ui/audio_effect_eq.h" -#include "audio_effects/aeffect.h" -#include "audio_effects/eq.h" #include "ui/ui.h" +#include "audio_effects/aeffect.h" +#include "audio_effects/eq.h" + namespace ui { -const u32 menu_audio_effect_eq::freq_limits[5][2] = { +namespace { + +constexpr u32 FREQ_LIMITS[5][2] = { { 20, 2000 }, { 100, 10000 }, { 100, 10000 }, @@ -25,15 +28,18 @@ const u32 menu_audio_effect_eq::freq_limits[5][2] = { { 500, 16000 } }; +} // anonymous namespace + menu_audio_effect_eq::menu_audio_effect_eq(mame_ui_manager &mui, render_container &container, u16 chain, u16 entry, audio_effect *effect) : menu(mui, container) { m_chain = chain; m_entry = entry; - m_effect = static_cast<audio_effect_eq *>(effect); - set_heading(util::string_format("%s (%s)", - _(audio_effect::effect_names[audio_effect::EQ]), - chain == 0xffff ? _("Default") : machine().sound().effect_chain_tag(chain))); + m_effect = dynamic_cast<audio_effect_eq *>(effect); + set_heading(util::string_format( + (chain == 0xffff) ? _("menu-aeffect-heading", "%1$s (default)") : _("menu-aeffect-heading", "%1$s (%2$s)"), + _("audio-effect", audio_effect::effect_names[audio_effect::EQ]), + (chain == 0xffff) ? "" : machine().sound().effect_chain_tag(chain))); set_process_flags(PROCESS_LR_REPEAT); } @@ -44,7 +50,7 @@ menu_audio_effect_eq::~menu_audio_effect_eq() u32 menu_audio_effect_eq::decrement_f(u32 band, bool alt_pressed, bool ctrl_pressed, bool shift_pressed) { if(!shift_pressed && alt_pressed) - return freq_limits[band][0]; + return FREQ_LIMITS[band][0]; u32 f = m_effect->f(band); @@ -76,13 +82,13 @@ u32 menu_audio_effect_eq::decrement_f(u32 band, bool alt_pressed, bool ctrl_pres f += incval - f % incval; f -= incval; - return std::clamp(f, freq_limits[band][0], freq_limits[band][1]); + return std::clamp(f, FREQ_LIMITS[band][0], FREQ_LIMITS[band][1]); } u32 menu_audio_effect_eq::increment_f(u32 band, bool alt_pressed, bool ctrl_pressed, bool shift_pressed) { if(!shift_pressed && alt_pressed) - return freq_limits[band][1]; + return FREQ_LIMITS[band][1]; u32 f = m_effect->f(band); @@ -114,7 +120,7 @@ u32 menu_audio_effect_eq::increment_f(u32 band, bool alt_pressed, bool ctrl_pres f -= f % incval; f += incval; - return std::clamp(f, freq_limits[band][0], freq_limits[band][1]); + return std::clamp(f, FREQ_LIMITS[band][0], FREQ_LIMITS[band][1]); } float menu_audio_effect_eq::change_q(u32 band, bool inc, bool alt_pressed, bool ctrl_pressed, bool shift_pressed) @@ -187,7 +193,8 @@ bool menu_audio_effect_eq::handle(event const *ev) m_effect->set_f(band, f); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_f(m_effect->f(band))); + ev->item->set_flags(flag_f(band)); return true; } @@ -196,7 +203,8 @@ bool menu_audio_effect_eq::handle(event const *ev) m_effect->set_q(band, q); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_q(m_effect->q(band))); + ev->item->set_flags(flag_q(band)); return true; } @@ -205,7 +213,8 @@ bool menu_audio_effect_eq::handle(event const *ev) m_effect->set_db(band, db); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_db(m_effect->db(band))); + ev->item->set_flags(flag_db(band)); return true; } } @@ -236,7 +245,8 @@ bool menu_audio_effect_eq::handle(event const *ev) m_effect->set_f(band, f); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_f(m_effect->f(band))); + ev->item->set_flags(flag_f(band)); return true; } @@ -245,7 +255,8 @@ bool menu_audio_effect_eq::handle(event const *ev) m_effect->set_q(band, q); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_q(m_effect->q(band))); + ev->item->set_flags(flag_q(band)); return true; } @@ -254,12 +265,14 @@ bool menu_audio_effect_eq::handle(event const *ev) m_effect->set_db(band, db); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_db(m_effect->db(band))); + ev->item->set_flags(flag_db(band)); return true; } } break; } + case IPT_UI_CLEAR: { switch(entry) { case MODE: @@ -281,14 +294,16 @@ bool menu_audio_effect_eq::handle(event const *ev) case F: m_effect->reset_f(band); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_f(m_effect->f(band))); + ev->item->set_flags(flag_f(band)); return true; case Q: { m_effect->reset_q(band); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_q(m_effect->q(band))); + ev->item->set_flags(flag_q(band)); return true; } @@ -296,29 +311,56 @@ bool menu_audio_effect_eq::handle(event const *ev) m_effect->reset_db(band); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_db(m_effect->db(band))); + ev->item->set_flags(flag_db(band)); return true; } } break; } + + case IPT_UI_PREV_GROUP: + switch (entry) + { + case SHELF: + case F: + case Q: + case DB: + if(band > 0) + set_selection((void *)uintptr_t(((band - 1) << 16) | ((band == 1) ? SHELF : F))); + break; + } + break; + + case IPT_UI_NEXT_GROUP: + switch (entry) + { + case SHELF: + case F: + case Q: + case DB: + if(band < 4) + set_selection((void *)uintptr_t(((band + 1) << 16) | ((band == 3) ? SHELF : F))); + break; + } + break; } return false; } std::string menu_audio_effect_eq::format_f(u32 f) { - return util::string_format("%d Hz", f); + return util::string_format(_("menu-aeffect-eq", "%1$d Hz"), f); } std::string menu_audio_effect_eq::format_q(float q) { - return util::string_format("%.2f", q); + return util::string_format(_("menu-aeffect-eq", "%1$.2f"), q); } std::string menu_audio_effect_eq::format_db(float db) { - return util::string_format("%g dB", db); + return util::string_format(_("menu-aeffect-eq", "%1$+g dB"), db); } u32 menu_audio_effect_eq::flag_mode() const @@ -363,9 +405,9 @@ u32 menu_audio_effect_eq::flag_f(u32 band) const if(!m_effect->isset_f(band)) flag |= FLAG_INVERT; u32 f = m_effect->f(band); - if(f > freq_limits[band][0]) + if(f > FREQ_LIMITS[band][0]) flag |= FLAG_LEFT_ARROW; - if(f < freq_limits[band][1]) + if(f < FREQ_LIMITS[band][1]) flag |= FLAG_RIGHT_ARROW; return flag; } @@ -398,48 +440,77 @@ u32 menu_audio_effect_eq::flag_db(u32 band) const void menu_audio_effect_eq::populate() { - item_append(_("Mode"), m_effect->mode() ? _("Active") : _("Bypass"), flag_mode(), (void *)MODE); - - item_append(_("Low Band"), FLAG_UI_HEADING | FLAG_DISABLE, nullptr); - item_append(_("Mode"), m_effect->low_shelf() ? _("Shelf") : _("Peak"), flag_low_shelf(), (void *)uintptr_t(SHELF | (0 << 16))); - item_append(_("Frequency"), format_f(m_effect->f(0)), flag_f(0), (void *)uintptr_t(F | (0 << 16))); - if(!m_effect->low_shelf()) - item_append(_("Q factor"), format_q(m_effect->q(0)), flag_q(0), (void *)uintptr_t(Q | (0 << 16))); - item_append(_("Gain"), format_db(m_effect->db(0)), flag_db(0), (void *)uintptr_t(DB | (0 << 16))); - - item_append(_("Low Mid Band"), FLAG_UI_HEADING | FLAG_DISABLE, nullptr); - item_append(_("Frequency"), format_f(m_effect->f(1)), flag_f(1), (void *)uintptr_t(F | (1 << 16))); - item_append(_("Q factor"), format_q(m_effect->q(1)), flag_q(1), (void *)uintptr_t(Q | (1 << 16))); - item_append(_("Gain"), format_db(m_effect->db(1)), flag_db(1), (void *)uintptr_t(DB | (1 << 16))); - - item_append(_("Mid Band"), FLAG_UI_HEADING | FLAG_DISABLE, nullptr); - item_append(_("Frequency"), format_f(m_effect->f(2)), flag_f(2), (void *)uintptr_t(F | (2 << 16))); - item_append(_("Q factor"), format_q(m_effect->q(2)), flag_q(2), (void *)uintptr_t(Q | (2 << 16))); - item_append(_("Gain"), format_db(m_effect->db(2)), flag_db(2), (void *)uintptr_t(DB | (2 << 16))); - - item_append(_("High Mid Band"), FLAG_UI_HEADING | FLAG_DISABLE, nullptr); - item_append(_("Frequency"), format_f(m_effect->f(3)), flag_f(3), (void *)uintptr_t(F | (3 << 16))); - item_append(_("Q factor"), format_q(m_effect->q(3)), flag_q(3), (void *)uintptr_t(Q | (3 << 16))); - item_append(_("Gain"), format_db(m_effect->db(3)), flag_db(3), (void *)uintptr_t(DB | (3 << 16))); - - item_append(_("High Band"), FLAG_UI_HEADING | FLAG_DISABLE, nullptr); - item_append(_("Mode"), m_effect->high_shelf() ? _("Shelf") : _("Peak"), flag_high_shelf(), (void *)uintptr_t(SHELF | (4 << 16))); - item_append(_("Frequency"), format_f(m_effect->f(4)), flag_f(4), (void *)uintptr_t(F | (4 << 16))); - if(!m_effect->high_shelf()) - item_append(_("Q factor"), format_q(m_effect->q(4)), flag_q(4), (void *)uintptr_t(Q | (4 << 16))); - item_append(_("Gain"), format_db(m_effect->db(4)), flag_db(4), (void *)uintptr_t(DB | (4 << 16))); + item_append( + _("menu-aeffect-eq", "Mode"), + m_effect->mode() ? _("menu-aeffect-eq", "Active") : _("menu-aeffect-eq", "Bypass"), + flag_mode(), + (void *)MODE); + + auto const add_band_controls = + [this] (u32 band, bool need_q) + { + item_append( + _("menu-aeffect-eq", "Frequency"), + format_f(m_effect->f(band)), + flag_f(band), + (void *)uintptr_t(F | (band << 16))); + if(need_q) + { + item_append( + _("menu-aeffect-eq", "Q factor"), + format_q(m_effect->q(band)), + flag_q(band), + (void *)uintptr_t(Q | (band << 16))); + } + item_append( + _("menu-aeffect-mode", "Gain"), + format_db(m_effect->db(band)), + flag_db(band), + (void *)uintptr_t(DB | (band << 16))); + }; + + item_append( + _("menu-aeffect-eq", "Low Band"), + FLAG_UI_HEADING | FLAG_DISABLE, + nullptr); + item_append( + _("menu-aeffect-eq", "Mode"), + m_effect->low_shelf() ? _("menu-aeffect-eq", "Shelf") : _("menu-aeffect-eq", "Peak"), + flag_low_shelf(), + (void *)uintptr_t(SHELF | (0 << 16))); + add_band_controls(0, !m_effect->low_shelf()); + + item_append( + _("menu-aeffect-eq", "Low Mid Band"), + FLAG_UI_HEADING | FLAG_DISABLE, + nullptr); + add_band_controls(1, true); + + item_append( + _("menu-aeffect-eq", "Mid Band"), + FLAG_UI_HEADING | FLAG_DISABLE, + nullptr); + add_band_controls(2, true); + + item_append( + _("menu-aeffect-eq", "High Mid Band"), + FLAG_UI_HEADING | FLAG_DISABLE, + nullptr); + add_band_controls(3, true); + + item_append( + _("menu-aeffect-eq", "High Band"), + FLAG_UI_HEADING | FLAG_DISABLE, + nullptr); + item_append( + _("menu-aeffect-eq", "Mode"), + m_effect->high_shelf() ? _("menu-aeffect-eq", "Shelf") : _("menu-aeffect-eq", "Peak"), + flag_high_shelf(), + (void *)uintptr_t(SHELF | (4 << 16))); + add_band_controls(4, !m_effect->high_shelf()); item_append(menu_item_type::SEPARATOR); - item_append(_("Reset All"), 0, (void *)RESET_ALL); -} - -void menu_audio_effect_eq::recompute_metrics(uint32_t width, uint32_t height, float aspect) -{ - menu::recompute_metrics(width, height, aspect); -} - -void menu_audio_effect_eq::custom_render(uint32_t flags, void *selectedref, float top, float bottom, float x1, float y1, float x2, float y2) -{ + item_append(_("menu-aeffect-eq", "Reset All"), 0, (void *)RESET_ALL); } void menu_audio_effect_eq::menu_activated() @@ -452,4 +523,4 @@ void menu_audio_effect_eq::menu_deactivated() { } -} +} // namespace ui diff --git a/src/frontend/mame/ui/audio_effect_eq.h b/src/frontend/mame/ui/audio_effect_eq.h index 4fb8c25a063..092353f39fc 100644 --- a/src/frontend/mame/ui/audio_effect_eq.h +++ b/src/frontend/mame/ui/audio_effect_eq.h @@ -26,16 +26,12 @@ public: virtual ~menu_audio_effect_eq() override; protected: - virtual void recompute_metrics(uint32_t width, uint32_t height, float aspect) override; - virtual void custom_render(uint32_t flags, void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override; virtual void menu_activated() override; virtual void menu_deactivated() override; private: enum { MODE = 1, SHELF, F, Q, DB, RESET_ALL = 0xff }; - static const u32 freq_limits[5][2]; - u16 m_chain, m_entry; audio_effect_eq *m_effect; diff --git a/src/frontend/mame/ui/audio_effect_filter.cpp b/src/frontend/mame/ui/audio_effect_filter.cpp index fc0491fbd96..057530794e9 100644 --- a/src/frontend/mame/ui/audio_effect_filter.cpp +++ b/src/frontend/mame/ui/audio_effect_filter.cpp @@ -10,22 +10,33 @@ #include "emu.h" #include "ui/audio_effect_filter.h" -#include "audio_effects/aeffect.h" -#include "audio_effects/filter.h" #include "ui/ui.h" +#include "audio_effects/aeffect.h" +#include "audio_effects/filter.h" + namespace ui { +namespace { + +static constexpr u32 FH_MIN = 20; +static constexpr u32 FH_MAX = 5000; +static constexpr u32 FL_MIN = 100; +static constexpr u32 FL_MAX = 20000; + +} // anonymous namespace + menu_audio_effect_filter::menu_audio_effect_filter(mame_ui_manager &mui, render_container &container, u16 chain, u16 entry, audio_effect *effect) : menu(mui, container) { m_chain = chain; m_entry = entry; - m_effect = static_cast<audio_effect_filter *>(effect); - set_heading(util::string_format("%s (%s)", - _(audio_effect::effect_names[audio_effect::FILTER]), - chain == 0xffff ? _("Default") : machine().sound().effect_chain_tag(chain))); + m_effect = dynamic_cast<audio_effect_filter *>(effect); + set_heading(util::string_format( + (chain == 0xffff) ? _("menu-aeffect-heading", "%1$s (default)") : _("menu-aeffect-heading", "%1$s (%2$s)"), + _("audio-effect", audio_effect::effect_names[audio_effect::FILTER]), + (chain == 0xffff) ? "" : machine().sound().effect_chain_tag(chain))); set_process_flags(PROCESS_LR_REPEAT); } @@ -156,7 +167,8 @@ bool menu_audio_effect_filter::handle(event const *ev) m_effect->set_highpass_active(false); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(_("menu-aeffect-filter", "Bypass")); + ev->item->set_flags(flag_highpass_active()); return true; case F | HP: { @@ -164,7 +176,8 @@ bool menu_audio_effect_filter::handle(event const *ev) m_effect->set_fh(std::clamp(f, FH_MIN, FH_MAX)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_fh(m_effect->fh())); + ev->item->set_flags(flag_fh()); return true; } @@ -173,7 +186,8 @@ bool menu_audio_effect_filter::handle(event const *ev) m_effect->set_qh(q); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_q(m_effect->qh())); + ev->item->set_flags(flag_qh()); return true; } @@ -181,7 +195,8 @@ bool menu_audio_effect_filter::handle(event const *ev) m_effect->set_lowpass_active(false); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(_("menu-aeffect-filter", "Bypass")); + ev->item->set_flags(flag_lowpass_active()); return true; case F | LP: { @@ -189,7 +204,8 @@ bool menu_audio_effect_filter::handle(event const *ev) m_effect->set_fl(std::clamp(f, FL_MIN, FL_MAX)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_fl(m_effect->fl())); + ev->item->set_flags(flag_fl()); return true; } @@ -198,7 +214,8 @@ bool menu_audio_effect_filter::handle(event const *ev) m_effect->set_ql(q); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_q(m_effect->ql())); + ev->item->set_flags(flag_ql()); return true; } } @@ -211,7 +228,8 @@ bool menu_audio_effect_filter::handle(event const *ev) m_effect->set_highpass_active(true); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(_("menu-aeffect-filter", "Active")); + ev->item->set_flags(flag_highpass_active()); return true; case F | HP: { @@ -219,7 +237,8 @@ bool menu_audio_effect_filter::handle(event const *ev) m_effect->set_fh(std::clamp(f, FH_MIN, FH_MAX)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_fh(m_effect->fh())); + ev->item->set_flags(flag_fh()); return true; } @@ -228,7 +247,8 @@ bool menu_audio_effect_filter::handle(event const *ev) m_effect->set_qh(q); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_q(m_effect->qh())); + ev->item->set_flags(flag_qh()); return true; } @@ -236,7 +256,8 @@ bool menu_audio_effect_filter::handle(event const *ev) m_effect->set_lowpass_active(true); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(_("menu-aeffect-filter", "Active")); + ev->item->set_flags(flag_lowpass_active()); return true; case F | LP: { @@ -244,7 +265,8 @@ bool menu_audio_effect_filter::handle(event const *ev) m_effect->set_fl(std::clamp(f, FL_MIN, FL_MAX)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_fl(m_effect->fl())); + ev->item->set_flags(flag_fl()); return true; } @@ -253,7 +275,8 @@ bool menu_audio_effect_filter::handle(event const *ev) m_effect->set_ql(q); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_q(m_effect->ql())); + ev->item->set_flags(flag_ql()); return true; } } @@ -266,42 +289,48 @@ bool menu_audio_effect_filter::handle(event const *ev) m_effect->reset_highpass_active(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(m_effect->highpass_active() ? _("menu-aeffect-filter", "Active") : _("menu-aeffect-filter", "Bypass")); + ev->item->set_flags(flag_highpass_active()); return true; case F | HP: m_effect->reset_fh(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_fh(m_effect->fh())); + ev->item->set_flags(flag_fh()); return true; case Q | HP: m_effect->reset_qh(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_q(m_effect->qh())); + ev->item->set_flags(flag_qh()); return true; case ACTIVE | LP: m_effect->reset_lowpass_active(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(m_effect->lowpass_active() ? _("menu-aeffect-filter", "Active") : _("menu-aeffect-filter", "Bypass")); + ev->item->set_flags(flag_lowpass_active()); return true; case F | LP: m_effect->reset_fl(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_fl(m_effect->fl())); + ev->item->set_flags(flag_fl()); return true; case Q | LP: m_effect->reset_ql(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_q(m_effect->ql())); + ev->item->set_flags(flag_ql()); return true; } break; @@ -312,17 +341,17 @@ bool menu_audio_effect_filter::handle(event const *ev) std::string menu_audio_effect_filter::format_fh(u32 f) { - return (f <= FH_MIN) ? _("DC removal") : util::string_format("%d Hz", f); + return (f <= FH_MIN) ? _("menu-aeffect-filter", "DC removal") : util::string_format(_("menu-aeffect-filter", "%1$d Hz"), f); } std::string menu_audio_effect_filter::format_fl(u32 f) { - return util::string_format("%d Hz", f); + return util::string_format(_("menu-aeffect-filter", "%1$d Hz"), f); } std::string menu_audio_effect_filter::format_q(float q) { - return util::string_format("%.2f", q); + return util::string_format(_("menu-aeffect-filter", "%1$.2f"), q); } u32 menu_audio_effect_filter::flag_highpass_active() const @@ -403,18 +432,48 @@ u32 menu_audio_effect_filter::flag_ql() const void menu_audio_effect_filter::populate() { - item_append(_("High-pass Filter"), FLAG_UI_HEADING | FLAG_DISABLE, nullptr); - item_append(_("Mode"), m_effect->highpass_active() ? _("Active") : _("Bypass"), flag_highpass_active(), (void *)(ACTIVE | HP)); - item_append(_("Cutoff frequency"), format_fh(m_effect->fh()), flag_fh(), (void *)(F | HP)); - item_append(_("Q factor"), format_q(m_effect->qh()), flag_qh(), (void *)(Q | HP)); - - item_append(_("Low-pass Filter"), FLAG_UI_HEADING | FLAG_DISABLE, nullptr); - item_append(_("Mode"), m_effect->lowpass_active() ? _("Active") : _("Bypass"), flag_lowpass_active(), (void *)(ACTIVE | LP)); - item_append(_("Cutoff frequency"), format_fl(m_effect->fl()), flag_fl(), (void *)(F | LP)); - item_append(_("Q factor"), format_q(m_effect->ql()), flag_ql(), (void *)(Q | LP)); + item_append( + _("menu-aeffect-filter", "High-pass Filter"), + FLAG_UI_HEADING | FLAG_DISABLE, + nullptr); + item_append( + _("menu-aeffect-filter", "Mode"), + m_effect->highpass_active() ? _("menu-aeffect-filter", "Active") : _("menu-aeffect-filter", "Bypass"), + flag_highpass_active(), + (void *)(ACTIVE | HP)); + item_append( + _("menu-aeffect-filter", "Cutoff frequency"), + format_fh(m_effect->fh()), + flag_fh(), + (void *)(F | HP)); + item_append( + _("menu-aeffect-filter", "Q factor"), + format_q(m_effect->qh()), + flag_qh(), + (void *)(Q | HP)); + + item_append( + _("menu-aeffect-filter", "Low-pass Filter"), + FLAG_UI_HEADING | FLAG_DISABLE, + nullptr); + item_append( + _("menu-aeffect-filter", "Mode"), + m_effect->lowpass_active() ? _("menu-aeffect-filter", "Active") : _("menu-aeffect-filter", "Bypass"), + flag_lowpass_active(), + (void *)(ACTIVE | LP)); + item_append( + _("menu-aeffect-filter", "Cutoff frequency"), + format_fl(m_effect->fl()), + flag_fl(), + (void *)(F | LP)); + item_append( + _("menu-aeffect-filter", "Q factor"), + format_q(m_effect->ql()), + flag_ql(), + (void *)(Q | LP)); item_append(menu_item_type::SEPARATOR); - item_append(_("Reset All"), 0, (void *)RESET_ALL); + item_append(_("menu-aeffect-filter", "Reset All"), 0, (void *)RESET_ALL); } void menu_audio_effect_filter::recompute_metrics(uint32_t width, uint32_t height, float aspect) diff --git a/src/frontend/mame/ui/audio_effect_filter.h b/src/frontend/mame/ui/audio_effect_filter.h index 8af5475476b..e810b5f1251 100644 --- a/src/frontend/mame/ui/audio_effect_filter.h +++ b/src/frontend/mame/ui/audio_effect_filter.h @@ -34,11 +34,6 @@ protected: private: enum { ACTIVE = 1, F = 2, Q = 3, HP = 0, LP = 8, RESET_ALL = 0xff }; - static constexpr u32 FH_MIN = 20; - static constexpr u32 FH_MAX = 5000; - static constexpr u32 FL_MIN = 100; - static constexpr u32 FL_MAX = 20000; - u16 m_chain, m_entry; audio_effect_filter *m_effect; diff --git a/src/frontend/mame/ui/audio_effect_reverb.cpp b/src/frontend/mame/ui/audio_effect_reverb.cpp index a238e05e2bc..344897756e1 100644 --- a/src/frontend/mame/ui/audio_effect_reverb.cpp +++ b/src/frontend/mame/ui/audio_effect_reverb.cpp @@ -10,22 +10,25 @@ #include "emu.h" #include "ui/audio_effect_reverb.h" -#include "audio_effects/aeffect.h" -#include "audio_effects/reverb.h" #include "ui/ui.h" +#include "audio_effects/aeffect.h" +#include "audio_effects/reverb.h" + namespace ui { + menu_audio_effect_reverb::menu_audio_effect_reverb(mame_ui_manager &mui, render_container &container, u16 chain, u16 entry, audio_effect *effect) : menu(mui, container) { m_chain = chain; m_entry = entry; - m_effect = static_cast<audio_effect_reverb *>(effect); + m_effect = dynamic_cast<audio_effect_reverb *>(effect); m_preset = m_effect->find_current_preset(); - set_heading(util::string_format("%s (%s)", - _(audio_effect::effect_names[audio_effect::REVERB]), - chain == 0xffff ? _("Default") : machine().sound().effect_chain_tag(chain))); + set_heading(util::string_format( + (chain == 0xffff) ? _("menu-aeffect-heading", "%1$s (default)") : _("menu-aeffect-heading", "%1$s (%2$s)"), + _("audio-effect", audio_effect::effect_names[audio_effect::REVERB]), + (chain == 0xffff) ? "" : machine().sound().effect_chain_tag(chain))); set_process_flags(PROCESS_LR_REPEAT); } @@ -43,7 +46,7 @@ bool menu_audio_effect_reverb::handle(event const *ev) bool shift_pressed = machine().input().code_pressed(KEYCODE_LSHIFT) || machine().input().code_pressed(KEYCODE_RSHIFT); switch(ev->iptkey) { - case IPT_UI_SELECT: { + case IPT_UI_SELECT: switch(uintptr_t(ev->itemref)) { case PRESET: m_effect->load_preset(m_preset); @@ -61,7 +64,6 @@ bool menu_audio_effect_reverb::handle(event const *ev) return true; } break; - } case IPT_UI_LEFT: { switch(uintptr_t(ev->itemref)) { @@ -69,111 +71,132 @@ bool menu_audio_effect_reverb::handle(event const *ev) m_effect->set_mode(0); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(_("menu-aeffect-reverb", "Bypass")); + ev->item->set_flags(flag_mode()); return true; case PRESET: - if(m_preset != 0) - m_preset --; - reset(reset_options::REMEMBER_POSITION); + if(m_preset != 0) { + m_preset--; + auto const preset_name = _("audio-reverb-preset", audio_effect_reverb::preset_name(m_preset)); + if (m_preset == m_effect->default_preset()) + ev->item->set_subtext(util::string_format(_("menu-aeffect-reverb", "%1$s (default)"), preset_name)); + else + ev->item->set_subtext(preset_name); + ev->item->set_flags(flag_preset()); + } return true; case DRYL: m_effect->set_dry_level(change_percent(m_effect->dry_level(), false, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->dry_level())); + ev->item->set_flags(flag_percent(m_effect->dry_level(), m_effect->isset_dry_level())); return true; case EL: m_effect->set_early_level(change_percent(m_effect->early_level(), false, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->early_level())); + ev->item->set_flags(flag_percent(m_effect->early_level(), m_effect->isset_early_level())); return true; case LL: m_effect->set_late_level(change_percent(m_effect->late_level(), false, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->late_level())); + ev->item->set_flags(flag_percent(m_effect->late_level(), m_effect->isset_late_level())); return true; case E2LL: m_effect->set_early_to_late_level(change_percent(m_effect->early_to_late_level(), false, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->early_to_late_level())); + ev->item->set_flags(flag_percent(m_effect->early_to_late_level(), m_effect->isset_early_to_late_level())); return true; case ERS: m_effect->set_early_room_size(change_percent(m_effect->early_room_size(), false, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->early_room_size())); + ev->item->set_flags(flag_percent(m_effect->early_room_size(), m_effect->isset_early_room_size())); return true; case LRS: m_effect->set_late_room_size(change_percent(m_effect->late_room_size(), false, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->late_room_size())); + ev->item->set_flags(flag_percent(m_effect->late_room_size(), m_effect->isset_late_room_size())); return true; case SW: m_effect->set_stereo_width(change_percent(m_effect->stereo_width(), false, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->stereo_width())); + ev->item->set_flags(flag_percent(m_effect->stereo_width(), m_effect->isset_stereo_width())); return true; case LDIFF: m_effect->set_late_diffusion(change_percent(m_effect->late_diffusion(), false, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->late_diffusion())); + ev->item->set_flags(flag_percent(m_effect->late_diffusion(), m_effect->isset_late_diffusion())); return true; case LWANDER: m_effect->set_late_wander(change_percent(m_effect->late_wander(), false, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->late_wander())); + ev->item->set_flags(flag_percent(m_effect->late_wander(), m_effect->isset_late_wander())); return true; case EDAMP: m_effect->set_early_damping(change_freq(m_effect->early_damping(), false, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_freq(m_effect->early_damping())); + ev->item->set_flags(flag_freq(m_effect->early_damping(), m_effect->isset_early_damping())); return true; case LDAMP: m_effect->set_late_damping(change_freq(m_effect->late_damping(), false, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_freq(m_effect->late_damping())); + ev->item->set_flags(flag_freq(m_effect->late_damping(), m_effect->isset_late_damping())); return true; case LPDELAY: m_effect->set_late_predelay(change_ms(m_effect->late_predelay(), false, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_ms(m_effect->late_predelay())); + ev->item->set_flags(flag_ms(m_effect->late_predelay(), m_effect->isset_late_predelay())); return true; case LDECAY: m_effect->set_late_global_decay(change_decay(m_effect->late_global_decay(), false, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_decay(m_effect->late_global_decay())); + ev->item->set_flags(flag_decay(m_effect->late_global_decay(), m_effect->isset_late_global_decay())); return true; case LSPIN: m_effect->set_late_spin(change_spin(m_effect->late_spin(), false, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_spin(m_effect->late_spin())); + ev->item->set_flags(flag_spin(m_effect->late_spin(), m_effect->isset_late_spin())); return true; case ETAP: @@ -181,7 +204,8 @@ bool menu_audio_effect_reverb::handle(event const *ev) m_effect->set_early_tap_setup(m_effect->early_tap_setup() - 1); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(audio_effect_reverb::early_tap_setup_name(m_effect->early_tap_setup())); + ev->item->set_flags(flag_tap_setup()); } return true; } @@ -194,111 +218,132 @@ bool menu_audio_effect_reverb::handle(event const *ev) m_effect->set_mode(1); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(_("menu-aeffect-reverb", "Active")); + ev->item->set_flags(flag_mode()); return true; case PRESET: - if(m_preset != audio_effect_reverb::preset_count() - 1) - m_preset ++; - reset(reset_options::REMEMBER_POSITION); + if(m_preset != audio_effect_reverb::preset_count() - 1) { + m_preset++; + auto const preset_name = _("audio-reverb-preset", audio_effect_reverb::preset_name(m_preset)); + if (m_preset == m_effect->default_preset()) + ev->item->set_subtext(util::string_format(_("menu-aeffect-reverb", "%1$s (default)"), preset_name)); + else + ev->item->set_subtext(preset_name); + ev->item->set_flags(flag_preset()); + } return true; case DRYL: m_effect->set_dry_level(change_percent(m_effect->dry_level(), true, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->dry_level())); + ev->item->set_flags(flag_percent(m_effect->dry_level(), m_effect->isset_dry_level())); return true; case EL: m_effect->set_early_level(change_percent(m_effect->early_level(), true, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->early_level())); + ev->item->set_flags(flag_percent(m_effect->early_level(), m_effect->isset_early_level())); return true; case LL: m_effect->set_late_level(change_percent(m_effect->late_level(), true, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->late_level())); + ev->item->set_flags(flag_percent(m_effect->late_level(), m_effect->isset_late_level())); return true; case E2LL: m_effect->set_early_to_late_level(change_percent(m_effect->early_to_late_level(), true, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->early_to_late_level())); + ev->item->set_flags(flag_percent(m_effect->early_to_late_level(), m_effect->isset_early_to_late_level())); return true; case ERS: m_effect->set_early_room_size(change_percent(m_effect->early_room_size(), true, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->early_room_size())); + ev->item->set_flags(flag_percent(m_effect->early_room_size(), m_effect->isset_early_room_size())); return true; case LRS: m_effect->set_late_room_size(change_percent(m_effect->late_room_size(), true, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->late_room_size())); + ev->item->set_flags(flag_percent(m_effect->late_room_size(), m_effect->isset_late_room_size())); return true; case SW: m_effect->set_stereo_width(change_percent(m_effect->stereo_width(), true, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->stereo_width())); + ev->item->set_flags(flag_percent(m_effect->stereo_width(), m_effect->isset_stereo_width())); return true; case LDIFF: m_effect->set_late_diffusion(change_percent(m_effect->late_diffusion(), true, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->late_diffusion())); + ev->item->set_flags(flag_percent(m_effect->late_diffusion(), m_effect->isset_late_diffusion())); return true; case LWANDER: m_effect->set_late_wander(change_percent(m_effect->late_wander(), true, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->late_wander())); + ev->item->set_flags(flag_percent(m_effect->late_wander(), m_effect->isset_late_wander())); return true; case EDAMP: m_effect->set_early_damping(change_freq(m_effect->early_damping(), true, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_freq(m_effect->early_damping())); + ev->item->set_flags(flag_freq(m_effect->early_damping(), m_effect->isset_early_damping())); return true; case LDAMP: m_effect->set_late_damping(change_freq(m_effect->late_damping(), true, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_freq(m_effect->late_damping())); + ev->item->set_flags(flag_freq(m_effect->late_damping(), m_effect->isset_late_damping())); return true; case LPDELAY: m_effect->set_late_predelay(change_ms(m_effect->late_predelay(), true, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_ms(m_effect->late_predelay())); + ev->item->set_flags(flag_ms(m_effect->late_predelay(), m_effect->isset_late_predelay())); return true; case LDECAY: m_effect->set_late_global_decay(change_decay(m_effect->late_global_decay(), true, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_decay(m_effect->late_global_decay())); + ev->item->set_flags(flag_decay(m_effect->late_global_decay(), m_effect->isset_late_global_decay())); return true; case LSPIN: m_effect->set_late_spin(change_spin(m_effect->late_spin(), true, shift_pressed, ctrl_pressed, alt_pressed)); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_spin(m_effect->late_spin())); + ev->item->set_flags(flag_spin(m_effect->late_spin(), m_effect->isset_late_spin())); return true; case ETAP: @@ -306,7 +351,8 @@ bool menu_audio_effect_reverb::handle(event const *ev) m_effect->set_early_tap_setup(m_effect->early_tap_setup() + 1); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(audio_effect_reverb::early_tap_setup_name(m_effect->early_tap_setup())); + ev->item->set_flags(flag_tap_setup()); } return true; } @@ -320,112 +366,140 @@ bool menu_audio_effect_reverb::handle(event const *ev) m_effect->reset_mode(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(m_effect->mode() ? _("menu-aeffect-reverb", "Active") : _("menu-aeffect-reverb", "Bypass")); + ev->item->set_flags(flag_mode()); + return true; + + case PRESET: + if(m_preset != m_effect->default_preset()) { + m_preset = m_effect->default_preset(); + auto const preset_name = _("audio-reverb-preset", audio_effect_reverb::preset_name(m_preset)); + if (m_preset == m_effect->default_preset()) + ev->item->set_subtext(util::string_format(_("menu-aeffect-reverb", "%1$s (default)"), preset_name)); + else + ev->item->set_subtext(preset_name); + ev->item->set_flags(flag_preset()); + } return true; case DRYL: m_effect->reset_dry_level(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->dry_level())); + ev->item->set_flags(flag_percent(m_effect->dry_level(), m_effect->isset_dry_level())); return true; case EL: m_effect->reset_early_level(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->early_level())); + ev->item->set_flags(flag_percent(m_effect->early_level(), m_effect->isset_early_level())); return true; case LL: m_effect->reset_late_level(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->late_level())); + ev->item->set_flags(flag_percent(m_effect->late_level(), m_effect->isset_late_level())); return true; case E2LL: m_effect->reset_early_to_late_level(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->early_to_late_level())); + ev->item->set_flags(flag_percent(m_effect->early_to_late_level(), m_effect->isset_early_to_late_level())); return true; case ERS: m_effect->reset_early_room_size(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->early_room_size())); + ev->item->set_flags(flag_percent(m_effect->early_room_size(), m_effect->isset_early_room_size())); return true; case LRS: m_effect->reset_late_room_size(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->late_room_size())); + ev->item->set_flags(flag_percent(m_effect->late_room_size(), m_effect->isset_late_room_size())); return true; case SW: m_effect->reset_stereo_width(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->stereo_width())); + ev->item->set_flags(flag_percent(m_effect->stereo_width(), m_effect->isset_stereo_width())); return true; case LDIFF: m_effect->reset_late_diffusion(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->late_diffusion())); + ev->item->set_flags(flag_percent(m_effect->late_diffusion(), m_effect->isset_late_diffusion())); return true; case LWANDER: m_effect->reset_late_wander(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_percent(m_effect->late_wander())); + ev->item->set_flags(flag_percent(m_effect->late_wander(), m_effect->isset_late_wander())); return true; case EDAMP: m_effect->reset_early_damping(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_freq(m_effect->early_damping())); + ev->item->set_flags(flag_freq(m_effect->early_damping(), m_effect->isset_early_damping())); return true; case LDAMP: m_effect->reset_late_damping(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_freq(m_effect->late_damping())); + ev->item->set_flags(flag_freq(m_effect->late_damping(), m_effect->isset_late_damping())); return true; case LPDELAY: m_effect->reset_late_predelay(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_ms(m_effect->late_predelay())); + ev->item->set_flags(flag_ms(m_effect->late_predelay(), m_effect->isset_late_predelay())); return true; case LDECAY: m_effect->reset_late_global_decay(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_decay(m_effect->late_global_decay())); + ev->item->set_flags(flag_decay(m_effect->late_global_decay(), m_effect->isset_late_global_decay())); return true; case LSPIN: m_effect->reset_late_spin(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_spin(m_effect->late_spin())); + ev->item->set_flags(flag_spin(m_effect->late_spin(), m_effect->isset_late_spin())); return true; case ETAP: m_effect->reset_early_tap_setup(); if(m_chain == 0xffff) machine().sound().default_effect_changed(m_entry); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(audio_effect_reverb::early_tap_setup_name(m_effect->early_tap_setup())); + ev->item->set_flags(flag_tap_setup()); return true; } break; @@ -436,27 +510,27 @@ bool menu_audio_effect_reverb::handle(event const *ev) std::string menu_audio_effect_reverb::format_percent(double val) { - return util::string_format("%d%%", u32(val)); + return util::string_format(_("menu-aeffect-reverb", "%1$d%%"), u32(val)); } std::string menu_audio_effect_reverb::format_freq(double val) { - return util::string_format("%d Hz", u32(val + 0.5)); + return util::string_format(_("menu-aeffect-reverb", "%1$d Hz"), u32(val + 0.5)); } -std::string menu_audio_effect_reverb::format_ms(double val) +std::string menu_audio_effect_reverb::format_ms(float val) { - return util::string_format("%5.1f ms", val); + return util::string_format(_("menu-aeffect-reverb", "%1$5.1f ms"), val); } -std::string menu_audio_effect_reverb::format_decay(double val) +std::string menu_audio_effect_reverb::format_decay(float val) { - return util::string_format("%5.2f s", val); + return util::string_format(_("menu-aeffect-reverb", "%1$5.2f s"), val); } std::string menu_audio_effect_reverb::format_spin(double val) { - return util::string_format("%3.2f Hz", val); + return util::string_format(_("menu-aeffect-reverb", "%1$3.2f Hz"), val); } u32 menu_audio_effect_reverb::flag_mode() const @@ -498,9 +572,9 @@ u32 menu_audio_effect_reverb::flag_percent(double val, bool isset) u32 flag = 0; if(!isset) flag |= FLAG_INVERT; - if(val > 0) + if(val > 0.0) flag |= FLAG_LEFT_ARROW; - if(val < 100) + if(val < 100.0) flag |= FLAG_RIGHT_ARROW; return flag; } @@ -510,33 +584,33 @@ u32 menu_audio_effect_reverb::flag_freq(double val, bool isset) u32 flag = 0; if(!isset) flag |= FLAG_INVERT; - if(val > 100) + if(val > 100.0) flag |= FLAG_LEFT_ARROW; - if(val < 16000) + if(val < 16000.0) flag |= FLAG_RIGHT_ARROW; return flag; } -u32 menu_audio_effect_reverb::flag_ms(double val, bool isset) +u32 menu_audio_effect_reverb::flag_ms(float val, bool isset) { u32 flag = 0; if(!isset) flag |= FLAG_INVERT; - if(val > 0) + if(val > 0.0f) flag |= FLAG_LEFT_ARROW; - if(val < 200) + if(val < 200.0f) flag |= FLAG_RIGHT_ARROW; return flag; } -u32 menu_audio_effect_reverb::flag_decay(double val, bool isset) +u32 menu_audio_effect_reverb::flag_decay(float val, bool isset) { u32 flag = 0; if(!isset) flag |= FLAG_INVERT; - if(val > 0.1) + if(val > 0.1f) flag |= FLAG_LEFT_ARROW; - if(val < 30) + if(val < 30.0f) flag |= FLAG_RIGHT_ARROW; return flag; } @@ -546,9 +620,9 @@ u32 menu_audio_effect_reverb::flag_spin(double val, bool isset) u32 flag = 0; if(!isset) flag |= FLAG_INVERT; - if(val > 0) + if(val > 0.0) flag |= FLAG_LEFT_ARROW; - if(val < 5) + if(val < 5.0) flag |= FLAG_RIGHT_ARROW; return flag; } @@ -622,29 +696,33 @@ double menu_audio_effect_reverb::change_spin(double val, bool inc, bool shift, b void menu_audio_effect_reverb::populate() { - item_append(_("Mode"), m_effect->mode() ? _("Active") : _("Bypass"), flag_mode(), (void *)MODE); - item_append(_("Load preset"), util::string_format("%s%s", audio_effect_reverb::preset_name(m_preset), m_preset == m_effect->default_preset() ? _(" (Default)") : ""), flag_preset(), (void *)PRESET); - item_append(_("Dry level"), format_percent(m_effect->dry_level()), flag_percent(m_effect->dry_level(), m_effect->isset_dry_level()), (void *)DRYL); - item_append(_("Stereo width"), format_percent(m_effect->stereo_width()), flag_percent(m_effect->stereo_width(), m_effect->isset_stereo_width()), (void *)SW); - - item_append(_("Early Reflections"), FLAG_UI_HEADING | FLAG_DISABLE, nullptr); - item_append(_("Room size"), format_percent(m_effect->early_room_size()), flag_percent(m_effect->early_room_size(), m_effect->isset_early_room_size()), (void *)ERS); - item_append(_("Tap setup"), audio_effect_reverb::early_tap_setup_name(m_effect->early_tap_setup()), flag_tap_setup(), (void *)ETAP); - item_append(_("Damping"), format_freq(m_effect->early_damping()), flag_freq(m_effect->early_damping(), m_effect->isset_early_damping()), (void *)EDAMP); - item_append(_("Level"), format_percent(m_effect->early_level()), flag_percent(m_effect->early_level(), m_effect->isset_early_level()), (void *)EL); - item_append(_("Send to Late"), format_percent(m_effect->early_to_late_level()), flag_percent(m_effect->early_to_late_level(), m_effect->isset_early_to_late_level()), (void *)E2LL); - - item_append(_("Late Reflections"), FLAG_UI_HEADING | FLAG_DISABLE, nullptr); - item_append(_("Room size"), format_percent(m_effect->late_room_size()), flag_percent(m_effect->late_room_size(), m_effect->isset_late_room_size()), (void *)LRS); - item_append(_("Damping"), format_freq(m_effect->late_damping()), flag_freq(m_effect->late_damping(), m_effect->isset_late_damping()), (void *)LDAMP); - item_append(_("Pre-delay"), format_ms(m_effect->late_predelay()), flag_ms(m_effect->late_predelay(), m_effect->isset_late_predelay()), (void *)LPDELAY); - item_append(_("Diffusion"), format_percent(m_effect->late_diffusion()), flag_percent(m_effect->late_diffusion(), m_effect->isset_late_diffusion()), (void *)LDIFF); - item_append(_("Wander"), format_percent(m_effect->late_wander()), flag_percent(m_effect->late_wander(), m_effect->isset_late_wander()), (void *)LWANDER); - item_append(_("Decay"), format_decay(m_effect->late_global_decay()), flag_decay(m_effect->late_global_decay(), m_effect->isset_late_global_decay()), (void *)LDECAY); - item_append(_("Spin"), format_spin(m_effect->late_spin()), flag_spin(m_effect->late_spin(), m_effect->isset_late_spin()), (void *)LSPIN); - item_append(_("Level"), format_percent(m_effect->late_level()), flag_percent(m_effect->late_level(), m_effect->isset_late_level()), (void *)LL); + item_append(_("menu-aeffect-reverb", "Mode"), m_effect->mode() ? _("menu-aeffect-reverb", "Active") : _("menu-aeffect-reverb", "Bypass"), flag_mode(), (void *)MODE); + auto const preset_name = _("audio-reverb-preset", audio_effect_reverb::preset_name(m_preset)); + if (m_preset == m_effect->default_preset()) + item_append(_("menu-aeffect-reverb", "Load preset"), util::string_format(_("menu-aeffect-reverb", "%1$s (default)"), preset_name), flag_preset(), (void *)PRESET); + else + item_append(_("menu-aeffect-reverb", "Load preset"), preset_name, flag_preset(), (void *)PRESET); + item_append(_("menu-aeffect-reverb", "Dry level"), format_percent(m_effect->dry_level()), flag_percent(m_effect->dry_level(), m_effect->isset_dry_level()), (void *)DRYL); + item_append(_("menu-aeffect-reverb", "Stereo width"), format_percent(m_effect->stereo_width()), flag_percent(m_effect->stereo_width(), m_effect->isset_stereo_width()), (void *)SW); + + item_append(_("menu-aeffect-reverb", "Early Reflections"), FLAG_UI_HEADING | FLAG_DISABLE, nullptr); + item_append(_("menu-aeffect-reverb", "Room size"), format_percent(m_effect->early_room_size()), flag_percent(m_effect->early_room_size(), m_effect->isset_early_room_size()), (void *)ERS); + item_append(_("menu-aeffect-reverb", "Tap setup"), audio_effect_reverb::early_tap_setup_name(m_effect->early_tap_setup()), flag_tap_setup(), (void *)ETAP); + item_append(_("menu-aeffect-reverb", "Damping"), format_freq(m_effect->early_damping()), flag_freq(m_effect->early_damping(), m_effect->isset_early_damping()), (void *)EDAMP); + item_append(_("menu-aeffect-reverb", "Level"), format_percent(m_effect->early_level()), flag_percent(m_effect->early_level(), m_effect->isset_early_level()), (void *)EL); + item_append(_("menu-aeffect-reverb", "Send to Late"), format_percent(m_effect->early_to_late_level()), flag_percent(m_effect->early_to_late_level(), m_effect->isset_early_to_late_level()), (void *)E2LL); + + item_append(_("menu-aeffect-reverb", "Late Reflections"), FLAG_UI_HEADING | FLAG_DISABLE, nullptr); + item_append(_("menu-aeffect-reverb", "Room size"), format_percent(m_effect->late_room_size()), flag_percent(m_effect->late_room_size(), m_effect->isset_late_room_size()), (void *)LRS); + item_append(_("menu-aeffect-reverb", "Damping"), format_freq(m_effect->late_damping()), flag_freq(m_effect->late_damping(), m_effect->isset_late_damping()), (void *)LDAMP); + item_append(_("menu-aeffect-reverb", "Pre-delay"), format_ms(m_effect->late_predelay()), flag_ms(m_effect->late_predelay(), m_effect->isset_late_predelay()), (void *)LPDELAY); + item_append(_("menu-aeffect-reverb", "Diffusion"), format_percent(m_effect->late_diffusion()), flag_percent(m_effect->late_diffusion(), m_effect->isset_late_diffusion()), (void *)LDIFF); + item_append(_("menu-aeffect-reverb", "Wander"), format_percent(m_effect->late_wander()), flag_percent(m_effect->late_wander(), m_effect->isset_late_wander()), (void *)LWANDER); + item_append(_("menu-aeffect-reverb", "Decay"), format_decay(m_effect->late_global_decay()), flag_decay(m_effect->late_global_decay(), m_effect->isset_late_global_decay()), (void *)LDECAY); + item_append(_("menu-aeffect-reverb", "Spin"), format_spin(m_effect->late_spin()), flag_spin(m_effect->late_spin(), m_effect->isset_late_spin()), (void *)LSPIN); + item_append(_("menu-aeffect-reverb", "Level"), format_percent(m_effect->late_level()), flag_percent(m_effect->late_level(), m_effect->isset_late_level()), (void *)LL); item_append(menu_item_type::SEPARATOR); - item_append(_("Reset All"), 0, (void *)RESET_ALL); + item_append(_("menu-aeffect-reverb", "Reset All"), 0, (void *)RESET_ALL); } void menu_audio_effect_reverb::recompute_metrics(uint32_t width, uint32_t height, float aspect) diff --git a/src/frontend/mame/ui/audio_effect_reverb.h b/src/frontend/mame/ui/audio_effect_reverb.h index 2efaa2a8b49..9f0e2becd94 100644 --- a/src/frontend/mame/ui/audio_effect_reverb.h +++ b/src/frontend/mame/ui/audio_effect_reverb.h @@ -65,8 +65,8 @@ private: static std::string format_percent(double val); static std::string format_freq(double val); - static std::string format_ms(double val); - static std::string format_decay(double val); + static std::string format_ms(float val); + static std::string format_decay(float val); static std::string format_spin(double val); u32 flag_mode() const; @@ -75,8 +75,8 @@ private: static u32 flag_percent(double val, bool isset); static u32 flag_freq(double val, bool isset); - static u32 flag_ms(double val, bool isset); - static u32 flag_decay(double val, bool isset); + static u32 flag_ms(float val, bool isset); + static u32 flag_decay(float val, bool isset); static u32 flag_spin(double val, bool isset); static double change_percent(double val, bool inc, bool shift, bool ctrl, bool alt); diff --git a/src/frontend/mame/ui/audioeffects.cpp b/src/frontend/mame/ui/audioeffects.cpp index 536e13b6950..80e28e43b50 100644 --- a/src/frontend/mame/ui/audioeffects.cpp +++ b/src/frontend/mame/ui/audioeffects.cpp @@ -10,24 +10,25 @@ #include "emu.h" #include "ui/audioeffects.h" -#include "audio_effects/aeffect.h" - -#include "audio_effect_compressor.h" -#include "audio_effect_eq.h" -#include "audio_effect_filter.h" -#include "audio_effect_reverb.h" +#include "ui/audio_effect_compressor.h" +#include "ui/audio_effect_eq.h" +#include "ui/audio_effect_filter.h" +#include "ui/audio_effect_reverb.h" #include "ui/ui.h" -#include "osdepend.h" +#include "audio_effects/aeffect.h" + #include "speaker.h" +#include "osdepend.h" + namespace ui { menu_audio_effects::menu_audio_effects(mame_ui_manager &mui, render_container &container) : menu(mui, container) { - set_heading(_("Audio Effects")); + set_heading(_("menu-aeffect", "Audio Effects")); set_process_flags(PROCESS_LR_REPEAT); } @@ -126,17 +127,20 @@ bool menu_audio_effects::handle(event const *ev) case RS_LATENCY: machine().sound().set_resampler_hq_latency(0.005); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_lat(machine().sound().resampler_hq_latency())); + ev->item->set_flags(flag_lat()); return true; case RS_LENGTH: machine().sound().set_resampler_hq_length(400); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_u32(machine().sound().resampler_hq_length())); + ev->item->set_flags(flag_length()); return true; case RS_PHASES: machine().sound().set_resampler_hq_phases(200); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_u32(machine().sound().resampler_hq_phases())); + ev->item->set_flags(flag_phases()); return true; } break; @@ -151,17 +155,20 @@ bool menu_audio_effects::handle(event const *ev) case RS_LATENCY: machine().sound().set_resampler_hq_latency(change_f(latencies, machine().sound().resampler_hq_latency(), -1)); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_lat(machine().sound().resampler_hq_latency())); + ev->item->set_flags(flag_lat()); return true; case RS_LENGTH: machine().sound().set_resampler_hq_length(change_u32(lengths, machine().sound().resampler_hq_length(), -1)); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_u32(machine().sound().resampler_hq_length())); + ev->item->set_flags(flag_length()); return true; case RS_PHASES: machine().sound().set_resampler_hq_phases(change_u32(phases, machine().sound().resampler_hq_phases(), -1)); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_u32(machine().sound().resampler_hq_phases())); + ev->item->set_flags(flag_phases()); return true; } break; @@ -176,17 +183,20 @@ bool menu_audio_effects::handle(event const *ev) case RS_LATENCY: machine().sound().set_resampler_hq_latency(change_f(latencies, machine().sound().resampler_hq_latency(), 1)); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_lat(machine().sound().resampler_hq_latency())); + ev->item->set_flags(flag_lat()); return true; case RS_LENGTH: machine().sound().set_resampler_hq_length(change_u32(lengths, machine().sound().resampler_hq_length(), 1)); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_u32(machine().sound().resampler_hq_length())); + ev->item->set_flags(flag_length()); return true; case RS_PHASES: machine().sound().set_resampler_hq_phases(change_u32(phases, machine().sound().resampler_hq_phases(), 1)); - reset(reset_options::REMEMBER_POSITION); + ev->item->set_subtext(format_u32(machine().sound().resampler_hq_phases())); + ev->item->set_flags(flag_phases()); return true; } break; @@ -199,12 +209,12 @@ bool menu_audio_effects::handle(event const *ev) std::string menu_audio_effects::format_lat(double latency) { - return util::string_format("%3.1f ms", 1000 * latency); + return util::string_format(_("menu-aeffect", "%1$3.1f ms"), 1000 * latency); } std::string menu_audio_effects::format_u32(u32 val) { - return util::string_format("%u", val); + return util::string_format(_("menu-aeffect", "%u"), val); } u32 menu_audio_effects::flag_type() const @@ -267,16 +277,16 @@ void menu_audio_effects::populate() for(u32 e = 0; e != eff.size(); e++) item_append(_(audio_effect::effect_names[eff[e]->type()]), 0, (void *)intptr_t((chain << 16) | e)); } - item_append(_("Default"), FLAG_UI_HEADING | FLAG_DISABLE, nullptr); + item_append(_("menu-aeffect", "Default"), FLAG_UI_HEADING | FLAG_DISABLE, nullptr); auto eff = sound.default_effect_chain(); for(u32 e = 0; e != eff.size(); e++) - item_append(_(audio_effect::effect_names[eff[e]->type()]), 0, (void *)intptr_t((0xffff << 16) | e)); + item_append(_("audio-effect", audio_effect::effect_names[eff[e]->type()]), 0, (void *)intptr_t((0xffff << 16) | e)); - item_append(_("Resampler"), FLAG_UI_HEADING | FLAG_DISABLE, nullptr); - item_append(_("Type"), sound.resampler_type_names(sound.resampler_type()), flag_type(), (void *)RS_TYPE); - item_append(_("HQ latency"), format_lat(sound.resampler_hq_latency()), flag_lat(), (void *)RS_LATENCY); - item_append(_("HQ filter max size"), format_u32(sound.resampler_hq_length()), flag_length(), (void *)RS_LENGTH); - item_append(_("HQ filter max phases"), format_u32(sound.resampler_hq_phases()), flag_phases(), (void *)RS_PHASES); + item_append(_("menu-aeffect", "Resampler"), FLAG_UI_HEADING | FLAG_DISABLE, nullptr); + item_append(_("menu-aeffect", "Type"), sound.resampler_type_names(sound.resampler_type()), flag_type(), (void *)RS_TYPE); + item_append(_("menu-aeffect", "HQ latency"), format_lat(sound.resampler_hq_latency()), flag_lat(), (void *)RS_LATENCY); + item_append(_("menu-aeffect", "HQ filter max size"), format_u32(sound.resampler_hq_length()), flag_length(), (void *)RS_LENGTH); + item_append(_("menu-aeffect", "HQ filter max phases"), format_u32(sound.resampler_hq_phases()), flag_phases(), (void *)RS_PHASES); item_append(menu_item_type::SEPARATOR); } diff --git a/src/frontend/mame/ui/audiomix.cpp b/src/frontend/mame/ui/audiomix.cpp index 5b6c5ef80ba..155bc2f720e 100644 --- a/src/frontend/mame/ui/audiomix.cpp +++ b/src/frontend/mame/ui/audiomix.cpp @@ -11,26 +11,50 @@ #include "emu.h" #include "ui/audiomix.h" +// frontend #include "ui/ui.h" -#include "osdepend.h" +// emu #include "speaker.h" +// osd +#include "osdepend.h" + + namespace ui { +namespace { + +enum { + MT_UNDEFINED, // At startup + MT_NONE, // [no mapping] + MT_FULL, // Full mapping to node + MT_CHANNEL, // Channel-to-channel mapping + MT_INTERNAL // Go back to previous menu or other non-mapping entry +}; + +enum { + ITM_GUEST_CHANNEL = 1, + ITM_NODE, + ITM_NODE_CHANNEL, + ITM_DB, + ITM_DELETE, + ITM_EMPTY +}; + +} // anonymous namespace + menu_audio_mixer::menu_audio_mixer(mame_ui_manager &mui, render_container &container) : menu(mui, container) + , m_generation(0) + , m_reset_item(0) { - set_heading(_("Audio Mixer")); - m_generation = 0; - m_current_selection.m_maptype = MT_UNDEFINED; - m_current_selection.m_dev = nullptr; - m_current_selection.m_guest_channel = 0; - m_current_selection.m_node = 0; - m_current_selection.m_node_channel = 0; - m_current_group = GRP_NODE; - - set_process_flags(PROCESS_LR_ALWAYS); + set_heading(_("menu-audiomix", "Audio Mixer")); + m_reset_selection.m_maptype = MT_UNDEFINED; + m_reset_selection.m_dev = nullptr; + m_reset_selection.m_guest_channel = 0; + m_reset_selection.m_node = 0; + m_reset_selection.m_node_channel = 0; } menu_audio_mixer::~menu_audio_mixer() @@ -39,475 +63,543 @@ menu_audio_mixer::~menu_audio_mixer() bool menu_audio_mixer::handle(event const *ev) { + const auto selection_ref = uintptr_t(get_selection_ref()); + set_process_flags((BIT(selection_ref, 0, 3) == ITM_DB) ? PROCESS_LR_REPEAT : 0); + if(!ev) { if(m_generation != machine().sound().get_osd_info().m_generation) { - reset(reset_options::REMEMBER_POSITION); + const uint32_t selection_num = selection_ref >> 3; + if((1 <= selection_num) && (m_selections.size() >= selection_num)) + { + m_reset_selection = m_selections[selection_num - 1]; + m_reset_item = BIT(selection_ref, 0, 3); + reset(reset_options::REMEMBER_POSITION); + } + else + { + m_reset_selection.m_maptype = MT_INTERNAL; + reset(reset_options::REMEMBER_REF); + } return true; } return false; } - bool const alt_pressed = machine().input().code_pressed(KEYCODE_LALT) || machine().input().code_pressed(KEYCODE_RALT); - bool const ctrl_pressed = machine().input().code_pressed(KEYCODE_LCONTROL) || machine().input().code_pressed(KEYCODE_RCONTROL); - bool const shift_pressed = machine().input().code_pressed(KEYCODE_LSHIFT) || machine().input().code_pressed(KEYCODE_RSHIFT); + const bool alt_pressed = machine().input().code_pressed(KEYCODE_LALT) || machine().input().code_pressed(KEYCODE_RALT); + const bool ctrl_pressed = machine().input().code_pressed(KEYCODE_LCONTROL) || machine().input().code_pressed(KEYCODE_RCONTROL); + const bool shift_pressed = machine().input().code_pressed(KEYCODE_LSHIFT) || machine().input().code_pressed(KEYCODE_RSHIFT); + + const auto item_ref = uintptr_t(ev->itemref); + const uint32_t item_num = item_ref >> 3; + const uint32_t current_item = BIT(item_ref, 0, 3); + select_entry *const current_selection = ((1 <= item_num) && (m_selections.size() >= item_num)) ? &m_selections[item_num - 1] : nullptr; switch(ev->iptkey) { case IPT_UI_MIXER_ADD_FULL: - if(m_current_selection.m_maptype == MT_INTERNAL) + if(!current_selection) return false; + return add_full(*current_selection); - if(full_mapping_available(m_current_selection.m_dev, 0)) { - m_current_selection.m_node = 0; - machine().sound().config_add_sound_io_connection_default(m_current_selection.m_dev, 0.0); + case IPT_UI_MIXER_ADD_CHANNEL: + if(!current_selection) + return false; + return add_channel(*current_selection); + case IPT_UI_PREV_GROUP: + if(!current_selection || (current_selection->m_dev == m_selections.front().m_dev)) { + return false; } else { - uint32_t node = find_next_available_node(m_current_selection.m_dev, 0); - if(node == 0xffffffff) - return false; - m_current_selection.m_node = node; - machine().sound().config_add_sound_io_connection_node(m_current_selection.m_dev, find_node_name(node), 0.0); + uint32_t i = item_num - 2; + sound_io_device *prev = nullptr; + while(0 < i) { + if(!prev) { + if(m_selections[i].m_dev != current_selection->m_dev) + prev = m_selections[i].m_dev; + } else { + if(m_selections[i].m_dev != prev) { + ++i; + break; + } + } + --i; + } + set_selection(reinterpret_cast<void *>(((i + 1) << 3) | ((m_selections[i].m_maptype == MT_NONE) ? ITM_EMPTY : ITM_GUEST_CHANNEL))); + return true; } + break; - m_current_selection.m_maptype = MT_FULL; - m_current_selection.m_guest_channel = 0; - m_current_selection.m_node_channel = 0; - m_current_selection.m_db = 0.0; - m_generation --; - return true; + case IPT_UI_NEXT_GROUP: + if(!current_selection || (current_selection->m_dev == m_selections.back().m_dev)) { + return false; + } else { + for(uint32_t i = item_num; m_selections.size() > i; i++) { + if(m_selections[i].m_dev != current_selection->m_dev) { + set_selection(reinterpret_cast<void *>(((i + 1) << 3) | ((m_selections[i].m_maptype == MT_NONE) ? ITM_EMPTY : ITM_GUEST_CHANNEL))); + break; + } + } + return true; + } - case IPT_UI_MIXER_ADD_CHANNEL: { - if(m_current_selection.m_maptype == MT_INTERNAL) + case IPT_UI_SELECT: + if(!current_selection) return false; - // Find a possible triplet, any triplet - const auto &info = machine().sound().get_osd_info(); - u32 guest_channel; - u32 node_index, node_id; - u32 node_channel; - u32 default_osd_id = m_current_selection.m_dev->is_output() ? info.m_default_sink : info.m_default_source; - for(node_index = default_osd_id == 0 ? 0 : 0xffffffff; node_index != info.m_nodes.size(); node_index++) { - node_id = node_index == 0xffffffff ? 0 : info.m_nodes[node_index].m_id; - u32 guest_channel_count = m_current_selection.m_dev->is_output() ? m_current_selection.m_dev->inputs() : m_current_selection.m_dev->outputs(); - u32 node_channel_count = 0; - if(node_index == 0xffffffff) { - for(u32 i = 0; i != info.m_nodes.size(); i++) - if(info.m_nodes[i].m_id == default_osd_id) { - node_channel_count = m_current_selection.m_dev->is_output() ? info.m_nodes[i].m_sinks : info.m_nodes[i].m_sources; - break; - } - } else - node_channel_count = m_current_selection.m_dev->is_output() ? info.m_nodes[node_index].m_sinks : info.m_nodes[node_index].m_sources; - for(guest_channel = 0; guest_channel != guest_channel_count; guest_channel ++) - for(node_channel = 0; node_channel != node_channel_count; node_channel ++) - if(channel_mapping_available(m_current_selection.m_dev, guest_channel, node_id, node_channel)) - goto found; + switch(current_item) { + case ITM_DELETE: + return delete_route(current_item - 1, *current_selection); } - return false; - - found: - if(node_id) - machine().sound().config_add_sound_io_channel_connection_node(m_current_selection.m_dev, guest_channel, info.m_nodes[node_index].name(), node_channel, 0.0); - else - machine().sound().config_add_sound_io_channel_connection_default(m_current_selection.m_dev, guest_channel, node_channel, 0.0); - m_current_selection.m_maptype = MT_CHANNEL; - m_current_selection.m_guest_channel = guest_channel; - m_current_selection.m_node = node_id; - m_current_selection.m_node_channel = node_channel; - m_current_selection.m_db = 0.0; - m_generation --; - return true; - } + break; - case IPT_UI_CLEAR: { - if(m_current_selection.m_maptype == MT_NONE || m_current_selection.m_maptype == MT_INTERNAL) + case IPT_UI_CLEAR: + if(!current_selection) return false; - if(m_current_selection.m_maptype == MT_FULL) { - if(m_current_selection.m_node == 0) - machine().sound().config_remove_sound_io_connection_default(m_current_selection.m_dev); - else - machine().sound().config_remove_sound_io_connection_node(m_current_selection.m_dev, find_node_name(m_current_selection.m_node)); - } else { - if(m_current_selection.m_node == 0) - machine().sound().config_remove_sound_io_channel_connection_default(m_current_selection.m_dev, m_current_selection.m_guest_channel, m_current_selection.m_node_channel); - else - machine().sound().config_remove_sound_io_channel_connection_node(m_current_selection.m_dev, m_current_selection.m_guest_channel, find_node_name(m_current_selection.m_node), m_current_selection.m_node_channel); + switch(current_item) { + case ITM_DB: + current_selection->m_db = 0.0f; + return set_route_volume(*ev->item, *current_selection); } + break; - // Find where the selection was - uint32_t cursel_index = 0; - for(uint32_t i = 0; i != m_selections.size(); i++) - if(m_selections[i] == m_current_selection) { - cursel_index = i; - break; - } + case IPT_UI_LEFT: + if(!current_selection) + return false; - // If the next item exists and is the same speaker, go there (visually, the cursor stays on the same line) - // Otherwise if the previous item exists and is the same speaker, go there (visually, the cursor goes up once) - // Otherwise create a MT_NONE, because one is going to appear at the same place - if(cursel_index + 1 < m_selections.size() && m_selections[cursel_index+1].m_dev == m_current_selection.m_dev) - m_current_selection = m_selections[cursel_index+1]; - else if(cursel_index != 0 && m_selections[cursel_index-1].m_dev == m_current_selection.m_dev) - m_current_selection = m_selections[cursel_index-1]; - else { - m_current_selection.m_maptype = MT_NONE; - m_current_selection.m_guest_channel = 0; - m_current_selection.m_node = 0; - m_current_selection.m_node_channel = 0; - m_current_selection.m_db = 0.0; - } + switch(current_item) { + case ITM_GUEST_CHANNEL: + return set_prev_guest_channel(*current_selection); - m_generation --; - return true; - } + case ITM_NODE: + return set_prev_node(*current_selection); - case IPT_UI_UP: - case IPT_UI_DOWN: - if(!ev->itemref) { - m_current_selection.m_maptype = MT_INTERNAL; - m_generation --; - return true; - } + case ITM_NODE_CHANNEL: + return set_prev_node_channel(*current_selection); - m_current_selection = *(select_entry *)(ev->itemref); - if(m_current_selection.m_maptype == MT_FULL) { - if(m_current_group == GRP_GUEST_CHANNEL || m_current_group == GRP_NODE_CHANNEL) - m_current_group = GRP_NODE; + case ITM_DB: + if(shift_pressed) { + current_selection->m_db -= 0.1f; + } else if(ctrl_pressed) { + current_selection->m_db -= 10.0f; + } else if(alt_pressed) { + if(current_selection->m_db > 0.0f) + current_selection->m_db = 0.0f; + else + current_selection->m_db = -96.0f; + } else { + current_selection->m_db -= 1.0f; + } + + return set_route_volume(*ev->item, *current_selection); } - m_generation --; - return true; + break; - case IPT_UI_NEXT_GROUP: - if(m_current_selection.m_maptype == MT_NONE || m_current_selection.m_maptype == MT_INTERNAL) + case IPT_UI_RIGHT: + if(!current_selection) return false; - if(m_current_selection.m_maptype == MT_FULL) { - if(m_current_group == GRP_NODE) - m_current_group = GRP_DB; - else - m_current_group = GRP_NODE; - - } else if(m_current_selection.m_maptype == MT_CHANNEL) { - if(m_current_group == GRP_NODE) - m_current_group = GRP_NODE_CHANNEL; - else if(m_current_group == GRP_NODE_CHANNEL) - m_current_group = GRP_DB; - else if(m_current_group == GRP_DB) - m_current_group = GRP_GUEST_CHANNEL; - else - m_current_group = GRP_NODE; - } - m_generation --; - return true; + switch(current_item) { + case ITM_GUEST_CHANNEL: + return set_next_guest_channel(*current_selection); - case IPT_UI_PREV_GROUP: - if(m_current_selection.m_maptype == MT_NONE || m_current_selection.m_maptype == MT_INTERNAL) - return false; + case ITM_NODE: + return set_next_node(*current_selection); - if(m_current_selection.m_maptype == MT_FULL) { - if(m_current_group == GRP_NODE) - m_current_group = GRP_DB; - else - m_current_group = GRP_NODE; - - } else if(m_current_selection.m_maptype == MT_CHANNEL) { - if(m_current_group == GRP_NODE) - m_current_group = GRP_GUEST_CHANNEL; - else if(m_current_group == GRP_GUEST_CHANNEL) - m_current_group = GRP_DB; - else if(m_current_group == GRP_DB) - m_current_group = GRP_NODE_CHANNEL; - else - m_current_group = GRP_NODE; + case ITM_NODE_CHANNEL: + return set_next_node_channel(*current_selection); + + case ITM_DB: + if(shift_pressed) { + current_selection->m_db += 0.1f; + } else if(ctrl_pressed) { + current_selection->m_db += 10.0f; + } else if(alt_pressed) { + if(current_selection->m_db < 0.0f) + current_selection->m_db = 0.0f; + else + current_selection->m_db = 12.0f; + } else { + current_selection->m_db += 1.0f; + } + + return set_route_volume(*ev->item, *current_selection); } - m_generation --; - return true; + break; + } + + return false; +} - case IPT_UI_LEFT: { - if(m_current_selection.m_maptype == MT_NONE || m_current_selection.m_maptype == MT_INTERNAL) + +bool menu_audio_mixer::add_full(select_entry ¤t_selection) +{ + if(full_mapping_available(current_selection.m_dev, 0)) { + m_reset_selection.m_node = 0; + machine().sound().config_add_sound_io_connection_default(current_selection.m_dev, 0.0); + } else { + const uint32_t node = find_next_available_node(current_selection.m_dev, 0); + if(node == 0xffffffff) + { + machine().popmessage(util::string_format( + current_selection.m_dev->is_output() + ? _("menu-audiomix", "No full routes available for output device %1$s") + : _("menu-audiomix", "No full routes available for input device %1$s"), + current_selection.m_dev->tag())); return false; + } + m_reset_selection.m_node = node; + machine().sound().config_add_sound_io_connection_node(current_selection.m_dev, find_node_name(node), 0.0); + } - switch(m_current_group) { - case GRP_NODE: { - if(m_current_selection.m_maptype == MT_FULL) { - uint32_t prev_node = m_current_selection.m_node; - uint32_t next_node = find_previous_available_node(m_current_selection.m_dev, prev_node); - if(next_node != 0xffffffff) { - m_current_selection.m_node = next_node; - if(prev_node) - machine().sound().config_remove_sound_io_connection_node(m_current_selection.m_dev, find_node_name(prev_node)); - else - machine().sound().config_remove_sound_io_connection_default(m_current_selection.m_dev); - if(next_node) - machine().sound().config_add_sound_io_connection_node(m_current_selection.m_dev, find_node_name(next_node), m_current_selection.m_db); - else - machine().sound().config_add_sound_io_connection_default(m_current_selection.m_dev, m_current_selection.m_db); - m_generation --; - return true; - } - } else if(m_current_selection.m_maptype == MT_CHANNEL) { - uint32_t prev_node = m_current_selection.m_node; - uint32_t next_node = find_previous_available_channel_node(m_current_selection.m_dev, m_current_selection.m_guest_channel, prev_node, m_current_selection.m_node_channel); - if(next_node != 0xffffffff) { - m_current_selection.m_node = next_node; - if(prev_node) - machine().sound().config_remove_sound_io_channel_connection_node(m_current_selection.m_dev, m_current_selection.m_guest_channel, find_node_name(prev_node), m_current_selection.m_node_channel); - else - machine().sound().config_remove_sound_io_channel_connection_default(m_current_selection.m_dev, m_current_selection.m_guest_channel, m_current_selection.m_node_channel); - if(next_node) - machine().sound().config_add_sound_io_channel_connection_node(m_current_selection.m_dev, m_current_selection.m_guest_channel, find_node_name(next_node), m_current_selection.m_node_channel, m_current_selection.m_db); - else - machine().sound().config_add_sound_io_channel_connection_default(m_current_selection.m_dev, m_current_selection.m_guest_channel, m_current_selection.m_node_channel, m_current_selection.m_db); - m_generation --; - return true; + m_reset_selection.m_maptype = MT_FULL; + m_reset_selection.m_dev = current_selection.m_dev; + m_reset_selection.m_guest_channel = 0; + m_reset_selection.m_node_channel = 0; + m_reset_selection.m_db = 0.0; + m_reset_item = ITM_GUEST_CHANNEL; + reset(reset_options::REMEMBER_POSITION); + return true; +} + + +bool menu_audio_mixer::add_channel(select_entry ¤t_selection) +{ + // Find a possible triplet, any triplet + const auto &info = machine().sound().get_osd_info(); + uint32_t guest_channel; + uint32_t node_index, node_id; + uint32_t node_channel; + uint32_t default_osd_id = current_selection.m_dev->is_output() ? info.m_default_sink : info.m_default_source; + for(node_index = (default_osd_id == 0) ? 0 : 0xffffffff; node_index != info.m_nodes.size(); node_index++) { + node_id = node_index == 0xffffffff ? 0 : info.m_nodes[node_index].m_id; + uint32_t guest_channel_count = current_selection.m_dev->is_output() ? current_selection.m_dev->inputs() : current_selection.m_dev->outputs(); + uint32_t node_channel_count = 0; + if(node_index == 0xffffffff) { + for(uint32_t i = 0; i != info.m_nodes.size(); i++) { + if(info.m_nodes[i].m_id == default_osd_id) { + node_channel_count = current_selection.m_dev->is_output() ? info.m_nodes[i].m_sinks : info.m_nodes[i].m_sources; + break; } } - break; + } else { + node_channel_count = current_selection.m_dev->is_output() ? info.m_nodes[node_index].m_sinks : info.m_nodes[node_index].m_sources; } - - case GRP_DB: { - if(shift_pressed) - m_current_selection.m_db -= 0.1f; - else if(ctrl_pressed) - m_current_selection.m_db -= 10.0f; - else if(alt_pressed) { - if(m_current_selection.m_db > 0.0f) - m_current_selection.m_db = 0.0f; - else - m_current_selection.m_db = -96.0f; + for(guest_channel = 0; guest_channel != guest_channel_count; guest_channel++) { + for(node_channel = 0; node_channel != node_channel_count; node_channel++) { + if(channel_mapping_available(current_selection.m_dev, guest_channel, node_id, node_channel)) + goto found; } - else - m_current_selection.m_db -= 1.0f; + } + } + machine().popmessage(util::string_format( + current_selection.m_dev->is_output() + ? _("menu-audiomix", "No channel routes available for output device %1$s") + : _("menu-audiomix", "No channel routes available for input device %1$s"), + current_selection.m_dev->tag())); + return false; - m_current_selection.m_db = floorf(m_current_selection.m_db * 10.0f + 0.5f) / 10.0f; - m_current_selection.m_db = std::clamp(m_current_selection.m_db, -96.0f, 12.0f); +found: + if(node_id) + machine().sound().config_add_sound_io_channel_connection_node(current_selection.m_dev, guest_channel, info.m_nodes[node_index].name(), node_channel, 0.0); + else + machine().sound().config_add_sound_io_channel_connection_default(current_selection.m_dev, guest_channel, node_channel, 0.0); + m_reset_selection.m_maptype = MT_CHANNEL; + m_reset_selection.m_dev = current_selection.m_dev; + m_reset_selection.m_guest_channel = guest_channel; + m_reset_selection.m_node = node_id; + m_reset_selection.m_node_channel = node_channel; + m_reset_selection.m_db = 0.0; + m_reset_item = ITM_GUEST_CHANNEL; + reset(reset_options::REMEMBER_POSITION); + return true; +} - if(m_current_selection.m_maptype == MT_FULL) { - if(m_current_selection.m_node == 0) - machine().sound().config_set_volume_sound_io_connection_default(m_current_selection.m_dev, m_current_selection.m_db); - else - machine().sound().config_set_volume_sound_io_connection_node(m_current_selection.m_dev, find_node_name(m_current_selection.m_node), m_current_selection.m_db); + +bool menu_audio_mixer::delete_route(uint32_t cursel_index, select_entry ¤t_selection) +{ + if(current_selection.m_maptype == MT_FULL) { + if(current_selection.m_node == 0) + machine().sound().config_remove_sound_io_connection_default(current_selection.m_dev); + else + machine().sound().config_remove_sound_io_connection_node(current_selection.m_dev, find_node_name(current_selection.m_node)); + } else { + if(current_selection.m_node == 0) + machine().sound().config_remove_sound_io_channel_connection_default(current_selection.m_dev, current_selection.m_guest_channel, current_selection.m_node_channel); + else + machine().sound().config_remove_sound_io_channel_connection_node(current_selection.m_dev, current_selection.m_guest_channel, find_node_name(current_selection.m_node), current_selection.m_node_channel); + } + + // If the next item exists and is the same speaker, go there (visually, the cursor stays on the same line) + // Otherwise if the previous item exists and is the same speaker, go there (visually, the cursor goes up once) + // Otherwise create a MT_NONE, because one is going to appear at the same place + if(cursel_index + 1 < m_selections.size() && m_selections[cursel_index+1].m_dev == current_selection.m_dev) { + m_reset_selection = m_selections[cursel_index+1]; + m_reset_item = ITM_GUEST_CHANNEL; + } else if(cursel_index != 0 && m_selections[cursel_index-1].m_dev == current_selection.m_dev) { + m_reset_selection = m_selections[cursel_index-1]; + m_reset_item = ITM_GUEST_CHANNEL; + } else { + m_reset_selection.m_maptype = MT_NONE; + m_reset_selection.m_dev = current_selection.m_dev; + m_reset_selection.m_guest_channel = 0; + m_reset_selection.m_node = 0; + m_reset_selection.m_node_channel = 0; + m_reset_selection.m_db = 0.0; + m_reset_item = ITM_EMPTY; + } + + reset(reset_options::REMEMBER_POSITION); + return true; +} + + +bool menu_audio_mixer::set_prev_guest_channel(select_entry ¤t_selection) +{ + if(current_selection.m_maptype != MT_CHANNEL) + return false; + + uint32_t guest_channel_count = current_selection.m_dev->is_output() ? current_selection.m_dev->inputs() : current_selection.m_dev->outputs(); + if(guest_channel_count == 1) + return false; + + uint32_t guest_channel = current_selection.m_guest_channel; + for(;;) { + if(guest_channel == 0) + guest_channel = guest_channel_count - 1; + else + guest_channel--; + if(guest_channel == current_selection.m_guest_channel) + return false; + if(channel_mapping_available(current_selection.m_dev, guest_channel, current_selection.m_node, current_selection.m_node_channel)) { + if(current_selection.m_node) { + const auto node = find_node_name(current_selection.m_node); + machine().sound().config_remove_sound_io_channel_connection_node(current_selection.m_dev, current_selection.m_guest_channel, node, current_selection.m_node_channel); + machine().sound().config_add_sound_io_channel_connection_node(current_selection.m_dev, guest_channel, node, current_selection.m_node_channel, current_selection.m_db); } else { - if(m_current_selection.m_node == 0) - machine().sound().config_set_volume_sound_io_channel_connection_default(m_current_selection.m_dev, m_current_selection.m_guest_channel, m_current_selection.m_node_channel, m_current_selection.m_db); - else - machine().sound().config_set_volume_sound_io_channel_connection_node(m_current_selection.m_dev, m_current_selection.m_guest_channel, find_node_name(m_current_selection.m_node), m_current_selection.m_node_channel, m_current_selection.m_db); + machine().sound().config_remove_sound_io_channel_connection_default(current_selection.m_dev, current_selection.m_guest_channel, current_selection.m_node_channel); + machine().sound().config_add_sound_io_channel_connection_default(current_selection.m_dev, guest_channel, current_selection.m_node_channel, current_selection.m_db); } - m_generation --; + m_reset_selection.m_maptype = MT_INTERNAL; + reset(reset_options::REMEMBER_POSITION); return true; } + } - case GRP_GUEST_CHANNEL: { - if(m_current_selection.m_maptype != MT_CHANNEL) - return false; - - u32 guest_channel_count = m_current_selection.m_dev->is_output() ? m_current_selection.m_dev->inputs() : m_current_selection.m_dev->outputs(); - if(guest_channel_count == 1) - return false; - u32 guest_channel = m_current_selection.m_guest_channel; - for(;;) { - if(guest_channel == 0) - guest_channel = guest_channel_count - 1; - else - guest_channel --; - if(guest_channel == m_current_selection.m_guest_channel) - return false; - if(channel_mapping_available(m_current_selection.m_dev, guest_channel, m_current_selection.m_node, m_current_selection.m_node_channel)) { - if(m_current_selection.m_node) { - std::string node = find_node_name(m_current_selection.m_node); - machine().sound().config_remove_sound_io_channel_connection_node(m_current_selection.m_dev, m_current_selection.m_guest_channel, node, m_current_selection.m_node_channel); - machine().sound().config_add_sound_io_channel_connection_node(m_current_selection.m_dev, guest_channel, node, m_current_selection.m_node_channel, m_current_selection.m_db); - } else { - machine().sound().config_remove_sound_io_channel_connection_default(m_current_selection.m_dev, m_current_selection.m_guest_channel, m_current_selection.m_node_channel); - machine().sound().config_add_sound_io_channel_connection_default(m_current_selection.m_dev, guest_channel, m_current_selection.m_node_channel, m_current_selection.m_db); - } - m_current_selection.m_guest_channel = guest_channel; - m_generation --; - return true; - } + return false; +} + + +bool menu_audio_mixer::set_next_guest_channel(select_entry ¤t_selection) +{ + if(current_selection.m_maptype != MT_CHANNEL) + return false; + + uint32_t guest_channel_count = current_selection.m_dev->is_output() ? current_selection.m_dev->inputs() : current_selection.m_dev->outputs(); + if(guest_channel_count == 1) + return false; + + uint32_t guest_channel = current_selection.m_guest_channel; + for(;;) { + guest_channel++; + if(guest_channel == guest_channel_count) + guest_channel = 0; + if(guest_channel == current_selection.m_guest_channel) + return false; + if(channel_mapping_available(current_selection.m_dev, guest_channel, current_selection.m_node, current_selection.m_node_channel)) { + if(current_selection.m_node) { + const auto node = find_node_name(current_selection.m_node); + machine().sound().config_remove_sound_io_channel_connection_node(current_selection.m_dev, current_selection.m_guest_channel, node, current_selection.m_node_channel); + machine().sound().config_add_sound_io_channel_connection_node(current_selection.m_dev, guest_channel, node, current_selection.m_node_channel, current_selection.m_db); + } else { + machine().sound().config_remove_sound_io_channel_connection_default(current_selection.m_dev, current_selection.m_guest_channel, current_selection.m_node_channel); + machine().sound().config_add_sound_io_channel_connection_default(current_selection.m_dev, guest_channel, current_selection.m_node_channel, current_selection.m_db); } - break; + m_reset_selection.m_maptype = MT_INTERNAL; + reset(reset_options::REMEMBER_POSITION); + return true; } + } - case GRP_NODE_CHANNEL: { - if(m_current_selection.m_maptype != MT_CHANNEL) - return false; - - u32 node_channel_count = find_node_channel_count(m_current_selection.m_node, m_current_selection.m_dev->is_output()); - if(node_channel_count == 1) - return false; - u32 node_channel = m_current_selection.m_node_channel; - for(;;) { - if(node_channel == 0) - node_channel = node_channel_count - 1; - else - node_channel --; - if(node_channel == m_current_selection.m_node_channel) - return false; - if(channel_mapping_available(m_current_selection.m_dev, m_current_selection.m_guest_channel, m_current_selection.m_node, node_channel)) { - if(m_current_selection.m_node) { - std::string node = find_node_name(m_current_selection.m_node); - machine().sound().config_remove_sound_io_channel_connection_node(m_current_selection.m_dev, m_current_selection.m_guest_channel, node, m_current_selection.m_node_channel); - machine().sound().config_add_sound_io_channel_connection_node(m_current_selection.m_dev, m_current_selection.m_guest_channel, node, node_channel, m_current_selection.m_db); - } else { - machine().sound().config_remove_sound_io_channel_connection_default(m_current_selection.m_dev, m_current_selection.m_guest_channel, m_current_selection.m_node_channel); - machine().sound().config_add_sound_io_channel_connection_default(m_current_selection.m_dev, m_current_selection.m_guest_channel, node_channel, m_current_selection.m_db); - } - m_current_selection.m_node_channel = node_channel; - m_generation --; - return true; - } - } - break; + return false; +} + + +bool menu_audio_mixer::set_prev_node(select_entry ¤t_selection) +{ + if(current_selection.m_maptype == MT_FULL) { + const uint32_t prev_node = current_selection.m_node; + const uint32_t next_node = find_previous_available_node(current_selection.m_dev, prev_node); + if(next_node != 0xffffffff) { + if(prev_node) + machine().sound().config_remove_sound_io_connection_node(current_selection.m_dev, find_node_name(prev_node)); + else + machine().sound().config_remove_sound_io_connection_default(current_selection.m_dev); + if(next_node) + machine().sound().config_add_sound_io_connection_node(current_selection.m_dev, find_node_name(next_node), current_selection.m_db); + else + machine().sound().config_add_sound_io_connection_default(current_selection.m_dev, current_selection.m_db); + m_reset_selection.m_maptype = MT_INTERNAL; + reset(reset_options::REMEMBER_POSITION); + return true; } + } else if(current_selection.m_maptype == MT_CHANNEL) { + const uint32_t prev_node = current_selection.m_node; + const uint32_t next_node = find_previous_available_channel_node(current_selection.m_dev, current_selection.m_guest_channel, prev_node, current_selection.m_node_channel); + if(next_node != 0xffffffff) { + if(prev_node) + machine().sound().config_remove_sound_io_channel_connection_node(current_selection.m_dev, current_selection.m_guest_channel, find_node_name(prev_node), current_selection.m_node_channel); + else + machine().sound().config_remove_sound_io_channel_connection_default(current_selection.m_dev, current_selection.m_guest_channel, current_selection.m_node_channel); + if(next_node) + machine().sound().config_add_sound_io_channel_connection_node(current_selection.m_dev, current_selection.m_guest_channel, find_node_name(next_node), current_selection.m_node_channel, current_selection.m_db); + else + machine().sound().config_add_sound_io_channel_connection_default(current_selection.m_dev, current_selection.m_guest_channel, current_selection.m_node_channel, current_selection.m_db); + m_reset_selection.m_maptype = MT_INTERNAL; + reset(reset_options::REMEMBER_POSITION); + return true; } - break; } - case IPT_UI_RIGHT: { - if(m_current_selection.m_maptype == MT_NONE || m_current_selection.m_maptype == MT_INTERNAL) - return false; + return false; +} - switch(m_current_group) { - case GRP_NODE: { - if(m_current_selection.m_maptype == MT_FULL) { - uint32_t prev_node = m_current_selection.m_node; - uint32_t next_node = find_next_available_node(m_current_selection.m_dev, prev_node); - if(next_node != 0xffffffff) { - m_current_selection.m_node = next_node; - if(prev_node) - machine().sound().config_remove_sound_io_connection_node(m_current_selection.m_dev, find_node_name(prev_node)); - else - machine().sound().config_remove_sound_io_connection_default(m_current_selection.m_dev); - if(next_node) - machine().sound().config_add_sound_io_connection_node(m_current_selection.m_dev, find_node_name(next_node), m_current_selection.m_db); - else - machine().sound().config_add_sound_io_connection_default(m_current_selection.m_dev, m_current_selection.m_db); - m_generation --; - return true; - } - } else if(m_current_selection.m_maptype == MT_CHANNEL) { - uint32_t prev_node = m_current_selection.m_node; - uint32_t next_node = find_next_available_channel_node(m_current_selection.m_dev, m_current_selection.m_guest_channel, prev_node, m_current_selection.m_node_channel); - if(next_node != 0xffffffff) { - m_current_selection.m_node = next_node; - if(prev_node) - machine().sound().config_remove_sound_io_channel_connection_node(m_current_selection.m_dev, m_current_selection.m_guest_channel, find_node_name(prev_node), m_current_selection.m_node_channel); - else - machine().sound().config_remove_sound_io_channel_connection_default(m_current_selection.m_dev, m_current_selection.m_guest_channel, m_current_selection.m_node_channel); - if(next_node) - machine().sound().config_add_sound_io_channel_connection_node(m_current_selection.m_dev, m_current_selection.m_guest_channel, find_node_name(next_node), m_current_selection.m_node_channel, m_current_selection.m_db); - else - machine().sound().config_add_sound_io_channel_connection_default(m_current_selection.m_dev, m_current_selection.m_guest_channel, m_current_selection.m_node_channel, m_current_selection.m_db); - m_generation --; - return true; - } - } - break; - } - case GRP_DB: { - if(shift_pressed) - m_current_selection.m_db += 0.1f; - else if(ctrl_pressed) - m_current_selection.m_db += 10.0f; - else if(alt_pressed) { - if(m_current_selection.m_db < 0.0f) - m_current_selection.m_db = 0.0f; - else - m_current_selection.m_db = 12.0f; - } +bool menu_audio_mixer::set_next_node(select_entry ¤t_selection) +{ + if(current_selection.m_maptype == MT_FULL) { + const uint32_t prev_node = current_selection.m_node; + const uint32_t next_node = find_next_available_node(current_selection.m_dev, prev_node); + if(next_node != 0xffffffff) { + current_selection.m_node = next_node; + if(prev_node) + machine().sound().config_remove_sound_io_connection_node(current_selection.m_dev, find_node_name(prev_node)); else - m_current_selection.m_db += 1.0f; + machine().sound().config_remove_sound_io_connection_default(current_selection.m_dev); + if(next_node) + machine().sound().config_add_sound_io_connection_node(current_selection.m_dev, find_node_name(next_node), current_selection.m_db); + else + machine().sound().config_add_sound_io_connection_default(current_selection.m_dev, current_selection.m_db); + m_reset_selection.m_maptype = MT_INTERNAL; + reset(reset_options::REMEMBER_POSITION); + return true; + } + } else if(current_selection.m_maptype == MT_CHANNEL) { + const uint32_t prev_node = current_selection.m_node; + const uint32_t next_node = find_next_available_channel_node(current_selection.m_dev, current_selection.m_guest_channel, prev_node, current_selection.m_node_channel); + if(next_node != 0xffffffff) { + current_selection.m_node = next_node; + if(prev_node) + machine().sound().config_remove_sound_io_channel_connection_node(current_selection.m_dev, current_selection.m_guest_channel, find_node_name(prev_node), current_selection.m_node_channel); + else + machine().sound().config_remove_sound_io_channel_connection_default(current_selection.m_dev, current_selection.m_guest_channel, current_selection.m_node_channel); + if(next_node) + machine().sound().config_add_sound_io_channel_connection_node(current_selection.m_dev, current_selection.m_guest_channel, find_node_name(next_node), current_selection.m_node_channel, current_selection.m_db); + else + machine().sound().config_add_sound_io_channel_connection_default(current_selection.m_dev, current_selection.m_guest_channel, current_selection.m_node_channel, current_selection.m_db); + m_reset_selection.m_maptype = MT_INTERNAL; + reset(reset_options::REMEMBER_POSITION); + return true; + } + } - m_current_selection.m_db = floorf(m_current_selection.m_db * 10.0f + 0.5f) / 10.0f; - m_current_selection.m_db = std::clamp(m_current_selection.m_db, -96.0f, 12.0f); + return false; +} - if(m_current_selection.m_maptype == MT_FULL) { - if(m_current_selection.m_node == 0) - machine().sound().config_set_volume_sound_io_connection_default(m_current_selection.m_dev, m_current_selection.m_db); - else - machine().sound().config_set_volume_sound_io_connection_node(m_current_selection.m_dev, find_node_name(m_current_selection.m_node), m_current_selection.m_db); + +bool menu_audio_mixer::set_prev_node_channel(select_entry ¤t_selection) +{ + if(current_selection.m_maptype != MT_CHANNEL) + return false; + + uint32_t node_channel_count = find_node_channel_count(current_selection.m_node, current_selection.m_dev->is_output()); + if(node_channel_count == 1) + return false; + + uint32_t node_channel = current_selection.m_node_channel; + for(;;) { + if(node_channel == 0) + node_channel = node_channel_count - 1; + else + node_channel--; + if(node_channel == current_selection.m_node_channel) + return false; + if(channel_mapping_available(current_selection.m_dev, current_selection.m_guest_channel, current_selection.m_node, node_channel)) { + if(current_selection.m_node) { + const auto node = find_node_name(current_selection.m_node); + machine().sound().config_remove_sound_io_channel_connection_node(current_selection.m_dev, current_selection.m_guest_channel, node, current_selection.m_node_channel); + machine().sound().config_add_sound_io_channel_connection_node(current_selection.m_dev, current_selection.m_guest_channel, node, node_channel, current_selection.m_db); } else { - if(m_current_selection.m_node == 0) - machine().sound().config_set_volume_sound_io_channel_connection_default(m_current_selection.m_dev, m_current_selection.m_guest_channel, m_current_selection.m_node_channel, m_current_selection.m_db); - else - machine().sound().config_set_volume_sound_io_channel_connection_node(m_current_selection.m_dev, m_current_selection.m_guest_channel, find_node_name(m_current_selection.m_node), m_current_selection.m_node_channel, m_current_selection.m_db); + machine().sound().config_remove_sound_io_channel_connection_default(current_selection.m_dev, current_selection.m_guest_channel, current_selection.m_node_channel); + machine().sound().config_add_sound_io_channel_connection_default(current_selection.m_dev, current_selection.m_guest_channel, node_channel, current_selection.m_db); } - m_generation --; + m_reset_selection.m_maptype = MT_INTERNAL; + reset(reset_options::REMEMBER_POSITION); return true; } + } - case GRP_GUEST_CHANNEL: { - if(m_current_selection.m_maptype != MT_CHANNEL) - return false; - - u32 guest_channel_count = m_current_selection.m_dev->is_output() ? m_current_selection.m_dev->inputs() : m_current_selection.m_dev->outputs(); - if(guest_channel_count == 1) - return false; - u32 guest_channel = m_current_selection.m_guest_channel; - for(;;) { - guest_channel ++; - if(guest_channel == guest_channel_count) - guest_channel = 0; - if(guest_channel == m_current_selection.m_guest_channel) - return false; - if(channel_mapping_available(m_current_selection.m_dev, guest_channel, m_current_selection.m_node, m_current_selection.m_node_channel)) { - if(m_current_selection.m_node) { - std::string node = find_node_name(m_current_selection.m_node); - machine().sound().config_remove_sound_io_channel_connection_node(m_current_selection.m_dev, m_current_selection.m_guest_channel, node, m_current_selection.m_node_channel); - machine().sound().config_add_sound_io_channel_connection_node(m_current_selection.m_dev, guest_channel, node, m_current_selection.m_node_channel, m_current_selection.m_db); - } else { - machine().sound().config_remove_sound_io_channel_connection_default(m_current_selection.m_dev, m_current_selection.m_guest_channel, m_current_selection.m_node_channel); - machine().sound().config_add_sound_io_channel_connection_default(m_current_selection.m_dev, guest_channel, m_current_selection.m_node_channel, m_current_selection.m_db); - } - m_current_selection.m_guest_channel = guest_channel; - m_generation --; - return true; - } - } - break; - } + return false; +} - case GRP_NODE_CHANNEL: { - if(m_current_selection.m_maptype != MT_CHANNEL) - return false; - - u32 node_channel_count = find_node_channel_count(m_current_selection.m_node, m_current_selection.m_dev->is_output()); - if(node_channel_count == 1) - return false; - u32 node_channel = m_current_selection.m_node_channel; - for(;;) { - node_channel ++; - if(node_channel == node_channel_count) - node_channel = 0; - if(node_channel == m_current_selection.m_node_channel) - return false; - if(channel_mapping_available(m_current_selection.m_dev, m_current_selection.m_guest_channel, m_current_selection.m_node, node_channel)) { - if(m_current_selection.m_node) { - std::string node = find_node_name(m_current_selection.m_node); - machine().sound().config_remove_sound_io_channel_connection_node(m_current_selection.m_dev, m_current_selection.m_guest_channel, node, m_current_selection.m_node_channel); - machine().sound().config_add_sound_io_channel_connection_node(m_current_selection.m_dev, m_current_selection.m_guest_channel, node, node_channel, m_current_selection.m_db); - } else { - machine().sound().config_remove_sound_io_channel_connection_default(m_current_selection.m_dev, m_current_selection.m_guest_channel, m_current_selection.m_node_channel); - machine().sound().config_add_sound_io_channel_connection_default(m_current_selection.m_dev, m_current_selection.m_guest_channel, node_channel, m_current_selection.m_db); - } - m_current_selection.m_node_channel = node_channel; - m_generation --; - return true; - } + +bool menu_audio_mixer::set_next_node_channel(select_entry ¤t_selection) +{ + if(current_selection.m_maptype != MT_CHANNEL) + return false; + + uint32_t node_channel_count = find_node_channel_count(current_selection.m_node, current_selection.m_dev->is_output()); + if(node_channel_count == 1) + return false; + + uint32_t node_channel = current_selection.m_node_channel; + for(;;) { + node_channel++; + if(node_channel == node_channel_count) + node_channel = 0; + if(node_channel == current_selection.m_node_channel) + return false; + if(channel_mapping_available(current_selection.m_dev, current_selection.m_guest_channel, current_selection.m_node, node_channel)) { + if(current_selection.m_node) { + const auto node = find_node_name(current_selection.m_node); + machine().sound().config_remove_sound_io_channel_connection_node(current_selection.m_dev, current_selection.m_guest_channel, node, current_selection.m_node_channel); + machine().sound().config_add_sound_io_channel_connection_node(current_selection.m_dev, current_selection.m_guest_channel, node, node_channel, current_selection.m_db); + } else { + machine().sound().config_remove_sound_io_channel_connection_default(current_selection.m_dev, current_selection.m_guest_channel, current_selection.m_node_channel); + machine().sound().config_add_sound_io_channel_connection_default(current_selection.m_dev, current_selection.m_guest_channel, node_channel, current_selection.m_db); } - break; - } + m_reset_selection.m_maptype = MT_INTERNAL; + reset(reset_options::REMEMBER_POSITION); + return true; } - break; - } } return false; } +bool menu_audio_mixer::set_route_volume(menu_item &item, select_entry ¤t_selection) +{ + current_selection.m_db = floorf(current_selection.m_db * 10.0f + 0.5f) / 10.0f; + current_selection.m_db = std::clamp(current_selection.m_db, -96.0f, 12.0f); + + if(current_selection.m_maptype == MT_FULL) { + if(current_selection.m_node == 0) + machine().sound().config_set_volume_sound_io_connection_default(current_selection.m_dev, current_selection.m_db); + else + machine().sound().config_set_volume_sound_io_connection_node(current_selection.m_dev, find_node_name(current_selection.m_node), current_selection.m_db); + } else { + if(current_selection.m_node == 0) + machine().sound().config_set_volume_sound_io_channel_connection_default(current_selection.m_dev, current_selection.m_guest_channel, current_selection.m_node_channel, current_selection.m_db); + else + machine().sound().config_set_volume_sound_io_channel_connection_node(current_selection.m_dev, current_selection.m_guest_channel, find_node_name(current_selection.m_node), current_selection.m_node_channel, current_selection.m_db); + } + + item.set_subtext(util::string_format(_("menu-audiomix", "%1$g dB"), current_selection.m_db)); + item.set_flags(((current_selection.m_db > -96.0f) ? FLAG_LEFT_ARROW : 0) | ((current_selection.m_db < 12.0f) ? FLAG_RIGHT_ARROW : 0)); + return true; +} + + //------------------------------------------------- // menu_audio_mixer_populate - populate the audio_mixer // menu @@ -519,23 +611,24 @@ void menu_audio_mixer::populate() const auto &info = machine().sound().get_osd_info(); m_generation = info.m_generation; - auto find_node = [&info](u32 node_id) -> const osd::audio_info::node_info * { - for(const auto &node : info.m_nodes) - if(node.m_id == node_id) - return &node; - // Never happens - return nullptr; - }; + const auto find_node = + [&info](uint32_t node_id) -> const osd::audio_info::node_info * { + for(const auto &node : info.m_nodes) + if(node.m_id == node_id) + return &node; + // Never happens + return nullptr; + }; // Rebuild the selections list m_selections.clear(); for(const auto &omap : mapping) { for(const auto &nmap : omap.m_node_mappings) - m_selections.emplace_back(select_entry { MT_FULL, omap.m_dev, 0, nmap.m_is_system_default ? 0 : nmap.m_node, 0, nmap.m_db }); + m_selections.emplace_back(select_entry{ MT_FULL, omap.m_dev, 0, nmap.m_is_system_default ? 0 : nmap.m_node, 0, nmap.m_db }); for(const auto &cmap : omap.m_channel_mappings) - m_selections.emplace_back(select_entry { MT_CHANNEL, omap.m_dev, cmap.m_guest_channel, cmap.m_is_system_default ? 0 : cmap.m_node, cmap.m_node_channel, cmap.m_db }); + m_selections.emplace_back(select_entry{ MT_CHANNEL, omap.m_dev, cmap.m_guest_channel, cmap.m_is_system_default ? 0 : cmap.m_node, cmap.m_node_channel, cmap.m_db }); if(omap.m_node_mappings.empty() && omap.m_channel_mappings.empty()) - m_selections.emplace_back(select_entry { MT_NONE, omap.m_dev, 0, 0, 0, 0 }); + m_selections.emplace_back(select_entry{ MT_NONE, omap.m_dev, 0, 0, 0, 0 }); } // If there's nothing, get out of there @@ -544,97 +637,133 @@ void menu_audio_mixer::populate() // Find the line of the current selection, if any. // Otherwise default to the first line - u32 cursel_line = 0xffffffff; - - for(u32 i = 0; i != m_selections.size(); i++) { - if(m_current_selection == m_selections[i]) { + uint32_t cursel_line = 0xffffffff; + for(uint32_t i = 0; i != m_selections.size(); i++) { + if(m_reset_selection == m_selections[i]) { cursel_line = i; break; } } - if(cursel_line == 0xffffffff) - for(u32 i = 0; i != m_selections.size(); i++) { - if(m_current_selection.m_dev == m_selections[i].m_dev) { + if(cursel_line == 0xffffffff) { + for(uint32_t i = 0; i != m_selections.size(); i++) { + if(m_reset_selection.m_dev == m_selections[i].m_dev) { + if (m_selections[i].m_maptype != MT_NONE) + m_reset_item = ITM_GUEST_CHANNEL; + else + m_reset_item = ITM_EMPTY; cursel_line = i; break; } } + } if(cursel_line == 0xffffffff) cursel_line = 0; - if(m_current_selection.m_maptype == MT_INTERNAL) + if(m_reset_selection.m_maptype == MT_INTERNAL) cursel_line = 0xffffffff; - else - m_current_selection = m_selections[cursel_line]; - if(m_current_selection.m_maptype == MT_FULL) { - if(m_current_group == GRP_GUEST_CHANNEL || m_current_group == GRP_NODE_CHANNEL) - m_current_group = GRP_NODE; + if((cursel_line < m_selections.size()) && (m_selections[cursel_line].m_maptype == MT_FULL)) { + if(m_reset_item == ITM_NODE_CHANNEL) + m_reset_item = ITM_NODE; } // (Re)build the menu - u32 curline = 0; + uint32_t cursel = 0; for(const auto &omap : mapping) { item_append(omap.m_dev->tag(), FLAG_UI_HEADING | FLAG_DISABLE, nullptr); + bool first = true; for(const auto &nmap : omap.m_node_mappings) { const auto &node = find_node(nmap.m_node); - std::string lnode = nmap.m_is_system_default ? "[default]" : node->m_display_name; - if(!omap.m_dev->is_output() && node->m_sinks) - lnode = util::string_format("Monitor of %s", lnode); - if(curline == cursel_line && m_current_group == GRP_NODE) - lnode = u8"\u25c4" + lnode + u8"\u25ba"; - std::string line = (omap.m_dev->is_output() ? "> " : "< ") + lnode; - - std::string db = util::string_format("%g dB", nmap.m_db); - if(curline == cursel_line && m_current_group == GRP_DB) - db = u8"\u25c4" + db + u8"\u25ba"; - - item_append(line, db, 0, m_selections.data() + curline); - curline ++; + if(first) + first = false; + else + item_append(menu_item_type::SEPARATOR); + + item_append( + omap.m_dev->is_output() ? _("menu-audiomix", "Output") : _("menu-audiomix", "Input"), + _("menu-audiomix", "[all]"), + 0, + reinterpret_cast<void *>(((cursel + 1) << 3) | ITM_GUEST_CHANNEL)); + item_append( + _("menu-audiomix", "Device"), + nmap.m_is_system_default ? + _("menu-audiomix", "[default]") : + (omap.m_dev->is_output() || !node->m_sinks) ? + node->m_display_name : + util::string_format(_("menu-audiomix", "Monitor of %1$s"), node->m_display_name), + FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW, + reinterpret_cast<void *>(((cursel + 1) << 3) | ITM_NODE)); + item_append( + _("menu-audiomix", "Volume"), + util::string_format(_("menu-audiomix", "%1$g dB"), nmap.m_db), + ((nmap.m_db > -96.0f) ? FLAG_LEFT_ARROW : 0) | ((nmap.m_db < 12.0f) ? FLAG_RIGHT_ARROW : 0), + reinterpret_cast<void *>(((cursel + 1) << 3) | ITM_DB)); + item_append( + _("menu-audiomix", "Delete route"), + 0, + reinterpret_cast<void *>(((cursel + 1) << 3) | ITM_DELETE)); + + ++cursel; } for(const auto &cmap : omap.m_channel_mappings) { const auto &node = find_node(cmap.m_node); - std::string guest_channel = omap.m_dev->get_position(cmap.m_guest_channel).name(); - if(curline == cursel_line && m_current_group == GRP_GUEST_CHANNEL) - guest_channel = u8"\u25c4" + guest_channel + u8"\u25ba"; - - std::string lnode = cmap.m_is_system_default ? "[default]" : node->m_display_name; - if(!omap.m_dev->is_output() && node->m_sinks) - lnode = util::string_format("Monitor of %s", lnode); - if(curline == cursel_line && m_current_group == GRP_NODE) - lnode = u8"\u25c4" + lnode + u8"\u25ba"; - std::string lnode_channel = node->m_port_names[cmap.m_node_channel]; - if(curline == cursel_line && m_current_group == GRP_NODE_CHANNEL) - lnode_channel = u8"\u25c4" + lnode_channel + u8"\u25ba"; - - std::string line = guest_channel + " > " + lnode + ":" + lnode_channel; - - std::string db = util::string_format("%g dB", cmap.m_db); - if(curline == cursel_line && m_current_group == GRP_DB) - db = u8"\u25c4" + db + u8"\u25ba"; - - item_append(line, db, 0, m_selections.data() + curline); - curline ++; + if(first) + first = false; + else + item_append(menu_item_type::SEPARATOR); + + item_append( + omap.m_dev->is_output() ? _("menu-audiomix", "Output") : _("menu-audiomix", "Input"), + omap.m_dev->get_position(cmap.m_guest_channel).name(), + FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW, + reinterpret_cast<void *>(((cursel + 1) << 3) | ITM_GUEST_CHANNEL)); + item_append( + _("menu-audiomix", "Device"), + cmap.m_is_system_default ? + _("menu-audiomix", "[default]") : + (omap.m_dev->is_output() || !node->m_sinks) ? + node->m_display_name : + util::string_format(_("menu-audiomix", "Monitor of %1$s"), node->m_display_name), + FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW, + reinterpret_cast<void *>(((cursel + 1) << 3) | ITM_NODE)); + item_append( + _("menu-audiomix", "Channel"), + node->m_port_names[cmap.m_node_channel], + FLAG_LEFT_ARROW | FLAG_RIGHT_ARROW, + reinterpret_cast<void *>(((cursel + 1) << 3) | ITM_NODE_CHANNEL)); + item_append( + _("menu-audiomix", "Volume"), + util::string_format(_("menu-audiomix", "%1$g dB"), cmap.m_db), + ((cmap.m_db > -96.0f) ? FLAG_LEFT_ARROW : 0) | ((cmap.m_db < 12.0f) ? FLAG_RIGHT_ARROW : 0), + reinterpret_cast<void *>(((cursel + 1) << 3) | ITM_DB)); + item_append( + _("menu-audiomix", "Delete route"), + 0, + reinterpret_cast<void *>(((cursel + 1) << 3) | ITM_DELETE)); + + ++cursel; } if(omap.m_node_mappings.empty() && omap.m_channel_mappings.empty()) { - item_append("[no mapping]", 0, m_selections.data() + curline); - curline ++; + item_append( + _("menu-audiomix", "[no routes]"), + 0, + reinterpret_cast<void *>(((cursel + 1) << 3) | ITM_EMPTY)); + + ++cursel; } } - item_append(menu_item_type::SEPARATOR); - item_append(util::string_format("%s: add a full mapping", ui().get_general_input_setting(IPT_UI_MIXER_ADD_FULL)), FLAG_DISABLE, nullptr); - item_append(util::string_format("%s: add a channel mapping", ui().get_general_input_setting(IPT_UI_MIXER_ADD_CHANNEL)), FLAG_DISABLE, nullptr); - item_append(util::string_format("%s: remove a mapping", ui().get_general_input_setting(IPT_UI_CLEAR)), FLAG_DISABLE, nullptr); + item_append(menu_item_type::SEPARATOR); if(cursel_line != 0xffffffff) - set_selection(m_selections.data() + cursel_line); + set_selection(reinterpret_cast<void *>(((cursel_line + 1) << 3) | m_reset_item)); - set_process_flags(PROCESS_LR_ALWAYS | ((m_current_group == GRP_DB) ? PROCESS_LR_REPEAT : 0)); + m_add_full_prompt = util::string_format(_("menu-audiomix", "Press %1$s to add a full route\n"), ui().get_general_input_setting(IPT_UI_MIXER_ADD_FULL)); + m_add_channel_prompt = util::string_format(_("menu-audiomix", "Press %1$s to add a channel route\n"), ui().get_general_input_setting(IPT_UI_MIXER_ADD_CHANNEL)); } @@ -646,7 +775,8 @@ void menu_audio_mixer::recompute_metrics(uint32_t width, uint32_t height, float { menu::recompute_metrics(width, height, aspect); - // set_custom_space(0.0f, 2.0f * line_height() + 2.0f * tb_border()); + // leave space for showing prompts below the menu + set_custom_space(0.0f, 2.0f * line_height() + 3.0f * tb_border()); } @@ -657,6 +787,14 @@ void menu_audio_mixer::recompute_metrics(uint32_t width, uint32_t height, float void menu_audio_mixer::custom_render(uint32_t flags, void *selectedref, float top, float bottom, float x1, float y1, float x2, float y2) { + char const *const text[] = { + m_add_full_prompt.c_str(), + m_add_channel_prompt.c_str() }; + draw_text_box( + std::begin(text), std::end(text), + x1, x2, y2 + tb_border(), y2 + bottom, + text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER, false, + ui().colors().text_color(), ui().colors().background_color()); } @@ -667,7 +805,19 @@ void menu_audio_mixer::custom_render(uint32_t flags, void *selectedref, float to void menu_audio_mixer::menu_activated() { // scripts or the other form of the menu could have changed something in the mean time - reset(reset_options::REMEMBER_POSITION); + const auto selection_ref = uintptr_t(get_selection_ref()); + const uint32_t selection_num = selection_ref >> 3; + if((1 <= selection_num) && (m_selections.size() >= selection_num)) + { + m_reset_selection = m_selections[selection_num - 1]; + m_reset_item = BIT(selection_ref, 0, 3); + reset(reset_options::REMEMBER_POSITION); + } + else + { + m_reset_selection.m_maptype = MT_INTERNAL; + reset(reset_options::REMEMBER_REF); + } } diff --git a/src/frontend/mame/ui/audiomix.h b/src/frontend/mame/ui/audiomix.h index 5f8468f01f0..446512e71bb 100644 --- a/src/frontend/mame/ui/audiomix.h +++ b/src/frontend/mame/ui/audiomix.h @@ -15,6 +15,9 @@ #include "ui/menu.h" +#include <string> +#include <vector> + namespace ui { @@ -31,42 +34,46 @@ protected: virtual void menu_deactivated() override; private: - enum { - MT_UNDEFINED, // At startup - MT_NONE, // [no mapping] - MT_FULL, // Full mapping to node - MT_CHANNEL, // Channel-to-channel mapping - MT_INTERNAL // Go back to previous menu or other non-mapping entry - }; - - enum { - GRP_GUEST_CHANNEL, - GRP_NODE, - GRP_NODE_CHANNEL, - GRP_DB - }; - struct select_entry { - u32 m_maptype; + uint32_t m_maptype; sound_io_device *m_dev; - u32 m_guest_channel; - u32 m_node; - u32 m_node_channel; + uint32_t m_guest_channel; + uint32_t m_node; + uint32_t m_node_channel; float m_db; - inline bool operator ==(const select_entry &sel) { - return sel.m_maptype == m_maptype && sel.m_dev == m_dev && sel.m_guest_channel == m_guest_channel && sel.m_node == m_node && sel.m_node_channel == m_node_channel; + bool operator==(const select_entry &sel) const { + return + (sel.m_maptype == m_maptype) && + (sel.m_dev == m_dev) && + (sel.m_guest_channel == m_guest_channel) && + (sel.m_node == m_node) && + (sel.m_node_channel == m_node_channel); } }; uint32_t m_generation; - select_entry m_current_selection; - uint32_t m_current_group; + select_entry m_reset_selection; + uint32_t m_reset_item; std::vector<select_entry> m_selections; + std::string m_add_full_prompt; + std::string m_add_channel_prompt; + virtual void populate() override; virtual bool handle(event const *ev) override; + bool add_full(select_entry ¤t_selection); + bool add_channel(select_entry ¤t_selection); + bool delete_route(uint32_t cursel_index, select_entry ¤t_selection); + bool set_prev_guest_channel(select_entry ¤t_selection); + bool set_next_guest_channel(select_entry ¤t_selection); + bool set_prev_node(select_entry ¤t_selection); + bool set_next_node(select_entry ¤t_selection); + bool set_prev_node_channel(select_entry ¤t_selection); + bool set_next_node_channel(select_entry ¤t_selection); + bool set_route_volume(menu_item &item, select_entry ¤t_selection); + uint32_t find_node_index(uint32_t node) const; std::string find_node_name(uint32_t node) const; uint32_t find_node_channel_count(uint32_t node, bool is_output) const; diff --git a/src/frontend/mame/ui/imgcntrl.cpp b/src/frontend/mame/ui/imgcntrl.cpp index cbddb793d13..74ab2702e28 100644 --- a/src/frontend/mame/ui/imgcntrl.cpp +++ b/src/frontend/mame/ui/imgcntrl.cpp @@ -24,7 +24,6 @@ #include "drivenum.h" #include "emuopts.h" #include "image.h" -#include "mame.h" #include "softlist_dev.h" #include "util/zippath.h" @@ -198,8 +197,7 @@ void menu_control_device_image::load_software_part() } else { - machine().popmessage(_("The software selected is missing one or more required ROM or CHD images.\nPlease acquire the correct file(s) applicable to %1$s %2$s, or select a different one."), - emulator_info::get_appname(), bare_build_version); + machine().popmessage(_("Files required for the selected software are missing or incorrect.")); m_state = SELECT_SOFTLIST; menu_activated(); } diff --git a/src/frontend/mame/ui/mainmenu.cpp b/src/frontend/mame/ui/mainmenu.cpp index 72f368f8e61..987febb7b67 100644 --- a/src/frontend/mame/ui/mainmenu.cpp +++ b/src/frontend/mame/ui/mainmenu.cpp @@ -12,8 +12,8 @@ #include "ui/mainmenu.h" #include "ui/about.h" -#include "ui/audiomix.h" #include "ui/audioeffects.h" +#include "ui/audiomix.h" #include "ui/barcode.h" #include "ui/cheatopt.h" #include "ui/confswitch.h" diff --git a/src/frontend/mame/ui/selmenu.cpp b/src/frontend/mame/ui/selmenu.cpp index 88fc3aba332..5af866846c1 100644 --- a/src/frontend/mame/ui/selmenu.cpp +++ b/src/frontend/mame/ui/selmenu.cpp @@ -3879,13 +3879,15 @@ std::string menu_select_launch::make_system_audit_fail_text(media_auditor const { str << "System media audit failed:\n"; auditor.summarize(nullptr, &str); - osd_printf_info(str.str()); + osd_printf_info(std::move(str).str()); str.str(""); } - str << util::string_format(_("Required ROM/disk images for the selected system are missing or incorrect.\nPlease acquire the correct file(s) applicable to %1$s %2$s, or select a different system.\n\n"), - emulator_info::get_appname(), bare_build_version); + if ((media_auditor::NOTFOUND != summary) && !auditor.records().empty()) + str << _("The following ROM/disk images required for the selected system are missing or incorrect:\n\n"); + else + str << _("Required ROM/disk images for the selected system are missing or incorrect.\n\n"); make_audit_fail_text(str, auditor, summary); - return str.str(); + return std::move(str).str(); } @@ -3894,15 +3896,17 @@ std::string menu_select_launch::make_software_audit_fail_text(media_auditor cons std::ostringstream str; if (!auditor.records().empty()) { - str << "System media audit failed:\n"; + str << "Software media audit failed:\n"; auditor.summarize(nullptr, &str); - osd_printf_info(str.str()); + osd_printf_info(std::move(str).str()); str.str(""); } - str << util::string_format(_("Required ROM/disk images for the selected software are missing or incorrect.\nPlease acquire the correct file(s) applicable to %1$s %2$s, or select a different software item.\n\n"), - emulator_info::get_appname(), bare_build_version); + if ((media_auditor::NOTFOUND != summary) && !auditor.records().empty()) + str << _("The following ROM/disk images required for the selected software are missing or incorrect:\n\n"); + else + str << _("Required ROM/disk images for the selected software are missing or incorrect.\n\n"); make_audit_fail_text(str, auditor, summary); - return str.str(); + return std::move(str).str(); } diff --git a/src/frontend/mame/ui/sliders.cpp b/src/frontend/mame/ui/sliders.cpp index 813593eb3dc..d59757914ef 100644 --- a/src/frontend/mame/ui/sliders.cpp +++ b/src/frontend/mame/ui/sliders.cpp @@ -60,14 +60,6 @@ bool menu_sliders::handle(event const *ev) } } - // make sure menu won't be hidden when re-entering it - if (!m_menuless_mode && m_hidden && ev->iptkey == IPT_UI_MENU) - { - m_hidden = false; - set_process_flags(PROCESS_LR_REPEAT); - return true; - } - // handle keys if there is a valid item selected if (ev->itemref && (ev->item->type() == menu_item_type::SLIDER)) { diff --git a/src/frontend/mame/ui/ui.cpp b/src/frontend/mame/ui/ui.cpp index 42e3af06eb4..cb6a66b24a2 100644 --- a/src/frontend/mame/ui/ui.cpp +++ b/src/frontend/mame/ui/ui.cpp @@ -671,6 +671,33 @@ void mame_ui_manager::display_startup_screens(bool first_time) return HANDLER_CANCEL; } + ui_event event; + while (machine().ui_input().pop_event(&event)) + { + if (event.target) + { + switch (event.event_type) + { + case ui_event::type::NONE: + case ui_event::type::WINDOW_FOCUS: + case ui_event::type::WINDOW_DEFOCUS: + case ui_event::type::MOUSE_WHEEL: + break; + + case ui_event::type::POINTER_UPDATE: + // exit on primary button down + if (BIT(event.pointer_pressed, 0) && (1 == event.pointer_clicks)) + return HANDLER_CANCEL; + break; + + case ui_event::type::POINTER_LEAVE: + case ui_event::type::POINTER_ABORT: + case ui_event::type::IME_CHAR: + break; + } + } + } + return 0; }; set_handler(ui_callback_type::GENERAL, handler_callback_func(&mame_ui_manager::handler_ingame, this)); @@ -799,6 +826,7 @@ void mame_ui_manager::display_startup_screens(bool first_time) // clear the input memory and wait for all keys to be released poller.reset(); while (poller.poll() != INPUT_CODE_INVALID) { } + machine().ui_input().reset(); if (m_handler_callback_type == ui_callback_type::MODAL) { diff --git a/src/lib/util/language.h b/src/lib/util/language.h index 6e13def02e8..5b523409f8a 100644 --- a/src/lib/util/language.h +++ b/src/lib/util/language.h @@ -21,7 +21,7 @@ // LOCALIZATION SUPPORT //************************************************************************** -#define _(...) lang_translate(__VA_ARGS__) +#define _(...) (::util::lang_translate(__VA_ARGS__)) #define N_(msg) (msg) #define N_p(ctx, msg) (msg) diff --git a/src/mame/casio/ct8000.cpp b/src/mame/casio/ct8000.cpp index 87d098d672c..0edd91f87f8 100644 --- a/src/mame/casio/ct8000.cpp +++ b/src/mame/casio/ct8000.cpp @@ -137,7 +137,7 @@ protected: TIMER_CALLBACK_MEMBER(bbd_tick); void bbd_setup_next_tick(); - + emu_timer *m_bbd_timer; u16 m_key_select; @@ -315,7 +315,7 @@ void ct8000_state::driver_start() void ct8000_state::driver_reset() { if (m_bbd) - bbd_setup_next_tick(); + bbd_setup_next_tick(); } //************************************************************************** diff --git a/src/mame/casio/fz1.cpp b/src/mame/casio/fz1.cpp index 95f73407612..aea73b07f12 100644 --- a/src/mame/casio/fz1.cpp +++ b/src/mame/casio/fz1.cpp @@ -2,23 +2,23 @@ // copyright-holders:Devin Acker /* - Driver for Casio FZ-1 and FZ-10M/20M samplers + Driver for Casio FZ-1 and FZ-10M/20M samplers - Custom sound + video hardware consists of: + Custom sound + video hardware consists of: - - GAA (uPD65081G-012): address generator for sample RAM - - GAB (uPD65042G-052): timing generator for PCM interrupt and sample/hold signals - - GAS (uPD65012G-074): bus arbiter & DRAM refresh signal generator - - GAX (MB653121): demultiplexes sample RAM output to two DACs - - 4x MB87186 DCF/DCA (two inputs/outputs each) - - GAL (uPD65012G-046): generates data & strobe signals for LCD controller - - HD44350 LCD controller + 2x HD44251 segment drivers + - GAA (uPD65081G-012): address generator for sample RAM + - GAB (uPD65042G-052): timing generator for PCM interrupt and sample/hold signals + - GAS (uPD65012G-074): bus arbiter & DRAM refresh signal generator + - GAX (MB653121): demultiplexes sample RAM output to two DACs + - 4x MB87186 DCF/DCA (two inputs/outputs each) + - GAL (uPD65012G-046): generates data & strobe signals for LCD controller + - HD44350 LCD controller + 2x HD44251 segment drivers - Floppy drive: Panasonic JU-386 @ 360 rpm - Disk format: 2HD, 80 tracks * 8 sectors * 1024 bytes + Floppy drive: Panasonic JU-386 @ 360 rpm + Disk format: 2HD, 80 tracks * 8 sectors * 1024 bytes - A good deal of hardware and programming info is available courtesy of Rainer Buchty: - http://www.buchty.net/casio/ + A good deal of hardware and programming info is available courtesy of Rainer Buchty: + http://www.buchty.net/casio/ */ #include "emu.h" @@ -28,8 +28,6 @@ #include "bus/nscsi/hd.h" #include "cpu/mcs48/mcs48.h" #include "cpu/nec/v5x.h" -#include "formats/fz1_dsk.h" -#include "formats/hxchfe_dsk.h" #include "imagedev/floppy.h" #include "machine/bankdev.h" #include "machine/mb87030.h" @@ -43,6 +41,10 @@ #include "screen.h" #include "speaker.h" +#include "formats/fz1_dsk.h" +#include "formats/hxchfe_dsk.h" + + namespace { class fz1_state : public driver_device @@ -193,10 +195,10 @@ static INPUT_PORTS_START(fz10m) PORT_START("AN5") PORT_BIT(0xff, 0xff, IPT_POSITIONAL_V) PORT_NAME("Master Volume") PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_CENTERDELTA(0) PORT_PLAYER(2) PORT_CODE_DEC(JOYCODE_Y_DOWN_SWITCH) PORT_CODE_INC(JOYCODE_Y_UP_SWITCH) - + PORT_START("AN6") PORT_BIT(0xff, 0x80, IPT_POSITIONAL_V) PORT_NAME("Value") PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_CENTERDELTA(0) PORT_CODE_DEC(JOYCODE_Y_DOWN_SWITCH) PORT_CODE_INC(JOYCODE_Y_UP_SWITCH) - + INPUT_PORTS_END static INPUT_PORTS_START(fz1) @@ -328,7 +330,7 @@ static INPUT_PORTS_START(fz1) PORT_START("kbd:VELOCITY") PORT_BIT(0x3f, 0x3f, IPT_POSITIONAL_V) PORT_NAME("Key Velocity") PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_CENTERDELTA(0) PORT_PLAYER(7) PORT_CODE_DEC(JOYCODE_X_LEFT_SWITCH) PORT_CODE_INC(JOYCODE_X_RIGHT_SWITCH) - + PORT_START("AN1") PORT_BIT(0xff, 0xff, IPT_POSITIONAL_V) PORT_NAME("Volume Pedal") PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_CENTERDELTA(0) PORT_PLAYER(6) PORT_CODE_DEC(JOYCODE_Y_DOWN_SWITCH) PORT_CODE_INC(JOYCODE_Y_UP_SWITCH) @@ -337,10 +339,10 @@ static INPUT_PORTS_START(fz1) PORT_START("AN3") PORT_BIT(0xff, 0x00, IPT_POSITIONAL_V) PORT_NAME("Modulation Wheel") PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_CENTERDELTA(0) PORT_PLAYER(4) PORT_CODE_DEC(JOYCODE_Y_DOWN_SWITCH) PORT_CODE_INC(JOYCODE_Y_UP_SWITCH) - + PORT_START("AN4") PORT_BIT(0xff, 0x7f, IPT_PADDLE) PORT_NAME("Pitch Wheel") PORT_SENSITIVITY(100) PORT_KEYDELTA(10) PORT_MINMAX(0x00, 0xff) PORT_PLAYER(3) PORT_CODE_DEC(JOYCODE_Y_DOWN_SWITCH) PORT_CODE_INC(JOYCODE_Y_UP_SWITCH) - + INPUT_PORTS_END /**************************************************************************/ diff --git a/src/osd/interface/audio.cpp b/src/osd/interface/audio.cpp index 2f04f949642..a9663b04fe5 100644 --- a/src/osd/interface/audio.cpp +++ b/src/osd/interface/audio.cpp @@ -1,33 +1,51 @@ // license:BSD-3-Clause // copyright-holders:Olivier Galibert -#include "emu.h" #include "audio.h" -bool osd::channel_position::is_lfe() const { return *this == LFE; } -bool osd::channel_position::is_onreq() const { return *this == ONREQ; } -bool osd::channel_position::is_unknown() const { return *this == UNKNOWN; } - -const osd::detail::position_name_mapping osd::detail::position_name_mappings[] = { - { channel_position::FC, "Front center" }, - { channel_position::FL, "Front left" }, - { channel_position::FR, "Front right" }, - { channel_position::RC, "Rear center" }, - { channel_position::RL, "Rear left" }, - { channel_position::RR, "Rear right" }, - { channel_position::HC, "Headrest center" }, - { channel_position::HL, "Headrest left" }, - { channel_position::HR, "Headrest right" }, - { channel_position::BACKREST, "Backrest" }, - { channel_position::LFE, "Subwoofer" }, - { channel_position::ONREQ, "Auxiliary" }, - { channel_position::UNKNOWN, "Unknown" } +#include "util/language.h" +#include "util/strformat.h" + +#include <algorithm> +#include <iterator> + + +namespace osd { + +namespace { + +struct position_name_mapping { + channel_position m_pos; + const char *m_name; }; -std::string osd::channel_position::name() const +const position_name_mapping f_position_name_mappings[] = { + { channel_position::FC(), N_p("audio-position", "Front center") }, + { channel_position::FL(), N_p("audio-position", "Front left") }, + { channel_position::FR(), N_p("audio-position", "Front right") }, + { channel_position::RC(), N_p("audio-position", "Rear center") }, + { channel_position::RL(), N_p("audio-position", "Rear left") }, + { channel_position::RR(), N_p("audio-position", "Rear right") }, + { channel_position::HC(), N_p("audio-position", "Headrest center") }, + { channel_position::HL(), N_p("audio-position", "Headrest left") }, + { channel_position::HR(), N_p("audio-position", "Headrest right") }, + { channel_position::BACKREST(), N_p("audio-position", "Backrest") }, + { channel_position::LFE(), N_p("audio-position", "Subwoofer") }, + { channel_position::ONREQ(), N_p("audio-position", "Auxiliary") }, + { channel_position::UNKNOWN(), N_p("audio-position", "Unknown") } }; + +} // anonymous namespace + +std::string channel_position::name() const { - for(unsigned int i = 0; i != sizeof(detail::position_name_mappings) / sizeof(detail::position_name_mappings[0]); i++) - if(*this == detail::position_name_mappings[i].m_pos) - return detail::position_name_mappings[i].m_name; - return util::string_format("[%f %f %f]", m_x, m_y, m_z); + auto const found = std::find_if( + std::begin(f_position_name_mappings), + std::end(f_position_name_mappings), + [this] (const position_name_mapping &val) { return *this == val.m_pos; }); + if (std::end(f_position_name_mappings) != found) + return _("audio-position", found->m_name); + else + return util::string_format(_("audio-position", "[%1$f %2$f %3$f]"), m_x, m_y, m_z); } + +} // anonymous namespace diff --git a/src/osd/interface/audio.h b/src/osd/interface/audio.h index 8105eb1db98..0ebe16efffa 100644 --- a/src/osd/interface/audio.h +++ b/src/osd/interface/audio.h @@ -6,7 +6,6 @@ #pragma once -#include <array> #include <cmath> #include <cstdint> #include <string> @@ -20,66 +19,41 @@ struct channel_position { // Special positions // Position is unknown, placed in the middle - static const channel_position UNKNOWN; + static constexpr channel_position UNKNOWN() { return channel_position(0.0, 0.0, 0.0); } // This channel should only be mapped explicitely through a channel mapping (on request) - static const channel_position ONREQ; + static constexpr channel_position ONREQ() { return channel_position(0.0, 0.0, 10.0); } // This channel is a LFE - static const channel_position LFE; + static constexpr channel_position LFE() { return channel_position(0.0, 0.0, 11.0); } // Standard positions - static const channel_position FC; - static const channel_position FL; - static const channel_position FR; - static const channel_position RC; - static const channel_position RL; - static const channel_position RR; - static const channel_position HC; - static const channel_position HL; - static const channel_position HR; - static const channel_position BACKREST; + static constexpr channel_position FC() { return channel_position( 0.0, 0.0, 1.0); } + static constexpr channel_position FL() { return channel_position(-0.2, 0.0, 1.0); } + static constexpr channel_position FR() { return channel_position( 0.2, 0.0, 1.0); } + static constexpr channel_position RC() { return channel_position( 0.0, 0.0,-0.5); } + static constexpr channel_position RL() { return channel_position(-0.2, 0.0,-0.5); } + static constexpr channel_position RR() { return channel_position( 0.2, 0.0,-0.5); } + static constexpr channel_position HC() { return channel_position( 0.0, 0.0,-0.1); } + static constexpr channel_position HL() { return channel_position(-0.1, 0.0,-0.1); } + static constexpr channel_position HR() { return channel_position( 0.1, 0.0,-0.1); } + static constexpr channel_position BACKREST() { return channel_position( 0.0,-0.2, 0.1); } double m_x, m_y, m_z; - bool is_lfe() const; - bool is_onreq() const; - bool is_unknown() const; + constexpr channel_position() : channel_position(UNKNOWN()) {} + constexpr channel_position(double x, double y, double z) : m_x(x), m_y(y), m_z(z) {} + constexpr channel_position(const channel_position &pos) : m_x(pos.m_x), m_y(pos.m_y), m_z(pos.m_z) {} - channel_position() : channel_position(UNKNOWN) {} - channel_position(double x, double y, double z) : m_x(x), m_y(y), m_z(z) {} - channel_position(const channel_position &pos) : m_x(pos.m_x), m_y(pos.m_y), m_z(pos.m_z) {} - - bool operator == (const channel_position &pos) const { - return pos.m_x == m_x && pos.m_y == m_y && pos.m_z == m_z; + constexpr bool operator==(const channel_position &pos) const { + return (pos.m_x == m_x) && (pos.m_y == m_y) && (pos.m_z == m_z); } - std::string name() const; -}; - -// initialize channel positions -inline const channel_position channel_position::UNKNOWN = { 0.0, 0.0, 0.0 }; -inline const channel_position channel_position::ONREQ = { 0.0, 0.0,10.0 }; -inline const channel_position channel_position::LFE = { 0.0, 0.0,11.0 }; - -inline const channel_position channel_position::FC = { 0.0, 0.0, 1.0 }; -inline const channel_position channel_position::FL = {-0.2, 0.0, 1.0 }; -inline const channel_position channel_position::FR = { 0.2, 0.0, 1.0 }; -inline const channel_position channel_position::RC = { 0.0, 0.0,-0.5 }; -inline const channel_position channel_position::RL = {-0.2, 0.0,-0.5 }; -inline const channel_position channel_position::RR = { 0.2, 0.0,-0.5 }; -inline const channel_position channel_position::HC = { 0.0, 0.0,-0.1 }; -inline const channel_position channel_position::HL = {-0.1, 0.0,-0.1 }; -inline const channel_position channel_position::HR = { 0.1, 0.0,-0.1 }; -inline const channel_position channel_position::BACKREST = { 0.0,-0.2, 0.1 }; - -namespace detail { -struct position_name_mapping { - struct channel_position m_pos; - const char *m_name; -}; + constexpr bool is_lfe() const { return *this == LFE(); } + constexpr bool is_onreq() const { return *this == ONREQ(); } + constexpr bool is_unknown() const { return *this == UNKNOWN(); } -extern const position_name_mapping position_name_mappings[]; + std::string name() const; }; struct audio_rate_range { diff --git a/src/osd/modules/sound/coreaudio_sound.cpp b/src/osd/modules/sound/coreaudio_sound.cpp index 939f8b9d566..03c02976245 100644 --- a/src/osd/modules/sound/coreaudio_sound.cpp +++ b/src/osd/modules/sound/coreaudio_sound.cpp @@ -102,16 +102,16 @@ static const char *sMacChannelLabels[sMacChannelCount] = // "Surround" channels are at X = -0.4 (left) and 0.4 (right). static const osd::channel_position sChannelPositions[sMacChannelCount] = { - osd::channel_position::UNKNOWN, // unused - osd::channel_position::FL, // Front Left - osd::channel_position::FR, // Front Right - osd::channel_position::FC, // Front Center - osd::channel_position::LFE, // Low Frequency Effects - osd::channel_position::RL, // Rear Left - osd::channel_position::RR, // Rear Right + osd::channel_position::UNKNOWN(), // unused + osd::channel_position::FL(), // Front Left + osd::channel_position::FR(), // Front Right + osd::channel_position::FC(), // Front Center + osd::channel_position::LFE(), // Low Frequency Effects + osd::channel_position::RL(), // Rear Left + osd::channel_position::RR(), // Rear Right osd::channel_position( -0.1, 0.0, 1.0 ), // Front Left of Center osd::channel_position( 0.1, 0.0, 1.0 ), // Front Right of Center - osd::channel_position::RC, // Rear Center + osd::channel_position::RC(), // Rear Center osd::channel_position( -0.2, 0.0, 0.5 ), // Side Left osd::channel_position( 0.2, 0.0, 0.5 ), // Side Right osd::channel_position( 0.0, 0.5, -0.1 ), // Top Center @@ -121,27 +121,27 @@ static const osd::channel_position sChannelPositions[sMacChannelCount] = osd::channel_position( -0.2, 0.5, -0.5 ), // Top Rear Left osd::channel_position( 0.2, 0.5, -0.5 ), // Top Rear Center osd::channel_position( 0.2, 0.5, -0.5 ), // Top Rear Right - osd::channel_position::UNKNOWN, osd::channel_position::UNKNOWN, - osd::channel_position::UNKNOWN, osd::channel_position::UNKNOWN, osd::channel_position::UNKNOWN, osd::channel_position::UNKNOWN, osd::channel_position::UNKNOWN, osd::channel_position::UNKNOWN, osd::channel_position::UNKNOWN, osd::channel_position::UNKNOWN, osd::channel_position::UNKNOWN, osd::channel_position::UNKNOWN, - osd::channel_position::UNKNOWN, osd::channel_position::UNKNOWN, + osd::channel_position::UNKNOWN(), osd::channel_position::UNKNOWN(), + osd::channel_position::UNKNOWN(), osd::channel_position::UNKNOWN(), osd::channel_position::UNKNOWN(), osd::channel_position::UNKNOWN(), osd::channel_position::UNKNOWN(), osd::channel_position::UNKNOWN(), osd::channel_position::UNKNOWN(), osd::channel_position::UNKNOWN(), osd::channel_position::UNKNOWN(), osd::channel_position::UNKNOWN(), + osd::channel_position::UNKNOWN(), osd::channel_position::UNKNOWN(), osd::channel_position( -0.4, 0.0, -0.5 ), // Rear Surround Left osd::channel_position( 0.4, 0.0, -0.5 ), // Rear Surround Right osd::channel_position( -0.4, 0.0, 1.0 ), // Left Wide osd::channel_position( 0.4, 0.0, 1.0 ), // Right Wide - osd::channel_position::LFE, // Low Frequency Effects 2 - osd::channel_position::HL, // Left Total - osd::channel_position::HR, // Right Total - osd::channel_position::FC, // Hearing Impaired - osd::channel_position::FC, // Narration - osd::channel_position::FC, // Mono - osd::channel_position::FC, // Dialog Centric Mix - osd::channel_position::HC, // Center Surround Direct - osd::channel_position::UNKNOWN, // Haptic - osd::channel_position::UNKNOWN, // unused - osd::channel_position::UNKNOWN, // unused - osd::channel_position::UNKNOWN, // unused + osd::channel_position::LFE(), // Low Frequency Effects 2 + osd::channel_position::HL(), // Left Total + osd::channel_position::HR(), // Right Total + osd::channel_position::FC(), // Hearing Impaired + osd::channel_position::FC(), // Narration + osd::channel_position::FC(), // Mono + osd::channel_position::FC(), // Dialog Centric Mix + osd::channel_position::HC(), // Center Surround Direct + osd::channel_position::UNKNOWN(), // Haptic + osd::channel_position::UNKNOWN(), // unused + osd::channel_position::UNKNOWN(), // unused + osd::channel_position::UNKNOWN(), // unused osd::channel_position( -0.2, 0.5, 0.0 ), // Left Top Middle - osd::channel_position::UNKNOWN, // unused + osd::channel_position::UNKNOWN(), // unused osd::channel_position( 0.2, 0.5, 0.0 ), // Right Top Middle osd::channel_position( -0.2, 0.5, -0.5 ), // Left Top Rear osd::channel_position( 0.0, 0.5, -0.5 ), // Center Top Rear @@ -153,7 +153,7 @@ static const osd::channel_position sChannelPositions[sMacChannelCount] = osd::channel_position( 0.0, -0.5, 0.0 ), // Center Bottom osd::channel_position( -0.4, 0.5, -0.1 ), // Left Top Surround osd::channel_position( 0.4, 0.5, -0.1 ), // Right Top Surround - osd::channel_position::UNKNOWN, // Low Frequency Effects 3 + osd::channel_position::UNKNOWN(), // Low Frequency Effects 3 osd::channel_position( -0.4, 0.0, -0.5 ), // Left Rear Surround osd::channel_position( 0.4, 0.0, -0.5 ), // Right Rear Surround osd::channel_position( -0.1, 0.0, 1.0 ), // Left Edge of Screen @@ -1064,7 +1064,7 @@ void sound_coreaudio::build_device_list() { std::string chLabel = "Channel " + std::to_string(desc + 1); node.m_port_names.push_back(chLabel); - node.m_port_positions.emplace_back(osd::channel_position::FC); + node.m_port_positions.emplace_back(osd::channel_position::FC()); } else { diff --git a/src/osd/modules/sound/mmdevice_helpers.cpp b/src/osd/modules/sound/mmdevice_helpers.cpp index a78ac82fd53..c72915df1ad 100644 --- a/src/osd/modules/sound/mmdevice_helpers.cpp +++ b/src/osd/modules/sound/mmdevice_helpers.cpp @@ -28,49 +28,45 @@ namespace { using mm_endpoint_ptr = Microsoft::WRL::ComPtr<IMMEndpoint>; -char const *const f_speaker_names[] = -{ - "FL", // SPEAKER_FRONT_LEFT - "FR", // SPEAKER_FRONT_RIGHT - "FC", // SPEAKER_FRONT_CENTER - "LFE", // SPEAKER_LOW_FREQUENCY - "BL", // SPEAKER_BACK_LEFT - "BR", // SPEAKER_BACK_RIGHT - "FCL", // SPEAKER_FRONT_LEFT_OF_CENTER - "FCR", // SPEAKER_FRONT_RIGHT_OF_CENTER - "BC", // SPEAKER_BACK_CENTER - "SL", // SPEAKER_SIDE_LEFT - "SR", // SPEAKER_SIDE_RIGHT - "TC", // SPEAKER_TOP_CENTER - "TFL", // SPEAKER_TOP_FRONT_LEFT - "TFC", // SPEAKER_TOP_FRONT_CENTER - "TFR", // SPEAKER_TOP_FRONT_RIGHT - "TBL", // SPEAKER_TOP_BACK_LEFT - "TBC", // SPEAKER_TOP_BACK_CENTER - "TBR" // SPEAKER_TOP_BACK_RIGHT -}; - -osd::channel_position const f_speaker_positions[] = -{ - osd::channel_position::FL, // SPEAKER_FRONT_LEFT - osd::channel_position::FR, // SPEAKER_FRONT_RIGHT - osd::channel_position::FC, // SPEAKER_FRONT_CENTER - osd::channel_position::LFE, // SPEAKER_LOW_FREQUENCY - osd::channel_position::RL, // SPEAKER_BACK_LEFT - osd::channel_position::RR, // SPEAKER_BACK_RIGHT - osd::channel_position( -0.1, 0.0, 1.0 ), // SPEAKER_FRONT_LEFT_OF_CENTER - osd::channel_position( 0.1, 0.0, 1.0 ), // SPEAKER_FRONT_RIGHT_OF_CENTER - osd::channel_position::RC, // SPEAKER_BACK_CENTER - osd::channel_position( -0.2, 0.0, 0.0 ), // SPEAKER_SIDE_LEFT - osd::channel_position( 0.2, 0.0, 0.0 ), // SPEAKER_SIDE_RIGHT - osd::channel_position( 0.0, 0.5, 0.0 ), // SPEAKER_TOP_CENTER - osd::channel_position( -0.2, 0.5, 1.0 ), // SPEAKER_TOP_FRONT_LEFT - osd::channel_position( 0.0, 0.5, 1.0 ), // SPEAKER_TOP_FRONT_CENTER - osd::channel_position( 0.2, 0.5, 1.0 ), // SPEAKER_TOP_FRONT_RIGHT - osd::channel_position( -0.2, 0.5, -0.5 ), // SPEAKER_TOP_BACK_LEFT - osd::channel_position( 0.0, 0.5, -0.5 ), // SPEAKER_TOP_BACK_CENTER - osd::channel_position( 0.2, 0.5, -0.5 ) // SPEAKER_TOP_BACK_RIGHT -}; +char const *const f_speaker_names[] ={ + "FL", // SPEAKER_FRONT_LEFT + "FR", // SPEAKER_FRONT_RIGHT + "FC", // SPEAKER_FRONT_CENTER + "LFE", // SPEAKER_LOW_FREQUENCY + "BL", // SPEAKER_BACK_LEFT + "BR", // SPEAKER_BACK_RIGHT + "FCL", // SPEAKER_FRONT_LEFT_OF_CENTER + "FCR", // SPEAKER_FRONT_RIGHT_OF_CENTER + "BC", // SPEAKER_BACK_CENTER + "SL", // SPEAKER_SIDE_LEFT + "SR", // SPEAKER_SIDE_RIGHT + "TC", // SPEAKER_TOP_CENTER + "TFL", // SPEAKER_TOP_FRONT_LEFT + "TFC", // SPEAKER_TOP_FRONT_CENTER + "TFR", // SPEAKER_TOP_FRONT_RIGHT + "TBL", // SPEAKER_TOP_BACK_LEFT + "TBC", // SPEAKER_TOP_BACK_CENTER + "TBR" }; // SPEAKER_TOP_BACK_RIGHT + +channel_position const f_speaker_positions[] = { + channel_position::FL(), // SPEAKER_FRONT_LEFT + channel_position::FR(), // SPEAKER_FRONT_RIGHT + channel_position::FC(), // SPEAKER_FRONT_CENTER + channel_position::LFE(), // SPEAKER_LOW_FREQUENCY + channel_position::RL(), // SPEAKER_BACK_LEFT + channel_position::RR(), // SPEAKER_BACK_RIGHT + channel_position( -0.1, 0.0, 1.0 ), // SPEAKER_FRONT_LEFT_OF_CENTER + channel_position( 0.1, 0.0, 1.0 ), // SPEAKER_FRONT_RIGHT_OF_CENTER + channel_position::RC(), // SPEAKER_BACK_CENTER + channel_position( -0.2, 0.0, 0.0 ), // SPEAKER_SIDE_LEFT + channel_position( 0.2, 0.0, 0.0 ), // SPEAKER_SIDE_RIGHT + channel_position( 0.0, 0.5, 0.0 ), // SPEAKER_TOP_CENTER + channel_position( -0.2, 0.5, 1.0 ), // SPEAKER_TOP_FRONT_LEFT + channel_position( 0.0, 0.5, 1.0 ), // SPEAKER_TOP_FRONT_CENTER + channel_position( 0.2, 0.5, 1.0 ), // SPEAKER_TOP_FRONT_RIGHT + channel_position( -0.2, 0.5, -0.5 ), // SPEAKER_TOP_BACK_LEFT + channel_position( 0.0, 0.5, -0.5 ), // SPEAKER_TOP_BACK_CENTER + channel_position( 0.2, 0.5, -0.5 ) }; // SPEAKER_TOP_BACK_RIGHT } // anonymous namespace @@ -239,7 +235,7 @@ HRESULT populate_audio_node_info( // set up channel info std::vector<std::string> channel_names; - std::vector<osd::channel_position> channel_positions; + std::vector<channel_position> channel_positions; try { channel_names.reserve(format->nChannels); @@ -265,7 +261,7 @@ HRESULT populate_audio_node_info( channel_names.emplace_back(util::string_format("Channel %u", i + 1)); ++i; } - channel_positions.resize(format->nChannels, osd::channel_position::UNKNOWN); + channel_positions.resize(format->nChannels, channel_position::UNKNOWN()); } catch (std::bad_alloc const &) { diff --git a/src/osd/modules/sound/none.cpp b/src/osd/modules/sound/none.cpp index ca215255140..ac648afa755 100644 --- a/src/osd/modules/sound/none.cpp +++ b/src/osd/modules/sound/none.cpp @@ -27,6 +27,20 @@ public: virtual int init(osd_interface &osd, const osd_options &options) override { return 0; } virtual void exit() override { } + + virtual uint32_t get_generation() override { return 1; } + virtual audio_info get_information() override + { + audio_info result; + result.m_generation = 1; + result.m_default_sink = 0; + result.m_default_source = 0; + return result; + } + + virtual uint32_t stream_sink_open(uint32_t node, std::string name, uint32_t rate) override { return 0; } + virtual void stream_close(uint32_t id) override { } + virtual void stream_sink_update(uint32_t id, const int16_t *buffer, int samples_this_frame) override { } }; } // anonymous namespace diff --git a/src/osd/modules/sound/pa_sound.cpp b/src/osd/modules/sound/pa_sound.cpp index 8eb556ac506..4d014226229 100644 --- a/src/osd/modules/sound/pa_sound.cpp +++ b/src/osd/modules/sound/pa_sound.cpp @@ -102,16 +102,16 @@ int sound_pa::init(osd_interface &osd, osd_options const &options) static const char *const posname[10] = { "FL", "FR", "FC", "LFE", "BL", "BR", "BC", "SL", "SR", "AUX" }; static const osd::channel_position pos3d[10] = { - osd::channel_position::FL, - osd::channel_position::FR, - osd::channel_position::FC, - osd::channel_position::LFE, - osd::channel_position::RL, - osd::channel_position::RR, - osd::channel_position::RC, + osd::channel_position::FL(), + osd::channel_position::FR(), + osd::channel_position::FC(), + osd::channel_position::LFE(), + osd::channel_position::RL(), + osd::channel_position::RR(), + osd::channel_position::RC(), osd::channel_position(-0.2, 0.0, 0.0), osd::channel_position( 0.2, 0.0, 0.0), - osd::channel_position::ONREQ + osd::channel_position::ONREQ() }; static const uint32_t positions[9][9] = { diff --git a/src/osd/modules/sound/pipewire_sound.cpp b/src/osd/modules/sound/pipewire_sound.cpp index f818ef4c1db..809638dc245 100644 --- a/src/osd/modules/sound/pipewire_sound.cpp +++ b/src/osd/modules/sound/pipewire_sound.cpp @@ -165,16 +165,16 @@ private: // Try to more or less map to speaker.h positions const sound_pipewire::position_info sound_pipewire::position_infos[] = { - { SPA_AUDIO_CHANNEL_MONO, osd::channel_position::FC }, - { SPA_AUDIO_CHANNEL_FL, osd::channel_position::FL }, - { SPA_AUDIO_CHANNEL_FR, osd::channel_position::FR }, - { SPA_AUDIO_CHANNEL_FC, osd::channel_position::FC }, - { SPA_AUDIO_CHANNEL_LFE, osd::channel_position::LFE }, - { SPA_AUDIO_CHANNEL_RL, osd::channel_position::RL }, - { SPA_AUDIO_CHANNEL_RR, osd::channel_position::RR }, - { SPA_AUDIO_CHANNEL_RC, osd::channel_position::RC }, - { SPA_AUDIO_CHANNEL_AUX0, osd::channel_position::ONREQ }, - { SPA_AUDIO_CHANNEL_UNKNOWN, osd::channel_position::UNKNOWN } + { SPA_AUDIO_CHANNEL_MONO, osd::channel_position::FC() }, + { SPA_AUDIO_CHANNEL_FL, osd::channel_position::FL() }, + { SPA_AUDIO_CHANNEL_FR, osd::channel_position::FR() }, + { SPA_AUDIO_CHANNEL_FC, osd::channel_position::FC() }, + { SPA_AUDIO_CHANNEL_LFE, osd::channel_position::LFE() }, + { SPA_AUDIO_CHANNEL_RL, osd::channel_position::RL() }, + { SPA_AUDIO_CHANNEL_RR, osd::channel_position::RR() }, + { SPA_AUDIO_CHANNEL_RC, osd::channel_position::RC() }, + { SPA_AUDIO_CHANNEL_AUX0, osd::channel_position::ONREQ() }, + { SPA_AUDIO_CHANNEL_UNKNOWN, osd::channel_position::UNKNOWN() } }; diff --git a/src/osd/modules/sound/pulse_sound.cpp b/src/osd/modules/sound/pulse_sound.cpp index f6e7c391d85..093bd4d75f8 100644 --- a/src/osd/modules/sound/pulse_sound.cpp +++ b/src/osd/modules/sound/pulse_sound.cpp @@ -122,15 +122,15 @@ private: // Try to more or less map to speaker.h positions const sound_pulse::position_info sound_pulse::position_infos[] = { - { PA_CHANNEL_POSITION_MONO, osd::channel_position::FC }, - { PA_CHANNEL_POSITION_FRONT_LEFT, osd::channel_position::FL }, - { PA_CHANNEL_POSITION_FRONT_RIGHT, osd::channel_position::FR }, - { PA_CHANNEL_POSITION_FRONT_CENTER, osd::channel_position::FC }, - { PA_CHANNEL_POSITION_LFE, osd::channel_position::LFE }, - { PA_CHANNEL_POSITION_REAR_LEFT, osd::channel_position::RL }, - { PA_CHANNEL_POSITION_REAR_RIGHT, osd::channel_position::RR }, - { PA_CHANNEL_POSITION_REAR_CENTER, osd::channel_position::RC }, - { PA_CHANNEL_POSITION_MAX, osd::channel_position::ONREQ }, + { PA_CHANNEL_POSITION_MONO, osd::channel_position::FC() }, + { PA_CHANNEL_POSITION_FRONT_LEFT, osd::channel_position::FL() }, + { PA_CHANNEL_POSITION_FRONT_RIGHT, osd::channel_position::FR() }, + { PA_CHANNEL_POSITION_FRONT_CENTER, osd::channel_position::FC() }, + { PA_CHANNEL_POSITION_LFE, osd::channel_position::LFE() }, + { PA_CHANNEL_POSITION_REAR_LEFT, osd::channel_position::RL() }, + { PA_CHANNEL_POSITION_REAR_RIGHT, osd::channel_position::RR() }, + { PA_CHANNEL_POSITION_REAR_CENTER, osd::channel_position::RC() }, + { PA_CHANNEL_POSITION_MAX, osd::channel_position::ONREQ() }, }; diff --git a/src/osd/modules/sound/sdl_sound.cpp b/src/osd/modules/sound/sdl_sound.cpp index 542d0bf4ac1..f1dc7fd5dc3 100644 --- a/src/osd/modules/sound/sdl_sound.cpp +++ b/src/osd/modules/sound/sdl_sound.cpp @@ -149,16 +149,16 @@ osd::audio_info sound_sdl::get_information() static const char *const posname[10] = { "FL", "FR", "FC", "LFE", "BL", "BR", "BC", "SL", "SR", "AUX" }; static const osd::channel_position pos3d[10] = { - osd::channel_position::FL, - osd::channel_position::FR, - osd::channel_position::FC, - osd::channel_position::LFE, - osd::channel_position::RL, - osd::channel_position::RR, - osd::channel_position::RC, + osd::channel_position::FL(), + osd::channel_position::FR(), + osd::channel_position::FC(), + osd::channel_position::LFE(), + osd::channel_position::RL(), + osd::channel_position::RR(), + osd::channel_position::RC(), osd::channel_position(-0.2, 0.0, 0.0), osd::channel_position( 0.2, 0.0, 0.0), - osd::channel_position::ONREQ + osd::channel_position::ONREQ() }; static const uint32_t positions[8][9] = { diff --git a/src/osd/modules/sound/sound_module.cpp b/src/osd/modules/sound/sound_module.cpp index 5b0432bc4d0..ae5e03ebf82 100644 --- a/src/osd/modules/sound/sound_module.cpp +++ b/src/osd/modules/sound/sound_module.cpp @@ -11,31 +11,7 @@ sound_module::~sound_module() { -} - -osd::audio_info sound_module::get_information() -{ - osd::audio_info result; - result.m_generation = 1; - result.m_default_sink = 1; - result.m_default_source = 0; - result.m_nodes.resize(1); - result.m_nodes[0].m_name = "-"; - result.m_nodes[0].m_display_name = "fallthrough"; - result.m_nodes[0].m_id = 1; - result.m_nodes[0].m_rate.m_default_rate = 0; // Magic value meaning "use configured sample rate" - result.m_nodes[0].m_rate.m_min_rate = 0; - result.m_nodes[0].m_rate.m_max_rate = 0; - result.m_nodes[0].m_sinks = 2; - result.m_nodes[0].m_sources = 0; - result.m_nodes[0].m_port_names.emplace_back("L"); - result.m_nodes[0].m_port_names.emplace_back("R"); - result.m_nodes[0].m_port_positions.emplace_back(osd::channel_position::FL); - result.m_nodes[0].m_port_positions.emplace_back(osd::channel_position::FR); - result.m_streams.resize(1); - result.m_streams[0].m_id = 1; - result.m_streams[0].m_node = 1; - return result; + // implementing this here forces the vtable and inline virtual member functions to be instantiated } sound_module::abuffer::abuffer(uint32_t channels) noexcept : m_channels(channels), m_used_buffers(0), m_last_sample(channels, 0) diff --git a/src/osd/modules/sound/sound_module.h b/src/osd/modules/sound/sound_module.h index 3a2c2552bf9..85d5b50c720 100644 --- a/src/osd/modules/sound/sound_module.h +++ b/src/osd/modules/sound/sound_module.h @@ -23,16 +23,16 @@ class sound_module public: virtual ~sound_module(); - virtual uint32_t get_generation() { return 1; } - virtual osd::audio_info get_information(); + virtual uint32_t get_generation() = 0; + virtual osd::audio_info get_information() = 0; virtual bool external_per_channel_volume() { return false; } virtual bool split_streams_per_source() { return false; } - virtual uint32_t stream_sink_open(uint32_t node, std::string name, uint32_t rate) { return 1; } + virtual uint32_t stream_sink_open(uint32_t node, std::string name, uint32_t rate) = 0; virtual uint32_t stream_source_open(uint32_t node, std::string name, uint32_t rate) { return 0; } virtual void stream_set_volumes(uint32_t id, const std::vector<float> &db) {} - virtual void stream_close(uint32_t id) {} - virtual void stream_sink_update(uint32_t id, const int16_t *buffer, int samples_this_frame) {} + virtual void stream_close(uint32_t id) = 0; + virtual void stream_sink_update(uint32_t id, const int16_t *buffer, int samples_this_frame) = 0; virtual void stream_source_update(uint32_t id, int16_t *buffer, int samples_this_frame) {} virtual void begin_update() {} |
