[Solved]switch backend from Speaker to PortAudio(naudiodon)
Closed this issue · 0 comments
Zazck commented
looks like node-speaker just a mpg123 wrapper, and maybe my fault, it always throw an exception
Error: specified PCM format is not supported by "win32" backend
I tried to replace the speaker with portaudio directly, it seems no problem if we specify a fixed chunk size. the size should be highWaterMark / 8.
# av/src/devices/node-speaker.coffee
EventEmitter = require '../core/events'
AudioDevice = require '../device'
class NodeSpeakerDevice extends EventEmitter
AudioDevice.register(NodeSpeakerDevice)
try
Speaker = require('naudiodon').AudioOutput
Readable = require('stream').Readable
@supported: Speaker?
constructor: (@sampleRate, @channels) ->
@speaker = new Speaker
channels: @channels
sampleRate: @sampleRate
sampleFormat: 32
deviceId: -1
@buffer = null
@currentFrame = 0
@ended = false
# setup a node readable stream and pipe to speaker output
@input = new Readable
@input._read = @refill
@speaker.on 'end', @speaker.end
@speaker.on 'error', (error) -> console.log error
@speaker.start()
@input.pipe @speaker
refill: (n) =>
{buffer} = this
len = n / 4
arr = new Float32Array(len)
@emit 'refill', arr
return if @ended
if buffer?.length isnt n
@buffer = buffer = new Buffer(n)
# copy the data from the Float32Array into the node buffer
offset = 0
for frame in arr
buffer.writeFloatLE(frame, offset)
offset += 4
@input.push buffer
@currentFrame += len / @channels
destroy: ->
@ended = true
@input.push null
getDeviceTime: ->
return @currentFrame # TODO: make this more accurate
// naudiodon/src/AudioOut.cc
// line 76
case 8: outParams.sampleFormat = paInt8; break;
case 16: outParams.sampleFormat = paInt16; break;
case 24: outParams.sampleFormat = paInt24; break;
case 32: outParams.sampleFormat = paFloat32; break; //switch to Float
// line 87
uint32_t framesPerBuffer = 2048; // fixed packet size 16384bit to 2048byte