-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.dart
107 lines (80 loc) · 2.91 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
import 'dart:io';
import 'dart:math';
import 'dart:typed_data';
const sampleRate = 44100;
const notesFrequencies = {
'Do': 261.63,
'Re': 293.66,
'Mi': 329.63,
'Fa': 349.23,
'Sol': 392.00,
'La': 440.00,
'Si': 493.88,
};
void main() async {
const durationSeconds = 2;
for (var entry in notesFrequencies.entries) {
final noteName = entry.key;
final frequency = entry.value;
print('Generating sound for $noteName ($frequency Hz)...');
final samples = generateSineWave(frequency, durationSeconds);
final wavData = generateWavData(samples);
final fileName = '${noteName.replaceAll(' ', '_')}.wav';
await File('out/$fileName').writeAsBytes(wavData);
print('Saved $noteName as $fileName');
}
print('All notes generated!');
}
Float32List generateSineWave(double frequency, int durationSeconds) {
final totalSamples = sampleRate * durationSeconds;
final samples = Float32List(totalSamples);
for (var i = 0; i < totalSamples; i++) {
final time = i / sampleRate;
samples[i] = sin(2 * pi * frequency * time);
}
return samples;
}
List<int> generateWavData(Float32List samples) {
final byteRate = sampleRate * 2;
final blockAlign = 2;
final wavHeader = ByteData(44);
// RIFF Header
wavHeader.setUint8(0, 'R'.codeUnitAt(0));
wavHeader.setUint8(1, 'I'.codeUnitAt(0));
wavHeader.setUint8(2, 'F'.codeUnitAt(0));
wavHeader.setUint8(3, 'F'.codeUnitAt(0));
wavHeader.setUint32(4, 36 + samples.lengthInBytes, Endian.little); // File size (bytes 4 - 7)
// Wave header
wavHeader.setUint8(8, 'W'.codeUnitAt(0));
wavHeader.setUint8(9, 'A'.codeUnitAt(0));
wavHeader.setUint8(10, 'V'.codeUnitAt(0));
wavHeader.setUint8(11, 'E'.codeUnitAt(0));
// fmt chunk
wavHeader.setUint8(12, 'f'.codeUnitAt(0));
wavHeader.setUint8(13, 'm'.codeUnitAt(0));
wavHeader.setUint8(14, 't'.codeUnitAt(0));
wavHeader.setUint8(15, ' '.codeUnitAt(0));
wavHeader.setUint32(16, 16, Endian.little); // chunk size
wavHeader.setUint16(20, 1, Endian.little); // audio format
wavHeader.setUint16(22, 1, Endian.little); // number of channel
wavHeader.setUint32(24, sampleRate, Endian.little); // sample rate
wavHeader.setUint32(28, byteRate, Endian.little); // byte rate
wavHeader.setUint16(32, blockAlign, Endian.little); // block align
wavHeader.setUint16(34, 16, Endian.little); // bits per sample
// data chunk
wavHeader.setUint8(36, 'd'.codeUnitAt(0));
wavHeader.setUint8(37, 'a'.codeUnitAt(0));
wavHeader.setUint8(38, 't'.codeUnitAt(0));
wavHeader.setUint8(39, 'a'.codeUnitAt(0));
wavHeader.setUint32(40, samples.lengthInBytes, Endian.little);
// raw audio data
final wavData = <int>[];
wavData.addAll(wavHeader.buffer.asUint8List());
for (final sample in samples) {
final intSample = (sample * 32767).clamp(-32768, 32767).toInt();
wavData.addAll(
Uint8List.sublistView(ByteData(2)..setInt16(0, intSample, Endian.little))
);
}
return wavData;
}