dart - Audio has a lot of jitters and distorted noise when sending it to mumble server from flutter app - Stack Overflow

admin2025-04-29  3

i created a flutter app similar to clubhouse that provides rooms to have audio chats with users, now everything works as expected in the app and i am able to listen to audio when i send audio from mumble client to test but when i send audio from the microphone on my app, i hear a lot of distorted sounds on the client and other devices.

what could be the issue and what can i change in the code to avoid the distortion in the audio, i have tried with various frame times and input sample rates but it doesn't fix my issue

i am using the dumble package for flutter : /packages/dumble

Any suggestions will be helpful, Thanks!

const int inputSampleRate = 48000;
const int frameTimeMs = 40; // use frames of 40ms
const FrameTime frameTime = FrameTime.ms40;
const int outputSampleRate = 48000;
const int channels = 1;
int frameByteSize = (inputSampleRate ~/ 1000) * frameTimeMs * channels * 2;
// const int BUFFER_SIZE = 960 * 2; // 16-bit samples

class MumbleAPI {
  late MumbleClient client;
  bool _isConnected = false;
  final String host = "SERVER_HOST_IP";
  final int port = PORT_ADDRESS;

  AudioFrameSink? _audioOutput;
  late StreamOpusEncoder<int> encoder;

  //// Connect to the Mumble Server
  Future<void> connect({
    required String username,
    String password = '',
  }) async {
    try {
      client = await MumbleClient.connect(
          options: ConnectionOptions(
            host: host,
            port: port,
            name: username,
            context: await CertificateManager.getSecurityContext(),
          ),
          onBadCertificate: (X509Certificate certificate) {
            //Accept every certificate
            return true;
          });
      MumbleExampleCallback callback = MumbleExampleCallback(client);
      client.add(callback);
      client.self.add(SelfCallback(client.self.session));
      client.self.registerUser();
      client.self.setSelfMute(mute: true);
      client.audio.add(callback);
      _isConnected = true;
      encoder = StreamOpusEncoder.bytes(
          frameTime: frameTime,
          floatInput: false,
          sampleRate: inputSampleRate,
          channels: channels,
          application: Application.voip);
      _audioOutput = client.audio.sendAudio(codec: AudioCodec.opus);

      /// Method - as documented in the the dumble package
      /// .dart
      /// instead of using the file to get data, i converted it to get stream from the
      /// mic_stream and using it to yield the buffer and sending it.
   

      microphoneAudioStream()
          .transform(encoder)
          .map((Uint8List audioBytes) => AudioFrame.outgoing(frame: audioBytes))
          .pipe(_audioOutput!);

      // Watch all users that are already on the server
      // New users will reported to the callback and we will
      // watch these new users in onUserAdded below
      client.getUsers().values.forEach((User element) => element.add(callback));

      print('Connected to the server as $username');
    } catch (e) {
      print('Failed to connect: $e');
      rethrow;
    }
  }

  Stream<List<int>> microphoneAudioStream() async* {
    // Request permission to use the microphone
    mic_stream.MicStream.shouldRequestPermission(true);

    // Start capturing audio from the microphone with the specified sample rate and config
    Stream<Uint8List>? micStream = mic_stream.MicStream.microphone(
      audioSource: mic_stream.AudioSource.DEFAULT,
      sampleRate: inputSampleRate,
      channelConfig: mic_stream.ChannelConfig.CHANNEL_IN_MONO,
      audioFormat: mic_stream.AudioFormat.ENCODING_PCM_16BIT,
    );
    if (micStream == null) {
      throw Exception('Failed to initialize microphone stream.');
    }
    Uint8List? buffer;
    int bufferIndex = 0;
    await for (Uint8List data in micStream) {
      int consumed = 0;
      while (consumed < data.length) {
        if (buffer == null && frameByteSize <= (data.length - consumed)) {
          yield data.buffer.asUint8List(consumed, frameByteSize);
          consumed += frameByteSize;
        } else if (buffer == null) {
          buffer = Uint8List(frameByteSize);
          bufferIndex = 0;
        } else {
          int read = min(frameByteSize - bufferIndex, data.length - consumed);
          buffer.setRange(bufferIndex, bufferIndex + read, data, consumed);
          consumed += read;
          bufferIndex += read;
          if (bufferIndex == frameByteSize) {
            yield buffer;
            buffer = null;
          }
        }
      }
    } // Send remaining buffer if exists
    if (buffer != null && bufferIndex > 0) {
      yield buffer.sublist(0, bufferIndex);
    }
  }

I have tried using the frame time of 10ms, 20ms, 40ms, but it did not succeed, i have also used input sample rate of 8000 and 48000, but again the distorted audio did not fix.

转载请注明原文地址:http://anycun.com/QandA/1745857334a91299.html