cw-generator/scenes/main.gd

132 lines
4.2 KiB
GDScript

extends Control
var sample_hz = 22050.0 # Keep the number of samples to mix low, GDScript is not super fast.
var pulse_hz = 440.0 * 2
var phase = 0.0
var morse_state := false
var playback: AudioStreamPlayback = null
var vol_on := -30
func _process(_delta):
fill_buffer()
func fill_buffer():
var increment = pulse_hz / sample_hz
var frames_available = playback.get_frames_available()
for i in range(frames_available):
playback.push_frame(Vector2.ONE * sin(phase * TAU))
phase = fmod(phase + increment, 1.0)
func _ready():
$Player.stream.mix_rate = sample_hz
$Player.volume_db = -100
$Player.play()
playback = $Player.get_stream_playback()
fill_buffer()
OS.open_midi_inputs()
print(OS.get_connected_midi_inputs())
func set_morse_state(state: bool):
MorseState.set_state(state)
morse_state = state
if state:
%ColorRect.color = Color(0, 128, 0)
$Player.volume_db = vol_on
else:
%ColorRect.color = Color(0, 0, 0)
$Player.volume_db = -100
func _on_morse_button_down() -> void:
set_morse_state(true)
func _on_morse_button_up() -> void:
set_morse_state(false)
func _input(input_event):
if input_event is InputEventMIDI:
_process_midi_event(input_event)
func _process_midi_event(midi_event):
if midi_event.channel in [0, 9]:
if midi_event.message == MIDI_MESSAGE_NOTE_ON:
set_morse_state(true)
elif midi_event.message == MIDI_MESSAGE_NOTE_OFF:
set_morse_state(false)
#print(midi_event)
#print("Channel ", midi_event.channel)
#print("Message ", midi_event.message)
#print("Pitch ", midi_event.pitch)
#print("Velocity ", midi_event.velocity)
#print("Instrument ", midi_event.instrument)
#print("Pressure ", midi_event.pressure)
#print("Controller number: ", midi_event.controller_number)
#print("Controller value: ", midi_event.controller_value)
func _make_tone(freq_hz: float, length: float, sample_rate: int, amplitude: int):
var result: Array[int] = []
var _phase := 0.0
var increment: float = freq_hz / float(sample_rate)
for i in range(round(sample_rate * length)):
result.append(int(round(sin(_phase * TAU) * amplitude)))
_phase = fmod(_phase + increment, 1.0)
return result
func _on_wav_button_pressed() -> void:
var data: Array[int] = []
var _use_test_data := false
var amp := 100
if not _use_test_data:
data.append_array(_make_tone(0, 0.2, sample_hz, amp))
var _morse_on := true
for n in range(1, MorseState.states.size()):
var _freq = pulse_hz if _morse_on else 0.0
print(_freq, " of length ", MorseState.states[n] / 1000.0)
data.append_array(_make_tone(_freq, MorseState.states[n] / 1000.0, sample_hz, amp))
_morse_on = not _morse_on
data.append_array(_make_tone(0, 0.2, sample_hz, amp))
else:
data.append_array(_make_tone(pulse_hz, 0.5, sample_hz, 100))
data.append_array(_make_tone(0, 0.5, sample_hz, 100))
data.append_array(_make_tone(pulse_hz, 0.5, sample_hz, 100))
data.append_array(_make_tone(0, 0.5, sample_hz, 100))
data.append_array(_make_tone(pulse_hz, 0.5, sample_hz, 100))
# save wav
var wav := AudioStreamWAV.new()
wav.format = AudioStreamWAV.FORMAT_8_BITS
wav.mix_rate = sample_hz
wav.stereo = false
wav.data = data
print("Writing WAV with ", data.size(), " length")
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")
print("GLobalized path: " + ProjectSettings.globalize_path("user://morse.wav"))
"Android":
print("Sharing file on android")
var tmp_file_path := OS.get_user_data_dir().path_join(proposed_fname)
wav.save_to_wav(tmp_file_path)
$Share.share_file(tmp_file_path, "audio/vnd.wave", proposed_fname, "", "")
# DirAccess.remove_absolute(tmp_file_path)
"Web":
print("Download on Web")
# 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()