import 'dart:async'; import 'dart:math'; import 'package:flutter/services.dart'; class G711 { Future> readAssetFile(String assetPath) async { final ByteData data = await rootBundle.load(assetPath); final List bytes = data.buffer.asUint8List(); return bytes; } int ALawToLinear(int aVal) { // 取反 aVal = ~aVal; // 计算偏移 int t = ((aVal & 0x0F) << 3) + 0x84; t <<= (aVal & 0x70) >> 4; // 根据符号位决定返回值的正负 return (aVal & 0x80) != 0 ? 0x84 - t : t - 0x84; } int decodeG711(int encodedValue, bool isALaw) { if (isALaw) { // A律解码 encodedValue ^= 0x55; // 反转最高位 int sign = encodedValue & 0x80; // 符号位 int exponent = (encodedValue & 0x70) >> 4; // 指数位 int mantissa = encodedValue & 0x0F; // 尾数位 int pcmSample = (mantissa << 4) + 0x84; // 计算量化值 pcmSample <<= exponent; // 根据指数位移位 pcmSample = (sign == 0) ? pcmSample : -pcmSample; // 处理符号位 return pcmSample; } else { // μ律解码 encodedValue ^= 0xFF; // 反转最高位 int sign = encodedValue & 0x80; // 符号位 int exponent = (encodedValue & 0x70) >> 4; // 指数位 int mantissa = encodedValue & 0x0F; // 尾数位 int pcmSample = (mantissa << 3) + 0x84; // 计算量化值 pcmSample <<= exponent + 1; // 根据指数位移位(μ律需要额外加1) pcmSample = (sign == 0) ? pcmSample : -pcmSample; // 处理符号位 return pcmSample; } } /// 高通滤波 List highPassFilter( List audioData, int sampleRate, double cutoffFreq) { final double rc = 1.0 / (2 * pi * cutoffFreq); final double dt = 1.0 / sampleRate; final double alpha = rc / (rc + dt); List filteredData = []; int prevInput = 0; int prevOutput = 0; for (int sample in audioData) { int output = (alpha * (prevOutput + sample - prevInput)).round(); filteredData.add(output); prevInput = sample; prevOutput = output; } return filteredData; } /// 噪声门 List noiseGate(List audioData, int threshold) { return audioData .map((sample) => sample.abs() > threshold ? sample : 0) .toList(); } List removeEcho(List audioData, int delaySamples, double decay) { final List processedData = []; for (int i = 0; i < audioData.length; i++) { int sample = audioData[i]; if (i >= delaySamples) { sample -= (audioData[i - delaySamples] * decay).round(); } processedData.add(sample); } return processedData; } /// 解码并降噪 List decodeAndDenoise(List encodedData, bool isALaw, int sampleRate, double cutoffFreq, int threshold) { // 解码 G.711 数据 List decodedData = encodedData.map((value) => decodeG711(value, isALaw)).toList(); // 高通滤波 List filteredData = highPassFilter(decodedData, sampleRate, cutoffFreq); // 噪声门 List denoisedData = noiseGate(filteredData, threshold); // 回声消除处理 final List processedData = removeEcho(denoisedData, 160, 0.5); return processedData; } //711解码为pcm数据 List convertList(List aLawList) { // 将 ALawToLinear 函数应用于 List final List linearList = aLawList.map(ALawToLinear).toList(); return linearList; } //List转为Uint8List Uint8List convertToInt8ListLittleEndian(List intList) { final List int8List = []; for (int intValue in intList) { intValue = intValue * 2; // 将 int 拆分为两个字节,采用小端序 int8List.add(intValue & 0xFF); // 低 8 位 int8List.add((intValue & 0xFF00) >> 8); // 高 8 位 } return Uint8List.fromList(int8List); } }