fix:调整发送g711音频数据

This commit is contained in:
liyi 2025-01-15 15:43:53 +08:00
parent 6df3783f90
commit 1fb9a5a188
4 changed files with 64 additions and 87 deletions

View File

@ -11,6 +11,7 @@ import 'package:star_lock/talk/startChart/proto/gateway_reset.pb.dart';
import 'package:star_lock/talk/startChart/proto/generic.pb.dart';
import 'package:star_lock/talk/startChart/proto/rbcu.pb.dart';
import 'package:star_lock/talk/startChart/proto/talk_accept.pb.dart';
import 'package:star_lock/talk/startChart/proto/talk_data.pb.dart';
import 'package:star_lock/talk/startChart/proto/talk_expect.pb.dart';
import 'package:star_lock/talk/startChart/proto/talk_hangup.pb.dart';
import 'package:star_lock/talk/startChart/proto/talk_ping.pb.dart';
@ -272,16 +273,12 @@ class MessageCommand {
required String FromPeerId,
required String ToPeerId,
int? MessageId,
List<int>? payload,
required TalkData talkData,
int? SpTotal,
int? SpIndex,
}) {
// payload 4
// final payloadBytes = ByteData(payload!.length * 4);
// for (int i = 0; i < payload.length; i++) {
// payloadBytes.setInt32(i * 4, payload[i], Endian.big); // 使
// }
// final payload = talkData.writeToBuffer();
final payload = talkData.writeToBuffer();
ScpMessage message = ScpMessage(
ProtocolFlag: ProtocolFlagConstant.scp01,
MessageType: MessageTypeConstant.RealTimeData,
@ -291,7 +288,7 @@ class MessageCommand {
FromPeerId: FromPeerId,
ToPeerId: ToPeerId,
Payload: payload,
PayloadCRC: calculationCrcFromIntList(payload!),
PayloadCRC: calculationCrcFromIntList(payload),
PayloadLength: payload.length,
PayloadType: PayloadTypeConstant.talkData,
);

View File

@ -438,7 +438,7 @@ class StartChartManage {
end = payload.length;
}
//
List<int> packet = payload.sublist(start, end);
List<int> packetTalkData = payload.sublist(start, end);
// messageID
final messageId =
@ -447,12 +447,15 @@ class StartChartManage {
final message = MessageCommand.talkDataMessage(
ToPeerId: toPeerId,
FromPeerId: FromPeerId,
payload: packet,
talkData: TalkData(
contentType: talkData.contentType,
content: packetTalkData,
durationMs: talkData.durationMs,
),
SpTotal: totalPackets,
SpIndex: i + 1,
MessageId: messageId,
);
//
await _sendMessage(message: message);
}

View File

@ -8,10 +8,8 @@ import 'package:flutter/services.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_pcm_sound/flutter_pcm_sound.dart';
import 'package:flutter_screen_recording/flutter_screen_recording.dart';
import 'package:flutter_voice_processor/flutter_voice_processor.dart';
import 'package:gallery_saver/gallery_saver.dart';
import 'package:get/get.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:path_provider/path_provider.dart';
@ -560,6 +558,7 @@ class TalkViewLogic extends BaseGetXController {
} on PlatformException catch (ex) {
// state.errorMessage.value = 'Failed to start recorder: $ex';
}
state.isOpenVoice.value = false;
}
///
@ -581,34 +580,20 @@ class TalkViewLogic extends BaseGetXController {
} finally {
final bool? isRecording = await state.voiceProcessor?.isRecording();
state.isRecordingAudio.value = isRecording!;
state.isOpenVoice.value = true;
}
}
Future<void> _onFrame(List<int> frame) async {
// state.recordingAudioAllFrames.add(frame); //
// final List<int> concatenatedFrames =
// concatenateFrames(state.recordingAudioAllFrames); //
// final List<int> pcmBytes = _listLinearToULaw(frame);
// final aLaw = G711().encodeALaw(frame);
// final aLawFrame = listLinearToALaw(frame);
// 640 0 PCM
// 640 0 8 PCM
final pcmSamples = List<int>.filled(640, 0); // 128 8 PCM 0
// A-law
final aLawSamples = listLinearToALaw(pcmSamples, isUnsigned: true);
AppLog.log('msg');
// AppLog.log('录制的音频数据A-law$aLawFrame, size${aLawFrame.length}');
final list = listLinearToALaw(frame);
final ms = DateTime.now().millisecondsSinceEpoch -
state.startRecordingAudioTime.value.millisecondsSinceEpoch;
//
await StartChartManage().sendTalkDataMessage(
talkData: TalkData(
content: aLawSamples,
content: list,
contentType: TalkData_ContentTypeE.G711,
durationMs: DateTime.now().millisecondsSinceEpoch -
state.startRecordingAudioTime.value.millisecondsSinceEpoch,
durationMs: ms,
),
);
}
@ -618,77 +603,69 @@ class TalkViewLogic extends BaseGetXController {
AppLog.log(error.message!);
}
int linearToALaw(int pcmVal) {
const int ALAW_MAX = 0x7FFF; // 16 PCM
const int ALAW_BIAS = 0x84; // A-law
List<int> listLinearToALaw(List<int> pcmList) {
final List<int> aLawList = [];
for (int pcmVal in pcmList) {
final int aLawVal = linearToALaw(pcmVal);
aLawList.add(aLawVal);
}
return aLawList;
}
//
int sign = (pcmVal & 0x8000) != 0 ? 0x00 : 0x80; // A-law
if (sign == 0x80) {
pcmVal = -pcmVal; //
int linearToALaw(int pcmVal) {
const int ALAW_MAX = 0x7FFF; // 32767
const int ALAW_BIAS = 0x84; // 132
int mask;
int seg;
int aLawVal;
// Handle sign
if (pcmVal < 0) {
pcmVal = -pcmVal;
mask = 0x7F; // 127 (sign bit is 1)
} else {
mask = 0xFF; // 255 (sign bit is 0)
}
// PCM
// Add bias and clamp to ALAW_MAX
pcmVal += ALAW_BIAS;
if (pcmVal > ALAW_MAX) {
pcmVal = ALAW_MAX;
}
//
pcmVal += ALAW_BIAS;
// Determine segment
seg = search(pcmVal);
//
int seg = searchALawSegment(pcmVal);
int quantizedValue = (pcmVal >> (seg + 3)) & 0x0F;
// Calculate A-law value
if (seg >= 8) {
aLawVal = 0x7F ^ mask; // Clamp to maximum value
} else {
int quantized = (pcmVal >> (seg + 3)) & 0xF;
aLawVal = (seg << 4) | quantized;
aLawVal ^= 0xD5; // XOR with 0xD5 to match standard A-law table
}
// A-law
int aLawVal = sign | (seg << 4) | quantizedValue;
return aLawVal;
}
int searchALawSegment(int val) {
const List<int> ALAW_SEGMENT_TABLE = [
0x1F,
0x3F,
0x7F,
0xFF,
0x1FF,
0x3FF,
0x7FF,
0xFFF
int search(int val) {
final List<int> table = [
0xFF, // Segment 0
0x1FF, // Segment 1
0x3FF, // Segment 2
0x7FF, // Segment 3
0xFFF, // Segment 4
0x1FFF, // Segment 5
0x3FFF, // Segment 6
0x7FFF // Segment 7
];
const int size = 8;
for (int i = 0; i < size; i++) {
if (val <= ALAW_SEGMENT_TABLE[i]) {
if (val <= table[i]) {
return i;
}
}
return size;
}
List<int> listLinearToALaw(List<int> pcmList, {bool isUnsigned = true}) {
final List<int> aLawList = [];
// 8 PCM 16 PCM
for (int i = 0; i < pcmList.length; i += 2) {
int pcm8High = pcmList[i];
int pcm8Low = (i + 1 < pcmList.length) ? pcmList[i + 1] : 0; // 0
// 8 PCM 16 PCM
int pcm16;
if (isUnsigned) {
// 8 PCM 16 PCM
pcm16 = ((pcm8High - 128) << 8) | (pcm8Low - 128);
} else {
// 8 PCM 16 PCM
pcm16 = (pcm8High << 8) | pcm8Low;
}
// 16 PCM A-law
final int aLawVal = linearToALaw(pcm16);
aLawList.add(aLawVal);
}
return aLawList;
}
}

View File

@ -82,7 +82,7 @@ class TalkViewState {
RxInt recordingAudioTime = 0.obs; //
RxDouble fps = 0.0.obs; // FPS
late VoiceProcessor? voiceProcessor; //
final int frameLength = 640; //640
final int frameLength = 320; //640
final int sampleRate = 8000; //8000
List<List<int>> recordingAudioAllFrames = <List<int>>[]; //
RxInt rotateAngle = 0.obs; //