Make wav downloadable on web

The "Write Wav" button now lets the user download the resulting wav file
on web. Sadly, we cannot directly get a PackedByteArray from
AudioStreamWAV - the WAV header is only written as part of its
save_to_wav() method, which only accepts a string to a file and does all
the file handling itself. Therefore we now write the file to (temp)
disk, re-read it and then send it to the user. The other options I
currently see are a) to write the WAV header myself b) find a better way
to write a tempfile (at least tempfile naming seems to be a Godot >4.3
feature) or c) to contribute a get_wav_header() method AudioStreamWAV
upstream.

The "standardized" mimetype for wav seems to be audio/vnd.wave and not
audio/wav - I never knew! Many seem to point to RFC2361 regarding to
this.
This commit is contained in:
Sebastian Lohff 2025-02-08 13:26:59 +01:00
parent 56281c6b27
commit fe967b96b9
1 changed files with 17 additions and 4 deletions

View File

@ -75,8 +75,6 @@ func _make_tone(freq_hz: float, length: float, sample_rate: int, amplitude: int
func _on_wav_button_pressed() -> void:
var data: Array[int] = []
var loc_phase := 0.0
var increment = pulse_hz / sample_hz
var _use_test_data := false
var amp := 100
@ -106,8 +104,23 @@ func _on_wav_button_pressed() -> void:
wav.data = data
print("Writing WAV with ", data.size(), " length")
wav.save_to_wav("/tmp/foo.wav")
var proposed_fname := "morse-" + Time.get_datetime_string_from_system(true) + ".wav"
match OS.get_name():
["Linux", "macOS", "Windows"]:
wav.save_to_wav("/tmp/foo.wav")
"Android":
print("Whaaat")
"Web":
print("download")
# we either write our own wave header method or we use a temporary file
# FIXME: find out if we have our own temp / if our filename needs to be random
var tmp_file := "/tmp/morse.wav"
wav.save_to_wav(tmp_file)
# var wav_file := FileAccess.open(tmp_file, FileAccess.READ)
var wav_data := FileAccess.get_file_as_bytes(tmp_file)
JavaScriptBridge.download_buffer(wav_data, proposed_fname, "audio/vnd.wave")
var platform:
print("Saving not supported on platform " + platform)
func _on_reset_button_pressed() -> void:
MorseState.reset()