liwei1dao 1 year ago
parent
commit
660820065e
  1. 2
      lib/modules/chat/controllers/chat_controller.dart
  2. 6
      lib/modules/chat/views/animated_gradient_background.dart
  3. 17
      lib/modules/chat/views/chat_view.dart
  4. 25
      local_plugins/opus/example/lib/main.dart

2
lib/modules/chat/controllers/chat_controller.dart

@ -588,6 +588,8 @@ class ChatController extends GetxController {
if (isHoldSpeak.value) return;
_voiceInteractionService.pauseVoiceInteraction();
// 中断当前响应
_interruptCurrentResponse("发送新消息,中断当前响应");
try {
final recognitionStream = await _asrService.startContinuousRecognition();

6
lib/modules/chat/views/animated_gradient_background.dart

@ -1,7 +1,9 @@
import 'package:flutter/material.dart';
class AnimatedGradientBackground extends StatefulWidget {
const AnimatedGradientBackground({super.key});
final Widget child;
const AnimatedGradientBackground(this.child, {super.key});
@override
State<AnimatedGradientBackground> createState() =>
@ -58,8 +60,10 @@ class _AnimatedGradientBackgroundState extends State<AnimatedGradientBackground>
end: _endAnimation.value!,
),
),
child: child,
);
},
child: widget.child,
);
}
}

17
lib/modules/chat/views/chat_view.dart

@ -513,18 +513,23 @@ class ChatView extends GetView<ChatController> {
// 构建语音输入面板
Widget _buildVoiceInputPanel(bool isDarkMode) {
return Container(
decoration: BoxDecoration(
color: isDarkMode ? AppColors.cardBackground : Colors.white,
),
child: SafeArea(
return AnimatedGradientBackground(
SafeArea(
child: Column(
children: [
Row(
children: [],
),
Expanded(
child: AnimatedGradientBackground(),
child: Container(
width: 100.w,
height: 100.w,
decoration: BoxDecoration(
color:
isDarkMode ? Colors.white.withOpacity(0.1) : Colors.white,
shape: BoxShape.circle,
),
),
),
SizedBox(
height: 80.h,

25
local_plugins/opus/example/lib/main.dart

@ -1,6 +1,7 @@
import 'dart:typed_data';
import 'package:flutter/material.dart';
import 'package:opus/opus.dart';
import '../../lib/opus.dart';
void main() {
runApp(const OpusExampleApp());
@ -92,13 +93,13 @@ class _OpusExamplePageState extends State<OpusExamplePage> {
const int frequency = 440; // 440Hz - A4音符
const int durationMs = 20; // 20ms,按照常规frameSize=960
const int frameSize = 960; // 对应20ms@48kHz
// 创建PCM数据缓冲区,16位有符号整数,每采样2字节,双声道
final int samplesToGenerate = (sampleRate * durationMs / 1000).round();
final int bufferSize = samplesToGenerate * channels * 2; // 2字节/样本
final byteBuffer = ByteData(bufferSize);
// 生成正弦波
for (int i = 0; i < samplesToGenerate; i++) {
// 计算当前时间点
@ -107,18 +108,17 @@ class _OpusExamplePageState extends State<OpusExamplePage> {
final double amplitude = sin(2 * 3.14159265359 * frequency * t);
// 缩放到16位有符号整数范围 (-32768 to 32767)
final int sample = (amplitude * 32767).round();
// 为所有声道写入相同的值
for (int channel = 0; channel < channels; channel++) {
final int offset = (i * channels + channel) * 2;
byteBuffer.setInt16(offset, sample, Endian.little);
}
}
_samplePcmData = Uint8List.fromList(
List.generate(bufferSize, (index) => byteBuffer.getUint8(index))
);
List.generate(bufferSize, (index) => byteBuffer.getUint8(index)));
setState(() {
_statusMessage = '已创建${_samplePcmData!.length}字节测试PCM数据';
});
@ -272,6 +272,9 @@ class _OpusExamplePageState extends State<OpusExamplePage> {
String _formatBytes(Uint8List data) {
final length = data.length > 16 ? 16 : data.length;
return data.sublist(0, length).map((e) => e.toRadixString(16).padLeft(2, '0')).join(' ');
return data
.sublist(0, length)
.map((e) => e.toRadixString(16).padLeft(2, '0'))
.join(' ');
}
}
}

Loading…
Cancel
Save