diff --git a/src/client/components/mod-player.vue b/src/client/components/mod-player.vue
index a568e3c56..ad84538e2 100644
--- a/src/client/components/mod-player.vue
+++ b/src/client/components/mod-player.vue
@@ -10,13 +10,18 @@
@@ -37,6 +42,7 @@ export default defineComponent({
data() {
return {
hide: true,
+ playing: false
};
},
created() {
@@ -46,6 +52,9 @@ export default defineComponent({
this.buffer = null;
this.player.load(this.module.url).then((result) => {
this.buffer = result;
+ this.player.play(this.buffer);
+ this.display();
+ this.player.stop();
}).catch((error) => {
console.error(error);
});
@@ -88,16 +97,27 @@ export default defineComponent({
}
}
},
- play() {
+ playPause() {
this.player.addHandler('onRowChange', () => {
this.$refs.progress.max = this.player.duration();
this.$refs.progress.value = this.player.position() % this.player.duration();
this.display(this.player);
});
- this.player.play(this.buffer);
+ if (this.player.currentPlayingNode === null) {
+ this.player.play(this.buffer);
+ this.playing = true;
+ } else {
+ this.player.togglePause();
+ this.playing = !this.player.currentPlayingNode.paused;
+ }
},
stop() {
this.player.stop();
+ this.playing = false;
+ this.player.play(this.buffer);
+ this.display();
+ this.player.stop();
+ this.$refs.progress.value = 0;
this.player.handlers = [];
}
},
@@ -147,23 +167,111 @@ export default defineComponent({
padding: 4px 8px;
}
- > button {
+ > button, a {
border: none;
background-color: transparent;
- color: var(--accentLighten);
+ color: var(--accent);
&:hover {
background-color: var(--fg);
}
}
+ > input[type=range] {
+ height: 21px;
+ -webkit-appearance: none;
+ width: 90px;
+ padding: 0;
+ margin: 4px 8px;
+
+ &:focus {
+ outline: none;
+
+ &::-webkit-slider-runnable-track {
+ background: var(--bg);
+ }
+
+ &::-ms-fill-lower, &::-ms-fill-upper {
+ background: var(--bg);
+ }
+ }
+
+ &::-webkit-slider-runnable-track {
+ width: 100%;
+ height: 100%;
+ cursor: pointer;
+ border-radius: 0;
+ animate: 0.2s;
+ background: var(--bg);
+ border: 1px solid var(--fg);
+ }
+
+ &::-webkit-slider-thumb {
+ border: none;
+ height: 100%;
+ width: 14px;
+ border-radius: 0;
+ background: var(--accent);
+ cursor: pointer;
+ -webkit-appearance: none;
+ margin-top: -0.5px;
+ }
+
+ &::-moz-range-track {
+ width: 100%;
+ height: 100%;
+ cursor: pointer;
+ border-radius: 0;
+ animate: 0.2s;
+ background: var(--bg);
+ border: 1px solid var(--fg);
+ }
+
+ &::-moz-range-thumb {
+ border: none;
+ height: 100%;
+ border-radius: 0;
+ width: 14px;
+ background: var(--accent);
+ cursoer: pointer;
+ }
+
+ &::-ms-track {
+ width: 100%;
+ height: 100%;
+ cursor: pointer;
+ border-radius: 0;
+ animate: 0.2s;
+ background: transparent;
+ border-color: transparent;
+ color: transparent;
+ }
+
+ &::-ms-fill-lower, &::-ms-fill-upper {
+ background: var(--bg);
+ border: 1px solid var(--fg);
+ border-radius: 0;
+ }
+
+ &::-ms-thumb {
+ margin-top: 1px;
+ border: none;
+ height: 100%;
+ width: 14px;
+ border-radius: 0;
+ background: var(--accent);
+ cursor: pointer;
+ }
+ }
+
> progress {
padding: unset;
margin: 4px 8px;
flex-grow: 1;
+ background-color: var(--bg);
&::-moz-progress-bar, &::-webkit-progress-value {
- background-color: var(--accentLighten);
+ background-color: var(--accent);
}
}
}
diff --git a/src/client/scripts/chiptune2.ts b/src/client/scripts/chiptune2.ts
index 2302688c6..0b0629a35 100644
--- a/src/client/scripts/chiptune2.ts
+++ b/src/client/scripts/chiptune2.ts
@@ -11,10 +11,12 @@ ChiptuneJsConfig.prototype.constructor = ChiptuneJsConfig;
export function ChiptuneJsPlayer (config: object) {
this.config = config;
- this.context = config.context || new ChiptuneAudioContext();
+ this.audioContext = config.context || new ChiptuneAudioContext();
+ this.context = this.audioContext.createGain();
this.currentPlayingNode = null;
this.handlers = [];
this.touchLocked = true;
+ this.volume = 1;
}
ChiptuneJsPlayer.prototype.constructor = ChiptuneJsPlayer;
@@ -70,11 +72,12 @@ ChiptuneJsPlayer.prototype.metadata = function () {
};
ChiptuneJsPlayer.prototype.unlock = function () {
- const context = this.context;
+ const context = this.audioContext;
const buffer = context.createBuffer(1, 1, 22050);
const unlockSource = context.createBufferSource();
unlockSource.buffer = buffer;
- unlockSource.connect(context.destination);
+ unlockSource.connect(this.context);
+ this.context.connect(context.destination);
unlockSource.start(0);
this.touchLocked = false;
};
@@ -113,7 +116,8 @@ ChiptuneJsPlayer.prototype.play = function (buffer: ArrayBuffer) {
}
libopenmpt._openmpt_module_set_repeat_count(processNode.modulePtr, this.config.repeatCount || 1);
this.currentPlayingNode = processNode;
- processNode.connect(this.context.destination);
+ processNode.connect(this.context);
+ this.context.connect(this.audioContext.destination);
};
ChiptuneJsPlayer.prototype.stop = function () {
@@ -160,7 +164,7 @@ ChiptuneJsPlayer.prototype.getPatternRowChannel = function (pattern: number, row
ChiptuneJsPlayer.prototype.createLibopenmptNode = function (buffer, config: object) {
const maxFramesPerChunk = 4096;
- const processNode = this.context.createScriptProcessor(2048, 0, 2);
+ const processNode = this.audioContext.createScriptProcessor(2048, 0, 2);
processNode.config = config;
processNode.player = this;
const byteArray = new Int8Array(buffer);