|
1 | | -import { Essentia, arrayToVector } from 'essentia.js' |
2 | 1 | import mic from 'mic' |
3 | 2 | import WebSocket from 'ws' |
4 | 3 |
|
5 | | -async function main() { |
6 | | - const url = process.argv[2] || 'ws://localhost:8081' |
7 | | - const ws = new WebSocket(url) |
8 | | - await new Promise(resolve => ws.once('open', resolve)) |
| 4 | +const url = process.argv[2] || 'ws://localhost:8081' |
| 5 | +const ws = new WebSocket(url) |
9 | 6 |
|
10 | | - const essentia = await Essentia() |
11 | | - const sampleRate = 44100 |
12 | | - const bufferSizeSec = 5 |
13 | | - const bufferSize = sampleRate * bufferSizeSec |
14 | | - let buffer = new Float32Array(0) |
15 | | - |
16 | | - const rhythmAlgo = (signal) => |
17 | | - essentia.RhythmExtractor2013({ signal, sampleRate }) |
18 | | - |
19 | | - const micInst = mic({ rate: sampleRate.toString(), channels: '1' }) |
| 7 | +ws.on('open', () => { |
| 8 | + const micInst = mic({ rate: '44100', channels: '1' }) |
20 | 9 | const micStream = micInst.getAudioStream() |
21 | | - |
22 | 10 | micInst.start() |
23 | | - |
24 | | - micStream.on('data', (chunk) => { |
25 | | - ws.send(chunk) |
26 | | - const pcm = new Float32Array(chunk.buffer, chunk.byteOffset, chunk.length / 4) |
27 | | - const tmp = new Float32Array(buffer.length + pcm.length) |
28 | | - tmp.set(buffer) |
29 | | - tmp.set(pcm, buffer.length) |
30 | | - buffer = tmp |
31 | | - if (buffer.length >= bufferSize) { |
32 | | - const sigVec = arrayToVector(buffer) |
33 | | - const res = rhythmAlgo(sigVec) |
34 | | - const bpm = res.bpm |
35 | | - ws.send(JSON.stringify({ bpm })) |
36 | | - console.log(`BPM: ${bpm.toFixed(2)}, ticks: ${res.ticks.length}`) |
37 | | - buffer = buffer.subarray(bufferSize) |
38 | | - } |
39 | | - }) |
40 | | - |
| 11 | + micStream.on('data', chunk => ws.send(chunk)) |
41 | 12 | micStream.on('error', console.error) |
42 | | -} |
43 | | - |
44 | | -main().catch(console.error) |
| 13 | +}) |
45 | 14 |
|
0 commit comments