// ReceivePCM will receive on the the Discordgo OpusRecv channel and decode // the opus audio into PCM then send it on the provided channel. func ReceivePCM(v *discordgo.VoiceConnection, c chan *discordgo.Packet) { // make sure this only runs one instance at a time. mu.Lock() if recvpcm || c == nil { mu.Unlock() return } recvpcm = true mu.Unlock() defer func() { sendpcm = false }() var err error for { if v.Ready == false || v.OpusRecv == nil { fmt.Printf("Discordgo not ready to receive opus packets. %+v : %+v", v.Ready, v.OpusSend) return } p, ok := <-v.OpusRecv if !ok { return } if speakers == nil { speakers = make(map[uint32]*gopus.Decoder) } _, ok = speakers[p.SSRC] if !ok { speakers[p.SSRC], err = gopus.NewDecoder(48000, 2) if err != nil { fmt.Println("error creating opus decoder:", err) continue } } p.PCM, err = speakers[p.SSRC].Decode(p.Opus, 960, false) if err != nil { fmt.Println("Error decoding opus data: ", err) continue } c <- p } }
func (*generator) NewDecoder() gumble.AudioDecoder { d, _ := gopus.NewDecoder(gumble.AudioSampleRate, gumble.AudioChannels) return &Decoder{ d, } }
func handleUserState(c *Client, buffer []byte) error { var packet MumbleProto.UserState if err := proto.Unmarshal(buffer, &packet); err != nil { return err } if packet.Session == nil { return errIncompleteProtobuf } event := UserChangeEvent{ Client: c, } var user, actor *User { session := uint(*packet.Session) if !c.users.Exists(session) { user = c.users.create(session) user.channel = c.channels.ByID(0) user.client = c event.Type |= UserChangeConnected decoder, _ := gopus.NewDecoder(AudioSampleRate, 1) user.decoder = decoder if user.channel == nil { return errInvalidProtobuf } event.Type |= UserChangeChannel user.channel.users[session] = user } else { user = c.users.BySession(session) } } event.User = user if packet.Actor != nil { actor = c.users.BySession(uint(*packet.Actor)) if actor == nil { return errInvalidProtobuf } event.Actor = actor } if packet.Name != nil { if *packet.Name != user.name { event.Type |= UserChangeName } user.name = *packet.Name } if packet.UserId != nil { if *packet.UserId != user.userID && !event.Type.Has(UserChangeConnected) { if *packet.UserId != math.MaxUint32 { event.Type |= UserChangeRegistered user.userID = *packet.UserId } else { event.Type |= UserChangeUnregistered user.userID = 0 } } else { user.userID = *packet.UserId } } if packet.ChannelId != nil { if user.channel != nil { user.channel.users.delete(user.Session()) } newChannel := c.channels.ByID(uint(*packet.ChannelId)) if newChannel == nil { return errInvalidProtobuf } if newChannel != user.channel { event.Type |= UserChangeChannel user.channel = newChannel } user.channel.users[user.Session()] = user } if packet.Mute != nil { if *packet.Mute != user.mute { event.Type |= UserChangeAudio } user.mute = *packet.Mute } if packet.Deaf != nil { if *packet.Deaf != user.deaf { event.Type |= UserChangeAudio } user.deaf = *packet.Deaf } if packet.Suppress != nil { if *packet.Suppress != user.suppress { event.Type |= UserChangeAudio } user.suppress = *packet.Suppress } if packet.SelfMute != nil { if *packet.SelfMute != user.selfMute { event.Type |= UserChangeAudio } user.selfMute = *packet.SelfMute } if packet.SelfDeaf != nil { if *packet.SelfDeaf != user.selfDeaf { event.Type |= UserChangeAudio } user.selfDeaf = *packet.SelfDeaf } if packet.Texture != nil { event.Type |= UserChangeTexture user.texture = packet.Texture user.textureHash = nil } if packet.Comment != nil { if *packet.Comment != user.comment { event.Type |= UserChangeComment } user.comment = *packet.Comment user.commentHash = nil } if packet.Hash != nil { user.hash = *packet.Hash } if packet.CommentHash != nil { event.Type |= UserChangeComment user.commentHash = packet.CommentHash user.comment = "" } if packet.TextureHash != nil { event.Type |= UserChangeTexture user.textureHash = packet.TextureHash user.texture = nil } if packet.PrioritySpeaker != nil { if *packet.PrioritySpeaker != user.prioritySpeaker { event.Type |= UserChangePrioritySpeaker } user.prioritySpeaker = *packet.PrioritySpeaker } if packet.Recording != nil { if *packet.Recording != user.recording { event.Type |= UserChangeRecording } user.recording = *packet.Recording } if c.state == StateSynced { c.listeners.OnUserChange(&event) } return nil }