Permalink
Browse files

refactor player

  • Loading branch information...
jinjor committed May 5, 2017
1 parent 521fd70 commit 5245d8a1862d758f2d66581ffc48aff205b3c74b
Showing with 15,002 additions and 589 deletions.
  1. +421 −429 assets/elm.js
  2. +14,075 −0 assets/player.js
  3. +0 −15 assets/{script.js → setup-audio.js}
  4. +18 −1 index.html
  5. +1 −1 package.json
  6. +26 −0 player.html
  7. +10 −0 src/Core.elm
  8. +23 −124 src/Main.elm
  9. +155 −19 src/MidiPlayer.elm
  10. +273 −0 src/Player.elm
View

Large diffs are not rendered by default.

Oops, something went wrong.
View

Large diffs are not rendered by default.

Oops, something went wrong.
@@ -1,9 +1,3 @@
-window.onerror = (message, url, line) => {
- document.getElementById('errors').textContent = message + '\n' +
- url + '\n' + line;
- return false;
-};
-let app = Elm.Main.fullscreen();
let AudioContext = window.AudioContext || window.webkitAudioContext;
let context = new AudioContext();
var unlock = function() {
@@ -17,15 +11,6 @@ var unlock = function() {
window.addEventListener('touchend', unlock, true);
var source = null;
-app.ports.moveToCard.subscribe(id => {
- var element = document.getElementById(id);
- if (element) {
- var rect = element.getBoundingClientRect();
- setTimeout(() => {
- window.scrollTo(0, window.pageYOffset + rect.top);
- });
- }
-});
app.ports.webAudioApiPlay.subscribe(data => {
let buffer = data[0];
let time = data[1];
View
@@ -22,5 +22,22 @@
<body>
<audio src="./assets/dummy.mp3"></audio>
<pre id="errors"></pre>
- <script src="./assets/script.js"></script>
+ <script>
+ window.onerror = (message, url, line) => {
+ document.getElementById('errors').textContent = message + '\n' +
+ url + '\n' + line;
+ return false;
+ };
+ let app = Elm.Main.fullscreen();
+ app.ports.moveToCard.subscribe(id => {
+ var element = document.getElementById(id);
+ if (element) {
+ var rect = element.getBoundingClientRect();
+ setTimeout(() => {
+ window.scrollTo(0, window.pageYOffset + rect.top);
+ });
+ }
+ });
+ </script>
+ <script src="./assets/setup-audio.js"></script>
</body>
View
@@ -6,7 +6,7 @@
"scripts": {
"dev-client": "elm-live src/Main.elm --output=assets/elm.js --open --warn",
"dev-server": "dev_appserver.py app.yaml",
- "build": "elm-make src/GenJson.elm --output=elm-gen-json.js && node gen-json && elm-make src/Main.elm --output=assets/elm.js --warn",
+ "build": "elm-make src/GenJson.elm --output=elm-gen-json.js && node gen-json && elm-make src/Main.elm --output=assets/elm.js --warn && elm-make src/Player.elm --output=assets/player.js --warn",
"test": "echo \"Error: no test specified\" && exit 1",
"deploy": "gcloud app deploy"
},
View
@@ -0,0 +1,26 @@
+<!DOCTYPE HTML>
+<html>
+
+<head>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
+ <script src="./assets/player.js"></script>
+ <link href="./assets/normalize.css" rel="stylesheet">
+ <link href="./assets/style.css" rel="stylesheet">
+ <link href="https://fonts.googleapis.com/earlyaccess/notosansjapanese.css" rel="stylesheet">
+ <link href="https://fonts.googleapis.com/css?family=Alegreya+Sans+SC|Alegreya+Sans" rel="stylesheet">
+</head>
+
+<body>
+ <audio src="./assets/dummy.mp3"></audio>
+ <pre id="errors"></pre>
+ <script>
+ window.onerror = (message, url, line) => {
+ document.getElementById('errors').textContent = message + '\n' +
+ url + '\n' + line;
+ return false;
+ };
+ let app = Elm.Player.fullscreen();
+ </script>
+ <script src="./assets/setup-audio.js"></script>
+</body>
View
@@ -0,0 +1,10 @@
+module Core exposing (..)
+
+
+andThen : (model1 -> ( model2, Cmd msg )) -> ( model1, Cmd msg ) -> ( model2, Cmd msg )
+andThen f ( model, cmd ) =
+ let
+ ( newModel, newCmd ) =
+ f model
+ in
+ newModel ! [ cmd, newCmd ]
View
@@ -13,14 +13,15 @@ import BinaryDecoder.File as File exposing (File)
import BinaryDecoder.Byte as Byte exposing (ArrayBuffer, Error)
import SmfDecoder exposing (Smf)
import Midi exposing (Midi, Note, Detailed)
-import MidiPlayer
+import MidiPlayer exposing (MidiPlayer)
import GitHub exposing (GitHub)
-import WebAudioApi exposing (AudioBuffer)
import Markdown
import Navigation exposing (Location)
import Json.Decode as Decode
import UrlParser exposing ((<?>))
import MusicContents exposing (..)
+import Core exposing (..)
+import WebAudioApi exposing (AudioBuffer)
main : Program Never Model Msg
@@ -37,12 +38,7 @@ main =
type alias Model =
{ midiContents : Dict String MidiContent
, selected : Maybe Content
- , playing : Bool
- , startTime : Time
- , currentTime : Time
- , futureNotes : List (Detailed Note)
- , selectedMidiOut : Maybe String
- , showConfig : Bool
+ , midiPlayer : MidiPlayer
, gitHub : GitHub
, fullscreen : Bool
, error : Error
@@ -63,15 +59,10 @@ type Msg
| OpenPlayer Bool Content
| TriggerLoadMidiAndMp3 Bool FileName FileName
| LoadedMidiAndMp3 Bool FileName FileName (Result String ( AudioBuffer, ArrayBuffer ))
- | Back
- | TriggerStart Midi AudioBuffer
- | Start Midi AudioBuffer Time
- | Stop
| Fullscreen Bool
| Close
- | Tick Time
- | ToggleConfig
| GitHubMsg GitHub.Msg
+ | MidiPlayerMsg MidiPlayer.Msg
port moveToCard : String -> Cmd msg
@@ -92,7 +83,7 @@ init location =
(\gitHub ->
let
model =
- Model initialMidiCountents Nothing False 0 0 [] Nothing False gitHub False NoError
+ Model initialMidiCountents Nothing MidiPlayer.init gitHub False NoError
firstContent =
UrlParser.parsePath parser location
@@ -122,15 +113,6 @@ parser =
UrlParser.top <?> UrlParser.stringParam "content"
-andThen : (model1 -> ( model2, Cmd msg )) -> ( model1, Cmd msg ) -> ( model2, Cmd msg )
-andThen f ( model, cmd ) =
- let
- ( newModel, newCmd ) =
- f model
- in
- newModel ! [ cmd, newCmd ]
-
-
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
@@ -139,9 +121,9 @@ update msg model =
OpenPlayer isInitialLoad content ->
model.selected
- |> Maybe.map (\_ -> update Stop model)
+ |> Maybe.map (\_ -> update (MidiPlayerMsg MidiPlayer.stop) model)
|> Maybe.withDefault ( model, Cmd.none )
- |> andThen (update Back)
+ |> andThen (update <| MidiPlayerMsg MidiPlayer.back)
|> andThen
(if isInitialLoad then
update (Fullscreen True)
@@ -204,7 +186,7 @@ update msg model =
(if isInitialLoad then
flip (,) Cmd.none
else
- update (TriggerStart midi mp3AudioBuffer)
+ update (MidiPlayerMsg <| MidiPlayer.triggerStart midi mp3AudioBuffer)
)
Err e ->
@@ -223,50 +205,12 @@ update msg model =
++ "': "
++ s
- Back ->
- ( { model
- | startTime = 0
- , currentTime = 0
- , playing = False
- }
- , Cmd.none
- )
-
- TriggerStart midi mp3AudioBuffer ->
- ( model
- , Time.now
- |> Task.perform (Start midi mp3AudioBuffer)
- )
-
- Start midi mp3AudioBuffer currentTime ->
- let
- startTime =
- if model.currentTime > 0 then
- currentTime - (model.currentTime - model.startTime)
- else
- currentTime
- in
- ( { model
- | startTime = startTime
- , currentTime = currentTime
- , playing = True
- , futureNotes = prepareFutureNotes (currentTime - startTime) midi
- }
- , WebAudioApi.play mp3AudioBuffer (currentTime - startTime)
- )
- |> andThen (update (Tick currentTime))
-
- Stop ->
- ( { model | playing = False }
- , WebAudioApi.stop
- )
-
Fullscreen fullscreen ->
( { model | fullscreen = fullscreen }, Cmd.none )
Close ->
model.selected
- |> Maybe.map (\_ -> update Stop model)
+ |> Maybe.map (\_ -> update (MidiPlayerMsg MidiPlayer.stop) model)
|> Maybe.withDefault ( model, Cmd.none )
|> andThen
(\model ->
@@ -275,67 +219,23 @@ update msg model =
)
)
- Tick currentTime ->
- ( { model
- | currentTime = currentTime
- }
- , Cmd.none
- )
-
- ToggleConfig ->
- ( { model | showConfig = not model.showConfig }
- , Cmd.none
- )
-
GitHubMsg msg ->
( { model | gitHub = GitHub.update msg model.gitHub }
, Cmd.none
)
-
-prepareFutureNotes : Time -> Midi -> List (Detailed Note)
-prepareFutureNotes time midi =
- midi.tracks
- |> List.indexedMap (,)
- |> List.concatMap (\( index, track ) -> List.map (Midi.addDetails index track.channel) track.notes)
- |> List.sortBy .position
- |> dropWhile (\note -> Midi.positionToTime midi.timeBase midi.tempo note.position < time)
-
-
-dropWhile : (a -> Bool) -> List a -> List a
-dropWhile f list =
- case list of
- [] ->
- []
-
- x :: xs ->
- if f x then
- dropWhile f xs
- else
- list
-
-
-splitWhile : (a -> Bool) -> List a -> List a -> ( List a, List a )
-splitWhile f taken list =
- case list of
- [] ->
- ( taken, [] )
-
- x :: xs ->
- if f x then
- splitWhile f (x :: taken) xs
- else
- ( taken, list )
+ MidiPlayerMsg msg ->
+ MidiPlayer.update msg model.midiPlayer
+ |> Tuple.mapSecond (Cmd.map MidiPlayerMsg)
+ |> andThen
+ (\midiPlayer ->
+ ( { model | midiPlayer = midiPlayer }, Cmd.none )
+ )
subscriptions : Model -> Sub Msg
subscriptions model =
- Sub.batch
- [ if model.playing then
- Time.every (1000 * Time.millisecond / 30) Tick
- else
- Sub.none
- ]
+ Sub.map MidiPlayerMsg (MidiPlayer.subscriptions model.midiPlayer)
initialMidiCountents : Dict String MidiContent
@@ -432,19 +332,18 @@ viewPlayerHelp model content =
|> Maybe.map
(\( midi, mp3 ) ->
MidiPlayer.view
- { onBack = Back
- , onStart = TriggerStart midi mp3
- , onStop = Stop
- , onFullscreen = Fullscreen True
+ { onFullscreen = Fullscreen True
, onMinimize = Fullscreen False
, onClose = Close
+ , transform = MidiPlayerMsg
}
content.id
content.title
model.fullscreen
- model.playing
- (model.currentTime - model.startTime + delay)
midi
+ mp3
+ delay
+ model.midiPlayer
)
|> Maybe.withDefault (MidiPlayer.viewLoading Close)
)
Oops, something went wrong.

0 comments on commit 5245d8a

Please sign in to comment.