-
Notifications
You must be signed in to change notification settings - Fork 4
/
main.dart
159 lines (144 loc) · 4.07 KB
/
main.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter_soloud/flutter_soloud.dart';
import 'package:sound_spectrum/sound_spectrum.dart';
import 'package:permission_handler/permission_handler.dart';
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
/// Initialize the player
await SoLoud.instance.init().then(
(_) {
debugPrint('player started');
SoLoud.instance.setVisualizationEnabled(true);
SoLoud.instance.setGlobalVolume(1);
SoLoud.instance.setMaxActiveVoiceCount(32);
},
onError: (Object e) {
debugPrint('player starting error: $e');
},
);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Audio Visualizer Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
brightness: Brightness.dark,
),
home: const SoundSpectrumDemo(),
);
}
}
class SoundSpectrumDemo extends StatefulWidget {
const SoundSpectrumDemo({super.key});
@override
State<SoundSpectrumDemo> createState() => _SoundSpectrumDemoState();
}
class _SoundSpectrumDemoState extends State<SoundSpectrumDemo>
with SingleTickerProviderStateMixin {
late Ticker _ticker;
late AudioData _audioData;
bool _isRecording = false;
@override
void initState() {
super.initState();
_audioData = AudioData(GetSamplesFrom.microphone, GetSamplesKind.linear);
_ticker = createTicker(_onTick);
_startCapture();
}
void _onTick(Duration elapsed) {
if (_isRecording) {
setState(() {
_audioData.updateSamples();
});
}
}
@override
void dispose() {
_ticker.dispose();
_audioData.dispose();
_stopCapture();
super.dispose();
}
void _startCapture() async {
var status = await Permission.microphone.status;
debugPrint('Current microphone permission status: $status');
status = await Permission.microphone.request();
debugPrint('Microphone permission status after request: $status');
if (status != PermissionStatus.granted) {
debugPrint('Microphone permission not granted');
return;
}
if (!_isRecording) {
debugPrint('Initializing capture');
final initResult = SoLoudCapture.instance.init();
debugPrint('Capture init result: $initResult');
if (initResult == CaptureErrors.captureNoError) {
debugPrint('Starting capture');
final startResult = SoLoudCapture.instance.startCapture();
debugPrint('Capture start result: $startResult');
if (startResult == CaptureErrors.captureNoError) {
setState(() {
_isRecording = true;
_ticker.start();
});
debugPrint('Recording started');
} else {
debugPrint('Failed to start capture: $startResult');
}
} else {
debugPrint('Failed to initialize capture: $initResult');
}
}
}
void _stopCapture() {
if (_isRecording) {
SoLoudCapture.instance.stopCapture();
setState(() {
_isRecording = false;
_ticker.stop();
});
}
}
void _toggleRecording() {
if (_isRecording) {
_stopCapture();
} else {
_startCapture();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Audio Visualizer Demo'),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
SizedBox(
width: 300,
height: 150,
child: CustomPaint(
painter: AudioVisualizerPainter(
audioData: _audioData,
frequencyBands: 32,
),
),
),
const SizedBox(height: 20),
ElevatedButton(
onPressed: _toggleRecording,
child: Text(_isRecording ? 'Stop Recording' : 'Start Recording'),
),
],
),
),
);
}
}