mirror of
https://github.com/Relintai/gdfxr.git
synced 2024-11-18 09:07:23 +01:00
Add import options for bit depth and sample rate
This commit is contained in:
parent
5b910afb64
commit
576708bb4a
@ -6,6 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
### Added
|
||||
- Bit depth and sample rate import options.
|
||||
- Paste from JSXFR.
|
||||
|
||||
## [1.2.0] - 2022-10-13
|
||||
|
@ -32,6 +32,8 @@
|
||||
|
||||
如果你希望使用原始的 sfxr 保存出的文件,请确保使用 `.sfxr` 扩展名保存。你也可以在原始的 sfxr 中加载并编辑 `.sfxr` 文件。
|
||||
|
||||
`.sfxr` 文件有循环(Loop)、位深度(Bit Depth)、采样率(Sample Rate)等导入选项。可以在 Godot 编辑器的导入面板中找到。
|
||||
|
||||
**注意:** 由于 GDScript 的性能限制,生成较长的音效时编辑器可能会有短暂的停滞。只有编辑器会受此影响。在游戏中使用 `.sfxr` 文件是不会在运行时生成任何东西的。
|
||||
|
||||
## 更新日志
|
||||
|
@ -42,6 +42,9 @@ But they can be used directly as regular `AudioStream`s.
|
||||
If you want to reuse an existing sound from the original sfxr, make sure to save it with an
|
||||
`.sfxr` extension. You can also load & edit the `.sfxr` file with the original sfxr.
|
||||
|
||||
Options for changing Looping, Bit Depth, and Sample Rate are available as import options
|
||||
of the `.sfxr` file. You can find these options in Godot editor's Import dock.
|
||||
|
||||
**Note:** Due to performance constraints with GDScript, the editor may freeze a bit when generating
|
||||
long sounds. This only happens in-editor.
|
||||
Using `.sfxr` files in-game won't generate anything at runtime.
|
||||
|
@ -5,6 +5,15 @@ const SFXRConfig := preload("SFXRConfig.gd")
|
||||
|
||||
const master_vol := 0.05
|
||||
|
||||
enum WavBits {
|
||||
WAV_BITS_8,
|
||||
WAV_BITS_16,
|
||||
}
|
||||
enum WavFreq {
|
||||
WAV_FREQ_44100,
|
||||
WAV_FREQ_22050,
|
||||
}
|
||||
|
||||
var _config: SFXRConfig
|
||||
|
||||
var rep_time: int
|
||||
@ -41,32 +50,42 @@ var fltdmp: float
|
||||
var fltphp: float
|
||||
|
||||
|
||||
func generate_audio_stream(config: SFXRConfig) -> AudioStreamSample:
|
||||
func generate_audio_stream(
|
||||
config: SFXRConfig,
|
||||
wav_bits: int = WavBits.WAV_BITS_8,
|
||||
wav_freq: int = WavFreq.WAV_FREQ_44100
|
||||
) -> AudioStreamSample:
|
||||
var stream := AudioStreamSample.new()
|
||||
stream.format = AudioStreamSample.FORMAT_8_BITS
|
||||
stream.mix_rate = 44100
|
||||
stream.format = AudioStreamSample.FORMAT_8_BITS if wav_bits == WavBits.WAV_BITS_8 else AudioStreamSample.FORMAT_16_BITS
|
||||
stream.mix_rate = 44100 if wav_freq == WavFreq.WAV_FREQ_44100 else 22050
|
||||
|
||||
_config = config
|
||||
stream.data = _generate_samples()
|
||||
stream.data = _generate_samples(wav_bits, wav_freq).data_array
|
||||
_config = null
|
||||
|
||||
return stream
|
||||
|
||||
|
||||
func generate_samples(config: SFXRConfig) -> PoolByteArray:
|
||||
func generate_samples(
|
||||
config: SFXRConfig,
|
||||
wav_bits: int = WavBits.WAV_BITS_8,
|
||||
wav_freq: int = WavFreq.WAV_FREQ_44100
|
||||
) -> PoolByteArray:
|
||||
_config = config
|
||||
var data := _generate_samples()
|
||||
var data := _generate_samples(wav_bits, wav_freq).data_array
|
||||
_config = null
|
||||
return data
|
||||
|
||||
|
||||
func _generate_samples() -> PoolByteArray:
|
||||
func _generate_samples(wav_bits: int, wav_freq: int) -> StreamPeerBuffer:
|
||||
_reset_sample(true)
|
||||
|
||||
var playing_sample := true
|
||||
var env_stage := 0
|
||||
var env_time := 0
|
||||
var output := PoolByteArray([])
|
||||
var filesample: float = 0
|
||||
var fileacc := 0
|
||||
var buffer := StreamPeerBuffer.new()
|
||||
|
||||
# SynthSample
|
||||
while playing_sample:
|
||||
@ -174,15 +193,21 @@ func _generate_samples() -> PoolByteArray:
|
||||
ssample *= 4.0 # arbitrary gain to get reasonable output volume...
|
||||
ssample = clamp(ssample, -1.0, +1.0)
|
||||
|
||||
var filesample := int((1 + ssample) / 2 * 255)
|
||||
filesample += ssample
|
||||
fileacc += 1
|
||||
|
||||
# This is a hack, AudioStreamSample wants a int8_t directly interpreted as uint8_t
|
||||
filesample += 128
|
||||
if filesample > 255:
|
||||
filesample -= 255
|
||||
if wav_freq == WavFreq.WAV_FREQ_44100 or fileacc == 2:
|
||||
filesample /= fileacc
|
||||
fileacc = 0
|
||||
|
||||
output.push_back(filesample)
|
||||
return output
|
||||
if wav_bits == WavBits.WAV_BITS_8:
|
||||
buffer.put_8(filesample * 255)
|
||||
else:
|
||||
buffer.put_16(filesample * 32000)
|
||||
|
||||
filesample = 0
|
||||
|
||||
return buffer
|
||||
|
||||
|
||||
func _reset_sample(restart: bool) -> void:
|
||||
|
@ -39,6 +39,18 @@ func get_import_options(preset):
|
||||
name="loop",
|
||||
default_value=false,
|
||||
},
|
||||
{
|
||||
name="bit_depth",
|
||||
property_hint=PROPERTY_HINT_ENUM,
|
||||
hint_string="8 Bits,16 Bits",
|
||||
default_value=SFXRGenerator.WavBits.WAV_BITS_8,
|
||||
},
|
||||
{
|
||||
name="sample_rate",
|
||||
property_hint=PROPERTY_HINT_ENUM,
|
||||
hint_string="44100 Hz,22050 Hz",
|
||||
default_value=SFXRGenerator.WavFreq.WAV_FREQ_44100,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@ -53,7 +65,9 @@ func import(source_file, save_path, options, platform_variants, gen_files):
|
||||
printerr("Failed to open %s: %d" % [source_file, err])
|
||||
return err
|
||||
|
||||
var stream := SFXRGenerator.new().generate_audio_stream(config)
|
||||
var stream := SFXRGenerator.new().generate_audio_stream(
|
||||
config, options.bit_depth, options.sample_rate
|
||||
)
|
||||
if options.loop:
|
||||
stream.loop_mode = AudioStreamSample.LOOP_FORWARD
|
||||
stream.loop_end = stream.data.size()
|
||||
|
@ -12,3 +12,5 @@ dest_files=[ "res://.import/example.sfxr-e3731bcdcd8403a2391e92667a5d1076.sample
|
||||
[params]
|
||||
|
||||
loop=false
|
||||
bit_depth=0
|
||||
sample_rate=0
|
||||
|
Loading…
Reference in New Issue
Block a user