132 lines
4.2 KiB
GDScript
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()
|