Skip to content

Commit 3627f45

Browse files
committed
feat(.): Init
1 parent 86246ca commit 3627f45

10 files changed

+266
-2
lines changed

Diff for: .editorconfig

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
[*]
2+
# possible values: number (e.g. 2), "unset" (makes ktlint ignore indentation completely)
3+
indent_size=2
4+
# possible values: number (e.g. 2), "unset"
5+
continuation_indent_size=2
6+
# true (recommended) / false
7+
insert_final_newline=unset
8+
# possible values: number (e.g. 120) (package name, imports & comments are ignored), "off"
9+
# it's automatically set to 100 on `ktlint --android ...` (per Android Kotlin Style Guide)
10+
max_line_length=80

Diff for: .eslintignore

Whitespace-only changes.

Diff for: .eslintrc

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"rules": "off"
3+
}

Diff for: .npmrc

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
tag-version-prefix=""
2+
message="chore(release): %s :tada:"

Diff for: .travis.yml

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
language: node_js
2+
node_js:
3+
- "8"
4+
install:
5+
- npm install
6+
script:
7+
- npm run test
8+
- npm run lint
9+
cache:
10+
directories:
11+
- "node_modules"

Diff for: README.md

+88-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,88 @@
1-
# hypermidi
2-
Load and play MIDI from Hyperdrive over the DAT network
1+
hypermidi
2+
=========
3+
4+
Load and play MIDI from Hyperdrive over the DAT network using
5+
[timidity](https://github.com/feross/timidity) and
6+
[hyperdrive](https://github.com/mafintosh/hyperdrive).
7+
8+
## Installation
9+
10+
```sh
11+
$ npm install hypermidi
12+
```
13+
14+
## Usage
15+
16+
```js
17+
const midi = require('hypermidi')('/path/to/storage', 'KEY', opts)
18+
// replicate somehow (discovery-swarm-web works well)
19+
midi.play('/path/to/track.mid') // probably need a user gesture/event
20+
```
21+
22+
The module expects to load
23+
[`libtimidity.wasm`](https://github.com/feross/timidity/blob/master/libtimidity.wasm)
24+
and [freepats sounds sets](https://github.com/feross/freepats) over the network so
25+
your web server should be able to serve them.
26+
27+
## Example
28+
29+
```js
30+
const hypermidi = require('hyperidi')
31+
const Discovery = require('discovery-swarm-web')
32+
const ram = require('random-access-memory')
33+
34+
const key = '4f25776241c2333fa2cb724aac6fcf4d49f6fa7e243238c589cf021728762695'
35+
const midi = hypermidi(ram, key)
36+
37+
global.midi = midi
38+
midi.ready(() => {
39+
const swarm = new Discovery({
40+
stream: () => midi.replicate()
41+
})
42+
43+
swarm.join(midi.discoveryKey)
44+
45+
const button = document.body.appendChild(document.createElement('button'))
46+
button.innerText = 'play'
47+
button.onclick = () => midi.play('Bean.mid', console.log)
48+
})
49+
```
50+
51+
Run with [budo]()
52+
53+
```sh
54+
$ budo example.js --live --port 3000 --dir node_modules/timidity --dir node_modules/freepats
55+
```
56+
57+
Visit `http://localhost:3000` and press `play`! Assuming you can connect
58+
to the DAT network and replicate the archive.
59+
60+
## API
61+
62+
### `const midi = require('hypermidi')(storage, key, opts)`
63+
64+
Same arguments as [Hyperdrive](https://github.com/mafintosh/hyperdrive).
65+
66+
#### `midi.play(filename, callback)`
67+
68+
Load and play a midi file over the network.
69+
70+
#### `midi.pause()`
71+
72+
Pause current track.
73+
74+
#### `midi.seek(seconds)`
75+
76+
Seek track to current time in seconds
77+
78+
#### `midi.destroy()`
79+
80+
Destroy the player.
81+
82+
#### `midi.close()`
83+
84+
Close and destroy the player
85+
86+
## License
87+
88+
MIT

Diff for: example.js

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
const hypermidi = require('./')
2+
const Discovery = require('discovery-swarm-web')
3+
const ram = require('random-access-memory')
4+
5+
const key = '4f25776241c2333fa2cb724aac6fcf4d49f6fa7e243238c589cf021728762695'
6+
const midi = hypermidi(ram, key)
7+
8+
global.midi = midi
9+
midi.ready(() => {
10+
const swarm = new Discovery({
11+
stream: () => midi.replicate()
12+
})
13+
14+
swarm.join(midi.discoveryKey)
15+
16+
const button = document.body.appendChild(document.createElement('button'))
17+
button.innerText = 'play'
18+
button.onclick = () => midi.play('Bean.mid', console.log)
19+
})

Diff for: index.js

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
const Hyperdrive = require('hyperdrive')
2+
const Timidity = require('timidity')
3+
4+
class HyperMIDI extends Hyperdrive {
5+
constructor(storage, key, opts) {
6+
if (null === opts || 'object' !== typeof opts) {
7+
opts = {}
8+
}
9+
10+
super(storage, key, opts)
11+
12+
this.ready(() => {
13+
this.player = new Timidity(opts.timidity)
14+
})
15+
}
16+
17+
get duration() {
18+
if (this.player) {
19+
return this.player.duration
20+
}
21+
return 0
22+
}
23+
24+
get currentTime() {
25+
if (this.player) {
26+
return this.player.currentTime
27+
}
28+
return 0
29+
}
30+
31+
play(filename, cb) {
32+
const { player } = this
33+
const drive = this
34+
let retries = 3
35+
36+
if ('function' !== typeof cb) {
37+
cb = () => void 0
38+
}
39+
40+
drive.access(filename, onaccess)
41+
42+
return this
43+
44+
function onaccess(err) {
45+
if (err) {
46+
if (retries-- > 0) {
47+
return (drive.content || drive.metadata).once('sync', onsync)
48+
} else {
49+
return cb(err)
50+
}
51+
}
52+
53+
console.log('read');
54+
drive.readFile(filename, onread)
55+
}
56+
57+
function onread(err, buf) {
58+
if (err) {
59+
return cb(err)
60+
}
61+
62+
console.log('playing');
63+
player.load(buf)
64+
player.play()
65+
}
66+
67+
function onsync() {
68+
drive.access(filename, onaccess)
69+
}
70+
}
71+
72+
close() {
73+
this.destroy()
74+
return super.close()
75+
}
76+
77+
destroy() {
78+
if (this.player) {
79+
this.player.destroy()
80+
}
81+
82+
return this
83+
}
84+
85+
pause() {
86+
if (this.player) {
87+
this.player.pause()
88+
}
89+
90+
return this
91+
}
92+
93+
seek(seconds) {
94+
if (this.player) {
95+
this.player.seek(seconds)
96+
}
97+
98+
return this
99+
}
100+
}
101+
102+
function createHyperMIDI(storage, key, opts) {
103+
const midi = new HyperMIDI(storage, key, opts)
104+
return midi
105+
}
106+
107+
module.exports = Object.assign(createHyperMIDI, { HyperMIDI })

Diff for: package.json

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"name": "hypermidi",
3+
"version": "0.0.1",
4+
"description": "Load and play MIDI from Hyperdrive over the DAT network",
5+
"main": "index.js",
6+
"scripts": {
7+
"lint": ":",
8+
"test": ":"
9+
},
10+
"keywords": [
11+
"hyper",
12+
"midi",
13+
"hyperdrive",
14+
"dat"
15+
],
16+
"author": "Joseph Werle <[email protected]>",
17+
"license": "MIT",
18+
"devDependencies": {
19+
"discovery-swarm-web": "^1.0.4",
20+
"budo": "^11.6.1"
21+
},
22+
"dependencies": {
23+
"random-access-memory": "^3.1.1",
24+
"timidity": "^1.0.1"
25+
}
26+
}

Diff for: player.js

Whitespace-only changes.

0 commit comments

Comments
 (0)