Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature request] Allow to use custom .wav audio file as MIC input #174

Open
tairosonloa opened this issue Oct 9, 2022 · 9 comments
Open

Comments

@tairosonloa
Copy link

Standalone MelonDS allows using a custom .WAV file as microphone input, to be used instead of the default "white noise" when pressing the "make mic noise" button. See "Microphone input" in https://melonds.kuribo64.net/faq.php

Some games, like The Legend of Zelda Spirit Tracks, has very little sensibility to the default mic white noise, and a custom .wav file is needed instead to make the game properly work.

See: https://melonds.kuribo64.net/board/thread.php?pid=1403
Also see: https://www.reddit.com/r/RetroArch/comments/w68k9a/melonds_how_to_adjustfix_microphone_noise/

Would it be possible to add this feature to the RetroArch core too, please? :) (so I can play it on my steam deck with emudeck xD)

Thanks!

@tairosonloa
Copy link
Author

I don't mind working on this, as this should be in the codebase already (from the fork). However, I would be grateful if someone could point me to some docs or how to / where to look to integrate it with the Retro Arch core menu or options.

@up2early
Copy link

up2early commented Nov 17, 2022

Hey thanks for looking into this! I also want to play spirit tracks with emudeck 😃 Not sure how much progress you've made but I did some digging and found the docs related to retroarch core options.

retro_core_options_v2

/* const struct retro_core_options_v2 * --
* Allows an implementation to signal the environment
* which variables it might want to check for later using
* GET_VARIABLE.
* This allows the frontend to present these variables to
* a user dynamically.
* This should only be called if RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION
* returns an API version of >= 2.
* This should be called instead of RETRO_ENVIRONMENT_SET_VARIABLES.
* This should be called instead of RETRO_ENVIRONMENT_SET_CORE_OPTIONS.
* This should be called the first time as early as
* possible (ideally in retro_set_environment).
* Afterwards it may be called again for the core to communicate
* updated options to the frontend, but the number of core
* options must not change from the number in the initial call.
* If RETRO_ENVIRONMENT_GET_CORE_OPTIONS_VERSION returns an API
* version of >= 2, this callback is guaranteed to succeed
* (i.e. callback return value does not indicate success)
* If callback returns true, frontend has core option category
* support.
* If callback returns false, frontend does not have core option
* category support.
*
* 'data' points to a retro_core_options_v2 struct, containing
* of two pointers:
* - retro_core_options_v2::categories is an array of
* retro_core_option_v2_category structs terminated by a
* { NULL, NULL, NULL } element. If retro_core_options_v2::categories
* is NULL, all core options will have no category and will be shown
* at the top level of the frontend core option interface. If frontend
* does not have core option category support, categories array will
* be ignored.
* - retro_core_options_v2::definitions is an array of
* retro_core_option_v2_definition structs terminated by a
* { NULL, NULL, NULL, NULL, NULL, NULL, {{0}}, NULL }
* element.
*
* >> retro_core_option_v2_category notes:
*
* - retro_core_option_v2_category::key should contain string
* that uniquely identifies the core option category. Valid
* key characters are [a-z, A-Z, 0-9, _, -]
* Namespace collisions with other implementations' category
* keys are permitted.
* - retro_core_option_v2_category::desc should contain a human
* readable description of the category key.
* - retro_core_option_v2_category::info should contain any
* additional human readable information text that a typical
* user may need to understand the nature of the core option
* category.
*
* Example entry:
* {
* "advanced_settings",
* "Advanced",
* "Options affecting low-level emulation performance and accuracy."
* }
*
* >> retro_core_option_v2_definition notes:
*
* - retro_core_option_v2_definition::key should be namespaced to not
* collide with other implementations' keys. e.g. A core called
* 'foo' should use keys named as 'foo_option'. Valid key characters
* are [a-z, A-Z, 0-9, _, -].
* - retro_core_option_v2_definition::desc should contain a human readable
* description of the key. Will be used when the frontend does not
* have core option category support. Examples: "Aspect Ratio" or
* "Video > Aspect Ratio".
* - retro_core_option_v2_definition::desc_categorized should contain a
* human readable description of the key, which will be used when
* frontend has core option category support. Example: "Aspect Ratio",
* where associated retro_core_option_v2_category::desc is "Video".
* If empty or NULL, the string specified by
* retro_core_option_v2_definition::desc will be used instead.
* retro_core_option_v2_definition::desc_categorized will be ignored
* if retro_core_option_v2_definition::category_key is empty or NULL.
* - retro_core_option_v2_definition::info should contain any additional
* human readable information text that a typical user may need to
* understand the functionality of the option.
* - retro_core_option_v2_definition::info_categorized should contain
* any additional human readable information text that a typical user
* may need to understand the functionality of the option, and will be
* used when frontend has core option category support. This is provided
* to accommodate the case where info text references an option by
* name/desc, and the desc/desc_categorized text for that option differ.
* If empty or NULL, the string specified by
* retro_core_option_v2_definition::info will be used instead.
* retro_core_option_v2_definition::info_categorized will be ignored
* if retro_core_option_v2_definition::category_key is empty or NULL.
* - retro_core_option_v2_definition::category_key should contain a
* category identifier (e.g. "video" or "audio") that will be
* assigned to the core option if frontend has core option category
* support. A categorized option will be shown in a subsection/
* submenu of the frontend core option interface. If key is empty
* or NULL, or if key does not match one of the
* retro_core_option_v2_category::key values in the associated
* retro_core_option_v2_category array, option will have no category
* and will be shown at the top level of the frontend core option
* interface.
* - retro_core_option_v2_definition::values is an array of
* retro_core_option_value structs terminated by a { NULL, NULL }
* element.
* --> retro_core_option_v2_definition::values[index].value is an
* expected option value.
* --> retro_core_option_v2_definition::values[index].label is a
* human readable label used when displaying the value on screen.
* If NULL, the value itself is used.
* - retro_core_option_v2_definition::default_value is the default
* core option setting. It must match one of the expected option
* values in the retro_core_option_v2_definition::values array. If
* it does not, or the default value is NULL, the first entry in the
* retro_core_option_v2_definition::values array is treated as the
* default.
*
* The number of possible option values should be very limited,
* and must be less than RETRO_NUM_CORE_OPTION_VALUES_MAX.
* i.e. it should be feasible to cycle through options
* without a keyboard.
*
* Example entries:
*
* - Uncategorized:
*
* {
* "foo_option",
* "Speed hack coprocessor X",
* NULL,
* "Provides increased performance at the expense of reduced accuracy.",
* NULL,
* NULL,
* {
* { "false", NULL },
* { "true", NULL },
* { "unstable", "Turbo (Unstable)" },
* { NULL, NULL },
* },
* "false"
* }
*
* - Categorized:
*
* {
* "foo_option",
* "Advanced > Speed hack coprocessor X",
* "Speed hack coprocessor X",
* "Setting 'Advanced > Speed hack coprocessor X' to 'true' or 'Turbo' provides increased performance at the expense of reduced accuracy",
* "Setting 'Speed hack coprocessor X' to 'true' or 'Turbo' provides increased performance at the expense of reduced accuracy",
* "advanced_settings",
* {
* { "false", NULL },
* { "true", NULL },
* { "unstable", "Turbo (Unstable)" },
* { NULL, NULL },
* },
* "false"
* }
*
* Only strings are operated on. The possible values will
* generally be displayed and stored as-is by the frontend.
*/

I think that is the relevant portion and it looks like that struct gets defined here in the melonDS core!

@tairosonloa
Copy link
Author

Hey thanks for looking into this! I also want to play spirit tracks with emudeck 😃 Not sure how much progress you've made

Hi @up2early! Sadly, I did not make any progress, and abandoned it after no getting response. Currently, my situation has changed, and I have not the time nor the energy to face this challenge, so it's all yours if you want to try. Good luck!

@bslenul
Copy link

bslenul commented Nov 23, 2022

Gave it a try few weeks ago and got it to work:

ds_mic.mp4

I've made it so you have 3 choices as a core option:

Unfortunately there's a function I reused (https://github.com/libretro/melonDS/blob/master/src/frontend/qt_sdl/main.cpp#L184-L263) that requires SDL2 and apparently we want to avoid that... and I couldn't find a way around (my C/C++ are very limited) so I gave up :/

I really hope someone will be able to implement this properly at some point... :(

@up2early
Copy link

Hey @bslenul could you share the branch or compiled core?

@bslenul
Copy link

bslenul commented Nov 27, 2022

Sure! The changes: bslenul@270d0d4

And the compiled core for Windows: melonds_win.zip and Linux: melonds_linux.zip

@up2early
Copy link

up2early commented Nov 28, 2022

The blow noise option works in Spirit Tracks, thanks @bslenul!

If the blow noise works in most games, maybe loading a custom wav file is not needed and we could get the blow noise change released?

@bslenul
Copy link

bslenul commented Nov 28, 2022

Yeah, PR sent! With only Blow Noise/White Noise as a choice, hopefully someone will be able to include support for WAV files properly in the future :)

@Mugglajo
Copy link

Does anyone know if I can do this on mobile? I really enjoy driving the train in spirit tracks but I cant continue cause im at the first flute bit, and im not spending 200$+ for a copy of the game

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants