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

View File

@ -438,7 +438,7 @@ class StartChartManage {
end = payload.length; end = payload.length;
} }
// //
List<int> packet = payload.sublist(start, end); List<int> packetTalkData = payload.sublist(start, end);
// messageID // messageID
final messageId = final messageId =
@ -447,12 +447,15 @@ class StartChartManage {
final message = MessageCommand.talkDataMessage( final message = MessageCommand.talkDataMessage(
ToPeerId: toPeerId, ToPeerId: toPeerId,
FromPeerId: FromPeerId, FromPeerId: FromPeerId,
payload: packet, talkData: TalkData(
contentType: talkData.contentType,
content: packetTalkData,
durationMs: talkData.durationMs,
),
SpTotal: totalPackets, SpTotal: totalPackets,
SpIndex: i + 1, SpIndex: i + 1,
MessageId: messageId, MessageId: messageId,
); );
// //
await _sendMessage(message: message); 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_easyloading/flutter_easyloading.dart';
import 'package:flutter_pcm_sound/flutter_pcm_sound.dart'; import 'package:flutter_pcm_sound/flutter_pcm_sound.dart';
import 'package:flutter_screen_recording/flutter_screen_recording.dart'; import 'package:flutter_screen_recording/flutter_screen_recording.dart';
import 'package:flutter_voice_processor/flutter_voice_processor.dart'; import 'package:flutter_voice_processor/flutter_voice_processor.dart';
import 'package:gallery_saver/gallery_saver.dart'; import 'package:gallery_saver/gallery_saver.dart';
import 'package:get/get.dart'; import 'package:get/get.dart';
import 'package:image_gallery_saver/image_gallery_saver.dart'; import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:path_provider/path_provider.dart'; import 'package:path_provider/path_provider.dart';
@ -560,6 +558,7 @@ class TalkViewLogic extends BaseGetXController {
} on PlatformException catch (ex) { } on PlatformException catch (ex) {
// state.errorMessage.value = 'Failed to start recorder: $ex'; // state.errorMessage.value = 'Failed to start recorder: $ex';
} }
state.isOpenVoice.value = false;
} }
/// ///
@ -581,34 +580,20 @@ class TalkViewLogic extends BaseGetXController {
} finally { } finally {
final bool? isRecording = await state.voiceProcessor?.isRecording(); final bool? isRecording = await state.voiceProcessor?.isRecording();
state.isRecordingAudio.value = isRecording!; state.isRecordingAudio.value = isRecording!;
state.isOpenVoice.value = true;
} }
} }
Future<void> _onFrame(List<int> frame) async { Future<void> _onFrame(List<int> frame) async {
// state.recordingAudioAllFrames.add(frame); // final list = listLinearToALaw(frame);
// final List<int> concatenatedFrames = final ms = DateTime.now().millisecondsSinceEpoch -
// concatenateFrames(state.recordingAudioAllFrames); // state.startRecordingAudioTime.value.millisecondsSinceEpoch;
// 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}');
// //
await StartChartManage().sendTalkDataMessage( await StartChartManage().sendTalkDataMessage(
talkData: TalkData( talkData: TalkData(
content: aLawSamples, content: list,
contentType: TalkData_ContentTypeE.G711, contentType: TalkData_ContentTypeE.G711,
durationMs: DateTime.now().millisecondsSinceEpoch - durationMs: ms,
state.startRecordingAudioTime.value.millisecondsSinceEpoch,
), ),
); );
} }
@ -618,77 +603,69 @@ class TalkViewLogic extends BaseGetXController {
AppLog.log(error.message!); AppLog.log(error.message!);
} }
int linearToALaw(int pcmVal) { List<int> listLinearToALaw(List<int> pcmList) {
const int ALAW_MAX = 0x7FFF; // 16 PCM final List<int> aLawList = [];
const int ALAW_BIAS = 0x84; // A-law for (int pcmVal in pcmList) {
final int aLawVal = linearToALaw(pcmVal);
aLawList.add(aLawVal);
}
return aLawList;
}
// int linearToALaw(int pcmVal) {
int sign = (pcmVal & 0x8000) != 0 ? 0x00 : 0x80; // A-law const int ALAW_MAX = 0x7FFF; // 32767
if (sign == 0x80) { const int ALAW_BIAS = 0x84; // 132
pcmVal = -pcmVal; //
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) { if (pcmVal > ALAW_MAX) {
pcmVal = ALAW_MAX; pcmVal = ALAW_MAX;
} }
// // Determine segment
pcmVal += ALAW_BIAS; seg = search(pcmVal);
// // Calculate A-law value
int seg = searchALawSegment(pcmVal); if (seg >= 8) {
int quantizedValue = (pcmVal >> (seg + 3)) & 0x0F; 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; return aLawVal;
} }
int searchALawSegment(int val) { int search(int val) {
const List<int> ALAW_SEGMENT_TABLE = [ final List<int> table = [
0x1F, 0xFF, // Segment 0
0x3F, 0x1FF, // Segment 1
0x7F, 0x3FF, // Segment 2
0xFF, 0x7FF, // Segment 3
0x1FF, 0xFFF, // Segment 4
0x3FF, 0x1FFF, // Segment 5
0x7FF, 0x3FFF, // Segment 6
0xFFF 0x7FFF // Segment 7
]; ];
const int size = 8; const int size = 8;
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
if (val <= ALAW_SEGMENT_TABLE[i]) { if (val <= table[i]) {
return i; return i;
} }
} }
return size; 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; // RxInt recordingAudioTime = 0.obs; //
RxDouble fps = 0.0.obs; // FPS RxDouble fps = 0.0.obs; // FPS
late VoiceProcessor? voiceProcessor; // late VoiceProcessor? voiceProcessor; //
final int frameLength = 640; //640 final int frameLength = 320; //640
final int sampleRate = 8000; //8000 final int sampleRate = 8000; //8000
List<List<int>> recordingAudioAllFrames = <List<int>>[]; // List<List<int>> recordingAudioAllFrames = <List<int>>[]; //
RxInt rotateAngle = 0.obs; // RxInt rotateAngle = 0.obs; //