getWaveformBytes method
Future<List<double> >
getWaveformBytes(
- Uint8List inputData,
- String formatHint,
- int numberOfSamples, {
- WaveformNormalization normalization = WaveformNormalization.perFile,
override
Implementation
@override
Future<List<double>> getWaveformBytes(
Uint8List inputData,
String formatHint,
int numberOfSamples, {
WaveformNormalization normalization = WaveformNormalization.perFile,
}) async {
try {
final buffer = await _decodeAudioData(inputData);
final channelData = buffer.getChannelData(0).toDart;
final totalSamples = channelData.length;
if (totalSamples == 0) {
return List.filled(numberOfSamples, 0.0);
}
final samplesPerWindow = max(1, totalSamples ~/ numberOfSamples);
final waveform = <double>[];
var maxRms = 0.0;
for (var i = 0; i < numberOfSamples; i++) {
final start = i * totalSamples ~/ numberOfSamples;
final end = min(start + samplesPerWindow, totalSamples);
if (start >= totalSamples) break;
var sumSquares = 0.0;
for (var j = start; j < end; j++) {
final s = channelData[j];
sumSquares += s * s;
}
final rms = sqrt(sumSquares / (end - start));
waveform.add(rms);
if (rms > maxRms) maxRms = rms;
}
// Web Audio API delivers samples already in [-1.0, 1.0], so absolute
// normalization is the raw RMS value. Per-file normalization scales by
// the loudest window in this file.
final List<double> result;
switch (normalization) {
case WaveformNormalization.perFile:
result = waveform.map((rms) => maxRms > 0 ? rms / maxRms : 0.0).toList();
case WaveformNormalization.absolute:
result = List<double>.from(waveform);
}
while (result.length < numberOfSamples) {
result.add(0.0);
}
return result;
} catch (e) {
if (e is AudioConversionException) rethrow;
throw AudioConversionException('Waveform extraction failed: $e');
}
}