[ab9d63b] | 1 | |
---|
| 2 | |
---|
| 3 | |
---|
| 4 | |
---|
| 5 | |
---|
| 6 | |
---|
| 7 | |
---|
| 8 | |
---|
| 9 | |
---|
| 10 | |
---|
| 11 | |
---|
| 12 | #import <QuartzCore/QuartzCore.h> |
---|
| 13 | #import "FlightViewController.h" |
---|
| 14 | #import "AppDelegate.h" |
---|
| 15 | #import "SignalConverter.h" |
---|
| 16 | |
---|
[2246ba0] | 17 | #import "StatisticsViewController.h" |
---|
| 18 | |
---|
[ab9d63b] | 19 | #define STATUS_DEFAULT 0 |
---|
| 20 | #define STATUS_CONNECTING 1 |
---|
| 21 | #define STATUS_CONNECTED 2 |
---|
| 22 | #define STATUS_PROCESSING 3 |
---|
| 23 | #define STATUS_ACTIVE 4 |
---|
| 24 | |
---|
| 25 | @implementation FlightViewController { |
---|
[ad80ed2] | 26 | SignalConverter *signalConverter; |
---|
| 27 | int deviceStatus; |
---|
| 28 | BOOL warned; |
---|
[ab9d63b] | 29 | } |
---|
| 30 | |
---|
[8a0f920f] | 31 | @synthesize attention, meditation, signal, power, attentionThreshold, meditationThreshold, connectButton, testButton, statusImage, signalPercent, attentionPercent, meditationPercent, powerPercent; |
---|
[ab9d63b] | 32 | |
---|
| 33 | - (void)viewDidLoad |
---|
| 34 | { |
---|
[ad80ed2] | 35 | [super viewDidLoad]; |
---|
| 36 | |
---|
| 37 | attention.progressTintColor = [UIColor redColor]; |
---|
| 38 | self.attentionThreshold.minimumTrackTintColor = [UIColor grayColor]; |
---|
| 39 | meditation.progressTintColor = [UIColor blueColor]; |
---|
| 40 | self.meditationThreshold.minimumTrackTintColor = [UIColor grayColor]; |
---|
| 41 | self.meditationThreshold.value = 0; |
---|
[ba2b6ff] | 42 | |
---|
[ad80ed2] | 43 | AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; |
---|
| 44 | signalConverter = appDelegate.signalConverter; |
---|
| 45 | |
---|
| 46 | signalConverter.delegate = self; |
---|
| 47 | [self setThresholds]; |
---|
| 48 | [self.attentionThreshold addTarget:self action:@selector(setThresholds) forControlEvents:UIControlEventValueChanged]; |
---|
| 49 | [self.meditationThreshold addTarget:self action:@selector(setThresholds) forControlEvents:UIControlEventValueChanged]; |
---|
[ad40faa] | 50 | |
---|
[ab9d63b] | 51 | } |
---|
| 52 | |
---|
| 53 | #pragma mark view updates |
---|
| 54 | |
---|
| 55 | |
---|
| 56 | - (void) resetViews |
---|
| 57 | { |
---|
[ad80ed2] | 58 | signal.progress = 0; |
---|
| 59 | signalPercent.text = @"0%"; |
---|
| 60 | attention.progress = 0; |
---|
| 61 | attentionPercent.text = @"0%"; |
---|
| 62 | meditation.progress = 0; |
---|
| 63 | meditationPercent.text = @"0%"; |
---|
| 64 | power.progress = 0; |
---|
| 65 | powerPercent.text = @"0%"; |
---|
| 66 | [self updateStatusImage:STATUS_DEFAULT]; |
---|
| 67 | connectButton.title = @"Connect"; |
---|
[ab9d63b] | 68 | } |
---|
| 69 | |
---|
| 70 | - (void) updateStatusImage:(int) statusNo |
---|
| 71 | { |
---|
[ad80ed2] | 72 | if (statusNo != deviceStatus) { |
---|
| 73 | [statusImage setImage: [UIImage imageNamed:[NSString stringWithFormat:@"status_%u", statusNo]]]; |
---|
| 74 | deviceStatus = statusNo; |
---|
| 75 | } |
---|
[ab9d63b] | 76 | } |
---|
| 77 | |
---|
[8a0f920f] | 78 | - (void) setThresholds |
---|
[ab9d63b] | 79 | { |
---|
[ad80ed2] | 80 | [signalConverter setValuesForAttention:attentionThreshold.value meditation:meditationThreshold.value]; |
---|
[ab9d63b] | 81 | } |
---|
| 82 | |
---|
| 83 | #pragma mark - SignalConverterDelegate methods |
---|
| 84 | |
---|
| 85 | - (void) updatedValuesForSignal: (float)signalStrength |
---|
| 86 | attention: (float)attentionLevel |
---|
| 87 | meditation: (float)meditationLevel |
---|
| 88 | power: (float)powerLevel |
---|
| 89 | { |
---|
[af91708] | 90 | |
---|
[ad80ed2] | 91 | |
---|
| 92 | if (signalStrength < 100.0) { |
---|
| 93 | attentionLevel = 0.000000; |
---|
| 94 | meditationLevel = 0.000000; |
---|
| 95 | powerLevel = 0.000000; |
---|
| 96 | } |
---|
[d249b65] | 97 | |
---|
[ad80ed2] | 98 | self.signal.progress = signalStrength / 100; |
---|
| 99 | self.signalPercent.text = [NSString stringWithFormat:@"%i%%", (int)(signalStrength)]; |
---|
| 100 | self.attention.progress = attentionLevel; |
---|
| 101 | self.attentionPercent.text = [NSString stringWithFormat:@"%i%%", (int)(attentionLevel * 100)]; |
---|
| 102 | self.meditation.progress = meditationLevel; |
---|
| 103 | self.meditationPercent.text = [NSString stringWithFormat:@"%i%%", (int)(meditationLevel * 100)]; |
---|
| 104 | self.power.progress = powerLevel; |
---|
| 105 | self.powerPercent.text = [NSString stringWithFormat:@"%i%%", (int)(powerLevel * 100)]; |
---|
| 106 | [self updateStatusImage:[self statusFromSignal:signalStrength power:powerLevel]]; |
---|
[d249b65] | 107 | |
---|
[b5aa714] | 108 | [self updateScores]; |
---|
| 109 | |
---|
[9015b1e] | 110 | } |
---|
| 111 | |
---|
| 112 | - (int) statusFromSignal: (float)signalLevel power:(float)powerLevel |
---|
| 113 | { |
---|
[812f274] | 114 | |
---|
[af91708] | 115 | |
---|
[812f274] | 116 | |
---|
| 117 | if (signalLevel == 0.0) { |
---|
| 118 | return STATUS_CONNECTING; |
---|
| 119 | } |
---|
| 120 | |
---|
| 121 | if (signalLevel < 100.0) { |
---|
[ad80ed2] | 122 | return STATUS_CONNECTED; |
---|
[812f274] | 123 | } |
---|
| 124 | |
---|
| 125 | if (powerLevel == 0.0) { |
---|
[ad80ed2] | 126 | return STATUS_PROCESSING; |
---|
| 127 | } else { |
---|
| 128 | return STATUS_ACTIVE; |
---|
| 129 | } |
---|
[812f274] | 130 | |
---|
[ab9d63b] | 131 | } |
---|
| 132 | |
---|
| 133 | - (void) notifyHeadsetConnect |
---|
| 134 | { |
---|
[ad80ed2] | 135 | [self updateStatusImage:STATUS_CONNECTING]; |
---|
[ab9d63b] | 136 | } |
---|
| 137 | |
---|
| 138 | - (void) notifyHeadsetDisconnect |
---|
| 139 | { |
---|
[ad80ed2] | 140 | |
---|
| 141 | [self resetViews]; |
---|
[ab9d63b] | 142 | } |
---|
| 143 | |
---|
| 144 | - (void) notifyDeviceConnected:(NSString *)name |
---|
| 145 | { |
---|
[ad80ed2] | 146 | [self updateStatusImage:STATUS_CONNECTING]; |
---|
| 147 | connectButton.title = @"Disconnect"; |
---|
[9015b1e] | 148 | } |
---|
| 149 | |
---|
| 150 | - (void) appStopped |
---|
| 151 | { |
---|
[ad80ed2] | 152 | [self resetViews]; |
---|
[ab9d63b] | 153 | } |
---|
| 154 | |
---|
| 155 | #pragma mark - button press events |
---|
| 156 | |
---|
| 157 | - (IBAction) connectButtonPressed:(id) sender { |
---|
[ad80ed2] | 158 | |
---|
| 159 | if (signalConverter.running) { |
---|
| 160 | [signalConverter stopProcessing]; |
---|
| 161 | [self resetViews]; |
---|
| 162 | } else { |
---|
| 163 | BOOL volumeMax = [signalConverter isVolumeMax]; |
---|
| 164 | BOOL headphones = [signalConverter isAudioJackPlugged]; |
---|
| 165 | |
---|
| 166 | if (!warned && !volumeMax && !headphones) { |
---|
| 167 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Check Volume & Transmitter" message:@"Ensure the volume is at max and the transmitter is plugged into the headphones" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; |
---|
| 168 | [alert show]; |
---|
| 169 | } else if (!warned && !volumeMax) { |
---|
| 170 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Turn Up The Volume" message:@"Your device volume must be at the maximum for proper operation" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; |
---|
| 171 | [alert show]; |
---|
| 172 | } else if (!warned && !headphones) { |
---|
| 173 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Plug In The Transmitter" message:@"Ensure the infrared transmitter is plugged into the headphone jack" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; |
---|
| 174 | [alert show]; |
---|
| 175 | } else if (!signalConverter.isBluetoothReady) { |
---|
| 176 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Device not found" message:@"No Bluetooth device detected. Ensure Bluetooth is on and the Mindwave headset is paired" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; |
---|
| 177 | [alert show]; |
---|
| 178 | } else if ([signalConverter startProcessing]) { |
---|
| 179 | connectButton.title = @"Disconnect"; |
---|
| 180 | } else { |
---|
| 181 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Failed to connect" message:@"Check the device is correctly paired on Bluetooth" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; |
---|
| 182 | [alert show]; |
---|
| 183 | } |
---|
| 184 | warned = YES; |
---|
| 185 | } |
---|
[ab9d63b] | 186 | } |
---|
| 187 | |
---|
[de10cbc] | 188 | - (IBAction) testButtonPressed:(id) sender { |
---|
[4a56cfb] | 189 | |
---|
[af91708] | 190 | |
---|
[4a56cfb] | 191 | |
---|
[2246ba0] | 192 | |
---|
| 193 | |
---|
| 194 | |
---|
[ad80ed2] | 195 | [signalConverter isAudioJackPlugged]; |
---|
| 196 | if (signalConverter.running) { |
---|
[3434fbc] | 197 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Signal Processing Active" message:@"Please press the Disconnect button before sending a Test signal" delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil]; |
---|
[ad80ed2] | 198 | [alert show]; |
---|
| 199 | } else { |
---|
| 200 | if (signalConverter.testing) { |
---|
| 201 | testButton.title = @"Test"; |
---|
| 202 | [signalConverter stopTestSound]; |
---|
| 203 | } else { |
---|
| 204 | testButton.title = @"Stop"; |
---|
| 205 | [signalConverter playTestSound]; |
---|
| 206 | } |
---|
| 207 | } |
---|
[de10cbc] | 208 | } |
---|
| 209 | |
---|
[b5aa714] | 210 | - (void) updateScores |
---|
| 211 | { |
---|
[af91708] | 212 | |
---|
[f45b70a] | 213 | |
---|
| 214 | |
---|
| 215 | |
---|
| 216 | |
---|
| 217 | |
---|
| 218 | |
---|
| 219 | |
---|
| 220 | |
---|
| 221 | |
---|
| 222 | |
---|
| 223 | |
---|
| 224 | |
---|
| 225 | |
---|
| 226 | |
---|
| 227 | |
---|
| 228 | |
---|
| 229 | |
---|
| 230 | |
---|
| 231 | |
---|
[b5aa714] | 232 | |
---|
| 233 | int eegAttentionScore = 0; |
---|
| 234 | int eegAttention = self.attention.progress * 100; |
---|
| 235 | int eegAttentionTarget = self.attentionThreshold.value * 100; |
---|
[af91708] | 236 | |
---|
[b5aa714] | 237 | int eegMeditationScore = 0; |
---|
| 238 | int eegMeditation = self.meditation.progress * 100; |
---|
| 239 | int eegMeditationTarget = self.meditationThreshold.value * 100; |
---|
| 240 | |
---|
[af91708] | 241 | |
---|
[b5aa714] | 242 | if ((eegAttention >= eegAttentionTarget) && |
---|
| 243 | (eegAttentionTarget > minimumScoreTarget)) |
---|
| 244 | eegAttentionScore = eegAttentionTarget - minimumScoreTarget; |
---|
| 245 | |
---|
| 246 | if ((eegMeditation >= eegMeditationTarget) && |
---|
| 247 | (eegMeditationTarget > minimumScoreTarget)) |
---|
| 248 | eegMeditationScore = eegMeditationTarget - minimumScoreTarget; |
---|
| 249 | |
---|
| 250 | if (eegAttentionScore > eegMeditationScore) |
---|
| 251 | scoreCurrent = scoreCurrent + eegAttentionScore; |
---|
| 252 | else |
---|
| 253 | scoreCurrent = scoreCurrent + eegMeditationScore; |
---|
| 254 | |
---|
| 255 | |
---|
[af91708] | 256 | |
---|
| 257 | if (scoreCurrent > scoreHigh) { |
---|
| 258 | scoreHigh = scoreCurrent; |
---|
| 259 | } |
---|
[b5aa714] | 260 | |
---|
[af91708] | 261 | |
---|
| 262 | if (power.progress == 0) |
---|
| 263 | [self resetCurrentScore]; |
---|
[b5aa714] | 264 | |
---|
[af91708] | 265 | |
---|
| 266 | |
---|
| 267 | |
---|
| 268 | |
---|
| 269 | |
---|
| 270 | if ((eegAttention < eegAttentionTarget) && (eegMeditation < minimumScoreTarget)) |
---|
| 271 | [self resetCurrentScore]; |
---|
| 272 | |
---|
| 273 | if ((eegMeditation < eegMeditationTarget) && (eegAttention < minimumScoreTarget)) |
---|
| 274 | [self resetCurrentScore]; |
---|
| 275 | |
---|
| 276 | if ((eegAttention < minimumScoreTarget) && (eegMeditation < minimumScoreTarget)) |
---|
| 277 | [self resetCurrentScore]; |
---|
| 278 | |
---|
| 279 | |
---|
| 280 | [self displayScore]; |
---|
| 281 | |
---|
[f45b70a] | 282 | } |
---|
[b5aa714] | 283 | |
---|
[af91708] | 284 | - (void) displayScore |
---|
| 285 | { |
---|
[c6dde93] | 286 | |
---|
| 287 | NSString* newScore = [NSString stringWithFormat:@"Scores Current: %i Last: %i High: %i", (int)scoreCurrent, (int)scoreLast, (int)scoreHigh]; |
---|
| 288 | |
---|
| 289 | if (newScore.length >= 50) |
---|
| 290 | newScore = [NSString stringWithFormat:@"Scores Current: %i Last: %i High: %i", (int)scoreCurrent, (int)scoreLast, (int)scoreHigh]; |
---|
| 291 | |
---|
| 292 | if (newScore.length >= 50) |
---|
| 293 | newScore = [NSString stringWithFormat:@"Scores Current: %i Last: %i High: %i", (int)scoreCurrent, (int)scoreLast, (int)scoreHigh]; |
---|
| 294 | |
---|
| 295 | self.scoresDisplay.text = newScore; |
---|
[af91708] | 296 | } |
---|
[b5aa714] | 297 | |
---|
[af91708] | 298 | - (void) resetCurrentScore |
---|
| 299 | { |
---|
| 300 | if (scoreCurrent > 0) |
---|
| 301 | scoreLast = scoreCurrent; |
---|
| 302 | |
---|
| 303 | scoreCurrent = 0; |
---|
| 304 | |
---|
[f45b70a] | 305 | } |
---|
[b5aa714] | 306 | |
---|
[ab9d63b] | 307 | @end |
---|