[{"data":1,"prerenderedAt":809},["ShallowReactive",2],{"navigation_docs":3,"-core-audio-engines":81,"-core-audio-engines-surround":804},[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":58,"body":83,"description":797,"extension":798,"links":799,"meta":800,"navigation":801,"path":59,"seo":802,"stem":60,"__hash__":803},"docs\u002F2.core\u002F3.audio-engines.md",{"type":84,"value":85,"toc":791},"minimark",[86,104,140,147,150,387,422,428,450,637,651,657,676,680,687,787],[87,88,89,90,94,95,98,99,103],"p",{},"The core ships the audio→FFT pipelines as standalone factories, so you can produce FFT\nmagnitudes without the renderer — drive your own visuals, or feed the result into\n",[91,92,93],"code",{},"FFTVisualizer"," with ",[91,96,97],{},"mode: 'external'",". These are exactly what the\n",[100,101,102],"a",{"href":78},"Vue composables"," wrap.",[87,105,106,107,110,111,114,115,118,119,122,123,118,126,122,129,132,133,114,136,139],{},"All engines emit ",[91,108,109],{},"Uint8Array"," magnitudes (0–255 per bin) and share four options: ",[91,112,113],{},"fftSize","\n(default ",[91,116,117],{},"2048","), ",[91,120,121],{},"bins"," (default ",[91,124,125],{},"80",[91,127,128],{},"startFreq",[91,130,131],{},"100"," Hz), and ",[91,134,135],{},"endFreq",[91,137,138],{},"18000"," Hz).",[141,142,144],"h2",{"id":143},"createlocalaudiooptions",[91,145,146],{},"createLocalAudio(options?)",[87,148,149],{},"Captures mic or system\u002Ftab audio and computes the FFT in-browser via the Rust WASM processor.",[151,152,157],"pre",{"className":153,"code":154,"language":155,"meta":156,"style":156},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { createLocalAudio } from 'fft-visualizer-core'\n\nconst audio = createLocalAudio({\n  bins: 80,\n  onData: (data) => {\n    \u002F\u002F data: Uint8Array — fresh magnitudes each animation frame\n  },\n  onStateChange: () => {\n    \u002F\u002F isActive \u002F devices \u002F activeDeviceId \u002F sourceType changed\n  }\n})\n\nawait audio.getDevices()   \u002F\u002F enumerate inputs (prompts for mic permission)\nawait audio.start()        \u002F\u002F microphone (optional deviceId argument)\nawait audio.startDisplay() \u002F\u002F tab\u002Fsystem audio via screen sharing\naudio.stop()\n","ts","",[91,158,159,192,199,221,238,262,269,275,290,296,302,311,316,337,355,373],{"__ignoreMap":156},[160,161,164,168,172,176,179,182,185,189],"span",{"class":162,"line":163},"line",1,[160,165,167],{"class":166},"s7zQu","import",[160,169,171],{"class":170},"sMK4o"," {",[160,173,175],{"class":174},"sTEyZ"," createLocalAudio",[160,177,178],{"class":170}," }",[160,180,181],{"class":166}," from",[160,183,184],{"class":170}," '",[160,186,188],{"class":187},"sfazB","fft-visualizer-core",[160,190,191],{"class":170},"'\n",[160,193,195],{"class":162,"line":194},2,[160,196,198],{"emptyLinePlaceholder":197},true,"\n",[160,200,202,206,209,212,215,218],{"class":162,"line":201},3,[160,203,205],{"class":204},"spNyl","const",[160,207,208],{"class":174}," audio ",[160,210,211],{"class":170},"=",[160,213,175],{"class":214},"s2Zo4",[160,216,217],{"class":174},"(",[160,219,220],{"class":170},"{\n",[160,222,224,228,231,235],{"class":162,"line":223},4,[160,225,227],{"class":226},"swJcz","  bins",[160,229,230],{"class":170},":",[160,232,234],{"class":233},"sbssI"," 80",[160,236,237],{"class":170},",\n",[160,239,241,244,246,249,253,256,259],{"class":162,"line":240},5,[160,242,243],{"class":214},"  onData",[160,245,230],{"class":170},[160,247,248],{"class":170}," (",[160,250,252],{"class":251},"sHdIc","data",[160,254,255],{"class":170},")",[160,257,258],{"class":204}," =>",[160,260,261],{"class":170}," {\n",[160,263,265],{"class":162,"line":264},6,[160,266,268],{"class":267},"sHwdD","    \u002F\u002F data: Uint8Array — fresh magnitudes each animation frame\n",[160,270,272],{"class":162,"line":271},7,[160,273,274],{"class":170},"  },\n",[160,276,278,281,283,286,288],{"class":162,"line":277},8,[160,279,280],{"class":214},"  onStateChange",[160,282,230],{"class":170},[160,284,285],{"class":170}," ()",[160,287,258],{"class":204},[160,289,261],{"class":170},[160,291,293],{"class":162,"line":292},9,[160,294,295],{"class":267},"    \u002F\u002F isActive \u002F devices \u002F activeDeviceId \u002F sourceType changed\n",[160,297,299],{"class":162,"line":298},10,[160,300,301],{"class":170},"  }\n",[160,303,305,308],{"class":162,"line":304},11,[160,306,307],{"class":170},"}",[160,309,310],{"class":174},")\n",[160,312,314],{"class":162,"line":313},12,[160,315,198],{"emptyLinePlaceholder":197},[160,317,319,322,325,328,331,334],{"class":162,"line":318},13,[160,320,321],{"class":166},"await",[160,323,324],{"class":174}," audio",[160,326,327],{"class":170},".",[160,329,330],{"class":214},"getDevices",[160,332,333],{"class":174},"()   ",[160,335,336],{"class":267},"\u002F\u002F enumerate inputs (prompts for mic permission)\n",[160,338,340,342,344,346,349,352],{"class":162,"line":339},14,[160,341,321],{"class":166},[160,343,324],{"class":174},[160,345,327],{"class":170},[160,347,348],{"class":214},"start",[160,350,351],{"class":174},"()        ",[160,353,354],{"class":267},"\u002F\u002F microphone (optional deviceId argument)\n",[160,356,358,360,362,364,367,370],{"class":162,"line":357},15,[160,359,321],{"class":166},[160,361,324],{"class":174},[160,363,327],{"class":170},[160,365,366],{"class":214},"startDisplay",[160,368,369],{"class":174},"() ",[160,371,372],{"class":267},"\u002F\u002F tab\u002Fsystem audio via screen sharing\n",[160,374,376,379,381,384],{"class":162,"line":375},16,[160,377,378],{"class":174},"audio",[160,380,327],{"class":170},[160,382,383],{"class":214},"stop",[160,385,386],{"class":174},"()\n",[87,388,389,390,393,394,397,398,397,401,237,404,407,408,411,412,414,415,414,417,414,419,421],{},"The returned ",[91,391,392],{},"LocalAudioEngine"," exposes read-only ",[91,395,396],{},"fftData",", ",[91,399,400],{},"isActive",[91,402,403],{},"sourceType",[91,405,406],{},"devices",", and ",[91,409,410],{},"activeDeviceId",", plus the ",[91,413,330],{}," \u002F ",[91,416,348],{},[91,418,366],{},[91,420,383],{},"\nmethods above.",[141,423,425],{"id":424},"createwebsocketfftoptions",[91,426,427],{},"createWebSocketFft(options?)",[87,429,430,431,435,436,438,439,442,443,446,447,449],{},"Connects to a WebSocket that streams ",[432,433,434],"strong",{},"raw PCM"," and computes the FFT client-side via WASM —\ndistinct from ",[91,437,93],{},"'s ",[91,440,441],{},"websocket"," mode, which expects ",[432,444,445],{},"pre-computed"," FFT (see\n",[100,448,36],{"href":37},"). It produces mono, left, and right spectra.",[151,451,453],{"className":153,"code":452,"language":155,"meta":156,"style":156},"import { createWebSocketFft } from 'fft-visualizer-core'\n\nconst engine = createWebSocketFft({\n  bins: 80,\n  overlap: 0.5,        \u002F\u002F 0–0.75; more overlap = lower latency, ~2× FFT compute\n  autoReconnect: true,\n  onData: (mono, left, right) => { \u002F* Uint8Array each *\u002F }\n})\n\nengine.connect('wss:\u002F\u002Fyour-server\u002Fpcm')\nengine.processSamples(float32Pcm) \u002F\u002F or feed PCM manually\nengine.disconnect()\nengine.free() \u002F\u002F tear down and free WASM processors\n",[91,454,455,474,478,493,503,519,532,565,571,575,597,612,623],{"__ignoreMap":156},[160,456,457,459,461,464,466,468,470,472],{"class":162,"line":163},[160,458,167],{"class":166},[160,460,171],{"class":170},[160,462,463],{"class":174}," createWebSocketFft",[160,465,178],{"class":170},[160,467,181],{"class":166},[160,469,184],{"class":170},[160,471,188],{"class":187},[160,473,191],{"class":170},[160,475,476],{"class":162,"line":194},[160,477,198],{"emptyLinePlaceholder":197},[160,479,480,482,485,487,489,491],{"class":162,"line":201},[160,481,205],{"class":204},[160,483,484],{"class":174}," engine ",[160,486,211],{"class":170},[160,488,463],{"class":214},[160,490,217],{"class":174},[160,492,220],{"class":170},[160,494,495,497,499,501],{"class":162,"line":223},[160,496,227],{"class":226},[160,498,230],{"class":170},[160,500,234],{"class":233},[160,502,237],{"class":170},[160,504,505,508,510,513,516],{"class":162,"line":240},[160,506,507],{"class":226},"  overlap",[160,509,230],{"class":170},[160,511,512],{"class":233}," 0.5",[160,514,515],{"class":170},",",[160,517,518],{"class":267},"        \u002F\u002F 0–0.75; more overlap = lower latency, ~2× FFT compute\n",[160,520,521,524,526,530],{"class":162,"line":264},[160,522,523],{"class":226},"  autoReconnect",[160,525,230],{"class":170},[160,527,529],{"class":528},"sfNiH"," true",[160,531,237],{"class":170},[160,533,534,536,538,540,543,545,548,550,553,555,557,559,562],{"class":162,"line":271},[160,535,243],{"class":214},[160,537,230],{"class":170},[160,539,248],{"class":170},[160,541,542],{"class":251},"mono",[160,544,515],{"class":170},[160,546,547],{"class":251}," left",[160,549,515],{"class":170},[160,551,552],{"class":251}," right",[160,554,255],{"class":170},[160,556,258],{"class":204},[160,558,171],{"class":170},[160,560,561],{"class":267}," \u002F* Uint8Array each *\u002F",[160,563,564],{"class":170}," }\n",[160,566,567,569],{"class":162,"line":277},[160,568,307],{"class":170},[160,570,310],{"class":174},[160,572,573],{"class":162,"line":292},[160,574,198],{"emptyLinePlaceholder":197},[160,576,577,580,582,585,587,590,593,595],{"class":162,"line":298},[160,578,579],{"class":174},"engine",[160,581,327],{"class":170},[160,583,584],{"class":214},"connect",[160,586,217],{"class":174},[160,588,589],{"class":170},"'",[160,591,592],{"class":187},"wss:\u002F\u002Fyour-server\u002Fpcm",[160,594,589],{"class":170},[160,596,310],{"class":174},[160,598,599,601,603,606,609],{"class":162,"line":304},[160,600,579],{"class":174},[160,602,327],{"class":170},[160,604,605],{"class":214},"processSamples",[160,607,608],{"class":174},"(float32Pcm) ",[160,610,611],{"class":267},"\u002F\u002F or feed PCM manually\n",[160,613,614,616,618,621],{"class":162,"line":313},[160,615,579],{"class":174},[160,617,327],{"class":170},[160,619,620],{"class":214},"disconnect",[160,622,386],{"class":174},[160,624,625,627,629,632,634],{"class":162,"line":318},[160,626,579],{"class":174},[160,628,327],{"class":170},[160,630,631],{"class":214},"free",[160,633,369],{"class":174},[160,635,636],{"class":267},"\u002F\u002F tear down and free WASM processors\n",[87,638,639,640,397,642,397,645,397,648,327],{},"Read-only getters: ",[91,641,396],{},[91,643,644],{},"fftDataLeft",[91,646,647],{},"fftDataRight",[91,649,650],{},"isConnected",[141,652,654],{"id":653},"pcmtochannelsbuffer-bitdepth-channels",[91,655,656],{},"pcmToChannels(buffer, bitDepth, channels)",[87,658,659,660,663,664,667,668,671,672,675],{},"Decodes an interleaved integer-PCM ",[91,661,662],{},"ArrayBuffer"," (16\u002F24\u002F32-bit) into normalized Float32\nchannels — ",[91,665,666],{},"{ mono, left, right }",", each in ",[91,669,670],{},"[-1, 1)",". Mono input is duplicated to both\nchannels; only the first two channels of multichannel input are used. This is the decoder\n",[91,673,674],{},"createWebSocketFft"," uses internally.",[141,677,679],{"id":678},"raw-wasm-processor","Raw WASM processor",[87,681,682,683,686],{},"For full control, the Rust ",[91,684,685],{},"FftProcessor"," is exported from a dedicated subpath. It's kept out\nof the main entry so importing the visualizer never eagerly loads ~289 kB of WASM.",[151,688,690],{"className":153,"code":689,"language":155,"meta":156,"style":156},"import { FftProcessor } from 'fft-visualizer-core\u002Fwasm'\n\nconst processor = new FftProcessor(fftSize, bins, startFreq, endFreq, sampleRate)\nconst magnitudes = processor.process(float32TimeDomainSamples) \u002F\u002F Uint8Array\nprocessor.free()\n",[91,691,692,712,716,753,776],{"__ignoreMap":156},[160,693,694,696,698,701,703,705,707,710],{"class":162,"line":163},[160,695,167],{"class":166},[160,697,171],{"class":170},[160,699,700],{"class":174}," FftProcessor",[160,702,178],{"class":170},[160,704,181],{"class":166},[160,706,184],{"class":170},[160,708,709],{"class":187},"fft-visualizer-core\u002Fwasm",[160,711,191],{"class":170},[160,713,714],{"class":162,"line":194},[160,715,198],{"emptyLinePlaceholder":197},[160,717,718,720,723,725,728,730,733,735,738,740,743,745,748,750],{"class":162,"line":201},[160,719,205],{"class":204},[160,721,722],{"class":174}," processor ",[160,724,211],{"class":170},[160,726,727],{"class":170}," new",[160,729,700],{"class":214},[160,731,732],{"class":174},"(fftSize",[160,734,515],{"class":170},[160,736,737],{"class":174}," bins",[160,739,515],{"class":170},[160,741,742],{"class":174}," startFreq",[160,744,515],{"class":170},[160,746,747],{"class":174}," endFreq",[160,749,515],{"class":170},[160,751,752],{"class":174}," sampleRate)\n",[160,754,755,757,760,762,765,767,770,773],{"class":162,"line":223},[160,756,205],{"class":204},[160,758,759],{"class":174}," magnitudes ",[160,761,211],{"class":170},[160,763,764],{"class":174}," processor",[160,766,327],{"class":170},[160,768,769],{"class":214},"process",[160,771,772],{"class":174},"(float32TimeDomainSamples) ",[160,774,775],{"class":267},"\u002F\u002F Uint8Array\n",[160,777,778,781,783,785],{"class":162,"line":240},[160,779,780],{"class":174},"processor",[160,782,327],{"class":170},[160,784,631],{"class":214},[160,786,386],{"class":174},[788,789,790],"style",{},"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}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}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 .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 .sfNiH, html code.shiki .sfNiH{--shiki-light:#FF5370;--shiki-default:#FF9CAC;--shiki-dark:#FF9CAC}",{"title":156,"searchDepth":194,"depth":194,"links":792},[793,794,795,796],{"id":143,"depth":194,"text":146},{"id":424,"depth":194,"text":427},{"id":653,"depth":194,"text":656},{"id":678,"depth":194,"text":679},"Standalone FFT pipelines — local capture, client-side FFT of a PCM stream, PCM decoding, and the raw WASM processor.","md",null,{},{"icon":61},{"title":58,"description":797},"_3e8lpANjvr0gVb0fmRBz9TakfhdMDO5ymzlLA8g1BY",[805,807],{"title":53,"path":54,"stem":55,"description":806,"icon":56,"children":-1},"The FFTVisualizer class — constructor, getters, methods, events, and helpers.",{"title":48,"path":69,"stem":70,"description":808,"icon":51,"children":-1},"Install the package and render your first spectrum in under a minute.",1784963433391]