{"record":{"id":"34f58143be1f4bbe","repo":"remotion-dev/remotion","slug":"audio-data-is-not-big-enough-to-provide-samplesi","errorCode":null,"errorMessage":"Audio data is not big enough to provide ${sampleSize} bars.","messagePattern":"Audio data is not big enough to provide (.+?) bars\\.","errorType":"validation","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"packages/media-utils/src/fft/get-visualization.ts","lineNumber":43,"sourceCode":"\tsampleRate: number;\n\tfps: number;\n\tmaxInt: number;\n\toptimizeFor: OptimizeFor;\n\tdataOffsetInSeconds: number;\n}): number[] => {\n\tconst isPowerOfTwo = sampleSize > 0 && (sampleSize & (sampleSize - 1)) === 0;\n\tif (!isPowerOfTwo) {\n\t\tthrow new TypeError(\n\t\t\t`The argument \"bars\" must be a power of two. For example: 64, 128. Got instead: ${sampleSize}`,\n\t\t);\n\t}\n\n\tif (!fps) {\n\t\tthrow new TypeError('The argument \"fps\" was not provided');\n\t}\n\n\tif (data.length < sampleSize) {\n\t\tthrow new TypeError(\n\t\t\t'Audio data is not big enough to provide ' + sampleSize + ' bars.',\n\t\t);\n\t}\n\n\tconst start = Math.floor((frame / fps - dataOffsetInSeconds) * sampleRate);\n\n\tconst actualStart = Math.max(0, start - sampleSize / 2);\n\n\tconst ints = new Int16Array({\n\t\tlength: sampleSize,\n\t});\n\tints.set(\n\t\tdata.subarray(actualStart, actualStart + sampleSize).map((x) => toInt16(x)),\n\t);\n\tconst alg = optimizeFor === 'accuracy' ? fftAccurate : fftFast;\n\n\tconst phasors = alg(ints);\n\tconst magnitudes = fftMag(phasors).map((p) => p);","sourceCodeStart":25,"sourceCodeEnd":61,"githubUrl":"https://github.com/remotion-dev/remotion/blob/78fe4bb3fdb5a2cd68724393d63cb223db333fa7/packages/media-utils/src/fft/get-visualization.ts#L25-L61","documentation":"Thrown by getVisualization when the provided audio data array is shorter than sampleSize. The FFT needs at least sampleSize samples to produce that many bars; with fewer samples the visualization cannot be computed and the guard fails fast instead of reading out of bounds.","triggerScenarios":"Passing a Float32Array whose length is less than the requested number of bars (sampleSize). Happens when audio data is truncated, the sample window is too short, or sampleSize was increased beyond what the decoded audio provides.","commonSituations":"Very short audio clips where the decoded PCM is shorter than sampleSize. Requesting 2048 bars from a 1-second clip at low sample rate. A bug in data extraction that returns a subarray of the wrong length.","solutions":["Lower sampleSize so it fits within data.length (e.g. min(requestedBars, nextPow2(data.length))).","Ensure the audio data covers enough duration: at least sampleSize / sampleRate seconds.","Pad the data with zeros to the next power of two if a fixed sampleSize is required."],"exampleFix":"// before\ngetVisualization({ sampleSize: 2048, data: shortFloat32, ... });\n\n// after\nconst sampleSize = Math.min(2048, Math.pow(2, Math.floor(Math.log2(data.length))));\ngetVisualization({ sampleSize, data, ... });","handlingStrategy":"validation","validationCode":"if (data.length < sampleSize) throw new TypeError(`need at least ${sampleSize} samples, got ${data.length}`);\ngetVisualization({ sampleSize, data, ...rest });","typeGuard":"const hasEnoughSamples = (data: Float32Array, n: number) => data.length >= n;","tryCatchPattern":"try { return getVisualization({ sampleSize, data, ...rest }); } catch (e) { if (/not big enough/.test(String((e as Error).message))) { const fit = Math.pow(2, Math.floor(Math.log2(data.length))); return getVisualization({ sampleSize: fit, data, ...rest }); } throw e; }","preventionTips":["Clamp sampleSize to the next power of two <= data.length.","Ensure the audio clip is long enough for the requested bars.","Zero-pad short data when a fixed sampleSize is mandatory."],"tags":["media-utils","fft","visualization","audio","validation"],"backgroundTag":null,"analyzedSha":"78fe4bb3fdb5a2cd68724393d63cb223db333fa7","analyzedAt":"2026-08-12T17:18:50.444Z","schemaVersion":2},"datasetVersion":"2026-08-12T18:17:37.767Z"}