Esempio n. 1
0
// 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
	}
}
Esempio n. 2
0
func (*generator) NewDecoder() gumble.AudioDecoder {
	d, _ := gopus.NewDecoder(gumble.AudioSampleRate, gumble.AudioChannels)
	return &Decoder{
		d,
	}
}
Esempio n. 3
0
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
}