Skip to content

Commit

Permalink
fix(iOS): ensure sampleRate settings get applied appropriately (#61)
Browse files Browse the repository at this point in the history
  • Loading branch information
yama-yeah authored Apr 1, 2023
1 parent 789d04a commit 66efe47
Show file tree
Hide file tree
Showing 15 changed files with 116 additions and 73 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
.DS_Store
.dart_tool/

.vscode

.idea
.packages
.pub/
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 0.6.5
* Fixed sampleRate settings to be adapted to iOS

## 0.6.4

* Change interface from having const default values to taking nullable parameters (#54)
Expand Down
2 changes: 1 addition & 1 deletion example/ios/Flutter/AppFrameworkInfo.plist
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>8.0</string>
<string>11.0</string>
</dict>
</plist>
2 changes: 1 addition & 1 deletion example/ios/Podfile
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Uncomment this line to define a global platform for your project
# platform :ios, '9.0'
# platform :ios, '11.0'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
Expand Down
24 changes: 13 additions & 11 deletions example/ios/Runner.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
archiveVersion = 1;
classes = {
};
objectVersion = 50;
objectVersion = 54;
objects = {

/* Begin PBXBuildFile section */
Expand Down Expand Up @@ -163,7 +163,7 @@
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 1020;
LastUpgradeCheck = 1300;
ORGANIZATIONNAME = "";
TargetAttributes = {
97C146ED1CF9000F007C117D = {
Expand Down Expand Up @@ -207,6 +207,7 @@
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
Expand Down Expand Up @@ -238,6 +239,7 @@
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
Expand Down Expand Up @@ -347,7 +349,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
Expand All @@ -363,7 +365,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = TM2B4SJXNJ;
DEVELOPMENT_TEAM = "";
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
Expand All @@ -378,7 +380,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = "com.aaron.mic-stream-example";
PRODUCT_BUNDLE_IDENTIFIER = "com.example.mic-tester";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
Expand Down Expand Up @@ -433,7 +435,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
Expand Down Expand Up @@ -482,7 +484,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 11.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
Expand All @@ -500,7 +502,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = TM2B4SJXNJ;
DEVELOPMENT_TEAM = "";
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
Expand All @@ -515,7 +517,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = "com.aaron.mic-stream-example";
PRODUCT_BUNDLE_IDENTIFIER = "com.example.mic-tester";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
Expand All @@ -531,7 +533,7 @@
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = TM2B4SJXNJ;
DEVELOPMENT_TEAM = "";
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
Expand All @@ -546,7 +548,7 @@
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = "com.aaron.mic-stream-example";
PRODUCT_BUNDLE_IDENTIFIER = "com.example.mic-tester";
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1020"
LastUpgradeVersion = "1300"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
Expand All @@ -27,8 +27,6 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
Expand All @@ -38,8 +36,8 @@
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
Expand All @@ -61,8 +59,6 @@
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
Expand Down
4 changes: 4 additions & 0 deletions example/ios/Runner/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleExecutable</key>
Expand All @@ -24,6 +26,8 @@
<true/>
<key>NSMicrophoneUsageDescription</key>
<string>Microphone access required</string>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
<key>UILaunchStoryboardName</key>
<string>LaunchScreen</string>
<key>UIMainStoryboardFile</key>
Expand Down
57 changes: 26 additions & 31 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,7 @@ import 'dart:async';
import 'dart:math';
import 'dart:core';

import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
import 'package:flutter/animation.dart';
import 'package:flutter/rendering.dart';

import 'package:mic_stream/mic_stream.dart';

Expand Down Expand Up @@ -35,7 +32,6 @@ class _MicStreamExampleAppState extends State<MicStreamExampleApp>

Random rng = new Random();


// Refreshes the Widget for every possible tick to force a rebuild of the sound wave
late AnimationController controller;

Expand All @@ -48,7 +44,6 @@ class _MicStreamExampleAppState extends State<MicStreamExampleApp>
int page = 0;
List state = ["SoundWavePage", "IntensityWavePage", "InformationPage"];


@override
void initState() {
print("Init application");
Expand Down Expand Up @@ -79,7 +74,6 @@ class _MicStreamExampleAppState extends State<MicStreamExampleApp>
Future<bool> _changeListening() async =>
!isRecording ? await _startListening() : _stopListening();


late int bytesPerSample;
late int samplesPerSecond;

Expand All @@ -96,13 +90,15 @@ class _MicStreamExampleAppState extends State<MicStreamExampleApp>

stream = await MicStream.microphone(
audioSource: AudioSource.DEFAULT,
sampleRate: 1000 * (rng.nextInt(50) + 30),
// sampleRate: 1000 * (rng.nextInt(50) + 30),
sampleRate: 48000,
channelConfig: ChannelConfig.CHANNEL_IN_MONO,
audioFormat: AUDIO_FORMAT);
// after invoking the method for the first time, though, these will be available;
// It is not necessary to setup a listener first, the stream only needs to be returned first
print("Start Listening to the microphone, sample rate is ${await MicStream.sampleRate}, bit depth is ${await MicStream.bitDepth}, bufferSize: ${await MicStream.bufferSize}");
bytesPerSample = (await MicStream.bitDepth)! ~/ 8;
print(
"Start Listening to the microphone, sample rate is ${await MicStream.sampleRate}, bit depth is ${await MicStream.bitDepth}, bufferSize: ${await MicStream.bufferSize}");
bytesPerSample = (await MicStream.bitDepth)! ~/ 8;
samplesPerSecond = (await MicStream.sampleRate)!.toInt();
localMax = null;
localMin = null;
Expand All @@ -117,10 +113,8 @@ class _MicStreamExampleAppState extends State<MicStreamExampleApp>
}

void _calculateSamples(samples) {
if (page == 0)
_calculateWaveSamples(samples);
else if (page == 1)
_calculateIntensitySamples(samples);
if (page == 0) _calculateWaveSamples(samples);
else if (page == 1) _calculateIntensitySamples(samples);
}

void _calculateWaveSamples(samples) {
Expand All @@ -144,28 +138,29 @@ class _MicStreamExampleAppState extends State<MicStreamExampleApp>
}
first = !first;
}
print(visibleSamples);
print(visibleSamples.length);
}

void _calculateIntensitySamples(samples) {
currentSamples ??= [];
int currentSample = 0;
eachWithIndex(samples, (i, int sample) {
currentSample += sample;
if ((i % bytesPerSample) == bytesPerSample-1) {
if ((i % bytesPerSample) == bytesPerSample - 1) {
currentSamples!.add(currentSample);
currentSample = 0;
}
});

if (currentSamples!.length >= samplesPerSecond/10) {
visibleSamples.add(currentSamples!.map((i) => i).toList().reduce((a, b) => a+b));
if (currentSamples!.length >= samplesPerSecond / 10) {
visibleSamples
.add(currentSamples!.map((i) => i).toList().reduce((a, b) => a + b));
localMax ??= visibleSamples.last;
localMin ??= visibleSamples.last;
localMax = max(localMax!, visibleSamples.last);
localMin = min(localMin!, visibleSamples.last);
currentSamples = [];
setState(() {});
setState(() {});
}
}

Expand Down Expand Up @@ -195,8 +190,7 @@ class _MicStreamExampleAppState extends State<MicStreamExampleApp>
if (isRecording) setState(() {});
})
..addStatusListener((status) {
if (status == AnimationStatus.completed)
controller.reverse();
if (status == AnimationStatus.completed) controller.reverse();
else if (status == AnimationStatus.dismissed) controller.forward();
})
..forward();
Expand Down Expand Up @@ -297,7 +291,8 @@ class WavePainter extends CustomPainter {
// int absMax = 255*4; //(AUDIO_FORMAT == AudioFormat.ENCODING_PCM_8BIT) ? 127 : 32767;
// int absMin; //(AUDIO_FORMAT == AudioFormat.ENCODING_PCM_8BIT) ? 127 : 32767;

WavePainter({this.samples, this.color, this.context, this.localMax, this.localMin});
WavePainter(
{this.samples, this.color, this.context, this.localMax, this.localMin});

@override
void paint(Canvas canvas, Size? size) {
Expand All @@ -309,9 +304,7 @@ class WavePainter extends CustomPainter {
..strokeWidth = 1.0
..style = PaintingStyle.stroke;

if (samples!.length == 0)
return;

if (samples!.length == 0) return;

points = toPoints(samples);

Expand All @@ -327,18 +320,22 @@ class WavePainter extends CustomPainter {
// Maps a list of ints and their indices to a list of points on a cartesian grid
List<Offset> toPoints(List<int>? samples) {
List<Offset> points = [];
if (samples == null)
samples = List<int>.filled(size!.width.toInt(), (0.5).toInt());
double pixelsPerSample = size!.width/samples.length;
if (samples == null) samples = List<int>.filled(size!.width.toInt(), (0.5).toInt());
double pixelsPerSample = size!.width / samples.length;
for (int i = 0; i < samples.length; i++) {
var point = Offset(i * pixelsPerSample, 0.5 * size!.height * pow((samples[i] - localMin!)/(localMax! - localMin!), 5));
var point = Offset(
i * pixelsPerSample,
0.5 *
size!.height *
pow((samples[i] - localMin!) / (localMax! - localMin!), 5));
points.add(point);
}
return points;
}

double project(int val, int max, double height) {
double waveHeight = (max == 0) ? val.toDouble() : (val / max) * 0.5 * height;
double waveHeight =
(max == 0) ? val.toDouble() : (val / max) * 0.5 * height;
return waveHeight + 0.5 * height;
}
}
Expand Down Expand Up @@ -370,7 +367,6 @@ class Statistics extends StatelessWidget {
}
}


Iterable<T> eachWithIndex<E, T>(
Iterable<T> items, E Function(int index, T item) f) {
var index = 0;
Expand All @@ -382,4 +378,3 @@ Iterable<T> eachWithIndex<E, T>(

return items;
}

2 changes: 1 addition & 1 deletion example/macos/Podfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
platform :osx, '10.11'
platform :osx, '10.14'

# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
Expand Down
Loading

0 comments on commit 66efe47

Please sign in to comment.