Skip to content

Commit ae5ac4b

Browse files
authored
feat: comply with flutter's and dart's null safety (anarchuser#25)
1 parent 35305d9 commit ae5ac4b

File tree

5 files changed

+66
-64
lines changed

5 files changed

+66
-64
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
### 0.5.3
2+
3+
* Comply with [Null safety](https://flutter.dev/docs/null-safety)
4+
15
### 0.5.2
26

37
* Fixed permissions to record audio not being requested (solves [#19](https://github.com/anarchuser/mic_stream/issues/19))

example/lib/main.dart

Lines changed: 41 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,22 @@ class MicStreamExampleApp extends StatefulWidget {
2828

2929
class _MicStreamExampleAppState extends State<MicStreamExampleApp>
3030
with SingleTickerProviderStateMixin, WidgetsBindingObserver {
31-
Stream stream;
32-
StreamSubscription listener;
33-
List<int> currentSamples = [];
31+
Stream? stream;
32+
late StreamSubscription listener;
33+
List<int>? currentSamples = [];
3434
List<int> visibleSamples = [];
35-
int localMax;
36-
int localMin;
35+
int? localMax;
36+
int? localMin;
3737

3838

3939
// Refreshes the Widget for every possible tick to force a rebuild of the sound wave
40-
AnimationController controller;
40+
late AnimationController controller;
4141

4242
Color _iconColor = Colors.white;
4343
bool isRecording = false;
4444
bool memRecordingState = false;
45-
bool isActive;
46-
DateTime startTime;
45+
late bool isActive;
46+
DateTime? startTime;
4747

4848
int page = 0;
4949
List state = ["SoundWavePage", "IntensityWavePage", "InformationPage"];
@@ -53,7 +53,7 @@ class _MicStreamExampleAppState extends State<MicStreamExampleApp>
5353
void initState() {
5454
print("Init application");
5555
super.initState();
56-
WidgetsBinding.instance.addObserver(this);
56+
WidgetsBinding.instance!.addObserver(this);
5757
setState(() {
5858
initPlatformState();
5959
});
@@ -80,8 +80,8 @@ class _MicStreamExampleAppState extends State<MicStreamExampleApp>
8080
!isRecording ? await _startListening() : _stopListening();
8181

8282

83-
int bytesPerSample;
84-
int samplesPerSecond;
83+
late int bytesPerSample;
84+
late int samplesPerSecond;
8585

8686
Future<bool> _startListening() async {
8787
print("STARRT LISTENING");
@@ -98,8 +98,8 @@ class _MicStreamExampleAppState extends State<MicStreamExampleApp>
9898
// after invoking the method for the first time, though, these will be available;
9999
// It is not necessary to setup a listener first, the stream only needs to be returned first
100100
print("Start Listening to the microphone, sample rate is ${await MicStream.sampleRate}, bit depth is ${await MicStream.bitDepth}, bufferSize: ${await MicStream.bufferSize}");
101-
bytesPerSample = (await MicStream.bitDepth / 8).toInt();
102-
samplesPerSecond = (await MicStream.sampleRate).toInt();
101+
bytesPerSample = ((await MicStream.bitDepth)! / 8).toInt();
102+
samplesPerSecond = (await MicStream.sampleRate)!.toInt();
103103
localMax = null;
104104
localMin = null;
105105

@@ -108,7 +108,7 @@ class _MicStreamExampleAppState extends State<MicStreamExampleApp>
108108
startTime = DateTime.now();
109109
});
110110
visibleSamples = [];
111-
listener = stream.listen(_calculateSamples);
111+
listener = stream!.listen(_calculateSamples);
112112
return true;
113113
}
114114

@@ -121,7 +121,7 @@ class _MicStreamExampleAppState extends State<MicStreamExampleApp>
121121

122122
void _calculateWaveSamples(samples) {
123123
bool first = true;
124-
visibleSamples = List();
124+
visibleSamples = [];
125125
int tmp = 0;
126126
for (int sample in samples) {
127127
if (sample > 128) sample -= 255;
@@ -133,8 +133,8 @@ class _MicStreamExampleAppState extends State<MicStreamExampleApp>
133133

134134
localMax ??= visibleSamples.last;
135135
localMin ??= visibleSamples.last;
136-
localMax = max(localMax, visibleSamples.last);
137-
localMin = min(localMin, visibleSamples.last);
136+
localMax = max(localMax!, visibleSamples.last);
137+
localMin = min(localMin!, visibleSamples.last);
138138

139139
tmp = 0;
140140
}
@@ -146,20 +146,20 @@ class _MicStreamExampleAppState extends State<MicStreamExampleApp>
146146
void _calculateIntensitySamples(samples) {
147147
currentSamples ??= [];
148148
int currentSample = 0;
149-
eachWithIndex(samples, (i, sample) {
149+
eachWithIndex(samples, (i, int sample) {
150150
currentSample += sample;
151151
if ((i % bytesPerSample) == bytesPerSample-1) {
152-
currentSamples.add(currentSample);
152+
currentSamples!.add(currentSample);
153153
currentSample = 0;
154154
}
155155
});
156156

157-
if (currentSamples.length >= samplesPerSecond/10) {
158-
visibleSamples.add(currentSamples.map((i) => i).toList().reduce((a, b) => a+b));
157+
if (currentSamples!.length >= samplesPerSecond/10) {
158+
visibleSamples.add(currentSamples!.map((i) => i).toList().reduce((a, b) => a+b));
159159
localMax ??= visibleSamples.last;
160160
localMin ??= visibleSamples.last;
161-
localMax = max(localMax, visibleSamples.last);
162-
localMin = min(localMin, visibleSamples.last);
161+
localMax = max(localMax!, visibleSamples.last);
162+
localMin = min(localMin!, visibleSamples.last);
163163
currentSamples = [];
164164
setState(() {});
165165
}
@@ -275,19 +275,19 @@ class _MicStreamExampleAppState extends State<MicStreamExampleApp>
275275
void dispose() {
276276
listener.cancel();
277277
controller.dispose();
278-
WidgetsBinding.instance.removeObserver(this);
278+
WidgetsBinding.instance!.removeObserver(this);
279279
super.dispose();
280280
}
281281
}
282282

283283
class WavePainter extends CustomPainter {
284-
int localMax;
285-
int localMin;
286-
List<int> samples;
287-
List<Offset> points;
288-
Color color;
289-
BuildContext context;
290-
Size size;
284+
int? localMax;
285+
int? localMin;
286+
List<int>? samples;
287+
late List<Offset> points;
288+
Color? color;
289+
BuildContext? context;
290+
Size? size;
291291

292292
// Set max val possible in stream, depending on the config
293293
// int absMax = 255*4; //(AUDIO_FORMAT == AudioFormat.ENCODING_PCM_8BIT) ? 127 : 32767;
@@ -296,16 +296,16 @@ class WavePainter extends CustomPainter {
296296
WavePainter({this.samples, this.color, this.context, this.localMax, this.localMin});
297297

298298
@override
299-
void paint(Canvas canvas, Size size) {
300-
this.size = context.size;
299+
void paint(Canvas canvas, Size? size) {
300+
this.size = context!.size;
301301
size = this.size;
302302

303303
Paint paint = new Paint()
304-
..color = color
304+
..color = color!
305305
..strokeWidth = 1.0
306306
..style = PaintingStyle.stroke;
307307

308-
if (samples.length == 0)
308+
if (samples!.length == 0)
309309
return;
310310

311311

@@ -321,13 +321,13 @@ class WavePainter extends CustomPainter {
321321
bool shouldRepaint(CustomPainter oldPainting) => true;
322322

323323
// Maps a list of ints and their indices to a list of points on a cartesian grid
324-
List<Offset> toPoints(List<int> samples) {
324+
List<Offset> toPoints(List<int>? samples) {
325325
List<Offset> points = [];
326326
if (samples == null)
327-
samples = List<int>.filled(size.width.toInt(), (0.5).toInt());
328-
double pixelsPerSample = size.width/samples.length;
327+
samples = List<int>.filled(size!.width.toInt(), (0.5).toInt());
328+
double pixelsPerSample = size!.width/samples.length;
329329
for (int i = 0; i < samples.length; i++) {
330-
var point = Offset(i * pixelsPerSample, 0.5 * size.height * pow((samples[i] - localMin)/(localMax - localMin), 5));
330+
var point = Offset(i * pixelsPerSample, 0.5 * size!.height * pow((samples[i] - localMin!)/(localMax! - localMin!), 5));
331331
points.add(point);
332332
}
333333
return points;
@@ -341,7 +341,7 @@ class WavePainter extends CustomPainter {
341341

342342
class Statistics extends StatelessWidget {
343343
final bool isRecording;
344-
final DateTime startTime;
344+
final DateTime? startTime;
345345

346346
final String url = "https://github.com/anarchuser/mic_stream";
347347

@@ -360,7 +360,7 @@ class Statistics extends StatelessWidget {
360360
ListTile(
361361
leading: Icon(Icons.access_time),
362362
title: Text((isRecording
363-
? DateTime.now().difference(startTime).toString()
363+
? DateTime.now().difference(startTime!).toString()
364364
: "Not recording"))),
365365
]);
366366
}

example/pubspec.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ description: Demonstrates how to use the mic_stream plugin.
33
publish_to: 'none'
44

55
environment:
6-
sdk: ">=2.1.0 <3.0.0"
6+
sdk: '>=2.12.0 <3.0.0'
77

88
dependencies:
99
flutter:
1010
sdk: flutter
1111

1212
# The following adds the Cupertino Icons font to your application.
1313
# Use with the CupertinoIcons class for iOS style icons.
14-
cupertino_icons: ^0.1.2
14+
cupertino_icons: ^1.0.4
1515
path_provider:
1616
dev_dependencies:
1717
flutter_test:

lib/mic_stream.dart

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,18 @@ class MicStream {
4040
MethodChannel('aaron.code.com/mic_stream_method_channel');
4141

4242
/// The actual sample rate used for streaming. This may return zero if invoked without listening to the _microphone Stream
43-
static Future<double> _sampleRate;
44-
static Future<double> get sampleRate => _sampleRate;
43+
static Future<double>? _sampleRate;
44+
static Future<double>? get sampleRate => _sampleRate;
4545

4646
/// The actual bit depth used for streaming. This may return zero if invoked without listening to the _microphone Stream first.
47-
static Future<int> _bitDepth;
48-
static Future<int> get bitDepth => _bitDepth;
47+
static Future<int>? _bitDepth;
48+
static Future<int>? get bitDepth => _bitDepth;
4949

50-
static Future<int> _bufferSize;
51-
static Future<int> get bufferSize => _bufferSize;
50+
static Future<int>? _bufferSize;
51+
static Future<int>? get bufferSize => _bufferSize;
5252

5353
/// The configured microphone stream;
54-
static Stream<Uint8List> _microphone;
54+
static Stream<Uint8List>? _microphone;
5555

5656
// This function manages the permission and ensures you're allowed to record audio
5757
static Future<bool> get permissionStatus async {
@@ -70,16 +70,16 @@ class MicStream {
7070
/// channelConfig: States whether audio is mono or stereo
7171
/// audioFormat: Switch between 8- and 16-bit PCM streams
7272
///
73-
static Future<Stream<Uint8List>> microphone(
73+
static Future<Stream<Uint8List>?> microphone(
7474
{AudioSource audioSource: _DEFAULT_AUDIO_SOURCE,
7575
int sampleRate: _DEFAULT_SAMPLE_RATE,
7676
ChannelConfig channelConfig: _DEFAULT_CHANNELS_CONFIG,
7777
AudioFormat audioFormat: _DEFAULT_AUDIO_FORMAT}) async {
7878
if (sampleRate < _MIN_SAMPLE_RATE || sampleRate > _MAX_SAMPLE_RATE)
7979
throw (RangeError.range(sampleRate, _MIN_SAMPLE_RATE, _MAX_SAMPLE_RATE));
80-
if (!(await permissionStatus)) throw (PlatformException);
80+
if (!(await permissionStatus))
81+
throw (PlatformException);
8182

82-
print("Receive pbroadacast stream");
8383
_microphone = _microphone ??
8484
_microphoneEventChannel.receiveBroadcastStream([
8585
audioSource.index,
@@ -91,25 +91,23 @@ class MicStream {
9191
// sampleRate/bitDepth should be populated before any attempt to consume the stream externally.
9292
// configure these as Completers and listen to the stream internally before returning
9393
// these will complete only when this internal listener is called
94-
StreamSubscription<Uint8List> listener;
94+
StreamSubscription<Uint8List>? listener;
9595
var sampleRateCompleter = new Completer<double>();
9696
var bitDepthCompleter = new Completer<int>();
9797
var bufferSizeCompleter = new Completer<int>();
9898
_sampleRate = sampleRateCompleter.future;
9999
_bitDepth = bitDepthCompleter.future;
100100
_bufferSize = bufferSizeCompleter.future;
101101

102-
print("LISTEN NOW: $_microphone");
103-
listener = _microphone.listen((x) async {
104-
print("listening........");
105-
await listener.cancel();
102+
listener = _microphone!.listen((x) async {
103+
await listener!.cancel();
106104
listener = null;
107105
sampleRateCompleter.complete(await _microphoneMethodChannel
108-
.invokeMethod("getSampleRate") as double);
106+
.invokeMethod("getSampleRate") as double?);
109107
bitDepthCompleter.complete(
110-
await _microphoneMethodChannel.invokeMethod("getBitDepth") as int);
108+
await _microphoneMethodChannel.invokeMethod("getBitDepth") as int?);
111109
bufferSizeCompleter.complete(
112-
await _microphoneMethodChannel.invokeMethod("getBufferSize") as int);
110+
await _microphoneMethodChannel.invokeMethod("getBufferSize") as int?);
113111
});
114112

115113
return _microphone;

pubspec.yaml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
name: mic_stream
22
description: Provides a tool to get the microphone input as PCM Stream
3-
version: 0.5.2
3+
version: 0.5.3
44
homepage: https://github.com/anarchuser
55

66
environment:
7-
sdk: ">=2.1.0 <3.0.0"
7+
sdk: '>=2.12.0 <3.0.0'
88
flutter: ">=2.0.1"
99

1010
module:
@@ -13,7 +13,7 @@ module:
1313
dependencies:
1414
flutter:
1515
sdk: flutter
16-
permission_handler: ^8.1.4
16+
permission_handler: ^8.2.6
1717

1818
# For information on the generic Dart part of this file, see the
1919
# following page: https://www.dartlang.org/tools/pub/pubspec

0 commit comments

Comments
 (0)