@harmonia-audio/voice 0.1.5 → 0.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -366,7 +366,11 @@ var VoiceConnection = class extends events.EventEmitter {
366
366
  * ```
367
367
  */
368
368
  subscribe(player) {
369
+ if (this.subscribedPlayer) {
370
+ this.subscribedPlayer.removeConnection(this);
371
+ }
369
372
  this.subscribedPlayer = player;
373
+ player.addConnection(this);
370
374
  }
371
375
  /**
372
376
  * Unsubscribe the current audio player.
@@ -377,6 +381,9 @@ var VoiceConnection = class extends events.EventEmitter {
377
381
  * ```
378
382
  */
379
383
  unsubscribe() {
384
+ if (this.subscribedPlayer) {
385
+ this.subscribedPlayer.removeConnection(this);
386
+ }
380
387
  this.subscribedPlayer = void 0;
381
388
  }
382
389
  /**
@@ -710,7 +717,7 @@ var AudioPlayer = class extends events.EventEmitter {
710
717
  _state = "idle" /* Idle */;
711
718
  resource;
712
719
  connections = /* @__PURE__ */ new Set();
713
- playbackTimer;
720
+ audioThread;
714
721
  noSubscriberBehavior;
715
722
  constructor(options = {}) {
716
723
  super();
@@ -789,9 +796,12 @@ var AudioPlayer = class extends events.EventEmitter {
789
796
  this.connections.delete(connection);
790
797
  }
791
798
  startPlaybackLoop() {
792
- this.playbackTimer = setInterval(() => {
799
+ if (!this.audioThread) {
800
+ this.audioThread = new native.AudioThread();
801
+ }
802
+ this.audioThread.start(() => {
793
803
  this.processFrame();
794
- }, 20);
804
+ });
795
805
  }
796
806
  processFrame() {
797
807
  if (this._state !== "playing" /* Playing */) {
@@ -816,9 +826,9 @@ var AudioPlayer = class extends events.EventEmitter {
816
826
  }
817
827
  }
818
828
  stopInternal() {
819
- if (this.playbackTimer) {
820
- clearInterval(this.playbackTimer);
821
- this.playbackTimer = void 0;
829
+ if (this.audioThread) {
830
+ this.audioThread.stop();
831
+ this.audioThread = void 0;
822
832
  }
823
833
  if (this.resource) {
824
834
  this.resource.destroy();
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/encryption.ts","../src/errors.ts","../src/store.ts","../src/types.ts","../src/receiver.ts","../src/connection.ts","../src/player.ts","../src/join.ts","../src/resource.ts"],"names":["EncryptionMode","secretboxEncrypt","randomBytes","xchacha20Encrypt","secretboxDecrypt","xchacha20Decrypt","VoiceConnectionState","AudioPlayerState","Readable","EventEmitter","OpusDecoder","parseRtpHeader","buildRtpHeader","WebSocket","dgram","configureSocketForAudio","OpusEncoderStream"],"mappings":"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","file":"index.cjs","sourcesContent":["import {\n\tsecretboxEncrypt,\n\tsecretboxDecrypt,\n\txchacha20Encrypt,\n\txchacha20Decrypt,\n\trandomBytes,\n\tbuildRtpHeader,\n\tparseRtpHeader,\n\ttype RtpHeader as NativeRtpHeader,\n} from \"@harmonia-audio/native\";\n\nconst NONCE_SIZE_XSALSA20 = 24;\nconst NONCE_SIZE_LITE = 4;\n\n/**\n * Available encryption modes for voice connections.\n *\n * @example\n * ```ts\n * connection.setEncryptionMode(EncryptionMode.XSalsa20Poly1305);\n * ```\n */\nexport enum EncryptionMode {\n\tXSalsa20Poly1305 = \"xsalsa20_poly1305\",\n\tXSalsa20Poly1305Suffix = \"xsalsa20_poly1305_suffix\",\n\tXSalsa20Poly1305Lite = \"xsalsa20_poly1305_lite\",\n\tAeadAes256Gcm = \"aead_aes256_gcm\",\n\tAeadXChaCha20Poly1305 = \"aead_xchacha20_poly1305_rtpsize\",\n}\n\n/** Parsed RTP packet. */\nexport interface RtpPacket {\n\theader: NativeRtpHeader;\n\tpayload: Buffer;\n\tnonce: Buffer;\n}\n\nconst PREFERRED_MODES: EncryptionMode[] = [\n\tEncryptionMode.AeadXChaCha20Poly1305,\n\tEncryptionMode.AeadAes256Gcm,\n\tEncryptionMode.XSalsa20Poly1305Lite,\n\tEncryptionMode.XSalsa20Poly1305Suffix,\n\tEncryptionMode.XSalsa20Poly1305,\n];\n\n/**\n * Select the best available encryption mode from a list of supported modes.\n *\n * @example\n * ```ts\n * const mode = selectEncryptionMode(['xsalsa20_poly1305', 'xsalsa20_poly1305_suffix']);\n * ```\n */\nexport function selectEncryptionMode(\n\tavailable: readonly string[],\n): EncryptionMode {\n\tfor (const preferred of PREFERRED_MODES) {\n\t\tif (available.includes(preferred)) {\n\t\t\treturn preferred;\n\t\t}\n\t}\n\tconst first = available[0];\n\tif (first !== undefined) {\n\t\treturn first as EncryptionMode;\n\t}\n\treturn EncryptionMode.XSalsa20Poly1305;\n}\n\n/**\n * Encrypt an RTP payload.\n *\n * @example\n * ```ts\n * const encrypted = encryptOpusPacket(header, payload, key, mode, nonceCounter);\n * ```\n */\nexport function encryptOpusPacket(\n\trtpHeader: Buffer,\n\tpayload: Buffer,\n\tsecretKey: Buffer,\n\tmode: EncryptionMode,\n\tnonceCounter: number,\n): Buffer {\n\tswitch (mode) {\n\t\tcase EncryptionMode.XSalsa20Poly1305: {\n\t\t\tconst nonce = Buffer.alloc(NONCE_SIZE_XSALSA20);\n\t\t\trtpHeader.copy(nonce, 0, 0, 12);\n\t\t\tconst encrypted = secretboxEncrypt(payload, nonce, secretKey);\n\t\t\treturn Buffer.concat([rtpHeader, encrypted]);\n\t\t}\n\n\t\tcase EncryptionMode.XSalsa20Poly1305Suffix: {\n\t\t\tconst nonce = randomBytes(NONCE_SIZE_XSALSA20);\n\t\t\tconst encrypted = secretboxEncrypt(payload, nonce, secretKey);\n\t\t\treturn Buffer.concat([rtpHeader, encrypted, nonce]);\n\t\t}\n\n\t\tcase EncryptionMode.XSalsa20Poly1305Lite: {\n\t\t\tconst nonce = Buffer.alloc(NONCE_SIZE_XSALSA20);\n\t\t\tnonce.writeUInt32BE(nonceCounter, 0);\n\t\t\tconst encrypted = secretboxEncrypt(payload, nonce, secretKey);\n\t\t\tconst nonceAppend = Buffer.alloc(NONCE_SIZE_LITE);\n\t\t\tnonceAppend.writeUInt32BE(nonceCounter, 0);\n\t\t\treturn Buffer.concat([rtpHeader, encrypted, nonceAppend]);\n\t\t}\n\n\t\tcase EncryptionMode.AeadXChaCha20Poly1305: {\n\t\t\tconst nonce = Buffer.alloc(24);\n\t\t\tnonce.writeUInt32BE(nonceCounter, 0);\n\t\t\tconst encrypted = xchacha20Encrypt(payload, nonce, secretKey, rtpHeader);\n\t\t\tconst nonceAppend = Buffer.alloc(4);\n\t\t\tnonceAppend.writeUInt32BE(nonceCounter, 0);\n\t\t\treturn Buffer.concat([rtpHeader, encrypted, nonceAppend]);\n\t\t}\n\n\t\tdefault:\n\t\t\treturn Buffer.concat([rtpHeader, payload]);\n\t}\n}\n\n/**\n * Decrypt an RTP packet payload.\n *\n * @example\n * ```ts\n * const decrypted = decryptOpusPacket(packet, secretKey, mode);\n * ```\n */\nexport function decryptOpusPacket(\n\tpacket: Buffer,\n\tsecretKey: Buffer,\n\tmode: EncryptionMode,\n): Buffer {\n\tconst rtpHeader = packet.subarray(0, 12);\n\n\tswitch (mode) {\n\t\tcase EncryptionMode.XSalsa20Poly1305: {\n\t\t\tconst nonce = Buffer.alloc(NONCE_SIZE_XSALSA20);\n\t\t\trtpHeader.copy(nonce, 0, 0, 12);\n\t\t\tconst ciphertext = packet.subarray(12);\n\t\t\treturn secretboxDecrypt(ciphertext, nonce, secretKey);\n\t\t}\n\n\t\tcase EncryptionMode.XSalsa20Poly1305Suffix: {\n\t\t\tconst nonce = packet.subarray(packet.length - NONCE_SIZE_XSALSA20);\n\t\t\tconst ciphertext = packet.subarray(12, packet.length - NONCE_SIZE_XSALSA20);\n\t\t\treturn secretboxDecrypt(ciphertext, nonce, secretKey);\n\t\t}\n\n\t\tcase EncryptionMode.XSalsa20Poly1305Lite: {\n\t\t\tconst nonce = Buffer.alloc(NONCE_SIZE_XSALSA20);\n\t\t\tconst nonceFragment = packet.subarray(packet.length - NONCE_SIZE_LITE);\n\t\t\tnonceFragment.copy(nonce, 0, 0, NONCE_SIZE_LITE);\n\t\t\tconst ciphertext = packet.subarray(12, packet.length - NONCE_SIZE_LITE);\n\t\t\treturn secretboxDecrypt(ciphertext, nonce, secretKey);\n\t\t}\n\n\t\tcase EncryptionMode.AeadXChaCha20Poly1305: {\n\t\t\tconst nonce = Buffer.alloc(24);\n\t\t\tconst nonceFragment = packet.subarray(packet.length - 4);\n\t\t\tnonceFragment.copy(nonce, 0, 0, 4);\n\t\t\tconst ciphertext = packet.subarray(12, packet.length - 4);\n\t\t\treturn xchacha20Decrypt(ciphertext, nonce, secretKey, rtpHeader);\n\t\t}\n\n\t\tdefault: {\n\t\t\treturn packet.subarray(12);\n\t\t}\n\t}\n}\n","/**\n * Error class for all voice-related errors in harmonia.\n *\n * @example\n * ```ts\n * try {\n * await connection.connect();\n * } catch (error) {\n * if (error instanceof HarmoniaVoiceError) {\n * console.error(error.code);\n * }\n * }\n * ```\n */\nexport class HarmoniaVoiceError extends Error {\n\tpublic readonly code: string;\n\tpublic readonly context: Record<string, unknown>;\n\n\tconstructor(\n\t\tcode: string,\n\t\tmessage: string,\n\t\tcontext: Record<string, unknown> = {},\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"HarmoniaVoiceError\";\n\t\tthis.code = code;\n\t\tthis.context = context;\n\t}\n}\n","import type { VoiceConnection } from \"./connection.js\";\n\nconst connections = new Map<string, VoiceConnection>();\n\n/**\n * Get a voice connection by guild ID.\n *\n * @example\n * ```ts\n * const connection = getVoiceConnection('guild-id');\n * ```\n */\nexport function getVoiceConnection(guildId: string): VoiceConnection | undefined {\n\treturn connections.get(guildId);\n}\n\n/**\n * Get all active voice connections.\n *\n * @example\n * ```ts\n * const all = getVoiceConnections();\n * ```\n */\nexport function getVoiceConnections(): ReadonlyMap<string, VoiceConnection> {\n\treturn connections;\n}\n\n/** @internal */\nexport function setVoiceConnection(guildId: string, connection: VoiceConnection): void {\n\tconnections.set(guildId, connection);\n}\n\n/** @internal */\nexport function removeVoiceConnection(guildId: string): void {\n\tconnections.delete(guildId);\n}\n","import type { EventEmitter } from \"node:events\";\n\n/**\n * Voice connection states.\n *\n * @example\n * ```ts\n * if (connection.state === VoiceConnectionState.Ready) {\n * // connection is ready\n * }\n * ```\n */\nexport enum VoiceConnectionState {\n\tIdle = \"idle\",\n\tSignalling = \"signalling\",\n\tConnecting = \"connecting\",\n\tReady = \"ready\",\n\tResuming = \"resuming\",\n\tDisconnected = \"disconnected\",\n\tDestroyed = \"destroyed\",\n}\n\n/**\n * Audio player states.\n *\n * @example\n * ```ts\n * if (player.state === AudioPlayerState.Playing) {\n * player.pause();\n * }\n * ```\n */\nexport enum AudioPlayerState {\n\tIdle = \"idle\",\n\tBuffering = \"buffering\",\n\tPlaying = \"playing\",\n\tPaused = \"paused\",\n\tAutoPaused = \"autopaused\",\n}\n\n/**\n * Events emitted by a voice connection.\n *\n * @example\n * ```ts\n * connection.on('stateChange', (oldState, newState) => {\n * console.log(`${oldState} -> ${newState}`);\n * });\n * ```\n */\nexport interface VoiceConnectionEvents {\n\tstateChange: [oldState: VoiceConnectionState, newState: VoiceConnectionState];\n\tready: [];\n\tdisconnected: [];\n\tdestroyed: [];\n\terror: [error: Error];\n}\n\n/**\n * Events emitted by an audio player.\n *\n * @example\n * ```ts\n * player.on('stateChange', (oldState, newState) => {\n * console.log(`${oldState} -> ${newState}`);\n * });\n * ```\n */\nexport interface AudioPlayerEvents {\n\tstateChange: [oldState: AudioPlayerState, newState: AudioPlayerState];\n\tidle: [];\n\terror: [error: Error];\n}\n","import { EventEmitter } from \"node:events\";\nimport { Readable } from \"node:stream\";\nimport { OpusDecoder } from \"@harmonia-audio/codec\";\nimport { parseRtpHeader } from \"@harmonia-audio/native\";\nimport type { VoiceConnection } from \"./connection.js\";\n\n/**\n * Options for the audio receiver.\n *\n * @example\n * ```ts\n * const receiver = connection.getReceiver();\n * ```\n */\nexport interface AudioReceiverOptions {\n\treadonly autoDecodeOpus?: boolean;\n}\n\ninterface SsrcState {\n\tuserId: string | undefined;\n\tdecoder: OpusDecoder;\n\tstream: UserAudioStream;\n}\n\n/**\n * A readable stream of audio from a specific user.\n *\n * @example\n * ```ts\n * const stream = receiver.subscribe('user-id');\n * stream.on('data', (pcm) => { ... });\n * ```\n */\nexport class UserAudioStream extends Readable {\n\tpublic readonly userId: string;\n\n\tconstructor(userId: string) {\n\t\tsuper({ objectMode: false });\n\t\tthis.userId = userId;\n\t}\n\n\toverride _read(): void {\n\t\t// Data is pushed from the receiver\n\t}\n}\n\n/**\n * Receives and routes incoming audio from voice connections.\n *\n * @example\n * ```ts\n * const receiver = connection.getReceiver();\n * const stream = receiver.subscribe('user-id');\n *\n * stream.on('data', (pcm: Buffer) => {\n * // Process received audio\n * });\n * ```\n */\nexport class AudioReceiver extends EventEmitter {\n\tprivate readonly connection: VoiceConnection;\n\tprivate readonly ssrcMap = new Map<number, SsrcState>();\n\tprivate readonly userSsrcMap = new Map<string, number>();\n\tprivate readonly subscriptions = new Map<string, UserAudioStream>();\n\n\tconstructor(connection: VoiceConnection) {\n\t\tsuper();\n\t\tthis.connection = connection;\n\t}\n\n\t/**\n\t * Subscribe to audio from a specific user.\n\t *\n\t * @param userId - The Discord user ID to receive audio from\n\t * @returns A readable stream of PCM audio from that user\n\t *\n\t * @example\n\t * ```ts\n\t * const stream = receiver.subscribe('123456789');\n\t * stream.pipe(fileWriteStream);\n\t * ```\n\t */\n\tsubscribe(userId: string): UserAudioStream {\n\t\tconst existing = this.subscriptions.get(userId);\n\t\tif (existing) {\n\t\t\treturn existing;\n\t\t}\n\n\t\tconst stream = new UserAudioStream(userId);\n\t\tthis.subscriptions.set(userId, stream);\n\n\t\tstream.on(\"close\", () => {\n\t\t\tthis.subscriptions.delete(userId);\n\t\t});\n\n\t\treturn stream;\n\t}\n\n\t/**\n\t * Unsubscribe from a user's audio.\n\t *\n\t * @example\n\t * ```ts\n\t * receiver.unsubscribe('123456789');\n\t * ```\n\t */\n\tunsubscribe(userId: string): void {\n\t\tconst stream = this.subscriptions.get(userId);\n\t\tif (stream) {\n\t\t\tstream.destroy();\n\t\t\tthis.subscriptions.delete(userId);\n\t\t}\n\t}\n\n\t/** @internal */\n\tmapSsrcToUser(ssrc: number, userId: string): void {\n\t\tlet state = this.ssrcMap.get(ssrc);\n\t\tif (!state) {\n\t\t\tstate = {\n\t\t\t\tuserId,\n\t\t\t\tdecoder: new OpusDecoder({ sampleRate: 48000, channels: 2 }),\n\t\t\t\tstream: new UserAudioStream(userId),\n\t\t\t};\n\t\t\tthis.ssrcMap.set(ssrc, state);\n\t\t} else {\n\t\t\tstate.userId = userId;\n\t\t}\n\t\tthis.userSsrcMap.set(userId, ssrc);\n\t\tthis.emit(\"userConnected\", userId, ssrc);\n\t}\n\n\t/** @internal */\n\tremoveUser(userId: string): void {\n\t\tconst ssrc = this.userSsrcMap.get(userId);\n\t\tif (ssrc !== undefined) {\n\t\t\tconst state = this.ssrcMap.get(ssrc);\n\t\t\tif (state) {\n\t\t\t\tstate.stream.destroy();\n\t\t\t\tthis.ssrcMap.delete(ssrc);\n\t\t\t}\n\t\t\tthis.userSsrcMap.delete(userId);\n\t\t}\n\t\tthis.subscriptions.get(userId)?.destroy();\n\t\tthis.subscriptions.delete(userId);\n\t\tthis.emit(\"userDisconnected\", userId);\n\t}\n\n\t/** @internal */\n\thandlePacket(rawPacket: Buffer, decryptedPayload: Buffer): void {\n\t\ttry {\n\t\t\tconst header = parseRtpHeader(rawPacket);\n\t\t\tconst state = this.ssrcMap.get(header.ssrc);\n\n\t\t\tif (!state?.userId) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst pcm = state.decoder.decode(decryptedPayload);\n\n\t\t\tconst subscription = this.subscriptions.get(state.userId);\n\t\t\tif (subscription && !subscription.destroyed) {\n\t\t\t\tsubscription.push(pcm);\n\t\t\t}\n\n\t\t\tthis.emit(\"audio\", state.userId, pcm, header);\n\t\t} catch {\n\t\t\t// Silently drop malformed packets\n\t\t}\n\t}\n\n\t/**\n\t * Destroy all streams and clean up.\n\t *\n\t * @example\n\t * ```ts\n\t * receiver.destroy();\n\t * ```\n\t */\n\tdestroy(): this {\n\t\tfor (const [, stream] of this.subscriptions) {\n\t\t\tstream.destroy();\n\t\t}\n\t\tthis.subscriptions.clear();\n\t\tthis.ssrcMap.clear();\n\t\tthis.userSsrcMap.clear();\n\t\treturn this;\n\t}\n}\n","import { EventEmitter } from \"node:events\";\nimport dgram from \"node:dgram\";\nimport WebSocket from \"ws\";\nimport {\n\tbuildRtpHeader,\n\tconfigureSocketForAudio,\n\tAudioThread as NativeAudioThread,\n\tAudioRingBuffer,\n} from \"@harmonia-audio/native\";\nimport { OpusEncoder } from \"@harmonia-audio/codec\";\nimport type {\n\tDiscordGatewayAdapter,\n\tDiscordGatewayAdapterCreator,\n\tVoiceServerUpdateData,\n\tVoiceStateUpdateData,\n} from \"./adapter.js\";\nimport {\n\tencryptOpusPacket,\n\tEncryptionMode,\n\tselectEncryptionMode,\n\tdecryptOpusPacket,\n} from \"./encryption.js\";\nimport { HarmoniaVoiceError } from \"./errors.js\";\nimport { removeVoiceConnection, setVoiceConnection } from \"./store.js\";\nimport { VoiceConnectionState, type VoiceConnectionEvents } from \"./types.js\";\nimport type { AudioPlayer } from \"./player.js\";\nimport { AudioReceiver } from \"./receiver.js\";\n\nconst VOICE_GATEWAY_VERSION = 8;\nconst HEARTBEAT_MAX_MISSED = 3;\nconst IP_DISCOVERY_PACKET_SIZE = 74;\n\n/**\n * Options for creating a voice connection.\n *\n * @example\n * ```ts\n * const options: VoiceConnectionOptions = {\n * guildId: '123456789',\n * channelId: '987654321',\n * selfDeaf: false,\n * selfMute: false,\n * };\n * ```\n */\nexport interface VoiceConnectionOptions {\n\treadonly guildId: string;\n\treadonly channelId: string;\n\treadonly selfDeaf?: boolean;\n\treadonly selfMute?: boolean;\n\treadonly adapterCreator: DiscordGatewayAdapterCreator;\n}\n\ninterface VoiceGatewayReady {\n\tssrc: number;\n\tip: string;\n\tport: number;\n\tmodes: string[];\n}\n\n/**\n * Manages a voice connection to a Discord voice channel.\n *\n * @example\n * ```ts\n * import { VoiceConnection } from '@harmonia/voice';\n *\n * const connection = new VoiceConnection({\n * guildId: '123',\n * channelId: '456',\n * adapterCreator: guild.voiceAdapterCreator,\n * });\n *\n * connection.on('ready', () => {\n * console.log('Connected to voice!');\n * });\n * ```\n */\nexport class VoiceConnection extends EventEmitter {\n\tprivate _state: VoiceConnectionState = VoiceConnectionState.Idle;\n\tprivate readonly guildId: string;\n\tprivate channelId: string;\n\tprivate readonly selfDeaf: boolean;\n\tprivate readonly selfMute: boolean;\n\tprivate adapter: DiscordGatewayAdapter | undefined;\n\n\tprivate sessionId: string | undefined;\n\tprivate voiceToken: string | undefined;\n\tprivate endpoint: string | undefined;\n\n\tprivate ws: WebSocket | undefined;\n\tprivate udpSocket: dgram.Socket | undefined;\n\tprivate ssrc = 0;\n\tprivate remoteIp = \"\";\n\tprivate remotePort = 0;\n\tprivate localIp = \"\";\n\tprivate localPort = 0;\n\tprivate secretKey: Buffer | undefined;\n\tprivate encryptionMode: EncryptionMode = EncryptionMode.XSalsa20Poly1305;\n\tprivate sequence = 0;\n\tprivate timestamp = 0;\n\tprivate nonceCounter = 0;\n\n\tprivate heartbeatInterval: ReturnType<typeof setInterval> | undefined;\n\tprivate heartbeatNonce = 0;\n\tprivate missedHeartbeats = 0;\n\tprivate lastHeartbeatAck = 0;\n\n\tprivate subscribedPlayer: AudioPlayer | undefined;\n\tprivate audioThread: NativeAudioThread | undefined;\n\tprivate ringBuffer: AudioRingBuffer | undefined;\n\n\tprivate readonly receiver: AudioReceiver;\n\n\tprivate voiceStateResolve: (() => void) | undefined;\n\tprivate voiceServerResolve: (() => void) | undefined;\n\n\tconstructor(options: VoiceConnectionOptions) {\n\t\tsuper();\n\t\tthis.guildId = options.guildId;\n\t\tthis.channelId = options.channelId;\n\t\tthis.selfDeaf = options.selfDeaf ?? false;\n\t\tthis.selfMute = options.selfMute ?? false;\n\t\tthis.receiver = new AudioReceiver(this);\n\n\t\tthis.adapter = options.adapterCreator({\n\t\t\tonVoiceStateUpdate: (data) => this.handleVoiceStateUpdate(data),\n\t\t\tonVoiceServerUpdate: (data) => this.handleVoiceServerUpdate(data),\n\t\t\tdestroy: () => this.destroy(),\n\t\t});\n\n\t\tsetVoiceConnection(this.guildId, this);\n\t\tthis.sendVoiceStateUpdate();\n\t}\n\n\t/**\n\t * Current connection state.\n\t *\n\t * @example\n\t * ```ts\n\t * if (connection.state === VoiceConnectionState.Ready) { ... }\n\t * ```\n\t */\n\tget state(): VoiceConnectionState {\n\t\treturn this._state;\n\t}\n\n\t/**\n\t * Get the audio receiver for this connection.\n\t *\n\t * @example\n\t * ```ts\n\t * const receiver = connection.getReceiver();\n\t * ```\n\t */\n\tgetReceiver(): AudioReceiver {\n\t\treturn this.receiver;\n\t}\n\n\t/**\n\t * Subscribe an audio player to this connection.\n\t *\n\t * @example\n\t * ```ts\n\t * connection.subscribe(player);\n\t * ```\n\t */\n\tsubscribe(player: AudioPlayer): void {\n\t\tthis.subscribedPlayer = player;\n\t}\n\n\t/**\n\t * Unsubscribe the current audio player.\n\t *\n\t * @example\n\t * ```ts\n\t * connection.unsubscribe();\n\t * ```\n\t */\n\tunsubscribe(): void {\n\t\tthis.subscribedPlayer = undefined;\n\t}\n\n\t/**\n\t * Destroy the connection and clean up all resources.\n\t *\n\t * @example\n\t * ```ts\n\t * connection.destroy();\n\t * ```\n\t */\n\tdestroy(): void {\n\t\tif (this._state === VoiceConnectionState.Destroyed) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.transitionTo(VoiceConnectionState.Destroyed);\n\t\tthis.cleanup();\n\t\tremoveVoiceConnection(this.guildId);\n\n\t\tif (this.adapter) {\n\t\t\tthis.adapter.sendPayload({\n\t\t\t\top: 4,\n\t\t\t\td: {\n\t\t\t\t\tguild_id: this.guildId,\n\t\t\t\t\tchannel_id: null,\n\t\t\t\t\tself_mute: false,\n\t\t\t\t\tself_deaf: false,\n\t\t\t\t},\n\t\t\t});\n\t\t\tthis.adapter.destroy();\n\t\t\tthis.adapter = undefined;\n\t\t}\n\n\t\tthis.emit(\"destroyed\");\n\t}\n\n\t/**\n\t * Send an Opus packet through the voice connection.\n\t *\n\t * @example\n\t * ```ts\n\t * connection.sendOpusPacket(opusBuffer);\n\t * ```\n\t */\n\tsendOpusPacket(opusPacket: Buffer): void {\n\t\tif (this._state !== VoiceConnectionState.Ready) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.secretKey || !this.udpSocket) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst header = buildRtpHeader(this.sequence, this.timestamp, this.ssrc, 0x78);\n\n\t\tconst encrypted = encryptOpusPacket(\n\t\t\theader,\n\t\t\topusPacket,\n\t\t\tthis.secretKey,\n\t\t\tthis.encryptionMode,\n\t\t\tthis.nonceCounter,\n\t\t);\n\n\t\tthis.udpSocket.send(encrypted, this.remotePort, this.remoteIp);\n\n\t\tthis.sequence = (this.sequence + 1) & 0xFFFF;\n\t\tthis.timestamp = (this.timestamp + 960) >>> 0;\n\t\tthis.nonceCounter = (this.nonceCounter + 1) >>> 0;\n\t}\n\n\tprivate sendVoiceStateUpdate(): void {\n\t\tthis.transitionTo(VoiceConnectionState.Signalling);\n\n\t\tthis.adapter?.sendPayload({\n\t\t\top: 4,\n\t\t\td: {\n\t\t\t\tguild_id: this.guildId,\n\t\t\t\tchannel_id: this.channelId,\n\t\t\t\tself_mute: this.selfMute,\n\t\t\t\tself_deaf: this.selfDeaf,\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate handleVoiceStateUpdate(data: VoiceStateUpdateData): void {\n\t\tthis.sessionId = data.session_id;\n\t\tif (this.voiceStateResolve) {\n\t\t\tthis.voiceStateResolve();\n\t\t\tthis.voiceStateResolve = undefined;\n\t\t}\n\t\tthis.tryConnect();\n\t}\n\n\tprivate handleVoiceServerUpdate(data: VoiceServerUpdateData): void {\n\t\tthis.voiceToken = data.token;\n\t\tthis.endpoint = data.endpoint ?? undefined;\n\t\tif (this.voiceServerResolve) {\n\t\t\tthis.voiceServerResolve();\n\t\t\tthis.voiceServerResolve = undefined;\n\t\t}\n\t\tthis.tryConnect();\n\t}\n\n\tprivate tryConnect(): void {\n\t\tif (!this.sessionId || !this.voiceToken || !this.endpoint) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.transitionTo(VoiceConnectionState.Connecting);\n\t\tthis.connectWebSocket();\n\t}\n\n\tprivate connectWebSocket(): void {\n\t\tconst wsUrl = `wss://${this.endpoint}/?v=${VOICE_GATEWAY_VERSION}`;\n\n\t\tthis.ws?.close();\n\t\tthis.ws = new WebSocket(wsUrl);\n\n\t\tthis.ws.on(\"open\", () => {\n\t\t\tthis.sendIdentify();\n\t\t});\n\n\t\tthis.ws.on(\"message\", (raw: WebSocket.Data) => {\n\t\t\tconst data = JSON.parse(raw.toString()) as {\n\t\t\t\top: number;\n\t\t\t\td: Record<string, unknown>;\n\t\t\t};\n\t\t\tthis.handleGatewayMessage(data.op, data.d);\n\t\t});\n\n\t\tthis.ws.on(\"close\", (code: number) => {\n\t\t\tthis.stopHeartbeat();\n\t\t\tif (this._state !== VoiceConnectionState.Destroyed) {\n\t\t\t\tif (code === 4014 || code === 4006) {\n\t\t\t\t\tthis.transitionTo(VoiceConnectionState.Disconnected);\n\t\t\t\t\tthis.emit(\"disconnected\");\n\t\t\t\t} else if (this._state !== VoiceConnectionState.Disconnected) {\n\t\t\t\t\tthis.transitionTo(VoiceConnectionState.Resuming);\n\t\t\t\t\tsetTimeout(() => this.connectWebSocket(), 1000);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.ws.on(\"error\", (error: Error) => {\n\t\t\tthis.emit(\"error\", error);\n\t\t});\n\t}\n\n\tprivate sendIdentify(): void {\n\t\tthis.wsSend(0, {\n\t\t\tserver_id: this.guildId,\n\t\t\tuser_id: \"\", // filled by adapter\n\t\t\tsession_id: this.sessionId,\n\t\t\ttoken: this.voiceToken,\n\t\t});\n\t}\n\n\tprivate handleGatewayMessage(op: number, d: Record<string, unknown>): void {\n\t\tswitch (op) {\n\t\t\tcase 2: // READY\n\t\t\t\tthis.handleReady(d as unknown as VoiceGatewayReady);\n\t\t\t\tbreak;\n\t\t\tcase 4: // SESSION_DESCRIPTION\n\t\t\t\tthis.handleSessionDescription(d);\n\t\t\t\tbreak;\n\t\t\tcase 5: // SPEAKING\n\t\t\t\tthis.handleSpeaking(d);\n\t\t\t\tbreak;\n\t\t\tcase 6: // HEARTBEAT_ACK\n\t\t\t\tthis.handleHeartbeatAck(d);\n\t\t\t\tbreak;\n\t\t\tcase 8: // HELLO\n\t\t\t\tthis.handleHello(d);\n\t\t\t\tbreak;\n\t\t\tcase 9: // RESUMED\n\t\t\t\tthis.transitionTo(VoiceConnectionState.Ready);\n\t\t\t\tbreak;\n\t\t\tcase 12: // CLIENT_CONNECT\n\t\t\t\tthis.handleClientConnect(d);\n\t\t\t\tbreak;\n\t\t\tcase 13: // CLIENT_DISCONNECT\n\t\t\t\tthis.handleClientDisconnect(d);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate handleReady(data: VoiceGatewayReady): void {\n\t\tthis.ssrc = data.ssrc;\n\t\tthis.remoteIp = data.ip;\n\t\tthis.remotePort = data.port;\n\n\t\tthis.encryptionMode = selectEncryptionMode(data.modes);\n\t\tthis.connectUdp();\n\t}\n\n\tprivate connectUdp(): void {\n\t\tthis.udpSocket?.close();\n\t\tthis.udpSocket = dgram.createSocket(\"udp4\");\n\n\t\tthis.udpSocket.on(\"message\", (msg: Buffer) => {\n\t\t\tthis.handleUdpMessage(msg);\n\t\t});\n\n\t\tthis.udpSocket.on(\"error\", (error: Error) => {\n\t\t\tthis.emit(\"error\", error);\n\t\t});\n\n\t\tthis.udpSocket.bind(0, () => {\n\t\t\tconst address = this.udpSocket?.address();\n\t\t\tif (address) {\n\t\t\t\tthis.localPort = address.port;\n\n\t\t\t\t// Configure socket for low-latency audio\n\t\t\t\tconst fd = (this.udpSocket as unknown as { _handle: { fd: number } })?._handle?.fd;\n\t\t\t\tif (typeof fd === \"number\" && fd >= 0) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconfigureSocketForAudio(fd);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Non-critical, continue without socket tuning\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.performIpDiscovery();\n\t\t});\n\t}\n\n\tprivate performIpDiscovery(): void {\n\t\tconst discoveryPacket = Buffer.alloc(IP_DISCOVERY_PACKET_SIZE);\n\t\tdiscoveryPacket.writeUInt16BE(0x1, 0); // Type: request\n\t\tdiscoveryPacket.writeUInt16BE(70, 2); // Length\n\t\tdiscoveryPacket.writeUInt32BE(this.ssrc, 4);\n\n\t\tthis.udpSocket?.send(\n\t\t\tdiscoveryPacket,\n\t\t\tthis.remotePort,\n\t\t\tthis.remoteIp,\n\t\t);\n\t}\n\n\tprivate handleUdpMessage(msg: Buffer): void {\n\t\tif (msg.length === IP_DISCOVERY_PACKET_SIZE) {\n\t\t\tthis.handleIpDiscoveryResponse(msg);\n\t\t\treturn;\n\t\t}\n\n\t\t// Incoming audio packet\n\t\tif (msg.length > 12 && this.secretKey) {\n\t\t\ttry {\n\t\t\t\tconst decrypted = decryptOpusPacket(msg, this.secretKey, this.encryptionMode);\n\t\t\t\tthis.receiver.handlePacket(msg, decrypted);\n\t\t\t} catch {\n\t\t\t\t// Ignore malformed packets\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handleIpDiscoveryResponse(response: Buffer): void {\n\t\t// Extract IP (null-terminated string starting at offset 8)\n\t\tconst ipEnd = response.indexOf(0, 8);\n\t\tthis.localIp = response.subarray(8, ipEnd > 8 ? ipEnd : 72).toString(\"utf8\").replace(/\\0/g, \"\");\n\t\tthis.localPort = response.readUInt16BE(72);\n\n\t\t// Send select protocol\n\t\tthis.wsSend(1, {\n\t\t\tprotocol: \"udp\",\n\t\t\tdata: {\n\t\t\t\taddress: this.localIp,\n\t\t\t\tport: this.localPort,\n\t\t\t\tmode: this.encryptionMode,\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate handleSessionDescription(d: Record<string, unknown>): void {\n\t\tconst keyArray = d[\"secret_key\"] as number[];\n\t\tthis.secretKey = Buffer.from(keyArray);\n\t\tthis.encryptionMode = (d[\"mode\"] as string) as EncryptionMode;\n\n\t\tthis.sequence = 0;\n\t\tthis.timestamp = 0;\n\t\tthis.nonceCounter = 0;\n\n\t\tthis.transitionTo(VoiceConnectionState.Ready);\n\t\tthis.emit(\"ready\");\n\n\t\t// Send speaking\n\t\tthis.setSpeaking(1);\n\t}\n\n\tprivate handleSpeaking(d: Record<string, unknown>): void {\n\t\tconst userId = d[\"user_id\"] as string;\n\t\tconst ssrc = d[\"ssrc\"] as number;\n\t\tthis.receiver.mapSsrcToUser(ssrc, userId);\n\t}\n\n\tprivate handleClientConnect(d: Record<string, unknown>): void {\n\t\tconst userId = d[\"user_id\"] as string;\n\t\tconst audioSsrc = d[\"audio_ssrc\"] as number;\n\t\tif (audioSsrc) {\n\t\t\tthis.receiver.mapSsrcToUser(audioSsrc, userId);\n\t\t}\n\t}\n\n\tprivate handleClientDisconnect(d: Record<string, unknown>): void {\n\t\tconst userId = d[\"user_id\"] as string;\n\t\tthis.receiver.removeUser(userId);\n\t}\n\n\tprivate handleHello(d: Record<string, unknown>): void {\n\t\tconst interval = d[\"heartbeat_interval\"] as number;\n\t\tthis.startHeartbeat(interval);\n\t}\n\n\tprivate handleHeartbeatAck(_d: Record<string, unknown>): void {\n\t\tthis.missedHeartbeats = 0;\n\t\tthis.lastHeartbeatAck = Date.now();\n\t}\n\n\tprivate startHeartbeat(intervalMs: number): void {\n\t\tthis.stopHeartbeat();\n\t\tthis.missedHeartbeats = 0;\n\n\t\tthis.heartbeatInterval = setInterval(() => {\n\t\t\tif (this.missedHeartbeats >= HEARTBEAT_MAX_MISSED) {\n\t\t\t\tthis.ws?.close(4009);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.heartbeatNonce = Date.now();\n\t\t\tthis.wsSend(3, this.heartbeatNonce);\n\t\t\tthis.missedHeartbeats++;\n\t\t}, intervalMs);\n\t}\n\n\tprivate stopHeartbeat(): void {\n\t\tif (this.heartbeatInterval) {\n\t\t\tclearInterval(this.heartbeatInterval);\n\t\t\tthis.heartbeatInterval = undefined;\n\t\t}\n\t}\n\n\t/**\n\t * Set the speaking flags.\n\t *\n\t * @example\n\t * ```ts\n\t * connection.setSpeaking(1); // speaking\n\t * ```\n\t */\n\tsetSpeaking(flags: number): void {\n\t\tthis.wsSend(5, {\n\t\t\tspeaking: flags,\n\t\t\tdelay: 0,\n\t\t\tssrc: this.ssrc,\n\t\t});\n\t}\n\n\tprivate wsSend(op: number, d: unknown): void {\n\t\tif (this.ws?.readyState === WebSocket.OPEN) {\n\t\t\tthis.ws.send(JSON.stringify({ op, d }));\n\t\t}\n\t}\n\n\tprivate transitionTo(newState: VoiceConnectionState): void {\n\t\tconst oldState = this._state;\n\t\tif (oldState === newState) {\n\t\t\treturn;\n\t\t}\n\t\tthis._state = newState;\n\t\tthis.emit(\"stateChange\", oldState, newState);\n\t}\n\n\tprivate cleanup(): void {\n\t\tthis.stopHeartbeat();\n\n\t\tif (this.audioThread) {\n\t\t\tthis.audioThread.stop();\n\t\t\tthis.audioThread = undefined;\n\t\t}\n\n\t\tif (this.ws) {\n\t\t\tthis.ws.removeAllListeners();\n\t\t\tthis.ws.close();\n\t\t\tthis.ws = undefined;\n\t\t}\n\n\t\tif (this.udpSocket) {\n\t\t\tthis.udpSocket.removeAllListeners();\n\t\t\tthis.udpSocket.close();\n\t\t\tthis.udpSocket = undefined;\n\t\t}\n\n\t\tthis.secretKey = undefined;\n\t}\n}\n","import { EventEmitter } from \"node:events\";\nimport { AudioPlayerState, type AudioPlayerEvents } from \"./types.js\";\nimport type { VoiceConnection } from \"./connection.js\";\nimport { HarmoniaVoiceError } from \"./errors.js\";\n\n/** Represents a playable audio source. */\nexport interface PlayableResource {\n\tread(): Buffer | null;\n\treadonly ended: boolean;\n\tdestroy(): void;\n}\n\n/**\n * Options for creating an audio player.\n *\n * @example\n * ```ts\n * const player = new AudioPlayer({ noSubscriber: 'pause' });\n * ```\n */\nexport interface AudioPlayerOptions {\n\treadonly noSubscriber?: \"pause\" | \"stop\" | \"play\";\n}\n\n/**\n * Plays audio resources and dispatches packets to voice connections.\n *\n * @example\n * ```ts\n * import { AudioPlayer } from '@harmonia/voice';\n *\n * const player = new AudioPlayer();\n * player.play(resource);\n *\n * player.on('idle', () => {\n * console.log('Playback finished');\n * });\n * ```\n */\nexport class AudioPlayer extends EventEmitter {\n\tprivate _state: AudioPlayerState = AudioPlayerState.Idle;\n\tprivate resource: PlayableResource | undefined;\n\tprivate connections: Set<VoiceConnection> = new Set();\n\tprivate playbackTimer: ReturnType<typeof setInterval> | undefined;\n\tprivate readonly noSubscriberBehavior: \"pause\" | \"stop\" | \"play\";\n\n\tconstructor(options: AudioPlayerOptions = {}) {\n\t\tsuper();\n\t\tthis.noSubscriberBehavior = options.noSubscriber ?? \"pause\";\n\t}\n\n\t/**\n\t * Current player state.\n\t *\n\t * @example\n\t * ```ts\n\t * if (player.state === AudioPlayerState.Playing) { ... }\n\t * ```\n\t */\n\tget state(): AudioPlayerState {\n\t\treturn this._state;\n\t}\n\n\t/**\n\t * Start playing an audio resource.\n\t *\n\t * @example\n\t * ```ts\n\t * player.play(audioResource);\n\t * ```\n\t */\n\tplay(resource: PlayableResource): void {\n\t\tthis.stopInternal();\n\t\tthis.resource = resource;\n\t\tthis.transitionTo(AudioPlayerState.Playing);\n\t\tthis.startPlaybackLoop();\n\t}\n\n\t/**\n\t * Pause playback.\n\t *\n\t * @example\n\t * ```ts\n\t * player.pause();\n\t * ```\n\t */\n\tpause(): void {\n\t\tif (this._state === AudioPlayerState.Playing) {\n\t\t\tthis.transitionTo(AudioPlayerState.Paused);\n\t\t}\n\t}\n\n\t/**\n\t * Resume playback.\n\t *\n\t * @example\n\t * ```ts\n\t * player.resume();\n\t * ```\n\t */\n\tresume(): void {\n\t\tif (\n\t\t\tthis._state === AudioPlayerState.Paused ||\n\t\t\tthis._state === AudioPlayerState.AutoPaused\n\t\t) {\n\t\t\tthis.transitionTo(AudioPlayerState.Playing);\n\t\t}\n\t}\n\n\t/**\n\t * Stop playback and release the resource.\n\t *\n\t * @example\n\t * ```ts\n\t * player.stop();\n\t * ```\n\t */\n\tstop(): void {\n\t\tthis.stopInternal();\n\t\tthis.transitionTo(AudioPlayerState.Idle);\n\t\tthis.emit(\"idle\");\n\t}\n\n\t/** @internal */\n\taddConnection(connection: VoiceConnection): void {\n\t\tthis.connections.add(connection);\n\t}\n\n\t/** @internal */\n\tremoveConnection(connection: VoiceConnection): void {\n\t\tthis.connections.delete(connection);\n\t}\n\n\tprivate startPlaybackLoop(): void {\n\t\tthis.playbackTimer = setInterval(() => {\n\t\t\tthis.processFrame();\n\t\t}, 20);\n\t}\n\n\tprivate processFrame(): void {\n\t\tif (this._state !== AudioPlayerState.Playing) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.resource) {\n\t\t\tthis.stop();\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.resource.ended) {\n\t\t\tthis.stopInternal();\n\t\t\tthis.transitionTo(AudioPlayerState.Idle);\n\t\t\tthis.emit(\"idle\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst packet = this.resource.read();\n\t\tif (!packet) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const connection of this.connections) {\n\t\t\tconnection.sendOpusPacket(packet);\n\t\t}\n\t}\n\n\tprivate stopInternal(): void {\n\t\tif (this.playbackTimer) {\n\t\t\tclearInterval(this.playbackTimer);\n\t\t\tthis.playbackTimer = undefined;\n\t\t}\n\t\tif (this.resource) {\n\t\t\tthis.resource.destroy();\n\t\t\tthis.resource = undefined;\n\t\t}\n\t}\n\n\tprivate transitionTo(newState: AudioPlayerState): void {\n\t\tconst oldState = this._state;\n\t\tif (oldState === newState) {\n\t\t\treturn;\n\t\t}\n\t\tthis._state = newState;\n\t\tthis.emit(\"stateChange\", oldState, newState);\n\t}\n}\n","import { VoiceConnection, type VoiceConnectionOptions } from \"./connection.js\";\nimport type { DiscordGatewayAdapterCreator } from \"./adapter.js\";\nimport { getVoiceConnection } from \"./store.js\";\n\n/**\n * Options for joining a voice channel.\n *\n * @example\n * ```ts\n * const connection = joinVoiceChannel({\n * guildId: '123',\n * channelId: '456',\n * adapterCreator: guild.voiceAdapterCreator,\n * });\n * ```\n */\nexport interface JoinVoiceChannelOptions {\n\treadonly guildId: string;\n\treadonly channelId: string;\n\treadonly selfDeaf?: boolean;\n\treadonly selfMute?: boolean;\n\treadonly adapterCreator: DiscordGatewayAdapterCreator;\n}\n\n/**\n * Join a Discord voice channel and return a VoiceConnection.\n *\n * @example\n * ```ts\n * import { joinVoiceChannel } from '@harmonia/voice';\n *\n * const connection = joinVoiceChannel({\n * guildId: interaction.guildId,\n * channelId: member.voice.channelId,\n * adapterCreator: guild.voiceAdapterCreator,\n * });\n * ```\n */\nexport function joinVoiceChannel(options: JoinVoiceChannelOptions): VoiceConnection {\n\tconst existing = getVoiceConnection(options.guildId);\n\tif (existing) {\n\t\texisting.destroy();\n\t}\n\n\treturn new VoiceConnection(options);\n}\n","import { Readable } from \"node:stream\";\nimport { OpusEncoder, OpusEncoderStream } from \"@harmonia-audio/codec\";\nimport type { PlayableResource } from \"./player.js\";\n\n/**\n * Options for creating an audio resource.\n *\n * @example\n * ```ts\n * const resource = createAudioResource('./song.pcm', {\n * inputType: 'pcm',\n * });\n * ```\n */\nexport interface AudioResourceOptions {\n\treadonly inputType?: \"opus\" | \"pcm\" | \"raw\";\n\treadonly inlineVolume?: boolean;\n\treadonly signal?: AbortSignal;\n}\n\n/**\n * Audio resource that can be played by an AudioPlayer.\n *\n * @example\n * ```ts\n * const resource = createAudioResource(readableStream, { inputType: 'pcm' });\n * player.play(resource);\n * ```\n */\nexport class AudioResource implements PlayableResource {\n\tprivate readonly stream: Readable;\n\tprivate readonly packets: Buffer[] = [];\n\tprivate _ended = false;\n\tprivate draining = false;\n\n\tconstructor(stream: Readable) {\n\t\tthis.stream = stream;\n\n\t\tstream.on(\"data\", (chunk: Buffer) => {\n\t\t\tthis.packets.push(chunk);\n\t\t});\n\n\t\tstream.on(\"end\", () => {\n\t\t\tthis._ended = true;\n\t\t});\n\n\t\tstream.on(\"error\", () => {\n\t\t\tthis._ended = true;\n\t\t});\n\t}\n\n\t/**\n\t * Read the next Opus packet.\n\t *\n\t * @example\n\t * ```ts\n\t * const packet = resource.read();\n\t * ```\n\t */\n\tread(): Buffer | null {\n\t\treturn this.packets.shift() ?? null;\n\t}\n\n\t/** Whether the resource has finished producing packets. */\n\tget ended(): boolean {\n\t\treturn this._ended && this.packets.length === 0;\n\t}\n\n\t/**\n\t * Destroy the resource and release underlying streams.\n\t *\n\t * @example\n\t * ```ts\n\t * resource.destroy();\n\t * ```\n\t */\n\tdestroy(): void {\n\t\tthis.stream.destroy();\n\t\tthis.packets.length = 0;\n\t\tthis._ended = true;\n\t}\n}\n\n/**\n * Create an AudioResource from various input types.\n *\n * @example\n * ```ts\n * import { createAudioResource } from '@harmonia/voice';\n * import { createReadStream } from 'fs';\n *\n * const resource = createAudioResource(createReadStream('./audio.pcm'), {\n * inputType: 'pcm',\n * });\n * ```\n */\nexport function createAudioResource(\n\tinput: Readable | string | Buffer,\n\toptions: AudioResourceOptions = {},\n): AudioResource {\n\tlet readable: Readable;\n\n\tif (typeof input === \"string\") {\n\t\tconst { createReadStream } = require(\"node:fs\") as typeof import(\"node:fs\");\n\t\treadable = createReadStream(input);\n\t} else if (Buffer.isBuffer(input)) {\n\t\treadable = Readable.from(input);\n\t} else {\n\t\treadable = input;\n\t}\n\n\tif (options.inputType === \"opus\") {\n\t\treturn new AudioResource(readable);\n\t}\n\n\t// PCM input: pipe through Opus encoder\n\tconst encoder = new OpusEncoderStream({\n\t\tsampleRate: 48000,\n\t\tchannels: 2,\n\t\tapplication: \"audio\",\n\t});\n\n\treadable.pipe(encoder);\n\n\tif (options.signal) {\n\t\toptions.signal.addEventListener(\n\t\t\t\"abort\",\n\t\t\t() => {\n\t\t\t\treadable.destroy();\n\t\t\t\tencoder.destroy();\n\t\t\t},\n\t\t\t{ once: true },\n\t\t);\n\t}\n\n\treturn new AudioResource(encoder);\n}\n"]}
1
+ {"version":3,"sources":["../src/encryption.ts","../src/errors.ts","../src/store.ts","../src/types.ts","../src/receiver.ts","../src/connection.ts","../src/player.ts","../src/join.ts","../src/resource.ts"],"names":["EncryptionMode","secretboxEncrypt","randomBytes","xchacha20Encrypt","secretboxDecrypt","xchacha20Decrypt","VoiceConnectionState","AudioPlayerState","Readable","EventEmitter","OpusDecoder","parseRtpHeader","buildRtpHeader","WebSocket","dgram","configureSocketForAudio","AudioThread","OpusEncoderStream"],"mappings":"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","file":"index.cjs","sourcesContent":["import {\n\tsecretboxEncrypt,\n\tsecretboxDecrypt,\n\txchacha20Encrypt,\n\txchacha20Decrypt,\n\trandomBytes,\n\tbuildRtpHeader,\n\tparseRtpHeader,\n\ttype RtpHeader as NativeRtpHeader,\n} from \"@harmonia-audio/native\";\n\nconst NONCE_SIZE_XSALSA20 = 24;\nconst NONCE_SIZE_LITE = 4;\n\n/**\n * Available encryption modes for voice connections.\n *\n * @example\n * ```ts\n * connection.setEncryptionMode(EncryptionMode.XSalsa20Poly1305);\n * ```\n */\nexport enum EncryptionMode {\n\tXSalsa20Poly1305 = \"xsalsa20_poly1305\",\n\tXSalsa20Poly1305Suffix = \"xsalsa20_poly1305_suffix\",\n\tXSalsa20Poly1305Lite = \"xsalsa20_poly1305_lite\",\n\tAeadAes256Gcm = \"aead_aes256_gcm\",\n\tAeadXChaCha20Poly1305 = \"aead_xchacha20_poly1305_rtpsize\",\n}\n\n/** Parsed RTP packet. */\nexport interface RtpPacket {\n\theader: NativeRtpHeader;\n\tpayload: Buffer;\n\tnonce: Buffer;\n}\n\nconst PREFERRED_MODES: EncryptionMode[] = [\n\tEncryptionMode.AeadXChaCha20Poly1305,\n\tEncryptionMode.AeadAes256Gcm,\n\tEncryptionMode.XSalsa20Poly1305Lite,\n\tEncryptionMode.XSalsa20Poly1305Suffix,\n\tEncryptionMode.XSalsa20Poly1305,\n];\n\n/**\n * Select the best available encryption mode from a list of supported modes.\n *\n * @example\n * ```ts\n * const mode = selectEncryptionMode(['xsalsa20_poly1305', 'xsalsa20_poly1305_suffix']);\n * ```\n */\nexport function selectEncryptionMode(\n\tavailable: readonly string[],\n): EncryptionMode {\n\tfor (const preferred of PREFERRED_MODES) {\n\t\tif (available.includes(preferred)) {\n\t\t\treturn preferred;\n\t\t}\n\t}\n\tconst first = available[0];\n\tif (first !== undefined) {\n\t\treturn first as EncryptionMode;\n\t}\n\treturn EncryptionMode.XSalsa20Poly1305;\n}\n\n/**\n * Encrypt an RTP payload.\n *\n * @example\n * ```ts\n * const encrypted = encryptOpusPacket(header, payload, key, mode, nonceCounter);\n * ```\n */\nexport function encryptOpusPacket(\n\trtpHeader: Buffer,\n\tpayload: Buffer,\n\tsecretKey: Buffer,\n\tmode: EncryptionMode,\n\tnonceCounter: number,\n): Buffer {\n\tswitch (mode) {\n\t\tcase EncryptionMode.XSalsa20Poly1305: {\n\t\t\tconst nonce = Buffer.alloc(NONCE_SIZE_XSALSA20);\n\t\t\trtpHeader.copy(nonce, 0, 0, 12);\n\t\t\tconst encrypted = secretboxEncrypt(payload, nonce, secretKey);\n\t\t\treturn Buffer.concat([rtpHeader, encrypted]);\n\t\t}\n\n\t\tcase EncryptionMode.XSalsa20Poly1305Suffix: {\n\t\t\tconst nonce = randomBytes(NONCE_SIZE_XSALSA20);\n\t\t\tconst encrypted = secretboxEncrypt(payload, nonce, secretKey);\n\t\t\treturn Buffer.concat([rtpHeader, encrypted, nonce]);\n\t\t}\n\n\t\tcase EncryptionMode.XSalsa20Poly1305Lite: {\n\t\t\tconst nonce = Buffer.alloc(NONCE_SIZE_XSALSA20);\n\t\t\tnonce.writeUInt32BE(nonceCounter, 0);\n\t\t\tconst encrypted = secretboxEncrypt(payload, nonce, secretKey);\n\t\t\tconst nonceAppend = Buffer.alloc(NONCE_SIZE_LITE);\n\t\t\tnonceAppend.writeUInt32BE(nonceCounter, 0);\n\t\t\treturn Buffer.concat([rtpHeader, encrypted, nonceAppend]);\n\t\t}\n\n\t\tcase EncryptionMode.AeadXChaCha20Poly1305: {\n\t\t\tconst nonce = Buffer.alloc(24);\n\t\t\tnonce.writeUInt32BE(nonceCounter, 0);\n\t\t\tconst encrypted = xchacha20Encrypt(payload, nonce, secretKey, rtpHeader);\n\t\t\tconst nonceAppend = Buffer.alloc(4);\n\t\t\tnonceAppend.writeUInt32BE(nonceCounter, 0);\n\t\t\treturn Buffer.concat([rtpHeader, encrypted, nonceAppend]);\n\t\t}\n\n\t\tdefault:\n\t\t\treturn Buffer.concat([rtpHeader, payload]);\n\t}\n}\n\n/**\n * Decrypt an RTP packet payload.\n *\n * @example\n * ```ts\n * const decrypted = decryptOpusPacket(packet, secretKey, mode);\n * ```\n */\nexport function decryptOpusPacket(\n\tpacket: Buffer,\n\tsecretKey: Buffer,\n\tmode: EncryptionMode,\n): Buffer {\n\tconst rtpHeader = packet.subarray(0, 12);\n\n\tswitch (mode) {\n\t\tcase EncryptionMode.XSalsa20Poly1305: {\n\t\t\tconst nonce = Buffer.alloc(NONCE_SIZE_XSALSA20);\n\t\t\trtpHeader.copy(nonce, 0, 0, 12);\n\t\t\tconst ciphertext = packet.subarray(12);\n\t\t\treturn secretboxDecrypt(ciphertext, nonce, secretKey);\n\t\t}\n\n\t\tcase EncryptionMode.XSalsa20Poly1305Suffix: {\n\t\t\tconst nonce = packet.subarray(packet.length - NONCE_SIZE_XSALSA20);\n\t\t\tconst ciphertext = packet.subarray(12, packet.length - NONCE_SIZE_XSALSA20);\n\t\t\treturn secretboxDecrypt(ciphertext, nonce, secretKey);\n\t\t}\n\n\t\tcase EncryptionMode.XSalsa20Poly1305Lite: {\n\t\t\tconst nonce = Buffer.alloc(NONCE_SIZE_XSALSA20);\n\t\t\tconst nonceFragment = packet.subarray(packet.length - NONCE_SIZE_LITE);\n\t\t\tnonceFragment.copy(nonce, 0, 0, NONCE_SIZE_LITE);\n\t\t\tconst ciphertext = packet.subarray(12, packet.length - NONCE_SIZE_LITE);\n\t\t\treturn secretboxDecrypt(ciphertext, nonce, secretKey);\n\t\t}\n\n\t\tcase EncryptionMode.AeadXChaCha20Poly1305: {\n\t\t\tconst nonce = Buffer.alloc(24);\n\t\t\tconst nonceFragment = packet.subarray(packet.length - 4);\n\t\t\tnonceFragment.copy(nonce, 0, 0, 4);\n\t\t\tconst ciphertext = packet.subarray(12, packet.length - 4);\n\t\t\treturn xchacha20Decrypt(ciphertext, nonce, secretKey, rtpHeader);\n\t\t}\n\n\t\tdefault: {\n\t\t\treturn packet.subarray(12);\n\t\t}\n\t}\n}\n","/**\n * Error class for all voice-related errors in harmonia.\n *\n * @example\n * ```ts\n * try {\n * await connection.connect();\n * } catch (error) {\n * if (error instanceof HarmoniaVoiceError) {\n * console.error(error.code);\n * }\n * }\n * ```\n */\nexport class HarmoniaVoiceError extends Error {\n\tpublic readonly code: string;\n\tpublic readonly context: Record<string, unknown>;\n\n\tconstructor(\n\t\tcode: string,\n\t\tmessage: string,\n\t\tcontext: Record<string, unknown> = {},\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"HarmoniaVoiceError\";\n\t\tthis.code = code;\n\t\tthis.context = context;\n\t}\n}\n","import type { VoiceConnection } from \"./connection.js\";\n\nconst connections = new Map<string, VoiceConnection>();\n\n/**\n * Get a voice connection by guild ID.\n *\n * @example\n * ```ts\n * const connection = getVoiceConnection('guild-id');\n * ```\n */\nexport function getVoiceConnection(guildId: string): VoiceConnection | undefined {\n\treturn connections.get(guildId);\n}\n\n/**\n * Get all active voice connections.\n *\n * @example\n * ```ts\n * const all = getVoiceConnections();\n * ```\n */\nexport function getVoiceConnections(): ReadonlyMap<string, VoiceConnection> {\n\treturn connections;\n}\n\n/** @internal */\nexport function setVoiceConnection(guildId: string, connection: VoiceConnection): void {\n\tconnections.set(guildId, connection);\n}\n\n/** @internal */\nexport function removeVoiceConnection(guildId: string): void {\n\tconnections.delete(guildId);\n}\n","import type { EventEmitter } from \"node:events\";\n\n/**\n * Voice connection states.\n *\n * @example\n * ```ts\n * if (connection.state === VoiceConnectionState.Ready) {\n * // connection is ready\n * }\n * ```\n */\nexport enum VoiceConnectionState {\n\tIdle = \"idle\",\n\tSignalling = \"signalling\",\n\tConnecting = \"connecting\",\n\tReady = \"ready\",\n\tResuming = \"resuming\",\n\tDisconnected = \"disconnected\",\n\tDestroyed = \"destroyed\",\n}\n\n/**\n * Audio player states.\n *\n * @example\n * ```ts\n * if (player.state === AudioPlayerState.Playing) {\n * player.pause();\n * }\n * ```\n */\nexport enum AudioPlayerState {\n\tIdle = \"idle\",\n\tBuffering = \"buffering\",\n\tPlaying = \"playing\",\n\tPaused = \"paused\",\n\tAutoPaused = \"autopaused\",\n}\n\n/**\n * Events emitted by a voice connection.\n *\n * @example\n * ```ts\n * connection.on('stateChange', (oldState, newState) => {\n * console.log(`${oldState} -> ${newState}`);\n * });\n * ```\n */\nexport interface VoiceConnectionEvents {\n\tstateChange: [oldState: VoiceConnectionState, newState: VoiceConnectionState];\n\tready: [];\n\tdisconnected: [];\n\tdestroyed: [];\n\terror: [error: Error];\n}\n\n/**\n * Events emitted by an audio player.\n *\n * @example\n * ```ts\n * player.on('stateChange', (oldState, newState) => {\n * console.log(`${oldState} -> ${newState}`);\n * });\n * ```\n */\nexport interface AudioPlayerEvents {\n\tstateChange: [oldState: AudioPlayerState, newState: AudioPlayerState];\n\tidle: [];\n\terror: [error: Error];\n}\n","import { EventEmitter } from \"node:events\";\nimport { Readable } from \"node:stream\";\nimport { OpusDecoder } from \"@harmonia-audio/codec\";\nimport { parseRtpHeader } from \"@harmonia-audio/native\";\nimport type { VoiceConnection } from \"./connection.js\";\n\n/**\n * Options for the audio receiver.\n *\n * @example\n * ```ts\n * const receiver = connection.getReceiver();\n * ```\n */\nexport interface AudioReceiverOptions {\n\treadonly autoDecodeOpus?: boolean;\n}\n\ninterface SsrcState {\n\tuserId: string | undefined;\n\tdecoder: OpusDecoder;\n\tstream: UserAudioStream;\n}\n\n/**\n * A readable stream of audio from a specific user.\n *\n * @example\n * ```ts\n * const stream = receiver.subscribe('user-id');\n * stream.on('data', (pcm) => { ... });\n * ```\n */\nexport class UserAudioStream extends Readable {\n\tpublic readonly userId: string;\n\n\tconstructor(userId: string) {\n\t\tsuper({ objectMode: false });\n\t\tthis.userId = userId;\n\t}\n\n\toverride _read(): void {\n\t\t// Data is pushed from the receiver\n\t}\n}\n\n/**\n * Receives and routes incoming audio from voice connections.\n *\n * @example\n * ```ts\n * const receiver = connection.getReceiver();\n * const stream = receiver.subscribe('user-id');\n *\n * stream.on('data', (pcm: Buffer) => {\n * // Process received audio\n * });\n * ```\n */\nexport class AudioReceiver extends EventEmitter {\n\tprivate readonly connection: VoiceConnection;\n\tprivate readonly ssrcMap = new Map<number, SsrcState>();\n\tprivate readonly userSsrcMap = new Map<string, number>();\n\tprivate readonly subscriptions = new Map<string, UserAudioStream>();\n\n\tconstructor(connection: VoiceConnection) {\n\t\tsuper();\n\t\tthis.connection = connection;\n\t}\n\n\t/**\n\t * Subscribe to audio from a specific user.\n\t *\n\t * @param userId - The Discord user ID to receive audio from\n\t * @returns A readable stream of PCM audio from that user\n\t *\n\t * @example\n\t * ```ts\n\t * const stream = receiver.subscribe('123456789');\n\t * stream.pipe(fileWriteStream);\n\t * ```\n\t */\n\tsubscribe(userId: string): UserAudioStream {\n\t\tconst existing = this.subscriptions.get(userId);\n\t\tif (existing) {\n\t\t\treturn existing;\n\t\t}\n\n\t\tconst stream = new UserAudioStream(userId);\n\t\tthis.subscriptions.set(userId, stream);\n\n\t\tstream.on(\"close\", () => {\n\t\t\tthis.subscriptions.delete(userId);\n\t\t});\n\n\t\treturn stream;\n\t}\n\n\t/**\n\t * Unsubscribe from a user's audio.\n\t *\n\t * @example\n\t * ```ts\n\t * receiver.unsubscribe('123456789');\n\t * ```\n\t */\n\tunsubscribe(userId: string): void {\n\t\tconst stream = this.subscriptions.get(userId);\n\t\tif (stream) {\n\t\t\tstream.destroy();\n\t\t\tthis.subscriptions.delete(userId);\n\t\t}\n\t}\n\n\t/** @internal */\n\tmapSsrcToUser(ssrc: number, userId: string): void {\n\t\tlet state = this.ssrcMap.get(ssrc);\n\t\tif (!state) {\n\t\t\tstate = {\n\t\t\t\tuserId,\n\t\t\t\tdecoder: new OpusDecoder({ sampleRate: 48000, channels: 2 }),\n\t\t\t\tstream: new UserAudioStream(userId),\n\t\t\t};\n\t\t\tthis.ssrcMap.set(ssrc, state);\n\t\t} else {\n\t\t\tstate.userId = userId;\n\t\t}\n\t\tthis.userSsrcMap.set(userId, ssrc);\n\t\tthis.emit(\"userConnected\", userId, ssrc);\n\t}\n\n\t/** @internal */\n\tremoveUser(userId: string): void {\n\t\tconst ssrc = this.userSsrcMap.get(userId);\n\t\tif (ssrc !== undefined) {\n\t\t\tconst state = this.ssrcMap.get(ssrc);\n\t\t\tif (state) {\n\t\t\t\tstate.stream.destroy();\n\t\t\t\tthis.ssrcMap.delete(ssrc);\n\t\t\t}\n\t\t\tthis.userSsrcMap.delete(userId);\n\t\t}\n\t\tthis.subscriptions.get(userId)?.destroy();\n\t\tthis.subscriptions.delete(userId);\n\t\tthis.emit(\"userDisconnected\", userId);\n\t}\n\n\t/** @internal */\n\thandlePacket(rawPacket: Buffer, decryptedPayload: Buffer): void {\n\t\ttry {\n\t\t\tconst header = parseRtpHeader(rawPacket);\n\t\t\tconst state = this.ssrcMap.get(header.ssrc);\n\n\t\t\tif (!state?.userId) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst pcm = state.decoder.decode(decryptedPayload);\n\n\t\t\tconst subscription = this.subscriptions.get(state.userId);\n\t\t\tif (subscription && !subscription.destroyed) {\n\t\t\t\tsubscription.push(pcm);\n\t\t\t}\n\n\t\t\tthis.emit(\"audio\", state.userId, pcm, header);\n\t\t} catch {\n\t\t\t// Silently drop malformed packets\n\t\t}\n\t}\n\n\t/**\n\t * Destroy all streams and clean up.\n\t *\n\t * @example\n\t * ```ts\n\t * receiver.destroy();\n\t * ```\n\t */\n\tdestroy(): this {\n\t\tfor (const [, stream] of this.subscriptions) {\n\t\t\tstream.destroy();\n\t\t}\n\t\tthis.subscriptions.clear();\n\t\tthis.ssrcMap.clear();\n\t\tthis.userSsrcMap.clear();\n\t\treturn this;\n\t}\n}\n","import { EventEmitter } from \"node:events\";\nimport dgram from \"node:dgram\";\nimport WebSocket from \"ws\";\nimport {\n\tbuildRtpHeader,\n\tconfigureSocketForAudio,\n\tAudioThread as NativeAudioThread,\n\tAudioRingBuffer,\n} from \"@harmonia-audio/native\";\nimport { OpusEncoder } from \"@harmonia-audio/codec\";\nimport type {\n\tDiscordGatewayAdapter,\n\tDiscordGatewayAdapterCreator,\n\tVoiceServerUpdateData,\n\tVoiceStateUpdateData,\n} from \"./adapter.js\";\nimport {\n\tencryptOpusPacket,\n\tEncryptionMode,\n\tselectEncryptionMode,\n\tdecryptOpusPacket,\n} from \"./encryption.js\";\nimport { HarmoniaVoiceError } from \"./errors.js\";\nimport { removeVoiceConnection, setVoiceConnection } from \"./store.js\";\nimport { VoiceConnectionState, type VoiceConnectionEvents } from \"./types.js\";\nimport type { AudioPlayer } from \"./player.js\";\nimport { AudioReceiver } from \"./receiver.js\";\n\nconst VOICE_GATEWAY_VERSION = 8;\nconst HEARTBEAT_MAX_MISSED = 3;\nconst IP_DISCOVERY_PACKET_SIZE = 74;\n\n/**\n * Options for creating a voice connection.\n *\n * @example\n * ```ts\n * const options: VoiceConnectionOptions = {\n * guildId: '123456789',\n * channelId: '987654321',\n * selfDeaf: false,\n * selfMute: false,\n * };\n * ```\n */\nexport interface VoiceConnectionOptions {\n\treadonly guildId: string;\n\treadonly channelId: string;\n\treadonly selfDeaf?: boolean;\n\treadonly selfMute?: boolean;\n\treadonly adapterCreator: DiscordGatewayAdapterCreator;\n}\n\ninterface VoiceGatewayReady {\n\tssrc: number;\n\tip: string;\n\tport: number;\n\tmodes: string[];\n}\n\n/**\n * Manages a voice connection to a Discord voice channel.\n *\n * @example\n * ```ts\n * import { VoiceConnection } from '@harmonia/voice';\n *\n * const connection = new VoiceConnection({\n * guildId: '123',\n * channelId: '456',\n * adapterCreator: guild.voiceAdapterCreator,\n * });\n *\n * connection.on('ready', () => {\n * console.log('Connected to voice!');\n * });\n * ```\n */\nexport class VoiceConnection extends EventEmitter {\n\tprivate _state: VoiceConnectionState = VoiceConnectionState.Idle;\n\tprivate readonly guildId: string;\n\tprivate channelId: string;\n\tprivate readonly selfDeaf: boolean;\n\tprivate readonly selfMute: boolean;\n\tprivate adapter: DiscordGatewayAdapter | undefined;\n\n\tprivate sessionId: string | undefined;\n\tprivate voiceToken: string | undefined;\n\tprivate endpoint: string | undefined;\n\n\tprivate ws: WebSocket | undefined;\n\tprivate udpSocket: dgram.Socket | undefined;\n\tprivate ssrc = 0;\n\tprivate remoteIp = \"\";\n\tprivate remotePort = 0;\n\tprivate localIp = \"\";\n\tprivate localPort = 0;\n\tprivate secretKey: Buffer | undefined;\n\tprivate encryptionMode: EncryptionMode = EncryptionMode.XSalsa20Poly1305;\n\tprivate sequence = 0;\n\tprivate timestamp = 0;\n\tprivate nonceCounter = 0;\n\n\tprivate heartbeatInterval: ReturnType<typeof setInterval> | undefined;\n\tprivate heartbeatNonce = 0;\n\tprivate missedHeartbeats = 0;\n\tprivate lastHeartbeatAck = 0;\n\n\tprivate subscribedPlayer: AudioPlayer | undefined;\n\tprivate audioThread: NativeAudioThread | undefined;\n\tprivate ringBuffer: AudioRingBuffer | undefined;\n\n\tprivate readonly receiver: AudioReceiver;\n\n\tprivate voiceStateResolve: (() => void) | undefined;\n\tprivate voiceServerResolve: (() => void) | undefined;\n\n\tconstructor(options: VoiceConnectionOptions) {\n\t\tsuper();\n\t\tthis.guildId = options.guildId;\n\t\tthis.channelId = options.channelId;\n\t\tthis.selfDeaf = options.selfDeaf ?? false;\n\t\tthis.selfMute = options.selfMute ?? false;\n\t\tthis.receiver = new AudioReceiver(this);\n\n\t\tthis.adapter = options.adapterCreator({\n\t\t\tonVoiceStateUpdate: (data) => this.handleVoiceStateUpdate(data),\n\t\t\tonVoiceServerUpdate: (data) => this.handleVoiceServerUpdate(data),\n\t\t\tdestroy: () => this.destroy(),\n\t\t});\n\n\t\tsetVoiceConnection(this.guildId, this);\n\t\tthis.sendVoiceStateUpdate();\n\t}\n\n\t/**\n\t * Current connection state.\n\t *\n\t * @example\n\t * ```ts\n\t * if (connection.state === VoiceConnectionState.Ready) { ... }\n\t * ```\n\t */\n\tget state(): VoiceConnectionState {\n\t\treturn this._state;\n\t}\n\n\t/**\n\t * Get the audio receiver for this connection.\n\t *\n\t * @example\n\t * ```ts\n\t * const receiver = connection.getReceiver();\n\t * ```\n\t */\n\tgetReceiver(): AudioReceiver {\n\t\treturn this.receiver;\n\t}\n\n\t/**\n\t * Subscribe an audio player to this connection.\n\t *\n\t * @example\n\t * ```ts\n\t * connection.subscribe(player);\n\t * ```\n\t */\n\tsubscribe(player: AudioPlayer): void {\n\t\tif (this.subscribedPlayer) {\n\t\t\tthis.subscribedPlayer.removeConnection(this);\n\t\t}\n\t\tthis.subscribedPlayer = player;\n\t\tplayer.addConnection(this);\n\t}\n\n\t/**\n\t * Unsubscribe the current audio player.\n\t *\n\t * @example\n\t * ```ts\n\t * connection.unsubscribe();\n\t * ```\n\t */\n\tunsubscribe(): void {\n\t\tif (this.subscribedPlayer) {\n\t\t\tthis.subscribedPlayer.removeConnection(this);\n\t\t}\n\t\tthis.subscribedPlayer = undefined;\n\t}\n\n\t/**\n\t * Destroy the connection and clean up all resources.\n\t *\n\t * @example\n\t * ```ts\n\t * connection.destroy();\n\t * ```\n\t */\n\tdestroy(): void {\n\t\tif (this._state === VoiceConnectionState.Destroyed) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.transitionTo(VoiceConnectionState.Destroyed);\n\t\tthis.cleanup();\n\t\tremoveVoiceConnection(this.guildId);\n\n\t\tif (this.adapter) {\n\t\t\tthis.adapter.sendPayload({\n\t\t\t\top: 4,\n\t\t\t\td: {\n\t\t\t\t\tguild_id: this.guildId,\n\t\t\t\t\tchannel_id: null,\n\t\t\t\t\tself_mute: false,\n\t\t\t\t\tself_deaf: false,\n\t\t\t\t},\n\t\t\t});\n\t\t\tthis.adapter.destroy();\n\t\t\tthis.adapter = undefined;\n\t\t}\n\n\t\tthis.emit(\"destroyed\");\n\t}\n\n\t/**\n\t * Send an Opus packet through the voice connection.\n\t *\n\t * @example\n\t * ```ts\n\t * connection.sendOpusPacket(opusBuffer);\n\t * ```\n\t */\n\tsendOpusPacket(opusPacket: Buffer): void {\n\t\tif (this._state !== VoiceConnectionState.Ready) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.secretKey || !this.udpSocket) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst header = buildRtpHeader(this.sequence, this.timestamp, this.ssrc, 0x78);\n\n\t\tconst encrypted = encryptOpusPacket(\n\t\t\theader,\n\t\t\topusPacket,\n\t\t\tthis.secretKey,\n\t\t\tthis.encryptionMode,\n\t\t\tthis.nonceCounter,\n\t\t);\n\n\t\tthis.udpSocket.send(encrypted, this.remotePort, this.remoteIp);\n\n\t\tthis.sequence = (this.sequence + 1) & 0xFFFF;\n\t\tthis.timestamp = (this.timestamp + 960) >>> 0;\n\t\tthis.nonceCounter = (this.nonceCounter + 1) >>> 0;\n\t}\n\n\tprivate sendVoiceStateUpdate(): void {\n\t\tthis.transitionTo(VoiceConnectionState.Signalling);\n\n\t\tthis.adapter?.sendPayload({\n\t\t\top: 4,\n\t\t\td: {\n\t\t\t\tguild_id: this.guildId,\n\t\t\t\tchannel_id: this.channelId,\n\t\t\t\tself_mute: this.selfMute,\n\t\t\t\tself_deaf: this.selfDeaf,\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate handleVoiceStateUpdate(data: VoiceStateUpdateData): void {\n\t\tthis.sessionId = data.session_id;\n\t\tif (this.voiceStateResolve) {\n\t\t\tthis.voiceStateResolve();\n\t\t\tthis.voiceStateResolve = undefined;\n\t\t}\n\t\tthis.tryConnect();\n\t}\n\n\tprivate handleVoiceServerUpdate(data: VoiceServerUpdateData): void {\n\t\tthis.voiceToken = data.token;\n\t\tthis.endpoint = data.endpoint ?? undefined;\n\t\tif (this.voiceServerResolve) {\n\t\t\tthis.voiceServerResolve();\n\t\t\tthis.voiceServerResolve = undefined;\n\t\t}\n\t\tthis.tryConnect();\n\t}\n\n\tprivate tryConnect(): void {\n\t\tif (!this.sessionId || !this.voiceToken || !this.endpoint) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.transitionTo(VoiceConnectionState.Connecting);\n\t\tthis.connectWebSocket();\n\t}\n\n\tprivate connectWebSocket(): void {\n\t\tconst wsUrl = `wss://${this.endpoint}/?v=${VOICE_GATEWAY_VERSION}`;\n\n\t\tthis.ws?.close();\n\t\tthis.ws = new WebSocket(wsUrl);\n\n\t\tthis.ws.on(\"open\", () => {\n\t\t\tthis.sendIdentify();\n\t\t});\n\n\t\tthis.ws.on(\"message\", (raw: WebSocket.Data) => {\n\t\t\tconst data = JSON.parse(raw.toString()) as {\n\t\t\t\top: number;\n\t\t\t\td: Record<string, unknown>;\n\t\t\t};\n\t\t\tthis.handleGatewayMessage(data.op, data.d);\n\t\t});\n\n\t\tthis.ws.on(\"close\", (code: number) => {\n\t\t\tthis.stopHeartbeat();\n\t\t\tif (this._state !== VoiceConnectionState.Destroyed) {\n\t\t\t\tif (code === 4014 || code === 4006) {\n\t\t\t\t\tthis.transitionTo(VoiceConnectionState.Disconnected);\n\t\t\t\t\tthis.emit(\"disconnected\");\n\t\t\t\t} else if (this._state !== VoiceConnectionState.Disconnected) {\n\t\t\t\t\tthis.transitionTo(VoiceConnectionState.Resuming);\n\t\t\t\t\tsetTimeout(() => this.connectWebSocket(), 1000);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.ws.on(\"error\", (error: Error) => {\n\t\t\tthis.emit(\"error\", error);\n\t\t});\n\t}\n\n\tprivate sendIdentify(): void {\n\t\tthis.wsSend(0, {\n\t\t\tserver_id: this.guildId,\n\t\t\tuser_id: \"\", // filled by adapter\n\t\t\tsession_id: this.sessionId,\n\t\t\ttoken: this.voiceToken,\n\t\t});\n\t}\n\n\tprivate handleGatewayMessage(op: number, d: Record<string, unknown>): void {\n\t\tswitch (op) {\n\t\t\tcase 2: // READY\n\t\t\t\tthis.handleReady(d as unknown as VoiceGatewayReady);\n\t\t\t\tbreak;\n\t\t\tcase 4: // SESSION_DESCRIPTION\n\t\t\t\tthis.handleSessionDescription(d);\n\t\t\t\tbreak;\n\t\t\tcase 5: // SPEAKING\n\t\t\t\tthis.handleSpeaking(d);\n\t\t\t\tbreak;\n\t\t\tcase 6: // HEARTBEAT_ACK\n\t\t\t\tthis.handleHeartbeatAck(d);\n\t\t\t\tbreak;\n\t\t\tcase 8: // HELLO\n\t\t\t\tthis.handleHello(d);\n\t\t\t\tbreak;\n\t\t\tcase 9: // RESUMED\n\t\t\t\tthis.transitionTo(VoiceConnectionState.Ready);\n\t\t\t\tbreak;\n\t\t\tcase 12: // CLIENT_CONNECT\n\t\t\t\tthis.handleClientConnect(d);\n\t\t\t\tbreak;\n\t\t\tcase 13: // CLIENT_DISCONNECT\n\t\t\t\tthis.handleClientDisconnect(d);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate handleReady(data: VoiceGatewayReady): void {\n\t\tthis.ssrc = data.ssrc;\n\t\tthis.remoteIp = data.ip;\n\t\tthis.remotePort = data.port;\n\n\t\tthis.encryptionMode = selectEncryptionMode(data.modes);\n\t\tthis.connectUdp();\n\t}\n\n\tprivate connectUdp(): void {\n\t\tthis.udpSocket?.close();\n\t\tthis.udpSocket = dgram.createSocket(\"udp4\");\n\n\t\tthis.udpSocket.on(\"message\", (msg: Buffer) => {\n\t\t\tthis.handleUdpMessage(msg);\n\t\t});\n\n\t\tthis.udpSocket.on(\"error\", (error: Error) => {\n\t\t\tthis.emit(\"error\", error);\n\t\t});\n\n\t\tthis.udpSocket.bind(0, () => {\n\t\t\tconst address = this.udpSocket?.address();\n\t\t\tif (address) {\n\t\t\t\tthis.localPort = address.port;\n\n\t\t\t\t// Configure socket for low-latency audio\n\t\t\t\tconst fd = (this.udpSocket as unknown as { _handle: { fd: number } })?._handle?.fd;\n\t\t\t\tif (typeof fd === \"number\" && fd >= 0) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconfigureSocketForAudio(fd);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Non-critical, continue without socket tuning\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.performIpDiscovery();\n\t\t});\n\t}\n\n\tprivate performIpDiscovery(): void {\n\t\tconst discoveryPacket = Buffer.alloc(IP_DISCOVERY_PACKET_SIZE);\n\t\tdiscoveryPacket.writeUInt16BE(0x1, 0); // Type: request\n\t\tdiscoveryPacket.writeUInt16BE(70, 2); // Length\n\t\tdiscoveryPacket.writeUInt32BE(this.ssrc, 4);\n\n\t\tthis.udpSocket?.send(\n\t\t\tdiscoveryPacket,\n\t\t\tthis.remotePort,\n\t\t\tthis.remoteIp,\n\t\t);\n\t}\n\n\tprivate handleUdpMessage(msg: Buffer): void {\n\t\tif (msg.length === IP_DISCOVERY_PACKET_SIZE) {\n\t\t\tthis.handleIpDiscoveryResponse(msg);\n\t\t\treturn;\n\t\t}\n\n\t\t// Incoming audio packet\n\t\tif (msg.length > 12 && this.secretKey) {\n\t\t\ttry {\n\t\t\t\tconst decrypted = decryptOpusPacket(msg, this.secretKey, this.encryptionMode);\n\t\t\t\tthis.receiver.handlePacket(msg, decrypted);\n\t\t\t} catch {\n\t\t\t\t// Ignore malformed packets\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handleIpDiscoveryResponse(response: Buffer): void {\n\t\t// Extract IP (null-terminated string starting at offset 8)\n\t\tconst ipEnd = response.indexOf(0, 8);\n\t\tthis.localIp = response.subarray(8, ipEnd > 8 ? ipEnd : 72).toString(\"utf8\").replace(/\\0/g, \"\");\n\t\tthis.localPort = response.readUInt16BE(72);\n\n\t\t// Send select protocol\n\t\tthis.wsSend(1, {\n\t\t\tprotocol: \"udp\",\n\t\t\tdata: {\n\t\t\t\taddress: this.localIp,\n\t\t\t\tport: this.localPort,\n\t\t\t\tmode: this.encryptionMode,\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate handleSessionDescription(d: Record<string, unknown>): void {\n\t\tconst keyArray = d[\"secret_key\"] as number[];\n\t\tthis.secretKey = Buffer.from(keyArray);\n\t\tthis.encryptionMode = (d[\"mode\"] as string) as EncryptionMode;\n\n\t\tthis.sequence = 0;\n\t\tthis.timestamp = 0;\n\t\tthis.nonceCounter = 0;\n\n\t\tthis.transitionTo(VoiceConnectionState.Ready);\n\t\tthis.emit(\"ready\");\n\n\t\t// Send speaking\n\t\tthis.setSpeaking(1);\n\t}\n\n\tprivate handleSpeaking(d: Record<string, unknown>): void {\n\t\tconst userId = d[\"user_id\"] as string;\n\t\tconst ssrc = d[\"ssrc\"] as number;\n\t\tthis.receiver.mapSsrcToUser(ssrc, userId);\n\t}\n\n\tprivate handleClientConnect(d: Record<string, unknown>): void {\n\t\tconst userId = d[\"user_id\"] as string;\n\t\tconst audioSsrc = d[\"audio_ssrc\"] as number;\n\t\tif (audioSsrc) {\n\t\t\tthis.receiver.mapSsrcToUser(audioSsrc, userId);\n\t\t}\n\t}\n\n\tprivate handleClientDisconnect(d: Record<string, unknown>): void {\n\t\tconst userId = d[\"user_id\"] as string;\n\t\tthis.receiver.removeUser(userId);\n\t}\n\n\tprivate handleHello(d: Record<string, unknown>): void {\n\t\tconst interval = d[\"heartbeat_interval\"] as number;\n\t\tthis.startHeartbeat(interval);\n\t}\n\n\tprivate handleHeartbeatAck(_d: Record<string, unknown>): void {\n\t\tthis.missedHeartbeats = 0;\n\t\tthis.lastHeartbeatAck = Date.now();\n\t}\n\n\tprivate startHeartbeat(intervalMs: number): void {\n\t\tthis.stopHeartbeat();\n\t\tthis.missedHeartbeats = 0;\n\n\t\tthis.heartbeatInterval = setInterval(() => {\n\t\t\tif (this.missedHeartbeats >= HEARTBEAT_MAX_MISSED) {\n\t\t\t\tthis.ws?.close(4009);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.heartbeatNonce = Date.now();\n\t\t\tthis.wsSend(3, this.heartbeatNonce);\n\t\t\tthis.missedHeartbeats++;\n\t\t}, intervalMs);\n\t}\n\n\tprivate stopHeartbeat(): void {\n\t\tif (this.heartbeatInterval) {\n\t\t\tclearInterval(this.heartbeatInterval);\n\t\t\tthis.heartbeatInterval = undefined;\n\t\t}\n\t}\n\n\t/**\n\t * Set the speaking flags.\n\t *\n\t * @example\n\t * ```ts\n\t * connection.setSpeaking(1); // speaking\n\t * ```\n\t */\n\tsetSpeaking(flags: number): void {\n\t\tthis.wsSend(5, {\n\t\t\tspeaking: flags,\n\t\t\tdelay: 0,\n\t\t\tssrc: this.ssrc,\n\t\t});\n\t}\n\n\tprivate wsSend(op: number, d: unknown): void {\n\t\tif (this.ws?.readyState === WebSocket.OPEN) {\n\t\t\tthis.ws.send(JSON.stringify({ op, d }));\n\t\t}\n\t}\n\n\tprivate transitionTo(newState: VoiceConnectionState): void {\n\t\tconst oldState = this._state;\n\t\tif (oldState === newState) {\n\t\t\treturn;\n\t\t}\n\t\tthis._state = newState;\n\t\tthis.emit(\"stateChange\", oldState, newState);\n\t}\n\n\tprivate cleanup(): void {\n\t\tthis.stopHeartbeat();\n\n\t\tif (this.audioThread) {\n\t\t\tthis.audioThread.stop();\n\t\t\tthis.audioThread = undefined;\n\t\t}\n\n\t\tif (this.ws) {\n\t\t\tthis.ws.removeAllListeners();\n\t\t\tthis.ws.close();\n\t\t\tthis.ws = undefined;\n\t\t}\n\n\t\tif (this.udpSocket) {\n\t\t\tthis.udpSocket.removeAllListeners();\n\t\t\tthis.udpSocket.close();\n\t\t\tthis.udpSocket = undefined;\n\t\t}\n\n\t\tthis.secretKey = undefined;\n\t}\n}\n","import { EventEmitter } from \"node:events\";\nimport { AudioPlayerState, type AudioPlayerEvents } from \"./types.js\";\nimport type { VoiceConnection } from \"./connection.js\";\nimport { AudioThread } from \"@harmonia-audio/native\";\nimport { HarmoniaVoiceError } from \"./errors.js\";\n\n/** Represents a playable audio source. */\nexport interface PlayableResource {\n\tread(): Buffer | null;\n\treadonly ended: boolean;\n\tdestroy(): void;\n}\n\n/**\n * Options for creating an audio player.\n *\n * @example\n * ```ts\n * const player = new AudioPlayer({ noSubscriber: 'pause' });\n * ```\n */\nexport interface AudioPlayerOptions {\n\treadonly noSubscriber?: \"pause\" | \"stop\" | \"play\";\n}\n\n/**\n * Plays audio resources and dispatches packets to voice connections.\n *\n * @example\n * ```ts\n * import { AudioPlayer } from '@harmonia/voice';\n *\n * const player = new AudioPlayer();\n * player.play(resource);\n *\n * player.on('idle', () => {\n * console.log('Playback finished');\n * });\n * ```\n */\nexport class AudioPlayer extends EventEmitter {\n\tprivate _state: AudioPlayerState = AudioPlayerState.Idle;\n\tprivate resource: PlayableResource | undefined;\n\tprivate connections: Set<VoiceConnection> = new Set();\n\tprivate audioThread: AudioThread | undefined;\n\tprivate readonly noSubscriberBehavior: \"pause\" | \"stop\" | \"play\";\n\n\tconstructor(options: AudioPlayerOptions = {}) {\n\t\tsuper();\n\t\tthis.noSubscriberBehavior = options.noSubscriber ?? \"pause\";\n\t}\n\n\t/**\n\t * Current player state.\n\t *\n\t * @example\n\t * ```ts\n\t * if (player.state === AudioPlayerState.Playing) { ... }\n\t * ```\n\t */\n\tget state(): AudioPlayerState {\n\t\treturn this._state;\n\t}\n\n\t/**\n\t * Start playing an audio resource.\n\t *\n\t * @example\n\t * ```ts\n\t * player.play(audioResource);\n\t * ```\n\t */\n\tplay(resource: PlayableResource): void {\n\t\tthis.stopInternal();\n\t\tthis.resource = resource;\n\t\tthis.transitionTo(AudioPlayerState.Playing);\n\t\tthis.startPlaybackLoop();\n\t}\n\n\t/**\n\t * Pause playback.\n\t *\n\t * @example\n\t * ```ts\n\t * player.pause();\n\t * ```\n\t */\n\tpause(): void {\n\t\tif (this._state === AudioPlayerState.Playing) {\n\t\t\tthis.transitionTo(AudioPlayerState.Paused);\n\t\t}\n\t}\n\n\t/**\n\t * Resume playback.\n\t *\n\t * @example\n\t * ```ts\n\t * player.resume();\n\t * ```\n\t */\n\tresume(): void {\n\t\tif (\n\t\t\tthis._state === AudioPlayerState.Paused ||\n\t\t\tthis._state === AudioPlayerState.AutoPaused\n\t\t) {\n\t\t\tthis.transitionTo(AudioPlayerState.Playing);\n\t\t}\n\t}\n\n\t/**\n\t * Stop playback and release the resource.\n\t *\n\t * @example\n\t * ```ts\n\t * player.stop();\n\t * ```\n\t */\n\tstop(): void {\n\t\tthis.stopInternal();\n\t\tthis.transitionTo(AudioPlayerState.Idle);\n\t\tthis.emit(\"idle\");\n\t}\n\n\t/** @internal */\n\taddConnection(connection: VoiceConnection): void {\n\t\tthis.connections.add(connection);\n\t}\n\n\t/** @internal */\n\tremoveConnection(connection: VoiceConnection): void {\n\t\tthis.connections.delete(connection);\n\t}\n\n\tprivate startPlaybackLoop(): void {\n\t\tif (!this.audioThread) {\n\t\t\tthis.audioThread = new AudioThread();\n\t\t}\n\t\t\n\t\tthis.audioThread.start(() => {\n\t\t\tthis.processFrame();\n\t\t});\n\t}\n\n\tprivate processFrame(): void {\n\t\tif (this._state !== AudioPlayerState.Playing) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.resource) {\n\t\t\tthis.stop();\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.resource.ended) {\n\t\t\tthis.stopInternal();\n\t\t\tthis.transitionTo(AudioPlayerState.Idle);\n\t\t\tthis.emit(\"idle\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst packet = this.resource.read();\n\t\tif (!packet) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const connection of this.connections) {\n\t\t\tconnection.sendOpusPacket(packet);\n\t\t}\n\t}\n\n\tprivate stopInternal(): void {\n\t\tif (this.audioThread) {\n\t\t\tthis.audioThread.stop();\n\t\t\tthis.audioThread = undefined;\n\t\t}\n\t\tif (this.resource) {\n\t\t\tthis.resource.destroy();\n\t\t\tthis.resource = undefined;\n\t\t}\n\t}\n\n\tprivate transitionTo(newState: AudioPlayerState): void {\n\t\tconst oldState = this._state;\n\t\tif (oldState === newState) {\n\t\t\treturn;\n\t\t}\n\t\tthis._state = newState;\n\t\tthis.emit(\"stateChange\", oldState, newState);\n\t}\n}\n","import { VoiceConnection, type VoiceConnectionOptions } from \"./connection.js\";\nimport type { DiscordGatewayAdapterCreator } from \"./adapter.js\";\nimport { getVoiceConnection } from \"./store.js\";\n\n/**\n * Options for joining a voice channel.\n *\n * @example\n * ```ts\n * const connection = joinVoiceChannel({\n * guildId: '123',\n * channelId: '456',\n * adapterCreator: guild.voiceAdapterCreator,\n * });\n * ```\n */\nexport interface JoinVoiceChannelOptions {\n\treadonly guildId: string;\n\treadonly channelId: string;\n\treadonly selfDeaf?: boolean;\n\treadonly selfMute?: boolean;\n\treadonly adapterCreator: DiscordGatewayAdapterCreator;\n}\n\n/**\n * Join a Discord voice channel and return a VoiceConnection.\n *\n * @example\n * ```ts\n * import { joinVoiceChannel } from '@harmonia/voice';\n *\n * const connection = joinVoiceChannel({\n * guildId: interaction.guildId,\n * channelId: member.voice.channelId,\n * adapterCreator: guild.voiceAdapterCreator,\n * });\n * ```\n */\nexport function joinVoiceChannel(options: JoinVoiceChannelOptions): VoiceConnection {\n\tconst existing = getVoiceConnection(options.guildId);\n\tif (existing) {\n\t\texisting.destroy();\n\t}\n\n\treturn new VoiceConnection(options);\n}\n","import { Readable } from \"node:stream\";\nimport { OpusEncoder, OpusEncoderStream } from \"@harmonia-audio/codec\";\nimport type { PlayableResource } from \"./player.js\";\n\n/**\n * Options for creating an audio resource.\n *\n * @example\n * ```ts\n * const resource = createAudioResource('./song.pcm', {\n * inputType: 'pcm',\n * });\n * ```\n */\nexport interface AudioResourceOptions {\n\treadonly inputType?: \"opus\" | \"pcm\" | \"raw\";\n\treadonly inlineVolume?: boolean;\n\treadonly signal?: AbortSignal;\n}\n\n/**\n * Audio resource that can be played by an AudioPlayer.\n *\n * @example\n * ```ts\n * const resource = createAudioResource(readableStream, { inputType: 'pcm' });\n * player.play(resource);\n * ```\n */\nexport class AudioResource implements PlayableResource {\n\tprivate readonly stream: Readable;\n\tprivate readonly packets: Buffer[] = [];\n\tprivate _ended = false;\n\tprivate draining = false;\n\n\tconstructor(stream: Readable) {\n\t\tthis.stream = stream;\n\n\t\tstream.on(\"data\", (chunk: Buffer) => {\n\t\t\tthis.packets.push(chunk);\n\t\t});\n\n\t\tstream.on(\"end\", () => {\n\t\t\tthis._ended = true;\n\t\t});\n\n\t\tstream.on(\"error\", () => {\n\t\t\tthis._ended = true;\n\t\t});\n\t}\n\n\t/**\n\t * Read the next Opus packet.\n\t *\n\t * @example\n\t * ```ts\n\t * const packet = resource.read();\n\t * ```\n\t */\n\tread(): Buffer | null {\n\t\treturn this.packets.shift() ?? null;\n\t}\n\n\t/** Whether the resource has finished producing packets. */\n\tget ended(): boolean {\n\t\treturn this._ended && this.packets.length === 0;\n\t}\n\n\t/**\n\t * Destroy the resource and release underlying streams.\n\t *\n\t * @example\n\t * ```ts\n\t * resource.destroy();\n\t * ```\n\t */\n\tdestroy(): void {\n\t\tthis.stream.destroy();\n\t\tthis.packets.length = 0;\n\t\tthis._ended = true;\n\t}\n}\n\n/**\n * Create an AudioResource from various input types.\n *\n * @example\n * ```ts\n * import { createAudioResource } from '@harmonia/voice';\n * import { createReadStream } from 'fs';\n *\n * const resource = createAudioResource(createReadStream('./audio.pcm'), {\n * inputType: 'pcm',\n * });\n * ```\n */\nexport function createAudioResource(\n\tinput: Readable | string | Buffer,\n\toptions: AudioResourceOptions = {},\n): AudioResource {\n\tlet readable: Readable;\n\n\tif (typeof input === \"string\") {\n\t\tconst { createReadStream } = require(\"node:fs\") as typeof import(\"node:fs\");\n\t\treadable = createReadStream(input);\n\t} else if (Buffer.isBuffer(input)) {\n\t\treadable = Readable.from(input);\n\t} else {\n\t\treadable = input;\n\t}\n\n\tif (options.inputType === \"opus\") {\n\t\treturn new AudioResource(readable);\n\t}\n\n\t// PCM input: pipe through Opus encoder\n\tconst encoder = new OpusEncoderStream({\n\t\tsampleRate: 48000,\n\t\tchannels: 2,\n\t\tapplication: \"audio\",\n\t});\n\n\treadable.pipe(encoder);\n\n\tif (options.signal) {\n\t\toptions.signal.addEventListener(\n\t\t\t\"abort\",\n\t\t\t() => {\n\t\t\t\treadable.destroy();\n\t\t\t\tencoder.destroy();\n\t\t\t},\n\t\t\t{ once: true },\n\t\t);\n\t}\n\n\treturn new AudioResource(encoder);\n}\n"]}
package/dist/index.d.cts CHANGED
@@ -173,7 +173,7 @@ declare class AudioPlayer extends EventEmitter {
173
173
  private _state;
174
174
  private resource;
175
175
  private connections;
176
- private playbackTimer;
176
+ private audioThread;
177
177
  private readonly noSubscriberBehavior;
178
178
  constructor(options?: AudioPlayerOptions);
179
179
  /**
package/dist/index.d.ts CHANGED
@@ -173,7 +173,7 @@ declare class AudioPlayer extends EventEmitter {
173
173
  private _state;
174
174
  private resource;
175
175
  private connections;
176
- private playbackTimer;
176
+ private audioThread;
177
177
  private readonly noSubscriberBehavior;
178
178
  constructor(options?: AudioPlayerOptions);
179
179
  /**
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { EventEmitter } from 'events';
2
2
  import dgram from 'dgram';
3
3
  import WebSocket from 'ws';
4
- import { parseRtpHeader, buildRtpHeader, configureSocketForAudio, xchacha20Encrypt, secretboxEncrypt, randomBytes, xchacha20Decrypt, secretboxDecrypt } from '@harmonia-audio/native';
4
+ import { parseRtpHeader, buildRtpHeader, configureSocketForAudio, AudioThread, xchacha20Encrypt, secretboxEncrypt, randomBytes, xchacha20Decrypt, secretboxDecrypt } from '@harmonia-audio/native';
5
5
  import { OpusDecoder, OpusEncoderStream } from '@harmonia-audio/codec';
6
6
  import { Readable } from 'stream';
7
7
 
@@ -359,7 +359,11 @@ var VoiceConnection = class extends EventEmitter {
359
359
  * ```
360
360
  */
361
361
  subscribe(player) {
362
+ if (this.subscribedPlayer) {
363
+ this.subscribedPlayer.removeConnection(this);
364
+ }
362
365
  this.subscribedPlayer = player;
366
+ player.addConnection(this);
363
367
  }
364
368
  /**
365
369
  * Unsubscribe the current audio player.
@@ -370,6 +374,9 @@ var VoiceConnection = class extends EventEmitter {
370
374
  * ```
371
375
  */
372
376
  unsubscribe() {
377
+ if (this.subscribedPlayer) {
378
+ this.subscribedPlayer.removeConnection(this);
379
+ }
373
380
  this.subscribedPlayer = void 0;
374
381
  }
375
382
  /**
@@ -703,7 +710,7 @@ var AudioPlayer = class extends EventEmitter {
703
710
  _state = "idle" /* Idle */;
704
711
  resource;
705
712
  connections = /* @__PURE__ */ new Set();
706
- playbackTimer;
713
+ audioThread;
707
714
  noSubscriberBehavior;
708
715
  constructor(options = {}) {
709
716
  super();
@@ -782,9 +789,12 @@ var AudioPlayer = class extends EventEmitter {
782
789
  this.connections.delete(connection);
783
790
  }
784
791
  startPlaybackLoop() {
785
- this.playbackTimer = setInterval(() => {
792
+ if (!this.audioThread) {
793
+ this.audioThread = new AudioThread();
794
+ }
795
+ this.audioThread.start(() => {
786
796
  this.processFrame();
787
- }, 20);
797
+ });
788
798
  }
789
799
  processFrame() {
790
800
  if (this._state !== "playing" /* Playing */) {
@@ -809,9 +819,9 @@ var AudioPlayer = class extends EventEmitter {
809
819
  }
810
820
  }
811
821
  stopInternal() {
812
- if (this.playbackTimer) {
813
- clearInterval(this.playbackTimer);
814
- this.playbackTimer = void 0;
822
+ if (this.audioThread) {
823
+ this.audioThread.stop();
824
+ this.audioThread = void 0;
815
825
  }
816
826
  if (this.resource) {
817
827
  this.resource.destroy();
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/encryption.ts","../src/errors.ts","../src/store.ts","../src/types.ts","../src/receiver.ts","../src/connection.ts","../src/player.ts","../src/join.ts","../src/resource.ts"],"names":["EncryptionMode","VoiceConnectionState","AudioPlayerState","parseRtpHeader","EventEmitter","buildRtpHeader","Readable"],"mappings":"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","file":"index.js","sourcesContent":["import {\n\tsecretboxEncrypt,\n\tsecretboxDecrypt,\n\txchacha20Encrypt,\n\txchacha20Decrypt,\n\trandomBytes,\n\tbuildRtpHeader,\n\tparseRtpHeader,\n\ttype RtpHeader as NativeRtpHeader,\n} from \"@harmonia-audio/native\";\n\nconst NONCE_SIZE_XSALSA20 = 24;\nconst NONCE_SIZE_LITE = 4;\n\n/**\n * Available encryption modes for voice connections.\n *\n * @example\n * ```ts\n * connection.setEncryptionMode(EncryptionMode.XSalsa20Poly1305);\n * ```\n */\nexport enum EncryptionMode {\n\tXSalsa20Poly1305 = \"xsalsa20_poly1305\",\n\tXSalsa20Poly1305Suffix = \"xsalsa20_poly1305_suffix\",\n\tXSalsa20Poly1305Lite = \"xsalsa20_poly1305_lite\",\n\tAeadAes256Gcm = \"aead_aes256_gcm\",\n\tAeadXChaCha20Poly1305 = \"aead_xchacha20_poly1305_rtpsize\",\n}\n\n/** Parsed RTP packet. */\nexport interface RtpPacket {\n\theader: NativeRtpHeader;\n\tpayload: Buffer;\n\tnonce: Buffer;\n}\n\nconst PREFERRED_MODES: EncryptionMode[] = [\n\tEncryptionMode.AeadXChaCha20Poly1305,\n\tEncryptionMode.AeadAes256Gcm,\n\tEncryptionMode.XSalsa20Poly1305Lite,\n\tEncryptionMode.XSalsa20Poly1305Suffix,\n\tEncryptionMode.XSalsa20Poly1305,\n];\n\n/**\n * Select the best available encryption mode from a list of supported modes.\n *\n * @example\n * ```ts\n * const mode = selectEncryptionMode(['xsalsa20_poly1305', 'xsalsa20_poly1305_suffix']);\n * ```\n */\nexport function selectEncryptionMode(\n\tavailable: readonly string[],\n): EncryptionMode {\n\tfor (const preferred of PREFERRED_MODES) {\n\t\tif (available.includes(preferred)) {\n\t\t\treturn preferred;\n\t\t}\n\t}\n\tconst first = available[0];\n\tif (first !== undefined) {\n\t\treturn first as EncryptionMode;\n\t}\n\treturn EncryptionMode.XSalsa20Poly1305;\n}\n\n/**\n * Encrypt an RTP payload.\n *\n * @example\n * ```ts\n * const encrypted = encryptOpusPacket(header, payload, key, mode, nonceCounter);\n * ```\n */\nexport function encryptOpusPacket(\n\trtpHeader: Buffer,\n\tpayload: Buffer,\n\tsecretKey: Buffer,\n\tmode: EncryptionMode,\n\tnonceCounter: number,\n): Buffer {\n\tswitch (mode) {\n\t\tcase EncryptionMode.XSalsa20Poly1305: {\n\t\t\tconst nonce = Buffer.alloc(NONCE_SIZE_XSALSA20);\n\t\t\trtpHeader.copy(nonce, 0, 0, 12);\n\t\t\tconst encrypted = secretboxEncrypt(payload, nonce, secretKey);\n\t\t\treturn Buffer.concat([rtpHeader, encrypted]);\n\t\t}\n\n\t\tcase EncryptionMode.XSalsa20Poly1305Suffix: {\n\t\t\tconst nonce = randomBytes(NONCE_SIZE_XSALSA20);\n\t\t\tconst encrypted = secretboxEncrypt(payload, nonce, secretKey);\n\t\t\treturn Buffer.concat([rtpHeader, encrypted, nonce]);\n\t\t}\n\n\t\tcase EncryptionMode.XSalsa20Poly1305Lite: {\n\t\t\tconst nonce = Buffer.alloc(NONCE_SIZE_XSALSA20);\n\t\t\tnonce.writeUInt32BE(nonceCounter, 0);\n\t\t\tconst encrypted = secretboxEncrypt(payload, nonce, secretKey);\n\t\t\tconst nonceAppend = Buffer.alloc(NONCE_SIZE_LITE);\n\t\t\tnonceAppend.writeUInt32BE(nonceCounter, 0);\n\t\t\treturn Buffer.concat([rtpHeader, encrypted, nonceAppend]);\n\t\t}\n\n\t\tcase EncryptionMode.AeadXChaCha20Poly1305: {\n\t\t\tconst nonce = Buffer.alloc(24);\n\t\t\tnonce.writeUInt32BE(nonceCounter, 0);\n\t\t\tconst encrypted = xchacha20Encrypt(payload, nonce, secretKey, rtpHeader);\n\t\t\tconst nonceAppend = Buffer.alloc(4);\n\t\t\tnonceAppend.writeUInt32BE(nonceCounter, 0);\n\t\t\treturn Buffer.concat([rtpHeader, encrypted, nonceAppend]);\n\t\t}\n\n\t\tdefault:\n\t\t\treturn Buffer.concat([rtpHeader, payload]);\n\t}\n}\n\n/**\n * Decrypt an RTP packet payload.\n *\n * @example\n * ```ts\n * const decrypted = decryptOpusPacket(packet, secretKey, mode);\n * ```\n */\nexport function decryptOpusPacket(\n\tpacket: Buffer,\n\tsecretKey: Buffer,\n\tmode: EncryptionMode,\n): Buffer {\n\tconst rtpHeader = packet.subarray(0, 12);\n\n\tswitch (mode) {\n\t\tcase EncryptionMode.XSalsa20Poly1305: {\n\t\t\tconst nonce = Buffer.alloc(NONCE_SIZE_XSALSA20);\n\t\t\trtpHeader.copy(nonce, 0, 0, 12);\n\t\t\tconst ciphertext = packet.subarray(12);\n\t\t\treturn secretboxDecrypt(ciphertext, nonce, secretKey);\n\t\t}\n\n\t\tcase EncryptionMode.XSalsa20Poly1305Suffix: {\n\t\t\tconst nonce = packet.subarray(packet.length - NONCE_SIZE_XSALSA20);\n\t\t\tconst ciphertext = packet.subarray(12, packet.length - NONCE_SIZE_XSALSA20);\n\t\t\treturn secretboxDecrypt(ciphertext, nonce, secretKey);\n\t\t}\n\n\t\tcase EncryptionMode.XSalsa20Poly1305Lite: {\n\t\t\tconst nonce = Buffer.alloc(NONCE_SIZE_XSALSA20);\n\t\t\tconst nonceFragment = packet.subarray(packet.length - NONCE_SIZE_LITE);\n\t\t\tnonceFragment.copy(nonce, 0, 0, NONCE_SIZE_LITE);\n\t\t\tconst ciphertext = packet.subarray(12, packet.length - NONCE_SIZE_LITE);\n\t\t\treturn secretboxDecrypt(ciphertext, nonce, secretKey);\n\t\t}\n\n\t\tcase EncryptionMode.AeadXChaCha20Poly1305: {\n\t\t\tconst nonce = Buffer.alloc(24);\n\t\t\tconst nonceFragment = packet.subarray(packet.length - 4);\n\t\t\tnonceFragment.copy(nonce, 0, 0, 4);\n\t\t\tconst ciphertext = packet.subarray(12, packet.length - 4);\n\t\t\treturn xchacha20Decrypt(ciphertext, nonce, secretKey, rtpHeader);\n\t\t}\n\n\t\tdefault: {\n\t\t\treturn packet.subarray(12);\n\t\t}\n\t}\n}\n","/**\n * Error class for all voice-related errors in harmonia.\n *\n * @example\n * ```ts\n * try {\n * await connection.connect();\n * } catch (error) {\n * if (error instanceof HarmoniaVoiceError) {\n * console.error(error.code);\n * }\n * }\n * ```\n */\nexport class HarmoniaVoiceError extends Error {\n\tpublic readonly code: string;\n\tpublic readonly context: Record<string, unknown>;\n\n\tconstructor(\n\t\tcode: string,\n\t\tmessage: string,\n\t\tcontext: Record<string, unknown> = {},\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"HarmoniaVoiceError\";\n\t\tthis.code = code;\n\t\tthis.context = context;\n\t}\n}\n","import type { VoiceConnection } from \"./connection.js\";\n\nconst connections = new Map<string, VoiceConnection>();\n\n/**\n * Get a voice connection by guild ID.\n *\n * @example\n * ```ts\n * const connection = getVoiceConnection('guild-id');\n * ```\n */\nexport function getVoiceConnection(guildId: string): VoiceConnection | undefined {\n\treturn connections.get(guildId);\n}\n\n/**\n * Get all active voice connections.\n *\n * @example\n * ```ts\n * const all = getVoiceConnections();\n * ```\n */\nexport function getVoiceConnections(): ReadonlyMap<string, VoiceConnection> {\n\treturn connections;\n}\n\n/** @internal */\nexport function setVoiceConnection(guildId: string, connection: VoiceConnection): void {\n\tconnections.set(guildId, connection);\n}\n\n/** @internal */\nexport function removeVoiceConnection(guildId: string): void {\n\tconnections.delete(guildId);\n}\n","import type { EventEmitter } from \"node:events\";\n\n/**\n * Voice connection states.\n *\n * @example\n * ```ts\n * if (connection.state === VoiceConnectionState.Ready) {\n * // connection is ready\n * }\n * ```\n */\nexport enum VoiceConnectionState {\n\tIdle = \"idle\",\n\tSignalling = \"signalling\",\n\tConnecting = \"connecting\",\n\tReady = \"ready\",\n\tResuming = \"resuming\",\n\tDisconnected = \"disconnected\",\n\tDestroyed = \"destroyed\",\n}\n\n/**\n * Audio player states.\n *\n * @example\n * ```ts\n * if (player.state === AudioPlayerState.Playing) {\n * player.pause();\n * }\n * ```\n */\nexport enum AudioPlayerState {\n\tIdle = \"idle\",\n\tBuffering = \"buffering\",\n\tPlaying = \"playing\",\n\tPaused = \"paused\",\n\tAutoPaused = \"autopaused\",\n}\n\n/**\n * Events emitted by a voice connection.\n *\n * @example\n * ```ts\n * connection.on('stateChange', (oldState, newState) => {\n * console.log(`${oldState} -> ${newState}`);\n * });\n * ```\n */\nexport interface VoiceConnectionEvents {\n\tstateChange: [oldState: VoiceConnectionState, newState: VoiceConnectionState];\n\tready: [];\n\tdisconnected: [];\n\tdestroyed: [];\n\terror: [error: Error];\n}\n\n/**\n * Events emitted by an audio player.\n *\n * @example\n * ```ts\n * player.on('stateChange', (oldState, newState) => {\n * console.log(`${oldState} -> ${newState}`);\n * });\n * ```\n */\nexport interface AudioPlayerEvents {\n\tstateChange: [oldState: AudioPlayerState, newState: AudioPlayerState];\n\tidle: [];\n\terror: [error: Error];\n}\n","import { EventEmitter } from \"node:events\";\nimport { Readable } from \"node:stream\";\nimport { OpusDecoder } from \"@harmonia-audio/codec\";\nimport { parseRtpHeader } from \"@harmonia-audio/native\";\nimport type { VoiceConnection } from \"./connection.js\";\n\n/**\n * Options for the audio receiver.\n *\n * @example\n * ```ts\n * const receiver = connection.getReceiver();\n * ```\n */\nexport interface AudioReceiverOptions {\n\treadonly autoDecodeOpus?: boolean;\n}\n\ninterface SsrcState {\n\tuserId: string | undefined;\n\tdecoder: OpusDecoder;\n\tstream: UserAudioStream;\n}\n\n/**\n * A readable stream of audio from a specific user.\n *\n * @example\n * ```ts\n * const stream = receiver.subscribe('user-id');\n * stream.on('data', (pcm) => { ... });\n * ```\n */\nexport class UserAudioStream extends Readable {\n\tpublic readonly userId: string;\n\n\tconstructor(userId: string) {\n\t\tsuper({ objectMode: false });\n\t\tthis.userId = userId;\n\t}\n\n\toverride _read(): void {\n\t\t// Data is pushed from the receiver\n\t}\n}\n\n/**\n * Receives and routes incoming audio from voice connections.\n *\n * @example\n * ```ts\n * const receiver = connection.getReceiver();\n * const stream = receiver.subscribe('user-id');\n *\n * stream.on('data', (pcm: Buffer) => {\n * // Process received audio\n * });\n * ```\n */\nexport class AudioReceiver extends EventEmitter {\n\tprivate readonly connection: VoiceConnection;\n\tprivate readonly ssrcMap = new Map<number, SsrcState>();\n\tprivate readonly userSsrcMap = new Map<string, number>();\n\tprivate readonly subscriptions = new Map<string, UserAudioStream>();\n\n\tconstructor(connection: VoiceConnection) {\n\t\tsuper();\n\t\tthis.connection = connection;\n\t}\n\n\t/**\n\t * Subscribe to audio from a specific user.\n\t *\n\t * @param userId - The Discord user ID to receive audio from\n\t * @returns A readable stream of PCM audio from that user\n\t *\n\t * @example\n\t * ```ts\n\t * const stream = receiver.subscribe('123456789');\n\t * stream.pipe(fileWriteStream);\n\t * ```\n\t */\n\tsubscribe(userId: string): UserAudioStream {\n\t\tconst existing = this.subscriptions.get(userId);\n\t\tif (existing) {\n\t\t\treturn existing;\n\t\t}\n\n\t\tconst stream = new UserAudioStream(userId);\n\t\tthis.subscriptions.set(userId, stream);\n\n\t\tstream.on(\"close\", () => {\n\t\t\tthis.subscriptions.delete(userId);\n\t\t});\n\n\t\treturn stream;\n\t}\n\n\t/**\n\t * Unsubscribe from a user's audio.\n\t *\n\t * @example\n\t * ```ts\n\t * receiver.unsubscribe('123456789');\n\t * ```\n\t */\n\tunsubscribe(userId: string): void {\n\t\tconst stream = this.subscriptions.get(userId);\n\t\tif (stream) {\n\t\t\tstream.destroy();\n\t\t\tthis.subscriptions.delete(userId);\n\t\t}\n\t}\n\n\t/** @internal */\n\tmapSsrcToUser(ssrc: number, userId: string): void {\n\t\tlet state = this.ssrcMap.get(ssrc);\n\t\tif (!state) {\n\t\t\tstate = {\n\t\t\t\tuserId,\n\t\t\t\tdecoder: new OpusDecoder({ sampleRate: 48000, channels: 2 }),\n\t\t\t\tstream: new UserAudioStream(userId),\n\t\t\t};\n\t\t\tthis.ssrcMap.set(ssrc, state);\n\t\t} else {\n\t\t\tstate.userId = userId;\n\t\t}\n\t\tthis.userSsrcMap.set(userId, ssrc);\n\t\tthis.emit(\"userConnected\", userId, ssrc);\n\t}\n\n\t/** @internal */\n\tremoveUser(userId: string): void {\n\t\tconst ssrc = this.userSsrcMap.get(userId);\n\t\tif (ssrc !== undefined) {\n\t\t\tconst state = this.ssrcMap.get(ssrc);\n\t\t\tif (state) {\n\t\t\t\tstate.stream.destroy();\n\t\t\t\tthis.ssrcMap.delete(ssrc);\n\t\t\t}\n\t\t\tthis.userSsrcMap.delete(userId);\n\t\t}\n\t\tthis.subscriptions.get(userId)?.destroy();\n\t\tthis.subscriptions.delete(userId);\n\t\tthis.emit(\"userDisconnected\", userId);\n\t}\n\n\t/** @internal */\n\thandlePacket(rawPacket: Buffer, decryptedPayload: Buffer): void {\n\t\ttry {\n\t\t\tconst header = parseRtpHeader(rawPacket);\n\t\t\tconst state = this.ssrcMap.get(header.ssrc);\n\n\t\t\tif (!state?.userId) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst pcm = state.decoder.decode(decryptedPayload);\n\n\t\t\tconst subscription = this.subscriptions.get(state.userId);\n\t\t\tif (subscription && !subscription.destroyed) {\n\t\t\t\tsubscription.push(pcm);\n\t\t\t}\n\n\t\t\tthis.emit(\"audio\", state.userId, pcm, header);\n\t\t} catch {\n\t\t\t// Silently drop malformed packets\n\t\t}\n\t}\n\n\t/**\n\t * Destroy all streams and clean up.\n\t *\n\t * @example\n\t * ```ts\n\t * receiver.destroy();\n\t * ```\n\t */\n\tdestroy(): this {\n\t\tfor (const [, stream] of this.subscriptions) {\n\t\t\tstream.destroy();\n\t\t}\n\t\tthis.subscriptions.clear();\n\t\tthis.ssrcMap.clear();\n\t\tthis.userSsrcMap.clear();\n\t\treturn this;\n\t}\n}\n","import { EventEmitter } from \"node:events\";\nimport dgram from \"node:dgram\";\nimport WebSocket from \"ws\";\nimport {\n\tbuildRtpHeader,\n\tconfigureSocketForAudio,\n\tAudioThread as NativeAudioThread,\n\tAudioRingBuffer,\n} from \"@harmonia-audio/native\";\nimport { OpusEncoder } from \"@harmonia-audio/codec\";\nimport type {\n\tDiscordGatewayAdapter,\n\tDiscordGatewayAdapterCreator,\n\tVoiceServerUpdateData,\n\tVoiceStateUpdateData,\n} from \"./adapter.js\";\nimport {\n\tencryptOpusPacket,\n\tEncryptionMode,\n\tselectEncryptionMode,\n\tdecryptOpusPacket,\n} from \"./encryption.js\";\nimport { HarmoniaVoiceError } from \"./errors.js\";\nimport { removeVoiceConnection, setVoiceConnection } from \"./store.js\";\nimport { VoiceConnectionState, type VoiceConnectionEvents } from \"./types.js\";\nimport type { AudioPlayer } from \"./player.js\";\nimport { AudioReceiver } from \"./receiver.js\";\n\nconst VOICE_GATEWAY_VERSION = 8;\nconst HEARTBEAT_MAX_MISSED = 3;\nconst IP_DISCOVERY_PACKET_SIZE = 74;\n\n/**\n * Options for creating a voice connection.\n *\n * @example\n * ```ts\n * const options: VoiceConnectionOptions = {\n * guildId: '123456789',\n * channelId: '987654321',\n * selfDeaf: false,\n * selfMute: false,\n * };\n * ```\n */\nexport interface VoiceConnectionOptions {\n\treadonly guildId: string;\n\treadonly channelId: string;\n\treadonly selfDeaf?: boolean;\n\treadonly selfMute?: boolean;\n\treadonly adapterCreator: DiscordGatewayAdapterCreator;\n}\n\ninterface VoiceGatewayReady {\n\tssrc: number;\n\tip: string;\n\tport: number;\n\tmodes: string[];\n}\n\n/**\n * Manages a voice connection to a Discord voice channel.\n *\n * @example\n * ```ts\n * import { VoiceConnection } from '@harmonia/voice';\n *\n * const connection = new VoiceConnection({\n * guildId: '123',\n * channelId: '456',\n * adapterCreator: guild.voiceAdapterCreator,\n * });\n *\n * connection.on('ready', () => {\n * console.log('Connected to voice!');\n * });\n * ```\n */\nexport class VoiceConnection extends EventEmitter {\n\tprivate _state: VoiceConnectionState = VoiceConnectionState.Idle;\n\tprivate readonly guildId: string;\n\tprivate channelId: string;\n\tprivate readonly selfDeaf: boolean;\n\tprivate readonly selfMute: boolean;\n\tprivate adapter: DiscordGatewayAdapter | undefined;\n\n\tprivate sessionId: string | undefined;\n\tprivate voiceToken: string | undefined;\n\tprivate endpoint: string | undefined;\n\n\tprivate ws: WebSocket | undefined;\n\tprivate udpSocket: dgram.Socket | undefined;\n\tprivate ssrc = 0;\n\tprivate remoteIp = \"\";\n\tprivate remotePort = 0;\n\tprivate localIp = \"\";\n\tprivate localPort = 0;\n\tprivate secretKey: Buffer | undefined;\n\tprivate encryptionMode: EncryptionMode = EncryptionMode.XSalsa20Poly1305;\n\tprivate sequence = 0;\n\tprivate timestamp = 0;\n\tprivate nonceCounter = 0;\n\n\tprivate heartbeatInterval: ReturnType<typeof setInterval> | undefined;\n\tprivate heartbeatNonce = 0;\n\tprivate missedHeartbeats = 0;\n\tprivate lastHeartbeatAck = 0;\n\n\tprivate subscribedPlayer: AudioPlayer | undefined;\n\tprivate audioThread: NativeAudioThread | undefined;\n\tprivate ringBuffer: AudioRingBuffer | undefined;\n\n\tprivate readonly receiver: AudioReceiver;\n\n\tprivate voiceStateResolve: (() => void) | undefined;\n\tprivate voiceServerResolve: (() => void) | undefined;\n\n\tconstructor(options: VoiceConnectionOptions) {\n\t\tsuper();\n\t\tthis.guildId = options.guildId;\n\t\tthis.channelId = options.channelId;\n\t\tthis.selfDeaf = options.selfDeaf ?? false;\n\t\tthis.selfMute = options.selfMute ?? false;\n\t\tthis.receiver = new AudioReceiver(this);\n\n\t\tthis.adapter = options.adapterCreator({\n\t\t\tonVoiceStateUpdate: (data) => this.handleVoiceStateUpdate(data),\n\t\t\tonVoiceServerUpdate: (data) => this.handleVoiceServerUpdate(data),\n\t\t\tdestroy: () => this.destroy(),\n\t\t});\n\n\t\tsetVoiceConnection(this.guildId, this);\n\t\tthis.sendVoiceStateUpdate();\n\t}\n\n\t/**\n\t * Current connection state.\n\t *\n\t * @example\n\t * ```ts\n\t * if (connection.state === VoiceConnectionState.Ready) { ... }\n\t * ```\n\t */\n\tget state(): VoiceConnectionState {\n\t\treturn this._state;\n\t}\n\n\t/**\n\t * Get the audio receiver for this connection.\n\t *\n\t * @example\n\t * ```ts\n\t * const receiver = connection.getReceiver();\n\t * ```\n\t */\n\tgetReceiver(): AudioReceiver {\n\t\treturn this.receiver;\n\t}\n\n\t/**\n\t * Subscribe an audio player to this connection.\n\t *\n\t * @example\n\t * ```ts\n\t * connection.subscribe(player);\n\t * ```\n\t */\n\tsubscribe(player: AudioPlayer): void {\n\t\tthis.subscribedPlayer = player;\n\t}\n\n\t/**\n\t * Unsubscribe the current audio player.\n\t *\n\t * @example\n\t * ```ts\n\t * connection.unsubscribe();\n\t * ```\n\t */\n\tunsubscribe(): void {\n\t\tthis.subscribedPlayer = undefined;\n\t}\n\n\t/**\n\t * Destroy the connection and clean up all resources.\n\t *\n\t * @example\n\t * ```ts\n\t * connection.destroy();\n\t * ```\n\t */\n\tdestroy(): void {\n\t\tif (this._state === VoiceConnectionState.Destroyed) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.transitionTo(VoiceConnectionState.Destroyed);\n\t\tthis.cleanup();\n\t\tremoveVoiceConnection(this.guildId);\n\n\t\tif (this.adapter) {\n\t\t\tthis.adapter.sendPayload({\n\t\t\t\top: 4,\n\t\t\t\td: {\n\t\t\t\t\tguild_id: this.guildId,\n\t\t\t\t\tchannel_id: null,\n\t\t\t\t\tself_mute: false,\n\t\t\t\t\tself_deaf: false,\n\t\t\t\t},\n\t\t\t});\n\t\t\tthis.adapter.destroy();\n\t\t\tthis.adapter = undefined;\n\t\t}\n\n\t\tthis.emit(\"destroyed\");\n\t}\n\n\t/**\n\t * Send an Opus packet through the voice connection.\n\t *\n\t * @example\n\t * ```ts\n\t * connection.sendOpusPacket(opusBuffer);\n\t * ```\n\t */\n\tsendOpusPacket(opusPacket: Buffer): void {\n\t\tif (this._state !== VoiceConnectionState.Ready) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.secretKey || !this.udpSocket) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst header = buildRtpHeader(this.sequence, this.timestamp, this.ssrc, 0x78);\n\n\t\tconst encrypted = encryptOpusPacket(\n\t\t\theader,\n\t\t\topusPacket,\n\t\t\tthis.secretKey,\n\t\t\tthis.encryptionMode,\n\t\t\tthis.nonceCounter,\n\t\t);\n\n\t\tthis.udpSocket.send(encrypted, this.remotePort, this.remoteIp);\n\n\t\tthis.sequence = (this.sequence + 1) & 0xFFFF;\n\t\tthis.timestamp = (this.timestamp + 960) >>> 0;\n\t\tthis.nonceCounter = (this.nonceCounter + 1) >>> 0;\n\t}\n\n\tprivate sendVoiceStateUpdate(): void {\n\t\tthis.transitionTo(VoiceConnectionState.Signalling);\n\n\t\tthis.adapter?.sendPayload({\n\t\t\top: 4,\n\t\t\td: {\n\t\t\t\tguild_id: this.guildId,\n\t\t\t\tchannel_id: this.channelId,\n\t\t\t\tself_mute: this.selfMute,\n\t\t\t\tself_deaf: this.selfDeaf,\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate handleVoiceStateUpdate(data: VoiceStateUpdateData): void {\n\t\tthis.sessionId = data.session_id;\n\t\tif (this.voiceStateResolve) {\n\t\t\tthis.voiceStateResolve();\n\t\t\tthis.voiceStateResolve = undefined;\n\t\t}\n\t\tthis.tryConnect();\n\t}\n\n\tprivate handleVoiceServerUpdate(data: VoiceServerUpdateData): void {\n\t\tthis.voiceToken = data.token;\n\t\tthis.endpoint = data.endpoint ?? undefined;\n\t\tif (this.voiceServerResolve) {\n\t\t\tthis.voiceServerResolve();\n\t\t\tthis.voiceServerResolve = undefined;\n\t\t}\n\t\tthis.tryConnect();\n\t}\n\n\tprivate tryConnect(): void {\n\t\tif (!this.sessionId || !this.voiceToken || !this.endpoint) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.transitionTo(VoiceConnectionState.Connecting);\n\t\tthis.connectWebSocket();\n\t}\n\n\tprivate connectWebSocket(): void {\n\t\tconst wsUrl = `wss://${this.endpoint}/?v=${VOICE_GATEWAY_VERSION}`;\n\n\t\tthis.ws?.close();\n\t\tthis.ws = new WebSocket(wsUrl);\n\n\t\tthis.ws.on(\"open\", () => {\n\t\t\tthis.sendIdentify();\n\t\t});\n\n\t\tthis.ws.on(\"message\", (raw: WebSocket.Data) => {\n\t\t\tconst data = JSON.parse(raw.toString()) as {\n\t\t\t\top: number;\n\t\t\t\td: Record<string, unknown>;\n\t\t\t};\n\t\t\tthis.handleGatewayMessage(data.op, data.d);\n\t\t});\n\n\t\tthis.ws.on(\"close\", (code: number) => {\n\t\t\tthis.stopHeartbeat();\n\t\t\tif (this._state !== VoiceConnectionState.Destroyed) {\n\t\t\t\tif (code === 4014 || code === 4006) {\n\t\t\t\t\tthis.transitionTo(VoiceConnectionState.Disconnected);\n\t\t\t\t\tthis.emit(\"disconnected\");\n\t\t\t\t} else if (this._state !== VoiceConnectionState.Disconnected) {\n\t\t\t\t\tthis.transitionTo(VoiceConnectionState.Resuming);\n\t\t\t\t\tsetTimeout(() => this.connectWebSocket(), 1000);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.ws.on(\"error\", (error: Error) => {\n\t\t\tthis.emit(\"error\", error);\n\t\t});\n\t}\n\n\tprivate sendIdentify(): void {\n\t\tthis.wsSend(0, {\n\t\t\tserver_id: this.guildId,\n\t\t\tuser_id: \"\", // filled by adapter\n\t\t\tsession_id: this.sessionId,\n\t\t\ttoken: this.voiceToken,\n\t\t});\n\t}\n\n\tprivate handleGatewayMessage(op: number, d: Record<string, unknown>): void {\n\t\tswitch (op) {\n\t\t\tcase 2: // READY\n\t\t\t\tthis.handleReady(d as unknown as VoiceGatewayReady);\n\t\t\t\tbreak;\n\t\t\tcase 4: // SESSION_DESCRIPTION\n\t\t\t\tthis.handleSessionDescription(d);\n\t\t\t\tbreak;\n\t\t\tcase 5: // SPEAKING\n\t\t\t\tthis.handleSpeaking(d);\n\t\t\t\tbreak;\n\t\t\tcase 6: // HEARTBEAT_ACK\n\t\t\t\tthis.handleHeartbeatAck(d);\n\t\t\t\tbreak;\n\t\t\tcase 8: // HELLO\n\t\t\t\tthis.handleHello(d);\n\t\t\t\tbreak;\n\t\t\tcase 9: // RESUMED\n\t\t\t\tthis.transitionTo(VoiceConnectionState.Ready);\n\t\t\t\tbreak;\n\t\t\tcase 12: // CLIENT_CONNECT\n\t\t\t\tthis.handleClientConnect(d);\n\t\t\t\tbreak;\n\t\t\tcase 13: // CLIENT_DISCONNECT\n\t\t\t\tthis.handleClientDisconnect(d);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate handleReady(data: VoiceGatewayReady): void {\n\t\tthis.ssrc = data.ssrc;\n\t\tthis.remoteIp = data.ip;\n\t\tthis.remotePort = data.port;\n\n\t\tthis.encryptionMode = selectEncryptionMode(data.modes);\n\t\tthis.connectUdp();\n\t}\n\n\tprivate connectUdp(): void {\n\t\tthis.udpSocket?.close();\n\t\tthis.udpSocket = dgram.createSocket(\"udp4\");\n\n\t\tthis.udpSocket.on(\"message\", (msg: Buffer) => {\n\t\t\tthis.handleUdpMessage(msg);\n\t\t});\n\n\t\tthis.udpSocket.on(\"error\", (error: Error) => {\n\t\t\tthis.emit(\"error\", error);\n\t\t});\n\n\t\tthis.udpSocket.bind(0, () => {\n\t\t\tconst address = this.udpSocket?.address();\n\t\t\tif (address) {\n\t\t\t\tthis.localPort = address.port;\n\n\t\t\t\t// Configure socket for low-latency audio\n\t\t\t\tconst fd = (this.udpSocket as unknown as { _handle: { fd: number } })?._handle?.fd;\n\t\t\t\tif (typeof fd === \"number\" && fd >= 0) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconfigureSocketForAudio(fd);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Non-critical, continue without socket tuning\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.performIpDiscovery();\n\t\t});\n\t}\n\n\tprivate performIpDiscovery(): void {\n\t\tconst discoveryPacket = Buffer.alloc(IP_DISCOVERY_PACKET_SIZE);\n\t\tdiscoveryPacket.writeUInt16BE(0x1, 0); // Type: request\n\t\tdiscoveryPacket.writeUInt16BE(70, 2); // Length\n\t\tdiscoveryPacket.writeUInt32BE(this.ssrc, 4);\n\n\t\tthis.udpSocket?.send(\n\t\t\tdiscoveryPacket,\n\t\t\tthis.remotePort,\n\t\t\tthis.remoteIp,\n\t\t);\n\t}\n\n\tprivate handleUdpMessage(msg: Buffer): void {\n\t\tif (msg.length === IP_DISCOVERY_PACKET_SIZE) {\n\t\t\tthis.handleIpDiscoveryResponse(msg);\n\t\t\treturn;\n\t\t}\n\n\t\t// Incoming audio packet\n\t\tif (msg.length > 12 && this.secretKey) {\n\t\t\ttry {\n\t\t\t\tconst decrypted = decryptOpusPacket(msg, this.secretKey, this.encryptionMode);\n\t\t\t\tthis.receiver.handlePacket(msg, decrypted);\n\t\t\t} catch {\n\t\t\t\t// Ignore malformed packets\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handleIpDiscoveryResponse(response: Buffer): void {\n\t\t// Extract IP (null-terminated string starting at offset 8)\n\t\tconst ipEnd = response.indexOf(0, 8);\n\t\tthis.localIp = response.subarray(8, ipEnd > 8 ? ipEnd : 72).toString(\"utf8\").replace(/\\0/g, \"\");\n\t\tthis.localPort = response.readUInt16BE(72);\n\n\t\t// Send select protocol\n\t\tthis.wsSend(1, {\n\t\t\tprotocol: \"udp\",\n\t\t\tdata: {\n\t\t\t\taddress: this.localIp,\n\t\t\t\tport: this.localPort,\n\t\t\t\tmode: this.encryptionMode,\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate handleSessionDescription(d: Record<string, unknown>): void {\n\t\tconst keyArray = d[\"secret_key\"] as number[];\n\t\tthis.secretKey = Buffer.from(keyArray);\n\t\tthis.encryptionMode = (d[\"mode\"] as string) as EncryptionMode;\n\n\t\tthis.sequence = 0;\n\t\tthis.timestamp = 0;\n\t\tthis.nonceCounter = 0;\n\n\t\tthis.transitionTo(VoiceConnectionState.Ready);\n\t\tthis.emit(\"ready\");\n\n\t\t// Send speaking\n\t\tthis.setSpeaking(1);\n\t}\n\n\tprivate handleSpeaking(d: Record<string, unknown>): void {\n\t\tconst userId = d[\"user_id\"] as string;\n\t\tconst ssrc = d[\"ssrc\"] as number;\n\t\tthis.receiver.mapSsrcToUser(ssrc, userId);\n\t}\n\n\tprivate handleClientConnect(d: Record<string, unknown>): void {\n\t\tconst userId = d[\"user_id\"] as string;\n\t\tconst audioSsrc = d[\"audio_ssrc\"] as number;\n\t\tif (audioSsrc) {\n\t\t\tthis.receiver.mapSsrcToUser(audioSsrc, userId);\n\t\t}\n\t}\n\n\tprivate handleClientDisconnect(d: Record<string, unknown>): void {\n\t\tconst userId = d[\"user_id\"] as string;\n\t\tthis.receiver.removeUser(userId);\n\t}\n\n\tprivate handleHello(d: Record<string, unknown>): void {\n\t\tconst interval = d[\"heartbeat_interval\"] as number;\n\t\tthis.startHeartbeat(interval);\n\t}\n\n\tprivate handleHeartbeatAck(_d: Record<string, unknown>): void {\n\t\tthis.missedHeartbeats = 0;\n\t\tthis.lastHeartbeatAck = Date.now();\n\t}\n\n\tprivate startHeartbeat(intervalMs: number): void {\n\t\tthis.stopHeartbeat();\n\t\tthis.missedHeartbeats = 0;\n\n\t\tthis.heartbeatInterval = setInterval(() => {\n\t\t\tif (this.missedHeartbeats >= HEARTBEAT_MAX_MISSED) {\n\t\t\t\tthis.ws?.close(4009);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.heartbeatNonce = Date.now();\n\t\t\tthis.wsSend(3, this.heartbeatNonce);\n\t\t\tthis.missedHeartbeats++;\n\t\t}, intervalMs);\n\t}\n\n\tprivate stopHeartbeat(): void {\n\t\tif (this.heartbeatInterval) {\n\t\t\tclearInterval(this.heartbeatInterval);\n\t\t\tthis.heartbeatInterval = undefined;\n\t\t}\n\t}\n\n\t/**\n\t * Set the speaking flags.\n\t *\n\t * @example\n\t * ```ts\n\t * connection.setSpeaking(1); // speaking\n\t * ```\n\t */\n\tsetSpeaking(flags: number): void {\n\t\tthis.wsSend(5, {\n\t\t\tspeaking: flags,\n\t\t\tdelay: 0,\n\t\t\tssrc: this.ssrc,\n\t\t});\n\t}\n\n\tprivate wsSend(op: number, d: unknown): void {\n\t\tif (this.ws?.readyState === WebSocket.OPEN) {\n\t\t\tthis.ws.send(JSON.stringify({ op, d }));\n\t\t}\n\t}\n\n\tprivate transitionTo(newState: VoiceConnectionState): void {\n\t\tconst oldState = this._state;\n\t\tif (oldState === newState) {\n\t\t\treturn;\n\t\t}\n\t\tthis._state = newState;\n\t\tthis.emit(\"stateChange\", oldState, newState);\n\t}\n\n\tprivate cleanup(): void {\n\t\tthis.stopHeartbeat();\n\n\t\tif (this.audioThread) {\n\t\t\tthis.audioThread.stop();\n\t\t\tthis.audioThread = undefined;\n\t\t}\n\n\t\tif (this.ws) {\n\t\t\tthis.ws.removeAllListeners();\n\t\t\tthis.ws.close();\n\t\t\tthis.ws = undefined;\n\t\t}\n\n\t\tif (this.udpSocket) {\n\t\t\tthis.udpSocket.removeAllListeners();\n\t\t\tthis.udpSocket.close();\n\t\t\tthis.udpSocket = undefined;\n\t\t}\n\n\t\tthis.secretKey = undefined;\n\t}\n}\n","import { EventEmitter } from \"node:events\";\nimport { AudioPlayerState, type AudioPlayerEvents } from \"./types.js\";\nimport type { VoiceConnection } from \"./connection.js\";\nimport { HarmoniaVoiceError } from \"./errors.js\";\n\n/** Represents a playable audio source. */\nexport interface PlayableResource {\n\tread(): Buffer | null;\n\treadonly ended: boolean;\n\tdestroy(): void;\n}\n\n/**\n * Options for creating an audio player.\n *\n * @example\n * ```ts\n * const player = new AudioPlayer({ noSubscriber: 'pause' });\n * ```\n */\nexport interface AudioPlayerOptions {\n\treadonly noSubscriber?: \"pause\" | \"stop\" | \"play\";\n}\n\n/**\n * Plays audio resources and dispatches packets to voice connections.\n *\n * @example\n * ```ts\n * import { AudioPlayer } from '@harmonia/voice';\n *\n * const player = new AudioPlayer();\n * player.play(resource);\n *\n * player.on('idle', () => {\n * console.log('Playback finished');\n * });\n * ```\n */\nexport class AudioPlayer extends EventEmitter {\n\tprivate _state: AudioPlayerState = AudioPlayerState.Idle;\n\tprivate resource: PlayableResource | undefined;\n\tprivate connections: Set<VoiceConnection> = new Set();\n\tprivate playbackTimer: ReturnType<typeof setInterval> | undefined;\n\tprivate readonly noSubscriberBehavior: \"pause\" | \"stop\" | \"play\";\n\n\tconstructor(options: AudioPlayerOptions = {}) {\n\t\tsuper();\n\t\tthis.noSubscriberBehavior = options.noSubscriber ?? \"pause\";\n\t}\n\n\t/**\n\t * Current player state.\n\t *\n\t * @example\n\t * ```ts\n\t * if (player.state === AudioPlayerState.Playing) { ... }\n\t * ```\n\t */\n\tget state(): AudioPlayerState {\n\t\treturn this._state;\n\t}\n\n\t/**\n\t * Start playing an audio resource.\n\t *\n\t * @example\n\t * ```ts\n\t * player.play(audioResource);\n\t * ```\n\t */\n\tplay(resource: PlayableResource): void {\n\t\tthis.stopInternal();\n\t\tthis.resource = resource;\n\t\tthis.transitionTo(AudioPlayerState.Playing);\n\t\tthis.startPlaybackLoop();\n\t}\n\n\t/**\n\t * Pause playback.\n\t *\n\t * @example\n\t * ```ts\n\t * player.pause();\n\t * ```\n\t */\n\tpause(): void {\n\t\tif (this._state === AudioPlayerState.Playing) {\n\t\t\tthis.transitionTo(AudioPlayerState.Paused);\n\t\t}\n\t}\n\n\t/**\n\t * Resume playback.\n\t *\n\t * @example\n\t * ```ts\n\t * player.resume();\n\t * ```\n\t */\n\tresume(): void {\n\t\tif (\n\t\t\tthis._state === AudioPlayerState.Paused ||\n\t\t\tthis._state === AudioPlayerState.AutoPaused\n\t\t) {\n\t\t\tthis.transitionTo(AudioPlayerState.Playing);\n\t\t}\n\t}\n\n\t/**\n\t * Stop playback and release the resource.\n\t *\n\t * @example\n\t * ```ts\n\t * player.stop();\n\t * ```\n\t */\n\tstop(): void {\n\t\tthis.stopInternal();\n\t\tthis.transitionTo(AudioPlayerState.Idle);\n\t\tthis.emit(\"idle\");\n\t}\n\n\t/** @internal */\n\taddConnection(connection: VoiceConnection): void {\n\t\tthis.connections.add(connection);\n\t}\n\n\t/** @internal */\n\tremoveConnection(connection: VoiceConnection): void {\n\t\tthis.connections.delete(connection);\n\t}\n\n\tprivate startPlaybackLoop(): void {\n\t\tthis.playbackTimer = setInterval(() => {\n\t\t\tthis.processFrame();\n\t\t}, 20);\n\t}\n\n\tprivate processFrame(): void {\n\t\tif (this._state !== AudioPlayerState.Playing) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.resource) {\n\t\t\tthis.stop();\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.resource.ended) {\n\t\t\tthis.stopInternal();\n\t\t\tthis.transitionTo(AudioPlayerState.Idle);\n\t\t\tthis.emit(\"idle\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst packet = this.resource.read();\n\t\tif (!packet) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const connection of this.connections) {\n\t\t\tconnection.sendOpusPacket(packet);\n\t\t}\n\t}\n\n\tprivate stopInternal(): void {\n\t\tif (this.playbackTimer) {\n\t\t\tclearInterval(this.playbackTimer);\n\t\t\tthis.playbackTimer = undefined;\n\t\t}\n\t\tif (this.resource) {\n\t\t\tthis.resource.destroy();\n\t\t\tthis.resource = undefined;\n\t\t}\n\t}\n\n\tprivate transitionTo(newState: AudioPlayerState): void {\n\t\tconst oldState = this._state;\n\t\tif (oldState === newState) {\n\t\t\treturn;\n\t\t}\n\t\tthis._state = newState;\n\t\tthis.emit(\"stateChange\", oldState, newState);\n\t}\n}\n","import { VoiceConnection, type VoiceConnectionOptions } from \"./connection.js\";\nimport type { DiscordGatewayAdapterCreator } from \"./adapter.js\";\nimport { getVoiceConnection } from \"./store.js\";\n\n/**\n * Options for joining a voice channel.\n *\n * @example\n * ```ts\n * const connection = joinVoiceChannel({\n * guildId: '123',\n * channelId: '456',\n * adapterCreator: guild.voiceAdapterCreator,\n * });\n * ```\n */\nexport interface JoinVoiceChannelOptions {\n\treadonly guildId: string;\n\treadonly channelId: string;\n\treadonly selfDeaf?: boolean;\n\treadonly selfMute?: boolean;\n\treadonly adapterCreator: DiscordGatewayAdapterCreator;\n}\n\n/**\n * Join a Discord voice channel and return a VoiceConnection.\n *\n * @example\n * ```ts\n * import { joinVoiceChannel } from '@harmonia/voice';\n *\n * const connection = joinVoiceChannel({\n * guildId: interaction.guildId,\n * channelId: member.voice.channelId,\n * adapterCreator: guild.voiceAdapterCreator,\n * });\n * ```\n */\nexport function joinVoiceChannel(options: JoinVoiceChannelOptions): VoiceConnection {\n\tconst existing = getVoiceConnection(options.guildId);\n\tif (existing) {\n\t\texisting.destroy();\n\t}\n\n\treturn new VoiceConnection(options);\n}\n","import { Readable } from \"node:stream\";\nimport { OpusEncoder, OpusEncoderStream } from \"@harmonia-audio/codec\";\nimport type { PlayableResource } from \"./player.js\";\n\n/**\n * Options for creating an audio resource.\n *\n * @example\n * ```ts\n * const resource = createAudioResource('./song.pcm', {\n * inputType: 'pcm',\n * });\n * ```\n */\nexport interface AudioResourceOptions {\n\treadonly inputType?: \"opus\" | \"pcm\" | \"raw\";\n\treadonly inlineVolume?: boolean;\n\treadonly signal?: AbortSignal;\n}\n\n/**\n * Audio resource that can be played by an AudioPlayer.\n *\n * @example\n * ```ts\n * const resource = createAudioResource(readableStream, { inputType: 'pcm' });\n * player.play(resource);\n * ```\n */\nexport class AudioResource implements PlayableResource {\n\tprivate readonly stream: Readable;\n\tprivate readonly packets: Buffer[] = [];\n\tprivate _ended = false;\n\tprivate draining = false;\n\n\tconstructor(stream: Readable) {\n\t\tthis.stream = stream;\n\n\t\tstream.on(\"data\", (chunk: Buffer) => {\n\t\t\tthis.packets.push(chunk);\n\t\t});\n\n\t\tstream.on(\"end\", () => {\n\t\t\tthis._ended = true;\n\t\t});\n\n\t\tstream.on(\"error\", () => {\n\t\t\tthis._ended = true;\n\t\t});\n\t}\n\n\t/**\n\t * Read the next Opus packet.\n\t *\n\t * @example\n\t * ```ts\n\t * const packet = resource.read();\n\t * ```\n\t */\n\tread(): Buffer | null {\n\t\treturn this.packets.shift() ?? null;\n\t}\n\n\t/** Whether the resource has finished producing packets. */\n\tget ended(): boolean {\n\t\treturn this._ended && this.packets.length === 0;\n\t}\n\n\t/**\n\t * Destroy the resource and release underlying streams.\n\t *\n\t * @example\n\t * ```ts\n\t * resource.destroy();\n\t * ```\n\t */\n\tdestroy(): void {\n\t\tthis.stream.destroy();\n\t\tthis.packets.length = 0;\n\t\tthis._ended = true;\n\t}\n}\n\n/**\n * Create an AudioResource from various input types.\n *\n * @example\n * ```ts\n * import { createAudioResource } from '@harmonia/voice';\n * import { createReadStream } from 'fs';\n *\n * const resource = createAudioResource(createReadStream('./audio.pcm'), {\n * inputType: 'pcm',\n * });\n * ```\n */\nexport function createAudioResource(\n\tinput: Readable | string | Buffer,\n\toptions: AudioResourceOptions = {},\n): AudioResource {\n\tlet readable: Readable;\n\n\tif (typeof input === \"string\") {\n\t\tconst { createReadStream } = require(\"node:fs\") as typeof import(\"node:fs\");\n\t\treadable = createReadStream(input);\n\t} else if (Buffer.isBuffer(input)) {\n\t\treadable = Readable.from(input);\n\t} else {\n\t\treadable = input;\n\t}\n\n\tif (options.inputType === \"opus\") {\n\t\treturn new AudioResource(readable);\n\t}\n\n\t// PCM input: pipe through Opus encoder\n\tconst encoder = new OpusEncoderStream({\n\t\tsampleRate: 48000,\n\t\tchannels: 2,\n\t\tapplication: \"audio\",\n\t});\n\n\treadable.pipe(encoder);\n\n\tif (options.signal) {\n\t\toptions.signal.addEventListener(\n\t\t\t\"abort\",\n\t\t\t() => {\n\t\t\t\treadable.destroy();\n\t\t\t\tencoder.destroy();\n\t\t\t},\n\t\t\t{ once: true },\n\t\t);\n\t}\n\n\treturn new AudioResource(encoder);\n}\n"]}
1
+ {"version":3,"sources":["../src/encryption.ts","../src/errors.ts","../src/store.ts","../src/types.ts","../src/receiver.ts","../src/connection.ts","../src/player.ts","../src/join.ts","../src/resource.ts"],"names":["EncryptionMode","VoiceConnectionState","AudioPlayerState","parseRtpHeader","EventEmitter","buildRtpHeader","Readable"],"mappings":"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","file":"index.js","sourcesContent":["import {\n\tsecretboxEncrypt,\n\tsecretboxDecrypt,\n\txchacha20Encrypt,\n\txchacha20Decrypt,\n\trandomBytes,\n\tbuildRtpHeader,\n\tparseRtpHeader,\n\ttype RtpHeader as NativeRtpHeader,\n} from \"@harmonia-audio/native\";\n\nconst NONCE_SIZE_XSALSA20 = 24;\nconst NONCE_SIZE_LITE = 4;\n\n/**\n * Available encryption modes for voice connections.\n *\n * @example\n * ```ts\n * connection.setEncryptionMode(EncryptionMode.XSalsa20Poly1305);\n * ```\n */\nexport enum EncryptionMode {\n\tXSalsa20Poly1305 = \"xsalsa20_poly1305\",\n\tXSalsa20Poly1305Suffix = \"xsalsa20_poly1305_suffix\",\n\tXSalsa20Poly1305Lite = \"xsalsa20_poly1305_lite\",\n\tAeadAes256Gcm = \"aead_aes256_gcm\",\n\tAeadXChaCha20Poly1305 = \"aead_xchacha20_poly1305_rtpsize\",\n}\n\n/** Parsed RTP packet. */\nexport interface RtpPacket {\n\theader: NativeRtpHeader;\n\tpayload: Buffer;\n\tnonce: Buffer;\n}\n\nconst PREFERRED_MODES: EncryptionMode[] = [\n\tEncryptionMode.AeadXChaCha20Poly1305,\n\tEncryptionMode.AeadAes256Gcm,\n\tEncryptionMode.XSalsa20Poly1305Lite,\n\tEncryptionMode.XSalsa20Poly1305Suffix,\n\tEncryptionMode.XSalsa20Poly1305,\n];\n\n/**\n * Select the best available encryption mode from a list of supported modes.\n *\n * @example\n * ```ts\n * const mode = selectEncryptionMode(['xsalsa20_poly1305', 'xsalsa20_poly1305_suffix']);\n * ```\n */\nexport function selectEncryptionMode(\n\tavailable: readonly string[],\n): EncryptionMode {\n\tfor (const preferred of PREFERRED_MODES) {\n\t\tif (available.includes(preferred)) {\n\t\t\treturn preferred;\n\t\t}\n\t}\n\tconst first = available[0];\n\tif (first !== undefined) {\n\t\treturn first as EncryptionMode;\n\t}\n\treturn EncryptionMode.XSalsa20Poly1305;\n}\n\n/**\n * Encrypt an RTP payload.\n *\n * @example\n * ```ts\n * const encrypted = encryptOpusPacket(header, payload, key, mode, nonceCounter);\n * ```\n */\nexport function encryptOpusPacket(\n\trtpHeader: Buffer,\n\tpayload: Buffer,\n\tsecretKey: Buffer,\n\tmode: EncryptionMode,\n\tnonceCounter: number,\n): Buffer {\n\tswitch (mode) {\n\t\tcase EncryptionMode.XSalsa20Poly1305: {\n\t\t\tconst nonce = Buffer.alloc(NONCE_SIZE_XSALSA20);\n\t\t\trtpHeader.copy(nonce, 0, 0, 12);\n\t\t\tconst encrypted = secretboxEncrypt(payload, nonce, secretKey);\n\t\t\treturn Buffer.concat([rtpHeader, encrypted]);\n\t\t}\n\n\t\tcase EncryptionMode.XSalsa20Poly1305Suffix: {\n\t\t\tconst nonce = randomBytes(NONCE_SIZE_XSALSA20);\n\t\t\tconst encrypted = secretboxEncrypt(payload, nonce, secretKey);\n\t\t\treturn Buffer.concat([rtpHeader, encrypted, nonce]);\n\t\t}\n\n\t\tcase EncryptionMode.XSalsa20Poly1305Lite: {\n\t\t\tconst nonce = Buffer.alloc(NONCE_SIZE_XSALSA20);\n\t\t\tnonce.writeUInt32BE(nonceCounter, 0);\n\t\t\tconst encrypted = secretboxEncrypt(payload, nonce, secretKey);\n\t\t\tconst nonceAppend = Buffer.alloc(NONCE_SIZE_LITE);\n\t\t\tnonceAppend.writeUInt32BE(nonceCounter, 0);\n\t\t\treturn Buffer.concat([rtpHeader, encrypted, nonceAppend]);\n\t\t}\n\n\t\tcase EncryptionMode.AeadXChaCha20Poly1305: {\n\t\t\tconst nonce = Buffer.alloc(24);\n\t\t\tnonce.writeUInt32BE(nonceCounter, 0);\n\t\t\tconst encrypted = xchacha20Encrypt(payload, nonce, secretKey, rtpHeader);\n\t\t\tconst nonceAppend = Buffer.alloc(4);\n\t\t\tnonceAppend.writeUInt32BE(nonceCounter, 0);\n\t\t\treturn Buffer.concat([rtpHeader, encrypted, nonceAppend]);\n\t\t}\n\n\t\tdefault:\n\t\t\treturn Buffer.concat([rtpHeader, payload]);\n\t}\n}\n\n/**\n * Decrypt an RTP packet payload.\n *\n * @example\n * ```ts\n * const decrypted = decryptOpusPacket(packet, secretKey, mode);\n * ```\n */\nexport function decryptOpusPacket(\n\tpacket: Buffer,\n\tsecretKey: Buffer,\n\tmode: EncryptionMode,\n): Buffer {\n\tconst rtpHeader = packet.subarray(0, 12);\n\n\tswitch (mode) {\n\t\tcase EncryptionMode.XSalsa20Poly1305: {\n\t\t\tconst nonce = Buffer.alloc(NONCE_SIZE_XSALSA20);\n\t\t\trtpHeader.copy(nonce, 0, 0, 12);\n\t\t\tconst ciphertext = packet.subarray(12);\n\t\t\treturn secretboxDecrypt(ciphertext, nonce, secretKey);\n\t\t}\n\n\t\tcase EncryptionMode.XSalsa20Poly1305Suffix: {\n\t\t\tconst nonce = packet.subarray(packet.length - NONCE_SIZE_XSALSA20);\n\t\t\tconst ciphertext = packet.subarray(12, packet.length - NONCE_SIZE_XSALSA20);\n\t\t\treturn secretboxDecrypt(ciphertext, nonce, secretKey);\n\t\t}\n\n\t\tcase EncryptionMode.XSalsa20Poly1305Lite: {\n\t\t\tconst nonce = Buffer.alloc(NONCE_SIZE_XSALSA20);\n\t\t\tconst nonceFragment = packet.subarray(packet.length - NONCE_SIZE_LITE);\n\t\t\tnonceFragment.copy(nonce, 0, 0, NONCE_SIZE_LITE);\n\t\t\tconst ciphertext = packet.subarray(12, packet.length - NONCE_SIZE_LITE);\n\t\t\treturn secretboxDecrypt(ciphertext, nonce, secretKey);\n\t\t}\n\n\t\tcase EncryptionMode.AeadXChaCha20Poly1305: {\n\t\t\tconst nonce = Buffer.alloc(24);\n\t\t\tconst nonceFragment = packet.subarray(packet.length - 4);\n\t\t\tnonceFragment.copy(nonce, 0, 0, 4);\n\t\t\tconst ciphertext = packet.subarray(12, packet.length - 4);\n\t\t\treturn xchacha20Decrypt(ciphertext, nonce, secretKey, rtpHeader);\n\t\t}\n\n\t\tdefault: {\n\t\t\treturn packet.subarray(12);\n\t\t}\n\t}\n}\n","/**\n * Error class for all voice-related errors in harmonia.\n *\n * @example\n * ```ts\n * try {\n * await connection.connect();\n * } catch (error) {\n * if (error instanceof HarmoniaVoiceError) {\n * console.error(error.code);\n * }\n * }\n * ```\n */\nexport class HarmoniaVoiceError extends Error {\n\tpublic readonly code: string;\n\tpublic readonly context: Record<string, unknown>;\n\n\tconstructor(\n\t\tcode: string,\n\t\tmessage: string,\n\t\tcontext: Record<string, unknown> = {},\n\t) {\n\t\tsuper(message);\n\t\tthis.name = \"HarmoniaVoiceError\";\n\t\tthis.code = code;\n\t\tthis.context = context;\n\t}\n}\n","import type { VoiceConnection } from \"./connection.js\";\n\nconst connections = new Map<string, VoiceConnection>();\n\n/**\n * Get a voice connection by guild ID.\n *\n * @example\n * ```ts\n * const connection = getVoiceConnection('guild-id');\n * ```\n */\nexport function getVoiceConnection(guildId: string): VoiceConnection | undefined {\n\treturn connections.get(guildId);\n}\n\n/**\n * Get all active voice connections.\n *\n * @example\n * ```ts\n * const all = getVoiceConnections();\n * ```\n */\nexport function getVoiceConnections(): ReadonlyMap<string, VoiceConnection> {\n\treturn connections;\n}\n\n/** @internal */\nexport function setVoiceConnection(guildId: string, connection: VoiceConnection): void {\n\tconnections.set(guildId, connection);\n}\n\n/** @internal */\nexport function removeVoiceConnection(guildId: string): void {\n\tconnections.delete(guildId);\n}\n","import type { EventEmitter } from \"node:events\";\n\n/**\n * Voice connection states.\n *\n * @example\n * ```ts\n * if (connection.state === VoiceConnectionState.Ready) {\n * // connection is ready\n * }\n * ```\n */\nexport enum VoiceConnectionState {\n\tIdle = \"idle\",\n\tSignalling = \"signalling\",\n\tConnecting = \"connecting\",\n\tReady = \"ready\",\n\tResuming = \"resuming\",\n\tDisconnected = \"disconnected\",\n\tDestroyed = \"destroyed\",\n}\n\n/**\n * Audio player states.\n *\n * @example\n * ```ts\n * if (player.state === AudioPlayerState.Playing) {\n * player.pause();\n * }\n * ```\n */\nexport enum AudioPlayerState {\n\tIdle = \"idle\",\n\tBuffering = \"buffering\",\n\tPlaying = \"playing\",\n\tPaused = \"paused\",\n\tAutoPaused = \"autopaused\",\n}\n\n/**\n * Events emitted by a voice connection.\n *\n * @example\n * ```ts\n * connection.on('stateChange', (oldState, newState) => {\n * console.log(`${oldState} -> ${newState}`);\n * });\n * ```\n */\nexport interface VoiceConnectionEvents {\n\tstateChange: [oldState: VoiceConnectionState, newState: VoiceConnectionState];\n\tready: [];\n\tdisconnected: [];\n\tdestroyed: [];\n\terror: [error: Error];\n}\n\n/**\n * Events emitted by an audio player.\n *\n * @example\n * ```ts\n * player.on('stateChange', (oldState, newState) => {\n * console.log(`${oldState} -> ${newState}`);\n * });\n * ```\n */\nexport interface AudioPlayerEvents {\n\tstateChange: [oldState: AudioPlayerState, newState: AudioPlayerState];\n\tidle: [];\n\terror: [error: Error];\n}\n","import { EventEmitter } from \"node:events\";\nimport { Readable } from \"node:stream\";\nimport { OpusDecoder } from \"@harmonia-audio/codec\";\nimport { parseRtpHeader } from \"@harmonia-audio/native\";\nimport type { VoiceConnection } from \"./connection.js\";\n\n/**\n * Options for the audio receiver.\n *\n * @example\n * ```ts\n * const receiver = connection.getReceiver();\n * ```\n */\nexport interface AudioReceiverOptions {\n\treadonly autoDecodeOpus?: boolean;\n}\n\ninterface SsrcState {\n\tuserId: string | undefined;\n\tdecoder: OpusDecoder;\n\tstream: UserAudioStream;\n}\n\n/**\n * A readable stream of audio from a specific user.\n *\n * @example\n * ```ts\n * const stream = receiver.subscribe('user-id');\n * stream.on('data', (pcm) => { ... });\n * ```\n */\nexport class UserAudioStream extends Readable {\n\tpublic readonly userId: string;\n\n\tconstructor(userId: string) {\n\t\tsuper({ objectMode: false });\n\t\tthis.userId = userId;\n\t}\n\n\toverride _read(): void {\n\t\t// Data is pushed from the receiver\n\t}\n}\n\n/**\n * Receives and routes incoming audio from voice connections.\n *\n * @example\n * ```ts\n * const receiver = connection.getReceiver();\n * const stream = receiver.subscribe('user-id');\n *\n * stream.on('data', (pcm: Buffer) => {\n * // Process received audio\n * });\n * ```\n */\nexport class AudioReceiver extends EventEmitter {\n\tprivate readonly connection: VoiceConnection;\n\tprivate readonly ssrcMap = new Map<number, SsrcState>();\n\tprivate readonly userSsrcMap = new Map<string, number>();\n\tprivate readonly subscriptions = new Map<string, UserAudioStream>();\n\n\tconstructor(connection: VoiceConnection) {\n\t\tsuper();\n\t\tthis.connection = connection;\n\t}\n\n\t/**\n\t * Subscribe to audio from a specific user.\n\t *\n\t * @param userId - The Discord user ID to receive audio from\n\t * @returns A readable stream of PCM audio from that user\n\t *\n\t * @example\n\t * ```ts\n\t * const stream = receiver.subscribe('123456789');\n\t * stream.pipe(fileWriteStream);\n\t * ```\n\t */\n\tsubscribe(userId: string): UserAudioStream {\n\t\tconst existing = this.subscriptions.get(userId);\n\t\tif (existing) {\n\t\t\treturn existing;\n\t\t}\n\n\t\tconst stream = new UserAudioStream(userId);\n\t\tthis.subscriptions.set(userId, stream);\n\n\t\tstream.on(\"close\", () => {\n\t\t\tthis.subscriptions.delete(userId);\n\t\t});\n\n\t\treturn stream;\n\t}\n\n\t/**\n\t * Unsubscribe from a user's audio.\n\t *\n\t * @example\n\t * ```ts\n\t * receiver.unsubscribe('123456789');\n\t * ```\n\t */\n\tunsubscribe(userId: string): void {\n\t\tconst stream = this.subscriptions.get(userId);\n\t\tif (stream) {\n\t\t\tstream.destroy();\n\t\t\tthis.subscriptions.delete(userId);\n\t\t}\n\t}\n\n\t/** @internal */\n\tmapSsrcToUser(ssrc: number, userId: string): void {\n\t\tlet state = this.ssrcMap.get(ssrc);\n\t\tif (!state) {\n\t\t\tstate = {\n\t\t\t\tuserId,\n\t\t\t\tdecoder: new OpusDecoder({ sampleRate: 48000, channels: 2 }),\n\t\t\t\tstream: new UserAudioStream(userId),\n\t\t\t};\n\t\t\tthis.ssrcMap.set(ssrc, state);\n\t\t} else {\n\t\t\tstate.userId = userId;\n\t\t}\n\t\tthis.userSsrcMap.set(userId, ssrc);\n\t\tthis.emit(\"userConnected\", userId, ssrc);\n\t}\n\n\t/** @internal */\n\tremoveUser(userId: string): void {\n\t\tconst ssrc = this.userSsrcMap.get(userId);\n\t\tif (ssrc !== undefined) {\n\t\t\tconst state = this.ssrcMap.get(ssrc);\n\t\t\tif (state) {\n\t\t\t\tstate.stream.destroy();\n\t\t\t\tthis.ssrcMap.delete(ssrc);\n\t\t\t}\n\t\t\tthis.userSsrcMap.delete(userId);\n\t\t}\n\t\tthis.subscriptions.get(userId)?.destroy();\n\t\tthis.subscriptions.delete(userId);\n\t\tthis.emit(\"userDisconnected\", userId);\n\t}\n\n\t/** @internal */\n\thandlePacket(rawPacket: Buffer, decryptedPayload: Buffer): void {\n\t\ttry {\n\t\t\tconst header = parseRtpHeader(rawPacket);\n\t\t\tconst state = this.ssrcMap.get(header.ssrc);\n\n\t\t\tif (!state?.userId) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\tconst pcm = state.decoder.decode(decryptedPayload);\n\n\t\t\tconst subscription = this.subscriptions.get(state.userId);\n\t\t\tif (subscription && !subscription.destroyed) {\n\t\t\t\tsubscription.push(pcm);\n\t\t\t}\n\n\t\t\tthis.emit(\"audio\", state.userId, pcm, header);\n\t\t} catch {\n\t\t\t// Silently drop malformed packets\n\t\t}\n\t}\n\n\t/**\n\t * Destroy all streams and clean up.\n\t *\n\t * @example\n\t * ```ts\n\t * receiver.destroy();\n\t * ```\n\t */\n\tdestroy(): this {\n\t\tfor (const [, stream] of this.subscriptions) {\n\t\t\tstream.destroy();\n\t\t}\n\t\tthis.subscriptions.clear();\n\t\tthis.ssrcMap.clear();\n\t\tthis.userSsrcMap.clear();\n\t\treturn this;\n\t}\n}\n","import { EventEmitter } from \"node:events\";\nimport dgram from \"node:dgram\";\nimport WebSocket from \"ws\";\nimport {\n\tbuildRtpHeader,\n\tconfigureSocketForAudio,\n\tAudioThread as NativeAudioThread,\n\tAudioRingBuffer,\n} from \"@harmonia-audio/native\";\nimport { OpusEncoder } from \"@harmonia-audio/codec\";\nimport type {\n\tDiscordGatewayAdapter,\n\tDiscordGatewayAdapterCreator,\n\tVoiceServerUpdateData,\n\tVoiceStateUpdateData,\n} from \"./adapter.js\";\nimport {\n\tencryptOpusPacket,\n\tEncryptionMode,\n\tselectEncryptionMode,\n\tdecryptOpusPacket,\n} from \"./encryption.js\";\nimport { HarmoniaVoiceError } from \"./errors.js\";\nimport { removeVoiceConnection, setVoiceConnection } from \"./store.js\";\nimport { VoiceConnectionState, type VoiceConnectionEvents } from \"./types.js\";\nimport type { AudioPlayer } from \"./player.js\";\nimport { AudioReceiver } from \"./receiver.js\";\n\nconst VOICE_GATEWAY_VERSION = 8;\nconst HEARTBEAT_MAX_MISSED = 3;\nconst IP_DISCOVERY_PACKET_SIZE = 74;\n\n/**\n * Options for creating a voice connection.\n *\n * @example\n * ```ts\n * const options: VoiceConnectionOptions = {\n * guildId: '123456789',\n * channelId: '987654321',\n * selfDeaf: false,\n * selfMute: false,\n * };\n * ```\n */\nexport interface VoiceConnectionOptions {\n\treadonly guildId: string;\n\treadonly channelId: string;\n\treadonly selfDeaf?: boolean;\n\treadonly selfMute?: boolean;\n\treadonly adapterCreator: DiscordGatewayAdapterCreator;\n}\n\ninterface VoiceGatewayReady {\n\tssrc: number;\n\tip: string;\n\tport: number;\n\tmodes: string[];\n}\n\n/**\n * Manages a voice connection to a Discord voice channel.\n *\n * @example\n * ```ts\n * import { VoiceConnection } from '@harmonia/voice';\n *\n * const connection = new VoiceConnection({\n * guildId: '123',\n * channelId: '456',\n * adapterCreator: guild.voiceAdapterCreator,\n * });\n *\n * connection.on('ready', () => {\n * console.log('Connected to voice!');\n * });\n * ```\n */\nexport class VoiceConnection extends EventEmitter {\n\tprivate _state: VoiceConnectionState = VoiceConnectionState.Idle;\n\tprivate readonly guildId: string;\n\tprivate channelId: string;\n\tprivate readonly selfDeaf: boolean;\n\tprivate readonly selfMute: boolean;\n\tprivate adapter: DiscordGatewayAdapter | undefined;\n\n\tprivate sessionId: string | undefined;\n\tprivate voiceToken: string | undefined;\n\tprivate endpoint: string | undefined;\n\n\tprivate ws: WebSocket | undefined;\n\tprivate udpSocket: dgram.Socket | undefined;\n\tprivate ssrc = 0;\n\tprivate remoteIp = \"\";\n\tprivate remotePort = 0;\n\tprivate localIp = \"\";\n\tprivate localPort = 0;\n\tprivate secretKey: Buffer | undefined;\n\tprivate encryptionMode: EncryptionMode = EncryptionMode.XSalsa20Poly1305;\n\tprivate sequence = 0;\n\tprivate timestamp = 0;\n\tprivate nonceCounter = 0;\n\n\tprivate heartbeatInterval: ReturnType<typeof setInterval> | undefined;\n\tprivate heartbeatNonce = 0;\n\tprivate missedHeartbeats = 0;\n\tprivate lastHeartbeatAck = 0;\n\n\tprivate subscribedPlayer: AudioPlayer | undefined;\n\tprivate audioThread: NativeAudioThread | undefined;\n\tprivate ringBuffer: AudioRingBuffer | undefined;\n\n\tprivate readonly receiver: AudioReceiver;\n\n\tprivate voiceStateResolve: (() => void) | undefined;\n\tprivate voiceServerResolve: (() => void) | undefined;\n\n\tconstructor(options: VoiceConnectionOptions) {\n\t\tsuper();\n\t\tthis.guildId = options.guildId;\n\t\tthis.channelId = options.channelId;\n\t\tthis.selfDeaf = options.selfDeaf ?? false;\n\t\tthis.selfMute = options.selfMute ?? false;\n\t\tthis.receiver = new AudioReceiver(this);\n\n\t\tthis.adapter = options.adapterCreator({\n\t\t\tonVoiceStateUpdate: (data) => this.handleVoiceStateUpdate(data),\n\t\t\tonVoiceServerUpdate: (data) => this.handleVoiceServerUpdate(data),\n\t\t\tdestroy: () => this.destroy(),\n\t\t});\n\n\t\tsetVoiceConnection(this.guildId, this);\n\t\tthis.sendVoiceStateUpdate();\n\t}\n\n\t/**\n\t * Current connection state.\n\t *\n\t * @example\n\t * ```ts\n\t * if (connection.state === VoiceConnectionState.Ready) { ... }\n\t * ```\n\t */\n\tget state(): VoiceConnectionState {\n\t\treturn this._state;\n\t}\n\n\t/**\n\t * Get the audio receiver for this connection.\n\t *\n\t * @example\n\t * ```ts\n\t * const receiver = connection.getReceiver();\n\t * ```\n\t */\n\tgetReceiver(): AudioReceiver {\n\t\treturn this.receiver;\n\t}\n\n\t/**\n\t * Subscribe an audio player to this connection.\n\t *\n\t * @example\n\t * ```ts\n\t * connection.subscribe(player);\n\t * ```\n\t */\n\tsubscribe(player: AudioPlayer): void {\n\t\tif (this.subscribedPlayer) {\n\t\t\tthis.subscribedPlayer.removeConnection(this);\n\t\t}\n\t\tthis.subscribedPlayer = player;\n\t\tplayer.addConnection(this);\n\t}\n\n\t/**\n\t * Unsubscribe the current audio player.\n\t *\n\t * @example\n\t * ```ts\n\t * connection.unsubscribe();\n\t * ```\n\t */\n\tunsubscribe(): void {\n\t\tif (this.subscribedPlayer) {\n\t\t\tthis.subscribedPlayer.removeConnection(this);\n\t\t}\n\t\tthis.subscribedPlayer = undefined;\n\t}\n\n\t/**\n\t * Destroy the connection and clean up all resources.\n\t *\n\t * @example\n\t * ```ts\n\t * connection.destroy();\n\t * ```\n\t */\n\tdestroy(): void {\n\t\tif (this._state === VoiceConnectionState.Destroyed) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.transitionTo(VoiceConnectionState.Destroyed);\n\t\tthis.cleanup();\n\t\tremoveVoiceConnection(this.guildId);\n\n\t\tif (this.adapter) {\n\t\t\tthis.adapter.sendPayload({\n\t\t\t\top: 4,\n\t\t\t\td: {\n\t\t\t\t\tguild_id: this.guildId,\n\t\t\t\t\tchannel_id: null,\n\t\t\t\t\tself_mute: false,\n\t\t\t\t\tself_deaf: false,\n\t\t\t\t},\n\t\t\t});\n\t\t\tthis.adapter.destroy();\n\t\t\tthis.adapter = undefined;\n\t\t}\n\n\t\tthis.emit(\"destroyed\");\n\t}\n\n\t/**\n\t * Send an Opus packet through the voice connection.\n\t *\n\t * @example\n\t * ```ts\n\t * connection.sendOpusPacket(opusBuffer);\n\t * ```\n\t */\n\tsendOpusPacket(opusPacket: Buffer): void {\n\t\tif (this._state !== VoiceConnectionState.Ready) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.secretKey || !this.udpSocket) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst header = buildRtpHeader(this.sequence, this.timestamp, this.ssrc, 0x78);\n\n\t\tconst encrypted = encryptOpusPacket(\n\t\t\theader,\n\t\t\topusPacket,\n\t\t\tthis.secretKey,\n\t\t\tthis.encryptionMode,\n\t\t\tthis.nonceCounter,\n\t\t);\n\n\t\tthis.udpSocket.send(encrypted, this.remotePort, this.remoteIp);\n\n\t\tthis.sequence = (this.sequence + 1) & 0xFFFF;\n\t\tthis.timestamp = (this.timestamp + 960) >>> 0;\n\t\tthis.nonceCounter = (this.nonceCounter + 1) >>> 0;\n\t}\n\n\tprivate sendVoiceStateUpdate(): void {\n\t\tthis.transitionTo(VoiceConnectionState.Signalling);\n\n\t\tthis.adapter?.sendPayload({\n\t\t\top: 4,\n\t\t\td: {\n\t\t\t\tguild_id: this.guildId,\n\t\t\t\tchannel_id: this.channelId,\n\t\t\t\tself_mute: this.selfMute,\n\t\t\t\tself_deaf: this.selfDeaf,\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate handleVoiceStateUpdate(data: VoiceStateUpdateData): void {\n\t\tthis.sessionId = data.session_id;\n\t\tif (this.voiceStateResolve) {\n\t\t\tthis.voiceStateResolve();\n\t\t\tthis.voiceStateResolve = undefined;\n\t\t}\n\t\tthis.tryConnect();\n\t}\n\n\tprivate handleVoiceServerUpdate(data: VoiceServerUpdateData): void {\n\t\tthis.voiceToken = data.token;\n\t\tthis.endpoint = data.endpoint ?? undefined;\n\t\tif (this.voiceServerResolve) {\n\t\t\tthis.voiceServerResolve();\n\t\t\tthis.voiceServerResolve = undefined;\n\t\t}\n\t\tthis.tryConnect();\n\t}\n\n\tprivate tryConnect(): void {\n\t\tif (!this.sessionId || !this.voiceToken || !this.endpoint) {\n\t\t\treturn;\n\t\t}\n\n\t\tthis.transitionTo(VoiceConnectionState.Connecting);\n\t\tthis.connectWebSocket();\n\t}\n\n\tprivate connectWebSocket(): void {\n\t\tconst wsUrl = `wss://${this.endpoint}/?v=${VOICE_GATEWAY_VERSION}`;\n\n\t\tthis.ws?.close();\n\t\tthis.ws = new WebSocket(wsUrl);\n\n\t\tthis.ws.on(\"open\", () => {\n\t\t\tthis.sendIdentify();\n\t\t});\n\n\t\tthis.ws.on(\"message\", (raw: WebSocket.Data) => {\n\t\t\tconst data = JSON.parse(raw.toString()) as {\n\t\t\t\top: number;\n\t\t\t\td: Record<string, unknown>;\n\t\t\t};\n\t\t\tthis.handleGatewayMessage(data.op, data.d);\n\t\t});\n\n\t\tthis.ws.on(\"close\", (code: number) => {\n\t\t\tthis.stopHeartbeat();\n\t\t\tif (this._state !== VoiceConnectionState.Destroyed) {\n\t\t\t\tif (code === 4014 || code === 4006) {\n\t\t\t\t\tthis.transitionTo(VoiceConnectionState.Disconnected);\n\t\t\t\t\tthis.emit(\"disconnected\");\n\t\t\t\t} else if (this._state !== VoiceConnectionState.Disconnected) {\n\t\t\t\t\tthis.transitionTo(VoiceConnectionState.Resuming);\n\t\t\t\t\tsetTimeout(() => this.connectWebSocket(), 1000);\n\t\t\t\t}\n\t\t\t}\n\t\t});\n\n\t\tthis.ws.on(\"error\", (error: Error) => {\n\t\t\tthis.emit(\"error\", error);\n\t\t});\n\t}\n\n\tprivate sendIdentify(): void {\n\t\tthis.wsSend(0, {\n\t\t\tserver_id: this.guildId,\n\t\t\tuser_id: \"\", // filled by adapter\n\t\t\tsession_id: this.sessionId,\n\t\t\ttoken: this.voiceToken,\n\t\t});\n\t}\n\n\tprivate handleGatewayMessage(op: number, d: Record<string, unknown>): void {\n\t\tswitch (op) {\n\t\t\tcase 2: // READY\n\t\t\t\tthis.handleReady(d as unknown as VoiceGatewayReady);\n\t\t\t\tbreak;\n\t\t\tcase 4: // SESSION_DESCRIPTION\n\t\t\t\tthis.handleSessionDescription(d);\n\t\t\t\tbreak;\n\t\t\tcase 5: // SPEAKING\n\t\t\t\tthis.handleSpeaking(d);\n\t\t\t\tbreak;\n\t\t\tcase 6: // HEARTBEAT_ACK\n\t\t\t\tthis.handleHeartbeatAck(d);\n\t\t\t\tbreak;\n\t\t\tcase 8: // HELLO\n\t\t\t\tthis.handleHello(d);\n\t\t\t\tbreak;\n\t\t\tcase 9: // RESUMED\n\t\t\t\tthis.transitionTo(VoiceConnectionState.Ready);\n\t\t\t\tbreak;\n\t\t\tcase 12: // CLIENT_CONNECT\n\t\t\t\tthis.handleClientConnect(d);\n\t\t\t\tbreak;\n\t\t\tcase 13: // CLIENT_DISCONNECT\n\t\t\t\tthis.handleClientDisconnect(d);\n\t\t\t\tbreak;\n\t\t}\n\t}\n\n\tprivate handleReady(data: VoiceGatewayReady): void {\n\t\tthis.ssrc = data.ssrc;\n\t\tthis.remoteIp = data.ip;\n\t\tthis.remotePort = data.port;\n\n\t\tthis.encryptionMode = selectEncryptionMode(data.modes);\n\t\tthis.connectUdp();\n\t}\n\n\tprivate connectUdp(): void {\n\t\tthis.udpSocket?.close();\n\t\tthis.udpSocket = dgram.createSocket(\"udp4\");\n\n\t\tthis.udpSocket.on(\"message\", (msg: Buffer) => {\n\t\t\tthis.handleUdpMessage(msg);\n\t\t});\n\n\t\tthis.udpSocket.on(\"error\", (error: Error) => {\n\t\t\tthis.emit(\"error\", error);\n\t\t});\n\n\t\tthis.udpSocket.bind(0, () => {\n\t\t\tconst address = this.udpSocket?.address();\n\t\t\tif (address) {\n\t\t\t\tthis.localPort = address.port;\n\n\t\t\t\t// Configure socket for low-latency audio\n\t\t\t\tconst fd = (this.udpSocket as unknown as { _handle: { fd: number } })?._handle?.fd;\n\t\t\t\tif (typeof fd === \"number\" && fd >= 0) {\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconfigureSocketForAudio(fd);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\t// Non-critical, continue without socket tuning\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tthis.performIpDiscovery();\n\t\t});\n\t}\n\n\tprivate performIpDiscovery(): void {\n\t\tconst discoveryPacket = Buffer.alloc(IP_DISCOVERY_PACKET_SIZE);\n\t\tdiscoveryPacket.writeUInt16BE(0x1, 0); // Type: request\n\t\tdiscoveryPacket.writeUInt16BE(70, 2); // Length\n\t\tdiscoveryPacket.writeUInt32BE(this.ssrc, 4);\n\n\t\tthis.udpSocket?.send(\n\t\t\tdiscoveryPacket,\n\t\t\tthis.remotePort,\n\t\t\tthis.remoteIp,\n\t\t);\n\t}\n\n\tprivate handleUdpMessage(msg: Buffer): void {\n\t\tif (msg.length === IP_DISCOVERY_PACKET_SIZE) {\n\t\t\tthis.handleIpDiscoveryResponse(msg);\n\t\t\treturn;\n\t\t}\n\n\t\t// Incoming audio packet\n\t\tif (msg.length > 12 && this.secretKey) {\n\t\t\ttry {\n\t\t\t\tconst decrypted = decryptOpusPacket(msg, this.secretKey, this.encryptionMode);\n\t\t\t\tthis.receiver.handlePacket(msg, decrypted);\n\t\t\t} catch {\n\t\t\t\t// Ignore malformed packets\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate handleIpDiscoveryResponse(response: Buffer): void {\n\t\t// Extract IP (null-terminated string starting at offset 8)\n\t\tconst ipEnd = response.indexOf(0, 8);\n\t\tthis.localIp = response.subarray(8, ipEnd > 8 ? ipEnd : 72).toString(\"utf8\").replace(/\\0/g, \"\");\n\t\tthis.localPort = response.readUInt16BE(72);\n\n\t\t// Send select protocol\n\t\tthis.wsSend(1, {\n\t\t\tprotocol: \"udp\",\n\t\t\tdata: {\n\t\t\t\taddress: this.localIp,\n\t\t\t\tport: this.localPort,\n\t\t\t\tmode: this.encryptionMode,\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate handleSessionDescription(d: Record<string, unknown>): void {\n\t\tconst keyArray = d[\"secret_key\"] as number[];\n\t\tthis.secretKey = Buffer.from(keyArray);\n\t\tthis.encryptionMode = (d[\"mode\"] as string) as EncryptionMode;\n\n\t\tthis.sequence = 0;\n\t\tthis.timestamp = 0;\n\t\tthis.nonceCounter = 0;\n\n\t\tthis.transitionTo(VoiceConnectionState.Ready);\n\t\tthis.emit(\"ready\");\n\n\t\t// Send speaking\n\t\tthis.setSpeaking(1);\n\t}\n\n\tprivate handleSpeaking(d: Record<string, unknown>): void {\n\t\tconst userId = d[\"user_id\"] as string;\n\t\tconst ssrc = d[\"ssrc\"] as number;\n\t\tthis.receiver.mapSsrcToUser(ssrc, userId);\n\t}\n\n\tprivate handleClientConnect(d: Record<string, unknown>): void {\n\t\tconst userId = d[\"user_id\"] as string;\n\t\tconst audioSsrc = d[\"audio_ssrc\"] as number;\n\t\tif (audioSsrc) {\n\t\t\tthis.receiver.mapSsrcToUser(audioSsrc, userId);\n\t\t}\n\t}\n\n\tprivate handleClientDisconnect(d: Record<string, unknown>): void {\n\t\tconst userId = d[\"user_id\"] as string;\n\t\tthis.receiver.removeUser(userId);\n\t}\n\n\tprivate handleHello(d: Record<string, unknown>): void {\n\t\tconst interval = d[\"heartbeat_interval\"] as number;\n\t\tthis.startHeartbeat(interval);\n\t}\n\n\tprivate handleHeartbeatAck(_d: Record<string, unknown>): void {\n\t\tthis.missedHeartbeats = 0;\n\t\tthis.lastHeartbeatAck = Date.now();\n\t}\n\n\tprivate startHeartbeat(intervalMs: number): void {\n\t\tthis.stopHeartbeat();\n\t\tthis.missedHeartbeats = 0;\n\n\t\tthis.heartbeatInterval = setInterval(() => {\n\t\t\tif (this.missedHeartbeats >= HEARTBEAT_MAX_MISSED) {\n\t\t\t\tthis.ws?.close(4009);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tthis.heartbeatNonce = Date.now();\n\t\t\tthis.wsSend(3, this.heartbeatNonce);\n\t\t\tthis.missedHeartbeats++;\n\t\t}, intervalMs);\n\t}\n\n\tprivate stopHeartbeat(): void {\n\t\tif (this.heartbeatInterval) {\n\t\t\tclearInterval(this.heartbeatInterval);\n\t\t\tthis.heartbeatInterval = undefined;\n\t\t}\n\t}\n\n\t/**\n\t * Set the speaking flags.\n\t *\n\t * @example\n\t * ```ts\n\t * connection.setSpeaking(1); // speaking\n\t * ```\n\t */\n\tsetSpeaking(flags: number): void {\n\t\tthis.wsSend(5, {\n\t\t\tspeaking: flags,\n\t\t\tdelay: 0,\n\t\t\tssrc: this.ssrc,\n\t\t});\n\t}\n\n\tprivate wsSend(op: number, d: unknown): void {\n\t\tif (this.ws?.readyState === WebSocket.OPEN) {\n\t\t\tthis.ws.send(JSON.stringify({ op, d }));\n\t\t}\n\t}\n\n\tprivate transitionTo(newState: VoiceConnectionState): void {\n\t\tconst oldState = this._state;\n\t\tif (oldState === newState) {\n\t\t\treturn;\n\t\t}\n\t\tthis._state = newState;\n\t\tthis.emit(\"stateChange\", oldState, newState);\n\t}\n\n\tprivate cleanup(): void {\n\t\tthis.stopHeartbeat();\n\n\t\tif (this.audioThread) {\n\t\t\tthis.audioThread.stop();\n\t\t\tthis.audioThread = undefined;\n\t\t}\n\n\t\tif (this.ws) {\n\t\t\tthis.ws.removeAllListeners();\n\t\t\tthis.ws.close();\n\t\t\tthis.ws = undefined;\n\t\t}\n\n\t\tif (this.udpSocket) {\n\t\t\tthis.udpSocket.removeAllListeners();\n\t\t\tthis.udpSocket.close();\n\t\t\tthis.udpSocket = undefined;\n\t\t}\n\n\t\tthis.secretKey = undefined;\n\t}\n}\n","import { EventEmitter } from \"node:events\";\nimport { AudioPlayerState, type AudioPlayerEvents } from \"./types.js\";\nimport type { VoiceConnection } from \"./connection.js\";\nimport { AudioThread } from \"@harmonia-audio/native\";\nimport { HarmoniaVoiceError } from \"./errors.js\";\n\n/** Represents a playable audio source. */\nexport interface PlayableResource {\n\tread(): Buffer | null;\n\treadonly ended: boolean;\n\tdestroy(): void;\n}\n\n/**\n * Options for creating an audio player.\n *\n * @example\n * ```ts\n * const player = new AudioPlayer({ noSubscriber: 'pause' });\n * ```\n */\nexport interface AudioPlayerOptions {\n\treadonly noSubscriber?: \"pause\" | \"stop\" | \"play\";\n}\n\n/**\n * Plays audio resources and dispatches packets to voice connections.\n *\n * @example\n * ```ts\n * import { AudioPlayer } from '@harmonia/voice';\n *\n * const player = new AudioPlayer();\n * player.play(resource);\n *\n * player.on('idle', () => {\n * console.log('Playback finished');\n * });\n * ```\n */\nexport class AudioPlayer extends EventEmitter {\n\tprivate _state: AudioPlayerState = AudioPlayerState.Idle;\n\tprivate resource: PlayableResource | undefined;\n\tprivate connections: Set<VoiceConnection> = new Set();\n\tprivate audioThread: AudioThread | undefined;\n\tprivate readonly noSubscriberBehavior: \"pause\" | \"stop\" | \"play\";\n\n\tconstructor(options: AudioPlayerOptions = {}) {\n\t\tsuper();\n\t\tthis.noSubscriberBehavior = options.noSubscriber ?? \"pause\";\n\t}\n\n\t/**\n\t * Current player state.\n\t *\n\t * @example\n\t * ```ts\n\t * if (player.state === AudioPlayerState.Playing) { ... }\n\t * ```\n\t */\n\tget state(): AudioPlayerState {\n\t\treturn this._state;\n\t}\n\n\t/**\n\t * Start playing an audio resource.\n\t *\n\t * @example\n\t * ```ts\n\t * player.play(audioResource);\n\t * ```\n\t */\n\tplay(resource: PlayableResource): void {\n\t\tthis.stopInternal();\n\t\tthis.resource = resource;\n\t\tthis.transitionTo(AudioPlayerState.Playing);\n\t\tthis.startPlaybackLoop();\n\t}\n\n\t/**\n\t * Pause playback.\n\t *\n\t * @example\n\t * ```ts\n\t * player.pause();\n\t * ```\n\t */\n\tpause(): void {\n\t\tif (this._state === AudioPlayerState.Playing) {\n\t\t\tthis.transitionTo(AudioPlayerState.Paused);\n\t\t}\n\t}\n\n\t/**\n\t * Resume playback.\n\t *\n\t * @example\n\t * ```ts\n\t * player.resume();\n\t * ```\n\t */\n\tresume(): void {\n\t\tif (\n\t\t\tthis._state === AudioPlayerState.Paused ||\n\t\t\tthis._state === AudioPlayerState.AutoPaused\n\t\t) {\n\t\t\tthis.transitionTo(AudioPlayerState.Playing);\n\t\t}\n\t}\n\n\t/**\n\t * Stop playback and release the resource.\n\t *\n\t * @example\n\t * ```ts\n\t * player.stop();\n\t * ```\n\t */\n\tstop(): void {\n\t\tthis.stopInternal();\n\t\tthis.transitionTo(AudioPlayerState.Idle);\n\t\tthis.emit(\"idle\");\n\t}\n\n\t/** @internal */\n\taddConnection(connection: VoiceConnection): void {\n\t\tthis.connections.add(connection);\n\t}\n\n\t/** @internal */\n\tremoveConnection(connection: VoiceConnection): void {\n\t\tthis.connections.delete(connection);\n\t}\n\n\tprivate startPlaybackLoop(): void {\n\t\tif (!this.audioThread) {\n\t\t\tthis.audioThread = new AudioThread();\n\t\t}\n\t\t\n\t\tthis.audioThread.start(() => {\n\t\t\tthis.processFrame();\n\t\t});\n\t}\n\n\tprivate processFrame(): void {\n\t\tif (this._state !== AudioPlayerState.Playing) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!this.resource) {\n\t\t\tthis.stop();\n\t\t\treturn;\n\t\t}\n\n\t\tif (this.resource.ended) {\n\t\t\tthis.stopInternal();\n\t\t\tthis.transitionTo(AudioPlayerState.Idle);\n\t\t\tthis.emit(\"idle\");\n\t\t\treturn;\n\t\t}\n\n\t\tconst packet = this.resource.read();\n\t\tif (!packet) {\n\t\t\treturn;\n\t\t}\n\n\t\tfor (const connection of this.connections) {\n\t\t\tconnection.sendOpusPacket(packet);\n\t\t}\n\t}\n\n\tprivate stopInternal(): void {\n\t\tif (this.audioThread) {\n\t\t\tthis.audioThread.stop();\n\t\t\tthis.audioThread = undefined;\n\t\t}\n\t\tif (this.resource) {\n\t\t\tthis.resource.destroy();\n\t\t\tthis.resource = undefined;\n\t\t}\n\t}\n\n\tprivate transitionTo(newState: AudioPlayerState): void {\n\t\tconst oldState = this._state;\n\t\tif (oldState === newState) {\n\t\t\treturn;\n\t\t}\n\t\tthis._state = newState;\n\t\tthis.emit(\"stateChange\", oldState, newState);\n\t}\n}\n","import { VoiceConnection, type VoiceConnectionOptions } from \"./connection.js\";\nimport type { DiscordGatewayAdapterCreator } from \"./adapter.js\";\nimport { getVoiceConnection } from \"./store.js\";\n\n/**\n * Options for joining a voice channel.\n *\n * @example\n * ```ts\n * const connection = joinVoiceChannel({\n * guildId: '123',\n * channelId: '456',\n * adapterCreator: guild.voiceAdapterCreator,\n * });\n * ```\n */\nexport interface JoinVoiceChannelOptions {\n\treadonly guildId: string;\n\treadonly channelId: string;\n\treadonly selfDeaf?: boolean;\n\treadonly selfMute?: boolean;\n\treadonly adapterCreator: DiscordGatewayAdapterCreator;\n}\n\n/**\n * Join a Discord voice channel and return a VoiceConnection.\n *\n * @example\n * ```ts\n * import { joinVoiceChannel } from '@harmonia/voice';\n *\n * const connection = joinVoiceChannel({\n * guildId: interaction.guildId,\n * channelId: member.voice.channelId,\n * adapterCreator: guild.voiceAdapterCreator,\n * });\n * ```\n */\nexport function joinVoiceChannel(options: JoinVoiceChannelOptions): VoiceConnection {\n\tconst existing = getVoiceConnection(options.guildId);\n\tif (existing) {\n\t\texisting.destroy();\n\t}\n\n\treturn new VoiceConnection(options);\n}\n","import { Readable } from \"node:stream\";\nimport { OpusEncoder, OpusEncoderStream } from \"@harmonia-audio/codec\";\nimport type { PlayableResource } from \"./player.js\";\n\n/**\n * Options for creating an audio resource.\n *\n * @example\n * ```ts\n * const resource = createAudioResource('./song.pcm', {\n * inputType: 'pcm',\n * });\n * ```\n */\nexport interface AudioResourceOptions {\n\treadonly inputType?: \"opus\" | \"pcm\" | \"raw\";\n\treadonly inlineVolume?: boolean;\n\treadonly signal?: AbortSignal;\n}\n\n/**\n * Audio resource that can be played by an AudioPlayer.\n *\n * @example\n * ```ts\n * const resource = createAudioResource(readableStream, { inputType: 'pcm' });\n * player.play(resource);\n * ```\n */\nexport class AudioResource implements PlayableResource {\n\tprivate readonly stream: Readable;\n\tprivate readonly packets: Buffer[] = [];\n\tprivate _ended = false;\n\tprivate draining = false;\n\n\tconstructor(stream: Readable) {\n\t\tthis.stream = stream;\n\n\t\tstream.on(\"data\", (chunk: Buffer) => {\n\t\t\tthis.packets.push(chunk);\n\t\t});\n\n\t\tstream.on(\"end\", () => {\n\t\t\tthis._ended = true;\n\t\t});\n\n\t\tstream.on(\"error\", () => {\n\t\t\tthis._ended = true;\n\t\t});\n\t}\n\n\t/**\n\t * Read the next Opus packet.\n\t *\n\t * @example\n\t * ```ts\n\t * const packet = resource.read();\n\t * ```\n\t */\n\tread(): Buffer | null {\n\t\treturn this.packets.shift() ?? null;\n\t}\n\n\t/** Whether the resource has finished producing packets. */\n\tget ended(): boolean {\n\t\treturn this._ended && this.packets.length === 0;\n\t}\n\n\t/**\n\t * Destroy the resource and release underlying streams.\n\t *\n\t * @example\n\t * ```ts\n\t * resource.destroy();\n\t * ```\n\t */\n\tdestroy(): void {\n\t\tthis.stream.destroy();\n\t\tthis.packets.length = 0;\n\t\tthis._ended = true;\n\t}\n}\n\n/**\n * Create an AudioResource from various input types.\n *\n * @example\n * ```ts\n * import { createAudioResource } from '@harmonia/voice';\n * import { createReadStream } from 'fs';\n *\n * const resource = createAudioResource(createReadStream('./audio.pcm'), {\n * inputType: 'pcm',\n * });\n * ```\n */\nexport function createAudioResource(\n\tinput: Readable | string | Buffer,\n\toptions: AudioResourceOptions = {},\n): AudioResource {\n\tlet readable: Readable;\n\n\tif (typeof input === \"string\") {\n\t\tconst { createReadStream } = require(\"node:fs\") as typeof import(\"node:fs\");\n\t\treadable = createReadStream(input);\n\t} else if (Buffer.isBuffer(input)) {\n\t\treadable = Readable.from(input);\n\t} else {\n\t\treadable = input;\n\t}\n\n\tif (options.inputType === \"opus\") {\n\t\treturn new AudioResource(readable);\n\t}\n\n\t// PCM input: pipe through Opus encoder\n\tconst encoder = new OpusEncoderStream({\n\t\tsampleRate: 48000,\n\t\tchannels: 2,\n\t\tapplication: \"audio\",\n\t});\n\n\treadable.pipe(encoder);\n\n\tif (options.signal) {\n\t\toptions.signal.addEventListener(\n\t\t\t\"abort\",\n\t\t\t() => {\n\t\t\t\treadable.destroy();\n\t\t\t\tencoder.destroy();\n\t\t\t},\n\t\t\t{ once: true },\n\t\t);\n\t}\n\n\treturn new AudioResource(encoder);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@harmonia-audio/voice",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "Discord voice connection management for harmonia",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -24,8 +24,8 @@
24
24
  ],
25
25
  "dependencies": {
26
26
  "ws": "^8.18.0",
27
- "@harmonia-audio/codec": "0.1.5",
28
- "@harmonia-audio/native": "0.1.5"
27
+ "@harmonia-audio/codec": "0.1.7",
28
+ "@harmonia-audio/native": "0.1.7"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@types/ws": "^8.5.13",