audiocogs/aurora.js

[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

naudiodon (PortAudio)