6
6
7
7
#define MINIAUDIO_IMPLEMENTATION
8
8
#include " miniaudio.h"
9
- #include " ../src/ crepe.hpp"
9
+ #include " crepe.hpp"
10
10
11
11
12
- class AudioProcessor {
12
+ class AudioProcessor
13
+ {
13
14
private:
14
15
moodycamel::ReaderWriterQueue<float > queue;
15
16
std::atomic<bool > finished{false };
16
17
size_t frame_size;
17
-
18
+
18
19
public:
19
- explicit AudioProcessor (const size_t size) : queue(size * 10 ), frame_size(size) {}
20
-
21
- void push (const float * data, const size_t count) {
22
- for (size_t i = 0 ; i < count; i++) {
20
+ explicit AudioProcessor (const size_t size) : queue(size * 10 ), frame_size(size)
21
+ {
22
+ }
23
+
24
+ void push (const float *data, const size_t count)
25
+ {
26
+ for (size_t i = 0 ; i < count; i++)
27
+ {
23
28
queue.enqueue (data[i]);
24
29
}
25
30
}
26
-
27
- bool get_frame (std::vector<float >& frame) {
28
- if (finished && queue.size_approx () < frame_size) {
31
+
32
+ bool get_frame (std::vector<float > &frame)
33
+ {
34
+ if (finished && queue.size_approx () < frame_size)
35
+ {
29
36
return false ;
30
37
}
31
-
38
+
32
39
// until we have enough data
33
- while (queue.size_approx () < frame_size && !finished) {
40
+ while (queue.size_approx () < frame_size && !finished)
41
+ {
34
42
std::this_thread::sleep_for (std::chrono::milliseconds (1 ));
35
43
}
36
-
37
- if (queue.size_approx () < frame_size) {
44
+
45
+ if (queue.size_approx () < frame_size)
46
+ {
38
47
return false ;
39
48
}
40
-
49
+
41
50
frame.resize (frame_size);
42
- for (size_t i = 0 ; i < frame_size; i++) {
51
+ for (size_t i = 0 ; i < frame_size; i++)
52
+ {
43
53
float value;
44
- if (bool success = queue.try_dequeue (value); !success) return false ;
54
+ if (bool success = queue.try_dequeue (value); !success)
55
+ return false ;
45
56
frame[i] = value;
46
57
}
47
58
return true ;
48
59
}
49
-
50
- void set_finished () {
60
+
61
+ void set_finished ()
62
+ {
51
63
finished = true ;
52
64
}
53
65
};
54
66
55
67
// miniaudio callbacl
56
- void data_callback (ma_device* device, void * output, const void * input, ma_uint32 frame_count) {
57
- auto * processor = static_cast <AudioProcessor*>(device->pUserData );
58
- const auto * in_samples = static_cast <const float *>(input);
59
-
68
+ void data_callback (ma_device *device, void *output, const void *input, ma_uint32 frame_count)
69
+ {
70
+ auto *processor = static_cast <AudioProcessor *>(device->pUserData );
71
+ const auto *in_samples = static_cast <const float *>(input);
72
+
60
73
// push
61
74
processor->push (in_samples, frame_count * device->capture .channels );
62
-
75
+
63
76
// clear if it's required
64
- if (output != nullptr ) {
77
+ if (output != nullptr )
78
+ {
65
79
memset (output, 0 , frame_count * device->playback .channels * sizeof (float ));
66
80
}
67
81
}
68
82
69
- int main () {
70
- try {
83
+ int main ()
84
+ {
85
+ try
86
+ {
71
87
// init miniaudio
72
88
ma_device_config config = ma_device_config_init (ma_device_type_capture);
73
89
config.capture .format = ma_format_f32;
74
- config.capture .channels = 1 ; // Mono for simplicity
90
+ config.capture .channels = 1 ; // Mono for simplicity
75
91
config.sampleRate = crepe::constants::SAMPLE_RATE;
76
92
config.dataCallback = data_callback;
77
93
78
94
AudioProcessor processor (crepe::constants::FRAME_LENGTH);
79
95
config.pUserData = &processor;
80
-
96
+
81
97
ma_device device;
82
- if (ma_device_init (nullptr , &config, &device) != MA_SUCCESS) {
98
+ if (ma_device_init (nullptr , &config, &device) != MA_SUCCESS)
99
+ {
83
100
std::cerr << " Error: Failed to initialize audio device" << std::endl;
84
101
}
85
-
86
- if (ma_device_start (&device) != MA_SUCCESS) {
102
+
103
+ if (ma_device_start (&device) != MA_SUCCESS)
104
+ {
87
105
ma_device_uninit (&device);
88
106
std::cerr << " Error: Failed to start audio device" << std::endl;
89
107
}
90
108
91
-
92
109
std::cout << " Recording. Press Enter to stop." << std::endl;
93
-
110
+
94
111
// analysis thread
95
112
std::atomic<bool > running{true };
96
113
std::thread analysis_thread ([&]() {
97
114
std::vector<float > frame;
98
- while (running) {
99
- if (processor.get_frame (frame)) {
115
+ while (running)
116
+ {
117
+ if (processor.get_frame (frame))
118
+ {
100
119
// Run inference on the frame
101
120
// Display the detected pitch
102
- if (crepe::PredictionResults results = crepe::run_inference (frame, crepe::constants::SAMPLE_RATE); results.num_frames > 0 ) {
103
- std::cout << " Pitch: " << results.pitches (0 ) << " Hz, Confidence: "
104
- << results.confidences (0 ) << " \r " << std::flush;
121
+ if (crepe::PredictionResults results = crepe::run_inference (
122
+ frame, crepe::constants::SAMPLE_RATE); results.num_frames > 0 )
123
+ {
124
+ std::cout << " Pitch: " << results.pitches (0 ) << " Hz, Confidence: "
125
+ << results.confidences (0 ) << " \r " << std::flush;
105
126
}
106
127
}
107
128
}
108
129
});
109
-
130
+
110
131
// Wait for user to press Enter
111
132
std::cin.get ();
112
133
113
134
running = false ;
114
135
processor.set_finished ();
115
-
116
- if (analysis_thread.joinable ()) {
136
+
137
+ if (analysis_thread.joinable ())
138
+ {
117
139
analysis_thread.join ();
118
140
}
119
-
141
+
120
142
ma_device_uninit (&device);
121
143
std::cout << " \n Recording stopped." << std::endl;
122
-
123
- } catch (const std::exception & e) {
144
+
145
+ }
146
+ catch (const std::exception &e)
147
+ {
124
148
std::cerr << " Error: " << e.what () << std::endl;
125
149
return 1 ;
126
150
}
127
-
151
+
128
152
return 0 ;
129
153
}
0 commit comments