A music player that connects to your cloud/distributed storage.
5
fork

Configure Feed

Select the types of activity you want to include in your feed.

Remove WebAudioAPI usage (remove EQ, keep volume)

+34 -133
+1 -1
src/Applications/UI/Alfred/View.elm
··· 9 9 import Html.Events exposing (onInput) 10 10 import Html.Ext exposing (onTapPreventDefault) 11 11 import Json.Decode 12 - import Material.Icons as Icons 12 + import Material.Icons.Round as Icons 13 13 import Material.Icons.Types exposing (Coloring(..)) 14 14 import Maybe.Extra as Maybe 15 15 import UI.Types as UI
+1 -1
src/Applications/UI/Authentication/View.elm
··· 10 10 import Html.Extra as Html 11 11 import Html.Lazy as Lazy 12 12 import Markdown 13 - import Material.Icons as Icons 13 + import Material.Icons.Round as Icons 14 14 import Material.Icons.Types exposing (Coloring(..)) 15 15 import Svg exposing (Svg) 16 16 import UI.Authentication.Types as Authentication exposing (..)
+1 -1
src/Applications/UI/Commands/Alfred.elm
··· 3 3 import Alfred exposing (..) 4 4 import Conditional exposing (ifThenElse) 5 5 import List.Extra as List 6 - import Material.Icons as Icons 6 + import Material.Icons.Round as Icons 7 7 import Tracks exposing (Grouping(..), SortBy(..)) 8 8 import UI.Page as Page 9 9 import UI.Queue.Types as Queue
+1 -1
src/Applications/UI/Console.elm
··· 6 6 import Html.Attributes exposing (style, title) 7 7 import Html.Events exposing (on, onClick) 8 8 import Json.Decode as Decode 9 - import Material.Icons as Icons 9 + import Material.Icons.Round as Icons 10 10 import Material.Icons.Types exposing (Coloring(..)) 11 11 import Queue 12 12 import UI.Queue.Types as Queue
+2 -19
src/Applications/UI/Equalizer/View.elm
··· 8 8 import Html.Events 9 9 import Html.Events.Extra.Pointer as Pointer 10 10 import Json.Decode as Decode 11 - import Material.Icons as Icons 11 + import Material.Icons.Round as Icons 12 12 import Svg 13 13 import Svg.Attributes 14 14 import UI.Kit ··· 42 42 [ "relative", "select-none" ] 43 43 [ chunk 44 44 [ "absolute", "left-0", "top-0" ] 45 - [ UI.Kit.canister [ UI.Kit.h1 "Equalizer" ] 45 + [ UI.Kit.canister [ UI.Kit.h1 "Volume" ] 46 46 ] 47 47 ] 48 48 ··· 71 71 , "dark:border-base00" 72 72 ] 73 73 [ knob Volume settings.volume 74 - ] 75 - 76 - -- 77 - , chunk 78 - [ "border" 79 - , "border-black-05" 80 - , "rounded" 81 - , "flex" 82 - , "mt-4" 83 - 84 - -- Dark mode 85 - ------------ 86 - , "dark:border-base00" 87 - ] 88 - [ knob Low settings.low 89 - , knob Mid settings.mid 90 - , knob High settings.high 91 74 ] 92 75 ] 93 76
+1 -1
src/Applications/UI/Kit.elm
··· 6 6 import Html exposing (Html) 7 7 import Html.Attributes as A exposing (href, style) 8 8 import Html.Events exposing (onClick, onInput) 9 - import Material.Icons as Icons 9 + import Material.Icons.Round as Icons 10 10 import Material.Icons.Types exposing (Coloring(..)) 11 11 import Svg 12 12
+1 -1
src/Applications/UI/Playlists/Alfred.elm
··· 2 2 3 3 import Alfred exposing (..) 4 4 import List.Extra as List 5 - import Material.Icons as Icons 5 + import Material.Icons.Round as Icons 6 6 import Playlists exposing (..) 7 7 import Tracks exposing (IdentifiedTrack) 8 8 import UI.Types as UI
+1 -1
src/Applications/UI/Playlists/ContextMenu.elm
··· 3 3 import ContextMenu exposing (..) 4 4 import Coordinates exposing (Coordinates) 5 5 import Html.Events.Extra.Mouse 6 - import Material.Icons as Icons 6 + import Material.Icons.Round as Icons 7 7 import Playlists exposing (Playlist) 8 8 import Playlists.Matching 9 9 import Tracks exposing (IdentifiedTrack)
+1 -1
src/Applications/UI/Playlists/View.elm
··· 7 7 import Html.Attributes exposing (href, placeholder, style, value) 8 8 import Html.Events exposing (onInput, onSubmit) 9 9 import List.Extra as List 10 - import Material.Icons as Icons 10 + import Material.Icons.Round as Icons 11 11 import Material.Icons.Types exposing (Coloring(..)) 12 12 import Playlists exposing (..) 13 13 import UI.Kit exposing (ButtonType(..))
+1 -1
src/Applications/UI/Queue/ContextMenu.elm
··· 2 2 3 3 import ContextMenu exposing (..) 4 4 import Coordinates exposing (Coordinates) 5 - import Material.Icons as Icons 5 + import Material.Icons.Round as Icons 6 6 import Queue 7 7 import UI.Queue.Types as Queue 8 8 import UI.Tracks.ContextMenu
+1 -1
src/Applications/UI/Queue/View.elm
··· 7 7 import Html.Attributes exposing (href) 8 8 import Html.Lazy as Lazy 9 9 import Icons 10 - import Material.Icons as Icons 10 + import Material.Icons.Round as Icons 11 11 import Material.Icons.Types exposing (Coloring(..)) 12 12 import Queue exposing (..) 13 13 import UI.DnD as DnD
+1 -1
src/Applications/UI/Settings.elm
··· 7 7 import Html.Events exposing (onClick) 8 8 import Html.Lazy 9 9 import LastFm 10 - import Material.Icons as Icons 10 + import Material.Icons.Round as Icons 11 11 import Material.Icons.Types exposing (Coloring(..)) 12 12 import UI.Authentication.Types as Authentication 13 13 import UI.Backdrop as Backdrop exposing (backgroundPositioning)
+1 -1
src/Applications/UI/Settings/ImportExport.elm
··· 2 2 3 3 import Chunky exposing (..) 4 4 import Html exposing (Html, text) 5 - import Material.Icons as Icons 5 + import Material.Icons.Round as Icons 6 6 import UI.Kit exposing (ButtonType(..)) 7 7 import UI.Navigation exposing (..) 8 8 import UI.Page
+1 -1
src/Applications/UI/Sources/ContextMenu.elm
··· 3 3 import Conditional exposing (ifThenElse) 4 4 import ContextMenu exposing (..) 5 5 import Coordinates exposing (Coordinates) 6 - import Material.Icons as Icons 6 + import Material.Icons.Round as Icons 7 7 import Sources exposing (Source) 8 8 import UI.Page 9 9 import UI.Sources.Page
+1 -1
src/Applications/UI/Sources/Form.elm
··· 8 8 import Html.Attributes exposing (for, name, placeholder, required, selected, type_, value) 9 9 import Html.Events exposing (onInput, onSubmit) 10 10 import List.Extra as List 11 - import Material.Icons as Icons 11 + import Material.Icons.Round as Icons 12 12 import Material.Icons.Types exposing (Coloring(..)) 13 13 import Sources exposing (..) 14 14 import Sources.Services as Services
+1 -1
src/Applications/UI/Sources/View.elm
··· 7 7 import Html.Attributes exposing (href) 8 8 import Html.Lazy as Lazy 9 9 import List.Extra as List 10 - import Material.Icons as Icons 10 + import Material.Icons.Round as Icons 11 11 import Material.Icons.Types exposing (Coloring(..)) 12 12 import Sources exposing (..) 13 13 import UI.Kit
+1 -1
src/Applications/UI/Tracks/ContextMenu.elm
··· 3 3 import Conditional exposing (ifThenElse) 4 4 import ContextMenu exposing (..) 5 5 import Coordinates exposing (Coordinates) 6 - import Material.Icons as Icons 6 + import Material.Icons.Round as Icons 7 7 import Maybe.Extra as Maybe 8 8 import Playlists exposing (Playlist) 9 9 import Queue
+1 -1
src/Applications/UI/Tracks/Scene.elm
··· 4 4 import Conditional exposing (..) 5 5 import Html exposing (Html, text) 6 6 import Html.Attributes as A 7 - import Material.Icons as Icons 7 + import Material.Icons.Round as Icons 8 8 import Material.Icons.Types exposing (Coloring(..)) 9 9 import Tracks 10 10
+1 -1
src/Applications/UI/Tracks/Scene/Covers.elm
··· 12 12 import Html.Events.Extra.Mouse as Mouse 13 13 import Html.Lazy 14 14 import InfiniteList 15 - import Material.Icons as Icons 15 + import Material.Icons.Round as Icons 16 16 import Material.Icons.Types exposing (Coloring(..)) 17 17 import Maybe.Extra as Maybe 18 18 import Queue
+1 -1
src/Applications/UI/Tracks/Scene/List.elm
··· 13 13 import Html.Lazy 14 14 import InfiniteList 15 15 import Json.Decode as Decode 16 - import Material.Icons as Icons 16 + import Material.Icons.Round as Icons 17 17 import Material.Icons.Types exposing (Coloring(..)) 18 18 import Maybe.Extra as Maybe 19 19 import Queue
+3 -3
src/Applications/UI/Tracks/View.elm
··· 9 9 import Html.Events.Extra.Mouse as Mouse 10 10 import Html.Ext exposing (onEnterKey) 11 11 import Html.Lazy exposing (..) 12 - import Material.Icons as Icons 12 + import Material.Icons.Round as Icons 13 13 import Material.Icons.Types exposing (Coloring(..)) 14 14 import Playlists exposing (Playlist) 15 15 import Tracks exposing (..) ··· 339 339 , Label "Queue" Hidden 340 340 , NavigateToPage (Page.Queue UI.Queue.Page.Index) 341 341 ) 342 - , ( Icon Icons.equalizer 343 - , Label "Equalizer" Hidden 342 + , ( Icon Icons.volume_up 343 + , Label "Volume" Hidden 344 344 , NavigateToPage Page.Equalizer 345 345 ) 346 346 ]
+9 -91
src/Javascript/audio-engine.js
··· 22 22 // Audio context 23 23 // ------------- 24 24 25 - var context 26 - 27 - if (window.AudioContext) { 28 - context = new window.AudioContext() 29 - } else if (window.webkitAudioContext) { 30 - context = new window.webkitAudioContext() 31 - } 32 - 33 - self.context = context 34 - 35 - 36 25 let SINGLE_AUDIO_NODE = IS_SAFARI 37 26 38 27 39 28 export function usesSingleAudioNode() { 40 29 return SINGLE_AUDIO_NODE 41 30 } 42 - 43 - 44 - function unlockAudioContext() { 45 - if (context.state !== "suspended") return 46 - const b = document.body 47 - const events = [ "touchstart", "touchend", "mousedown", "keydown" ] 48 - events.forEach(e => b.addEventListener(e, unlock, false)) 49 - function unlock() { context.resume().then(clean) } 50 - function clean() { events.forEach(e => b.removeEventListener(e, unlock)) } 51 - } 52 - 53 - 54 - unlockAudioContext() 55 31 56 32 57 33 ··· 106 82 107 83 108 84 109 - // Audio nodes 110 - // ----------- 111 - // Flow: 112 - // {Input} -> Volume -> Low -> Mid -> High -> {Output} 113 - 114 - let volume, 115 - low, 116 - mid, 117 - high 118 - 119 - // volume 120 - volume = context.createGain() 121 - volume.gain.value = 1 85 + // EQ 86 + // -- 122 87 123 - // biquad filters 124 - low = context.createBiquadFilter() 125 - mid = context.createBiquadFilter() 126 - high = context.createBiquadFilter() 88 + let volume = 0.5 127 89 128 - low.type = "lowshelf" 129 - mid.type = "peaking" 130 - high.type = "highshelf" 131 - 132 - low.frequency.value = 250 133 - mid.frequency.value = 2750 134 - mid.Q.value = 1 135 - high.frequency.value = 8000 136 - 137 - // connect them nodes 138 - volume.connect(low) 139 - low.connect(mid) 140 - mid.connect(high) 141 - high.connect(context.destination) 142 - 143 - 144 - function determineNodeGainValue(knobType, value) { 90 + export function adjustEqualizerSetting(orchestrion, knobType, value) { 145 91 switch (knobType) { 146 - case "VOLUME" : return value 147 - default : return value < 0 ? value * 50 : value * 15 92 + case "VOLUME": 93 + volume = value 94 + if (orchestrion.audio) orchestrion.audio.volume = value 95 + break; 148 96 } 149 97 } 150 98 151 99 152 - export function adjustEqualizerSetting(knobType, value) { 153 - let node 154 - 155 - switch (knobType) { 156 - case "LOW" : node = low; break 157 - case "MID" : node = mid; break 158 - case "HIGH" : node = high; break 159 - case "VOLUME" : node = volume; break 160 - } 161 - 162 - node.gain.setValueAtTime( 163 - determineNodeGainValue(knobType, value), 164 - context.currentTime 165 - ) 166 - } 167 - 168 - 169 100 170 101 // Playback 171 102 // -------- ··· 179 110 orchestrion.app.ports.setAudioPosition.send(0) 180 111 clearTimeout(orchestrion.unstallTimeout) 181 112 timesStalled = 1 182 - 183 - // resume audio context if it's suspended 184 - if (context.resume && context.state !== "running") { 185 - context.resume() 186 - } 187 113 188 114 // metadata 189 115 if ("mediaSession" in navigator && queueItem.trackTags) { ··· 224 150 } else if (audioNode = findExistingAudioElement(queueItem)) { 225 151 audioNode.setAttribute("data-preload", "f") 226 152 audioNode.setAttribute("data-timestamp", Date.now()) 227 - audioNode.context = context.createMediaElementSource(audioNode) 228 - audioNode.context.connect(volume) 229 153 230 154 if (audioNode.readyState >= 4) { 231 155 playAudio(audioNode, queueItem, orchestrion.app) ··· 236 160 237 161 } else { 238 162 audioNode = createAudioElement(orchestrion, queueItem, Date.now()) 239 - audioNode.context = context.createMediaElementSource(audioNode) 240 - audioNode.context.connect(volume) 241 163 242 164 } 243 165 166 + audioNode.volume = volume 244 167 orchestrion.audio = audioNode 245 168 }) 246 169 } ··· 594 517 nodes.forEach(node => { 595 518 const t = parseInt(node.getAttribute("data-timestamp"), 10) 596 519 if (t >= timestamp) return 597 - 598 - if (node.context) { 599 - node.context.disconnect() 600 - node.context = null 601 - } 602 520 603 521 // Force browser to stop loading 604 522 node.src = silentMp3File
+1 -1
src/Javascript/index.js
··· 236 236 237 237 238 238 function adjustEqualizerSetting(e) { 239 - audioEngine.adjustEqualizerSetting(e.knob, e.value) 239 + audioEngine.adjustEqualizerSetting(orchestrion, e.knob, e.value) 240 240 } 241 241 242 242