{"version":3,"sources":["../src/components/visualization/agent-multiband-audio-visualizer.tsx"],"sourcesContent":["/*\n *  Copyright (c) 2024. Rapida\n *\n *  Permission is hereby granted, free of charge, to any person obtaining a copy\n *  of this software and associated documentation files (the \"Software\"), to deal\n *  in the Software without restriction, including without limitation the rights\n *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\n *  copies of the Software, and to permit persons to whom the Software is\n *  furnished to do so, subject to the following conditions:\n *\n *  The above copyright notice and this permission notice shall be included in\n *  all copies or substantial portions of the Software.\n *\n *  THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\n *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\n *  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\n *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\n *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\n *  THE SOFTWARE.\n *\n *  Author: Prashant <prashant@rapida.ai>\n *\n */\nimport { cn } from \"@/rapida/styles\";\nimport { useEffect, useState } from \"react\";\n\n/**\n * @beta\n */\nexport type AgentState =\n  | \"disconnected\"\n  | \"connecting\"\n  | \"initializing\"\n  | \"listening\"\n  | \"thinking\"\n  | \"speaking\";\n\ntype AgentMultibandAudioVisualizerProps = {\n  classNames?: string;\n  state: AgentState;\n  barWidth: number;\n  minBarHeight: number;\n  maxBarHeight: number;\n  barColor?: string;\n  frequencies: Float32Array[] | number[][];\n};\n\nexport const AgentMultibandAudioVisualizer = ({\n  classNames,\n  state,\n  barWidth,\n  minBarHeight,\n  maxBarHeight,\n  barColor = \"bg-white\",\n  frequencies,\n}: AgentMultibandAudioVisualizerProps) => {\n  const summedFrequencies = frequencies.map((bandFrequencies) => {\n    const sum = (bandFrequencies as number[]).reduce((a, b) => a + b, 0);\n    return Math.sqrt(sum / bandFrequencies.length);\n  });\n\n  const [thinkingIndex, setThinkingIndex] = useState(\n    Math.floor(summedFrequencies.length / 2)\n  );\n  const [thinkingDirection, setThinkingDirection] = useState<\"left\" | \"right\">(\n    \"right\"\n  );\n\n  useEffect(() => {\n    if (state !== \"thinking\") {\n      setThinkingIndex(Math.floor(summedFrequencies.length / 2));\n      return;\n    }\n    const timeout = setTimeout(() => {\n      if (thinkingDirection === \"right\") {\n        if (thinkingIndex === summedFrequencies.length - 1) {\n          setThinkingDirection(\"left\");\n          setThinkingIndex((prev) => prev - 1);\n        } else {\n          setThinkingIndex((prev) => prev + 1);\n        }\n      } else {\n        if (thinkingIndex === 0) {\n          setThinkingDirection(\"right\");\n          setThinkingIndex((prev) => prev + 1);\n        } else {\n          setThinkingIndex((prev) => prev - 1);\n        }\n      }\n    }, 200);\n\n    return () => clearTimeout(timeout);\n  }, [state, summedFrequencies.length, thinkingDirection, thinkingIndex]);\n\n  return (\n    <div className={cn(classNames, \"flex flex-row items-center\")}>\n      {summedFrequencies.map((frequency, index) => {\n        const isCenter = index === Math.floor(summedFrequencies.length / 2);\n        let transform;\n\n        return (\n          <div\n            className={cn(\n              barColor,\n              \"rounded-full\",\n              isCenter && state === \"listening\" ? \"animate-pulse\" : \"\"\n            )}\n            key={\"frequency-\" + index}\n            style={{\n              height:\n                minBarHeight + frequency * (maxBarHeight - minBarHeight) + \"px\",\n              width: barWidth + \"px\",\n              transition:\n                \"background-color 0.35s ease-out, transform 0.25s ease-out\",\n              transform: transform,\n            }}\n          ></div>\n        );\n      })}\n    </div>\n  );\n};\n"],"mappings":";;;;;AAyBA,SAAS,WAAW,gBAAgB;AA6E1B;AAtDH,IAAM,gCAAgC,CAAC;AAAA,EAC5C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,WAAW;AAAA,EACX;AACF,MAA0C;AACxC,QAAM,oBAAoB,YAAY,IAAI,CAAC,oBAAoB;AAC7D,UAAM,MAAO,gBAA6B,OAAO,CAAC,GAAG,MAAM,IAAI,GAAG,CAAC;AACnE,WAAO,KAAK,KAAK,MAAM,gBAAgB,MAAM;AAAA,EAC/C,CAAC;AAED,QAAM,CAAC,eAAe,gBAAgB,IAAI;AAAA,IACxC,KAAK,MAAM,kBAAkB,SAAS,CAAC;AAAA,EACzC;AACA,QAAM,CAAC,mBAAmB,oBAAoB,IAAI;AAAA,IAChD;AAAA,EACF;AAEA,YAAU,MAAM;AACd,QAAI,UAAU,YAAY;AACxB,uBAAiB,KAAK,MAAM,kBAAkB,SAAS,CAAC,CAAC;AACzD;AAAA,IACF;AACA,UAAM,UAAU,WAAW,MAAM;AAC/B,UAAI,sBAAsB,SAAS;AACjC,YAAI,kBAAkB,kBAAkB,SAAS,GAAG;AAClD,+BAAqB,MAAM;AAC3B,2BAAiB,CAAC,SAAS,OAAO,CAAC;AAAA,QACrC,OAAO;AACL,2BAAiB,CAAC,SAAS,OAAO,CAAC;AAAA,QACrC;AAAA,MACF,OAAO;AACL,YAAI,kBAAkB,GAAG;AACvB,+BAAqB,OAAO;AAC5B,2BAAiB,CAAC,SAAS,OAAO,CAAC;AAAA,QACrC,OAAO;AACL,2BAAiB,CAAC,SAAS,OAAO,CAAC;AAAA,QACrC;AAAA,MACF;AAAA,IACF,GAAG,GAAG;AAEN,WAAO,MAAM,aAAa,OAAO;AAAA,EACnC,GAAG,CAAC,OAAO,kBAAkB,QAAQ,mBAAmB,aAAa,CAAC;AAEtE,SACE,oBAAC,SAAI,WAAW,GAAG,YAAY,4BAA4B,GACxD,4BAAkB,IAAI,CAAC,WAAW,UAAU;AAC3C,UAAM,WAAW,UAAU,KAAK,MAAM,kBAAkB,SAAS,CAAC;AAClE,QAAI;AAEJ,WACE;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,UACT;AAAA,UACA;AAAA,UACA,YAAY,UAAU,cAAc,kBAAkB;AAAA,QACxD;AAAA,QAEA,OAAO;AAAA,UACL,QACE,eAAe,aAAa,eAAe,gBAAgB;AAAA,UAC7D,OAAO,WAAW;AAAA,UAClB,YACE;AAAA,UACF;AAAA,QACF;AAAA;AAAA,MARK,eAAe;AAAA,IASrB;AAAA,EAEL,CAAC,GACH;AAEJ;","names":[]}