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

Add compatibility for JSFXR and/or CFXR #2

Open
philippedcote opened this issue Jul 29, 2022 · 13 comments
Open

Add compatibility for JSFXR and/or CFXR #2

philippedcote opened this issue Jul 29, 2022 · 13 comments
Labels
enhancement New feature or request

Comments

@philippedcote
Copy link

Compatibility with SFXR is great! However, it is not compatible with macOS. It would be nice if we could use the output generated by JSFXR and/or CFXR. Thanks!

@timothyqiu timothyqiu added the enhancement New feature or request label Jul 30, 2022
@philippedcote
Copy link
Author

Would it be possible to edit and/or view numerical values next to the sliders? It would really help with fine-tuning inside the editor. Thanks!

@timothyqiu
Copy link
Owner

@philippedcote Thanks for your support :)

I made the sliders to display current value when hovered. And you can now hold CTRL to snap the value to 0.01 increments while dragging. See the current master branch (2a73615).

Using a slider similar to the one Inspector uses might be the way to go if we need more precise value editing.

@philippedcote
Copy link
Author

@timothyqiu Sure, you’re welcome! :)

Wow, thanks for this. However, if I want to type in the value directly inside a field, would that be possible?

@timothyqiu
Copy link
Owner

if I want to type in the value directly inside a field, would that be possible?

That could be done. But I'm not sure how to arrange the UI. I'll work on this over the weekend.

@timothyqiu
Copy link
Owner

@philippedcote I've implemented a custom slider which allows to type in the value directly after clicked, like in Blender 🎉

@philippedcote
Copy link
Author

@philippedcote I've implemented a custom slider which allows to type in the value directly after clicked, like in Blender 🎉

Got the chance to try it today. That’s very nice, great work!

I noticed something missing, though. Would it be possible to edit the kHz (44, 22, 11, 8kHz) and Bit (16, 8-Bit) values as well? Because it changes the texture of the sound, some sounds can only be produced by playing with those values.

Thanks! :)

@chr15m
Copy link

chr15m commented Dec 2, 2022

@timothyqiu would you be interested on working together on getting https://sfxr.me exported base58 or JSON to be loadable into Gdfxr?

Here's an example of the base58 encoded sound:

34T6PkmKkNTf3aUynCpV3oetaq6ecj9Grh9W7tiTbccVYK8FxNKBbfBFXJCLzk8QTy4d7fbiCfY2gXDaiengXbENjdLWt5jZBtcz8QmSCXjHCSuooDCWp4SrT

Here's the JSON representation:

{
  "oldParams": true,
  "wave_type": 1,
  "p_env_attack": 0,
  "p_env_sustain": 0.316476047039032,
  "p_env_punch": 0,
  "p_env_decay": 0.37630516290664673,
  "p_base_freq": 0.2605574131011963,
  "p_freq_limit": 0,
  "p_freq_ramp": 0.4602612853050232,
  "p_freq_dramp": 0,
  "p_vib_strength": 0,
  "p_vib_speed": 0,
  "p_arp_mod": 0,
  "p_arp_speed": 0,
  "p_duty": 1,
  "p_duty_ramp": 0,
  "p_repeat_speed": 0.663515031337738,
  "p_pha_offset": 0,
  "p_pha_ramp": 0,
  "p_lpf_freq": 1,
  "p_lpf_ramp": 0,
  "p_lpf_resonance": 0,
  "p_hpf_freq": 0,
  "p_hpf_ramp": 0,
  "sound_vol": 0.25,
  "sample_rate": 44100,
  "sample_size": 8
}

You can hear the corresponding sound here:

https://sfxr.me/#34T6PkmKkNTf3aUynCpV3oetaq6ecj9Grh9W7tiTbccVYK8FxNKBbfBFXJCLzk8QTy4d7fbiCfY2gXDaiengXbENjdLWt5jZBtcz8QmSCXjHCSuooDCWp4SrT

@timothyqiu
Copy link
Owner

@chr15m The B58 string contains the same fields as the original sfxr (according to this). After base58 decoding, all you have to do is fill in the corresponding fields in SFXRConfig and call _restore_from_config() in editor to sync the parameters UI.

var wave_type: int = WaveType.SQUARE_WAVE
var p_env_attack := 0.0 # Attack Time
var p_env_sustain := 0.3 # Sustain Time
var p_env_punch := 0.0 # Sustain Punch
var p_env_decay := 0.4 # Decay Time
var p_base_freq := 0.3 # Start Frequency
var p_freq_limit := 0.0 # Min Frequency
var p_freq_ramp := 0.0 # Slide
var p_freq_dramp := 0.0 # Delta Slide
var p_vib_strength := 0.0 # Vibrato Depth
var p_vib_speed := 0.0 # Vibrato Speed
var p_duty := 0.0 # Square Duty
var p_duty_ramp := 0.0 # Duty Sweep
var p_arp_mod := 0.0 # Change Amount
var p_arp_speed := 0.0 # Change Speed
var p_repeat_speed := 0.0 # Repeat Speed
var p_pha_offset := 0.0 # Phaser Offset
var p_pha_ramp := 0.0 # Phaser Weep
var p_lpf_freq := 1.0 # Lp Filter Cutoff
var p_lpf_ramp := 0.0 # Lp Filter Cutoff Sweep
var p_lpf_resonance := 0.0 # Lp Filter Resonance
var p_hpf_freq := 0.0 # Hp Filter Cutoff
var p_hpf_ramp := 0.0 # Hp Filter Cutoff Sweep
var sound_vol := 0.5

func _restore_from_config(config: SFXRConfig) -> void:

The JSON representation is basically the same. But it contains extra fields about sample rate and sample size. These two are currently hardcoded 44100 and 8 in gdfxr.

I'll try adding support for changing sample rate and sample size when I have spare time. But feel free to open an Pull Request if you're interested :)

@chr15m
Copy link

chr15m commented Dec 2, 2022

Super cool, thanks for sharing. I will document this and see if I can make the process any smoother. Maybe with the help of @philippedcote I can even generate GDSCript code that a developer can copy-paste into their project, or download a .gd file containing all of the sounds already initialized. 🤔

@timothyqiu
Copy link
Owner

I think copy-pasting the base58 code into gdfxr is a good idea. I can try adding one as it's relatively simple.

Generating long sounds on the fly using GDScript might take some time, e.g. explosions. This is a performance limitation of GDScript. But the user can cache it at the beginning of the game I guess.

@chr15m
Copy link

chr15m commented Dec 2, 2022

If it's possible to provide me with a .gd example script showing how to render a sound using Gdfxr so it's ready to play and the user can just call e.g. mymodule.mysound.play() then I can have my tool export a snippet so they don't have to do any work transforming it.

Only if you have time though, I can work it out myself it will just take me a bit longer. 😅

@timothyqiu
Copy link
Owner

I've implemented "Paste from jsfxr" so users can now paste the base58 code from jsfxr directly into the editor 🎉

ksnip_20221204-140616

I also modified the example scene to show how to generate the sound effect on the fly from the base58 code.

gdfxr/example/Example.gd

Lines 20 to 38 in 5b910af

func _on_Generate_pressed() -> void:
var config := SFXRConfig.new()
# Fill the fields manually
# config.p_base_freq = 0.5
# Load from .sfxr file
# config.load("res://example/example.sfxr")
# Load from jsfxr base58 string
config.load_from_base58("34T6PkmKkNTf3aUynCpV3oetaq6ecj9Grh9W7tiTbccVYK8FxNKBbfBFXJCLzk8QTy4d7fbiCfY2gXDaiengXbENjdLWt5jZBtcz8QmSCXjHCSuooDCWp4SrT")
# generate_audio_stream() might freeze a bit when generating long sounds.
# It's recommended to pre-generate the sound effects in editor.
# If you do want to generate the sound effects on the fly, you might want
# to generate and cache the sound effects at the start of your game.
var generator := SFXRGenerator.new()
adhoc_audio_player.stream = generator.generate_audio_stream(config)
adhoc_audio_player.play()

@chr15m
Copy link

chr15m commented Dec 4, 2022

🤯 Whoa this is awesome, thank you! I'll add a link to Gdfxr.

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

No branches or pull requests

3 participants