11import 'dart:async' ;
22import 'dart:io' show Platform;
3+ import 'dart:math' show max;
34
45import 'package:flutter/material.dart' ;
56
@@ -10,23 +11,26 @@ class RecorderController extends ChangeNotifier {
1011 final List <double > _waveData = [];
1112
1213 /// At which rate waveform needs to be updated
13- late Duration updateFrequency = const Duration (milliseconds: 100 );
14+ Duration updateFrequency = const Duration (milliseconds: 100 );
1415
15- late AndroidEncoder androidEncoder = AndroidEncoder .aac;
16+ AndroidEncoder androidEncoder = AndroidEncoder .aac;
1617
17- late AndroidOutputFormat androidOutputFormat = AndroidOutputFormat .mpeg4;
18+ AndroidOutputFormat androidOutputFormat = AndroidOutputFormat .mpeg4;
1819
19- late IosEncoder iosEncoder = IosEncoder .kAudioFormatMPEG4AAC;
20+ IosEncoder iosEncoder = IosEncoder .kAudioFormatMPEG4AAC;
2021
21- late int sampleRate = 44100 ;
22+ int sampleRate = 44100 ;
2223
23- late int bitRate = 48000 ;
24+ int bitRate = 48000 ;
2425
25- ///Db we get from native is too high so in Android it the value is subtracted
26- ///and in IOS value added
27- late double normalizationFactor = Platform .isAndroid ? 60 : 40 ;
26+ /// Current maximum peak power for ios and peak amplitude android.
27+ double _maxPeak = Platform .isIOS ? 1 : 32786.0 ;
2828
29- ///Current list of decibels(different values for each platform)
29+ /// Current list of scaled waves. For IOS, this list contains normalised
30+ /// peak power and for Android, this list contains normalised peak
31+ /// amplitude.
32+ ///
33+ /// Values are between 0.0 to 1.0.
3034 List <double > get waveData => _waveData;
3135
3236 RecorderState _recorderState = RecorderState .stopped;
@@ -92,14 +96,27 @@ class RecorderController extends ChangeNotifier {
9296 ///
9397 /// 2. Stopped -: If a recorder is stopped from previous recording and again
9498 /// this function is called then it will re-initialise the recorder.
95- Future <void > record ([String ? path]) async {
96- if (_recorderState != RecorderState .recording) {
99+ Future <void > record ({
100+ String ? path,
101+ AndroidEncoder ? androidEncoder,
102+ AndroidOutputFormat ? androidOutputFormat,
103+ IosEncoder ? iosEncoder,
104+ int ? sampleRate,
105+ int ? bitRate,
106+ }) async {
107+ if (! _recorderState.isRecording) {
97108 await checkPermission ();
98109 if (_hasPermission) {
99- if (Platform .isAndroid && _recorderState == RecorderState .stopped) {
100- await _initRecorder (path);
110+ if (Platform .isAndroid && _recorderState.isStopped) {
111+ await _initRecorder (
112+ path: path,
113+ androidEncoder: androidEncoder,
114+ androidOutputFormat: androidOutputFormat,
115+ sampleRate: sampleRate,
116+ bitRate: bitRate,
117+ );
101118 }
102- if (_recorderState == RecorderState .paused ) {
119+ if (_recorderState.isPaused ) {
103120 _isRecording = await AudioWaveformsInterface .instance.resume ();
104121 if (_isRecording) {
105122 _startTimer ();
@@ -113,12 +130,13 @@ class RecorderController extends ChangeNotifier {
113130 if (Platform .isIOS) {
114131 _recorderState = RecorderState .initialized;
115132 }
116- if (_recorderState == RecorderState .initialized ) {
133+ if (_recorderState.isInitialized ) {
117134 _isRecording = await AudioWaveformsInterface .instance.record (
118- audioFormat:
119- Platform .isIOS ? iosEncoder.index : androidEncoder.index,
120- sampleRate: sampleRate,
121- bitRate: bitRate,
135+ audioFormat: Platform .isIOS
136+ ? iosEncoder? .index ?? this .iosEncoder.index
137+ : androidEncoder? .index ?? this .androidEncoder.index,
138+ sampleRate: sampleRate ?? this .sampleRate,
139+ bitRate: bitRate ?? this .bitRate,
122140 path: path,
123141 );
124142 if (_isRecording) {
@@ -137,13 +155,20 @@ class RecorderController extends ChangeNotifier {
137155 }
138156
139157 /// Initialises recorder for android platform.
140- Future <void > _initRecorder (String ? path) async {
158+ Future <void > _initRecorder ({
159+ String ? path,
160+ AndroidEncoder ? androidEncoder,
161+ AndroidOutputFormat ? androidOutputFormat,
162+ int ? sampleRate,
163+ int ? bitRate,
164+ }) async {
141165 final initialized = await AudioWaveformsInterface .instance.initRecorder (
142166 path: path,
143- encoder: androidEncoder.index,
144- outputFormat: androidOutputFormat.index,
145- sampleRate: sampleRate,
146- bitRate: bitRate,
167+ encoder: androidEncoder? .index ?? this .androidEncoder.index,
168+ outputFormat:
169+ androidOutputFormat? .index ?? this .androidOutputFormat.index,
170+ sampleRate: sampleRate ?? this .sampleRate,
171+ bitRate: bitRate ?? this .bitRate,
147172 );
148173 if (initialized) {
149174 _recorderState = RecorderState .initialized;
@@ -172,7 +197,7 @@ class RecorderController extends ChangeNotifier {
172197
173198 /// Pauses the current recording. Call [record] to resume recording.
174199 Future <void > pause () async {
175- if (_recorderState == RecorderState .recording ) {
200+ if (_recorderState.isRecording ) {
176201 _isRecording = (await AudioWaveformsInterface .instance.pause ()) ?? true ;
177202 if (_isRecording) {
178203 throw "Failed to pause recording" ;
@@ -195,8 +220,7 @@ class RecorderController extends ChangeNotifier {
195220 /// manually else it will start showing waveforms from same place where it
196221 /// left of for previous recording.
197222 Future <String ?> stop ([bool callReset = true ]) async {
198- if (_recorderState == RecorderState .recording ||
199- _recorderState == RecorderState .paused) {
223+ if (_recorderState.isRecording || _recorderState.isPaused) {
200224 final path = await AudioWaveformsInterface .instance.stop ();
201225
202226 if (path != null ) {
@@ -251,19 +275,12 @@ class RecorderController extends ChangeNotifier {
251275 );
252276 }
253277
254- /// Normalises the decibel
255- void _normalise (double db) {
256- if (Platform .isAndroid) {
257- waveData.add (db - normalizationFactor);
258- } else {
259- if (db == 0.0 ) {
260- waveData.add (0 );
261- } else if (db + normalizationFactor < 1 ) {
262- waveData.add (0 );
263- } else {
264- waveData.add (db + normalizationFactor);
265- }
266- }
278+ /// Normalises the peak power for ios and peak amplitude for android
279+ void _normalise (double peak) {
280+ final absDb = peak.abs ();
281+ _maxPeak = max (absDb, _maxPeak);
282+ final scaledWave = (absDb / _maxPeak);
283+ _waveData.add (scaledWave);
267284 notifyListeners ();
268285 }
269286
0 commit comments