{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "impact-punch-medium-004",
  "type": "registry:block",
  "title": "Impact Punch Medium 004",
  "author": "Kenney <https://kenney.nl>",
  "description": "A clean, medium punch sound, excellent for general game combat feedback, confirming a successful interaction, or a clear button press.",
  "files": [
    {
      "path": "registry/soundcn/sounds/impact-punch-medium-004/impact-punch-medium-004.ts",
      "content": "import type { SoundAsset } from \"@/lib/sound-types\";\n\nexport const impactPunchMedium004Sound: SoundAsset = {\n  name: \"impact-punch-medium-004\",\n  dataUri: \"data:audio/mpeg;base64,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ggxBYwEt4GCJbajfyaSMoOVnDaFSI/LOquntjkpGWpVumOVYXy5CkgVmwrJqAIwKbOw4CJsDhJPhm1JIoRArAURlYjcF1ztKKpKu4vG0ZAk22hvOlRg0bsE4kejhMTsAEMJ3dlqhgymI0jcYq+kQEJcGMowu8pChsoT5LhZNjknwUREUCUrv9uxFJBhm+UnBhJQaut0z///BGFFWrNg0FO5MsjAcLiQhJWFoMppmNFbzSOwpvyZyqxYZOtUiOqcQGykR5ZhnRWjts9VP//tSxE+CDZVk+C2kacFup2AZpIxgZ9DQyjESmuhLTpBAdIqGCMQPUQ+YoYkddqEuqf3+rLqZHkZhKcgtJ+WqN/kYiND3tfNi0OPLGa0mi8C3Lp7CEm/2LZNIDjyU8JrmLltIFk7RTeSxTRHszVi8bTI3DIe0zR3L8tfY+HwyZTENZRoug8BQgXYeDVfPETKkuOytpo3BzxpaJGZQFpcZZI06HBO8sy2bBkkMprreya2GJoVsci2oe2u6dEU1aYNU0gPTdalWERmJzo4DDUGyweX/+1LESQPKjOb6DRhtQTmU3gGkjTge/SSWdEueLYhW7rd9WeiaSjo8ijE8EDN03ADjJ9JgzjhQUozDub7OsmoAJIAwVDBtMUsBZgLITOTQoUStGiWCyNnwlGuTN1kWVl2aRNdND+qwbIY7/SzAWbzArkVMDYhFFQ5oEUqkOBZhU6EIJAAX6hgiGCABAGEzkrkUC5d8rDAzM37MGBMMFD6A1HGee2ppp26BALJpvmef//RxIlX/lE4kSpiWij58vDEoTEbDfTP1EywjegNAQKimgv/7UsRVgwmAqN4O4SFJKBUaheYZaQogIxS37FkAiFjAVb0Dff+XxMDgPQbhyHWOMxi+FwUJPEMv///+rEMlOtBpg0FUnE5tzAM/hD8weDY47Cass6bw48yXmMkRmAJAFjiAjpIKLsLckkb//ztclEoVhFJZdq06VIh2kktb///w2qKirYXrAyp1TbafzbtFBBbjcONC4K1mguu7gXGCpKaMI0C60XtsLqJyx6I8ViNHrKZOljEZPKxEaPKxG6WKYzoCrKaOlVidHlYydLFMZHCU//tSxGiDSPh22g7l4YEbjttJ3LwgJSB8EYGFglYMqFLFqlUhaMqAVC1SNSqOmVUDpGIyMFYPpgrBlIxIWirBlU6wBLeK6ZhzqATiw4JBiri82TjSwyZBYWEZkW+P48U62x+gV/F+pn/4pxVvUj+3SLM1C6f/irVMQU1FMy4xMDBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVX/+1LEfwMN1M78bCRliNSE3Uj0mEBVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVQ==\",\n  duration: 0.543,\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.543,
    "format": "mp3",
    "sizeKb": 5,
    "license": "CC0",
    "tags": [
      "impact",
      "punch",
      "medium",
      "004"
    ],
    "keywords": [
      "impact",
      "punch",
      "medium",
      "clean",
      "game combat",
      "successful interaction",
      "button press",
      "feedback",
      "ui",
      "solid",
      "crisp",
      "thud",
      "positive",
      "action",
      "confirm",
      "select",
      "game sfx",
      "interface",
      "response",
      "strike"
    ]
  },
  "categories": [
    "impact"
  ]
}