llfbandit / record

Audio recorder from microphone to a given file path. No external dependencies, MediaRecorder is used for Android an AVAudioRecorder for iOS.
https://pub.dev/packages/record
243 stars 204 forks source link

Incorrect mic data when accessed by byte buffer #351

Closed jaween closed 4 months ago

jaween commented 4 months ago

Package version 5.1.1

Environment

Describe the bug The values of the audio frames from the microphone change depending on whether they're accessed by index or by the byte buffer.

To Reproduce

  1. Run this example:
    
    import 'dart:typed_data';

import 'package:flutter/material.dart'; import 'package:record/record.dart';

void main() async { WidgetsFlutterBinding.ensureInitialized();

final stream = await AudioRecorder().startStream( const RecordConfig( encoder: AudioEncoder.pcm16bits, sampleRate: 16000, numChannels: 1, ), ); stream.listen((original) { final copy = Uint8List.fromList(original); final originalIndex0 = original[0]; final originalIndex1 = original[1]; final originalByte0 = original.buffer.asByteData().getUint8(0); final originalByte1 = original.buffer.asByteData().getUint8(1); final copyIndex0 = copy[0]; final copyIndex1 = copy[1]; final copyByte0 = copy.buffer.asByteData().getUint8(0); final copyByte1 = copy.buffer.asByteData().getUint8(1); print('Original: ($originalIndex0, $originalIndex1), ($originalByte0, $originalByte1)'); print('Copy: ($copyIndex0, $copyIndex1), ($copyByte0, $copyByte1)'); }); }

2. At each frame, observe the printed output:

Original: 61, 255, 0, 8 Copy: 61, 255, 61, 255


**Expected behavior**
In this case, all four pairs of bytes should be `(61, 255)`, but accessing the original frame by the buffer always produces the same incorrect values `(0, 8)`.

**Additional context**
Copying the values into a separate Uint8List fixes the issue, which suggests the plugin is using an implementation of Uint8List that has a bug. 

Flutter doctor output:

[✓] Flutter (Channel stable, 3.19.1, on macOS 14.5 23F79 darwin-arm64, locale en-AU) • Flutter version 3.19.1 on channel stable at /opt/flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision abb292a07e (4 months ago), 2024-02-20 14:35:05 -0800 • Engine revision 04817c99c9 • Dart version 3.3.0 • DevTools version 2.31.1

[✗] Android toolchain - develop for Android devices ✗ Unable to locate Android SDK. Install Android Studio from: https://developer.android.com/studio/index.html On first launch it will assist you in installing the Android SDK components. (or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions). If the Android SDK has been installed to a custom location, please use flutter config --android-sdk to update to that location.

[✓] Xcode - develop for iOS and macOS (Xcode 15.4) • Xcode at /Applications/Xcode.app/Contents/Developer • Build 15F31d • CocoaPods version 1.15.2

[✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[!] Android Studio (not installed) • Android Studio not found; download from https://developer.android.com/studio/index.html (or visit https://flutter.dev/docs/get-started/install/macos#android-setup for detailed instructions).

[✓] VS Code (version 1.90.2) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.90.0

[✓] Connected device (3 available)
• Jaween’s iPhone (mobile) • 02669b794c29bb14a717a3d0987dc6c5c116d819 • ios • iOS 15.7.9 19H365 • macOS (desktop) • macos • darwin-arm64 • macOS 14.5 23F79 darwin-arm64 • Chrome (web) • chrome • web-javascript • Google Chrome 126.0.6478.114

[✓] Network resources • All expected network resources are available.

! Doctor found issues in 2 categories.

llfbandit commented 4 months ago

There's currently a bug on iOS and macos that has been fixed through 2242ae3. A release will be published soon. I answered too quickly.

If you need to convert int8 to int16 list, there's convertBytesToInt16 utility method for this. I guess the diff you see is about direct allocation of Uint8List and a view of it. Dart doesn't provide this distinction from our perpective.