import 'dart:typed_data'; enum G711Type { uLaw, aLaw, } class G711Decoder { Uint8List g711Encode(Uint8List pcmData, G711Type g711Type) { List g711Data = []; for (int sample in pcmData) { int sign = (sample < 0) ? 0x80 : 0; int magnitude = (sample < 0) ? -sample : sample; int exponent = 7; while (magnitude < (1 << exponent) && exponent > 0) { exponent--; } int mantissa = (magnitude >> (exponent - 4)) & 0x0F; if (g711Type == G711Type.uLaw) { // μ-law encoding int value = ~(sign | ((exponent << 4) & 0x70) | (mantissa >> 4)); g711Data.add(value & 0xFF); } else { // A-law encoding int value = sign | ((exponent << 4) & 0x70) | (mantissa >> 4); g711Data.add(value & 0xFF); } } return Uint8List.fromList(g711Data); } List pcm16ToG711u(List pcm16Data) { List g711uData = []; for (int i = 0; i < pcm16Data.length; i += 2) { int pcmSample = (pcm16Data[i + 1] << 8) | pcm16Data[i]; int g711Sample = pcmToG711u(pcmSample); // 将 G.711 样本拆分成两个字节 g711uData.add(g711Sample & 0xFF); g711uData.add((g711Sample >> 8) & 0xFF); } return g711uData; } int pcmToG711u(int pcmSample) { const int MULAW_BIAS = 0x84; const int CLIP = 32635; // 剪裁 PCM 样本 if (pcmSample > CLIP) { pcmSample = CLIP; } else if (pcmSample < -CLIP) { pcmSample = -CLIP; } // 增加偏置并取反 pcmSample += MULAW_BIAS; pcmSample = ~pcmSample & 0xFF; return pcmSample; } }