[{"data":1,"prerenderedAt":840},["ShallowReactive",2],{"navigation_docs":3,"-guide-data-modes":81,"-guide-data-modes-surround":835},[4,41,62],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":40},"Guide","i-lucide-book-open","\u002Fguide","1.guide",[10,15,20,25,30,35],{"title":11,"path":12,"stem":13,"icon":14},"Introduction","\u002Fguide\u002Fintroduction","1.guide\u002F1.introduction","i-lucide-house",{"title":16,"path":17,"stem":18,"icon":19},"How it works","\u002Fguide\u002Fhow-it-works","1.guide\u002F2.how-it-works","i-lucide-workflow",{"title":21,"path":22,"stem":23,"icon":24},"Data modes","\u002Fguide\u002Fdata-modes","1.guide\u002F3.data-modes","i-lucide-git-fork",{"title":26,"path":27,"stem":28,"icon":29},"Options","\u002Fguide\u002Foptions","1.guide\u002F4.options","i-lucide-settings-2",{"title":31,"path":32,"stem":33,"icon":34},"Gradients","\u002Fguide\u002Fgradients","1.guide\u002F5.gradients","i-lucide-palette",{"title":36,"path":37,"stem":38,"icon":39},"WebSocket protocol","\u002Fguide\u002Fwebsocket-protocol","1.guide\u002F6.websocket-protocol","i-lucide-radio",false,{"title":42,"icon":43,"path":44,"stem":45,"children":46,"page":40},"Core","i-lucide-box","\u002Fcore","2.core",[47,52,57],{"title":48,"path":49,"stem":50,"icon":51},"Installation","\u002Fcore\u002Finstallation","2.core\u002F1.installation","i-lucide-download",{"title":53,"path":54,"stem":55,"icon":56},"API reference","\u002Fcore\u002Fapi","2.core\u002F2.api","i-lucide-code",{"title":58,"path":59,"stem":60,"icon":61},"Audio engines","\u002Fcore\u002Faudio-engines","2.core\u002F3.audio-engines","i-lucide-audio-lines",{"title":63,"icon":64,"path":65,"stem":66,"children":67,"page":40},"Vue","i-simple-icons-vuedotjs","\u002Fvue","3.vue",[68,71,76],{"title":48,"path":69,"stem":70,"icon":51},"\u002Fvue\u002Finstallation","3.vue\u002F1.installation",{"title":72,"path":73,"stem":74,"icon":75},"Props, events & methods","\u002Fvue\u002Fprops","3.vue\u002F2.props","i-lucide-sliders-horizontal",{"title":77,"path":78,"stem":79,"icon":80},"Composables","\u002Fvue\u002Fcomposables","3.vue\u002F3.composables","i-lucide-plug",{"id":82,"title":21,"body":83,"description":828,"extension":829,"links":830,"meta":831,"navigation":832,"path":22,"seo":833,"stem":23,"__hash__":834},"docs\u002F1.guide\u002F3.data-modes.md",{"type":84,"value":85,"toc":823},"minimark",[86,95,181,186,197,336,340,351,513,527,531,546,792,819],[87,88,89,90,94],"p",{},"The visualizer has one job — render a spectrum — and three ways to get the data, selected\nwith the ",[91,92,93],"code",{},"mode"," option (a prop in Vue, a constructor option in Core).",[96,97,98,114],"table",{},[99,100,101],"thead",{},[102,103,104,108,111],"tr",{},[105,106,107],"th",{},"Mode",[105,109,110],{},"How data arrives",[105,112,113],{},"Use when",[115,116,117,131,158],"tbody",{},[102,118,119,125,128],{},[120,121,122],"td",{},[91,123,124],{},"local",[120,126,127],{},"Captures mic or display audio and computes the FFT in-browser (Rust\u002FWASM)",[120,129,130],{},"You want a zero-backend, client-side visualizer",[102,132,133,143,155],{},[120,134,135,138,139],{},[91,136,137],{},"websocket"," ",[140,141,142],"em",{},"(default)",[120,144,145,146,149,150,154],{},"Connects to ",[91,147,148],{},"websocketUrl"," and reads ",[151,152,153],"strong",{},"pre-computed"," FFT frames",[120,156,157],{},"A server\u002Fdevice already produces FFT data (e.g. a Raspberry Pi)",[102,159,160,165,178],{},[120,161,162],{},[91,163,164],{},"external",[120,166,167,168,171,172,171,175],{},"You pass FFT magnitudes as ",[91,169,170],{},"data"," \u002F ",[91,173,174],{},"dataLeft",[91,176,177],{},"dataRight",[120,179,180],{},"You have your own audio pipeline (Web Audio, another analyser, etc.)",[182,183,185],"h2",{"id":184},"local-mode","Local mode",[87,187,188,189,192,193,196],{},"Set ",[91,190,191],{},"audioSource"," to ",[91,194,195],{},"display"," to capture tab\u002Fsystem audio via screen sharing instead of the\nmicrophone.",[198,199,200,279],"code-group",{},[201,202,207],"pre",{"className":203,"code":204,"filename":42,"language":205,"meta":206,"style":206},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","new FFTVisualizer(canvas, { mode: 'local', audioSource: 'mic', bands: 80 })\n","ts","",[91,208,209],{"__ignoreMap":206},[210,211,214,218,222,226,229,232,236,239,242,245,248,250,253,255,257,260,262,264,267,269,273,276],"span",{"class":212,"line":213},"line",1,[210,215,217],{"class":216},"sMK4o","new",[210,219,221],{"class":220},"s2Zo4"," FFTVisualizer",[210,223,225],{"class":224},"sTEyZ","(canvas",[210,227,228],{"class":216},",",[210,230,231],{"class":216}," {",[210,233,235],{"class":234},"swJcz"," mode",[210,237,238],{"class":216},":",[210,240,241],{"class":216}," '",[210,243,124],{"class":244},"sfazB",[210,246,247],{"class":216},"'",[210,249,228],{"class":216},[210,251,252],{"class":234}," audioSource",[210,254,238],{"class":216},[210,256,241],{"class":216},[210,258,259],{"class":244},"mic",[210,261,247],{"class":216},[210,263,228],{"class":216},[210,265,266],{"class":234}," bands",[210,268,238],{"class":216},[210,270,272],{"class":271},"sbssI"," 80",[210,274,275],{"class":216}," }",[210,277,278],{"class":224},")\n",[201,280,284],{"className":281,"code":282,"filename":63,"language":283,"meta":206,"style":206},"language-vue shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","\u003CFFTVisualizer mode=\"local\" audio-source=\"mic\" :bands=\"80\" \u002F>\n","vue",[91,285,286],{"__ignoreMap":206},[210,287,288,291,294,297,300,303,305,307,310,312,314,316,318,321,324,326,328,331,333],{"class":212,"line":213},[210,289,290],{"class":216},"\u003C",[210,292,293],{"class":234},"FFTVisualizer",[210,295,235],{"class":296},"spNyl",[210,298,299],{"class":216},"=",[210,301,302],{"class":216},"\"",[210,304,124],{"class":244},[210,306,302],{"class":216},[210,308,309],{"class":296}," audio-source",[210,311,299],{"class":216},[210,313,302],{"class":216},[210,315,259],{"class":244},[210,317,302],{"class":216},[210,319,320],{"class":216}," :",[210,322,323],{"class":296},"bands",[210,325,299],{"class":216},[210,327,302],{"class":216},[210,329,330],{"class":271},"80",[210,332,302],{"class":216},[210,334,335],{"class":216}," \u002F>\n",[182,337,339],{"id":338},"websocket-mode","WebSocket mode",[87,341,342,343,346,347,350],{},"The server streams a small config message then binary FFT frames — see the\n",[344,345,36],"a",{"href":37},". Reference servers for Python, Node.js and\nRust are in the repository's ",[91,348,349],{},"backend-examples\u002F",".",[198,352,353,438],{},[201,354,356],{"className":203,"code":355,"filename":42,"language":205,"meta":206,"style":206},"new FFTVisualizer(canvas, {\n  mode: 'websocket',\n  websocketUrl: 'wss:\u002F\u002Fyour-server\u002Ffft',\n  bands: 40,\n  autoReconnect: true\n})\n",[91,357,358,371,388,405,418,430],{"__ignoreMap":206},[210,359,360,362,364,366,368],{"class":212,"line":213},[210,361,217],{"class":216},[210,363,221],{"class":220},[210,365,225],{"class":224},[210,367,228],{"class":216},[210,369,370],{"class":216}," {\n",[210,372,374,377,379,381,383,385],{"class":212,"line":373},2,[210,375,376],{"class":234},"  mode",[210,378,238],{"class":216},[210,380,241],{"class":216},[210,382,137],{"class":244},[210,384,247],{"class":216},[210,386,387],{"class":216},",\n",[210,389,391,394,396,398,401,403],{"class":212,"line":390},3,[210,392,393],{"class":234},"  websocketUrl",[210,395,238],{"class":216},[210,397,241],{"class":216},[210,399,400],{"class":244},"wss:\u002F\u002Fyour-server\u002Ffft",[210,402,247],{"class":216},[210,404,387],{"class":216},[210,406,408,411,413,416],{"class":212,"line":407},4,[210,409,410],{"class":234},"  bands",[210,412,238],{"class":216},[210,414,415],{"class":271}," 40",[210,417,387],{"class":216},[210,419,421,424,426],{"class":212,"line":420},5,[210,422,423],{"class":234},"  autoReconnect",[210,425,238],{"class":216},[210,427,429],{"class":428},"sfNiH"," true\n",[210,431,433,436],{"class":212,"line":432},6,[210,434,435],{"class":216},"}",[210,437,278],{"class":224},[201,439,441],{"className":281,"code":440,"filename":63,"language":283,"meta":206,"style":206},"\u003CFFTVisualizer\n  mode=\"websocket\"\n  websocket-url=\"wss:\u002F\u002Fyour-server\u002Ffft\"\n  :bands=\"40\"\n  :auto-reconnect=\"true\"\n\u002F>\n",[91,442,443,450,463,476,492,508],{"__ignoreMap":206},[210,444,445,447],{"class":212,"line":213},[210,446,290],{"class":216},[210,448,449],{"class":234},"FFTVisualizer\n",[210,451,452,454,456,458,460],{"class":212,"line":373},[210,453,376],{"class":296},[210,455,299],{"class":216},[210,457,302],{"class":216},[210,459,137],{"class":244},[210,461,462],{"class":216},"\"\n",[210,464,465,468,470,472,474],{"class":212,"line":390},[210,466,467],{"class":296},"  websocket-url",[210,469,299],{"class":216},[210,471,302],{"class":216},[210,473,400],{"class":244},[210,475,462],{"class":216},[210,477,478,481,483,485,487,490],{"class":212,"line":407},[210,479,480],{"class":216},"  :",[210,482,323],{"class":296},[210,484,299],{"class":216},[210,486,302],{"class":216},[210,488,489],{"class":271},"40",[210,491,462],{"class":216},[210,493,494,496,499,501,503,506],{"class":212,"line":420},[210,495,480],{"class":216},[210,497,498],{"class":296},"auto-reconnect",[210,500,299],{"class":216},[210,502,302],{"class":216},[210,504,505],{"class":428},"true",[210,507,462],{"class":216},[210,509,510],{"class":212,"line":432},[210,511,512],{"class":224},"\u002F>\n",[514,515,516,517,522,523,526],"warning",{},"On an HTTPS page you must use a ",[151,518,519],{},[91,520,521],{},"wss:\u002F\u002F"," URL — browsers block insecure ",[91,524,525],{},"ws:\u002F\u002F"," from\nsecure pages as mixed content.",[182,528,530],{"id":529},"external-mode","External mode",[87,532,533,534,537,538,540,541,543,544,350],{},"Pass a ",[91,535,536],{},"Uint8Array"," of magnitudes (0–255); update it and the visual follows. For stereo,\npass ",[91,539,174],{}," and ",[91,542,177],{}," instead of ",[91,545,170],{},[198,547,548,621],{},[201,549,551],{"className":203,"code":550,"filename":42,"language":205,"meta":206,"style":206},"const viz = new FFTVisualizer(canvas, { mode: 'external', bands: 40 })\n\n\u002F\u002F ...each frame, feed fresh magnitudes (the data is copied):\nviz.feedData(myUint8Array)\n",[91,552,553,596,602,608],{"__ignoreMap":206},[210,554,555,558,561,563,566,568,570,572,574,576,578,580,582,584,586,588,590,592,594],{"class":212,"line":213},[210,556,557],{"class":296},"const",[210,559,560],{"class":224}," viz ",[210,562,299],{"class":216},[210,564,565],{"class":216}," new",[210,567,221],{"class":220},[210,569,225],{"class":224},[210,571,228],{"class":216},[210,573,231],{"class":216},[210,575,235],{"class":234},[210,577,238],{"class":216},[210,579,241],{"class":216},[210,581,164],{"class":244},[210,583,247],{"class":216},[210,585,228],{"class":216},[210,587,266],{"class":234},[210,589,238],{"class":216},[210,591,415],{"class":271},[210,593,275],{"class":216},[210,595,278],{"class":224},[210,597,598],{"class":212,"line":373},[210,599,601],{"emptyLinePlaceholder":600},true,"\n",[210,603,604],{"class":212,"line":390},[210,605,607],{"class":606},"sHwdD","\u002F\u002F ...each frame, feed fresh magnitudes (the data is copied):\n",[210,609,610,613,615,618],{"class":212,"line":407},[210,611,612],{"class":224},"viz",[210,614,350],{"class":216},[210,616,617],{"class":220},"feedData",[210,619,620],{"class":224},"(myUint8Array)\n",[201,622,624],{"className":281,"code":623,"filename":63,"language":283,"meta":206,"style":206},"\u003Cscript setup>\nimport { ref } from 'vue'\nimport { FFTVisualizer } from 'fft-visualizer-vue'\n\nconst data = ref(new Uint8Array(80))\n\u002F\u002F ...fill data.value from your own analyser each frame\n\u003C\u002Fscript>\n\n\u003Ctemplate>\n  \u003CFFTVisualizer mode=\"external\" :data=\"data\" :bands=\"40\" \u002F>\n\u003C\u002Ftemplate>\n",[91,625,626,639,662,681,685,711,716,726,731,741,783],{"__ignoreMap":206},[210,627,628,630,633,636],{"class":212,"line":213},[210,629,290],{"class":216},[210,631,632],{"class":234},"script",[210,634,635],{"class":296}," setup",[210,637,638],{"class":216},">\n",[210,640,641,645,647,650,652,655,657,659],{"class":212,"line":373},[210,642,644],{"class":643},"s7zQu","import",[210,646,231],{"class":216},[210,648,649],{"class":224}," ref",[210,651,275],{"class":216},[210,653,654],{"class":643}," from",[210,656,241],{"class":216},[210,658,283],{"class":244},[210,660,661],{"class":216},"'\n",[210,663,664,666,668,670,672,674,676,679],{"class":212,"line":390},[210,665,644],{"class":643},[210,667,231],{"class":216},[210,669,221],{"class":224},[210,671,275],{"class":216},[210,673,654],{"class":643},[210,675,241],{"class":216},[210,677,678],{"class":244},"fft-visualizer-vue",[210,680,661],{"class":216},[210,682,683],{"class":212,"line":407},[210,684,601],{"emptyLinePlaceholder":600},[210,686,687,689,692,694,696,699,701,704,706,708],{"class":212,"line":420},[210,688,557],{"class":296},[210,690,691],{"class":224}," data ",[210,693,299],{"class":216},[210,695,649],{"class":220},[210,697,698],{"class":224},"(",[210,700,217],{"class":216},[210,702,703],{"class":220}," Uint8Array",[210,705,698],{"class":224},[210,707,330],{"class":271},[210,709,710],{"class":224},"))\n",[210,712,713],{"class":212,"line":432},[210,714,715],{"class":606},"\u002F\u002F ...fill data.value from your own analyser each frame\n",[210,717,719,722,724],{"class":212,"line":718},7,[210,720,721],{"class":216},"\u003C\u002F",[210,723,632],{"class":234},[210,725,638],{"class":216},[210,727,729],{"class":212,"line":728},8,[210,730,601],{"emptyLinePlaceholder":600},[210,732,734,736,739],{"class":212,"line":733},9,[210,735,290],{"class":216},[210,737,738],{"class":234},"template",[210,740,638],{"class":216},[210,742,744,747,749,751,753,755,757,759,762,764,766,768,770,773,775,777,779,781],{"class":212,"line":743},10,[210,745,746],{"class":216},"  \u003C",[210,748,293],{"class":234},[210,750,235],{"class":296},[210,752,299],{"class":216},[210,754,302],{"class":216},[210,756,164],{"class":244},[210,758,302],{"class":216},[210,760,761],{"class":296}," :data",[210,763,299],{"class":216},[210,765,302],{"class":216},[210,767,170],{"class":244},[210,769,302],{"class":216},[210,771,772],{"class":296}," :bands",[210,774,299],{"class":216},[210,776,302],{"class":216},[210,778,489],{"class":244},[210,780,302],{"class":216},[210,782,335],{"class":216},[210,784,786,788,790],{"class":212,"line":785},11,[210,787,721],{"class":216},[210,789,738],{"class":234},[210,791,638],{"class":216},[793,794,795,798,799,802,803,805,806,808,809,812,813,818],"tip",{},[151,796,797],{},"Feed data by copy for in-place buffers."," Core's ",[91,800,801],{},"feedData()"," copies the data, so reusing\none ",[91,804,536],{}," each frame is fine. In Vue the ",[91,807,170],{}," prop is watched ",[151,810,811],{},"by reference"," — if\nyou mutate the same array in place, Vue won't detect the change, so either assign a fresh\narray or call the exposed ",[344,814,816],{"href":815},"\u002Fvue\u002Fprops#exposed-methods",[91,817,801],{}," method (which also copies).",[820,821,822],"style",{},"html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}",{"title":206,"searchDepth":373,"depth":373,"links":824},[825,826,827],{"id":184,"depth":373,"text":185},{"id":338,"depth":373,"text":339},{"id":529,"depth":373,"text":530},"The three ways to get audio data into the visualizer — local, WebSocket, and external.","md",null,{},{"icon":24},{"title":21,"description":828},"wijgc8cS_nb84i_EC9Eu3LfUDe-m4jIC7a3GBhpoy90",[836,838],{"title":16,"path":17,"stem":18,"description":837,"icon":19,"children":-1},"The signal pipeline from raw audio to rendered bars — and where the FFT actually runs.",{"title":26,"path":27,"stem":28,"description":839,"icon":29,"children":-1},"The canonical option reference — every visualizer option, its type, default, and meaning.",1784963432760]