{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "orc-male-goodbye-02",
  "type": "registry:block",
  "title": "Orc Male Goodbye 02",
  "author": "Kenney <https://kenney.nl>",
  "description": "Orc Male Goodbye 02 sound effect.",
  "files": [
    {
      "path": "registry/soundcn/sounds/orc-male-goodbye-02/orc-male-goodbye-02.ts",
      "content": "import type { SoundAsset } from \"@/lib/sound-types\";\n\nexport const orcMaleGoodbye02Sound: SoundAsset = {\n  name: \"orc-male-goodbye-02\",\n  dataUri: \"data:audio/mpeg;base64,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sbQI3toWEhUOKPoq//tSxLKASokLS6wwRWFEGmgpkwnofG02hwN+QrJS5T2QDK/FggaEDU0wJXEAnIi8SziFqyoCzZOH5QHx4HK1zunKpDARAg/f+2yqVn9UdFUajoLQsrgirb0IIHcqNq6P9iHGMRYDJle8THiMYAIEAemasachEvK3AgZ8cynSZeTGSrwzzhZcMNVM3P2U7hMoqdUmzmCJ6pa52ZWqhoiD74VqklaiaJtYv/bmmUqX2mr8kNLM1BwGn18FZ0RPPFvrK2oqAABgQ0vwECXiLB2houT/+1LEvYAM1R087LBNyVwVJrGUlWgicKRiCSsAw+monLawCICYBlyajRKAaEoiCSyIlLPIkv9YCB0rUBf/1FR4SPf2nuz/9NzOrz3TTEFNRTMuMTAwVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVf/7UsS8gEsU8yoMsE0BVpYkJZeguFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV//tSxMMDyJxLCkwwwxAAADSAAAAEVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVU=\",\n  duration: 0.821,\n  format: \"mp3\",\n  license: \"CC0\",\n  author: \"Kenney\",\n};\n",
      "type": "registry:lib"
    },
    {
      "path": "registry/soundcn/lib/sound-types.ts",
      "content": "export interface SoundAsset {\r\n  /** Unique identifier for the sound */\r\n  name: string;\r\n  /** Base64-encoded data URI (data:audio/mpeg;base64,...) */\r\n  dataUri: string;\r\n  /** Duration in seconds */\r\n  duration: number;\r\n  /** Audio format */\r\n  format: \"mp3\" | \"wav\" | \"ogg\";\r\n  /** License identifier */\r\n  license: \"CC0\" | \"OGA-BY\" | \"MIT\";\r\n  /** Original author/creator */\r\n  author: string;\r\n}\r\n\r\nexport interface UseSoundOptions {\r\n  /** Volume level from 0 to 1. Default: 1 */\r\n  volume?: number;\r\n  /** Playback speed multiplier. Default: 1 */\r\n  playbackRate?: number;\r\n  /** If true, calling play() stops current playback first. Default: false */\r\n  interrupt?: boolean;\r\n  /** If false, play() does nothing. Useful for user preferences. Default: true */\r\n  soundEnabled?: boolean;\r\n  /** Called when playback starts */\r\n  onPlay?: () => void;\r\n  /** Called when playback ends naturally */\r\n  onEnd?: () => void;\r\n  /** Called when pause() is called */\r\n  onPause?: () => void;\r\n  /** Called when stop() is called */\r\n  onStop?: () => void;\r\n}\r\n\r\nexport type PlayFunction = (overrides?: {\r\n  volume?: number;\r\n  playbackRate?: number;\r\n}) => void;\r\n\r\nexport interface SoundControls {\r\n  stop: () => void;\r\n  pause: () => void;\r\n  isPlaying: boolean;\r\n  duration: number | null;\r\n  sound: SoundAsset;\r\n}\r\n\r\nexport type UseSoundReturn = readonly [PlayFunction, SoundControls];\r\n",
      "type": "registry:lib"
    },
    {
      "path": "registry/soundcn/lib/sound-engine.ts",
      "content": "let audioContext: AudioContext | null = null;\nconst bufferCache = new Map<string, AudioBuffer>();\n\nexport function getAudioContext(): AudioContext {\n  if (!audioContext) {\n    audioContext = new AudioContext();\n  }\n  return audioContext;\n}\n\nexport async function decodeAudioData(dataUri: string): Promise<AudioBuffer> {\n  const cached = bufferCache.get(dataUri);\n  if (cached) return cached;\n\n  const ctx = getAudioContext();\n  const base64 = dataUri.split(\",\")[1];\n  const binaryString = atob(base64);\n  const bytes = new Uint8Array(binaryString.length);\n  for (let i = 0; i < binaryString.length; i++) {\n    bytes[i] = binaryString.charCodeAt(i);\n  }\n\n  const audioBuffer = await ctx.decodeAudioData(bytes.buffer.slice(0));\n  bufferCache.set(dataUri, audioBuffer);\n  return audioBuffer;\n}\n\nexport interface PlaySoundOptions {\n  volume?: number;\n  playbackRate?: number;\n  onEnd?: () => void;\n}\n\nexport interface SoundPlayback {\n  stop: () => void;\n}\n\nexport async function playSound(\n  dataUri: string,\n  options: PlaySoundOptions = {}\n): Promise<SoundPlayback> {\n  const { volume = 1, playbackRate = 1, onEnd } = options;\n  const ctx = getAudioContext();\n  if (ctx.state === \"suspended\") {\n    await ctx.resume();\n  }\n\n  const buffer = await decodeAudioData(dataUri);\n  const source = ctx.createBufferSource();\n  const gain = ctx.createGain();\n\n  source.buffer = buffer;\n  source.playbackRate.value = playbackRate;\n  gain.gain.value = volume;\n\n  source.connect(gain);\n  gain.connect(ctx.destination);\n\n  source.onended = () => {\n    onEnd?.();\n  };\n\n  source.start(0);\n\n  return {\n    stop: () => {\n      try {\n        source.stop();\n      } catch {\n        // No-op if already stopped.\n      }\n    },\n  };\n}\n",
      "type": "registry:lib"
    }
  ],
  "meta": {
    "duration": 0.821,
    "format": "mp3",
    "sizeKb": 7,
    "license": "CC0",
    "tags": [
      "orc",
      "male",
      "goodbye",
      "02"
    ]
  },
  "categories": [
    "warcraft",
    "voice"
  ]
}