Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save MayamaTakeshi/89bcd17a4af8bade71ae152d7df2fd57 to your computer and use it in GitHub Desktop.
Save MayamaTakeshi/89bcd17a4af8bade71ae152d7df2fd57 to your computer and use it in GitHub Desktop.
const Speaker = require('speaker')
var Mic = require('node-microphone')
speaker = new Speaker({
audioFormat: 1,
endianness: 'LE',
channels: 1,
sampleRate: 8000,
blockAlign: 2,
bitDepth: 16,
signed: true
})
var opts = {
endian: 'little',
bitWidth: 16,
encoding: 'signed-integer',
rate: 16000,
channels: 1,
device: 'default',
}
var mic = new Mic(opts)
var micStream = mic.startRecording()
micStream.on('data', data => {
console.log(`data: ${data.length}`)
var buf = Buffer.alloc(data.length/2)
// for every 4 bytes in data, discard 2
for(var i=0; i<data.length/2 ; i++) {
buf[i*2] = data[i*4]
buf[i*2+1] = data[i*4+1]
}
speaker.write(buf)
})
mic.on('info', (info) => {
console.log(`info: ${info}`)
})
mic.on('error', (error) => {
console.log(`error: ${error}`)
});
// The above works. But we listen to 'clicks'. How to get rid of them?
@MayamaTakeshi
Copy link
Author

// The same problem with 'clicks' happens if we average each 4 bytes from source:

const Speaker = require('speaker')
var Mic = require('node-microphone')

speaker = new Speaker({
audioFormat: 1,
endianness: 'LE',
channels: 1,
sampleRate: 8000,
blockAlign: 2,
bitDepth: 16,
signed: true
})

var opts = {
endian: 'little',
bitWidth: 16,
encoding: 'signed-integer',
rate: 16000,
channels: 1,
device: 'default',
}

var mic = new Mic(opts)
var micStream = mic.startRecording()

micStream.on('data', data => {
console.log(data: ${data.length})

var buf = Buffer.alloc(data.length/2)
// averaging each 4 bytes from data
for(var i=0; i<data.length/2 ; i++) {
    var s1 = (data[i*4]) + (data[i*4+1] << 8)
    var s2 = (data[i*4+2]) + (data[i*4+3] << 8)
    var average = s1//(s1 + s2) / 2
    buf[i*2] = average & 0xFF
    buf[i*2+1] = average >> 8 
}
speaker.write(buf)

})

mic.on('info', (info) => {
console.log(info: ${info})
})

mic.on('error', (error) => {
console.log(error: ${error})
});

@MayamaTakeshi
Copy link
Author

MayamaTakeshi commented Jun 11, 2021

// however, double-checkingby writing to a file, the generated test.wav doesn't contain the 'clicks' so this is an issue with module Speaker or with the OS sound system:

const Speaker = require('speaker')
var FileWriter = require('wav').FileWriter;
var Mic = require('node-microphone')

speaker = new Speaker({
audioFormat: 1,
endianness: 'LE',
channels: 1,
sampleRate: 8000,
blockAlign: 2,
bitDepth: 16,
signed: true
})

var outputFileStream = new FileWriter('./test.wav', {
sampleRate: 8000,
channels: 1
});

var opts = {
endian: 'little',
bitWidth: 16,
encoding: 'signed-integer',
rate: 16000,
channels: 1,
device: 'default',
}

var mic = new Mic(opts)

var micStream = mic.startRecording()

micStream.on('data', data => {
console.log(data: ${data.length})

var buf = Buffer.alloc(data.length/2)
// averaging each 4 bytes from data
for(var i=0; i<data.length/2 ; i++) {
    var s1 = (data[i*4]) + (data[i*4+1] << 8)
    var s2 = (data[i*4+2]) + (data[i*4+3] << 8)
    var average = s1//(s1 + s2) / 2
    buf[i*2] = average & 0xFF
    buf[i*2+1] = average >> 8 
}
speaker.write(buf)
outputFileStream.write(buf)

})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment