Canardoux / flutter_sound

Flutter plugin for sound. Audio recorder and player.
Mozilla Public License 2.0
880 stars 575 forks source link

[BUG]: toStream on iOS returning long buffer chunks #957

Open zakecSudo opened 1 year ago

zakecSudo commented 1 year ago

Flutter Sound Version : 9.2.13

- |-- flutter_sound 9.2.13
|   |-- flutter_sound_platform_interface 9.2.13
|   |-- flutter_sound_web 9.2.13
|   |   |-- flutter_sound_platform_interface...

Severity


Platforms you faced the error


Describe the bug I've created an app that captures data from flutterSoundRecorder and then calculates the volume from it (I know i could just use the decibels from recorder but i also have a use case where i have audioFile already given and i need to calculate the amplitude from it). Everything was working fine on android but when i tested the app on an iOS device i noticed a stutter in live waveform data display. After further investigation i noticed that on android the data from stream is coming in smaller chunks of ~200(recorders sampleRate is set to 16.000) while on the iOS device the data is coming in exact 12.800 samples. I assume the problem is with how often the iOS devices are transmitting the data from the microphone to the stream. Is there any way we could maybe set the bufferSubscription duration in a similar way as we can set subscription duration with Future setSubscriptionDuration(Duration duration).

My recorder configuration

recordingDataController.stream.listen((buffer) => {bufferToBufferData(buffer)});

await myRecorder.startRecorder(
  toStream: recordingDataController.sink,
  codec: Codec.pcm16,
  numChannels: 1,
  sampleRate: 16000,
);

How i capture data and calculate the volume from it

void bufferToBufferData(FoodData buffer) {
  rawRecordingData.addAll(buffer.data);
  _calculateVolume();
}

/// Calculate RMS (Root Mean Square) for certain interval of samples
void _calculateVolume({int interval = 800}) {
  List<int> rawData = Int16List.view(Uint8List.fromList(rawRecordingData).buffer);
  while (decibelsAdded < rawData.length ~/ interval) {
    double sumOfSquares = 0;
    for (var element in rawData.sublist(decibelsAdded * interval, decibelsAdded * interval + interval)) {
      sumOfSquares += pow(element / 32767, 2);
    }
    double meanSquare = sumOfSquares / interval;
    double rms = sqrt(meanSquare);
    decibels.add(rms);

  _waveformData.add(decibels);
}

To Reproduce Steps to reproduce the behavior:

  1. Start recording
  2. Capture data from stream continously
Goallying commented 1 year ago

I have the same issue, How to resolve it ?

zakecSudo commented 1 year ago

I have the same issue, How to resolve it ?

No luck resolving it so far.

sveinbjornt commented 1 year ago

I'm having the same problem. For what it's worth, I worked around it by cloning the project and editing the file FlautoRecorderEngine.mm:

This is the pertinent line.

[inputNode installTapOnBus: 0 bufferSize: 20480 format: inputFormat block: ...

Reduce bufferSize to 4096 or something, and you should get smaller buffers (not necessarily 4096 bytes, AVAudioEngine doesn't seem to respect this param literally) and thus more frequent updates.

github-actions[bot] commented 11 months ago

This issue is stale because it has been open 90 days with no activity. Leave a comment or this will be closed in 7 days.