layeh / gumble

gumble is a Mumble client implementation in Go (golang)
https://pkg.go.dev/mod/layeh.com/gumble
Mozilla Public License 2.0
172 stars 55 forks source link

Event which user speaks ? #41

Open Tux04 opened 6 years ago

Tux04 commented 6 years ago

Hello everybody,

I can see in gumble / see if and which user now speaks? Is there an event and how do I bind it?

regards

Dirk

job580 commented 6 years ago

Hello,

If it can help someone:

In my case I made some modification to the stream.go in gumbleopenal to change a GPIO PIN on the raspberry. I did that with a timer that is reset all the time audio data is coming and that expire after 20ms on no reset that trigger a GPIO. This way I have a RX pin led.

func (s Stream) OnAudioStream(e gumble.AudioStreamEvent) {

rpio.Open()
pin := rpio.Pin(17)
pin.Output()
fmt.Printf("A")
pin.Low()
timerptt := time.NewTimer(time.Millisecond * 20)

var watchpin = true
go func() {
    for watchpin {
            <-timerptt.C
                pin.Low()
        }
}()

go func() {
    source := openal.NewSource()
    emptyBufs := openal.NewBuffers(8)
    reclaim := func() {
        if n := source.BuffersProcessed(); n > 0 {
            reclaimedBufs := make(openal.Buffers, n)
            source.UnqueueBuffers(reclaimedBufs)
            emptyBufs = append(emptyBufs, reclaimedBufs...)

        }
    }

    var raw [gumble.AudioMaximumFrameSize * 2]byte

    for packet := range e.C {
        samples := len(packet.AudioBuffer)
        pin.High()
        timerptt.Reset(time.Second)
        if samples > cap(raw) {         
            continue
        }
        for i, value := range packet.AudioBuffer {
            binary.LittleEndian.PutUint16(raw[i*2:], uint16(value))
        }
        reclaim()
        if len(emptyBufs) == 0 {
            continue
        }

        last := len(emptyBufs) - 1
        buffer := emptyBufs[last]
        emptyBufs = emptyBufs[:last]
        buffer.SetData(openal.FormatMono16, raw[:samples*2], gumble.AudioSampleRate)
        source.QueueBuffer(buffer)

        if source.State() != openal.Playing {
            source.Play()                       
        }

    }
    watchpin = false
    reclaim()
    emptyBufs.Delete()
    source.Delete()

}()

}

sensboston commented 3 years ago

If it can help someone

Your hack helped me today, thanks! BTW, will be great to refactor this to more standard way (i.e. declare and fire events instead of switching pin directly) and issue PR to @layeh.