diff --git a/assets/source/music/.gitignore b/assets/source/music/.gitignore new file mode 100644 index 0000000..946a708 --- /dev/null +++ b/assets/source/music/.gitignore @@ -0,0 +1,5 @@ +target/ +resources/ +!resources/public/index.html +.* +!.gitignore diff --git a/assets/source/music/README.md b/assets/source/music/README.md new file mode 100644 index 0000000..fe60e3d --- /dev/null +++ b/assets/source/music/README.md @@ -0,0 +1,30 @@ +# Bugged racing music source + +Music for this game is builts using [edna](https://github.com/oakes/edna) clojure library, which uses [alda](https://github.com/alda-lang/alda) underneath. + +To build this project, you'll need the Clojure CLI tool: + +https://clojure.org/guides/deps_and_cli + +To develop in a browser with live code reloading: + +`clj -M dev.clj` + + +To build a release version for the web: + +`clj -M prod.clj` + + +To play the song once: + +`clj -M dev.clj play [song]` + + +To build wav: + +`clj -M prod.clj wav [song]` + +To build wav for all songs: + +`clj -M prod.clj soundtrack` diff --git a/assets/source/music/deps.edn b/assets/source/music/deps.edn new file mode 100644 index 0000000..fdd8a7d --- /dev/null +++ b/assets/source/music/deps.edn @@ -0,0 +1,4 @@ +{:paths ["src" "resources"] + :deps {org.clojure/clojurescript {:mvn/version "1.10.764"} + com.bhauman/figwheel-main {:mvn/version "0.2.9"} + edna/edna {:mvn/version "1.6.0"}}} diff --git a/assets/source/music/dev.clj b/assets/source/music/dev.clj new file mode 100644 index 0000000..bfe1daa --- /dev/null +++ b/assets/source/music/dev.clj @@ -0,0 +1,20 @@ +(defmulti task first) + +(defmethod task :default + [[task-name]] + (println "Unknown task:" task-name) + (System/exit 1)) + +(require '[figwheel.main :as figwheel]) + +(defmethod task nil + [_] + (figwheel/-main "--build" "dev")) + +(require '[music.core]) + +(defmethod task "play" + [_] + (music.core/-main)) + +(task *command-line-args*) diff --git a/assets/source/music/dev.cljs.edn b/assets/source/music/dev.cljs.edn new file mode 100644 index 0000000..a0fcbf9 --- /dev/null +++ b/assets/source/music/dev.cljs.edn @@ -0,0 +1,5 @@ +{:main music.core + :optimizations :none + :output-to "resources/public/main.js" + :output-dir "resources/public/main.out" + :asset-path "/main.out"} diff --git a/assets/source/music/figwheel-main.edn b/assets/source/music/figwheel-main.edn new file mode 100644 index 0000000..61eeb55 --- /dev/null +++ b/assets/source/music/figwheel-main.edn @@ -0,0 +1,2 @@ +{:open-url "http://localhost:9500" + :clean-outputs true} diff --git a/assets/source/music/prod.clj b/assets/source/music/prod.clj new file mode 100644 index 0000000..b79a56b --- /dev/null +++ b/assets/source/music/prod.clj @@ -0,0 +1,55 @@ +(defmulti task first) + +(defmethod task :default + [[task-name]] + (println "Unknown task:" task-name) + (System/exit 1)) + +(require + '[edna.core :as edna] + '[music.core :as c] + '[cljs.build.api :as api] + '[clojure.java.io :as io]) + +(defn delete-children-recursively! [f] + (when (.isDirectory f) + (doseq [f2 (.listFiles f)] + (delete-children-recursively! f2))) + (when (.exists f) (io/delete-file f))) + +(defmethod task nil + [_] + (let [out-file "resources/public/main.js" + out-dir "resources/public/main.out"] + (println "Building main.js") + (delete-children-recursively! (io/file out-dir)) + (api/build "src" {:main 'music.core + :optimizations :advanced + :output-to out-file + :output-dir out-dir + :infer-externs true}) + (delete-children-recursively! (io/file out-dir)) + (println "Build complete:" out-file) + (System/exit 0))) + +(defn export-song-wav [song] + (let [wav-name (str song ".wav") + build-dir "target" + output-file (io/file build-dir wav-name)] + (.mkdir (io/file build-dir)) + (println "Building" wav-name) + (edna/export! (c/read-music song) {:type :wav, :out output-file}) + (println "Build complete:" wav-name) + (println "Song saved into:" (.getPath output-file)))) + +(defmethod task "wav" + [[_ song]] + (export-song-wav song) + (System/exit 0)) + +(defmethod task "soundtrack" + [_] + (run! #(task ["wav" %]) (c/get-all-songs)) + (System/exit 0)) + +(task *command-line-args*) diff --git a/assets/source/music/src/music/core.clj b/assets/source/music/src/music/core.clj new file mode 100644 index 0000000..281493e --- /dev/null +++ b/assets/source/music/src/music/core.clj @@ -0,0 +1,21 @@ +(ns music.core + (:require [edna.core :as edna] + [clojure.java.io :as io] + [clojure.string :as string])) + +(def songs-dir "src/music/songs/") + +(defn read-music [song] + (load-file (str songs-dir song ".clj"))) + +(defn get-all-songs [] + (map #(string/replace (.getName %) ".clj" "") (.listFiles (io/file songs-dir)))) + +(defonce state (atom nil)) + +(defn -main [song] + (swap! state edna/stop!) + (reset! state (edna/play! (read-music song)))) + +(defmacro build-for-cljs [] + (edna/edna->data-uri (read-music "main-theme"))) diff --git a/assets/source/music/src/music/core.cljs b/assets/source/music/src/music/core.cljs new file mode 100644 index 0000000..1e59774 --- /dev/null +++ b/assets/source/music/src/music/core.cljs @@ -0,0 +1,10 @@ +(ns music.core + (:require-macros [music.music] + [music.core :refer [build-for-cljs]])) + +(defonce audio (js/document.createElement "audio")) +(set! (.-src audio) (build-for-cljs)) +(set! (.-controls audio) true) +(js/document.body.appendChild audio) +(.play audio) + diff --git a/assets/source/music/src/music/music.clj b/assets/source/music/src/music/music.clj new file mode 100644 index 0000000..8f9e839 --- /dev/null +++ b/assets/source/music/src/music/music.clj @@ -0,0 +1,10 @@ +(ns music.music) + +[:piano {:octave 4 + :tempo 74} + + 1/8 #{:-d :-a :e :f#} :a 1/2 #{:f# :+d} + 1/8 #{:-e :e :+c} :a 1/2 #{:c :e :f} + + 1/8 #{:-d :-a :e :f#} :a :+d :+c# :+e :+d :b :+c# + 1/2 #{:-e :c :a} 1/2 #{:c :e}] diff --git a/assets/source/music/src/music/songs/main-theme.clj b/assets/source/music/src/music/songs/main-theme.clj new file mode 100644 index 0000000..4e8706b --- /dev/null +++ b/assets/source/music/src/music/songs/main-theme.clj @@ -0,0 +1,10 @@ +(ns music.songs.main-theme) + +[:piano {:octave 4 + :tempo 60} + + 1/8 #{:-d :-a :e :f#} :a 1/2 #{:f# :+d} + 1/8 #{:-e :e :+c} :a 1/2 #{:c :e :f} + + 1/8 #{:-d :-a :e :f#} :a :+d :+c# :+e :+d :b :+c# + 1/2 #{:-e :c :a} 1/2 #{:c :e}]