Browse Source

Added playing music and removed accidental music files

Allexit 4 years ago
parent
commit
8a3823f210
10 changed files with 285 additions and 12 deletions
  1. 4
    1
      README.md
  2. BIN
      audio/battle_music.ogg
  3. BIN
      audio/clang01.ogg
  4. BIN
      audio/gripofnature.ogg
  5. 2
    1
      index.html
  6. 117
    0
      ts/jukebox.ts
  7. 4
    2
      ts/main.ts
  8. 64
    0
      ts/soundtest.ts
  9. 79
    0
      ts/std.ts
  10. 15
    8
      ts/testprogram.ts

+ 4
- 1
README.md View File

@@ -45,12 +45,15 @@ A lot of the usage you can find from the TypeScript docs included in the sources
45 45
 What about the _nittygritty legal stuff_?
46 46
 -----------------------------------------
47 47
 
48
-Every part of the JavaScript Terminal is licensed under the [MIT-license][mit] (see [COPYING](COPYING)), except for `jsx.ts`, which is licensed under the [GNU GPLv3 License][gplv3] (see [COPYING-GPL](COPYING-GPL)), and except for `main.ts` and `custom.scss` which are licensed under [CC-0][cc0].
48
+Every part of the JavaScript Terminal is licensed under the [MIT-license][mit] (see [COPYING](COPYING)) excluding a few exceptions:
49
+- `jsx.ts`, which is licensed under the [GNU GPLv3 License][gplv3] (see [COPYING-GPL](COPYING-GPL)).
50
+- `main.ts`, `custom.scss`, `testprogram.ts`, `soundtest.ts` (all of these are testfiles) and the fabulous music for testing in `soundtest.ts`, [Grip of Nature by Sindwiller][gripnature] which are all licensed under [CC-0][cc0].
49 51
 
50 52
 This basically means that for the MIT-licensed parts, you can do [basically anything][mit-tldr], but you need to include the copyright and license with them.
51 53
 For the GPLv3 licensed part (only `jsx.ts`) you can also do [Almost anything][gplv3-tldr], but you need to do few other steps too like keeping the same license with the project where it's used, state what changes have been done, discose source, and include build instructions.  
52 54
 **EITHER WAY** this isn't legal advice; I'm not a lawyer, I'm a gamedev.
53 55
 
56
+[gripnature]: [http://opengameart.org/content/grip-nature
54 57
 [sass]: http://sass-lang.com/
55 58
 [ts]: http://www.typescriptlang.org/
56 59
 [jquery]: https://jquery.com/

BIN
audio/battle_music.ogg View File


BIN
audio/clang01.ogg View File


BIN
audio/gripofnature.ogg View File


+ 2
- 1
index.html View File

@@ -7,12 +7,13 @@
7 7
       <meta charset="utf-8">
8 8
 
9 9
       <script src="lib/jquery-3.1.0.min.js"></script>
10
+      <script src="js/jukebox.js"></script>
10 11
       <script src="js/std.js"></script>
11 12
       <script src="js/jsterminal.js"></script>
12 13
       <script src="js/jash.js"></script>
13 14
       <script src="js/jsx.js"></script>
14 15
       <script src="js/jsxcommands.js"></script>
15
-      <script src="js/testprogram.js"></script>
16
+      <script src="js/soundtest.js"></script>
16 17
       <script src="js/main.js"></script>
17 18
    </head>
18 19
    <body onload="main()">

+ 117
- 0
ts/jukebox.ts View File

@@ -0,0 +1,117 @@
1
+/**
2
+* Copyright (c) 2016 Aleksi 'Allexit' Talarmo
3
+*
4
+*
5
+* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+*
7
+* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+*
9
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
10
+*/
11
+namespace Jukebox {
12
+
13
+   /**
14
+   * The Jukebox Player is a program which when run sets up a virtual stereo
15
+   * so you can hear the sounds played by stdio's sound-methods!
16
+   */
17
+   export class Player implements JSTerminal.Program, Std.AudioOutput {
18
+
19
+      soundCounter = 0;
20
+      loadedSounds: {[id: string]: JQuery} = {};
21
+      soundChannels: {[id: number]: SoundChannel} = {};
22
+
23
+      terminal: JSTerminal.Terminal;
24
+
25
+      create(terminal: JSTerminal.Terminal, stdio: Std.IO, args?: string[]) {
26
+         this.terminal = terminal;
27
+         stdio.setAudioOutput(this);
28
+      }
29
+      enable() {}
30
+      disable() {}
31
+
32
+      onClose(): boolean {
33
+         return true;
34
+      }
35
+
36
+      play(channel?: number, sound?: Std.Sound) {
37
+         let ch = channel | 0;
38
+         if (!(ch in this.soundChannels)) {
39
+            // Create a new channel
40
+            let audio = $(document.createElement("audio"));
41
+            audio.attr("autoplay", "true")
42
+            audio.appendTo($(this.terminal.selector));
43
+            this.soundChannels[ch] = {
44
+               element: audio,
45
+               sound: undefined
46
+            }
47
+         }
48
+         let currChannel = this.soundChannels[ch];
49
+         let oldSound = currChannel.sound;
50
+
51
+         if (sound !== undefined) {
52
+            if (!(sound.soundRefrence in this.loadedSounds)) {
53
+               console.error("Unable to find sound refrence " + sound.soundRefrence);
54
+               return;
55
+            }
56
+            sound.onEndCallback = sound.onEndCallback || (() => {});
57
+            sound.onStartCallback = sound.onEndCallback || (() => {});
58
+            if (oldSound) {
59
+               currChannel.element.prop("currentTime", "0");
60
+            }
61
+            currChannel.sound = sound;
62
+         }
63
+         if (oldSound != currChannel.sound) {
64
+            currChannel.element.empty();
65
+            currChannel.element.trigger("pause");
66
+            if (oldSound && oldSound.onEndCallback) {
67
+               oldSound.onEndCallback();
68
+            }
69
+            if (currChannel.sound !== undefined) {
70
+               currChannel.element.append(this.loadedSounds[currChannel.sound.soundRefrence]);
71
+            }
72
+         }
73
+         if (currChannel.sound && currChannel.element) {
74
+            currChannel.sound.onStartCallback();
75
+            currChannel.element.trigger("play");
76
+         }
77
+      }
78
+
79
+      pause(channel?: number) {
80
+         let ch = channel | 0;
81
+         if (!(ch in this.soundChannels)) {
82
+            return;
83
+         }
84
+         this.soundChannels[ch].sound.onEndCallback();
85
+         this.soundChannels[ch].element.trigger("pause");
86
+      }
87
+
88
+      stop(channel?: number) {
89
+         let ch = channel | 0;
90
+         if (!(ch in this.soundChannels)) {
91
+            return;
92
+         }
93
+         this.soundChannels[ch].sound.onEndCallback();
94
+         this.soundChannels[ch].element.prop("currentTime", "0");
95
+         this.soundChannels[ch].element.trigger("pause");
96
+      }
97
+
98
+      loadSound(path: string, onready?: (ref: string) => void): string {
99
+         let id = this.soundCounter++ + "";
100
+         let source = $(document.createElement("source"));
101
+         source.attr("src", path);
102
+         source.ready(() => { if (onready) { onready(id); } });
103
+         source.appendTo($(this.terminal.selector));
104
+         this.loadedSounds[id] = source;
105
+         return "";
106
+      }
107
+   }
108
+
109
+   interface SoundChannel {
110
+      element: JQuery;
111
+      sound: Std.Sound;
112
+   }
113
+
114
+   function soundGuard(o: any): o is Std.Sound {
115
+      return o.soundRefrence !== undefined;
116
+   }
117
+}

+ 4
- 2
ts/main.ts View File

@@ -8,11 +8,13 @@ var globJsx;
8 8
 function main() {
9 9
    globJsterm = JSTerminal.createTerminal(".js-terminal", 80, 20);
10 10
 
11
+   globJsterm.launchProgram(new Jukebox.Player());
12
+
11 13
    globJash = new Jash.SH();
12 14
    globJsterm.launchProgram(globJash);
13 15
 
14 16
    globJash.setDefaultStyle("test");
15 17
 
16
-   //globJsterm.launchProgram(new TestProgram());
17
-   globJsterm.launchProgram(globJsx = new JavaScriptX.JSX());
18
+   globJsterm.launchProgram(new SoundTest());
19
+   //globJsterm.launchProgram(globJsx = new JavaScriptX.JSX());
18 20
 }

+ 64
- 0
ts/soundtest.ts View File

@@ -0,0 +1,64 @@
1
+/**
2
+* This file is an exception. It's licensed CC-0.
3
+*/
4
+class SoundTest implements JSTerminal.Program {
5
+
6
+   stdio: Std.IO;
7
+   sound: Std.Sound;
8
+
9
+   create(terminal: JSTerminal.Terminal, stdio: Std.IO) {
10
+      this.stdio = stdio;
11
+
12
+      stdio.loadSound("audio/gripofnature.ogg", (ref) => {
13
+         this.sound = {
14
+            soundRefrence: ref,
15
+            onStartCallback: () => {
16
+               console.log("I started!");
17
+            },
18
+            onEndCallback: () => {
19
+               console.log("I ended :(");
20
+            }
21
+         };
22
+
23
+         stdio.println("Welcome to the soundtester. Simply input some of these commands to begin:");
24
+         stdio.println("play 0\nstop 0\npause 0\nplaynew 0", "red");
25
+         this.takeCommand();
26
+      });
27
+   }
28
+
29
+   enable() {
30
+
31
+   }
32
+
33
+   disable() {
34
+
35
+   }
36
+
37
+   onClose() {
38
+      return true;
39
+   }
40
+
41
+   takeCommand() {
42
+      this.stdio.readline({
43
+         callback: (res) => {
44
+            let parts = res.split(" ");
45
+            let command = parts[0];
46
+            let channel = parseInt(parts[1]);
47
+            if (!isNaN(channel)) {
48
+               if (command == "play") {
49
+                  this.stdio.playSound(channel);
50
+               } else if (command == "pause") {
51
+                  this.stdio.pauseSound(channel);
52
+               } else if (command == "stop") {
53
+                  this.stdio.stopSound(channel);
54
+               } else if (command == "playnew") {
55
+                  this.stdio.playSound(channel, this.sound);
56
+               }
57
+            }
58
+            this.takeCommand();
59
+         },
60
+         prefix: "\n> "
61
+      })
62
+   }
63
+
64
+}

+ 79
- 0
ts/std.ts View File

@@ -19,6 +19,7 @@ namespace Std {
19 19
 
20 20
       output: Output;
21 21
       input: Input;
22
+      audioOutput: AudioOutput;
22 23
 
23 24
       mousePos: {x: number, y: number} = {x: -1, y: -1};
24 25
 
@@ -139,6 +140,14 @@ namespace Std {
139 140
          this.input = input;
140 141
       }
141 142
 
143
+      /**
144
+      * Set standard audio output channel
145
+      * Used when calling playSound, stopSound, and loadSound
146
+      */
147
+      setAudioOutput(audioOutput: AudioOutput) {
148
+         this.audioOutput = audioOutput;
149
+      }
150
+
142 151
       /**
143 152
       * Calls print for the assigned IO interface.
144 153
       * Standard IO prints out a line to the cursor's last location
@@ -186,6 +195,47 @@ namespace Std {
186 195
          if (!this.input) { return; }
187 196
          this.input.readline(readline);
188 197
       }
198
+
199
+      /**
200
+      * Calls play for the assigned AudioOutput interface.
201
+      * Jukebox (Standerd IO) starts playing a sound in the given channel. If no channel is given, channel 0.
202
+      * Note: Some IO interfaces might not implement this method.
203
+      */
204
+      playSound(channel?: number, sound?: Sound) {
205
+         if (!this.audioOutput) { return; }
206
+         this.audioOutput.play(channel, sound);
207
+      }
208
+
209
+
210
+      /**
211
+      * Calls pause for the assigned AudioOutput interface.
212
+      * Jukebox (Standerd IO) pauses the sound at the specified channel. Sound can be resumed with stdio.play(channel).
213
+      * Note: Some IO interfaces might not implement this method.
214
+      */
215
+      pauseSound(channel?: number) {
216
+         if (!this.audioOutput) { return; }
217
+         this.audioOutput.pause(channel);
218
+      }
219
+
220
+      /**
221
+      * Calls stop for the assigned AudioOutput interface.
222
+      * Jukebox (Standerd IO) stops the current sound at given channel. If no channel is given, channel 0.
223
+      * Note: Some IO interfaces might not implement this method.
224
+      */
225
+      stopSound(channel?: number) {
226
+         if (!this.audioOutput) { return; }
227
+         this.audioOutput.stop(channel);
228
+      }
229
+
230
+      /**
231
+      * Calls stop for the assigned AudioOutput interface.
232
+      * Jukebox (Standerd IO) loads the given sound and returns a refrence string, which points to a loaded sound.
233
+      * Note: Some IO interfaces might not implement this method. If AudioOutput-interface not specified (or Jukebox launched), it will return an empty string.
234
+      */
235
+      loadSound(path: string, onready?: (ref: string) => void): string {
236
+         if (!this.audioOutput) { return ""; }
237
+         return this.audioOutput.loadSound(path, onready);
238
+      }
189 239
    }
190 240
 
191 241
    /**
@@ -205,6 +255,35 @@ namespace Std {
205 255
       clear(style?: string);
206 256
    }
207 257
 
258
+   /**
259
+   * Anything with the Std.AudioOutput-interface will be able to produce audio output through Std.IO.
260
+   * The AudioOutput is implemented in the default terminal, but can be overriden.
261
+   */
262
+   export interface AudioOutput {
263
+      play(channel?: number, sound?: Sound);
264
+      pause(channel?: number);
265
+      stop(channel?: number);
266
+      loadSound(path: string, onready?: (ref: string) => void): string;
267
+   }
268
+
269
+   /**
270
+   * An interface used to define properties of a sound played.
271
+   *
272
+   * soundRefrence is the string returned by AudioOutput to play the corresponding sound.
273
+   * volume defines the volume of the sound played.
274
+   * loops defines weather the sound should loop once played.
275
+   * onLoadedCallback is the callback triggered once the soundfile is loaded. This is also called in the AudioOutput-interface.
276
+   * onEndCallback is the callback triggered when the sound has stopped playing.
277
+   * onStartCallback is the callback triggered when the sound has started playing.
278
+   */
279
+   export interface Sound {
280
+      soundRefrence: string;
281
+      volume?: number;
282
+      loops?: boolean;
283
+      onEndCallback?: () => void;
284
+      onStartCallback?: () => void;
285
+   }
286
+
208 287
    /**
209 288
    * Utility interface to define what options can be defined when readme is called.
210 289
    */

+ 15
- 8
ts/testprogram.ts View File

@@ -1,16 +1,22 @@
1 1
 /**
2
-* Copyright (c) 2016 Aleksi 'Allexit' Talarmo
3
-*
4
-*
5
-* Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
-*
7
-* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
-*
9
-* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
2
+* This file is an exception. It's licensed CC-0.
10 3
 */
11 4
 class TestProgram implements JSTerminal.Program {
12 5
 
13 6
    create(terminal: JSTerminal.Terminal, stdio: Std.IO) {
7
+      let ref = stdio.loadSound("audio/battle_music.ogg", (ref) => {
8
+         let sound = {
9
+            soundRefrence: ref,
10
+            onStartCallback: () => {
11
+               console.log("I started!");
12
+            },
13
+            onEndCallback: () => {
14
+               console.log("I ended :(");
15
+            }
16
+         };
17
+
18
+         stdio.playSound(0, sound);
19
+      });
14 20
       stdio.println("Welcome to a tour! This is a tour for JSh, a platform for the upcoming JSX!");
15 21
       stdio.println("\nFirst things first:\nWho are you?");
16 22
       stdio.refresh();
@@ -22,6 +28,7 @@ class TestProgram implements JSTerminal.Program {
22 28
             stdio.print(resp, "red");
23 29
             stdio.print("', I am JSh, the JavaScript Bash.");
24 30
             stdio.println("I am but a mere tool that can print and read stuff from the terminal");
31
+            stdio.stopSound(0);
25 32
             terminal.closeProgram(this);
26 33
          },
27 34
          printAfterDone: true,