{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "footstep-snow-004",
  "type": "registry:block",
  "title": "Footstep Snow 004",
  "author": "Kenney <https://kenney.nl>",
  "description": "A crunching footstep sound on snow, suitable for indicating cold environment movement, winter exploration, or navigation in a frosty setting.",
  "files": [
    {
      "path": "registry/soundcn/sounds/footstep-snow-004/footstep-snow-004.ts",
      "content": "import type { SoundAsset } from \"@/lib/sound-types\";\n\nexport const footstepSnow004Sound: SoundAsset = {\n  name: \"footstep-snow-004\",\n  dataUri: \"data:audio/mpeg;base64,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oKejeYz6UjpCpSIlQs17DwDBcGsBLDckeeEvT34ope/+x//57/o3VjH/Ux4AIaI8BSO86IEWOyUgo04KSbTQZBQKuxKCqgVdcdDUsVKu/aVGnZPfT5ERI/Lblu8qCvh1usZw7yvkafOh0ELEROpKAbTAJwBYANGyxSBg//tSxCeBB7AlDk4gwkCKAlvZ/BgICVbX4v//9bP//R////t//+g/mwEKMB/AMzJrOcUodRqXS7QhKqNsPwGSzf/////R////t//+g/mIELMBDAEwW4uM3Vg4oASQwPkKf/////o////2///RP6OAnDANwFY3sjAXEkVbmDUIZmhxYKhJ//////0f///7f//oP5MAvwEAigLAOeXbZe5cbCyBAEAQBBP/////0f///7f//oVMQU1FMy4xMDBVVVVVH/TwwG4AXOd8PRBUlxOlWvX/+1LEVYPEsB7YD+UggIGC2wH8GAj1gaBp//////6P///9v//0H8kAORgPwBcZaIJlFk2ALojobZFb1AifMs/////9H///+3//6ExBTUUzLjEwMFVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVU/pIBzFQBsJxDQnrZaYP/7UsSQg8SAGtgP5SCAigLbAfwYEArDoaI//////0f///7f//oP5cBDjADwDsxOGwj20RF1uwIyqzL3TBMt/////9H///+3//6FTEFNRTMuMTAwVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVT+cgOcwFkAyPGQOPac5gE0QUc1k//////o////2///QfzYBTGBa//tSxMSDxCQW2A/l4ACTg1sB/KQQgAp61l6hqoQAuk28tYewOKOPPFDG/unuQaGn3//zZBjnwLsRTuiI8JXu8H//3f///1///uU+SgYdMTSHyjGAAvoweQHSMCSBATBIwKkwIcB3MAPAPDALAAIAACwYAAID7kEJeQGseBJ2xOIYoIJSKQ4boSdEFXoeh6Hq+JljVz5lWFIxWZp2VwaoT19Zyftsjx0pF53nFu//9X+v/X////rAACAAABa8S5MgGUx8F3CkZdNMcRh5H2pWb+H/+1LEwwPDyBLYD+TAQJED2wH8JBDACBi/9+qqjQALhz104FgRYjIVJDbfqsy4TICaPYG8Hf/8qxwvMxnUT06CUpzOsfx1W2OCsqcRvHkbsM0f//48OP53kRIJ1FKs5mdQ///9kljv90xE6lVKK0nlOrmt1////4kO7/ER5rebp1wVzcolzGYWBWwP/////uPSkTN77+6aiXcmJ2wyq1qesT9ihuLC4///////+8fFP///////////2LCub3Io4cSrXOBiWkQCixIBVdmOrQokg//7UsTPA8P8FtgP5QBA6pAbAfygGAE2oYCFGFAVgZfKnQaeCx6d/PTv4KqDqwaPAq4OeVOiJ4mDqw0r//DSg6sRPEs94lOg08TB1YaLKkxBTUUzLjEwMKqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqq//tSxP+ADYiA2BX3gAMHOyJXOPAAqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqr/+1LExoPJpFyOHGGAAAAANIAAAASqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqg==\",\n  duration: 0.371,\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.371,
    "format": "mp3",
    "sizeKb": 4,
    "license": "CC0",
    "tags": [
      "footstep",
      "snow",
      "004"
    ],
    "keywords": [
      "footstep",
      "snow",
      "crunch",
      "cold",
      "winter",
      "movement",
      "frosty",
      "walk",
      "step",
      "crisp",
      "icy",
      "outdoor",
      "progress",
      "navigation",
      "character",
      "environment",
      "short",
      "unique",
      "brisk",
      "trek",
      "frozen"
    ]
  },
  "categories": [
    "footstep"
  ]
}