import 'dart:async'; import 'dart:math'; import 'package:flutter/services.dart'; class G711 { List _aLawTable = [ 1, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 ]; Future> readAssetFile(String assetPath) async { final ByteData data = await rootBundle.load(assetPath); final List bytes = data.buffer.asUint8List(); return bytes; } List encodeALaw(List pcmSamples) { final List aLawSamples = []; for (final sample in pcmSamples) { // 将 16 位 PCM 样本归一化为 13 位有符号整数 int normalizedSample = sample >> 3; // 获取样本的符号位 int sign = (normalizedSample & 0x8000) != 0 ? 0x80 : 0x00; // 取绝对值 normalizedSample = normalizedSample.abs(); // 查找编码表中的段 int segment = _aLawTable[normalizedSample >> 8]; // 计算量化值 int quantizedValue = (normalizedSample >> (segment + 3)) & 0x0F; // 生成 A-law 编码 int aLawSample = sign | (segment << 4) | quantizedValue; // 添加到结果列表 aLawSamples.add(aLawSample); } return aLawSamples; } 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 = ~encodedValue; int t = ((encodedValue & 0x0F) << 3) + 0x84; t <<= (encodedValue & 0x70) >> 4; return (encodedValue & 0x80) != 0 ? 0x84 - t : t - 0x84; } else { // μ律解码 encodedValue = ~encodedValue; int t = ((encodedValue & 0x0F) << 3) + 0x84; t <<= (encodedValue & 0x70) >> 4; return (encodedValue & 0x80) != 0 ? 0x84 - t : t - 0x84; } } /// 高通滤波 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 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); return denoisedData; } //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); } }