diff options
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() {} |
