func (c *Client) JoinVoiceChannel(ctx context.Context, guildID, channelID string, mute, deaf bool) (*voice.Connection, error) {
	c.mu.Lock()
	defer c.mu.Unlock()
	if !c.isConnected() {
		return nil, discord.ErrGatewayNotConnected
	}
	if _, ok := c.voiceConnections[guildID]; ok {
		return nil, discord.ErrAlreadyConnectedToVoice
	}
	c.connectingToVoice.Store(true)
	defer c.connectingToVoice.Store(false)
	vsu := &voice.StateUpdate{
		State: voice.State{
			GuildID:   guildID,
			ChannelID: &channelID,
			SelfMute:  mute,
			SelfDeaf:  deaf,
		},
	}
	if err := c.sendPayload(ctx, gatewayOpcodeVoiceStateUpdate, vsu); err != nil {
		return nil, err
	}
	state, server, err := getStateAndServer(c.voicePayloads)
	if err != nil {
		return nil, err
	}
	conn, err := voice.Connect(ctx, state, server, voice.WithLogger(c.logger))
	if err != nil {
		return nil, err
	}
	c.voiceConnections[guildID] = conn
	return conn, nil
}
JoinVoiceChannel will create a new voice connection to the given voice channel.
If you already have an existing connection and want to switch to a different channel
instead, use the SwitchVoiceChannel method.
This method is safe to call from multiple goroutines, but connections will happen
sequentially.
To properly leave the voice channel, call LeaveVoiceChannel.
package harmony
import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"time"
	"github.com/skwair/harmony/discord"
	"github.com/skwair/harmony/internal/payload"
	"github.com/skwair/harmony/voice"
)