<commit_before>(ns infinitelives.utils.sound
  (:require [cljs.core.async :refer [put! chan <! >! alts! timeout close!]]
            ))

(def audio-context (if js/window.AudioContext (js/window.AudioContext.) (js/window.webkitAudioContext.)))

(def default-gain 0.7)

(defn load-sound
  "Initiates a download of the url as a sound. Returns a channel.
  When loaded and decoded, sends a decoded buffer object down the
  channel. This buffer can be used directly as a sound source"
  [url]
  (let [req (js/XMLHttpRequest.)
        c (chan)]
    (.open req "GET" url true)
    (set! (.-responseType req) "arraybuffer")
    (set! (.-onload req) (fn [] (.decodeAudioData audio-context (.-response req) #(put! c %))))
    (.send req)
    c))

(defn play-sound
  "pass this a buffer, and an optional gain parameter, and the
  sound will be played to the speakers"
  ([buff g & [loop-flag]]
   (let [source (.createBufferSource audio-context)
         gain (.createGain audio-context)]
     (if loop-flag
       (set! (.-loop source) true)
       (set! (.-loop source) false))
     (set! (.-buffer source) buff)
     (.connect source gain)
     (.connect gain (.-destination audio-context))
     (set! (.-gain.value gain) g)
     (.start source 0)
     [source gain]))
  ([buff]
   (play-sound buff default-gain)))
<commit_msg>sounds interface to register sounds into an atom<commit_after>(ns infinitelives.utils.sound
  (:require [cljs.core.async :refer [put! chan <! >! alts! timeout close!]]
            ))

(def audio-context (if js/window.AudioContext (js/window.AudioContext.) (js/window.webkitAudioContext.)))

(def default-gain 0.7)

;; where we store all the loaded sounds
(defonce !sounds (atom {}))

(defn load-sound
  "Initiates a download of the url as a sound. Returns a channel.
  When loaded and decoded, sends a decoded buffer object down the
  channel. This buffer can be used directly as a sound source"
  [url]
  (let [req (js/XMLHttpRequest.)
        c (chan)]
    (.open req "GET" url true)
    (set! (.-responseType req) "arraybuffer")
    (set! (.-onload req) (fn [] (.decodeAudioData audio-context (.-response req) #(put! c %))))
    (.send req)
    c))

(defn register-sound
  [url]
  (when (apply or (map #(string/end-with? url %)
                       [".ogg" ".mp3" ".wav"]))
    (go
      (swap! !sounds
             assoc (string/url-keyword url)
             (<! (load-sound url))))))

(defn get-sound [key]
  (key @!sounds))

(defn play-sound
  "pass this a buffer, and an optional gain parameter, and the
  sound will be played to the speakers"
  ([buff g & [loop-flag]]
   (let [source (.createBufferSource audio-context)
         gain (.createGain audio-context)]
     (if loop-flag
       (set! (.-loop source) true)
       (set! (.-loop source) false))
     (set! (.-buffer source)
           (if (keyword? buff) (get-sound buff) buff))
     (.connect source gain)
     (.connect gain (.-destination audio-context))
     (set! (.-gain.value gain) g)
     (.start source 0)
     [source gain]))
  ([buff]
   (play-sound buff default-gain)))

{'fraction_non_alphanumeric': 0.14718332790621946, 'fraction_numerical': 0.0022793878215564964, 'mean_word_length': 2.773955773955774, 'pattern_counts': {'":': 0, '<': 6, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 3, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6874353', 'n_tokens_mistral': 1018, 'n_tokens_neox': 978, 'n_words': 341}