From 8cdddc87cea011aa3eb83bd595754f6872894592 Mon Sep 17 00:00:00 2001 From: Aaron Franke Date: Mon, 9 Mar 2020 03:48:22 -0400 Subject: [PATCH] Add README files to audio demos --- audio/bpm_sync/README.md | 18 ++++++++++ audio/bpm_sync/bpm_sync.gd | 18 +++++----- audio/bpm_sync/icon.png | Bin 0 -> 921 bytes audio/bpm_sync/icon.png.import | 34 ++++++++++++++++++ audio/bpm_sync/project.godot | 1 + audio/bpm_sync/screenshots/.gdignore | 0 audio/bpm_sync/screenshots/bpm.png | Bin 0 -> 10891 bytes audio/device_changer/Changer.gd | 31 ++++++++-------- audio/device_changer/README.md | 18 ++++++++++ audio/device_changer/screenshots/.gdignore | 0 .../screenshots/device_changer.png | Bin 0 -> 17950 bytes audio/generator/README.md | 16 +++++++++ audio/generator/generator_demo.gd | 4 +-- audio/mic_record/README.md | 8 +++++ audio/mic_record/project.godot | 2 +- audio/spectrum/README.md | 12 +++++++ audio/spectrum/icon.png | Bin 0 -> 398 bytes audio/spectrum/icon.png.import | 34 ++++++++++++++++++ audio/spectrum/project.godot | 1 + audio/spectrum/screenshots/.gdignore | 0 audio/spectrum/screenshots/spectrum.png | Bin 0 -> 1359 bytes 21 files changed, 171 insertions(+), 26 deletions(-) create mode 100644 audio/bpm_sync/README.md create mode 100644 audio/bpm_sync/icon.png create mode 100644 audio/bpm_sync/icon.png.import create mode 100644 audio/bpm_sync/screenshots/.gdignore create mode 100644 audio/bpm_sync/screenshots/bpm.png create mode 100644 audio/device_changer/README.md create mode 100644 audio/device_changer/screenshots/.gdignore create mode 100644 audio/device_changer/screenshots/device_changer.png create mode 100644 audio/generator/README.md create mode 100644 audio/mic_record/README.md create mode 100644 audio/spectrum/README.md create mode 100644 audio/spectrum/icon.png create mode 100644 audio/spectrum/icon.png.import create mode 100644 audio/spectrum/screenshots/.gdignore create mode 100644 audio/spectrum/screenshots/spectrum.png diff --git a/audio/bpm_sync/README.md b/audio/bpm_sync/README.md new file mode 100644 index 00000000..6138242d --- /dev/null +++ b/audio/bpm_sync/README.md @@ -0,0 +1,18 @@ +# Audio BPM Sync + +A demo of how to sync the audio playback with the time for a consistent BPM. + +Language: GDScript + +Renderer: GLES 2 + +## How does it work? + +For the sound clock, it uses methods in +[`AudioServer`](https://docs.godotengine.org/en/latest/classes/class_audioserver.html) +to sync the audio playback. +For the system clock, it uses `OS.get_ticks_usec()`. + +## Screenshots + +![Screenshot](screenshots/bpm.png) diff --git a/audio/bpm_sync/bpm_sync.gd b/audio/bpm_sync/bpm_sync.gd index 4a7da9b7..3149e2e6 100644 --- a/audio/bpm_sync/bpm_sync.gd +++ b/audio/bpm_sync/bpm_sync.gd @@ -7,10 +7,12 @@ var playing = false const COMPENSATE_FRAMES = 2 const COMPENSATE_HZ = 60.0 -const SYNC_SOURCE_SYSTEM_CLOCK = 0 -const SYNC_SOURCE_SOUND_CLOCK = 1 +enum SyncSource { + SYSTEM_CLOCK, + SOUND_CLOCK, +} -var sync_source = SYNC_SOURCE_SYSTEM_CLOCK +var sync_source = SyncSource.SYSTEM_CLOCK # Used by system clock. var time_begin @@ -25,16 +27,16 @@ func strsec(secs): func _process(_delta): - if (!playing or !$Player.playing): + if !playing or !$Player.playing: return var time = 0.0 - if (sync_source == SYNC_SOURCE_SYSTEM_CLOCK): + if sync_source == SyncSource.SYSTEM_CLOCK: # Obtain from ticks. time = (OS.get_ticks_usec() - time_begin) / 1000000.0 # Compensate. time -= time_delay - elif (sync_source == SYNC_SOURCE_SOUND_CLOCK): + elif sync_source == SyncSource.SOUND_CLOCK: time = $Player.get_playback_position() + AudioServer.get_time_since_last_mix() - AudioServer.get_output_latency() + (1 / COMPENSATE_HZ) * COMPENSATE_FRAMES var beat = int(time * BPM / 60.0) @@ -44,7 +46,7 @@ func _process(_delta): func _on_PlaySystem_pressed(): - sync_source = SYNC_SOURCE_SYSTEM_CLOCK + sync_source = SyncSource.SYSTEM_CLOCK time_begin = OS.get_ticks_usec() time_delay = AudioServer.get_time_to_next_mix() + AudioServer.get_output_latency() playing = true @@ -52,6 +54,6 @@ func _on_PlaySystem_pressed(): func _on_PlaySound_pressed(): - sync_source = SYNC_SOURCE_SOUND_CLOCK + sync_source = SyncSource.SOUND_CLOCK playing = true $Player.play() diff --git a/audio/bpm_sync/icon.png b/audio/bpm_sync/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..419c18b3aa085eb4a49cc88866b83033d5ecfa36 GIT binary patch literal 921 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSY)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmPVGbg(-PqX#U4-5>bId=pWt2y6yqzl=6|!mCk-Y7qyMM1;VU!=cRp)S}aehPZ*{>ZP6<@!l z?y3C#>)luW_x5fsI)84R{FrHTGpc{p=WC(fm(QzD6wy)W*&U^&AYBX0A?!>4cm`1bPn zna;G{@RECrURUdUEHZC2Z@#@#=&aQG7kgZ^i0XHYp8~F%@bd~TIC*>HGSj`ivMi#$cW)n9^;z$)LPp@MUA%Lq znENlDd9}tYRUk!r$D8q@&uM8TZuOEoU zv(IKZH{-hdp?9XTfCsR;ph$ z(tW>Vmbj(+-H*%eF*J84#(Z^~DE6brtyuRY+`@!0?b4Vp00i_>zopr0CF~Svj6}9 literal 0 HcmV?d00001 diff --git a/audio/bpm_sync/icon.png.import b/audio/bpm_sync/icon.png.import new file mode 100644 index 00000000..96cbf462 --- /dev/null +++ b/audio/bpm_sync/icon.png.import @@ -0,0 +1,34 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.png" +dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/audio/bpm_sync/project.godot b/audio/bpm_sync/project.godot index c5fa72ea..cb718fa5 100644 --- a/audio/bpm_sync/project.godot +++ b/audio/bpm_sync/project.godot @@ -17,6 +17,7 @@ _global_script_class_icons={ config/name="BPM Sync Demo" run/main_scene="res://bpm_sync.tscn" +config/icon="res://icon.png" [rendering] diff --git a/audio/bpm_sync/screenshots/.gdignore b/audio/bpm_sync/screenshots/.gdignore new file mode 100644 index 00000000..e69de29b diff --git a/audio/bpm_sync/screenshots/bpm.png b/audio/bpm_sync/screenshots/bpm.png new file mode 100644 index 0000000000000000000000000000000000000000..ff20c3af2f710ff52f17205f751969cc37fd7ba1 GIT binary patch literal 10891 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 literal 0 HcmV?d00001 diff --git a/audio/device_changer/Changer.gd b/audio/device_changer/Changer.gd index df44db61..73585572 100644 --- a/audio/device_changer/Changer.gd +++ b/audio/device_changer/Changer.gd @@ -1,36 +1,37 @@ extends Control -onready var itemList = get_node("ItemList") +onready var item_list = get_node("ItemList") func _ready(): for item in AudioServer.get_device_list(): - itemList.add_item(item) + item_list.add_item(item) var device = AudioServer.get_device() - for i in range(itemList.get_item_count()): - if device == itemList.get_item_text(i): - itemList.select(i) + for i in range(item_list.get_item_count()): + if device == item_list.get_item_text(i): + item_list.select(i) break func _process(_delta): - var speakerMode = "Stereo" + var speaker_mode_text = "Stereo" + var speaker_mode = AudioServer.get_speaker_mode() - if AudioServer.get_speaker_mode() == AudioServer.SPEAKER_SURROUND_31: - speakerMode = "Surround 3.1" - elif AudioServer.get_speaker_mode() == AudioServer.SPEAKER_SURROUND_51: - speakerMode = "Surround 5.1" - elif AudioServer.get_speaker_mode() == AudioServer.SPEAKER_SURROUND_71: - speakerMode = "Surround 7.1" + if speaker_mode == AudioServer.SPEAKER_SURROUND_31: + speaker_mode_text = "Surround 3.1" + elif speaker_mode == AudioServer.SPEAKER_SURROUND_51: + speaker_mode_text = "Surround 5.1" + elif speaker_mode == AudioServer.SPEAKER_SURROUND_71: + speaker_mode_text = "Surround 7.1" $DeviceInfo.text = "Current Device: " + AudioServer.get_device() + "\n" - $DeviceInfo.text += "Speaker Mode: " + speakerMode + $DeviceInfo.text += "Speaker Mode: " + speaker_mode_text func _on_Button_button_down(): - for item in itemList.get_selected_items(): - var device = itemList.get_item_text(item) + for item in item_list.get_selected_items(): + var device = item_list.get_item_text(item) AudioServer.set_device(device) diff --git a/audio/device_changer/README.md b/audio/device_changer/README.md new file mode 100644 index 00000000..09d7a391 --- /dev/null +++ b/audio/device_changer/README.md @@ -0,0 +1,18 @@ +# Audio Device Changer + +This is a demo showing how the audio output device can be changed from Godot. + +Language: GDScript + +Renderer: GLES 2 + +## How does it work? + +It uses the `set_device()` method in +[`AudioServer`](https://docs.godotengine.org/en/latest/classes/class_audioserver.html) +to change the audio device. +The list of devices is populated using `get_device_list()`. + +## Screenshots + +![Screenshot](screenshots/device_changer.png) diff --git a/audio/device_changer/screenshots/.gdignore b/audio/device_changer/screenshots/.gdignore new file mode 100644 index 00000000..e69de29b diff --git a/audio/device_changer/screenshots/device_changer.png b/audio/device_changer/screenshots/device_changer.png new file mode 100644 index 0000000000000000000000000000000000000000..43b41017a560dbb90d94365034a50c0d08e374f8 GIT binary patch literal 17950 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 0): + while to_fill > 0: playback.push_frame(Vector2.ONE * sin(phase * TAU)) # Audio frames are stereo. phase = fmod(phase + increment, 1.0) - to_fill -= 1; + to_fill -= 1 func _process(_delta): diff --git a/audio/mic_record/README.md b/audio/mic_record/README.md new file mode 100644 index 00000000..5386968c --- /dev/null +++ b/audio/mic_record/README.md @@ -0,0 +1,8 @@ +# Audio Mic Record + +This is an example showing how one can record audio from +the microphone and later play it back or save it to a file. + +Language: GDScript + +Renderer: GLES 2 diff --git a/audio/mic_record/project.godot b/audio/mic_record/project.godot index b75f7bd9..2b43c4c9 100644 --- a/audio/mic_record/project.godot +++ b/audio/mic_record/project.godot @@ -15,7 +15,7 @@ _global_script_class_icons={ [application] -config/name="Mic Record Demo" +config/name="Audio Mic Record Demo" run/main_scene="res://MicRecord.tscn" config/icon="res://icon.png" diff --git a/audio/spectrum/README.md b/audio/spectrum/README.md new file mode 100644 index 00000000..d61895e1 --- /dev/null +++ b/audio/spectrum/README.md @@ -0,0 +1,12 @@ +# Audio Spectrum + +This is a demo showing how a spectrum analyzer +can be built using Godot. + +Language: GDScript + +Renderer: GLES 2 + +## Screenshots + +![Screenshot](screenshots/spectrum.png) diff --git a/audio/spectrum/icon.png b/audio/spectrum/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..d9ae092bbc025e4ef3f34e227b8709ae3d21d5fe GIT binary patch literal 398 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSY)RhkE)4%caKYZ?lYt_f1s;*b z3=G`DAk4@xYmNj^kiEpy*OmPVGbg*T=^eYm9}EnP(w;7kAr-gY-f84)FyLWud|dPL z-{T{aE*;nI^ajjZl3-}GneUjDY$JmJ1Cs*-2Lq!514{#$oc!)pyS}b}uytCnF(c5p zga@(W8)M0QL70(Y)*K0-AbW|YuPgf#W=?iJfsC+|iy0VL?s&R5hE&{od$*DIkb;0i zV73JRvb~J2S$w6KpEP_I%Q)gv|1N58*4ppv3=Mhv`WP4-5*QgcbQl;KSs5A*Ffj-K z-NM8T<|=FenkNS4lB5Wzhpv7V6N;q@1zKIbtpXwE=5wP4Do)7*vg z#Th2Fa*}8r)OQoY3R&K}9{G^H<(iBMgU&e?ZsLL>!Qj8^jGq72EDc|0Lfq4EXAK8` z3NI%^GLnGgA*oA|jC0OFjeU~l%As@EN>m`?0r%ZVMh=}1t?$+_yf|nJ32s>U0z<_? zYMv6yj5F^m5B^&h^?L8&c20)kPKyeleufJ(MHLz9H@<2~S3_u%Nj(+Z!oZ+zcn}_W zAk(0s35p1q;ixf8lp;{7AZQYjB2d!7ZXFIqNXYbGe16JSotWmDhpWj OF?hQAxvX