User report after the 8x boost commit (e85a6d3): playback STILL broken, but now the diagnostic clearly shows the actual problem. Render-callback peak_out_i16 SATURATES at 32767 on speech peaks (cb=600, 1100, 1200, 2400) because the 8x boost amplifies an already-loud signal into hard clipping. Quiet content reaches audible level but loud peaks are catastrophically distorted. The 8x boost was treating the wrong cause. Real root cause (researched online after user prompted: 'this is iOS a popular platform, there must be solutions'): iOS has TWO independent audio channels: In-call channel (.voiceChat / .videoChat modes) * Routes through the phone-call audio path. * Aggressively ducks non-voice content to the earpiece. * Volume controlled by a separate in-call hardware register, not the side buttons when not actively on a phone call. Media channel (.default mode) * Routes through the standard media playback path. * No automatic ducking. * Volume controlled by the side volume buttons normally. With AVAudioSession mode .voiceChat, iOS sends our output through the in-call channel which plays at 'earpiece-level' loudness on the speaker too. Signal is technically present but buried under the speaker's noise floor. With mode .default + .defaultToSpeaker option, output routes via media channel and plays at normal loudness. Both Twilio (video-quickstart-ios) and Daily.co (patched WebRTC module) document the same workaround and use VPIO for AEC while keeping the session mode at .default for loud playback: github.com/twilio/video-quickstart-ios/issues/522 stackoverflow.com/questions/79834998 (Daily.co) The user also noticed 'tx/rx almost no changes even receiving packages' \u2014 likely a misinterpretation of the frames counter not advancing as fast as expected during quiet voice; AudioHandler returns silence when its jitter buffer is in buffering_samples state which doesn't fire 'decode failed' but also doesn't increment frames_received. The real issue is still the playback ducking; the counter behaviour is a downstream symptom. Changes: 1. AppDelegate.swift: AVAudioSession mode .voiceChat -> .default with options [.defaultToSpeaker, .allowBluetoothHFP, .allowBluetoothA2DP]. VPIO continues to do its job (AEC, NS, AGC on the mic side); only the playback routing changes. The earlier 'speaker selector silent under .default' bug does NOT apply because we no longer use cpal RemoteIO \u2014 VPIO honours overrideOutputAudioPort under any mode. 2. ios_voice_unit.rs: revert the 8x output boost frome85a6d3. With media-channel routing, signal levels are correct and no software amplification is needed. Render callback restored to plain (l+r)*0.5*gain downmix. 3. ios_voice_unit.rs: revert the BypassVoiceProcessing toggle fromc16318c. The VPIO chain stays enabled so we keep capture-side AEC/AGC/NS for free \u2014 the playback breakage it was trying to fix was the wrong layer all along. 4. ios_voice_unit.rs: drop the diagnostic render-callback log line. Production-clean code; can be re-enabled by reverting the diff in the closure if future debugging needs it. Build counter 69 -> 70.
138 lines
6.0 KiB
YAML
138 lines
6.0 KiB
YAML
name: chanora_flutter
|
|
description: "Chanora — cross-platform voice client for TeamSpeak-compatible servers."
|
|
# The following line prevents the package from being accidentally published to
|
|
# pub.dev using `flutter pub publish`. This is preferred for private packages.
|
|
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
|
|
|
# The following defines the version and build number for your application.
|
|
# A version number is three numbers separated by dots, like 1.2.43
|
|
# followed by an optional build number separated by a +.
|
|
# Both the version and the builder number may be overridden in flutter
|
|
# build by specifying --build-name and --build-number, respectively.
|
|
# In Android, build-name is used as versionName while build-number used as versionCode.
|
|
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
|
|
# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
|
|
# Read more about iOS versioning at
|
|
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
|
|
# In Windows, build-name is used as the major, minor, and patch parts
|
|
# of the product and file versions while build-number is used as the build suffix.
|
|
version: 1.0.0-rc.8+70
|
|
|
|
environment:
|
|
sdk: ^3.11.5
|
|
|
|
# Dependencies specify other packages that your package needs in order to work.
|
|
# To automatically upgrade your package dependencies to the latest versions
|
|
# consider running `flutter pub upgrade --major-versions`. Alternatively,
|
|
# dependencies can be manually updated by changing the version numbers below to
|
|
# the latest version available on pub.dev. To see which dependencies have newer
|
|
# versions available, run `flutter pub outdated`.
|
|
dependencies:
|
|
flutter:
|
|
sdk: flutter
|
|
flutter_localizations:
|
|
sdk: flutter
|
|
intl: any
|
|
|
|
# The following adds the Cupertino Icons font to your application.
|
|
# Use with the CupertinoIcons class for iOS style icons.
|
|
cupertino_icons: ^1.0.8
|
|
flutter_rust_bridge: 2.12.0
|
|
freezed_annotation: ^3.1.0
|
|
connectivity_plus: ^6.1.0
|
|
path_provider: ^2.1.4
|
|
# audio_session 0.2.3 (MIT, Ryan Heise, 865k downloads) gives us
|
|
# programmatic access to AVAudioSession on iOS + AudioManager on
|
|
# Android. We use:
|
|
#
|
|
# * AVAudioSession.availableInputs \u2014 enumerate real input ports
|
|
# (Built-in Mic, Bluetooth HFP, wired headset, USB).
|
|
# * AVAudioSession.currentRoute \u2014 inputs + outputs of the
|
|
# active route.
|
|
# * AVAudioSession.setPreferredInput(port) \u2014 switch input
|
|
# (also drives matching output for HFP devices).
|
|
# * AVAudioSession.overrideOutputAudioPort(speaker|none) \u2014
|
|
# toggle the built-in receiver/earpiece vs speakerphone.
|
|
# * AVAudioSession.routeChangeStream \u2014 live notifications when
|
|
# the user plugs / unplugs / connects a device.
|
|
#
|
|
# This is the right primitive for a VoIP-style 'pick speaker /
|
|
# receiver / AirPods / wired' picker. Discord, WhatsApp, FaceTime
|
|
# all do exactly this. We previously tried audio_router 1.1.1
|
|
# whose iOS path is AVRoutePickerView (the AirPlay button) \u2014 the
|
|
# wrong UI: only lists AirPlay output destinations, not the
|
|
# speaker/receiver/Bluetooth choices we actually want.
|
|
audio_session: ^0.2.3
|
|
# package_info_plus 8.x (Flutter Community Plus, BSD-3, ~3M
|
|
# downloads) exposes the platform-canonical app version + build
|
|
# number at runtime so the About dialog (and any future
|
|
# diagnostic export) can display "v1.0.0-rc.8+60" sourced from
|
|
# the SAME pubspec.yaml field that drives CFBundleShortVersionString
|
|
# + CFBundleVersion on iOS and versionName + versionCode on
|
|
# Android. Single source of truth means the version on the
|
|
# iPhone screen always matches the commit that built it; no
|
|
# more "am I testing the right build?" question during the
|
|
# iOS audio test cycle.
|
|
package_info_plus: ^8.0.0
|
|
|
|
dev_dependencies:
|
|
flutter_test:
|
|
sdk: flutter
|
|
|
|
# The "flutter_lints" package below contains a set of recommended lints to
|
|
# encourage good coding practices. The lint set provided by the package is
|
|
# activated in the `analysis_options.yaml` file located at the root of your
|
|
# package. See that file for information about deactivating specific lint
|
|
# rules and activating additional ones.
|
|
flutter_lints: ^6.0.0
|
|
freezed: ^3.2.5
|
|
build_runner: ^2.15.0
|
|
|
|
# For information on the generic Dart part of this file, see the
|
|
# following page: https://dart.dev/tools/pub/pubspec
|
|
|
|
# The following section is specific to Flutter packages.
|
|
flutter:
|
|
|
|
# Generate localization bindings from lib/l10n/*.arb at build time.
|
|
# Per DEC-015 (register v0.9.5) Chanora ships English + Chinese
|
|
# Simplified at MVP with an i18n-ready architecture for additional
|
|
# languages.
|
|
generate: true
|
|
|
|
# The following line ensures that the Material Icons font is
|
|
# included with your application, so that you can use the icons in
|
|
# the material Icons class.
|
|
uses-material-design: true
|
|
|
|
# To add assets to your application, add an assets section, like this:
|
|
# assets:
|
|
# - images/a_dot_burr.jpeg
|
|
# - images/a_dot_ham.jpeg
|
|
|
|
# An image asset can refer to one or more resolution-specific "variants", see
|
|
# https://flutter.dev/to/resolution-aware-images
|
|
|
|
# For details regarding adding assets from package dependencies, see
|
|
# https://flutter.dev/to/asset-from-package
|
|
|
|
# To add custom fonts to your application, add a fonts section here,
|
|
# in this "flutter" section. Each entry in this list should have a
|
|
# "family" key with the font family name, and a "fonts" key with a
|
|
# list giving the asset and other descriptors for the font. For
|
|
# example:
|
|
# fonts:
|
|
# - family: Schyler
|
|
# fonts:
|
|
# - asset: fonts/Schyler-Regular.ttf
|
|
# - asset: fonts/Schyler-Italic.ttf
|
|
# style: italic
|
|
# - family: Trajan Pro
|
|
# fonts:
|
|
# - asset: fonts/TrajanPro.ttf
|
|
# - asset: fonts/TrajanPro_Bold.ttf
|
|
# weight: 700
|
|
#
|
|
# For details regarding fonts from package dependencies,
|
|
# see https://flutter.dev/to/font-from-package
|