Browse Source

Tweaked sound detection parameters

Thomas Buck 8 years ago
parent
commit
98f9a56871
2 changed files with 46 additions and 8 deletions
  1. 45
    7
      CaseLights/AudioVisualizer.m
  2. 1
    1
      CaseLights/Info.plist

+ 45
- 7
CaseLights/AudioVisualizer.m View File

15
 
15
 
16
 // Enabling this will cause crashes when changing audio input
16
 // Enabling this will cause crashes when changing audio input
17
 // devices while the app is running. Select it before enabling.
17
 // devices while the app is running. Select it before enabling.
18
+#ifdef DEBUG
18
 #define DEBUG_PLOT_FFT
19
 #define DEBUG_PLOT_FFT
19
 //#define DEBUG_PLOT_FFT_RAW
20
 //#define DEBUG_PLOT_FFT_RAW
21
+#endif
20
 
22
 
23
+#ifdef DEBUG_PLOT_FFT
21
 #define DEBUG_LOG_BEATS
24
 #define DEBUG_LOG_BEATS
25
+#endif
22
 
26
 
23
 #import "AudioVisualizer.h"
27
 #import "AudioVisualizer.h"
24
 #import "AppDelegate.h"
28
 #import "AppDelegate.h"
31
 
35
 
32
 // Parameters for fine-tuning beat detection
36
 // Parameters for fine-tuning beat detection
33
 #define FFT_BUCKET_COUNT 64
37
 #define FFT_BUCKET_COUNT 64
34
-#define FFT_BUCKET_HISTORY 43
35
-#define FFT_C_FACTOR 4.2
36
-#define FFT_V0_FACTOR 0.000015
37
-#define FFT_MAX_V0_COLOR 0.0002
38
-#define FFT_COLOR_DECAY 0.99
38
+#define FFT_BUCKET_HISTORY 45
39
+#define FFT_C_FACTOR 3.3
40
+#define FFT_V0_FACTOR 0.00001
41
+#define FFT_MAX_V0_COLOR 0.00025
42
+#define FFT_COLOR_DECAY 0.98
43
+
44
+// Use this to skip specific frequencies
45
+// Only check bass frequencies
46
+//#define FFT_BUCKET_SKIP_CONDITION (i > (FFT_BUCKET_COUNT / 4))
47
+// Only check mid frequencies
48
+//#define FFT_BUCKET_SKIP_CONDITION ((i < (FFT_BUCKET_COUNT / 4)) || (i > (FFT_BUCKET_COUNT * 3 / 4)))
49
+// Only check high frequencies
50
+//#define FFT_BUCKET_SKIP_CONDITION (i < (FFT_BUCKET_COUNT * 3 / 4))
39
 
51
 
40
 // Factors for nicer debug display
52
 // Factors for nicer debug display
41
 #define FFT_DEBUG_RAW_FACTOR 42.0
53
 #define FFT_DEBUG_RAW_FACTOR 42.0
98
     int beatCount = 0;
110
     int beatCount = 0;
99
 #endif
111
 #endif
100
     
112
     
113
+    // Slowly fade old colors to black
101
     static unsigned char lastRed = 0, lastGreen = 0, lastBlue = 0;
114
     static unsigned char lastRed = 0, lastGreen = 0, lastBlue = 0;
102
     lastRed = lastRed * FFT_COLOR_DECAY;
115
     lastRed = lastRed * FFT_COLOR_DECAY;
103
     lastGreen = lastGreen * FFT_COLOR_DECAY;
116
     lastGreen = lastGreen * FFT_COLOR_DECAY;
105
     
118
     
106
     // Check for any beats
119
     // Check for any beats
107
     for (int i = 0; i < FFT_BUCKET_COUNT; i++) {
120
     for (int i = 0; i < FFT_BUCKET_COUNT; i++) {
121
+        // Skip frequency bands, if required
122
+#ifdef FFT_BUCKET_SKIP_CONDITION
123
+        if (FFT_BUCKET_SKIP_CONDITION) continue;
124
+#endif
125
+        
126
+        // Calculate average of history of this frequency
108
         float average = 0.0f;
127
         float average = 0.0f;
109
         for (int j = 0; j < FFT_BUCKET_HISTORY; j++) {
128
         for (int j = 0; j < FFT_BUCKET_HISTORY; j++) {
110
             average += history[i][j];
129
             average += history[i][j];
111
         }
130
         }
112
         average /= FFT_BUCKET_HISTORY;
131
         average /= FFT_BUCKET_HISTORY;
132
+        
133
+        // Calculate variance of current bucket in history
113
         float v = 0.0f;
134
         float v = 0.0f;
114
         for (int j = 0; j < FFT_BUCKET_HISTORY; j++) {
135
         for (int j = 0; j < FFT_BUCKET_HISTORY; j++) {
115
             float tmp = history[i][j] - average;
136
             float tmp = history[i][j] - average;
117
             v += tmp;
138
             v += tmp;
118
         }
139
         }
119
         v /= FFT_BUCKET_HISTORY;
140
         v /= FFT_BUCKET_HISTORY;
141
+        
142
+        // Check for beat conditions
120
         if ((history[i][nextHistory] > (FFT_C_FACTOR * average)) && (v > FFT_V0_FACTOR)) {
143
         if ((history[i][nextHistory] > (FFT_C_FACTOR * average)) && (v > FFT_V0_FACTOR)) {
121
             // Found a beat on this frequency band, map to a single color
144
             // Found a beat on this frequency band, map to a single color
122
             if (v < FFT_V0_FACTOR) v = FFT_V0_FACTOR;
145
             if (v < FFT_V0_FACTOR) v = FFT_V0_FACTOR;
137
 #ifdef DEBUG_LOG_BEATS
160
 #ifdef DEBUG_LOG_BEATS
138
             NSLog(@"Beat in %d with c: %f v: %f", i, (history[i][nextHistory] / average), v);
161
             NSLog(@"Beat in %d with c: %f v: %f", i, (history[i][nextHistory] / average), v);
139
 #endif
162
 #endif
163
+            
140
 #ifdef DEBUG_PLOT_FFT
164
 #ifdef DEBUG_PLOT_FFT
141
             beatCount++;
165
             beatCount++;
142
 #endif
166
 #endif
143
         }
167
         }
144
     }
168
     }
145
     
169
     
146
-    [appDelegate setLightsR:lastRed G:lastGreen B:lastBlue];
170
+    // Send new RGB value to lights, if it has changed
171
+    static unsigned char lastSentRed = 42, lastSentGreen = 23, lastSentBlue = 99;
172
+    if ((lastSentRed != lastRed) || (lastSentGreen != lastGreen) || (lastSentBlue != lastBlue)) {
173
+        [appDelegate setLightsR:lastRed G:lastGreen B:lastBlue];
174
+        lastSentRed = lastRed;
175
+        lastSentGreen = lastGreen;
176
+        lastSentBlue = lastBlue;
177
+    }
147
 
178
 
179
+    // Display debug FFT plot, if required
148
 #ifdef DEBUG_PLOT_FFT
180
 #ifdef DEBUG_PLOT_FFT
149
     static NSWindow *window = nil;
181
     static NSWindow *window = nil;
150
     static EZAudioPlot *plot = nil;
182
     static EZAudioPlot *plot = nil;
151
     static NSTextField *label = nil;
183
     static NSTextField *label = nil;
152
     if ((window == nil) || (plot == nil) || (label == nil)) {
184
     if ((window == nil) || (plot == nil) || (label == nil)) {
185
+        // Create window
153
         NSRect frame = NSMakeRect(450, 300, 600, 400);
186
         NSRect frame = NSMakeRect(450, 300, 600, 400);
154
         window = [[NSWindow alloc] initWithContentRect:frame
187
         window = [[NSWindow alloc] initWithContentRect:frame
155
                                              styleMask:NSClosableWindowMask | NSTitledWindowMask | NSBorderlessWindowMask
188
                                              styleMask:NSClosableWindowMask | NSTitledWindowMask | NSBorderlessWindowMask
157
                                                  defer:NO];
190
                                                  defer:NO];
158
         [window setTitle:@"Debug FFT"];
191
         [window setTitle:@"Debug FFT"];
159
         
192
         
193
+        // Create FFT Plot and add to window
160
         plot = [[EZAudioPlot alloc] initWithFrame:window.contentView.frame];
194
         plot = [[EZAudioPlot alloc] initWithFrame:window.contentView.frame];
161
         plot.color = [NSColor whiteColor];
195
         plot.color = [NSColor whiteColor];
162
         plot.shouldOptimizeForRealtimePlot = NO; // Not working with 'YES' here?!
196
         plot.shouldOptimizeForRealtimePlot = NO; // Not working with 'YES' here?!
166
         plot.plotType = EZPlotTypeBuffer;
200
         plot.plotType = EZPlotTypeBuffer;
167
         [window.contentView addSubview:plot];
201
         [window.contentView addSubview:plot];
168
         
202
         
203
+        // Create beat count label
169
         label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 380, 600, 20)];
204
         label = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 380, 600, 20)];
170
         [label setTextColor:[NSColor whiteColor]];
205
         [label setTextColor:[NSColor whiteColor]];
171
         [label setEditable:NO];
206
         [label setEditable:NO];
175
         [label setStringValue:@"-"];
210
         [label setStringValue:@"-"];
176
         [window.contentView addSubview:label];
211
         [window.contentView addSubview:label];
177
         
212
         
213
+        // Make window visible
178
         [window makeKeyAndOrderFront:appDelegate.application];
214
         [window makeKeyAndOrderFront:appDelegate.application];
179
         NSLog(@"Created debugging FFT Plot window...\n");
215
         NSLog(@"Created debugging FFT Plot window...\n");
180
     }
216
     }
181
     
217
     
182
-    // Scale so we can see something
218
+    // Copy output to input buffer (a bit ugly, but is always big enough)
219
+    // Scale so user can see something
183
 # ifdef DEBUG_PLOT_FFT_RAW
220
 # ifdef DEBUG_PLOT_FFT_RAW
184
     memcpy(buffer, fft.fftData, bufferSize * sizeof(float));
221
     memcpy(buffer, fft.fftData, bufferSize * sizeof(float));
185
     for (UInt32 i = 0; i < bufferSize; i++) {
222
     for (UInt32 i = 0; i < bufferSize; i++) {
196
     }
233
     }
197
     [plot updateBuffer:buffer withBufferSize:bufferSize];
234
     [plot updateBuffer:buffer withBufferSize:bufferSize];
198
     
235
     
236
+    // Change background color to match color output and show beat counter
199
     [window setBackgroundColor:[NSColor colorWithCalibratedRed:lastRed / 255.0 green:lastGreen / 255.0 blue:lastBlue / 255.0 alpha:1.0]];
237
     [window setBackgroundColor:[NSColor colorWithCalibratedRed:lastRed / 255.0 green:lastGreen / 255.0 blue:lastBlue / 255.0 alpha:1.0]];
200
     [label setStringValue:[NSString stringWithFormat:@"Beats: %d", beatCount]];
238
     [label setStringValue:[NSString stringWithFormat:@"Beats: %d", beatCount]];
201
 #endif
239
 #endif

+ 1
- 1
CaseLights/Info.plist View File

21
 	<key>CFBundleSignature</key>
21
 	<key>CFBundleSignature</key>
22
 	<string>????</string>
22
 	<string>????</string>
23
 	<key>CFBundleVersion</key>
23
 	<key>CFBundleVersion</key>
24
-	<string>359</string>
24
+	<string>388</string>
25
 	<key>LSApplicationCategoryType</key>
25
 	<key>LSApplicationCategoryType</key>
26
 	<string>public.app-category.utilities</string>
26
 	<string>public.app-category.utilities</string>
27
 	<key>LSMinimumSystemVersion</key>
27
 	<key>LSMinimumSystemVersion</key>

Loading…
Cancel
Save